diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml
new file mode 100644
index 000000000..0d709ba12
--- /dev/null
+++ b/.github/workflows/gradle.yml
@@ -0,0 +1,25 @@
+name: Prison Build
+
+on: [push]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up JDK 1.8
+ uses: actions/setup-java@v1
+ with:
+ java-version: 1.8
+ - name: Gradlew permission
+ run: chmod +x gradlew
+ - name: Build
+ run: ./gradlew build
+
+ - name: Upload Jar
+ uses: actions/upload-artifact@v2
+ with:
+ name: Prison
+ path: prison-spigot/build/libs/Prison.jar
diff --git a/PrisonSpigotMC.bbcode.txt b/PrisonSpigotMC.bbcode.txt
new file mode 100644
index 000000000..d2873c960
--- /dev/null
+++ b/PrisonSpigotMC.bbcode.txt
@@ -0,0 +1 @@
+[size=200][center][font=Verdana][color=#e69138][b]Prison [/b][/color][/font][/center][/size]
\ No newline at end of file
diff --git a/README.md b/README.md
index bba1119d7..d6c2f0298 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
[![License](https://img.shields.io/badge/license-GPL%20License%20v3-blue.svg)](LICENSE.md)
[![Build Status](https://travis-ci.org/MC-Prison/Prison.svg?branch=master)](https://travis-ci.org/MC-Prison/Prison)
-[![Discord](https://discordapp.com/api/guilds/332602419483770890/widget.png)](https://discord.gg/396ed5F)
+[![Discord](https://discordapp.com/api/guilds/332602419483770890/widget.png)](https://discord.gg/DCJ3j6r)
1. [What is Prison?](#what-is-prison)
2. [Why should I use Prison?](#why-should-i-use-prison)
diff --git a/changelog_v3.2.x.md b/changelog_v3.2.x.md
index b72a3c3e1..9d0f0b811 100644
--- a/changelog_v3.2.x.md
+++ b/changelog_v3.2.x.md
@@ -2,2021 +2,435 @@
## Prison Build Logs for v3.2.x
+## Build logs
+ - **[v3.2.3-alpha - Current](changelog_v3.2.x.md)**
+ - **[v3.2.0 - 2019-12-03](docs/prison_changelog_v3.2.0.md)**
+ - **[v3.2.1 - 2020-09-27](docs/prison_changelog_v3.2.1.md)**
+ - **[v3.2.2 - 2020-11-21](docs/prison_changelog_v3.2.2.md)**
+
+
Greetings! I'm delighted that you are interested in the build logs for the
Prison plugin. I'm wanting to provide a more formal documentation as to what
is going on in each build so you have a better idea if it may be something
that you need.
-## tag v3.2.2-alpha.14 - 2020-11-21
-
-
-* **v3.2.2-alpha.14 - 2020-11-21**
-Bump version... preparing for v3.2.2 bug fix.
-
-
-* **Refactored where the commands that are outside of the modules are registered.**
-They are now registered within the function where the modules are registered to allow the related commands to either be registered or not, based upon the modules.
-Refactored how some of the commands/configs are setup to be more flexible, or to better follow the standards of how prison has been instantiating them (ListenersPrisonManager).
-
-
-* **Split out the gui ranks and gui mines commands** from the main spigot gui commands. This allows them to be enabled on their own, or more importantly, prevent them from being registered if the modules are not loaded.
-
-
-
-* **Changes to the gui commands to prevent console from running a few gui commands.**
-Also remove the alias of "prisonmanager" for "gui".
-It was reported that when a non-admin tried to use /mines that it was giving the error message associated with /gui. Cannot see a direct relationship there, but hard linked /mines to /gui mines by calling the function directly instead of resubmitting the command. Not sure if this fixes the issue, but I was unable to reproduce it.
-
-
-* **Minor changes**
-Add more to the BaseCommands and start to hook them up. Fix usage of getting the current economy.
-
-
-* **To prevent prestige related commands from being registered with bukkit**,
-pulled prestige related commands in to their own command class and then conditionally register them if prestiges are enabled. Cleaned up a few other things such as remove use of deprecated functions and
-moving the implementation of isPrisonConfig to SpigotPrison to simplify a few things and eliminate duplication.
-
-
-* **Fixed a problem with bukkit on a paper v1.16.4 server where the Bukkit.getOfflinePlayers() was returning either a null player, or a player had a name that was null.**
-
-
-* **v3.2.2-alpha.13 - 2020-11-15**
-
-
-* **Updates to the GUI: many.**
-Moving configs to a common package to better manage them, or to prepare to merge them in the future. Many other fixes and enhancements.
-
-
-* **Updated the SpigotMineBlockPercentageGUI to include a Close button and to show the selected block top and center.**
-Also provided links back to the block list gui. Setup the parameters to return back by setting the font color to black so it is visible that they exist as the players hover.
-
-
-* **Fixed issue with GUI block list.**
-Using a combination of XMaterial and ItemStacks, its able to display the viewable blocks. Added Prior button to go back to prior page. Got the Next page button working (it was incorrectly just blindly deleting the first two characters of the button name; changed it to strip color so it is not destructive. Setup this page to be able to return to it from other pages. Confirmed that this works with spigot v1.8.8 and spigot v1.16.3.
-
-
-* **Fix issue with GUI not being able to display red or lime stained glass panes**
-due to use of material instead of ItemStacks. This applies to mc v1.8 through mc v1.12 and they display as plain glass panes (no colors).
-
-
-* **Added a SpigotPrison function to strip all colors from text.**
-Needed in the GUI to hide extra parameters.
-
-
-* **GUI direct support for ItemStacks when creating buttons for mc v1.8 through mc v1.12. **
-With the use of magic numbers with Minecraft versions less than 1.13 the use of Materail to create ItemStacks fails to get the correct type if magic numbers are involved. Created a new createButton function to work directly with item stacks so the proper blocks can be used with mc v1.8 through v1.12.
-
-
-* **Additions to PrisonBlock handlers to provide more utility functions**
-and to solve a few complex challenges. Removed NULL_BLOCK from the valid block lists.
-
-
-* **Found function names that started with capital letters and changed them to lower case.**
-Function names should never be capitalized since that would imply they are classes, or similar objects, and not functions.
-
-
-* **Compile error with the removal of the prison core gui...**
-Removal of this code was forgotten when removing the prison core gui code. Not sure how that passed the compiler before committing to git?
-
-
-* **cleaned up unused imports in the gui code; were causing compile warnings.**
-
-
-* **New feature! Hooked the prison GUI up to the new prison command manager.**
-Assigned aliases so as to preserve backwards compatibility with admins who are used to the prisonmanager command.
-The /prisonmanager command has been replaced with just /gui. Tested and appears to be working well. Can do /gui mines, /gui ranks, /gui prestige, /gui prestiges.
-
-
-* **Added /mtp as an alias to /mines tp.**
-
-
-* **New GUI config system**
-- It's an improvement. Has many code changes
-- Deleted the GuiListener.java class, only SpigotPlatform was using it so nothing should break.
-
-
-* **New Feature! Tab complete is now functional with prison's command handler.**
-When typing in prison related commands, you can now press tab to complete the typing for you if there was only one option available, or it will fill in common letters until you need to make a choice. Also typing in a command pressing space then tab shows all available options. In game is slightly different that in console, where in game show a ghosting of the command where you are typing so tabbing will select that option.
-Works on spigot 1.8 through 1.16.x. Also works in console. Functional with aliases too.
-
-
-* **New Feature! Command Aliases!**
-Add the complexities of supporting aliases in the prison command handler. Each command can have one or more aliases mapped to almost any level of paths.
-This also includes a rich support of the sub-command and help listings to better identify which commands are aliases and also what aliases are available. There is room for enhancements that will be added soon.
-
-
-* **v3.2.2-alpha.12 - 2020-11-10**
-
-
-* **removed the trailing &f from the rank tag**
-This was within the new feature /ranks autoConfigure. It was reported that there were issues within the plugin Scoreboard-r by RienBijl that data was being truncated and lost. Looking in to the issue it was found that there was a stray &f at the end of a tag. It had no impact, but it was removed anyway since it does nothing. It was determined that the scoreboard-r plugin is buggy and was causing errors.
-
-
-* **New Feature: Now provides the capture of the actual label that a command is registered with Bukkit when there is a conflict.** The prison Command Handler now uses the registered label when displaying any of the sub commands or list of all registered root commands. This will allow the users to know what commands they actually have to enter to get them to work, instead of guessing when there is a conflict.
-
-
-* **Improve block matching for pre mc v1.13.0**
-For the 1.8.x material types in prison, there exists different states with the data value that could result in block types that are unknown. Some of it may be orientation or degree of flowing water, or even wetness of soil. I've seen it with leaves of different shades, or even with logs.
-The idea here to fix this issue is not so much that we don't know the block type as much as it shouldn't matter the slight variations in the data field. Therefore if we fail to match on the id and data, then go off of the material name. That's a good fallback.
-
-
-* **Bug fix: Fix incorrect display of no other mines near for /mines whereami**
-If the player was standing in a mine and there are no other mines around, it used to show the mine they are in, plus say there are no other mines within 150 blocks.
-Now it will not show the "no other mines in 150 blocks" message.
-
-
-* **Mines Blocks GUI Fix**
-
-
-* **Bug Fix: Found a bug in the command registration code** that could result in failing to properly register commands. This would have been an issue if there were upper case letters in a command, since all commands are converted to lowercase when added, but when checking to see if a subcommand was already processed (ie... the "set" in the following two commands: /mines set tag, /mines set resetTime). The symptoms would be missing commands at runtime. I actually have seen this failure in the past, and realized that all commands should be entered as lowercase due to this error. Now it should work correctly.
-
-
-* **Clarify the role of a CommandHandler field that is used in a situation of when there is a command collision.**
-
-
-* **Fix typo: In the /mines command add function, a & was placed one character to the right of where it should have been.**
-
-
-* **Added an unregister all for the commands and hooked it up on the plugin's onDisable.**
-
-
-* **Fixed issue with dropping of inventory.**
-Had a ! where it shouldn't have been and forgot to hook up the new messageId variable so the warning can change.
-I'm not so sure about messaging this way, using the action bar, but don't want to flood chat with a ton of messages either. Would have to put a limiter on the chat messages?
-
-
-* **Fixed an index out of range issue in the gui.**
-Was 45 when should have been 44.
-
-
-* **New Feature: Added XP calculations to the block break (auto pickup) function**
-which can be disabled. Give the option to drop the xp as orbs (default) or give it directly to the player with no orbs.
-
-
-* **It was realized that dropItemsIfInventoryIsFull was not hooked up.**
-Hooked it up.
-
-
-* **Update some docs and added a few screen prints.**
-Updates to a few documents to reflect some of the more recent updates to prison.
-
-
-* **Updates to the IntegrationManager** so the variable is more consistent and especially the message for WorldGuard integration is clear that it is not an error that it is not yet active.
-
-
-* **Change the command /prison alerts so they can be ran from the console** since it made no sense why the console was locked out from using them.
-Slight changed the information for /prison gui that shows that it could be preferred to configure the autofeatures.
-
-
-* **Changed the perms to lower case, specifically the mine/rank name. Should have been lower case.**
-
-
-* **Had the wrong block name for dark_oak_planks (thought I fixed that already).**
-
-
-* **v3.2.2-alpha.11 - 2020-10-29**
-
-
-* **For /ranks autoConfigure: Almost forgot to add the removal of the mines.tp. An instance will always be available after
@@ -135,15 +138,7 @@ public boolean init(Platform platform, String minecraftVersion) {
this.commandHandler.registerCommands(prisonCommands);
- // Setup hooks in to the valid prison block types. This will be only
- // the block types that have tested to be valid on the server that is
- // running prison. This provides full compatibility to the admins that
- // if a block is listed, then it's usable. No more guessing or finding
- // out after the fact that a block that was used was invalid for
- // their version of minecraft.
- this.prisonBlockTypes = new PrisonBlockTypes();
- this.prisonBlockTypes.loadServerBlockTypes();
-
+
long stopTime = System.currentTimeMillis();
@@ -217,6 +212,7 @@ private void initManagers() {
this.selectionManager = new SelectionManager();
this.troubleshootManager = new TroubleshootManager();
this.integrationManager = new IntegrationManager();
+ this.placeholderManager = new PlaceholderManager();
// try {
@@ -375,16 +371,13 @@ public IntegrationManager getIntegrationManager() {
return integrationManager;
}
+
/**
- * Setup hooks in to the valid prison block types. This will be only the
- * block types that have tested to be valid on the server that is running
- * prison. This provides full compatibility to the admins that if a block
- * is listed, then it's usable. No more guessing or finding out after the
- * fact that a block that was used was invalid for their version of minecraft.
+ * Returns the integration manager, which returns {@link tech.mcprison.prison.integration.Integration}s.
*/
- public PrisonBlockTypes getPrisonBlockTypes() {
- return prisonBlockTypes;
- }
-
+ public PlaceholderManager getPlaceholderManager() {
+ return placeholderManager;
+ }
+
}
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 117ea07e1..5237d147d 100644
--- a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java
+++ b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java
@@ -673,6 +673,19 @@ public void autoFeaturesInformation(CommandSender sender) {
}
+ @Command(identifier = "prison debug",
+ description = "For internal use only. Do not use until instructed since this is not hookedup.",
+ onlyPlayers = false )
+ public void toggleDebug(CommandSender sender ) {
+
+ Output.get().setDebug( !Output.get().isDebug() );
+
+ String message = "Debug logging: " + (Output.get().isDebug() ? "enabled" : "disabled");
+
+ sender.sendMessage( message );
+ }
+
+
// 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 67b8cd2a1..b23ffaf3c 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
@@ -2,11 +2,13 @@
import java.io.File;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import tech.mcprison.prison.Prison;
+import tech.mcprison.prison.autofeatures.ValueNode.NodeType;
import tech.mcprison.prison.file.YamlFileIO;
import tech.mcprison.prison.output.Output;
@@ -17,7 +19,7 @@ public class AutoFeaturesFileConfig {
// private FileConfiguration config;
private Map Get the children nodes to the given item.
@@ -372,6 +439,11 @@ public AutoFeaturesFileConfig() {
// key, value.toString() );
// }
+ List The getOfflinePlayer() will now include RankPlayer as a fall back to help
+ * ensure a player is always returned, if its a valid player.
+ * This function is supposed to identify if the given block is a custom block, and
+ * if it is a custom block, then this function will return the correct PrisonBlock
+ * to match it's type. The PrisonBlock that will be returned, will come from the
+ * collection of valid blocks that were generated upon server startup.
+ * If there is no match, then this function will return a null.
+ * It's also important to know that the original block that is retrieved from
+ * PrisonBlockTypes.getBlockTypesByName() is cloned prior to returning it to this
+ * function, so it's safe to do anything you want with it.
+ * The given place holders should have both the prison prefix and without,
- * with the without having the suppress value set. The suppressable items
- * will not always be displayed since it would be implied that the prefix
- * would have been provided.
- * Update: The placeholders without the prison prefix have been eliminated
- * since the prefix is now prepended when it is missing prior to matching to a
- * valid placeholder enum. This cuts the number of generated placeholders in half.
- * This is significant since with the addition of the aliases there would be about
- * 744 placeholders generated if the prison had 30 mines setup! Now a 30 mine prison
- * would have about 372.
- * Note: In order to use these placeholders with something like holographic display
- * you need to also include the placeholderAPI,
- * plugin holographic extension and protocolib.
- * In order to get the holographics extension to work it is critical you read
- * their spigot page since you have to specify a refresh speed.
- * This function uses the settings within the config.yml to construct a progress
- * bar. It takes two numeric values and constructs it upon those parameters.
- * The parameter The lowest range is always zero and gradlew wrapper --gradle-version 5.0
:: Sets the new wrapper version
- * gradlew --version
:: Will actually install the new version
- * gradlew build
:: Will build project with the new version to ensure all is good. If build is good, then you can try to upgrade to the next version.
- * Update to v5.0 was successful. Had to remove enableFeaturePreview('STABLE_PUBLISHING')
- since it has been deprecated. It does nothing in v5.x, but will be removed in v6.0.
- * Update to v5.1.1, v5.2.1, v5.3.1, v5.4.1, v5.5.1, v5.6.4 was successful.
-
-
-* **Minor clean up to Gradle scripts**
-The "compile" directive is actually very old and was deprecated back around version
-v2.x. The replacements for that is "implementation" or "api" instead. The use of
-api does not make sense since its use is to tag when internal functions are exposed
-to the outside world as if it will be used as an externally facing API. That
-really does not fit our use case, but what api also does is to force compiling all
-source that is associated with something marked as api, including everyone's children. So performance will suffer due to that usage, since it shuts down incremental
-building of resources.
-
-I also found that use of compileOnly may not be used correctly, but at this point
-I'm just leaving this as a mention and then revisit in the future if time
-permits, or issues appear to be related. Its a very old addition that provided
-gradle with "some" maven like behaviors. It was only intended to be strictly used
-for compile time dependencies, such as for annotations that are only needed for
-compile-time checks, of which the plugins and resources we have marked as
-compileOnly do not fit that use case.
-[discuss.gradle.org: compileOnly](https://discuss.gradle.org/t/is-it-recommended-to-use-compileonly-over-implementation-if-another-module-use-implementation-already/26699/2)
-
-
-* **Redesigned mine block generation works - Async and paged enabled**
-Redesigned how prison blocks are generated to improve performance and to allow the
-asynch generation of blocks, but more importantly, allows for paging of actual
-block updates. The paging is a major feature change that will allow for minimal
-impact on server lag, even with stupid-large mines. The idea is to chop up the
-large number of blocks that need to be regenerated in to smaller chunks that can
-be performed within one or two ticks, then defer the other updates to the future.
-Thus freeing up the main bukkit/spigot execution thread to allow other tasks
-to run to help prevent the server from lagging.
-
-* **Support for LuckPerms v5.0.x**
-In addition to supporting older versions of LuckPerms, Prison now is able to
-integrate LuckPerms v5.0.x or LuckPerms v.4.x or earlier. Take your pick.
-
-* **Minor changes to reduce the number of compiler warnings**
-Minor changes, but better code overall.
-
-
-* **Improved mine regeneration performance by 33.3%**
-Figured out how to improve performance on mine regeneration by roughly about 33.3% overall. This
-could help drastically improve performance and reduce lag since block updates must run
-synchronously to prevent server corruption (limitation is due to the bukkit and spigot api).
-
-* **Mine stats and whereami**
-Added a new command, **/mines stats**, to toggle the stats on the mine resets. Viewable with **/mines list** and **/mines info**. Stats are now within the MineManager so it can be accessed from within
-the individual mines.
-Added a new command, **/mines whereami**, to tell you what mine you are in, or up to three mines you are nearest to and the distance from their centers.
-
-
-* **Major restructuring of how Mines work - Self-managing their own workflow**
-They now are able to self-manage their own workflow for sending out notifications and for resetting automatically.
-Mines is now layered, where each layer (abstract class of its ancestors) contributes a type of behavior and business logic that allows Mines to be more autonomous.
-As a result, PrisonMines and MineManager are greatly simplified since they have less to manage.
-Because Mines are now self-managing their own workflow, and they have taken on a more expanded role, some of the mine configurations are obsolete and removed.
-Mines only notify players that are within a limited range of their center; they no longer blindly broadcast to all players within a given world or the whole server.
-Mines extend from MineScheduler, which extend from MineReset, which extend from MineData. Each layer focuses on it's own business rules and reduces the clutter in the others, which results in tighter
-code and less moving parts and less possible errors and bugs.
-
-
-* **Concept of distance added to Bound objects**
-Added the concept of distance between two Bound objects so as to support new
-functionalities between mines and players.
-
-
-* **Gradle now ready to upgrade to v5**
-Resolved the last few issues that would have caused issues when upgrading to gradle
-v5. Explored how gradle can use java fragments and variables.
-
-
-## tag v3.2.0 - 2019-12-03
-
-
-* **Now works in 1.14.4!!**
-Added in the missing library to get it to work with 1.14.4.
-
-
-* **Fixed issue with pull request 132**
-Fixes the https://github.com/PrisonTeam/Prison/pull/132 pull request.
-It causes prison to fail on a clean server and throws a class not found exception.
-The new library needs compile instead of compileOnly and it must also be shadowed.
-
-
-* **Update to org.inventivetalent.spiget-update** Updated to version 1.4.2-SNAPSHOT since
-the old version 1.4.0 was no longer available.
-
-
-* **Updates to bStats** The Maven repository was updated and so was the version of
-bStats that is being included on the project. It is now using the current 1.5 version,
-was using 1.3 which is no longer available in the repository and was causing a build
-failure for gradle.
-
-
-* **New Feature - Decimals in Block chances now supported!**
-Added support to display and use two decimal positions on block chances.
-
-
-* **Fix - TP of Players out of the Mines upon Rest**
-This is one part of a multi-step process to help ensure players are TP'd out of mines upon
-a reset. In an effort to help start to address the
-known bug [![Mine doesn't teleport to safety #82](https://github.com/PrisonTeam/Prison/issues/82)]
-Rewrote the player teleport function to help address the issue.
-
-
-* **New Feature - Block search!!**
-You can now search for blocks to add to the mines! It uses the BlockTypes and is able
-to search on the ID and the enumeration name. It displays up to 10 at a times and
-provides Next Page and Previous Page controls to page through the results.
-If you click on a BlockType, it will suggest the command for adding blocks:
-** /mines block add gradlew wrapper --gradle-version 4.5.1
:: Sets the new wrapper version
- * gradlew --version
:: Will actually install the new version
- * gradlew build
:: Will build project with the new version to ensure all is good. If build is good, then you can try to upgrade to the next version.
- * Gradle v4.10.3 version of the project's build scripts has a few v5.0 issues that
- need to be addressed before upgrading any farther. Future upgrades will be performed
- after these issues are addressed. ETA unknown.
-
-
-* **Removed Guava Caching**
-There were a number of reasons (about 18) for the removal of Guava caching. Primarily
-it really wasn't being used and the use case of the data does not warrant caching.
-Removal of caching also helped to reduce memory consumption and reduce the overhead
-associated with the caching library.
-
-
-* **Update the FileStorage Class**
-Provided Java docs and also the logging of warnings.
-Altered the behavior so it actually does not delete a FileDatabase but instead it virtually deletes it.
-This provides the user with a way to undelete something if they realize later they should not have
-deleted it To undelete it, they would have to manually rename the underlying directory and then
-restart the server (but the data is not lost!).
-Also cleaned up the nature of some of the code so the functions have one exit point.
-Updated Storage so the functions are declared as public and so createDatabase and deleteDatabase returns
-a boolean value to indicate if it was successful so the code using these functions know if it should
-generate warnings.
-
-
-* **Refactored the Virtual Delete**
-I created an abstract class that has the virtual delete code in it so now anything that needs to use
-that functionality can extend from that class. I updated FileStorage so it now extends from
-FileVirtualDelete.
-
-
-* **Refactored FileStorage, FileCollection, and FileDatabase that were in the src/test packages**
-I deleted these three source files from the prison-spigot module. Not sure why they were there, but
-simple refactoring made these obsolete.
-
-
-* **Found and fixed a fatal bug in PrisonMines.enable()**
-Within PrisonMines.enable() the errorManager was being instantiated AFTER initConfig but if there was a
-failure with initConfig, then it would have hit a Null Pointer Exception since that was what the value
-of errorManager was, a null since it was not initialized yet.
-
-
-* **Created FileIO, JsonFileIO, and FileIOData**
-Created a couple of classes and an interface to deal better with saving and loading of the data and
-to also better encapsulate the generation of the JSON files. The MinesConfig class was the first
-class to get this hooked up with, which simplified a great deal of the code that deals with files.
-
-
-* **Minor updates to PrisonMines class**
-asyncGen is not being used right now, so commented it out to eliminate warnings. Performance
-improvements may have made this obsolete. May revisit in the future with actual mine
-resets instead of just precomputing.
-Also clear the precomputed new blocks for the mines to free up memory between resets of the mines.
-
-
-* **Major changes for the FileCollection and Document related classes**
-This was a major change that encompasses the removal of Guava, the caching library.
-Everything works the same as before, but with the exception of saving the individual
-files as change occur; that will be added in next. This touched basically every module
-including the prison-ranks.
-
-
-* **Update FileStorage and FileDatabase**
-These changes are fairly similar in nature and the two classes are so very similar.
-Maybe in the future they can be merged so there is the same code base handling both of them.
-
-
-* **Various clean up items**
-Like removal of useless comments that are in the wrong places. Fixing includes that are including
-packages that are not being used. Removal of warnings. Etc... just mostly items that will result
-is easier to read code without any functional changes (and no program changes in most places).
-
-
-* **Simple refactorings**
-There were a few items that were refactored back in to their controlling class. For example ranks
-and ladders add on an id to generate their file names. Created a filename function for those
-classes so externally all users of those classes do not have to know what the business rules are
-for constructing the filenames. This also can help to eliminate errors in the future; only one
-location for constructing filenames instead of a few different locations.
-
-
-* **New Feature: Add a text component to RowComponent**
-Expanded the ability of RowComponent to accept parameterized text now.
-
-
-* **New Feature: Add volume to the mines info**
-Provide a little more information for mines by now showing the mine's volume.
-
-
-* **Bug fix - Mine blocks updating wrong values and problems deleting blocks**
-Fixed a few bugs with adding, setting, and deleting by the wrong value. By default
-it was trying to delete by id, but multiple blocks have the same id, so it was
-corrupting the block lists for a mine.
-It now uses the block name instead of block id. This eliminated problems.
-
-
-* **New Feature - Identify all BlockTypes that are blocks as blocks**
-Trying to define each BlockType as a BLOCK or not. This will be used to filter
-the results on /mines block search to ensure only blocks that are placeable can be
-set in the mines. Tried to programatically identify what a block is within all
-supported minecraft versions, but it did not work due to conflicts with the
-blocks names within Materials and within the Prison plugin's BlockType enum.
-Manually marked each BlockType since programatic attempts were running in to
-numerous issues. There may be a few that do not
-make sense or are incorrect, but can update later when found. Created a new enum
-by the name of MaterialType that is used to mark the BlockTypes as
-BLOCKs. Can also use that enum to label the other items with something more
-meaningful such as ITEMs, or even ARMOR or WEAPON. Can have a great deal of
-flexibility moving forward with that.
-
-
-* **New Feature - Block search new only includes blocks that are actually placable in the mines**
-Hooked up the BlockType.getMaterialType() == MaterialType.BLOCK to the block
-search and the block add.
-
-
-* **New Feature - Added confirm on Mine Delete**
-Added a new feature to provide a confirmation when deleting a mine. The user can
-click on the notification message to have the command reentered for them, then they
-only need to change **cancel** to **confirm**.
-This will help prevent accidental deletion of mines. Yes mines can be manually
-undeleted, but this can prevent mistakes.
-
-
-* **New Feature - Using /mines set block will add new blocks**
-If you click on a block from under /mines list and you change the mine's name on that
-/mines block set command, it will be treated like an add instead of an error.
-This is beneficial if you want to copy a block from one mine to another and you forget
-to change "set" to "add".
-
-
-* **New Feature - Added a center Location to Bounds**
-Added a center location for Bounds which will be used for a few things for mines.
-Currently it was added as a fall back location for if a spawn point does not exist for
-teleporting in to a mine. But it will also be used to identify all players within a
-given radius from that location to selectively target broadcast messages pertaining
-to that mine.
-
-
-* **New Feature - Clone existing Locations**
-Makes it easier to create clones of Locations.
-
-
-* **New Feature - Track last Mine name used and substitute it for the generic place holder**
-Track what the last value for mine was, and put it on a timer. If it was last
-referenced within 30 minutes, then use that reference by default in the block
-search function.
-In the future, when auto suggest is enabled, this value will also be used for the
-targeted mine names instead of just a generic gradlew wrapper --gradle-version 4.5.1
:: Sets the new wrapper version
+ * gradlew --version
:: Will actually install the new version
+ * gradlew build
:: Will build project with the new version to ensure all is good. If build is good, then you can try to upgrade to the next version.
+ * Gradle v4.10.3 version of the project's build scripts has a few v5.0 issues that
+ need to be addressed before upgrading any farther. Future upgrades will be performed
+ after these issues are addressed. ETA unknown.
+
+
+* **Removed Guava Caching**
+There were a number of reasons (about 18) for the removal of Guava caching. Primarily
+it really wasn't being used and the use case of the data does not warrant caching.
+Removal of caching also helped to reduce memory consumption and reduce the overhead
+associated with the caching library.
+
+
+* **Update the FileStorage Class**
+Provided Java docs and also the logging of warnings.
+Altered the behavior so it actually does not delete a FileDatabase but instead it virtually deletes it.
+This provides the user with a way to undelete something if they realize later they should not have
+deleted it To undelete it, they would have to manually rename the underlying directory and then
+restart the server (but the data is not lost!).
+Also cleaned up the nature of some of the code so the functions have one exit point.
+Updated Storage so the functions are declared as public and so createDatabase and deleteDatabase returns
+a boolean value to indicate if it was successful so the code using these functions know if it should
+generate warnings.
+
+
+* **Refactored the Virtual Delete**
+I created an abstract class that has the virtual delete code in it so now anything that needs to use
+that functionality can extend from that class. I updated FileStorage so it now extends from
+FileVirtualDelete.
+
+
+* **Refactored FileStorage, FileCollection, and FileDatabase that were in the src/test packages**
+I deleted these three source files from the prison-spigot module. Not sure why they were there, but
+simple refactoring made these obsolete.
+
+
+* **Found and fixed a fatal bug in PrisonMines.enable()**
+Within PrisonMines.enable() the errorManager was being instantiated AFTER initConfig but if there was a
+failure with initConfig, then it would have hit a Null Pointer Exception since that was what the value
+of errorManager was, a null since it was not initialized yet.
+
+
+* **Created FileIO, JsonFileIO, and FileIOData**
+Created a couple of classes and an interface to deal better with saving and loading of the data and
+to also better encapsulate the generation of the JSON files. The MinesConfig class was the first
+class to get this hooked up with, which simplified a great deal of the code that deals with files.
+
+
+* **Minor updates to PrisonMines class**
+asyncGen is not being used right now, so commented it out to eliminate warnings. Performance
+improvements may have made this obsolete. May revisit in the future with actual mine
+resets instead of just precomputing.
+Also clear the precomputed new blocks for the mines to free up memory between resets of the mines.
+
+
+* **Major changes for the FileCollection and Document related classes**
+This was a major change that encompasses the removal of Guava, the caching library.
+Everything works the same as before, but with the exception of saving the individual
+files as change occur; that will be added in next. This touched basically every module
+including the prison-ranks.
+
+
+* **Update FileStorage and FileDatabase**
+These changes are fairly similar in nature and the two classes are so very similar.
+Maybe in the future they can be merged so there is the same code base handling both of them.
+
+
+* **Various clean up items**
+Like removal of useless comments that are in the wrong places. Fixing includes that are including
+packages that are not being used. Removal of warnings. Etc... just mostly items that will result
+is easier to read code without any functional changes (and no program changes in most places).
+
+
+* **Simple refactorings**
+There were a few items that were refactored back in to their controlling class. For example ranks
+and ladders add on an id to generate their file names. Created a filename function for those
+classes so externally all users of those classes do not have to know what the business rules are
+for constructing the filenames. This also can help to eliminate errors in the future; only one
+location for constructing filenames instead of a few different locations.
+
+
+* **New Feature: Add a text component to RowComponent**
+Expanded the ability of RowComponent to accept parameterized text now.
+
+
+* **New Feature: Add volume to the mines info**
+Provide a little more information for mines by now showing the mine's volume.
+
+
+* **Bug fix - Mine blocks updating wrong values and problems deleting blocks**
+Fixed a few bugs with adding, setting, and deleting by the wrong value. By default
+it was trying to delete by id, but multiple blocks have the same id, so it was
+corrupting the block lists for a mine.
+It now uses the block name instead of block id. This eliminated problems.
+
+
+* **New Feature - Identify all BlockTypes that are blocks as blocks**
+Trying to define each BlockType as a BLOCK or not. This will be used to filter
+the results on /mines block search to ensure only blocks that are placeable can be
+set in the mines. Tried to programatically identify what a block is within all
+supported minecraft versions, but it did not work due to conflicts with the
+blocks names within Materials and within the Prison plugin's BlockType enum.
+Manually marked each BlockType since programatic attempts were running in to
+numerous issues. There may be a few that do not
+make sense or are incorrect, but can update later when found. Created a new enum
+by the name of MaterialType that is used to mark the BlockTypes as
+BLOCKs. Can also use that enum to label the other items with something more
+meaningful such as ITEMs, or even ARMOR or WEAPON. Can have a great deal of
+flexibility moving forward with that.
+
+
+* **New Feature - Block search new only includes blocks that are actually placable in the mines**
+Hooked up the BlockType.getMaterialType() == MaterialType.BLOCK to the block
+search and the block add.
+
+
+* **New Feature - Added confirm on Mine Delete**
+Added a new feature to provide a confirmation when deleting a mine. The user can
+click on the notification message to have the command reentered for them, then they
+only need to change **cancel** to **confirm**.
+This will help prevent accidental deletion of mines. Yes mines can be manually
+undeleted, but this can prevent mistakes.
+
+
+* **New Feature - Using /mines set block will add new blocks**
+If you click on a block from under /mines list and you change the mine's name on that
+/mines block set command, it will be treated like an add instead of an error.
+This is beneficial if you want to copy a block from one mine to another and you forget
+to change "set" to "add".
+
+
+* **New Feature - Added a center Location to Bounds**
+Added a center location for Bounds which will be used for a few things for mines.
+Currently it was added as a fall back location for if a spawn point does not exist for
+teleporting in to a mine. But it will also be used to identify all players within a
+given radius from that location to selectively target broadcast messages pertaining
+to that mine.
+
+
+* **New Feature - Clone existing Locations**
+Makes it easier to create clones of Locations.
+
+
+* **New Feature - Track last Mine name used and substitute it for the generic place holder**
+Track what the last value for mine was, and put it on a timer. If it was last
+referenced within 30 minutes, then use that reference by default in the block
+search function.
+In the future, when auto suggest is enabled, this value will also be used for the
+targeted mine names instead of just a generic gradlew wrapper --gradle-version 5.0
:: Sets the new wrapper version
+ * gradlew --version
:: Will actually install the new version
+ * gradlew build
:: Will build project with the new version to ensure all is good. If build is good, then you can try to upgrade to the next version.
+ * Update to v5.0 was successful. Had to remove enableFeaturePreview('STABLE_PUBLISHING')
+ since it has been deprecated. It does nothing in v5.x, but will be removed in v6.0.
+ * Update to v5.1.1, v5.2.1, v5.3.1, v5.4.1, v5.5.1, v5.6.4 was successful.
+
+
+* **Minor clean up to Gradle scripts**
+The "compile" directive is actually very old and was deprecated back around version
+v2.x. The replacements for that is "implementation" or "api" instead. The use of
+api does not make sense since its use is to tag when internal functions are exposed
+to the outside world as if it will be used as an externally facing API. That
+really does not fit our use case, but what api also does is to force compiling all
+source that is associated with something marked as api, including everyone's children. So performance will suffer due to that usage, since it shuts down incremental
+building of resources.
+
+I also found that use of compileOnly may not be used correctly, but at this point
+I'm just leaving this as a mention and then revisit in the future if time
+permits, or issues appear to be related. Its a very old addition that provided
+gradle with "some" maven like behaviors. It was only intended to be strictly used
+for compile time dependencies, such as for annotations that are only needed for
+compile-time checks, of which the plugins and resources we have marked as
+compileOnly do not fit that use case.
+[discuss.gradle.org: compileOnly](https://discuss.gradle.org/t/is-it-recommended-to-use-compileonly-over-implementation-if-another-module-use-implementation-already/26699/2)
+
+
+* **Redesigned mine block generation works - Async and paged enabled**
+Redesigned how prison blocks are generated to improve performance and to allow the
+asynch generation of blocks, but more importantly, allows for paging of actual
+block updates. The paging is a major feature change that will allow for minimal
+impact on server lag, even with stupid-large mines. The idea is to chop up the
+large number of blocks that need to be regenerated in to smaller chunks that can
+be performed within one or two ticks, then defer the other updates to the future.
+Thus freeing up the main bukkit/spigot execution thread to allow other tasks
+to run to help prevent the server from lagging.
+
+* **Support for LuckPerms v5.0.x**
+In addition to supporting older versions of LuckPerms, Prison now is able to
+integrate LuckPerms v5.0.x or LuckPerms v.4.x or earlier. Take your pick.
+
+* **Minor changes to reduce the number of compiler warnings**
+Minor changes, but better code overall.
+
+
+* **Improved mine regeneration performance by 33.3%**
+Figured out how to improve performance on mine regeneration by roughly about 33.3% overall. This
+could help drastically improve performance and reduce lag since block updates must run
+synchronously to prevent server corruption (limitation is due to the bukkit and spigot api).
+
+* **Mine stats and whereami**
+Added a new command, **/mines stats**, to toggle the stats on the mine resets. Viewable with **/mines list** and **/mines info**. Stats are now within the MineManager so it can be accessed from within
+the individual mines.
+Added a new command, **/mines whereami**, to tell you what mine you are in, or up to three mines you are nearest to and the distance from their centers.
+
+
+* **Major restructuring of how Mines work - Self-managing their own workflow**
+They now are able to self-manage their own workflow for sending out notifications and for resetting automatically.
+Mines is now layered, where each layer (abstract class of its ancestors) contributes a type of behavior and business logic that allows Mines to be more autonomous.
+As a result, PrisonMines and MineManager are greatly simplified since they have less to manage.
+Because Mines are now self-managing their own workflow, and they have taken on a more expanded role, some of the mine configurations are obsolete and removed.
+Mines only notify players that are within a limited range of their center; they no longer blindly broadcast to all players within a given world or the whole server.
+Mines extend from MineScheduler, which extend from MineReset, which extend from MineData. Each layer focuses on it's own business rules and reduces the clutter in the others, which results in tighter
+code and less moving parts and less possible errors and bugs.
+
+
+* **Concept of distance added to Bound objects**
+Added the concept of distance between two Bound objects so as to support new
+functionalities between mines and players.
+
+
+* **Gradle now ready to upgrade to v5**
+Resolved the last few issues that would have caused issues when upgrading to gradle
+v5. Explored how gradle can use java fragments and variables.
+
+
+
diff --git a/docs/prison_changelog_v3.2.2.md b/docs/prison_changelog_v3.2.2.md
new file mode 100644
index 000000000..f60f4f232
--- /dev/null
+++ b/docs/prison_changelog_v3.2.2.md
@@ -0,0 +1,725 @@
+[Prison Documents - Table of Contents](prison_docs_000_toc.md)
+
+# Prison Build Logs for v3.2.2 - 2020-11-27
+
+## Build logs
+ - **[v3.2.3-alpha - Current](../changelog_v3.2.x.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)**
+
+
+Greetings! I'm delighted that you are interested in the build logs for the
+Prison plugin. I'm wanting to provide a more formal documentation as to what
+is going on in each build so you have a better idea if it may be something
+that you need.
+
+
+
+
+# V3.2.2 Release - 2020-11-21
+
+This version is being released to fix outstanding bugs and to provide a better end user experience. Preparing for a few other changes, so want to get this released before possibly changing the stability of any feature.
+
+
+* **v3.2.2-alpha.14 - 2020-11-21**
+Bump version... preparing for v3.2.2 bug fix.
+
+
+* **Refactored where the commands that are outside of the modules are registered.**
+They are now registered within the function where the modules are registered to allow the related commands to either be registered or not, based upon the modules.
+Refactored how some of the commands/configs are setup to be more flexible, or to better follow the standards of how prison has been instantiating them (ListenersPrisonManager).
+
+
+* **Split out the gui ranks and gui mines commands** from the main spigot gui commands. This allows them to be enabled on their own, or more importantly, prevent them from being registered if the modules are not loaded.
+
+
+
+* **Changes to the gui commands to prevent console from running a few gui commands.**
+Also remove the alias of "prisonmanager" for "gui".
+It was reported that when a non-admin tried to use /mines that it was giving the error message associated with /gui. Cannot see a direct relationship there, but hard linked /mines to /gui mines by calling the function directly instead of resubmitting the command. Not sure if this fixes the issue, but I was unable to reproduce it.
+
+
+* **Minor changes**
+Add more to the BaseCommands and start to hook them up. Fix usage of getting the current economy.
+
+
+* **To prevent prestige related commands from being registered with bukkit**,
+pulled prestige related commands in to their own command class and then conditionally register them if prestiges are enabled. Cleaned up a few other things such as remove use of deprecated functions and
+moving the implementation of isPrisonConfig to SpigotPrison to simplify a few things and eliminate duplication.
+
+
+* **Fixed a problem with bukkit on a paper v1.16.4 server where the Bukkit.getOfflinePlayers() was returning either a null player, or a player had a name that was null.**
+
+
+* **v3.2.2-alpha.13 - 2020-11-15**
+
+
+* **Updates to the GUI: many.**
+Moving configs to a common package to better manage them, or to prepare to merge them in the future. Many other fixes and enhancements.
+
+
+* **Updated the SpigotMineBlockPercentageGUI to include a Close button and to show the selected block top and center.**
+Also provided links back to the block list gui. Setup the parameters to return back by setting the font color to black so it is visible that they exist as the players hover.
+
+
+* **Fixed issue with GUI block list.**
+Using a combination of XMaterial and ItemStacks, its able to display the viewable blocks. Added Prior button to go back to prior page. Got the Next page button working (it was incorrectly just blindly deleting the first two characters of the button name; changed it to strip color so it is not destructive. Setup this page to be able to return to it from other pages. Confirmed that this works with spigot v1.8.8 and spigot v1.16.3.
+
+
+* **Fix issue with GUI not being able to display red or lime stained glass panes**
+due to use of material instead of ItemStacks. This applies to mc v1.8 through mc v1.12 and they display as plain glass panes (no colors).
+
+
+* **Added a SpigotPrison function to strip all colors from text.**
+Needed in the GUI to hide extra parameters.
+
+
+* **GUI direct support for ItemStacks when creating buttons for mc v1.8 through mc v1.12. **
+With the use of magic numbers with Minecraft versions less than 1.13 the use of Materail to create ItemStacks fails to get the correct type if magic numbers are involved. Created a new createButton function to work directly with item stacks so the proper blocks can be used with mc v1.8 through v1.12.
+
+
+* **Additions to PrisonBlock handlers to provide more utility functions**
+and to solve a few complex challenges. Removed NULL_BLOCK from the valid block lists.
+
+
+* **Found function names that started with capital letters and changed them to lower case.**
+Function names should never be capitalized since that would imply they are classes, or similar objects, and not functions.
+
+
+* **Compile error with the removal of the prison core gui...**
+Removal of this code was forgotten when removing the prison core gui code. Not sure how that passed the compiler before committing to git?
+
+
+* **cleaned up unused imports in the gui code; were causing compile warnings.**
+
+
+* **New feature! Hooked the prison GUI up to the new prison command manager.**
+Assigned aliases so as to preserve backwards compatibility with admins who are used to the prisonmanager command.
+The /prisonmanager command has been replaced with just /gui. Tested and appears to be working well. Can do /gui mines, /gui ranks, /gui prestige, /gui prestiges.
+
+
+* **Added /mtp as an alias to /mines tp.**
+
+
+* **New GUI config system**
+- It's an improvement. Has many code changes
+- Deleted the GuiListener.java class, only SpigotPlatform was using it so nothing should break.
+
+
+* **New Feature! Tab complete is now functional with prison's command handler.**
+When typing in prison related commands, you can now press tab to complete the typing for you if there was only one option available, or it will fill in common letters until you need to make a choice. Also typing in a command pressing space then tab shows all available options. In game is slightly different that in console, where in game show a ghosting of the command where you are typing so tabbing will select that option.
+Works on spigot 1.8 through 1.16.x. Also works in console. Functional with aliases too.
+
+
+* **New Feature! Command Aliases!**
+Add the complexities of supporting aliases in the prison command handler. Each command can have one or more aliases mapped to almost any level of paths.
+This also includes a rich support of the sub-command and help listings to better identify which commands are aliases and also what aliases are available. There is room for enhancements that will be added soon.
+
+
+* **v3.2.2-alpha.12 - 2020-11-10**
+
+
+* **removed the trailing &f from the rank tag**
+This was within the new feature /ranks autoConfigure. It was reported that there were issues within the plugin Scoreboard-r by RienBijl that data was being truncated and lost. Looking in to the issue it was found that there was a stray &f at the end of a tag. It had no impact, but it was removed anyway since it does nothing. It was determined that the scoreboard-r plugin is buggy and was causing errors.
+
+
+* **New Feature: Now provides the capture of the actual label that a command is registered with Bukkit when there is a conflict.** The prison Command Handler now uses the registered label when displaying any of the sub commands or list of all registered root commands. This will allow the users to know what commands they actually have to enter to get them to work, instead of guessing when there is a conflict.
+
+
+* **Improve block matching for pre mc v1.13.0**
+For the 1.8.x material types in prison, there exists different states with the data value that could result in block types that are unknown. Some of it may be orientation or degree of flowing water, or even wetness of soil. I've seen it with leaves of different shades, or even with logs.
+The idea here to fix this issue is not so much that we don't know the block type as much as it shouldn't matter the slight variations in the data field. Therefore if we fail to match on the id and data, then go off of the material name. That's a good fallback.
+
+
+* **Bug fix: Fix incorrect display of no other mines near for /mines whereami**
+If the player was standing in a mine and there are no other mines around, it used to show the mine they are in, plus say there are no other mines within 150 blocks.
+Now it will not show the "no other mines in 150 blocks" message.
+
+
+* **Mines Blocks GUI Fix**
+
+
+* **Bug Fix: Found a bug in the command registration code** that could result in failing to properly register commands. This would have been an issue if there were upper case letters in a command, since all commands are converted to lowercase when added, but when checking to see if a subcommand was already processed (ie... the "set" in the following two commands: /mines set tag, /mines set resetTime). The symptoms would be missing commands at runtime. I actually have seen this failure in the past, and realized that all commands should be entered as lowercase due to this error. Now it should work correctly.
+
+
+* **Clarify the role of a CommandHandler field that is used in a situation of when there is a command collision.**
+
+
+* **Fix typo: In the /mines command add function, a & was placed one character to the right of where it should have been.**
+
+
+* **Added an unregister all for the commands and hooked it up on the plugin's onDisable.**
+
+
+* **Fixed issue with dropping of inventory.**
+Had a ! where it shouldn't have been and forgot to hook up the new messageId variable so the warning can change.
+I'm not so sure about messaging this way, using the action bar, but don't want to flood chat with a ton of messages either. Would have to put a limiter on the chat messages?
+
+
+* **Fixed an index out of range issue in the gui.**
+Was 45 when should have been 44.
+
+
+* **New Feature: Added XP calculations to the block break (auto pickup) function**
+which can be disabled. Give the option to drop the xp as orbs (default) or give it directly to the player with no orbs.
+
+
+* **It was realized that dropItemsIfInventoryIsFull was not hooked up.**
+Hooked it up.
+
+
+* **Update some docs and added a few screen prints.**
+Updates to a few documents to reflect some of the more recent updates to prison.
+
+
+* **Updates to the IntegrationManager** so the variable is more consistent and especially the message for WorldGuard integration is clear that it is not an error that it is not yet active.
+
+
+* **Change the command /prison alerts so they can be ran from the console** since it made no sense why the console was locked out from using them.
+Slight changed the information for /prison gui that shows that it could be preferred to configure the autofeatures.
+
+
+* **Changed the perms to lower case, specifically the mine/rank name. Should have been lower case.**
+
+
+* **Had the wrong block name for dark_oak_planks (thought I fixed that already).**
+
+
+* **v3.2.2-alpha.11 - 2020-10-29**
+
+
+* **For /ranks autoConfigure: Almost forgot to add the removal of the mines.tp.
# New! Prison Fast Start
@@ -135,9 +141,8 @@ Prison now has a new set of features that can help you get up and running faster
-* **Setting up Vault** - (coming soon)
+* [Setting up Vault](prison_docs_016_setting_up_Vault.md)
Including Vault is Strongly Suggested.
- Hint: Download from spigotmc.org and copy jar to plugin folder. Zero setup.
* [Setting up EssentialsX](prison_docs_0xx_setting_up_EssentialsX.md) -
diff --git a/docs/prison_docs_012_setting_up_prison_basics.md b/docs/prison_docs_012_setting_up_prison_basics.md
index b4d835409..060179695 100644
--- a/docs/prison_docs_012_setting_up_prison_basics.md
+++ b/docs/prison_docs_012_setting_up_prison_basics.md
@@ -26,13 +26,10 @@ There may be no hard dependencies that will prevent Prison from running, but the
* **EssentialsX Chat** - Optional - Enhanced Chat experience.
-* **EssentialsX Spawn** - Optional - Enhanced support for Spawns.
-
-
* **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.
* Warning: LuckPerms v5.0.x crashes older versions of prison, such as V3.2.0 and earlier.
- * Notice: Prison v3.2.1 (including the pre-release versions) supports all versions of LuckPerms.
- * Strongly suggest using LuckPerms v5.0.x with latest pre-release version of Prison.
+ * Notice: Prison v3.2.1, and newer, supports all versions of LuckPerms.
+ * Strongly suggest using LuckPerms v5.x with all of the latest versions of Prison.
* **PlaceholderAPI** - 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.
@@ -48,20 +45,24 @@ Download Prison from [spigotmc.org's Prison History Page](https://www.spigotmc.o
Setting up Prison is simple:
-* Download Prison - Current Releases
- - Go to the SpigotMC.org LuckPerm's resource page:
+* Download Prison - Current Release
+ - Go to the SpigotMC.org Prison's resource page:
- [Prison Downloads](https://www.spigotmc.org/resources/prison.1223/history "Prison download can be found under the Version History tab")
- - Click on the Version History tab
- - Choose the version to download
+ - Click on the Version History tab if needed
+ - Choose the latest version to download
* **Download Prison's Pre-Release Version**
- Useful to access newer features and fixes
- - You can usually find a build on the Discord Server:
+ - You can always find the latest alpha build on the Discord Server in the #alpha-versions channel:
- [Prison Discord Server](https://discord.gg/DCJ3j6r)
-* Copy to your server's plugin directory
+* Copy the prison jar file to your server's plugin directory.
+
+* Remove any older prison jar file
-* Restart the server
+* Restart the server.
+
+* 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.
* Follow Prison's documentation on customization, but at this point it's ready for use.
@@ -131,6 +132,13 @@ On the startup screen, prison shows all of the base commands that are active. Fr
* **/rankup**
+If you use the command `/prison` it will not only display all of the sub commands available for `/prison`, but it will also include a list of all the other *root* commands and aliases that have been setup.
+
+
+
+
+
+
These commands are intended to run in game, but most can be ran from the system console. Sometimes the system console is easier to displays longer listings, such as **/mines list**. Also the console is better with wider text, and with easier to read text since it's not trying to display over a mc world.
diff --git a/docs/prison_docs_016_setting_up_Vault.md b/docs/prison_docs_016_setting_up_Vault.md
new file mode 100644
index 000000000..1fb8d8a65
--- /dev/null
+++ b/docs/prison_docs_016_setting_up_Vault.md
@@ -0,0 +1,35 @@
+
+### Prison Documentation
+[Prison Documents - Table of Contents](prison_docs_000_toc.md)
+
+## Setting up Vault
+
+This document provides a quick overview on how to install Vault.
+
+Vault may be optional, but it is a very important plugin. It provides easy integration with economies and permissions. This is useful because its a standard way for prison to hook in and use any plugin that supports Vault.
+
+
+
+
+# Optional Dependencies
+
+There aren't any required dependencies to using Vault, but Vault will be useless if there were no other plugins to hook in to it.
+
+The two most useful plugins to use would be EssentialsX and LuckPerms. EssentialsX is useful for its economy, and LP for the permissions.
+
+
+
+
+# Setting up Vault
+
+Vault is simple to setup since there are no required configurations.
+
+* Download Vault:
+ - Go to SigotMC.org Vault download page
+ - [Vault Download Page]()
+
+* Copy to your server's plugin directory
+
+
+
+
diff --git a/docs/prison_docs_0xx_setting_up_EssentialsX.md b/docs/prison_docs_0xx_setting_up_EssentialsX.md
index 18f8849ce..6c41ee280 100644
--- a/docs/prison_docs_0xx_setting_up_EssentialsX.md
+++ b/docs/prison_docs_0xx_setting_up_EssentialsX.md
@@ -26,22 +26,29 @@ Setting up Essentials is easy, but you've to choose which plugins to add.
- [EssentialsX Download page](https://www.spigotmc.org/resources/essentialsx.9089/)
* Unzip the download.
* Copy the jar files of your choice to your server's `plugin/` directory.
-* The zip file contains multiple jars of the same version. Always use the same versions with each other, but never mix one EssentialsX jar version with another version.
-* Available Modules and what is recommended:
+* The zip file contains multiple jars of the same version. Always use the same versions with each other, and never mix one EssentialsX jar version with another version.
+
+
+* Available Modules and what is recommended and what isn't:
* EssentialsX - Main jar - **Required**
* EssentialsXAntiBuild - *Optional* - Don't use if using WorldGuard?
* EssentialsXChat - **Recommended** - Provides chat based placeholders (see below)
* EssentialsXGeoIP - *Optional* - Provide geo locations for players IP addresses
* EssentialsXProtect - *Optional* - Not sure, but shouldn't be used with WorldGuard?
* EssentialsXSpawn - *Optional* - Not sure, but provides special behaviors for spawn? Not sure.
- * EssentialsXXMPP - *Don't Use* - Google XXMPP for spigot to confirm if you really have a need to use this. You probably never will.
+ * EssentialsXXMPP - *Don't Use* - Google _XXMPP for spigot_ to confirm if you really have a need to use this. You probably never will.
+
+
+* Prison does not require you to change any settings in EssentialsX, but you may if you want to customize a few things.
+
-* Prison does not require you to change any settings in EssentialsX, but you may if you want to customize some things.
* List of possible items to modify:
* Chat prefixes (see below)
* Item prices if you will be using the shop functions through EssentialsX. If you do, I suggest you remove the entries for armor, weapons, tools, food, etc. Otherwise players may accidentally sell things they need. Also you can add new items to be sold.
* Customize kits
* etc...
+
+
* Restart your server
@@ -50,19 +57,21 @@ Setting up Essentials is easy, but you've to choose which plugins to add.
## Add the Prison placeholder *Rank Tag* to Player's Chat Prefix
-* EssentialsX's plugin folder on the server
+* Go to the EssentialsX's plugin folder on the server:
+
+
* Path: `plugins\Essentials\`
+
+
* Edit the `config.yml` file:
- Search for the section pertaining to chat by using the keyword: **EssentialsChat**
- Add the placeholders {prison_rank_tag} or {prison_rank} to the "format:" line.
- * The placeholders should be entered in all lower case
+ * The placeholders should be **all lower case**
* The curly braces is used by EssentialsX chat engine, not Prison. Other chat plugins may use percent symbols instead.
* {prison_rank} is the rank name without special formatting
* {prison_rank_tag} is the defined tag (with formatting) for that rank
- Example:
- ```
- format: '<{prison_rank_tag}:{DISPLAYNAME}>{MESSAGE}'
- ```
+ format: `<{prison_rank_tag}:{DISPLAYNAME}>{MESSAGE}`
Reload EssentialsX settings, or restart the server.
@@ -72,13 +81,21 @@ Reload EssentialsX settings, or restart the server.
# Applying Settings and Reloading Essentials
+
* Restart the server. Or use **/essentials reload**.
-* Notice: **Don't use /reload to reload the whole server!** Using /reload or another tool such as plugman could corrupt plugins. Prison was not designed to do soft reloads and as such mines, ranks, ladders, and even some player settings and histories could be corrupted.
+
-
+
+* If you reload essentials and the placeholders are not working, then you may have to either restart the server, or reload the prison's placeholders with the following commands, both of which are exactly the same:
+ - `/prison placeholders reload`
+ - `/prison reload placeholders`
+
+
+* Notice: **Don't use /reload to reload the whole server!** Using /reload or another tool such as plugman could corrupt plugins. Prison was not designed to do soft reloads and as such mines, ranks, ladders, and even some player settings and histories could be corrupted.
+
@@ -89,7 +106,7 @@ Reload EssentialsX settings, or restart the server.
# Essentials Currency Commands
-Eventually you may have to deal with currency, so here are the esstentals commands.
+Eventually you may have to deal with currency, so here are the essentials commands.
* `/eco` - Show the EssentialsX economy commands
* `/eco give
@@ -52,9 +54,28 @@ Use the command **/prison placeholders** for a listing the placeholder commands.
* **/prison placeholders search
@@ -76,9 +97,18 @@ The solution was to download from PlaceholderAPI, their modified version of Vaul
/papi reload
```
-As a note, I'm not sure how well Prison behaves with the use of `/papi reload`. It may be good to test with, but safer to just restart the server, once everything appears to be working and looks good. The point is that any plugin reload is good to test with, but if you're going to let your server run for months, its probably best to do a clean restart.
+If you use `/papi reload`/ then you will have to reload the placeholders in prison so they are registered with papi. When papi reloads, it forgets everything that was registered before.
+
+
+You can use either one of the following commands to reload and re-register all of prison's placeholders. Both commands are exactly the same.
+
+```
+/prison placeholders reload
+/prison reload placeholders
+```
+
+If you create new ranks or mines you will also have to reload the prison placeholders. You don't have to reload papi in these situations, just prison.
-With this example of installing the PlaceholderAPI and downloading their version of Vault and Essentials, the player reported that once the economy placeholder was working, another placeholder stopped working. Their solution was to reinstall all of the papi (PlaceholderAPI) plugins (not sure if that includes reinstalling papi's version of Vault and Essentials) and then restarted the server. The point here, is a clean start is probably helpful.
diff --git a/docs/prison_docs_101_setting_up_mines.md b/docs/prison_docs_101_setting_up_mines.md
index f1cddb4ef..dfb8755ac 100644
--- a/docs/prison_docs_101_setting_up_mines.md
+++ b/docs/prison_docs_101_setting_up_mines.md
@@ -24,7 +24,7 @@ Items to add to this document:
# New! Prison Fast Start
Prison now has a new set of features that can help you get up and running faster than ever! `/ranks autoConfigure`. It can auto create your ranks and virtual mines, A through Z, it will link the mines to the ranks, setup the basic rank commands to provide basic access permissions for your players, and assign blocks of increasing values to all mines. All you need to do is to use the command `/mines set area` on all mines to make them physical mines. Plus there are a new features to help provide the finishing touches in almost no time.
- - `/ranks autoConfigure`
+ - `/ranks autoConfigure`
- `/mines set area help`
- `/mines set tracer help`
- `/mines set size help`
@@ -265,6 +265,26 @@ Note: The new command `/mines set move` is not yet enabled. It is still in devel
+# Large Mines - Preventing Lag
+
+Large mines present their special own special challenges, one of which is that they can take a long time to reset. Since bukkit cannot handle async resets of blocks because of world corruption, the updates must happen synchronously in the main server thread. For large mines, that can mean causing a significant amount of lag.
+
+To prevent lagging the server, Prison has a feature that can prevent any lag from happening while performing the reset. This feature is called **Reset Paging**. This feature doesn't have to be used with just large mines, but the reset process is a little more complex. When testing, it was actually found to be slightly faster than the normal reset method.
+
+To enable reset paging use the following commands to enable and disable it.
+
+```
+/mines set resetPaging
+
# Next Steps - Skipping Resets, Notifications, and Zero Blocks
diff --git a/docs/prison_docs_113_setting_up_sellall.md b/docs/prison_docs_113_setting_up_sellall.md
index fc96ac1b6..97193130e 100644
--- a/docs/prison_docs_113_setting_up_sellall.md
+++ b/docs/prison_docs_113_setting_up_sellall.md
@@ -83,6 +83,42 @@ How Multipliers work -> they'll just multiply the value of what you sold, for ex
so ```1000 * 1 = 1000``` is what you'll get (by default this's the value in the sellallconfig.yml), but if you've a Prestige with a multiplier of maybe ```1.5```, then
you'll get ```1000 * 1.5 = 1500```, this isn't even hard math but could make you some confusion.
+**SellaAll Signs:**
+
+Open your config.yml and turn on true the sellall sign like this:
+```
+# NEW: SellAll sign
+# New sellall feature which enable a sign with the name of [SellAll] to execute the command /sellall sell of Prison
+# To make a sign, give yourself the permission prison.admin and then add as the first line of a sign the tag [SellAll]
+sellall-sign: true
+sellall-sign-notify: true
+sellall-sign-visible-tag: "&7[&3SellAll&7]"
+```
+You can also turn on or off a notification when clicking the sign, you can edit that in the module-conf/lang/en_US.yml file, and you can edit
+the tag from the config.yml which's shown in the sign.
+
+To make a Sign, just place a sign and add as the first line ```[SellAll]```, also be sure to have the permissions ```prison.sign```.
+If everything's right, the sign will look like the sellall-sign-visible-tag from the config.yml, and will work on right clicking it.
+
+**SellAll Auto**
+
+You can turn on or off from the SellAllConfig.yml file the SellAll Auto feature, which will sell everything sellable from the player inventory when it's full.
+Just edit these config lines like this:
+```
+ Full_Inv_AutoSell: 'true'
+ Full_Inv_AutoSell_Notification: 'false'
+```
+You can edit the autoSell notification as you want.
+
+It's also possible to enable or disable sellAll per-User, it'll be them to choose if enable it or not.
+They'll need to use the command: `/sellall auto toggle`, it'll let them enable or disable it, when used
+for the first time, the user will be stored in the `users` section of the `sellAllConfig.yml`.
+
+The admin can enable this feature from the `sellAllConfig.yml`, by changing this option from `false` to `true`:
+```
+ Options.Full_Inv_AutoSell_perUserToggleable: false
+```
+
# LIST OF COMMANDS
```
/sellall
diff --git a/gradle.properties b/gradle.properties
index e98ec377c..50012d982 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.2-alpha.14
+version=3.2.3
## org.gradle.warning.mode=(all,none,summary)
org.gradle.warning.mode=all
diff --git a/knownissues_v3.2.x.md b/knownissues_v3.2.x.md
index ee9ae611b..6b79f4e18 100644
--- a/knownissues_v3.2.x.md
+++ b/knownissues_v3.2.x.md
@@ -7,7 +7,77 @@ a short list of To Do's. This list is intended to help work through known
issues, and/or to serve as items that should be added, or fixed.
-# To Do Items - During Alpha v3.2.2
+# To Do Items - During Alpha v3.2.3
+
+
+- Placeholder Attributes:
+ A way for placeholders to be customized dynamically other plugin configs.
+ Example would be a scoreboard that uses bar graphs but customizes each one to different colors, characters, and size.
+ Use :: to identify the start of an attribute followed by the type of attribute.
+ Examples: ::nFormat: and ::bar:
+ Use of : to separate each parameter.
+
+
+
+- Hex colors:
+ https://www.spigotmc.org/threads/hex-color-code-translate.449748/#post-3867804
+ https://regex101.com/
+ (?i)[A-Fa-f0-9]{6}|&[0-9A-FK-OR]
+
+
+- Possible issue with auto features preventing WorldGuard from protecting a
+ mine. In the auto features GUI, when the bottom three features are turned
+ off then WG won't protect the region.
+
+
+- auto manager - durability not working even when feature is enabled
+- autoConfigure - fixed?
+
+
+- mines - add storage for liner so it can be regenerated
+- mine liner - add bedrock
+- BlockEvents - submit to run synch or async.
+- BlockEvents - multiple on same command. Use ; as separators
+- auto features - fixed - durabilty not working
+- auto features - cannot turn off smelt or blocking
+- auto features - issue with lore
+- world guard - not working properly
+
+
+* **Custom block issues**
+- If CustomItems is loaded successfully but yet not using new block model, show error message
+- Show a message at startup indicating that the new block model is enabled or not enabled
+
+
+* **Rework rank permissions to eliminate need to put perms in rank commands**
+- Enhance the PermissionIntegration abstract class to also work with group perms.
+- Add to ranks two new fields: permissions and permissionGroups. Save and load.
+- Add a new boolean field to ranks: usePermissions. Save and load.
+- Add support for these perms within rank commands
+- Rewrite rankups to use these perms when ranking up, promote, demote, and also for prestiges
+
+
+* **Prestige Options**
+ - Reset money on prestige - boolean option
+ - Auto Prestige - server setting or player setting?
+ - prestigemax - keep applying prestiges until run out of funds
+ - rankmax - keep applying rankups until run out of funds
+ - Eliminate prestige ranks - (optional)
+ * Would need ladder commands
+ * Need to define an upper limit of how many
+ * tags may have a placeholder: `&7[&3P&a{p_level}&7]`
+ * Have a base cost of prestige: example 100,000,000
+ * Have a cost multiplier for ranks: example: 10% more expensive each rank with each prestige
+ * Have a cost multiplier for prestiging: example: 20% more expensive each prestige
+ * Have a cost multiplier for /sellall: Example: 0.005% (1/2 increase in sale price) or -0.015% (1.5% decrease in sale price to make it even more difficult per prestige)
+ * Have a list of permissions and permission groups
+ * The above settings are pretty general and would apply to all generated prestige levels, but to allow for customizations, then ladder ranks, perms and perm groups could be setup to accept a level parameter to be applied at a specific level. Tags set at a given level could also be applied to higher levels until another tag takes it place.
+
+
+
+* **DONE: Sellall - Hook up to prison command handler**
+Currently sellall is not hooked up to the prison command handler and it needs to be.
+
* **Get new block model working**
@@ -84,7 +154,7 @@ Implement and have a fully functional new block handling mechanism that operate
-* **DONE? Rework commands within the spigot module so all user facing commands are routed through Prison's Command Interface**
+* **DONE! Rework commands within the spigot module so all user facing commands are routed through Prison's Command Interface**
Blue should work on this.
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 7287907b6..66b09988f 100644
--- a/prison-core/src/main/java/tech/mcprison/prison/Prison.java
+++ b/prison-core/src/main/java/tech/mcprison/prison/Prison.java
@@ -27,7 +27,7 @@
import tech.mcprison.prison.commands.CommandHandler;
import tech.mcprison.prison.error.ErrorManager;
import tech.mcprison.prison.integration.IntegrationManager;
-import tech.mcprison.prison.internal.block.PrisonBlockTypes;
+import tech.mcprison.prison.integration.PlaceholderManager;
import tech.mcprison.prison.internal.platform.Platform;
import tech.mcprison.prison.localization.LocaleManager;
import tech.mcprison.prison.modules.Module;
@@ -83,9 +83,12 @@ public class Prison
private ErrorManager errorManager;
private TroubleshootManager troubleshootManager;
private IntegrationManager integrationManager;
+
+ private PlaceholderManager placeholderManager;
+
private Database metaDatabase;
- private PrisonBlockTypes prisonBlockTypes;
+
/**
* Gets the current instance of this class.
- * /hd addline temp2 Mine Size: {slowest}{prison_mines_blocks_size_temp2}
- * or
- * /hd addline temp2 Mine Size: {slowest}{prison_mines_blocks_size_temp2}
- * /hd addline temp2 Mine Size: {slowest}%prison_mines_blocks_size_temp2%
- *
- *
- * https://dev.bukkit.org/projects/holographic-displays
- * https://www.spigotmc.org/resources/placeholderapi.6245/
- * https://www.spigotmc.org/resources/protocollib.1997/
- * https://www.spigotmc.org/resources/holographicextension.18461/
- */
- public enum PrisonPlaceHolders {
-
- no_match__(PlaceHolderFlags.SUPRESS),
-
- // Rank aliases:
- prison_r(PlaceHolderFlags.PLAYER, PlaceHolderFlags.ALIAS),
- prison_rt(PlaceHolderFlags.PLAYER, PlaceHolderFlags.ALIAS),
- prison_rc(PlaceHolderFlags.PLAYER, PlaceHolderFlags.ALIAS),
- prison_rcf(PlaceHolderFlags.PLAYER, PlaceHolderFlags.ALIAS),
- prison_rcp(PlaceHolderFlags.PLAYER, PlaceHolderFlags.ALIAS),
- prison_rcb(PlaceHolderFlags.PLAYER, PlaceHolderFlags.ALIAS),
- prison_rcr(PlaceHolderFlags.PLAYER, PlaceHolderFlags.ALIAS),
- prison_rcrf(PlaceHolderFlags.PLAYER, PlaceHolderFlags.ALIAS),
- prison_rr(PlaceHolderFlags.PLAYER, PlaceHolderFlags.ALIAS),
- prison_rrt(PlaceHolderFlags.PLAYER, PlaceHolderFlags.ALIAS),
-
-
- prison_rank(prison_r, PlaceHolderFlags.PLAYER),
- prison_rank_tag(prison_rt, PlaceHolderFlags.PLAYER),
- prison_rankup_cost(prison_rc, PlaceHolderFlags.PLAYER),
- prison_rankup_cost_formatted(prison_rcf, PlaceHolderFlags.PLAYER),
- prison_rankup_cost_percent(prison_rcp, PlaceHolderFlags.PLAYER),
- prison_rankup_cost_bar(prison_rcb, PlaceHolderFlags.PLAYER),
- prison_rankup_cost_remaining(prison_rcr, PlaceHolderFlags.PLAYER),
- prison_rankup_cost_remaining_formatted(prison_rcrf, PlaceHolderFlags.PLAYER),
- prison_rankup_rank(prison_rr, PlaceHolderFlags.PLAYER),
- prison_rankup_rank_tag(prison_rrt, PlaceHolderFlags.PLAYER),
-
-
- // Ladder aliases:
- prison_r_laddername(PlaceHolderFlags.LADDERS, PlaceHolderFlags.ALIAS),
- prison_rt_laddername(PlaceHolderFlags.LADDERS, PlaceHolderFlags.ALIAS),
- prison_rc_laddername(PlaceHolderFlags.LADDERS, PlaceHolderFlags.ALIAS),
- prison_rcf_laddername(PlaceHolderFlags.LADDERS, PlaceHolderFlags.ALIAS),
- prison_rcp_laddername(PlaceHolderFlags.LADDERS, PlaceHolderFlags.ALIAS),
- prison_rcb_laddername(PlaceHolderFlags.LADDERS, PlaceHolderFlags.ALIAS),
- prison_rcr_laddername(PlaceHolderFlags.LADDERS, PlaceHolderFlags.ALIAS),
- prison_rcrf_laddername(PlaceHolderFlags.LADDERS, PlaceHolderFlags.ALIAS),
- prison_rr_laddername(PlaceHolderFlags.LADDERS, PlaceHolderFlags.ALIAS),
- prison_rrt_laddername(PlaceHolderFlags.LADDERS, PlaceHolderFlags.ALIAS),
-
-
- prison_rank_laddername(prison_r_laddername, PlaceHolderFlags.LADDERS),
- prison_rank_tag_laddername(prison_rt_laddername, PlaceHolderFlags.LADDERS),
- prison_rankup_cost_laddername(prison_rc_laddername, PlaceHolderFlags.LADDERS),
- prison_rankup_cost_formatted_laddername(prison_rcf_laddername, PlaceHolderFlags.LADDERS),
- prison_rankup_cost_percent_laddername(prison_rcp_laddername, PlaceHolderFlags.LADDERS),
- prison_rankup_cost_bar_laddername(prison_rcb_laddername, PlaceHolderFlags.LADDERS),
- prison_rankup_cost_remaining_laddername(prison_rcr_laddername, PlaceHolderFlags.LADDERS),
- prison_rankup_cost_remaining_formatted_laddername(prison_rcrf_laddername, PlaceHolderFlags.LADDERS),
- prison_rankup_rank_laddername(prison_rr_laddername, PlaceHolderFlags.LADDERS),
- prison_rankup_rank_tag_laddername(prison_rrt_laddername, PlaceHolderFlags.LADDERS),
-
-
-
- // player
- prison_pb(PlaceHolderFlags.PLAYER, PlaceHolderFlags.ALIAS),
- prison_player_balance(prison_pb, PlaceHolderFlags.PLAYER),
-
- prison_pb_laddername(prison_pb, PlaceHolderFlags.LADDERS),
- prison_player_balance_laddername(prison_pb_laddername, PlaceHolderFlags.LADDERS),
-
-
-
- // Mine aliases:
- prison_mn_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS),
- prison_mt_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS),
- prison_mi_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS),
- prison_mif_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS),
- prison_mtl_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS),
- prison_mtlb_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS),
- prison_mtlf_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS),
- prison_ms_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS),
- prison_mr_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS),
- prison_mrb_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS),
- prison_mp_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS),
- prison_mpc_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS),
- prison_mbm_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS),
- prison_mrc_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS),
-
-
- // reset_interval, reset_timeleft, blocks_size, blocks_remaining, blocks_percent
- // player_count
- // NOTE: Remove PrisonPlaceHolderFlags.SUPRESS when ready to be used:
- prison_mines_name_minename(prison_mn_minename, PlaceHolderFlags.MINES),
- prison_mines_tag_minename(prison_mt_minename, PlaceHolderFlags.MINES),
- prison_mines_interval_minename(prison_mi_minename, PlaceHolderFlags.MINES),
- prison_mines_interval_formatted_minename(prison_mif_minename, PlaceHolderFlags.MINES),
- prison_mines_timeleft_minename(prison_mtl_minename, PlaceHolderFlags.MINES),
- prison_mines_timeleft_bar_minename(prison_mtlb_minename, PlaceHolderFlags.MINES),
- prison_mines_timeleft_formatted_minename(prison_mtlf_minename, PlaceHolderFlags.MINES),
- prison_mines_size_minename(prison_ms_minename, PlaceHolderFlags.MINES),
- prison_mines_remaining_minename(prison_mr_minename, PlaceHolderFlags.MINES),
- prison_mines_remaining_bar_minename(prison_mrb_minename, PlaceHolderFlags.MINES),
- prison_mines_percent_minename(prison_mp_minename, PlaceHolderFlags.MINES),
- prison_mines_player_count_minename(prison_mpc_minename, PlaceHolderFlags.MINES),
- prison_mines_blocks_mined_minename(prison_mbm_minename, PlaceHolderFlags.MINES),
- prison_mines_reset_count_minename(prison_mrc_minename, PlaceHolderFlags.MINES),
-
-
-
- // PlayerMine aliases:
- prison_mn_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS),
- prison_mt_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS),
- prison_mi_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS),
- prison_mif_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS),
- prison_mtl_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS),
- prison_mtlb_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS),
- prison_mtlf_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS),
- prison_ms_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS),
- prison_mr_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS),
- prison_mrb_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS),
- prison_mp_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS),
- prison_mpc_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS),
- prison_mbm_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS),
- prison_mrc_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS),
-
-
- prison_mines_name_playermines(prison_mn_pm, PlaceHolderFlags.PLAYERMINES),
- prison_mines_tag_playermines(prison_mt_pm, PlaceHolderFlags.PLAYERMINES),
- prison_mines_interval_playermines(prison_mi_pm, PlaceHolderFlags.PLAYERMINES),
- prison_mines_interval_formatted_playermines(prison_mif_pm, PlaceHolderFlags.PLAYERMINES),
- prison_mines_timeleft_playermines(prison_mtl_pm, PlaceHolderFlags.PLAYERMINES),
- prison_mines_timeleft_bar_playermines(prison_mtlb_pm, PlaceHolderFlags.PLAYERMINES),
- prison_mines_timeleft_formatted_playermines(prison_mtlf_pm, PlaceHolderFlags.PLAYERMINES),
- prison_mines_size_playermines(prison_ms_pm, PlaceHolderFlags.PLAYERMINES),
- prison_mines_remaining_playermines(prison_mr_pm, PlaceHolderFlags.PLAYERMINES),
- prison_mines_remaining_bar_playermines(prison_mrb_pm, PlaceHolderFlags.PLAYERMINES),
- prison_mines_percent_playermines(prison_mp_pm, PlaceHolderFlags.PLAYERMINES),
- prison_mines_player_count_playermines(prison_mpc_pm, PlaceHolderFlags.PLAYERMINES),
- prison_mines_blocks_mined_playermines(prison_mbm_pm, PlaceHolderFlags.PLAYERMINES),
- prison_mines_reset_count_playermines(prison_mrc_pm, PlaceHolderFlags.PLAYERMINES),
-
-
-
- ;
-
-
- private final PrisonPlaceHolders alias;
- private final Listvalue
is the value that changes, and is the value that
- * sets where the bar changes. The parameter valueTotal
is the max value
- * of where the value
is increasing to.
- * value
will be set to zero if
- * it is negative. If value
is greater than valueTotal
- * then it will be set to that value. The valid range for this function is only 0 percent
- * to 100 percent.
- *
If the progress bar is moving in the wrong direction, then set the parameter - *
reverseto true and then the
valuewill be inverted by subtracting - * its value from
valueTotal. - * - * - * @param value A value that is changing. Will be set to zero if negative. Will be - * set to valueTotal if greater than that amount. - * @param valueTotal The target value that is non-changing. - * @param reverse Changes the growth direction of the progress bar. - * @return - */ - public String getProgressBar( double value, double valueTotal, boolean reverse ) { - StringBuilder sb = new StringBuilder(); - - // value cannot be greater than valueTotal: - if ( value > valueTotal ) { - value = valueTotal; - } - else if ( value < 0 ) { - value = 0; - } - - // If reverse, then the new value is subtracted from valueTotal: - if ( reverse ) { - value = valueTotal - value; - } - - double percent = value / valueTotal * 100.0; - - PlaceholderProgressBarConfig barConfig = - Prison.get().getIntegrationManager().getProgressBarConfig(); - - String lastColorCode = null; - for ( int i = 0; i < barConfig.getSegments(); i++ ) { - double pct = i / ((double)barConfig.getSegments()) * 100.0; - - if ( pct < percent ) { - if ( lastColorCode == null || - !barConfig.getPositiveColor().equalsIgnoreCase( lastColorCode )) { - sb.append( barConfig.getPositiveColor() ); - lastColorCode = barConfig.getPositiveColor(); - } - sb.append( barConfig.getPositiveSegment() ); - } - else { - if ( lastColorCode == null || - !barConfig.getNegativeColor().equalsIgnoreCase( lastColorCode )) { - sb.append( barConfig.getNegativeColor() ); - lastColorCode = barConfig.getNegativeColor(); - } - sb.append( barConfig.getNegativeSegment() ); - - } - } - - - return sb.toString(); - } - - /** * Returns a list of all of the {@link Integration}s that are registered under a certain {@link IntegrationType}, if any. * This includes integrations that have not successfully integrated. @@ -598,6 +110,35 @@ public EconomyCurrencyIntegration getEconomyForCurrency(String currency) { return results; } + + + public CustomBlockIntegration getCustomBlockIntegration( PrisonBlockType blockType ) + { + CustomBlockIntegration results = null; + + if(integrations.containsKey(IntegrationType.CUSTOMBLOCK)) { + + List
The given place holders should have both the prison prefix and without, + * with the without having the suppress value set. The suppressable items + * will not always be displayed since it would be implied that the prefix + * would have been provided. + *
+ * + *Update: The placeholders without the prison prefix have been eliminated + * since the prefix is now prepended when it is missing prior to matching to a + * valid placeholder enum. This cuts the number of generated placeholders in half. + * This is significant since with the addition of the aliases there would be about + * 744 placeholders generated if the prison had 30 mines setup! Now a 30 mine prison + * would have about 372. + *
+ * + *Note: In order to use these placeholders with something like holographic display + * you need to also include the placeholderAPI, + * plugin holographic extension and protocolib. + *
+ * + *In order to get the holographics extension to work it is critical you read + * their spigot page since you have to specify a refresh speed. + *
+ *
+ * /hd addline temp2 Mine Size: {slowest}{prison_mines_blocks_size_temp2}
+ * or
+ * /hd addline temp2 Mine Size: {slowest}{prison_mines_blocks_size_temp2}
+ * /hd addline temp2 Mine Size: {slowest}%prison_mines_blocks_size_temp2%
+ *
+ *
+ * https://dev.bukkit.org/projects/holographic-displays
+ * https://www.spigotmc.org/resources/placeholderapi.6245/
+ * https://www.spigotmc.org/resources/protocollib.1997/
+ * https://www.spigotmc.org/resources/holographicextension.18461/
+ */
+ public enum PrisonPlaceHolders {
+
+ no_match__(PlaceHolderFlags.SUPRESS),
+
+ // Rank aliases:
+ prison_r(PlaceHolderFlags.PLAYER, PlaceHolderFlags.ALIAS),
+ prison_rn(PlaceHolderFlags.PLAYER, PlaceHolderFlags.ALIAS),
+ prison_rt(PlaceHolderFlags.PLAYER, PlaceHolderFlags.ALIAS),
+ prison_rc(PlaceHolderFlags.PLAYER, PlaceHolderFlags.ALIAS),
+ prison_rcf(PlaceHolderFlags.PLAYER, PlaceHolderFlags.ALIAS),
+ prison_rcp(PlaceHolderFlags.PLAYER, PlaceHolderFlags.ALIAS),
+ prison_rcb(PlaceHolderFlags.PLAYER, PlaceHolderFlags.ALIAS),
+ prison_rcr(PlaceHolderFlags.PLAYER, PlaceHolderFlags.ALIAS),
+ prison_rcrf(PlaceHolderFlags.PLAYER, PlaceHolderFlags.ALIAS),
+ prison_rr(PlaceHolderFlags.PLAYER, PlaceHolderFlags.ALIAS),
+ prison_rrt(PlaceHolderFlags.PLAYER, PlaceHolderFlags.ALIAS),
+
+
+ prison_rank(prison_r, PlaceHolderFlags.PLAYER),
+ prison_rank_number(prison_rn, PlaceHolderFlags.PLAYER),
+ prison_rank_tag(prison_rt, PlaceHolderFlags.PLAYER),
+ prison_rankup_cost(prison_rc, PlaceHolderFlags.PLAYER),
+ prison_rankup_cost_formatted(prison_rcf, PlaceHolderFlags.PLAYER),
+ prison_rankup_cost_percent(prison_rcp, PlaceHolderFlags.PLAYER),
+ prison_rankup_cost_bar(prison_rcb, PlaceHolderFlags.PLAYER),
+ prison_rankup_cost_remaining(prison_rcr, PlaceHolderFlags.PLAYER),
+ prison_rankup_cost_remaining_formatted(prison_rcrf, PlaceHolderFlags.PLAYER),
+ prison_rankup_rank(prison_rr, PlaceHolderFlags.PLAYER),
+ prison_rankup_rank_tag(prison_rrt, PlaceHolderFlags.PLAYER),
+
+
+ // Ladder aliases:
+ prison_r_laddername(PlaceHolderFlags.LADDERS, PlaceHolderFlags.ALIAS),
+ prison_rn_laddername(PlaceHolderFlags.LADDERS, PlaceHolderFlags.ALIAS),
+ prison_rt_laddername(PlaceHolderFlags.LADDERS, PlaceHolderFlags.ALIAS),
+ prison_rc_laddername(PlaceHolderFlags.LADDERS, PlaceHolderFlags.ALIAS),
+ prison_rcf_laddername(PlaceHolderFlags.LADDERS, PlaceHolderFlags.ALIAS),
+ prison_rcp_laddername(PlaceHolderFlags.LADDERS, PlaceHolderFlags.ALIAS),
+ prison_rcb_laddername(PlaceHolderFlags.LADDERS, PlaceHolderFlags.ALIAS),
+ prison_rcr_laddername(PlaceHolderFlags.LADDERS, PlaceHolderFlags.ALIAS),
+ prison_rcrf_laddername(PlaceHolderFlags.LADDERS, PlaceHolderFlags.ALIAS),
+ prison_rr_laddername(PlaceHolderFlags.LADDERS, PlaceHolderFlags.ALIAS),
+ prison_rrt_laddername(PlaceHolderFlags.LADDERS, PlaceHolderFlags.ALIAS),
+
+
+ prison_rank_laddername(prison_r_laddername, PlaceHolderFlags.LADDERS),
+ prison_rank_number_laddername(prison_rn_laddername, PlaceHolderFlags.LADDERS),
+ prison_rank_tag_laddername(prison_rt_laddername, PlaceHolderFlags.LADDERS),
+ prison_rankup_cost_laddername(prison_rc_laddername, PlaceHolderFlags.LADDERS),
+ prison_rankup_cost_formatted_laddername(prison_rcf_laddername, PlaceHolderFlags.LADDERS),
+ prison_rankup_cost_percent_laddername(prison_rcp_laddername, PlaceHolderFlags.LADDERS),
+ prison_rankup_cost_bar_laddername(prison_rcb_laddername, PlaceHolderFlags.LADDERS),
+ prison_rankup_cost_remaining_laddername(prison_rcr_laddername, PlaceHolderFlags.LADDERS),
+ prison_rankup_cost_remaining_formatted_laddername(prison_rcrf_laddername, PlaceHolderFlags.LADDERS),
+ prison_rankup_rank_laddername(prison_rr_laddername, PlaceHolderFlags.LADDERS),
+ prison_rankup_rank_tag_laddername(prison_rrt_laddername, PlaceHolderFlags.LADDERS),
+
+
+
+ // player balances. Both with and without ladders.
+ prison_pb(PlaceHolderFlags.PLAYER, PlaceHolderFlags.ALIAS),
+ prison_player_balance(prison_pb, PlaceHolderFlags.PLAYER),
+
+ prison_pb_laddername(PlaceHolderFlags.LADDERS, PlaceHolderFlags.ALIAS),
+ prison_player_balance_laddername(prison_pb_laddername, PlaceHolderFlags.LADDERS),
+
+
+
+ // Mine aliases:
+ prison_mn_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS),
+ prison_mt_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS),
+ prison_mi_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS),
+ prison_mif_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS),
+ prison_mtl_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS),
+ prison_mtlb_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS),
+ prison_mtlf_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS),
+ prison_ms_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS),
+ prison_mr_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS),
+ prison_mrb_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS),
+ prison_mp_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS),
+ prison_mpc_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS),
+ prison_mbm_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS),
+ prison_mrc_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS),
+
+
+ // reset_interval, reset_timeleft, blocks_size, blocks_remaining, blocks_percent
+ // player_count
+ // NOTE: Remove PrisonPlaceHolderFlags.SUPRESS when ready to be used:
+ prison_mines_name_minename(prison_mn_minename, PlaceHolderFlags.MINES),
+ prison_mines_tag_minename(prison_mt_minename, PlaceHolderFlags.MINES),
+ prison_mines_interval_minename(prison_mi_minename, PlaceHolderFlags.MINES),
+ prison_mines_interval_formatted_minename(prison_mif_minename, PlaceHolderFlags.MINES),
+ prison_mines_timeleft_minename(prison_mtl_minename, PlaceHolderFlags.MINES),
+ prison_mines_timeleft_bar_minename(prison_mtlb_minename, PlaceHolderFlags.MINES),
+ prison_mines_timeleft_formatted_minename(prison_mtlf_minename, PlaceHolderFlags.MINES),
+ prison_mines_size_minename(prison_ms_minename, PlaceHolderFlags.MINES),
+ prison_mines_remaining_minename(prison_mr_minename, PlaceHolderFlags.MINES),
+ prison_mines_remaining_bar_minename(prison_mrb_minename, PlaceHolderFlags.MINES),
+ prison_mines_percent_minename(prison_mp_minename, PlaceHolderFlags.MINES),
+ prison_mines_player_count_minename(prison_mpc_minename, PlaceHolderFlags.MINES),
+ prison_mines_blocks_mined_minename(prison_mbm_minename, PlaceHolderFlags.MINES),
+ prison_mines_reset_count_minename(prison_mrc_minename, PlaceHolderFlags.MINES),
+
+
+
+ // PlayerMine aliases:
+ prison_mn_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS),
+ prison_mt_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS),
+ prison_mi_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS),
+ prison_mif_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS),
+ prison_mtl_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS),
+ prison_mtlb_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS),
+ prison_mtlf_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS),
+ prison_ms_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS),
+ prison_mr_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS),
+ prison_mrb_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS),
+ prison_mp_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS),
+ prison_mpc_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS),
+ prison_mbm_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS),
+ prison_mrc_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS),
+
+
+ prison_mines_name_playermines(prison_mn_pm, PlaceHolderFlags.PLAYERMINES),
+ prison_mines_tag_playermines(prison_mt_pm, PlaceHolderFlags.PLAYERMINES),
+ prison_mines_interval_playermines(prison_mi_pm, PlaceHolderFlags.PLAYERMINES),
+ prison_mines_interval_formatted_playermines(prison_mif_pm, PlaceHolderFlags.PLAYERMINES),
+ prison_mines_timeleft_playermines(prison_mtl_pm, PlaceHolderFlags.PLAYERMINES),
+ prison_mines_timeleft_bar_playermines(prison_mtlb_pm, PlaceHolderFlags.PLAYERMINES),
+ prison_mines_timeleft_formatted_playermines(prison_mtlf_pm, PlaceHolderFlags.PLAYERMINES),
+ prison_mines_size_playermines(prison_ms_pm, PlaceHolderFlags.PLAYERMINES),
+ prison_mines_remaining_playermines(prison_mr_pm, PlaceHolderFlags.PLAYERMINES),
+ prison_mines_remaining_bar_playermines(prison_mrb_pm, PlaceHolderFlags.PLAYERMINES),
+ prison_mines_percent_playermines(prison_mp_pm, PlaceHolderFlags.PLAYERMINES),
+ prison_mines_player_count_playermines(prison_mpc_pm, PlaceHolderFlags.PLAYERMINES),
+ prison_mines_blocks_mined_playermines(prison_mbm_pm, PlaceHolderFlags.PLAYERMINES),
+ prison_mines_reset_count_playermines(prison_mrc_pm, PlaceHolderFlags.PLAYERMINES),
+
+
+
+ ;
+
+
+ private final PrisonPlaceHolders alias;
+ private final ListThis will extract attributes from dynamic placeholders and will return. + *
+ * + *Planning on using : as separators. :: for identifying each attribute, and then + * within each attribute : will separate the individual fields and values. + * For example it a number format attribute could look like this: + *
+ * + *::nFormat:0.00{unit}for no spaces. + *
::nFormat:#,##0.0+{unit}for spaces since + will be converted to spaces. + * + * @param placeholder + * @return + */ + public List
This function uses the settings within the config.yml to construct a progress + * bar. It takes two numeric values and constructs it upon those parameters. + * The parameter
valueis the value that changes, and is the value that + * sets where the bar changes. The parameter
valueTotalis the max value + * of where the
valueis increasing to. + * + * + *
The lowest range is always zero and
valuewill be set to zero if + * it is negative. If
valueis greater than
valueTotal+ * then it will be set to that value. The valid range for this function is only 0 percent + * to 100 percent. + * + * + *
If the progress bar is moving in the wrong direction, then set the parameter + *
reverseto true and then the
valuewill be inverted by subtracting + * its value from
valueTotal. + * + * + * @param value A value that is changing. Will be set to zero if negative. Will be + * set to valueTotal if greater than that amount. + * @param valueTotal The target value that is non-changing. + * @param reverse Changes the growth direction of the progress bar. + * @return + */ + public String getProgressBar( double value, double valueTotal, boolean reverse ) { + StringBuilder sb = new StringBuilder(); + + // value cannot be greater than valueTotal: + if ( value > valueTotal ) { + value = valueTotal; + } + else if ( value < 0 ) { + value = 0; + } + + // If reverse, then the new value is subtracted from valueTotal: + if ( reverse ) { + value = valueTotal - value; + } + + double percent = value / valueTotal * 100.0; + + PlaceholderProgressBarConfig barConfig = + Prison.get().getPlaceholderManager().getProgressBarConfig(); + + String lastColorCode = null; + for ( int i = 0; i < barConfig.getSegments(); i++ ) { + double pct = i / ((double)barConfig.getSegments()) * 100.0; + + if ( pct < percent ) { + if ( lastColorCode == null || + !barConfig.getPositiveColor().equalsIgnoreCase( lastColorCode )) { + sb.append( barConfig.getPositiveColor() ); + lastColorCode = barConfig.getPositiveColor(); + } + sb.append( barConfig.getPositiveSegment() ); + } + else { + if ( lastColorCode == null || + !barConfig.getNegativeColor().equalsIgnoreCase( lastColorCode )) { + sb.append( barConfig.getNegativeColor() ); + lastColorCode = barConfig.getNegativeColor(); + } + sb.append( barConfig.getNegativeSegment() ); + + } + } + + + return sb.toString(); + } + + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/integration/Placeholders.java b/prison-core/src/main/java/tech/mcprison/prison/integration/Placeholders.java index 6a417ebb5..b252cfdc9 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/integration/Placeholders.java +++ b/prison-core/src/main/java/tech/mcprison/prison/integration/Placeholders.java @@ -4,7 +4,7 @@ import java.util.Map; import java.util.UUID; -import tech.mcprison.prison.integration.IntegrationManager.PlaceHolderFlags; +import tech.mcprison.prison.integration.PlaceholderManager.PlaceHolderFlags; public interface Placeholders { diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/ItemStack.java b/prison-core/src/main/java/tech/mcprison/prison/internal/ItemStack.java index a4c5d9ee5..87cd350e2 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/ItemStack.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/ItemStack.java @@ -18,12 +18,17 @@ package tech.mcprison.prison.internal; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import org.apache.commons.lang3.StringUtils; + import tech.mcprison.prison.util.BlockType; import tech.mcprison.prison.util.Text; -import java.util.*; - /** * Represents an item stack. An item stack is a uniquely named stack in a player's inventory. * @@ -38,6 +43,14 @@ public class ItemStack { private List
This function always prefixes the block name with the BlockType. + * This is critical when saving the block to a file because there + * are no guarantees that when the server restarts the environment + * will be the same. There is a good chance that if new blocks are + * added, or if new plugins are added with new collection of custom + * blocks, then there could be a conflict. There is also the + * chance that a plugin could be removed for a block that's in a + * mine too. + *
+ * + *So having the BlockType as a prefix will help correctly align + * the blocks back to their proper source. This is critical because + * the correct plugin must handle both the block placements, and also + * the correct plugin must be used when breaking the blocks. + *
+ * + * @return + */ + public String getBlockNameFormal() { + return getBlockType().name() + ":" + getBlockName(); + } + + /** + *This provides the blockName prefixed with the block type if it is not + * a type of minecraft. + *
+ * + * @return + */ + public String getBlockNameSearch() { + return getBlockType() != PrisonBlockType.minecraft ? + getBlockType().name() + ":" + getBlockName() : getBlockName(); + } + /** + * When adding custom blocks to prison, there is a check to ensure + * that the name is not in conflict with a preexisting block name. + * If there is a conflict, then this field will be set to true and + * then the BlockType will be used as the prefix. + * + * @return + */ + public boolean isUseBlockTypeAsPrefix() { + return useBlockTypeAsPrefix; + } + public void setUseBlockTypeAsPrefix( boolean useBlockTypeAsPrefix ) { + this.useBlockTypeAsPrefix = useBlockTypeAsPrefix; + } + public double getChance() { return chance; } @@ -115,12 +198,16 @@ public void setLegacyBlock( boolean legacyBlock ) { this.legacyBlock = legacyBlock; } + public PrisonBlock clone() { + return new PrisonBlock( this ); + } + @Override public boolean equals( Object block ) { boolean results = false; if ( block != null && block instanceof PrisonBlock) { - results = getBlockName().equalsIgnoreCase( ((PrisonBlock) block).getBlockName() ); + results = getBlockNameFormal().equalsIgnoreCase( ((PrisonBlock) block).getBlockNameFormal() ); } return results; 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 8e632784f..362b3d460 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 @@ -4,7 +4,7 @@ import java.util.List; import java.util.TreeMap; -import tech.mcprison.prison.Prison; +import tech.mcprison.prison.internal.block.PrisonBlock.PrisonBlockType; /** *This class is a new way of dealing with blocks within prison.
@@ -18,6 +18,7 @@ public class PrisonBlockTypes {
private TreeMap This internally sets up the internal block types that should be
+ * accessible to the end users. For example, INGORE needs to be exposed
+ * so it can be used within mines, but NULL_BLOCK should never be
+ * exposed since it is used in block caching. At best, it should only
+ * be just one or a few blocks.
+ * When all bukkit blocks are verified and added, it would use the
+ * addBlockTypes
to add in those blocks. The bukkit block
+ * lists must be added prior to any custom blocks.
+ *
This function adds in supported block types to the listings of + * valid blocks that are available for use on the server instance that + * is being ran. Spigot v1.8.8 will produce a different set of blocks + * than what Spigot v1.16.4 would produce. + *
+ * + *The bukkit blocks must be added prior to any custom blocks. + * When a block is added, it first confirms if the block name already + * exists. If it does exist, then it sets that block so it will + * automatically use the prefix to make sure it is unique. + *
+ * + * @param blockTypes + */ + public void addBlockTypes( ListMines are now saved whenever changes are made. Do not save the Mines on server + * shutdown since they will never be in a dirty state; they will always be saved. + *
+ * + *This should shutdown all active mines. Future to do item. + *
+ * + */ + @Override + public void disable() { + // Nothing to do... + } + + + private void initDb() { OptionalMines are now saved whenever changes are made. Do not save the Mines on server - * shutdown since they will never be in a dirty state; they will always be saved. - *
- * - */ - public void disable() { - // Nothing to do... - } public MinesConfig getConfig() { return config; @@ -255,9 +275,9 @@ public LocaleManager getMinesMessages() { // return worlds; // } - public PlayerManager getPlayerManager() { - return player; - } +// public PlayerManager getPlayerManager() { +// return player; +// } public MinesCommands getMinesCommands() { return minesCommands; diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesCommands.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesCommands.java index 9e19a58b9..ef848440f 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesCommands.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesCommands.java @@ -38,13 +38,16 @@ import tech.mcprison.prison.internal.CommandSender; import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.internal.block.PrisonBlock; +import tech.mcprison.prison.internal.block.PrisonBlockTypes; import tech.mcprison.prison.mines.PrisonMines; import tech.mcprison.prison.mines.data.Block; import tech.mcprison.prison.mines.data.Mine; import tech.mcprison.prison.mines.data.MineData; import tech.mcprison.prison.mines.data.MineData.MineNotificationMode; -import tech.mcprison.prison.mines.data.MineLinerBuilder; -import tech.mcprison.prison.mines.data.MineLinerBuilder.LinerPatterns; +import tech.mcprison.prison.mines.features.MineBlockEvent; +import tech.mcprison.prison.mines.features.MineBlockEvent.BlockEventType; +import tech.mcprison.prison.mines.features.MineLinerBuilder; +import tech.mcprison.prison.mines.features.MineLinerBuilder.LinerPatterns; import tech.mcprison.prison.mines.data.PrisonSortableResults; import tech.mcprison.prison.mines.managers.MineManager; import tech.mcprison.prison.mines.managers.MineManager.MineSortOrder; @@ -410,13 +413,18 @@ public void addBlockCommand(CommandSender sender, // return; // } - if ( Prison.get().getPlatform().getConfigBooleanFalse( "use-new-prison-block-model" ) ) { + boolean useNewBlockModel = Prison.get().getPlatform().getConfigBooleanFalse( "use-new-prison-block-model" ); + + + if ( useNewBlockModel ) { block = block == null ? null : block.trim().toLowerCase(); PrisonBlock prisonBlock = null; - if ( block != null && Prison.get().getPrisonBlockTypes().getBlockTypesByName().containsKey( block ) ) { - prisonBlock = Prison.get().getPrisonBlockTypes().getBlockTypesByName().get( block ); + PrisonBlockTypes prisonBlockTypes = Prison.get().getPlatform().getPrisonBlockTypes(); + + if ( block != null && prisonBlockTypes.getBlockTypesByName().containsKey( block ) ) { + prisonBlock = prisonBlockTypes.getBlockTypesByName().get( block ); } if ( prisonBlock == null ) { @@ -489,7 +497,7 @@ else if ( chance <= 0 ) { .withReplacements(block, mineName).sendTo(sender); } - getBlocksList(m, null).send(sender); + getBlocksList(m, null, useNewBlockModel).send(sender); //pMines.getMineManager().clearCache(); } @@ -523,7 +531,7 @@ private void updateMinePrisonBlock( CommandSender sender, Mine m, PrisonBlock pr if ( chance <= 0 ) { // remove the block since it has zero chance - m.getPrisonBlocks().remove( existingPrisonBlock ); + m.removePrisonBlock( existingPrisonBlock ); } else { // update chance for the prisonBlock. This block is @@ -538,7 +546,7 @@ private void updateMinePrisonBlock( CommandSender sender, Mine m, PrisonBlock pr } else { prisonBlock.setChance( chance ); - m.getPrisonBlocks().add( prisonBlock ); + m.addPrisonBlock( prisonBlock ); pMines.getMineManager().saveMine( m ); @@ -572,14 +580,18 @@ public void setBlockCommand(CommandSender sender, // return; // } - if ( Prison.get().getPlatform().getConfigBooleanFalse( "use-new-prison-block-model" ) ) { + boolean useNewBlockModel = Prison.get().getPlatform().getConfigBooleanFalse( "use-new-prison-block-model" ); + + if ( useNewBlockModel ) { block = block == null ? null : block.trim().toLowerCase(); PrisonBlock prisonBlock = null; - if ( block != null && Prison.get().getPrisonBlockTypes().getBlockTypesByName().containsKey( block ) ) { - prisonBlock = Prison.get().getPrisonBlockTypes().getBlockTypesByName().get( block ); + PrisonBlockTypes prisonBlockTypes = Prison.get().getPlatform().getPrisonBlockTypes(); + + if ( block != null && prisonBlockTypes.getBlockTypesByName().containsKey( block ) ) { + prisonBlock = prisonBlockTypes.getBlockTypesByName().get( block ); } @@ -690,7 +702,7 @@ public void setBlockCommand(CommandSender sender, } - getBlocksList(m, null).send(sender); + getBlocksList(m, null, useNewBlockModel ).send(sender); //pMines.getMineManager().clearCache(); @@ -711,9 +723,6 @@ private BlockPercentTotal calculatePercentage( double chance, BlockType blockTyp } } - if ( results.getOldBlock() == null ) { - results.setOldBlock( new Block(blockType, chance) ); - } return results; } @@ -787,15 +796,19 @@ public void delBlockCommand(CommandSender sender, PrisonMines pMines = PrisonMines.getInstance(); Mine m = pMines.getMine(mineName); + boolean useNewBlockModel = Prison.get().getPlatform().getConfigBooleanFalse( "use-new-prison-block-model" ); - if ( Prison.get().getPlatform().getConfigBooleanFalse( "use-new-prison-block-model" ) ) { + if ( useNewBlockModel ) { block = block == null ? null : block.trim().toLowerCase(); PrisonBlock prisonBlock = null; - if ( block != null && Prison.get().getPrisonBlockTypes().getBlockTypesByName().containsKey( block ) ) { - prisonBlock = Prison.get().getPrisonBlockTypes().getBlockTypesByName().get( block ); + + PrisonBlockTypes prisonBlockTypes = Prison.get().getPlatform().getPrisonBlockTypes(); + + if ( block != null && prisonBlockTypes.getBlockTypesByName().containsKey( block ) ) { + prisonBlock = prisonBlockTypes.getBlockTypesByName().get( block ); } // Cannot delete a block if it does not exist: @@ -830,7 +843,7 @@ public void delBlockCommand(CommandSender sender, deleteBlock( sender, pMines, m, blockType ); } - getBlocksList(m, null).send(sender); + getBlocksList(m, null, useNewBlockModel).send(sender); } /** @@ -841,16 +854,8 @@ public void delBlockCommand(CommandSender sender, * @param m * @param prisonBlock */ - private void deleteBlock( CommandSender sender, PrisonMines pMines, Mine m, PrisonBlock prisonBlock ) - { - PrisonBlock rBlock = null; - for ( PrisonBlock block : m.getPrisonBlocks() ) { - if (block.getBlockName().equalsIgnoreCase( prisonBlock.getBlockName() )) { - rBlock = block; - break; - } - } - if ( m.getPrisonBlocks().remove( rBlock )) { + private void deleteBlock( CommandSender sender, PrisonMines pMines, Mine m, PrisonBlock prisonBlock ) { + if ( m.removePrisonBlock( prisonBlock ) ) { pMines.getMineManager().saveMine( m ); pMines.getMinesMessages().getLocalizable("block_deleted"). @@ -912,13 +917,9 @@ public void searchBlockCommand(CommandSender sender, private ChatDisplay prisonBlockSearchBuilder(String search, String page) { - ListThis is the time in ticks that is used when submitting + * the reset jobs. A value of 0 could cause the server to lock up since + * it does not have enough time to deal with other tasks. + *
+ * + *One tick is 50 milliseconds, 2 is 100 milliseconds or 1/10 of + * a second. + *
+ */ + public static final long MINE_RESET__PAGE_SUBMIT_DELAY_TICKS = 1; /** *When placing blocks, this is the block count that is used to check for @@ -228,38 +247,50 @@ private void resetSynchonouslyInternal() { // for (int y = getBounds().getyBlockMin(); y <= getBounds().getyBlockMax(); y++) { for (int x = getBounds().getxBlockMin(); x <= getBounds().getxBlockMax(); x++) { for (int z = getBounds().getzBlockMin(); z <= getBounds().getzBlockMax(); z++) { - Location targetBlock = new Location(world, x, y, z); + Location targetLocation = new Location(world, x, y, z); + + tech.mcprison.prison.internal.block.Block targetBlock = targetLocation.getBlockAt(); if ( useNewBlockModel ) { + PrisonBlock prisonBlock = targetBlock.isEmpty() ? null : + targetBlock.getPrisonBlock(); + if (!isFillMode || - isFillMode && targetBlock.getBlockAt().isEmpty() || - isFillMode && targetBlock.equals(altTp) && - altTp.getBlockAt().getPrisonBlock().getBlockName().equalsIgnoreCase( "GLASS" ) ) { + isFillMode && prisonBlock == null || + isFillMode && targetLocation.equals(altTp) && + prisonBlock.getBlockName().equalsIgnoreCase( "GLASS" ) || + isFillMode && targetLocation.equals(altTp) && + prisonBlock.getBlockName().equalsIgnoreCase( "AIR" ) ) { - - targetBlock.getBlockAt().setPrisonBlock( randomlySelectPrisonBlock( random )); + PrisonBlock targetPrisonBlock = randomlySelectPrisonBlock( random ); + if ( !targetPrisonBlock.equals( PrisonBlock.IGNORE ) ) { + + targetBlock.setPrisonBlock( randomlySelectPrisonBlock( random )); + } i++; + // targetBlock.getBlockAt().setType(getRandomizedBlocks().get(i++)); } - if ( targetBlock.getBlockAt().getPrisonBlock().getBlockName().equalsIgnoreCase( "AIR" ) ) { + if ( prisonBlock == null || + prisonBlock.getBlockName().equalsIgnoreCase( "AIR" ) ) { incrementBlockBreakCount(); } } else { if (!isFillMode || - isFillMode && targetBlock.getBlockAt().isEmpty() || - isFillMode && targetBlock.equals(altTp) && altTp.getBlockAt().getType() == BlockType.GLASS ) { + isFillMode && targetBlock.isEmpty() || + isFillMode && targetLocation.equals(altTp) && altTp.getBlockAt().getType() == BlockType.GLASS ) { - targetBlock.getBlockAt().setType(randomlySelectBlock( random )); + targetBlock.setType(randomlySelectBlock( random )); i++; // targetBlock.getBlockAt().setType(getRandomizedBlocks().get(i++)); } - if ( targetBlock.getBlockAt().getType() == BlockType.AIR ) { + if ( targetBlock.getType() == BlockType.AIR ) { incrementBlockBreakCount(); } } @@ -341,8 +372,10 @@ public String statsMessage() { sb.append( "&3 ResetPages: &7" ); sb.append( iFmt.format(getStatsResetPages() )); - double avgBlocks = getStatsResetPageBlocks() / getStatsResetPages(); - double avgMs = getStatsResetPageMs() / getStatsResetPages(); + double avgBlocks = getStatsResetPages() == 0 ? 0 : + getStatsResetPageBlocks() / getStatsResetPages(); + double avgMs = getStatsResetPages() == 0 ? 0 : + getStatsResetPageMs() / getStatsResetPages(); sb.append( "&3 avgBlocks: &7" ); sb.append( dFmt.format(avgBlocks)); @@ -565,6 +598,9 @@ protected void generateBlockListAsync() { // Clear the mineTargetBlocks list: getMineTargetBlocks().clear(); + boolean useNewBlockModel = Prison.get().getPlatform().getConfigBooleanFalse( "use-new-prison-block-model" ); + + // // Reset the mineAirBlocks to all false values: // boolean[] mAirBlocks = new boolean[ getBounds().getTotalBlockCount() ]; // // Arrays.fill( mAirBlocks, false ); // redundant but prevents nulls if were Boolean @@ -576,17 +612,34 @@ protected void generateBlockListAsync() { for (int x = getBounds().getxBlockMin(); x <= getBounds().getxBlockMax(); x++) { for (int z = getBounds().getzBlockMin(); z <= getBounds().getzBlockMax(); z++) { - BlockType blockType = randomlySelectBlock( random ); + MineTargetBlock mtb = null; - MineTargetBlock mtb = new MineTargetBlock( blockType, x, y, z); + if ( useNewBlockModel ) { + + PrisonBlock prisonBlock = randomlySelectPrisonBlock( random ); + + mtb = new MineTargetPrisonBlock( prisonBlock, x, y, z); + + if ( prisonBlock.equals( PrisonBlock.AIR ) ) { +// mAirBlocks[i++] = true; + airCount++; + } + } + else { + + BlockType blockType = randomlySelectBlock( random ); + + mtb = new MineTargetBlock( blockType, x, y, z); + + if ( blockType == BlockType.AIR ) { +// mAirBlocks[i++] = true; + airCount++; + } + } getMineTargetBlocks().add( mtb ); getMineTargetBlocksMap().put( mtb.getBlockKey(), mtb ); - if ( blockType == BlockType.AIR ) { -// mAirBlocks[i++] = true; - airCount++; - } } } } @@ -840,6 +893,10 @@ private void resetAsynchonouslyUpdate() { else { World world = getBounds().getCenter().getWorld(); + boolean useNewBlockModel = Prison.get().getPlatform().getConfigBooleanFalse( "use-new-prison-block-model" ); + + + long start = System.currentTimeMillis(); boolean isFillMode = PrisonMines.getInstance().getConfig().fillMode; @@ -857,8 +914,16 @@ private void resetAsynchonouslyUpdate() { target.getBlockKey().getZ()); if (!isFillMode || isFillMode && targetBlock.getBlockAt().isEmpty()) { - targetBlock.getBlockAt().setType(target.getBlockType()); } + if ( useNewBlockModel ) { + MineTargetPrisonBlock pbTarget = (MineTargetPrisonBlock) target; + + targetBlock.getBlockAt().setPrisonBlock( pbTarget.getPrisonBlock() ); + } + else { + + targetBlock.getBlockAt().setType(target.getBlockType()); + } /** * About every 250 blocks, or so, check to see if the current wall time @@ -909,11 +974,11 @@ private void resetAsynchonouslyUpdate() { * @param callbackAsync */ public void submitAsyncTask( PrisonRunnable callbackAsync ) { - Prison.get().getPlatform().getScheduler().runTaskLaterAsync( callbackAsync, 0L ); + Prison.get().getPlatform().getScheduler().runTaskLaterAsync( callbackAsync, MINE_RESET__PAGE_SUBMIT_DELAY_TICKS ); } public void submitSyncTask( PrisonRunnable callbackSync ) { - Prison.get().getPlatform().getScheduler().runTaskLater( callbackSync, 0L ); + Prison.get().getPlatform().getScheduler().runTaskLater( callbackSync, MINE_RESET__PAGE_SUBMIT_DELAY_TICKS ); } // /** @@ -993,8 +1058,7 @@ protected void refreshAirCountAsyncTask() } else if ( useNewBlockModel && getPrisonBlocks().size() == 1 && - getPrisonBlocks().get( 0 ).getBlockName().equalsIgnoreCase( InternalBlockTypes.IGNORE.name() ) && - getPrisonBlocks().get( 0 ).getChance() == 100.0 ) { + getPrisonBlocks().get( 0 ).equals( PrisonBlock.IGNORE ) ) { // This mine is set to ignore all blocks when trying to do a reset, // so for now ignore the types and just set air count to zero. @@ -1004,8 +1068,7 @@ else if ( useNewBlockModel && } else if ( !useNewBlockModel && getBlocks().size() == 1 && - getBlocks().get( 0 ).getType() == BlockType.IGNORE && - getBlocks().get( 0 ).getChance() == 100.0 ) { + getBlocks().get( 0 ).getType() == BlockType.IGNORE ) { // This mine is set to ignore all blocks when trying to do a reset, // so for now ignore the types and just set air count to zero. @@ -1032,7 +1095,8 @@ else if ( !useNewBlockModel && if ( useNewBlockModel ) { - if ( targetBlock.getBlockAt().getPrisonBlock().getBlockName().equalsIgnoreCase( "AIR" ) ) { + if ( targetBlock.getBlockAt().getPrisonBlock() == null || + targetBlock.getBlockAt().getPrisonBlock().equals( PrisonBlock.AIR ) ) { airCount++; } } @@ -1055,7 +1119,7 @@ else if ( !useNewBlockModel && String message = String.format( "MineReset.refreshAirCountAsyncTask: Error counting air blocks: " + "Mine=%s coords=%s Error: %s ", getName(), coords, e.getMessage() ); - if ( e.getMessage().contains( "Asynchronous entity world add" )) { + if ( e.getMessage() != null && e.getMessage().contains( "Asynchronous entity world add" )) { Output.get().logWarn( message ); } else { Output.get().logWarn( message, e ); @@ -1153,32 +1217,34 @@ public void refreshMineAsyncResubmitTask() { } - /** - * Generates blocks for the specified mine and caches the result. - * - * The random chance is now calculated upon a double instead of integer. - * - * @param mine the mine to randomize - */ - private void generateBlockList() { - long start = System.currentTimeMillis(); - - Random random = new Random(); - - - getRandomizedBlocks().clear(); - - for (int i = 0; i < getBounds().getTotalBlockCount(); i++) { - BlockType blockType = randomlySelectBlock( random ); - getRandomizedBlocks().add(blockType); - } - long stop = System.currentTimeMillis(); - - setStatsBlockGenTimeMS( stop - start ); - -// Output.get().logInfo("&cMine reset: " + getName() + " generated " + getBounds().getTotalBlockCount() + -// " blocks in " + getStatsBlockGenTimeMS() + " ms"); - } +// NOTE: Obsolete: the reset is no longer using a generated block list since it does not +// provide much of a performance improvement for the cost of the memory it uses. +// /** +// * Generates blocks for the specified mine and caches the result. +// * +// * The random chance is now calculated upon a double instead of integer. +// * +// * @param mine the mine to randomize +// */ +// private void generateBlockList() { +// long start = System.currentTimeMillis(); +// +// Random random = new Random(); +// +// +// getRandomizedBlocks().clear(); +// +// for (int i = 0; i < getBounds().getTotalBlockCount(); i++) { +// BlockType blockType = randomlySelectBlock( random ); +// getRandomizedBlocks().add(blockType); +// } +// long stop = System.currentTimeMillis(); +// +// setStatsBlockGenTimeMS( stop - start ); +// +//// Output.get().logInfo("&cMine reset: " + getName() + " generated " + getBounds().getTotalBlockCount() + +//// " blocks in " + getStatsBlockGenTimeMS() + " ms"); +// } private PrisonBlock randomlySelectPrisonBlock( Random random ) @@ -1331,6 +1397,8 @@ public void adjustSize( Edges edge, int amount ) { // First clear the mine: clearMine( false ); + // if amount is zero, then just refresh the liner: + if ( amount < 0 ) { while ( amount++ < 0 ) { @@ -1342,13 +1410,24 @@ public void adjustSize( Edges edge, int amount ) { new MineLinerBuilder( (Mine) this, edge, LinerPatterns.repair, false ); } } - else { + else if ( amount > 0 ) { new MineLinerBuilder( (Mine) this, edge, LinerPatterns.repair, false ); Bounds newBounds = new Bounds( getBounds(), edge, amount ); setBounds( newBounds ); } + // Rebuild the liner if it exists: + for ( Edges targtEdge : Edges.values() ) { + + if ( getLinerData().hasEdge( targtEdge ) ) { + + LinerPatterns pattern = LinerPatterns.fromString( getLinerData().getEdge( targtEdge ) ); + boolean force = getLinerData().getForce( targtEdge ); + + new MineLinerBuilder( (Mine) this, targtEdge, pattern, force ); + } + } // Finally trace the mine: clearMine( true ); diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineResetAsyncResubmitTask.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineResetAsyncResubmitTask.java index c00e1d0a9..55602b4b5 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineResetAsyncResubmitTask.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineResetAsyncResubmitTask.java @@ -1,5 +1,7 @@ package tech.mcprison.prison.mines.data; +import tech.mcprison.prison.tasks.PrisonRunnable; + public class MineResetAsyncResubmitTask implements PrisonRunnable { diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineResetAsyncTask.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineResetAsyncTask.java index bdb0c88bb..85f24788e 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineResetAsyncTask.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineResetAsyncTask.java @@ -1,5 +1,7 @@ package tech.mcprison.prison.mines.data; +import tech.mcprison.prison.tasks.PrisonRunnable; + public class MineResetAsyncTask implements PrisonRunnable { diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineScheduler.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineScheduler.java index 67a67276b..416e6e7c2 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineScheduler.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineScheduler.java @@ -1,15 +1,22 @@ package tech.mcprison.prison.mines.data; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.Random; import java.util.Stack; import tech.mcprison.prison.Prison; +import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.internal.World; import tech.mcprison.prison.mines.PrisonMines; +import tech.mcprison.prison.mines.features.MineBlockEvent; +import tech.mcprison.prison.mines.features.MineBlockEvent.BlockEventType; import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.tasks.PrisonRunnable; +import tech.mcprison.prison.tasks.PrisonTaskSubmitter; public abstract class MineScheduler extends MineReset @@ -394,7 +401,7 @@ private void submitTask() { // Submit currentJob using delay in the job. Must be a one time run, no repeats. - int taskId = Prison.get().getPlatform().getScheduler().runTaskLater(this, ticksToWait); + int taskId = PrisonTaskSubmitter.runTaskLater(this, ticksToWait); setTaskId( taskId ); } else { Output.get().logError("Mine " + getName() + @@ -415,16 +422,16 @@ public void terminateJob() { int taskId = getTaskId(); - Prison.get().getPlatform().getScheduler().cancelTask( taskId ); + PrisonTaskSubmitter.cancelTask( taskId ); } - public void submit( int offset ) { - submitNextAction(offset); + public void submit( double offsetSeconds ) { + submitNextAction(offsetSeconds); } private void submitNextAction() { submitNextAction(0); } - private void submitNextAction(int offset) { + private void submitNextAction(double offsetSeconds) { if ( getJobStack().size() == 0 ) { resetJobStack(); } @@ -432,8 +439,8 @@ private void submitNextAction(int offset) { setCurrentJob( getJobStack().pop() ); // Offset tries to stagger the mine resets, assuming most will have the same delays: - if ( offset > 0 ) { - getCurrentJob().setDelayActionSec( getCurrentJob().getDelayActionSec() + offset ); + if ( offsetSeconds > 0 ) { + getCurrentJob().setDelayActionSec( getCurrentJob().getDelayActionSec() + offsetSeconds ); } // Submit currentJob using delay in the job. Must be a one time run, no repeats. @@ -453,16 +460,103 @@ public void manualReset() { } + /** + *
This function checks if the block break event should execute a + * given command or not. If it needs to, then it will submit them to run as + * a task instead of running them in this thread. + *
+ * + * @param blockCount + * @param player + */ + public void processBlockBreakEventCommands( int blockCount, Player player, BlockEventType eventType ) { + + if ( getBlockEvents().size() > 0 ) { + Random random = new Random(); + + for ( int i = 0; i < blockCount; i ++ ) { + double chance = random.nextDouble() * 100; + + for ( MineBlockEvent blockEvent : getBlockEvents() ) { + + processBlockEventDetails( player, eventType, chance, blockEvent ); + } + + } + } + } + + private void processBlockEventDetails( Player player, BlockEventType eventType, double chance, MineBlockEvent blockEvent ) + { + if ( blockEvent.getEventType() == BlockEventType.eventTypeAll || + blockEvent.getEventType() == eventType ) { + + // If perms are set, check them, otherwise ignore perm check: + String perms = blockEvent.getPermission(); + if ( perms != null && perms.trim().length() > 0 && player.hasPermission( perms ) || + perms == null || + perms.trim().length() == 0 + ) { + + if ( chance <= blockEvent.getChance() ) { + + String formatted = blockEvent.getCommand(). + replace("{player}", player.getName()) + .replace("{player_uid}", player.getUUID().toString()); + + // Split multiple commands in to a List of indivual tasks: + ListThis is an internal function that builds this object as a String so it can be saved and + * restored. The format it generates is edge-colon-value and if there are more than one, then + * it will insert a comma with no spaces. + *
+ * + * @param sb + * @param edge + * @param value + */ + private void addSaveString( StringBuilder sb, Edges edge, String value, + boolean forced, + String color1, String color2 ) { + if ( value != null && value.trim().length() > 0 ) { + if ( sb.length() > 0 ) { + sb.append( "," ); + } + + sb.append( color1 ).append( edge.name() ).append( ":" ) + .append( color2 ).append( value ); + if ( forced ) { + sb.append( ":" ).append( color2 ).append( "forced" ); + } + } + } + + public static MineLinerData fromSaveString( String savedLiner ) { + MineLinerData results = new MineLinerData(); + + if ( savedLiner != null && savedLiner.trim().length() > 0 ) { + + String[] surfaces = savedLiner.split( "," ); + + for ( String surface : surfaces ) { + if ( surface != null && surface.indexOf( ':' ) != -1 ) { + String[] edgePatternName = surface.split( ":" ); + Edges edge = Edges.fromString( edgePatternName[0] ); + String pattern = edgePatternName[1]; + boolean forced = edgePatternName.length > 2 && + "forced".equalsIgnoreCase( edgePatternName[2] ); + + results.setLiner( edge, pattern, forced ); + } + } + } + + return results; + } + + private void setLiner( Edges edge, String pattern, boolean forced ) { + switch ( edge ) + { + case north: + setNorth( pattern ); + setForceNorth( forced ); + break; + + case east: + setEast( pattern ); + setForceEast( forced ); + break; + + case south: + setSouth( pattern ); + setForceSouth( forced ); + break; + + case west: + setWest( pattern ); + setForceWest( forced ); + break; + + case walls: + setWalls( pattern ); + setForceWalls( forced ); + break; + + case top: + setTop( pattern ); + setForceTop( forced ); + break; + + case bottom: + setBottom( pattern ); + setForceBottom( forced ); + break; + + default: + break; + } + } + + + + public void setLiner( Edges edge, LinerPatterns linerPattern, boolean isForced ) { + + setLiner( edge, linerPattern.name(), isForced ); + } + + public boolean hasEdge( Edges edge ) { + + return getEdge( edge ) != null; + } + + public String getEdge( Edges edge ) { + String results = null; + + switch ( edge ) + { + case north: + results = getNorth() != null ? getNorth() : getWalls(); + break; + + case east: + results = getEast() != null ? getEast() : getWalls(); + break; + + case south: + results = getSouth() != null ? getSouth() : getWalls(); + break; + + case west: + results = getWest() != null ? getWest() : getWalls(); + break; + + case walls: + results = getWalls(); + break; + + case top: + results = getTop(); + break; + + case bottom: + results = getBottom(); + break; + + default: + break; + } + + return results; + } + + public boolean getForce( Edges edge ) { + boolean results = false; + + switch ( edge ) + { + case north: + results = isForceNorth() || isForceWalls(); + break; + + case east: + results = isForceEast() || isForceWalls(); + break; + + case south: + results = isForceSouth() || isForceWalls(); + break; + + case west: + results = isForceWest() || isForceWalls(); + break; + + case walls: + results = isForceWalls(); + break; + + case top: + results = isForceTop(); + break; + + case bottom: + results = isForceBottom(); + break; + + default: + break; + } + return results; + } + + public String getNorth() { + return north; + } + public void setNorth( String north ) { + this.north = north; + } + + public String getEast() { + return east; + } + public void setEast( String east ) { + this.east = east; + } + + public String getSouth() { + return south; + } + public void setSouth( String south ) { + this.south = south; + } + + public String getWest() { + return west; + } + public void setWest( String west ) { + this.west = west; + } + + public String getWalls() { + return walls; + } + public void setWalls( String walls ) { + this.walls = walls; + } + + public String getTop() { + return top; + } + public void setTop( String top ) { + this.top = top; + } + + public String getBottom() { + return bottom; + } + public void setBottom( String bottom ) { + this.bottom = bottom; + } + + public boolean isForceNorth() { + return forceNorth; + } + public void setForceNorth( boolean forceNorth ) { + this.forceNorth = forceNorth; + } + + public boolean isForceEast() { + return forceEast; + } + public void setForceEast( boolean forceEast ) { + this.forceEast = forceEast; + } + + public boolean isForceSouth() { + return forceSouth; + } + public void setForceSouth( boolean forceSouth ) { + this.forceSouth = forceSouth; + } + + public boolean isForceWest() { + return forceWest; + } + public void setForceWest( boolean forceWest ) { + this.forceWest = forceWest; + } + + public boolean isForceWalls() { + return forceWalls; + } + public void setForceWalls( boolean forceWalls ) { + this.forceWalls = forceWalls; + } + + public boolean isForceTop() { + return forceTop; + } + public void setForceTop( boolean forceTop ) { + this.forceTop = forceTop; + } + + public boolean isForceBottom() { + return forceBottom; + } + public void setForceBottom( boolean forceBottom ) { + this.forceBottom = forceBottom; + } + + + +} diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineMover.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineMover.java similarity index 81% rename from prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineMover.java rename to prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineMover.java index 10898d3e3..d5dcee4b5 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineMover.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineMover.java @@ -1,6 +1,7 @@ -package tech.mcprison.prison.mines.data; +package tech.mcprison.prison.mines.features; -import tech.mcprison.prison.mines.data.MineLinerBuilder.LinerPatterns; +import tech.mcprison.prison.mines.data.Mine; +import tech.mcprison.prison.mines.features.MineLinerBuilder.LinerPatterns; import tech.mcprison.prison.util.Bounds; import tech.mcprison.prison.util.Bounds.Edges; diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineTargetBlock.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineTargetBlock.java similarity index 83% rename from prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineTargetBlock.java rename to prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineTargetBlock.java index 6753b79c5..3ced612c5 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineTargetBlock.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineTargetBlock.java @@ -1,4 +1,4 @@ -package tech.mcprison.prison.mines.data; +package tech.mcprison.prison.mines.features; import tech.mcprison.prison.util.BlockType; @@ -8,10 +8,14 @@ public class MineTargetBlock private BlockType blockType; - public MineTargetBlock( BlockType blockType, int x, int y, int z ) { - super(); + protected MineTargetBlock( int x, int y, int z ) { this.blockKey = new MineTargetBlockKey( x, y, z ); + } + + public MineTargetBlock( BlockType blockType, int x, int y, int z ) { + this( x, y, z ); + this.blockType = blockType; } diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineTargetBlockKey.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineTargetBlockKey.java similarity index 93% rename from prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineTargetBlockKey.java rename to prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineTargetBlockKey.java index 2c55e1308..12b1e76be 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineTargetBlockKey.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineTargetBlockKey.java @@ -1,4 +1,4 @@ -package tech.mcprison.prison.mines.data; +package tech.mcprison.prison.mines.features; public class MineTargetBlockKey implements Comparable