diff --git a/docs/changelog_v3.2.x.md b/docs/changelog_v3.2.x.md
index f2ec3d3a3..c55bc2e1e 100644
--- a/docs/changelog_v3.2.x.md
+++ b/docs/changelog_v3.2.x.md
@@ -30,10 +30,8 @@ that you need.
# v3.2.6 2021-04-11
-
* **v3.2.6 2021-04-11**
-
* **Start to add in a PrisonMinesBlockEventEvent class.**
It has been disabled because it cannot be used yet; the BlockEvents need to under go some major changes to support its use.
Currently the BlockEvents receive only references to the sources (block names and not the actual blocks), but in order to hook this up properly, all blocks and details need to be passed. The current system for controlling the BlockEvents is unable to support that kind of an environment right now. It will be changed in the very near future to get this working.
diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md
index a76b3b826..aae7a5a96 100644
--- a/docs/changelog_v3.3.x.md
+++ b/docs/changelog_v3.3.x.md
@@ -13,952 +13,1008 @@ These build logs represent the work that has been going on within prison.
*Will continue as v3.3.0-alpha.7 2021-06-?? in the near future.*
+# 3.2.11 2022-01-22
-# v3.2.10 2021-08-22
+**3.2.11 2022-01-22**
+
+
+* **Added to SpigotPlayer the ability to enable flying and to check to see if the player is flying. This is to prepare for mine effects.**
+
+
+* **Considering adding heads support to prison. Added a few parts, but they are not functional.**
+
+
+* **3.2.11-alpha.17 2022-01-18**
+
+
+* **More updates to the player's rank menu with the ability to add rank specific lore to the configs.**
+When referring to ranks, the names much match exactly since they are case sensitive.
+
+
+* **Bug fix with the rank cost calculations since they were not pulling in the last rank in the rang of ranks.**
-* **Prison Release v3.2.10**
+* **Fixed an issue with CI's function that was not returning any ids.**
-* **Updated to the support of the Prison's ExplosiveBlockBreakEvent. There were a few adjustments that were needed.**
+* **Mine auto resets can now be disabled.**
+When disabled, they will never reset based upon time. The resets can still be triggered by blocks remaining thresholds.
-* **Some blocks within the liners are not compatible with all versions of bukkit/spigot/minecraft.**
-Added minimal versions to the patterns so as to help prevent the use of the wrong patterns for the server version.
+* **3.2.11-alpha.16 2022-01-16**
-* **Found an error with two Mine Liners that had pillar_quartz_block instead of quartz_pillar.**
+* **Lot of updates to the GUI menus.**
+Major improvements to the player's /gui ranks to work better with placeholders. Added comments to the GuiConfig.yml file on how to use it and the placeholders.
+Delete the GuiConfig.yml file to regenerate with the updated information on lore settings.
-* **Added support for Prison's own ExplosiveBlockBreakEvent.**
-This will be used for Prison's up coming Prison Bombs. Also this can be used by other plugins too.
+* **Update a few of the player's GUIs to support the SpigotGUIMenutools.**
+Added capability to control the return command and the paging command so it now works more intuitivily.
-* **Update the PrisonEnchants code for handing their PEExplosionEvent object.**
+* **Fix issue with the placeholders related to prison_rankup_cost.**
+This now works correctly to include the next prestig rank's cost when at the last rank in the default ladder.
-* **Fix a problem with NPE when getting the player's Locale when it wasn't set.**
+* **Bug fix: Get the 32 placeholders related to prison_rankup_cost working correctly when dealing with various prestige conditions.**
-* **More adjustments to the /ranks list to add information about the player's current multipliers on all the ladders.**
-This makes it easier to understand why the rank multiplier is a specific value.
-* **Some adjustments to `/ranks list` to remove "admin stuff" from the list for non-admins.**
+* **Bug fix: The player based playSound was not working, but the world's playSound works perfectly. Not sue why bukkit player would be messed up that **
-* **v3.2.10-alpha.14b 2021-08-22**
+* **Bug fix: Hooking up the rollover to the next prestige rank cost, when at th end of the ladder, had a typo where it would not evaluate any rank.**
-* **Removed the option to delete a rank from the ranks info command since it should not be that easy to remove a rank, which could easily be clicked on in game.**
-Also commented out dead code.
+**3.2.11-alpha.15 2022-01-13**
-* **Hook up the process to have all unjoined players added to prison by giving them the default rank.**
-This is also ran now at the end of the /ranks autoConfigure to ensure all players are hooked up as soon as the default ladder and it's ranks exists.
+* **Bug Fix: If the wrong sound file was being used it used to throw a NPE.**
+Now this is a safer way to find the correct file, and it will fall back upon a plink sound for any version of spigot.
-* **Player join bug: Fixed a bug... if a player is not on the default ladder, then this was preventing them from being added.**
+* **If upon loading a mine, there is a reson or need to resave the data, since this is an auto update, then this will make a backup copy of the mine's save file before saving it.**
-* **Added virtual checks to prevent placeholders from trying to access mine features that do not exist.**
+* **Bug fix: If spigot version is less than 1.13.0, and trying to use a _WOOD block, XMaterials cannot map that correctly to a Material and then back to the same XMaterial.**
+This is causing a problem when using in a mine since it cannot be tied back to the block that was placed. So for these versions, all _WOOD blocks are removed from the server. If a _WOOD block is saved in a mine, it will be remapped to the same _PLANKS block, which will work just fine.
-* **v3.2.10-alpha.14 2021-08-21**
+* **Bug fix: Prevent stack traces when a broken block cannot be mapped to a PrisonBlockStatusData object.**
+This is happening with spigot versions 1.8 through 1.12.2 when using "WOOD" blocks since XSeries translates these blocks to LOGs, so they will never map back to the XMaterial WOOD entries. This was producing a stacktrace and would prevent the proper handling of the auto features.
-* **reduce what is shown on /rank if for non-op players.**
+* **3.2.11-alpha.14 2022-01-11**
-* **Decrease the autoConfigure's prestige costs from 2 B to just 1 B.**
+* **Update the failed rank message so it is clearer.**
-* **Reload auto features after running ranks autoconfigure to enable the auto pickup.**
-It wasn't working right after generating the mines.
+* **When a player is on the default ladder at the last possible rank, instead of showing nothing for rankup costs, percent, bar, etc, it will now use the next prestige rank if prestiges are enabled.**
-* **Fixed an issue with virtual mines not being included in /mines list all command.**
+ These changes apply to the following placeholders:
+ prison_rc prison_rankup_cost prison_rc_laddername prison_rankup_cost_laddername
+ prison_rcf prison_rankup_cost_formatted prison_rcf_laddername prison_rankup_cost_formatted_laddername
+ prison_rcp prison_rankup_cost_percent prison_rcp_laddername prison_rankup_cost_percent_laddername
+ prison_rcb prison_rankup_cost_bar prison_rcb_laddername prison_rankup_cost_bar_laddername
+ prison_rcr prison_rankup_cost_remaining prison_rcr_laddername prison_rankup_cost_remaining_laddername
+ prison_rcrf prison_rankup_cost_remaining_formatted prison_rcrf_laddername prison_rankup_cost_remaining_formatted_laddername
+ prison_rcrp prison_rankup_cost_remaining_percent prison_rcrp_laddername prison_rankup_cost_remaining_percent_laddername
+ prison_rcrb prison_rankup_cost_remaining_bar prison_rcrb_laddername prison_rankup_cost_remaining_bar_laddername
-* **Now `/ranks autoConfigure` creates 10 prestiges ranks. **
-* **Have placeholders reload after mines or ranks are created, removed, or renamed.**
-Create mine and create rank now has an option to suppress updating placeholders since commands like autoConfigure will cause tons of messages to be generated. The placeholders are regenerated after all mines and ranks are created.
+* **On delayed startup, allow a combination of selectors to target essentials, since the class name has changed in v2.19.x**
-* **Command '/mines set area' fixed confirmation to use yes or confirm.**
-Added the ability to set size when using feet. The size is what is used with the '/mines set size' command. So 20 width is really 41 since it's adding 40 blocks in all directions.
+* **Setup the block inspector to auto select a diamond shovel, a diamond axe, or a diamond pickaxe.**
+* **On the blockbreak debug information, show the information on either the block that was hit, or if that is null, just dashes to show such a block was not provided.**
-* **Redesign the /mines info command to reduce and compact the listing.**
-`/mines info ` is the reduced listing where disabled features are not shown. `/mines info all` is the expanded listing that includes more details.
-Reworked the block list to use the String.format for spacing instead of manual adjustments.
+* **For EssentialsX v2.19.x, the class being used to identify if the economy has been loaded has changed.**
+This commit has the references to the proper class to use depeending upon the version of EssentialsX. It should be noted that this only applies if delayed startup is enabled for the EssentialsX economy, which generally does not require it.
-* **v3.2.10-alpha.13 2021-08-20**
+* **Change in how prison deals with ranks when there isn't an economy plugin loaded.**
+Now, instead of printing a simple little message in the console, which everyone appear to miss, it also enables a generic `/ranks` command that only displays a message indicating that no economy was found, with links to documentation. This should make it more obvious.
-* **Fixed an issue with null for the playerUuid..**
-it's rare, but it could be null. This prevents the failures.
+* **Change to auto features for the event listeners: now MONITOR is not enabled unless set to priority of MONITOR.**
-* **Fixed a few issues with ranks, a NPEs.**
+* **If a language file has a message that is set to an empty string or a space, it will now no longer generate an empty message.**
+Instead it will supress the sending of any message that is blank.
-* **The text for ladder info was changed to remove player's name, which does not make sense to include, especially if ran from console.**
+* **Move the placeholder `prison_player_blocks_total` from being a player mine placeholder, to a player placeholder since it is not tied to a specific mine.**
+Added a formatted version (with commas) and this one became unformatted so it can be used within scripts if needed.
-* **Yet another situation where CMI needed prison to start with a delay; confirmed setting is correct.**
-It was confirmed for the second time that 'Economy_CMI' works so I moved that to the 'vault-economy-name:' setting.
+* **The use of the `/ranks command remove` within the `/ranks info`, or `/ranks command list` was not correctly including the correct row number**; it was using one higher than what it should have due to prior incrementing.
-* **Fixes a bug when checking offline players which was returning a null with rPlayer.getRank(). Was fixed.**
+* **Issues with SellAll when dealing with varient block types when bukkit version is less than 1.13.**
+Eliminate usage of org.bukkit.Material where possible. XMaterial must generate the ItemStack directly, instead of creating a Material object.
-* **Ranks autoConfigure: Add to the prestiges ladder the base rank cost multiplier of 10 percent.**
-Provide a few messages to document it when the /ranks autoConfigure command is ran.
+* **Fix some issues with canceling drops:**
+Will not work on 1.8.x and maybe a few other versions of spigot with no work arounds. Works on newer versions.
-* **For the /ranks autoConfigure command, setup an alias to /prison autoConfigure.**
+**New Feature: Dump the BlockBreakEvent and monitor changes per listener.**
+This provides a great deal of information on what is modifying the blocks.
+To use, enter prison debug mode with `/prison debug` and then shift-click on a block using the prison wand (`/mines wand`).
-* **Setup a task that is to be ran whenever there is a rank change within a ladder, or if the ladder has the base rank cost multiplier changed.**
-This helps to ensure that the rank costs are correct for all players.
-* **Renamed the command `/ranks remove rank` to `/ranks removeRank` since the prior command was a single command within it's own sub-group.**
-This change will now list the command with the others when using `/ranks`. It was "lost" and "hidden" and admins were not able to find it that easily.
+* **Bug Fix: When loading the mines, and if using the old block model, some blocks were not mapping to the new PrisonBlocks.**
+When this now happens, the loader now tries to use the old block model's getXMaterialName() function, which returns one or more names that can map to XMaterial objects. It tries all of them until it is able to get a non-null PrisonBlock result.
-* **Changed the /ranks ladder delete command to prevent a ladder from being deleted if it has any ranks associated with it.**
-To delete a ladder with ranks would corrupt the ranks. The ranks would have to be removed first to ensure no players are on the ranks.
+* **Added a safty backup of the player's cache file... if it is detected that the new size is smaller than the prior size, then make a backup copy saving the original version instead of deleting it.**
+This implies that stats will always be added to the player's cache and that the file should alwaysbe getting larger. This only makes sense when recording stats. The file could become smaller when balances are reset, such as spending a lot of tokens.
+This also implies that some times, such as player inventories, should not be stored in this object... player's backpacks will be removed in the near future.
+It should be mentioned that on a test server I saw my player stats for my test player being wipped out. I have no idea if it was because of file system commands that I ran, or if it was a bug in prison that reset it. But because there was a potential loss, I'm making sure certain things cannot happen anymore, or trying to reduce the risk of losses.
-* **After a change in a player's rank, have the player's Rank Cost Multipliers recalculated.**
+* **Fix the sellall block list gui for when there is an invalid XMaterial name**, that it will print out the error to the console, and continue with using COBBLESTONE instead of producing a NPE.
-* **The command /ranks player perms was generating an error with offline players so this fixes that issue.**
-* **Changed config.yml to enable and disable prestige confirmations.**
-Updated the GUI to support this. Settings where changed and config.yml may need to be reset when updating prison to use these new features.
+* **For the list of displaying the ranks on a ladder, split them up to show 15 per line which will help when there are a lot of ranks on a given ladder.**
-* **Fixed bug with `/ranks ladder moveRank`.**
-It was not removing the rank from the source ladder, but was also adding it to the destination ladder. This was fixed and is now working correctly.
+* **Increased the confirmation on mine size from 25,000 to 50,000 blocks so as to minimize the number of times this will occur.**
-* **Removed the remainder of the ladder/rank permissions that were never used.**
+* **Add support for specifying the sound to use for inventory full event.**
+Valid sounds can be listed with the command /prison utils sounds list.
-* **Start to setup MineBombs basics.**
+* **Added support for doubles in the AutoFeatures settings.**
+The basics were there, but the actual AutoFeatures enum did not have them hooked up.
-* **Add to the World object, a function to set the block.**
-The SpigotWorld class uses prison's compatibility functions to perform this action.
+* **Remove an unused function on the PlayerCache.**
-* **v3.2.10-alpha.12 2021-08-16**
-Released alpha.12
+* **Bug fix for mohist, or other platforms that are trying to use SuperPerms, or other perm plugins that do not support groups.**
-* **Updates to fix the prestige issues.**
-Moved more of the processing in to the PlayerRank object to reduce issues. Shutdown one of the constructors since it could lead to the wrong amounts.
-Prestige was fixed by rewriting the way the rankup handled the ranks and playerRanks.
+* **Add *all* to the command /mines set tpAccessByRank.**
-* **Fixed an issue with logging when using a debug target mode.**
-It was not logging when the global debug was off.
+* **Add '*all*' as an option for applying Access by Rank for mines command: /mines set mineAccessByRank.**
-* **Added some rankup debug logging details.**
-Enable with `/prison debug rankup`.
+* **3.2.11-alpha.13** 2021-12-24
-* **v3.2.10-alpha.11 2021-08-15**
-Bump the version
+* **Prison command handler: adds the ability to add new aliases from the config file.**
-* **Changed the /ranks info to show the ranks multiplier information.**
+* **For ranks that are null, made some changes so either empty strings are used instad, or most of the time the rank name is used.**
-* **Work on /ranks list to improve the content to better present the rank cost multiplier.**
+* **Fixed a potential issue with nulls in the language file parameters. All nulls are replaced with empty strings.**
-* **General changes to code that uses getRank() that returns a PlayerData object... **
-Since that is a player's instance of a rank, this may be null for a lot of players. A lot of the old code would not take in to consideration that there may be no value, so hence the NPEs that we've been seeing. This should address a lot of the potential issues.
+* **Added the ability for admins to add aliases to commands so they can better customize their environment.**
-* **Found situations where players are not on a ladder and its causing issues.**
-Need to expand to other code...
+* **Disable block break events in the worlds where prison commands are disabled.**
-* **Bump to v3.2.10-alpha.10f.**
-Will be trying to release a more formal alpha later today.
+* **Added the ability to disable prison command hander is specific worlds.**
+The settings are within config.yml. The disabling of prison is only done on the command handler, and will soon be hooked up to the block break events too.
+The command /prison now lists worlds in which prison has been disabled
-* **Fixed a typo in the name of a function. Prevent a possible NPE. Revised how one of the PlayerRank constructors works so it will actually calculate the correct multiplier.**
+**3.2.11-alpha.12** 2021-12-21
+Alpha 12 released.
-* **v3.2.10-alpha.10e 2021-08-13**
+* **Fixed issue with XMaterial when trying to parse a custom blcok that is not compatible with prison.**
+The function will now return a null value and everything that uses it, must ensure it's not null before trying to use it.
-* **More adjustments to rankups and PlayerRanks.** I think I've addressed all issues with ranks.
+* **Make sure the targetBlock is not null before trying to process it.**
-* **Remove three redundant ladder commands dealing with ranks: listranks, addrank, and delrank.**
+* **Docs: Updated the LuckPerms Tracks and Groups document to provide more details on how to set them up.**
-* **There was a report that the mine would continue to reset after it was deleted.**
-Cleaned up a few things and added a boolean field to indicate it's delete. If its set to deleted, then it will prevent the resets from happening. Just as a safety check. Not 100% sure that this was actually an issue.
+* **Bug fix: Ran in to a rare situation where the use of essentialsX economy failed to allow prison to load the players during startup.**
+Prison was trying to "rank" the players within each rank that they were in, and that required prison to get their balance.... but bukkit was not able to return an OfflinePlayer instance for any of the plyers. Therefore prison could not access the player through vault. No idea why bukkit is not able to provide the players. The server in question had about 2500 players.
+So to prevent this from happening, the initial ranking bypasses the loading of any monetary amounts; they will be updated later.
-* **Setup the AsyncPlayerChatEvent listener within Prison to be able to dynamically set the priority based upon a new setting in the config.yml file.**
+* **Update and create some new LuckPerms docs.**
-* **Bug fixes: Fixed some issues with the use of the new PlayerRank object.**
-They were not always not-null, and there were some instances of the wrong variable being used.
+* **Move gui tools menu changes to improve them and hook them up to menus that did not have any paging.**
-* **Fixed an issue with the regular expression block quote... didn't need the second backslash.**
+* **Adjustments to improve the way the new gui tools work to reduce the amount of use of lore, or at least the visible lore.**
+This visually cleans it up a lot.
-* **Bug fix: Fixed a few issues with PlayerRank object not being set correctly everywhere.**
-Was also checking the wrong object for null. These fix about 3 different NPEs.
+* **Hooked up some of the new features to the /gui ranks menu, plus added a /gui ladders and hooked that up. Simplified how the ladders page was setup.**
-* **Removal of the obsolete ranks related permissions and permission groups.**
-This was a failed attempt to automate the user of permissions with ranks. This did not work, since vault does not support the creation of permission groups, plus a few other issues and limitations with vault.
+* **More work on the GUI menu tools to not only get them to work better (correctly) but also add new capabilities... now supports adding a menu option and the tool auto assigns it to the next available slot.**
-* **Initial setup of ladder rank cost multipliers.**
-All ladders a player has, will contribute to the total rank cost multiplier value, and all ranks for that player will have their cost adjusted.
-Overall this will allow an increasing rank cost as players rankup on the prestige ladder, and/or it can help reduce rank costs if donor ranks provide a negative adjustment.
-Currently there is no way to set the ladder's multiplier... that's next. But everything else is hooked up and should be functional.
+* **GUI menu tools update...**
-* **v3.2.10-alpha.10 2021-08-11**
+* **Prison Tokens: Remove the alias so they will not cause conflict with other token plugins.**
-* **Added a missing ranks message: when removing a player from a rank and it fails.**
+* **Potential bug fix: There was a situation where with multiverse-core a delayed world loading resulted in the world not being found**, and therefore it was preventing the loading of all locations tied to the mine. This now allows the locations to be loaded without a valid world. Then when the world is finally loaded, it will refresh the references to the world objects.
-* **LocalManager.getLocale: Fixed an issue with player being null when the player object originated from a task processing offline players.**
+* **GUI Menu: a few minor changes before more radical changes to go with the final "idea".**
-* **Added the event level MONITOR and changed the event listeners to only register the MONITOR event when the config is set to MONITOR.**
+* **GUI Menu Tools - Added a first page and last page button.**
-* **Updates to the JumboTextFont by adding most of the lowercase characters.**
+* **GUI Bug fix: If there are more than 45 ranks on a ladder, the GUI will NOW be able to provide paging capabilities to view all ranks.**
+By default it will start off with page one, but this can handle an unlimited number of pages.
+This paging system can be expanded and easily used on other GUI lists with minimal changes to hook it up.
-* **Alter the use of accessing the player to help eliminate the risk of concurrent modification events.**
+* **Found a bug in XMaterial where it was converting "melon" to melon_slice instead of the melon block.**
-* **Added a spigot module en_US.properties language file.**
+* **Bug fix: Fixed an incorrect use of XMaterial which prevented it from working properly with spigot 1.8 through 1.12.**
+It was using XMaterial to get the Material value, which is wrong, since it's the item stack that contains the variants of the materials. So the change is to extract the item stack directly from XMaterial which solves the problem.
+Also there was another error where if amounts are greater than 64, setting them to 1 so the GUI will still work, but it will suppress the incorrect counts for the itemstack.
-* **Added a new function to the PrisonEventManager to return the list of event listeners as a string so they can be logged to the console, or through helpch.at which is not yet hooked up.**
+* **Update XSeries to v8.5.0.1 to better support spigot 1.18.**
-* **Added JumboTextFonts to prison support submit ranks.**
-Fixed a few issues and added more characters to the fonts. Added /ranks info all to the ranks output for more detailed information.
+**Prison tokens: Add a few more prison tokens placeholders.**
+Fixed the admin token commands to use longs and not integers.
-* **Found and fixed an obscure bug with regular expression quotes.**
-It was duplicating text and making the results much larger than what they should have been.
+* **Ranks GUI Error.** ~~Fixed an error with Ranks GUI.~~ This did not fix anything.
-* **Created a JumboTextFont to be included in the prison support submit documents.**
-Hooked up to mines. This will make it easier to identify the various mines in the listings.
+* **Some adjustments to admin token functions.**
-* **Add the capture and display of all support submit URLs in each additional submission.**
+* **Bug fix: Rankup on a ladder in which there is not already a rank was producing an error.**
+Similar to prior problem... just did not fix it correctly for all situations.
-* **Expand '/prison support submit mines' details by including the '/mines info all' command.**
-Had to redesign some of the mine commands to be able to capture all of those details. Added a table of contents to the submission so it's clear all these details are included, since it could be a HUGE file.
+* **Start building the structure for the Top N rankings.**
-* **Added 6 new placeholders to provide the whole line for the prison_top_mine_block_ plus the heading and total line.**
+* **Mine Bombs: Noticed the player inventory was not be "updated" through bukkit.**
+This could help prevent wrong item amounts.
-* **Placeholders with _nnn_ numeric ranges: Fixes a potential problem of where it was unable to match a placeholder if placeholder escape characters were not used.**
-Now it will properly identify and match the series.
+* **Mine Bombs: Set them up to auto refresh the data structure that is being saved, if it is detected that there has been a change.**
+Added a version number to the mine bomb save data structure so as to use that to detect when the structure changes. That number will be updated in code when it has been modified. So when running the mine bomb loader, it will detect that the saved data is in an older format, and so it will rename the old file to preserve it as a backup, then write the new data to the file system. This will allow new fields to be added,and then they will appear in the save file upon the next restart. This will make it easier for admins to update and use the new features.
-* **Fixed a problem with block constrains, the min number of blocks, when no blocks were initially added to the mine.**
-When revisiting to ensure the min amount is set, it did not have the correct values set for the ranges.
-This has been fixed by adding a low and high limit field that not does record the actual block positions of this block type, but of the limits as defined by the constraints. This allows adding more blocks to reach the min amount, when no block has been added before.
+* **Bug fix: Was causing a null pointer exception when trying to add a player to a new ladder.**
+This now correctly gives the player the requested rank, or if not specified, then the lowest rank on that ladder.
-* **Prevent the use of % in the ranks and ladder commands.**
-Could not use them before, but they would cause errors when messaging details about the commands. Now the command will be rejected and it will have to be submitted correctly.
+* **3.2.11-alpha.11 2021-12-07**
-* **ButtonLore Utility got a couple of new methods.**
+* **Mine Bombs: A few other minor fixes and changes.**
-* **Some GUIs were still using the old deprecated buttons. This got fixed.**
+* **Mine Bombs: Some changes in how they are setup. Added a bombItemId which becomes line one of the lore and is used to identify that it's a mine bomb.**
+Added a nameTag that is used to put a nameTag on the armor stand. Added a itemRemovalDelayTicks field to better control when the armor stand is removed (exact time).
+Update a lot of Mine Bomb code for creating the time, placing the item (armor stand) etc... It's working better overall.
-* **All GUIs got a new common lore Format.**
+* **Update Tokens to fix an issue with the admin set.**
+Added better tracking of adminAdded and adminRemoved stats.
-* **All GUIs now use ButtonLore utility and lore format.**
+* **Bug fix: Fixed a class not found except caused by google guava trying to load functions that it should not have been using for their event manager.**
+Moved the PEE event out of this class all together, so now it's safe to use in other areas of prison, such as with guava's event handler. This was not an issue with spigot 1.8.8, but manifested itself with Spigot 1.16.5 since I believe that version of spigot is using a newer version of guava that has that behavior.
-* **Fixed an issue with spigot 1.17.1 where they appear to be extending the BlockBreakEvent for FurnaceExtractEvent but not isolating the listeners.**
-Forced to check to ensure the event is actually a BlockBreakEvent to ensure the correct event is really being fired correctly.
+* **Upgrade XSeries to v8.5.0**
-* **Added prison's version to the chat display's title.**
-is will help support since it wil help show us what version someone is using.
+* **3.2.11-alpha.10 2021-12-05**
-* **Added the recording of earnings per mine.**
-The add earnings must be called within the time limit as defined by the session timeout for mining, which is currently 15 seconds.
-If something is sold outside of that session timeout, then it will not be attributed to the mine.
+* **Bug fix: There was an issue that I found where blocks outside of the explosion events were being marked as mined without actually being broken.**
+Therefore prison would not be able to break those blocks. This was caused by the initial explosion setting off a chained reaction explosion through a blockEvent. Now blocks that are part of an explosion cannot be part of a future explosion.
-* **Minor design changes to the main GUI /gui**: to apply them you should reset (delete it) your en_US.yml at this path ->
- Prison/module_conf/lang/en_US.yml. More changes will come in the future.
+* **Added a new debug mode to inspect blocks by click on them with the mine wand tool when prison is in debug mode.**
-* **ButtonLore is quite ready and already in use for the /gui main GUI, only the first page uses it.**
+* **Renamed Prison's PlayerListener to PrisonPlayerListener to reduce a conflict and to make it more obvious which object is which.**
-* **Started working on a new ButtonLore Utility that will be included in the SpigotGUI Utility.**
+* **For the bukkit 1.8 through bukkit 1.12, if an object has a different data value than what it normally has**,
+it would not be matched through XMaterials... Examples are leaves, chests, etc... if there is no match initially using the block then try to then match on just the name, which eliminates the problem of a failed match.
-* **v3.2.10-alpha.9 2021-08-04**
-Released...
-Upgraded gradle to use v6.1.0 of Jengleman's ShadowJar... was v5.2.0.
+* **Add a selective debug option where only the selected element is loged through the debugger.**
-* **Modify the block break events to merge most of the preliminary processing from all of the different kind of block events.**
-This enables a single function to be able to handle most of the initial setup processes for all of the different block break events. This will reduce the amount of code, eliminate possible errors, and make it a lot easier to enable more events to be processed.
+* **Removed the DebugTarget value of "support" since it is not using anymore.**
-* **Add the option for using '*all*' for mine name for adding block events, which will add the event to all mines.**
+* **Bug fix: If a block has been placed in the mine that should not be there, prison was canceling the event which was preventing other plugins, or normal breakage, from breaking the block.**
+The event is no longer being canceled.
-* **All GUIs now use PrisonGUI Utility, finally it should be done now.**
+* **Added 12 new placeholders: 4 new ones for player balances and 8 new ones for tokens.**
-* **2 more autofeatures GUIs now use PrisonGUI Utility.**
+* **Prison tokens: Added admin functions of balance, add, remove, and set.**
-* **All SellAll GUIs now use PrisonGUI Utility.**
+* **Added the title and actionBar to the Player object so it will work in all forms of Player, such as RankPlayer.**
+Had to use the Platform to cross over to spigot from core.
-* **All Mines GUIs now use PrisonGUI Utility.**
+* **Added access to the player cache within the Player object so it's easier to use it.**
-* **Disabled some old Block model code in use for GUIs.**
+* **Updates some documents.**
-* **Mines Blocks List GUI now uses PrisonGUI utility.**
+* **Bug fix: One of the blockEvent placeholders was inserting the wrong value.**
+{blocksMinedTotal} was inserted the blockName.
-* **Fixed Mines Blocks List GUI (the one that shows the blocks currently in the mine).** The GUI wasn't translating
-correctly blocks, and showing a "barrier" instead of the block, the GUI was working anyway, just
- not good looking, now it's fixed for newer versions.
+* **Slight adjustment to the mine backups's file name.**
-* **Mines Reset Time GUI now uses PrisonGUI utility.**
+* **Move the messages for /mines tp to the language files.**
-* **Mines Set Notification Mode GUI now uses PrisonGUI utility.**
+* **3.2.11-alpha.9 2021-12-02**
+Version v3.2.11-alpha.9
-* **Mines Notification Radius GUI now uses PrisonGUI utility.**
+* **Added a new feature to back up a mine and to provide a way to convert a mine to a virtual mine.**
+When converting to a virtual, with the command '/mines set area virtual', a back up is made first.
+The new backup command is '/mines back help'.
-* **Mines Blocks Set Percentage GUI now uses PrisonGUI utility.**
+* **added mine name to reset notifications**
-* **Updated Buttons PrisonGUI Utility to support enchantments.**
+* **Bug fix: If a MONITOR event listener, then it should not process the block break event.**
+Monitors were processing the block break events when they shouldn't so monitors are not terminated after validation since their "processing" is handled there.
-* **For the fortune calculations, converted the use of the old block model over to use XMaterial instead.**
-Updated to include the newest 1.17 blocks too.
+* **Bug fix: The command '/mines reset *all* details' was not working and was only running one mine reset instead of all mines.**
-* **Updated smelting to use the newer 1.17 blocks, such as all of the deepslate variations, and the raw iron, raw copper, and raw gold.**
-Updated all code that had these variations.
+* **Rank data refactoring. A few changes to get this working. The ladderRanks collection was not being setup was the main issue.**
-* **Updated the XP calculations to include the newer blocks from 1.17**
+* **Rank data refactoring. A few changes to get this to work well.**
-* **Upgrade XSeries from v8.2.0 to v8.3.0**
+* **Major refactoring of Rank Player data objects.**
+This is to transition to easier use of player objects in prison. Some of the key classes have been moved from Ranks module to Core module, with the removal of rank functions being moved back to the ranks module.
+This is a work in progress and does not yet work. The player's ladders and ranks have not been linked together yet.
-* **Remove the dump of block break events from the command /prison version all since it was appearing first.**
-It will need to be rewritten to capture in a list of strings.
+* **Fixed the auto sell command within the auto features to include the ability to use autosell based upon the auto features settings.**
-* **Added mining time by Mine.**
-This will also track in which mine, players are mining.
+* **Fixed issue with a block break event happening outside of a mine, which will result in mine being null.**
-* **Found a bug in the TokenEnchant event listener class.**
-It was casting to the wrong class for the Monitor event.
-* **Fixed an issue with PlayerCache and mining duration.**
-Also added logging if unable to rename a temp file.
+* **Fixed issue with getMine not striping color codes, but in the function before this one is called, it strips them to check to see if the mine name is valid.**
-* **Added support for jumbo and full ladder types with the mine liners.**
-* **Update the custom ladder type feature in mine liners.**
-Now you can select none, normal, and wide.
+**3.2.11-alpha.8 2021-11-28**
+Release v3.2.11-alpha.8.
-* **Provide break the list of placeholders down by placeholder types, along with sub total counts.**
-Also added total count at the top of the list. Breaking down the large list in to sub-types will make it easier to read the list.
+* **Update the last seen time.**
+But will not set dirty. If player is not active, then it will not be recorded.
-* **Provided a way to specify a last next rank message for the placeholder:**
-prison_rankup_rank_tag_default
-This will only apply on the default ladder and when the next rank tag is empty.
+* **Expand the last seen information on the command /ranks player, which now includes how long ago instead of just a date and time.**
-* **Started to look in to providing the ability to import player ranks** based upon perms, but ran in to an issue that if the player is not online, then it can be very difficult to get their actual perms. Would not be able to get a listing of all perms, as if they were online, so it would make this less flexible.
-This has been canned because the person who was needing it, is no longer needing it. May revisit in the future.
+* **Add a listSeenDate to the player's cache data.**
+This will be used to track when the player was last on, and more importantly, determine if the player's cache data should be updated for stats reporting for top-n functions.
-* **About 56 new placeholders!** SpigotPlayerUtil has been updated to provide support for all of the functionality that it needs. It's been hooked up to the placeholders so they should be functional.
+* **Fix a rare condition where the wrapper of the PrisonBlock is null (the actual bukkit block).**
+This may not fix everything related to this issue, but it will prevent a NPE at this location.
-* **Setup the Platform to be able to provide a SpigotPlayerUtil object.**
-This is needed for placeholder support and a few other things.
+* **Minor changes to clean up auto features a bit:** move functions that are no longer used in the normal block break code to OnBlockBreakPlayerManualCore so it's not confused with the main-core functions and accidentally used.
+Also clean up the messaging and sellall usage to eliminate duplication.
-* **There was a concurrent modification exception on the line with** `playerData.setDirty( false );`.
-These changes will not prevent that issue, but it will trap it so it does not register in the log files. If this happens, then the player's cache will be saved on the next attempt. This should be a rare event.
-The changes needed are more complex that this simple "fix" and will be made in the near future.
+* **Fixed an issue with the mine state mutex being null.**
+Not sure what's causing it, but I suspect it mabe an issue with loading the mine from a saved state on server startup and that field never gets initialized. So fixed it by doing a lazy initialization on the field.
-* **Prison Mines Blocks Set Percentage GUI now uses PrisonGUI Utility.**
+* **Fixes a minor issue with the command '/mines set spawn' where it was requiring an option be specified.**
+I fixed it by setting a default value of "set" which does nothing, but makes the optional options, optional now.
-* **Prison Mine Blocks List GUI now uses PrisonGUI Utility.**
+* **Removed from the GUI the hologram on inventory full, and replaced it with actionBar.**
-* **Prison Blocks List GUI now uses PrisonGUI Utility.**
+* **Some adjustments to the overflow of the drops and other inventory controls.**
+On normal drops, disconnected autosell except if it is forced through the pmEvent.
+Fix inventory full sounds. For 1.13 and up it had the wrong sound file. Using something less harsh than anvil and turned down the volume which was horribly excessive with the volume set to 10, when normal is 1.
-* **Fixed some errors of the Prison Mines Blocks Set Percentage GUI:** There were some ArrayOutOfBonds exceptions.
+* **Prison Tokens: Prison now is able to auto generate player tokens based upon blocks mined.**
+It's enabled through AutoFeatures config file's setting 'tokensEnabled' and is able to set the blocks per token earnings rate with 'tokensBlocksPerToken'.
+More features will be added soon, such admin functions and top-n token holders.... etc...
-* **Auto Features: Added food exhaustion calculations.**
-Now on each block break, Configurable to be disabled. For explosions events, only applies to the one block they actually mined.
-* **For various add commands, the messages for the 'placeholders' was being sent to the console instead of the player issuing the command. This was an issue in game, but not the console.**
+* **3.2.11-alpha.7 2021-11-26**
+Released alpha.7. Major advancements to mine bombs.
-* **Placeholders durability: add support for a percentage and bars.**
+* **Mine Bombs: Added the use of a armor stand for holding the item, with an animation of swirling it around.**
+The item's armor stand is managed in a task which removes itself when finished. This process is independent from the visual and sound effects.
+Removed the static functions that were being used (which is much better).
-* **3 new Backpacks GUIs for admins now use PrisonGUI Utility.**
+* **Mine Bombs: Added more effects to the examples.**
+Removed some that would not work. These are not perfectly selected and may not work for most versions of spigot. The visual effect do not appear to really do much.
-* **Bug fixes with the setup of token enchant event listeners.**
+* **Mine Bombs: Setup some changes in how classes are related to each other so as to prepare for significant changes.**
-* **Added many more features to SpigotPlayerUtil and getting ready for the new placeholders.**
+* **Mine Bombs: Got the sounds and visual effects hooked up to the explosions.**
+Made many revisions on how all of this works, but pushed the tasks to a new class PrisonUtilsMinBombsTask.
-* **Started to add a PlayerUtil and SpigotPlayerUtil to prison.**
-This will allow an easier access to specific player values in other parts of prison with just a single call to a util function. This will be used with a number of new placeholders.
+* **Mine Bombs: Updated the listings of the mine bombs, which now includes full detail including the visual and sound effects, the list of shapes, list of sounds, and list of visual effects that can be used.**
-* **Removal of a function from the prison Player object that is no longer being used.**
+* **Mine Bombs: Updated the junit test for validating that the EffectState is sorted in the proper order when using the MineBombEffectsData as a comparator.**
-* **A couple of updates for CMI economy.**
-Added a note on what value to try first for cmi with prison.
+* **Mine Bombs: Setup a test unit test to confirm that the sorting of the EffectStates is as expected.**
+Needs to be: placed, explode, finished.
-* **Changed some logging information from debug to info so it will be registered when requested by the admin.**
+* **Mine Bombs: Add the sound effects and visual effects to the default test bombs.**
+NOTE: Some of these settings may not work on all versions of spigot, and some may not work on any version.
-* **PrisonEnchants changed the class name of their event.**
-This updates prison's code and changes the api jar file.
+* **Bug fix: Auto features get drops not always working with explosions.**
+The get drops was moved around to help ensure it does not try to get the block drops if the block is not what it is expected. This is now passing the needed object used for the check, instead of extracting it from the target blocks, which have not yet been set.
-* **Created a new group within auto features for durability related items and created a new group autoManager just for the isAutoManagerEnabled to get it out of the options.general grouping since that is the main "switch" and it is getting lost in the configs.**
-There was too many for the general group, and they were not being kept together, especially since we have a comment now.
+* **Bug fix: Auto Features Auto Pickup is now ignored if sellall has not been setup on the server.**
+If getting an instance of SellAll when it is disabled, will result in a null value.
-* **Backpacks admin GUI now uses PrisonGUI Utility.**
+* **Mine Bombs: Added a few new shapes.**
+Disk and Ring. Available in each plane x, y, and z.
-* **v3.2.10-alpha.8 2021-07-25**
+* **Mine Bombs: Added the collections for sound effects and visual effects.**
+Both share the same object, MineBombEffectsData.
+An effect has a name, plus an EffectState, and an offset in ticks that will apply that effect based upon the EffectState.
+The EffectState can be placed, explode, or finished.
-* **Auto features: Removed unused classes and cleaned up a few things. Fixed a reference to one of the deleted classes.**
+* **Ran in to another Java format exception.**
+Not sure what caused this problem, but added it to the catch so it can be reported in details so it can be fixed.
-* **Auto features events: Added an abstract class to manage the unregisterListeners in one place, to eliminate duplication of code.**
+* **Add the ability to remove a mine's spawn point.**
-* **For the command /prison reload autoFeatures hooked it up to include unregistering all of the event listeners that auto features setup, then it uses the configurations to reregister them all.**
+* **Reworked how the drops were processed to prevent dropping the wrong contents.**
+There was an issue where the drops were retrieved later in the process that allowed it to incorrectly pickup drops that were related to a decay function. This resolves the incorrect drops.
-* **Fixes a major problem with how Zenchantments works because the plugin extends the BlockBreakEvent with their BlockShredEvent.**
-It has issues.. but... this ensures that the correct event is being trapped.
+* **Player cache timing improvements.** This fixes issues with tracking the timing when mining.
+Not 100% sure it is perfect, but it's actually working much better. Will need to revisit later.
-* **Change to player cache field that was not so clear with it's name.**
-It's supposed to be the config field name, but the description did not reflect that.
+* **Added a check to detect that a block has been altered and is not the block that was placed there by the mine reset.**
+There have been drops of other materials making it in to an explosion event, and mostly due to block changes that happen due to other means.
-* **Fixed GuiUtility button add lore method:** The method to add a line to an already existing button got now fixed.
+* **Refactored some of the checks to determin if the event should be processed or not, so this can be used with a new feature that may help to auto manage access when WorldGuard is being used.**
-* **Adjustments to get the new event listeners working fully. Still need to hook them up to the reloading.**
+* **Setup a mutex for locking the mine resets, which prevents active block break attempts, including explosions, from trying to break blocks while a mine is actively being reset.**
+This helps to reduce the chance of hitting a concurrent modification exception.
-* **Next step in rewriting how the event listeners are setup...**
+* **Shut down auto manager and all auto features if the setting 'autoManager.isAutoManagerEnabled' is set to 'false' in autoFeaturesConfig.yml.**
+If anyone wants to use prison's block events, then they must use the auto manager.
-* **Move the event listener managers in to a common package to prepare to extend them to the non-auto features event listeners.**
+* **When using autosell through auto features, if a block cannot be sold, then the block is now placed in the player's inventory, or dropped if their inventory is full.**
+If a block is unable to be sold, the amount returned for the item stack will be zero.
-* **Rewriting how the event listeners are being registered.**
-Added ability to unregister. This is working, but is only for the auto pickups. WIll need more work to hook up to the non-auto manager.
+* **Bug Fix: There was originally a problem with applying block constraints that resulted in being unable to select a block when trying to randomly choose one.**
+Initially as a first quick fix was to trying to reselect a block, but if the block chances were really low, then it could still fail to select a block. Then it was attempted to select a default block, but that too failed to work, especially if there were a sizable chance for AIR, and it would fail 100% of the time if the was only one block with a very low chance. The failure was the whole mine could be filled with that one block with the very small chance.
+This fix completely redesigns the block selection, by first selecting only the blocks that are valid for that level of the mine. That way, when selecting blocks where blocks should be excluded from that level, those excluded blocks are never in the selected blocks to be considered. Also if AIR is a valid option, then this new process adds an AIR block to the temporary level block list with the percent chance assigned to the air.
+Overall, this is working really well now, and it actually simplifies a lot of code and reduces the amount of processing involved. This new process always selects a block on the first pass too so it never haves to try to reselect a block.
-* **Setup the ability to log more than just the BlockBreakEvent.**
-It it mow able to log details to Lists so they can be included in other output, such as support submits.
+* **Moved the multi-column formatting of data to the class Text so it can be used in other parts of the project.**
+It was originally created for use in /ranks player but is now extended to be usd to list the plugins within the /prison version command.
-* **Rewrote how the event listener is registered so the priority is dynamic.**
-This appears to be working well.
+* **Bug fix: If player is mining outside of a mine, then don't process anything.**
+May want to allow prison to manage block breaks outside of mines in the future, but for now, prison is only managing mines.
-* **clean up some of the /prison version all commands to better reflect the actual details with dependencies with the settings for auto features.**
-This should help better convey what the settings are doing, especially when a setting disables another setting. This should help reduce support issues.
+* **3.2.11-alpha.6 2021-11-21**
-* **Prestige confirming fix:** Fixing Prestige confirm by chat or GUI when possible.
+* **New feature which lists all of the Player Cache stats in the command `/ranks player`. This includes stats for block breaks, time spent in mines, and earnings per mine.**
-* **v3.2.10-alpha.7 2021-07-23**
+* **Capture an error within prison's Output class when trying to log content that has an UnknownFormatConversionException error.**
+This happens when there is a problem with text formatting characters that conflict with Java's formating class. This tries to log the error with better details so it can be fixed and resolved where the error is happening. This does not "fix" the problem, but just better reports it so it can be identified and fixed.
+* **Update on how prison manages the tracking of block breaks and earnings when auto features has autosell enabled.**
-* **Fixed the way some of the autofeature block settings were named.**
-They had "autoBlock" when auto has nothing to do with it anymore, since those setting will be applied for normal drops too.
-Fixed an issue with auto smelt and auto block where it was not using the config settings, so now it's working correctly.
-Added more debugInfo messages to better understand what's going on when something is not working correctly.
+* **Changes to how the event listeners are setup: reduced by 1/3rd.**
+Used to be that all three would be set if autopickup was enabled, but now only two will be set... monitor, and then either autopickup or manual drops.
+This should improve performance since prison will be processing 1/3 less events.
-* **Added a note on how fortune works... it's been confusing...**
+* **3.2.11-alpha.5 2021-11-19**
-* **Updates to the liner to allow the use of '*all*' for the mine name to apply the same pattern to all mines.**
-For auto configure, ensure that the random liner applied to the mines is not remove, removeAll, or repair.
+Post the alpha.5 release.
-* **Prevent slime fun from registering if it is disabled.**
+* **Remove the now obsolete auto features setting isAutoSellPerBlockBreaknliedEnabled.**
+It is no longer needed since the auto features autosell per block break is now optimized and has no impact anymore.
+Improve the autosell integration in to the auto features for both the auto pickup and also the normal drops. Improved the debug logging to include a list of all blocks being sold, or dropped, and their quantity and value. Also the total counts too.
-* **Fixed a problem with the registration of the events failed due to the parameter of ExplosiveEvent.**
-Had to set it to Object to allow it to be registered when the plugin and class does not exist on the server.
+* **Bug fix with SellAll: bug in original logic where the delayed notification when initialized is losing the first amount.**
+It now always adds the amount to the delayed queue.
-* **Added more internal debug details.**
+* **Autofeatures ignore certain events to improve performance and reduce logging entries when in debug mode.**
+Since there are multiple listeners on block break events, which monitor the same event, these changes are able to mark a specific block within the MineTargetPrisonBlock objects that will be able to pass along an "ignore" event status to the other listeners to short-circuit their processing. This is highly beneficial when using large mine bombs and the mine has blockEvents setup to perform explosions... which will help reduce a ton of "dead" events.
-* **Mine liners: Added glowstone and also added the ability to apply a liner change, or removal, from all mines with one command by using `*all*` for the mine name.**
+* **Auto Features Forced Auto Sell Optimization Improvement: AutoSell within auto features now only uses sellall by item stack and not the player interface that accesses all of the player's inventories.**
+Since the auto features items are not placed in the player's inventories at this time in the process of auto features, there is no reason to access the player's inventories. Selling directly reduces a lot of sellall overhead and as a result sellall is just calculating the prices.
+The old autosell code within autofeatures has not be removed yet, but it cannot be called anymore.
-* **Add the debugInfo to more functions and a few more messages.**
+* **PrisonDispatchCommandTask: Removed the debug logging since it can be very numerous when used with a large mine bomb and it's pointless since most of the block events being submitted runs in less that one millisecond.**
+So this is just cleaning up a messy logging item.
-* **Changed the debugInfo variable to a StringBuilder instead of just a String.**
-This will provide a little bit of a performance improvement, plus it can then be passed in to the functions to gather more information.
+* **SellAll: Setup a sellall function that will allow the selling of one ItemStack, which is not tied to any of the player's inventories.**
+This is used in prison's auto features when enabling the option to auto sell on a per block break event basis. This is highly optimized and a lot faster than using the normal sellall since it does not deal with any of the player's inventories or backpacks.
+This forces a delayed sold amount message since an explosion could includ many ItemStacks.
-* **A few minor adjustments to better identify the function that is running when logging the debug information on BlockBreaks.**
-Tweaks to the PrisonEnchant's plugin code. Missed a few changes.
+* **Mine bombs: Add cooldown and fuse delay to the mine bomb settings so each bomb can be customized.
+Added gravity to the mine bombs too.** Gravity, like glow, was added in minecraft 1.9 so older versions won't work.
-* **Changed some of the DebugTarget names to better reflect where in the project they are occurring.**
+* **Bug fix: For TokenEnchant's explosive event processing,** need to set PrisonMinesBlockBreakEvent's setForceIfAirBlock( true ) so the explosion event can be processed, even if the initial block has already been processed.
+This allows TE explosion events to work correctly now.
-* **Bug Fix: If a message is removed, such that there is nothing left of the = character in the language properties files, it will now not throw an index out of bounds exception.**
-Removal of the message was not expected and there was unable to handle that situation.
+* **Bug fix: refined the use of a few internal registers that are being used to control block break behavior, and also block counts and block events.*
+A few of the settings were being changed in the wrong places, which was out of synch with when they should have been applied.
+A few of the side effects was failure of tracking block counts, block events, and handling some explosion events.
-* **Added support for 4 new types of placeholders that uses the PlayerCache:**
-Player's total block count. And player's count per mine.
+* **Mine Bombs: More features and fixes.**
+Added support for radiusInner (for hollow sphere explosion shapes), removalChance (chance for block inclusion), glowing, autoSell, tool material type, tool fortune level.
+ Added a new shape which is "cube" and hooked up sphereHollow. Hooked up cube, sphereHollow, removalChance, glowing, the specified tool in hand with the custom fortune level. Did not hook up the forced autosell yet.
+Fixed some issues to get things to work a little better too.
-* **Issue with using offline players with the playerCache.**
-The playerCache should typically only contain active players, but in testing, like using /prison placeholders search, it may add an offline player to get placeholder data from them.
-This prevents null issues with the locations, and eliminates the excessive error message when trying to use getLocation() on an offline player.
+* **Prison Bombs: enabled the right clicking of AIR to set the bombs.**
+If clicking air blocks, then the block tied to the event will be null (at least for spigot 1.13.x) in that case, will use the block location of the player, and then adding the player's vector to it times three.
-* **PlayerCache changes: Start to take in to consideration that a player within the cache may be offline.**
-If that's the case, then prevent some calculations, and remove them from the cache. Offline players would be added to look up some stats, but then they would be safe to purge.
-When checking the timerTasks, add an earnings of zero to purge past earnings. This will prevent the average earnings from staying there forever when the player stops mining.
+* **Fixed a bug with how the regex handles block quotes.**
+Not only was it not working correctly for multiple block quotes, but it was incorrectly handling the tail end of the processed text and was basically doubling the text. It now works correctly, even with multiple block quotes.
-* **Added a debug logging entry for XP Calculations.**
-This will be able to provide detail infomation on if it's working and what the results are.
+* **Fixed an unexpected "bug" with the JumboText font for the letter Q.**
+One section was setup to use "\Q" which is an escape character for a regex block quote. This was causing problems since it was forcing large sections of text to be ignored when translating minecraft color codes. By changing it to "\q", a lower case Q, this eliminated the translation from making the mistake.
-* **Add support for PrisonEnchants' ExplosiveEvent.**
-While adding support for the ExplosiveEvent, found a few issues and fixed them. Some changes were just in names of functions, others were functional, such as improving the support of unbreakable and blocks that fall outside of a mine.
+* **Bug fix: The command "/prison support submit ranks" was passing a null sender, which is valid when generated by this support tool.**
+The fixes now works well, and treats the null basically the same as an OP'd player, or the command being ran from the console.
-* **Simplified how the title, subtitle, and actionBar are setup with the /prison utils titles title command. **
+* **Bug fix. If a null message is sent to this function, it would cause a NPE.**
+This now prevents a few failures from causing potential problems.
-* **New Feature: Prison now tracks average earnings per minute.**
-If you have auto sell enabled (sell upon each block break, see autoFeaturesConfig.yml) then prison will be able to report your average earnings over the last 5 minutes of mining activity.
-`prison_player_balance_earnings_per_minute` prison_pb_epm
-`prison_player_balance_earnings_per_minute_formatted` prison_pb_epmf
+* **Fixes a concurrent modification exception when the PlayerCacheCheckTimersTask is running.**
+This happens rarely when a player is logging off while "trying" to process their entries; they have been removed.
+So when this happens, the process retries to start over a total of 2 more times and it skips processing players that have already been processed. Any update that was skipped would be covered in the next pass with no real loss.
-* **Rewrite how the player uses title, subtitle, and actionBar for the /prison utils titles command.**
-Spigot 1.8 does not support any of this.
-Spigot 1.8.8 is when this was introduced. But 1.8.8 does not have actionBar, so instead it shows the message in the subtitle.
-Spigot 1.9+ are able to display title, subtitle, and actionBar at the same time.
+* **The use of a command placeholders for `{actionBar}` and `{title}` were added to the placeholder enumeration so they are included in the placeholders listings.**
+The support for these two commands were added a while ago, but because they were not added to the enum, they were not being listed in the help.
-* **Release of v3.2.10-alpha.6 - 2021-07-19**
+**3.2.11-alpha.4 2021-11-01**
+ Released alpha.4.
-* **Try to better handle situations where integrations fail when integrating.**
-Now has the ability to disable the integration and remove it when it fails.
+* **Changes to improve the way the upcoming mine bombs.**
+They are currently non-functional.
-* **New feature: prison utils titles.**
-This enables sending messages to the player's console as either a title, a subtitle, and/or actionBar. Can also clear, reset, or set the timings on the titles.
-All three can be sent through the title by using a double colon to indicate the various parts.
-For example: 'Hello Title!::Subtitle is Here!::I'm on an actionBar!'
+* **Adjustments to get block events, such as decays, to work correctly with the new auto feature block event handlers.**
+ Block events were moved to be processed after the block is broke. Also if a block has already been processed, it now will cancel the event to prevent normal block breakage when none should happen.
+At this point, the new auto manager appears to be working really well.
-* **Add feature to Auto Features to prevent tools from breaking or being used when durability is equal to or greater than maxDurability.**
+* **Changed the location usage with block event placeholders, which now uses the location that is tied to the targetBlock instead of the mined block.**
+The mined block may be null so it's not stable.
-* **Added some documentation to the ExplosiveBlockBreakEvent so users can better understand how it should be used.**
+* **Fixed an issue with /mines block list when an incorrect mine name is used.**
+Now displays an error stating the name is invalid.
-* **This is an example of an explosive block break event that should be used so prison can monitor for it, and consume it.**
+* **Starting to add some video documents for prison.**
-* **More adjustments to the Taiwanese language files.**
+* **Fixed an issue with adding a non-block item to a mine.**
+It now validates that the specified item is a block. Also if a specified block is not in a mine when trying to remove it, it will now display a message indicating that nothing was removed.
-* **More tweaks to player cache file saving... **
+* **Major rewrites to how auto features work.**
+Using the PrisonMinesBlockBreakEvent object to carry all of the various parameters that are used within the auto features code. This allowed the elimination of many functions since they have been combined together. It also allowed for more efficient handling of explosions by combining similar blocks together and processing them as a single unit, so massive explosions are handled far more efficiently. If the admin chooses to break the blocks in another thread, then handling of many blocks is optimized to reduce the overhead. The state of the blocks being broken are being tracked through the MineTargetPrisonBlock such that it's flagged as soon as it starts to process the impacted blocks so as to prevent the same block from being processed more than once, even when there are many explosions occurring at the same time. Changes to the block (block break) has been moved out of the depths of the code, to be closer to the event handlers so it's easier to monitor/track.
+Due to the many changes and major alterations to the logic, this is a work in progress and needs more testing.
-* **PlayerCache adjustments for timing tracking. A work in progress.**
+* **Async Mine Reset performance Improvements.** Adjustments were made to improve the performance of the asynch mine resets by providing the ability to fine tune the page sizes, and also provide the ability to reset more than one block in the synchronous thread at a time. This is called a slice. Measuring the actual block reset time with nanos for better resolution.
+MineTargetBlockKey class was relocated to allow for the use of sub listings on the synchronized block updates.
-* **Updates to he Taiwanese language files.**
+* **Cloning a bomb was not complete. Some details were omitted.**
-* **Improvements to adding new players to prison upon startup.**
-This process scans bukkit's offline players and finds everyone who is not already setup in prison and adds them.
-It now uses the /ranks set rank command now.
+* **Fix for Potion IllegalArgumentException:** Fixed an error with potions in Player inventories when
+using sellall sell, potions aren't supported by now and won't be sold, but at least it won't break
+sellall anymore.
-* **Added support for zh_TW Taiwanese.**
-This is just an initial setup for now. To enable it, set the language in the config.yml file to zh_TW.
+* **Switched prison block debugging timing to use nanoTime instead of milliseconds since milliseconds is too large of a unit.**
-* **Player Cache: Hooked up block tracking for players.**
-Appears to be working as far as tracking blocks that are being broke. It loads and unloads when a player joins and leaves the server so only active players have their data online. Performs periodical updates on saving.
-This tracks total blocks, block counts by mine, and block counts by block type.
-Starting to setup time tracking.
+* **Bug Fix: When using block constraints,** there was a common situation where an AIR block was being used in the top layers because all other blocks were being rejected due to chance. Order of blocks had an impact on this error, when it shouldn't. Now, if a block cannot be selected, the first block with no constraint issue will be used instead. Also found a bug in the applying of the chance to each block. Under some situations, the percent chance was not being reduced for a bypassed block, when it should have. This now will better select the blocks, and better preserve their intended percentage odds of being spawned.
-* **More changes to setting up a player cache.**
-The basics should be represented, with startup and shutdown of the cache, running a periodical task to refresh the data, running a periodical task to save the data.
-No data is processed as of yet, but the cache should be reactive to players logging on and off the server.
+**Prison v3.2.11-alpha.3 2021-10-18**
-* **Initial work on setting up the Player Cache.**
+* **Enable the ability to choose between setting the block to air inline, or through submitting a synch task to allow the blockBreak event handler to finish quicker, which may reduce lag.**
-* **Minor SellAll utility changes.**
+* **Simplified the configuration of the handling of the block break events.**
+Instead of having a separate setting that is a boolean value that indicates it's either enabled or disabled, these are now using the priority value of DISABLED.
-* **SellAll Player Blocks List GUI now supports pages.**
+* **Add millisecond reporting for the time it takes to handle a block break event.**
-* **Minor improvements for GUIs to improve performance.**
-* **PrisonGUI Buttons utility minor changes.**
+**3.2.11-alpha.2 2021-10-14**
-* **Add the ability to play sounds through the /prison utils sound command.**
+* **A few updates to mine bombs. They have been disabled so they cannot be used.**
-* **Update docs... scale back what we support with WorldGuard regions since access by ranks solves so many problems.**
+* **Add the ability to glow the prison bombs when they are dropped/set.**
-* **SellAll Admin Blocks List GUI now supports pages.** Note: This was **not** part of the v3.2.10-alpha.5 release.
+* **For a couple of rankup messages, using the rank tag now instead of the rank name.**
-* **SpigotGUIComponents minor changes.** Note: This was **not** part of the v3.2.10-alpha.5 release.
+* **Fixed a compatibility issue with older versions of spigot.** Should have possibly use the compatibility classes, but if a method does not exist, then this will fall back on a string matching pattern.
-* **SellAll Blocks GUI now uses PrisonGUI Utility.** Note: This was **not** part of the v3.2.10-alpha.5 release.
+* **Changed the message about worn out tool to use the SpigotPlayer's setActionBar() function to prevent overloading console messages.**
+* **Bug fix: Logic was corrected to handle the double negative correctly.**
+The was an issue with the /mines set area command when the mine's area was larger than 25,000 blocks. They have to enter either "confirm" or "yes". The bug would require them to enter both to create the mine.
-* **v3.2.10-alpha.5 2021-07-14**
+* **Added an example of possible backpack object to the PlayerCachePlayerData object.**
-* **Made the RankLadder comparable and in the RankPlayer changed the map to a TreeMap.**
-This should fix the inconsistencies that I was seeing earlier.
+* **Adjustments to the new auto features for cancel block break events and block drops.**
-* **If a player is detected to be lacking a rank on the default ladder, it will adde the default rank.**
-Ran in a problem where getting the current rank for a ladder was failing when it was ran, but worked when stepped through a debugger.
+* **Removal of some auto feature commented out old code.**
-* **When checking for players not hooked up to prison, prison now ensures there is a default rank configured or it won't try to check the players.**
-This change also checks players within prison to ensure they have a rank on the default ladder.
+* **New auto features settings: Able to prevent event canceling and also control if the drops are cleared.**
+This has not been tested too much, but it may help make prison more compatible with other plugins that are needing to handle the block break events.
-* **MineInfo GUI now uses PrisonGUI Utility.**
+* **Fortune on a tool was appearing as a negative value: -1000.**
+Not sure how it became negative, but this will better deal with negative values.
-* **Removed unused imports from some GUI classes.**
+* **Added a listener for PlayerInteractEvent.**
-* **MineInfo GUI TP Button now has an Arrow instead of a red_bed:** red_bed can't be translated to a legacy block in 1.8.8.
+* **Add a new feature to the PrisonSpigotAPI to allow for the creation of a new mine through the API.**
+This could be used to generate player mines in a plot world.
-* **Fixed performance issues for MinesInfo GUI.**
+* **Able to give players bombs, based upon the item type as defined for the bomb.**
-* **Added information to the language files on how to use utf-8 text in these properties files.**
+* **Significant progress on Prison's Mine Bombs:**
+Moved the mine bombs primary classes to the prison core so it's accessible from all packages.
+Setup 4 default mine bombs if the commands are used and there are none defined.
+Setup a new /prison utils bomb commands to list all bombs and to give players bombs. These are not complete and fully tested yet.
-* **Setup prison to ensure all compliers within gradle is using utf-8.**
+* **Some initial work to setup the mine bombs configs.**
-* **Enable loading utf-8 encoding from the properties files. Java 1.8 is unable load them as utf-8, so this provides a work around.**
-At this point, this ensures that if a properties file contains utf-8 encoded text, that it can be packaged in the prison jar, extracted to the file system, then loaded and used and maintain full utf-8 encoding all the way until it hits bukkit. bukkit corrupts it and confirmed it was corrupted in spigot 1.8.8, 1.3.4, and 1.16.5 so its not an isolated issue for just one spigot version.
+* **Add placeholders {actionBar} and {title} to the blockEvent listing of placeholders that can be used.**
+They are shortcuts for the new prison utils commands.
-* **Updated cryptomorin's XSeries to v8.2.0.**
+* **For the actionBar and title, translate the color codes so they work properly.**
-* **Convert the CommandHandler.getHelpMessage() to return a ChatDisplay object to allow the use of creating clickable URLs in the help messages.**
-The help messages now has headers which shows the command that's being listed.
-Updated the /mines blockEvent add command to include two docURLs to use as an example; improved the help message.
+* **Hook up the auto features notification to use the new actionBar interface.**
+This "should" prevent duplicate messages from being sent to the player while the same message is displayed in the actionbar.
-* **If a Ladder has a bad rank that is already in another ladder, that rank will not be added to the new ladder that is being loaded.**
-An error message is already being logged, but this change will update the ladder to resave it without the duplicate rank.
+* **Fixed an error about backpacks and lore transition:** A single lore was being used for the backpacks utility, if a server
+was new and fresh, this would've been missing and an error could occur, this now got fixed with the full transition.
-* **Clean up Ranks a little more by removing more of the rank position and report failures if a rank is already loaded in another rank to prevent internal failures if a ladder save file is corrupted by manual editing.**
+* **Full transition of all messages to the .properties lang:** All messages are now on the .properties file and the old
+.yml one is unused from now on, you can delete it and start translating the new one. Please note that some messages may
+be wrong, as it's still in a young stage and a lot of messages got transitioned.
-* **Removed the use of rank.getPosition() from all saved information within ranks and ladders.**
-Position is no longer used to access any rank. It is only used to compare if one rank is higher or lower than another. It's lazy loaded only when it is needed the first time. If a rank is removed from a ladder, or inserted in to a ladder other than at the end, then all ranks in the ladder are set to -1 for the position so they recalculate when they are used the next time.
+* **The player cache, when being shut down ran in to a problem if the players were removed when they logged off.**
+This function was making a new collection based upon the original player cache copy of players, of which, when a few of the players are removed, then they were resulting in nulls.
-* **This fixes a user error situation, which is not a bug, in the listing of ranks.**
-The user copied the contents of one ladder to another ladder, without deleting the source ladder. Thus there were two instances of a series of ranks, when there should ever be only one instance of a rank. A rank can be in at most one ladder, or no ladder.
-The result of this issue is that when the second ladder was hookedup at prison's startup, it corrupted the ranks in the first ladder.
-This works around such problems by changing /ranks list by using the list of ranks within the ladder, instead of using the rank's prior and next associations.
-These changes also add the rankId to both the '/ranks list' and '/ranks ladder rankList' commands, and also '-' and '+' notations to indicate a rank is linked to a prior and next rank.
+* **Prevented a problem when unloading players, and when a player is null.**
+The condition that was causing a null player was that the player was unloaded when the player left the server at the same time when the server was shut down. Basically a race condition with two parallel async tasks trying to shut down the player cache object, each focusing on a different aspect (player vs. server).
-* **Simplify the command /mines blockEvent add by removing the permissions and taskMode from the add.**
-This was causing too muchh confusion for a lot of people. It should help to keep the add much more basic. There have been alternative commands to modify those settings so it really isn't important to set them on the add. Also odds are they will not anything but the default values for these two fields. The defaults are perms = none and taskMode = sync. TaskMode is not defaulting to inline due to increased risk of lag and prison being falsely blamed for it. If desired, the admin can always change the taskMode to what they need.
+* **Hooked up XSeries' Titles to the compatibility class instead of using version specific code.**
+XSeries says they support 1.8.8 through 1.17.1.
+Deleted the support for the Spigot110 classes since it was only to support the use of the ActionBar and also the Title, which are no longer needed for 1.10+.
-* **Bug fix: Fixed an issue where the "on click" events were using the wrong row number.**
-The row number was getting incremented at the wrong time.
+* **Adding a player messaging component to the PlayerCache.**
+When used, this will prevent more than one of the same messages from being displayed at the same time.
-* **v3.2.10-alpha.4 2021-07-10 **
+* **For the command /mines set area the confirmation of "yes" was setup incorrectly with being negated.**
-* **Few minor tweaks to the mines info command with formatting.**
+* **Switch over to using XSeries for the actionBar.**
+XSeries claims it works for 1.8.8 through 1.17.1.
-* **Added player counts to the rank list command.**
+* **Moved all Lores to the new .properties Language file:** Changes to the old .yml language file about Lore messages
+won't take effect, only if you edit the .properties file they will.
-* **Hooked up the /ranks list all command to the /prison support submit ranks command.**
+* **Added the trigger "minebombs" for the utils command bombs.**
-* **Add option to /ranks list to include all ranks through the use of the "all" in place of the ladder name.**
+* **Adjustments to the BlockEvents and how it handles some of the event types.**
+Expanded and fixed some of the settings for prison's explosions, and PE's too.
+Added the ability to exclude specfic triggers.
-* **Fixed a bug where getting a player was returning a null.**
-When that null was encountered, it was not processing the placeholders, especially for the bars.
-Not really sure why it was failing, but replaced the use of getting the player balance with the most recent use of RankPlayer's getBalance() works perfectly.
+* **Updates to the Prison's explosion event handling to correct a few problems. **
-* **More adjustments on the /ranks list to prepare for listing all ladders.**
-Also added a couple of more messages.
+* **Fixed SellAll Hand not removing item:** SellAll Hand didn't work properly and got now fixed.
-* **Added an error message if there is a failure when using /prison support submit.**
-I assumed that other error messages would exist, but having doubts if it always will have other errors displayed.
+* **Initial setup of Prison's mine bombs.**
+Initially it will be controllable as a utils command, so random chances can be assigned to explosions.
-* **Improvements to the /ranks list command.**
-Enhanced the header so it's clear which ladder is involved. Also cleaned up the formatting with the tag colors so it does not impact the column alignments. Also doing a little more with injecting the "default" tag so it does not shift the columns.
+* **Cleaned up some of the unused variables in the Utils titles command.**
+There were plans for more commands, but they were eliminated. This will soon be rewritten to utilize XSeries's classes for these display items.
-* **Adds the listing of all mines to the /prison support submit mines command.**
-This provides an overview of all mines and is included at the top of the listing.
+* **Ran in to a situation where results was actually null. So this prevents a NPE.**
-* **Improve the layout of all of the mines with the command /mines list all.**
+* **Fixed issue with tool's durability being cutoff right before reaching the threshold.**
+Had to change a > to a >=.
-* **pasteChat update to keep the color codes.** It will only keep the color codes that start with &, and all others will be removed.
+* **3.2.11-alpha.1 2021-08-31**
+- Release the first alpha.1
-* **New feature: /prison reload locales. Its now possible to reload the language files that prison uses.**
-Added a new debug item to test to see if utf-8 is working: /prison debug testLocale. No, it does not work with utf-8 text yet.
-I did confirm that if the properties files are setup with UTF-8 and are a part of the prion jar, that the UTF-8 encoding will properly be saved to the local file system.
-The area that I think is causing failures is with the Properties object itself since that is not utf-8 compatible, so it appears.
+* **Replace the block with air through a task to get it out of the auto features thread.**
-* **v3.2.10-alpha.3 2021-07-09**
+* **If the settings isPreventToolBreage is enabled, then don't allow the tool to break.**
-* **reformat the /mines list command to mak it easier to read**
+* **Update some messages to be clearer as to what they are.**
+Removed the MONITOR from auto features since they should not have the monitor setting enabled. The blockBreakEvent has the monitoring event.
-* **Added support for prison support submit for ranks and ladders, and also for mines.**
-These two new commands will submit the raw json files.
+* **Trying to fix an error related to SpigotRankManager GUI:** I can't reproduce the issue but the NPE shouldn't
+give a stacktrace in the console anymore.
-* **New Feature!! Major support feature! Send all of prison's configs to paste.helpch.at so we can know exactly how servers are configured.**
-This logs the following config files: config.yml plugin.yml autoFeaturesConfig.yml modules.yml module_conf/mines/config.json
- SellAllConfig.yml GuiConfig.yml backpacks/backpacksconfig.yml
+* **If the primary block was null, which it never should be, then this prevents a failure in this section of code in the OnBlockBreakEventCore.**
-* **Added a success message when a player is added to prison's default rank.**
-* **Fixed issue with a few placeholders that were not working.**
-Was using the wrong translator so a number of mine related placeholders stopped working.
-The mineplayers were not working too. The bug was introduced by hooking up STATSMINES.
+* **For the initial startup air count task, which is used to "reset" the block counts on a mine.**
+This does not change any blocks, but just finds out where the mine was when the server was last shut down. This is needed to ensure we have valid counts for the mines before the first time they are reset. The other way to update these values is to do a full mine reset which is more costly.
+There was an inconclusive error that just listed "null" as the error messags, without identifying the actual line number. This error catching was changed to now generate a stack trace so it can be properly fixed if it occurs in the future.
-* **Hooked up STATSRANKS placeholders and got rid of obsolete ones. Still more testing needed.**
+* **Added a few more reporting entries on the block break handling.**
+Reporting how many blocks are being processed and if it passes the validation phase.
-* **Added a player check on prison startup that will add all offline players that are not hooked up to prison yet. Plus it will register name changes too.**
+* **Some fixes for teleporting and the removal of the teleport glass block.**
-* **Added top rank balance placeholders: 6 for now and more will be added soon once these are fully working.**
-These are based upon the player's balance within the rank.
-Also added a Hesitancy Delay Penalty to help encourage players to rankup instead of trying to dominate a single rank.
-These have not yet been tested.
+* **Updates to the PrisonEnchant's API.**
+Minor adjustments to work with the new API from PrisonEnchants.
-* **Added RankPlayers to Ranks.**
-This will allow quicker access to all players at each rank, which will help for top ranking reporting.
+* **Updates to async block updates.**
+Included changes to hook up the CustomItems to work with the async updates.
-* **Clean up some rank and ladder function to eliminate the use of magic numbers: both rank ids and ladder ids.**
-These were bad, since the objects were already linked together, so using these functions were just adding unneeded overhead.
+* **Clarify some of the messages related to listing of the block events.**
-* **v3.2.10-alpha.2 2021-07-06**
+* **Added the ability to identify if a block is able to be affected by gravity. Also the mine has a global setting to identify quickly if any block is gravity affected.**
+This will be used to alter the mine reset strategy to improve performance so as to hopefully eliminate long resets due to extensive lag from falling blocks. The idea is to get all the other blocks in to place before placing the falling blocks to ensure they are less likely to fall.
-* **Added the ability to fail silently for the Localizable object to prevent the message ID from flooding certain messages.**
-This will be employed in the Output.get() functions so if it cannot load the prefixes and level colors, then the message IDs will not be injected in to the messages.
-This new feature should never be used without careful consideration since it is important to identify when messages fail so they can be fixed properly.
+* **If the Mine's saved file data is corrupted (manually edited with incorrect data), this will prevent the mine from being loaded and will now generate an error message indicating which mine has a problem loading. It will print out the invalid data, and it will default to a value of 0.00001. The function has been updated to "properly" use the localized format, so if it saves in a non US way, then it should now be able to read it back in and parse it correctly.
-* **Adjustments to LocaleManager for updating the internal checks for if the external files need to be updated.**
-Also finalize how Prison object works with the LocaleManager.
+* **If the Mine's saved file data is corrupted (manually edited with incorrect data),**
+this will prevent the mine from being loaded and will now generate an error message indicating which mine has a problem loading. It will print out the invalid data, and it will default to a value of 0.00001.
-* **Removed obsolete placeholders that are not used anymore.**
+* **Checking to ensure the locations are not null when loading.**
+There was a failure with bad data on the files system that was resulting in trying to resolve nulls to a location, which obviously cannot happen.
-* **Adjustments to when the LocalManager is started so it can be activated as soon as possible.**
-This is because of the need for Output.get() to use externalized messages for it's prefixes and color codes. This does present some problems, but it actually works fine at runtime and also for junit tests too.
+* **There was an odd situation where the player was null, when usually they never can be, so this helps prevent possible errors.**
+The null was caused by an issue with a placeholder? Don't really remember.
-* **Setup a getConfigString in the Platform with a default value.**
+* **Adjustments to Prison's TPS calculations.**
+They were only taking the average of just two readings which was resulting in very unstable TPS values. Now 10 are being used.
+Enabled a new feature where the resolution can be changed from normal (a reading every tick) to high resolution (one reading every 2 ticks). When the resolution changes, the task will auto terminate and resubmit with the new settings.
-* **New placeholders for mine block stats: Renamed percent to chance. Added prison_top_mine_block_remaining_bar_nnn_minename.**
+* **For the command /ranks autoConfigure made some adjustments to the block lists being used so the top mines have more valuable ores and blocks. There was a shortage and the wrong blocks were being used.
-* **Used the wrong numeric formatter... needed to be an integer.**
+* **Fixed an auto features config setting for prison's ExplosiveBockBreakvents priority; it was missing the word priority.**
+Reworked some of the details on autofeatures as displayed through /prison version to update them to better reflect the correct settings and dependencies.
-* **Added 10 new placeholders to provide stats on mine blocks.**
-These use a series value in the placeholder to specify the specific block. The series number is not limited and can range from 1 through a large reasonable value. The number can be one or more digits, with or without a left padding zeros.
+* **Fixed a problem with placeholders when using the search feature, but not supplying a player's name.**
-* **Renamed the field PrisonBlockStatusData.getResetBlockCount() to getBlockPlacedCount() to be more descriptive of what it actually is.**
+* **some internal changes to improve the resets**
-* **Add the ability of a PlaceholderFlag to self identify as having a sequence.**
-This will allow for automatic processing of these kind of placeholders without having to hard code for them.
+* **eliminate the block access in this class since it handles everything in the submitted task.**
+This was causing an error when it was being ran in an async thread. When the task is submitted, it is ran synchoronously so it works correctly.
-* **Placeholders test: Fixed issue with player name being incorrect and also added player information if it is provided in the output.**
+* **Changed prison's TPS calculation to be able to enable a high-res setting when the `/mines stats` is enabled.**
+The one problem with enabling high resolution mode is that it could show an unrealistic low TPS during a reset. The /lag command shows a much higher TPS value.
-* **Fixed a typo that was made a long time ago. Placeholder has a capitol H in the name.**
+* **Setup up the basics for async updates.**
+In the code that does the update, it also now reads the block to ensure that the read and update is all done in the synch thread. Otherwise the old code would be risking chunk loading in an async thread.
+Using the Location and World to perform the async updates outside of needing access to the spigot module.
+At this time, only `/mines set tracer` is using the new async reset.
-* **Increased the number of rows displayed when using the placeholder search. It was showing six placeholders and I increased it to 10.**
+* **Tweaks to the event listener dumps for block breaks.**
+Updated the notes about prison's listeners.
+PEExplosionEvent was setup with the wrong forClass name.
-* **Renamed the PlaceHolderFlags from PLAYERMINES to MINEPLAYERS which is more consistent in how it is being used.**
+* **Setting up a new way to handle block updates in prison. Adding functions that are intended to be use while running in an async threads.**
-* **v3.2.10-alpha.1 2021-07-05**
+* **Transitioning over to the correct way to get the compatibility object.**
+Just a few classes are using the old way, but they will be switched over when they are done with the edits.
-* **Bug fix... when selling on each block break event, it needs to suppress the per-sale messages.**
+* **Fixed the way some of the language files were being generated**
+so it can include the spigot module, which makes it self-contained for actual Modules, since it's always based upon the module name.
+Core and spigot are not technically modules, so they have special setups.
+Changed the Module folder from dataFolder to moduleDataFolder so it would not conflict with the SpigotPrison object.
-* **Fix a few other issues with the new placeholders.**
+* **Fixed a problem with Prison's ExplosiveBlockBreakHandler**
+ in that it has a typo in the getHandlerList() and was not included with the registration processes. It also needed to be included with the generation of the listener dumps.
-* **Enhance the /ranks autoConfigure to work much better with existing mines and ranks when doing a force.**
+* **Added /sellall hand command.**
-* **New 18 new placeholders added to prison. Hooked up the following placeholders, but have not yet ran through testing yet.**
-prison_rank_ladder_position (prison_rlp), prison_rank_ladder_position_laddername (prison_rlp_laddername),
-prison_rank__ladder_position_rankname (prison_r_lp_rankname), prison_rank__player_cost_rankname (prison_r_pcst_rankname),
-prison_rank__player_cost_formatted_rankname (prison_r_pcf_rankname), prison_rank__player_cost_remaining_rankname (prison_r_pcf_rankname),
-prison_rank__player_cost_remaining_formatted_rankname (prison_r_pcf_rankname), prison_rank__player_cost_percent_rankname (prison_r_pcp_rankname),
-prison_rank__player_cost_bar_rankname (prison_r_pcb_rankname)
+* **Minor changes to SellAll Util.**
-* **Refactored ranks and RankLadders to eliminate old and inefficient ways to get the ranks and next ranks.**
-These change will help improve the performance of processing the placeholders.
-This also allows the elimination of a few functions that are now obsolete.
+* **Much better performance for SellAll generally.**
+
+
+* **SellAll Commands internal changes.**
+
+
+* **Minor changes to GUIs:** Some fixes and visual changes.
+
+
+* **SellAllUtil Rewrite:** New internals for SellAll and SellAll API.
+
+
+
+
+# v3.2.10 2021-08-22
# v3.2.9 2021-07-03
diff --git a/docs/images/prison_docs_100_setting_up_auto_configure_03.png b/docs/images/prison_docs_100_setting_up_auto_configure_03.png
index 058b90acc..4d5bf7bd4 100644
Binary files a/docs/images/prison_docs_100_setting_up_auto_configure_03.png and b/docs/images/prison_docs_100_setting_up_auto_configure_03.png differ
diff --git a/docs/images/prison_docs_100_setting_up_auto_configure_04.png b/docs/images/prison_docs_100_setting_up_auto_configure_04.png
index 5d20f112d..7e00e68ae 100644
Binary files a/docs/images/prison_docs_100_setting_up_auto_configure_04.png and b/docs/images/prison_docs_100_setting_up_auto_configure_04.png differ
diff --git a/docs/images/prison_docs_100_setting_up_auto_configure_05.png b/docs/images/prison_docs_100_setting_up_auto_configure_05.png
index a09761c73..0514bcbde 100644
Binary files a/docs/images/prison_docs_100_setting_up_auto_configure_05.png and b/docs/images/prison_docs_100_setting_up_auto_configure_05.png differ
diff --git a/docs/images/prison_docs_100_setting_up_auto_configure_06.png b/docs/images/prison_docs_100_setting_up_auto_configure_06.png
index 9ebd8c78d..eadfe8eb3 100644
Binary files a/docs/images/prison_docs_100_setting_up_auto_configure_06.png and b/docs/images/prison_docs_100_setting_up_auto_configure_06.png differ
diff --git a/docs/images/prison_docs_115_blockevents_01.png b/docs/images/prison_docs_115_blockevents_01.png
new file mode 100644
index 000000000..2adab6b28
Binary files /dev/null and b/docs/images/prison_docs_115_blockevents_01.png differ
diff --git a/docs/images/prison_docs_115_blockevents_02.png b/docs/images/prison_docs_115_blockevents_02.png
new file mode 100644
index 000000000..20c7c4d76
Binary files /dev/null and b/docs/images/prison_docs_115_blockevents_02.png differ
diff --git a/docs/knownissues_v3.3.x.md b/docs/knownissues_v3.3.x.md
index b0747c03e..082006343 100644
--- a/docs/knownissues_v3.3.x.md
+++ b/docs/knownissues_v3.3.x.md
@@ -3,43 +3,182 @@
# Prison Known Issues and To Do's for v3.3.x
+# TODO Items for v3.2.11-alpha.13
-# TODOs for v3.2.10 release:
-1. DONE: Final testing of ladder rank multipliers
-2. DONE: /ranks ladder moveRank not working
-3. DONE: Forced global refresh of rank multipliers when a ladder multiplier is changed.
- - Should be simple
- - Run as async task
- - DONE: Force update when updating a ladder's multiplier - all players
- - DONE: Force update when changing ranks - only targeted player
-4. DONE: Add ladder base cost multiplier to /ranks autoConfigure. Start with a simple 10%.
- - Include message that it's enabled and how to change it or disable it:
- - /ranks ladder rankCostMultiplier prestiges 0
-5. Add to /ranks player the detail information on rank cost multipliers
-6. DONE: For '/ranks autoConfigure' add an alias to '/prison autoConfigure'
-7. DONE: Change /ranks list so if non-op it does not show all the extra details. A simplified list for plain players.
+**Tasks needed for the v3.2.11 release:**
+* Review some documentation and udpate... especially with the luckperms.
+* Finalize the event listeners to use only one event (was three, now two, but reduce down to one).
+* Review placeholders
+* Try to hook up a top-n command - may be too complex and may need to be pushed over to the next release
+* Review Mine Bombs and see if there are some simple updates
+* Backpacks - may need to push over to next version
+* GUI menus - Add the new GUI Tools to more of the GUI menus to simplify some of the commands?
-8. Liners: Some are only for later releases and do not work with 1.8.8. So need to setup something to restrict the liners that are not functional for the older releases of spigot.
-9. Hook up Prison's Explosion event.
+* test Mine placements and resizing. Something does not look correct with tracer and liners.
-### Others
-* DONE: Add a rank cost multiplier to ladders. Sum all active ranks a player has to get the total multiplier to use for rank costs.
-* DONE: Fix the "next rank" value with PlayerRanks.... needs to recalc with the new rank.
-* DONE: When a ladder's rate cost multiplier is changed, need to recalculate all player's multipliers. Setup a task?
+
+* create a command placeholder that will be able to add a delay between submitting commands. Have it based upon ms.. and have it setup to be used when more than one command is combined with others.
+
+
+* Command cooldowns - ranks - use config file to customize on a per command basis. Modify the prison command handler to manage cooldows as a new attribte to the commands.
+
+
+* Mine Bombs: identify bombs... new way.
+See SelectionManager... Prison wand uses the whole items stack to identify a wand, instead of just one small part, such as name or lore. Well, actually, its only the display name and material... no lore.
+
+
+* Add Mine Regions - Similar to mines in a way, where they will allow players to have access to the region, have mine effects (outside of a mine)... and mine effects would also be tied to these too.
+
+
+* DONE: command handler - Ignore commands in certain worlds
+
+
+* Placing mines could triggers many resets... also placing mines may not clear all blocks.
+
+
+* DONE: Player Cache - Make sure the cache is loadable otherwise a new instance may be created that could wipe out the existing data.
+ - All player loads block... they do not submit a task anymore.
+ - ~block for all loads - currently it may return a null and load via async~
+ - (no) Track file last saved date and if they don't match, then create a backup of the file version and don't delete it.
+
+
+* GUI Menu Tools
+ - Page prior and page next
+ - Current page
+ - Go Back button
+ - Background colored panes when no options
+ - Current version is not tied to configs... future options...
+ -- Hook up to more gui menus
+
+
+* DONE: Add a base class for the mine bomb configs...
+ - DONE: Add a version so as to be able to auto refresh the formats
+
+
+* New documentation - Madog's knowledge
+ - look for pins
+
+
+* Add mine effects. See conversation with Madog.
+ - Use PlayerCache and existing utils.
+ - Simple to implement some features, including flying in a mine.
+
+
+**List for v3.2.11 release:**
+
+
+* DONE: Players need to be restructured. Move rank player object, or at least most of the core, to the core project so as to reduce the number of player types.
+
+* Cache player
+ - cache player's balance - Hmm... may need to put it in RankPlayer
+ - cache player's ranks... only prestiges, default
+
+* Top-n ranks
+ - total blocks mined
+ - total tokens earned (or currently has)
+ - balance
+ - highest rank: prestiges, default, balance
+ - most online time, or most mining time (which will probably be better)
+
+
+* DONE: FIXED: Issue with blocks. Explosions are creating "untouchable" blocks that cannot be included in other explosions.
+ - My observations were with multiple explosions leaving rings that are within the the radius of an explosion
+ - I could break the blocks.
+ - jamo said that the pillars that were created on his server could not be broke
+
+
+
+* Review placeholders - add and test placeholders that are tied to playerCache stats
+
+* Mine Bombs - Finish
+ - Add sound and particle effects
+ - Other features?
+ - Make sure the bomb is set within a mine. Do not allow it to be placed outside of a mine.
+ - DONE: When exploding large bombs with block decay, there is a chance that you can get the first block in the decay as part of the drops.
+ - DONE: Check to make sure the block broke is the one in the target block. If not, then ignore.
+ - make sure the block is not "locked"
+
+
+* Add a top 10 listing commands
+ - Top player on server (rank / ladder)
+ - Top player per mine?
+ - Top Player per Blocks
+ - Top Player per time
+
+* Add Block & Time requirements for rankups
+ - Upon rankup, player will get a new "object" that would track rankup progress
+ - Would record current blocks and time for that rank, which is needed for when they
+ prestige. The rankup Progress won't change until they rankup and it will be reset.
+ It's used to subtract from current stats to get "progress".
+
+* BackPacks & Vaults & Warehouses - rewrite
+ - Add PlayerCache support with integrated backpack data object to track details
+ - Create new gradle module for backpacks and other items. Call it something like Accessories.
+ - Remove hooks in the spigot module except for the code to read existing old backpacks to migrate contents.
+ - Backpacks are able to have pickup and sell used against them.
+ - Vaults are protected from pickup and sell - Have to manually move items in and out to main inventory in order to sell them. Max size limit is a double chest.
+ - Backpacks can be protected from pickup and sell via command, which can be used to charge players.
+ - Warehouses are not normal player inventory/chests. They are virtual containers for items and blocks.
+ - Warehouses have slots, where each slot is one item. A slot can have a dynamic amount of items it can store. The player can buy more slots in their warehouse and increase the capacity of each slot.
+ - Warehouses - have formula to calculate costs of slots and capacity, where prices increase on both depending upon number of slots, and total capacity size of warehouse.
+ - Warehouses - Initial capacity of 5 slots, each at 100 to 200 capacity.
+ - Should vaults be tied to a physical location, such a server-wide "bank"? If so, then players has to physically go there to access their vaults. Same with warehouses. A defined bank or warehouse would be similar to a mine in such it would be 3d and access would work anywhere in there. Or a given mine could be designated as a bank or mine. So like for example, mine c could be the bank so a player would have to rank up to C to access it. Then a vault could be tied to a third tier prestige or something (but those don't have physical locations, but could make it mine a) or create a new mine that is empty, then link that new mine to that prestige rank so players have access to it.
+
+
+
+
+
+
+* Mine reset messages: Have setting to control by percent remaining in the mine.
+
+
+* Save files do not include the block type prefix. Such as used with CustomItems.
+Not sure if it needs to? Need to test and confirm if working correctly. World coordinates would be wrong if missing.
+
+
+
+
+- Not sure why the following would be needed:
+* Auto Features Settings : Create an API object that has the auto features settings listed. Basically this would serve as a simple cache with a life span of about 10 seconds. So if a player is mining hundreds of blocks within 10 seconds, odds are these settings will not be changing... both server config settings, and the player's permissions. Can provide helper classes that will a simple check of all these details, such as passing tool in hand to check perms for auto pickup settings for the server, the player's perms and lore on the tool. ... as an example.
+- Store in the player cache object, but make transient. Refresh every 10 to 15 seconds.. maybe even 30?
+- Add to the auto features event so its available there
+- Change function parameters to use the event and this new object as parameters... reduces number of parms...
+
+
+
+
+
+* Multi-language - Unable to create a custom language file that is not within the prison jar. It's been reported by Ingrosso that cannot create a new language file that does not match a file within the jar?
+
+
+* BlockEvent processing queue - submit blockEvents to a job queue to run in another async thread... the individual commands would have to run in a sync thread.
+ - This will release the block break thread faster and won't contribute to lag.
+
+
+
+
+* DONE: https://github.com/PrisonTeam/Prison/issues/222
+ DecimalFormat not being used correctly in saving mine data so if different Locale is used, other than EN US, then parsing the saved file can result in a failure.
+ - MineBlockEvent is an example of where this was a problem
+ - The offending sections were corrected and should now work
+
+
+* Add option to /ranks to rename a rank. Tag too?
+
# Start on mine bombs
1. Select size of bomb. Configuration.
- 1a. Identify items to use as bombs
- 1b. Bomb size
- 1c. Bomb explosion pattern. Currently only sphere, but could include other shapes.
+ 1a. DONE: Identify items to use as bombs
+ 1b. DONE: Bomb size
+ 1c. DONE: Bomb explosion pattern. Currently only sphere, but could include other shapes.
2. DONE: Select list of blocks that will be effected by bomb explosion
3. Throw bomb, or place bomb... start processing count down.
4. Pre-fire effects: sound & particles (low priority)
@@ -48,6 +187,8 @@
7. Hook up prison's event handler for prison's explosion event
+
+
* DONE: Modified /ranks list to provide this feature
- Maybe provide a /rankcost command? Show current player rank costs with rank cost multipliers applied
- /rankcost
@@ -86,10 +227,6 @@
# **Possible bugs/issues:**
-* DONE: /ranks ladder moveRank did not work to move from one ladder to another
-
-* DONE: When adding a new rank or mine, auto reload all placeholders so they pick up the new entry.
-
* Test BlockEvent perms... they appear like they don't work.
* If ranks module fails due to no economy, try to make that a little more obvious.
@@ -498,6 +635,97 @@ Offers for translation:
+# Features recently added for v3.2.11
+
+
+
+
+
+
+
+
+
+
+* DONE: New update to combine block processing results in many block.getDrops() being combined. Since they are combined, the extended fortune calculations may not work properly since it does not know how many original blocks were included.
+- May need to have an intermediate object to better collect original blocks, drops, and targetBlocks. It can include some of the more basics that are not tracked, such as original block count to better calculate the fortunes.
+
+
+
+* DONE: Rewrite the `/prison utils titles` to use XSeries' title commands. XSeries only supports 1.9+ so I still need to support 1.8.8 directly within prison.
+
+
+
+* DONE: Common messaging framework so if hundreds of messages are sent, only one is displayed. Eliminate the duplicates.
+
+
+
+
+* DONE: Revert a mine to a virtual mine. Maybe with the command: `/mines set area *virtual*`. Backup the mine's data file before updating and saving.
+
+
+* DONE: the command /mines reset *all* is not working correctly. Could be an issue with the chaining not submitting the next reset since this is all done through async processes right now.
+
+
+* DONE: Add a few more options to auto features for auto sell, such on full inventory. This was removed recently to stabilize some of the new code.
+ - Just refined what was already there.
+
+
+
+
+* DONE: Concurrent modification error on the MineTargetPrisonBlock when resetting the mine.
+ tech.mcprison.prison.spigot.game.SpigotWorld.setBlocksSynchronously() (146).
+ Serialize Id the mine resets and provide a locking mechanism that will prevent auto features from being processed when it goes in to a reset mode. Also when in a reset mode, prevent another reset from being submitted so they cannot run concurrently or back to back. Maybe attach a cooldown to the resets too, such as 10 seconds would be long enough to prevent a runaway chained reaction.
+ - DONE: Create an object such as a MineStateToken that will hold the state of the mine reset (in progress, mineable, stable, usable, locked, etc... not sure proper terminology right now... or how many states), with a serial number that will be incremented on each reset.
+ - (on hold) Do not perform a clear on the collection of MineTargetPrisonBlocks within the mine. Just replace the collection with a new collection and let the garbage collection handle reclaiming all resources. Carefully review for possible memory leaks. May be a good idea to hold on to that collection and submit a task that runs in about 30 seconds to perform a clear on the collection to release the resources. This may be important since the target blocks contains references to the stats blocks and may not be GC'd automatically. May want to null those refs first too.
+ MineReset.clearMineTargetPrisonBlocks() (1799)
+
+* DONE: PlayerCache Time per Mine stats - not recording correctly.
+
+* DONE: new auto features autosell should place items in inventory that have no sell value. Items that cannot be auto sold.
+
+
+
+
+
+# Features recently added for v3.2.10
+
+
+# TODOs for v3.2.10 release:
+
+1. DONE: Final testing of ladder rank multipliers
+2. DONE: /ranks ladder moveRank not working
+3. DONE: Forced global refresh of rank multipliers when a ladder multiplier is changed.
+ - Should be simple
+ - Run as async task
+ - DONE: Force update when updating a ladder's multiplier - all players
+ - DONE: Force update when changing ranks - only targeted player
+4. DONE: Add ladder base cost multiplier to /ranks autoConfigure. Start with a simple 10%.
+ - Include message that it's enabled and how to change it or disable it:
+ - /ranks ladder rankCostMultiplier prestiges 0
+5. Add to /ranks player the detail information on rank cost multipliers
+6. DONE: For '/ranks autoConfigure' add an alias to '/prison autoConfigure'
+
+7. DONE: Change /ranks list so if non-op it does not show all the extra details. A simplified list for plain players.
+
+8. DONE: Liners: Some are only for later releases and do not work with 1.8.8. So need to setup something to restrict the liners that are not functional for the older releases of spigot.
+
+9. DONE: Hook up Prison's Explosion event.
+
+
+### Others
+
+* DONE: Add a rank cost multiplier to ladders. Sum all active ranks a player has to get the total multiplier to use for rank costs.
+* DONE: Fix the "next rank" value with PlayerRanks.... needs to recalc with the new rank.
+* DONE: When a ladder's rate cost multiplier is changed, need to recalculate all player's multipliers. Setup a task?
+
+
+
+* DONE: /ranks ladder moveRank did not work to move from one ladder to another
+
+* DONE: When adding a new rank or mine, auto reload all placeholders so they pick up the new entry.
+
+
+
# Features recently added since v3.2.9
diff --git a/docs/prison_changelog_v3.2.10.md b/docs/prison_changelog_v3.2.10.md
index 78c3d6290..699fa0041 100644
--- a/docs/prison_changelog_v3.2.10.md
+++ b/docs/prison_changelog_v3.2.10.md
@@ -32,7 +32,9 @@ These build logs represent the work that has been going on within prison.
* Provide a more robust support system in prison, in addition to the support submit features. Can now enable more debug mode targets to better trackdown potential issues.
-* Prison now supports reloadable locales and auto features. For the auto features, it also reregisters the block break events listeners that auto features use.
+* Prison now supports reloadable locales and auto features. For the auto features, it now unregisters all previously registered block event listeners, and the re-registers them based upon the updates to the settings in the reloaded auto features. The server no longer needs to be restarted if the configuration settings for event listeners have changed in any way.
+
+* Auto features has undergone more refactoring to prepare for future enhancements, and to streamline the existing processes. A few undiscovered bugs were found and fixed during these enhancements. As a result, auto features works better with other enchantment plugins.
* Rewrote some of the auto features to resolve some obscure issues, and to provide performance improvements and greater flexibility.
@@ -43,7 +45,7 @@ These build logs represent the work that has been going on within prison.
* Update many of the internal libraries.
-* Rewrites of the GUIs and Sellall features.
+* Performance improvements with GUIs, backpack, and Sellall features. Includes fixs and some layout functional improvements too.
* Expand Prison's utils features. Added a few more utilities.
diff --git a/docs/prison_changelog_v3.2.11.md b/docs/prison_changelog_v3.2.11.md
new file mode 100644
index 000000000..ee3fa9319
--- /dev/null
+++ b/docs/prison_changelog_v3.2.11.md
@@ -0,0 +1,1059 @@
+[Prison Documents - Table of Contents](prison_docs_000_toc.md)
+
+## Prison Build Logs for v3.2.11
+
+## Build logs
+ - **[v3.3.0-alpha - Current](changelog_v3.3.x.md)**
+ - [v3.2.0 through v3.2.10](prison_changelogs.md)
+
+
+These build logs represent the work that has been going on within prison.
+
+
+
+# 3.2.11 2022-01-22
+
+* Prison now supports 258 Placeholders, including aliases.
+
+- - - -
+
+Prison supports:
+ - Java 1.8 through Java 17.
+ - Spigot 1.8 through 1.18, and other platforms based upon Spigot.
+
+* Many updates and bug fixes. Please see the change log for all of them. Below is just a limited sumary of some of the more important updates.
+
+
+* Asynchronous mine reset enablement
+
+
+* Prison can now be disabled completely on a per world basis. See setting in config.yml.
+
+
+* If the server is missing an economy plugin, prison now does a better job at communicting what the problem is so it can be fixed quickly. An economy plugin is required for the ranks module to function.
+
+
+* Added a debug mode for inspecting a block. To enable, enabl prison debug with `/prison debug` then while holding a prison wand `/mines wand` click a block and it will show a couple of lines tied to the information that prison has recorded for that block. If you shift-right click a block, then prison will check each event listener to see what it does with the block. It will report when a block event is canceled and other details, on a per listener basis.
+
+
+* Start to add tokens to prison. Players can now earn tokens while mining. Its a work in progress, but they cannot spend them yet.
+
+
+* Updated block constraints so blocks can be spawned in spedific layers within a mine, and with a minimum or maximum amouts.
+
+
+* Placeholders - Prison now has 258 placeholders, including aliases. Added many placeholders and improve a few that were having some issues. There are still more that are planned to be added.
+
+
+* Added new Prison Mine Bombs - Work in progress - Basics exist and have a lot of functionality, but more work will be done to add new features and address issues when found and reported. If you have ideas, or need something specific, please visit our discord server and talk to Blue.
+
+
+* Coming Soon: Mine Region. Mine effects that are applied to Mine Regions. Mine Effects will include potion effects like night vision, and other effects such as no hunger, no fall damage, and fly. Also may be adding enhantments soon too.
+
+
+* Significant improvements for handling multi-block explosions with a major rewrite to improve the overall performance within the handling of block break events within the auto features. Many changes to improve performance on a per-block basis, and to prevent a block from being counted more than once when many different players are trying to break, or explode the same blocks.
+
+
+* Signficant updates to most Prison GUIs and sellall
+
+**NOTE:** It is currently recommended that the old Prison Backpacks should not be used at this time. They will be rewritten shortly to address the current issues.
+
+
+
+# 3.2.11-alpha.17 2022-01-18
+
+
+* **Added to SpigotPlayer the ability to enable flying and to check to see if the player is flying. This is to prepare for mine effects.**
+
+
+* **Considering adding heads support to prison. Added a few parts, but they are not functional.**
+
+
+* **3.2.11-alpha.17 2022-01-18**
+
+
+* **More updates to the player's rank menu with the ability to add rank specific lore to the configs.**
+When referring to ranks, the names much match exactly since they are case sensitive.
+
+
+* **Bug fix with the rank cost calculations since they were not pulling in the last rank in the rang of ranks.**
+
+
+* **Fixed an issue with CI's function that was not returning any ids.**
+
+
+* **Mine auto resets can now be disabled.**
+When disabled, they will never reset based upon time. The resets can still be triggered by blocks remaining thresholds.
+
+
+* **3.2.11-alpha.16 2022-01-16**
+
+
+* **Lot of updates to the GUI menus.**
+Major improvements to the player's /gui ranks to work better with placeholders. Added comments to the GuiConfig.yml file on how to use it and the placeholders.
+Delete the GuiConfig.yml file to regenerate with the updated information on lore settings.
+
+
+* **Update a few of the player's GUIs to support the SpigotGUIMenutools.**
+Added capability to control the return command and the paging command so it now works more intuitivily.
+
+
+* **Fix issue with the placeholders related to prison_rankup_cost.**
+This now works correctly to include the next prestig rank's cost when at the last rank in the default ladder.
+
+
+* **Bug fix: Get the 32 placeholders related to prison_rankup_cost working correctly when dealing with various prestige conditions.**
+
+
+
+* **Bug fix: The player based playSound was not working, but the world's playSound works perfectly. Not sue why bukkit player would be messed up that **
+
+
+* **Bug fix: Hooking up the rollover to the next prestige rank cost, when at th end of the ladder, had a typo where it would not evaluate any rank.**
+
+
+**3.2.11-alpha.15 2022-01-13**
+
+
+* **Bug Fix: If the wrong sound file was being used it used to throw a NPE.**
+Now this is a safer way to find the correct file, and it will fall back upon a plink sound for any version of spigot.
+
+
+* **If upon loading a mine, there is a reson or need to resave the data, since this is an auto update, then this will make a backup copy of the mine's save file before saving it.**
+
+
+* **Bug fix: If spigot version is less than 1.13.0, and trying to use a _WOOD block, XMaterials cannot map that correctly to a Material and then back to the same XMaterial.**
+This is causing a problem when using in a mine since it cannot be tied back to the block that was placed. So for these versions, all _WOOD blocks are removed from the server. If a _WOOD block is saved in a mine, it will be remapped to the same _PLANKS block, which will work just fine.
+
+
+* **Bug fix: Prevent stack traces when a broken block cannot be mapped to a PrisonBlockStatusData object.**
+This is happening with spigot versions 1.8 through 1.12.2 when using "WOOD" blocks since XSeries translates these blocks to LOGs, so they will never map back to the XMaterial WOOD entries. This was producing a stacktrace and would prevent the proper handling of the auto features.
+
+
+* **3.2.11-alpha.14 2022-01-11**
+
+
+* **Update the failed rank message so it is clearer.**
+
+
+
+* **When a player is on the default ladder at the last possible rank, instead of showing nothing for rankup costs, percent, bar, etc, it will now use the next prestige rank if prestiges are enabled.**
+
+ These changes apply to the following placeholders:
+
+ prison_rc prison_rankup_cost prison_rc_laddername prison_rankup_cost_laddername
+ prison_rcf prison_rankup_cost_formatted prison_rcf_laddername prison_rankup_cost_formatted_laddername
+ prison_rcp prison_rankup_cost_percent prison_rcp_laddername prison_rankup_cost_percent_laddername
+ prison_rcb prison_rankup_cost_bar prison_rcb_laddername prison_rankup_cost_bar_laddername
+ prison_rcr prison_rankup_cost_remaining prison_rcr_laddername prison_rankup_cost_remaining_laddername
+ prison_rcrf prison_rankup_cost_remaining_formatted prison_rcrf_laddername prison_rankup_cost_remaining_formatted_laddername
+ prison_rcrp prison_rankup_cost_remaining_percent prison_rcrp_laddername prison_rankup_cost_remaining_percent_laddername
+ prison_rcrb prison_rankup_cost_remaining_bar prison_rcrb_laddername prison_rankup_cost_remaining_bar_laddername
+
+
+
+* **On delayed startup, allow a combination of selectors to target essentials, since the class name has changed in v2.19.x**
+
+
+* **Setup the block inspector to auto select a diamond shovel, a diamond axe, or a diamond pickaxe.**
+
+
+* **On the blockbreak debug information, show the information on either the block that was hit, or if that is null, just dashes to show such a block was not provided.**
+
+
+* **For EssentialsX v2.19.x, the class being used to identify if the economy has been loaded has changed.**
+This commit has the references to the proper class to use depeending upon the version of EssentialsX. It should be noted that this only applies if delayed startup is enabled for the EssentialsX economy, which generally does not require it.
+
+
+* **Change in how prison deals with ranks when there isn't an economy plugin loaded.**
+Now, instead of printing a simple little message in the console, which everyone appear to miss, it also enables a generic `/ranks` command that only displays a message indicating that no economy was found, with links to documentation. This should make it more obvious.
+
+
+* **Change to auto features for the event listeners: now MONITOR is not enabled unless set to priority of MONITOR.**
+
+
+* **If a language file has a message that is set to an empty string or a space, it will now no longer generate an empty message.**
+Instead it will supress the sending of any message that is blank.
+
+
+* **Move the placeholder `prison_player_blocks_total` from being a player mine placeholder, to a player placeholder since it is not tied to a specific mine.**
+Added a formatted version (with commas) and this one became unformatted so it can be used within scripts if needed.
+
+
+* **The use of the `/ranks command remove` within the `/ranks info`, or `/ranks command list` was not correctly including the correct row number**; it was using one higher than what it should have due to prior incrementing.
+
+
+* **Issues with SellAll when dealing with varient block types when bukkit version is less than 1.13.**
+Eliminate usage of org.bukkit.Material where possible. XMaterial must generate the ItemStack directly, instead of creating a Material object.
+
+
+* **Fix some issues with canceling drops:**
+Will not work on 1.8.x and maybe a few other versions of spigot with no work arounds. Works on newer versions.
+
+
+**New Feature: Dump the BlockBreakEvent and monitor changes per listener.**
+This provides a great deal of information on what is modifying the blocks.
+To use, enter prison debug mode with `/prison debug` and then shift-click on a block using the prison wand (`/mines wand`).
+
+
+
+* **Bug Fix: When loading the mines, and if using the old block model, some blocks were not mapping to the new PrisonBlocks.**
+When this now happens, the loader now tries to use the old block model's getXMaterialName() function, which returns one or more names that can map to XMaterial objects. It tries all of them until it is able to get a non-null PrisonBlock result.
+
+
+* **Added a safty backup of the player's cache file... if it is detected that the new size is smaller than the prior size, then make a backup copy saving the original version instead of deleting it.**
+This implies that stats will always be added to the player's cache and that the file should alwaysbe getting larger. This only makes sense when recording stats. The file could become smaller when balances are reset, such as spending a lot of tokens.
+This also implies that some times, such as player inventories, should not be stored in this object... player's backpacks will be removed in the near future.
+It should be mentioned that on a test server I saw my player stats for my test player being wipped out. I have no idea if it was because of file system commands that I ran, or if it was a bug in prison that reset it. But because there was a potential loss, I'm making sure certain things cannot happen anymore, or trying to reduce the risk of losses.
+
+
+
+* **Fix the sellall block list gui for when there is an invalid XMaterial name**, that it will print out the error to the console, and continue with using COBBLESTONE instead of producing a NPE.
+
+
+
+* **For the list of displaying the ranks on a ladder, split them up to show 15 per line which will help when there are a lot of ranks on a given ladder.**
+
+
+* **Increased the confirmation on mine size from 25,000 to 50,000 blocks so as to minimize the number of times this will occur.**
+
+
+* **Add support for specifying the sound to use for inventory full event.**
+Valid sounds can be listed with the command /prison utils sounds list.
+
+
+* **Added support for doubles in the AutoFeatures settings.**
+The basics were there, but the actual AutoFeatures enum did not have them hooked up.
+
+
+* **Remove an unused function on the PlayerCache.**
+
+
+* **Bug fix for mohist, or other platforms that are trying to use SuperPerms, or other perm plugins that do not support groups.**
+
+
+* **Add *all* to the command /mines set tpAccessByRank.**
+
+
+* **Add '*all*' as an option for applying Access by Rank for mines command: /mines set mineAccessByRank.**
+
+
+* **3.2.11-alpha.13** 2021-12-24
+
+
+* **Prison command handler: adds the ability to add new aliases from the config file.**
+
+
+* **For ranks that are null, made some changes so either empty strings are used instad, or most of the time the rank name is used.**
+
+
+* **Fixed a potential issue with nulls in the language file parameters. All nulls are replaced with empty strings.**
+
+
+* **Added the ability for admins to add aliases to commands so they can better customize their environment.**
+
+
+* **Disable block break events in the worlds where prison commands are disabled.**
+
+
+* **Added the ability to disable prison command hander is specific worlds.**
+The settings are within config.yml. The disabling of prison is only done on the command handler, and will soon be hooked up to the block break events too.
+The command /prison now lists worlds in which prison has been disabled
+
+
+
+**3.2.11-alpha.12** 2021-12-21
+Alpha 12 released.
+
+
+* **Fixed issue with XMaterial when trying to parse a custom blcok that is not compatible with prison.**
+The function will now return a null value and everything that uses it, must ensure it's not null before trying to use it.
+
+
+* **Make sure the targetBlock is not null before trying to process it.**
+
+
+* **Docs: Updated the LuckPerms Tracks and Groups document to provide more details on how to set them up.**
+
+
+* **Bug fix: Ran in to a rare situation where the use of essentialsX economy failed to allow prison to load the players during startup.**
+Prison was trying to "rank" the players within each rank that they were in, and that required prison to get their balance.... but bukkit was not able to return an OfflinePlayer instance for any of the plyers. Therefore prison could not access the player through vault. No idea why bukkit is not able to provide the players. The server in question had about 2500 players.
+So to prevent this from happening, the initial ranking bypasses the loading of any monetary amounts; they will be updated later.
+
+
+* **Update and create some new LuckPerms docs.**
+
+
+* **Move gui tools menu changes to improve them and hook them up to menus that did not have any paging.**
+
+
+* **Adjustments to improve the way the new gui tools work to reduce the amount of use of lore, or at least the visible lore.**
+This visually cleans it up a lot.
+
+
+* **Hooked up some of the new features to the /gui ranks menu, plus added a /gui ladders and hooked that up. Simplified how the ladders page was setup.**
+
+
+* **More work on the GUI menu tools to not only get them to work better (correctly) but also add new capabilities... now supports adding a menu option and the tool auto assigns it to the next available slot.**
+
+
+* **GUI menu tools update...**
+
+
+* **Prison Tokens: Remove the alias so they will not cause conflict with other token plugins.**
+
+
+* **Potential bug fix: There was a situation where with multiverse-core a delayed world loading resulted in the world not being found**, and therefore it was preventing the loading of all locations tied to the mine. This now allows the locations to be loaded without a valid world. Then when the world is finally loaded, it will refresh the references to the world objects.
+
+
+* **GUI Menu: a few minor changes before more radical changes to go with the final "idea".**
+
+
+* **GUI Menu Tools - Added a first page and last page button.**
+
+
+* **GUI Bug fix: If there are more than 45 ranks on a ladder, the GUI will NOW be able to provide paging capabilities to view all ranks.**
+By default it will start off with page one, but this can handle an unlimited number of pages.
+This paging system can be expanded and easily used on other GUI lists with minimal changes to hook it up.
+
+
+* **Found a bug in XMaterial where it was converting "melon" to melon_slice instead of the melon block.**
+
+
+* **Bug fix: Fixed an incorrect use of XMaterial which prevented it from working properly with spigot 1.8 through 1.12.**
+It was using XMaterial to get the Material value, which is wrong, since it's the item stack that contains the variants of the materials. So the change is to extract the item stack directly from XMaterial which solves the problem.
+Also there was another error where if amounts are greater than 64, setting them to 1 so the GUI will still work, but it will suppress the incorrect counts for the itemstack.
+
+
+* **Update XSeries to v8.5.0.1 to better support spigot 1.18.**
+
+
+**Prison tokens: Add a few more prison tokens placeholders.**
+Fixed the admin token commands to use longs and not integers.
+
+
+* **Ranks GUI Error.** ~~Fixed an error with Ranks GUI.~~ This did not fix anything.
+
+
+* **Some adjustments to admin token functions.**
+
+
+* **Bug fix: Rankup on a ladder in which there is not already a rank was producing an error.**
+Similar to prior problem... just did not fix it correctly for all situations.
+
+
+* **Start building the structure for the Top N rankings.**
+
+
+* **Mine Bombs: Noticed the player inventory was not be "updated" through bukkit.**
+This could help prevent wrong item amounts.
+
+
+* **Mine Bombs: Set them up to auto refresh the data structure that is being saved, if it is detected that there has been a change.**
+Added a version number to the mine bomb save data structure so as to use that to detect when the structure changes. That number will be updated in code when it has been modified. So when running the mine bomb loader, it will detect that the saved data is in an older format, and so it will rename the old file to preserve it as a backup, then write the new data to the file system. This will allow new fields to be added,and then they will appear in the save file upon the next restart. This will make it easier for admins to update and use the new features.
+
+
+* **Bug fix: Was causing a null pointer exception when trying to add a player to a new ladder.**
+This now correctly gives the player the requested rank, or if not specified, then the lowest rank on that ladder.
+
+
+* **3.2.11-alpha.11 2021-12-07**
+
+
+* **Mine Bombs: A few other minor fixes and changes.**
+
+
+* **Mine Bombs: Some changes in how they are setup. Added a bombItemId which becomes line one of the lore and is used to identify that it's a mine bomb.**
+Added a nameTag that is used to put a nameTag on the armor stand. Added a itemRemovalDelayTicks field to better control when the armor stand is removed (exact time).
+Update a lot of Mine Bomb code for creating the time, placing the item (armor stand) etc... It's working better overall.
+
+
+* **Update Tokens to fix an issue with the admin set.**
+Added better tracking of adminAdded and adminRemoved stats.
+
+
+* **Bug fix: Fixed a class not found except caused by google guava trying to load functions that it should not have been using for their event manager.**
+Moved the PEE event out of this class all together, so now it's safe to use in other areas of prison, such as with guava's event handler. This was not an issue with spigot 1.8.8, but manifested itself with Spigot 1.16.5 since I believe that version of spigot is using a newer version of guava that has that behavior.
+
+
+* **Upgrade XSeries to v8.5.0**
+
+
+* **3.2.11-alpha.10 2021-12-05**
+
+
+* **Bug fix: There was an issue that I found where blocks outside of the explosion events were being marked as mined without actually being broken.**
+Therefore prison would not be able to break those blocks. This was caused by the initial explosion setting off a chained reaction explosion through a blockEvent. Now blocks that are part of an explosion cannot be part of a future explosion.
+
+
+* **Added a new debug mode to inspect blocks by click on them with the mine wand tool when prison is in debug mode.**
+
+
+* **Renamed Prison's PlayerListener to PrisonPlayerListener to reduce a conflict and to make it more obvious which object is which.**
+
+
+* **For the bukkit 1.8 through bukkit 1.12, if an object has a different data value than what it normally has**,
+it would not be matched through XMaterials... Examples are leaves, chests, etc... if there is no match initially using the block then try to then match on just the name, which eliminates the problem of a failed match.
+
+
+* **Add a selective debug option where only the selected element is loged through the debugger.**
+
+
+* **Removed the DebugTarget value of "support" since it is not using anymore.**
+
+
+* **Bug fix: If a block has been placed in the mine that should not be there, prison was canceling the event which was preventing other plugins, or normal breakage, from breaking the block.**
+The event is no longer being canceled.
+
+
+* **Added 12 new placeholders: 4 new ones for player balances and 8 new ones for tokens.**
+
+
+* **Prison tokens: Added admin functions of balance, add, remove, and set.**
+
+
+* **Added the title and actionBar to the Player object so it will work in all forms of Player, such as RankPlayer.**
+Had to use the Platform to cross over to spigot from core.
+
+
+* **Added access to the player cache within the Player object so it's easier to use it.**
+
+
+* **Updates some documents.**
+
+
+* **Bug fix: One of the blockEvent placeholders was inserting the wrong value.**
+{blocksMinedTotal} was inserted the blockName.
+
+
+* **Slight adjustment to the mine backups's file name.**
+
+
+* **Move the messages for /mines tp to the language files.**
+
+
+* **3.2.11-alpha.9 2021-12-02**
+Version v3.2.11-alpha.9
+
+
+* **Added a new feature to back up a mine and to provide a way to convert a mine to a virtual mine.**
+When converting to a virtual, with the command '/mines set area virtual', a back up is made first.
+The new backup command is '/mines back help'.
+
+
+* **added mine name to reset notifications**
+
+
+* **Bug fix: If a MONITOR event listener, then it should not process the block break event.**
+Monitors were processing the block break events when they shouldn't so monitors are not terminated after validation since their "processing" is handled there.
+
+
+* **Bug fix: The command '/mines reset *all* details' was not working and was only running one mine reset instead of all mines.**
+
+
+* **Rank data refactoring. A few changes to get this working. The ladderRanks collection was not being setup was the main issue.**
+
+
+* **Rank data refactoring. A few changes to get this to work well.**
+
+
+* **Major refactoring of Rank Player data objects.**
+This is to transition to easier use of player objects in prison. Some of the key classes have been moved from Ranks module to Core module, with the removal of rank functions being moved back to the ranks module.
+This is a work in progress and does not yet work. The player's ladders and ranks have not been linked together yet.
+
+
+* **Fixed the auto sell command within the auto features to include the ability to use autosell based upon the auto features settings.**
+
+
+* **Fixed issue with a block break event happening outside of a mine, which will result in mine being null.**
+
+
+
+* **Fixed issue with getMine not striping color codes, but in the function before this one is called, it strips them to check to see if the mine name is valid.**
+
+
+
+
+**3.2.11-alpha.8 2021-11-28**
+Release v3.2.11-alpha.8.
+
+
+
+* **Update the last seen time.**
+But will not set dirty. If player is not active, then it will not be recorded.
+
+
+* **Expand the last seen information on the command /ranks player, which now includes how long ago instead of just a date and time.**
+
+
+* **Add a listSeenDate to the player's cache data.**
+This will be used to track when the player was last on, and more importantly, determine if the player's cache data should be updated for stats reporting for top-n functions.
+
+
+* **Fix a rare condition where the wrapper of the PrisonBlock is null (the actual bukkit block).**
+This may not fix everything related to this issue, but it will prevent a NPE at this location.
+
+
+* **Minor changes to clean up auto features a bit:** move functions that are no longer used in the normal block break code to OnBlockBreakPlayerManualCore so it's not confused with the main-core functions and accidentally used.
+Also clean up the messaging and sellall usage to eliminate duplication.
+
+
+* **Fixed an issue with the mine state mutex being null.**
+Not sure what's causing it, but I suspect it mabe an issue with loading the mine from a saved state on server startup and that field never gets initialized. So fixed it by doing a lazy initialization on the field.
+
+
+* **Fixes a minor issue with the command '/mines set spawn' where it was requiring an option be specified.**
+I fixed it by setting a default value of "set" which does nothing, but makes the optional options, optional now.
+
+
+* **Removed from the GUI the hologram on inventory full, and replaced it with actionBar.**
+
+
+* **Some adjustments to the overflow of the drops and other inventory controls.**
+On normal drops, disconnected autosell except if it is forced through the pmEvent.
+Fix inventory full sounds. For 1.13 and up it had the wrong sound file. Using something less harsh than anvil and turned down the volume which was horribly excessive with the volume set to 10, when normal is 1.
+
+
+* **Prison Tokens: Prison now is able to auto generate player tokens based upon blocks mined.**
+It's enabled through AutoFeatures config file's setting 'tokensEnabled' and is able to set the blocks per token earnings rate with 'tokensBlocksPerToken'.
+More features will be added soon, such admin functions and top-n token holders.... etc...
+
+
+
+* **3.2.11-alpha.7 2021-11-26**
+Released alpha.7. Major advancements to mine bombs.
+
+
+* **Mine Bombs: Added the use of a armor stand for holding the item, with an animation of swirling it around.**
+The item's armor stand is managed in a task which removes itself when finished. This process is independent from the visual and sound effects.
+Removed the static functions that were being used (which is much better).
+
+
+* **Mine Bombs: Added more effects to the examples.**
+Removed some that would not work. These are not perfectly selected and may not work for most versions of spigot. The visual effect do not appear to really do much.
+
+
+* **Mine Bombs: Setup some changes in how classes are related to each other so as to prepare for significant changes.**
+
+
+* **Mine Bombs: Got the sounds and visual effects hooked up to the explosions.**
+Made many revisions on how all of this works, but pushed the tasks to a new class PrisonUtilsMinBombsTask.
+
+
+* **Mine Bombs: Updated the listings of the mine bombs, which now includes full detail including the visual and sound effects, the list of shapes, list of sounds, and list of visual effects that can be used.**
+
+
+* **Mine Bombs: Updated the junit test for validating that the EffectState is sorted in the proper order when using the MineBombEffectsData as a comparator.**
+
+
+* **Mine Bombs: Setup a test unit test to confirm that the sorting of the EffectStates is as expected.**
+Needs to be: placed, explode, finished.
+
+
+* **Mine Bombs: Add the sound effects and visual effects to the default test bombs.**
+NOTE: Some of these settings may not work on all versions of spigot, and some may not work on any version.
+
+
+* **Bug fix: Auto features get drops not always working with explosions.**
+The get drops was moved around to help ensure it does not try to get the block drops if the block is not what it is expected. This is now passing the needed object used for the check, instead of extracting it from the target blocks, which have not yet been set.
+
+
+* **Bug fix: Auto Features Auto Pickup is now ignored if sellall has not been setup on the server.**
+If getting an instance of SellAll when it is disabled, will result in a null value.
+
+
+* **Mine Bombs: Added a few new shapes.**
+Disk and Ring. Available in each plane x, y, and z.
+
+
+* **Mine Bombs: Added the collections for sound effects and visual effects.**
+Both share the same object, MineBombEffectsData.
+An effect has a name, plus an EffectState, and an offset in ticks that will apply that effect based upon the EffectState.
+The EffectState can be placed, explode, or finished.
+
+
+* **Ran in to another Java format exception.**
+Not sure what caused this problem, but added it to the catch so it can be reported in details so it can be fixed.
+
+
+* **Add the ability to remove a mine's spawn point.**
+
+
+* **Reworked how the drops were processed to prevent dropping the wrong contents.**
+There was an issue where the drops were retrieved later in the process that allowed it to incorrectly pickup drops that were related to a decay function. This resolves the incorrect drops.
+
+
+* **Player cache timing improvements.** This fixes issues with tracking the timing when mining.
+Not 100% sure it is perfect, but it's actually working much better. Will need to revisit later.
+
+
+* **Added a check to detect that a block has been altered and is not the block that was placed there by the mine reset.**
+There have been drops of other materials making it in to an explosion event, and mostly due to block changes that happen due to other means.
+
+
+* **Refactored some of the checks to determin if the event should be processed or not, so this can be used with a new feature that may help to auto manage access when WorldGuard is being used.**
+
+
+* **Setup a mutex for locking the mine resets, which prevents active block break attempts, including explosions, from trying to break blocks while a mine is actively being reset.**
+This helps to reduce the chance of hitting a concurrent modification exception.
+
+
+* **Shut down auto manager and all auto features if the setting 'autoManager.isAutoManagerEnabled' is set to 'false' in autoFeaturesConfig.yml.**
+If anyone wants to use prison's block events, then they must use the auto manager.
+
+
+* **When using autosell through auto features, if a block cannot be sold, then the block is now placed in the player's inventory, or dropped if their inventory is full.**
+If a block is unable to be sold, the amount returned for the item stack will be zero.
+
+
+* **Bug Fix: There was originally a problem with applying block constraints that resulted in being unable to select a block when trying to randomly choose one.**
+Initially as a first quick fix was to trying to reselect a block, but if the block chances were really low, then it could still fail to select a block. Then it was attempted to select a default block, but that too failed to work, especially if there were a sizable chance for AIR, and it would fail 100% of the time if the was only one block with a very low chance. The failure was the whole mine could be filled with that one block with the very small chance.
+This fix completely redesigns the block selection, by first selecting only the blocks that are valid for that level of the mine. That way, when selecting blocks where blocks should be excluded from that level, those excluded blocks are never in the selected blocks to be considered. Also if AIR is a valid option, then this new process adds an AIR block to the temporary level block list with the percent chance assigned to the air.
+Overall, this is working really well now, and it actually simplifies a lot of code and reduces the amount of processing involved. This new process always selects a block on the first pass too so it never haves to try to reselect a block.
+
+
+* **Moved the multi-column formatting of data to the class Text so it can be used in other parts of the project.**
+It was originally created for use in /ranks player but is now extended to be usd to list the plugins within the /prison version command.
+
+
+* **Bug fix: If player is mining outside of a mine, then don't process anything.**
+May want to allow prison to manage block breaks outside of mines in the future, but for now, prison is only managing mines.
+
+
+* **3.2.11-alpha.6 2021-11-21**
+
+
+* **New feature which lists all of the Player Cache stats in the command `/ranks player`. This includes stats for block breaks, time spent in mines, and earnings per mine.**
+
+
+* **Capture an error within prison's Output class when trying to log content that has an UnknownFormatConversionException error.**
+This happens when there is a problem with text formatting characters that conflict with Java's formating class. This tries to log the error with better details so it can be fixed and resolved where the error is happening. This does not "fix" the problem, but just better reports it so it can be identified and fixed.
+
+
+* **Update on how prison manages the tracking of block breaks and earnings when auto features has autosell enabled.**
+
+
+* **Changes to how the event listeners are setup: reduced by 1/3rd.**
+Used to be that all three would be set if autopickup was enabled, but now only two will be set... monitor, and then either autopickup or manual drops.
+This should improve performance since prison will be processing 1/3 less events.
+
+
+* **3.2.11-alpha.5 2021-11-19**
+
+Post the alpha.5 release.
+
+
+* **Remove the now obsolete auto features setting isAutoSellPerBlockBreaknliedEnabled.**
+It is no longer needed since the auto features autosell per block break is now optimized and has no impact anymore.
+Improve the autosell integration in to the auto features for both the auto pickup and also the normal drops. Improved the debug logging to include a list of all blocks being sold, or dropped, and their quantity and value. Also the total counts too.
+
+
+* **Bug fix with SellAll: bug in original logic where the delayed notification when initialized is losing the first amount.**
+It now always adds the amount to the delayed queue.
+
+
+* **Autofeatures ignore certain events to improve performance and reduce logging entries when in debug mode.**
+Since there are multiple listeners on block break events, which monitor the same event, these changes are able to mark a specific block within the MineTargetPrisonBlock objects that will be able to pass along an "ignore" event status to the other listeners to short-circuit their processing. This is highly beneficial when using large mine bombs and the mine has blockEvents setup to perform explosions... which will help reduce a ton of "dead" events.
+
+
+* **Auto Features Forced Auto Sell Optimization Improvement: AutoSell within auto features now only uses sellall by item stack and not the player interface that accesses all of the player's inventories.**
+Since the auto features items are not placed in the player's inventories at this time in the process of auto features, there is no reason to access the player's inventories. Selling directly reduces a lot of sellall overhead and as a result sellall is just calculating the prices.
+The old autosell code within autofeatures has not be removed yet, but it cannot be called anymore.
+
+
+* **PrisonDispatchCommandTask: Removed the debug logging since it can be very numerous when used with a large mine bomb and it's pointless since most of the block events being submitted runs in less that one millisecond.**
+So this is just cleaning up a messy logging item.
+
+
+* **SellAll: Setup a sellall function that will allow the selling of one ItemStack, which is not tied to any of the player's inventories.**
+This is used in prison's auto features when enabling the option to auto sell on a per block break event basis. This is highly optimized and a lot faster than using the normal sellall since it does not deal with any of the player's inventories or backpacks.
+This forces a delayed sold amount message since an explosion could includ many ItemStacks.
+
+
+* **Mine bombs: Add cooldown and fuse delay to the mine bomb settings so each bomb can be customized.
+Added gravity to the mine bombs too.** Gravity, like glow, was added in minecraft 1.9 so older versions won't work.
+
+
+* **Bug fix: For TokenEnchant's explosive event processing,** need to set PrisonMinesBlockBreakEvent's setForceIfAirBlock( true ) so the explosion event can be processed, even if the initial block has already been processed.
+This allows TE explosion events to work correctly now.
+
+
+* **Bug fix: refined the use of a few internal registers that are being used to control block break behavior, and also block counts and block events.*
+A few of the settings were being changed in the wrong places, which was out of synch with when they should have been applied.
+A few of the side effects was failure of tracking block counts, block events, and handling some explosion events.
+
+
+* **Mine Bombs: More features and fixes.**
+Added support for radiusInner (for hollow sphere explosion shapes), removalChance (chance for block inclusion), glowing, autoSell, tool material type, tool fortune level.
+ Added a new shape which is "cube" and hooked up sphereHollow. Hooked up cube, sphereHollow, removalChance, glowing, the specified tool in hand with the custom fortune level. Did not hook up the forced autosell yet.
+Fixed some issues to get things to work a little better too.
+
+
+* **Prison Bombs: enabled the right clicking of AIR to set the bombs.**
+If clicking air blocks, then the block tied to the event will be null (at least for spigot 1.13.x) in that case, will use the block location of the player, and then adding the player's vector to it times three.
+
+
+
+* **Fixed a bug with how the regex handles block quotes.**
+Not only was it not working correctly for multiple block quotes, but it was incorrectly handling the tail end of the processed text and was basically doubling the text. It now works correctly, even with multiple block quotes.
+
+
+* **Fixed an unexpected "bug" with the JumboText font for the letter Q.**
+One section was setup to use "\Q" which is an escape character for a regex block quote. This was causing problems since it was forcing large sections of text to be ignored when translating minecraft color codes. By changing it to "\q", a lower case Q, this eliminated the translation from making the mistake.
+
+
+* **Bug fix: The command "/prison support submit ranks" was passing a null sender, which is valid when generated by this support tool.**
+The fixes now works well, and treats the null basically the same as an OP'd player, or the command being ran from the console.
+
+
+* **Bug fix. If a null message is sent to this function, it would cause a NPE.**
+This now prevents a few failures from causing potential problems.
+
+
+* **Fixes a concurrent modification exception when the PlayerCacheCheckTimersTask is running.**
+This happens rarely when a player is logging off while "trying" to process their entries; they have been removed.
+So when this happens, the process retries to start over a total of 2 more times and it skips processing players that have already been processed. Any update that was skipped would be covered in the next pass with no real loss.
+
+
+* **The use of a command placeholders for `{actionBar}` and `{title}` were added to the placeholder enumeration so they are included in the placeholders listings.**
+The support for these two commands were added a while ago, but because they were not added to the enum, they were not being listed in the help.
+
+
+**3.2.11-alpha.4 2021-11-01**
+ Released alpha.4.
+
+
+* **Changes to improve the way the upcoming mine bombs.**
+They are currently non-functional.
+
+
+* **Adjustments to get block events, such as decays, to work correctly with the new auto feature block event handlers.**
+ Block events were moved to be processed after the block is broke. Also if a block has already been processed, it now will cancel the event to prevent normal block breakage when none should happen.
+At this point, the new auto manager appears to be working really well.
+
+
+* **Changed the location usage with block event placeholders, which now uses the location that is tied to the targetBlock instead of the mined block.**
+The mined block may be null so it's not stable.
+
+
+* **Fixed an issue with /mines block list when an incorrect mine name is used.**
+Now displays an error stating the name is invalid.
+
+
+* **Starting to add some video documents for prison.**
+
+
+* **Fixed an issue with adding a non-block item to a mine.**
+It now validates that the specified item is a block. Also if a specified block is not in a mine when trying to remove it, it will now display a message indicating that nothing was removed.
+
+
+* **Major rewrites to how auto features work.**
+Using the PrisonMinesBlockBreakEvent object to carry all of the various parameters that are used within the auto features code. This allowed the elimination of many functions since they have been combined together. It also allowed for more efficient handling of explosions by combining similar blocks together and processing them as a single unit, so massive explosions are handled far more efficiently. If the admin chooses to break the blocks in another thread, then handling of many blocks is optimized to reduce the overhead. The state of the blocks being broken are being tracked through the MineTargetPrisonBlock such that it's flagged as soon as it starts to process the impacted blocks so as to prevent the same block from being processed more than once, even when there are many explosions occurring at the same time. Changes to the block (block break) has been moved out of the depths of the code, to be closer to the event handlers so it's easier to monitor/track.
+Due to the many changes and major alterations to the logic, this is a work in progress and needs more testing.
+
+
+* **Async Mine Reset performance Improvements.** Adjustments were made to improve the performance of the asynch mine resets by providing the ability to fine tune the page sizes, and also provide the ability to reset more than one block in the synchronous thread at a time. This is called a slice. Measuring the actual block reset time with nanos for better resolution.
+MineTargetBlockKey class was relocated to allow for the use of sub listings on the synchronized block updates.
+
+
+* **Cloning a bomb was not complete. Some details were omitted.**
+
+
+* **Fix for Potion IllegalArgumentException:** Fixed an error with potions in Player inventories when
+using sellall sell, potions aren't supported by now and won't be sold, but at least it won't break
+sellall anymore.
+
+
+
+* **Switched prison block debugging timing to use nanoTime instead of milliseconds since milliseconds is too large of a unit.**
+
+
+* **Bug Fix: When using block constraints,** there was a common situation where an AIR block was being used in the top layers because all other blocks were being rejected due to chance. Order of blocks had an impact on this error, when it shouldn't. Now, if a block cannot be selected, the first block with no constraint issue will be used instead. Also found a bug in the applying of the chance to each block. Under some situations, the percent chance was not being reduced for a bypassed block, when it should have. This now will better select the blocks, and better preserve their intended percentage odds of being spawned.
+
+
+**Prison v3.2.11-alpha.3 2021-10-18**
+
+
+* **Enable the ability to choose between setting the block to air inline, or through submitting a synch task to allow the blockBreak event handler to finish quicker, which may reduce lag.**
+
+
+* **Simplified the configuration of the handling of the block break events.**
+Instead of having a separate setting that is a boolean value that indicates it's either enabled or disabled, these are now using the priority value of DISABLED.
+
+
+* **Add millisecond reporting for the time it takes to handle a block break event.**
+
+
+
+**3.2.11-alpha.2 2021-10-14**
+
+
+* **A few updates to mine bombs. They have been disabled so they cannot be used.**
+
+
+* **Add the ability to glow the prison bombs when they are dropped/set.**
+
+
+* **For a couple of rankup messages, using the rank tag now instead of the rank name.**
+
+
+* **Fixed a compatibility issue with older versions of spigot.** Should have possibly use the compatibility classes, but if a method does not exist, then this will fall back on a string matching pattern.
+
+
+* **Changed the message about worn out tool to use the SpigotPlayer's setActionBar() function to prevent overloading console messages.**
+
+
+* **Bug fix: Logic was corrected to handle the double negative correctly.**
+The was an issue with the /mines set area command when the mine's area was larger than 25,000 blocks. They have to enter either "confirm" or "yes". The bug would require them to enter both to create the mine.
+
+
+* **Added an example of possible backpack object to the PlayerCachePlayerData object.**
+
+
+* **Adjustments to the new auto features for cancel block break events and block drops.**
+
+
+* **Removal of some auto feature commented out old code.**
+
+
+* **New auto features settings: Able to prevent event canceling and also control if the drops are cleared.**
+This has not been tested too much, but it may help make prison more compatible with other plugins that are needing to handle the block break events.
+
+
+* **Fortune on a tool was appearing as a negative value: -1000.**
+Not sure how it became negative, but this will better deal with negative values.
+
+
+* **Added a listener for PlayerInteractEvent.**
+
+
+* **Add a new feature to the PrisonSpigotAPI to allow for the creation of a new mine through the API.**
+This could be used to generate player mines in a plot world.
+
+
+
+* **Able to give players bombs, based upon the item type as defined for the bomb.**
+
+
+* **Significant progress on Prison's Mine Bombs:**
+Moved the mine bombs primary classes to the prison core so it's accessible from all packages.
+Setup 4 default mine bombs if the commands are used and there are none defined.
+Setup a new /prison utils bomb commands to list all bombs and to give players bombs. These are not complete and fully tested yet.
+
+
+* **Some initial work to setup the mine bombs configs.**
+
+
+* **Add placeholders {actionBar} and {title} to the blockEvent listing of placeholders that can be used.**
+They are shortcuts for the new prison utils commands.
+
+
+* **For the actionBar and title, translate the color codes so they work properly.**
+
+
+* **Hook up the auto features notification to use the new actionBar interface.**
+This "should" prevent duplicate messages from being sent to the player while the same message is displayed in the actionbar.
+
+
+* **Fixed an error about backpacks and lore transition:** A single lore was being used for the backpacks utility, if a server
+was new and fresh, this would've been missing and an error could occur, this now got fixed with the full transition.
+
+
+* **Full transition of all messages to the .properties lang:** All messages are now on the .properties file and the old
+.yml one is unused from now on, you can delete it and start translating the new one. Please note that some messages may
+be wrong, as it's still in a young stage and a lot of messages got transitioned.
+
+
+* **The player cache, when being shut down ran in to a problem if the players were removed when they logged off.**
+This function was making a new collection based upon the original player cache copy of players, of which, when a few of the players are removed, then they were resulting in nulls.
+
+
+* **Prevented a problem when unloading players, and when a player is null.**
+The condition that was causing a null player was that the player was unloaded when the player left the server at the same time when the server was shut down. Basically a race condition with two parallel async tasks trying to shut down the player cache object, each focusing on a different aspect (player vs. server).
+
+
+* **Hooked up XSeries' Titles to the compatibility class instead of using version specific code.**
+XSeries says they support 1.8.8 through 1.17.1.
+Deleted the support for the Spigot110 classes since it was only to support the use of the ActionBar and also the Title, which are no longer needed for 1.10+.
+
+
+* **Adding a player messaging component to the PlayerCache.**
+When used, this will prevent more than one of the same messages from being displayed at the same time.
+
+
+* **For the command /mines set area the confirmation of "yes" was setup incorrectly with being negated.**
+
+
+* **Switch over to using XSeries for the actionBar.**
+XSeries claims it works for 1.8.8 through 1.17.1.
+
+
+* **Moved all Lores to the new .properties Language file:** Changes to the old .yml language file about Lore messages
+won't take effect, only if you edit the .properties file they will.
+
+
+* **Added the trigger "minebombs" for the utils command bombs.**
+
+
+* **Adjustments to the BlockEvents and how it handles some of the event types.**
+Expanded and fixed some of the settings for prison's explosions, and PE's too.
+Added the ability to exclude specfic triggers.
+
+
+* **Updates to the Prison's explosion event handling to correct a few problems. **
+
+
+* **Fixed SellAll Hand not removing item:** SellAll Hand didn't work properly and got now fixed.
+
+
+* **Initial setup of Prison's mine bombs.**
+Initially it will be controllable as a utils command, so random chances can be assigned to explosions.
+
+
+* **Cleaned up some of the unused variables in the Utils titles command.**
+There were plans for more commands, but they were eliminated. This will soon be rewritten to utilize XSeries's classes for these display items.
+
+
+* **Ran in to a situation where results was actually null. So this prevents a NPE.**
+
+
+* **Fixed issue with tool's durability being cutoff right before reaching the threshold.**
+Had to change a > to a >=.
+
+
+* **3.2.11-alpha.1 2021-08-31**
+- Release the first alpha.1
+
+
+* **Replace the block with air through a task to get it out of the auto features thread.**
+
+
+* **If the settings isPreventToolBreage is enabled, then don't allow the tool to break.**
+
+
+* **Update some messages to be clearer as to what they are.**
+Removed the MONITOR from auto features since they should not have the monitor setting enabled. The blockBreakEvent has the monitoring event.
+
+
+* **Trying to fix an error related to SpigotRankManager GUI:** I can't reproduce the issue but the NPE shouldn't
+give a stacktrace in the console anymore.
+
+
+* **If the primary block was null, which it never should be, then this prevents a failure in this section of code in the OnBlockBreakEventCore.**
+
+
+
+* **For the initial startup air count task, which is used to "reset" the block counts on a mine.**
+This does not change any blocks, but just finds out where the mine was when the server was last shut down. This is needed to ensure we have valid counts for the mines before the first time they are reset. The other way to update these values is to do a full mine reset which is more costly.
+There was an inconclusive error that just listed "null" as the error messags, without identifying the actual line number. This error catching was changed to now generate a stack trace so it can be properly fixed if it occurs in the future.
+
+
+* **Added a few more reporting entries on the block break handling.**
+Reporting how many blocks are being processed and if it passes the validation phase.
+
+
+* **Some fixes for teleporting and the removal of the teleport glass block.**
+
+
+* **Updates to the PrisonEnchant's API.**
+Minor adjustments to work with the new API from PrisonEnchants.
+
+
+* **Updates to async block updates.**
+Included changes to hook up the CustomItems to work with the async updates.
+
+
+* **Clarify some of the messages related to listing of the block events.**
+
+
+* **Added the ability to identify if a block is able to be affected by gravity. Also the mine has a global setting to identify quickly if any block is gravity affected.**
+This will be used to alter the mine reset strategy to improve performance so as to hopefully eliminate long resets due to extensive lag from falling blocks. The idea is to get all the other blocks in to place before placing the falling blocks to ensure they are less likely to fall.
+
+
+* **If the Mine's saved file data is corrupted (manually edited with incorrect data), this will prevent the mine from being loaded and will now generate an error message indicating which mine has a problem loading. It will print out the invalid data, and it will default to a value of 0.00001. The function has been updated to "properly" use the localized format, so if it saves in a non US way, then it should now be able to read it back in and parse it correctly.
+
+
+* **If the Mine's saved file data is corrupted (manually edited with incorrect data),**
+this will prevent the mine from being loaded and will now generate an error message indicating which mine has a problem loading. It will print out the invalid data, and it will default to a value of 0.00001.
+
+
+* **Checking to ensure the locations are not null when loading.**
+There was a failure with bad data on the files system that was resulting in trying to resolve nulls to a location, which obviously cannot happen.
+
+
+* **There was an odd situation where the player was null, when usually they never can be, so this helps prevent possible errors.**
+The null was caused by an issue with a placeholder? Don't really remember.
+
+
+* **Adjustments to Prison's TPS calculations.**
+They were only taking the average of just two readings which was resulting in very unstable TPS values. Now 10 are being used.
+Enabled a new feature where the resolution can be changed from normal (a reading every tick) to high resolution (one reading every 2 ticks). When the resolution changes, the task will auto terminate and resubmit with the new settings.
+
+
+* **For the command /ranks autoConfigure made some adjustments to the block lists being used so the top mines have more valuable ores and blocks. There was a shortage and the wrong blocks were being used.
+
+
+* **Fixed an auto features config setting for prison's ExplosiveBockBreakvents priority; it was missing the word priority.**
+Reworked some of the details on autofeatures as displayed through /prison version to update them to better reflect the correct settings and dependencies.
+
+
+* **Fixed a problem with placeholders when using the search feature, but not supplying a player's name.**
+
+
+* **some internal changes to improve the resets**
+
+
+* **eliminate the block access in this class since it handles everything in the submitted task.**
+This was causing an error when it was being ran in an async thread. When the task is submitted, it is ran synchoronously so it works correctly.
+
+
+* **Changed prison's TPS calculation to be able to enable a high-res setting when the `/mines stats` is enabled.**
+The one problem with enabling high resolution mode is that it could show an unrealistic low TPS during a reset. The /lag command shows a much higher TPS value.
+
+
+* **Setup up the basics for async updates.**
+In the code that does the update, it also now reads the block to ensure that the read and update is all done in the synch thread. Otherwise the old code would be risking chunk loading in an async thread.
+Using the Location and World to perform the async updates outside of needing access to the spigot module.
+At this time, only `/mines set tracer` is using the new async reset.
+
+
+* **Tweaks to the event listener dumps for block breaks.**
+Updated the notes about prison's listeners.
+PEExplosionEvent was setup with the wrong forClass name.
+
+
+* **Setting up a new way to handle block updates in prison. Adding functions that are intended to be use while running in an async threads.**
+
+
+* **Transitioning over to the correct way to get the compatibility object.**
+Just a few classes are using the old way, but they will be switched over when they are done with the edits.
+
+
+* **Fixed the way some of the language files were being generated**
+so it can include the spigot module, which makes it self-contained for actual Modules, since it's always based upon the module name.
+Core and spigot are not technically modules, so they have special setups.
+Changed the Module folder from dataFolder to moduleDataFolder so it would not conflict with the SpigotPrison object.
+
+
+* **Fixed a problem with Prison's ExplosiveBlockBreakHandler**
+ in that it has a typo in the getHandlerList() and was not included with the registration processes. It also needed to be included with the generation of the listener dumps.
+
+
+* **Added /sellall hand command.**
+
+
+* **Minor changes to SellAll Util.**
+
+
+* **Much better performance for SellAll generally.**
+
+
+* **SellAll Commands internal changes.**
+
+
+* **Minor changes to GUIs:** Some fixes and visual changes.
+
+
+* **SellAllUtil Rewrite:** New internals for SellAll and SellAll API.
+
+
diff --git a/docs/prison_changelogs.md b/docs/prison_changelogs.md
index 90e81a861..73aa35c18 100644
--- a/docs/prison_changelogs.md
+++ b/docs/prison_changelogs.md
@@ -3,20 +3,31 @@
## Prison Build Logs for v3.3.x
## Build logs
+
+These build logs represent the work that has been going on within prison.
+
- **[v3.3.0-alpha - Current](changelog_v3.3.x.md)**
+ - Future updates will be under the v3.3.x release
+
+
+ - [v3.2.11 - 2022-01-22](prison_changelog_v3.2.11.md)
+ - [v3.2.10 - 2021-08-23](prison_changelog_v3.2.10.md)
+ - [v3.2.9 - 2021-07-03](prison_changelog_v3.2.9.md)
+ - [v3.2.8 - 2021-06-17](prison_changelog_v3.2.8.md)
+
+
+ - [v3.2.7 - 2021-05-02](prison_changelog_v3.2.7.md)
+ - [v3.2.6 - 2021-04-11](prison_changelog_v3.2.6.md)
+ - [v3.2.5 - 2021-04-01](prison_changelog_v3.2.5.md)
+ - [v3.2.4 - 2021-03-01](prison_changelog_v3.2.4.md)
+
+
+ - [v3.2.3 - 2020-12-25](prison_changelog_v3.2.3.md)
+ - [v3.2.2 - 2020-11-21](prison_changelog_v3.2.2.md)
+ - [v3.2.1 - 2020-09-27](prison_changelog_v3.2.1.md)
- [v3.2.0 - 2019-12-03](prison_changelog_v3.2.0.md)
-[v3.2.1 - 2020-09-27](prison_changelog_v3.2.1.md)
-[v3.2.2 - 2020-11-21](prison_changelog_v3.2.2.md)
-[v3.2.3 - 2020-12-25](prison_changelog_v3.2.3.md)
-[v3.2.4 - 2021-03-01](prison_changelog_v3.2.4.md)
-[v3.2.5 - 2021-04-01](prison_changelog_v3.2.5.md)
-[v3.2.6 - 2021-04-11](prison_changelog_v3.2.6.md)
-[v3.2.7 - 2021-05-02](prison_changelog_v3.2.7.md)
-[v3.2.8 - 2021-06-17](prison_changelog_v3.2.8.md)
-[v3.2.9 - 2021-07-03](prison_changelog_v3.2.9.md)
-[v3.2.10 - 2021-08-23](prison_changelog_v3.2.10.md)
+
-These build logs represent the work that has been going on within prison.
diff --git a/docs/prison_docs_000_toc.md b/docs/prison_docs_000_toc.md
index 7f2aac8bc..1e48226ee 100644
--- a/docs/prison_docs_000_toc.md
+++ b/docs/prison_docs_000_toc.md
@@ -17,7 +17,8 @@
## Build logs
- **[v3.3.0-alpha - Current](changelog_v3.3.x.md)**
- - [v3.2.0 through v3.2.10](prison_changelogs.md)
+
+ - [v3.2.0 through v3.2.11](prison_changelogs.md)
@@ -25,25 +26,70 @@
-# Prison Now Fully Supports Spigot 1.17.1 and Java 16 !!
+# Prison Supports Spigot 1.8 through Spigot 1.18.x
+# Prison Supports Java 1.8 though Java 17
+# Prison is created for the Spigot Platform, and works on other platforms based upon Spigot
-## Prison now has Access By Rank to Reduce the number of Permissions needed!
-
+With the release of Spigot 1.17.x, there were a few minor changes that were needed to be made to prison to support Java 16. These were mostly related to a couple of NMS routines that were trying to figure out the player's default language they have selected. Due to new restrictions moving forward with Spigot, the ability to correctly identify the player's default language may not be possible, but prison will still use the selected language setting in the config files.
+
+
+Prison supports both Spigot 1.17.1 and Spigot 1.18.x, along with Java 17. At this time there hasn't been any reports of incompatibilities. Since prison is using a library to support the correct blocks for the version of the server that you are running, we are limited to when updates are released for that library. Luckily they have had a couple of releases and we have applied them to the latest alpha releases. So if you are wanting to maximize the new Spigot 1.18.x experience, please upgrade to the latest alpha release as found on our discord server in the #alpha channel.
+
+
+### Newer features and updates in Prison:
+
+
+* Auto Configure: Even if you really don't want to use auto configure when setting up your server, it may be worth trying it out just to see what it does. If you're not happy with it, then deleting the `plugins/Prison/` directory will remove "everything" and on the next restart of your server, prison will load for the first time. So if you are just getting started with prison, it's worth a try.
+
+
+* Prison now has Access By Rank to reduce the number of Permissions needed! This simplifies a lot of settings and on a simple Prison server, can get you up and running much faster.
+
+* Backpacks: It is advised not to use Prison's backpacks at this time. They will be going through a rewrite and may result in content losses when upgrading when the newer version is available. It is suggested you give MinePacks at try.
+
+* Prison Mine Bombs! Prison is starting to add mine bombs to the list of available features. This is a work in progress and more enhancements and features will be added in the future. The idea with these, is that you can configure almost every aspect of the mine bombs, and you can have as many different varieties as you want.
+
+* Prison Tokens! Prison is starting to implement the earning of tokens within the mines as the players mine. This is a work in progress. Currently the hooks are added to earn tokens, and for admins to manage them. But more features need to be added to help enable using them.
+
+* Prison Stats! More stats are being tracked for each player. This is a work in progress. Prison is tracking blocks mined and even per mine. Prison is tracking time spent mining in each mine, along with how much a player is earning per mine with both regular currency, and with tokens. Top-n reports will be available shortly. Rankup requirements will soon include the ability to specify blocks mined, time spent mining, and even tokens. This will help you customize how you want your players to ranup.
+
+
+### Features planned for the near future
+
+These new features are in the planning stages...
+
+* New backpacks: A rewrite of the backpacks that will give a little more flexibility. You will be ble to use them as backpacks, or as vaults. Could even sell, or trade backpacks/vaults with their contents. ETA is unknown since a new storage management system needs to be created.
+
+* Mine Effects: The ability to set mine effects for a given mine, or to allow players to buy effects using their earned tokens. Effects could be simple potion effects (haste, night vision), or even effects such as no fall damage, and even flight. Other options could be no-pvp, enable pvp, no block break, no fire, etc... The options are numerous, but will be added a little at a time, and upon request.
-
+ * Mine Regions: Mine regions may be added to prison soon. They would be "area" that will control the Mine Effects and a region would/should enclose a given mine. But mine regions could be used on their own, were no mine is involved, such as at spawn to enble flight and no fall damage for your higher ranking players, or even allow players to "buy" regions to put around their bases so they can enable nigh vision and flight.
+
+* Custom Menus: Simple custom menus could be added so admins can setup simple commands and features. For example, custom token shop for enchantments or other in game items, or run any commands in general. This will start off simple, but will expand upon requests.
+
+* Unlimited Prestiges: This has been a long standing requested feature. It's close to being added. Although the levels may be unlimited, special configurations could be added for different levels, such as adding ladder commands at specific levels (ladder commands allows you to peform any action upon rankup, even from other plugins).
+
+* Custom Shops: Custom shops will allow for an unlimited number of new shops to be created. These shops can be tied to perms or player Ranks, or even specific mines. Each shop could be either stand alone, or it could be based upon another shop with price modifies and new items to prevent the need to redefine all entries for each shop. A mine shop would only be able to sell items that are retrived from mining in that mine.
+
+* Cells: They have been requested many times in the past. At this time, we cannot add them yet, but we would like to sometime in the distant future.
+
+* Enchantments: In the past we have stated that Prison will never support enchantments for pickaxes, or other tools, or weapons and amour. But as Prison is evolving and more features such as mine bombs and mine effects are added, along with natively supporting tokens within prison, the idea of adding enchantments is almost a no-brainer since most of the complicated details will already be supported through other features. So in the distant future, some time after mine bombs and mine effects have matured, we may add our own Enchantments.
+
+
+
+
# New! Prison Fast Start
+See the Auto Configure documentation for more information:
[Prison Auto Configure / Prison Quick Start!](prison_docs_100_setting_up_auto_configure.md)
Prison now has a new set of features that can help you get up and running faster than ever! With the latest version of Prison, you can even have a functional Prison server running with just two Prison commands. See below for more information.
-**It is strongly recommended that the '/ranks autoConfigure' should always be ran first.** Prison's Auto Configure sets up so many features, that it can help resolve many initial issues.
+**It is strongly recommended that the '/ranks autoConfigure' should always be ran first.** Prison's Auto Configure sets up so many features, that it can help resolve many initial issues. It's worth trying the first time you run prison since it's easy to undo: just delete the `plugins/Prison' directory and the next time you restart your server Prison will startup as if it was just installed with no settings.
-Before you try to setup Prison, you really need to install an Economy or the Ranks module will not be enabled. It is strongly suggested you install the following plugins: Vault, EssentialsX, EssentialsX-Chat, PlaceholderAPI, LuckPerms, WorldEdit, WorldGuard (or Fast Async World Edit, FAWE, on newer versions of Spigot).
+Before you try to setup Prison, you really need to install an Economy or the Ranks module will not be enabled. It is strongly suggested you install the following plugins: Vault, EssentialsX, EssentialsX-Chat, PlaceholderAPI, LuckPerms, WorldEdit (or Fast Async World Edit, FAWE, on newer versions of Spigot), WorldGuard.
`/ranks autoConfigure`. It can auto create your ranks and virtual mines, A through Z, it will link the mines to the ranks, setup the Mine Access By Rank and TP Access By Rank. It will also setup the Mine as a Virtual Mine will and assign blocks of increasing values to all mines. Each mine will also be assigned a random liner. The Ranks autoConfigure will also enable sellall and load over 90 default blocks for your shop. Auto features will be enabled (auto pickup, auto smelt, and auto blocking).
@@ -205,7 +251,9 @@ Auto configure can get you up and running with as little as two commands. The f
* [Setting up LuckPerms](prison_docs_020_setting_up_luckperms.md)
- Setting up LuckPerms. Warning about LuckPerms Versions.
+ Setting up LuckPerms.
+* [Setting up LuckPerms Groups & Tracks](prison_docs_030_LuckPerms_Groups_Tracks.md)
+ Using LuckPerms's groups and tracks with Prison.
* [Setting up PermissionsEX](prison_docs_022_setting_up_PermissionsEX.md)
diff --git a/docs/prison_docs_010_setting_up_a_spigot_server.md b/docs/prison_docs_010_setting_up_a_spigot_server.md
index 12b635bf6..814fbc645 100644
--- a/docs/prison_docs_010_setting_up_a_spigot_server.md
+++ b/docs/prison_docs_010_setting_up_a_spigot_server.md
@@ -13,6 +13,7 @@ Buildtools also allows easy setup of many test environments since all you
would need to do is to just change the version.
+*Documented updated: 2021-12-03*
@@ -22,8 +23,9 @@ This is intended strictly as a high-level overview on how to setup Java.
If you need more assistance, please search for online documentation since
there are many good resources out there.
-* First install a copy of Java that is accessible from the command line.
- - It’s strongly suggested to use only the latest version 1.8.0_x since that is the version spigot and most other plugins are developed under.
+* First install a copy of Java that is accessible from the command line.
+ - The current version of Java is version 17. Even if you are using jars and other plugins that were compiled with Java 1.8.x, it is recommended to use Java 17.
+ - If you feel like you must use Java 1.8, it’s strongly suggested to use only the latest version 1.8.0_x.
* You can download it from [Sun SE Development Kit 8]https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html) for product that you need.
@@ -48,18 +50,25 @@ there are many good resources out there.
```
java -jar BuildTools.jar --rev 1.8.8
+ java -jar BuildTools.jar --rev 1.9.4
+ java -jar BuildTools.jar --rev 1.10.2
+ java -jar BuildTools.jar --rev 1.11
java -jar BuildTools.jar --rev 1.12.2
java -jar BuildTools.jar --rev 1.13.2
java -jar BuildTools.jar --rev 1.14.4
- java -jar BuildTools.jar --rev 1.15.1
+ java -jar BuildTools.jar --rev 1.15.2
+ java -jar BuildTools.jar --rev 1.16.5
+ java -jar BuildTools.jar --rev 1.17.1
+ java -jar BuildTools.jar --rev 1.18
```
-* For example, with BuildTools.jar being in a root directory, create a subdirectory and then start a build within that directory. The benefit is that you can use the same BuildTools.jar to build multiple different versions of spigot. This example starts off with building a v1.14.4 instance and then builds a 1.8.8 instance.
+* For example, with BuildTools.jar being in a root directory, create a subdirectory and then start a build within that directory. The benefit is that you can use the same BuildTools.jar to build multiple different versions of spigot. This example starts off with building a v1.17.1 instance and then builds a 1.8.8 instance. Normally you wouldn't build multiple versions of spigot, but this shows how easy and flexible it is to build any version of spigot that has been released.
```
- mkdir spigot-1.14.4
- cd spigot-1.14.4
- java -jar ../BuildTools.jar –rev 1.14.4
+ mkdir spigot-1.17.1
+ cd spigot-1.17.1
+ java -jar ../BuildTools.jar –rev 1.17.1
+
cd ..
mkdir spigot-1.8.8
cd spigot-1.8.8
@@ -78,33 +87,35 @@ there are many good resources out there.
# Creating a Runnable Spigot Server
-* Create a runnable server directory by creating a new directory outside of the build directory. Then copy the newly generated jar file, such as spigot-1.14.4.jar, to the new server run time directory.
+* Create a runnable server directory by creating a new directory outside of the build directory. Then copy the newly generated jar file, such as spigot-1.17.1.jar, to the new server run time directory.
+
+* NOTE: At the time when this document was updated, Spigot 1.18 was just released. Because 1.18 requires Java 17, it is advisable to use that version of Java. Prison, because it is still being ran on older servers and under older environments, it must try to support the widest array of Spigot versions; therefore it is built with the latest version of Java 1.8.x, and built using Spigot 1.13.2. The environments in which Prison is built, should not impact how you build and run your server, of which it could easily be with Java 17 and Spigot 18.
* Windows example, if you’re still in the build directory:
```
cd ../..
- mkdir spigot-1.14.4_server
- copy /B builds\spigot-1.14.4\spigot-1.14.4.jar spigot-1.14.4_server
+ mkdir spigot-1.17.1_server
+ copy /B builds\spigot-1.17.1\spigot-1.17.1.jar spigot-1.17.1_server
```
* Linux example, if you’re still in the build directory:
```
cd ../..
- mkdir spigot-1.14.4_server
- cp builds/spigot-1.14.4/spigot-1.14.4.jar spigot-1.14.4_server
+ mkdir spigot-1.17.1_server
+ cp builds/spigot-1.17.1/spigot-1.17.1.jar spigot-1.17.1_server
```
-* Run the server for the first time (see the next step). It will start to auto-generate the server environment and then will stop. You will need to manually modify eula.txt and set eula=true. Save. Close. Restart the server. It will startup successfully now.
+* Run the server for the first time (see the next step). It will start to auto-generate the server environment and then will stop. You will need to manually modify the `eula.txt` file and set `eula=true`. Save. Close. Restart the server. It will startup successfully now.
* This is a simple example of what is needed for a windows cmd file. It sets the minimum memory to 2 GB and the max to 8 GB. A linux script would be similar, but without the pause.
```
- java -Xms2g -Xmx8g -jar spigot-1.14.4.jar
+ java -Xms2g -Xmx8g -jar spigot-1.17.1.jar
pause
```
diff --git a/docs/prison_docs_012_setting_up_prison_basics.md b/docs/prison_docs_012_setting_up_prison_basics.md
index 35b801f3b..1dcf09962 100644
--- a/docs/prison_docs_012_setting_up_prison_basics.md
+++ b/docs/prison_docs_012_setting_up_prison_basics.md
@@ -6,6 +6,9 @@
This document provides a quick overview on how to install Prison and get it running.
+
+*Documented updated: 2021-12-03*
+
@@ -40,7 +43,7 @@ Setting up Prison is simple:
* Prison's startup information contains a lot of information. If you ever have issues, check that information first since it probably will identify what the issues are.
-* It is strongly suggested that `/ranks autoConfigure` is ran to initially setup your Prison environment.
+* It is strongly suggested that `/ranks autoConfigure` is ran to initially setup your Prison environment. A great deal of configurations are setup that can save a lot of effort. Even if you are wanting to start from scratch, it may be worth giving it a try to see how some of the more complex settings are configured. You can always start over by deleting the `plugins/Prison/` directory.
* Follow Prison's documentation on customization; at this point it's ready for use.
@@ -54,13 +57,15 @@ Setting up Prison is simple:
* **None - No hard dependencies** - There are no hard dependencies for Prison.
-There may be no hard dependencies that will prevent Prison from running, but there are some core plugins that will make it easier to use. This short list is just a suggestion, but alternatives do exist and may be outside of our ability to comment or assist in their usage.
+There may be no hard dependencies that will prevent Prison from running, but there are some core plugins that will make it easier to use, and are even required for activation of some features within Prison. This short list is just a suggestion, but alternatives do exist and may be outside of our ability to comment or assist in their usage.
* **Vault** - Optional, but STRONGLY Suggested - This is perhaps the most important plugin. This plugin provides a common way to access other plugins running on your server, but without having to write any code within Prison to support them. Vault provides the mapping of a plugin's unique APIs to a common Vault API. Vault helps support Economy, Permissions, and Placeholders. Because of Vault, Prison can work flawlessly with dozens of other plugins. Please refer to Vault's documentation for what it supports.
-* **EssentialsX** - **STRONGLY SUGGESTED**, but still Optional - Provides many of the basic commands and behaviors that you would expect from a Spigot server such as chat, warps, and even some moderation commands and commands that can be given to premium players. EssentialsX is not Essentials, since Essentials is an older abandoned project, and EssentialsX is a forked project that is still maintained. Unfortunately, internally it is identified as simply Essentials, but you can tell it's EssentialsX if the version is greater than 2.15.x. EssentialsX is released as a zip file and you must extract the jars that you are interested in. It should also be pointed out that all EssentialsX jars should come from the same zip file so they will be of the same version and the same release.
+* **EssentialsX** - **STRONGLY SUGGESTED**, but still Optional - Provides many of the basic commands and behaviors that you would expect from a Spigot server such as chat, warps, and even some moderation commands and commands that can be given to premium players. EssentialsX is not Essentials, since Essentials is an older abandoned project, and EssentialsX is a forked project that is still maintained. Unfortunately, internally it is identified as simply Essentials, but you can tell it's EssentialsX if the version is greater than 2.15.x.
+
+ EssentialsX is released as a zip file and you must extract the jars that you are interested in. It should also be pointed out that all EssentialsX jars should come from the same zip file so they will be of the same version and the same release. UPDATE: The last I checked EssentialsX may not be released in a single zip file anymore. It looks like you have to download the parts you are interested in using.
### Economy Plugins - Required
@@ -68,15 +73,36 @@ There may be no hard dependencies that will prevent Prison from running, but the
Prison requires an active economy in order to active the Ranks plugin. When Prison starts up, it performs many validations on the mines and ranks as they are being loaded. With Ranks, if Prison cannot find an active economy, then it will refuse to load the Ranks module due to possible server corruption (ie... what failed that there is no economy).
-* **EssentialsX Economy** - SUGGESTED - Optional - This is a simple economy plugin that just works well. If you don't have a specific need to use another economy plugin, then it may be best to use this one since it works so well.
+* **EssentialsX Economy** - SUGGESTED - Optional - This is a simple economy plugin that just works well. If you don't have a specific need to use another economy plugin, then it may be best to use this one since it works so well. The reason why we recommend this economy is because it always works. That said, we acknowledge the reason it works well, is because it is so simple, so if there are features in other economy plugins that you want to use on your sever, then please explore using them. But overall, if you just want an economy that is rock solid, then EssentialsX's Economy is a great choice.
+
+
+* **CMI Economy** - Optional - Formerly we could not recommend its use, but Prison now has a couple of advanced tools that is able to allow CMI to fully load before Prison needs to use CMI's functions. Therefore if you want to use many of CMI's features, you now can!
+
+ CMI "tries" to load last, thus it can ensure all of it's dependencies and hooks are in place before it starts up. That's understandable, and Prison also has similar requirements and expectations. Unfortunately, this also causes a conflict with Prison, since Prison must perform validation on startup, and if there is no economy, then Prison could fail to start.
+
+ To get CMIE to work correctly with prison, there are a couple of things that you must do.
+
+ 1) You must use the normal version of Vault and then use the CMI Vault Injector. We've never seen the CMI provided version of Vault work with prison, so therefore recommend not using it. Symptom is that prison reports a 0.00 amount for the online player when using `/ranks player `. The Vault inject has always worked well.
+ 2) The CMI Economy **has** to be fully loaded and active *before* prison loads the Ranks. Otherwise prison will refuse to load the ranks and prison will not work. You must make a configuration change within Prison's `plugins/Prison/config.yml` file. Near the bottom of that config, are a few settings that need to be enabled. The following is an example of what is needed, along with a configuration that will work in most situations.
+
+```
+delayedPrisonStartup:
+ enabled: true
+ cooldown-secs: 5
+ max-attempts: 6
+ inspect-vault: true
+ triggers:
+ vault: true
+ vault-economy-name: Economy_Essentials
+```
+ If enabled, and you are still having problems, please contact Blue on Prison's discord server. To get CMIE to work may be as simple as increasing the `cooldown-secs` or the `max-attempts` settings, but there could be another conflict going on. Blue can review your server's startup log to identify the problem and help you fix it.
+
-* **CMI Economy** - Not Suggested - CMI has a lot of really neat features, so it's totally understandable that you may want to use their economy too. But the reason why we do not suggest it's use is because it is difficult to get to work with prison for a few reasons. We will try to support your use of CMIE, but you will have to try to be proactive in trying to get it to work; if you just want "simple", then try EssentialsX Economy first.
-1) You must use the normal Vault and then use the CMI Vault Injector. We've never seen the CMI provided version of Vault work with prison. Symptom is that prison reports a 0.00 amount for the player when using `/ranks player `. The Vault inject has always worked well.
-2) The CMI Economy **has** to be fully loaded and active *before* prison loads the Ranks. Otherwise prison will refuse to load the ranks and prison will not work. It appears as if CMIE is purposefully delaying it's activation until all other plugins are finished loading; I'm sure there is a good reason for that, but it causes prison to fail. Setting up proper soft dependencies within Prison does not work. To address this serious issue, because we really want CMIE to work with Prison, there is a new setting that will actually delay prison's startup to give CMIE a chance to active. This new feature should not be used without a good reason since it alters Prison's startup processes, but it has shown to work very well. The configs are within the config.yml file, but talk to Blue *before* trying to enable it.
+### Chat Prefix Plugins - Optional
+These plugins are used to add rank tags to the player's chat messages that they send.
-### Chat Plugins - Optional
* **EssentialsX Chat** - Optional - Enhanced Chat experience. Provides customizations to the chat prefixes.
@@ -95,36 +121,55 @@ Permission plugins are not *strictly* required for Prison to work, but within a
Prison actually uses bukkit's permission interfaces. This makes it simple for Prison, but it also limits what prison can do. For example, one limitation is with permission groups; Prison is unable to resolve permission groups since that "concept" does not exist in bukkit, but is a concept that is implemented through plugins like PEX and LuckPerms.
-* **LuckPerms** - Required - LuckPerms is a great permission plugin that is actively supported and has many new features to make managing your server easier.
+* **LuckPerms** - Required - Strongly Suggested - LuckPerms is a great permission plugin that is actively supported and has many new features to make managing your server easier.
-* **LuckPerms v5.x.x** - Use the latest version of LuckPerms whenever you can. Keep in mind that releases to spigotmc.org is somewhat infrequent; giving them the "counts" for downloads is nice, but you may have to go to their main download page to get the most recent releases: [https://luckperms.net/download](https://luckperms.net/download). Please note that is normal for issues to surface once in a while, and there were a few that needs to be avoided: The releases v5.3.0 through about v5.3.3 had some issues that caused significant logging and failures.
+* **LuckPerms v5.x.x** - Use the latest version of LuckPerms whenever you can. Keep in mind that releases to spigotmc.org is somewhat infrequent; giving them the "counts" for downloads is nice, but you may have to go to their main download page to get the most recent releases: [https://luckperms.net/download](https://luckperms.net/download). Please note that it is normal for issues to surface once in a while, and there were a few that needs to be avoided: The releases v5.3.0 through about v5.3.3 had some issues that caused significant logging and failures.
* **LuckPerms v4.x.x** This older version of LuckPerms is still supported, but it is highly recommended to upgrade to the latest v5.x.x release. LuckPerms v4.x.x is required for prison v3.2.0 and older (Prison v3.2.1 and newer supports all versions of LuckPerms). Please consider upgrading both Prison and LuckPerms to the latest releases for the best experience.
-* **NOTE: A permissions plugin of your choice** - Required - Prison works with many different permission plugins through Vault. I strongly suggest LuckPerms since it is free and is under active development so bugs and performance issues will be addressed. If you choose to use another permission plugin, then please consider ones that work with Vault; Prison uses Vault provide the flexibility of choosing from many different plugins.
+* **Gems Economy** - Gems Economy supports multiple currencies. Support for Gems Economy was added a few years ago and worked well at the time. If you try to use this plugin and have issues, please contact Blue on Prison's discord server so the issues can be addressed.
+
+
+* **NOTE: A permissions plugin of your choice** - Required - Prison works with many different permission plugins through Vault. I strongly suggest LuckPerms since it is free and is under active development so bugs and performance issues will be addressed if they ever become an issue. If you choose to use another permission plugin, then please consider ones that work with Vault; Prison uses Vault to provide the flexibility of choosing from many different plugins.
* **Other Permission Plugins** There are many out there, and as developer of Prison, and through providing support, we don't hear of any issues with other permission plugins. The reason for this is because they probably just work well to begin with, and that Prison uses bukkit's permission interfaces. So it keeps things simple for setting up Prison. If you are just getting started with building a server, then we suggested keeping it simple with something like LuckPerms, but there are other permission plugins out there that can provide a whole new experience with your server, such as jobs and careers for your players.
+
### Placeholder Plugins
-Chat related plugins provides access to Prison placeholders, but these placeholder plugins takes it to the next level and allows other plugins to access prison data. There are not many out there, mostly because papi is so simple and does it so well so there is no real need for other plugins.
+Chat related plugins are able to provides access to Prison placeholders, which can allow Prison data to be included in their content. PAPI is simple and works so well, that it usually is the default choice.
+
+
+The way a placeholder works, is that it is a text based **key** that is used to request data. Generally the key is included with other text, such as a chat message, holographic display, or a scoreboard content, and the key is replaced with the requested data. Usually the plugins using placeholders have no idea what other plugins are supplying the requested data; they basically make a general request for information to all plugins, and the plugins that recognize that **key** will respond.
+
+
+It should be noted that Prison's placeholders are just text based keys. They are usually all lower case alpha numeric characters, with underscores, and maybe some colons too. The important thing to understand is that they do not include the escape characters, and that the escape characters may differ from what is required in other plugins. Placeholder escape characters are usually `{ }` or `% %`, and sometimes you may have to mix the two. The plugin's documentation should help you identify what's the correct usage.
+
+All prison placeholders start with `prison_` and are usually all lower case. Upper case may work too, but lower case is recommended. Prison tries to ignore the case of its placeholder keys, but its the other plugins that can have issues. For example, if Prison registers all of the plugins as lower case, then the other plugins may not recognize all upper case, or mixed case, as being related to Prison, so therefore they may not send the request to Prison.
-It should be noted that Prison's placeholders do not include the escape characters, and they may vary in the other plugins that you use placeholders. Sometimes they may be { } or % %, and sometimes you may have to mix the two. The plugin's documentation should help you identify what's the correct usage.
+An example of a prison placeholder is `prison_rank`. But used in another plugin, you will need to add escape characters such that it may be either `{prison_rank}` or `%prison_rank%`. Prison only controls what the text key is; prison cannot control which escape characters are used in another plugin.
-* **PlaceholderAPI** - Strongly Suggested - Also known as papi. Used through Vault, it is free and provides the core interfaces in to the usage of placeholders. Prison also has a special integration setup for PlaceholderAPI to register all of the Prison placeholders dynamically upon startup. You do not need to download anything from the cloud for prison to work with this plugin. Also if you reload papi, you do not have to reload Prison's placeholders. Prison registers placeholders that are all lower case and more recently, all upper case too so it's easier to use placholders through papi.
+
+All of Prison's placeholders have an alias. An alias is a shortened name for a placeholder. Some placeholder names can become large based upon trying to keep their names informative as to what they represent. As an example, `prison_rank` has an alias of `prison_r`. And `prison_player_balance_earnings_per_minute_formatted` has an alias of `prison_pb_epmf` which can be useful if there is limited space in the configurations. The command `/prison placeholders list` shows all available placeholders, along with their aliases.
+
+
+* **PlaceholderAPI** - Strongly Suggested - Also known as **papi**. Used through Vault, it is free and provides the core interfaces in to the usage of placeholders. Prison also has a special integration setup for PlaceholderAPI to register all of the Prison placeholders dynamically upon startup. You do not need to download anything from the cloud for prison to work with this plugin. Also if you reload papi, you do not have to reload Prison's placeholders. Prison registers placeholders that are all lower case and more recently, all upper case too so it's easier to use placeholders through papi.
+
+ NOTE: You may also need to install the follow plugin for full support: ProtocolLib.
* **MVdWPlaceholder** - Suggested to Avoid - Prison does support this plugin, but since it is used mostly with premium plugins, we have no way to fully test this plugin to ensure it actually works correctly. We've heard very few people have used this plugin, but we've heard it does work well. Use at your own risk.
-With this plugin, all placeholders are registered with it automatically when prison starts up, and all placeholders should be used as all lower case. Because prison has so many plugins, with many that are expanded based upon ladders, ranks, and mine names, a modest prison server could generate and register well over 1000 placeholders. MVdWPlaceholder appears to be very verbose so you will see a lot of logging.
-It should also be noted that because of some of the limitations of MVdW, not all features of Prison's placeholder support will be supported. For example, you may not be able to reload placeholders, or use placeholder attributes to customize how placeholders are used.
+With this plugin, all placeholders are registered with it automatically when prison starts up, and all placeholders should be used as all lower case. Because prison has so many placeholders, with many that are expanded based upon ladders, ranks, and mine names, a modest prison server could generate and register well over 1000 placeholders. MVdWPlaceholder appears to be very verbose so you will see a lot of logging in the console when it starts up.
+
+ It should also be noted that because of some of the limitations of MVdW, not all features of Prison's placeholder support will be supported. For example, you may not be able to reload placeholders, or use placeholder attributes to customize how placeholders are used.
@@ -216,7 +261,7 @@ Some of the important details that are listed:
* Which modules were successfully loaded
* The root commands that are available
* The integration status of all related plugins that are supported
-* The list of active placeholders
+* The list of active placeholders (removed due to size. see `/prison placeholders list`)
* Startup error messages, if any. Examples would be if a rank is configured to use a
custom currency and that currency cannot be found in any economy.
@@ -230,7 +275,7 @@ custom currency and that currency cannot be found in any economy.
If you are leasing a server from a hosting service you may not be able to customize the startup script. But if you have control over it, then the following information may help.
-`java -Xdebug -Xms2g -Xmx4g -jar spigot-1.16.5.jar -nogui`
+`java -Xms2g -Xmx4g -jar spigot-1.16.5.jar -nogui`
Example of enabling debug hooks for the server. This is used with Eclipse, and may work with other IDEs since it's a java directive.
@@ -274,6 +319,35 @@ through:
```
+# Prison Support Submit Information
+
+Prison now has a built in way to share your configurations and settings with support personnel.
+
+More information will be documented in the future, but for now, here are the basics on how to use it.
+
+When requested by the Prison support team, you would first enter the following command to set your name that will be included on all reports to help identify who the are related to. It doesn't have to be your full discord name, but enough characters to allow us to identify who you are.
+
+
+These commands will collect all of the related information from your Prison setup, and send it to the website `https://paste.helpch.at`. It will provide you with an URL. All you need to do is to copy and paste that URL in to the discord chat so the Prison support team can help with your issue.
+
+
+`/prison support setSupportName `
+
+Once entered, it will enable the following submit tools:
+
+`/prison support submit` - Show the available tools.
+
+```
+/prison support submit configs
+/prison support submit latestLogs
+/prison support submit mines
+/prison support submit ranks
+/prison support submit version
+```
+
+Here is an example that I generated from one of my test servers on 2021-12-03. I have no idea how long the content remains available, but for support purposes, we only need this information for a few hours.
+ [https://paste.helpch.at/itejovejeh](https://paste.helpch.at/itejovejeh)
+
# Prison Commands
diff --git a/docs/prison_docs_013_Prison_Help.md b/docs/prison_docs_013_Prison_Help.md
index 4bddd8f26..f6d6bd04e 100644
--- a/docs/prison_docs_013_Prison_Help.md
+++ b/docs/prison_docs_013_Prison_Help.md
@@ -6,6 +6,9 @@
This document provides some important information on how to find help in setting up your prison server, and ultimately, how and where to ask for help.
+
+*Documented updated: 2021-12-03*
+
# Overview
@@ -20,19 +23,50 @@ If you are having problem, please take a quick look at the following documents a
+
+# Asking for Help
+
+Before you actually ask for help, take a look at some of the documents presented here. You may find your answer, or at least become a little more familiar with Prison. There is a good chance that if your question is a common one, then you will just be referred to this documentation anyway.
+
+When you do ask for help, please realize if you can provide a clear description of the problems you are experiencing, plus the versions of Prison, Spigot, etc, then we can help you faster and more accurately. To help provide you with answers to these questions, see the next section of this document for information on what you can copy and paste to provide all those much needed details.
+
+
+
+
+
+
+
+# Prison Command 'help' keyword
+
+
+Prison has a very advanced command handler that provides a lot of advance features. But one simple feature to know about and to use is the use of the 'help' keyword.
+
+
+If you add '**help**' to any command within prison, prison's command handler will show you information on what the command is, how to use it, parameters, how to get more help and details, and also what permissions are needed to use the command.
+
+
+Prison automatically inserts the **help** keyword if you enter the base commands. So the command **/mines** is really the command handler recognizing there are many commands tied to the path '/mines' that it automatically injects the **help** keyword for you so it will generate the list. It's exactly the same as if you've entered **/mines help**.
+
+
# General Information on Prison Commands
+
All of the commands for Prison can be ran in-game, and most can be ran from the console. When running commands from the console, you do not have to prefix the commands with a **/**. But within these documents, all commands will be referenced with a prefixed **/** so it is clear that it's a command. Just don't include it when running within the console.
-Personal preference is to run the commands from the console since there are less restrictions on width or number of lines shown, and they are easier to see without the busy background of the game.
-Within most of these documents, the console will be used to screen print from for those reasons.
+My (Blue) personal preference is to run the commands from the console since there are less restrictions on width or number of lines shown, and they are easier to see without the busy background of the game.
+
+
+Within most of these documents, the console will be used for screen prints for those reasons.
+
The only commands that cannot be ran from the console are the commands that expect you to be an in-game player. Examples are **/mines whereami** and **/mines tp **. But note, you can now run the TP command from the console if you supply the name of an online player: **/mines tp **.
+
If you need to do some maintenance, or configurating of your Prison, the console could be an easier environment to use.
-But in-game, some commands have clickable actions. Such as page next or page prior. Or even command completion, such as with **/mines block search** and clicking on a search result provides you with a filled in copy of **/mines block add** where all you need to do is just fill in the percentage since it uses the last mine name that has been used.
+
+But in-game, some commands have clickable actions such as **page next** or **page prior**. Or even command completion, such as with **/mines block search** and clicking on a search result provides you with a filled in copy of **/mines block add** where all you need to do is just fill in the percentage since it uses the last mine name that has been used.
@@ -43,14 +77,16 @@ But in-game, some commands have clickable actions. Such as page next or page pr
It may be helpful to know what commands are available, and what options exist for those commands.
+Prison's command handler not only understands what commands have been registered within Prison, but it has awareness of what parameters are needed, and what permissions some commands are required. The command handler is able to provide a lot of information if you know a few basic things.
-**Note: the details below still apply, but are slightly out of date.** The best way to start exploring all commands within prison is to start with `/prison` which will list all subcommands related to `/prison`, but also will show all other root commands and aliases.
+Prison's commands are based upon a hierarchy of commands, which groups them by context. If you enter a lower command in the hierarchy that includes sub commands, then Prison will list them. This is a great way to explore what commands are available within Prison.
-Upon startup, prison lists many details about the environment, and one set of those details, are the base commands that are available within Prison. See the area pertaining to the modules, since the commands generally are tied to modules.
+The best starting point is with the root command `/prison`. Not only is that the root command for everything that starts with `/prison`, but it has special behavior in that it also includes all other command roots. So if a command exists in prison, you can find it through starting with `/prison` and exploring their children.
-
+
+Some of the root commands that are important to know: `/prison`, `/mines`, `/ranks`, `/rankup`, `/gui`, `/sellall`.
Many commands within prison are compound commands, such that they start with a base command, followed by one or more other commands. When Prison lists the available commands, if there are sub commands, that information is included in the command listing, including the sub command count. For example:
@@ -73,8 +109,6 @@ Let's take a closer look at **/mines set notification** and how the **help** key
But notice within the above screen print, the same command has been entered, but this time with the keyword **help** added as if it were the first parameter. For example, **/mines set notification help**. Prison recognizes that you are requesting help for that command, and then it displays all of the information it has for each parameter.
-Prison automatically inserts the **help** keyword if you enter the base commands. So **/mines** is really injecting the **help** keyword for you so it will generate the list. It's like you've entered **/mines help**.
-
@@ -95,40 +129,42 @@ You can also submit a help ticket on the Prison github Issues tab, but the respo
-# Asking for Help
-
-Before you actually ask for help, take a look at some of the documents presented here. You may find your answer, or at least become a little more familiar with Prison. There is a good chance that if your question is a common one, then you will just be referred to this documentation anyway.
-
-When you do ask for help, please realize if you can provide a clear description of the problems you are experiencing, plus the versions of Prison, Spigot, etc, then we can help you faster and more accurately. To help provide you with answers to these questions, see the next section of this document for information on what you can copy and paste to provide all those much needed details.
-
-
-
-
-
-
# Prison Debugger
Prison has been evolving to provide many new features, but as a result, it's also becoming very complex in some areas. To help address these greater complexities, Prison has some debugging details that can be dynamically enabled. These can help identify what's happening and provide hints as to what may be the trouble.
-New targets will be added to Prison overtime. So check with the command for the latests updates for the version that you are using.
+New targets will be added to Prison overtime. So check with the command for the latest updates for the version that you are using.
To enable the debugger, you can toggle them all on with `/prison debug` once to turn it on, and again to turn them all off.
+
To review the options available, use the command `/prison debug help`. There are also debug targets that only enable specific debug statements and the list of the available targets can be displayed with `/prison debug targets`.
+
```
>prison debug help
-[21:07:00 INFO]: For internal use only. Do not use unless instructed.
-[21:07:00 INFO]: /prison debug [targets]
-[21:07:00 INFO]: [targets] Enable or disable a debugging target. 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.
-[21:07:00 INFO]: Permissions:
-[21:07:00 INFO]: prison.debug
+[12:16:39 INFO]: ---------- < Cmd: /prison debug > ------------- (3.2.11-alpha.9)
+[12:16:39 INFO]: Enables debugging and trouble shooting information. For internal use only. Do not use unless instructed.
+[12:16:39 INFO]: /prison debug [targets]
+[12:16:39 INFO]: [targets] Optional. Enable or disable a debugging target. [on, off, targets, jarScan, testPlayerUtil, testLocale, rankup] Use 'targets' to list all available targets. Use 'on' or 'off' to toggle on and off individual targets, or all targets if no target is specified. jarScan will identify what Java version compiled the class files within the listed jars
+[12:16:39 INFO]: Permissions:
+[12:16:39 INFO]: prison.debug
+
+
>prison debug targets
-[21:08:21 INFO]: Global Debug Logging is enabled
-[21:08:21 INFO]: . Valid Targets: all, on, off, blockBreak, blockBreakFortune, durability
+[12:17:19 INFO]: Global Debug Logging is enabled
+[12:17:19 INFO]: . Valid Targets: all, on, off, blockBreak, blockBreakFortune, rankup, support
+
+>prison debug
+[12:18:18 INFO]: Global Debug Logging is enabled
+[12:18:18 INFO]: . Valid Targets: all, on, off, blockBreak, blockBreakFortune, rankup, support
+
+>prison debug
+[12:18:20 INFO]: Global Debug Logging is disabled
+[12:18:20 INFO]: . Valid Targets: all, on, off, blockBreak, blockBreakFortune, rankup, support
```
It should be noted that every time you use the command, other than with the help keyword, it will always show the current status of the debugging information. It will show if the global logging is enabled or not, and if any targets are enabled, it will list all of the active ones. Plus it will show all of the available targets too.
@@ -359,4 +395,9 @@ Once you are running Prison v3.x.x then you can safely upgrade to Prison v3.2.0,
+**Obsolete Screen Prints:**
+
+
+
+
diff --git a/docs/prison_docs_020_setting_up_luckperms.md b/docs/prison_docs_020_setting_up_luckperms.md
index e00ce9331..f00d9628f 100644
--- a/docs/prison_docs_020_setting_up_luckperms.md
+++ b/docs/prison_docs_020_setting_up_luckperms.md
@@ -6,14 +6,20 @@
This document provides a quick overview on how to install LuckPerms.
+*Documented updated: 2021-12-19*
+
-# Dependencies
+# Dependencies & Other Information
* **Vault** - **Required** - Provides the permission integration with Prison
+
+* [Setting up LuckPerms Groups & Tracks](prison_docs_030_LuckPerms_Groups_Tracks.md)
+ Using LuckPerms's groups and tracks with Prison.
+
@@ -25,14 +31,23 @@ Setting up LuckPerms is simple:
* Download LuckPerms
- Go to the SpigotMC.org LuckPerm's resource page:
- [LuckPerms Downloads](https://www.spigotmc.org/resources/luckperms-an-advanced-permissions-plugin.28140/history "LuckPerms download can be found under the Version History tab")
+ - A benefit of downloading from spigotmc.org is that downloads are tracked and LuckPerms will get a higher rating
- Click on the Version History tab
- Choose the version to download
+
+* LuckPerms Website
+ - You can also directly download LuckPerms from their own website
+ - [LuckPerms Website](https://luckperms.net/)
+ - Updates are released on their own website more frequently than to spigotmc.org
+ - If you are having issues, check this website for most recent release
+
+
* Copy to your server's plugin directory
* Restart the server
-* Follow LuckPerm's documentation on customization, but at this point it's ready for use with the Prison plugin.
+* Follow LuckPerm's documentation on customization, but at this point it's ready for use with the Prison plugin.
@@ -40,14 +55,17 @@ Setting up LuckPerms is simple:
-# Warning about LuckPerms Versions
+# Older Versions of LuckPerms and Prison
+
+Older versions of Prison only worked with older versions of LuckPerms. Prison v3.2.0 and older required luckperms v4.4.1 and older.
+
+Newer versions of Prison supports both the older version of LuckPerms, and all current releases. It is strongly suggested that you use the latest version of both Prison and LuckPerms.
-Due to how LuckPerms registers with the Spigot Plugin Manager, it will cause plugins to fail if they were designed for the older LuckPerms version. Therefore, plugins can only be used with the version of LuckPerms that they were designed for and it's up to the server owner to be able to figure that out on their own.
**Prison plugin v3.2.0** *only* works with LuckPerms v4.4.1 and older. Luckperms v4.4.1 is the suggested version and can be downloaded here:
-[LuckPerms v4.4.1](https://www.spigotmc.org/resources/luckperms-an-advanced-permissions-plugin.28140/history "LuckPerms v4.4.1 can be found under the Version History tab")
+[LuckPerms v4.4.1](https://www.spigotmc.org/resources/luckperms.28140/history "LuckPerms v4.4.1 can be found under the Version History tab")
-**Prison plugin v3.2.1** and newer works with *any* version of LuckPerms. It is suggested that LuckPerms v5.0.x is used, but you may also use LuckPerms v4.4.1.
+**Prison plugin v3.2.1** and newer works with *any* version of LuckPerms. It is suggested that LuckPerms v5.x.x is used, but you may also use LuckPerms v4.4.1.
diff --git a/docs/prison_docs_030_LuckPerms_Groups_Tracks.md b/docs/prison_docs_030_LuckPerms_Groups_Tracks.md
new file mode 100644
index 000000000..57f445b3e
--- /dev/null
+++ b/docs/prison_docs_030_LuckPerms_Groups_Tracks.md
@@ -0,0 +1,218 @@
+
+### Prison Documentation
+[Prison Documents - Table of Contents](prison_docs_000_toc.md)
+
+## Setting up LuckPerms' Groups and Tracks
+
+This document provides an overview to help setup LuckPerms groups and tracks.
+
+
+*Documented updated: 2021-12-19*
+
+
+
+
+
+# Setting Up LuckPerms
+
+
+Setup LuckPerms as needed. Information on where to download it can be found here:
+
+[Setting Up LuckPerms](prison_docs_020_setting_up_luckperms.md)
+
+
+Other plugin...
+
+
+
+
+# LuckPerms Groups
+
+To help simplify the management of permissions for players, LuckPerms uses permission Groups to form a collection of permissions. This helps to simplify assigning permission to players since one group can contain many permissions. For example, if there are 20 permissions in a group, then you would only have to issue one group command instead of 20 permission commands.
+
+
+# LuckPerms Tracks
+
+A brief overview of Tracks: Tracks are to LuckPerms, as ranks and ladders are to Prison. They provide an easy way to manage player's perms by associating them with these ranks. Tracks are also linked together, just like Prison ladders. A player is then moved along these Tracks to provide a way to change their permissions to match the evolving access and roles.
+
+
+To advance a player within LuckPerms Tracks, you just promote the player to the next higher Track. This is very similar to how Prison ranks and ladders are used.
+
+
+Since Prison needs to use their own ranks, and is not directly tied to LuckPerms Tracks, Prison Ranks can help manage a player's LuckPerms Track.
+
+
+
+
+# Using Prison Rank Commands with Groups and Tracks
+
+Since LuckPerm Groups and Tracks must be synchronized with Prison Ranks, the Prison Rank Commands are used to provide this linkage through Prison Rank Commands. This allows the player to control when they rankup within Prison, which then synchronizes the LuckPerms' Track.
+
+
+If you are not using LuckPerms Tracks, the following is the command you would use to setup the prison rank command.
+
+
+```
+/ranks command add B lp user {player} parent set [group]
+```
+
+
+As a quick review, to get more help about the prison rank commands. The `help` key word displays detailed help about the selected Prison command. And the `placeholders` keyword is important for prison commands since it lists all of the available placeholders that can be used to provide prison related data and values to be used within the commands.
+
+```
+/ranks command add help
+/ranks command add placeholders
+```
+
+
+The following is how you would setup a Prison rank command to use tracks.
+
+```
+/ranks command add B lp user {player} parent settrack [track] [group]
+```
+
+Setting up these rank commands, will cause Prison to run these commands when the player ranks up.
+
+
+So in review, this are two examples of rankup commands for a player who joins the server for the first time, are demoted back to A, or the prestiged and are reset to rank A. The Prison rank is named `A` and so is the LuckPerms group. The first command is for setups with no tracks, and the second is for tracks; insert the track's name for `[track]`. If you name your track `PrisonRanks`, with the Track's Groups named the same as the Prison Ranks.
+
+
+```
+/ranks command add B lp user {player} parent set A
+
+/ranks command add B lp user {player} parent settrack PrisonRanks A
+```
+
+
+
+
+
+# More Examples of Usage
+
+
+If you change a player's rank from E to A, the Prison rank commands for A will run, and set the player to group A, or default.
+
+When you prestige, your rank goes from Z to A, so rank's A commands will be ran.
+Plus the rank on your first Prestige rank (typically P1) will **ALSO** be ran. This is highly useful since if you want certain prestige levels to have their own certain benefits/perms, you can setup a separate track and groups for Prestige ranks.
+
+For example, where `P1` is the Prestige 1 rank:
+
+```
+/ranks command add P1 lp user {player} parent settrack [track] P1
+```
+
+
+
+
+
+
+
+# The Suggested Way to Setup LuckPerms Groups and Tracks
+
+Although there are many ways to configure any plugin, these suggestions tries to keep things simple through using the same names as the counter parts between Prison and LuckPerms. It may be slightly confusion which is which, as far as Prison or LuckPerms, but it makes it easier by being consistent with the same names for the similar parts.
+
+
+The best way to setup LuckPerms Groups is to make 1 group for every Prison Rank. Then use the Rank Commands to assign users to that group automatically when they rankup. Then to tie things together within LuckPerms, place these created LuckPerms Groups on a LuckPerms Track.
+
+
+If you have not done so already, the best option to get started with Prison, is to run `/ranks autoConfigure`. That provides so much of the basic configurations and can save you hours just trying to get the basics setup. You can always change the default settings later to fine tune your setup.
+
+
+The command `/ranks autoConfigure` will create Ranks and Mines with names from A through Z. It will also create the first 10 Prestige ranks with the names P01 through P10.
+
+
+So to get started with how you would setup a Prison Rank command for Rank B:
+`/ranks command add B lp user {player} parent settrack [track] b`
+
+
+When they become rank B, the command `/lp user {player} parent settrack [track] b` will be ran as console/admin. The Prison placeholder `{player}` is the player's name, and `[track]` is the name you're calling your track.
+
+
+To setup all the LuckPerms groups, you can use `/lp editor` to make it easier. And setup the ranks from A through Z.
+
+
+
+Next you should setup the LuckPerms Tracks, which will take a little more effort up front. You don't have to use Tracks, but it will simplify some things later on by simplifying the synchronization between Prison Ranks and the LuckPerms Groups.
+
+
+For our examples, we will name our track **PrisonRank**.
+
+```
+/luckperms createtrack [track]
+
+/luckperms createtrack PrisonRanks
+
+```
+
+
+Now we need to add all of our created groups to this track. It's important to add them **IN ORDER**. Yes, the order is critical. Remember our Prison Ranks are named A through Z, and so are our LuckPerms Groups, so we have to add them all.
+
+
+```
+/luckperms track [track] append
+
+/luckperms track PrisonRank append A
+/luckperms track PrisonRank append B
+/luckperms track PrisonRank append C
+/luckperms track PrisonRank append D
+
+...
+
+/luckperms track PrisonRank append Z
+
+```
+
+
+The next step that you need to do, is to setup all the perms for each of your groups. The perms that you need, are based upon the plugins that you have setup on your server, and the perms that they will require.
+
+
+For brevity, we will only show you the commands to use manually. You can use the command `/lp editor` too. Remember that the **group** listed in this command are the LuckPerms groups that you created earlier, that are named A trough Z. The **permission**s that you use in these commands should be entered exactly as they are needed.
+
+```
+/lp group permission set
+
+```
+
+It may take a while to setup all the permissions, and you will have to revisit these as you're adding more plugins.
+
+
+Next, we need to setup Prison's Rank Commands to allow the rankup process to keep the LuckPerms Track's Groups in synchronization. Luckily, this is pretty simple and is accomplished with just one Rank Command per rank. Please not that for Prison's Rank names they are not case sensitive, but the LuckPerms track names may be, so they are listed here in upper case.
+
+
+These are based upon the two individual commands; the Prison Ranks Command and the LP command. The **command** reference in the Prison Rank Command is the whole LP command, as you will see following the templates.
+
+```
+/ranks command add
+/lp user {player} parent settrack [track]
+
+/ranks command add a lp user {player} parent settrack PrisonRank A
+/ranks command add b lp user {player} parent settrack PrisonRank B
+/ranks command add c lp user {player} parent settrack PrisonRank C
+/ranks command add d lp user {player} parent settrack PrisonRank D
+
+...
+
+/ranks command add z lp user {player} parent settrack PrisonRank Z
+```
+
+
+The following is optional, but what it does is to apply all rank commands to all players at their current ranks. So this will apply everything we just entered above to anyone who is already setup in Prison.
+
+`/ranks set rank *all* *same* default`
+
+
+And that should be it.
+
+
+
+
+
+
+
+
+# Setting up LuckPerms Chat Prefixes
+
+*coming soon...*
+
+
+
\ No newline at end of file
diff --git a/docs/prison_docs_100_setting_up_auto_configure.md b/docs/prison_docs_100_setting_up_auto_configure.md
index af084e7db..e267ba0ed 100644
--- a/docs/prison_docs_100_setting_up_auto_configure.md
+++ b/docs/prison_docs_100_setting_up_auto_configure.md
@@ -7,6 +7,11 @@
This document provides information on how to get started quickly using Prison's `/ranks autoConfigure`.
+[Prison Log File Examples - Starting Prison & auto configure](prison_docs_101_auto_configure_log_examples.md)
+
+
+*Documented updated: 2021-12-11*
+
# Overview
@@ -77,33 +82,30 @@ Some of the steps involved and which are covered by this document:
* **Turning Virtual Mines in to Actual Mines** - How to set the mine's locations so they become real.
-* **Setting a Mine's Spawn Location**
-* **Resizing A Mine**
+Other topics that may be helpful but not fully covered in this document:
+* **Setting a Mine's Spawn Location**
-* **Moving A Mine**
+* **Resizing A Mine**
+* **Moving A Mine**
* **Changing A Mine's Liner**
-
* **Submitting a New Liner Request**
-
* **Working with Mines within a Void World** - Special considerations for resizing, moving, and liners when in a Void World.
-
* **Working with Mine's Permissions**
-
* **Using Mine Reset Commands**
-
* **Working with Rank Commands**
+
@@ -119,9 +121,9 @@ These listings are to help guide you in planning on what you need. A minecraft
* **Minecraft Server Version**
- - Prison support a native minecraft server version of v1.8 through v1.16.5.
- - Prison is developed and compiled with the Spigot v1.13.2 build. This ensures that Prison is able to natively support all functional behaviors from v1.8 through v1.16.5 since v.1.13 is the only version of Spigot that has both the old internal functions and new internal functions coexisting at the same time.
- - Prison will try to support v1.17 when it is released, but not sure what special requirements it will place upon the development environment.
+ - Prison support a native minecraft server version of v1.8 through v1.18.x.
+ - Prison is developed and compiled with the Spigot v1.13.2 build. This ensures that Prison is able to natively support all functional behaviors from v1.8 through v1.18.x since v.1.13 is the only version of Spigot that has both the old internal functions and new internal functions coexisting at the same time.
+ - Prison supports the early releases of v1.18. There has been no issues found. Prison will try to support all of the new blocks within 1.18, we use a library called XSeries to provide the new blocks. So as they release their updates, prison will pickup support for more blocks.
* **Memory Requirements**
@@ -206,7 +208,7 @@ The current version of Prison's `/ranks autoConfigure` uses Access by Ranks to a
The use of Access by Ranks prevents the need for `/ranks autoConfigure` to generate any rank commands dealing with permissions. You may need to add them for your own needs.
-**Critical:** It should be noted that the ideal conditions to running this command is without having any mines or ranks previously defined. If any are detected, this command will terminate and will not attempt to perform any actions. You can use the Option **force** to force the auto configure to run if there are ranks and mines already defined. If you do force it, keep in mind that it will skip over any rank or mine that it would otherwise try to generate. It will not add rank commands to existing ranks. It will not add blocks to existing mines. It will not hook up ranks to mines. Nor will it configure such features as Mine Access Permissions. If you decide to use **force** you do so at your own risks. That said, it's easy to delete the `plugins/Prison/` directory and start over (or just rename it).
+**Critical:** It should be noted that the ideal conditions to running this command is without having any mines or ranks previously defined. If any are detected, this command will terminate and will not attempt to perform any actions. You can use the Option **force** to force the auto configure to run if there are ranks and mines already defined. If you do force it, keep in mind that it will skip over any rank or mine that it would otherwise try to generate. It will not add blocks to existing mines. It will not hook up ranks to mines. Nor will it configure such features as Mine Access Permissions. If you decide to use **force** you do so at your own risks. That said, it's easy to delete the `plugins/Prison/` directory and start over (or just rename it).
Almost every command within prison has detailed help, and it can be activated by adding the `help` keyword to the end of the command. For example:
@@ -239,339 +241,37 @@ The server that was created to run this example was using 9 core plugins:
-
Note: The following is from an older release of prison that generated rank commands that controlled the way prison worked.
+The generated log files can now be found in this document:
-Sample of prison starting up for the first time and it's console messages:
+[Prison Log File Examples - Starting Prison & auto configure](prison_docs_101_auto_configure_log_examples.md)
-```
-[03:02:59 INFO]: [Prison] Enabling Prison v3.2.5-alpha.14
-[03:02:59 INFO]: [Prison] Using version adapter tech.mcprison.prison.spigot.compat.Spigot18
-[03:02:59 INFO]: | Prison |
-[03:02:59 INFO]: | Prison | _____ _
-[03:02:59 INFO]: | Prison | | __ \ (_)
-[03:02:59 INFO]: | Prison | | |__) | __ _ ___ ___ _ __
-[03:02:59 INFO]: | Prison | | ___/ '__| / __|/ _ \| '_ \
-[03:02:59 INFO]: | Prison | | | | | | \__ \ (_) | | | |
-[03:02:59 INFO]: | Prison | |_| |_| |_|___/\___/|_| |_|
-[03:02:59 INFO]: | Prison |
-[03:02:59 INFO]: | Prison | Loading Prison version: 3.2.5-alpha.14
-[03:02:59 INFO]: | Prison | Running on platform: SpigotPlatform
-[03:02:59 INFO]: | Prison | Minecraft version: git-Spigot-21fe707-e1ebe52 (MC: 1.8.8)
-[03:02:59 INFO]: | Prison |
-[03:02:59 INFO]: | Prison | Enabling and starting...
-[03:02:59 INFO]: | Prison | Enabled Prison v3.2.5-alpha.14 in 223 milliseconds.
-[03:02:59 INFO]: | Prison | There were 19 new values added to the GuiConfig.yml file located at C:\mc_servers\spigot-1.8.8-autoConfig_server\plugins\Prison\GuiConfig.yml
-[03:02:59 INFO]: | Prison | There were 37 new values added for the language files used by the SellAllConfig.yml file located at C:\mc_servers\spigot-1.8.8-autoConfig_server\plugins\Prison\SellAllConfig.yml
-[03:02:59 INFO]: | Prison | There were 37 new values added for the language files used by the SellAllConfig.yml file located at C:\mc_servers\spigot-1.8.8-autoConfig_server\plugins\Prison\SellAllConfig.yml
-[03:02:59 INFO]: | Prison | There were 272 new values added for the language files used by the GuiConfig.yml file located at C:\mc_servers\spigot-1.8.8-autoConfig_server\plugins\Prison\module_conf\lang\en_US.yml
-[03:02:59 INFO]: | Prison | Notice: AutoManager config file was just updated with 89 new entries. May need to be configured. File: autoFeaturesConfig.yml
-[03:02:59 INFO]: | Prison | Notice: AutoManager config file was just created. You must configure it to use it. File: autoFeaturesConfig.yml
-[03:02:59 INFO]: | Prison | ###--### AutoFeaturesFileConfig: test autoPickupBlockNameList: length = 2 value = [coal_block, iron_ore]
-[03:02:59 INFO]: | Prison | ### VaultEconomyWrapper : vaultVersion = 1.5.6-b49 is pre1_4= false
-[03:02:59 INFO]: | Prison | EssentialsEconomy is not directly enabled - Available as backup.
-[03:02:59 INFO]: [PlaceholderAPI] Successfully registered expansion: prison
-[03:02:59 INFO]: | Prison | Mines Module enablement starting...
-[03:02:59 INFO]: | Prison | Mines Module enabled successfully in 152 milliseconds.
-[03:02:59 INFO]: | Prison | Ranks Module enablement starting...
-[03:03:00 INFO]: | Prison | Loaded 0 ranks.
-[03:03:00 INFO]: | Prison | Loaded 2 ladders.
-[03:03:00 INFO]: | Prison | Loaded 0 players.
-[03:03:00 INFO]: | Prison | Ranks by ladders:
-[03:03:00 INFO]: | Prison | default:
-[03:03:00 INFO]: | Prison | prestiges:
-[03:03:00 INFO]: | Prison | none:
-[03:03:00 INFO]: | Prison | Ranks Module enabled successfully in 580 milliseconds.
-[03:03:00 INFO]: | Prison | Utils Module enablement starting...
-[03:03:00 INFO]: | Prison | Utils Module enabled successfully in 7 milliseconds.
-[03:03:00 INFO]: | Prison | Loaded 0 mines and submitted with a 5000 millisecond offset timing for auto resets.
-[03:03:00 INFO]: [PlaceholderAPI] Successfully registered expansion: prison
-[03:03:00 INFO]: | Prison | Total placeholders generated: 122
-[03:03:00 INFO]: | Prison | PLAYER: 26
-[03:03:00 INFO]: | Prison | LADDERS: 48
-[03:03:00 INFO]: | Prison | PLAYERMINES: 48
-[03:03:00 INFO]: | Prison | ALIAS: 61
-[03:03:00 INFO]: | Prison | Total placeholders available to be Registered: 122
-[03:03:00 INFO]: | Prison | A total of 0 Mines and Ranks have been linked together.
-[03:03:00 INFO]: | Prison | ------------- < /prison version > ---------------
-[03:03:00 INFO]: | Prison | Prison Version: 3.2.5-alpha.14
-[03:03:00 INFO]: | Prison | Running on Platform: tech.mcprison.prison.spigot.SpigotPlatform
-[03:03:00 INFO]: | Prison | Minecraft Version: git-Spigot-21fe707-e1ebe52 (MC: 1.8.8)
-[03:03:00 INFO]: | Prison |
-[03:03:00 INFO]: | Prison | Commands: /prison
-[03:03:00 INFO]: | Prison | Module: Mines : Enabled
-[03:03:00 INFO]: | Prison | . Base Commands: /mines
-[03:03:00 INFO]: | Prison | Module: Ranks : Enabled
-[03:03:00 INFO]: | Prison | . Base Commands: /ranks /rankup /rankupMax /prestige /prestiges
-[03:03:00 INFO]: | Prison | Module: Utils : Enabled
-[03:03:00 INFO]: | Prison | . Base Commands: /prison utils
-[03:03:00 INFO]: | Prison |
-[03:03:00 INFO]: | Prison | Integrations:
-[03:03:00 INFO]: | Prison | Permissions: LuckPerms (Vault)
-[03:03:00 INFO]: | Prison | Economy: Essentials Economy (Vault)
-[03:03:00 INFO]: | Prison | Integration Type: ECONOMY
-[03:03:00 INFO]: | Prison | Essentials Economy (Vault) [URL]
-[03:03:00 INFO]: | Prison | Essentials (EssentialsX) (disabled) [URL]
-[03:03:00 INFO]: | Prison | SaneEconomy (API v0.15.0) [URL]
-[03:03:00 INFO]: | Prison | GemsEconomy [URL]
-[03:03:00 INFO]: | Prison | Integration Type: PERMISSION
-[03:03:00 INFO]: | Prison | LuckPerms (Vault)
-[03:03:00 INFO]: | Prison | LuckPerms (LuckPermsV5) [URL]
-[03:03:00 INFO]: | Prison | LuckPerms (LuckPerms-Legacy) [URL]
-[03:03:00 INFO]: | Prison | Integration Type: PLACEHOLDER
-[03:03:00 INFO]: | Prison | To list all or search for placeholders see: /prison placeholders
-[03:03:00 INFO]: | Prison | MVdWPlaceholderAPI [URL]
-[03:03:00 INFO]: | Prison | PlaceholderAPI [URL]
-[03:03:00 INFO]: | Prison | MVdWPlaceholderAPI [URL]
-[03:03:00 INFO]: | Prison | PlaceholderAPI [URL]
-[03:03:00 INFO]: | Prison | Registered Plugins:
-[03:03:00 INFO]: | Prison | LuckPerms (5.1.26), WorldEdit (6.1;no_git_id)
-[03:03:00 INFO]: | Prison | Vault (1.5.6-b49), PlaceholderAPI (2.10.9)
-[03:03:00 INFO]: | Prison | ProtocolLib (4.5.0), WorldGuard (6.1)
-[03:03:00 INFO]: | Prison | Essentials (2.18.1.0), EssentialsChat (2.18.1.0)
-[03:03:00 INFO]: | Prison | Prison (3.2.5-alpha.14)
-[03:03:00 INFO]: | Prison | Prison - Finished loading.
-```
-Running the command:
-```
->ranks autoConfigure help
-[04:19:55 INFO]: Auto configures Ranks and Mines using single letters A through Z for both the rank and mine names. If both ranks and mines are generated, they will also be linked together automatically. To set the starting price use price=x. To set multiplier mult=x. Cannot autoConfigure if any ranks or mines are defined, but 'force' will attempt it but at your risk. Default values [full price=50000 mult=1.5]
-[04:19:55 INFO]: /ranks autoConfigure [options]
-[04:19:55 INFO]: [options | full] Options: [full ranks mines price=x mult=x force]
-[04:19:55 INFO]: Permissions:
-[04:19:55 INFO]: ranks.set
->ranks autoConfigure
-[04:20:03 INFO]: | Info | Your new rank, 'A', was created in the ladder 'default', using the tag value of '[A]'
-[04:20:03 INFO]: Virtual mine created: use command /mines set area to enable as a normal mine.
-[04:20:04 INFO]: | Info | Your new rank, 'B', was created in the ladder 'default', using the tag value of '[B]'
-[04:20:04 INFO]: Virtual mine created: use command /mines set area to enable as a normal mine.
-[04:20:04 INFO]: | Info | Your new rank, 'C', was created in the ladder 'default', using the tag value of '[C]'
-[04:20:04 INFO]: Virtual mine created: use command /mines set area to enable as a normal mine.
-[04:20:04 INFO]: | Info | Your new rank, 'D', was created in the ladder 'default', using the tag value of '[D]'
-[04:20:04 INFO]: Virtual mine created: use command /mines set area to enable as a normal mine.
-[04:20:04 INFO]: | Info | Your new rank, 'E', was created in the ladder 'default', using the tag value of '[E]'
-[04:20:04 INFO]: Virtual mine created: use command /mines set area to enable as a normal mine.
-[04:20:04 INFO]: | Info | Your new rank, 'F', was created in the ladder 'default', using the tag value of '[F]'
-[04:20:04 INFO]: Virtual mine created: use command /mines set area to enable as a normal mine.
-[04:20:04 INFO]: | Info | Your new rank, 'G', was created in the ladder 'default', using the tag value of '[G]'
-[04:20:04 INFO]: Virtual mine created: use command /mines set area to enable as a normal mine.
-[04:20:04 INFO]: | Info | Your new rank, 'H', was created in the ladder 'default', using the tag value of '[H]'
-[04:20:04 INFO]: Virtual mine created: use command /mines set area to enable as a normal mine.
-[04:20:04 INFO]: | Info | Your new rank, 'I', was created in the ladder 'default', using the tag value of '[I]'
-[04:20:04 INFO]: Virtual mine created: use command /mines set area to enable as a normal mine.
-[04:20:04 INFO]: | Info | Your new rank, 'J', was created in the ladder 'default', using the tag value of '[J]'
-[04:20:05 INFO]: Virtual mine created: use command /mines set area to enable as a normal mine.
-[04:20:05 INFO]: | Info | Your new rank, 'K', was created in the ladder 'default', using the tag value of '[K]'
-[04:20:05 INFO]: Virtual mine created: use command /mines set area to enable as a normal mine.
-[04:20:05 INFO]: | Info | Your new rank, 'L', was created in the ladder 'default', using the tag value of '[L]'
-[04:20:05 INFO]: Virtual mine created: use command /mines set area to enable as a normal mine.
-[04:20:05 INFO]: | Info | Your new rank, 'M', was created in the ladder 'default', using the tag value of '[M]'
-[04:20:05 INFO]: Virtual mine created: use command /mines set area to enable as a normal mine.
-[04:20:05 INFO]: | Info | Your new rank, 'N', was created in the ladder 'default', using the tag value of '[N]'
-[04:20:05 INFO]: Virtual mine created: use command /mines set area to enable as a normal mine.
-[04:20:05 INFO]: | Info | Your new rank, 'O', was created in the ladder 'default', using the tag value of '[O]'
-[04:20:05 INFO]: Virtual mine created: use command /mines set area to enable as a normal mine.
-[04:20:05 INFO]: | Info | Your new rank, 'P', was created in the ladder 'default', using the tag value of '[P]'
-[04:20:05 INFO]: Virtual mine created: use command /mines set area to enable as a normal mine.
-[04:20:05 INFO]: | Info | Your new rank, 'Q', was created in the ladder 'default', using the tag value of '[Q]'
-[04:20:05 INFO]: Virtual mine created: use command /mines set area to enable as a normal mine.
-[04:20:05 INFO]: | Info | Your new rank, 'R', was created in the ladder 'default', using the tag value of '[R]'
-[04:20:05 INFO]: Virtual mine created: use command /mines set area to enable as a normal mine.
-[04:20:05 INFO]: | Info | Your new rank, 'S', was created in the ladder 'default', using the tag value of '[S]'
-[04:20:05 INFO]: Virtual mine created: use command /mines set area to enable as a normal mine.
-[04:20:05 INFO]: | Info | Your new rank, 'T', was created in the ladder 'default', using the tag value of '[T]'
-[04:20:05 INFO]: Virtual mine created: use command /mines set area to enable as a normal mine.
-[04:20:05 INFO]: | Info | Your new rank, 'U', was created in the ladder 'default', using the tag value of '[U]'
-[04:20:05 INFO]: Virtual mine created: use command /mines set area to enable as a normal mine.
-[04:20:05 INFO]: | Info | Your new rank, 'V', was created in the ladder 'default', using the tag value of '[V]'
-[04:20:05 INFO]: Virtual mine created: use command /mines set area to enable as a normal mine.
-[04:20:05 INFO]: | Info | Your new rank, 'W', was created in the ladder 'default', using the tag value of '[W]'
-[04:20:05 INFO]: Virtual mine created: use command /mines set area to enable as a normal mine.
-[04:20:05 INFO]: | Info | Your new rank, 'X', was created in the ladder 'default', using the tag value of '[X]'
-[04:20:05 INFO]: Virtual mine created: use command /mines set area to enable as a normal mine.
-[04:20:05 INFO]: | Info | Your new rank, 'Y', was created in the ladder 'default', using the tag value of '[Y]'
-[04:20:05 INFO]: Virtual mine created: use command /mines set area to enable as a normal mine.
-[04:20:05 INFO]: | Info | Your new rank, 'Z', was created in the ladder 'default', using the tag value of '[Z]'
-[04:20:05 INFO]: Virtual mine created: use command /mines set area to enable as a normal mine.
-```
-Note: The following are the messages generated while building the **sellall** shop with the default items:
+Listing the generated ranks on all ladders using the `all` keyword:
+`/ranks list all`
-```
-[04:20:05 INFO]: Virtual mine created: use command /mines set area to enable as a normal mine.
-[04:20:05 INFO]: | Prison | ITEM [COBBLESTONE, 4.0] added with success!
-[04:20:05 INFO]: | Prison | ITEM [ANDESITE, 5.0] added with success!
-[04:20:05 INFO]: | Prison | ITEM [DIORITE, 6.0] added with success!
-[04:20:05 INFO]: | Prison | ITEM [COAL_ORE, 13.0] added with success!
-[04:20:05 INFO]: | Prison | ITEM [GRANITE, 8.0] added with success!
-[04:20:05 INFO]: | Prison | ITEM [STONE, 9.0] added with success!
-[04:20:05 INFO]: | Prison | ITEM [IRON_ORE, 18.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [POLISHED_ANDESITE, 7.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [GOLD_ORE, 45.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [MOSSY_COBBLESTONE, 29.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [COAL_BLOCK, 135.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [IRON_BLOCK, 190.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [LAPIS_ORE, 100.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [REDSTONE_ORE, 45.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [DIAMOND_ORE, 200.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [EMERALD_ORE, 250.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [GOLD_BLOCK, 450.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [LAPIS_BLOCK, 950.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [REDSTONE_BLOCK, 405.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [DIAMOND_BLOCK, 2000.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [EMERALD_BLOCK, 2250.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [OBSIDIAN, 450.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [CLAY, 12.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [GRAVEL, 3.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [SAND, 6.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [DIRT, 4.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [COARSE_DIRT, 7.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [PODZOL, 6.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [RED_SAND, 9.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [BEDROCK, 500.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [SANDSTONE, 3.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [POLISHED_DIORITE, 8.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [POLISHED_GRANITE, 9.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [CHISELED_NETHER_BRICKS, 39.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [CHISELED_RED_SANDSTONE, 11.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [CHISELED_STONE_BRICKS, 11.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [CUT_RED_SANDSTONE, 13.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [CUT_SANDSTONE, 10.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [NETHER_QUARTZ_ORE, 34.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [QUARTZ, 34.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [QUARTZ_BLOCK, 136.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [QUARTZ_SLAB, 68.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [CHISELED_QUARTZ_BLOCK, 136.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [QUARTZ_BRICKS, 136.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [QUARTZ_PILLAR, 136.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [SMOOTH_QUARTZ, 136.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [SMOOTH_RED_SANDSTONE, 14.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [SMOOTH_SANDSTONE, 14.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [SMOOTH_STONE, 14.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [CHARCOAL, 16.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [CRACKED_NETHER_BRICKS, 16.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [CRACKED_STONE_BRICKS, 14.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [EMERALD, 14.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [END_STONE, 14.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [END_STONE_BRICKS, 14.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [FLINT, 9.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [LAPIS_LAZULI, 14.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [MOSSY_STONE_BRICKS, 14.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [PRISMARINE_SHARD, 13.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [PRISMARINE, 52.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [PRISMARINE_BRICKS, 52.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [PRISMARINE_BRICK_SLAB, 52.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [PRISMARINE_CRYSTALS, 37.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [DARK_PRISMARINE, 52.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [DARK_PRISMARINE_SLAB, 52.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [PURPUR_BLOCK, 14.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [PURPUR_PILLAR, 14.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [TERRACOTTA, 10.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [ACACIA_LOG, 7.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [BIRCH_LOG, 7.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [DARK_OAK_LOG, 7.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [JUNGLE_LOG, 7.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [OAK_LOG, 7.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [SPRUCE_LOG, 7.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [ACACIA_PLANKS, 28.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [BIRCH_PLANKS, 28.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [DARK_OAK_PLANKS, 28.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [JUNGLE_PLANKS, 28.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [OAK_PLANKS, 28.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [SPRUCE_PLANKS, 28.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [ACACIA_WOOD, 7.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [BIRCH_WOOD, 7.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [DARK_OAK_WOOD, 7.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [JUNGLE_WOOD, 7.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [OAK_WOOD, 7.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [SPRUCE_WOOD, 7.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [IRON_NUGGET, 3.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [IRON_INGOT, 27.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [GOLD_NUGGET, 12.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [GOLD_INGOT, 108.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [REDSTONE, 45.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [GLOWSTONE, 52.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [GLOWSTONE_DUST, 14.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [COAL, 15.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [DIAMOND, 200.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [SUGAR_CANE, 13.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [SUGAR, 13.0] added with success!
-[04:20:06 INFO]: | Prison | ITEM [PAPER, 13.0] added with success!
-```
-
-The following are log entries from the generation and assignment of the blocks to all of the generated mines.
-
-```
-[04:20:06 INFO]: | Prison | Mine A: [ANDESITE 5.0, COBBLESTONE 95.0]
-[04:20:06 INFO]: | Prison | Mine B: [DIORITE 5.0, ANDESITE 10.0, COBBLESTONE 85.0]
-[04:20:06 INFO]: | Prison | Mine C: [COAL_ORE 5.0, DIORITE 10.0, ANDESITE 20.0, COBBLESTONE 65.0]
-[04:20:06 INFO]: | Prison | Mine D: [GRANITE 5.0, COAL_ORE 10.0, DIORITE 20.0, ANDESITE 20.0, COBBLESTONE 45.0]
-[04:20:06 INFO]: | Prison | Mine E: [STONE 5.0, GRANITE 10.0, COAL_ORE 20.0, DIORITE 20.0, ANDESITE 20.0, COBBLESTONE 25.0]
-[04:20:06 INFO]: | Prison | Mine F: [IRON_ORE 5.0, STONE 10.0, GRANITE 20.0, COAL_ORE 20.0, DIORITE 20.0, ANDESITE 25.0]
-[04:20:06 INFO]: | Prison | Mine G: [POLISHED_ANDESITE 5.0, IRON_ORE 10.0, STONE 20.0, GRANITE 20.0, COAL_ORE 20.0, DIORITE 25.0]
-[04:20:06 INFO]: | Prison | Mine H: [GOLD_ORE 5.0, POLISHED_ANDESITE 10.0, IRON_ORE 20.0, STONE 20.0, GRANITE 20.0, COAL_ORE 25.0]
-[04:20:06 INFO]: | Prison | Mine I: [MOSSY_COBBLESTONE 5.0, GOLD_ORE 10.0, POLISHED_ANDESITE 20.0, IRON_ORE 20.0, STONE 20.0, GRANITE 25.0]
-[04:20:06 INFO]: | Prison | Mine J: [COAL_BLOCK 5.0, MOSSY_COBBLESTONE 10.0, GOLD_ORE 20.0, POLISHED_ANDESITE 20.0, IRON_ORE 20.0, STONE 25.0]
-[04:20:06 INFO]: | Prison | Mine K: [NETHER_QUARTZ_ORE 5.0, COAL_BLOCK 10.0, MOSSY_COBBLESTONE 20.0, GOLD_ORE 20.0, POLISHED_ANDESITE 20.0, IRON_ORE 25.0]
-[04:20:06 INFO]: | Prison | Mine L: [IRON_BLOCK 5.0, NETHER_QUARTZ_ORE 10.0, COAL_BLOCK 20.0, MOSSY_COBBLESTONE 20.0, GOLD_ORE 20.0, POLISHED_ANDESITE 25.0]
-[04:20:06 INFO]: | Prison | Mine M: [LAPIS_ORE 5.0, IRON_BLOCK 10.0, NETHER_QUARTZ_ORE 20.0, COAL_BLOCK 20.0, MOSSY_COBBLESTONE 20.0, GOLD_ORE 25.0]
-[04:20:06 INFO]: | Prison | Mine N: [REDSTONE_ORE 5.0, LAPIS_ORE 10.0, IRON_BLOCK 20.0, NETHER_QUARTZ_ORE 20.0, COAL_BLOCK 20.0, MOSSY_COBBLESTONE 25.0]
-[04:20:06 INFO]: | Prison | Mine O: [DIAMOND_ORE 5.0, REDSTONE_ORE 10.0, LAPIS_ORE 20.0, IRON_BLOCK 20.0, NETHER_QUARTZ_ORE 20.0, COAL_BLOCK 25.0]
-[04:20:06 INFO]: | Prison | Mine P: [QUARTZ_BLOCK 5.0, DIAMOND_ORE 10.0, REDSTONE_ORE 20.0, LAPIS_ORE 20.0, IRON_BLOCK 20.0, NETHER_QUARTZ_ORE 25.0]
-[04:20:06 INFO]: | Prison | Mine Q: [EMERALD_ORE 5.0, QUARTZ_BLOCK 10.0, DIAMOND_ORE 20.0, REDSTONE_ORE 20.0, LAPIS_ORE 20.0, IRON_BLOCK 25.0]
-[04:20:06 INFO]: | Prison | Mine R: [GOLD_BLOCK 5.0, EMERALD_ORE 10.0, QUARTZ_BLOCK 20.0, DIAMOND_ORE 20.0, REDSTONE_ORE 20.0, LAPIS_ORE 25.0]
-[04:20:06 INFO]: | Prison | Mine S: [LAPIS_BLOCK 5.0, GOLD_BLOCK 10.0, EMERALD_ORE 20.0, QUARTZ_BLOCK 20.0, DIAMOND_ORE 20.0, REDSTONE_ORE 25.0]
-[04:20:06 INFO]: | Prison | Mine T: [REDSTONE_BLOCK 5.0, LAPIS_BLOCK 10.0, GOLD_BLOCK 20.0, EMERALD_ORE 20.0, QUARTZ_BLOCK 20.0, DIAMOND_ORE 25.0]
-[04:20:06 INFO]: | Prison | Mine U: [DIAMOND_BLOCK 5.0, REDSTONE_BLOCK 10.0, LAPIS_BLOCK 20.0, GOLD_BLOCK 20.0, EMERALD_ORE 20.0, QUARTZ_BLOCK 25.0]
-[04:20:06 INFO]: | Prison | Mine V: [EMERALD_BLOCK 5.0, DIAMOND_BLOCK 10.0, REDSTONE_BLOCK 20.0, LAPIS_BLOCK 20.0, GOLD_BLOCK 20.0, EMERALD_ORE 25.0]
-[04:20:07 INFO]: | Prison | Mine W: [EMERALD_BLOCK 10.0, DIAMOND_BLOCK 20.0, REDSTONE_BLOCK 20.0, LAPIS_BLOCK 20.0, GOLD_BLOCK 30.0]
-[04:20:07 INFO]: | Prison | Mine X: [EMERALD_BLOCK 20.0, DIAMOND_BLOCK 20.0, REDSTONE_BLOCK 20.0, LAPIS_BLOCK 40.0]
-[04:20:07 INFO]: | Prison | Mine Y: [EMERALD_BLOCK 20.0, DIAMOND_BLOCK 20.0, REDSTONE_BLOCK 60.0]
-[04:20:07 INFO]: | Prison | Mine Z: [EMERALD_BLOCK 20.0, DIAMOND_BLOCK 80.0]
-[04:20:07 INFO]: | Prison | Ranks autoConfigure: 26 ranks were created.
-[04:20:07 INFO]: | Prison | Ranks autoConfigure: 26 rank commands were created.
-[04:20:07 INFO]: | Prison | Ranks autoConfigure: The permission mines. and mines.tp. was created for each rank. Make sure you add every permission to your permission plugin or they may not work.
-[04:20:07 INFO]: | Prison | Ranks autoConfigure: 26 mines were created.
-[04:20:07 INFO]: | Prison | Ranks autoConfigure: 26 ranks and mines were linked.
-[04:20:07 INFO]: | Prison |
-```
-
-
-
-Listing the generated ranks:
-
-`/ranks list`
-Listing the information on Rank A:
+Listing the information on Rank A, including the ladder and rank commands.:
-`/ranks info a`
+`/ranks info a all`
-`/ranks command list a`
-Note: This list of commands for Rank A is how all the other ranks will look, but Rank A actually contains all the removals of all ranks now. This will allow Prestige to use the command `/ranks set rank` on a player, and then let these commands remove the permissions they should not have while at rank A.
+Using the keyword `all` is the same as also running the command: `/ranks command list a`
+
-```
->ranks command list a
-[04:21:51 INFO]: ------- < RankUpCommand for [A] > ---------
-[04:21:51 INFO]: Click a command to remove it.
-[04:21:51 INFO]: * /lp user {player} permission set mines.a
-[04:21:51 INFO]: * /lp user {player} permission set mines.tp.a
-[04:21:51 INFO]: [+] Add
->
-```
@@ -679,6 +379,23 @@ The other method is a little more controlled, and that's using prison wand to se
+
+
+# A Quick Overview of the 'help' Keyword
+
+Prison has an advanced command handler that is able to do a lot of things. One of it's features is to provide more information on each command that it has registered. To activate this feature, just add the keyword `help` to the end of any command. Here are a few examples.
+
+```
+/mines info help
+/ranks promote help
+/ranks command add help
+/prison support submit
+/prison utils potionEffect help
+```
+
+The `help` keyword can be used on sub-command listings, which will display the list of commands at that level. The `help` keyword is applied automatically for sub-commands and is what actually triggers the command listings.
+
+
diff --git a/docs/prison_docs_101_auto_configure_log_example.md b/docs/prison_docs_101_auto_configure_log_example.md
new file mode 100644
index 000000000..cecc7c657
--- /dev/null
+++ b/docs/prison_docs_101_auto_configure_log_example.md
@@ -0,0 +1,348 @@
+
+### Prison Documentation
+[Prison Documents - Table of Contents](prison_docs_000_toc.md)
+
+## Prison - Examples of Prison's Log Entries
+
+This document provides information on what log entries are generated when prison starts up for the first time, and while running the command `/ranks autoConfigure`.
+
+NOTE: Prison has been designed to behave the same under any version of bukkit/Spigot from 1.8 through 1.18. Therefore the spigot version in these logs are not important, and apply to all versions. The same applies for Java versions 1.8.x through Java 17.
+
+*Documented updated: 2021-12-11*
+
+
+
+# Prison logs when starting for the first time
+
+When the prison jar file has been added for the first time to a server, you will see something similar to these startup logs.
+
+
+```
+[13:14:48 INFO]: [Prison] Enabling Prison v3.2.11-alpha.11
+[13:14:49 INFO]: | Prison | -------------------- < > ----------------------- (3.2.11-alpha.11)
+[13:14:49 INFO]: | Prison |
+[13:14:49 INFO]: | Prison | _____ _
+[13:14:49 INFO]: | Prison | | __ \ (_)
+[13:14:49 INFO]: | Prison | | |__) | __ _ ___ ___ _ __
+[13:14:49 INFO]: | Prison | | ___/ '__| / __|/ _ \| '_ \
+[13:14:49 INFO]: | Prison | | | | | | \__ \ (_) | | | |
+[13:14:49 INFO]: | Prison | |_| |_| |_|___/\___/|_| |_|
+[13:14:49 INFO]: | Prison |
+[13:14:49 INFO]: | Prison | Loading Prison version: 3.2.11-alpha.11
+[13:14:49 INFO]: | Prison | Running on platform: SpigotPlatform
+[13:14:49 INFO]: | Prison | Minecraft version: git-Spigot-21fe707-e1ebe52 (MC: 1.8.8)
+[13:14:49 INFO]: | Prison |
+[13:14:49 INFO]: | Prison | Server runtime: 0s
+[13:14:49 INFO]: | Prison | Java Version: 1.8.0_291 Processor cores: 8
+[13:14:49 INFO]: | Prison | Memory Max: 3.556 GB Total: 1.054 GB Free: 674.204 MB Used: 405.296 MB
+[13:14:49 INFO]: | Prison | Total Server Disk Space: 943.719 GB Usable: 689.799 GB Free: 689.799 GB Used: 253.919 GB
+[13:14:49 INFO]: | Prison | Prison's File Count: 10 Folder Count: 5 Disk Space: 60.154 KB Other Objects: 0
+[13:14:49 INFO]: | Prison | Prison TPS Average: 0.00 Min: 20.00 Max: 20.00 Interval: 10 ticks Samples: 0
+[13:14:49 INFO]: | Prison |
+[13:14:49 INFO]: | Prison | Enabling and starting...
+[13:14:49 INFO]: | Prison | Enabled Prison v3.2.11-alpha.11 in 376 milliseconds.
+[13:14:49 INFO]: | Prison | Using version adapter tech.mcprison.prison.spigot.compat.Spigot18
+[13:14:49 INFO]: | Prison | There were 21 new values added to the GuiConfig.yml file located at C:\mc_servers\spigot-1.8.8-basic_server\plugins\Prison\GuiConfig.yml
+[13:14:49 INFO]: | Prison | SpigotListener: Trying to register events
+[13:14:49 INFO]: | Prison | There were 41 new values added for the language files used by the SellAllConfig.yml file located at C:\mc_servers\spigot-1.8.8-basic_server\plugins\Prison\SellAllConfig.yml
+[13:14:49 INFO]: | Prison | There were 41 new values added for the language files used by the SellAllConfig.yml file located at C:\mc_servers\spigot-1.8.8-basic_server\plugins\Prison\SellAllConfig.yml
+[13:14:49 INFO]: | Prison | EssentialsEconomy is not directly enabled - Available as backup.
+[13:14:49 INFO]: [PlaceholderAPI] Successfully registered expansion: prison
+[13:14:49 INFO]: [PlaceholderAPI] Successfully registered expansion: PRISON
+[13:14:49 INFO]: | Prison | Mines Module enablement starting...
+[13:14:49 INFO]: | Prison | Mines Module enabled successfully in 271 milliseconds.
+[13:14:49 INFO]: | Prison | Ranks Module enablement starting...
+[13:14:50 INFO]: | Prison | Loaded 0 ranks.
+[13:14:50 INFO]: | Prison | Loaded 2 ladders.
+[13:14:50 INFO]: | Prison | Loaded 0 players.
+[13:14:50 INFO]: | Prison | Ranks by ladders:
+[13:14:50 INFO]: | Prison | default:
+[13:14:50 INFO]: | Prison | prestiges:
+[13:14:50 INFO]: | Prison | none:
+[13:14:50 INFO]: | Prison | Ranks Module enabled successfully in 241 milliseconds.
+[13:14:50 INFO]: | Prison | Utils Module enablement starting...
+[13:14:50 INFO]: | Prison | Utils Module enabled successfully in 15 milliseconds.
+[13:14:50 INFO]: | Prison | Loaded 0 mines and submitted with a 5000 millisecond offset timing for auto resets.
+[13:14:50 INFO]: | Prison | Total placeholders generated: 197
+[13:14:50 INFO]: | Prison | PLAYER: 102
+[13:14:50 INFO]: | Prison | LADDERS: 64
+[13:14:50 INFO]: | Prison | MINEPLAYERS: 31
+[13:14:50 INFO]: | Prison | ALIAS: 99
+[13:14:50 INFO]: | Prison | Total placeholders available to be Registered: 197
+[13:14:50 INFO]: | Prison | A total of 0 Mines and Ranks have been linked together.
+[13:14:50 INFO]: | Prison | Notice: AutoManager config file was just updated with 120 new entries. May need to be configured. File: autoFeaturesConfig.yml
+[13:14:50 INFO]: | Prison | Notice: AutoManager config file was just created. You must configure it to use it. File: autoFeaturesConfig.yml
+[13:14:50 INFO]: | Prison | AutoManager: AutoFeatures and the Mine module are enabled. Prison will register the selected block break listeners.
+[13:14:50 INFO]: | Prison | AutoManager: Trying to register BlockBreakEvent
+[13:14:50 INFO]: | Prison | ------------- < /prison version > --------------- (3.2.11-alpha.11)
+[13:14:50 INFO]: | Prison | Prison Version: 3.2.11-alpha.11
+[13:14:50 INFO]: | Prison | Running on Platform: tech.mcprison.prison.spigot.SpigotPlatform
+[13:14:50 INFO]: | Prison | Minecraft Version: git-Spigot-21fe707-e1ebe52 (MC: 1.8.8)
+[13:14:50 INFO]: | Prison |
+[13:14:50 INFO]: | Prison | Server runtime: 1s
+[13:14:50 INFO]: | Prison | Java Version: 1.8.0_291 Processor cores: 8
+[13:14:50 INFO]: | Prison | Memory Max: 3.556 GB Total: 1.054 GB Free: 644.558 MB Used: 434.942 MB
+[13:14:50 INFO]: | Prison | Total Server Disk Space: 943.719 GB Usable: 689.799 GB Free: 689.799 GB Used: 253.919 GB
+[13:14:50 INFO]: | Prison | Prison's File Count: 28 Folder Count: 23 Disk Space: 174.540 KB Other Objects: 0
+[13:14:50 INFO]: | Prison | Prison TPS Average: 0.00 Min: 20.00 Max: 20.00 Interval: 10 ticks Samples: 0
+[13:14:50 INFO]: | Prison |
+[13:14:50 INFO]: | Prison | Prison's root Command: /prison
+[13:14:50 INFO]: | Prison | Module: Mines : Enabled
+[13:14:50 INFO]: | Prison | Module: Ranks : Enabled
+[13:14:50 INFO]: | Prison | Module: Utils : Enabled
+[13:14:50 INFO]: | Prison |
+[13:14:50 INFO]: | Prison | AutoManager Enabled: true
+[13:14:50 INFO]: | Prison | . Apply Block Breaks through Sync Tasks: true
+[13:14:50 INFO]: | Prison | . Cancel all Block Break Events: true
+[13:14:50 INFO]: | Prison | . Cancel All Block Break Events Block Drops: false
+[13:14:50 INFO]: | Prison | . 'org.bukkit.BlockBreakEvent' Priority: LOW
+[13:14:50 INFO]: | Prison | . Auto Pickup: true
+[13:14:50 INFO]: | Prison | . Auto Smelt: true
+[13:14:50 INFO]: | Prison | . Auto Block: true
+[13:14:50 INFO]: | Prison |
+[13:14:50 INFO]: | Prison | . Calculate Fortune: true
+[13:14:50 INFO]: | Prison | . . Extended Bukkit Fortune Enabled: true
+[13:14:50 INFO]: | Prison |
+[13:14:50 INFO]: | Prison | . Calculate XP: true
+[13:14:50 INFO]: | Prison | . Drop XP as Orbs: false
+[13:14:50 INFO]: | Prison | . Calculate Food Exhustion: true
+[13:14:50 INFO]: | Prison | . Calculate Additional Items in Drop: true (like flint in gravel)
+[13:14:50 INFO]: | Prison | Prestiges Enabled: true
+[13:14:50 INFO]: | Prison | . Reset Money: true
+[13:14:50 INFO]: | Prison | . Reset Default Ladder: true
+[13:14:50 INFO]: | Prison |
+[13:14:50 INFO]: | Prison | GUI Enabled: true
+[13:14:50 INFO]: | Prison | Sellall Enabled: true
+[13:14:50 INFO]: | Prison | Backpacks Enabled: false
+[13:14:50 INFO]: | Prison |
+[13:14:50 INFO]: | Prison | Integrations:
+[13:14:50 INFO]: | Prison | . . Permissions: LuckPerms (Vault)
+[13:14:50 INFO]: | Prison | . . Economy: Essentials Economy (Vault)
+[13:14:50 INFO]: | Prison | Integration Type: ECONOMY
+[13:14:50 INFO]: | Prison | . . Essentials Economy (Vault) [URL]
+[13:14:50 INFO]: | Prison | Integration Type: PERMISSION
+[13:14:50 INFO]: | Prison | . . LuckPerms (Vault)
+[13:14:50 INFO]: | Prison | . . LuckPerms (LuckPermsV5) [URL]
+[13:14:50 INFO]: | Prison | Integration Type: PLACEHOLDER
+[13:14:50 INFO]: | Prison | . . To list all or search for placeholders see: /prison placeholders
+[13:14:50 INFO]: | Prison | . . PlaceholderAPI [URL]
+[13:14:50 INFO]: | Prison |
+[13:14:50 INFO]: | Prison | Registered Plugins:
+[13:14:50 INFO]: | Prison | CS-CoreLib (1.5.4 JavaSE_6) Essentials (2.18.2.0 JavaSE_8)
+[13:14:50 INFO]: | Prison | EssentialsChat (2.18.2.0 JavaSE_8) HolographicDisplays (2.4.1 JavaSE_8)
+[13:14:50 INFO]: | Prison | HolographicExtension (1.10.8 JavaSE_8) LuckPerms (5.1.26 JavaSE_8)
+[13:14:50 INFO]: | Prison | PlaceholderAPI (2.10.10 JavaSE_8) Prison (3.2.11-alpha.11 JavaSE_8)
+[13:14:50 INFO]: | Prison | ProtocolLib (4.5.0 JavaSE_8) Vault (1.5.6-b49 JavaSE_6)
+[13:14:50 INFO]: | Prison | WorldEdit (6.1;no_git_id JavaSE_6) WorldGuard (6.1 JavaSE_6)
+[13:14:50 INFO]: | Prison | Prison - Finished loading.
+```
+
+
+
+
+
+# Prison Information - Setting up a new Prison Server
+
+
+When Prison detects that it has not ran on the server before, it will display the following message in the console, after waiting about 10 seconds for the other plugins to finish logging their startup information.
+
+
+```
+[13:14:55 INFO]: | Prison | ----- < Setting up a new Prison Server > -------- (3.2.11-alpha.11)
+[13:14:55 INFO]: | Prison | Welcome to Prison!
+[13:14:55 INFO]: | Prison |
+[13:14:55 INFO]: | Prison | To quickly get started, it is suggested to use the following command which will setup Ranks, Mines, link the Mines to the Ranks, setup automatic Access by Ranks, auto assign blocks to the generated Mines in increasing value,Enable the auto features (auto pickup, smelt, and block), setup the sellall's default shop pricing on about 95 items, etc...
+[13:14:55 INFO]: | Prison | . /ranks autoConfigure
+[13:14:55 INFO]: | Prison |
+[13:14:55 INFO]: | Prison | For more information on what to do next, after running autoConfigure, check out this document:
+[13:14:55 INFO]: | Prison | . https://prisonteam.github.io/Prison/prison_docs_100_setting_up_auto_configure.html
+[13:14:55 INFO]: | Prison |
+[13:14:55 INFO]: | Prison |
+[13:14:55 INFO]: | Prison | For more information on how to setup Prison, see our extensive documentation that is online:
+[13:14:55 INFO]: | Prison | . https://prisonteam.github.io/Prison/prison_docs_000_toc.html
+[13:14:55 INFO]: | Prison |
+[13:14:55 INFO]: | Prison | Information on suggested plugins can be found here:
+[13:14:55 INFO]: | Prison | . https://prisonteam.github.io/Prison/prison_docs_012_setting_up_prison_basics.html
+[13:14:55 INFO]: | Prison |
+[13:14:55 INFO]: | Prison | If you need help with setting up prison, please see our documentation.
+[13:14:55 INFO]: | Prison | If you find an issue with Prison, or need help for things not in the documentation, then please visit our discord server:
+[13:14:55 INFO]: | Prison |
+[13:14:55 INFO]: | Prison |
+>
+
+```
+
+
+
+
+# Running command: /ranks autoConfigure help
+
+
+```
+>ranks autoConfigure help
+[13:31:26 INFO]: ------- < Cmd: /ranks autoConfigure > --------- (3.2.11-alpha.11)
+[13:31:26 INFO]: Auto configures Ranks and Mines using single letters A through Z for both the rank and mine names. Both ranks and mines are generated, they will also be linked together automatically. To set the starting price use price=x. To set multiplier mult=x. AutoConfigure will try to merge any preexsiting ranks and mines, but you must use the 'force' keyword in 'options'. Force will replace all blocks in preexisting mines. To keep preexisting blocks, use 'forceKeepBlocks' with the 'force' option. Default values [full price=50000 mult=1.5]
+[13:31:26 INFO]: /ranks autoConfigure [options]
+[13:31:26 INFO]: [options | full] Options: [full ranks mines price=x mult=x force forceKeepBlocks dontForceLinerWalls dontForceLinerBottoms]
+[13:31:26 INFO]: Permissions:
+[13:31:26 INFO]: ranks.set
+[13:31:26 INFO]: Aliases:
+[13:31:26 INFO]: [prison autoConfigure]
+>
+```
+
+
+
+
+
+# Running command: /ranks autoConfigure
+
+
+```
+>ranks autoConfigure
+[13:33:38 INFO]: Your new rank, 'A', was created in the ladder 'default', using the tag value of '[A]'
+[13:33:38 INFO]: Virtual mine created: use command '/mines set area help' set an area within a world to enable as a normal mine.
+[13:33:38 INFO]: Your new rank, 'B', was created in the ladder 'default', using the tag value of '[B]'
+[13:33:38 INFO]: Virtual mine created: use command '/mines set area help' set an area within a world to enable as a normal mine.
+[13:33:38 INFO]: Your new rank, 'C', was created in the ladder 'default', using the tag value of '[C]'
+[13:33:38 INFO]: Virtual mine created: use command '/mines set area help' set an area within a world to enable as a normal mine.
+[13:33:38 INFO]: Your new rank, 'D', was created in the ladder 'default', using the tag value of '[D]'
+[13:33:38 INFO]: Virtual mine created: use command '/mines set area help' set an area within a world to enable as a normal mine.
+[13:33:38 INFO]: Your new rank, 'E', was created in the ladder 'default', using the tag value of '[E]'
+[13:33:38 INFO]: Virtual mine created: use command '/mines set area help' set an area within a world to enable as a normal mine.
+[13:33:38 INFO]: Your new rank, 'F', was created in the ladder 'default', using the tag value of '[F]'
+[13:33:38 INFO]: Virtual mine created: use command '/mines set area help' set an area within a world to enable as a normal mine.
+[13:33:38 INFO]: Your new rank, 'G', was created in the ladder 'default', using the tag value of '[G]'
+[13:33:38 INFO]: Virtual mine created: use command '/mines set area help' set an area within a world to enable as a normal mine.
+[13:33:38 INFO]: Your new rank, 'H', was created in the ladder 'default', using the tag value of '[H]'
+[13:33:38 INFO]: Virtual mine created: use command '/mines set area help' set an area within a world to enable as a normal mine.
+[13:33:38 INFO]: Your new rank, 'I', was created in the ladder 'default', using the tag value of '[I]'
+[13:33:38 INFO]: Virtual mine created: use command '/mines set area help' set an area within a world to enable as a normal mine.
+[13:33:38 INFO]: Your new rank, 'J', was created in the ladder 'default', using the tag value of '[J]'
+[13:33:38 INFO]: Virtual mine created: use command '/mines set area help' set an area within a world to enable as a normal mine.
+[13:33:38 INFO]: Your new rank, 'K', was created in the ladder 'default', using the tag value of '[K]'
+[13:33:38 INFO]: Virtual mine created: use command '/mines set area help' set an area within a world to enable as a normal mine.
+[13:33:38 INFO]: Your new rank, 'L', was created in the ladder 'default', using the tag value of '[L]'
+[13:33:38 INFO]: Virtual mine created: use command '/mines set area help' set an area within a world to enable as a normal mine.
+[13:33:38 INFO]: Your new rank, 'M', was created in the ladder 'default', using the tag value of '[M]'
+[13:33:39 INFO]: Virtual mine created: use command '/mines set area help' set an area within a world to enable as a normal mine.
+[13:33:39 INFO]: Your new rank, 'N', was created in the ladder 'default', using the tag value of '[N]'
+[13:33:39 INFO]: Virtual mine created: use command '/mines set area help' set an area within a world to enable as a normal mine.
+[13:33:39 INFO]: Your new rank, 'O', was created in the ladder 'default', using the tag value of '[O]'
+[13:33:39 INFO]: Virtual mine created: use command '/mines set area help' set an area within a world to enable as a normal mine.
+[13:33:39 INFO]: Your new rank, 'P', was created in the ladder 'default', using the tag value of '[P]'
+[13:33:39 INFO]: Virtual mine created: use command '/mines set area help' set an area within a world to enable as a normal mine.
+[13:33:39 INFO]: Your new rank, 'Q', was created in the ladder 'default', using the tag value of '[Q]'
+[13:33:39 INFO]: Virtual mine created: use command '/mines set area help' set an area within a world to enable as a normal mine.
+[13:33:39 INFO]: Your new rank, 'R', was created in the ladder 'default', using the tag value of '[R]'
+[13:33:39 INFO]: Virtual mine created: use command '/mines set area help' set an area within a world to enable as a normal mine.
+[13:33:39 INFO]: Your new rank, 'S', was created in the ladder 'default', using the tag value of '[S]'
+[13:33:39 INFO]: Virtual mine created: use command '/mines set area help' set an area within a world to enable as a normal mine.
+[13:33:39 INFO]: Your new rank, 'T', was created in the ladder 'default', using the tag value of '[T]'
+[13:33:39 INFO]: Virtual mine created: use command '/mines set area help' set an area within a world to enable as a normal mine.
+[13:33:39 INFO]: Your new rank, 'U', was created in the ladder 'default', using the tag value of '[U]'
+[13:33:39 INFO]: Virtual mine created: use command '/mines set area help' set an area within a world to enable as a normal mine.
+[13:33:39 INFO]: Your new rank, 'V', was created in the ladder 'default', using the tag value of '[V]'
+[13:33:39 INFO]: Virtual mine created: use command '/mines set area help' set an area within a world to enable as a normal mine.
+[13:33:39 INFO]: Your new rank, 'W', was created in the ladder 'default', using the tag value of '[W]'
+[13:33:39 INFO]: Virtual mine created: use command '/mines set area help' set an area within a world to enable as a normal mine.
+[13:33:39 INFO]: Your new rank, 'X', was created in the ladder 'default', using the tag value of '[X]'
+[13:33:39 INFO]: Virtual mine created: use command '/mines set area help' set an area within a world to enable as a normal mine.
+[13:33:39 INFO]: Your new rank, 'Y', was created in the ladder 'default', using the tag value of '[Y]'
+[13:33:39 INFO]: Virtual mine created: use command '/mines set area help' set an area within a world to enable as a normal mine.
+[13:33:39 INFO]: Your new rank, 'Z', was created in the ladder 'default', using the tag value of '[Z]'
+[13:33:39 INFO]: Virtual mine created: use command '/mines set area help' set an area within a world to enable as a normal mine.
+[13:33:39 INFO]: Your new rank, 'P1', was created in the ladder 'prestiges', using the tag value of '[+]'
+[13:33:39 INFO]: Your new rank, 'P2', was created in the ladder 'prestiges', using the tag value of '[+2]'
+[13:33:39 INFO]: Your new rank, 'P3', was created in the ladder 'prestiges', using the tag value of '[+3]'
+[13:33:39 INFO]: Your new rank, 'P4', was created in the ladder 'prestiges', using the tag value of '[+4]'
+[13:33:39 INFO]: Your new rank, 'P5', was created in the ladder 'prestiges', using the tag value of '[+5]'
+[13:33:39 INFO]: Your new rank, 'P6', was created in the ladder 'prestiges', using the tag value of '[+6]'
+[13:33:39 INFO]: Your new rank, 'P7', was created in the ladder 'prestiges', using the tag value of '[+7]'
+[13:33:39 INFO]: Your new rank, 'P8', was created in the ladder 'prestiges', using the tag value of '[+8]'
+[13:33:39 INFO]: Your new rank, 'P9', was created in the ladder 'prestiges', using the tag value of '[+9]'
+[13:33:39 INFO]: Your new rank, 'P10', was created in the ladder 'prestiges', using the tag value of '[+10]'
+[13:33:40 INFO]: | Prison | Mine A: [minecraft: andesite 5.0, minecraft: cobblestone 95.0]
+[13:33:40 INFO]: | Prison | Mine B: [minecraft: diorite 5.0, minecraft: andesite 10.0, minecraft: cobblestone 85.0]
+[13:33:40 INFO]: | Prison | Mine C: [minecraft: coal_ore 5.0, minecraft: diorite 10.0, minecraft: andesite 20.0, minecraft: cobblestone 65.0]
+[13:33:40 INFO]: | Prison | Mine D: [minecraft: granite 5.0, minecraft: coal_ore 10.0, minecraft: diorite 20.0, minecraft: andesite 20.0, minecraft: cobblestone 45.0]
+[13:33:40 INFO]: | Prison | Mine E: [minecraft: stone 5.0, minecraft: granite 10.0, minecraft: coal_ore 20.0, minecraft: diorite 20.0, minecraft: andesite 20.0, minecraft: cobblestone 25.0]
+[13:33:40 INFO]: | Prison | Mine F: [minecraft: iron_ore 5.0, minecraft: stone 10.0, minecraft: granite 20.0, minecraft: coal_ore 20.0, minecraft: diorite 20.0, minecraft: andesite 25.0]
+[13:33:40 INFO]: | Prison | Mine G: [minecraft: polished_andesite 5.0, minecraft: iron_ore 10.0, minecraft: stone 20.0, minecraft: granite 20.0, minecraft: coal_ore 20.0, minecraft: diorite 25.0]
+[13:33:40 INFO]: | Prison | Mine H: [minecraft: gold_ore 5.0, minecraft: polished_andesite 10.0, minecraft: iron_ore 20.0, minecraft: stone 20.0, minecraft: granite 20.0, minecraft: coal_ore 25.0]
+[13:33:40 INFO]: | Prison | Mine I: [minecraft: mossy_cobblestone 5.0, minecraft: gold_ore 10.0, minecraft: polished_andesite 20.0, minecraft: iron_ore 20.0, minecraft: stone 20.0, minecraft: granite 25.0]
+[13:33:40 INFO]: | Prison | Mine J: [minecraft: coal_block 5.0, minecraft: mossy_cobblestone 10.0, minecraft: gold_ore 20.0, minecraft: polished_andesite 20.0, minecraft: iron_ore 20.0, minecraft: stone 25.0]
+[13:33:40 INFO]: | Prison | Mine K: [minecraft: nether_quartz_ore 5.0, minecraft: coal_block 10.0, minecraft: mossy_cobblestone 20.0, minecraft: gold_ore 20.0, minecraft: polished_andesite 20.0, minecraft: iron_ore 25.0]
+[13:33:40 INFO]: | Prison | Mine L: [minecraft: lapis_ore 5.0, minecraft: nether_quartz_ore 10.0, minecraft: coal_block 20.0, minecraft: mossy_cobblestone 20.0, minecraft: gold_ore 20.0, minecraft: polished_andesite 25.0]
+[13:33:40 INFO]: | Prison | Mine M: [minecraft: end_stone 5.0, minecraft: lapis_ore 10.0, minecraft: nether_quartz_ore 20.0, minecraft: coal_block 20.0, minecraft: mossy_cobblestone 20.0, minecraft: gold_ore 25.0]
+[13:33:40 INFO]: | Prison | Mine N: [minecraft: iron_block 5.0, minecraft: end_stone 10.0, minecraft: lapis_ore 20.0, minecraft: nether_quartz_ore 20.0, minecraft: coal_block 20.0, minecraft: mossy_cobblestone 25.0]
+[13:33:40 INFO]: | Prison | Mine O: [minecraft: redstone_ore 5.0, minecraft: iron_block 10.0, minecraft: end_stone 20.0, minecraft: lapis_ore 20.0, minecraft: nether_quartz_ore 20.0, minecraft: coal_block 25.0]
+[13:33:40 INFO]: | Prison | Mine P: [minecraft: diamond_ore 5.0, minecraft: redstone_ore 10.0, minecraft: iron_block 20.0, minecraft: end_stone 20.0, minecraft: lapis_ore 20.0, minecraft: nether_quartz_ore 25.0]
+[13:33:40 INFO]: | Prison | Mine Q: [minecraft: quartz_block 5.0, minecraft: diamond_ore 10.0, minecraft: redstone_ore 20.0, minecraft: iron_block 20.0, minecraft: end_stone 20.0, minecraft: lapis_ore 25.0]
+[13:33:40 INFO]: | Prison | Mine R: [minecraft: emerald_ore 5.0, minecraft: quartz_block 10.0, minecraft: diamond_ore 20.0, minecraft: redstone_ore 20.0, minecraft: iron_block 20.0, minecraft: end_stone 25.0]
+[13:33:40 INFO]: | Prison | Mine S: [minecraft: gold_block 5.0, minecraft: emerald_ore 10.0, minecraft: quartz_block 20.0, minecraft: diamond_ore 20.0, minecraft: redstone_ore 20.0, minecraft: iron_block 25.0]
+[13:33:40 INFO]: | Prison | Mine T: [minecraft: prismarine 5.0, minecraft: gold_block 10.0, minecraft: emerald_ore 20.0, minecraft: quartz_block 20.0, minecraft: diamond_ore 20.0, minecraft: redstone_ore 25.0]
+[13:33:40 INFO]: | Prison | Mine U: [minecraft: lapis_block 5.0, minecraft: prismarine 10.0, minecraft: gold_block 20.0, minecraft: emerald_ore 20.0, minecraft: quartz_block 20.0, minecraft: diamond_ore 25.0]
+[13:33:40 INFO]: | Prison | Mine V: [minecraft: redstone_block 5.0, minecraft: lapis_block 10.0, minecraft: prismarine 20.0, minecraft: gold_block 20.0, minecraft: emerald_ore 20.0, minecraft: quartz_block 25.0]
+[13:33:40 INFO]: | Prison | Mine W: [minecraft: obsidian 5.0, minecraft: redstone_block 10.0, minecraft: lapis_block 20.0, minecraft: prismarine 20.0, minecraft: gold_block 20.0, minecraft: emerald_ore 25.0]
+[13:33:40 INFO]: | Prison | Mine X: [minecraft: diamond_block 5.0, minecraft: obsidian 10.0, minecraft: redstone_block 20.0, minecraft: lapis_block 20.0, minecraft: prismarine 20.0, minecraft: gold_block 25.0]
+[13:33:40 INFO]: | Prison | Mine Y: [minecraft: dark_prismarine 5.0, minecraft: diamond_block 10.0, minecraft: obsidian 20.0, minecraft: redstone_block 20.0, minecraft: lapis_block 20.0, minecraft: prismarine 25.0]
+[13:33:40 INFO]: | Prison | Mine Z: [minecraft: emerald_block 5.0, minecraft: dark_prismarine 10.0, minecraft: diamond_block 20.0, minecraft: obsidian 20.0, minecraft: redstone_block 20.0, minecraft: lapis_block 25.0]
+[13:33:40 INFO]: | Prison | Mine Liner status: A (Created) : walls:bricked:forced,bottom:bedrock:forced,ladderType:normal
+[13:33:41 INFO]: | Prison | Mine Liner status: B (Created) : walls:darkForest:forced,bottom:glowstone:forced,ladderType:normal
+[13:33:41 INFO]: | Prison | Mine Liner status: C (Created) : walls:blackAndWhite:forced,bottom:glowingPlanks:forced,ladderType:normal
+[13:33:41 INFO]: | Prison | Mine Liner status: D (Created) : walls:glowstone:forced,bottom:bedrock:forced,ladderType:normal
+[13:33:41 INFO]: | Prison | Mine Liner status: E (Created) : walls:obby:forced,bottom:glowstone:forced,ladderType:normal
+[13:33:41 INFO]: | Prison | Mine Liner status: F (Created) : walls:bricked:forced,bottom:bright:forced,ladderType:normal
+[13:33:41 INFO]: | Prison | Mine Liner status: G (Created) : walls:darkForest:forced,bottom:glowingPlanks:forced,ladderType:normal
+[13:33:41 INFO]: | Prison | Mine Liner status: H (Created) : walls:bedrock:forced,bottom:beacon:forced,ladderType:normal
+[13:33:41 INFO]: | Prison | Mine Liner status: I (Created) : walls:beacon:forced,bottom:glowstone:forced,ladderType:normal
+[13:33:41 INFO]: | Prison | Mine Liner status: J (Created) : walls:seaEchos:forced,bottom:bricked:forced,ladderType:normal
+[13:33:41 INFO]: | Prison | Mine Liner status: K (Created) : walls:blackAndWhite:forced,bottom:glowingPlanks:forced,ladderType:normal
+[13:33:41 INFO]: | Prison | Mine Liner status: L (Created) : walls:bricked:forced,bottom:bricked:forced,ladderType:normal
+[13:33:41 INFO]: | Prison | Mine Liner status: M (Created) : walls:glowingPlanks:forced,bottom:glowingPlanks:forced,ladderType:normal
+[13:33:41 INFO]: | Prison | Mine Liner status: N (Created) : walls:beacon:forced,bottom:blackAndWhite:forced,ladderType:normal
+[13:33:41 INFO]: | Prison | Mine Liner status: O (Created) : walls:darkOakPrismarine:forced,bottom:glowstone:forced,ladderType:normal
+[13:33:41 INFO]: | Prison | Mine Liner status: P (Created) : walls:bricked:forced,bottom:glowingPlanks:forced,ladderType:normal
+[13:33:41 INFO]: | Prison | Mine Liner status: Q (Created) : walls:bright:forced,bottom:beacon:forced,ladderType:normal
+[13:33:41 INFO]: | Prison | Mine Liner status: R (Created) : walls:glowstone:forced,bottom:obby:forced,ladderType:normal
+[13:33:41 INFO]: | Prison | Mine Liner status: S (Created) : walls:darkForest:forced,bottom:darkOakPrismarine:forced,ladderType:normal
+[13:33:41 INFO]: | Prison | Mine Liner status: T (Created) : walls:obby:forced,bottom:glowingPlanks:forced,ladderType:normal
+[13:33:41 INFO]: | Prison | Mine Liner status: U (Created) : walls:bricked:forced,bottom:obby:forced,ladderType:normal
+[13:33:41 INFO]: | Prison | Mine Liner status: V (Created) : walls:beacon:forced,bottom:darkForest:forced,ladderType:normal
+[13:33:41 INFO]: | Prison | Mine Liner status: W (Created) : walls:bricked:forced,bottom:obby:forced,ladderType:normal
+[13:33:41 INFO]: | Prison | Mine Liner status: X (Created) : walls:darkOakPrismarine:forced,bottom:beacon:forced,ladderType:normal
+[13:33:41 INFO]: | Prison | Mine Liner status: Y (Created) : walls:darkOakPrismarine:forced,bottom:seaEchos:forced,ladderType:normal
+[13:33:41 INFO]: | Prison | Mine Liner status: Z (Created) : walls:white:forced,bottom:darkForest:forced,ladderType:normal
+[13:33:41 INFO]: The 'prestiges' ladder has been enabled to apply a Base Rank Cost Multiplier of 0.1000 that will be applied to 'all' rank costs. This multiplier will be increased with each rank on the ladder.
+[13:33:41 INFO]: The Base Rank Cost Multiplier can be adjusted, or disabled, with the command: '/ranks ladder rankCostMultiplier
+[13:33:41 INFO]: Ranks autoConfigure: 26 ranks were created.
+[13:33:41 INFO]: Ranks autoConfigure: No rank commands were created.
+[13:33:41 INFO]: | Prison | Total placeholders generated: 1419
+[13:33:41 INFO]: | Prison | PLAYER: 102
+[13:33:41 INFO]: | Prison | LADDERS: 64
+[13:33:41 INFO]: | Prison | MINES: 832
+[13:33:41 INFO]: | Prison | MINEPLAYERS: 57
+[13:33:41 INFO]: | Prison | STATSMINES: 364
+[13:33:41 INFO]: | Prison | ALIAS: 697
+[13:33:41 INFO]: | Prison | Total placeholders available to be Registered: 1419
+[13:33:41 INFO]: | Prison | AutoManagerEventsManager: unregistered a total of 2 event listeners.
+[13:33:41 INFO]: | Prison | AutoManager: Trying to register BlockBreakEvent
+[13:33:41 INFO]: | Prison | Welcome! RoyalBlueRanger just joined the server and was assigned the default ranks.
+[13:33:41 INFO]: | Prison | Welcome! Myrqua just joined the server and was assigned the default ranks.
+[13:33:41 INFO]: | Prison | Welcome! RoyalCoffeeBeans just joined the server and was assigned the default ranks.
+[13:33:41 INFO]: Ranks autoConfigure: 26 mines were created.
+[13:33:41 INFO]: Ranks autoConfigure: 26 ranks and mines were linked.
+[13:33:41 INFO]: Created 10 prestige ranks (temp message).
+[13:33:41 INFO]: | Prison |
+>
+
+
+```
+
+
+
+
+
+
+
diff --git a/docs/prison_docs_115_using_BlockEvents.md b/docs/prison_docs_115_using_BlockEvents.md
index 65e55fcf5..c0f374bf2 100644
--- a/docs/prison_docs_115_using_BlockEvents.md
+++ b/docs/prison_docs_115_using_BlockEvents.md
@@ -13,11 +13,52 @@ A single BlockEvent can also have more than one command that is ran together wit
BlockEvents have a taskMode that defines how the specified commands are to be ran.
+*Documented updated: 2021-12-03*
+
+# BlockEvent Commands
+
+BlockEvents can be access through the command prefixes of:
+
+`/mines blockEvent`
+
+There are 9 sub-commands, which includes add and list, which are probably the most important of the commands.
+
+
+
+
+
+In the above screen print, the sub-commands have as a parameter named **row**. See the next section in this document for more information.
+
+
+The BlockEvent listings can also be included in the following command by including the keyword **all**:
+`/mines info all`
+
+
+## Use of Row Numbers In The BlockEvent Commands:
+
+ Due to the complexity of the blockEvent commands being deeply nested, and there could be so many of them, many of the blockEvent commands uses a **Row** identifier. This row identifier is based upon the order of the commands as listed under the `/mines blockEvent list` command.
+
+A number of examples of a few different blockEvets is as follows. Emphasis is on the row numbers.
+
+
+
+
+
+
+
# BlockEvents Placeholders
-Within the BlockEvents commands you can use placeholders and Prison will substitute the correct values for you.
+Within the BlockEvents commands you can use placeholders and Prison will substitute the correct values within the commands.
+
+
+For a current list of all blockEvent commands use **placeholders** keyword with the **add** command:
+
+`/mines blockEvent add placeholders`
+
+
+`{player} {player_uid} {msg} {broadcast} {title} {actionBar} {inline} {inlinePlayer} {sync} {syncPlayer} {blockName} {mineName} {locationWorld} {locationX} {locationY} {locationZ} {coordinates} {worldCoordinates} {blockCoordinates} {blockChance} {blockIsAir} {blocksPlaced} {blockRemaining} {blocksMinedTotal} {mineBlocksRemaining} {mineBlocksRemainingPercent} {mineBlocksTotalMined} {mineBlocksSize} {blockMinedName} {blockMinedNameFormal} {blockMinedBlockType} {eventType} {eventTriggered} {utilsDecay}`
- **{player}** Provides the player's name.
@@ -32,22 +73,124 @@ Prison's BlockEvents also supports more advanced placeholders that can help simp
- **{msg}** Send a message to the player. This is a shortcut for the prison command: `/prison utils msg`. Example: `{msg} Congrats! You found a token!`.
-- **{broadcast}** Sends a broadcast message to all players on the server. this is a shortcut for the prison command: `/prison utils broadcast`. Example: `{broadcast} {player} found a treasure trove of 100 voter keys!`.
+- **{broadcast}** Sends a broadcast message to all players on the server. Just use this placeholder followed by the message. This is a shortcut for the prison command: `/prison utils broadcast`. Example: `{broadcast} {player} found a treasure trove of 100 voter keys!`.
+
+
+- **{actionBar}** Sends a message to the "actionBar" on the player's screen. Just use this placeholder followed by the message. This is a shortcut for the prison command: `\prison utils titles actionBar `. Example: `{actionBar}You Found Tokens!`
+
+
+- **{title}** Sends a message to the "title" on the player's screen. Just use this placeholder followed by the message. This is a shortcut for the prison command: `\prison utils titles title `. Example: `{title}You Found Tokens!`
+
+
+
+**How the command runs:**
+
+There are four **taskModes** on how BlockEvent commands run. The taskModes can be setup through the command `/mines blockEvent taskMode help`, or they can be specified as placeholders. There are 4 taskModes, and the placeholder versions are listed here:
+
+- **{inline}** This is the default taskMode if not specified. **{inline}** runs the commands in the same thread that in which Prison is handling the Block Break Events within Auto Features, and runs them as console (OP). If the command you use with BlockEvents is "slow" to run, then it could cause significant lag on the server.
+
+- **{inlinePlayer}** This placeholder is similar to the **{inline}** placeholder, but it is ran as the player who is mining. This too can cause significant lag if the command is not fast.
+- **{sync}** This placeholder uses the taskMode of synchronous task submission. The command specified will be submitted to run in the bukkit's synchronous thread, and is ran as console (OP). Since all block break events are ran in the same bukkit synchronous thread, the specified command will run after prison is finished processing the broken block. Long running commands will not cause lag through the handling of the block break events, but they could still cause lag.
+- **{syncPlayer}** This placeholder is similar to the **{sync}** placeholder, with the exception the commands are ran as the player, so the player must have access to those commands.
-Some examples showing how to use these in BlockEvent:
+NOTE: It is impossible to run a command asynchronously, since the execution of a command must always be in a synchronous thread. Hence you can submit an async task, but then when you run the command, it does so in a sync thread.
+
+
+`/mines blockEvent add help`
+`/mines blockEvent add placeholders`
+
+
+Some examples showing how to use placeholders in the blockEvents.
```
-/mines blockevent add A 0.075 none inline prison utils repairAll {player};{msg} Congrats! Everything in your inventory has been repaired!
-/mines blockevent add A 1 none inline prison utils smelt {player};prison utils block {player}
+/mines blockEvent add a 100 {utilsDecay} rainbow {blockCoordinates} AIR 40 {mineName}
+
+/mines blockevent add A 0.075 prison utils repairAll {player};{actionBar}Your items have been repaired!
+
+/mines blockevent add A 1 prison utils smelt {player}
-/mines blockEvent add A 5.0 none inline prison utils potionEffect speed 90 2;prison utils potionEffect night_vision 300 1
+/mines blockEvent add A 5.0 prison utils potionEffect speed 90 2;prison utils potionEffect night_vision 300 1
```
+
+- **{blockName}** The name of the block that was placed in the mine during the last mine reset. The same name as used and provided within the command `/mines block search`.
+
+
+- **{mineName}** The name of the mine. If outside of a mine it will be blank.
+
+
+- **{locationWorld}** Provides the world name in which the block was mined.
+
+
+-**{locationX}** The **X** coordinates for the broken block. This is an integer value.
+
+
+- **{locationY}** The **Y** coordinates for the broken block. This is an integer value.
+
+
+- **{locationZ}** The **Z** coordinates for the broken block. This is an integer value.
+
+
+- **{coordinates}** This provides the X, Y, and Z coordinates for the broken block. These are double values, surrounded by parenthesis and separated by commas. Format: **(X,Y,Z)** Example: `(183.2,88.3792,-3828.248)`
+
+
+- **{blockCoordinates}** This is similar to the **{coordinates}** placeholder, except for the use of integer values. Format: **(blockName,world,X,Y,Z)** Example: `(,prisonWorld,183,88,-3828)`
+
+
+- **{worldCoordinates}** This combines both the **{locationWorld}** and **{blockCoordinates}** placeholder in to one placeholder. The coordinates are integer values. Format: **(world,X,Y,Z)** Example: `(prisonWorld,183,88,-3828)`
+
+
+- **{blockChance}** The blockEvent's percent chance as defined when setting up the command.
+
+
+- **{blockIsAir}** A boolean value of either TRUE or FALSE as to if the block was originally set to AIR during the last mine reset. Technically, if the block is set to AIR, then it is ignored in all block events that prison processes through the auto features. Therefore this should always return FALSE.
+
+
+- **{blocksPlaced}** This is the number of blocks placed in the mine during the last Mine reset. This value should be equal to the mine's total block size, minus the number of AIR blocks that were placed during the reset.
+
+
+- **{blockRemaining}** The current number of blocks remaining in the mine, until there would be zero blocks left to mine. Note that this is a dynamic and changing value, especially if many other players are mining at the same time. There is even a chance that this value may be non-zero with another player's block break handling triggering a mine reset event, or zero blocks remaining.
+
+
+- **{blocksMinedTotal}** The total number of blocks mined of the same type that was just broke since the last mine reset.
+
+
+- **{mineBlocksRemaining}** The total number of block remaining of the same type that was just broke. See **{blockName}** for the block name.
+
+- **{mineBlocksRemainingPercent}** The percent number of blocks remaining in the mine.
+
+
+- **{mineBlocksTotalMined}** This is the total number of all blocks mined since the stats were first enabled.
+
+
+- **{mineBlocksSize}** This is the total block count of all blocks mined.
+
+
+- **{blockMinedName}** This is the name of the block that was mined. It may not be identical to the **{blockName}** placeholder, especially if another process replaced it with another block.
+
+
+- **{blockMinedNameFormal}** This is the formal name of the block that was mined. The formal nature is the namespace prefixed to the block name, with a colon between the two. For example a block name may be "cobblestone" and then the formal name being "minecraft:cobblestone". This is more useful for custom blocks, such that their namespace is not "minecraft", which an example being "customitems:compressed_cobblestone".
+
+
+- **{blockMinedBlockType}** This is the bukkit Material name for the block. It may not match the block name, especially on older versions of spigot.
+
+
+- **{eventType}** This is the event type that Prison listened to that initiated the block break handling.
+
+
+- **{eventTriggered}** A few enchantment plugins identify the enchantment that triggered the event. If it is available, then that value will be provided by this placeholder. One plugin that provides this value is TokenEnchant.
+
+
+- **{utilsDecay}** This is a shortcut for `/prison utils decay`.
+
+
+
+
diff --git a/docs/prison_docs_117_setting_up_backpacks.md b/docs/prison_docs_117_setting_up_backpacks.md
index cf47f4124..b39dc6646 100644
--- a/docs/prison_docs_117_setting_up_backpacks.md
+++ b/docs/prison_docs_117_setting_up_backpacks.md
@@ -5,10 +5,15 @@
# Backpacks
+*NOTE: At this time it is not advisable to use Prison's backpacks. It is scheduled to undergo a rewrite soon. An alternative backbacks plugin that should work with Prison is MinePacks.*
+
+
Prison provides backpacks.
+*Documented updated: 2021-12-03*
+
diff --git a/docs/prison_docs_310_guide_placeholders.md b/docs/prison_docs_310_guide_placeholders.md
index 0c5e3cc34..0b4a04f28 100644
--- a/docs/prison_docs_310_guide_placeholders.md
+++ b/docs/prison_docs_310_guide_placeholders.md
@@ -6,6 +6,10 @@
This document covers different aspects of placeholders within Prison. It explains how they work, how to use them, and different ways to use them.
+
+*Documented updated: 2021-12-03*
+
+
@@ -13,34 +17,100 @@ This document covers different aspects of placeholders within Prison. It explai
Placeholders allow the sharing of data from one plugin with another plugin, and without either plugin knowing anything about each other.
-On the surface they appear to be simple, but there are a lot of moving parts below the surface, and with Prison Mines, there are even more things going on.
+On the surface they appear to be simple, but there are a lot of moving parts below the surface, and with Prison Mines, there are even more complicated things going on.
Add in to the mix, that different plugins deal with placeholders in slightly different ways, and you can wind up with a challenge to get them to work under different circumstances.
+
+
+
+# Placeholder Commands
+
+
+*Since Prison v3.2.1-alpha.13*
+
+
+There are a few useful commands within prison that will allow you list placeholders, search for placeholders, and to test random text that includes placeholders.
+
+
+Sub-command listing of all placeholders commands:
+
+* **/prison placeholders**
+
+
+* **/prison placeholders list**
+* **/prison placeholders search**
+* **/prison placeholders test**
+
+* **/prison placeholders reload**
+
+NOTE: the `/prison placeholders reload` command only reloads and registers the placeholders with the placeholder integrations. This would be required to enable placeholders when adding a new mine, a new rank, or a new ladder. If you reload another plugin, such as papi, you may need to reload the placeholders which will re-register them. Prison has been setup to survive a papi restart, but there could still be issues.
+
+
+NOTE: Information on these command are provided in detail below.
+
+
+
+
+
# Placeholder Types and Counts
-* **Rank Related:** 4 including aliases
-* **Rankup Related:** 18 including aliases
+Prison has numerous placeholders, with number of different types. Each of these types have different internal requirements and conditions of usage. This is a high overview of the various types and their counts.
+
+* **Player Related:** 92 including aliases
+ * **Rank Related:** 8 including aliases
+ * **Rankup Related:** 20 including aliases
+ * **Player Balance Related:** 8 including aliases
+ * **Player Tool Related:** 34 including aliases
+ * **Player Health Related:** 14 including aliases
+ * **Player XP and Levels Related:** 6 including aliases
+ * **Player Walk Speed:** 2 including aliases
+
+
+* **Ladders Related:** 30 including aliases **times** each ladder
+ A LADDERS placeholder must include the ladder's name in the placeholder and therefore is static.
+
+
+* **Ranks Related:** 22 including aliases **times** each rank
+ A RANKS placeholder needs to specify the Rank name as part of the placeholder. Each placeholder must specify a Rank and is static.
-* **Rank Ladder Related:** 4 including aliases **times** each ladder
-* **Rankup Ladder Related:** 18 including aliases **times** each ladder
+* **RankPlayers Related:** 12 including aliases **times** each rank
-* **Player Balance Related:** 2 including aliases
-* **Player Ladder Balance Related:** 2 including aliases **times** each ladder
+ A RANKPLAYERS placeholder is one that will change based upon the player's own Rank. Each player could have a different rank. Because of this relationship, these can only be used with instances of players such as scoreboards and chat prefixes; they will not work in holographic displays or with signs.
-* **Mine Related:** 28 including aliases **times** each mine
-* **Mine Player Related:** 14 including aliases
+* **Mines Related:** 18 including aliases **times** each ladder
-**Total base Placeholders:** 90 including aliases
+* **Player Ladder Balance Related:** 32 including aliases **times** each Mine
+
+ A MINES placeholder must specify the Mine mine as part of the placeholder. Each placeholder must specify a mine and is static.
+
+
+* **MinePlayers Related:** 34 including aliases
+
+ A MINEPLAYERS placholder is similar to a RankPlayers placeholder in that it is dynamic and you cannot specify a mine's name with it. How it works, is that it provides the related stats for the mine in which the player is standing in. When the player leaves the mine, then these placeholders returns an empty string value (a blank).
+
+
+* *STATSMINES Related:** 14 including aliases
+
+ These are a work in progress, but will provide access to some mine stats such as total blocks mined.
+
+
+* *STATSRANKS Related:** 6 including aliases
+
+ These are a work in progress, but will provide access to some rank stats such as top ranked player in that rank.
+
+
+
+**Total base Placeholders:** 240 including aliases
+
-**Total if 26 Mines and 3 Ladders:** 844 placeholder including aliases (22 + 26*3 ladder + 2 + 28*26 mines + 14)
@@ -57,7 +127,7 @@ There is always more than one way to do things, and the same goes for having mor
# Placeholder Theory for Prison
-There are two major types of placeholders in prison: Player based and Mine based. With the most recent releases of prison, there have been hybrids added that are a combination of the two. For example there are now ladder based placeholder that allow targeting ranks on a specific ladder, instead of all ladders. Also there are player mine placeholders that report on the mine stats for the mine in which the player is physically located in. The player mine placeholders have no value when the player is not in a mine, and they will change as the player goes from mine to mine.
+There are few major types of placeholders in prison: Player, Ranks, Ladders, Mines, and Stats based. With the most recent releases of prison, there have been hybrids added that are a combination of the player placeholders and with mines and ranks. For example there are now ladder based placeholder that allow targeting ranks on a specific ladder, instead of all ladders. Also there are player mine placeholders that report on the mine stats for the mine in which the player is physically located in. The player mine placeholders have no value when the player is not in a mine, and they will change as the player goes from mine to mine.
There are also different types of data that are returned in placeholders. Text, numbers, formatted numbers, and bar graphs.
@@ -348,31 +418,6 @@ This is mentioned here since these rank command placeholders are not part of all
-# Placeholder Commands
-
-
-*Since Prison v3.2.1-alpha.13*
-
-
-There are a few commands within prison that will allow you list placeholders, search for placeholders, and to test random text that includes placeholders.
-
-
-* **/prison placeholders**
-
-
-* **/prison placeholders list**
-* **/prison placeholders search**
-* **/prison placeholders test**
-
-* **/prison placeholders reload**
-
-NOTE: the `/prison placeholders reload` command only reloads and registers the placeholders with the placeholder integrations. This would be required to enable placeholders on a new mine or new ranks or a new ladder that were added since the last server restart. Also if you reload another plugin, such as papi, you will need to reload the plugins, which just re-registers them.
-
-
-
-* **/prison version** No longer provides a list of placeholders since it's become too large.
-
-
Prison Placeholder Command Listing
diff --git a/docs/prison_video_000_video_list.md b/docs/prison_video_000_video_list.md
new file mode 100644
index 000000000..013f4784d
--- /dev/null
+++ b/docs/prison_video_000_video_list.md
@@ -0,0 +1,32 @@
+# Prison Video Listings
+
+
+
+[Prison Documents - Table of Contents](prison_docs_000_toc.md)
+
+
+## Prison Videos - Basic Setup
+
+
+* **[Prison Video - Auto Configure](prison_video_001_auto_configure.md)**
+
+This video covers the very basics on what you need to do to get your Prison server up and running. Prison has an Auto Configure feature that will setup almost everything you need to run the most basic Prison Server.
+
+
+* **[Prison Video - After Running Auto Configure - Setting Up The Physical Mines](prison_video_002_after_auto_config.md)**
+
+Prison's Auto Configure configures almost everything needed to run a basic Prison Server, including creating all of the virtual mines with assigned blocks, a mine liner, and links the mines to the proper ranks. This video covers how to place a mine, which takes a virtual mine and turns it in to a physical mine. This video covers the different ways you can place a mine.
+
+
+
+## Future Videos Coming Soon
+
+
+* **Prison Video - Mine Liners**
+
+
+* **Prison Video - Adjusting the Size of Your Mines**
+
+
+
+
\ No newline at end of file
diff --git a/docs/prison_video_001_auto_configure.md b/docs/prison_video_001_auto_configure.md
new file mode 100644
index 000000000..5d00bcf9e
--- /dev/null
+++ b/docs/prison_video_001_auto_configure.md
@@ -0,0 +1,108 @@
+# Prison Videos
+
+
+
+[Prison Documents - Table of Contents](prison_docs_000_toc.md)
+
+[Prison Video Listings](prison_video_000_video_list.md)
+
+
+# Prison Videos - Basic Setup - Auto Configure
+
+This video covers the very basics on what you need to do to get your Prison server up and running. Prison has an Auto Configure feature that will setup almost everything you need to run the most basic Prison Server.
+
+
+[video url goes here](url.to.video.com)
+
+
+This document is the transcript for this video. It includes a few screen prints, URLs to resources, and copy and pastable commands. This document will also contain some updates, more information, and clarifications if they are needed.
+
+
+
+
+
+#Video Transcript
+
+> "Hello, this is RoyalBlueRanger and I'm the lead developer of the Prison Plugin. Thank you for your interest in Prison, and for taking the time to view this video. This video will cover the basic setup of a Prison server, which can serve as the foundation of building a uniquely customized server of your own."
+>
+>
+> "If you ever need help with Prison, Please visit our Discord server. You will also find on our Discord server the latest alpha releases, which not only fixes any bugs or issues found, but also contains the new updates that will be included in Prison's next release."
+>
+
+Prison's Discord server:
+[![Discord](https://discordapp.com/api/guilds/332602419483770890/widget.png)](https://discord.gg/DCJ3j6r)
+
+>
+> "Prison works great on Spigot 1.8.8 through Spigot 1.17.1. Since it's built on Spigot, it will also work great on other platforms based upon Bukkit and Spigot, such as paper. For the purpose of this demonstration video, I'm using Spigot 1.8.8."
+>
+>
+> "I should point out that this video will not cover the details on how to build a Spigot server; that would be the subject of a future video. For this video it is assumed you have your sever built and it's ready to be started. But before you start your server, let's first go over some of the basic plugins you will need."
+>
+>
+> "All plugins will need to be placed in the **plugins** directory within your Spigot server's directory. If you do not see that directory, go ahead and create it manually, or just start the server for the first time and spigot will create it for you."
+>
+>
+> "Download the following plugins, which will be in **jar** files. You can find the URLs for these resources within this video's description below, and also within Prison's documentation for this video. You will need this plugin, which is of course **Prison**. Plus **EssentialsX**, **Vault**, **LuckPerms**, **WorldEdit**, and **WorldGuard**. Please note for all of these listed plugins, download the latest version that is available, except for Vault, WorldEdit and WorldGuard, of which you must use the version that is designed for your version of Spigot."
+>
+
+(URLs to all mentioned plugins)
+ * Prison
+ - Download - https://www.spigotmc.org/resources/prison.1223/
+ * EssentialsX
+ - https://www.spigotmc.org/resources/essentialsx.9089/
+ - Download - https://essentialsx.net/downloads.html?branch=stable - Download only the stable release of the "core" component.
+ * Vault
+ - Download - 1.13 to 1.17 - https://www.spigotmc.org/resources/vault.34315/
+ - Download - 1.8 to 1.11 use v1.5.6 - https://dev.bukkit.org/projects/vault/files
+ * LuckPerms
+ - Download - https://www.spigotmc.org/resources/luckperms.28140/
+ - Download - https://luckperms.net/
+ * WorldEdit
+ - Download - https://dev.bukkit.org/projects/worldedit/files
+ * WorldGuard
+ - Download - https://dev.bukkit.org/projects/worldguard/files
+
+(Screen prints of basic directories prior to starting the server the first time)
+
+>
+> "Let me show you the directories of this test server. As you can see, in the server's directory is the plugins folder, the eula.txt file that has been set to `true` so the server starts up fully for the first time, and the spigot jar file along with the startup script to start the server. As you can also see in the plugins directory, are the previously listed plugins."
+>
+>
+>
+> "Once you have placed all of these plugins in the server's **plugin** directory, you can can then start your server. Let it fully startup. It may be a good idea to review the startup messages to ensure everything loaded successfully. Every time you add a new plugin, or make significant changes, you should review the startup messages in the console if something appears to be misbehaving. With these few plugins, the server should startup with no issues, especially if you are using the correct version of Vault, WorldEdit and WorldGuard."
+>
+>
+> "Before we configure Prison, let me first introduce you to some very basic details about Prison. For the purpose of this video, and when using most Prison commands that generate a lot of text and information, it's best to run them within the server's console, instead of in-game."
+>
+>
+> "First off, it is important to know that all commands within Prison can be reviewed with the command `/prison`. This command lists all of Prison's root commands that are available, including any commands that had a conflict with another plugin's commands when prison was registering it's commands. If a listed command has subcommands, it will be indicated in that list. You can then enter that command to drill down to see the list of subcommands."
+>
+
+(Screen print of `/prison`)
+
+>
+> "Another important feature with Prison, is that Prison's command handler is able to provide detailed information about the command, including all parameters, permissions, and even links to some online documentation. To view the **help**, all you need to do is to add the `help` keyword to any command. For example: `/ranks autoConfigure help` provides detailed information on the autoConfigure command.
+>
+
+(Screen print of `/prison autoConfigure help`)
+
+>
+> "Finally let's get to the purpose of this video, running Prison's autoConfigure command."
+>
+> "From the server's console, enter the command:"
+> `/ranks autoConfigure`
+>
+> "The command will run for a few seconds, generate a lot of text, which documents all of the configurations that it sets up. Review the generated text in the console if you like."
+>
+>
+> "And that's it. This is the end of the video, which just covered the basics of running the command `/prison autoConfigure`. The Prison server is now using the most common features and settings enabled that will allow your server to work properly."
+>
+>
+> "In the next video we will cover what you need to do in-game to finalize your server setup, which is also very simple. The details that will be covered is configuring WorldGuard to protect your Prison world so players cannot break blocks outside of the mines. It will also explain the various ways you can **set the mines** which will turn the virtual mines in to fully functional physical mines. At the end of that video, we will have a fully functional Prison server."
+
+
+(end of video)
+
+
+
+
diff --git a/docs/prison_video_002_after_auto_config.md b/docs/prison_video_002_after_auto_config.md
new file mode 100644
index 000000000..881d37975
--- /dev/null
+++ b/docs/prison_video_002_after_auto_config.md
@@ -0,0 +1,36 @@
+# Prison Videos
+
+
+
+[Prison Documents - Table of Contents](prison_docs_000_toc.md)
+
+[Prison Video Listings](prison_video_000_video_list.md)
+
+
+# Prison Videos - Basic Setup
+# After Running Auto Configure - Setting Up The Physical Mines
+
+This video covers the very basics on what you need to do to get your Prison server up and running. Prison has an Auto Configure feature that will setup almost everything you need to run the most basic Prison Server.
+
+
+[video url goes here](url.to.video.com)
+
+
+This document is the transcript for this video. It includes a few screen prints, URLs to resources, and copy and pastable commands. This document will also contain some updates, more information, and clarifications if they are needed.
+
+
+
+
+
+#Video Transcript
+
+> "Hello, this is RoyalBlueRanger and I'm the lead developer of the Prison Plugin. Thank you for your interest in Prison, and for taking the time to view this video. This video will cover the basic setup of a Prison server, which can serve as the foundation of building a uniquely customized server of your own."
+>
+>
+> "If you ever need help with Prison, Please visit our Discord server. You will also find on our Discord server the latest alpha releases, which not only fixes any bugs or issues found, but also contains the new updates that will be included in Prison's next release."
+>
+>
+ (to be determined...)
+
+
+
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
index 7706c53f6..a51d4fbdb 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.2.10
+version=3.2.11
#version=3.2.8.2
#version=3.3.0-alpha.6
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 bbf1b9ae8..2c47766ff 100644
--- a/prison-core/src/main/java/tech/mcprison/prison/Prison.java
+++ b/prison-core/src/main/java/tech/mcprison/prison/Prison.java
@@ -88,7 +88,10 @@ public class Prison
private CommandHandler commandHandler;
private SelectionManager selectionManager;
private EventBus eventBus;
+
private LocaleManager localeManager;
+ private File moduleDataFolder;
+
// private ItemManager itemManager;
private ErrorManager errorManager;
private TroubleshootManager troubleshootManager;
@@ -135,11 +138,27 @@ public static Prison get() {
public LocaleManager getLocaleManager() {
if ( this.localeManager == null ) {
+
this.localeManager = new LocaleManager(this, "lang/core");
}
return localeManager;
}
+ /**
+ * Returns this module's data folder, where all data can be stored.
+ * It is located in the Prison data folder, and has the name of the module.
+ * It is automatically generated.
+ *
+ * @return The {@link File} representing the data folder.
+ */
+ public File getModuleDataFolder() {
+
+ if ( moduleDataFolder == null ) {
+ this.moduleDataFolder = Module.setupModuleDataFolder( "core" );
+ }
+ return moduleDataFolder;
+ }
+
/**
* 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.
@@ -503,7 +522,7 @@ public void setStorageSize( long storageSize ) {
private boolean initDataFolder() {
// Creates the /Prison directory, for core configuration.
this.dataFolder = getPlatform().getPluginDirectory();
- return this.dataFolder.exists() || this.dataFolder.mkdir();
+ return this.dataFolder.exists() || this.dataFolder.mkdirs();
}
private boolean initMetaDatabase() {
@@ -634,6 +653,8 @@ public File getDataFolder() {
return dataFolder;
}
+
+
/**
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 e28d7cf16..ea12bb5aa 100644
--- a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java
+++ b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java
@@ -25,6 +25,7 @@
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Optional;
@@ -55,6 +56,7 @@
import tech.mcprison.prison.troubleshoot.Troubleshooter;
import tech.mcprison.prison.util.JumboTextFont;
import tech.mcprison.prison.util.PrisonJarReporter;
+import tech.mcprison.prison.util.Text;
/**
* Root commands for managing the platform as a whole, in-game.
@@ -345,21 +347,31 @@ else if ( !isBasic ) {
if ( getRegisteredPlugins().size() > 0 ) {
display.addText("");
display.addText( "&7Registered Plugins: " );
- StringBuilder sb = new StringBuilder();
- for ( String plugin : getRegisteredPlugins() ) {
- if ( sb.length() == 0) {
- sb.append( ". " );
- sb.append( plugin );
- } else {
- sb.append( ", " );
- sb.append( plugin );
- display.addText( sb.toString() );
- sb.setLength( 0 );
- }
- }
- if ( sb.length() > 0 ) {
- display.addText( sb.toString());
- }
+
+ List plugins = getRegisteredPlugins();
+ Collections.sort( plugins );
+ List plugins2Cols = Text.formatColumnsFromList( plugins, 2 );
+
+ for ( String rp : plugins2Cols ) {
+
+ display.addText( rp );
+ }
+
+// StringBuilder sb = new StringBuilder();
+// for ( String plugin : getRegisteredPlugins() ) {
+// if ( sb.length() == 0) {
+// sb.append( ". " );
+// sb.append( plugin );
+// } else {
+// sb.append( ", " );
+// sb.append( plugin );
+// display.addText( sb.toString() );
+// sb.setLength( 0 );
+// }
+// }
+// if ( sb.length() > 0 ) {
+// display.addText( sb.toString());
+// }
}
// This version of plugins does not have all the registered commands:
@@ -882,92 +894,96 @@ public void autoFeaturesInformation(CommandSender sender) {
afw.isBoolean( AutoFeatures.isAutoManagerEnabled ));
-
-
- display.addText( "&b " );
- display.addText( "&b options.blockBreakEvents.isProcessTokensEnchantExplosiveEvents: %s",
- afw.isBoolean( AutoFeatures.isProcessTokensEnchantExplosiveEvents ) );
- display.addText( "&b options.blockBreakEvents.TokenEnchantBlockExplodeEventPriority: %s",
- afw.getMessage( AutoFeatures.isProcessTokensEnchantExplosiveEvents ) );
-
- display.addText( "&b options.blockBreakEvents.isProcessCrazyEnchantsBlockExplodeEvents: %s",
- afw.isBoolean( AutoFeatures.isProcessCrazyEnchantsBlockExplodeEvents ) );
- display.addText( "&b options.blockBreakEvents.CrazyEnchantsBlastUseEventPriority: %s",
- afw.getMessage( AutoFeatures.CrazyEnchantsBlastUseEventPriority ) );
-
- display.addText( "&b options.blockBreakEvents.isProcessZenchantsBlockExplodeEvents: %s",
- afw.isBoolean( AutoFeatures.isProcessZenchantsBlockExplodeEvents ) );
- display.addText( "&b options.blockBreakEvents.ZenchantmentsBlockShredEventPriority: %s",
- afw.getMessage( AutoFeatures.ZenchantmentsBlockShredEventPriority ) );
-
- display.addText( "&b options.blockBreakEvents.isProcessPrisonEnchantsExplosiveEvents: %s",
- afw.isBoolean( AutoFeatures.isProcessPrisonEnchantsExplosiveEvents ) );
- display.addText( "&b options.blockBreakEvents.PrisonEnchantsExplosiveEventPriority: %s",
- afw.getMessage( AutoFeatures.PrisonEnchantsExplosiveEventPriority ) );
-
-
- display.addText( "&b " );
- display.addText( "&b Normal Drops (if auto pickup is off):" );
- display.addText( "&b options.normalDrop.isProcessNormalDropsEvents: %s",
- afw.isBoolean( AutoFeatures.handleNormalDropsEvents ) );
-
- display.addText( "&b " );
- display.addText( "&7 NOTE: If this is enabled, then lore and perms will override the settings for " );
- display.addText( "&7 pickup, smelt, and block when they are turned off." );
-
-
- display.addText( "&b " );
-
-
- display.addText( "&b options.autoPickup.autoPickupEnabled %s",
- afw.isBoolean( AutoFeatures.autoPickupEnabled ));
-
- display.addText( "&b options.autoSmelt.autoSmeltEnabled %s",
- afw.isBoolean( AutoFeatures.autoSmeltEnabled ));
- display.addText( "&b options.autoBlock.autoBlockEnabled %s",
- afw.isBoolean( AutoFeatures.autoBlockEnabled ));
-
-
-
- display.addText( "&b " );
- display.addText( "&b options.general.isCalculateDurabilityEnabled %s",
- afw.isBoolean( AutoFeatures.isCalculateDurabilityEnabled ));
- display.addText( "&b options.general.isCalculateFortuneEnabled %s",
- afw.isBoolean( AutoFeatures.isCalculateFortuneEnabled ));
- display.addText( "&b options.general.isCalculateAltFortuneOnAllBlocksEnabled %s",
- afw.isBoolean( AutoFeatures.isCalculateAltFortuneOnAllBlocksEnabled ));
- display.addText( "&b options.general.isCalculateXPEnabled %s",
- afw.isBoolean( AutoFeatures.isCalculateXPEnabled ));
- display.addText( "&b options.general.givePlayerXPAsOrbDrops %s",
- afw.isBoolean( AutoFeatures.givePlayerXPAsOrbDrops ));
- display.addText( "&b options.general.fortuneMultiplierMax %s",
- afw.getMessage( AutoFeatures.fortuneMultiplierMax ));
-
- display.addText( "&b " );
- display.addText( "&b options.isProcessTokensEnchantExplosiveEvents %s",
- afw.isBoolean( AutoFeatures.isProcessTokensEnchantExplosiveEvents ));
- display.addText( "&b options.isProcessCrazyEnchantsBlockExplodeEvents %s",
- afw.isBoolean( AutoFeatures.isProcessCrazyEnchantsBlockExplodeEvents ));
- display.addText( "&b options.isProcessMcMMOBlockBreakEvents %s",
- afw.isBoolean( AutoFeatures.isProcessMcMMOBlockBreakEvents ));
- display.addText( "&b " );
-
-
- display.addText( "&b " );
- display.addText( "&b options.lore.isLoreEnabled %s",
- afw.isBoolean( AutoFeatures.isLoreEnabled ));
- display.addText( "&b options.lore.loreTrackBlockBreakCount %s",
- afw.isBoolean( AutoFeatures.loreTrackBlockBreakCount ));
- display.addText( "&b options.lore.loreBlockBreakCountName %s",
- afw.getMessage( AutoFeatures.loreBlockBreakCountName ));
-
- display.addText( "&b options.lore.loreBlockExplosionCountName %s",
- afw.getMessage( AutoFeatures.loreBlockExplosionCountName ));
- display.addText( "&b options.lore.loreDurabiltyResistance %s",
- afw.isBoolean( AutoFeatures.loreDurabiltyResistance ));
- display.addText( "&b options.lore.loreDurabiltyResistanceName %s",
- afw.getMessage( AutoFeatures.loreDurabiltyResistanceName ));
- display.addText( "&b " );
+ if ( afw.isBoolean( AutoFeatures.isAutoManagerEnabled ) ) {
+
+
+ display.addText( "&b " );
+ display.addText( "&b options.blockBreakEvents.applyBlockBreaksThroughSyncTask: %s",
+ afw.getMessage( AutoFeatures.applyBlockBreaksThroughSyncTask ) );
+
+ display.addText( "&b options.blockBreakEvents.cancelAllBlockBreakEvents: %s",
+ afw.getMessage( AutoFeatures.cancelAllBlockBreakEvents ) );
+
+ display.addText( "&b options.blockBreakEvents.cancelAllBlockEventBlockDrops: %s",
+ afw.getMessage( AutoFeatures.cancelAllBlockEventBlockDrops ) );
+
+
+ display.addText( "&b options.blockBreakEvents.TokenEnchantBlockExplodeEventPriority: %s",
+ afw.getMessage( AutoFeatures.TokenEnchantBlockExplodeEventPriority ) );
+
+ display.addText( "&b options.blockBreakEvents.CrazyEnchantsBlastUseEventPriority: %s",
+ afw.getMessage( AutoFeatures.CrazyEnchantsBlastUseEventPriority ) );
+
+ display.addText( "&b options.blockBreakEvents.ZenchantmentsBlockShredEventPriority: %s",
+ afw.getMessage( AutoFeatures.ZenchantmentsBlockShredEventPriority ) );
+
+ display.addText( "&b options.blockBreakEvents.PrisonEnchantsExplosiveEventPriority: %s",
+ afw.getMessage( AutoFeatures.PrisonEnchantsExplosiveEventPriority ) );
+
+ display.addText( "&b options.blockBreakEvents.ProcessPrisons_ExplosiveBlockBreakEventsPriority: %s",
+ afw.getMessage( AutoFeatures.ProcessPrisons_ExplosiveBlockBreakEventsPriority ) );
+
+
+
+ display.addText( "&b " );
+ display.addText( "&b Normal Drops (if auto pickup is off):" );
+ display.addText( "&b options.normalDrop.isProcessNormalDropsEvents: %s",
+ afw.isBoolean( AutoFeatures.handleNormalDropsEvents ) );
+
+ display.addText( "&b " );
+ display.addText( "&7 NOTE: If this is enabled, then lore and perms will override the settings for " );
+ display.addText( "&7 pickup, smelt, and block when they are turned off." );
+
+
+ display.addText( "&b " );
+
+
+ display.addText( "&b options.autoPickup.autoPickupEnabled %s",
+ afw.isBoolean( AutoFeatures.autoPickupEnabled ));
+
+ display.addText( "&b options.autoSmelt.autoSmeltEnabled %s",
+ afw.isBoolean( AutoFeatures.autoSmeltEnabled ));
+ display.addText( "&b options.autoBlock.autoBlockEnabled %s",
+ afw.isBoolean( AutoFeatures.autoBlockEnabled ));
+
+
+
+ display.addText( "&b " );
+ display.addText( "&b options.general.isCalculateDurabilityEnabled %s",
+ afw.isBoolean( AutoFeatures.isCalculateDurabilityEnabled ));
+ display.addText( "&b options.general.isCalculateFortuneEnabled %s",
+ afw.isBoolean( AutoFeatures.isCalculateFortuneEnabled ));
+ display.addText( "&b options.general.isCalculateAltFortuneOnAllBlocksEnabled %s",
+ afw.isBoolean( AutoFeatures.isCalculateAltFortuneOnAllBlocksEnabled ));
+ display.addText( "&b options.general.isCalculateXPEnabled %s",
+ afw.isBoolean( AutoFeatures.isCalculateXPEnabled ));
+ display.addText( "&b options.general.givePlayerXPAsOrbDrops %s",
+ afw.isBoolean( AutoFeatures.givePlayerXPAsOrbDrops ));
+ display.addText( "&b options.general.fortuneMultiplierMax %s",
+ afw.getMessage( AutoFeatures.fortuneMultiplierMax ));
+
+ display.addText( "&b " );
+ display.addText( "&b options.isProcessMcMMOBlockBreakEvents %s",
+ afw.isBoolean( AutoFeatures.isProcessMcMMOBlockBreakEvents ));
+ display.addText( "&b " );
+
+
+ display.addText( "&b " );
+ display.addText( "&b options.lore.isLoreEnabled %s",
+ afw.isBoolean( AutoFeatures.isLoreEnabled ));
+ display.addText( "&b options.lore.loreTrackBlockBreakCount %s",
+ afw.isBoolean( AutoFeatures.loreTrackBlockBreakCount ));
+ display.addText( "&b options.lore.loreBlockBreakCountName %s",
+ afw.getMessage( AutoFeatures.loreBlockBreakCountName ));
+
+ display.addText( "&b options.lore.loreBlockExplosionCountName %s",
+ afw.getMessage( AutoFeatures.loreBlockExplosionCountName ));
+ display.addText( "&b options.lore.loreDurabiltyResistance %s",
+ afw.isBoolean( AutoFeatures.loreDurabiltyResistance ));
+ display.addText( "&b options.lore.loreDurabiltyResistanceName %s",
+ afw.getMessage( AutoFeatures.loreDurabiltyResistanceName ));
+ display.addText( "&b " );
+ }
@@ -990,10 +1006,12 @@ public void toggleDebug(CommandSender sender,
@Wildcard(join=true)
@Arg(name = "targets", def = " ",
description = "Optional. Enable or disable a debugging target. " +
- "[on, off, targets, jarScan, " +
- "testPlayerUtil, testLocale, rankup] " +
+ "[on, off, targets, selective, jarScan, " +
+ "testPlayerUtil, testLocale, rankup ] " +
"Use 'targets' to list all available targets. Use 'on' or 'off' to toggle " +
- "on and off individual targets, or all targets if no target is specified. " +
+ "on and off individual targets, or 'all' targets if no target is specified. " +
+ "If any targets are enabled, then debug in general will be enabled. Selective will only " +
+ "activate debug with the specified targets. " +
"jarScan will identify what Java version compiled the class files within the listed jars"
) String targets ) {
@@ -1022,7 +1040,7 @@ public void toggleDebug(CommandSender sender,
return;
}
-
+ // Applies normal and selective targets:
Output.get().applyDebugTargets( targets );
String message = "Global Debug Logging is " + (Output.get().isDebug() ? "enabled" : "disabled");
@@ -1041,6 +1059,19 @@ public void toggleDebug(CommandSender sender,
}
}
+ Set selectiveDebugTargets = Output.get().getSelectiveDebugTargets();
+
+ if ( selectiveDebugTargets.size() > 0 ) {
+ message = ". Selective Debug Targets:";
+ sender.sendMessage( message );
+
+ for ( DebugTarget target : selectiveDebugTargets )
+ {
+ message = String.format( ". . Target: %s", target.name() );
+ sender.sendMessage( message );
+ }
+ }
+
String validTargets = Output.get().getDebugTargetsString();
message = String.format( ". Valid Targets: %s", validTargets );
sender.sendMessage( message );
@@ -1260,7 +1291,7 @@ public void supportSubmitMines(CommandSender sender
List files = listFiles( "data_storage/mines/mines/", ".json" );
-
+ Collections.sort( files );
StringBuilder text = new StringBuilder();
@@ -1473,7 +1504,7 @@ 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. " +
- "[blockBreak, traceBlockBreak, chat]"
+ "[blockBreak, traceBlockBreak, chat, playerInteract]"
) String listener
) {
@@ -1502,6 +1533,11 @@ public void supportListenersDump(CommandSender sender,
return;
}
+ if ( "playerInteract".equalsIgnoreCase( listener ) ) {
+
+ results = Prison.get().getPlatform().dumpEventListenersPlayerInteractEvents();
+ }
+
if ( results != null ) {
for ( String line : results.split( "\n" ) ) {
@@ -1512,6 +1548,240 @@ public void supportListenersDump(CommandSender sender,
}
+
+ @Command(identifier = "prison tokens balance",
+ description = "Prison tokens: a player's current balance.",
+ // aliases = "tokens bal",
+ permissions = "tokens.bal",
+ altPermissions = "tokens.bal.others" )
+ public void tokensBalance(CommandSender sender,
+ @Arg(name = "player", def = "", description = "Player to get token balance for. " +
+ "If player is online this is not required for their own balance. " +
+ "This is needed if used from console or to get the balance of " +
+ "another player.") String playerName
+ ) {
+
+ Player player = getPlayer( sender );
+
+ // If player is null, then need to use the playerName, so if it's empty, we have a problem:
+ if ( ( player == null || !player.isOnline() ) &&
+ ( playerName == null || playerName.isEmpty() ) ) {
+
+ String message = "Prison Tokens: A player's name is required when used from console.";
+
+ Output.get().logWarn( message );
+ return;
+ }
+ else
+ if ( playerName != null && !playerName.isEmpty() ){
+
+ if ( !sender.isOp() &&
+ !sender.hasPermission( "tokens.bal.others" ) ) {
+ String message = "Prison Tokens: You do not have permission to view other " +
+ "player's balances.";
+ Output.get().logWarn( message );
+ return;
+ }
+
+ Player tempPlayer = getPlayer( playerName );
+
+ if ( tempPlayer != null ) {
+ player = tempPlayer;
+ }
+ }
+
+
+// player.getPlayerCache()
+
+ DecimalFormat dFmt = new DecimalFormat("#,##0");
+
+ long tokens = player.getPlayerCachePlayerData().getTokens();
+
+ String tokensMsg = dFmt.format( tokens );
+
+ String message = String.format( "&3%s has %s tokens.", player.getName(), tokensMsg );
+
+ sender.sendMessage( message );
+ }
+
+ @Command(identifier = "prison tokens add",
+ description = "Prison tokens Admin: an admins tool to give more tokens to a player",
+ permissions = "tokens.admin.add" )
+ public void tokensAdd( CommandSender sender,
+ @Arg(name = "player",
+ description = "Player to add the tokens to.") String playerName,
+
+ @Arg(name = "amount", verifiers = "min[1]",
+ description = "The number of tokens to add to the player's account.") long amount
+ ) {
+
+ if ( playerName == null || playerName.isEmpty() ) {
+
+ String message = "Prison Tokens: A player's name is required.";
+ Output.get().logWarn( message );
+ return;
+ }
+
+ DecimalFormat dFmt = new DecimalFormat("#,##0");
+
+ if ( amount <= 0 ) {
+
+ String message =
+ String.format(
+ "Prison Tokens: Invalid amount: '%s'. Must be greater than zero.",
+ dFmt.format( amount ) );
+ Output.get().logWarn( message );
+ return;
+ }
+
+ Player player = getPlayer( playerName );
+
+ player.getPlayerCachePlayerData().addTokensAdmin( amount );
+
+
+
+ String tokens = dFmt.format( player.getPlayerCachePlayerData().getTokens() );
+
+ String message = String.format( "&3%s now has &7%s &3tokens after adding &7%s&3.",
+ player.getName(), tokens, dFmt.format( amount ) );
+
+ // The person adding the tokens, or console:
+ sender.sendMessage( message );
+
+ // The player getting the tokens, if they are online:
+ if ( player.isOnline() && !player.getName().equalsIgnoreCase( sender.getName() ) ) {
+
+ player.sendMessage( message );
+ }
+ }
+
+ @Command(identifier = "prison tokens remove",
+ description = "Prison tokens Admin: an admins tool to remove tokens from a player. " +
+ "It is possible to remove more tokens than what the player has, which can " +
+ "be treated like a debt.",
+ permissions = "tokens.admin.add" )
+ public void tokensRemove( CommandSender sender,
+ @Arg(name = "player",
+ description = "Player to remove the tokens from.") String playerName,
+
+ @Arg(name = "amount", verifiers = "min[1]",
+ description = "The number of tokens to remove from the player's account. " +
+ "This amount must be positive. ") long amount
+ ) {
+
+ if ( playerName == null || playerName.isEmpty() ) {
+
+ String message = "Prison Tokens: A player's name is required.";
+ Output.get().logWarn( message );
+ return;
+ }
+
+ DecimalFormat dFmt = new DecimalFormat("#,##0");
+
+ if ( amount <= 0 ) {
+
+ String message =
+ String.format(
+ "Prison Tokens: Invalid amount: '%s'. Must be greater than zero.",
+ dFmt.format( amount ) );
+ Output.get().logWarn( message );
+ return;
+ }
+
+ Player player = getPlayer( playerName );
+
+ player.getPlayerCachePlayerData().removeTokensAdmin( amount );
+
+
+
+ String tokens = dFmt.format( player.getPlayerCachePlayerData().getTokens() );
+
+ String message = String.format( "&3%s now has &7%s &3tokens after removing &7%s&3.",
+ player.getName(), tokens, dFmt.format( amount ) );
+
+ // The person adding the tokens, or console:
+ sender.sendMessage( message );
+
+ // The player getting the tokens, if they are online:
+ if ( player.isOnline() && !player.getName().equalsIgnoreCase( sender.getName() ) ) {
+
+ player.sendMessage( message );
+ }
+ }
+
+ @Command(identifier = "prison tokens set",
+ description = "Prison tokens Admin: an admins tool to set number of tokens " +
+ "for a player to a specific amount. " +
+ "It is possible to set the tokens to a negavtie amount, which can " +
+ "be treated like a debt.",
+ permissions = "tokens.admin.add" )
+ public void tokensSet( CommandSender sender,
+ @Arg(name = "player",
+ description = "Player to remove the tokens from.") String playerName,
+
+ @Arg(name = "amount",
+ description = "The number of tokens to set the player's account to. " +
+ "This amount must amount can be negative. ") long amount
+ ) {
+
+ if ( playerName == null || playerName.isEmpty() ) {
+
+ String message = "Prison Tokens: A player's name is required.";
+ Output.get().logWarn( message );
+ return;
+ }
+
+ DecimalFormat dFmt = new DecimalFormat("#,##0");
+
+ Player player = getPlayer( playerName );
+
+// // Set to zero:
+// long totalTokens = player.getPlayerCachePlayerData().getTokens();
+// player.getPlayerCachePlayerData().removeTokensAdmin( totalTokens );
+
+
+ player.getPlayerCachePlayerData().setTokensAdmin( amount );
+
+
+ String tokens = dFmt.format( player.getPlayerCachePlayerData().getTokens() );
+
+ String message = String.format( "&3%s now has &7%s &3tokens.",
+ player.getName(), tokens );
+
+ // The person adding the tokens, or console:
+ sender.sendMessage( message );
+
+ // The player getting the tokens, if they are online:
+ if ( player.isOnline() && !player.getName().equalsIgnoreCase( sender.getName() ) ) {
+
+ player.sendMessage( message );
+ }
+ }
+
+
+
+ /**
+ *
This function tries to first get the online player, otherwise it
+ * gets an offline player. Hopefully it always returns a player if the
+ * have been on the server before.
+ *
+ *
+ * @param playerName
+ * @return
+ */
+ private Player getPlayer( String playerName ) {
+ Player player = null;
+ if ( playerName != null && !playerName.trim().isEmpty() ) {
+
+ player = Prison.get().getPlatform().getPlayer( playerName ).orElse( null );
+ }
+ if ( player == null ) {
+
+ player = Prison.get().getPlatform().getOfflinePlayer( playerName ).orElse( null );
+ }
+ return player;
+ }
+
// This functionality should not be available in v3.2.1! If someone is still running Prison 2.x.x
// then they must first upgrade to
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 d92b99567..64fe470c1 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
@@ -49,28 +49,36 @@ public enum AutoFeatures {
blockBreakEvents(options),
- blockBreakEventPriority(blockBreakEvents, "LOW"),
+ // Setting this to true will cancel the block break events (normal prison behavior):
+ cancelAllBlockBreakEvents(blockBreakEvents, true),
+ // Setting this to false will not zero out the block drops (normal prison behavior).
+ // When set to true, it will zero it out so if the block break event is not canceled,
+ // then it will prevent double drops:
+ cancelAllBlockEventBlockDrops(blockBreakEvents, false),
+
+
+ applyBlockBreaksThroughSyncTask(blockBreakEvents, true),
+
+
+ blockBreakEventPriority(blockBreakEvents, "LOW"),
- isProcessTokensEnchantExplosiveEvents(blockBreakEvents, false),
TokenEnchantBlockExplodeEventPriority(blockBreakEvents, "DISABLED"),
- isProcessCrazyEnchantsBlockExplodeEvents(blockBreakEvents, false),
CrazyEnchantsBlastUseEventPriority(blockBreakEvents, "DISABLED"),
- isProcessZenchantsBlockExplodeEvents(blockBreakEvents, false),
ZenchantmentsBlockShredEventPriority(blockBreakEvents, "DISABLED"),
- isProcessPrisonEnchantsExplosiveEvents(blockBreakEvents, false),
PrisonEnchantsExplosiveEventPriority(blockBreakEvents, "DISABLED"),
- isProcessPrisons_ExplosiveBlockBreakEvents(blockBreakEvents, false),
- ProcessPrisons_ExplosiveBlockBreakEvents(blockBreakEvents, "DISABLED"),
+ ProcessPrisons_ExplosiveBlockBreakEventsPriority(blockBreakEvents, "DISABLED"),
blockBreakEvents__ReadMe(blockBreakEvents,
"Use the following event priorities with the blockBreakEvents: " +
"DISABLED, LOWEST, LOW, NORMAL, HIGH, HIGHEST, MONITOR" ),
+
+
general(options),
@@ -82,12 +90,40 @@ public enum AutoFeatures {
isCalculateXPEnabled(general, true),
givePlayerXPAsOrbDrops(general, false),
- dropItemsIfInventoryIsFull(general, true),
- playSoundIfInventoryIsFull(general, true),
- hologramIfInventoryIsFull(general, false),
+
+
+ inventory(options),
+
+
+ isAutoSellPerBlockBreakEnabled(inventory, false),
+// isAutoSellPerBlockBreakInlinedEnabled(general, false),
+
+ isAutoSellIfInventoryIsFull(inventory, true),
+
+ dropItemsIfInventoryIsFull(inventory, true),
+
+ playSoundIfInventoryIsFull(inventory, true),
+ playSoundIfInventoryIsFullSound(inventory, "block_note_block_pling" ),
+ playSoundIfInventoryIsFullSoundVolume(inventory, 4.0d ),
+ playSoundIfInventoryIsFullSoundPitch(inventory, 1.0d ),
+ playSoundIfInventoryIsFullSound__readme(inventory,
+ "The name of the sound must be valid for the server platform and " +
+ "its version, and is case insensitive. To get a list of valid " +
+ "sounds use the command: " +
+ "'/prison utils sounds list '. Page is optional. Use page " +
+ "numbers to see all available sounds. An invalid sound will " +
+ "default to NOTE_PLING, BLOCK_NOTE_PLING, or BLOCK_NOTE_BLOCK_PLING, " +
+ "as valid for your server."),
+
+ actionBarMessageIfInventoryIsFull(inventory, true),
+// hologramIfInventoryIsFull(general, false),
- isAutoSellPerBlockBreakEnabled(general, false),
- isAutoSellPerBlockBreakInlinedEnabled(general, false),
+
+
+ tokens(options),
+
+ tokensEnabled( tokens, false ),
+ tokensBlocksPerToken( tokens, 100 ),
permissions(options),
@@ -232,11 +268,12 @@ public enum AutoFeatures {
- debug(options),
- isDebugSupressOnBlockBreakEventCancels(debug, false),
- isDebugSupressOnTEExplodeEventCancels(debug, false),
- isDebugSupressOnCEBlastUseEventCancels(debug, false),
- isDebugSupressOnPEExplosiveEventCancels(debug, false)
+// debug(options),
+// isDebugSupressOnBlockBreakEventCancels(debug, false),
+// isDebugSupressOnTEExplodeEventCancels(debug, false),
+// isDebugSupressOnCEBlastUseEventCancels(debug, false),
+// isDebugSupressOnPEExplosiveEventCancels(debug, false),
+// isDebugSupressOnPrisonMinesBlockBreakEventCancels(debug, false)
;
@@ -348,6 +385,24 @@ private AutoFeatures(AutoFeatures section, int value) {
this.doubleValue = null;
this.listValue = new ArrayList<>();
}
+ private AutoFeatures(AutoFeatures section, double value) {
+ this.parent = section;
+ this.isSection = false;
+ this.isBoolean = false;
+ this.isMessage = false;
+ this.isInteger = false;
+ this.isLong = false;
+ this.isDouble = true;
+ this.isStringList = false;
+
+ this.path = section.getKey();
+ this.message = null;
+ this.value = null;
+ this.intValue = null;
+ this.longValue = null;
+ this.doubleValue = value;
+ this.listValue = new ArrayList<>();
+ }
private AutoFeatures(AutoFeatures section, NodeType nodeType, String... values ) {
this.parent = section;
this.isSection = false;
@@ -505,13 +560,27 @@ public int getInteger( Map conf ) {
IntegerNode intValue = (IntegerNode) conf.get( getKey() );
results = intValue.getValue();
}
- else if ( getValue() != null ) {
+ else if ( getIntValue() != null ) {
results = getIntValue();
}
return results;
}
+ public double getDouble( Map conf ) {
+ double results = 0d;
+
+ if ( conf.containsKey(getKey()) && conf.get( getKey() ).isDoubleNode() ) {
+ DoubleNode doubleValue = (DoubleNode) conf.get( getKey() );
+ results = doubleValue.getValue();
+ }
+ else if ( getDoubleValue() != null ) {
+ results = getDoubleValue();
+ }
+
+ return results;
+ }
+
public List getStringList( Map conf ) {
List results = null;
@@ -519,10 +588,14 @@ public List getStringList( Map conf ) {
StringListNode list = (StringListNode) conf.get( getKey() );
results = list.getValue();
}
- else if ( getValue() != null ) {
- results = new ArrayList<>();
+ else if ( getListValue() != null && getListValue().size() > 0 ) {
+ results = getListValue();
}
+ if ( results == null ) {
+ results = new ArrayList<>();
+ }
+
return results;
}
@@ -706,6 +779,10 @@ public int getInteger( AutoFeatures feature ) {
return feature.getInteger( getConfig() );
}
+ public double getDouble( AutoFeatures feature ) {
+ return feature.getDouble( getConfig() );
+ }
+
public List getFeatureStringList( AutoFeatures feature ) {
return feature.getStringList( getConfig() );
@@ -724,7 +801,7 @@ public boolean saveConf() {
* initial saving of the data since the original file will not be deleted first.
*
*
- * @param afConfig
+ * @param config
* @return
*/
private boolean saveConf( Map config ) {
diff --git a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesWrapper.java b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesWrapper.java
index 91a9f0f2c..50f964a89 100644
--- a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesWrapper.java
+++ b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/AutoFeaturesWrapper.java
@@ -48,6 +48,10 @@ public int getInteger( AutoFeatures feature ) {
return autoFeaturesConfig.getInteger( feature );
}
+ public double getDouble( AutoFeatures feature ) {
+ return autoFeaturesConfig.getDouble( feature );
+ }
+
public List getListString( AutoFeatures feature ) {
List results = null;
if ( feature.isStringList() ) {
diff --git a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/PlayerMessageData.java b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/PlayerMessageData.java
new file mode 100644
index 000000000..a839d4d86
--- /dev/null
+++ b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/PlayerMessageData.java
@@ -0,0 +1,122 @@
+package tech.mcprison.prison.autofeatures;
+
+import tech.mcprison.prison.autofeatures.PlayerMessaging.MessageType;
+
+public class PlayerMessageData
+{
+ private final long startTime;
+ private long targetEndTime;
+
+ private final MessageType messageType;
+ private final String message;
+ private long ticks = 20L;
+
+ private int submitted = 0;
+ private int hits = -1;
+
+ private int taskId;
+
+
+ public PlayerMessageData( MessageType messageType, String message, long ticks ) {
+ super();
+
+ this.startTime = System.currentTimeMillis();
+
+ this.targetEndTime = this.startTime + ( ticks * 50 );
+
+ this.messageType = messageType;
+ this.message = message;
+ this.ticks = ticks;
+
+ this.hits++;
+ }
+
+
+ /**
+ *
When a new message has been submitted to be displayed to the
+ * player, this function will check to see if the same message is
+ * currently being displayed to the player by checking if the
+ * current system time is greater than targetEndTime.
+ *
+ *
+ *
If the current time is less than targetEndTime, then that
+ * indicates that the message is active and therefore can be
+ * ignored.
+ *
+ *
+ *
If the current time is greater than the targetEndTime then
+ * that indicates that the message should be displayed. The way
+ * it is indicated that the message needs to be displayed is
+ * by setting the jobId to -1, which indicates no job is currently
+ * running.
+ *
+ *
+ * @param ticks
+ */
+ public void addRepeatMessage( long ticks ) {
+ this.hits++;
+
+ long currentTime = System.currentTimeMillis();
+
+ // if currentType is greater than targetEndTime then
+ // needs to submit a new task, which will be indicated
+ // by setting the jobId to -1.
+ if ( currentTime > targetEndTime ) {
+ setTaskId( -1 );
+ }
+ else {
+ // do nothing... the message is already being displayed
+ }
+ }
+
+ public long getStartTime() {
+ return startTime;
+ }
+
+ public long getTargetEndTime() {
+ return targetEndTime;
+ }
+ public void setTargetEndTime( long targetEndTime ) {
+ this.targetEndTime = targetEndTime;
+ }
+
+ public MessageType getMessageType() {
+ return messageType;
+ }
+
+ public String getMessage()
+ {
+ return message;
+ }
+
+ public long getTicks() {
+ return ticks;
+ }
+ public void setTicks( long ticks ) {
+ this.ticks = ticks;
+ }
+
+ public int getSubmitted() {
+ return submitted;
+ }
+ public void setSubmitted( int submitted ) {
+ this.submitted = submitted;
+ }
+
+ public int getHits() {
+ return hits;
+ }
+ public void setHits( int hits ) {
+ this.hits = hits;
+ }
+
+ public int getTaskId() {
+ return taskId;
+ }
+ public void setTaskId( int taskId ) {
+ this.taskId = taskId;
+
+ this.submitted++;
+ }
+
+}
diff --git a/prison-core/src/main/java/tech/mcprison/prison/autofeatures/PlayerMessaging.java b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/PlayerMessaging.java
new file mode 100644
index 000000000..d23fea22c
--- /dev/null
+++ b/prison-core/src/main/java/tech/mcprison/prison/autofeatures/PlayerMessaging.java
@@ -0,0 +1,70 @@
+package tech.mcprison.prison.autofeatures;
+
+import java.util.TreeMap;
+
+public class PlayerMessaging
+{
+
+ private final TreeMap> messages;
+
+
+ public enum MessageType {
+ title,
+ actionBar;
+ }
+
+ public PlayerMessaging() {
+
+ this.messages = new TreeMap<>();
+
+ // Preload all the message types and setup their TreeMaps
+ for ( MessageType mType : MessageType.values() ) {
+
+ getMessages().put( mType, new TreeMap<>() );
+ }
+
+ }
+
+ /**
+ *
This function adds a message to the player's PlayerCached object. It uses the
+ * default duration of 40 ticks (2 seconds).
+ *
+ *
+ *
If the same message is active, then the message will not be submitted.
+ *
+ *
+ * @param messageType
+ * @param message
+ * @return
+ */
+ public PlayerMessageData addMessage( MessageType messageType, String message ) {
+
+ return addMessage( messageType, message, 40L );
+ }
+
+ public PlayerMessageData addMessage( MessageType messageType, String message, long ticks ) {
+ PlayerMessageData pmData = null;
+
+ TreeMap messagesOfType = getMessages().get( messageType );
+
+ if ( messagesOfType.containsKey( message ) ) {
+ pmData = messagesOfType.get( message );
+
+ // A message that was sent to the player before is requested to be sent again:
+ pmData.addRepeatMessage( ticks );
+ }
+ else {
+
+ // This message has not be sent to the player before:
+ pmData = new PlayerMessageData( messageType, message, ticks );
+ messagesOfType.put( message, pmData );
+ }
+
+ return pmData;
+ }
+
+ public TreeMap> getMessages() {
+ return messages;
+ }
+
+}
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
new file mode 100644
index 000000000..ba9a8aad6
--- /dev/null
+++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombData.java
@@ -0,0 +1,427 @@
+package tech.mcprison.prison.bombs;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.TreeSet;
+
+import tech.mcprison.prison.internal.block.Block;
+import tech.mcprison.prison.internal.block.PrisonBlock;
+
+public class MineBombData {
+
+ private String name;
+
+ private String description;
+
+
+ /**
+ *
The 'bombItemId' is first line of the bomb's item lore, and
+ * it really needs to be unique and not match any other bomb's id.
+ *
The String value that is shown over the placed item when the bomb is
+ * placed. Null or empty will show none. The placeholder '{name}' will show
+ * the bomb's name.
+ *
+ */
+ private String nameTag;
+
+ /**
+ *
The String name of an XMaterial item to use as the "bomb".
+ *
+ */
+ private String itemType;
+
+ /*
+ *
A transient reference to the actual XMaterial item that is used
+ * for the bomb. This is converted from the String itemType.
+ *
The radius identifies how large the blast should be as
+ * expressed in a radius. Generally this applies to a sphere or
+ * a circle or disk, but can also apply to other shapes such as
+ * cubes.
+ *
+ *
+ *
The radius is always based upon a center block, plus the radius.
+ * Therefore a radius of 1 will result in a sphere with a diameter of
+ * three (1 block for the center, and then 1 additional block on each
+ * side). The calculated diameter can never be even, and the actual
+ * blast size will appear to be larger than this specified radius due
+ * to the starting inner block.
+ *
+ *
+ */
+ private int radius = 1;
+
+
+ /**
+ *
Some shapes may require an inner radius, such as a hollow sphere or
+ * a torus. This is ignored for all other shapes.
+ *
+ */
+ private int radiusInner = 0;
+
+
+ /**
+ *
Some shapes may require a height, such as a cylinder or a cone.
+ * Even if the shape is laying on it's side, the height will still
+ * apply in other planes and not just up and down.
+ * This is ignored for all other shapes.
+ *
+ */
+ private int height = 0;
+
+ /**
+ *
The chance of complete removal. So if the explosion includes
+ * 100 blocks, but the chance is only 50%, each block will be given
+ * a 50% chance to be included from the explosion block list.
+ *
This is the number of ticks after the explosion occurs to when
+ * the armor stand is removed. This is preferred since bukkit is
+ * managing the removal of the armor stand, which will help prevent it
+ * from not being removed, which will create a zombie.
+ *
+ *
+ *
This value will be added to fuseDelayTicks to setup the removal
+ * time that will be used when placing the armor stand.
+ *
On spigot versions that support it, the bomb, when placed, will glow.
+ * Was introduced with Minecraft 1.9. Applies only to Entities, of which
+ * dropped items may be considered an entity?
+ *
This autosell will force the results of an explosion to autosell even when autosell
+ * is disabled on the server's auto features. This is almost a requirement for large
+ * explosions, especially if an unsafe fortune enchantment is being used.
+ *
The effectsName that is used should be one of the following, or it will not work.
+ * These effects depend upon the server's version too. If what you enter does not work,
+ * then try something else what would be compatible. It's important to test to make
+ * sure.
This finds a bomb with the given name, and returns a clone. The clone is
+ * important since individual instances will set the isActivated() variable to
+ * true if the bomb is active. If it's activated, then that indicates the
+ * bomb will be used and the bomb was removed from the player's inventory.
+ *
+ *
+ * @param bombName
+ * @return
+ */
+ public MineBombData findBomb( String bombName ) {
+ MineBombData bombOriginal = null;
+
+ if ( bombName != null ) {
+
+ bombOriginal = getConfigData().getBombs().get( bombName.toLowerCase() );
+ }
+
+ return bombOriginal.clone();
+ }
+
+ public void saveConfigJson() {
+
+ JsonFileIO fio = new JsonFileIO( null, null );
+
+ File configFile = getConfigFile( fio );
+
+ fio.saveJsonFile( configFile, getConfigData() );
+
+ }
+
+ public File getConfigFile( JsonFileIO jsonFileIO ) {
+
+ File path = new File( jsonFileIO.getProjectRootDiretory(), MINE_BOMBS_PATH_NAME );
+ path.mkdirs();
+ File configFile = new File( path, MINE_BOMBS_FILE_NAME );
+
+ return configFile;
+ }
+
+ public void loadConfigJson() {
+ JsonFileIO fio = new JsonFileIO( null, null );
+
+ File configFile = getConfigFile( fio );
+
+ if ( !configFile.exists() ) {
+ setupDefaultMineBombData();
+ }
+
+ else {
+
+ MineBombsConfigData configs =
+ (MineBombsConfigData) fio.readJsonFile( configFile, getConfigData() );
+
+ if ( configs != null ) {
+ setConfigData( configs );
+
+ if ( configs.getDataFormatVersion() <
+ MineBombsConfigData.MINE_BOMB_DATA_FORMAT_VERSION ) {
+
+ // Need to update the format version then save a new copy of the configs.
+
+ // first backup the old file by renaming it:
+
+ int oldVersion = configs.getDataFormatVersion();
+
+ String backupTag = "ver_" + oldVersion;
+ File backupFile = fio.getBackupFile( configFile, backupTag, "json" );
+
+ boolean renamed = configFile.renameTo( backupFile );
+
+ if ( renamed ) {
+ configs.setDataFormatVersion( MineBombsConfigData.MINE_BOMB_DATA_FORMAT_VERSION );
+
+ fio.saveJsonFile( configFile, configs );
+
+ Output.get().logInfo( String.format(
+ "MineBomb Data Format was updated and saved: Loaded v%d and updated to v%d. " +
+ "The old data is archived as: [%s]",
+ oldVersion, configs.getDataFormatVersion(),
+ backupFile.getName()
+// backupFile.getAbsolutePath()
+ ) );
+ }
+
+
+ }
+ }
+
+ }
+ }
+
+
+ public List calculateCylinder( Location loc, int radius, boolean hollow ) {
+ List results = new ArrayList<>();
+
+
+
+ return results;
+ }
+
+ public List calculateSphere( Location loc, int radius, boolean hollow ) {
+
+ return calculateSphere( loc, radius, hollow, 0, ExplosionOrientation.full );
+ }
+
+ public List calculateSphere( Location loc, int radius, boolean hollow,
+ int radiusInner ) {
+ return calculateSphere( loc, radius, hollow, radiusInner, ExplosionOrientation.full );
+ }
+
+
+
+ public List calculateSphere( Location loc, int radius, boolean hollow,
+ int radiusInner, ExplosionOrientation explosionOrientation ) {
+ List results = new ArrayList<>();
+
+ if ( loc != null && radius > 0 ) {
+ int cenX = loc.getBlockX();
+ int cenY = loc.getBlockY();
+ int cenZ = loc.getBlockZ();
+
+ boolean xOri = explosionOrientation == ExplosionOrientation.x_axis;
+ boolean yOri = explosionOrientation == ExplosionOrientation.y_axis;
+ boolean zOri = explosionOrientation == ExplosionOrientation.z_axis;
+
+ double radiusSqr = radius * radius;
+
+ // If the radiusInner is not specified (== 0), then subtract one from radius.
+ double radiusHSqr = radiusInner == 0 ?
+ ((radius - 1) * (radius - 1)) :
+ (radiusInner * radiusInner);
+
+ for ( int x = (xOri ? cenX : cenX - radius) ; x <= (xOri ? cenX : cenX + radius) ; x++ ) {
+ double xSqr = (cenX - x) * (cenX - x);
+
+ for ( int y = (yOri ? cenY : cenY - radius) ; y <= (yOri ? cenY : cenY + radius) ; y++ ) {
+ double ySqr = (cenY - y) * (cenY - y);
+
+ for ( int z = (zOri ? cenZ : cenZ - radius) ; z <= (zOri ? cenZ : cenZ + radius) ; z++ ) {
+ double zSqr = (cenZ - z) * (cenZ - z);
+
+ double distSqr = xSqr + ySqr + zSqr;
+
+ if ( distSqr <= radiusSqr &&
+ (!hollow ||
+ hollow && distSqr >= radiusHSqr )) {
+
+ Location l = new Location( loc.getWorld(), x, y, z );
+ results.add( l );
+ }
+ }
+ }
+ }
+ }
+ return results;
+ }
+
+
+ public List calculateCube( Location loc, int radius ) {
+ List results = new ArrayList<>();
+
+ if ( loc != null && radius > 0 ) {
+ int cenX = loc.getBlockX();
+ int cenY = loc.getBlockY();
+ int cenZ = loc.getBlockZ();
+
+ for ( int x = cenX - radius ; x <= cenX + radius ; x++ ) {
+ for ( int y = cenY + 1; y >= 0 && y >= cenY + 1 - (radius * 2) ; y-- ) {
+ for ( int z = cenZ - radius ; z <= cenZ + radius ; z++ ) {
+
+ Location l = new Location( loc.getWorld(), x, y, z );
+ results.add( l );
+
+ }
+ }
+ }
+ }
+ return results;
+ }
+
+
+ @SuppressWarnings( "unused" )
+ public void setupDefaultMineBombData()
+ {
+ if ( getConfigData().getBombs().size() == 0 ) {
+
+// XMaterial.WOODEN_PICKAXE;
+// XMaterial.STONE_PICKAXE;
+// XMaterial.IRON_PICKAXE;
+// XMaterial.GOLDEN_PICKAXE;
+// XMaterial.DIAMOND_PICKAXE;
+// XMaterial.NETHERITE_PICKAXE;
+
+ MineBombEffectsData mbeSound01 = new MineBombEffectsData( "ENTITY_CREEPER_PRIMED", EffectState.placed, 0 );
+ MineBombEffectsData mbeSound02 = new MineBombEffectsData( "CAT_HISS", EffectState.placed, 0 );
+
+ MineBombEffectsData mbeSound03 = new MineBombEffectsData( "ENTITY_GENERIC_EXPLODE", EffectState.explode, 0 );
+ MineBombEffectsData mbeSound04 = new MineBombEffectsData( "ENTITY_DRAGON_FIREBALL_EXPLODE", EffectState.explode, 0 );
+
+ // Does not work with spigot 1.8.x:
+ MineBombEffectsData mbeExplode01 = new MineBombEffectsData( "FIREWORKS_SPARK", EffectState.placed, 0 );
+ // Does not work with spigot 1.8.x:
+ MineBombEffectsData mbeExplode02 = new MineBombEffectsData( "BUBBLE_COLUMN_UP", EffectState.placed, 0 );
+ MineBombEffectsData mbeExplode03 = new MineBombEffectsData( "ENCHANTMENT_TABLE", EffectState.placed, 0 );
+
+// MineBombEffectsData mbeExplode05 = new MineBombEffectsData( "END_ROD", EffectState.placed, 0 );
+ MineBombEffectsData mbeExplode04 = new MineBombEffectsData( "FLAME", EffectState.placed, 0 );
+ // Does not work with spigot 1.8.x:
+ MineBombEffectsData mbeExplode08 = new MineBombEffectsData( "DRAGON_BREATH", EffectState.placed, 0 );
+
+ MineBombEffectsData mbeExplode06a = new MineBombEffectsData( "SMOKE", EffectState.placed, 0 );
+ // Does not work with spigot 1.8.x:
+ MineBombEffectsData mbeExplode06 = new MineBombEffectsData( "SMOKE_NORMAL", EffectState.placed, 0 );
+ // Does not work with spigot 1.8.x:
+ MineBombEffectsData mbeExplode07 = new MineBombEffectsData( "SMOKE_LARGE", EffectState.placed, 0 );
+
+ MineBombEffectsData mbeExplode10 = new MineBombEffectsData( "EXPLOSION_NORMAL", EffectState.explode, 0 );
+ MineBombEffectsData mbeExplode11 = new MineBombEffectsData( "EXPLOSION_LARGE", EffectState.explode, 0 );
+ // Does not work with spigot 1.8.x:
+ MineBombEffectsData mbeExplode12 = new MineBombEffectsData( "EXPLOSION_HUGE", EffectState.explode, 0 );
+
+
+ {
+ MineBombData mbd = new MineBombData(
+ "SmallBomb", "brewing_stand", ExplosionShape.sphere.name(), 2, "Small Mine Bomb" );
+ mbd.setToolInHandName( "DIAMOND_PICKAXE" );
+ mbd.setToolInHandFortuneLevel( 0 );
+ mbd.setDescription("A small mine bomb made with some chemicals and a brewing stand.");
+
+ mbd.getSoundEffects().add( mbeSound01.clone() );
+ mbd.getSoundEffects().add( mbeSound02.clone().setOffsetTicks( 30 ) );
+ mbd.getSoundEffects().add( mbeSound03.clone() );
+
+ mbd.getVisualEffects().add( mbeExplode04.clone() );
+ mbd.getVisualEffects().add( mbeExplode03.clone().setOffsetTicks( 30 ) );
+
+ mbd.getVisualEffects().add( mbeExplode06a.clone() );
+ mbd.getVisualEffects().add( mbeExplode10.clone() );
+ mbd.getVisualEffects().add( mbeExplode06.clone() );
+
+ mbd.setCooldownTicks( 60 );
+
+ getConfigData().getBombs().put( mbd.getName().toLowerCase(), mbd );
+
+ }
+
+ {
+ MineBombData mbd = new MineBombData(
+ "MediumBomb", "firework_rocket", ExplosionShape.sphere.name(), 5, "Medium Mine Bomb" );
+ mbd.setDescription("A medium mine bomb made from leftover fireworks, " +
+ "but supercharged with a strange green glowing liquid.");
+ mbd.setToolInHandName( "DIAMOND_PICKAXE" );
+ mbd.setToolInHandFortuneLevel( 3 );
+
+ mbd.getSoundEffects().add( mbeSound01.clone() );
+ mbd.getSoundEffects().add( mbeSound02.clone().setOffsetTicks( 30 ) );
+ mbd.getSoundEffects().add( mbeSound03.clone() );
+
+ mbd.getVisualEffects().add( mbeExplode04.clone() );
+ mbd.getVisualEffects().add( mbeExplode03.clone().setOffsetTicks( 30 ) );
+
+ mbd.getVisualEffects().add( mbeExplode10.clone() );
+ mbd.getVisualEffects().add( mbeExplode06.clone() );
+
+ mbd.setCooldownTicks( 60 );
+
+ getConfigData().getBombs().put( mbd.getName().toLowerCase(), mbd );
+
+ }
+
+ {
+ MineBombData mbd = new MineBombData(
+ "LargeBomb", "tnt", ExplosionShape.sphereHollow.name(), 12, "Large Mine Bomb" );
+ mbd.setRadiusInner( 3 );
+ mbd.setDescription("A large mine bomb made from TNT with some strange parts " +
+ "that maybe be described as alien technology.");
+ mbd.setToolInHandName( "DIAMOND_PICKAXE" );
+ mbd.setToolInHandFortuneLevel( 3 );
+
+ mbd.getSoundEffects().add( mbeSound01.clone() );
+ mbd.getSoundEffects().add( mbeSound02.clone().setOffsetTicks( 30 ) );
+ mbd.getSoundEffects().add( mbeSound03.clone().setVolumne( 2.0f ) );
+
+ mbd.getVisualEffects().add( mbeExplode04.clone() );
+ mbd.getVisualEffects().add( mbeExplode03.clone().setOffsetTicks( 30 ) );
+
+ mbd.getVisualEffects().add( mbeExplode10.clone() );
+ mbd.getVisualEffects().add( mbeExplode06.clone() );
+ mbd.getVisualEffects().add( mbeExplode06a.clone() );
+
+ mbd.setCooldownTicks( 60 );
+
+ getConfigData().getBombs().put( mbd.getName().toLowerCase(), mbd );
+ }
+
+ {
+ MineBombData mbd = new MineBombData(
+ "OofBomb", "tnt_minecart", ExplosionShape.sphereHollow.name(), 19, "Oof Mine Bomb" );
+ mbd.setRadiusInner( 3 );
+ mbd.setDescription("An oof-ably large mine bomb made with a minecart heaping with TNT. " +
+ "Unlike the large mine bomb, this one obviously is built with alien technology.");
+
+ mbd.setToolInHandName( "GOLDEN_PICKAXE" );
+ mbd.setToolInHandFortuneLevel( 13 );
+
+ mbd.getSoundEffects().add( mbeSound01.clone() );
+ mbd.getSoundEffects().add( mbeSound02.clone().setOffsetTicks( 10 ).setVolumne( 0.25f ).setPitch( 0.25f ) );
+ mbd.getSoundEffects().add( mbeSound02.clone().setOffsetTicks( 20 ).setVolumne( 0.5f ).setPitch( 0.5f ) );
+ mbd.getSoundEffects().add( mbeSound02.clone().setOffsetTicks( 30 ).setVolumne( 1.0f ).setPitch( 0.75f ) );
+ mbd.getSoundEffects().add( mbeSound02.clone().setOffsetTicks( 40 ).setVolumne( 2.0f ).setPitch( 1.5f ) );
+ mbd.getSoundEffects().add( mbeSound02.clone().setOffsetTicks( 50 ).setVolumne( 5.0f ).setPitch( 2.5f ) );
+
+ mbd.getSoundEffects().add( mbeSound03.clone().setOffsetTicks( 0 ).setVolumne( 3.0f ) );
+ mbd.getSoundEffects().add( mbeSound04.clone().setOffsetTicks( 5 ).setVolumne( 1.5f ) );
+ mbd.getSoundEffects().add( mbeSound03.clone().setOffsetTicks( 10 ).setVolumne( 2.5f ) );
+ mbd.getSoundEffects().add( mbeSound04.clone().setOffsetTicks( 15 ).setVolumne( 1.0f ) );
+ mbd.getSoundEffects().add( mbeSound03.clone().setOffsetTicks( 20 ).setVolumne( 2.0f ) );
+ mbd.getSoundEffects().add( mbeSound04.clone().setOffsetTicks( 25 ).setVolumne( 0.75f ) );
+ mbd.getSoundEffects().add( mbeSound03.clone().setOffsetTicks( 30 ).setVolumne( 1.5f ) );
+ mbd.getSoundEffects().add( mbeSound04.clone().setOffsetTicks( 35 ).setVolumne( 0.55f ) );
+ mbd.getSoundEffects().add( mbeSound03.clone().setOffsetTicks( 40 ).setVolumne( 1.0f ) );
+ mbd.getSoundEffects().add( mbeSound04.clone().setOffsetTicks( 45 ).setVolumne( 0.25f ) );
+ mbd.getSoundEffects().add( mbeSound03.clone().setOffsetTicks( 50 ).setVolumne( 0.5f ) );
+ mbd.getSoundEffects().add( mbeSound04.clone().setOffsetTicks( 55 ).setVolumne( 0.15f ) );
+
+
+ mbd.getVisualEffects().add( mbeExplode06.clone() );
+ mbd.getVisualEffects().add( mbeExplode06a.clone() );
+ mbd.getVisualEffects().add( mbeExplode03.clone() );
+ mbd.getVisualEffects().add( mbeExplode12.clone() );
+ mbd.getVisualEffects().add( mbeExplode12.clone().setOffsetTicks( 30 ) );
+ mbd.getVisualEffects().add( mbeExplode12.clone().setOffsetTicks( 60 ) );
+ mbd.getVisualEffects().add( mbeExplode07.clone().setOffsetTicks( 60 ) );
+ mbd.getVisualEffects().add( mbeExplode08.clone().setOffsetTicks( 90 ) );
+
+ mbd.getVisualEffects().add( mbeExplode10.clone() );
+ mbd.getVisualEffects().add( mbeExplode06.clone().setOffsetTicks( 20 ) );
+
+ mbd.setAutosell( true );
+ mbd.setGlowing( true );
+ mbd.setAutosell( true );
+
+ mbd.setCooldownTicks( 60 );
+ mbd.setFuseDelayTicks( 3 * 20 ); // 3 seconds
+
+ getConfigData().getBombs().put( mbd.getName().toLowerCase(), mbd );
+ }
+
+ {
+ MineBombData mbd = new MineBombData(
+ "WimpyBomb", "GUNPOWDER", ExplosionShape.sphere.name(), 5,
+ "A Wimpy Mine Bomb" );
+ mbd.setBombItemId( "&7A &2Wimpy &cBomb &9...&02A3F" );
+
+ mbd.setNameTag( "&7A &2Wimpy &cBomb" );
+
+ mbd.setRadiusInner( 2 );
+ mbd.setDescription("A whimpy bomb made with gunpowder and packs the punch of a " +
+ "dull wooden pickaxe. For some reason, it only has a 40% chance of removing " +
+ "a block.");
+
+ mbd.getLore().add( "" );
+ mbd.getLore().add( "A whimpy bomb made with gunpowder and packs the punch " );
+ mbd.getLore().add( "of a dull wooden pickaxe. For some reason, it only " );
+ mbd.getLore().add( "has a 40% chance of removing a block." );
+ mbd.getLore().add( "" );
+ mbd.getLore().add( "Not labeled for retail sale." );
+
+ mbd.setToolInHandName( "WOODEN_PICKAXE" );
+ mbd.setToolInHandFortuneLevel( 0 );
+ mbd.setRemovalChance( 40.0d );
+
+ mbd.getSoundEffects().add( mbeSound01.clone() );
+ mbd.getSoundEffects().add( mbeSound02.clone().setOffsetTicks( 30 ) );
+ mbd.getSoundEffects().add( mbeSound03.clone() );
+
+ mbd.getVisualEffects().add( mbeExplode01.clone() );
+ mbd.getVisualEffects().add( mbeExplode02.clone().setOffsetTicks( 30 ) );
+ mbd.getVisualEffects().add( mbeExplode03.clone().setOffsetTicks( 10 ) );
+ mbd.getVisualEffects().add( mbeExplode04.clone() );
+
+ mbd.getVisualEffects().add( mbeExplode10.clone() );
+ mbd.getVisualEffects().add( mbeExplode06.clone() );
+ mbd.getVisualEffects().add( mbeExplode06a.clone() );
+ mbd.getVisualEffects().add( mbeExplode11.clone().setOffsetTicks( 05 ) );
+
+ mbd.setCooldownTicks( 3 * 20 ); // 3 seconds
+ mbd.setFuseDelayTicks( 2 * 20 ); // 2 seconds
+
+ mbd.setGlowing( true );
+ mbd.setGravity( false );
+
+ mbd.setCooldownTicks( 5 );
+
+ getConfigData().getBombs().put( mbd.getName().toLowerCase(), mbd );
+ }
+
+
+ {
+ MineBombData mbd = new MineBombData(
+ "CubeBomb", "SLIME_BLOCK", ExplosionShape.cube.name(), 2,
+ "A Cubic Bomb" );
+ mbd.setDescription("The most anti-round bomb you will ever be able to find. " +
+ "It's totally cubic.");
+
+ mbd.setToolInHandName( "DIAMOND_PICKAXE" );
+ mbd.setToolInHandFortuneLevel( 7 );
+ mbd.setRemovalChance( 100.0d );
+
+ mbd.getSoundEffects().add( mbeSound01.clone() );
+ mbd.getSoundEffects().add( mbeSound02.clone().setOffsetTicks( 30 ) );
+ mbd.getSoundEffects().add( mbeSound03.clone() );
+
+ mbd.getVisualEffects().add( mbeExplode04.clone() );
+ mbd.getVisualEffects().add( mbeExplode02.clone().setOffsetTicks( 30 ) );
+
+ mbd.setGlowing( true );
+
+ mbd.setCooldownTicks( 60 );
+
+ getConfigData().getBombs().put( mbd.getName().toLowerCase(), mbd );
+ }
+
+
+ saveConfigJson();
+
+ Output.get().logInfo( "Mine bombs: setup default values." );
+ }
+ else {
+ Output.get().logInfo( "Could not generate a mine bombs save file since at least one " +
+ "mine bomb already exists." );
+ }
+
+ }
+
+
+ public MineBombsConfigData getConfigData() {
+ return configData;
+ }
+ public void setConfigData( MineBombsConfigData configData ) {
+ this.configData = configData;
+ }
+
+
+ public MineBombData findBombByItemId( String bombItemId )
+ {
+ MineBombData results = null;
+
+ String bombItemIdConvered = Text.convertToAmpColorCodes( bombItemId );
+
+ if ( bombItemIdConvered != null && !bombItemIdConvered.isEmpty() ) {
+ for ( String bombKey : getConfigData().getBombs().keySet() )
+ {
+ MineBombData bomb = getConfigData().getBombs().get( bombKey );
+
+ if ( bomb != null && bomb.getBombItemId() != null &&
+ bomb.getBombItemId().equalsIgnoreCase( bombItemIdConvered ) ) {
+
+ results = bomb;
+
+ }
+ }
+ }
+
+ return results;
+ }
+
+}
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
new file mode 100644
index 000000000..573002a0f
--- /dev/null
+++ b/prison-core/src/main/java/tech/mcprison/prison/bombs/MineBombsConfigData.java
@@ -0,0 +1,46 @@
+package tech.mcprison.prison.bombs;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+import tech.mcprison.prison.file.FileIOData;
+
+public class MineBombsConfigData
+ implements FileIOData
+{
+ /**
+ *
If the format of this class, or any other variables and their
+ * classes change that would effect the structure of the save file,
+ * then increment this variable by 1. This will force the saved
+ * files on the servers to be updated to the latest format of the
+ * data.
+ *
+ */
+ public static final int MINE_BOMB_DATA_FORMAT_VERSION = 1;
+
+ private int dataFormatVersion = 0;
+
+ private Map bombs;
+
+ public MineBombsConfigData() {
+ super();
+
+ this.dataFormatVersion = 0;
+
+ this.bombs = new TreeMap<>();
+ }
+
+ public int getDataFormatVersion() {
+ return dataFormatVersion;
+ }
+ public void setDataFormatVersion( int dataFormatVersion ) {
+ this.dataFormatVersion = dataFormatVersion;
+ }
+
+ public Map getBombs() {
+ return bombs;
+ }
+ public void setBombs( Map bombs ) {
+ this.bombs = bombs;
+ }
+}
diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCache.java b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCache.java
index c4d5f554a..9646746a7 100644
--- a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCache.java
+++ b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCache.java
@@ -9,7 +9,6 @@
import java.util.TreeSet;
import tech.mcprison.prison.internal.Player;
-import tech.mcprison.prison.internal.block.PrisonBlock;
import tech.mcprison.prison.internal.block.PrisonBlockStatusData;
import tech.mcprison.prison.output.Output;
import tech.mcprison.prison.tasks.PrisonTaskSubmitter;
@@ -206,11 +205,40 @@ public PlayerCachePlayerData removePlayerData( PlayerCachePlayerData playerData
}
+ /**
+ *
This function will return a null if the player is not loaded in the cache.
+ * Null is a valid value even if the player is online.
+ * This function should NEVER be used
+ * for any critical data such as tracking blocks, time, earnings, or inventory.
+ * Examples of acceptable loss would be with messaging. Loss of a few messages is
+ * not that critical, and actually would be a very rare situation. Example, if a
+ * player is mining then their cache should already be loaded so calling this function
+ * should never find the situation where the player's cache entry does not exist.
+ *
+ *
+ *
Since this function will fail with the return a null if the player is not loaded,
+ * this function will not cause blocking on the runnable thread.
+ *
+ *
+ *
If the player is not loaded, and a null is returned, then an async task
+ * will be submitted to load it.
+ *
+ *
+ * @param player
+ * @return
+ */
+ public PlayerCachePlayerData getOnlinePlayer( Player player ) {
+ PlayerCachePlayerData playerData = getPlayer( player );
+
+ return playerData;
+ }
/**
*
This returns the cached player object. If they have not been loaded
- * yet, then this will submit the loadPlayer task, which will then result
- * in this function returning a null.
+ * yet, then this will load the player object while waiting for it.
+ *
+ *
+ *
This used to return a null while submitting a loadPlayer task.
*
*
* @param player
@@ -222,7 +250,8 @@ private PlayerCachePlayerData getPlayer( Player player ) {
getStats().incrementGetPlayers();
- String playerUuid = player.getUUID().toString();
+ String playerUuid = player == null || player.getUUID() == null ? null :
+ player.getUUID().toString();
if ( !getPlayers().containsKey( playerUuid ) ) {
// Load the player's existing balance:
@@ -244,10 +273,16 @@ private PlayerCachePlayerData getPlayer( Player player ) {
playerData = getPlayers().get( playerUuid );
}
- if ( playerData != null &&
- (playerData.getPlayer() == null || !playerData.getPlayer().equals( player ) ) ) {
- playerData.setPlayer( player );
+ if ( playerData != null ) {
+
+ if ( playerData.getPlayer() == null || !playerData.getPlayer().equals( player ) ) {
+
+ playerData.setPlayer( player );
+ }
+
+ playerData.updateLastSeen();
}
+
return playerData;
}
@@ -265,18 +300,29 @@ protected void submitAsyncLoadPlayer( Player player ) {
}
}
- protected void runLoadPlayerNow( Player player ) {
-
- if ( player != null ) {
-
- PlayerCacheLoadPlayerTask task = new PlayerCacheLoadPlayerTask( player );
-
- task.run();
-// // Submit task to run right away:
-// int taskId = PrisonTaskSubmitter.runTaskLaterAsync( task, 0 );
-// task.setTaskId( taskId );
- }
- }
+
+// /**
+// *
This loads the player cache object inline. It does not run it as a
+// * task in another thread.
+// *
+// *
+// *
This is not used anywhere.
+// *
+// *
+// * @param player
+// */
+// protected void runLoadPlayerNow( Player player ) {
+//
+// if ( player != null ) {
+//
+// PlayerCacheLoadPlayerTask task = new PlayerCacheLoadPlayerTask( player );
+//
+// task.run();
+//// // Submit task to run right away:
+//// int taskId = PrisonTaskSubmitter.runTaskLaterAsync( task, 0 );
+//// task.setTaskId( taskId );
+// }
+// }
protected void submitAsyncUnloadPlayer( Player player ) {
@@ -325,20 +371,23 @@ public PlayerCacheRunnable submitCacheUpdatePlayerStats() {
public void addPlayerBlocks( Player player, String mine, PrisonBlockStatusData block, int quantity ) {
- addPlayerBlocks( player, mine, (PrisonBlock) block, quantity );
+ addPlayerBlocks( player, mine, block.getBlockName(), quantity );
}
- public void addPlayerBlocks( Player player, String mine, PrisonBlock block, int quantity ) {
+// public void addPlayerBlocks( Player player, String mine, PrisonBlock block, int quantity ) {
+// addPlayerBlocks( player, mine, block.getBlockName(), quantity );
+// }
+ public void addPlayerBlocks( Player player, String mine, String blockName, int quantity ) {
PlayerCachePlayerData playerData = getPlayer( player );
// Output.get().logInfo( "### addPlayerBlock: mine= " + (mine == null ? "null" : mine) +
// " block= " + (block == null ? "null" : block.getBlockName()) + " qty= " + quantity + " playerData= " +
// (playerData == null ? "null" : playerData.toString() ));
-
+
// if ( playerData != null && playerData.getBlocksTotal() % 20 == 0 ) {
// Output.get().logInfo( "#### PlayerCache: " + playerData.toString() );
// }
- playerData.addBlock( mine, block.getBlockName(), quantity );
+ playerData.addBlock( mine, blockName, quantity );
}
/**
@@ -351,7 +400,13 @@ public void addPlayerBlocks( Player player, String mine, PrisonBlock block, int
public void addPlayerEarnings( Player player, double earnings ) {
PlayerCachePlayerData playerData = getPlayer( player );
- playerData.addEarnings( earnings );
+ String mineName = null;
+ playerData.addEarnings( earnings, mineName );
+ }
+ public void addPlayerEarnings( Player player, double earnings, String mineName ) {
+ PlayerCachePlayerData playerData = getPlayer( player );
+
+ playerData.addEarnings( earnings, mineName );
}
public double getPlayerEarningsPerMinute( Player player ) {
double earningsPerMinute = 0;
diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheCheckTimersTask.java b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheCheckTimersTask.java
index 84292dc31..7ace3b302 100644
--- a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheCheckTimersTask.java
+++ b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheCheckTimersTask.java
@@ -1,6 +1,8 @@
package tech.mcprison.prison.cache;
import java.util.ArrayList;
+import java.util.ConcurrentModificationException;
+import java.util.HashSet;
import java.util.List;
/**
@@ -37,27 +39,68 @@ public class PlayerCacheCheckTimersTask
extends PlayerCacheRunnable
{
+ private HashSet processedKeys;
+ private int attempts = 0;
+
+ public PlayerCacheCheckTimersTask() {
+ super();
+
+ this.processedKeys = new HashSet<>();
+ }
+
@Override
public void run()
{
- PlayerCache pCache = PlayerCache.getInstance();
+ // Everytime this runs, clear the processed keys set:
+ processedKeys.clear();
+ attempts = 0;
- List keys = new ArrayList<>( pCache.getPlayers().keySet() );
+ processCache();
- for ( String key : keys )
- {
- PlayerCachePlayerData playerData = pCache.getPlayers().get( key );
+ }
+ private void processCache() {
+ PlayerCache pCache = PlayerCache.getInstance();
+
+ if ( pCache.getPlayers() != null && pCache.getPlayers().keySet().size() > 0 ) {
- if ( playerData != null ) {
+ try
+ {
+ List keys = new ArrayList<>( pCache.getPlayers().keySet() );
- playerData.checkTimers();
+ for ( String key : keys )
+ {
+ if ( processedKeys.contains( key ) ) {
+ // Already processed this key so skip it:
+ break;
+ }
+ processedKeys.add( key );
+
+
+ PlayerCachePlayerData playerData = pCache.getPlayers().get( key );
+
+ if ( playerData != null ) {
+
+ playerData.checkTimers();
+
+ // By adding a zero earnings, this will force the earnings "cache" to
+ // progress, even if the player stopped mining.
+ playerData.addEarnings( 0, null );
+ }
+
+ }
+ }
+ catch ( ConcurrentModificationException e )
+ {
+ // We can ignore this overall. It is a very rare occurrence which happens when
+ // a player is added or removed from an external process. Since this is a maintenance
+ // thread, it takes on a secondary priority.
- // By adding a zero earnings, this will force the earnings "cache" to
- // progress, even if the player stopped mining.
- playerData.addEarnings( 0 );
+ // Try to process the list three times then give up:
+ if ( attempts++ < 3 ) {
+ processCache();
+ }
}
-
}
}
diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheFiles.java b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheFiles.java
index 0241bfdef..8c5d4d15e 100644
--- a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheFiles.java
+++ b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheFiles.java
@@ -90,39 +90,66 @@ public String toJson( PlayerCachePlayerData player ) {
*/
public void toJsonFile( PlayerCachePlayerData player) {
- File playerFile = player.getPlayerFile();
- File outTemp = createTempFile( playerFile );
- boolean success = false;
-
- try (
- FileWriter fw = new FileWriter( outTemp );
- ){
- getGson().toJson( player, fw );
+ if ( player != null ) {
- success = true;
- }
- catch ( JsonIOException | IOException e ) {
- e.printStackTrace();
- }
-
- if ( success && ( !playerFile.exists() || playerFile.delete()) ) {
- outTemp.renameTo( playerFile );
- }
- else {
-
- boolean removed = false;
- if ( outTemp.exists() ) {
- removed = outTemp.delete();
+ File playerFile = player.getPlayerFile();
+ File outTemp = createTempFile( playerFile );
+ boolean success = false;
+
+ try (
+ FileWriter fw = new FileWriter( outTemp );
+ ){
+ getGson().toJson( player, fw );
+
+ success = true;
+ }
+ catch ( JsonIOException | IOException e ) {
+ e.printStackTrace();
}
-
- String message = String.format(
- "Unable to rename PlayerCache temp file. It was %sremoved: %s",
- (removed ? "" : "not "), outTemp.getAbsolutePath() );
- Output.get().logWarn( message );
+ // If there is a significant change in file size, or the new file is smaller than the
+ // old, then rename it to a backup and keep it. If it is smaller, then something went wrong
+ // because player cache data should always increase, with the only exception being
+ // the player cache.
+ if ( playerFile.exists() ) {
+ long pfSize = playerFile.length();
+ long tmpSize = outTemp.length();
+
+ if ( tmpSize < pfSize ) {
+
+ renamePlayerFileToBU( playerFile );
+ }
+ }
+
+ if ( success && ( !playerFile.exists() || playerFile.delete()) ) {
+ outTemp.renameTo( playerFile );
+ }
+ else {
+
+ boolean removed = false;
+ if ( outTemp.exists() ) {
+ removed = outTemp.delete();
+ }
+
+ String message = String.format(
+ "Unable to rename PlayerCache temp file. It was %sremoved: %s",
+ (removed ? "" : "not "), outTemp.getAbsolutePath() );
+
+ Output.get().logWarn( message );
+ }
}
}
+ private void renamePlayerFileToBU( File playerFile )
+ {
+ String buFileName = ".backup_" + playerFile.getName().replace( ".temp", ".bu" );
+
+ File backupFile = new File( playerFile.getParent(), buFileName );
+
+ playerFile.renameTo( backupFile );
+
+ }
+
private File createTempFile( File file ) {
SimpleDateFormat sdf = new SimpleDateFormat("_yyyy-MM-dd_HH-mm-ss");
String name = file.getName() + sdf.format( new Date() ) + ".temp";
diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCachePlayerData.java b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCachePlayerData.java
index befae9dc1..1ae833cfc 100644
--- a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCachePlayerData.java
+++ b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCachePlayerData.java
@@ -2,11 +2,17 @@
import java.io.File;
import java.text.SimpleDateFormat;
+import java.util.ArrayList;
import java.util.Date;
+import java.util.List;
import java.util.TreeMap;
+import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures;
+import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper;
+import tech.mcprison.prison.autofeatures.PlayerMessaging;
import tech.mcprison.prison.internal.Player;
import tech.mcprison.prison.internal.block.PrisonBlock;
+import tech.mcprison.prison.internal.inventory.Inventory;
import tech.mcprison.prison.placeholders.PlaceholdersUtil;
/**
@@ -27,6 +33,7 @@ public class PlayerCachePlayerData {
private transient Player player;
+
private String playerUuid;
private String playerName;
@@ -47,6 +54,11 @@ public class PlayerCachePlayerData {
private transient PlayerCacheRunnable task = null;
+ // lastSeenDate tries to track when the player was last on the server.
+ // This is important to know for refreshing player stats.
+ private long lastSeenDate;
+ private double lastSeenBalance;
+
private long onlineTimeTotal = 0L;
// "active" time is not needed. It's the total onlineTimeTotal minus
@@ -66,22 +78,41 @@ public class PlayerCachePlayerData {
private TreeMap timeByMine;
private String lastMine = null;
- private TreeMap earningsByMine;
+ private TreeMap earningsByMine;
private transient TreeMap earningsPerMinute;
+ private long tokens;
+ private long tokensTotal;
+ private long tokensTotalAdminAdded;
+ private long tokensTotalAdminRemoved;
+ private long tokensLastBlocksTotals;
+
+ private TreeMap tokensByMine;
+ private transient TreeMap tokensPerMinute;
+
+
+
+
+
// This is the time when the "session" was started:
private transient SessionType sessionType;
- private transient long sessionTimingStart = 0;
+// private transient long sessionTimingStart = 0;
private transient long sessionTimingLastCheck = 0;
// sessionLastLocation is used for afk calculations:
// private transient Location sessionLastLocation = null;
+
+ private transient PlayerMessaging playerMessaging;
+
+
+ private List backpacks;
+
private transient boolean dirty = false;
@@ -104,13 +135,22 @@ public PlayerCachePlayerData() {
this.earningsPerMinute = new TreeMap<>();
+
+ this.tokensByMine = new TreeMap<>();
+ this.tokensPerMinute = new TreeMap<>();
+
+
this.sessionType = SessionType.active;
- this.sessionTimingStart = System.currentTimeMillis();
- this.sessionTimingLastCheck = sessionTimingStart;
+// this.sessionTimingStart = System.currentTimeMillis();
+ this.sessionTimingLastCheck = System.currentTimeMillis();
// this.sessionLastLocation = null;
+ this.playerMessaging = new PlayerMessaging();
+
+ this.backpacks = new ArrayList<>();
+
}
public PlayerCachePlayerData( Player player, File playerFile ) {
@@ -118,6 +158,14 @@ public PlayerCachePlayerData( Player player, File playerFile ) {
this.player = player;
+ if ( isOnline() ) {
+
+ this.lastSeenDate = System.currentTimeMillis();
+// this.lastSeenBalance = player.get
+
+ this.dirty = true;
+ }
+
this.playerUuid = player.getUUID().toString();
this.playerName = player.getName();
@@ -135,8 +183,9 @@ public void checkTimers() {
if ( isOnline() ) {
- // Do not change the session type, so pass it the current:
- checkTimersMining( sessionType, getLastMine() );
+ // Do not change the session type, but pass null for the mine to indicate
+ // that this is a checkTimers...
+ checkTimersMining( sessionType, null );
}
}
@@ -159,12 +208,16 @@ public void checkTimers() {
*
If prior session type was mining, then do nothing if the last
* @param mine
*/
- private void checkTimersMining( SessionType targetType, String mine ) {
- final long currentTime = System.currentTimeMillis();
+ private void checkTimersMining( SessionType currentSessionType, String mine ) {
if ( !isOnline() ) {
return;
}
+
+ final long currentTime = System.currentTimeMillis();
+ final long duration = currentTime - sessionTimingLastCheck;
+
+
// temp fix:
if ( onlineTimeTotal < 0 ) {
@@ -174,94 +227,129 @@ private void checkTimersMining( SessionType targetType, String mine ) {
onlineMiningTimeTotal = 0;
}
- if ( sessionType == targetType && sessionType != SessionType.mining) {
- // No change in status
-
- sessionTimingLastCheck = currentTime;
- final long duration = currentTime - sessionTimingLastCheck;
- // if duration is greater than 15 minutes, then move the session start
- // point and save it.
- if ( duration > 900000 ) {
-
- sessionTimingStart = currentTime;
- dirty = true;
- }
-
- }
- else if ( sessionType != SessionType.mining ) {
-
- // Always Save as total time. Use sessionTimingStart. Ignore sessionTimingLastCheck.
- final long duration = currentTime - sessionTimingStart;
- onlineTimeTotal += duration;
+ if ( currentSessionType != SessionType.mining ) {
//checkTimersAfk();
- sessionType = targetType;
- sessionTimingStart = currentTime;
+ setLastMine( null );
+ sessionType = currentSessionType;
+
sessionTimingLastCheck = currentTime;
+
dirty = true;
}
- else {
- // The session type is still mining...
+
+ else if ( currentSessionType == SessionType.mining ) {
+ // The current session type is still mining... and was before.
// Must check sessionTimingLastCheck to see if we went over the
// max mining idle time:
- final long duration = currentTime - sessionTimingLastCheck;
-
- // If the duration is less than the session mining timeout, then player
- // is still mining. Just set the sessionTimingLastCheck.
- if ( duration < SESSION_TIMEOUT_MINING_MS ) {
-
- sessionTimingLastCheck = currentTime;
+ if ( sessionType != SessionType.mining ||
+ getLastMine() == null ) {
+
+ dirty = true;
+
}
- // Mining can only be active for no more than SESSION_TIMEOUT_MINING_MS
- // after the last block was broken. So check duration between now and
- // sessionOnlineTimeLastCheck and if more than permitted, then shutdown
- // mining session and log it for a duration since session start to
- // last check plus the mining timeout value. Then set session start to
- // that position.
+ else if ( mine == null && getLastMine() != null &&
+ duration > SESSION_TIMEOUT_MINING_MS ) {
+
+ addTimeToMine( getLastMine(), SESSION_TIMEOUT_MINING_MS );
+
+ onlineMiningTimeTotal += SESSION_TIMEOUT_MINING_MS;
+
+ // Since this is being called from checkTimer(), need to
+ // set lastMine to null and sessionType to active:
+
+ setLastMine( null );
+ sessionType = SessionType.active;
+
+ // Save as total online time.
+ onlineTimeTotal += duration;
+
+ dirty = true;
+ return;
+ }
- else if ( duration > SESSION_TIMEOUT_MINING_MS || getLastMine() == null ||
- mine.equalsIgnoreCase( getLastMine() )) {
+ else if ( mine == null ) {
- // Calculate the end point of the mining session, which will be 30 seconds after
- // the last time check:
- final long tempTime = sessionTimingLastCheck + SESSION_TIMEOUT_MINING_MS;
- final long miningDuration = tempTime - sessionTimingStart;
-// final long miningDuration = sessionTimingStart - tempTime;
- onlineTimeTotal += miningDuration;
- onlineMiningTimeTotal += miningDuration;
+ // This is running in checkTimers() and not enough time has passed to
+ // exceed the SESSION_TIMEOUT_MINING_MS. So need to wait longer.
+ // return without setting anything.
- addTimeToMine( mine, miningDuration );
+ return;
+ }
+
+ // Mine has changed since last check, so apply duration to last mine:
+ else if ( getLastMine() != null &&
+ (mine == null ||
+ !mine.equalsIgnoreCase( getLastMine() ) )) {
- // Set new session to this boundary:
- sessionTimingStart = tempTime;
- sessionTimingLastCheck = tempTime;
- // Since the last SessionType and current are mining, then the duration from
- // the new sessionTimingStart to currentTime needs to go to active:
- final long durationActive = currentTime - sessionTimingStart;
- onlineTimeTotal += durationActive;
+ if ( duration > SESSION_TIMEOUT_MINING_MS ) {
+ addTimeToMine( getLastMine(), SESSION_TIMEOUT_MINING_MS );
+
+ onlineMiningTimeTotal += SESSION_TIMEOUT_MINING_MS;
+
+ }
+ else {
+
+ addTimeToMine( getLastMine(), duration );
+
+ onlineMiningTimeTotal += duration;
+ }
+
+ }
+
+
+ else if ( duration > SESSION_TIMEOUT_MINING_MS ) {
- //checkTimersAfk();
+ // Same mine, but exceeded the duration:
+ addTimeToMine( mine, SESSION_TIMEOUT_MINING_MS );
- // Now reset the current session:
- sessionType = targetType;
- sessionTimingStart = currentTime;
- sessionTimingLastCheck = currentTime;
- dirty = true;
+ onlineMiningTimeTotal += SESSION_TIMEOUT_MINING_MS;
+
+ }
+ else {
+ // same mine and less than session length, so add duration:
+
+ addTimeToMine( mine, duration );
+ onlineMiningTimeTotal += duration;
+
}
+
+
+ // Now change the active mine
+ setLastMine( mine );
+
+ // Should already be mining:
+// sessionType = currentSessionType;
+
+ // Set new session to this boundary and discard the extra time:
+ sessionTimingLastCheck = currentTime;
+
+ dirty = true;
}
+
+ // Always Save as total online time.
+ onlineTimeTotal += duration;
}
+ /**
+ *
Also generates tokens based upon blocks mined.
+ *
+ *
+ * @param mine
+ * @param blockName
+ * @param quantity
+ */
public void addBlock( String mine, String blockName, int quantity )
{
if ( quantity > 0 && blockName != null &&
@@ -280,6 +368,8 @@ public void addBlock( String mine, String blockName, int quantity )
checkTimersMining( SessionType.mining, mine );
dirty = true;
}
+
+ addTokensByBlocks( mine, quantity );
}
private void addBlockByType( String blockName, int quantity ) {
@@ -313,6 +403,16 @@ private void addEarningsByMine( String mine, double amount ) {
getEarningsByMine().put( mine, amt );
}
+ private void addTokensByMine( String mine, long tokens ) {
+ long toks = 0;
+
+ if ( getTokensByMine().containsKey( mine ) ) {
+ toks = getTokensByMine().get( mine );
+ }
+
+ getTokensByMine().put( mine, (toks + tokens) );
+ }
+
private void addTimeToMine( String mine, long miningDuration )
{
if ( mine != null && !mine.trim().isEmpty() ) {
@@ -334,28 +434,37 @@ private void addTimeToMine( String mine, long miningDuration )
*
* @param earnings
*/
- public void addEarnings( double earnings ) {
+ public void addEarnings( double earnings, String mineName ) {
SimpleDateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd_hh:mm");
String key = dateFmt.format( new Date() );
- if ( earningsPerMinute.containsKey( key ) ) {
- earnings += earningsPerMinute.get( key ) + earnings;
+
+ double earningsPM = earnings;
+ if ( getEarningsPerMinute().containsKey( key ) ) {
+ earningsPM += getEarningsPerMinute().get( key );
}
+ getEarningsPerMinute().put( key, earningsPM );
- earningsPerMinute.put( key, earnings );
- if ( earningsPerMinute.size() > 5 ) {
- earningsPerMinute.remove(
- earningsPerMinute.firstEntry().getKey() );
+ if ( getEarningsPerMinute().size() > 5 ) {
+ getEarningsPerMinute().remove(
+ getEarningsPerMinute().firstEntry().getKey() );
}
+ if ( mineName != null && sessionType != SessionType.mining ) {
+ sessionType = SessionType.mining;
+ }
+ if ( mineName == null && getLastMine() != null ) {
+ mineName = getLastMine();
+ }
// If earnings are within the session timeout for mining, then add the
// earnings to the moneyByMine:
- if ( sessionType == SessionType.mining && getLastMine() != null ) {
+ if ( sessionType == SessionType.mining && mineName != null ) {
long duration = System.currentTimeMillis() - sessionTimingLastCheck;
if ( duration < SESSION_TIMEOUT_MINING_MS ) {
- addEarningsByMine( getLastMine(), earnings );
+
+ addEarningsByMine( mineName, earnings );
}
}
@@ -379,6 +488,188 @@ public double getAverageEarningsPerMinute() {
return ( size == 0 ? 0 : ( results / size ));
}
+ private void addTokensByBlocks( String mineName, int blocks ) {
+
+ if ( AutoFeaturesWrapper.getInstance().isBoolean( AutoFeatures.tokensEnabled ) ) {
+ int blocksPerToken = AutoFeaturesWrapper.getInstance().getInteger( AutoFeatures.tokensBlocksPerToken );
+
+ if ( blocksPerToken > 0 ) {
+
+ // If blocksTotal > 10k and tokensLastBlocksTotals == 0, then this means
+ // the player was mining before tokens was enabled, so set the
+ // tokensLastBlocksTotals to the blocks total, minus current block count.
+ if ( tokensLastBlocksTotals == 0 && blocksTotal > 10000 ) {
+ tokensLastBlocksTotals = blocksTotal - blocks;
+ }
+
+ // tokensLastBlocksTotals should never be greater than blocksTotal:
+ if ( tokensLastBlocksTotals > blocksTotal ) {
+ tokensLastBlocksTotals = blocksTotal;
+ }
+
+ double delta = blocksTotal - tokensLastBlocksTotals;
+
+ double tokens = delta / (double) blocksPerToken;
+
+ if ( tokens >= 1.0 ) {
+ long tokensLong = (long) Math.floor( tokens );
+
+ long blocksForTokens = tokensLong * blocksPerToken;
+ tokensLastBlocksTotals += blocksForTokens;
+
+ addTokens( tokensLong, mineName );
+
+ }
+ }
+ }
+ }
+
+ /**
+ *
This stores the tokens from the player so they can
+ * be averaged to find their tokens per minute. Tokens are
+ * automatically generated based upon blocks mined so normally
+ * you wouldn't have to call this function.
+ *
+ *
+ *
If you just want to add tokens, you can pass a null for the
+ * mine name.
+ *
+ *
+ *
Note: Unlike adding blocks from mines, adding tokens with a mine name
+ * does not need to be concerned about session types. If a mine name is
+ * provided, then that's the mine it should be attributed to.
+ *
+ *
+ * @param newTokens
+ */
+ public void addTokens( long newTokens, String mineName ) {
+
+ addTokens( newTokens );
+
+ SimpleDateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd_hh:mm");
+ String key = dateFmt.format( new Date() );
+
+
+ long tokensPM = newTokens;
+ if ( getTokensPerMinute().containsKey( key ) ) {
+ tokensPM += getTokensPerMinute().get( key );
+ }
+ getTokensPerMinute().put( key, tokensPM );
+
+
+ if ( getTokensPerMinute().size() > 5 ) {
+ getTokensPerMinute().remove(
+ getTokensPerMinute().firstEntry().getKey() );
+ }
+
+ // If we are getting tokens from mining, then we have the mine name.
+ // No need to mess with sessions.
+// if ( mineName != null && sessionType != SessionType.mining ) {
+// sessionType = SessionType.mining;
+// }
+// if ( mineName == null && getLastMine() != null ) {
+// mineName = getLastMine();
+// }
+
+ // If earnings are within the session timeout for mining, then add the
+ // earnings to the tokensByMine:
+ if ( mineName != null ) {
+
+ addTokensByMine( mineName, newTokens );
+ }
+
+ dirty = true;
+ }
+
+
+ /**
+ *
This adds tokens to the player, but it is from an admin-related purpose, or task,
+ * so it has no effects on the player's Tokens-Per-Minute calculations, or
+ * per mine stats.
+ *
This removes tokens from the player, but it is from an admin-related purpose, or task,
+ * so it has no effects on the player's Tokens-Per-Minute calculations, or
+ * per mine stats.
+ *
+ *
+ *
Note: The player can have a negative balance with this function! This may be useful for
+ * small "token loans" when purchasing something. Such allowances would have to be
+ * handled in the task that calls this function.
+ *
+ *
+ * @param newTokens
+ */
+ public void removeTokensAdmin( long removeTokens ) {
+
+ this.tokens -= removeTokens;
+ this.tokensTotalAdminRemoved += removeTokens;
+
+ dirty = true;
+ }
+ public void removeTokens( long removeTokens ) {
+
+ this.tokens -= removeTokens;
+
+ dirty = true;
+ }
+
+ public void setTokensAdmin( long newBalance ) {
+
+ if ( this.tokens > newBalance ) {
+
+ long delta = this.tokens - newBalance;
+
+ removeTokensAdmin( delta );
+ }
+ else if ( this.tokens < newBalance ) {
+
+ long delta = newBalance - this.tokens;
+
+ addTokensAdmin( delta );
+ }
+// else {
+// // do nothing if equals and no change is needed:
+// }
+
+ }
+
+ /**
+ * This returns the average tokens earned per minute for the
+ * last 5 minutes.
+ *
+ * @return
+ */
+ public double getAverageTokensPerMinute() {
+ double results = 0;
+
+ int size = 0;
+ for ( double value : tokensPerMinute.values() ) {
+ results += value;
+ size++;
+ }
+
+ return ( size == 0 ? 0 : ( results / size ));
+ }
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
@@ -404,11 +695,27 @@ public String toString() {
.append( " blocks: " )
.append( blocksByType )
+ .append( " avg tokens/min: " )
+ .append( getAverageTokensPerMinute() )
+ .append( " tokens: " )
+ .append( getTokens() )
+ .append( " totalTokens earned: " )
+ .append( getTokensTotal() )
+ .append( " totalTokensAdminAdded: " )
+ .append( getTokensTotalAdminAdded() )
+ .append( " totalTokensAdminRemoved: " )
+ .append( getTokensTotalAdminRemoved() )
;
return sb.toString();
}
-
+
+ public void updateLastSeen() {
+
+ if ( getPlayer() != null && getPlayer().isOnline() ) {
+ lastSeenDate = System.currentTimeMillis();
+ }
+ }
protected Player getPlayer() {
return player;
@@ -417,6 +724,13 @@ protected void setPlayer( Player player ) {
this.player = player;
}
+ public long getLastSeenDate() {
+ return lastSeenDate;
+ }
+ public void setLastSeenDate( long lastSeenDate ) {
+ this.lastSeenDate = lastSeenDate;
+ }
+
public File getPlayerFile() {
return playerFile;
}
@@ -510,6 +824,55 @@ public void setTimeByMine( TreeMap timeByMine ) {
this.timeByMine = timeByMine;
}
+ public long getTokens() {
+ return tokens;
+ }
+ public void setTokens( long tokens ) {
+ this.tokens = tokens;
+ }
+
+ public long getTokensTotal() {
+ return tokensTotal;
+ }
+ public void setTokensTotal( long tokensTotal ) {
+ this.tokensTotal = tokensTotal;
+ }
+
+ public long getTokensTotalAdminAdded() {
+ return tokensTotalAdminAdded;
+ }
+ public void setTokensTotalAdminAdded( long tokensTotalAdminAdded ) {
+ this.tokensTotalAdminAdded = tokensTotalAdminAdded;
+ }
+
+ public long getTokensTotalAdminRemoved() {
+ return tokensTotalAdminRemoved;
+ }
+ public void setTokensTotalAdminRemoved( long tokensTotalAdminRemoved ) {
+ this.tokensTotalAdminRemoved = tokensTotalAdminRemoved;
+ }
+
+ public long getTokensLastBlocksTotals() {
+ return tokensLastBlocksTotals;
+ }
+ public void setTokensLastBlocksTotals( long tokensLastBlocksTotals ) {
+ this.tokensLastBlocksTotals = tokensLastBlocksTotals;
+ }
+
+ public TreeMap getTokensByMine() {
+ return tokensByMine;
+ }
+ public void setTokensByMine( TreeMap tokensByMine ) {
+ this.tokensByMine = tokensByMine;
+ }
+
+ public TreeMap getTokensPerMinute() {
+ return tokensPerMinute;
+ }
+ public void setTokensPerMinute( TreeMap tokensPerMinute ) {
+ this.tokensPerMinute = tokensPerMinute;
+ }
+
public String getLastMine() {
return lastMine;
}
@@ -524,6 +887,20 @@ public void setEarningsByMine( TreeMap earningsByMine ) {
this.earningsByMine = earningsByMine;
}
+ public PlayerMessaging getPlayerMessaging() {
+ return playerMessaging;
+ }
+ public void setPlayerMessaging( PlayerMessaging playerMessaging ) {
+ this.playerMessaging = playerMessaging;
+ }
+
+ public List getBackpacks() {
+ return backpacks;
+ }
+ public void setBackpacks( List backpacks ) {
+ this.backpacks = backpacks;
+ }
+
public boolean isDirty() {
return dirty;
}
diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheSaveAllPlayersTask.java b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheSaveAllPlayersTask.java
index e4802a3d6..a3f0d3234 100644
--- a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheSaveAllPlayersTask.java
+++ b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheSaveAllPlayersTask.java
@@ -44,6 +44,7 @@
public class PlayerCacheSaveAllPlayersTask
extends PlayerCacheRunnable
{
+ public static long LAST_SEEN_INTERVAL_30_MINUTES = 30 * 60 * 1000;
@Override
public void run()
@@ -59,23 +60,40 @@ public void run()
{
PlayerCachePlayerData playerData = pCache.getPlayers().get( key );
- if ( playerData != null && playerData.isDirty() ) {
+ if ( playerData != null ) {
- try
- {
- playerData.setDirty( false );
- pCache.getCacheFiles().toJsonFile( playerData );
+ // If the player is online plus.. if dirty, or never last seen, or
+ // it's been more than 30 minutes since update of last seen field:
+ if ( playerData.isOnline() &&
+ (playerData.isDirty() ||
+ playerData.getLastSeenDate() == 0 ||
+ (System.currentTimeMillis() - playerData.getLastSeenDate())
+ > LAST_SEEN_INTERVAL_30_MINUTES ) ) {
+ // Update the player's last seen date only when dirty and they
+ // are online:
+ playerData.setLastSeenDate( System.currentTimeMillis() );
+ playerData.setDirty( true );
}
- catch ( Exception e )
- {
- String message = String.format(
- "PlayerCache: Error trying to save a player's " +
- "cache data. Will try again later. " +
- "%s", e.getMessage() );
- Output.get().logError( message, e );
+
+ if ( playerData.isDirty() ) {
+
+ try
+ {
+ playerData.setDirty( false );
+ pCache.getCacheFiles().toJsonFile( playerData );
+ }
+ catch ( Exception e )
+ {
+ String message = String.format(
+ "PlayerCache: Error trying to save a player's " +
+ "cache data. Will try again later. " +
+ "%s", e.getMessage() );
+ Output.get().logError( message, e );
+ }
}
}
+
// If a cached item is found with the player being offline, then
// purge them from the cache. They were usually added only because
// some process had to inspect their stats, so they are safe to remove.
diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/TopNBalancesComparator.java b/prison-core/src/main/java/tech/mcprison/prison/cache/TopNBalancesComparator.java
new file mode 100644
index 000000000..86a318877
--- /dev/null
+++ b/prison-core/src/main/java/tech/mcprison/prison/cache/TopNBalancesComparator.java
@@ -0,0 +1,13 @@
+package tech.mcprison.prison.cache;
+
+import java.util.Comparator;
+
+public class TopNBalancesComparator
+ implements Comparator
+{
+
+ @Override
+ public int compare( TopNStatsData o1, TopNStatsData o2 ) {
+ return Double.compare( o1.getCurrentBalance(), o2.getCurrentBalance() );
+ }
+}
diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/TopNBlocksComparator.java b/prison-core/src/main/java/tech/mcprison/prison/cache/TopNBlocksComparator.java
new file mode 100644
index 000000000..63b6cb9e7
--- /dev/null
+++ b/prison-core/src/main/java/tech/mcprison/prison/cache/TopNBlocksComparator.java
@@ -0,0 +1,14 @@
+package tech.mcprison.prison.cache;
+
+import java.util.Comparator;
+
+public class TopNBlocksComparator
+ implements Comparator
+{
+
+ @Override
+ public int compare( TopNStatsData o1, TopNStatsData o2 ) {
+ return Long.compare( o1.getTotalBlocks(), o2.getTotalBlocks() );
+ }
+
+}
diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/TopNRanksComparator.java b/prison-core/src/main/java/tech/mcprison/prison/cache/TopNRanksComparator.java
new file mode 100644
index 000000000..b54b83967
--- /dev/null
+++ b/prison-core/src/main/java/tech/mcprison/prison/cache/TopNRanksComparator.java
@@ -0,0 +1,52 @@
+package tech.mcprison.prison.cache;
+
+import java.util.Comparator;
+
+public class TopNRanksComparator
+ implements Comparator
+{
+ @Override
+ public int compare( TopNStatsData o1, TopNStatsData o2 ) {
+
+ int results = 0;
+
+ if ( o1.getTopRankPrestiges() == null && o2.getTopRankPrestiges() == null ) {
+ results = 0;
+ }
+ if ( o1.getTopRankPrestiges() == null ) {
+ return 1;
+ }
+ if ( o2.getTopRankPrestiges() == null ) {
+ return -1;
+ }
+
+ if ( o1.getTopRankDefault() == null && o2.getTopRankDefault() == null ) {
+ return Double.compare( o1.getCurrentBalance(), o2.getCurrentBalance() );
+ }
+ if ( o1.getTopRankDefault() == null ) {
+ return 1;
+ }
+ if ( o2.getTopRankDefault() == null ) {
+ return -1;
+ }
+
+ results = Integer.compare(
+ o1.getTopRankPrestiges().getPosition(),
+ o2.getTopRankPrestiges().getPosition() );
+
+ if ( results == 0 ) {
+
+ results = Integer.compare(
+ o1.getTopRankDefault().getPosition(),
+ o2.getTopRankDefault().getPosition() );
+
+ if ( results == 0 ) {
+
+ results = Double.compare( o1.getCurrentBalance(), o2.getCurrentBalance() );
+ }
+
+ }
+
+ return 0;
+ }
+}
diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/TopNStats.java b/prison-core/src/main/java/tech/mcprison/prison/cache/TopNStats.java
new file mode 100644
index 000000000..9b8f1ce92
--- /dev/null
+++ b/prison-core/src/main/java/tech/mcprison/prison/cache/TopNStats.java
@@ -0,0 +1,55 @@
+package tech.mcprison.prison.cache;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class TopNStats
+{
+
+ private static TopNStats instance;
+
+ List mainList;
+
+ List topBlocksList;
+ List topTokensList;
+ List topBalancesList;
+
+ List topRanksList;
+
+
+
+ private TopNStats() {
+ super();
+
+ this.mainList = new ArrayList<>();
+ }
+
+ public static TopNStats getInstance() {
+ if ( instance == null ) {
+ synchronized ( TopNStats.class )
+ {
+ if ( instance == null ) {
+
+ instance = new TopNStats();
+ }
+ }
+ }
+ return instance;
+ }
+
+
+ protected void sortAllLists() {
+
+ Collections.sort( topBlocksList, new TopNBlocksComparator() );
+
+ Collections.sort( topTokensList, new TopNTokensComparator() );
+
+ Collections.sort( topBalancesList, new TopNBalancesComparator() );
+
+ Collections.sort( topRanksList, new TopNRanksComparator() );
+
+ }
+
+
+}
diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/TopNStatsData.java b/prison-core/src/main/java/tech/mcprison/prison/cache/TopNStatsData.java
new file mode 100644
index 000000000..c4c08029a
--- /dev/null
+++ b/prison-core/src/main/java/tech/mcprison/prison/cache/TopNStatsData.java
@@ -0,0 +1,112 @@
+package tech.mcprison.prison.cache;
+
+import tech.mcprison.prison.ranks.data.Rank;
+
+public class TopNStatsData
+{
+
+ private String playerUuid;
+ private String playerName;
+
+
+ private long totalBlocks;
+
+ private long currentTokens;
+ private double currentBalance;
+
+
+ private String topRankPrestigesName;
+ private String topRankDefaultName;
+
+ private transient Rank topRankPrestiges;
+ private transient Rank topRankDefault;
+
+
+ private long lastSeenDate;
+
+ private long lastUpdateDate;
+
+
+ public TopNStatsData() {
+ super();
+
+ }
+
+ public String getPlayerUuid() {
+ return playerUuid;
+ }
+ public void setPlayerUuid( String playerUuid ) {
+ this.playerUuid = playerUuid;
+ }
+
+ public String getPlayerName() {
+ return playerName;
+ }
+ public void setPlayerName( String playerName ) {
+ this.playerName = playerName;
+ }
+
+ public long getTotalBlocks() {
+ return totalBlocks;
+ }
+ public void setTotalBlocks( long totalBlocks ) {
+ this.totalBlocks = totalBlocks;
+ }
+
+ public long getCurrentTokens() {
+ return currentTokens;
+ }
+ public void setCurrentTokens( long currentTokens ) {
+ this.currentTokens = currentTokens;
+ }
+
+ public double getCurrentBalance() {
+ return currentBalance;
+ }
+ public void setCurrentBalance( double currentBalance ) {
+ this.currentBalance = currentBalance;
+ }
+
+ public String getTopRankPrestigesName() {
+ return topRankPrestigesName;
+ }
+ public void setTopRankPrestigesName( String topRankPrestigesName ) {
+ this.topRankPrestigesName = topRankPrestigesName;
+ }
+
+ public String getTopRankDefaultName() {
+ return topRankDefaultName;
+ }
+ public void setTopRankDefaultName( String topRankDefaultName ) {
+ this.topRankDefaultName = topRankDefaultName;
+ }
+
+ public Rank getTopRankPrestiges() {
+ return topRankPrestiges;
+ }
+ public void setTopRankPrestiges( Rank topRankPrestiges ) {
+ this.topRankPrestiges = topRankPrestiges;
+ }
+
+ public Rank getTopRankDefault() {
+ return topRankDefault;
+ }
+ public void setTopRankDefault( Rank topRankDefault ) {
+ this.topRankDefault = topRankDefault;
+ }
+
+ public long getLastSeenDate() {
+ return lastSeenDate;
+ }
+ public void setLastSeenDate( long lastSeenDate ) {
+ this.lastSeenDate = lastSeenDate;
+ }
+
+ public long getLastUpdateDate() {
+ return lastUpdateDate;
+ }
+ public void setLastUpdateDate( long lastUpdateDate ) {
+ this.lastUpdateDate = lastUpdateDate;
+ }
+
+}
diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/TopNTokensComparator.java b/prison-core/src/main/java/tech/mcprison/prison/cache/TopNTokensComparator.java
new file mode 100644
index 000000000..172e9f198
--- /dev/null
+++ b/prison-core/src/main/java/tech/mcprison/prison/cache/TopNTokensComparator.java
@@ -0,0 +1,13 @@
+package tech.mcprison.prison.cache;
+
+import java.util.Comparator;
+
+public class TopNTokensComparator
+ implements Comparator
+{
+
+ @Override
+ public int compare( TopNStatsData o1, TopNStatsData o2 ) {
+ return Long.compare( o1.getCurrentTokens(), o2.getCurrentTokens() );
+ }
+}
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 60595d1bc..19ac5379b 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
@@ -289,6 +289,17 @@ public ChatDisplay getHelpMessage(RegisteredCommand command) {
}
}
+
+ ArrayList excludedWorlds = buildExcludedWorlds();
+ if ( excludedWorlds.size() > 1 ) {
+ for ( String excludedWorld : excludedWorlds )
+ {
+ chatDisplay.addText( excludedWorld );
+ }
+
+ }
+
+
}
@@ -296,6 +307,41 @@ public ChatDisplay getHelpMessage(RegisteredCommand command) {
// return message.toArray(new String[0]);
}
+ private ArrayList buildExcludedWorlds() {
+
+ ArrayList message = new ArrayList<>();
+
+ message.add(ChatColor.DARK_AQUA + "Prison is disabled in the following Worlds:");
+
+ TreeSet excludedWorlds = Prison.get().getPlatform().getExcludedWorlds();
+
+ StringBuilder sb = new StringBuilder();
+ int count = 0;
+ for ( String world : excludedWorlds )
+ {
+ if ( sb.length() > 0 ) {
+ sb.append( ", " );
+ }
+
+ if ( count++ > 5 ) {
+
+ message.add( " " + sb.toString() );
+ sb.setLength( 0 );
+ count = 0;
+ }
+
+ sb.append( world );
+
+ }
+
+ if ( sb.length() > 0 ) {
+ message.add( " " + sb.toString() );
+
+ }
+
+ return message;
+ }
+
private ArrayList buildHelpRootCommands() {
ArrayList message = new ArrayList<>();
@@ -526,6 +572,17 @@ public void registerArgumentHandler(Class extends T> clazz,
argHandler.handler = this;
argumentHandlers.put(clazz, argHandler);
}
+
+ public Object getRegisteredCommandClass( @SuppressWarnings( "rawtypes" ) Class commandClass ) {
+ Object results = null;
+
+ String key = commandClass.getSimpleName();
+ if ( key != null && getRegisteredCommands().containsKey( key ) ) {
+ results = getRegisteredCommands().get( key );
+ }
+
+ return results;
+ }
public void registerCommands(Object methodInstance) {
@@ -540,10 +597,16 @@ public void registerCommands(Object methodInstance) {
}
RegisteredCommand mainCommand = commandRegisterConfig( method, commandAnno, methodInstance );
+
+
+ String[] aliases = addConfigAliases( commandAnno.identifier(), commandAnno.aliases() );
- if ( commandAnno.aliases() != null && commandAnno.aliases().length > 0 ) {
+ if ( aliases.length > 0 ) {
+// if ( commandAnno.aliases() != null && commandAnno.aliases().length > 0 ) {
+
- for ( String alias : commandAnno.aliases() )
+ for ( String alias : aliases )
+// for ( String alias : commandAnno.aliases() )
{
RegisteredCommand aliasCommand = commandRegisterConfig( method, commandAnno, methodInstance, alias );
@@ -561,7 +624,8 @@ private RegisteredCommand commandRegisterConfig( Method method, Command commandA
return commandRegisterConfig( method, commandAnno, methodInstance, null );
}
- private RegisteredCommand commandRegisterConfig( Method method, Command commandAnno, Object methodInstance, String alias ) {
+ private RegisteredCommand commandRegisterConfig( Method method, Command commandAnno,
+ Object methodInstance, String alias ) {
String[] identifiers = ( alias == null ? commandAnno.identifier() : alias).split(" ");
if (identifiers.length == 0) {
@@ -573,10 +637,16 @@ private RegisteredCommand commandRegisterConfig( Method method, Command commandA
PluginCommand rootPluginCommand = plugin.getPlatform().getCommand(label).orElse( null );
if ( rootPluginCommand == null ) {
+
+ String[] aliases = addConfigAliases( commandAnno.identifier(), commandAnno.aliases() );
rootPluginCommand = new PluginCommand(label,
commandAnno.description(),
"/" + label,
- commandAnno.aliases() );
+ aliases );
+// rootPluginCommand = new PluginCommand(label,
+// commandAnno.description(),
+// "/" + label,
+// commandAnno.aliases() );
plugin.getPlatform().registerCommand(rootPluginCommand);
}
@@ -647,7 +717,34 @@ private RegisteredCommand commandRegisterConfig( Method method, Command commandA
}
- public boolean onCommand(CommandSender sender, PluginCommand command, String label,
+ public static String[] addConfigAliases( String label, String[] aliases )
+ {
+ String[] results = aliases;
+
+ String configKey = "prisonCommandHandler.aliases." + label.replace( " ", "." );
+
+ List> ca = Prison.get().getPlatform().getConfigStringArray( configKey );
+ if ( ca != null && ca.size() > 0 && ca.get( 0 ) instanceof String ) {
+
+ List configAliases = new ArrayList<>();
+
+ for ( String alias : aliases ) {
+ configAliases.add( alias );
+ }
+
+ for ( Object aliasObj : ca ) {
+ if ( aliasObj instanceof String ) {
+ configAliases.add( aliasObj.toString() );
+ }
+ }
+
+ results = configAliases.toArray( new String[0] );
+
+ }
+ return results;
+ }
+
+ public boolean onCommand(CommandSender sender, PluginCommand command, String label,
String[] args) {
RootCommand rootCommand = rootCommands.get(command);
diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/RegisteredCommand.java b/prison-core/src/main/java/tech/mcprison/prison/commands/RegisteredCommand.java
index ba3627088..d2eaf3cc7 100644
--- a/prison-core/src/main/java/tech/mcprison/prison/commands/RegisteredCommand.java
+++ b/prison-core/src/main/java/tech/mcprison/prison/commands/RegisteredCommand.java
@@ -260,7 +260,10 @@ private void executeMethod(CommandSender sender, String[] args) {
// to prevent this failure, escape all % with a double % such as %%.
message = message.replace( "%", "%%" );
- Output.get().sendError( sender, message );
+ Output.get().logError( message );
+
+ Output.get().sendError( sender, "An exception has occurred. Details have been " +
+ "logged to the server's console." );
// Generally these errors are major and require program fixes, so throw
// the exception so the stacklist is logged.
@@ -396,7 +399,12 @@ void set(Object methodInstance, Method method) {
this.description = command.description();
this.permissions = command.permissions();
this.altPermissions = command.altPermissions();
- this.aliases = command.aliases();
+
+ String[] aliases = CommandHandler.addConfigAliases( command.identifier(), command.aliases() );
+ //addConfigAliases( command.identifier(), command.aliases() );
+ this.aliases = aliases;
+
+// this.aliases = command.aliases();
this.docURLs = command.docURLs();
this.onlyPlayers = command.onlyPlayers();
@@ -517,6 +525,34 @@ void set(Object methodInstance, Method method) {
this.set = true;
}
+
+// private String[] addConfigAliases( String label, String[] aliases )
+// {
+// String[] results = aliases;
+//
+// String configKey = "prisonCommandHandler.aliases." + label.replace( " ", "." );
+//
+// List> ca = Prison.get().getPlatform().getConfigStringArray( configKey );
+// if ( ca != null && ca.size() > 0 && ca.get( 0 ) instanceof String ) {
+//
+// List configAliases = new ArrayList<>();
+//
+// for ( String alias : aliases ) {
+// configAliases.add( alias );
+// }
+//
+// for ( Object aliasObj : ca ) {
+// if ( aliasObj instanceof String ) {
+// configAliases.add( aliasObj.toString() );
+// }
+// }
+//
+// results = configAliases.toArray( new String[0] );
+//
+// }
+// return results;
+// }
+
public boolean testPermission(CommandSender sender) {
if (!set) {
return true;
diff --git a/prison-core/src/main/java/tech/mcprison/prison/discord/DiscordWebhook.java b/prison-core/src/main/java/tech/mcprison/prison/discord/DiscordWebhook.java
index 2490a5f95..09203dfb6 100644
--- a/prison-core/src/main/java/tech/mcprison/prison/discord/DiscordWebhook.java
+++ b/prison-core/src/main/java/tech/mcprison/prison/discord/DiscordWebhook.java
@@ -205,12 +205,12 @@ public void execute() throws IOException {
json.put("embeds", embedObjects.toArray());
}
- if ( Output.get().isDebug( DebugTarget.support ) ) {
- String jsonString = json.toString();
- Output.get().logDebug( DebugTarget.support,
- "Prison Webhook debug: jsonSize: " + jsonString.length() +
- " " + jsonString );
- }
+// if ( Output.get().isDebug( DebugTarget.support ) ) {
+// String jsonString = json.toString();
+// Output.get().logDebug( DebugTarget.support,
+// "Prison Webhook debug: jsonSize: " + jsonString.length() +
+// " " + jsonString );
+// }
URL url = new URL(this.url);
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
diff --git a/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonDiscordWebhook.java b/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonDiscordWebhook.java
index 085de2af6..66b4b40ec 100644
--- a/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonDiscordWebhook.java
+++ b/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonDiscordWebhook.java
@@ -80,19 +80,19 @@ public void send( CommandSender sender, String title, String message, boolean ad
}
- if ( Output.get().isDebug( DebugTarget.support ) ) {
- Output.get().logDebug( DebugTarget.support,
- "Prison Webhook debug: total fields: %d total chars: %d ",
- getFields().size(), totalSize );
-
- if ( getFields().size() > 25 || totalSize > 6000 ) {
- Output.get().logDebug( DebugTarget.support,
- "Prison Webhook debug: total fields: Failure. Max number of " +
- "fields is 25. Max number of characters is 6000. Please reduce " +
- "these to bring in to complience and resubmit. " );
- }
-
- }
+// if ( Output.get().isDebug( DebugTarget.support ) ) {
+// Output.get().logDebug( DebugTarget.support,
+// "Prison Webhook debug: total fields: %d total chars: %d ",
+// getFields().size(), totalSize );
+//
+// if ( getFields().size() > 25 || totalSize > 6000 ) {
+// Output.get().logDebug( DebugTarget.support,
+// "Prison Webhook debug: total fields: Failure. Max number of " +
+// "fields is 25. Max number of characters is 6000. Please reduce " +
+// "these to bring in to complience and resubmit. " );
+// }
+//
+// }
String results = submitWebhook( webhook );
diff --git a/prison-core/src/main/java/tech/mcprison/prison/error/ErrorManager.java b/prison-core/src/main/java/tech/mcprison/prison/error/ErrorManager.java
index f6185730c..cca993416 100644
--- a/prison-core/src/main/java/tech/mcprison/prison/error/ErrorManager.java
+++ b/prison-core/src/main/java/tech/mcprison/prison/error/ErrorManager.java
@@ -31,7 +31,7 @@ public class ErrorManager {
public ErrorManager(PluginEntity owner) {
this.owner = owner;
- this.errorDir = new File(owner.getDataFolder(), "errors");
+ this.errorDir = new File(owner.getModuleDataFolder(), "errors");
if (!this.errorDir.exists()) {
this.errorDir.mkdir();
}
diff --git a/prison-core/src/main/java/tech/mcprison/prison/file/FileCollection.java b/prison-core/src/main/java/tech/mcprison/prison/file/FileCollection.java
index d7785aad5..a94d97860 100644
--- a/prison-core/src/main/java/tech/mcprison/prison/file/FileCollection.java
+++ b/prison-core/src/main/java/tech/mcprison/prison/file/FileCollection.java
@@ -101,5 +101,14 @@ public boolean delete(String name)
File dbFile = new File(collDir, name + ".json");
return virtualDelete( dbFile );
}
+
+ @Override
+ public File backup( String name )
+ {
+ File dbFile = new File(collDir, name + ".json");
+ File backupFile = virtualBackup( dbFile );
+
+ return backupFile;
+ }
}
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 75071c04f..5c9f58bf0 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
@@ -9,6 +9,7 @@
import java.util.Date;
import java.util.List;
+import tech.mcprison.prison.Prison;
import tech.mcprison.prison.error.Error;
import tech.mcprison.prison.error.ErrorManager;
import tech.mcprison.prison.modules.ModuleStatus;
@@ -28,6 +29,11 @@ public FileIO()
this(null, null);
}
+ /**
+ *
+ * @param errorManager Optional; set to null if used outside of a module.
+ * @param status Optional; set to null if used outside of a module.
+ */
public FileIO(ErrorManager errorManager, ModuleStatus status)
{
super();
@@ -39,12 +45,45 @@ public FileIO(ErrorManager errorManager, ModuleStatus status)
}
+ public File getProjectRootDiretory() {
+ return Prison.get().getDataFolder();
+ }
+
+ public File getTempFile( File file ) {
+ String tempFileName = file.getName() + "." + getTimestampFormat() + ".tmp";
+ File tempFile = new File(file.getParentFile(), tempFileName);
+
+ return tempFile;
+ }
+
+ /**
+ *
This generates a new File with the filename of the backup file.
+ * This function only generates the File object and does not modify
+ * or save anything on the file system.
+ *
+ *
+ * @param file The original file name
+ * @param backupTag A no-spaced tag name to identify the type of backup.
+ * This is inserted after the original file name.
+ * @param suffix File suffix to use for the backup, not including the dot.
+ * @return File objct of the target backup file.
+ */
+ public File getBackupFile( File file, String backupTag, String suffix ) {
+
+ String tempFileName = file.getName() + "." + backupTag + "_" +
+ getTimestampFormat() + "." + suffix;
+ File tempFile = new File(file.getParentFile(), tempFileName);
+
+ return tempFile;
+ }
+
protected void saveFile( File file, String data )
{
if ( file != null && data != null )
{
- String tempFileName = file.getName() + "." + getTimestampFormat() + ".tmp";
- File tempFile = new File(file.getParentFile(), tempFileName);
+ File tempFile = getTempFile( file );
+// String tempFileName = file.getName() + "." + getTimestampFormat() + ".tmp";
+// File tempFile = new File(file.getParentFile(), tempFileName);
try
{
diff --git a/prison-core/src/main/java/tech/mcprison/prison/file/FileVirtualDelete.java b/prison-core/src/main/java/tech/mcprison/prison/file/FileVirtualDelete.java
index 5fc29be28..5be2b65a6 100644
--- a/prison-core/src/main/java/tech/mcprison/prison/file/FileVirtualDelete.java
+++ b/prison-core/src/main/java/tech/mcprison/prison/file/FileVirtualDelete.java
@@ -4,15 +4,21 @@
package tech.mcprison.prison.file;
import java.io.File;
+import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
+import com.google.common.io.Files;
+
+import tech.mcprison.prison.output.Output;
+
/**
*
*/
public abstract class FileVirtualDelete
{
public static final String FILE_LOGICAL_DELETE_PREFIX = ".deleted_";
+ public static final String FILE_LOGICAL_BACKUP_PREFIX = ".backup_";
public FileVirtualDelete()
{
@@ -38,6 +44,36 @@ protected boolean virtualDelete( File source )
return source.renameTo( newName );
}
+ /**
+ *
This function will make a backup of a file source. It's included in this virtual delete
+ * class since it's very similar and by changing the isDeleted() function, the backups can
+ * also be ignored.
+ *
This function will return a boolean value to indicate if it has been logically
* deleted. It will ONLY inspect the beginning of the file name which much have
@@ -49,7 +85,9 @@ protected boolean virtualDelete( File source )
*/
protected boolean isDeleted( File source )
{
- return source.getName().toLowerCase().startsWith( FILE_LOGICAL_DELETE_PREFIX );
+ return
+ source.getName().toLowerCase().startsWith( FILE_LOGICAL_DELETE_PREFIX ) ||
+ source.getName().toLowerCase().startsWith( FILE_LOGICAL_BACKUP_PREFIX );
}
}
diff --git a/prison-core/src/main/java/tech/mcprison/prison/file/JsonFileIO.java b/prison-core/src/main/java/tech/mcprison/prison/file/JsonFileIO.java
index 04482a331..bc872b0e8 100644
--- a/prison-core/src/main/java/tech/mcprison/prison/file/JsonFileIO.java
+++ b/prison-core/src/main/java/tech/mcprison/prison/file/JsonFileIO.java
@@ -14,6 +14,11 @@ public class JsonFileIO
{
private final Gson gson;
+ /**
+ *
+ * @param errorManager Optional; set to null if used outside of a module.
+ * @param status Optional; set to null if used outside of a module.
+ */
public JsonFileIO(ErrorManager errorManager, ModuleStatus status)
{
super(errorManager, status);
diff --git a/prison-core/src/main/java/tech/mcprison/prison/integration/CustomBlockIntegration.java b/prison-core/src/main/java/tech/mcprison/prison/integration/CustomBlockIntegration.java
index 591c13599..e9b118296 100644
--- a/prison-core/src/main/java/tech/mcprison/prison/integration/CustomBlockIntegration.java
+++ b/prison-core/src/main/java/tech/mcprison/prison/integration/CustomBlockIntegration.java
@@ -5,6 +5,7 @@
import tech.mcprison.prison.internal.block.Block;
import tech.mcprison.prison.internal.block.PrisonBlock;
import tech.mcprison.prison.internal.block.PrisonBlock.PrisonBlockType;
+import tech.mcprison.prison.util.Location;
public abstract class CustomBlockIntegration
extends IntegrationCore {
@@ -44,7 +45,9 @@ public CustomBlockIntegration( String keyName, String providerName,
public abstract PrisonBlock getCustomBlock( Block block );
public abstract Block setCustomBlockId( Block block, String customId, boolean doBlockUpdate );
-
+
+ public abstract void setCustomBlockIdAsync( PrisonBlock prisonBlock, Location location );
+
public abstract List getCustomBlockList();
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 f9386696d..c9029ef8f 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
@@ -22,6 +22,8 @@
import java.util.Optional;
import java.util.UUID;
+import tech.mcprison.prison.cache.PlayerCache;
+import tech.mcprison.prison.cache.PlayerCachePlayerData;
import tech.mcprison.prison.internal.block.Block;
import tech.mcprison.prison.internal.inventory.InventoryHolder;
import tech.mcprison.prison.internal.scoreboard.Scoreboard;
@@ -144,6 +146,11 @@ public interface Player
public void setActionBar( String actionBar );
+
+ public PlayerCache getPlayerCache();
+
+ public PlayerCachePlayerData getPlayerCachePlayerData();
+ public boolean isSneaking();
}
diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/PrisonStatsElapsedTimeNanos.java b/prison-core/src/main/java/tech/mcprison/prison/internal/PrisonStatsElapsedTimeNanos.java
new file mode 100644
index 000000000..9892358ad
--- /dev/null
+++ b/prison-core/src/main/java/tech/mcprison/prison/internal/PrisonStatsElapsedTimeNanos.java
@@ -0,0 +1,28 @@
+package tech.mcprison.prison.internal;
+
+public class PrisonStatsElapsedTimeNanos
+{
+
+ private long elapsedTimeNanos;
+
+ public PrisonStatsElapsedTimeNanos() {
+ super();
+
+ }
+
+ public synchronized void addNanos( Long nanos ) {
+
+ this.elapsedTimeNanos += nanos;
+ }
+
+ public long getElapsedTimeNanos()
+ {
+ return elapsedTimeNanos;
+ }
+
+ public void setElapsedTimeNanos( long elapsedTimeNanos )
+ {
+ this.elapsedTimeNanos = elapsedTimeNanos;
+ }
+
+}
diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/World.java b/prison-core/src/main/java/tech/mcprison/prison/internal/World.java
index 8f1b87117..8541c896d 100644
--- a/prison-core/src/main/java/tech/mcprison/prison/internal/World.java
+++ b/prison-core/src/main/java/tech/mcprison/prison/internal/World.java
@@ -21,6 +21,8 @@
import java.util.List;
import tech.mcprison.prison.internal.block.Block;
+import tech.mcprison.prison.internal.block.MineResetType;
+import tech.mcprison.prison.internal.block.MineTargetPrisonBlock;
import tech.mcprison.prison.internal.block.PrisonBlock;
import tech.mcprison.prison.util.Location;
@@ -37,7 +39,7 @@ public interface World {
*/
String getName();
- /**O
+ /**
* Returns a list of all the players in this world.
*/
List getPlayers();
@@ -53,4 +55,20 @@ public interface World {
public void setBlock( PrisonBlock block, int x, int y, int z );
+
+ /**
+ *
This function should be called from an async task, and it will
+ * drop down in to the synchronous thread to first get the block
+ * from the world, then it will change to the specified PrisonBlock type.
+ *
This is a quick way to check to see if the block was originally set to air, or if
+ * the block was previously broke and "counted". This field, airBroke, needs to be
+ * set to 'true' when the block is counted as broken the first time so it won't be
+ * double counted in the future. Explosion events tends to cause blocks to be
+ * counted multiple times since it does not check to see if they are air prior to
+ * selecting them.
+ *
+ *
+ * @return
+ */
+ public boolean isAirBroke() {
+ return airBroke;
+ }
+ public void setAirBroke( boolean airBroke ) {
+ this.airBroke = airBroke;
+ }
+
+ public boolean isEdge() {
+ return isEdge;
+ }
+ public void setEdge( boolean isEdge ) {
+ this.isEdge = isEdge;
+ }
+
+ public boolean isExploded() {
+ return exploded;
+ }
+ public void setExploded( boolean exploded ) {
+ this.exploded = exploded;
+ }
+
+ public boolean isMined() {
+ return mined;
+ }
+ public void setMined( boolean mined ) {
+ this.mined = mined;
+ }
+
+// public boolean isBlockEvent() {
+// return blockEvent;
+// }
+// public void setBlockEvent( boolean blockEvent ) {
+// this.blockEvent = blockEvent;
+// }
+
+ public boolean isCounted() {
+ return counted;
+ }
+ public void setCounted( boolean counted ) {
+ this.counted = counted;
+ }
+
+ public Block getMinedBlock() {
+ return minedBlock;
+ }
+ public void setMinedBlock( Block minedBlock ) {
+ this.minedBlock = minedBlock;
+ }
+
+ public boolean isIgnoreAllBlockEvents() {
+ return ignoreAllBlockEvents;
+ }
+ public void setIgnoreAllBlockEvents( boolean ignoreAllBlockEvents ) {
+ this.ignoreAllBlockEvents = ignoreAllBlockEvents;
+ }
+
+ @Override
+ public int compareTo( MineTargetPrisonBlock block ) {
+ return block.getBlockKey().compareTo( block.getBlockKey() );
+ }
+
+ public Location getLocation()
+ {
+ return getBlockKey().getLocation();
+ }
+}
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 28aac3252..d56a510a5 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
@@ -18,6 +18,7 @@ public class PrisonBlock
public static PrisonBlock AIR;
public static PrisonBlock GLASS;
+ public static PrisonBlock PINK_STAINED_GLASS;
public static PrisonBlock IGNORE;
public static PrisonBlock NULL_BLOCK;
@@ -38,13 +39,15 @@ public class PrisonBlock
static {
AIR = new PrisonBlock( InternalBlockTypes.AIR.name(), false );
GLASS = new PrisonBlock( InternalBlockTypes.GLASS.name(), true );
+ PINK_STAINED_GLASS = new PrisonBlock( InternalBlockTypes.PINK_STAINED_GLASS.name(), true );
IGNORE = new PrisonBlock( InternalBlockTypes.IGNORE.name(), false );
NULL_BLOCK = new PrisonBlock( InternalBlockTypes.NULL_BLOCK.name(), false );
}
public enum PrisonBlockType {
minecraft,
- CustomItems
+ CustomItems,
+ heads
}
/**
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 31b10143d..c2ff50d8b 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
@@ -33,6 +33,9 @@ public abstract class PrisonBlockStatusData {
private int rangeBlockCountHighLimit;
+ private boolean gravity = false;
+
+
public PrisonBlockStatusData( String blockName, double chance, long blockCountTotal ) {
super();
@@ -57,8 +60,28 @@ public PrisonBlockStatusData( String blockName, double chance, long blockCountTo
this.rangeBlockCountLowLimit = -1;
this.rangeBlockCountHighLimit = -1;
+
+ this.gravity = checkGravityAffects( blockName );
}
+
+
+ @Override
+ public boolean equals( Object obj )
+ {
+ boolean results = false;
+
+ if ( obj instanceof PrisonBlockStatusData ) {
+ PrisonBlockStatusData pbsBlock = (PrisonBlockStatusData) obj;
+
+ results = getBlockName().equalsIgnoreCase( pbsBlock.getBlockName() );
+ }
+
+ return results;
+ }
+
+
+
public void resetAfterSave() {
blockCountUnsaved = 0;
}
@@ -91,7 +114,11 @@ public static PrisonBlock parseFromSaveFileFormat( String blockString ) {
String[] split = blockString.split("-");
if ( split != null && split.length > 0 ) {
+ // The blockName is the first element. Use that to setup the PrisonBlock that
+ // will be used if the other stats that are available.
String blockTypeName = split[0];
+
+
// The new way to get the PrisonBlocks:
// The blocks return are cloned so they have their own instance:
results = Prison.get().getPlatform().getPrisonBlock( blockTypeName );
@@ -115,6 +142,8 @@ public static PrisonBlock parseFromSaveFileFormat( String blockString ) {
public void parseFromSaveFileFormatStats( String blockString ) {
+
+
if ( blockString != null ) {
String[] split = blockString.split("-");
@@ -289,6 +318,64 @@ public void addStats( PrisonBlockStatusData block ) {
}
+
+ /**
+ *
If a block is affected by gravity, which means the block can fall, then
+ * this function will return a value of true.
+ *
+ *
+ *
The items that are most likely to appear in the mine should
+ * be at the top to allow the minimization of what is required to be
+ * checked.
+ *
+ *
+ * https://minecraft.fandom.com/wiki/Falling_Block
+ *
+ * @param blockName
+ * @return
+ */
+ private boolean checkGravityAffects( String blockName )
+ {
+ boolean results = false;
+
+ switch ( blockName )
+ {
+ case "sand":
+ case "red_sand":
+ case "gravel":
+
+ case "white_concrete_powder":
+ case "orange_concrete_powder":
+ case "magenta_concrete_powder":
+ case "light_blue_concrete_powder":
+ case "yellow_concrete_powder":
+ case "lime_concrete_powder":
+ case "pink_concrete_powder":
+ case "gray_concrete_powder":
+ case "light_gray_concrete_powder":
+ case "cyan_concrete_powder":
+ case "purple_concrete_powder":
+ case "blue_concrete_powder":
+ case "brown_concrete_powder":
+ case "green_concrete_powder":
+ case "red_concrete_powder":
+ case "black_concrete_powder":
+
+ case "anvil":
+ case "chipped_anvil":
+ case "damaged_anvil":
+
+ case "scaffolding":
+ case "pointed_dripstone":
+ case "dragon_egg":
+ {
+ results = true;
+ }
+ }
+ return results;
+ }
+
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
@@ -400,4 +487,11 @@ public void setRangeBlockCountHighLimit( int rangeBlockCountHighLimit ) {
this.rangeBlockCountHighLimit = rangeBlockCountHighLimit;
}
+ public boolean isGravity() {
+ return gravity;
+ }
+ public void setGravity( boolean gravity ) {
+ this.gravity = gravity;
+ }
+
}
diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockTypes.java b/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockTypes.java
index b89393abb..5f593abf2 100644
--- a/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockTypes.java
+++ b/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockTypes.java
@@ -20,6 +20,7 @@ public class PrisonBlockTypes {
public enum InternalBlockTypes {
AIR,
GLASS,
+ PINK_STAINED_GLASS,
IGNORE,
NULL_BLOCK
}
diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/events/player/PlayerInteractEvent.java b/prison-core/src/main/java/tech/mcprison/prison/internal/events/player/PrisonPlayerInteractEvent.java
similarity index 92%
rename from prison-core/src/main/java/tech/mcprison/prison/internal/events/player/PlayerInteractEvent.java
rename to prison-core/src/main/java/tech/mcprison/prison/internal/events/player/PrisonPlayerInteractEvent.java
index 0f34ec64f..ab5a328f7 100644
--- a/prison-core/src/main/java/tech/mcprison/prison/internal/events/player/PlayerInteractEvent.java
+++ b/prison-core/src/main/java/tech/mcprison/prison/internal/events/player/PrisonPlayerInteractEvent.java
@@ -29,7 +29,7 @@
* @author Faizaan A. Datoo
* @since API 1.0
*/
-public class PlayerInteractEvent implements Cancelable {
+public class PrisonPlayerInteractEvent implements Cancelable {
private Player player;
private ItemStack itemInHand;
@@ -37,7 +37,7 @@ public class PlayerInteractEvent implements Cancelable {
private Location clicked;
private boolean canceled = false;
- public PlayerInteractEvent(Player player, ItemStack itemInHand, Action action,
+ public PrisonPlayerInteractEvent(Player player, ItemStack itemInHand, Action action,
Location clicked) {
this.player = player;
this.itemInHand = itemInHand;
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 ba68215d0..acd287923 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
@@ -22,6 +22,7 @@
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import java.util.TreeSet;
import java.util.UUID;
import tech.mcprison.prison.commands.PluginCommand;
@@ -311,6 +312,9 @@ default Optional getCommand(String label) {
public double getConfigDouble( String key, double defaultValue );
+
+ public boolean isWorldExcluded( String worldName );
+
/**
* Setup hooks in to the valid prison block types. This will be only the
@@ -370,6 +374,8 @@ public void autoCreateMineLinerAssignment( List rankMineNames,
public void traceEventListenersBlockBreakEvents( CommandSender sender );
+ public String dumpEventListenersPlayerInteractEvents();
+
public void testPlayerUtil( UUID uuid );
@@ -421,5 +427,18 @@ public void autoCreateMineLinerAssignment( List rankMineNames,
public void reloadAutoFeaturesEventListeners();
+ void setTitle( Player player, String title, String subtitle, int fadeIn, int stay, int fadeOut );
+
+
+ void setActionBar( Player player, String actionBar );
+
+
+ public TreeSet getExcludedWorlds();
+
+
+ public List> getConfigStringArray( String key );
+
+
+ public int compareServerVerisonTo( String comparisonVersion );
}
diff --git a/prison-core/src/main/java/tech/mcprison/prison/localization/LocaleManager.java b/prison-core/src/main/java/tech/mcprison/prison/localization/LocaleManager.java
index 644889ef4..4ec090789 100755
--- a/prison-core/src/main/java/tech/mcprison/prison/localization/LocaleManager.java
+++ b/prison-core/src/main/java/tech/mcprison/prison/localization/LocaleManager.java
@@ -189,7 +189,7 @@ public String toString() {
public File getLocalDataFolder() {
// Setup the local folders:
- File dataFolder = fixPrisonCoreLanguagePath( getOwningPlugin().getDataFolder() );
+ File dataFolder = fixPrisonCoreLanguagePath( getOwningPlugin().getModuleDataFolder() );
File localeDirectory = new File(dataFolder, LOCALE_FOLDER);
// if the folder does not exist, try to create it:
@@ -497,7 +497,7 @@ private void loadCustomLocales() {
private File fixPrisonCoreLanguagePath( File targetPath ) {
if ( !targetPath.getAbsolutePath().startsWith(
ModuleManager.getModuleRootDefault().getAbsolutePath() ) ) {
- targetPath = Module.setupDataFolder( Prison.PSEDUO_MODLE_NAME );
+ targetPath = Module.setupModuleDataFolder( Prison.PSEDUO_MODLE_NAME );
}
return targetPath;
}
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 3871fcf30..8878a9098 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
@@ -153,6 +153,17 @@ public Localizable setFailNormally() {
* @since 1.0
*/
public Localizable withReplacements(String... replacements) {
+ if ( replacements == null ) {
+ replacements = new String[1];
+ replacements[0] = "";
+ }
+ else {
+ for ( int i = 0; i < replacements.length; i++ ) {
+ if ( replacements[i] == null ) {
+ replacements[i] = "";
+ }
+ }
+ }
this.replacements = Arrays.copyOf(replacements, replacements.length);
this.locReplacements = null;
return this;
@@ -344,7 +355,11 @@ public String localizeFor(CommandSender sender) {
* @since 1.0
*/
public void sendTo(CommandSender sender, LogLevel level) {
- Output.get().sendMessage(sender, localizeFor(sender), level);
+ String message = localizeFor(sender);
+ if ( message != null && !message.isEmpty() ) {
+
+ Output.get().sendMessage(sender, message, level);
+ }
}
/**
@@ -370,10 +385,15 @@ public void sendTo(CommandSender sender) {
* @since 1.0
*/
public void broadcast() {
- for (Player player : Prison.get().getPlatform().getOnlinePlayers()) {
- sendTo(player);
- }
- Output.get().logInfo(localize());
+
+ String message = localize();
+ if ( message != null && !message.isEmpty() ) {
+
+ for (Player player : Prison.get().getPlatform().getOnlinePlayers()) {
+ sendTo(player);
+ }
+ Output.get().logInfo( message );
+ }
}
/**
@@ -384,12 +404,16 @@ public void broadcast() {
* @since 1.0
*/
public void broadcast(World... worlds) {
- for (World w : worlds) {
- for (Player player : w.getPlayers()) {
- sendTo(player);
- }
- }
- Output.get().logInfo(localize());
+ String message = localize();
+ if ( message != null && !message.isEmpty() ) {
+
+ for (World w : worlds) {
+ for (Player player : w.getPlayers()) {
+ sendTo(player);
+ }
+ }
+ Output.get().logInfo( message );
+ }
}
/**
diff --git a/prison-core/src/main/java/tech/mcprison/prison/modules/Module.java b/prison-core/src/main/java/tech/mcprison/prison/modules/Module.java
index 4c95f0cab..65a982a9e 100644
--- a/prison-core/src/main/java/tech/mcprison/prison/modules/Module.java
+++ b/prison-core/src/main/java/tech/mcprison/prison/modules/Module.java
@@ -37,7 +37,8 @@ public abstract class Module implements PluginEntity {
*/
private String name, version;
- private File dataFolder;
+ private File moduleDataFolder;
+
private int apiTarget;
private ModuleStatus status;
private ErrorManager errorManager;
@@ -58,18 +59,18 @@ public Module(String name, String version, int target) {
this.version = version;
this.apiTarget = target;
- this.dataFolder = setupDataFolder( name );
+ this.moduleDataFolder = setupModuleDataFolder( name );
this.status = new ModuleStatus();
this.errorManager = new ErrorManager(this);
}
- public static File setupDataFolder( String name ) {
+ public static File setupModuleDataFolder( String name ) {
File dataFolder = new File(ModuleManager.getModuleRootDefault(),
name.toLowerCase().replace(" ", "_"));
if (!dataFolder.exists()) {
- dataFolder.mkdir();
+ dataFolder.mkdirs();
}
return dataFolder;
}
@@ -185,8 +186,8 @@ public ModuleStatus getStatus() {
*
* @return The {@link File} representing the data folder.
*/
- public File getDataFolder() {
- return dataFolder;
+ public File getModuleDataFolder() {
+ return moduleDataFolder;
}
}
diff --git a/prison-core/src/main/java/tech/mcprison/prison/modules/PluginEntity.java b/prison-core/src/main/java/tech/mcprison/prison/modules/PluginEntity.java
index 03b3da3f6..6e64f95ff 100644
--- a/prison-core/src/main/java/tech/mcprison/prison/modules/PluginEntity.java
+++ b/prison-core/src/main/java/tech/mcprison/prison/modules/PluginEntity.java
@@ -30,6 +30,6 @@ public interface PluginEntity {
String getName();
- File getDataFolder();
+ File getModuleDataFolder();
}
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 1b3f3ac1e..165f711f1 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
@@ -19,10 +19,12 @@
package tech.mcprison.prison.output;
import java.util.Arrays;
+import java.util.FormatFlagsConversionMismatchException;
import java.util.HashSet;
import java.util.MissingFormatArgumentException;
import java.util.Set;
import java.util.TreeSet;
+import java.util.UnknownFormatConversionException;
import tech.mcprison.prison.Prison;
import tech.mcprison.prison.internal.CommandSender;
@@ -55,6 +57,7 @@ public class Output
private boolean debug = false;
private Set activeDebugTargets;
+ private Set selectiveDebugTargets;
public enum DebugTarget {
all,
@@ -62,12 +65,14 @@ public enum DebugTarget {
off,
blockBreak,
// blockBreakListeners,
- blockBreakDurability,
+// blockBreakDurability,
blockBreakFortune,
- blockBreakXpCalcs,
+// blockBreakXpCalcs, // Removed since it was inlined
- rankup,
- support
+ targetBlockMismatch,
+
+ rankup
+// support
;
public static DebugTarget fromString( String target ) {
@@ -105,6 +110,7 @@ private Output() {
instance = this;
this.activeDebugTargets = new HashSet<>();
+ this.selectiveDebugTargets = new HashSet<>();
this.prefixTemplate = coreOutputPrefixTemplateMsg();
@@ -197,7 +203,10 @@ public String format(String message, LogLevel level, Object... args) {
* Log a message with a specified {@link LogLevel}
*/
public void log(String message, LogLevel level, Object... args) {
- if ( Prison.get() == null || Prison.get().getPlatform() == null ) {
+ if ( message == null || message.trim().isEmpty() ) {
+ // do not send an empty message... do nothing...
+ }
+ else if ( Prison.get() == null || Prison.get().getPlatform() == null ) {
String errorMessage = coreOutputErrorStartupFailureMsg();
if ( errorMessage == null || errorMessage.trim().isEmpty() ) {
// NOTE: The following must remain as is. This is a fallback for if there
@@ -205,7 +214,14 @@ public void log(String message, LogLevel level, Object... args) {
// can be identified along with the reasons.
errorMessage = "Prison: (Sending to System.err due to Output.log Logger failure):";
}
- System.err.println( errorMessage + " " + message );
+
+ StringBuilder sb = new StringBuilder();
+ for ( Object arg : args ) {
+ sb.append( "[" ).append( arg ).append( "] " );
+ }
+
+ System.err.println( errorMessage + " message: [" + message +
+ "] params: " + sb.toString() );
} else {
try {
Prison.get().getPlatform().log(
@@ -229,6 +245,27 @@ public void log(String message, LogLevel level, Object... args) {
getLogColorCode(LogLevel.ERROR) +
errorMessage );
}
+ catch ( UnknownFormatConversionException |
+ FormatFlagsConversionMismatchException e)
+ {
+ StringBuilder sb = new StringBuilder();
+
+ for ( Object arg : args ) {
+ sb.append( "[" ).append( arg ).append( "] " );
+ }
+
+ String errorMessage = "Error with Java format usage (eg %s): " +
+ " LogLevel: " + level.name() +
+ " message: [" + message + "] params: [" + sb.toString() + "]" +
+ " error: [" + e.getMessage() + "]";
+
+ Prison.get().getPlatform().logCore(
+ prefixTemplatePrison + " " +
+ getLogColorCode(LogLevel.ERROR) +
+ errorMessage );
+
+ e.printStackTrace();
+ }
}
}
@@ -306,10 +343,19 @@ public String getDebugTargetsString() {
public void applyDebugTargets( String targets ) {
+ boolean isSelective = targets.contains( "selective" );
+
TreeSet trgts = DebugTarget.fromMultiString( targets );
if ( trgts.size() > 0 ) {
- applyDebugTargets( trgts );
+
+ if ( isSelective ) {
+ applySelectiveDebugTargets( trgts );
+ }
+ else {
+ applyDebugTargets( trgts );
+ }
+
}
else {
// No targets were set, so just toggle the debugger:
@@ -355,9 +401,41 @@ else if ( offTarget ) {
// Output.get().setDebug( !Output.get().isDebug() );
}
+ public void applySelectiveDebugTargets( TreeSet targets ) {
+
+ for ( DebugTarget target : targets ) {
+
+ if ( getSelectiveDebugTargets().contains( target ) ) {
+
+ getSelectiveDebugTargets().remove( target );
+ }
+ else {
+
+ getSelectiveDebugTargets().add( target );
+ }
+
+ }
+
+
+ }
+
public boolean isDebug( DebugTarget debugTarget ) {
- return isDebug() || getActiveDebugTargets().contains( debugTarget );
+ return isDebug() || getActiveDebugTargets().contains( debugTarget ) ||
+ getSelectiveDebugTargets().contains( debugTarget );
+ }
+
+ /**
+ *
This only return true if the specified debug target is enabled.
+ * The global debug mode, and other debugTargets, are ignored.
+ *