diff --git a/build.gradle b/build.gradle index 70bb842b1..fd832ddc4 100644 --- a/build.gradle +++ b/build.gradle @@ -20,6 +20,9 @@ import java.util.Date apply plugin: 'java' +compileJava.options.encoding = 'UTF-8' +compileTestJava.options.encoding = "UTF-8" + ext.targetArchiveClassifier = 'Java1.8' //ext.targetArchiveClassifier = 'Java16' @@ -91,7 +94,7 @@ buildscript { } dependencies { - classpath 'com.github.jengelman.gradle.plugins:shadow:5.2.0' + classpath 'com.github.jengelman.gradle.plugins:shadow:6.1.0' } } diff --git a/docs/changelog_v3.2.x.md b/docs/changelog_v3.2.x.md index bdadad408..f2ec3d3a3 100644 --- a/docs/changelog_v3.2.x.md +++ b/docs/changelog_v3.2.x.md @@ -21,6 +21,9 @@ is going on in each build so you have a better idea if it may be something that you need. +## NOTE: +* **A big amount of changelogs for 3.2.x version are listed under [changelog_v3.3.x.md](changelog_v3.3.x.md), this's + because of an early release of 3.3.x, then lately renamed back to 3.2.x, sorry for the confusion but just to know, newer changelogs are there.** diff --git a/docs/changelog_v3.3.x.md b/docs/changelog_v3.3.x.md index f7bef1eb4..a76b3b826 100644 --- a/docs/changelog_v3.3.x.md +++ b/docs/changelog_v3.3.x.md @@ -4,15 +4,7 @@ ## Build logs - **[v3.3.0-alpha - Current](changelog_v3.3.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)   -[v3.2.3 - 2020-12-25](prison_changelog_v3.2.3.md)   -[v3.2.4 - 2021-03-01](prison_changelog_v3.2.4.md)   -[v3.2.5 - 2021-04-01](prison_changelog_v3.2.5.md)   -[v3.2.6 - 2021-04-11](prison_changelog_v3.2.6.md)   -[v3.2.7 - 2021-05-02](prison_changelog_v3.2.7.md)   -[v3.2.8 - 2021-06-17](prison_changelog_v3.2.8.md) + - [v3.2.0 through v3.2.10](prison_changelogs.md) These build logs represent the work that has been going on within prison. @@ -21,11 +13,953 @@ These build logs represent the work that has been going on within prison. *Will continue as v3.3.0-alpha.7 2021-06-?? in the near future.* -# v3.2.3-alpha.0 2021-07-03 +# v3.2.10 2021-08-22 +* **Prison Release v3.2.10** +* **Updated to the support of the Prison's ExplosiveBlockBreakEvent. There were a few adjustments that were needed.** + + +* **Some blocks within the liners are not compatible with all versions of bukkit/spigot/minecraft.** +Added minimal versions to the patterns so as to help prevent the use of the wrong patterns for the server version. + + +* **Found an error with two Mine Liners that had pillar_quartz_block instead of quartz_pillar.** + + +* **Added support for Prison's own ExplosiveBlockBreakEvent.** +This will be used for Prison's up coming Prison Bombs. Also this can be used by other plugins too. + + +* **Update the PrisonEnchants code for handing their PEExplosionEvent object.** + + +* **Fix a problem with NPE when getting the player's Locale when it wasn't set.** + + +* **More adjustments to the /ranks list to add information about the player's current multipliers on all the ladders.** +This makes it easier to understand why the rank multiplier is a specific value. + + +* **Some adjustments to `/ranks list` to remove "admin stuff" from the list for non-admins.** + + +* **v3.2.10-alpha.14b 2021-08-22** + + +* **Removed the option to delete a rank from the ranks info command since it should not be that easy to remove a rank, which could easily be clicked on in game.** +Also commented out dead code. + + +* **Hook up the process to have all unjoined players added to prison by giving them the default rank.** +This is also ran now at the end of the /ranks autoConfigure to ensure all players are hooked up as soon as the default ladder and it's ranks exists. + + +* **Player join bug: Fixed a bug... if a player is not on the default ladder, then this was preventing them from being added.** + + +* **Added virtual checks to prevent placeholders from trying to access mine features that do not exist.** + + +* **v3.2.10-alpha.14 2021-08-21** + + +* **reduce what is shown on /rank if for non-op players.** + + +* **Decrease the autoConfigure's prestige costs from 2 B to just 1 B.** + + +* **Reload auto features after running ranks autoconfigure to enable the auto pickup.** +It wasn't working right after generating the mines. + + +* **Fixed an issue with virtual mines not being included in /mines list all command.** + + +* **Now `/ranks autoConfigure` creates 10 prestiges ranks. ** + + +* **Have placeholders reload after mines or ranks are created, removed, or renamed.** +Create mine and create rank now has an option to suppress updating placeholders since commands like autoConfigure will cause tons of messages to be generated. The placeholders are regenerated after all mines and ranks are created. + + +* **Command '/mines set area' fixed confirmation to use yes or confirm.** +Added the ability to set size when using feet. The size is what is used with the '/mines set size' command. So 20 width is really 41 since it's adding 40 blocks in all directions. + + + +* **Redesign the /mines info command to reduce and compact the listing.** +`/mines info ` is the reduced listing where disabled features are not shown. `/mines info all` is the expanded listing that includes more details. +Reworked the block list to use the String.format for spacing instead of manual adjustments. + + +* **v3.2.10-alpha.13 2021-08-20** + + +* **Fixed an issue with null for the playerUuid..** +it's rare, but it could be null. This prevents the failures. + + +* **Fixed a few issues with ranks, a NPEs.** + + +* **The text for ladder info was changed to remove player's name, which does not make sense to include, especially if ran from console.** + + +* **Yet another situation where CMI needed prison to start with a delay; confirmed setting is correct.** +It was confirmed for the second time that 'Economy_CMI' works so I moved that to the 'vault-economy-name:' setting. + + +* **Fixes a bug when checking offline players which was returning a null with rPlayer.getRank(). Was fixed.** + + +* **Ranks autoConfigure: Add to the prestiges ladder the base rank cost multiplier of 10 percent.** +Provide a few messages to document it when the /ranks autoConfigure command is ran. + + +* **For the /ranks autoConfigure command, setup an alias to /prison autoConfigure.** + + +* **Setup a task that is to be ran whenever there is a rank change within a ladder, or if the ladder has the base rank cost multiplier changed.** +This helps to ensure that the rank costs are correct for all players. + + +* **Renamed the command `/ranks remove rank` to `/ranks removeRank` since the prior command was a single command within it's own sub-group.** +This change will now list the command with the others when using `/ranks`. It was "lost" and "hidden" and admins were not able to find it that easily. + + +* **Changed the /ranks ladder delete command to prevent a ladder from being deleted if it has any ranks associated with it.** +To delete a ladder with ranks would corrupt the ranks. The ranks would have to be removed first to ensure no players are on the ranks. + + +* **After a change in a player's rank, have the player's Rank Cost Multipliers recalculated.** + + +* **The command /ranks player perms was generating an error with offline players so this fixes that issue.** + + +* **Changed config.yml to enable and disable prestige confirmations.** +Updated the GUI to support this. Settings where changed and config.yml may need to be reset when updating prison to use these new features. + + +* **Fixed bug with `/ranks ladder moveRank`.** +It was not removing the rank from the source ladder, but was also adding it to the destination ladder. This was fixed and is now working correctly. + + +* **Removed the remainder of the ladder/rank permissions that were never used.** + + +* **Start to setup MineBombs basics.** + + +* **Add to the World object, a function to set the block.** +The SpigotWorld class uses prison's compatibility functions to perform this action. + + +* **v3.2.10-alpha.12 2021-08-16** +Released alpha.12 + + +* **Updates to fix the prestige issues.** +Moved more of the processing in to the PlayerRank object to reduce issues. Shutdown one of the constructors since it could lead to the wrong amounts. +Prestige was fixed by rewriting the way the rankup handled the ranks and playerRanks. + + +* **Fixed an issue with logging when using a debug target mode.** +It was not logging when the global debug was off. + + +* **Added some rankup debug logging details.** +Enable with `/prison debug rankup`. + + +* **v3.2.10-alpha.11 2021-08-15** +Bump the version + + +* **Changed the /ranks info to show the ranks multiplier information.** + + +* **Work on /ranks list to improve the content to better present the rank cost multiplier.** + + +* **General changes to code that uses getRank() that returns a PlayerData object... ** +Since that is a player's instance of a rank, this may be null for a lot of players. A lot of the old code would not take in to consideration that there may be no value, so hence the NPEs that we've been seeing. This should address a lot of the potential issues. + + +* **Found situations where players are not on a ladder and its causing issues.** +Need to expand to other code... + + +* **Bump to v3.2.10-alpha.10f.** +Will be trying to release a more formal alpha later today. + + +* **Fixed a typo in the name of a function. Prevent a possible NPE. Revised how one of the PlayerRank constructors works so it will actually calculate the correct multiplier.** + + +* **v3.2.10-alpha.10e 2021-08-13** + + +* **More adjustments to rankups and PlayerRanks.** I think I've addressed all issues with ranks. + + +* **Remove three redundant ladder commands dealing with ranks: listranks, addrank, and delrank.** + + +* **There was a report that the mine would continue to reset after it was deleted.** +Cleaned up a few things and added a boolean field to indicate it's delete. If its set to deleted, then it will prevent the resets from happening. Just as a safety check. Not 100% sure that this was actually an issue. + + +* **Setup the AsyncPlayerChatEvent listener within Prison to be able to dynamically set the priority based upon a new setting in the config.yml file.** + + +* **Bug fixes: Fixed some issues with the use of the new PlayerRank object.** +They were not always not-null, and there were some instances of the wrong variable being used. + + +* **Fixed an issue with the regular expression block quote... didn't need the second backslash.** + + +* **Bug fix: Fixed a few issues with PlayerRank object not being set correctly everywhere.** +Was also checking the wrong object for null. These fix about 3 different NPEs. + + +* **Removal of the obsolete ranks related permissions and permission groups.** +This was a failed attempt to automate the user of permissions with ranks. This did not work, since vault does not support the creation of permission groups, plus a few other issues and limitations with vault. + + +* **Initial setup of ladder rank cost multipliers.** +All ladders a player has, will contribute to the total rank cost multiplier value, and all ranks for that player will have their cost adjusted. +Overall this will allow an increasing rank cost as players rankup on the prestige ladder, and/or it can help reduce rank costs if donor ranks provide a negative adjustment. +Currently there is no way to set the ladder's multiplier... that's next. But everything else is hooked up and should be functional. + + +* **v3.2.10-alpha.10 2021-08-11** + + +* **Added a missing ranks message: when removing a player from a rank and it fails.** + + +* **LocalManager.getLocale: Fixed an issue with player being null when the player object originated from a task processing offline players.** + + +* **Added the event level MONITOR and changed the event listeners to only register the MONITOR event when the config is set to MONITOR.** + + +* **Updates to the JumboTextFont by adding most of the lowercase characters.** + + +* **Alter the use of accessing the player to help eliminate the risk of concurrent modification events.** + + +* **Added a spigot module en_US.properties language file.** + + +* **Added a new function to the PrisonEventManager to return the list of event listeners as a string so they can be logged to the console, or through helpch.at which is not yet hooked up.** + + +* **Added JumboTextFonts to prison support submit ranks.** +Fixed a few issues and added more characters to the fonts. Added /ranks info all to the ranks output for more detailed information. + + +* **Found and fixed an obscure bug with regular expression quotes.** +It was duplicating text and making the results much larger than what they should have been. + + +* **Created a JumboTextFont to be included in the prison support submit documents.** +Hooked up to mines. This will make it easier to identify the various mines in the listings. + + +* **Add the capture and display of all support submit URLs in each additional submission.** + + +* **Expand '/prison support submit mines' details by including the '/mines info all' command.** +Had to redesign some of the mine commands to be able to capture all of those details. Added a table of contents to the submission so it's clear all these details are included, since it could be a HUGE file. + + +* **Added 6 new placeholders to provide the whole line for the prison_top_mine_block_ plus the heading and total line.** + + +* **Placeholders with _nnn_ numeric ranges: Fixes a potential problem of where it was unable to match a placeholder if placeholder escape characters were not used.** +Now it will properly identify and match the series. + + +* **Fixed a problem with block constrains, the min number of blocks, when no blocks were initially added to the mine.** +When revisiting to ensure the min amount is set, it did not have the correct values set for the ranges. +This has been fixed by adding a low and high limit field that not does record the actual block positions of this block type, but of the limits as defined by the constraints. This allows adding more blocks to reach the min amount, when no block has been added before. + + +* **Prevent the use of % in the ranks and ladder commands.** +Could not use them before, but they would cause errors when messaging details about the commands. Now the command will be rejected and it will have to be submitted correctly. + + +* **ButtonLore Utility got a couple of new methods.** + + +* **Some GUIs were still using the old deprecated buttons. This got fixed.** + + +* **All GUIs got a new common lore Format.** + + +* **All GUIs now use ButtonLore utility and lore format.** + + +* **Fixed an issue with spigot 1.17.1 where they appear to be extending the BlockBreakEvent for FurnaceExtractEvent but not isolating the listeners.** +Forced to check to ensure the event is actually a BlockBreakEvent to ensure the correct event is really being fired correctly. + + +* **Added prison's version to the chat display's title.** +is will help support since it wil help show us what version someone is using. + + +* **Added the recording of earnings per mine.** +The add earnings must be called within the time limit as defined by the session timeout for mining, which is currently 15 seconds. +If something is sold outside of that session timeout, then it will not be attributed to the mine. + + +* **Minor design changes to the main GUI /gui**: to apply them you should reset (delete it) your en_US.yml at this path -> + Prison/module_conf/lang/en_US.yml. More changes will come in the future. + + +* **ButtonLore is quite ready and already in use for the /gui main GUI, only the first page uses it.** + + +* **Started working on a new ButtonLore Utility that will be included in the SpigotGUI Utility.** + + +* **v3.2.10-alpha.9 2021-08-04** +Released... +Upgraded gradle to use v6.1.0 of Jengleman's ShadowJar... was v5.2.0. + + +* **Modify the block break events to merge most of the preliminary processing from all of the different kind of block events.** +This enables a single function to be able to handle most of the initial setup processes for all of the different block break events. This will reduce the amount of code, eliminate possible errors, and make it a lot easier to enable more events to be processed. + + +* **Add the option for using '*all*' for mine name for adding block events, which will add the event to all mines.** + + +* **All GUIs now use PrisonGUI Utility, finally it should be done now.** + + +* **2 more autofeatures GUIs now use PrisonGUI Utility.** + + +* **All SellAll GUIs now use PrisonGUI Utility.** + + +* **All Mines GUIs now use PrisonGUI Utility.** + + +* **Disabled some old Block model code in use for GUIs.** + + +* **Mines Blocks List GUI now uses PrisonGUI utility.** + + +* **Fixed Mines Blocks List GUI (the one that shows the blocks currently in the mine).** The GUI wasn't translating +correctly blocks, and showing a "barrier" instead of the block, the GUI was working anyway, just + not good looking, now it's fixed for newer versions. + + +* **Mines Reset Time GUI now uses PrisonGUI utility.** + + +* **Mines Set Notification Mode GUI now uses PrisonGUI utility.** + + +* **Mines Notification Radius GUI now uses PrisonGUI utility.** + + +* **Mines Blocks Set Percentage GUI now uses PrisonGUI utility.** + + +* **Updated Buttons PrisonGUI Utility to support enchantments.** + + +* **For the fortune calculations, converted the use of the old block model over to use XMaterial instead.** +Updated to include the newest 1.17 blocks too. + + +* **Updated smelting to use the newer 1.17 blocks, such as all of the deepslate variations, and the raw iron, raw copper, and raw gold.** +Updated all code that had these variations. + + +* **Updated the XP calculations to include the newer blocks from 1.17** + + +* **Upgrade XSeries from v8.2.0 to v8.3.0** + + +* **Remove the dump of block break events from the command /prison version all since it was appearing first.** +It will need to be rewritten to capture in a list of strings. + + +* **Added mining time by Mine.** +This will also track in which mine, players are mining. + + +* **Found a bug in the TokenEnchant event listener class.** +It was casting to the wrong class for the Monitor event. + + +* **Fixed an issue with PlayerCache and mining duration.** +Also added logging if unable to rename a temp file. + + +* **Added support for jumbo and full ladder types with the mine liners.** + + +* **Update the custom ladder type feature in mine liners.** +Now you can select none, normal, and wide. + + +* **Provide break the list of placeholders down by placeholder types, along with sub total counts.** +Also added total count at the top of the list. Breaking down the large list in to sub-types will make it easier to read the list. + + +* **Provided a way to specify a last next rank message for the placeholder:** +prison_rankup_rank_tag_default +This will only apply on the default ladder and when the next rank tag is empty. + + +* **Started to look in to providing the ability to import player ranks** based upon perms, but ran in to an issue that if the player is not online, then it can be very difficult to get their actual perms. Would not be able to get a listing of all perms, as if they were online, so it would make this less flexible. +This has been canned because the person who was needing it, is no longer needing it. May revisit in the future. + + +* **About 56 new placeholders!** SpigotPlayerUtil has been updated to provide support for all of the functionality that it needs. It's been hooked up to the placeholders so they should be functional. + + +* **Setup the Platform to be able to provide a SpigotPlayerUtil object.** +This is needed for placeholder support and a few other things. + + +* **There was a concurrent modification exception on the line with** `playerData.setDirty( false );`. +These changes will not prevent that issue, but it will trap it so it does not register in the log files. If this happens, then the player's cache will be saved on the next attempt. This should be a rare event. +The changes needed are more complex that this simple "fix" and will be made in the near future. + + +* **Prison Mines Blocks Set Percentage GUI now uses PrisonGUI Utility.** + + +* **Prison Mine Blocks List GUI now uses PrisonGUI Utility.** + + +* **Prison Blocks List GUI now uses PrisonGUI Utility.** + + +* **Fixed some errors of the Prison Mines Blocks Set Percentage GUI:** There were some ArrayOutOfBonds exceptions. + + +* **Auto Features: Added food exhaustion calculations.** +Now on each block break, Configurable to be disabled. For explosions events, only applies to the one block they actually mined. + + +* **For various add commands, the messages for the 'placeholders' was being sent to the console instead of the player issuing the command. This was an issue in game, but not the console.** + + +* **Placeholders durability: add support for a percentage and bars.** + + +* **3 new Backpacks GUIs for admins now use PrisonGUI Utility.** + + +* **Bug fixes with the setup of token enchant event listeners.** + + +* **Added many more features to SpigotPlayerUtil and getting ready for the new placeholders.** + + +* **Started to add a PlayerUtil and SpigotPlayerUtil to prison.** +This will allow an easier access to specific player values in other parts of prison with just a single call to a util function. This will be used with a number of new placeholders. + + +* **Removal of a function from the prison Player object that is no longer being used.** + + +* **A couple of updates for CMI economy.** +Added a note on what value to try first for cmi with prison. + + +* **Changed some logging information from debug to info so it will be registered when requested by the admin.** + + +* **PrisonEnchants changed the class name of their event.** +This updates prison's code and changes the api jar file. + + +* **Created a new group within auto features for durability related items and created a new group autoManager just for the isAutoManagerEnabled to get it out of the options.general grouping since that is the main "switch" and it is getting lost in the configs.** +There was too many for the general group, and they were not being kept together, especially since we have a comment now. + + +* **Backpacks admin GUI now uses PrisonGUI Utility.** + + +* **v3.2.10-alpha.8 2021-07-25** + + +* **Auto features: Removed unused classes and cleaned up a few things. Fixed a reference to one of the deleted classes.** + + +* **Auto features events: Added an abstract class to manage the unregisterListeners in one place, to eliminate duplication of code.** + + +* **For the command /prison reload autoFeatures hooked it up to include unregistering all of the event listeners that auto features setup, then it uses the configurations to reregister them all.** + + +* **Fixes a major problem with how Zenchantments works because the plugin extends the BlockBreakEvent with their BlockShredEvent.** +It has issues.. but... this ensures that the correct event is being trapped. + + +* **Change to player cache field that was not so clear with it's name.** +It's supposed to be the config field name, but the description did not reflect that. + + +* **Fixed GuiUtility button add lore method:** The method to add a line to an already existing button got now fixed. + + +* **Adjustments to get the new event listeners working fully. Still need to hook them up to the reloading.** + + +* **Next step in rewriting how the event listeners are setup...** + + +* **Move the event listener managers in to a common package to prepare to extend them to the non-auto features event listeners.** + + +* **Rewriting how the event listeners are being registered.** +Added ability to unregister. This is working, but is only for the auto pickups. WIll need more work to hook up to the non-auto manager. + + +* **Setup the ability to log more than just the BlockBreakEvent.** +It it mow able to log details to Lists so they can be included in other output, such as support submits. + + +* **Rewrote how the event listener is registered so the priority is dynamic.** +This appears to be working well. + + +* **clean up some of the /prison version all commands to better reflect the actual details with dependencies with the settings for auto features.** +This should help better convey what the settings are doing, especially when a setting disables another setting. This should help reduce support issues. + + +* **Prestige confirming fix:** Fixing Prestige confirm by chat or GUI when possible. + + +* **v3.2.10-alpha.7 2021-07-23** + + + +* **Fixed the way some of the autofeature block settings were named.** +They had "autoBlock" when auto has nothing to do with it anymore, since those setting will be applied for normal drops too. +Fixed an issue with auto smelt and auto block where it was not using the config settings, so now it's working correctly. +Added more debugInfo messages to better understand what's going on when something is not working correctly. + + +* **Added a note on how fortune works... it's been confusing...** + + +* **Updates to the liner to allow the use of '*all*' for the mine name to apply the same pattern to all mines.** +For auto configure, ensure that the random liner applied to the mines is not remove, removeAll, or repair. + + +* **Prevent slime fun from registering if it is disabled.** + + +* **Fixed a problem with the registration of the events failed due to the parameter of ExplosiveEvent.** +Had to set it to Object to allow it to be registered when the plugin and class does not exist on the server. + + +* **Added more internal debug details.** + + +* **Mine liners: Added glowstone and also added the ability to apply a liner change, or removal, from all mines with one command by using `*all*` for the mine name.** + + +* **Add the debugInfo to more functions and a few more messages.** + + +* **Changed the debugInfo variable to a StringBuilder instead of just a String.** +This will provide a little bit of a performance improvement, plus it can then be passed in to the functions to gather more information. + + +* **A few minor adjustments to better identify the function that is running when logging the debug information on BlockBreaks.** +Tweaks to the PrisonEnchant's plugin code. Missed a few changes. + + +* **Changed some of the DebugTarget names to better reflect where in the project they are occurring.** + + +* **Bug Fix: If a message is removed, such that there is nothing left of the = character in the language properties files, it will now not throw an index out of bounds exception.** +Removal of the message was not expected and there was unable to handle that situation. + + +* **Added support for 4 new types of placeholders that uses the PlayerCache:** +Player's total block count. And player's count per mine. + + +* **Issue with using offline players with the playerCache.** +The playerCache should typically only contain active players, but in testing, like using /prison placeholders search, it may add an offline player to get placeholder data from them. +This prevents null issues with the locations, and eliminates the excessive error message when trying to use getLocation() on an offline player. + + +* **PlayerCache changes: Start to take in to consideration that a player within the cache may be offline.** +If that's the case, then prevent some calculations, and remove them from the cache. Offline players would be added to look up some stats, but then they would be safe to purge. +When checking the timerTasks, add an earnings of zero to purge past earnings. This will prevent the average earnings from staying there forever when the player stops mining. + + +* **Added a debug logging entry for XP Calculations.** +This will be able to provide detail infomation on if it's working and what the results are. + + +* **Add support for PrisonEnchants' ExplosiveEvent.** +While adding support for the ExplosiveEvent, found a few issues and fixed them. Some changes were just in names of functions, others were functional, such as improving the support of unbreakable and blocks that fall outside of a mine. + + +* **Simplified how the title, subtitle, and actionBar are setup with the /prison utils titles title command. ** + + +* **New Feature: Prison now tracks average earnings per minute.** +If you have auto sell enabled (sell upon each block break, see autoFeaturesConfig.yml) then prison will be able to report your average earnings over the last 5 minutes of mining activity. +`prison_player_balance_earnings_per_minute` prison_pb_epm +`prison_player_balance_earnings_per_minute_formatted` prison_pb_epmf + + +* **Rewrite how the player uses title, subtitle, and actionBar for the /prison utils titles command.** +Spigot 1.8 does not support any of this. +Spigot 1.8.8 is when this was introduced. But 1.8.8 does not have actionBar, so instead it shows the message in the subtitle. +Spigot 1.9+ are able to display title, subtitle, and actionBar at the same time. + + +* **Release of v3.2.10-alpha.6 - 2021-07-19** + + + +* **Try to better handle situations where integrations fail when integrating.** +Now has the ability to disable the integration and remove it when it fails. + + +* **New feature: prison utils titles.** +This enables sending messages to the player's console as either a title, a subtitle, and/or actionBar. Can also clear, reset, or set the timings on the titles. +All three can be sent through the title by using a double colon to indicate the various parts. +For example: 'Hello Title!::Subtitle is Here!::I'm on an actionBar!' + + +* **Add feature to Auto Features to prevent tools from breaking or being used when durability is equal to or greater than maxDurability.** + + +* **Added some documentation to the ExplosiveBlockBreakEvent so users can better understand how it should be used.** + + +* **This is an example of an explosive block break event that should be used so prison can monitor for it, and consume it.** + + +* **More adjustments to the Taiwanese language files.** + + +* **More tweaks to player cache file saving... ** + + +* **PlayerCache adjustments for timing tracking. A work in progress.** + + +* **Updates to he Taiwanese language files.** + + +* **Improvements to adding new players to prison upon startup.** +This process scans bukkit's offline players and finds everyone who is not already setup in prison and adds them. +It now uses the /ranks set rank command now. + + +* **Added support for zh_TW Taiwanese.** +This is just an initial setup for now. To enable it, set the language in the config.yml file to zh_TW. + + +* **Player Cache: Hooked up block tracking for players.** +Appears to be working as far as tracking blocks that are being broke. It loads and unloads when a player joins and leaves the server so only active players have their data online. Performs periodical updates on saving. +This tracks total blocks, block counts by mine, and block counts by block type. +Starting to setup time tracking. + + +* **More changes to setting up a player cache.** +The basics should be represented, with startup and shutdown of the cache, running a periodical task to refresh the data, running a periodical task to save the data. +No data is processed as of yet, but the cache should be reactive to players logging on and off the server. + + +* **Initial work on setting up the Player Cache.** + + +* **Minor SellAll utility changes.** + + +* **SellAll Player Blocks List GUI now supports pages.** + + +* **Minor improvements for GUIs to improve performance.** + + +* **PrisonGUI Buttons utility minor changes.** + + +* **Add the ability to play sounds through the /prison utils sound command.** + + +* **Update docs... scale back what we support with WorldGuard regions since access by ranks solves so many problems.** + + +* **SellAll Admin Blocks List GUI now supports pages.** Note: This was **not** part of the v3.2.10-alpha.5 release. + + +* **SpigotGUIComponents minor changes.** Note: This was **not** part of the v3.2.10-alpha.5 release. + + +* **SellAll Blocks GUI now uses PrisonGUI Utility.** Note: This was **not** part of the v3.2.10-alpha.5 release. + + + +* **v3.2.10-alpha.5 2021-07-14** + + + +* **Made the RankLadder comparable and in the RankPlayer changed the map to a TreeMap.** +This should fix the inconsistencies that I was seeing earlier. + + +* **If a player is detected to be lacking a rank on the default ladder, it will adde the default rank.** +Ran in a problem where getting the current rank for a ladder was failing when it was ran, but worked when stepped through a debugger. + + +* **When checking for players not hooked up to prison, prison now ensures there is a default rank configured or it won't try to check the players.** +This change also checks players within prison to ensure they have a rank on the default ladder. + + +* **MineInfo GUI now uses PrisonGUI Utility.** + + +* **Removed unused imports from some GUI classes.** + + +* **MineInfo GUI TP Button now has an Arrow instead of a red_bed:** red_bed can't be translated to a legacy block in 1.8.8. + + +* **Fixed performance issues for MinesInfo GUI.** + + +* **Added information to the language files on how to use utf-8 text in these properties files.** + + +* **Setup prison to ensure all compliers within gradle is using utf-8.** + + +* **Enable loading utf-8 encoding from the properties files. Java 1.8 is unable load them as utf-8, so this provides a work around.** +At this point, this ensures that if a properties file contains utf-8 encoded text, that it can be packaged in the prison jar, extracted to the file system, then loaded and used and maintain full utf-8 encoding all the way until it hits bukkit. bukkit corrupts it and confirmed it was corrupted in spigot 1.8.8, 1.3.4, and 1.16.5 so its not an isolated issue for just one spigot version. + + +* **Updated cryptomorin's XSeries to v8.2.0.** + + +* **Convert the CommandHandler.getHelpMessage() to return a ChatDisplay object to allow the use of creating clickable URLs in the help messages.** +The help messages now has headers which shows the command that's being listed. +Updated the /mines blockEvent add command to include two docURLs to use as an example; improved the help message. + + +* **If a Ladder has a bad rank that is already in another ladder, that rank will not be added to the new ladder that is being loaded.** +An error message is already being logged, but this change will update the ladder to resave it without the duplicate rank. + + +* **Clean up Ranks a little more by removing more of the rank position and report failures if a rank is already loaded in another rank to prevent internal failures if a ladder save file is corrupted by manual editing.** + + +* **Removed the use of rank.getPosition() from all saved information within ranks and ladders.** +Position is no longer used to access any rank. It is only used to compare if one rank is higher or lower than another. It's lazy loaded only when it is needed the first time. If a rank is removed from a ladder, or inserted in to a ladder other than at the end, then all ranks in the ladder are set to -1 for the position so they recalculate when they are used the next time. + + +* **This fixes a user error situation, which is not a bug, in the listing of ranks.** +The user copied the contents of one ladder to another ladder, without deleting the source ladder. Thus there were two instances of a series of ranks, when there should ever be only one instance of a rank. A rank can be in at most one ladder, or no ladder. +The result of this issue is that when the second ladder was hookedup at prison's startup, it corrupted the ranks in the first ladder. +This works around such problems by changing /ranks list by using the list of ranks within the ladder, instead of using the rank's prior and next associations. +These changes also add the rankId to both the '/ranks list' and '/ranks ladder rankList' commands, and also '-' and '+' notations to indicate a rank is linked to a prior and next rank. + + +* **Simplify the command /mines blockEvent add by removing the permissions and taskMode from the add.** +This was causing too muchh confusion for a lot of people. It should help to keep the add much more basic. There have been alternative commands to modify those settings so it really isn't important to set them on the add. Also odds are they will not anything but the default values for these two fields. The defaults are perms = none and taskMode = sync. TaskMode is not defaulting to inline due to increased risk of lag and prison being falsely blamed for it. If desired, the admin can always change the taskMode to what they need. + + +* **Bug fix: Fixed an issue where the "on click" events were using the wrong row number.** +The row number was getting incremented at the wrong time. + + +* **v3.2.10-alpha.4 2021-07-10 ** + + +* **Few minor tweaks to the mines info command with formatting.** + + +* **Added player counts to the rank list command.** + + +* **Hooked up the /ranks list all command to the /prison support submit ranks command.** + + +* **Add option to /ranks list to include all ranks through the use of the "all" in place of the ladder name.** + + +* **Fixed a bug where getting a player was returning a null.** +When that null was encountered, it was not processing the placeholders, especially for the bars. +Not really sure why it was failing, but replaced the use of getting the player balance with the most recent use of RankPlayer's getBalance() works perfectly. + + +* **More adjustments on the /ranks list to prepare for listing all ladders.** +Also added a couple of more messages. + + +* **Added an error message if there is a failure when using /prison support submit.** +I assumed that other error messages would exist, but having doubts if it always will have other errors displayed. + + +* **Improvements to the /ranks list command.** +Enhanced the header so it's clear which ladder is involved. Also cleaned up the formatting with the tag colors so it does not impact the column alignments. Also doing a little more with injecting the "default" tag so it does not shift the columns. + + +* **Adds the listing of all mines to the /prison support submit mines command.** +This provides an overview of all mines and is included at the top of the listing. + + +* **Improve the layout of all of the mines with the command /mines list all.** + + +* **pasteChat update to keep the color codes.** It will only keep the color codes that start with &, and all others will be removed. + + +* **New feature: /prison reload locales. Its now possible to reload the language files that prison uses.** +Added a new debug item to test to see if utf-8 is working: /prison debug testLocale. No, it does not work with utf-8 text yet. +I did confirm that if the properties files are setup with UTF-8 and are a part of the prion jar, that the UTF-8 encoding will properly be saved to the local file system. +The area that I think is causing failures is with the Properties object itself since that is not utf-8 compatible, so it appears. + + +* **v3.2.10-alpha.3 2021-07-09** + + +* **reformat the /mines list command to mak it easier to read** + + +* **Added support for prison support submit for ranks and ladders, and also for mines.** +These two new commands will submit the raw json files. + + +* **New Feature!! Major support feature! Send all of prison's configs to paste.helpch.at so we can know exactly how servers are configured.** +This logs the following config files: config.yml plugin.yml autoFeaturesConfig.yml modules.yml module_conf/mines/config.json + SellAllConfig.yml GuiConfig.yml backpacks/backpacksconfig.yml + + +* **Added a success message when a player is added to prison's default rank.** + + +* **Fixed issue with a few placeholders that were not working.** +Was using the wrong translator so a number of mine related placeholders stopped working. +The mineplayers were not working too. The bug was introduced by hooking up STATSMINES. + + +* **Hooked up STATSRANKS placeholders and got rid of obsolete ones. Still more testing needed.** + + +* **Added a player check on prison startup that will add all offline players that are not hooked up to prison yet. Plus it will register name changes too.** + + +* **Added top rank balance placeholders: 6 for now and more will be added soon once these are fully working.** +These are based upon the player's balance within the rank. +Also added a Hesitancy Delay Penalty to help encourage players to rankup instead of trying to dominate a single rank. +These have not yet been tested. + + +* **Added RankPlayers to Ranks.** +This will allow quicker access to all players at each rank, which will help for top ranking reporting. + + +* **Clean up some rank and ladder function to eliminate the use of magic numbers: both rank ids and ladder ids.** +These were bad, since the objects were already linked together, so using these functions were just adding unneeded overhead. + + +* **v3.2.10-alpha.2 2021-07-06** + + +* **Added the ability to fail silently for the Localizable object to prevent the message ID from flooding certain messages.** +This will be employed in the Output.get() functions so if it cannot load the prefixes and level colors, then the message IDs will not be injected in to the messages. +This new feature should never be used without careful consideration since it is important to identify when messages fail so they can be fixed properly. + + +* **Adjustments to LocaleManager for updating the internal checks for if the external files need to be updated.** +Also finalize how Prison object works with the LocaleManager. + + +* **Removed obsolete placeholders that are not used anymore.** + + +* **Adjustments to when the LocalManager is started so it can be activated as soon as possible.** +This is because of the need for Output.get() to use externalized messages for it's prefixes and color codes. This does present some problems, but it actually works fine at runtime and also for junit tests too. + + +* **Setup a getConfigString in the Platform with a default value.** + + +* **New placeholders for mine block stats: Renamed percent to chance. Added prison_top_mine_block_remaining_bar_nnn_minename.** + + +* **Used the wrong numeric formatter... needed to be an integer.** + + +* **Added 10 new placeholders to provide stats on mine blocks.** +These use a series value in the placeholder to specify the specific block. The series number is not limited and can range from 1 through a large reasonable value. The number can be one or more digits, with or without a left padding zeros. + + +* **Renamed the field PrisonBlockStatusData.getResetBlockCount() to getBlockPlacedCount() to be more descriptive of what it actually is.** + + +* **Add the ability of a PlaceholderFlag to self identify as having a sequence.** +This will allow for automatic processing of these kind of placeholders without having to hard code for them. + + +* **Placeholders test: Fixed issue with player name being incorrect and also added player information if it is provided in the output.** + + +* **Fixed a typo that was made a long time ago. Placeholder has a capitol H in the name.** + + +* **Increased the number of rows displayed when using the placeholder search. It was showing six placeholders and I increased it to 10.** + + +* **Renamed the PlaceHolderFlags from PLAYERMINES to MINEPLAYERS which is more consistent in how it is being used.** + + +* **v3.2.10-alpha.1 2021-07-05** + + +* **Bug fix... when selling on each block break event, it needs to suppress the per-sale messages.** + + +* **Fix a few other issues with the new placeholders.** + + +* **Enhance the /ranks autoConfigure to work much better with existing mines and ranks when doing a force.** + + +* **New 18 new placeholders added to prison. Hooked up the following placeholders, but have not yet ran through testing yet.** +prison_rank_ladder_position (prison_rlp), prison_rank_ladder_position_laddername (prison_rlp_laddername), +prison_rank__ladder_position_rankname (prison_r_lp_rankname), prison_rank__player_cost_rankname (prison_r_pcst_rankname), +prison_rank__player_cost_formatted_rankname (prison_r_pcf_rankname), prison_rank__player_cost_remaining_rankname (prison_r_pcf_rankname), +prison_rank__player_cost_remaining_formatted_rankname (prison_r_pcf_rankname), prison_rank__player_cost_percent_rankname (prison_r_pcp_rankname), +prison_rank__player_cost_bar_rankname (prison_r_pcb_rankname) + + +* **Refactored ranks and RankLadders to eliminate old and inefficient ways to get the ranks and next ranks.** +These change will help improve the performance of processing the placeholders. +This also allows the elimination of a few functions that are now obsolete. + # v3.2.9 2021-07-03 diff --git a/docs/docs-commands/prison_docs_command_07_prison_reload.md b/docs/docs-commands/prison_docs_command_07_prison_reload.md index b04b1125c..17791009d 100644 --- a/docs/docs-commands/prison_docs_command_07_prison_reload.md +++ b/docs/docs-commands/prison_docs_command_07_prison_reload.md @@ -19,6 +19,8 @@ A couple of examples when you would need to use the reload command for placehold ## SubCommands: +- `/prison reload autofeatures` Reloads all of the auto features settings, including reregistering all of the event listeners that are related to block break events. +- `/prison reload locales` Reloads the language files. - `/prison reload placeholders` Regenerates all the placeholder mappings and reregisters them with the supported placeholder plugins. ## How to use the command diff --git a/docs/docs-commands/prison_docs_command_11_ranks.md b/docs/docs-commands/prison_docs_command_11_ranks.md index 44825ac57..cea65f6be 100644 --- a/docs/docs-commands/prison_docs_command_11_ranks.md +++ b/docs/docs-commands/prison_docs_command_11_ranks.md @@ -25,7 +25,7 @@ Main Prison Ranks command which will show all the subcommands to admins and open ## How to use the command -Execute the command himself to get a list of commands like in the example: `/ranks`. +Execute the command itself to get a list of commands like in the example: `/ranks`. This will also open a GUI to players showing a list of the ranks, you can enable or disable this in the config.yml. ### Command Format diff --git a/docs/docs-commands/prison_docs_command_12_ranks_command.md b/docs/docs-commands/prison_docs_command_12_ranks_command.md index 75a572b4d..3a88fee92 100644 --- a/docs/docs-commands/prison_docs_command_12_ranks_command.md +++ b/docs/docs-commands/prison_docs_command_12_ranks_command.md @@ -17,7 +17,7 @@ Add a command which will be executed when the player rankup to the rank with the ## How to use the command -Execute the command himself, and you'll get a list of the subcommands, like in the example: `/ranks command`. +Execute the command itself, and you'll get a list of the subcommands, like in the example: `/ranks command`. - `/ranks command add [rankName] [command]` will add a rankupCommand to a rank. - `/ranks command list [rankname]` will show a list of rankupCommands in a rank. - `/ranks command remove [rankName] [command]` will remove the rankupCommand from the rank. diff --git a/docs/docs-commands/prison_docs_command_13_ranks_create.md b/docs/docs-commands/prison_docs_command_13_ranks_create.md index 6eaca8997..e47162903 100644 --- a/docs/docs-commands/prison_docs_command_13_ranks_create.md +++ b/docs/docs-commands/prison_docs_command_13_ranks_create.md @@ -15,7 +15,7 @@ Create a rank. ## How to use the command -Execute the command himself following the format like in the example: +Execute the command itself following the format like in the example: - `/ranks create [rankName] [cost] [ladder] [tag]` - `/ranks create A 100 default &3[&1A&3]&f` diff --git a/docs/docs-commands/prison_docs_command_14_ranks_delete.md b/docs/docs-commands/prison_docs_command_14_ranks_delete.md index 6e425656c..3ed9c2a3d 100644 --- a/docs/docs-commands/prison_docs_command_14_ranks_delete.md +++ b/docs/docs-commands/prison_docs_command_14_ranks_delete.md @@ -15,7 +15,7 @@ Delete a rank. ## How to use the command -Execute the command himself like in the example to delete a rank: +Execute the command itself like in the example to delete a rank: - `/ranks delete [rankName]` - `/ranks delete A` diff --git a/docs/docs-commands/prison_docs_command_15_ranks_demote.md b/docs/docs-commands/prison_docs_command_15_ranks_demote.md index 4d4500786..855cda85d 100644 --- a/docs/docs-commands/prison_docs_command_15_ranks_demote.md +++ b/docs/docs-commands/prison_docs_command_15_ranks_demote.md @@ -15,7 +15,7 @@ Demote a player of a rank depending on the ladder you want. ## How to use the command -Execute the command himself following the format shown in the example to demote a player: +Execute the command itself following the format shown in the example to demote a player: - `/ranks demote [playerName] [ladder] [chargePlayers]` - `/ranks demote GABRYCA default` diff --git a/docs/docs-commands/prison_docs_command_17_ranks_ladder_info.md b/docs/docs-commands/prison_docs_command_17_ranks_ladder_info.md index f30d106be..dc1bb1852 100644 --- a/docs/docs-commands/prison_docs_command_17_ranks_ladder_info.md +++ b/docs/docs-commands/prison_docs_command_17_ranks_ladder_info.md @@ -11,22 +11,19 @@ Edit a rank on the ladder side, like moving it from a ladder to another or also ## SubCommands: -- `/ranks ladder addrank [ladderName] [rankName] [position]` +- `/ranks command` Sub-commands for Ladder commands - `/ranks ladder create [ladderName]` - `/ranks ladder delete [ladderName]` -- `/ranks ladder delrank [ladderName] [rankName]` -- `/ranks ladder listranks [ladderName]` -- `/ranks ladder list` +- `/ranks ladder list` Lists ladders +- `/ranks ladder moveRank [ladderName] [rankName] [position]` +- `/ranks ladder rankCostMultiplier [ladderName] [rankCostMultiplier]` ## How to use the command Execute the command or its variables like in the examples: -- `/ranks ladder addranks default A 1` This will move the Ranks A from whatever it's to the default ladder as the first rank. - `/ranks ladder create coolLadder` This will create a ladder named "coolLadder". - `/ranks ladder delete coolLadder` This will delete the ladder named "coolLadder" if found. -- `/ranks ladder delrank default A` Delete a rank from the specified ladder. -- `/ranks ladder listranks default` Shows a list of ranks of the "default" in the example. - `/ranks ladder list` Shows a list of ladders. ### Command Format diff --git a/docs/docs-commands/prison_docs_command_22_ranks_set.md b/docs/docs-commands/prison_docs_command_22_ranks_set.md index 1efec8f54..2e24726c5 100644 --- a/docs/docs-commands/prison_docs_command_22_ranks_set.md +++ b/docs/docs-commands/prison_docs_command_22_ranks_set.md @@ -11,6 +11,8 @@ Manages a rank or player. ## SubCommands: +(incomplete listing) + - `/ranks set cost [rankName] [cost]` - `/ranks set currency [rankName] [currency]` - `/ranks set rank [playerName] [rankName] [ladder]` diff --git a/docs/index.md b/docs/index.md index 983aa7d27..b76f0e30e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -14,21 +14,11 @@ Prison's table of contents of all documents. ### Prison Build Logs for v3.2.0 (2019-12-03) through v3.2.6-alpha (current) - - **[v3.3.x - Current](changelog_v3.3.x.md)** + - **[v3.3.0-alpha - Current](changelog_v3.3.x.md)** + - [v3.2.0 through v3.2.10](prison_changelogs.md) - - **[v3.2.0 - 2019-12-03](prison_changelog_v3.2.0.md)** - - **[v3.2.1 - 2020-09-27](prison_changelog_v3.2.1.md)** - - **[v3.2.2 - 2020-11-21](prison_changelog_v3.2.2.md)** - - **[v3.2.3 - 2020-12-25](prison_changelog_v3.2.3.md)** - - **[v3.2.4 - 2021-03-01](prison_changelog_v3.2.4.md)** - - **[v3.2.5 - 2021-04-01](prison_changelog_v3.2.5.md)** - - **[v3.2.6 - 2021-04-11](prison_changelog_v3.2.6.md)** - - **[v3.2.7 - 2021-05-02](prison_changelog_v3.2.7.md)** - - **[v3.2.8 - 2021-06-17](prison_changelog_v3.2.8.md)** - - **[v3.2.9 - 2021-07-03](prison_changelog_v3.2.9.md)** - - - **[v3.3.0 - 2021-??-??](prison_changelog_v3.3.x.md)** +
diff --git a/docs/knownissues_v3.3.x.md b/docs/knownissues_v3.3.x.md index ad467e04d..b0747c03e 100644 --- a/docs/knownissues_v3.3.x.md +++ b/docs/knownissues_v3.3.x.md @@ -3,33 +3,217 @@ # Prison Known Issues and To Do's for v3.3.x -* Issue with decay functions or at least it shows the problem exists. Enable a decay such as obby or rainbow, then test to confirm it works. Then enchant a tool (increase it's eff). Then test again and it does not. This was seen happening while OP'd. May not be related to decays, but it appears as if enchanting causes the pick to bypass prison? -- Was able to reproduce this at a later time +# TODOs for v3.2.10 release: -* prison should "scan" offline players upon startup and auto add anyone not already hooked up. This will help reduce a lot of questions and make the first experience with prison smoother.... +1. DONE: Final testing of ladder rank multipliers +2. DONE: /ranks ladder moveRank not working +3. DONE: Forced global refresh of rank multipliers when a ladder multiplier is changed. + - Should be simple + - Run as async task + - DONE: Force update when updating a ladder's multiplier - all players + - DONE: Force update when changing ranks - only targeted player +4. DONE: Add ladder base cost multiplier to /ranks autoConfigure. Start with a simple 10%. + - Include message that it's enabled and how to change it or disable it: + - /ranks ladder rankCostMultiplier prestiges 0 +5. Add to /ranks player the detail information on rank cost multipliers +6. DONE: For '/ranks autoConfigure' add an alias to '/prison autoConfigure' +7. DONE: Change /ranks list so if non-op it does not show all the extra details. A simplified list for plain players. -* DONE: BlockEvents - add block filters - tested successfully +8. Liners: Some are only for later releases and do not work with 1.8.8. So need to setup something to restrict the liners that are not functional for the older releases of spigot. +9. Hook up Prison's Explosion event. -* DONE: decay: Add a util function to respawn the block that was mined... use it with blockEvents. +### Others -* DONE: Ladder commands: +* DONE: Add a rank cost multiplier to ladders. Sum all active ranks a player has to get the total multiplier to use for rank costs. +* DONE: Fix the "next rank" value with PlayerRanks.... needs to recalc with the new rank. +* DONE: When a ladder's rate cost multiplier is changed, need to recalculate all player's multipliers. Setup a task? -* DONE: Delete by line number: -* Bug: placeholders are not working correctly when player is offline... - - Example with the bar graph placeholders. +# Start on mine bombs + + 1. Select size of bomb. Configuration. + 1a. Identify items to use as bombs + 1b. Bomb size + 1c. Bomb explosion pattern. Currently only sphere, but could include other shapes. + 2. DONE: Select list of blocks that will be effected by bomb explosion + 3. Throw bomb, or place bomb... start processing count down. + 4. Pre-fire effects: sound & particles (low priority) + 5. fire event + 6. Post-fire effects: sound & particles (low priority) + 7. Hook up prison's event handler for prison's explosion event + + +* DONE: Modified /ranks list to provide this feature + - Maybe provide a /rankcost command? Show current player rank costs with rank cost multipliers applied + - /rankcost + - Optional ranks can be provided as parameters and it will adjust the calculations. + - Example: /rankcost RoyalBlueRanger A p5 + * will show the rank costs based upon rank A and p5, no matter the players current ranks + - Will allow players to better understand what rankup costs will be if they prestige twice or 10 times. + + + +# **Mine Valuation Score** - **MVS** + - Calculate an estimated value for a mine based upon an inventory full. + - **Total Blocks** = 2,304 = 9 x 4 x 64 + - For each block, it's percent chance will be multiplied by the **Total Blocks** to get the number used in valuation. + - **BVS** = **Block Valuation Score** will be calculated by how many blocks are represented, times the block's value in /SELLALL + - **MVS** = **Rank Cost** divided by sum of all **Block Valuation Scores** + - Use block chances to determine amounts of each block. Ignore total stack sizes. + - Calculate how many inventory fulls it will take to reach the next rankup cost. + - This is a difficult calculation since it is based upon another rank's cost + - This will give a score value on Mine Valuation. + - MVS 1.0 or less indicates seriously easy and unbalanced. + - MVS 20.0 would be normalish range + - MVS 50.0 or higher would be considered extreme + - Prestiges Valuations should be calculated on the highest rank of the default ladder. + -Pickaxe enchantments, such as eff and fortune, will have a huge impact on how fast a player can rankup, but the Mine Valuation cannot take that in to consideration. + + +### others + +* placeholder for total block counts and other playercache stats + +* Include sellall costs in block lists + + + + +# **Possible bugs/issues:** + +* DONE: /ranks ladder moveRank did not work to move from one ladder to another + +* DONE: When adding a new rank or mine, auto reload all placeholders so they pick up the new entry. + +* Test BlockEvent perms... they appear like they don't work. + +* If ranks module fails due to no economy, try to make that a little more obvious. + +* If no ranks are defined and the placeholders are attempted to be used, it is causing some errors. No economy plugin so Ranks did not load. {prison_rank_tag} was causing an error with /prison placeholder test. "Server: Invalid json. Unterminated escape sequence..." +The ranks module did not load due to no economy. + +* Sometimes Player Ranks lores placeholders from placeholderAPI aren't working, +it's unknown why it's happening. + +* Auto features - disable lore by default - Maybe provide finer grained control on lore features? + + + +# **Document updates needed:** + +1. Document how to use Ladder Rank Cost Multipliers + +2. Document that to get TE explosions to work, you must also create WG regions in the mine. + - may be able to bypass with creative use of Access by Ranks (have prison directly fire the BlockBreakEvents within TE's functions?) + +3. BlockEvent docs need to be updated to reflect recent changes (select by number). + +4. Review commands listed in TOC. Remove obsolete commands (some ladder commands were removed). + + + +* Top Lists - Command based + - Top ranked players by server + - Top ranked players by mine + - Top ranked players by blocks? + + + +* Add a `*all*` for mine name on remove mines blockEvents. + + +- hybrid placeholder graphs - hybars + - super impose text in the graph and have it still be colored correctly. + - text can be centered, such as the percentage that is feeding the bar + - For wider bars, the title could be left justified, and the percentage right justified + + + +* mine groups + - Have global sharing of BlockEvents + - groups cannot be in more than one world + - all mines must be a part of a group + + +* Eliminate the following message from logging an error, but just keep a note in the code: + - Cannot initialize NMS components - ClassNotFoundException - NMS is not functional - net.minecraft.server.v1_17_R1.EntityPlayer + - This does not appear to have much of an impact at this time. + + + +* add all commands to the server.yml file. spigot 1.17.1 is getting fussy. + + +* Conversion tool to import SuperiorPrison users: + - rank is based upon perms `permission.mine.A` and they keep former rank perms. + - No prestiges + - able to reset ranks so conversion can be ran multiple times. + - Unable to really do this due to offline players not having access to the perms. As such, and also due to the need ceasing to exist, this has been put on the back burner. + + +* extended fortune : Apply fortune to all blocks that bukkit does not apply them to. + - Maybe do this through a list instead of blindly applying fortune to all blocks with a qty of 1? Some fortune calculations will result in a qty of one. + +* hook up alternative processing to have prison force the running of another plugin if a setting is enabled. This way prison can "control" how it processes the "left-overs". + + +* prison command handler: + - Add command cooldowns - time in ticks - And cooldownTypes: server, player + + +* Player Cache: + * DONE: Money earned per minute with placeholders + * Add placeholders for blocks counts + * Add placeholders for time onlines + * DONE: Add time mining: per mine + * Tracking by items such as mines or ranks, where the player's status can be reset, presents some problems. Such as the block counts need to be reset for those items, but yet, we need to store them for historical purposes too. So if someone prestiges 10 times, then there will be 10 different times through mine/rank A. If block counts become a requirement for rankups, which it will, then the block counts for that mine must be reset back to zero. So there must be a "current" and "historical" tracking. + - Online stats: + - track which players are online... may need to get the active player list every minute? freq could be configurable. + - track location of player... if the player has not moved in over x-ticks, then mark them as afk. distance traveled is an important aspect... so afk machines may keep them moving in a 1 block radius. Might be able to see if a player is being pushed by water or pistons? + + + + + +* When adding block stats.... add player online stats. + - add events that run, similar to blockEvents, but maybe call them statsEvents? + - So after so many blocks are mined... or so many minutes a player is online, run a command + +* Enable mine sweeper when auto features is disabled. Not sure if this is still needed? + + + + +* Add support for BOSS BAR when holding pick axe. Maybe setup placeholders in the config.yml? +- Example would be showing the bar and percent to next rank. + + +* Add mine notifications by Rank + - I forget what this is.... + + +* Prestiges: Rewrite and enhance so as to make it "automatic" without the need to create ranks +* Externalize the mines module on multi-lang +* Add top-n rankings for mines and maybe other ratings +* Add block break counts to players + + + +* Issue with decay functions or at least it shows the problem exists. Enable a decay such as obby or rainbow, then test to confirm it works. Then enchant a tool (increase it's eff). Then test again and it does not. This was seen happening while OP'd. May not be related to decays, but it appears as if enchanting causes the pick to bypass prison? +- Was able to reproduce this at a later time + * Add optional block counts to level up. So if money and block counts are used, then both have to be satisfied. If only one, then only one of those would be used. -- Count only the block mined and not the results of fortune. It will be easier to control how much mining a player does by ruling out the results of fortune... after all, it's "Blocks Broken" and not "Blocks Received". +- DONE: Count only the block mined and not the results of fortune. It will be easier to control how much mining a player does by ruling out the results of fortune... after all, it's "Blocks Broken" and not "Blocks Received". - Virtual Inventory Items from mining... With the player object, not only keep track of blocks mined, but have a virtual inventory to track what they have collected. @@ -45,13 +229,6 @@ https://www.spigotmc.org/resources/minetinker-50-modifiers-tools-and-armor.58940 -* If automanager is turned off, and /prison reload automanager is ran, it will reload the settings, but the event listeners are only registered upon server startup. So if that condition happens... should display a warning indicating the server must be restarted. -- Add a warning about event priority changes needing a server restart: - - - -* If ranks module fails due to no economy, try to make that a little more obvious. - @@ -73,10 +250,6 @@ https://www.spigotmc.org/resources/minetinker-50-modifiers-tools-and-armor.58940 * list world guard commands to protect the world (would then have functional world) -* If no ranks are defined and the placeholders are attempted to be used, it is causing some errors. No economy plugin so Ranks did not load. {prison_rank_tag} was causing an error with /prison placeholder test. "Server: Invalid json. Unterminated escape sequence..." -The ranks module did not load due to no economy. - - * Add a message count to the `/prison debug` features where it will only print a specific number of messages before turning off the logging for those targets. @@ -109,9 +282,6 @@ The ranks module did not load due to no economy. -* Sometimes Player Ranks lores placeholders from placeholderAPI aren't working, -it's unknown why it's happening. - * Fix per rank progress bars. This includes adding a new placeholder series since you will have to include the rank name in the placeholder. Current ladder placeholders are based upon the player's current rank only. @@ -121,8 +291,6 @@ it's unknown why it's happening. - Based upon total count of blocks broken. Example, after a player breaks 1,000 blocks, then fire a BlockEvent. - -* ladder commands * global virtual mine: To apply mine commands & blockEvents to all other mines. @@ -187,7 +355,7 @@ Auto features not working outside of the mines. -- Add blocks mined for players +- DONE: Add blocks mined for players @@ -216,12 +384,6 @@ Maybe: Have an alt block list for mines were blocks that are not actually - -- blockEvent - - DONE: simplify add - use common defaults - can change features with the other commands - - DONE: Add a target block name - - Not an issue: "Use of placeholders is failing %prison_ is failing on %p" Turned out they were trying to use %player% instead of {player}. - - auto features @@ -267,16 +429,6 @@ Maybe: Have an alt block list for mines were blocks that are not actually -* DONE **Get new block model working** - * Start to enable and test various functions - * Add in Custom Items Integration - * Code Integration for CI - Key to specific version due to api changes - * Pull in custom blocks from CI API - * Place blocks with CI api - * Not sure how block break would work with CI api? - * Setup sellall to work with CI api - - * **Combine a few commands & Other short Notes:** - DONE: Combine `/mines set rank` and `/mines set norank` @@ -300,15 +452,6 @@ We know what blocks are in the mine and the percentages. If people equally mine -* **Commands - Enhancement** -Be able to select rank and mine commands for edit and deletion, or even moving, with line numbers. - - - -* **Rank Commands - Edit and delete** -Add line numbers and enable the ability to edit and delete by line number. - - @@ -316,9 +459,6 @@ Add line numbers and enable the ability to edit and delete by line number. Preserving the current settings, replace the out of date config.yml file with the latest that is stored within the jar. Updating the settings as it goes. -* **Ladder commands - global for all ranks in that ladder** -Add new placeholders for ladder commands to be able to have generic ladder commands that will apply and be ran for all ranks. May be able to eliminate the need for most rank commands. - @@ -360,7 +500,121 @@ Offers for translation: -# Features recently added since v3.2.6 +# Features recently added since v3.2.9 + + + +* DONE: Enable and disable confirmations for prestiges + - DONE: Put in config.yml under the existing: prestiges. settings. + - DONE: Move the GUI confirm to the same group of prestiges. settings. + + + Player Cache possibilities? + * DONE: money earned per mine? + + +* DONE: Make ranks more expensive on each prestige.... + + +* NOT-AN-ISSUE: If automanager is turned off, and /prison reload automanager is ran, it will reload the settings, but the event listeners are only registered upon server startup. So if that condition happens... should display a warning indicating the server must be restarted. +- NOT-AN-ISSUE: Add a warning about event priority changes needing a server restart: +-- NOTE: these are no longer an issue since event listeners are reloaded when the auto features are reloaded. + + + +* DONE **Get new block model working** + * Start to enable and test various functions + * Add in Custom Items Integration + * Code Integration for CI - Key to specific version due to api changes + * Pull in custom blocks from CI API + * Place blocks with CI api + * Not sure how block break would work with CI api? + * Setup sellall to work with CI api + + + +DONE: - Block constraint error when there are no blocks spawned when applying min to add more... + - if rangeHigh and rangeLow are zero, or the same, then need to set the high and low values. + - May need to even set them when there are only a few? + - maybe rangeHigh and rangeLow should be the actual limits, and not the high and low range of where those blocks actually spawned? Right now it's actual spawned blocks, but if either, or both are 5000 blocks from the true limit, then the range of actual adjustments is artificially limited and narrowed. + - Maybe add 2 new fields: rangeHighLimit and rangeLowLimit that is the actual boundaries? These could be used to help normal spawning? + + +* DONE: On prison support submit mines, include /mines info a all? + +* DONE: To all headers that are displayed in prison commands, show the prison's version to the far right. + + +* CANNOT REPRODUCDE: The command /mines delete does not appear to be working - User error? + + +* DONE: Add an *all* for mine names under blockEvent add: + + +* DONE: ladder commands + + + +* DONE: On default ladder, at top rank, if prestige is enabled, then show a message that can be configured. + + +* DONE: Add hunger to auto features calculations + + +* DONE: /prison placeholders list - group by placeholder type. + + +* DONE: Placeholders for items in hand: name, + + +* DONE: try out the new event priority code. if it works, apply it to all classes + + Player Cache possibilities: + * DONE: blocks per mine? + * DONE: time mining per mine? + + +* DONE: Issue with placeholders bars and rankup costs... + + +* DONE: prison should "scan" offline players upon startup and auto add anyone not already hooked up. This will help reduce a lot of questions and make the first experience with prison smoother.... + + +* DONE: Bug: placeholders are not working correctly when player is offline... + - Example with the bar graph placeholders. + + +- blockEvent + - DONE: simplify add - use common defaults - can change features with the other commands + - DONE: Add a target block name + - Not an issue: "Use of placeholders is failing %prison_ is failing on %p" Turned out they were trying to use %player% instead of {player}. + + + + +Completed for v3.2.9: + + +* DONE: BlockEvents - add block filters - tested successfully + +* DONE: decay: Add a util function to respawn the block that was mined... use it with blockEvents. + +* DONE: Ladder commands: + +* DONE: Delete by line number: + + +* **Commands - Enhancement** +DONE: Be able to select rank and mine commands for edit and deletion, or even moving, with line numbers. + + +* **Rank Commands - Edit and delete** +DONE: Add line numbers and enable the ability to edit and delete by line number. + + +* **Ladder commands - global for all ranks in that ladder** +DONE: Add new placeholders for ladder commands to be able to have generic ladder commands that will apply and be ran for all ranks. May be able to eliminate the need for most rank commands. + diff --git a/docs/prison_changelog_v3.2.0.md b/docs/prison_changelog_v3.2.0.md index f93cde2f5..fb5ff77d7 100644 --- a/docs/prison_changelog_v3.2.0.md +++ b/docs/prison_changelog_v3.2.0.md @@ -3,17 +3,10 @@ # Prison Build Logs for v3.2.0 - 2019-12-03 + ## Build logs - - **[v3.3.x - Current](changelog_v3.3.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)**   -**[v3.2.3 - 2020-12-25](prison_changelog_v3.2.3.md)**   -**[v3.2.4 - 2021-03-01](prison_changelog_v3.2.4.md)**   -**[v3.2.5 - 2021-04-01](prison_changelog_v3.2.5.md)**   -**[v3.2.6 - 2021-04-11](prison_changelog_v3.2.6.md)**   -**[v3.2.7 - 2021-05-02](prison_changelog_v3.2.7.md)**   -**[v3.2.8 - 2021-06-17](prison_changelog_v3.2.8.md)**   -**[v3.2.9 - 2021-07-03](prison_changelog_v3.2.9.md)** + - **[v3.3.0-alpha - Current](changelog_v3.3.x.md)** + - [v3.2.0 through v3.2.10](prison_changelogs.md) + + Greetings! I'm delighted that you are interested in the build logs for the diff --git a/docs/prison_changelog_v3.2.1.md b/docs/prison_changelog_v3.2.1.md index 5177f1d10..aee01cf34 100644 --- a/docs/prison_changelog_v3.2.1.md +++ b/docs/prison_changelog_v3.2.1.md @@ -3,17 +3,10 @@ # Prison Build Logs for v3.2.1 - 2020-09-27 ## Build logs - - **[v3.3.x - Current](changelog_v3.3.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)**   -**[v3.2.3 - 2020-12-25](prison_changelog_v3.2.3.md)**   -**[v3.2.4 - 2021-03-01](prison_changelog_v3.2.4.md)**   -**[v3.2.5 - 2021-04-01](prison_changelog_v3.2.5.md)**   -**[v3.2.6 - 2021-04-11](prison_changelog_v3.2.6.md)**   -**[v3.2.7 - 2021-05-02](prison_changelog_v3.2.7.md)**   -**[v3.2.8 - 2021-06-17](prison_changelog_v3.2.8.md)**   -**[v3.2.9 - 2021-07-03](prison_changelog_v3.2.9.md)** + - **[v3.3.0-alpha - Current](changelog_v3.3.x.md)** + - [v3.2.0 through v3.2.10](prison_changelogs.md) + + Greetings! I'm delighted that you are interested in the build logs for the diff --git a/docs/prison_changelog_v3.2.10.md b/docs/prison_changelog_v3.2.10.md new file mode 100644 index 000000000..78c3d6290 --- /dev/null +++ b/docs/prison_changelog_v3.2.10.md @@ -0,0 +1,1079 @@ +[Prison Documents - Table of Contents](prison_docs_000_toc.md) + +## Prison Build Logs for v3.3.x + +## Build logs + - **[v3.3.0-alpha - Current](changelog_v3.3.x.md)** + - [v3.2.0 through v3.2.10](prison_changelogs.md) + + + + +These build logs represent the work that has been going on within prison. + + +*Will continue as v3.3.0-alpha.7 2021-06-?? in the near future.* + + + +#Build v3.2.10 2021-08-23 + +* Many new placeholders added. Prison now has 240 base placeholders including their aliases. + +* Numerous improvements and bug fixes in many areas + +* Improvements in multi-language support. Able to support UTF-8 encoding. + +* Player Cache: Improvements and enabling tracking of blocks broken, time spent in the mines, earnings, and online time. This will be used to enable many new placeholders and more features in the near future. + +* Auto add all players on the server that are not in prison. + +* Enable `/prison support submit` features where players can get better support by making it easier to share their configuration settings. Using paste.helpch.at. + +* Provide a more robust support system in prison, in addition to the support submit features. Can now enable more debug mode targets to better trackdown potential issues. + +* Prison now supports reloadable locales and auto features. For the auto features, it also reregisters the block break events listeners that auto features use. + +* Rewrote some of the auto features to resolve some obscure issues, and to provide performance improvements and greater flexibility. + + +* Redesigned the commands `/ranks list`, `/ranks info`, `/mines list`, and `/mines info` + +* Modified the way Prison edits commands (ranks, mines, blockEvents) so the row numbers can be used instead of copying and pasting the whole command(s). + +* Update many of the internal libraries. + +* Rewrites of the GUIs and Sellall features. + +* Expand Prison's utils features. Added a few more utilities. + +* Added support for Ladder Base Rank Cost Multipliers which enables the ability to make rank costs more expensive when prestiging. + + + + +# v3.2.10 2021-08-22 + +* **Prison Release v3.2.10** + + +* **Updated to the support of the Prison's ExplosiveBlockBreakEvent. There were a few adjustments that were needed.** + + +* **Some blocks within the liners are not compatible with all versions of bukkit/spigot/minecraft.** +Added minimal versions to the patterns so as to help prevent the use of the wrong patterns for the server version. + + +* **Found an error with two Mine Liners that had pillar_quartz_block instead of quartz_pillar.** + + +* **Added support for Prison's own ExplosiveBlockBreakEvent.** +This will be used for Prison's up coming Prison Bombs. Also this can be used by other plugins too. + + +* **Update the PrisonEnchants code for handing their PEExplosionEvent object.** + + +* **Fix a problem with NPE when getting the player's Locale when it wasn't set.** + + +* **More adjustments to the /ranks list to add information about the player's current multipliers on all the ladders.** +This makes it easier to understand why the rank multiplier is a specific value. + + +* **Some adjustments to `/ranks list` to remove "admin stuff" from the list for non-admins.** + + +* **v3.2.10-alpha.14b 2021-08-22** + + +* **Removed the option to delete a rank from the ranks info command since it should not be that easy to remove a rank, which could easily be clicked on in game.** +Also commented out dead code. + + +* **Hook up the process to have all unjoined players added to prison by giving them the default rank.** +This is also ran now at the end of the /ranks autoConfigure to ensure all players are hooked up as soon as the default ladder and it's ranks exists. + + +* **Player join bug: Fixed a bug... if a player is not on the default ladder, then this was preventing them from being added.** + + +* **Added virtual checks to prevent placeholders from trying to access mine features that do not exist.** + + +* **v3.2.10-alpha.14 2021-08-21** + + +* **reduce what is shown on /rank if for non-op players.** + + +* **Decrease the autoConfigure's prestige costs from 2 B to just 1 B.** + + +* **Reload auto features after running ranks autoconfigure to enable the auto pickup.** +It wasn't working right after generating the mines. + + +* **Fixed an issue with virtual mines not being included in /mines list all command.** + + +* **Now `/ranks autoConfigure` creates 10 prestiges ranks. ** + + +* **Have placeholders reload after mines or ranks are created, removed, or renamed.** +Create mine and create rank now has an option to suppress updating placeholders since commands like autoConfigure will cause tons of messages to be generated. The placeholders are regenerated after all mines and ranks are created. + + +* **Command '/mines set area' fixed confirmation to use yes or confirm.** +Added the ability to set size when using feet. The size is what is used with the '/mines set size' command. So 20 width is really 41 since it's adding 40 blocks in all directions. + + + +* **Redesign the /mines info command to reduce and compact the listing.** +`/mines info ` is the reduced listing where disabled features are not shown. `/mines info all` is the expanded listing that includes more details. +Reworked the block list to use the String.format for spacing instead of manual adjustments. + + +* **v3.2.10-alpha.13 2021-08-20** + + +* **Fixed an issue with null for the playerUuid..** +it's rare, but it could be null. This prevents the failures. + + +* **Fixed a few issues with ranks, a NPEs.** + + +* **The text for ladder info was changed to remove player's name, which does not make sense to include, especially if ran from console.** + + +* **Yet another situation where CMI needed prison to start with a delay; confirmed setting is correct.** +It was confirmed for the second time that 'Economy_CMI' works so I moved that to the 'vault-economy-name:' setting. + + +* **Fixes a bug when checking offline players which was returning a null with rPlayer.getRank(). Was fixed.** + + +* **Ranks autoConfigure: Add to the prestiges ladder the base rank cost multiplier of 10 percent.** +Provide a few messages to document it when the /ranks autoConfigure command is ran. + + +* **For the /ranks autoConfigure command, setup an alias to /prison autoConfigure.** + + +* **Setup a task that is to be ran whenever there is a rank change within a ladder, or if the ladder has the base rank cost multiplier changed.** +This helps to ensure that the rank costs are correct for all players. + + +* **Renamed the command `/ranks remove rank` to `/ranks removeRank` since the prior command was a single command within it's own sub-group.** +This change will now list the command with the others when using `/ranks`. It was "lost" and "hidden" and admins were not able to find it that easily. + + +* **Changed the /ranks ladder delete command to prevent a ladder from being deleted if it has any ranks associated with it.** +To delete a ladder with ranks would corrupt the ranks. The ranks would have to be removed first to ensure no players are on the ranks. + + +* **After a change in a player's rank, have the player's Rank Cost Multipliers recalculated.** + + +* **The command /ranks player perms was generating an error with offline players so this fixes that issue.** + + +* **Changed config.yml to enable and disable prestige confirmations.** +Updated the GUI to support this. Settings where changed and config.yml may need to be reset when updating prison to use these new features. + + +* **Fixed bug with `/ranks ladder moveRank`.** +It was not removing the rank from the source ladder, but was also adding it to the destination ladder. This was fixed and is now working correctly. + + +* **Removed the remainder of the ladder/rank permissions that were never used.** + + +* **Start to setup MineBombs basics.** + + +* **Add to the World object, a function to set the block.** +The SpigotWorld class uses prison's compatibility functions to perform this action. + + +* **v3.2.10-alpha.12 2021-08-16** +Released alpha.12 + + +* **Updates to fix the prestige issues.** +Moved more of the processing in to the PlayerRank object to reduce issues. Shutdown one of the constructors since it could lead to the wrong amounts. +Prestige was fixed by rewriting the way the rankup handled the ranks and playerRanks. + + +* **Fixed an issue with logging when using a debug target mode.** +It was not logging when the global debug was off. + + +* **Added some rankup debug logging details.** +Enable with `/prison debug rankup`. + + +* **v3.2.10-alpha.11 2021-08-15** +Bump the version + + +* **Changed the /ranks info to show the ranks multiplier information.** + + +* **Work on /ranks list to improve the content to better present the rank cost multiplier.** + + +* **General changes to code that uses getRank() that returns a PlayerData object... ** +Since that is a player's instance of a rank, this may be null for a lot of players. A lot of the old code would not take in to consideration that there may be no value, so hence the NPEs that we've been seeing. This should address a lot of the potential issues. + + +* **Found situations where players are not on a ladder and its causing issues.** +Need to expand to other code... + + +* **Bump to v3.2.10-alpha.10f.** +Will be trying to release a more formal alpha later today. + + +* **Fixed a typo in the name of a function. Prevent a possible NPE. Revised how one of the PlayerRank constructors works so it will actually calculate the correct multiplier.** + + +* **v3.2.10-alpha.10e 2021-08-13** + + +* **More adjustments to rankups and PlayerRanks.** I think I've addressed all issues with ranks. + + +* **Remove three redundant ladder commands dealing with ranks: listranks, addrank, and delrank.** + + +* **There was a report that the mine would continue to reset after it was deleted.** +Cleaned up a few things and added a boolean field to indicate it's delete. If its set to deleted, then it will prevent the resets from happening. Just as a safety check. Not 100% sure that this was actually an issue. + + +* **Setup the AsyncPlayerChatEvent listener within Prison to be able to dynamically set the priority based upon a new setting in the config.yml file.** + + +* **Bug fixes: Fixed some issues with the use of the new PlayerRank object.** +They were not always not-null, and there were some instances of the wrong variable being used. + + +* **Fixed an issue with the regular expression block quote... didn't need the second backslash.** + + +* **Bug fix: Fixed a few issues with PlayerRank object not being set correctly everywhere.** +Was also checking the wrong object for null. These fix about 3 different NPEs. + + +* **Removal of the obsolete ranks related permissions and permission groups.** +This was a failed attempt to automate the user of permissions with ranks. This did not work, since vault does not support the creation of permission groups, plus a few other issues and limitations with vault. + + +* **Initial setup of ladder rank cost multipliers.** +All ladders a player has, will contribute to the total rank cost multiplier value, and all ranks for that player will have their cost adjusted. +Overall this will allow an increasing rank cost as players rankup on the prestige ladder, and/or it can help reduce rank costs if donor ranks provide a negative adjustment. +Currently there is no way to set the ladder's multiplier... that's next. But everything else is hooked up and should be functional. + + +* **v3.2.10-alpha.10 2021-08-11** + + +* **Added a missing ranks message: when removing a player from a rank and it fails.** + + +* **LocalManager.getLocale: Fixed an issue with player being null when the player object originated from a task processing offline players.** + + +* **Added the event level MONITOR and changed the event listeners to only register the MONITOR event when the config is set to MONITOR.** + + +* **Updates to the JumboTextFont by adding most of the lowercase characters.** + + +* **Alter the use of accessing the player to help eliminate the risk of concurrent modification events.** + + +* **Added a spigot module en_US.properties language file.** + + +* **Added a new function to the PrisonEventManager to return the list of event listeners as a string so they can be logged to the console, or through helpch.at which is not yet hooked up.** + + +* **Added JumboTextFonts to prison support submit ranks.** +Fixed a few issues and added more characters to the fonts. Added /ranks info all to the ranks output for more detailed information. + + +* **Found and fixed an obscure bug with regular expression quotes.** +It was duplicating text and making the results much larger than what they should have been. + + +* **Created a JumboTextFont to be included in the prison support submit documents.** +Hooked up to mines. This will make it easier to identify the various mines in the listings. + + +* **Add the capture and display of all support submit URLs in each additional submission.** + + +* **Expand '/prison support submit mines' details by including the '/mines info all' command.** +Had to redesign some of the mine commands to be able to capture all of those details. Added a table of contents to the submission so it's clear all these details are included, since it could be a HUGE file. + + +* **Added 6 new placeholders to provide the whole line for the prison_top_mine_block_ plus the heading and total line.** + + +* **Placeholders with _nnn_ numeric ranges: Fixes a potential problem of where it was unable to match a placeholder if placeholder escape characters were not used.** +Now it will properly identify and match the series. + + +* **Fixed a problem with block constrains, the min number of blocks, when no blocks were initially added to the mine.** +When revisiting to ensure the min amount is set, it did not have the correct values set for the ranges. +This has been fixed by adding a low and high limit field that not does record the actual block positions of this block type, but of the limits as defined by the constraints. This allows adding more blocks to reach the min amount, when no block has been added before. + + +* **Prevent the use of % in the ranks and ladder commands.** +Could not use them before, but they would cause errors when messaging details about the commands. Now the command will be rejected and it will have to be submitted correctly. + + +* **ButtonLore Utility got a couple of new methods.** + + +* **Some GUIs were still using the old deprecated buttons. This got fixed.** + + +* **All GUIs got a new common lore Format.** + + +* **All GUIs now use ButtonLore utility and lore format.** + + +* **Fixed an issue with spigot 1.17.1 where they appear to be extending the BlockBreakEvent for FurnaceExtractEvent but not isolating the listeners.** +Forced to check to ensure the event is actually a BlockBreakEvent to ensure the correct event is really being fired correctly. + + +* **Added prison's version to the chat display's title.** +is will help support since it wil help show us what version someone is using. + + +* **Added the recording of earnings per mine.** +The add earnings must be called within the time limit as defined by the session timeout for mining, which is currently 15 seconds. +If something is sold outside of that session timeout, then it will not be attributed to the mine. + + +* **Minor design changes to the main GUI /gui**: to apply them you should reset (delete it) your en_US.yml at this path -> + Prison/module_conf/lang/en_US.yml. More changes will come in the future. + + +* **ButtonLore is quite ready and already in use for the /gui main GUI, only the first page uses it.** + + +* **Started working on a new ButtonLore Utility that will be included in the SpigotGUI Utility.** + + +* **v3.2.10-alpha.9 2021-08-04** +Released... +Upgraded gradle to use v6.1.0 of Jengleman's ShadowJar... was v5.2.0. + + +* **Modify the block break events to merge most of the preliminary processing from all of the different kind of block events.** +This enables a single function to be able to handle most of the initial setup processes for all of the different block break events. This will reduce the amount of code, eliminate possible errors, and make it a lot easier to enable more events to be processed. + + +* **Add the option for using '*all*' for mine name for adding block events, which will add the event to all mines.** + + +* **All GUIs now use PrisonGUI Utility, finally it should be done now.** + + +* **2 more autofeatures GUIs now use PrisonGUI Utility.** + + +* **All SellAll GUIs now use PrisonGUI Utility.** + + +* **All Mines GUIs now use PrisonGUI Utility.** + + +* **Disabled some old Block model code in use for GUIs.** + + +* **Mines Blocks List GUI now uses PrisonGUI utility.** + + +* **Fixed Mines Blocks List GUI (the one that shows the blocks currently in the mine).** The GUI wasn't translating +correctly blocks, and showing a "barrier" instead of the block, the GUI was working anyway, just + not good looking, now it's fixed for newer versions. + + +* **Mines Reset Time GUI now uses PrisonGUI utility.** + + +* **Mines Set Notification Mode GUI now uses PrisonGUI utility.** + + +* **Mines Notification Radius GUI now uses PrisonGUI utility.** + + +* **Mines Blocks Set Percentage GUI now uses PrisonGUI utility.** + + +* **Updated Buttons PrisonGUI Utility to support enchantments.** + + +* **For the fortune calculations, converted the use of the old block model over to use XMaterial instead.** +Updated to include the newest 1.17 blocks too. + + +* **Updated smelting to use the newer 1.17 blocks, such as all of the deepslate variations, and the raw iron, raw copper, and raw gold.** +Updated all code that had these variations. + + +* **Updated the XP calculations to include the newer blocks from 1.17** + + +* **Upgrade XSeries from v8.2.0 to v8.3.0** + + +* **Remove the dump of block break events from the command /prison version all since it was appearing first.** +It will need to be rewritten to capture in a list of strings. + + +* **Added mining time by Mine.** +This will also track in which mine, players are mining. + + +* **Found a bug in the TokenEnchant event listener class.** +It was casting to the wrong class for the Monitor event. + + +* **Fixed an issue with PlayerCache and mining duration.** +Also added logging if unable to rename a temp file. + + +* **Added support for jumbo and full ladder types with the mine liners.** + + +* **Update the custom ladder type feature in mine liners.** +Now you can select none, normal, and wide. + + +* **Provide break the list of placeholders down by placeholder types, along with sub total counts.** +Also added total count at the top of the list. Breaking down the large list in to sub-types will make it easier to read the list. + + +* **Provided a way to specify a last next rank message for the placeholder:** +prison_rankup_rank_tag_default +This will only apply on the default ladder and when the next rank tag is empty. + + +* **Started to look in to providing the ability to import player ranks** based upon perms, but ran in to an issue that if the player is not online, then it can be very difficult to get their actual perms. Would not be able to get a listing of all perms, as if they were online, so it would make this less flexible. +This has been canned because the person who was needing it, is no longer needing it. May revisit in the future. + + +* **About 56 new placeholders!** SpigotPlayerUtil has been updated to provide support for all of the functionality that it needs. It's been hooked up to the placeholders so they should be functional. + + +* **Setup the Platform to be able to provide a SpigotPlayerUtil object.** +This is needed for placeholder support and a few other things. + + +* **There was a concurrent modification exception on the line with** `playerData.setDirty( false );`. +These changes will not prevent that issue, but it will trap it so it does not register in the log files. If this happens, then the player's cache will be saved on the next attempt. This should be a rare event. +The changes needed are more complex that this simple "fix" and will be made in the near future. + + +* **Prison Mines Blocks Set Percentage GUI now uses PrisonGUI Utility.** + + +* **Prison Mine Blocks List GUI now uses PrisonGUI Utility.** + + +* **Prison Blocks List GUI now uses PrisonGUI Utility.** + + +* **Fixed some errors of the Prison Mines Blocks Set Percentage GUI:** There were some ArrayOutOfBonds exceptions. + + +* **Auto Features: Added food exhaustion calculations.** +Now on each block break, Configurable to be disabled. For explosions events, only applies to the one block they actually mined. + + +* **For various add commands, the messages for the 'placeholders' was being sent to the console instead of the player issuing the command. This was an issue in game, but not the console.** + + +* **Placeholders durability: add support for a percentage and bars.** + + +* **3 new Backpacks GUIs for admins now use PrisonGUI Utility.** + + +* **Bug fixes with the setup of token enchant event listeners.** + + +* **Added many more features to SpigotPlayerUtil and getting ready for the new placeholders.** + + +* **Started to add a PlayerUtil and SpigotPlayerUtil to prison.** +This will allow an easier access to specific player values in other parts of prison with just a single call to a util function. This will be used with a number of new placeholders. + + +* **Removal of a function from the prison Player object that is no longer being used.** + + +* **A couple of updates for CMI economy.** +Added a note on what value to try first for cmi with prison. + + +* **Changed some logging information from debug to info so it will be registered when requested by the admin.** + + +* **PrisonEnchants changed the class name of their event.** +This updates prison's code and changes the api jar file. + + +* **Created a new group within auto features for durability related items and created a new group autoManager just for the isAutoManagerEnabled to get it out of the options.general grouping since that is the main "switch" and it is getting lost in the configs.** +There was too many for the general group, and they were not being kept together, especially since we have a comment now. + + +* **Backpacks admin GUI now uses PrisonGUI Utility.** + + +* **v3.2.10-alpha.8 2021-07-25** + + +* **Auto features: Removed unused classes and cleaned up a few things. Fixed a reference to one of the deleted classes.** + + +* **Auto features events: Added an abstract class to manage the unregisterListeners in one place, to eliminate duplication of code.** + + +* **For the command /prison reload autoFeatures hooked it up to include unregistering all of the event listeners that auto features setup, then it uses the configurations to reregister them all.** + + +* **Fixes a major problem with how Zenchantments works because the plugin extends the BlockBreakEvent with their BlockShredEvent.** +It has issues.. but... this ensures that the correct event is being trapped. + + +* **Change to player cache field that was not so clear with it's name.** +It's supposed to be the config field name, but the description did not reflect that. + + +* **Fixed GuiUtility button add lore method:** The method to add a line to an already existing button got now fixed. + + +* **Adjustments to get the new event listeners working fully. Still need to hook them up to the reloading.** + + +* **Next step in rewriting how the event listeners are setup...** + + +* **Move the event listener managers in to a common package to prepare to extend them to the non-auto features event listeners.** + + +* **Rewriting how the event listeners are being registered.** +Added ability to unregister. This is working, but is only for the auto pickups. WIll need more work to hook up to the non-auto manager. + + +* **Setup the ability to log more than just the BlockBreakEvent.** +It it mow able to log details to Lists so they can be included in other output, such as support submits. + + +* **Rewrote how the event listener is registered so the priority is dynamic.** +This appears to be working well. + + +* **clean up some of the /prison version all commands to better reflect the actual details with dependencies with the settings for auto features.** +This should help better convey what the settings are doing, especially when a setting disables another setting. This should help reduce support issues. + + +* **Prestige confirming fix:** Fixing Prestige confirm by chat or GUI when possible. + + +* **v3.2.10-alpha.7 2021-07-23** + + + +* **Fixed the way some of the autofeature block settings were named.** +They had "autoBlock" when auto has nothing to do with it anymore, since those setting will be applied for normal drops too. +Fixed an issue with auto smelt and auto block where it was not using the config settings, so now it's working correctly. +Added more debugInfo messages to better understand what's going on when something is not working correctly. + + +* **Added a note on how fortune works... it's been confusing...** + + +* **Updates to the liner to allow the use of '*all*' for the mine name to apply the same pattern to all mines.** +For auto configure, ensure that the random liner applied to the mines is not remove, removeAll, or repair. + + +* **Prevent slime fun from registering if it is disabled.** + + +* **Fixed a problem with the registration of the events failed due to the parameter of ExplosiveEvent.** +Had to set it to Object to allow it to be registered when the plugin and class does not exist on the server. + + +* **Added more internal debug details.** + + +* **Mine liners: Added glowstone and also added the ability to apply a liner change, or removal, from all mines with one command by using `*all*` for the mine name.** + + +* **Add the debugInfo to more functions and a few more messages.** + + +* **Changed the debugInfo variable to a StringBuilder instead of just a String.** +This will provide a little bit of a performance improvement, plus it can then be passed in to the functions to gather more information. + + +* **A few minor adjustments to better identify the function that is running when logging the debug information on BlockBreaks.** +Tweaks to the PrisonEnchant's plugin code. Missed a few changes. + + +* **Changed some of the DebugTarget names to better reflect where in the project they are occurring.** + + +* **Bug Fix: If a message is removed, such that there is nothing left of the = character in the language properties files, it will now not throw an index out of bounds exception.** +Removal of the message was not expected and there was unable to handle that situation. + + +* **Added support for 4 new types of placeholders that uses the PlayerCache:** +Player's total block count. And player's count per mine. + + +* **Issue with using offline players with the playerCache.** +The playerCache should typically only contain active players, but in testing, like using /prison placeholders search, it may add an offline player to get placeholder data from them. +This prevents null issues with the locations, and eliminates the excessive error message when trying to use getLocation() on an offline player. + + +* **PlayerCache changes: Start to take in to consideration that a player within the cache may be offline.** +If that's the case, then prevent some calculations, and remove them from the cache. Offline players would be added to look up some stats, but then they would be safe to purge. +When checking the timerTasks, add an earnings of zero to purge past earnings. This will prevent the average earnings from staying there forever when the player stops mining. + + +* **Added a debug logging entry for XP Calculations.** +This will be able to provide detail infomation on if it's working and what the results are. + + +* **Add support for PrisonEnchants' ExplosiveEvent.** +While adding support for the ExplosiveEvent, found a few issues and fixed them. Some changes were just in names of functions, others were functional, such as improving the support of unbreakable and blocks that fall outside of a mine. + + +* **Simplified how the title, subtitle, and actionBar are setup with the /prison utils titles title command. ** + + +* **New Feature: Prison now tracks average earnings per minute.** +If you have auto sell enabled (sell upon each block break, see autoFeaturesConfig.yml) then prison will be able to report your average earnings over the last 5 minutes of mining activity. +`prison_player_balance_earnings_per_minute` prison_pb_epm +`prison_player_balance_earnings_per_minute_formatted` prison_pb_epmf + + +* **Rewrite how the player uses title, subtitle, and actionBar for the /prison utils titles command.** +Spigot 1.8 does not support any of this. +Spigot 1.8.8 is when this was introduced. But 1.8.8 does not have actionBar, so instead it shows the message in the subtitle. +Spigot 1.9+ are able to display title, subtitle, and actionBar at the same time. + + +* **Release of v3.2.10-alpha.6 - 2021-07-19** + + + +* **Try to better handle situations where integrations fail when integrating.** +Now has the ability to disable the integration and remove it when it fails. + + +* **New feature: prison utils titles.** +This enables sending messages to the player's console as either a title, a subtitle, and/or actionBar. Can also clear, reset, or set the timings on the titles. +All three can be sent through the title by using a double colon to indicate the various parts. +For example: 'Hello Title!::Subtitle is Here!::I'm on an actionBar!' + + +* **Add feature to Auto Features to prevent tools from breaking or being used when durability is equal to or greater than maxDurability.** + + +* **Added some documentation to the ExplosiveBlockBreakEvent so users can better understand how it should be used.** + + +* **This is an example of an explosive block break event that should be used so prison can monitor for it, and consume it.** + + +* **More adjustments to the Taiwanese language files.** + + +* **More tweaks to player cache file saving... ** + + +* **PlayerCache adjustments for timing tracking. A work in progress.** + + +* **Updates to he Taiwanese language files.** + + +* **Improvements to adding new players to prison upon startup.** +This process scans bukkit's offline players and finds everyone who is not already setup in prison and adds them. +It now uses the /ranks set rank command now. + + +* **Added support for zh_TW Taiwanese.** +This is just an initial setup for now. To enable it, set the language in the config.yml file to zh_TW. + + +* **Player Cache: Hooked up block tracking for players.** +Appears to be working as far as tracking blocks that are being broke. It loads and unloads when a player joins and leaves the server so only active players have their data online. Performs periodical updates on saving. +This tracks total blocks, block counts by mine, and block counts by block type. +Starting to setup time tracking. + + +* **More changes to setting up a player cache.** +The basics should be represented, with startup and shutdown of the cache, running a periodical task to refresh the data, running a periodical task to save the data. +No data is processed as of yet, but the cache should be reactive to players logging on and off the server. + + +* **Initial work on setting up the Player Cache.** + + +* **Minor SellAll utility changes.** + + +* **SellAll Player Blocks List GUI now supports pages.** + + +* **Minor improvements for GUIs to improve performance.** + + +* **PrisonGUI Buttons utility minor changes.** + + +* **Add the ability to play sounds through the /prison utils sound command.** + + +* **Update docs... scale back what we support with WorldGuard regions since access by ranks solves so many problems.** + + +* **SellAll Admin Blocks List GUI now supports pages.** Note: This was **not** part of the v3.2.10-alpha.5 release. + + +* **SpigotGUIComponents minor changes.** Note: This was **not** part of the v3.2.10-alpha.5 release. + + +* **SellAll Blocks GUI now uses PrisonGUI Utility.** Note: This was **not** part of the v3.2.10-alpha.5 release. + + + +* **v3.2.10-alpha.5 2021-07-14** + + + +* **Made the RankLadder comparable and in the RankPlayer changed the map to a TreeMap.** +This should fix the inconsistencies that I was seeing earlier. + + +* **If a player is detected to be lacking a rank on the default ladder, it will adde the default rank.** +Ran in a problem where getting the current rank for a ladder was failing when it was ran, but worked when stepped through a debugger. + + +* **When checking for players not hooked up to prison, prison now ensures there is a default rank configured or it won't try to check the players.** +This change also checks players within prison to ensure they have a rank on the default ladder. + + +* **MineInfo GUI now uses PrisonGUI Utility.** + + +* **Removed unused imports from some GUI classes.** + + +* **MineInfo GUI TP Button now has an Arrow instead of a red_bed:** red_bed can't be translated to a legacy block in 1.8.8. + + +* **Fixed performance issues for MinesInfo GUI.** + + +* **Added information to the language files on how to use utf-8 text in these properties files.** + + +* **Setup prison to ensure all compliers within gradle is using utf-8.** + + +* **Enable loading utf-8 encoding from the properties files. Java 1.8 is unable load them as utf-8, so this provides a work around.** +At this point, this ensures that if a properties file contains utf-8 encoded text, that it can be packaged in the prison jar, extracted to the file system, then loaded and used and maintain full utf-8 encoding all the way until it hits bukkit. bukkit corrupts it and confirmed it was corrupted in spigot 1.8.8, 1.3.4, and 1.16.5 so its not an isolated issue for just one spigot version. + + +* **Updated cryptomorin's XSeries to v8.2.0.** + + +* **Convert the CommandHandler.getHelpMessage() to return a ChatDisplay object to allow the use of creating clickable URLs in the help messages.** +The help messages now has headers which shows the command that's being listed. +Updated the /mines blockEvent add command to include two docURLs to use as an example; improved the help message. + + +* **If a Ladder has a bad rank that is already in another ladder, that rank will not be added to the new ladder that is being loaded.** +An error message is already being logged, but this change will update the ladder to resave it without the duplicate rank. + + +* **Clean up Ranks a little more by removing more of the rank position and report failures if a rank is already loaded in another rank to prevent internal failures if a ladder save file is corrupted by manual editing.** + + +* **Removed the use of rank.getPosition() from all saved information within ranks and ladders.** +Position is no longer used to access any rank. It is only used to compare if one rank is higher or lower than another. It's lazy loaded only when it is needed the first time. If a rank is removed from a ladder, or inserted in to a ladder other than at the end, then all ranks in the ladder are set to -1 for the position so they recalculate when they are used the next time. + + +* **This fixes a user error situation, which is not a bug, in the listing of ranks.** +The user copied the contents of one ladder to another ladder, without deleting the source ladder. Thus there were two instances of a series of ranks, when there should ever be only one instance of a rank. A rank can be in at most one ladder, or no ladder. +The result of this issue is that when the second ladder was hookedup at prison's startup, it corrupted the ranks in the first ladder. +This works around such problems by changing /ranks list by using the list of ranks within the ladder, instead of using the rank's prior and next associations. +These changes also add the rankId to both the '/ranks list' and '/ranks ladder rankList' commands, and also '-' and '+' notations to indicate a rank is linked to a prior and next rank. + + +* **Simplify the command /mines blockEvent add by removing the permissions and taskMode from the add.** +This was causing too muchh confusion for a lot of people. It should help to keep the add much more basic. There have been alternative commands to modify those settings so it really isn't important to set them on the add. Also odds are they will not anything but the default values for these two fields. The defaults are perms = none and taskMode = sync. TaskMode is not defaulting to inline due to increased risk of lag and prison being falsely blamed for it. If desired, the admin can always change the taskMode to what they need. + + +* **Bug fix: Fixed an issue where the "on click" events were using the wrong row number.** +The row number was getting incremented at the wrong time. + + +* **v3.2.10-alpha.4 2021-07-10 ** + + +* **Few minor tweaks to the mines info command with formatting.** + + +* **Added player counts to the rank list command.** + + +* **Hooked up the /ranks list all command to the /prison support submit ranks command.** + + +* **Add option to /ranks list to include all ranks through the use of the "all" in place of the ladder name.** + + +* **Fixed a bug where getting a player was returning a null.** +When that null was encountered, it was not processing the placeholders, especially for the bars. +Not really sure why it was failing, but replaced the use of getting the player balance with the most recent use of RankPlayer's getBalance() works perfectly. + + +* **More adjustments on the /ranks list to prepare for listing all ladders.** +Also added a couple of more messages. + + +* **Added an error message if there is a failure when using /prison support submit.** +I assumed that other error messages would exist, but having doubts if it always will have other errors displayed. + + +* **Improvements to the /ranks list command.** +Enhanced the header so it's clear which ladder is involved. Also cleaned up the formatting with the tag colors so it does not impact the column alignments. Also doing a little more with injecting the "default" tag so it does not shift the columns. + + +* **Adds the listing of all mines to the /prison support submit mines command.** +This provides an overview of all mines and is included at the top of the listing. + + +* **Improve the layout of all of the mines with the command /mines list all.** + + +* **pasteChat update to keep the color codes.** It will only keep the color codes that start with &, and all others will be removed. + + +* **New feature: /prison reload locales. Its now possible to reload the language files that prison uses.** +Added a new debug item to test to see if utf-8 is working: /prison debug testLocale. No, it does not work with utf-8 text yet. +I did confirm that if the properties files are setup with UTF-8 and are a part of the prion jar, that the UTF-8 encoding will properly be saved to the local file system. +The area that I think is causing failures is with the Properties object itself since that is not utf-8 compatible, so it appears. + + +* **v3.2.10-alpha.3 2021-07-09** + + +* **reformat the /mines list command to mak it easier to read** + + +* **Added support for prison support submit for ranks and ladders, and also for mines.** +These two new commands will submit the raw json files. + + +* **New Feature!! Major support feature! Send all of prison's configs to paste.helpch.at so we can know exactly how servers are configured.** +This logs the following config files: config.yml plugin.yml autoFeaturesConfig.yml modules.yml module_conf/mines/config.json + SellAllConfig.yml GuiConfig.yml backpacks/backpacksconfig.yml + + +* **Added a success message when a player is added to prison's default rank.** + + +* **Fixed issue with a few placeholders that were not working.** +Was using the wrong translator so a number of mine related placeholders stopped working. +The mineplayers were not working too. The bug was introduced by hooking up STATSMINES. + + +* **Hooked up STATSRANKS placeholders and got rid of obsolete ones. Still more testing needed.** + + +* **Added a player check on prison startup that will add all offline players that are not hooked up to prison yet. Plus it will register name changes too.** + + +* **Added top rank balance placeholders: 6 for now and more will be added soon once these are fully working.** +These are based upon the player's balance within the rank. +Also added a Hesitancy Delay Penalty to help encourage players to rankup instead of trying to dominate a single rank. +These have not yet been tested. + + +* **Added RankPlayers to Ranks.** +This will allow quicker access to all players at each rank, which will help for top ranking reporting. + + +* **Clean up some rank and ladder function to eliminate the use of magic numbers: both rank ids and ladder ids.** +These were bad, since the objects were already linked together, so using these functions were just adding unneeded overhead. + + +* **v3.2.10-alpha.2 2021-07-06** + + +* **Added the ability to fail silently for the Localizable object to prevent the message ID from flooding certain messages.** +This will be employed in the Output.get() functions so if it cannot load the prefixes and level colors, then the message IDs will not be injected in to the messages. +This new feature should never be used without careful consideration since it is important to identify when messages fail so they can be fixed properly. + + +* **Adjustments to LocaleManager for updating the internal checks for if the external files need to be updated.** +Also finalize how Prison object works with the LocaleManager. + + +* **Removed obsolete placeholders that are not used anymore.** + + +* **Adjustments to when the LocalManager is started so it can be activated as soon as possible.** +This is because of the need for Output.get() to use externalized messages for it's prefixes and color codes. This does present some problems, but it actually works fine at runtime and also for junit tests too. + + +* **Setup a getConfigString in the Platform with a default value.** + + +* **New placeholders for mine block stats: Renamed percent to chance. Added prison_top_mine_block_remaining_bar_nnn_minename.** + + +* **Used the wrong numeric formatter... needed to be an integer.** + + +* **Added 10 new placeholders to provide stats on mine blocks.** +These use a series value in the placeholder to specify the specific block. The series number is not limited and can range from 1 through a large reasonable value. The number can be one or more digits, with or without a left padding zeros. + + +* **Renamed the field PrisonBlockStatusData.getResetBlockCount() to getBlockPlacedCount() to be more descriptive of what it actually is.** + + +* **Add the ability of a PlaceholderFlag to self identify as having a sequence.** +This will allow for automatic processing of these kind of placeholders without having to hard code for them. + + +* **Placeholders test: Fixed issue with player name being incorrect and also added player information if it is provided in the output.** + + +* **Fixed a typo that was made a long time ago. Placeholder has a capitol H in the name.** + + +* **Increased the number of rows displayed when using the placeholder search. It was showing six placeholders and I increased it to 10.** + + +* **Renamed the PlaceHolderFlags from PLAYERMINES to MINEPLAYERS which is more consistent in how it is being used.** + + +* **v3.2.10-alpha.1 2021-07-05** + + +* **Bug fix... when selling on each block break event, it needs to suppress the per-sale messages.** + + +* **Fix a few other issues with the new placeholders.** + + +* **Enhance the /ranks autoConfigure to work much better with existing mines and ranks when doing a force.** + + +* **New 18 new placeholders added to prison. Hooked up the following placeholders, but have not yet ran through testing yet.** +prison_rank_ladder_position (prison_rlp), prison_rank_ladder_position_laddername (prison_rlp_laddername), +prison_rank__ladder_position_rankname (prison_r_lp_rankname), prison_rank__player_cost_rankname (prison_r_pcst_rankname), +prison_rank__player_cost_formatted_rankname (prison_r_pcf_rankname), prison_rank__player_cost_remaining_rankname (prison_r_pcf_rankname), +prison_rank__player_cost_remaining_formatted_rankname (prison_r_pcf_rankname), prison_rank__player_cost_percent_rankname (prison_r_pcp_rankname), +prison_rank__player_cost_bar_rankname (prison_r_pcb_rankname) + + +* **Refactored ranks and RankLadders to eliminate old and inefficient ways to get the ranks and next ranks.** +These change will help improve the performance of processing the placeholders. +This also allows the elimination of a few functions that are now obsolete. + + +# v3.2.9 2021-07-03 + +- release v3.2.9 + + +# v3.2.8.1 2021-06-18 + + +* **Note: Bug fixes for 3.2.8.** + +* **Fixed a failure on startup for new installations of prison.** +Basically it was unable to deploy the language files due to try-with-resources closing the initial zip connection. + + +# v3.2.8 2021-06-17 + +Prison V3.2.8 Release! +Prison now fully support Spigot 1.17 and Java 16! + + +**NOTE:** Since the start of the development on v3.3.0, Prison has had a few other releases under v3.2.7 and v3.2.8. The reason for these releases is that the major structures (and code) that would make prison v3.4.x, are not complete. Therefore, to get out new updates sooner than later, v3.2.7 and v3.2.8 have been release. + + +* **Released v3.2.8!** + + +* **v3.2.8-alpha.3 2021-06-16** + + +* **v3.2.8-alpha.2 2021-06-12** + +* **Spigot 1.17 release - v3.2.8-alpha.1 - 2021-06-11** +Only known issues: + * Unable to use nms to get the player's preferred language + +* **v3.2.8-alpha.1 2021-06-07** +Internally set the version, but will not release it until a few other things are finished. +The prison version is set to 3.2.8-alpha.1 to prepare for the release of prison that is compatible with Java 16 and Spigot 1.17. + + +NOTE: v3.2.8-alpha.1 is identical to v3.3.0-alpha.6. V3.3.0 is far from being ready to be released. So v3.2.8 will enable Java 16 and also Minecraft 1.17. + + +# v3.3.0-alpha.6 2021-06-07 + + +* **v3.3.0-alpha.6 2021-06-07** +Setting the version. The v3.3.0 release will be put on hold since focus will be to get v3.2.8 out which will support Java 16. It is unknown how many of the spigot 1.17 blocks will be initially supported. + +* **v3.3.0-alpha.5c - 2021-06-06** + +* **v3.3.0-alpha.5 2021-06-01** + +* **v3.3.0-alpha.4 2021-05-15** + + +* Next release will be v3.3.0-alpha.3 +Please note that the correct order of releases have been: +v3.2.6, v3.3.0-alpha.1, v3.3.0-alpha.2, v3.2.7, v3.3.0-alpha.3 + + +# v3.2.7 2021-05-02 + + +* **Set version to v3.2.7** + - Note that all changes that were made under v3.3.0-alpha.1 and v3.3.0-alpha.2 have been publicly released under v3.2.7 + + +* **3.3.0-alpha.2 2021-04-23** + + +* **v3.3.0-alpha.1 2021-04-16** + + +* **v3.3.0-alpha.0 2021-04-11** + + Start on the alpha.1 release. + diff --git a/docs/prison_changelog_v3.2.2.md b/docs/prison_changelog_v3.2.2.md index 888472113..2a96ef698 100644 --- a/docs/prison_changelog_v3.2.2.md +++ b/docs/prison_changelog_v3.2.2.md @@ -3,17 +3,10 @@ # Prison Build Logs for v3.2.2 - 2020-11-21 ## Build logs - - **[v3.3.x - Current](changelog_v3.3.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)**   -**[v3.2.3 - 2020-12-25](prison_changelog_v3.2.3.md)**   -**[v3.2.4 - 2021-03-01](prison_changelog_v3.2.4.md)**   -**[v3.2.5 - 2021-04-01](prison_changelog_v3.2.5.md)**   -**[v3.2.6 - 2021-04-11](prison_changelog_v3.2.6.md)**   -**[v3.2.7 - 2021-05-02](prison_changelog_v3.2.7.md)**   -**[v3.2.8 - 2021-06-17](prison_changelog_v3.2.8.md)**   -**[v3.2.9 - 2021-07-03](prison_changelog_v3.2.9.md)** + - **[v3.3.0-alpha - Current](changelog_v3.3.x.md)** + - [v3.2.0 through v3.2.10](prison_changelogs.md) + + Greetings! I'm delighted that you are interested in the build logs for the diff --git a/docs/prison_changelog_v3.2.3.md b/docs/prison_changelog_v3.2.3.md index e8b6f8226..91096150d 100644 --- a/docs/prison_changelog_v3.2.3.md +++ b/docs/prison_changelog_v3.2.3.md @@ -3,17 +3,10 @@ ## Prison Build Logs for v3.2.3 - 2020-12-25 ## Build logs - - **[v3.3.x - Current](changelog_v3.3.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)**   -**[v3.2.3 - 2020-12-25](prison_changelog_v3.2.3.md)**   -**[v3.2.4 - 2021-03-01](prison_changelog_v3.2.4.md)**   -**[v3.2.5 - 2021-04-01](prison_changelog_v3.2.5.md)**   -**[v3.2.6 - 2021-04-11](prison_changelog_v3.2.6.md)**   -**[v3.2.7 - 2021-05-02](prison_changelog_v3.2.7.md)**   -**[v3.2.8 - 2021-06-17](prison_changelog_v3.2.8.md)**   -**[v3.2.9 - 2021-07-03](prison_changelog_v3.2.9.md)** + - **[v3.3.0-alpha - Current](changelog_v3.3.x.md)** + - [v3.2.0 through v3.2.10](prison_changelogs.md) + + Greetings! I'm delighted that you are interested in the build logs for the diff --git a/docs/prison_changelog_v3.2.4.md b/docs/prison_changelog_v3.2.4.md index 965b3c5a3..7c6109411 100644 --- a/docs/prison_changelog_v3.2.4.md +++ b/docs/prison_changelog_v3.2.4.md @@ -3,17 +3,10 @@ ## Prison Build Logs for v3.2.4 - 2021-03-01 ## Build logs - - **[v3.3.x - Current](changelog_v3.3.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)**   -**[v3.2.3 - 2020-12-25](prison_changelog_v3.2.3.md)**   -**[v3.2.4 - 2021-03-01](prison_changelog_v3.2.4.md)**   -**[v3.2.5 - 2021-04-01](prison_changelog_v3.2.5.md)**   -**[v3.2.6 - 2021-04-11](prison_changelog_v3.2.6.md)**   -**[v3.2.7 - 2021-05-02](prison_changelog_v3.2.7.md)**   -**[v3.2.8 - 2021-06-17](prison_changelog_v3.2.8.md)**   -**[v3.2.9 - 2021-07-03](prison_changelog_v3.2.9.md)** + - **[v3.3.0-alpha - Current](changelog_v3.3.x.md)** + - [v3.2.0 through v3.2.10](prison_changelogs.md) + + Greetings! I'm delighted that you are interested in the build logs for the diff --git a/docs/prison_changelog_v3.2.5.md b/docs/prison_changelog_v3.2.5.md index bceaddfd1..2de584ebf 100644 --- a/docs/prison_changelog_v3.2.5.md +++ b/docs/prison_changelog_v3.2.5.md @@ -3,17 +3,10 @@ ## Prison Build Logs for v3.2.5 - 2021-04-01 ## Build logs - - **[v3.3.x - Current](changelog_v3.3.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)**   -**[v3.2.3 - 2020-12-25](prison_changelog_v3.2.3.md)**   -**[v3.2.4 - 2021-03-01](prison_changelog_v3.2.4.md)**   -**[v3.2.5 - 2021-04-01](prison_changelog_v3.2.5.md)**   -**[v3.2.6 - 2021-04-11](prison_changelog_v3.2.6.md)**   -**[v3.2.7 - 2021-05-02](prison_changelog_v3.2.7.md)**   -**[v3.2.8 - 2021-06-17](prison_changelog_v3.2.8.md)**   -**[v3.2.9 - 2021-07-03](prison_changelog_v3.2.9.md)** + - **[v3.3.0-alpha - Current](changelog_v3.3.x.md)** + - [v3.2.0 through v3.2.10](prison_changelogs.md) + + Greetings! I'm delighted that you are interested in the build logs for the diff --git a/docs/prison_changelog_v3.2.6.md b/docs/prison_changelog_v3.2.6.md index f6cef5755..4eb6a3417 100644 --- a/docs/prison_changelog_v3.2.6.md +++ b/docs/prison_changelog_v3.2.6.md @@ -3,17 +3,10 @@ ## Prison Build Logs for v3.2.5 - 2021-04-01 ## Build logs - - **[v3.3.x - Current](changelog_v3.3.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)**   -**[v3.2.3 - 2020-12-25](prison_changelog_v3.2.3.md)**   -**[v3.2.4 - 2021-03-01](prison_changelog_v3.2.4.md)**   -**[v3.2.5 - 2021-04-01](prison_changelog_v3.2.5.md)**   -**[v3.2.6 - 2021-04-11](prison_changelog_v3.2.6.md)**   -**[v3.2.7 - 2021-05-02](prison_changelog_v3.2.7.md)**   -**[v3.2.8 - 2021-06-17](prison_changelog_v3.2.8.md)**   -**[v3.2.9 - 2021-07-03](prison_changelog_v3.2.9.md)** + - **[v3.3.0-alpha - Current](changelog_v3.3.x.md)** + - [v3.2.0 through v3.2.10](prison_changelogs.md) + + Greetings! I'm delighted that you are interested in the build logs for the diff --git a/docs/prison_changelog_v3.2.7.md b/docs/prison_changelog_v3.2.7.md index 79e475028..906d5f13f 100644 --- a/docs/prison_changelog_v3.2.7.md +++ b/docs/prison_changelog_v3.2.7.md @@ -3,17 +3,10 @@ ## Prison Build Logs for v3.2.7 - 2021-05-02 ## Build logs - - **[v3.3.x - Current](changelog_v3.3.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)**   -**[v3.2.3 - 2020-12-25](prison_changelog_v3.2.3.md)**   -**[v3.2.4 - 2021-03-01](prison_changelog_v3.2.4.md)**   -**[v3.2.5 - 2021-04-01](prison_changelog_v3.2.5.md)**   -**[v3.2.6 - 2021-04-11](prison_changelog_v3.2.6.md)**   -**[v3.2.7 - 2021-05-02](prison_changelog_v3.2.7.md)**   -**[v3.2.8 - 2021-06-17](prison_changelog_v3.2.8.md)**   -**[v3.2.9 - 2021-07-03](prison_changelog_v3.2.9.md)** + - **[v3.3.0-alpha - Current](changelog_v3.3.x.md)** + - [v3.2.0 through v3.2.10](prison_changelogs.md) + + Greetings! I'm delighted that you are interested in the build logs for the diff --git a/docs/prison_changelog_v3.2.8.md b/docs/prison_changelog_v3.2.8.md index 501892f8c..e974d733d 100644 --- a/docs/prison_changelog_v3.2.8.md +++ b/docs/prison_changelog_v3.2.8.md @@ -3,17 +3,10 @@ ## Prison Build Logs for v3.2.8 - 2021-06-17 ## Build logs - - **[v3.3.x - Current](changelog_v3.3.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)**   -**[v3.2.3 - 2020-12-25](prison_changelog_v3.2.3.md)**   -**[v3.2.4 - 2021-03-01](prison_changelog_v3.2.4.md)**   -**[v3.2.5 - 2021-04-01](prison_changelog_v3.2.5.md)**   -**[v3.2.6 - 2021-04-11](prison_changelog_v3.2.6.md)**   -**[v3.2.7 - 2021-05-02](prison_changelog_v3.2.7.md)**   -**[v3.2.8 - 2021-06-17](prison_changelog_v3.2.8.md)**   -**[v3.2.9 - 2021-07-03](prison_changelog_v3.2.9.md)** + - **[v3.3.0-alpha - Current](changelog_v3.3.x.md)** + - [v3.2.0 through v3.2.10](prison_changelogs.md) + + Greetings! I'm delighted that you are interested in the build logs for the diff --git a/docs/prison_changelog_v3.2.9.md b/docs/prison_changelog_v3.2.9.md index fe3009922..d0d42260e 100644 --- a/docs/prison_changelog_v3.2.9.md +++ b/docs/prison_changelog_v3.2.9.md @@ -3,17 +3,10 @@ ## Prison Build Logs for v3.2.9 - 2021-07-03 ## Build logs - - **[v3.3.x - Current](changelog_v3.3.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)**   -**[v3.2.3 - 2020-12-25](prison_changelog_v3.2.3.md)**   -**[v3.2.4 - 2021-03-01](prison_changelog_v3.2.4.md)**   -**[v3.2.5 - 2021-04-01](prison_changelog_v3.2.5.md)**   -**[v3.2.6 - 2021-04-11](prison_changelog_v3.2.6.md)**   -**[v3.2.7 - 2021-05-02](prison_changelog_v3.2.7.md)**   -**[v3.2.8 - 2021-06-17](prison_changelog_v3.2.8.md)**   -**[v3.2.9 - 2021-07-03](prison_changelog_v3.2.9.md)** + - **[v3.3.0-alpha - Current](changelog_v3.3.x.md)** + - [v3.2.0 through v3.2.10](prison_changelogs.md) + + Greetings! I'm delighted that you are interested in the build logs for the @@ -29,6 +22,8 @@ that you need. ### v3.2.9 Release Highlights +v3.2.9 - Prison Update - Enhancements to blockEvents, placeholders, support, and events + * Prison now has new commands to help provide better support and can be found under: /prison support These commands will be expanded to help make it a lot easier to get help on many issues that could be configuration based. Prison is now able to help sent some information to https://paste.helpch.at. These tools also cleans up a lot junk in the log messages so they are easier to read. diff --git a/docs/prison_changelogs.md b/docs/prison_changelogs.md new file mode 100644 index 000000000..90e81a861 --- /dev/null +++ b/docs/prison_changelogs.md @@ -0,0 +1,22 @@ +[Prison Documents - Table of Contents](prison_docs_000_toc.md) + +## Prison Build Logs for v3.3.x + +## Build logs + - **[v3.3.0-alpha - Current](changelog_v3.3.x.md)** + - [v3.2.0 - 2019-12-03](prison_changelog_v3.2.0.md)   +[v3.2.1 - 2020-09-27](prison_changelog_v3.2.1.md)   +[v3.2.2 - 2020-11-21](prison_changelog_v3.2.2.md)   +[v3.2.3 - 2020-12-25](prison_changelog_v3.2.3.md)   +[v3.2.4 - 2021-03-01](prison_changelog_v3.2.4.md)   +[v3.2.5 - 2021-04-01](prison_changelog_v3.2.5.md)   +[v3.2.6 - 2021-04-11](prison_changelog_v3.2.6.md)   +[v3.2.7 - 2021-05-02](prison_changelog_v3.2.7.md)   +[v3.2.8 - 2021-06-17](prison_changelog_v3.2.8.md)   +[v3.2.9 - 2021-07-03](prison_changelog_v3.2.9.md)   +[v3.2.10 - 2021-08-23](prison_changelog_v3.2.10.md) + + +These build logs represent the work that has been going on within prison. + + diff --git a/docs/prison_docs_000_toc.md b/docs/prison_docs_000_toc.md index fe5015c3f..7f2aac8bc 100644 --- a/docs/prison_docs_000_toc.md +++ b/docs/prison_docs_000_toc.md @@ -7,7 +7,7 @@ * **[Prison README](prison_readme.md)** High level information, plus how to use with gradle builds. * **[Prison License](prison_license.md)** GNU General Public License -* **[Prison Change logs](changelog_v3.3.x.md)** Detailed changes to prison. +* **[Prison Change logs](prison_changelogs.md)** Detailed changes to prison. * **[Prison Known Issues](knownissues_v3.3.x.md)** Known Issues and To Do's. * **[Prison Discord Server](https://discord.gg/DCJ3j6r)** Get help here. @@ -16,24 +16,16 @@ ## Build logs - - **[v3.3.0.alpha.3 - Current](changelog_v3.3.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)**   -**[v3.2.3 - 2020-12-25](prison_changelog_v3.2.3.md)**   -**[v3.2.4 - 2021-03-01](prison_changelog_v3.2.4.md)**   -**[v3.2.5 - 2021-04-01](prison_changelog_v3.2.5.md)**   -**[v3.2.6 - 2021-04-11](prison_changelog_v3.2.6.md)**   -**[v3.2.7 - 2021-05-02](prison_changelog_v3.2.7.md)**   -**[v3.2.8 - 2021-06-17](prison_changelog_v3.2.8.md)**   -**[v3.2.9 - 2021-07-03](prison_changelog_v3.2.9.md)** + - **[v3.3.0-alpha - Current](changelog_v3.3.x.md)** + - [v3.2.0 through v3.2.10](prison_changelogs.md) +
-# Prison Now Fully Supports Spigot 1.17 and Java 16 !! +# Prison Now Fully Supports Spigot 1.17.1 and Java 16 !! ## Prison now has Access By Rank to Reduce the number of Permissions needed! @@ -45,28 +37,48 @@ [Prison Auto Configure / Prison Quick Start!](prison_docs_100_setting_up_auto_configure.md) -Prison now has a new set of features that can help you get up and running faster than ever! +Prison now has a new set of features that can help you get up and running faster than ever! With the latest version of Prison, you can even have a functional Prison server running with just two Prison commands. See below for more information. + + +**It is strongly recommended that the '/ranks autoConfigure' should always be ran first.** Prison's Auto Configure sets up so many features, that it can help resolve many initial issues. Before you try to setup Prison, you really need to install an Economy or the Ranks module will not be enabled. It is strongly suggested you install the following plugins: Vault, EssentialsX, EssentialsX-Chat, PlaceholderAPI, LuckPerms, WorldEdit, WorldGuard (or Fast Async World Edit, FAWE, on newer versions of Spigot). -`/ranks autoConfigure`. It can auto create your ranks and virtual mines, A through Z, it will link the mines to the ranks, setup the Mine Access By Rank and TP Access By Rank. It will also setup the Mine as a Virtual Mine will and assign blocks of increasing values to all mines. Each mine will also be assigned a random liner. The Ranks autoConfigure will also enable sellall and load over 90 default blocks for your shop. +`/ranks autoConfigure`. It can auto create your ranks and virtual mines, A through Z, it will link the mines to the ranks, setup the Mine Access By Rank and TP Access By Rank. It will also setup the Mine as a Virtual Mine will and assign blocks of increasing values to all mines. Each mine will also be assigned a random liner. The Ranks autoConfigure will also enable sellall and load over 90 default blocks for your shop. Auto features will be enabled (auto pickup, auto smelt, and auto blocking). + +Some of the newer features that are enabled with `/ranks autoConfigure` are: Ladder Base Rank Cost Multiplier (ranks cost more every time you prestige), auto configure 10 prestige levels, and improved placement of the mine. Based upon where you are standing, you can now define both the location of the mine, and the size. Once it generates all the virtual mines, all you need to do is to use the command `/mines set area help` on all mines to make them physical mines and then prison will be ready to use. Plus there are many new features to help provide the finishing touches in almost no time. +Auto configure can get you up and running with as little as two commands. The first command is: `/ranks autoConfigure`. Then the second command you run while you are in game, and it defines the mine for you in the world. It's based upon where you are standing to make it "simple": `/mines set area A feet 10 6`. This last command tells prison to place the mine at your feet and to expand the walls outward by 10 blocks in all directions, and push the bottom of the mine down by 6 blocks. The result will be a mine that is 21 x 21 x 7. + + - `/ranks autoConfigure` + - `/mines set area a feet 10 6` + + At this point you have a 1 mine functional prison server. Of course you will want to add more mines, but this is a quick overview of the basics on getting up and running. + + + To see the blocks at this point, just reset the mine: + + - `/mines reset a` + + Then to protect the world so players cannot break your builds, you need to setup a global WorldGuard region for that world: + + - `/rg flag __global__ -w world passthrough deny` + + + For more information, check out the following commands. + - `/mines set area help` - `/mines set tracer help` - `/mines set size help` - `/mines set liner help` - To protect your world, you need to use the following WorldGuard command: - - ``` -/rg flag __global__ passthrough deny - ``` + [Prison Auto Configure / Prison Quick Start Guide!](prison_docs_100_setting_up_auto_configure.md) @@ -113,7 +125,7 @@ Once it generates all the virtual mines, all you need to do is to use the comman **RANKS COMMANDS**: - [/ranks autoConfigure \[arg\] \[startPrice\] \[multiplier\] ](docs-commands/prison_docs_command_42_ranks_autoconfigure.md) `ranks.set` -- [/ranks \[ladder\] ](docs-commands/prison_docs_command_11_ranks.md) `ranks.admin` +- /ranks \[ladder\] `ranks.admin` - [/ranks command](docs-commands/prison_docs_command_12_ranks_command.md) `prison.alerts` - [/ranks create \[rankName\] \[cost\] \[ladder\] \[tag\] ](docs-commands/prison_docs_command_13_ranks_create.md) `ranks.create` - [/ranks delete \[rankName\] ](docs-commands/prison_docs_command_14_ranks_delete.md) `ranks.delete` @@ -128,29 +140,30 @@ Once it generates all the virtual mines, all you need to do is to use the comman **MINES COMMANDS: _Guidebook TO-DO_** (Work-In-Progress) -- [/mines](docs-commands/prison_docs_command_23_mines.md) `mines.admin` -- [/mines block](docs-commands/prison_docs_command_24_mines_block.md) `mines.admin` -- [/mines command](docs-commands/prison_docs_command_25_mines_command.md) `mines.admin` -- [/mines create \[mineName\] ](docs-commands/prison_docs_command_26_mines_create.md) `mines.create` -- [/mines delete \[mineName\] \[confirm\] ](docs-commands/prison_docs_command_27_mines_delete.md) `mines.delete` -- [/mines info \[mineName\] \[page\] ](docs-commands/prison_docs_command_28_mines_info.md) `mines.info` -- [/mines list \[page\] ](docs-commands/prison_docs_command_29_mines_list.md) `mines.list` -- [/mines rename \[page\] ](docs-commands/prison_docs_command_41_mines_rename.md) `mines.rename` -- [/mines reset \[mineName\] ](docs-commands/prison_docs_command_30_mines_reset.md) `mines.reset` -- [/mines set](docs-commands/prison_docs_command_31_mines_set.md) `mines.admin` -- [/mines stats](docs-commands/prison_docs_command_32_mines_stats.md) `mines.stats` -- [/mines tp \[mineName\] ](docs-commands/prison_docs_command_33_mines_tp.md) `mines.tp` `mines.tp.[mineName]` -- [/mines wand](docs-commands/prison_docs_command_34_mines_wand.md) `mines.wand` -- [/mines whereami](docs-commands/prison_docs_command_35_mines_whereami.md) `mines.whereami` +- /mines `mines.admin` +- /mines blockEvents +- /mines block `mines.admin` +- /mines command `mines.admin` +- /mines create \[mineName\] `mines.create` +- /mines delete \[mineName\] \[confirm\] `mines.delete` +- /mines info \[mineName\] \[page\] `mines.info` +- /mines list \[page\] `mines.list` +- /mines rename \[page\] `mines.rename` +- /mines reset \[mineName\] `mines.reset` +- /mines set `mines.admin` +- /mines stats `mines.stats` +- /mines tp \[mineName\] `mines.tp` `mines.tp.[mineName]` +- /mines wand `mines.wand` +- /mines whereami `mines.whereami` **MORE COMMANDS: _Guidebook TO-DO_** (Work-In-Progress) -- [/sellall](docs-commands/prison_docs_command_10_sellall.md) `prison.admin` `none for GUI` -- [/prisonmanager](docs-commands/prison_docs_command_36_prisonmanager.md) `prison.admin for Admin GUI` `none for Players GUIs` -- [/prestiges](docs-commands/prison_docs_command_37_prestiges.md) `none` -- [/prestige](docs-commands/prison_docs_command_38_prestige.md) `ranks.user` `ranks.rankup.prestiges` -- [/rankupMax \[ladder\]](docs-commands/prison_docs_command_39_rankupmax.md) `ranks.user` `ranks.rankupmax` `ranks.rankupmax.[ladderName]` -- [/rankup \[ladder\]](docs-commands/prison_docs_command_40_rankup.md) `ranks.user` `ranks.rankup.[ladderName]` +- /sellall `prison.admin` `none for GUI` +- /prisonmanager `prison.admin for Admin GUI` `none for Players GUIs` +- /prestiges `none` +- /prestige `ranks.user` `ranks.rankup.prestiges` +- /rankupMax \[ladder\] `ranks.user` `ranks.rankupmax` `ranks.rankupmax.[ladderName]` +- /rankup \[ladder\] `ranks.user` `ranks.rankup.[ladderName]` - /gui \[gui\] - [/backpack](docs-commands/prison_docs_command_43_backpack.md) diff --git a/docs/prison_docs_012_setting_up_prison_basics.md b/docs/prison_docs_012_setting_up_prison_basics.md index b95d176f0..35b801f3b 100644 --- a/docs/prison_docs_012_setting_up_prison_basics.md +++ b/docs/prison_docs_012_setting_up_prison_basics.md @@ -12,6 +12,7 @@ This document provides a quick overview on how to install Prison and get it runn # Download Prison + Download Prison from one of the following sites: * [spigotmc.org's Prison History Page](https://www.spigotmc.org/resources/prison.1223/history). * [Polymart.org](https://polymart.org/resource/prison-1-8-x-1-17.678) @@ -21,12 +22,10 @@ Download Prison from one of the following sites: Setting up Prison is simple: -* 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 if needed - - Choose the latest version to download - +* **Download Prison - Current Releases** + - Prison's published releases + + * **Download Prison's Pre-Release Version** - Useful to access newer features and fixes - You can always find the latest alpha build on the Discord Server in the #alpha-versions channel: @@ -40,7 +39,11 @@ Setting up Prison is simple: * Prison's startup information contains a lot of information. If you ever have issues, check that information first since it probably will identify what the issues are. -* Follow Prison's documentation on customization, but at this point it's ready for use. + +* It is strongly suggested that `/ranks autoConfigure` is ran to initially setup your Prison environment. + + +* Follow Prison's documentation on customization; at this point it's ready for use.
@@ -134,7 +137,7 @@ It should also be noted that because of some of the limitations of MVdW, not all * **WorldGuard** - Recommended - Used to protect your worlds. At a minimum setup the `__global__` region to protect your world from players. ``` -/rg flag __global__ passthrough deny +/rg flag __global__ -w world passthrough deny ``` @@ -156,6 +159,9 @@ It should also be noted that because of some of the limitations of MVdW, not all [https://polymart.org/resource/tokenenchant-1-7-10-1-17.155](https://polymart.org/resource/tokenenchant-1-7-10-1-17.155) +* **Prison Enchants** Newest supported enchantment plugin supported. More information will be added soon. + + * **Crazy Enchantments** - Optional - Some support is provided for Crazy Enchantments, but it may not be at 100% in all areas. This is an open source project and supports Spigot 1.8 through 1.16. [https://www.spigotmc.org/resources/crazy-enchantments.16470/](https://www.spigotmc.org/resources/crazy-enchantments.16470/) @@ -178,6 +184,9 @@ If you purchase this plugin to use on your server, do so with great caution sinc * **AnimatedScoreboard** - Optional - Scoreboard +* **Scoreboard-revision** - Optional - Scoreboard - NOTE: This is buggy if a color code falls in a certain area of the scoreboard. If you see glitches, you may be able to add a space or character before the placeholder. Such a fix may not always work though. + + * **TAB** - Optional - Tab Menu diff --git a/docs/prison_docs_100_setting_up_auto_configure.md b/docs/prison_docs_100_setting_up_auto_configure.md index f665a4470..af084e7db 100644 --- a/docs/prison_docs_100_setting_up_auto_configure.md +++ b/docs/prison_docs_100_setting_up_auto_configure.md @@ -14,6 +14,7 @@ This document provides information on how to get started quickly using Prison's This document covers how to run `/ranks autoConfigure`, it's options, and what to do after the command runs. + Prison's Auto Configure will perform most of the basic configurations to get you up and running quickly. This feature will perform the following tasks for you: @@ -29,16 +30,23 @@ Prison's Auto Configure will perform most of the basic configurations to get you * Auto Configure now uses a new feature called Access by Rank. This is automatically enabled for Mine Access and Access to TP for the players. Access by Rank eliminates the need to use perms for these access. As a player ranks up, they will gain access to ranks and mines, but all prior ranks and mines will automatically be included. +* Auto assign random Mine Liners to each mine. + + +* Auto generate 10 Prestige Ranks and have them enabled by default. + + +* Enable Ladder Base Rank Cost Multiplier for the Prestiges ladder. Once a player prestiges, this will enable a rank cost multiplier that will increase all rank cost. As the player ranks upon the prestiges ladder, the rank costs will increase. + + * Enable Prison's Sellall feature and preload the default shop prices with about 98 items and blocks. These defaults settings will allow your players to sell what they mine. * Enable Prison's Auto Features. This includes, by default, auto pickup, auto smelt, and auto block. It also enables other features such as providing XP for certain blocks, fortune, etc. -* ~~Enable Mine Access Permissions for each mine.~~ ~~The actual commands that are used are based upon the economy plugin that you have installed when you run this command.~~ ~~This allows prison to work with the minimal configurations of external plugins such as WorldGuard; all you need to do is to enable WorldGuard's global region with the flag `passthrough deny`. ~~ Notice: do not use the access by permissions since Access by Rank replaces it, but it can still be used if you want. -* ~~Setup some of the most basic rank commands that will give your players the permissions needed to access the mines associated with their rank, and to TP to those mines.~~ Note: Permissions are no longer setup since prison does not need them for TP or Mine Access. If you need to add any permission you would have to manually add them as usual to either Rank commands, or better yet, ladder commands: `/ranks command add help` and `/ranks ladder command add help`. Both of these have the same extended set of placeholders that can be used and the list can be provided with: `/ranks command add placeholders`. @@ -561,56 +569,6 @@ Note: This list of commands for Rank A is how all the other ranks will look, but [04:21:51 INFO]: Click a command to remove it. [04:21:51 INFO]: * /lp user {player} permission set mines.a [04:21:51 INFO]: * /lp user {player} permission set mines.tp.a -[04:21:51 INFO]: * /lp user {player} permission unset mines.b -[04:21:51 INFO]: * /lp user {player} permission unset mines.tp.b -[04:21:51 INFO]: * /lp user {player} permission unset mines.c -[04:21:51 INFO]: * /lp user {player} permission unset mines.tp.c -[04:21:51 INFO]: * /lp user {player} permission unset mines.d -[04:21:51 INFO]: * /lp user {player} permission unset mines.tp.d -[04:21:51 INFO]: * /lp user {player} permission unset mines.e -[04:21:51 INFO]: * /lp user {player} permission unset mines.tp.e -[04:21:51 INFO]: * /lp user {player} permission unset mines.f -[04:21:51 INFO]: * /lp user {player} permission unset mines.tp.f -[04:21:51 INFO]: * /lp user {player} permission unset mines.g -[04:21:51 INFO]: * /lp user {player} permission unset mines.tp.g -[04:21:51 INFO]: * /lp user {player} permission unset mines.h -[04:21:51 INFO]: * /lp user {player} permission unset mines.tp.h -[04:21:51 INFO]: * /lp user {player} permission unset mines.i -[04:21:51 INFO]: * /lp user {player} permission unset mines.tp.i -[04:21:51 INFO]: * /lp user {player} permission unset mines.j -[04:21:51 INFO]: * /lp user {player} permission unset mines.tp.j -[04:21:51 INFO]: * /lp user {player} permission unset mines.k -[04:21:51 INFO]: * /lp user {player} permission unset mines.tp.k -[04:21:51 INFO]: * /lp user {player} permission unset mines.l -[04:21:51 INFO]: * /lp user {player} permission unset mines.tp.l -[04:21:51 INFO]: * /lp user {player} permission unset mines.m -[04:21:51 INFO]: * /lp user {player} permission unset mines.tp.m -[04:21:51 INFO]: * /lp user {player} permission unset mines.n -[04:21:51 INFO]: * /lp user {player} permission unset mines.tp.n -[04:21:51 INFO]: * /lp user {player} permission unset mines.o -[04:21:51 INFO]: * /lp user {player} permission unset mines.tp.o -[04:21:51 INFO]: * /lp user {player} permission unset mines.p -[04:21:51 INFO]: * /lp user {player} permission unset mines.tp.p -[04:21:51 INFO]: * /lp user {player} permission unset mines.q -[04:21:51 INFO]: * /lp user {player} permission unset mines.tp.q -[04:21:51 INFO]: * /lp user {player} permission unset mines.r -[04:21:51 INFO]: * /lp user {player} permission unset mines.tp.r -[04:21:51 INFO]: * /lp user {player} permission unset mines.s -[04:21:51 INFO]: * /lp user {player} permission unset mines.tp.s -[04:21:51 INFO]: * /lp user {player} permission unset mines.t -[04:21:51 INFO]: * /lp user {player} permission unset mines.tp.t -[04:21:51 INFO]: * /lp user {player} permission unset mines.u -[04:21:51 INFO]: * /lp user {player} permission unset mines.tp.u -[04:21:51 INFO]: * /lp user {player} permission unset mines.v -[04:21:51 INFO]: * /lp user {player} permission unset mines.tp.v -[04:21:51 INFO]: * /lp user {player} permission unset mines.w -[04:21:51 INFO]: * /lp user {player} permission unset mines.tp.w -[04:21:51 INFO]: * /lp user {player} permission unset mines.x -[04:21:51 INFO]: * /lp user {player} permission unset mines.tp.x -[04:21:51 INFO]: * /lp user {player} permission unset mines.y -[04:21:51 INFO]: * /lp user {player} permission unset mines.tp.y -[04:21:51 INFO]: * /lp user {player} permission unset mines.z -[04:21:51 INFO]: * /lp user {player} permission unset mines.tp.z [04:21:51 INFO]: [+] Add > ``` @@ -686,8 +644,14 @@ To convert the virtual mines you need to define mine's area. There are two prim Use your feet - seriously ;) - Stand where you want the mine. Or if it is a void world, fly to the position. -- `/mines set area feet` -- This will create a 1x1x1 mine located at your feet. It will include the liner. +- `/mines set area feet 20 7` +- This will initially create a 1x1x1 mine located at your feet along with the liner. +- The keyword `feet` identifies that the coordinates for the location of the mine is based upon your feet location. +- The first number, 20, is used to expand the walls by 20 blocks in all directions. The result will be a mine with a width of 41 and a depth of 41 blocks. +- The second number, 7, indicates the increase of the bottom of the mine. The result will be a mine with a depth of 8 blocks (1 block for the initial size, plus 8 more). + + +This one command actually runs the next two commands automatically: - `/mines set size wall 20` @@ -696,13 +660,14 @@ Use your feet - seriously ;) - If a void world, you may need to `force` the liner. Now would also be a good time to change it if you wish. -- `/mines set liner ?` +- `/mines set liner ?` - Will show all available edges and patterns. - **Available Edges: [top bottom north east south west walls]** - - **Available Patterns: [bright white blackAndWhite seaEchos obby bedrock glowingPlanks darkOakPrismarine beacon bricked repair remove removeAll]** + - **Available Patterns for spigot 1.8.8: [bright white blackAndWhite seaEchos obby bedrock glowstone glowingPlanks darkOakPrismarine beacon bricked darkForest theColors repair remove removeAll]** - `/mines set liner walls bright force` - `/mines set liner bottom seaEchos force` +Note: You can also set the ladder widths. Please use the 'help' keyword for more information. diff --git a/docs/prison_docs_102_setting_up_ranks.md b/docs/prison_docs_102_setting_up_ranks.md index 31b079bcc..947929327 100644 --- a/docs/prison_docs_102_setting_up_ranks.md +++ b/docs/prison_docs_102_setting_up_ranks.md @@ -337,7 +337,7 @@ The following commands are intended for the use of admins only. They are to be /ranks set rank [playerName] [rankName] [ladder] /ranks set rank [playerName] -remove- [ladder] -/ranks remove rank [playerName] [ladder] +/ranks removeRank [playerName] [ladder] /ranks promote help /ranks demote help @@ -360,7 +360,7 @@ The parameter **ladder** is optional, and if not specified will default to the ` The parameter **rankName** is required and identifies what rank to set the player to. If there is more than one level of promotion or demotion, then there is a risk of corruption of the player's rank and missing permissions with promotions, or permissions the player should not have access to with demotions. -For the command `/ranks set rank` the parameter for **rankName** can be set to a value of `-remove-` to remove the player from the specified ladder. An alias for this command is `/ranks remove rank [player] [ladder]`. +For the command `/ranks set rank` the parameter for **rankName** can be set to a value of `-remove-` to remove the player from the specified ladder. An alias for this command is `/ranks removeRank [player] [ladder]`. The parameter **chargePlayers** will require that the player has enough of the specific currency for promotions, and will subtract that amount from their bank balance. If they do not have enough funds, then they will not be ranked up, just as if they ran the command. If the player is being demoted and this parameter is used, then the player will be issued a refund for the prior rank. diff --git a/docs/prison_docs_626_configuring_worldguard_regions.md b/docs/prison_docs_626_configuring_worldguard_regions.md index e191a974b..5eb5c9347 100644 --- a/docs/prison_docs_626_configuring_worldguard_regions.md +++ b/docs/prison_docs_626_configuring_worldguard_regions.md @@ -4,37 +4,60 @@ ## Configuring and Using WorldGuard with LuckPerms to Protect Mines -This document explains how to setup WorldGuard to protect your mines and how to prevent players from accessing it when they don't have the correct permissions. It also explains how to setup the permissions in the Prison's **/ranks command add -# Please READ This First +# Please READ This First - Using Access by Ranks to Simplify Many Things -As of Prison v3.2.5 (or v3.2.5-alpha.14 for pre-releases) there is a much easier way to setup mines to prevent access and to grant access to mines. The new feature uses the command `/mines set accessPermission help`. -Outline on what to do is as follows: +The latest versions of Prison has a new feature called **Access by Ranks** where a player, based upon their rank, is able to access a mine (break blocks within a mine) and also they can use the `/mtp` feature (mines teleport). By using **Access by Ranks** you do not have to setup any WorldGuard regions to allow players to break blocks within the mines, and you don't have to setup any permissions. -* Setup a WorldGuard __global__ region as defined just below. Must enable the flag `passthrough deny`. -* For each mine, add a permission to access the mine with `/mines set accessPermission help` -* For each rank's rankup command tasks, make sure the permission is given to the players as specified with the `set accessPermisson` command. + +How to use Access by Ranks: + +* Setup a WorldGuard __global__ region as defined below. That global region must enable the flag `passthrough deny`. + +* Then setup prison using `/ranks autoConfigure` since it will link mines to ranks, and enable the Access by Rank features. You are done. -**Note:** You do not need to set any WorldGuard regions for the mines. - -**Note:** You can still setup WorldGuard regions to keep out non-players. +If you need to manually setup Access By Ranks: +* Link mines to the ranks: `/mines set rank help` +* For each mine, enable this feature `/mines set mineAccessByRank help` +* To grant TP access for the players, then also enable `/mines set tpAccessByRank help`. -As of Prison v3.2.7 (or v3.2.6-alpha.2) you can now change the priority of prison's event listeners for BlockBreakEvents and explosion events. -Please see the `autoFeaturesConfig.yml` configuration file to make changes. Prison is using the default value of `LOW`, but if you need to make adjustments, you can do so under the group `options.blockBreakEvents` as listed below. + +**Note:** You can setup WorldGuard regions to keep out non-players from the surrounding area around a mine. Access by Rank does not prevent non-members from walking to a mine. + + +**Note:** As a fallback, you can use **Access by Permissions** which requires more setup and figuring out how to use the perms. But you do not have to define any WorldGuard regions to allow players to break blocks. See the command `/mines set accessPermission help` for more information. NOTE: This is not recommended since it's a more complex configuration process than Access by Ranks. + + +
+ + +# Prison's Event Priorities and WorldGuard Regions + + +**NOTE:** You can also grant access through WorldGuard regions, and then prison will allow anyone to break blocks in the mines. The catch is that you must ensure WorldGuard checks access prior to Prison getting control of the BlockBreakEvents. This requires setting up WorldGuard regions and permissions. + + +**WARNING:** **This is beyond the scope of what prison will provide support** since we highly recommend using **Access by Ranks**, or as a secondary option, Access by Permissions. Too many users have had problems getting WorldGuard to work properly with their permission plugins and with prison, that this way of granting players access to mine blocks is not supported by Prison any longer. You can still do it this way, but you are on your own. + + +If you will be setting up WorldGuard regions to permit block breakage, then keep in mind that as of Prison v3.2.7 you can now change the priority of prison's event listeners for BlockBreakEvents and explosion events. This can help you fine tune the use of the events. + + +Please see the `autoFeaturesConfig.yml` configuration file to make changes. Prison is using the default value of `LOW`, but if you need to make adjustments, you can do so under the group `options.blockBreakEvents` as listed below (which is out of date, please see the configuration file that ships with your version of Prison): ``` @@ -61,18 +84,26 @@ You cannot set any of the above event priorities to MONITOR since that goes agai -# Please READ This Second +# Please READ This Next This document is a work in progress. This is a complex topic and depending upon how your environment is setup, the actual configurations may need to vary from what's covered in this document. The first attempt at this document tried to use region templates, where a template would define the flags set for each region. That way each mine's specific region would have the template as a parent. Unfortunately, within LuckPerms there is no such thing as a hierarchical permissions, but instead its granted access to all associations. So this design failed because once you gave a player access to mine A, then they would have access to all mines. So if you're thinking about setting up group templates, then you may want to reconsider and do a lot of testing if you use them. + +This document used to go in to detail on how to setup WorldGuard regions to grant players the ability to break blocks. But since that proved numerous times to be confusing, and problematic, Access by Ranks and Access by Perms were added to replace the need to use WorldGuard regions for controlling block breakage. + + +If you decide not to use **Access by Ranks** or not to use **Access by Permissions** then we cannot support you in your setup and configurations. + + +The following document provides *some* information if you want to try to use WG regions, but we make no warranty as to how accurate these documents may be, or how successful you will be.
-# Dependencies +# Other Dependencies * [Install WorldGuard and WorldEdit](prison_docs_026_setting_up_worldguard_worldedit.md) * Install a Permissions Plugin that is compatible with Vault @@ -186,10 +217,12 @@ Note that the **/gamerule doMobSpawning false** may also help prevent mobs from # Various LuckPerm Commands for Templates and Mines +*Not supported - For informational purposes only* + The WorldGuard regions are covered below, but first you need to setup the groups within LuckPerm. Failure to create the groups prior to using them with the regions and prison rank commands may result in failures to work properly. -For prison, we will use the prefix of `prison.mines` so we know what these groups and permissions are related to the mines. +These examples use the prefix of `prison.mines` so we know what these groups and permissions are related to the mines. LuckPerms commands to create a group is as follows. @@ -239,9 +272,7 @@ And to now hook this up to prison, you do same command, dropping the leading sla # Unprotecting a Mine for its members - Required for all Mines - -**Important:** This is not needed if you are using **Mine Access Permissions**: `/mines set accessPermission help`. See the section at the top of this document titled: "Please READ This First". - +*Not supported - For informational purposes only* **Purpose:** This will actually give members the ability to perform mining related tasks within the mine. They need to be able to break the blocks within the mine, and to pickup items, XP, and allows item drops. @@ -254,7 +285,7 @@ This defines a WorldGuard region, and needs to be applied to all mines, unless t Select the same area of the mine with the WorldEdit **wand**, then use the following commands to define a mine. It will define a region with the mine’s name, and set the parent to mine_template, with the only member ever being the permission group **prison.mines.**. Never add a player to a WorldGuard region since it will get messy. Always use permission based groups and then add the player to that group. -In this example I have included an owner of this mine which is group owner. And added the group admin as a member so the admins will have full access to this mine, even if they do not personally have the player's rank to access this mine. The actual members you add are up to you, but these are just two examples that you should consider. +This example includes an owner of this mine which is the group owner. And added the group admin as a member so the admins will have full access to this mine, even if they do not personally have the player's rank to access this mine. The actual members you add are up to you, but these are just two examples that you should consider. /region define prison_mine_ @@ -278,17 +309,15 @@ In this example I have included an owner of this mine which is group owner. And Set the *priority* to a value of 10 to take higher precedence of other lower regions that may overlap. -Please note that with some versions of WorldGuard, such as 1.8.8, there are some blocks that cannot be broken within regions with the use of the **flag block-break allow**. The reasons of why this was setup this way is unknown to myself. Examples of some blocks are **sea_lantern**, **prismarine**, **dark_prismarine**, and other variations of prismarine. In order to break these blocks the **flag build allow** must be used, but then the players are able to place blocks within the mine, which is not usually acceptable. It should also be noted that depending upon how your server is configured prison may also be able to break these blocks within these regions, but if there are issues with these kinds of blocks, then realize the cause is how WorldGuard treats the blocks. +Please note that with some versions of WorldGuard, such as 1.8.8, there are some blocks that cannot be broken within regions with the use of the **flag block-break allow**. The reasons of why this was setup this way is unknown to myself. Examples of some blocks are **sea_lantern**, **prismarine**, **dark_prismarine**, and other variations of prismarine. In order to break these blocks the **flag build allow** must be used, but then the players are able to place blocks within the mine, which is not usually acceptable. It should also be noted that depending upon how your server is configured prison may also be able to break these blocks within these regions, but if there are issues with these kinds of blocks, then realize the cause is how WorldGuard treats the blocks. The following region setting for access and deny may *appear* to be useful, but don't use them. Explanations follow. **Do not use the following:** - ~~/region flag prison_mine_ entry -g nonmembers deny~~ - - ~~/region flag prison_mine_ x allow~~ - ~~/region flag prison_mine_ entry-deny-message You must rank-up to access this mine.~~ + /region flag prison_mine_ entry -g nonmembers deny + /region flag prison_mine_ x allow + /region flag prison_mine_ entry-deny-message You must rank-up to access this mine. -**NOTE:** The use of `~~` above are invalid and are added since markdown documentation *usually* uses them as strike though, but that does not work with github markdown. Nonetheless, i've kept them there just to add emphasis that it's wrong. **NOTE:** @@ -303,6 +332,9 @@ It’s a bad idea to deny access to the mines through these regions. Such as wit # Protecting a Mine's Area - Required for all Mine Areas +*This kind of a region is partially supported. It is used to physically prevent a player from entering an a mine's area.** + + **Purpose:** To keep out all non-members from a mining area. The mining area, as in this context, is the area that immediately surrounds a mine, and generally non-members should not have access to it. @@ -468,236 +500,58 @@ So to recap, for every rank, ideally you should add the new perms for that rank, -# Alternatives -There are many ways to accomplish the same goals and that's what makes Minecraft so versatile and interesting to play. The Prison Plugin does not want to impose a specific way to do most things, since it may not be the ideal way for your sever. - -One of the primary focuses for this document has been protecting the area around your mine to prevent players who should not access the mine, from enter that region. One alternative to needing to protect a mine, would be to limit the access to the mine so it does not have to be protected. One simple way of accomplishing that, is to have the mines in a void world, and then each mine would be a separate island. Then all that would need to be protected, or controlled, would be the warping to that location. - - -
- - - - - -
+# Adding the Prison Rank Commands - Summary of Rank Commands -# WG LP Commands - Overview +This is an example of setting up Rank Commands for mines a and b, we now need to add the Rank Commands to active the permission for both. Also included in these commands are the permissions for the mines.tp command, where mines.tp. is a permission and not a group. -**WARNING:** These sections that are prefixed with "WG LP Commands" are a step-by-step repeat of everything said in this document above, but it's scaled down. - - -These are entered in a step by step process, intended for you to follow. - - -You should be in game when you run these commands, otherwise you may have to specify the world name with almost all LuckPerm commands. When these are converted to scrips, the world parameter will be added. - - -Some code chunks will have **In Game:** which is intended to run from within minecraft. The **Console:** is intended to be ran from the console, where there is no player, so you have to provide the "world". Note that if your world is not named "world" then you will have to change that. If there are any code chunks that are marked as "script" then those provide an example of what kind of placeholders would have to be used. - - -
- - - -## WG LP Commands - Global for whole world (duplicate instructions) - -Run once. - - -In game: - - /rg flag __global__ passthrough deny - - /region flag __global__ mob-spawning deny - /gamerule doMobSpawning false - - -Console: - - /rg flag -w world __global__ passthrough deny - - /region flag -w world __global__ mob-spawning deny - /gamerule doMobSpawning false - - - -
- - - -## WG LP Commands - Setting up LuckPerm Groups - -Run once. You must know what your mines and ranks will be. Mines are just a simple letter like A through Z. The ranks generally have the same name. - - -For the sake of this document we will assume they will range from A to Z, but we will only create permissions and regions for only one mine, a. Be certain to duplicate this for all of the mines that you have. There could be donor mines too, but for now let's ignore those. - -For each mine, there will be - - /lp creategroup prison.mines.a - - /lp creategroup prison.mines.b - - ... - - /lp creategroup prison.mines.z - - - -## WG LP Commands - LuckPerms Adding Permissions to the Groups - -Run once for each mine/rank. - -There will be other permissions that players will require in order to use your server. You can add some of these permissions to the LuckPerm groups so when a player becomes a member of that group, then they will inherit the permissions that are in that group. - -A good example of these permissions are of course rank based, such as access to the mine's warp, or even other permissions that everybody should have. - -In this example we will give the group `prison.mines.a` the standard prison rank related permissions, but also other permissions that everyone should have. - - - /lp group prison.mines.a permission set prison.tp.a - /lp group prison.mines.a permission set prison.gui - /lp group prison.mines.a permission set prison.user - - - /lp group prison.mines.a permission set warp - /lp group prison.mines.a permission set warp.list - /lp group prison.mines.a permission set warp.a - - -You can also add in a lot of EsentialX's permissions to fine tune what your players can do. A nice listing of permissions can be found here: https://essinfo.xeya.me/permissions.html - -Since rank A will always be a permission group all your players have, you can use this group as a container for those permissions. - -Then all other ranks would only need what is required of the new ranks. Such as: - - /lp group prison.mines.b permission set prison.tp.b - /lp group prison.mines.b permission set warp.b - - -
- - - -## WG LP Commands - Creating the Mine's WorldGuard Region - - -**Important:** This step is not needed if you are using **Mine Access Permissions**. - - -You can either use the worldEdit wand to select what you want to set as a region, or you can use other WorldEdit features to set them. - - -These are a WorldEdit method that can be used in game if you know the x, y, z coordinate. This will not work with scripting because you cannot specify the world to apply it to. - - - //pos1 x, y, z - //pos2 x, y, z +For rank a: - -Once you have a WorldEdit selection then you can create a WorldGuard region. + /ranks command add a lp user {player} parent add prison.mines.a + /ranks command add a lp user {player} parent remove prison.mines.b + /ranks command add a lp user {player} permission set mines.tp.a true + /ranks command add a lp user {player} permission unset mines.tp.b - /region define prison_mine_a - /region setpriority prison_mine_a 10 - - /region flag prison_mine_a block-break -g members allow - - /region flag prison_mine_a item-pickup -g members allow - /region flag prison_mine_a exp-drops -g members allow - /region flag prison_mine_a item-drop -g members allow - - /region addmember prison_mine_a g:prison.mines.a +For rank b: -*Optional:* + /ranks command add b lp user {player} parent add prison.mines.b + /ranks command add b lp user {player} parent remove prison.mines.c + /ranks command add b lp user {player} permission set mines.tp.b true + /ranks command add b lp user {player} permission unset mines.tp.c - /region addowner prison_mine_a g:owner - /region addmember prison_mine_a g:admin - +And that's it! Just repeat for all your other mines. -Repeat the same for mine b. -
+
-## WG LP Commands - Creating the Mine Area WorldGuard Region -**Important:** This step is not needed if you are using geographical locations such as islands within a void world. +# Alternatives -The mine area is an area that surrounds the mine to protect the area from players who should not have access. This area should be at least 5 blocks larger in the X and Z axis than the mine, so as to prevent non-member players from being able to attempt mining. +There are many ways to accomplish the same goals and that's what makes Minecraft so versatile and interesting to play. The Prison Plugin does not want to impose a specific way to do most things, since it may not be the ideal way for your sever. -You need to select the area like the prior region and then define it with the following commands. The following `//pos1` and `//pos2` is just an example of making the selection. The `//expand vert` is required (strongly suggested) to ensure the region extends from the lowest to the highest blocks. +One of the primary focuses for this document has been protecting the area around your mine to prevent players who should not access the mine, from enter that region. One alternative to needing to protect a mine, would be to limit the access to the mine so it does not have to be protected. One simple way of accomplishing that, is to have the mines in a void world, and then each mine would be a separate island. Then all that would need to be protected, or controlled, would be the warping to that location. - //pos1 x, y, z - //pos2 x, y, z - - - //expand vert - - /region define prison_mines_area_a - /region setpriority prison_mines_area_a 10 - /region flag prison_mines_area_a entry -g nonmembers deny - /region flag prison_mines_area_a entry-deny-message You must rank-up to access this mine. - - /region addmember prison_mines_area_a g:prison.mines.a +
-*Optional:* - /region addowner prison_mines_area_a g:owner - /region addmember prison_mines_area_a g:admin - -Please notice that we have defined two WorldGuard regions: prison_mines_a and prison_mines_area_a. But for both of them, we've assigned the LuckPerms group g:prison.mines.a as members. This means, all we need to do is add the player to that LuckPerms group and they will have access to both the mine_area and also the mine. - - - -
- - - - -# WG LP Commands - Adding the Prison Rank Commands - - -So finally for our example of setting up mines a and b, we now need to add the Rank Commands to active the permission for both. Also included in these commands are the permissions for the mines.tp command, where mines.tp. is a permission and not a group. - - -For rank a: - - /ranks command add a lp user {player} parent add prison.mines.a - /ranks command add a lp user {player} parent remove prison.mines.b - /ranks command add a lp user {player} permission set mines.tp.a true - /ranks command add a lp user {player} permission unset mines.tp.b - - -For rank b: - - /ranks command add b lp user {player} parent add prison.mines.b - /ranks command add b lp user {player} parent remove prison.mines.c - /ranks command add b lp user {player} permission set mines.tp.b true - /ranks command add b lp user {player} permission unset mines.tp.c - - -And that's it! Just repeat for all your other mines. - - -
+ # Other Commands That May Be Important: diff --git a/gradle.properties b/gradle.properties index e8f45394e..7706c53f6 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.9 +version=3.2.10 #version=3.2.8.2 #version=3.3.0-alpha.6 diff --git a/gradlew8.bat b/gradlew8.bat index 3897b9fcb..83ac1e6c3 100644 --- a/gradlew8.bat +++ b/gradlew8.bat @@ -1 +1 @@ -./gradlew build -Dorg.gradle.java.home="C:\Program Files\Java\jdk1.8.0_291" \ No newline at end of file +./gradlew build -Dorg.gradle.java.home="C:\Program Files\Java\jdk1.8.0_291" --stacktrace \ No newline at end of file diff --git a/prison-core/build.gradle b/prison-core/build.gradle index f9bfed7b0..32998645b 100644 --- a/prison-core/build.gradle +++ b/prison-core/build.gradle @@ -18,6 +18,10 @@ apply plugin: 'eclipse' apply plugin: 'idea' +apply plugin: 'java' + +compileJava.options.encoding = 'UTF-8' +compileTestJava.options.encoding = "UTF-8" repositories { mavenCentral() 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 acdaad78a..bbf1b9ae8 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/Prison.java +++ b/prison-core/src/main/java/tech/mcprison/prison/Prison.java @@ -20,7 +20,9 @@ import java.io.File; import java.text.DecimalFormat; +import java.util.ArrayList; import java.util.LinkedHashMap; +import java.util.List; import java.util.Optional; import com.google.common.eventbus.EventBus; @@ -74,6 +76,7 @@ public class Prison public static final int API_LEVEL = 3; private String minecraftVersion; + private List versionMajMin; private long serverStartupTime; @@ -118,8 +121,25 @@ public static Prison get() { return instance; } - // Public methods + /** + * Lazy load LocalManager which ensures Prison is already loaded so + * can get the default language to use from the plugin configs. + * + * Returns the {@link LocaleManager} for the plugin. This contains the global messages that Prison + * uses to run its command library, and the like. {@link Module}s have their own {@link + * LocaleManager}s, so that each module can have independent localization. + * + * @return The global locale manager instance. + */ + public LocaleManager getLocaleManager() { + + if ( this.localeManager == null ) { + this.localeManager = new LocaleManager(this, "lang/core"); + } + return localeManager; + } + /** * Initializes prison-core. In the implementations, this should be called when the plugin is * enabled. After this is called, every getter in this class will return a value. @@ -129,6 +149,7 @@ public static Prison get() { public boolean init(Platform platform, String minecraftVersion) { long startTime = System.currentTimeMillis(); + this.platform = platform; this.minecraftVersion = minecraftVersion; @@ -142,7 +163,11 @@ public boolean init(Platform platform, String minecraftVersion) { this.prisonTPS = new PrisonTPS(); this.prisonTPS.submitAsyncTPSTask(); + + // Setup the LocalManager if it is not yet started: + getLocaleManager(); + sendBanner(); @@ -500,7 +525,10 @@ private boolean initMetaDatabase() { private void initManagers() { // Now we initialize the API - this.localeManager = new LocaleManager(this, "lang/core"); + + // LocalManager must be initialized ASAP due to dependencies with + // Output components: +// this.localeManager = new LocaleManager(this, "lang/core"); this.errorManager = new ErrorManager(this); this.eventBus = new EventBus(new EventExceptionHandler()); this.moduleManager = new ModuleManager(); @@ -549,6 +577,37 @@ public String getMinecraftVersion() { return minecraftVersion; } + + public List getMVersionMajMin() { + if ( versionMajMin == null ) { + + this.versionMajMin = new ArrayList<>(); + + String v = Prison.get().getMinecraftVersion(); + String versionStr = v.substring( v.indexOf( "(MC:" ) + 4, v.lastIndexOf( ")" ) ); + String[] vMN = versionStr.split( "\\." ); + + for ( int x = 0; x < vMN.length; x++ ) { + String ver = vMN[x]; + + try { + this.versionMajMin.add( + Integer.parseInt( ver.trim() ) ); + } + catch ( NumberFormatException e ) { + // ignore... just break out: + break; + } + } + +// Output.get().logInfo( "#### Prison.getMVersionMajMin() : " + +// ( versionMajMin != null && versionMajMin.size() > 0 ? versionMajMin.get(0) : "?" ) + " " + +// ( versionMajMin != null && versionMajMin.size() > 1 ? versionMajMin.get(1) : "?" ) + " " + +// ( versionMajMin != null && versionMajMin.size() > 2 ? versionMajMin.get(2) : "?" ) +// ); + } + return versionMajMin; + } @Override public String getName() { @@ -575,16 +634,7 @@ public File getDataFolder() { return dataFolder; } - /** - * Returns the {@link LocaleManager} for the plugin. This contains the global messages that Prison - * uses to run its command library, and the like. {@link Module}s have their own {@link - * LocaleManager}s, so that each module can have independent localization. - * - * @return The global locale manager instance. - */ - public LocaleManager getLocaleManager() { - return localeManager; - } + /** * Returns the core's {@link ErrorManager}. For modules, you should use your own module's error manager via {@link Module#getErrorManager()}. 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 749b90a25..e28d7cf16 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommand.java @@ -23,7 +23,9 @@ import java.io.IOException; import java.nio.file.Files; import java.text.DecimalFormat; +import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Date; import java.util.List; import java.util.Optional; import java.util.Set; @@ -41,6 +43,7 @@ import tech.mcprison.prison.integration.IntegrationType; import tech.mcprison.prison.internal.CommandSender; import tech.mcprison.prison.internal.Player; +import tech.mcprison.prison.localization.LocaleManager; import tech.mcprison.prison.modules.Module; import tech.mcprison.prison.modules.ModuleStatus; import tech.mcprison.prison.output.BulletedListComponent; @@ -50,6 +53,7 @@ import tech.mcprison.prison.output.Output.DebugTarget; import tech.mcprison.prison.troubleshoot.TroubleshootResult; import tech.mcprison.prison.troubleshoot.Troubleshooter; +import tech.mcprison.prison.util.JumboTextFont; import tech.mcprison.prison.util.PrisonJarReporter; /** @@ -58,7 +62,8 @@ * @author Faizaan A. Datoo * @since API 1.0 */ -public class PrisonCommand { +public class PrisonCommand + extends PrisonCommandMessages { private List registeredPlugins = new ArrayList<>(); @@ -67,6 +72,7 @@ public class PrisonCommand { private List prisonStartupDetails; private String supportName = null; + private TreeMap supportURLs; public PrisonCommand() { @@ -74,6 +80,8 @@ public PrisonCommand() { this.prisonStartupDetails = new ArrayList<>(); + this.supportURLs = new TreeMap<>(); + } @Command(identifier = "prison version", description = "Displays version information.", @@ -386,6 +394,10 @@ else if ( !isBasic ) { // display.text( pluginDetails ); +// if ( !isBasic ) { +// Prison.get().getPlatform().dumpEventListenersBlockBreakEvents(); +// } + Prison.get().getPlatform().getWorldLoadErrors( display ); @@ -539,12 +551,24 @@ public void placeholdersTestCommand(CommandSender sender, new BulletedListComponent.BulletedListBuilder(); - UUID playerUuid = (player == null ? null : player.getUUID()); + UUID playerUuid = player == null ? null : player.getUUID(); + playerName = player != null ? player.getName() : + (playerName.isEmpty() ? sender.getName() : playerName); + String translated = Prison.get().getPlatform().getPlaceholders() - .placeholderTranslateText( playerUuid, sender.getName(), text ); + .placeholderTranslateText( playerUuid, playerName, text ); builder.add( String.format( "&a Include one or more Prison placeholders with other text...")); builder.add( String.format( "&a Use { } to escape the placeholders.")); + + // Show player info here like with the search: + if ( player != null ) { + builder.add( String.format( "&a Player: &7%s &aPlayerUuid: &7%s", player.getName(), + (playerUuid == null ? "null" : playerUuid.toString()))); + + } + + builder.add( String.format( "&7 Original: \\Q%s\\E", text)); builder.add( String.format( "&7 Translated: %s", translated)); @@ -590,7 +614,7 @@ private Player getPlayer( CommandSender sender, String playerName ) { public void placeholdersSearchCommand(CommandSender sender, @Arg(name = "playerName", description = "Player name to use with player rank placeholders (optional)", def = "." ) String playerName, - @Arg(name = "pageNumber", description = "page number of results to display", def = "." ) String pageNumber, + @Arg(name = "pageNumber", description = "page number of results to display (optional)", def = "." ) String pageNumber, @Wildcard(join=true) @Arg(name = "patterns", description = "Patterns of placeholders to search for" ) String patterns ) { @@ -680,7 +704,7 @@ public void placeholdersSearchCommand(CommandSender sender, CommandPagedData cmdPageData = new CommandPagedData( "/prison placeholders search", placeholders.size(), - 0, Integer.toString( page ), 12 ); + 0, Integer.toString( page ), 20 ); // Need to provide more "parts" to the command that follows the page number: cmdPageData.setPageCommandSuffix( patterns ); @@ -750,6 +774,24 @@ public void placeholdersReloadCommand(CommandSender sender ) { sender.sendMessage( message ); } + + + @Command(identifier = "prison reload locales", + description = "Locales reload: This will reload all of the language files that are being used " + + "within prison. Based upon the configuration settings, this will load the proper locales.", + onlyPlayers = false, permissions = "prison.reload") + public void localesReloadCommand(CommandSender sender ) { + + for ( LocaleManager LocalManager : LocaleManager.getRegisteredInstances() ) { + LocalManager.reload(); + } + + String message = "Locales reload was attempted. " + + "No guarentees that it worked 100%. Restart server if any doubts."; + + sender.sendMessage( message ); + } + @Command(identifier = "prison reload autoFeatures", description = "AutoFeatures reload: Reloads the auto features settings. The current " + @@ -835,18 +877,41 @@ public void autoFeaturesInformation(CommandSender sender) { AutoFeaturesWrapper afw = AutoFeaturesWrapper.getInstance(); display.addText( "&3Selected Settings from &bplugins/Prison/autoFeaturesConfigs.yml&3:" ); + display.addText( "&b " ); + display.addText( "&b options.general.isAutoManagerEnabled %s", + afw.isBoolean( AutoFeatures.isAutoManagerEnabled )); + + + + + display.addText( "&b " ); + display.addText( "&b options.blockBreakEvents.isProcessTokensEnchantExplosiveEvents: %s", + afw.isBoolean( AutoFeatures.isProcessTokensEnchantExplosiveEvents ) ); + display.addText( "&b options.blockBreakEvents.TokenEnchantBlockExplodeEventPriority: %s", + afw.getMessage( AutoFeatures.isProcessTokensEnchantExplosiveEvents ) ); + + display.addText( "&b options.blockBreakEvents.isProcessCrazyEnchantsBlockExplodeEvents: %s", + afw.isBoolean( AutoFeatures.isProcessCrazyEnchantsBlockExplodeEvents ) ); + display.addText( "&b options.blockBreakEvents.CrazyEnchantsBlastUseEventPriority: %s", + afw.getMessage( AutoFeatures.CrazyEnchantsBlastUseEventPriority ) ); + + display.addText( "&b options.blockBreakEvents.isProcessZenchantsBlockExplodeEvents: %s", + afw.isBoolean( AutoFeatures.isProcessZenchantsBlockExplodeEvents ) ); + display.addText( "&b options.blockBreakEvents.ZenchantmentsBlockShredEventPriority: %s", + afw.getMessage( AutoFeatures.ZenchantmentsBlockShredEventPriority ) ); + + display.addText( "&b options.blockBreakEvents.isProcessPrisonEnchantsExplosiveEvents: %s", + afw.isBoolean( AutoFeatures.isProcessPrisonEnchantsExplosiveEvents ) ); + display.addText( "&b options.blockBreakEvents.PrisonEnchantsExplosiveEventPriority: %s", + afw.getMessage( AutoFeatures.PrisonEnchantsExplosiveEventPriority ) ); + + + display.addText( "&b " ); display.addText( "&b Normal Drops (if auto pickup is off):" ); display.addText( "&b options.normalDrop.isProcessNormalDropsEvents: %s", - afw.isBoolean( AutoFeatures.handleNormalDropsEvents ) ); - display.addText( "&b options.normalDrop.isProcessTokensEnchantExplosiveEvents: %s", - afw.isBoolean( AutoFeatures.isProcessTokensEnchantExplosiveEvents ) ); - display.addText( "&b options.normalDrop.isProcessTokensEnchantExplosiveEvents: %s", - afw.isBoolean( AutoFeatures.isProcessTokensEnchantExplosiveEvents ) ); - + afw.isBoolean( AutoFeatures.handleNormalDropsEvents ) ); display.addText( "&b " ); - display.addText( "&b options.general.isAutoManagerEnabled %s", - afw.isBoolean( AutoFeatures.isAutoManagerEnabled )); display.addText( "&7 NOTE: If this is enabled, then lore and perms will override the settings for " ); display.addText( "&7 pickup, smelt, and block when they are turned off." ); @@ -925,7 +990,8 @@ public void toggleDebug(CommandSender sender, @Wildcard(join=true) @Arg(name = "targets", def = " ", description = "Optional. Enable or disable a debugging target. " + - "[on, off, targets, jarScan, blockBreakListeners, chatListeners] " + + "[on, off, targets, jarScan, " + + "testPlayerUtil, testLocale, rankup] " + "Use 'targets' to list all available targets. Use 'on' or 'off' to toggle " + "on and off individual targets, or all targets if no target is specified. " + "jarScan will identify what Java version compiled the class files within the listed jars" @@ -940,23 +1006,18 @@ public void toggleDebug(CommandSender sender, return; } - if ( targets != null && "blockBreakListeners".equalsIgnoreCase( targets ) ) { - - Prison.get().getPlatform().dumpEventListenersBlockBreakEvents(); - - return; - } - if ( targets != null && "traceBlockBreakListeners".equalsIgnoreCase( targets ) ) { + if ( targets != null && "testLocale".equalsIgnoreCase( targets ) ) { - Prison.get().getPlatform().traceEventListenersBlockBreakEvents( sender ); + coreDebugTestLocaleseMsg( sender ); return; } - if ( targets != null && "chatListeners".equalsIgnoreCase( targets ) ) { + if ( targets != null && "testPlayerUtil".equalsIgnoreCase( targets ) ) { - Prison.get().getPlatform().dumpEventListenersPlayerChatEvents(); + Player player = getPlayer( sender, "RoyalBlueRanger" ); + Prison.get().getPlatform().testPlayerUtil( player.getUUID() ); return; } @@ -987,7 +1048,8 @@ public void toggleDebug(CommandSender sender, } - @Command(identifier = "prison findCmd", + + @Command(identifier = "prison findCmd", description = "For internal use only. Do not use. This command is used by internal code to look up " + "a command to get the registered command. Example would be when prison is registering the " + "command '/backpack' and it's already been registered, bukkit would then try to register prison's " + @@ -1050,10 +1112,12 @@ public void supportSubmitVersion(CommandSender sender ChatDisplay display = displayVersion("ALL"); StringBuilder text = display.toStringBuilder(); - PrisonPasteChat pasteChat = new PrisonPasteChat( getSupportName() ); + PrisonPasteChat pasteChat = new PrisonPasteChat( getSupportName(), getSupportURLs() ); String helpURL = pasteChat.post( text.toString() ); + getSupportURLs().put( "Submit version:", helpURL ); + if ( helpURL != null ) { Output.get().logInfo( "Prison's support information has been pasted. Copy and " + @@ -1061,15 +1125,262 @@ public void supportSubmitVersion(CommandSender sender Output.get().logInfo( "Paste this URL: %s", helpURL ); } else { - // Do nothing since if helpURL is null, then it has probably - // already sent an error message. + Output.get().logInfo( "There was an error trying to generate the paste.helpch.at URL." ); } + } + + @Command(identifier = "prison support submit configs", + description = "For Prison support: This will copy the contents of Prison's config " + + "file to paste.helpch.at so it can be easily shared with Prison's " + + "support staff. This will include the following: config.yml plugin.yml " + + "autoFeaturesConfig.yml modules.yml module_conf/mines/config.json " + + "SellAllConfig.yml GuiConfig.yml backpacks/backpacksconfig.yml", + onlyPlayers = false, permissions = "prison.debug" ) + public void supportSubmitConfigs(CommandSender sender + ) { + + + if ( getSupportName() == null || getSupportName().trim().isEmpty() ) { + Output.get().logInfo( "The support name needs to be set prior to using this command." ); + Output.get().logInfo( "Use &7/prison support setSupportName help" ); + + return; + } + + Prison.get().getPlatform().saveResource( "plugin.yml", true ); + + String fileNames = "config.yml plugin.yml autoFeaturesConfig.yml modules.yml module_conf/mines/config.json " + + "SellAllConfig.yml GuiConfig.yml backpacks/backpacksconfig.yml"; + List files = convertNamesToFiles( fileNames ); + + + StringBuilder text = new StringBuilder(); + + for ( File file : files ) { + + addFileToText( file, text ); + + if ( file.getName().equalsIgnoreCase( "plugin.yml" ) ) { + file.delete(); + } + } + + + PrisonPasteChat pasteChat = new PrisonPasteChat( getSupportName(), getSupportURLs() ); + + String helpURL = pasteChat.postKeepColorCodes( text.toString() ); + + getSupportURLs().put( "Submit configs:", helpURL ); + + if ( helpURL != null ) { + + Output.get().logInfo( "Prison's support information has been pasted. Copy and " + + "paste this URL in to Prison's Discord server." ); + Output.get().logInfo( "Paste this URL: %s", helpURL ); + } + else { + Output.get().logInfo( "There was an error trying to generate the paste.helpch.at URL." ); + } + + + } + + @Command(identifier = "prison support submit ranks", + description = "For Prison support: This will copy the contents of Prison's " + + "ladders and ranks configs to paste.helpch.at so it can be " + + "easily shared with Prison's support staff.", + onlyPlayers = false, permissions = "prison.debug" ) + public void supportSubmitRanks(CommandSender sender + ) { + + + if ( getSupportName() == null || getSupportName().trim().isEmpty() ) { + Output.get().logInfo( "The support name needs to be set prior to using this command." ); + Output.get().logInfo( "Use &7/prison support setSupportName help" ); + + return; + } + + + List files = listFiles( "data_storage/ranksDb/ladders/", ".json" ); + files.addAll( listFiles( "data_storage/ranksDb/ranks/", ".json" ) ); + + + StringBuilder text = new StringBuilder(); + + + text.append( Prison.get().getPlatform().getRanksListString() ); + printFooter( text ); + + + for ( File file : files ) { + + addFileToText( file, text ); + + } + + + PrisonPasteChat pasteChat = new PrisonPasteChat( getSupportName(), getSupportURLs() ); + + String helpURL = pasteChat.post( text.toString() ); + + getSupportURLs().put( "Submit ranks:", helpURL ); + + if ( helpURL != null ) { + + Output.get().logInfo( "Prison's support information has been pasted. Copy and " + + "paste this URL in to Prison's Discord server." ); + Output.get().logInfo( "Paste this URL: %s", helpURL ); + } + else { + Output.get().logInfo( "There was an error trying to generate the paste.helpch.at URL." ); + } + + + } + + + @Command(identifier = "prison support submit mines", + description = "For Prison support: This will copy the contents of Prison's " + + "mines configs to paste.helpch.at so it can be " + + "easily shared with Prison's support staff.", + onlyPlayers = false, permissions = "prison.debug" ) + public void supportSubmitMines(CommandSender sender + ) { + + + if ( getSupportName() == null || getSupportName().trim().isEmpty() ) { + Output.get().logInfo( "The support name needs to be set prior to using this command." ); + Output.get().logInfo( "Use &7/prison support setSupportName help" ); + + return; + } + + + List files = listFiles( "data_storage/mines/mines/", ".json" ); + + + StringBuilder text = new StringBuilder(); + + text.append( "\n" ); + text.append( "Table of contents:\n" ); + text.append( " 1. Mine list - All mines including virtual mines: /mines list all\n" ); + text.append( " 2. Mine info - All mines: /mines info all\n" ); + text.append( " 3. Mine files - Raw JSON dump of all mine configuration files.\n" ); + text.append( "\n" ); + + // Display a list of all mines, then display the /mines info all for each: + text.append( Prison.get().getPlatform().getMinesListString() ); + printFooter( text ); + + + + for ( File file : files ) { + + addFileToText( file, text ); + + } + + + PrisonPasteChat pasteChat = new PrisonPasteChat( getSupportName(), getSupportURLs() ); + + String helpURL = pasteChat.post( text.toString() ); + + getSupportURLs().put( "Submit mines:", helpURL ); + + if ( helpURL != null ) { + + Output.get().logInfo( "Prison's support information has been pasted. Copy and " + + "paste this URL in to Prison's Discord server." ); + Output.get().logInfo( "Paste this URL: %s", helpURL ); + } + else { + Output.get().logInfo( "There was an error trying to generate the paste.helpch.at URL." ); + } + + } - @Command(identifier = "prison support submit latestLog", + private List listFiles( String path, String fileSuffix ) { + List files = new ArrayList<>(); + + File dataFolder = Prison.get().getDataFolder(); + File filePaths = new File( dataFolder, path ); + + for ( File file : filePaths.listFiles() ) { + if ( file.getName().toLowerCase().endsWith( fileSuffix.toLowerCase() )) { + files.add( file ); + } + } + + return files; + } + + private void addFileToText( File file, StringBuilder sb ) + { + DecimalFormat dFmt = new DecimalFormat("#,##0"); + SimpleDateFormat sdFmt = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ); + + sb.append( "\n" ); + + JumboTextFont.makeJumboFontText( file.getName(), sb ); + + sb.append( "\n" ); + + sb.append( "File Name: " ).append( file.getName() ).append( "\n" ); + sb.append( "File Path: " ).append( file.getAbsolutePath() ).append( "\n" ); + sb.append( "File Size: " ).append( dFmt.format( file.length() ) ).append( " bytes\n" ); + sb.append( "File Date: " ).append( sdFmt.format( new Date(file.lastModified()) ) ).append( " bytes\n" ); + sb.append( "File Stats: " ) + .append( file.exists() ? "EXISTS " : "" ) + .append( file.canRead() ? "READABLE " : "" ) + .append( file.canWrite() ? "WRITEABLE " : "" ) + .append( "\n" ); + + sb.append( "\n" ); + sb.append( "=== --- --- --- --- --- --- --- --- --- ===\n" ); + sb.append( "\n" ); + + + if ( file.exists() && file.canRead() ) { + readFileToStringBulider( file, sb ); + } + else { + sb.append( "Warning: The file is not readable so it cannot be included.\n" ); + } + + + printFooter( sb ); + } + + public static void printFooter( StringBuilder sb ) { + + sb.append( "\n\n\n" ); + sb.append( "=== --- === --- === --- === --- === --- ===\n" ); + sb.append( "=== # # ### # # # ### # # # ### # # # ### # # # ### # # ===\n" ); + sb.append( "=== --- === --- === --- === --- === --- ===\n" ); + sb.append( "\n\n" ); + + } + + private List convertNamesToFiles( String fileNames ) + { + List files = new ArrayList<>(); + + File dataFolder = Prison.get().getDataFolder(); + + for ( String fileName : fileNames.split( " " )) { + File file = new File( dataFolder, fileName ); + files.add( file ); + } + + return files; + } + + @Command(identifier = "prison support submit latestLog", description = "For Prison support: This will copy the contents of `logs/latest.log` " + "to paste.helpch.at so it can be easily shared with Prison's support staff .", onlyPlayers = false, permissions = "prison.debug" ) @@ -1094,40 +1405,17 @@ public void supportSubmitLatestLog(CommandSender sender StringBuilder logText = new StringBuilder(); if ( latestLogFile.exists() && latestLogFile.canRead() ) { - try ( - BufferedReader br = Files.newBufferedReader( latestLogFile.toPath() ); - ) { - String line = br.readLine(); - while ( line != null && logText.length() < PrisonPasteChat.HASTEBIN_MAX_LENGTH ) { - - logText.append( line ).append( "\n" ); - - line = br.readLine(); - } - - if ( logText.length() > PrisonPasteChat.HASTEBIN_MAX_LENGTH ) { - - String trimMessage = "\n\n### Log has been trimmed to a max length of " + - PrisonPasteChat.HASTEBIN_MAX_LENGTH + "\n"; - int pos = PrisonPasteChat.HASTEBIN_MAX_LENGTH - trimMessage.length(); - - logText.insert( pos, trimMessage ); - logText.setLength( PrisonPasteChat.HASTEBIN_MAX_LENGTH ); - } - - } - catch ( IOException e ) { - Output.get().logInfo( "Failed to read log file: %s [%s]", - latestLogFile.getAbsolutePath(), e.getMessage() ); - return; - } + + readFileToStringBulider( latestLogFile, logText ); if ( logText != null ) { - PrisonPasteChat pasteChat = new PrisonPasteChat( getSupportName() ); + PrisonPasteChat pasteChat = new PrisonPasteChat( getSupportName(), getSupportURLs() ); String helpURL = pasteChat.post( logText.toString() ); + getSupportURLs().put( "Submit lastlog:", helpURL ); + if ( helpURL != null ) { Output.get().logInfo( "Prison's support information has been pasted. Copy and " + @@ -1144,9 +1432,85 @@ public void supportSubmitLatestLog(CommandSender sender Output.get().logInfo( "Unable to send log file. Unknown reason why." ); } - + private void readFileToStringBulider( File textFile, StringBuilder text ) + { + try ( + BufferedReader br = Files.newBufferedReader( textFile.toPath() ); + ) { + String line = br.readLine(); + while ( line != null && text.length() < PrisonPasteChat.HASTEBIN_MAX_LENGTH ) { + + text.append( line ).append( "\n" ); + + line = br.readLine(); + } + + if ( text.length() > PrisonPasteChat.HASTEBIN_MAX_LENGTH ) { + + String trimMessage = "\n\n### Log has been trimmed to a max length of " + + PrisonPasteChat.HASTEBIN_MAX_LENGTH + "\n"; + int pos = PrisonPasteChat.HASTEBIN_MAX_LENGTH - trimMessage.length(); + + text.insert( pos, trimMessage ); + text.setLength( PrisonPasteChat.HASTEBIN_MAX_LENGTH ); + } + + } + catch ( IOException e ) { + Output.get().logInfo( "Failed to read log file: %s [%s]", + textFile.getAbsolutePath(), e.getMessage() ); + return; + } + } + + @Command(identifier = "prison support listeners", + description = "For Prison support: Provide a 'dump' of all event listeners.", + onlyPlayers = false, permissions = "prison.debug" ) + public void supportListenersDump(CommandSender sender, + @Arg(name = "listener", def = " ", + description = "Provides a detailed list of all registered event listeners for" + + "the various event types. BlockBreak listeners will include all " + + "listeners that are being monitored within auto features. " + + "[blockBreak, traceBlockBreak, chat]" + ) String listener + ) { + + if ( listener == null ) { + String message = "You must supply a listener in order to use this command."; + sender.sendMessage( message ); + return; + } + + String results = null; + + if ( "blockBreak".equalsIgnoreCase( listener ) ) { + + results = Prison.get().getPlatform().dumpEventListenersBlockBreakEvents(); + } + + if ( "chat".equalsIgnoreCase( listener ) ) { + + results = Prison.get().getPlatform().dumpEventListenersPlayerChatEvents(); + } + + if ( "traceBlockBreak".equalsIgnoreCase( listener ) ) { + + Prison.get().getPlatform().traceEventListenersBlockBreakEvents( sender ); + + return; + } + + if ( results != null ) { + + for ( String line : results.split( "\n" ) ) { + + Output.get().logInfo( line ); + } + } + + } // This functionality should not be available in v3.2.1! If someone is still running Prison 2.x.x @@ -1205,4 +1569,11 @@ public void setSupportName( String supportName ) { this.supportName = supportName; } + public TreeMap getSupportURLs() { + return supportURLs; + } + public void setSupportURLs( TreeMap supportURLs ) { + this.supportURLs = supportURLs; + } + } diff --git a/prison-core/src/main/java/tech/mcprison/prison/PrisonCommandMessages.java b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommandMessages.java new file mode 100644 index 000000000..075bb4722 --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/PrisonCommandMessages.java @@ -0,0 +1,13 @@ +package tech.mcprison.prison; + +import tech.mcprison.prison.internal.CommandSender; + +public class PrisonCommandMessages +{ + protected void coreDebugTestLocaleseMsg( CommandSender sender ) { + Prison.get().getLocaleManager() + .getLocalizable( "core_prison_utf8_test" ) + .setFailSilently() + .sendTo( sender ); + } +} 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 6425461fb..d92b99567 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 @@ -23,6 +23,15 @@ public class AutoFeaturesFileConfig { public enum AutoFeatures { + autoManager, + + isAutoManagerEnabled(autoManager, true), + isAutoManagerEnabled__ReadMe(autoManager, + "Set to 'false' to turn off all auto manager features. " + + "Otherwise this must be set to 'true' to allow any of the " + + "options to work."), + + messages, inventoryIsFull(messages, "&cWARNING! Your inventory's full!"), @@ -51,13 +60,21 @@ public enum AutoFeatures { isProcessZenchantsBlockExplodeEvents(blockBreakEvents, false), ZenchantmentsBlockShredEventPriority(blockBreakEvents, "DISABLED"), + isProcessPrisonEnchantsExplosiveEvents(blockBreakEvents, false), + PrisonEnchantsExplosiveEventPriority(blockBreakEvents, "DISABLED"), + + isProcessPrisons_ExplosiveBlockBreakEvents(blockBreakEvents, false), + ProcessPrisons_ExplosiveBlockBreakEvents(blockBreakEvents, "DISABLED"), + + + blockBreakEvents__ReadMe(blockBreakEvents, + "Use the following event priorities with the blockBreakEvents: " + + "DISABLED, LOWEST, LOW, NORMAL, HIGH, HIGHEST, MONITOR" ), general(options), - isAutoManagerEnabled(general, true), - - isCalculateDurabilityEnabled(general, false), + isCalculateFoodExhustion(general, true), isCalculateSilkEnabled(general, true), isCalculateDropAdditionsEnabled(general, true), @@ -98,6 +115,8 @@ public enum AutoFeatures { autoFeatures(options), + isAutoFeaturesEnabled(autoFeatures, true), + autoPickupEnabled(autoFeatures, true), autoSmeltEnabled(autoFeatures, true), autoBlockEnabled(autoFeatures, true), @@ -109,6 +128,17 @@ public enum AutoFeatures { normalDropSmelt(normalDrop, true), normalDropBlock(normalDrop, true), + + durability(options), + + isCalculateDurabilityEnabled(durability, false), + + preventToolBreakageThreshold__ReadMe(durability, + "This option stops the tool from losing any more durability " + + "once it hits the number specified with the threshold"), + isPreventToolBreakage(durability, false), + preventToolBreakageThreshold(durability, 10), + fortuneFeature(options), @@ -120,6 +150,11 @@ public enum AutoFeatures { isExtendBukkitFortuneCalculationsEnabled(fortuneFeature, true), extendBukkitFortuneFactorPercentRangeLow(fortuneFeature, 70 ), extendBukkitFortuneFactorPercentRangeHigh(fortuneFeature, 110 ), + extendBukkitFortune__ReadMe(fortuneFeature, "To get fortune to work, First " + + "try to use the extendedBukkitFortune (set it to true). If it won't " + + "work, then you must disable it (set it to false), then enable " + + "CalculateAltFortune. AltFortune will never work if " + + "extendedBukkitFortune is enabled." ), isCalculateAltFortuneEnabled(fortuneFeature, false), @@ -172,28 +207,36 @@ public enum AutoFeatures { blockFeature(options), - autoBlockLimitToMines(blockFeature, true), - autoBlockAllBlocks(blockFeature, true), + blockLimitToMines(blockFeature, true), + blockAllBlocks(blockFeature, true), - autoBlockGoldBlock(blockFeature, true), - autoBlockIronBlock(blockFeature, true), - autoBlockCoalBlock(blockFeature, true), - autoBlockDiamondBlock(blockFeature, true), - autoBlockRedstoneBlock(blockFeature, true), - autoBlockEmeraldBlock(blockFeature, true), - autoBlockQuartzBlock(blockFeature, true), - autoBlockPrismarineBlock(blockFeature, true), - autoBlockLapisBlock(blockFeature, true), - autoBlockSnowBlock(blockFeature, true), - autoBlockGlowstone(blockFeature, true), - autoBlockCopperBlock(blockFeature, true), + blockGoldBlock(blockFeature, true), + blockIronBlock(blockFeature, true), + blockCoalBlock(blockFeature, true), + blockDiamondBlock(blockFeature, true), + blockRedstoneBlock(blockFeature, true), + blockEmeraldBlock(blockFeature, true), + blockQuartzBlock(blockFeature, true), + blockPrismarineBlock(blockFeature, true), + blockLapisBlock(blockFeature, true), + blockSnowBlock(blockFeature, true), + blockGlowstone(blockFeature, true), + blockCopperBlock(blockFeature, true), +// eventInjector(options), +// eventInjectorEnabled(eventInjector, false), +// +// eventInjectorData(eventInjector), + + + debug(options), isDebugSupressOnBlockBreakEventCancels(debug, false), isDebugSupressOnTEExplodeEventCancels(debug, false), - isDebugSupressOnCEBlastUseEventCancels(debug, false) + isDebugSupressOnCEBlastUseEventCancels(debug, false), + isDebugSupressOnPEExplosiveEventCancels(debug, false) ; @@ -568,6 +611,9 @@ public void reloadConfig() { List dne = yamlFileIO.loadYamlAutoFeatures( getConfig() ); dne.size(); + + // need to reload the auto features event listeners: + Prison.get().getPlatform().reloadAutoFeaturesEventListeners(); } diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCache.java b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCache.java new file mode 100644 index 000000000..c4d5f554a --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCache.java @@ -0,0 +1,467 @@ +package tech.mcprison.prison.cache; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; + +import tech.mcprison.prison.internal.Player; +import tech.mcprison.prison.internal.block.PrisonBlock; +import tech.mcprison.prison.internal.block.PrisonBlockStatusData; +import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.tasks.PrisonTaskSubmitter; + + +public class PlayerCache { + + public static final String PLAYER_CACHE_WRITE_DELAY_CONFIG_NAME = "playercache.write_delay"; + public static final long PLAYER_CACHE_WRITE_DELAY_VALUE_MS = 60000; // 60 seconds + + public static final String PLAYER_CACHE_TIME_TO_LIVE_CONFIG_NAME = "playercache.time_to_live"; + public static final long PLAYER_CACHE_TIME_TO_LIVE_VALUE_MS = 30 * 60 * 1000; // 30 mins + + private static PlayerCache instance; + + private PlayerCacheFiles cacheFiles; + private PlayerCacheEvents cacheEvents; + + + private long writeDelay = 0L; + + private PlayerCacheStats stats; + + + private TreeMap players; + + private Map tasks; + + private PlayerCacheRunnable saveAllTask; + + private PlayerCacheRunnable checkTimersTask; + + + private PlayerCache() { + super(); + + this.players = new TreeMap<>(); + + this.tasks = new HashMap<>(); + + this.cacheFiles = new PlayerCacheFiles(); + + + this.stats = new PlayerCacheStats(); + + } + + public static PlayerCache getInstance() { + if ( instance == null ) { + synchronized ( PlayerCache.class ) + { + if ( instance == null ) { + + instance = new PlayerCache(); + instance.internalInititalize(); + } + } + } + return instance; + } + + + private void internalInititalize() { + + // The PlayerCacheEvents self-registers with Prison's eventBus: + cacheEvents = new PlayerCacheEvents(); + + saveAllTask = submitCacheRefresh(); + + checkTimersTask = submitCacheUpdatePlayerStats(); + + } + + /** + *

The plugin is shutting down so flush all dirty cache items, but first + * disable the caching so as any changes are passed through directly to the + * database. + *

+ * + *

Since the plugin is shutting down, flush the cache synchronously in this + * thread. Do not submit, or the database may be shutdown before all dirty + * cache items can be saved. + *

+ */ + public static void onDisable() { + getInstance().onDisableInternal(); + + } + + /** + *

This shuts down the cache and unloads all the players while + * updating the database if they have uncommitted values. This also + * will cancel any outstanding tasks and then flush the uncommitted + * values if they still exist. + *

+ * + *

This function runs all database transactions synchronously so as to + * ensure all data is written to the database before the server is + * terminated. + *

+ * + */ + private void onDisableInternal() { + + // Shutdown the save all task so it won't reload players or try to refresh data: + PrisonTaskSubmitter.cancelTask( saveAllTask.getTaskId() ); + + // Shutdown the timerTasks + PrisonTaskSubmitter.cancelTask( checkTimersTask.getTaskId() ); + + + // save all dirty cache items and purge cache: + if ( getPlayers().size() > 0 ) { + + // Create a new set so as to prevent keys from being removed when purging + // the getPlayers() collection: + Set keys = new TreeSet<>(getPlayers().keySet()); + + for ( String key : keys ) { + // Remove the player from the cache and get the playerData: + PlayerCachePlayerData playerData = getPlayers().remove( key ); + + if ( playerData != null ) { + + // Note: Since we are logging online time, then all players that are + // in the cache are considered constantly dirty and needs to be + // saved. + + // Since the disable function has been called, we can only assume the + // server is shutting down. We need to save dirty player caches, but + // they must be done in-line so the shutdown process will wait for all + // players to be saved. + + getCacheFiles().toJsonFile( playerData ); + + if ( playerData.getTask() != null ) { + getTasks().remove( playerData.getTask() ); + + PrisonTaskSubmitter.cancelTask( playerData.getTask().getTaskId() ); + } + } + } + + } + + // Cancel and flush any uncompleted tasks that are scheduled to run: + if ( getTasks().size() > 0 ) { + List keys = new ArrayList<>( getTasks().keySet() ); + + for ( PlayerCacheRunnable key : keys ) { + + if ( !key.isCancelled() ) { + // Cancel the task: + key.cancel(); + + // Remove the task and get the player data: + PlayerCachePlayerData playerData = getTasks().remove( key ); + + if ( playerData != null && + playerData.getTask() != null && + playerData.getTask().getTaskId() > 0 ) { + + PrisonTaskSubmitter.cancelTask( playerData.getTask().getTaskId() ); + } + + } + } + + } + + // Shutdown the connections: + + } + + + public void addPlayerData( PlayerCachePlayerData playerData ) { + + if ( playerData != null ) { + getStats().incrementLoadPlayers(); + + getPlayers().put( playerData.getPlayerUuid(), playerData ); + + } + } + + public PlayerCachePlayerData removePlayerData( PlayerCachePlayerData playerData ) { + PlayerCachePlayerData removed = playerData; + if ( playerData != null ) { + getStats().incrementRemovePlayers(); + + removed = getPlayers().remove( playerData.getPlayerUuid() ); + } + return removed; + } + + + + /** + *

This returns the cached player object. If they have not been loaded + * yet, then this will submit the loadPlayer task, which will then result + * in this function returning a null. + *

+ * + * @param player + * @return The cached player object. If null, then may indicate the player is + * actively being loaded, so try again later. + */ + private PlayerCachePlayerData getPlayer( Player player ) { + PlayerCachePlayerData playerData = null; + + getStats().incrementGetPlayers(); + + String playerUuid = player.getUUID().toString(); + if ( !getPlayers().containsKey( playerUuid ) ) { + + // Load the player's existing balance: + playerData = getCacheFiles().fromJson( player ); + + // NOTE: playerData.isOnline() is dynamic and tied back to the Player object. + // So if they are offline, an OfflinePlayer, then it will automatically + // track that. Also if the PlayerData object does not have a reference + /// to Player, then it's automatically considered offline. + + // Save it to the cache: + addPlayerData( playerData ); +// runLoadPlayerNow( player ); +// submitAsyncLoadPlayer( player ); + } + else { + + // Note: if the player has not been loaded yet, this will return a null: + playerData = getPlayers().get( playerUuid ); + } + + if ( playerData != null && + (playerData.getPlayer() == null || !playerData.getPlayer().equals( player ) ) ) { + playerData.setPlayer( player ); + } + + return playerData; + } + + + protected void submitAsyncLoadPlayer( Player player ) { + + if ( player != null ) { + + PlayerCacheLoadPlayerTask task = new PlayerCacheLoadPlayerTask( player ); + + // Submit task to run right away: + int taskId = PrisonTaskSubmitter.runTaskLaterAsync( task, 0 ); + task.setTaskId( taskId ); + } + } + + protected void runLoadPlayerNow( Player player ) { + + if ( player != null ) { + + PlayerCacheLoadPlayerTask task = new PlayerCacheLoadPlayerTask( player ); + + task.run(); +// // Submit task to run right away: +// int taskId = PrisonTaskSubmitter.runTaskLaterAsync( task, 0 ); +// task.setTaskId( taskId ); + } + } + + + protected void submitAsyncUnloadPlayer( Player player ) { + + PlayerCachePlayerData playerData = getPlayer( player ); + + if ( playerData != null ) { + + // Submit to unload right away with no delay: + PlayerCacheUnloadPlayerTask task = new PlayerCacheUnloadPlayerTask( playerData ); + int taskId = PrisonTaskSubmitter.runTaskLaterAsync( task, 0 ); + task.setTaskId( taskId ); + } + } + + + + /** + * Submit task to run only once. Should be started when this cache initializes. + * + */ + public PlayerCacheRunnable submitCacheRefresh() { + + PlayerCacheSaveAllPlayersTask task = new PlayerCacheSaveAllPlayersTask(); + + // Submit Timer Task to start running in 10 minutes (6000 ticks) and then + // refresh stats every 5 minutes (3000 ticks): + int taskId = PrisonTaskSubmitter.runTaskTimerAsync( task, 6000, 3000 ); + task.setTaskId( taskId ); + + return task; + } + + + public PlayerCacheRunnable submitCacheUpdatePlayerStats() { + + PlayerCacheCheckTimersTask task = new PlayerCacheCheckTimersTask(); + + // Submit Timer Task to start running in 30 seconds (600 ticks) and then + // refresh stats every 10 seconds (200 ticks): + int taskId = PrisonTaskSubmitter.runTaskTimerAsync( task, 600, 200 ); + task.setTaskId( taskId ); + + return task; + } + + + public void addPlayerBlocks( Player player, String mine, PrisonBlockStatusData block, int quantity ) { + addPlayerBlocks( player, mine, (PrisonBlock) block, quantity ); + } + public void addPlayerBlocks( Player player, String mine, PrisonBlock block, int quantity ) { + PlayerCachePlayerData playerData = getPlayer( player ); + +// Output.get().logInfo( "### addPlayerBlock: mine= " + (mine == null ? "null" : mine) + +// " block= " + (block == null ? "null" : block.getBlockName()) + " qty= " + quantity + " playerData= " + +// (playerData == null ? "null" : playerData.toString() )); + +// if ( playerData != null && playerData.getBlocksTotal() % 20 == 0 ) { +// Output.get().logInfo( "#### PlayerCache: " + playerData.toString() ); +// } + + playerData.addBlock( mine, block.getBlockName(), quantity ); + } + + /** + * This stores the earnings from the player so they can + * be averaged to find their earnings per minute. + * + * @param player + * @param earnings + */ + public void addPlayerEarnings( Player player, double earnings ) { + PlayerCachePlayerData playerData = getPlayer( player ); + + playerData.addEarnings( earnings ); + } + public double getPlayerEarningsPerMinute( Player player ) { + double earningsPerMinute = 0; + + PlayerCachePlayerData playerData = getPlayer( player ); + + if ( playerData != null ) { + earningsPerMinute = playerData.getAverageEarningsPerMinute(); + } + + return earningsPerMinute; + } + + public long getPlayerBlocksTotal( Player player ) + { + long blocksTotal = 0; + + PlayerCachePlayerData playerData = getPlayer( player ); + + if ( playerData != null ) { + blocksTotal = playerData.getBlocksTotal(); + } + + return blocksTotal; + } + public long getPlayerBlocksTotalByMine( Player player, String mineName ) + { + long blocksTotalByMine = 0; + + PlayerCachePlayerData playerData = getPlayer( player ); + + if ( playerData != null && mineName != null && playerData.getBlocksByMine() != null && + playerData.getBlocksByMine().containsKey( mineName ) ) { + + blocksTotalByMine = playerData.getBlocksByMine().get( mineName ); + } + + return blocksTotalByMine; + } + public long getPlayerBlocksTotalByBlockType( Player player, String blockType ) + { + long blocksTotalByBlockType = 0; + + PlayerCachePlayerData playerData = getPlayer( player ); + + if ( playerData != null && blockType != null && playerData.getBlocksByType() != null && + playerData.getBlocksByType().containsKey( blockType ) ) { + blocksTotalByBlockType = playerData.getBlocksByType().get( blockType ); + } + + return blocksTotalByBlockType; + } + + + public String getPlayerDumpStats() { + StringBuilder sb = new StringBuilder(); + + List keys = new ArrayList<>( getPlayers().keySet() ); + + for ( String key : keys ) { + PlayerCachePlayerData playerData = getPlayers().get( key ); + + sb.append( playerData.toString() ); + } + return sb.toString(); + } + + public PlayerCacheFiles getCacheFiles() { + return cacheFiles; + } + public void setCacheFiles( PlayerCacheFiles cacheFiles ) { + this.cacheFiles = cacheFiles; + } + + public PlayerCacheEvents getCacheEvents() { + return cacheEvents; + } + public void setCacheEvents( PlayerCacheEvents cacheEvents ) { + this.cacheEvents = cacheEvents; + } + + public PlayerCacheStats getStats() { + return stats; + } + public void setStats( PlayerCacheStats stats ) { + this.stats = stats; + } + + + + protected void log( String message ) { + Output.get().logInfo( message ); + } + + + public long getWriteDelay() { + return writeDelay; + } + public void setWriteDelay( long writeDelay ) { + this.writeDelay = writeDelay; + } + + protected Map getPlayers() { + return players; + } + + + public Map getTasks() { + return tasks; + } + + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheCheckTimersTask.java b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheCheckTimersTask.java new file mode 100644 index 000000000..84292dc31 --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheCheckTimersTask.java @@ -0,0 +1,65 @@ +package tech.mcprison.prison.cache; + +import java.util.ArrayList; +import java.util.List; + +/** + *

This periodically ran task will go through all cached players and update + * their status with the timers and earnings. This is a light weight task + * that only updates a few variables, and can be ran fairly frequently of about + * once per minute. There is no real need to run more frequently, but could + * increase the cycle time with no real impact, other than identifying when a player + * becomes AFK. + *

+ * + *

This task has nothing to do with trying to save anything. That is + * performed in PlayerCacheSaveAllPlayersTask, which is why this is a + * fast and lightweight. + *

+ * + *

The checkTimers will cut the online + * time in to more manageable sizes, and will eventually include checks for + * AFK status. These checks are bypassed if the player is not online. + *

+ * + *

By adding a zero earnings, this will force the "cache" of the last few + * minutes to progress and purge the older entries. So if the player mines for + * 5 minutes and the cache keeps track of earnings per minute over the last 5 + * minutes, then when they stop mining, and when this task runs, there will be + * an add earnings of zero which will create a new entry for zero. As such, + * this will purge the oldest entry. If a player is active, adding a zero + * earning entry, will have no impact since it will change the stored value, + * nor would it advance the entries. + *

+ * + */ +public class PlayerCacheCheckTimersTask + extends PlayerCacheRunnable +{ + + @Override + public void run() + { + + PlayerCache pCache = PlayerCache.getInstance(); + + List keys = new ArrayList<>( pCache.getPlayers().keySet() ); + + for ( String key : keys ) + { + PlayerCachePlayerData playerData = pCache.getPlayers().get( key ); + + if ( playerData != null ) { + + playerData.checkTimers(); + + // By adding a zero earnings, this will force the earnings "cache" to + // progress, even if the player stopped mining. + playerData.addEarnings( 0 ); + } + + } + + } + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheEvents.java b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheEvents.java new file mode 100644 index 000000000..127f9e2f4 --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheEvents.java @@ -0,0 +1,70 @@ +package tech.mcprison.prison.cache; + +import com.google.common.eventbus.Subscribe; + +import tech.mcprison.prison.Prison; +import tech.mcprison.prison.internal.Player; +import tech.mcprison.prison.internal.events.player.PlayerJoinEvent; +import tech.mcprison.prison.internal.events.player.PlayerKickEvent; +import tech.mcprison.prison.internal.events.player.PlayerQuitEvent; + +/** + *

This PlayerCacheEvents class self-registers these events with + * prison's event bus. + *

+ * + * @author RoyalBlueRanger + * + */ +public class PlayerCacheEvents + { + + public PlayerCacheEvents() { + super(); + + Prison.get().getEventBus().register(this); + } + + // NOTE: These are the bukkit event listeners that within the spigot module. + // They are included here to better express what these are for. +// @EventHandler +// public void onPlayerJoin(PlayerJoinEvent e) { +// Prison.get().getEventBus().post( +// new tech.mcprison.prison.internal.events.player.PlayerJoinEvent( +// new SpigotPlayer(e.getPlayer()))); +// } +// +// @EventHandler +// public void onPlayerQuit(PlayerQuitEvent e) { +// Prison.get().getEventBus().post( +// new tech.mcprison.prison.internal.events.player.PlayerQuitEvent( +// new SpigotPlayer(e.getPlayer()))); +// } +// @EventHandler +// public void onPlayerKicked(PlayerKickEvent e) { +// Prison.get().getEventBus().post( +// new tech.mcprison.prison.internal.events.player.PlayerKickEvent( +// new SpigotPlayer(e.getPlayer()), e.getReason())); +// } + + @Subscribe + public void onPlayerJoin(PlayerJoinEvent event) { + + Player player = event.getPlayer(); + PlayerCache.getInstance().submitAsyncLoadPlayer( player ); + } + + @Subscribe + public void onPlayerQuit(PlayerQuitEvent event) { + + Player player = event.getPlayer(); + PlayerCache.getInstance().submitAsyncUnloadPlayer( player ); + } + + @Subscribe + public void onPlayerKicked(PlayerKickEvent event) { + + Player player = event.getPlayer(); + PlayerCache.getInstance().submitAsyncUnloadPlayer( player ); + } +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheFiles.java b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheFiles.java new file mode 100644 index 000000000..0241bfdef --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheFiles.java @@ -0,0 +1,320 @@ +package tech.mcprison.prison.cache; + +import java.io.File; +import java.io.FileFilter; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonIOException; +import com.google.gson.JsonSyntaxException; + +import tech.mcprison.prison.Prison; +import tech.mcprison.prison.internal.Player; +import tech.mcprison.prison.output.Output; + +/** + *

This class is intended to be kept online and active for the full + * life of the server. It is intended to be used for the source point + * for accessing the PlayerCache files and directory. Plus this class + * is intended to manage the ORM (Java Objects to json files). + *

+ * + *

It should be noted that the loading and saving of the Player's + * data should always be done asynchronously. This class makes no + * attempt to control that aspect, but it is intended that these functions + * will be used through an asyc thread. + *

+ * + * @author RoyalBlueRanger + * + */ +public class PlayerCacheFiles +{ + private Gson gson = null; + + private File playerCacheDirectory = null; + + public PlayerCacheFiles() { + super(); + + } + + /** + *

This constructs the Gson engine using the optional pretty + * printing to help make it human readable. + *

+ * + * @return + */ + private Gson getGson() { + if ( gson == null ) { + gson = new GsonBuilder().setPrettyPrinting().create(); + } + return gson; + } + + /** + *

For generating a json String object from the player's data. + *

+ * + * @param player + * @return + */ + public String toJson( PlayerCachePlayerData player ) { + return getGson().toJson( player ); + } + + /** + *

This function serializes the provided Player's object to the + * json file, using the player data object as the source for the + * json data, and the File object that is stored in that object too. + *

+ * + *

If the player changes their name while they are online, and if that change + * actually percolates through to bukkit, the caching system will never attempt + * to change the Player's cached file while it's active. It will rename the + * file upon loading in to the cache the next time they are activated. + *

+ * + *

This function first saves the new player data to a temp file. If that + * was successful, then it deletes the original file, and renames the temp + * file back to the original name. + *

+ * + * @param player + */ + public void toJsonFile( PlayerCachePlayerData player) { + + File playerFile = player.getPlayerFile(); + File outTemp = createTempFile( playerFile ); + boolean success = false; + + try ( + FileWriter fw = new FileWriter( outTemp ); + ){ + getGson().toJson( player, fw ); + + success = true; + } + catch ( JsonIOException | IOException e ) { + e.printStackTrace(); + } + + if ( success && ( !playerFile.exists() || playerFile.delete()) ) { + outTemp.renameTo( playerFile ); + } + else { + + boolean removed = false; + if ( outTemp.exists() ) { + removed = outTemp.delete(); + } + + String message = String.format( + "Unable to rename PlayerCache temp file. It was %sremoved: %s", + (removed ? "" : "not "), outTemp.getAbsolutePath() ); + + Output.get().logWarn( message ); + } + } + + private File createTempFile( File file ) { + SimpleDateFormat sdf = new SimpleDateFormat("_yyyy-MM-dd_HH-mm-ss"); + String name = file.getName() + sdf.format( new Date() ) + ".temp"; + + return new File( file.getParentFile(), name); + } + + /** + *

This loads the PlayerCachePlayerData object from a saved json file. + *

+ * + */ + public PlayerCachePlayerData fromJsonFile( File inputFile ) { + PlayerCachePlayerData results = null; + try ( + FileReader fr = new FileReader( inputFile ); + ) { + + results = getGson().fromJson( + fr, PlayerCachePlayerData.class ); + } + catch ( IOException e ) + { + e.printStackTrace(); + } + catch ( JsonSyntaxException | JsonIOException e ) + { + e.printStackTrace(); + } + + return results; + } + + /** + *

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

+ * + *

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

+ * + *

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

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

This function returns the first 13 characters of the supplied + * file name, or UUID String. 13 characters only because the 14th character + * is a hyphen. + *

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

This function will take the project's data folder and construct the the path + * to the directory, if it does not exist, to where the player cache files are stored. + *

+ * + * @return + */ + public File getPlayerFilePath() { + if ( playerCacheDirectory == null ) { + + playerCacheDirectory = new File( Prison.get().getDataFolder(), "data_storage/playerCache" ); + playerCacheDirectory.mkdirs(); + + } + return playerCacheDirectory; + } + + /** + *

Constructs a File object for a specific player. + *

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

This function will take a Prison Player object, and load the correct PlayerCache + * file. The file name has a prefix of the first part of the player's UUID and then + * followed by the player's name. But it is important to understand that the Player's + * name part is totally ignored since player could change their name at any time. + *

+ * + *

By using the Player's UUID and player name, it constructs the file's full name. + * Then it takes the prefix, of the first 14 characters of the UUID, and gets all of + * the File objects within the cache directory. Since minecraft UUIDs are generated + * from random numbers, the first 14 characters "should" be unique. If the returned + * Files are not unique, then each returned File object is loaded so the the correct + * file can be selected by the internal UUID. Odds are there will never be duplicates, + * but if there is, it will handle it. + *

+ * + *

If the supplied Player is not in the cache, a new PlayerCachePlayerData object + * is created for the player (keyed on the player's UUID and name) and then it is + * saved to the cache directory. + *

+ * + *

Although the Player's file name prefix will always match it's data file, their + * name portion of the file can be dynamic. It is important that if the Player changes + * their name, that their save cached file will be change within this function. + * This process will only happen the first time the player is loaded from the cache + * (which can vary, such as at server startup or they logoff and they are cleared from + * the cache, then added back when they login the next time). So this function will + * rename the cache file to reflect the player's current name. + *

+ * + * @param player + * @return + */ + public PlayerCachePlayerData fromJson( Player player ) { + PlayerCachePlayerData results = null; + + String playerFileName = getPlayerFileName( player ); + String fileNamePrefix = getFileNamePrefix( playerFileName ); + + // This is the "target" file name for the player, based upon their + // current name. The saved cache file may not be named exactly the same, + // and if it's not, then their existing cache file needs to be + // renamed. + File playerFile = getPlayerFile( playerFileName ); + + + FileFilter fileFilter = file -> !file.isDirectory() && + file.getName().startsWith(fileNamePrefix) && + file.getName().endsWith(".json"); + + File[] files = playerFile.getParentFile().listFiles( fileFilter ); + + if ( files != null && files.length > 0 ) { + + for ( File file : files ) + { + PlayerCachePlayerData temp = fromJsonFile( file ); + if ( temp != null && temp.getPlayerUuid().equalsIgnoreCase( + player.getUUID().toString() ) ) { + + results = temp; + results.setPlayerFile( file ); + break; + } + } + } + + // New player and file does not exist so create it. + if ( results == null ) { + results = new PlayerCachePlayerData( player, playerFile ); + + // Then save it: + toJsonFile( results ); + } + + // Check to see if the player's name has changed, which means the generated + // file name does not match. If that is the situation, then need to rename + // the file to match the current player's name. + if ( results != null ) { + if ( results.getPlayerFile().equals( playerFile ) ) { + + results.getPlayerFile().renameTo( playerFile ); + results.setPlayerFile( playerFile ); + } + } + + return results; + } + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheLoadPlayerTask.java b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheLoadPlayerTask.java new file mode 100644 index 000000000..f2c03a26e --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheLoadPlayerTask.java @@ -0,0 +1,30 @@ +package tech.mcprison.prison.cache; + +import tech.mcprison.prison.internal.Player; + +public class PlayerCacheLoadPlayerTask + extends PlayerCacheTask +{ + + private Player player; + + public PlayerCacheLoadPlayerTask( Player player ) { + super( null ); + + this.player = player; + } + + public void run() { + + PlayerCache pCache = PlayerCache.getInstance(); + + PlayerCachePlayerData playerData = pCache.getCacheFiles().fromJson( player ); + + if ( playerData != null ) { + + pCache.addPlayerData( playerData ); + } + + } + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCachePlayerData.java b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCachePlayerData.java new file mode 100644 index 000000000..befae9dc1 --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCachePlayerData.java @@ -0,0 +1,534 @@ +package tech.mcprison.prison.cache; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TreeMap; + +import tech.mcprison.prison.internal.Player; +import tech.mcprison.prison.internal.block.PrisonBlock; +import tech.mcprison.prison.placeholders.PlaceholdersUtil; + +/** + *

This class represents the temporal state of a player's balance + * represented by both the internal (within the database) all the way + * through to the uncommitted value. There are three primary values + * and they server an important part to maintaining a fast and + * reliable cache. + *

+ * + * + * @author RoyalBlueRanger + * + */ +public class PlayerCachePlayerData { + + public static final long SESSION_TIMEOUT_MINING_MS = 1000 * 15; // 15 seconds + + private transient Player player; + + private String playerUuid; + private String playerName; + + private transient File playerFile = null; + + // NOTE: Since we are logging time online all players that have been online are + // always considered dirty since their online time would need to be updated. +// private transient boolean dirty = false; + + /** + * This Object lock is used to synchronized the public side of this class + * and the protected side of this class which is the database transaction + * side of things. + */ + @SuppressWarnings( "unused" ) + private transient final Object lock = new Object(); + + private transient PlayerCacheRunnable task = null; + + + private long onlineTimeTotal = 0L; + + // "active" time is not needed. It's the total onlineTimeTotal minus + // the other types. Tracking active could result in discrepancies and + // would be redundant. +// private long onlineActiveTimeTotal = 0L; + private long onlineAFKTimeTotal = 0L; + private long onlineMiningTimeTotal = 0L; + + + + private long blocksTotal = 0L; + + private TreeMap blocksByMine; + private TreeMap blocksByType; + + private TreeMap timeByMine; + private String lastMine = null; + + private TreeMap earningsByMine; + + + private transient TreeMap earningsPerMinute; + + + // This is the time when the "session" was started: + private transient SessionType sessionType; + + + private transient long sessionTimingStart = 0; + private transient long sessionTimingLastCheck = 0; + + // sessionLastLocation is used for afk calculations: +// private transient Location sessionLastLocation = null; + + private transient boolean dirty = false; + + + public enum SessionType { + active, + mining, + afk; + } + + public PlayerCachePlayerData() { + super(); + + this.blocksByMine = new TreeMap<>(); + this.blocksByType = new TreeMap<>(); + + this.timeByMine = new TreeMap<>(); + this.lastMine = null; + + this.earningsByMine = new TreeMap<>(); + + this.earningsPerMinute = new TreeMap<>(); + + this.sessionType = SessionType.active; + + this.sessionTimingStart = System.currentTimeMillis(); + this.sessionTimingLastCheck = sessionTimingStart; + +// this.sessionLastLocation = null; + + } + + public PlayerCachePlayerData( Player player, File playerFile ) { + this(); + + this.player = player; + + this.playerUuid = player.getUUID().toString(); + this.playerName = player.getName(); + + this.playerFile = playerFile; + +// this.sessionLastLocation = player.getLocation(); + + } + + public boolean isOnline() { + return getPlayer() != null && getPlayer().isOnline(); + } + + public void checkTimers() { + + if ( isOnline() ) { + + // Do not change the session type, so pass it the current: + checkTimersMining( sessionType, getLastMine() ); + + } + } + + /** + *

If the SessionType is mining, then that means that the last time + * a checkTimer was called, it was for mining. Mining can only be active for + * only a short duration after breaking a block. So once a block is broken, + * another block must be broken in a specified amount of time to be considered + * actively mining. + *

+ * + *

This function can only be called from a block break event. + *

+ * + *

If the prior SessionType was not mining, then that session segment may be + * either afk or active. Pass to afk check. Set current session type to mining. + *

+ * + *

If prior session type was mining, then do nothing if the last + * @param mine + */ + private void checkTimersMining( SessionType targetType, String mine ) { + final long currentTime = System.currentTimeMillis(); + + if ( !isOnline() ) { + return; + } + + // temp fix: + if ( onlineTimeTotal < 0 ) { + onlineTimeTotal = 0; + } + if ( onlineMiningTimeTotal < 0 ) { + onlineMiningTimeTotal = 0; + } + + if ( sessionType == targetType && sessionType != SessionType.mining) { + // No change in status + + sessionTimingLastCheck = currentTime; + + final long duration = currentTime - sessionTimingLastCheck; + // if duration is greater than 15 minutes, then move the session start + // point and save it. + if ( duration > 900000 ) { + + sessionTimingStart = currentTime; + dirty = true; + } + + } + else if ( sessionType != SessionType.mining ) { + + // Always Save as total time. Use sessionTimingStart. Ignore sessionTimingLastCheck. + final long duration = currentTime - sessionTimingStart; + onlineTimeTotal += duration; + + //checkTimersAfk(); + + sessionType = targetType; + sessionTimingStart = currentTime; + sessionTimingLastCheck = currentTime; + dirty = true; + } + else { + // The session type is still mining... + // Must check sessionTimingLastCheck to see if we went over the + // max mining idle time: + + final long duration = currentTime - sessionTimingLastCheck; + + + // If the duration is less than the session mining timeout, then player + // is still mining. Just set the sessionTimingLastCheck. + if ( duration < SESSION_TIMEOUT_MINING_MS ) { + + sessionTimingLastCheck = currentTime; + } + + // Mining can only be active for no more than SESSION_TIMEOUT_MINING_MS + // after the last block was broken. So check duration between now and + // sessionOnlineTimeLastCheck and if more than permitted, then shutdown + // mining session and log it for a duration since session start to + // last check plus the mining timeout value. Then set session start to + // that position. + + else if ( duration > SESSION_TIMEOUT_MINING_MS || getLastMine() == null || + mine.equalsIgnoreCase( getLastMine() )) { + + // Calculate the end point of the mining session, which will be 30 seconds after + // the last time check: + final long tempTime = sessionTimingLastCheck + SESSION_TIMEOUT_MINING_MS; + final long miningDuration = tempTime - sessionTimingStart; +// final long miningDuration = sessionTimingStart - tempTime; + onlineTimeTotal += miningDuration; + onlineMiningTimeTotal += miningDuration; + + addTimeToMine( mine, miningDuration ); + + // Set new session to this boundary: + sessionTimingStart = tempTime; + sessionTimingLastCheck = tempTime; + + // Since the last SessionType and current are mining, then the duration from + // the new sessionTimingStart to currentTime needs to go to active: + final long durationActive = currentTime - sessionTimingStart; + onlineTimeTotal += durationActive; + + //checkTimersAfk(); + + + // Now reset the current session: + sessionType = targetType; + sessionTimingStart = currentTime; + sessionTimingLastCheck = currentTime; + dirty = true; + + } + } + + } + + + + public void addBlock( String mine, String blockName, int quantity ) + { + if ( quantity > 0 && blockName != null && + !PrisonBlock.AIR.getBlockName().equalsIgnoreCase( blockName ) + ) { + this.blocksTotal += quantity; + + if ( blockName != null ) { + addBlockByType( blockName, quantity ); + } + + if ( mine != null ) { + addBlockByMine( mine, quantity ); + } + + checkTimersMining( SessionType.mining, mine ); + dirty = true; + } + } + + private void addBlockByType( String blockName, int quantity ) { + int qty = quantity; + + if ( getBlocksByType().containsKey( blockName ) ) { + qty += getBlocksByType().get( blockName ); + } + + getBlocksByType().put( blockName, qty ); + } + private void addBlockByMine( String mine, int quantity ) { + int qty = quantity; + + if ( getBlocksByMine().containsKey( mine ) ) { + qty += getBlocksByMine().get( mine ); + + } + + getBlocksByMine().put( mine, qty ); + } + + private void addEarningsByMine( String mine, double amount ) { + double amt = amount; + + if ( getEarningsByMine().containsKey( mine ) ) { + amt += getEarningsByMine().get( mine ); + + } + + getEarningsByMine().put( mine, amt ); + } + + private void addTimeToMine( String mine, long miningDuration ) + { + if ( mine != null && !mine.trim().isEmpty() ) { + + long duration = miningDuration; + + if ( getTimeByMine().containsKey( mine ) ) { + duration += getTimeByMine().get( mine ); + } + + setLastMine( mine ); + getTimeByMine().put( mine, duration ); + } + } + + /** + * This stores the earnings from the player so they can + * be averaged to find their earnings per minute. + * + * @param earnings + */ + public void addEarnings( double earnings ) { + SimpleDateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd_hh:mm"); + String key = dateFmt.format( new Date() ); + + if ( earningsPerMinute.containsKey( key ) ) { + earnings += earningsPerMinute.get( key ) + earnings; + } + + earningsPerMinute.put( key, earnings ); + + if ( earningsPerMinute.size() > 5 ) { + earningsPerMinute.remove( + earningsPerMinute.firstEntry().getKey() ); + } + + + // If earnings are within the session timeout for mining, then add the + // earnings to the moneyByMine: + if ( sessionType == SessionType.mining && getLastMine() != null ) { + long duration = System.currentTimeMillis() - sessionTimingLastCheck; + if ( duration < SESSION_TIMEOUT_MINING_MS ) { + addEarningsByMine( getLastMine(), earnings ); + } + } + + } + + /** + * This returns the average amount earned per minute for the + * last 5 minutes. + * + * @return + */ + public double getAverageEarningsPerMinute() { + double results = 0; + + int size = 0; + for ( double value : earningsPerMinute.values() ) { + results += value; + size++; + } + + return ( size == 0 ? 0 : ( results / size )); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + + String totalTime = PlaceholdersUtil.formattedTime( onlineTimeTotal / 1000d ); + String miningTime = PlaceholdersUtil.formattedTime( onlineMiningTimeTotal / 1000d ); + + sb.append( getPlayerName() ) + .append( " " ) + .append( isOnline() ? "online" : "OFFLINE" ) + .append( " avg earnings/min: " ) + .append( getAverageEarningsPerMinute() ) + + .append( " TotalOnlineTime: " ) + .append( totalTime ) + .append( " MiningTime: " ) + .append( miningTime ) + + .append( " totalBlocks: " ) + .append( blocksTotal ) + .append( " mines: " ) + .append( blocksByMine ) + .append( " blocks: " ) + .append( blocksByType ) + + ; + + return sb.toString(); + } + + + protected Player getPlayer() { + return player; + } + protected void setPlayer( Player player ) { + this.player = player; + } + + public File getPlayerFile() { + return playerFile; + } + public void setPlayerFile( File playerFile ) { + this.playerFile = playerFile; + } + + public String getPlayerUuid() { + return playerUuid; + } + public void setPlayerUuid( String playerUuid ) { + this.playerUuid = playerUuid; + } + + public String getPlayerName() { + return playerName; + } + public void setPlayerName( String playerName ) { + this.playerName = playerName; + } + + public PlayerCacheRunnable getTask() { + return task; + } + public void setTask( PlayerCacheRunnable task ) { + this.task = task; + } + + public TreeMap getEarningsPerMinute() { + if ( earningsPerMinute == null ) { + earningsPerMinute = new TreeMap<>(); + } + return earningsPerMinute; + } + public void setEarningsPerMinute( TreeMap earningsPerMinute ) { + this.earningsPerMinute = earningsPerMinute; + } + + public long getOnlineTimeTotal() { + return onlineTimeTotal; + } + public void setOnlineTimeTotal( long onlineTimeTotal ) { + this.onlineTimeTotal = onlineTimeTotal; + } + + public long getOnlineAFKTimeTotal() { + return onlineAFKTimeTotal; + } + public void setOnlineAFKTimeTotal( long onlineAFKTimeTotal ) { + this.onlineAFKTimeTotal = onlineAFKTimeTotal; + } + + public long getOnlineMiningTimeTotal() { + return onlineMiningTimeTotal; + } + public void setOnlineMiningTimeTotal( long onlineMiningTimeTotal ) { + this.onlineMiningTimeTotal = onlineMiningTimeTotal; + } + + public long getBlocksTotal() { + return blocksTotal; + } + public void setBlocksTotal( long blocksTotal ) { + this.blocksTotal = blocksTotal; + } + + public TreeMap getBlocksByMine() { + if ( blocksByMine == null ) { + blocksByMine = new TreeMap<>(); + } + return blocksByMine; + } + public void setBlocksByMine( TreeMap blocksByMine ) { + this.blocksByMine = blocksByMine; + } + + public TreeMap getBlocksByType() { + if ( blocksByType == null ) { + blocksByType = new TreeMap<>(); + } + return blocksByType; + } + public void setBlocksByType( TreeMap blocksByType ) { + this.blocksByType = blocksByType; + } + + public TreeMap getTimeByMine() { + return timeByMine; + } + public void setTimeByMine( TreeMap timeByMine ) { + this.timeByMine = timeByMine; + } + + public String getLastMine() { + return lastMine; + } + public void setLastMine( String lastMine ) { + this.lastMine = lastMine; + } + + public TreeMap getEarningsByMine() { + return earningsByMine; + } + public void setEarningsByMine( TreeMap earningsByMine ) { + this.earningsByMine = earningsByMine; + } + + public boolean isDirty() { + return dirty; + } + public void setDirty( boolean dirty ) { + this.dirty = dirty; + } + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheRunnable.java b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheRunnable.java new file mode 100644 index 000000000..f91857b71 --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheRunnable.java @@ -0,0 +1,32 @@ +package tech.mcprison.prison.cache; + +import tech.mcprison.prison.tasks.PrisonRunnable; + +public abstract class PlayerCacheRunnable + implements PrisonRunnable +{ + private int taskId = 0; + private boolean cancelled = false; + + public PlayerCacheRunnable() { + super(); + + } + + public int getTaskId() { + return taskId; + } + public void setTaskId( int taskId ) { + this.taskId = taskId; + } + + public void cancel() { + setCancelled( true ); + } + public boolean isCancelled() { + return cancelled; + } + public void setCancelled( boolean cancelled ) { + this.cancelled = cancelled; + } +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheSaveAllPlayersTask.java b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheSaveAllPlayersTask.java new file mode 100644 index 000000000..e4802a3d6 --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheSaveAllPlayersTask.java @@ -0,0 +1,102 @@ +package tech.mcprison.prison.cache; + +import java.util.ArrayList; +import java.util.List; + +import tech.mcprison.prison.output.Output; + +/** + *

This class provide periodical saving of all player data. + * This ensures that it's at least stored every once in a while. + * The data is only saved if it is marked as dirty. + *

+ * + *

NOTICE: There is a possibility that there could be a timing issue + * with saving the data when the data is being changed. This could be + * solved with synchronization of all data points, but at the expense + * of creating blocking for other threads, which could slow down response + * time and cause lag. This point is not "that" important since no data + * will be lost since it would be updated in the next save. + * But to help minimize the conflict, a simple use of removing the + * dirty flag before starting the save. The worst cause situation would + * be that the changes were save, but was marked as dirty.... or some + * data points were save from that transaction, but others were not. + * But neither of those matter, since everything will be "corrected" on + * the next save. + *

+ * + *

It's important to understand where issues could occur, but data + * would not be lost, and issues will self-correct on the next save. + * So it's important to always be able to save the data successfully. + *

+ * + *

About every 10 to 15 minutes would be good. After the server has + * been running for a while and it appears to be stable, then you may + * increase the time between saves. + *

+ * + *

This class only saves the data. It does not recalculate anything. + *

+ * + * @author RoyalBlueRanger + * + */ +public class PlayerCacheSaveAllPlayersTask + extends PlayerCacheRunnable +{ + + @Override + public void run() + { + + PlayerCache pCache = PlayerCache.getInstance(); + + List purge = new ArrayList<>(); + + List keys = new ArrayList<>( pCache.getPlayers().keySet() ); + + for ( String key : keys ) + { + PlayerCachePlayerData playerData = pCache.getPlayers().get( key ); + + if ( playerData != null && playerData.isDirty() ) { + + try + { + playerData.setDirty( false ); + pCache.getCacheFiles().toJsonFile( playerData ); + } + catch ( Exception e ) + { + String message = String.format( + "PlayerCache: Error trying to save a player's " + + "cache data. Will try again later. " + + "%s", e.getMessage() ); + Output.get().logError( message, e ); + } + } + + // If a cached item is found with the player being offline, then + // purge them from the cache. They were usually added only because + // some process had to inspect their stats, so they are safe to remove. + if ( playerData != null && !playerData.isOnline() ) { + purge.add( playerData ); + } + } + + + for ( PlayerCachePlayerData playerData : purge ) { + try { + if ( !playerData.isDirty() ) { + + pCache.getPlayers().remove( playerData.getPlayerUuid() ); + } + } + catch ( Exception e ) { + // Ignore any possible errors. They will be addressed on the next + // run of this task. + } + } + + } +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheStats.java b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheStats.java new file mode 100644 index 000000000..f317e481c --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheStats.java @@ -0,0 +1,180 @@ +package tech.mcprison.prison.cache; + +public class PlayerCacheStats { + + private long startMs; + + private boolean enabled = false; + + private int loadPlayer = 0; + private int unloadPlayer = 0; + private int removePlayer = 0; + private int getPlayer = 0; + + private int submitDatabaseUpdate = 0; + private int synchronizePlayers = 0; + + + private Object lock1 = new Object(); + private Object lock2 = new Object(); + private Object lock3 = new Object(); + private Object lock4 = new Object(); + private Object lock5 = new Object(); +// private Object lock6 = new Object(); +// private Object lock7 = new Object(); +// private Object lock8 = new Object(); +// private Object lock9 = new Object(); +// private Object lockA = new Object(); + private Object lockB = new Object(); + + public PlayerCacheStats() { + super(); + + this.startMs = System.currentTimeMillis(); + } + + /** + *

If enabled, stats will be collected. + *

+ * + * @return + */ + public boolean isEnabled() { + return enabled; + } + public void setEnabled( boolean enabled ) { + this.enabled = enabled; + } + public void toggleEnabled() { + this.enabled = !this.enabled; + } + + + + public String displayStats() { + StringBuilder sb = new StringBuilder(); + + sb.append( "PlayerCache stats: loadPlayer=" ).append( getLoadPlayer() ) + .append( " unloadPlayer=" ).append( getUnloadPlayer() ) + .append( " removePlayer=" ).append( getRemovePlayer() ) + .append( " getPlayer=" ).append( getGetPlayer() ) + + .append( " submitDatabaseUpdate=" ).append( getSubmitDatabaseUpdate() ) + .append( " synchronizeDatabase=" ).append( getSynchronizePlayers() ) + + ; + + return sb.toString(); + } + + public void clear() { + + setStartMs( System.currentTimeMillis() ); + + setLoadPlayer( 0 ); + setUnloadPlayer( 0 ); + setRemovePlayer( 0 ); + setGetPlayer( 0 ); + + setSubmitDatabaseUpdate( 0 ); + setSynchronizePlayers( 0 ); + + + } + + public void incrementGetPlayers() { + if ( enabled ) { + synchronized ( lock1 ) { + getPlayer++; + } + } + } + public void incrementRemovePlayers() { + if ( enabled ) { + synchronized ( lock2 ) { + removePlayer++; + } + } + } + public void incrementLoadPlayers() { + if ( enabled ) { + synchronized ( lock3 ) { + loadPlayer++; + } + } + } + public void incrementUnloadPlayers() { + if ( enabled ) { + synchronized ( lock4 ) { + unloadPlayer++; + } + } + } + + + public void incrementSubmitDatabaseUpdate() { + if ( enabled ) { + synchronized ( lock5 ) { + submitDatabaseUpdate++; + } + } + } + public void incrementSubmitSynchronizePlayers() { + if ( enabled ) { + synchronized ( lockB ) { + synchronizePlayers++; + } + } + } + + + public long getStartMs() { + return startMs; + } + public void setStartMs( long startMs ) { + this.startMs = startMs; + } + + public int getGetPlayer() { + return getPlayer; + } + public void setGetPlayer( int getPlayer ) { + this.getPlayer = getPlayer; + } + + public int getRemovePlayer() { + return removePlayer; + } + public void setRemovePlayer( int removePlayer ) { + this.removePlayer = removePlayer; + } + + public int getLoadPlayer() { + return loadPlayer; + } + public void setLoadPlayer( int loadPlayer ) { + this.loadPlayer = loadPlayer; + } + + public int getUnloadPlayer() { + return unloadPlayer; + } + public void setUnloadPlayer( int unloadPlayer ) { + this.unloadPlayer = unloadPlayer; + } + + public int getSubmitDatabaseUpdate() { + return submitDatabaseUpdate; + } + public void setSubmitDatabaseUpdate( int submitDatabaseUpdate ) { + this.submitDatabaseUpdate = submitDatabaseUpdate; + } + + public int getSynchronizePlayers() { + return synchronizePlayers; + } + public void setSynchronizePlayers( int synchronizePlayers ) { + this.synchronizePlayers = synchronizePlayers; + } + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheTask.java b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheTask.java new file mode 100644 index 000000000..4b346c9cb --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheTask.java @@ -0,0 +1,18 @@ +package tech.mcprison.prison.cache; + +public abstract class PlayerCacheTask + extends PlayerCacheRunnable +{ + private final PlayerCachePlayerData playerData; + + public PlayerCacheTask( PlayerCachePlayerData playerData ) { + super(); + + this.playerData = playerData; + } + + public PlayerCachePlayerData getPlayerData() { + return playerData; + } + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheUnloadPlayerTask.java b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheUnloadPlayerTask.java new file mode 100644 index 000000000..80ac4aee3 --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/cache/PlayerCacheUnloadPlayerTask.java @@ -0,0 +1,23 @@ +package tech.mcprison.prison.cache; + +public class PlayerCacheUnloadPlayerTask + extends PlayerCacheTask +{ + + public PlayerCacheUnloadPlayerTask( PlayerCachePlayerData playerData ) { + super( playerData ); + + } + + public void run() { + + PlayerCache pCache = PlayerCache.getInstance(); + + // Remove from the player cache: + PlayerCachePlayerData removed = pCache.removePlayerData( getPlayerData() ); + + pCache.getCacheFiles().toJsonFile( removed ); + + } + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/chat/FancyMessage.java b/prison-core/src/main/java/tech/mcprison/prison/chat/FancyMessage.java index 92e1ddeeb..c469709b0 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/chat/FancyMessage.java +++ b/prison-core/src/main/java/tech/mcprison/prison/chat/FancyMessage.java @@ -644,6 +644,10 @@ private void send(CommandSender sender, String jsonString) { public void send(CommandSender sender) { send(sender, toJSONString()); } + + public void sendJson( CommandSender sender, String jsonString ) { + send( sender, jsonString ); + } /** * Sends this message to multiple command senders. diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/Command.java b/prison-core/src/main/java/tech/mcprison/prison/commands/Command.java index 2e0554598..014a0d7bc 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/Command.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/Command.java @@ -91,4 +91,13 @@ public String[] aliases() default {}; + /** + * This is a list of URLs that should point back to the documentation that is appropriate + * to the command that these URLs are tied to. + * + * @return + */ + public String[] docURLs() default {}; + + } diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/CommandHandler.java b/prison-core/src/main/java/tech/mcprison/prison/commands/CommandHandler.java index 228be199b..60595d1bc 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/CommandHandler.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/CommandHandler.java @@ -28,6 +28,7 @@ import java.util.TreeSet; import tech.mcprison.prison.Prison; +import tech.mcprison.prison.chat.FancyMessage; import tech.mcprison.prison.commands.handlers.BlockArgumentHandler; import tech.mcprison.prison.commands.handlers.DoubleArgumentHandler; import tech.mcprison.prison.commands.handlers.DoubleClassArgumentHandler; @@ -41,8 +42,10 @@ import tech.mcprison.prison.internal.CommandSender; import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.internal.World; +import tech.mcprison.prison.output.ChatDisplay; import tech.mcprison.prison.output.LogLevel; import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.output.RowComponent; import tech.mcprison.prison.util.BlockType; import tech.mcprison.prison.util.ChatColor; @@ -128,33 +131,36 @@ private String formatArgument(CommandArgument argument) { } @Override - public String[] getHelpMessage(RegisteredCommand command) { - ArrayList message = new ArrayList(); + public ChatDisplay getHelpMessage(RegisteredCommand command) { + + ChatDisplay chatDisplay = new ChatDisplay( + String.format( "Cmd: &7%s", + getUsageNoParameters(command)) ); if (command.isSet() && command.getDescription() != null && !command.getDescription().isEmpty()) { - message.add(ChatColor.DARK_AQUA + command.getDescription()); + chatDisplay.addText(ChatColor.DARK_AQUA + command.getDescription()); } - message.add(getUsage(command)); + chatDisplay.addText(getUsage(command)); if (command.isSet()) { for (CommandArgument argument : command.getArguments()) { - message.add(formatArgument(argument)); + chatDisplay.addText(formatArgument(argument)); } if (command.getWildcard() != null) { - message.add(formatArgument(command.getWildcard())); + chatDisplay.addText(formatArgument(command.getWildcard())); } List flags = command.getFlags(); if (flags.size() > 0) { - message.add(ChatColor.DARK_AQUA + "Flags:"); + chatDisplay.addText(ChatColor.DARK_AQUA + "Flags:"); for (Flag flag : flags) { StringBuilder args = new StringBuilder(); for (FlagArgument argument : flag.getArguments()) { args.append(" [" + argument.getName() + "]"); } - message.add("-" + flag.getIdentifier() + ChatColor.AQUA + args.toString()); + chatDisplay.addText("-" + flag.getIdentifier() + ChatColor.AQUA + args.toString()); for (FlagArgument argument : flag.getArguments()) { - message.add(formatArgument(argument)); + chatDisplay.addText(formatArgument(argument)); } } } @@ -181,11 +187,11 @@ public String[] getHelpMessage(RegisteredCommand command) { } if ( sb.length() > 0 ) { - message.add(ChatColor.DARK_AQUA + "Permissions:"); + chatDisplay.addText(ChatColor.DARK_AQUA + "Permissions:"); sb.insert( 0, ChatColor.AQUA ); sb.insert( 0, " " ); - message.add( sb.toString() ); + chatDisplay.addText( sb.toString() ); } } @@ -205,10 +211,36 @@ public String[] getHelpMessage(RegisteredCommand command) { } if ( sb.length() > 0 ) { - message.add(ChatColor.DARK_AQUA + "Aliases:"); + chatDisplay.addText(ChatColor.DARK_AQUA + "Aliases:"); sb.insert( 0, " " ); - message.add( sb.toString() ); + chatDisplay.addText( sb.toString() ); + } + + } + if ( command.getDocURLs() != null && command.getDocURLs().length > 0 ) { + + chatDisplay.addText(ChatColor.DARK_AQUA + "Documentation:"); + + for ( String docURL : command.getDocURLs() ) { + RowComponent row = new RowComponent(); + + row.addTextComponent( " " ); + FancyMessage fMessage = new FancyMessage( docURL ).link( docURL ) + .tooltip( "Click to open link" ); + row.addFancy( fMessage ); + + chatDisplay.addComponent( row ); + + + +// StringBuilder sb = new StringBuilder(); +// +// sb.append( " " ).append( ChatColor.DARK_BLUE ).append( "[" ) +// .append( ChatColor.AQUA ).append( docURL ) +// .append( ChatColor.DARK_BLUE ).append( "]" ); +// +// chatDisplay.addText( sb.toString() ); } } @@ -216,7 +248,7 @@ public String[] getHelpMessage(RegisteredCommand command) { List subcommands = command.getSuffixes(); if (subcommands.size() > 0) { - message.add(ChatColor.DARK_AQUA + "Subcommands:"); + chatDisplay.addText(ChatColor.DARK_AQUA + "Subcommands:"); // Force a sorting by use of a TreeSet. Collections.sort() would not work. TreeSet subCommandSet = new TreeSet<>(); for (RegisteredCommand scommand : subcommands) { @@ -233,7 +265,7 @@ public String[] getHelpMessage(RegisteredCommand command) { } for (String subCmd : subCommandSet) { - message.add(subCmd); + chatDisplay.addText(subCmd); } } @@ -242,17 +274,26 @@ public String[] getHelpMessage(RegisteredCommand command) { ArrayList rootCommandsMessages = buildHelpRootCommands(); if ( rootCommandsMessages.size() > 1 ) { - message.addAll( rootCommandsMessages ); + for ( String rootCmd : rootCommandsMessages ) + { + chatDisplay.addText( rootCmd ); + } + } ArrayList aliasesMessages = buildHelpAliases(); if ( aliasesMessages.size() > 1 ) { - message.addAll( aliasesMessages ); + for ( String alias : aliasesMessages ) + { + chatDisplay.addText( alias ); + } + } } - return message.toArray(new String[0]); + return chatDisplay; +// return message.toArray(new String[0]); } private ArrayList buildHelpRootCommands() { @@ -390,6 +431,25 @@ private String getRootCommandRegisteredLabel(RegisteredCommand command ) { return commandLabel; } + @Override + public String getUsageNoParameters(RegisteredCommand command) { + StringBuilder usage = new StringBuilder(); + + String cmdLabel = getRootCommandRegisteredLabel( command ); + usage.append(cmdLabel); + + RegisteredCommand parent = command.getParent(); + while (parent != null) { + String label = getRootCommandRegisteredLabel( parent ); + usage.insert(0, label + " "); + parent = parent.getParent(); + } + + usage.insert(0, "/"); + + return usage.toString(); + } + @Override public String getUsage(RegisteredCommand command) { StringBuilder usage = new StringBuilder(); diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/HelpHandler.java b/prison-core/src/main/java/tech/mcprison/prison/commands/HelpHandler.java index c19c61515..525562117 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/HelpHandler.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/HelpHandler.java @@ -18,9 +18,13 @@ package tech.mcprison.prison.commands; +import tech.mcprison.prison.output.ChatDisplay; + public interface HelpHandler { - public String[] getHelpMessage(RegisteredCommand command); + public ChatDisplay getHelpMessage(RegisteredCommand command); + public String getUsageNoParameters(RegisteredCommand command); + public String getUsage(RegisteredCommand command); } diff --git a/prison-core/src/main/java/tech/mcprison/prison/commands/RegisteredCommand.java b/prison-core/src/main/java/tech/mcprison/prison/commands/RegisteredCommand.java index 8a3034574..ba3627088 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/commands/RegisteredCommand.java +++ b/prison-core/src/main/java/tech/mcprison/prison/commands/RegisteredCommand.java @@ -29,6 +29,7 @@ import tech.mcprison.prison.Prison; import tech.mcprison.prison.internal.CommandSender; +import tech.mcprison.prison.output.ChatDisplay; import tech.mcprison.prison.output.LogLevel; import tech.mcprison.prison.output.Output; @@ -47,6 +48,9 @@ public class RegisteredCommand private String[] permissions; private String[] altPermissions; private String[] aliases; + private String[] docURLs; + + private List registeredAliases; private RegisteredCommand parentOfAlias; @@ -297,7 +301,7 @@ public List getFlags() { return flags; } - public String[] getHelpMessage() { + public ChatDisplay getHelpMessage() { return handler.getHelpHandler().getHelpMessage(this); } @@ -328,6 +332,10 @@ public String[] getAliases() { return aliases; } + public String[] getDocURLs() { + return docURLs; + } + public List getRegisteredAliases() { return registeredAliases; } @@ -375,7 +383,8 @@ public boolean onlyPlayers() { } public void sendHelpMessage(CommandSender sender) { - sender.sendMessage(getHelpMessage()); + + getHelpMessage().send( sender ); } void set(Object methodInstance, Method method) { @@ -388,6 +397,7 @@ void set(Object methodInstance, Method method) { this.permissions = command.permissions(); this.altPermissions = command.altPermissions(); this.aliases = command.aliases(); + this.docURLs = command.docURLs(); this.onlyPlayers = command.onlyPlayers(); diff --git a/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonPasteChat.java b/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonPasteChat.java index 433e0206d..3ac2fc252 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonPasteChat.java +++ b/prison-core/src/main/java/tech/mcprison/prison/discord/PrisonPasteChat.java @@ -9,6 +9,8 @@ import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.Set; +import java.util.TreeMap; import javax.net.ssl.HttpsURLConnection; @@ -65,27 +67,44 @@ public class PrisonPasteChat { private static final String hastebinURLraw = "raw/"; // private static final String hastebinURL = "https://hastebin.com/documents"; - public static final int HASTEBIN_MAX_LENGTH = 200000; + public static final int HASTEBIN_MAX_LENGTH = 390000; private static final String SUBMISSION_SIZE_PLACEHOLDER = "{submissionSizeInBytes-------}"; private String supportName; + private TreeMap supportURLs; - public PrisonPasteChat( String supportName ) { + public PrisonPasteChat( String supportName, TreeMap supportURLs ) { super(); this.supportName = supportName; + this.supportURLs = supportURLs; } - public String post ( String text ) { - return post( text, false ); + public String post( String text ) { + return post( text, false, false ); } - public String post( String text, boolean raw ) { + /** + *

This posts the text, but during the cleaning process it keeps the + * color codes. This is good for configuration files. This is bad for + * processed, and already translated output and log files. + *

+ * + * @param text + * @return + */ + public String postKeepColorCodes( String text ) { + return post( text, false, true ); + } + + public String post( String text, boolean raw, boolean keepColorCodes ) { String results = null; try { - String cleanedText = cleanText( text ); + String cleanedText = cleanText( text, keepColorCodes ); + + cleanedText = addHeaders( cleanedText ); results = postPaste( cleanedText, raw ); } @@ -97,11 +116,33 @@ public String post( String text, boolean raw ) { return results; } - private String cleanText( String text ) + /** + *

This function will clean up the text by removing a lot of the + * junk color codes (the unicode fails) and also remove translated color + * codes that have already been converted. + *

+ * + *

The option keepcolorCodes will preserve the & color codes. It does this + * by first converting them to an arbitrary placeholder, then the text is + * cleaned, then the temporary placeholders are converted back to &. + *

+ * + * @param text + * @param keepColorCodes + * @return + */ + protected String cleanText( String text, boolean keepColorCodes ) { - String cleanedText = Text.stripColor( text ); + String cleanedText = text; + + if ( keepColorCodes ) { + cleanedText = cleanedText.replaceAll("&", "^amp^"); + } + + cleanedText = Text.stripColor( cleanedText ); + - cleanedText = setupSupportPrefix() + + cleanedText = cleanedText.replaceAll( "\\[m|\\[0;30;1m|\\[0;31;1m|\\[0;32;1m|\\[0;33;1m|\\[0;34;1m|\\[0;35;1m|" + "\\[0;36;1m|\\[0;37;1m|\\[0;38;1m|\\[0;39;1m|" + @@ -110,21 +151,41 @@ private String cleanText( String text ) "", "" ); + if ( keepColorCodes ) { + cleanedText = cleanedText.replaceAll("\\^amp\\^", "&"); + } + // Max length of 400,000 characters: Trim and send first section only. if ( cleanedText.length() > HASTEBIN_MAX_LENGTH ) { cleanedText = cleanedText.substring( 0, HASTEBIN_MAX_LENGTH ); } +// // Injects the size back in to the text without changing the total length of the text: +// int size = cleanedText.length(); +// DecimalFormat dFmt = new DecimalFormat("#,##0"); +// String sizeString = (dFmt.format( size ) + " bytes ") +// .substring( 0, SUBMISSION_SIZE_PLACEHOLDER.length() ); +// +// cleanedText = cleanedText.replace( SUBMISSION_SIZE_PLACEHOLDER, sizeString ); + + return cleanedText; + } + + private String addHeaders( String text ) { + + text = setupSupportPrefix() + text; + // Injects the size back in to the text without changing the total length of the text: - int size = cleanedText.length(); + int size = text.length(); + DecimalFormat dFmt = new DecimalFormat("#,##0"); String sizeString = (dFmt.format( size ) + " bytes ") .substring( 0, SUBMISSION_SIZE_PLACEHOLDER.length() ); - cleanedText = cleanedText.replace( SUBMISSION_SIZE_PLACEHOLDER, sizeString ); + text = text.replace( SUBMISSION_SIZE_PLACEHOLDER, sizeString ); - return cleanedText; + return text; } private String setupSupportPrefix() { @@ -133,15 +194,26 @@ private String setupSupportPrefix() { SimpleDateFormat sdFmt = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ); - sb.append( "Support Name: " ).append( supportName ).append( "\n" ); - sb.append( "Submission Date: " ).append( sdFmt.format( new Date() ) ).append( "\n" ); - sb.append( "Submission Size: " ).append( SUBMISSION_SIZE_PLACEHOLDER ).append( "\n" ); + sb.append( "Support Name: " ).append( supportName ).append( "\n" ); + sb.append( "Submission Date: " ).append( sdFmt.format( new Date() ) ).append( "\n" ); + sb.append( "Submission Size: " ).append( SUBMISSION_SIZE_PLACEHOLDER ).append( "\n" ); + + sb.append( "\n" ); + + Set urlKeys = getSupportURLs().keySet(); + for ( String key : urlKeys ) { + sb.append( padSpaces(key) ).append( getSupportURLs().get( key ) ).append( "\n" ); + } sb.append( "\n" ); return sb.toString(); } + private String padSpaces( String keyName ) { + return (keyName + " ").substring( 0,18 ); + } + private String postPaste( String text, boolean raw ) throws IOException { String results = null; @@ -198,4 +270,11 @@ private String postPaste( String text, boolean raw ) return results; } + public TreeMap getSupportURLs() { + return supportURLs; + } + public void setSupportURLs( TreeMap supportURLs ) { + this.supportURLs = supportURLs; + } + } diff --git a/prison-core/src/main/java/tech/mcprison/prison/integration/Integration.java b/prison-core/src/main/java/tech/mcprison/prison/integration/Integration.java index 06c4bbf7c..5a3f0e02d 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/integration/Integration.java +++ b/prison-core/src/main/java/tech/mcprison/prison/integration/Integration.java @@ -128,4 +128,7 @@ public interface Integration { public String getDebugInfo(); public void setDebugInfo( String debugInfo ); public void addDebugInfo( String debugInfo ); + + + public void disableIntegration(); } diff --git a/prison-core/src/main/java/tech/mcprison/prison/integration/IntegrationCore.java b/prison-core/src/main/java/tech/mcprison/prison/integration/IntegrationCore.java index 07516dac4..f644cbed5 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/integration/IntegrationCore.java +++ b/prison-core/src/main/java/tech/mcprison/prison/integration/IntegrationCore.java @@ -81,7 +81,10 @@ public void integrate() { } - + public void disableIntegration() { + + } + public String getKeyName() { return keyName; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/integration/IntegrationManager.java b/prison-core/src/main/java/tech/mcprison/prison/integration/IntegrationManager.java index aacc3e390..9f7e2529e 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/integration/IntegrationManager.java +++ b/prison-core/src/main/java/tech/mcprison/prison/integration/IntegrationManager.java @@ -12,6 +12,7 @@ import tech.mcprison.prison.internal.block.PrisonBlock.PrisonBlockType; import tech.mcprison.prison.output.DisplayComponent; import tech.mcprison.prison.output.FancyMessageComponent; +import tech.mcprison.prison.output.Output; import tech.mcprison.prison.output.TextComponent; import tech.mcprison.prison.placeholders.PlaceholderManager.PrisonPlaceHolders; @@ -295,12 +296,12 @@ else if ( plugins == null || plugins.size() == 0 ) { */ public void getPlaceholderTemplateList( List results ) { - results.add( new TextComponent( " &7Available PlaceHolders: " )); + //results.add( new TextComponent( " &7Available PlaceHolders: " )); List placeholders = PrisonPlaceHolders.getAllChatList(true); // StringBuilder sb = new StringBuilder(); for ( String placeholder : placeholders ) { - results.add( new TextComponent( " " + placeholder )); + results.add( new TextComponent( " " + placeholder )); // if ( sb.length() == 0) { // sb.append( " " ); @@ -337,12 +338,60 @@ public void addDeferredInitialization( Integration defferedIntegration ) { public void register( Integration integration, boolean isRegistered, String version ) { - integration.setRegistered( isRegistered ); - integration.setVersion( version ); + try { + + integration.setRegistered( isRegistered ); + integration.setVersion( version ); + + integration.integrate(); + + if ( integration.hasIntegrated() ) { + register(integration ); + } +// else { +// boolean deferredRemoved = getDeferredIntegrations().remove( integration ); +// +// Output.get().logWarn( +// String.format( "Warning: An integration that is registered with bukkit " + +// "failed to integrate: %s %s %s[%s]", +// integration.getKeyName(), integration.getVersion(), +// ( deferredRemoved ? "(Deferred Processing Removed) " : "" ), +// (integration.getDebugInfo() == null ? +// "no debug info" : integration.getDebugInfo()) )); +// } + } + catch ( Exception e ) { + boolean deferredRemoved = getDeferredIntegrations().remove( integration ); + + removeIntegration( integration ); - integration.integrate(); + Output.get().logWarn( + String.format( "Warning: An integration caused an error while loading. " + + "Disabling the integration to protect Prison: %s %s %s[%s]", + integration.getKeyName(), integration.getVersion(), + ( deferredRemoved ? "(Deferred Processing Removed) " : "" ), + (integration.getDebugInfo() == null ? + "no debug info" : integration.getDebugInfo()) )); + + } - register(integration ); + } + + + /** + *

This will perform a best effort to remove an integration. It will not remove it from + * the deferred list, but it would not be able to run. + *

+ * + * @param integration + */ + public void removeIntegration( Integration integration ) + { + // make sure it's disabled: + integration.setRegistered( false ); + integration.disableIntegration(); + + integrations.get( integration.getType() ).remove( integration ); } diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/Player.java b/prison-core/src/main/java/tech/mcprison/prison/internal/Player.java index 18ad7c4bb..f9386696d 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/Player.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/Player.java @@ -47,6 +47,8 @@ public interface Player */ String getDisplayName(); + public String toString(); + /** * Sets the player's display name (nickname). * @@ -131,10 +133,17 @@ public interface Player void updateInventory(); - /** - * Dumps the inventory contents of the player to the console. - * - */ - public void printDebugInventoryInformationToConsole(); +// /** +// * Dumps the inventory contents of the player to the console. +// * +// */ +// public void printDebugInventoryInformationToConsole(); + + + public void setTitle( String title, String subtitle, int fadeIn, int stay, int fadeOut ); + + public void setActionBar( String actionBar ); + + } diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/PlayerUtil.java b/prison-core/src/main/java/tech/mcprison/prison/internal/PlayerUtil.java new file mode 100644 index 000000000..49be5f869 --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/PlayerUtil.java @@ -0,0 +1,151 @@ +package tech.mcprison.prison.internal; + +import java.util.UUID; + +public abstract class PlayerUtil +{ + + private UUID playerUuid; + + + public enum ItemType { + pickaxe, + axe, + shovel, + hoe, + + sword, + bow, + crossbow, + shears, + + boots, + chestplate, + helmet, + horse_armor, + leggings, + shield; + + public static ItemType fromString( String value ) { + ItemType results = null; + + if ( value != null && !value.isEmpty() ) { + value = value.trim().toLowerCase(); + + for ( ItemType iType : values() ) + { + if ( value.contains( iType.name() )) { + results = iType; + break; + } + } + } + return results; + } + } + + public enum ItemMaterial { + stone, + wooden, + iron, + golden, + diamond, + netherite, + chainmail, + leather, + turtle; + + public static ItemMaterial fromString( String value ) { + ItemMaterial results = null; + + if ( value != null && !value.isEmpty() ) { + value = value.trim().toLowerCase(); + + for ( ItemMaterial iTMaterial : values() ) + { + if ( value.contains( iTMaterial.name() )) { + results = iTMaterial; + break; + } + } + } + return results; + } + } + + public PlayerUtil( UUID playerUuid ) { + super(); + + this.playerUuid = playerUuid; + + } + + public abstract boolean isActive(); + + public abstract double getHealth(); + + public abstract double getMaxHealth(); + + public abstract void setMaxHealth( double maxHealth ); + + public abstract int getMaximumAir(); + + public abstract int getRemainingAir(); + + public abstract int getFoodLevel(); + + public abstract void setFoodLevel( int foodLevel ); + + public abstract void incrementFoodExhaustionBlockBreak(); + + public abstract double getFoodSaturation(); + + public abstract double getFoodExhaustion(); + + public abstract double getExp(); + + public abstract int getExpToLevel(); + + public abstract int getLevel(); + + public abstract double getWalkSpeed(); + + public abstract ItemStack getPrisonItemStack(); + + public abstract String getItemInHandName(); + + public abstract String getItemInHandDisplayID(); + + public abstract String getItemInHandDisplayName(); + + public abstract String getItemInHandItemType(); + + public abstract String getItemInHandItemMaterial(); + + public abstract int getItemInHandDurabilityUsed(); + + public abstract int getItemInHandDurabilityMax(); + + public abstract int getItemInHandDurabilityRemaining(); + + public abstract double getItemInHandDurabilityPercent(); + + public abstract int getItemInHandEnchantmentFortune(); + + public abstract int getItemInHandEnchantmentEfficency(); + + public abstract int getItemInHandEnchantmentSilkTouch(); + + public abstract int getItemInHandEnchantmentUnbreaking(); + + public abstract int getItemInHandEnchantmentMending(); + + public abstract int getItemInHandEnchantmentLuck(); + + public UUID getPlayerUuid() { + return playerUuid; + } + public void setPlayerUuid( UUID playerUuid ) { + this.playerUuid = playerUuid; + } +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/World.java b/prison-core/src/main/java/tech/mcprison/prison/internal/World.java index 9921126e7..8f1b87117 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/World.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/World.java @@ -21,6 +21,7 @@ import java.util.List; import tech.mcprison.prison.internal.block.Block; +import tech.mcprison.prison.internal.block.PrisonBlock; import tech.mcprison.prison.util.Location; /** @@ -47,5 +48,9 @@ public interface World { * @param location The {@link Location} of the block. */ public Block getBlockAt(Location location); + + + + public void setBlock( PrisonBlock block, int x, int y, int z ); } diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockStatusData.java b/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockStatusData.java index 731490c5c..31b10143d 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockStatusData.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/block/PrisonBlockStatusData.java @@ -18,7 +18,7 @@ public abstract class PrisonBlockStatusData { private int constraintExcludeTopLayers; private int constraintExcludeBottomLayers; - private int blockCountOnReset; + private int blockPlacedCount; private long blockCountTotal; private long blockCountSession; @@ -29,6 +29,9 @@ public abstract class PrisonBlockStatusData { private int rangeBlockCountLow; private int rangeBlockCountHigh; + private int rangeBlockCountLowLimit; + private int rangeBlockCountHighLimit; + public PrisonBlockStatusData( String blockName, double chance, long blockCountTotal ) { super(); @@ -43,7 +46,7 @@ public PrisonBlockStatusData( String blockName, double chance, long blockCountTo this.constraintExcludeTopLayers = 0; this.constraintExcludeBottomLayers = 0; - this.blockCountOnReset = 0; + this.blockPlacedCount = 0; this.blockCountTotal = blockCountTotal; this.blockCountSession = 0; @@ -51,6 +54,9 @@ public PrisonBlockStatusData( String blockName, double chance, long blockCountTo this.rangeBlockCountLow = -1; this.rangeBlockCountHigh = -1; + + this.rangeBlockCountLowLimit = -1; + this.rangeBlockCountHighLimit = -1; } public void resetAfterSave() { @@ -58,11 +64,11 @@ public void resetAfterSave() { } public void incrementResetBlockCount() { - blockCountOnReset++; + blockPlacedCount++; } public void decrementResetBlockCount() { - blockCountOnReset--; + blockPlacedCount--; } public void incrementMiningBlockCount() { @@ -169,7 +175,7 @@ public String toPlaceholderString() { String percent = fFmt.format(getChance()); // String spawned = dFmt.format( getResetBlockCount() ); - String remaining = dFmt.format( getResetBlockCount() - getBlockCountUnsaved() ); + String remaining = dFmt.format( getBlockPlacedCount() - getBlockCountUnsaved() ); String total = PlaceholdersUtil.formattedKmbtSISize( 1.0d * getBlockCountTotal(), dFmt, "" ); sb.append( getBlockName() ).append( " (" ) @@ -257,7 +263,7 @@ currentLevel < getConstraintExcludeBottomLayers() ) ) { // If Max is enabled (non zero) has the block reached that limit yet? if ( ( getConstraintMax() == 0 || - getConstraintMax() > 0 && getResetBlockCount() < getConstraintMax() ) + getConstraintMax() > 0 && getBlockPlacedCount() < getConstraintMax() ) ) { enabled = true; @@ -276,7 +282,7 @@ currentLevel < getConstraintExcludeBottomLayers() ) ) { */ public void addStats( PrisonBlockStatusData block ) { - setResetBlockCount( getResetBlockCount() + block.getResetBlockCount() ); + setBlockPlacedCount( getBlockPlacedCount() + block.getBlockPlacedCount() ); setBlockCountSession( getBlockCountSession() + block.getBlockCountSession() ); setBlockCountTotal( getBlockCountTotal() + block.getBlockCountTotal() ); setBlockCountUnsaved( getBlockCountUnsaved() + block.getBlockCountUnsaved() ); @@ -310,11 +316,11 @@ public void setChance( double chance ) { this.chance = chance; } - public int getResetBlockCount() { - return blockCountOnReset; + public int getBlockPlacedCount() { + return blockPlacedCount; } - public void setResetBlockCount( int resetBlockCount ) { - this.blockCountOnReset = resetBlockCount; + public void setBlockPlacedCount( int blockPlacedCount ) { + this.blockPlacedCount = blockPlacedCount; } public long getBlockCountTotal() { @@ -380,4 +386,18 @@ public void setRangeBlockCountHigh( int rangeBlockCountHigh ) { this.rangeBlockCountHigh = rangeBlockCountHigh; } + public int getRangeBlockCountLowLimit() { + return rangeBlockCountLowLimit; + } + public void setRangeBlockCountLowLimit( int rangeBlockCountLowLimit ) { + this.rangeBlockCountLowLimit = rangeBlockCountLowLimit; + } + + public int getRangeBlockCountHighLimit() { + return rangeBlockCountHighLimit; + } + public void setRangeBlockCountHighLimit( int rangeBlockCountHighLimit ) { + this.rangeBlockCountHighLimit = rangeBlockCountHighLimit; + } + } diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/platform/HandlerList.java b/prison-core/src/main/java/tech/mcprison/prison/internal/platform/HandlerList.java new file mode 100644 index 000000000..ca6a1799e --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/platform/HandlerList.java @@ -0,0 +1,6 @@ +package tech.mcprison.prison.internal.platform; + +public interface HandlerList +{ + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/internal/platform/Platform.java b/prison-core/src/main/java/tech/mcprison/prison/internal/platform/Platform.java index 1a93f4b76..ba68215d0 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/internal/platform/Platform.java +++ b/prison-core/src/main/java/tech/mcprison/prison/internal/platform/Platform.java @@ -28,6 +28,7 @@ import tech.mcprison.prison.file.YamlFileIO; import tech.mcprison.prison.internal.CommandSender; import tech.mcprison.prison.internal.Player; +import tech.mcprison.prison.internal.PlayerUtil; import tech.mcprison.prison.internal.Scheduler; import tech.mcprison.prison.internal.World; import tech.mcprison.prison.internal.block.PrisonBlock; @@ -81,7 +82,10 @@ public interface Platform { * Returns a list of all online players. */ List getOnlinePlayers(); - + + public List getOfflinePlayers(); + + // NOTE: Disabling for now. There is an internal failure within the Prison code base when trying // to use this, so will revisit in the future. public Optional getOfflinePlayer(String name); @@ -261,6 +265,8 @@ default Optional getCommand(String label) { public String getConfigString( String key ); + public String getConfigString( String key, String defaultValue ); + /** *

This returns the boolean value that is associated with the key. @@ -339,10 +345,11 @@ public ModuleElement createModuleElement( CommandSender sender, ModuleElementTyp public boolean isMineAccessibleByRank( Player player, ModuleElement mine ); - public void autoCreateMineBlockAssignment( boolean forceKeepBlocks ); + public void autoCreateMineBlockAssignment( List rankMineNames, boolean forceKeepBlocks ); - public void autoCreateMineLinerAssignment(); + public void autoCreateMineLinerAssignment( List rankMineNames, + boolean forceLinersBottom, boolean forceLinersWalls ); public void autoCreateConfigureMines(); @@ -356,11 +363,63 @@ public ModuleElement createModuleElement( CommandSender sender, ModuleElementTyp public List getActiveFeatures(); - public void dumpEventListenersBlockBreakEvents(); + public String dumpEventListenersBlockBreakEvents(); - public void dumpEventListenersPlayerChatEvents(); + public String dumpEventListenersPlayerChatEvents(); public void traceEventListenersBlockBreakEvents( CommandSender sender ); + + + public void testPlayerUtil( UUID uuid ); + + + public void saveResource( String string, boolean replace ); + + + public String getMinesListString(); + + + public String getRanksListString(); + + + public PlayerUtil getPlayerUtil( UUID playerUuid ); + + + /** + *

Some information on events... + *

+ * + * https://bukkit.fandom.com/wiki/Event_API_Reference + * + *

When changing values of an event the changes of one with the higher priority will + * override any changes done before by a listener with a lower priority so that in the + * end the one with the highest priority can have the final say in the actually outcome. + * To achieve this priority order listeners are called from the ones with the + * lowest to the ones with the highest priority. Any listener with the MONITOR + * priority is called last. + * + *

+ * + * @param eventType + * @param handlerList + */ + public List dumpEventListenersList( String eventType, HandlerList handlerList ); + + + public ChatDisplay dumpEventListenersChatDisplay( String eventType, HandlerList handlerList ); + + + /** + *

This only reloads the event listeners that auto features uses. This is called by + * the command "/prison reload autoFeatures". + *

+ * + * tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.reloadConfig() + * + */ + public void reloadAutoFeaturesEventListeners(); + + } diff --git a/prison-core/src/main/java/tech/mcprison/prison/localization/LocaleManager.java b/prison-core/src/main/java/tech/mcprison/prison/localization/LocaleManager.java index d4f855d14..644889ef4 100755 --- a/prison-core/src/main/java/tech/mcprison/prison/localization/LocaleManager.java +++ b/prison-core/src/main/java/tech/mcprison/prison/localization/LocaleManager.java @@ -41,11 +41,13 @@ import java.io.InputStreamReader; import java.io.StringReader; import java.net.URL; +import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.security.CodeSource; import java.text.DateFormat; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; @@ -115,6 +117,8 @@ public class LocaleManager { private String internalPath; private File localFolder; + + private static final List registeredInstances = new ArrayList<>(); /** * Constructs a new {@link LocaleManager} owned by the given {@link PluginEntity}. @@ -128,6 +132,26 @@ public LocaleManager(PluginEntity module, String internalPath) { this.localFolder = getLocalDataFolder(); + getRegisteredInstances().add( this ); + + reload(); + } + + public LocaleManager(PluginEntity module) { + this(module, LOCALE_FOLDER); + } + + + public void reload() { + + // Reset configs: + configs.clear(); + + + // Always get the config's default-language settings to ensure we are always + // accessing the correct files. + setDefaultLocale( Prison.get().getPlatform().getConfigString( "default-language", "en_US" )); + // Check to see if there are any updates that need to be applied to the // the properties files that are local. @@ -139,16 +163,20 @@ public LocaleManager(PluginEntity module, String internalPath) { // Load the shipped locales first first from the prison jar file: loadShippedLocales(); - // Then any custom locales will overried and replace the internal locales: + + // Then any custom locales will override and replace the internal locales: loadCustomLocales(); // custom locales will override - } - public LocaleManager(PluginEntity module) { - this(module, LOCALE_FOLDER); } - @Override + + public static List getRegisteredInstances() + { + return registeredInstances; + } + + @Override public String toString() { StringBuilder sb = new StringBuilder(); @@ -367,11 +395,11 @@ private void checkLocalPropertiesStatus( LocalManagerPropertyFileData pfd ) ) { prop.load( fr ); - boolean hasVersion = prop.containsKey( "ranks_messages__version" ); - String version = prop.getProperty( "ranks_messages__version" ); + boolean hasVersion = prop.containsKey( "messages__version" ); + String version = prop.getProperty( "messages__version" ); - boolean hasAutoRefresh = prop.containsKey( "ranks_messages__auto_refresh" ); - String autoRefresh = prop.getProperty( "ranks_messages__auto_refresh" ); + boolean hasAutoRefresh = prop.containsKey( "messages__auto_refresh" ); + String autoRefresh = prop.getProperty( "messages__auto_refresh" ); if ( hasVersion && version != null && !version.trim().isEmpty() ) { pfd.setLocalVersion( version ); @@ -396,11 +424,11 @@ private void checkJarPropertiesStatus( LocalManagerPropertyFileData pfd, String prop.load( new StringReader( propertiesData ) ); - boolean hasVersion = prop.containsKey( "ranks_messages__version" ); - String version = prop.getProperty( "ranks_messages__version" ); + boolean hasVersion = prop.containsKey( "messages__version" ); + String version = prop.getProperty( "messages__version" ); - boolean hasAutoRefresh = prop.containsKey( "ranks_messages__auto_refresh" ); - String autoRefresh = prop.getProperty( "ranks_messages__auto_refresh" ); + boolean hasAutoRefresh = prop.containsKey( "messages__auto_refresh" ); + String autoRefresh = prop.getProperty( "messages__auto_refresh" ); if ( hasVersion && version != null && !version.trim().isEmpty() ) { pfd.setJarVersion( version ); @@ -433,15 +461,15 @@ private void loadCustomLocales() { } catch (IOException ex) { Output.get().logWarn( - "Failed to load custom locale \"" + locale.getName() + - "\" for plugin " + getOwningPlugin() + " (" + + "Failed to load custom locale " + locale.getName() + + " for plugin " + getOwningPlugin() + " (" + ex.getMessage() + ")"); } } else { - Output.get().logWarn("Found subfolder \"" + locale.getName() + - "\" within locale folder \"" + LOCALE_FOLDER + - "\" in data folder for plugin " + getOwningPlugin() + + Output.get().logWarn("Found subfolder " + locale.getName() + + " within locale folder " + LOCALE_FOLDER + + " in data folder for plugin " + getOwningPlugin() + " - not loading"); } } @@ -578,18 +606,38 @@ private void loadShippedLocales() { private void loadLocale(String name, InputStream is, boolean printStackTrace) { try { - Properties temp = new Properties(); - temp.load(is); + + + Properties temp = new Properties(); +// temp.load(is); + + // The InputStream is part of a zipEntry so it cannot be closed, or it will close the zip stream + BufferedReader br = new BufferedReader( new InputStreamReader( is, Charset.forName("UTF-8") )); + String line = br.readLine(); + + while ( line != null ) { + if ( !line.startsWith( "#" ) && line.contains( "=" ) ) { + + String[] keyValue = line.split( "\\=" ); + String value = (keyValue.length > 1 ? keyValue[1] : ""); // StringEscapeUtils.escapeJava( keyValue[1] ); + temp.put( keyValue[0], value ); + } + + line = br.readLine(); + } + + Properties config; if (configs.containsKey(name)) { config = configs.get(name); + for (Map.Entry e : temp.entrySet()) { config.put(e.getKey(), e.getValue()); } } else { config = temp; + configs.put(name, config); } - configs.put(name, config); } catch (IOException ex) { if (printStackTrace) { @@ -619,6 +667,12 @@ public PluginEntity getOwningPlugin() { * @since 1.0 */ public String getDefaultLocale() { + if ( defaultLocale == null ) { + defaultLocale = Prison.get().getPlatform().getConfigString( "default-language", "en_US" ); + if ( defaultLocale == null ) { + defaultLocale = "en_US"; + } + } return defaultLocale; } @@ -646,7 +700,8 @@ public Localizable getLocalizable(String key) { } String getLocale(Player player) { - return player.getLocale().orElse(getDefaultLocale()); + return player != null && player.getLocale() != null ? + player.getLocale().orElse(getDefaultLocale()) : getDefaultLocale(); } public String getInternalPath() { diff --git a/prison-core/src/main/java/tech/mcprison/prison/localization/Localizable.java b/prison-core/src/main/java/tech/mcprison/prison/localization/Localizable.java index 5228bac91..3871fcf30 100755 --- a/prison-core/src/main/java/tech/mcprison/prison/localization/Localizable.java +++ b/prison-core/src/main/java/tech/mcprison/prison/localization/Localizable.java @@ -66,6 +66,8 @@ public class Localizable { private Localizable[] locReplacements = new Localizable[0]; private String prefix = ""; private String suffix = ""; + + private boolean failSilently = false; Localizable(LocaleManager parent, String key) { this.parent = parent; @@ -92,6 +94,47 @@ public String getKey() { return key; } + /** + * This identifies if the message id (key) is to be printed if Prison is unable to load + * the message files. By default, the message id is always displayed if the message files + * cannot be loaded. + * + * @return + */ + public boolean isFailSilently() { + return failSilently; + } + + /** + * This sets the Localization to fail silently if it cannot load the message files. + * This is a very dangerous setting to use, and should only be used in very rare + * situations where a failure will not be an issue. The problem with using this + * setting is that nobody may ever know that there is a failure, so it may never + * be fixed. + * + * One area where it is used is with the Output.get() settings since those are heavily + * used. Suppressing the prefixes and color codes that Output.get() tries to load from + * the message files will not prevent Prison from performing any logging. But if + * the message IDs are shown instead, it could make the logging difficult to read. + * + * @return + */ + public Localizable setFailSilently() { + this.failSilently = true; + return this; + } + + /** + * This disables the failSilently setting so message IDs will be shown if there are + * failures in reading from the message files. + * + * @return + */ + public Localizable setFailNormally() { + this.failSilently = false; + return this; + } + /** * Sets the replacements for placeholder sequences in this * {@link Localizable}. @@ -239,9 +282,17 @@ private String localizeIn(String locale, boolean recursive, String... fallbacks) System.arraycopy(fallbacks, 1, newFallbacks, 0, newFallbacks.length); // drop the first element return localizeIn(fallbacks[0], true, newFallbacks); // try the next fallback - } else if (!locale.equals(getParent().getDefaultLocale())) { + } + else if (!locale.equals(getParent().getDefaultLocale())) { return localizeIn(getParent().getDefaultLocale(), true); // try the default locale - } else { + } + else if ( isFailSilently() ) { + // NOTE: The message file was unable to be loaded, but failSilently was enabled so return an + // empty String: + return ""; + } + else { + // NOTE: The message file was unable to be loaded so default by printing out the message key (id): return prefix + getKey() + suffix; // last resort if no locale is available } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/output/ChatDisplay.java b/prison-core/src/main/java/tech/mcprison/prison/output/ChatDisplay.java index c737fb6b7..ac0eb2bd8 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/output/ChatDisplay.java +++ b/prison-core/src/main/java/tech/mcprison/prison/output/ChatDisplay.java @@ -83,6 +83,7 @@ public void toLog(LogLevel logLevel) { } public void sendtoOutputLogInfo() { + Output.get().logInfo( title ); for (DisplayComponent component : displayComponents) { Output.get().logInfo( component.text() ); } @@ -109,6 +110,23 @@ public StringBuilder toStringBuilderEscaped() { return sb; } - + public void addChatDisplay( ChatDisplay cDisp ) + { + + addComponent(new TextComponent(cDisp.getTitle())); + + for (DisplayComponent component : cDisp.getDisplayComponents() ) { + addComponent( component ); + } + } + + protected String getTitle() { + return title; + } + + protected LinkedList getDisplayComponents() { + return displayComponents; + } + } diff --git a/prison-core/src/main/java/tech/mcprison/prison/output/Output.java b/prison-core/src/main/java/tech/mcprison/prison/output/Output.java index 739f52468..1b3f3ac1e 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/output/Output.java +++ b/prison-core/src/main/java/tech/mcprison/prison/output/Output.java @@ -33,17 +33,25 @@ * @author Faizaan A. Datoo * @since API 1.0 */ -public class Output { +public class Output + extends OutputMessages { - // Fields private static Output instance; - private String PREFIX_TEMPLATE = "| %s | &7"; -// private String PREFIX_TEMPLATE = "&8| %s &8| &7"; - public String INFO_PREFIX = gen("Info"); - public String WARNING_PREFIX = gen("Warning"); - public String ERROR_PREFIX = gen("Error"); - public String DEBUG_PREFIX = gen("Debug"); + private String prefixTemplate; + + private String prefixTemplatePrison; + + private String prefixTemplateInfo; + private String prefixTemplateWarning; + private String prefixTemplateError; + private String prefixTemplateDebug; + + private String colorCodeInfo; + private String colorCodeWarning; + private String colorCodeError; + private String colorCodeDebug; + private boolean debug = false; private Set activeDebugTargets; @@ -54,8 +62,11 @@ public enum DebugTarget { off, blockBreak, // blockBreakListeners, + blockBreakDurability, blockBreakFortune, - durability, + blockBreakXpCalcs, + + rankup, support ; @@ -91,12 +102,26 @@ public static TreeSet fromMultiString( String targets ) { private Output() { - instance = this; + instance = this; + + this.activeDebugTargets = new HashSet<>(); + + this.prefixTemplate = coreOutputPrefixTemplateMsg(); + + this.prefixTemplatePrison = gen( coreOutputPrefixTemplatePrisonMsg() ); + + this.prefixTemplateInfo = gen( coreOutputPrefixTemplateInfoMsg() ); + this.prefixTemplateWarning = gen( coreOutputPrefixTemplateWarningMsg() ); + this.prefixTemplateError = gen( coreOutputPrefixTemplateErrorMsg() ); + this.prefixTemplateDebug = gen( coreOutputPrefixTemplateDebugMsg() ); + + this.colorCodeInfo = coreOutputColorCodeInfoMsg(); + this.colorCodeWarning = coreOutputColorCodeWarningMsg(); + this.colorCodeError = coreOutputColorCodeErrorMsg(); + this.colorCodeDebug = coreOutputColorCodeDebugMsg(); - this.activeDebugTargets = new HashSet<>(); } - // Public methods public static Output get() { if (instance == null) { @@ -118,16 +143,16 @@ private String getLogPrefix( LogLevel level) { switch ( level ) { case INFO: - prefix = INFO_PREFIX; + prefix = prefixTemplateInfo; break; case WARNING: - prefix = WARNING_PREFIX; + prefix = prefixTemplateWarning; break; case ERROR: - prefix = ERROR_PREFIX; + prefix = prefixTemplateError; break; case DEBUG: - prefix = DEBUG_PREFIX; + prefix = prefixTemplateDebug; break; case PLAIN: @@ -144,16 +169,16 @@ private String getLogColorCode( LogLevel level) { switch ( level ) { case INFO: - colorCode = "&3"; + colorCode = colorCodeInfo; break; case WARNING: - colorCode = "&c"; + colorCode = colorCodeWarning; break; case ERROR: - colorCode = "&c"; + colorCode = colorCodeError; break; case DEBUG: - colorCode = "&9"; + colorCode = colorCodeDebug; break; case PLAIN: @@ -173,11 +198,18 @@ public String format(String message, LogLevel level, Object... args) { */ public void log(String message, LogLevel level, Object... args) { if ( Prison.get() == null || Prison.get().getPlatform() == null ) { - System.err.println("Prison: Output.log Logger failure: " + message ); + String errorMessage = coreOutputErrorStartupFailureMsg(); + if ( errorMessage == null || errorMessage.trim().isEmpty() ) { + // NOTE: The following must remain as is. This is a fallback for if there + // are major failures in prison. At least it can prefix the messages so they + // can be identified along with the reasons. + errorMessage = "Prison: (Sending to System.err due to Output.log Logger failure):"; + } + System.err.println( errorMessage + " " + message ); } else { try { Prison.get().getPlatform().log( - gen("Prison") + " " + + prefixTemplatePrison + " " + getLogColorCode(level) + String.format(message, args)); } @@ -186,17 +218,16 @@ public void log(String message, LogLevel level, Object... args) { StringBuilder sb = new StringBuilder(); for ( Object arg : args ) { - sb.append( "[" ); - sb.append( arg ); - sb.append( "] " ); + sb.append( "[" ).append( arg ).append( "] " ); } + String errorMessage = coreOutputErrorIncorrectNumberOfParametersMsg( + level.name(), e.getMessage(), message, sb.toString() ); + Prison.get().getPlatform().logCore( - gen("Prison") + " " + + prefixTemplatePrison + " " + getLogColorCode(LogLevel.ERROR) + - "Failure to generate log message due to incorrect number of parameters: [" + - e.getMessage() + "] :: Original raw message [" + message + "] " + - "Arguments: " + sb.toString() ); + errorMessage ); } } } @@ -250,7 +281,8 @@ public void logDebug( DebugTarget debugTarget, String message, Object... args) { if ( isDebug( debugTarget ) ) { - logDebug(message, args ); + log(message, LogLevel.DEBUG, args); +// logDebug(message, args ); } // // The following is not yet enabled since the user interfaces are not in place to manage the set: @@ -385,7 +417,7 @@ public void sendError(CommandSender sender, String message, Object... args) { // Private methods private String gen(String name) { - return String.format(PREFIX_TEMPLATE, name); + return String.format(prefixTemplate, name); } } diff --git a/prison-core/src/main/java/tech/mcprison/prison/output/OutputMessages.java b/prison-core/src/main/java/tech/mcprison/prison/output/OutputMessages.java new file mode 100644 index 000000000..84a410682 --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/output/OutputMessages.java @@ -0,0 +1,94 @@ +package tech.mcprison.prison.output; + +import tech.mcprison.prison.Prison; + +public class OutputMessages +{ + protected String coreOutputPrefixTemplateMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_output__prefix_template" ) + .withReplacements( "%s" ) + .setFailSilently() + .localize(); + } + + protected String coreOutputPrefixTemplatePrisonMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_output__prefix_template_prison" ) + .setFailSilently() + .localize(); + } + + protected String coreOutputPrefixTemplateInfoMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_output__prefix_template_info" ) + .setFailSilently() + .localize(); + } + + protected String coreOutputPrefixTemplateWarningMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_output__prefix_template_warning" ) + .setFailSilently() + .localize(); + } + + protected String coreOutputPrefixTemplateErrorMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_output__prefix_template_error" ) + .setFailSilently() + .localize(); + } + + protected String coreOutputPrefixTemplateDebugMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_output__prefix_template_debug" ) + .setFailSilently() + .localize(); + } + + protected String coreOutputColorCodeInfoMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_output__color_code_info" ) + .setFailSilently() + .localize(); + } + + protected String coreOutputColorCodeWarningMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_output__color_code_warning" ) + .setFailSilently() + .localize(); + } + + protected String coreOutputColorCodeErrorMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_output__color_code_error" ) + .setFailSilently() + .localize(); + } + + protected String coreOutputColorCodeDebugMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_output__color_code_debug" ) + .setFailSilently() + .localize(); + } + + protected String coreOutputErrorStartupFailureMsg() { + return Prison.get().getLocaleManager() + .getLocalizable( "core_output__error_startup_failure" ) + .localize(); + } + + protected String coreOutputErrorIncorrectNumberOfParametersMsg( + String levelName, String errorMessage, + String originalMessage, String arguments ) { + return Prison.get().getLocaleManager() + .getLocalizable( "core_output__error_incorrect_number_of_parameters" ) + .withReplacements( levelName, errorMessage, + originalMessage, arguments ) + .localize(); + } + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceHolderKey.java b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceHolderKey.java index a33b5a31b..f33d83961 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceHolderKey.java +++ b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceHolderKey.java @@ -1,5 +1,8 @@ package tech.mcprison.prison.placeholders; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + import tech.mcprison.prison.placeholders.PlaceholderManager.PrisonPlaceHolders; public class PlaceHolderKey { @@ -10,6 +13,11 @@ public class PlaceHolderKey { private boolean primary = true; private String aliasName; + + // NOTE: Pattern is thread safe so make it static. Matcher is not thead safe. + public static Pattern PLACEHOLDER_SEQUENCE_PATTERN = Pattern.compile( "(\\_([0-9]+)\\_)" ); + + public PlaceHolderKey( String key, PrisonPlaceHolders placeholder ) { this(key, placeholder, true); } @@ -40,19 +48,71 @@ public PlaceHolderKey( String key, PrisonPlaceHolders placeholder, String data, public PlaceholderResults getIdentifier( String text ) { PlaceholderResults results = new PlaceholderResults(this); + String textLowercase = text.toLowerCase(); String key = getKey().toLowerCase(); - checkIdentifier( key, text, textLowercase, "{", "}", results ); - if ( textLowercase.contains( key ) || - checkIdentifier( key, text, textLowercase, "{", "}", results ) || - checkIdentifier( key, text, textLowercase, "%", "%", results ) - ) { + // For placeholders with sequence numbers, such as _nnn_, will need to search + // for 1 to 3 digits and replace the number in the "text" with _nnn_ and also + // need to store that numeric value in the PlaceholderResults object. + if ( getPlaceholder().hasSequence() ) { - // Nothing to do, since it was already done within this if statement. + Matcher matcher = PLACEHOLDER_SEQUENCE_PATTERN.matcher( textLowercase ); + if ( matcher.find() ) { + + //String group0 = matcher.group( 0 ); + String group1 = matcher.group( 1 ); + String group2 = matcher.group( 2 ); + + textLowercase = textLowercase.replace( group1, "_nnn_" ); + +// Output.get().logInfo( "### PlaceHolderKey: seq pattern detected: " + placeholder.name() + +// " group0= " + group0 + " group1= " + group1 + " group2= " + group2 + " replacedText: " + textLowercase ); + + results.setNumericSequencePattern( group1 ); + + // a value of -1 indicates it was not able to be parsed: + int parsed = -1; + + try { + parsed = Integer.parseInt( group2 ); + } + catch ( NumberFormatException e ) { + // Not a number so ignore... but based upon matcher.find() it should be... Hmm... + } + + results.setNumericSequence( parsed ); + + + // DO something more: + + } + } + + + // If the text is an exact match to the key (no escape characters): + if ( textLowercase.equalsIgnoreCase( key ) ) { + results.setIdentifier( textLowercase ); + results.setPlaceholder( this ); + + } + else { + checkIdentifier( key, text, textLowercase, "{", "}", results ); + + if ( textLowercase.equalsIgnoreCase( key ) || + textLowercase.contains( key ) || + checkIdentifier( key, text, textLowercase, "{", "}", results ) || + checkIdentifier( key, text, textLowercase, "%", "%", results ) + ) { + + + + // Nothing to do, since it was already done within this if statement. + + // // Performing all the String searching and indexing can be expensive, especially // // since there can be thousands of PlaceHolderKeys on a server. So to provide // // a quick proof to see if additional, more complex calculations should be @@ -83,7 +143,8 @@ public PlaceholderResults getIdentifier( String text ) { //// pm.getTranslatePlayerPlaceHolder( playerUuid, playerName, identifier ) ); // } // } - + + } } @@ -108,15 +169,27 @@ private boolean checkIdentifier( String key, String text, String textLowercase, String test2 = escLeft + key + PlaceholderManager.PRISON_PLACEHOLDER_ATTRIBUTE_SEPARATOR; + int adjustment = 0; + // If the text contains a sequence, then calculate the adjustment position based upon + // the length of '_nnn_' compared to the original value. + // These adjustments will align properly with 'text'. + if ( results.getNumericSequence() >= 0 && results.getNumericSequencePattern() != null ) { + adjustment = 5 - results.getNumericSequencePattern().length(); + } + // Warning this is not case insensitive in the results: if ( textLowercase.contains( test1 ) ) { int idx = textLowercase.indexOf( test1 ); int idxStart = idx + 1; - int idxEnd = idx + test1.length() - 1; + + + int idxEnd = idx + test1.length() - 1 - adjustment; String identifier = text.substring( idxStart, idxEnd); results.setIdentifier( identifier, escLeft, escRight ); + results.setPlaceholder( this ); + // results.setIdentifier( key, escLeft, escRight ); foundIdentifier = true; } @@ -128,16 +201,34 @@ else if ( text.contains( test2 ) ) { String key2 = escRight; int idx = text.indexOf( key1 ); - int idx2 = ( idx == -1 ? -1 : text.indexOf( key2, idx + key1.length() - 1 ) ); + int idx2 = ( idx == -1 ? -1 : text.indexOf( key2, idx + key1.length() - 1 ) ) - adjustment; if ( idx > -1 && idx2 > -1 ) { String identifier = text.substring( idx + 1, idx2 ); + results.setIdentifier( identifier, escLeft, escRight ); + results.setPlaceholder( this ); + foundIdentifier = true; // results = results.replace("{" + identifier + "}", // pm.getTranslatePlayerPlaceHolder( playerUuid, playerName, identifier ) ); } } +// else if ( textLowercase.contains( key ) ) { +// +// int idx = textLowercase.indexOf( key ); +// int idxStart = idx + 1; +// +// +// int idxEnd = idx + key.length() - 1 - adjustment; +// String identifier = text.substring( idxStart, idxEnd); +// +// results.setIdentifier( identifier, "", "" ); +// results.setPlaceholder( this ); +// +//// results.setIdentifier( key, escLeft, escRight ); +// foundIdentifier = true; +// } return foundIdentifier; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderManager.java b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderManager.java index a2d62ce4d..1159db5b7 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderManager.java +++ b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderManager.java @@ -23,17 +23,57 @@ public class PlaceholderManager { private PlaceholderProgressBarConfig progressBarConfig; - public enum PlaceHolderFlags { + public enum placeholderFlagType { + supress, + sequence, + normal + } + + public enum PlaceholderFlags { PLAYER, LADDERS, RANKS, + RANKPLAYERS, + MINES, - PLAYERMINES, + MINEPLAYERS, + + STATSMINES( true ), + STATSRANKS( true ), + SUPRESS, ALIAS ; + + private final boolean sequence; + private final String desc; + + private PlaceholderFlags() { + this.sequence = false; + this.desc = null; + } + private PlaceholderFlags( boolean hasSequence ) { + this.sequence = hasSequence; + this.desc = null; + } + + /** + *

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

+ * + * @return + */ + public boolean hasSequence() { + return sequence; + } } public enum PlaceholderAttributePrefixes { @@ -114,258 +154,410 @@ public static NumberTransformationUnitTypes fromString( String value ) { */ public enum PrisonPlaceHolders { - no_match__(PlaceHolderFlags.SUPRESS), + 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_r(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_rn(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_rt(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_rlp(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_rcrp(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_rcrb(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + + prison_rr(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_rrt(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_rcrp(PlaceHolderFlags.PLAYER, PlaceHolderFlags.ALIAS), - prison_rcrb(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_rank_ladder_position(prison_rlp, PlaceholderFlags.PLAYER), - prison_rr(PlaceHolderFlags.PLAYER, PlaceHolderFlags.ALIAS), - prison_rrt(PlaceHolderFlags.PLAYER, PlaceHolderFlags.ALIAS), - + 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_cost_remaining_percent(prison_rcrp, PlaceholderFlags.PLAYER), + prison_rankup_cost_remaining_bar(prison_rcrb, PlaceholderFlags.PLAYER), + + prison_rankup_rank(prison_rr, PlaceholderFlags.PLAYER), + prison_rankup_rank_tag(prison_rrt, PlaceholderFlags.PLAYER), - prison_rank(prison_r, PlaceHolderFlags.PLAYER), - prison_rank_number(prison_rn, PlaceHolderFlags.PLAYER), - prison_rank_tag(prison_rt, 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_rlp_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_rcrp_laddername(PlaceholderFlags.LADDERS, PlaceholderFlags.ALIAS), + prison_rcrb_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_rank_ladder_position_laddername(prison_rlp_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_cost_remaining_percent_laddername(prison_rcrp_laddername, PlaceholderFlags.LADDERS), + prison_rankup_cost_remaining_bar_laddername(prison_rcrb_laddername, PlaceholderFlags.LADDERS), + + prison_rankup_rank_laddername(prison_rr_laddername, PlaceholderFlags.LADDERS), + prison_rankup_rank_tag_laddername(prison_rrt_laddername, PlaceholderFlags.LADDERS), + - 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_cost_remaining_percent(prison_rcrp, PlaceHolderFlags.PLAYER), - prison_rankup_cost_remaining_bar(prison_rcrb, PlaceHolderFlags.PLAYER), + // player balances. Both with and without ladders. + prison_pb(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_player_balance(prison_pb, PlaceholderFlags.PLAYER), + + + prison_pb_epm(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_pb_epmf(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_player_balance_earnings_per_minute(prison_pb_epm, PlaceholderFlags.PLAYER), + prison_player_balance_earnings_per_minute_formatted(prison_pb_epmf, PlaceholderFlags.PLAYER), - prison_rankup_rank(prison_rr, PlaceHolderFlags.PLAYER), - prison_rankup_rank_tag(prison_rrt, PlaceHolderFlags.PLAYER), + + prison_pb_laddername(PlaceholderFlags.LADDERS, PlaceholderFlags.ALIAS), + prison_player_balance_laddername(prison_pb_laddername, PlaceholderFlags.LADDERS), - // Ladder aliases: - prison_r_laddername(PlaceHolderFlags.LADDERS, PlaceHolderFlags.ALIAS), - prison_rn_laddername(PlaceHolderFlags.LADDERS, PlaceHolderFlags.ALIAS), - prison_rt_laddername(PlaceHolderFlags.LADDERS, PlaceHolderFlags.ALIAS), + prison_psm(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_player_sellall_multiplier(prison_psm, PlaceholderFlags.PLAYER), + - 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_rcrp_laddername(PlaceHolderFlags.LADDERS, PlaceHolderFlags.ALIAS), - prison_rcrb_laddername(PlaceHolderFlags.LADDERS, PlaceHolderFlags.ALIAS), - prison_rr_laddername(PlaceHolderFlags.LADDERS, PlaceHolderFlags.ALIAS), - prison_rrt_laddername(PlaceHolderFlags.LADDERS, PlaceHolderFlags.ALIAS), + prison_pbt(PlaceholderFlags.MINEPLAYERS, PlaceholderFlags.ALIAS), + prison_pbtm(PlaceholderFlags.MINEPLAYERS, PlaceholderFlags.ALIAS), + prison_player_blocks_total(prison_pbt, PlaceholderFlags.MINEPLAYERS), + prison_player_blocks_total_minename(prison_pbtm, PlaceholderFlags.MINEPLAYERS), - 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_cost_remaining_percent_laddername(prison_rcrp_laddername, PlaceHolderFlags.LADDERS), - prison_rankup_cost_remaining_bar_laddername(prison_rcrb_laddername, PlaceHolderFlags.LADDERS), + // Player tools: - prison_rankup_rank_laddername(prison_rr_laddername, PlaceHolderFlags.LADDERS), - prison_rankup_rank_tag_laddername(prison_rrt_laddername, PlaceHolderFlags.LADDERS), - +/* */ + prison_ptid(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_ptn(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_ptmt(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_ptt(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_ptdata(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_ptlore(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_ptdu(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_ptdm(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_ptdr(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_ptdp(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_ptdb(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), - // player balances. Both with and without ladders. - prison_pb(PlaceHolderFlags.PLAYER, PlaceHolderFlags.ALIAS), - prison_player_balance(prison_pb, PlaceHolderFlags.PLAYER), + prison_ptef(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_ptee(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_ptes(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_pteu(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_ptem(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_ptel(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + + prison_ph(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_phm(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_pam(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_par(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + + prison_pfl(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_pfs(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_pfe(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + + prison_pxp(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_pxptl(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_pl(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + prison_pws(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), +// prison_pas(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), +// prison_pms(PlaceholderFlags.PLAYER, PlaceholderFlags.ALIAS), + + + prison_player_tool_id(prison_ptid, PlaceholderFlags.PLAYER), + prison_player_tool_name(prison_ptn, PlaceholderFlags.PLAYER), + prison_player_tool_type(prison_ptt, PlaceholderFlags.PLAYER), + prison_player_tool_material_type(prison_ptmt, PlaceholderFlags.PLAYER), - prison_pb_laddername(PlaceHolderFlags.LADDERS, PlaceHolderFlags.ALIAS), - prison_player_balance_laddername(prison_pb_laddername, PlaceHolderFlags.LADDERS), + prison_player_tool_data(prison_ptdata, PlaceholderFlags.PLAYER), + prison_player_tool_lore(prison_ptlore, PlaceholderFlags.PLAYER), + + + prison_player_tool_durability_used(prison_ptdu, PlaceholderFlags.PLAYER), + prison_player_tool_durability_max(prison_ptdm, PlaceholderFlags.PLAYER), + prison_player_tool_durability_remaining(prison_ptdr, PlaceholderFlags.PLAYER), - + prison_player_tool_durability_percent(prison_ptdp, PlaceholderFlags.PLAYER), + prison_player_tool_durability_bar(prison_ptdb, PlaceholderFlags.PLAYER), + + + prison_player_tool_enchantment_fortune(prison_ptef, PlaceholderFlags.PLAYER), + prison_player_tool_enchantment_efficency(prison_ptee, PlaceholderFlags.PLAYER), + prison_player_tool_enchantment_silktouch(prison_ptes, PlaceholderFlags.PLAYER), + prison_player_tool_enchantment_unbreaking(prison_pteu, PlaceholderFlags.PLAYER), + prison_player_tool_enchantment_mending(prison_ptem, PlaceholderFlags.PLAYER), + prison_player_tool_enchantment_luck(prison_ptel, PlaceholderFlags.PLAYER), - prison_psm(PlaceHolderFlags.PLAYER, PlaceHolderFlags.ALIAS), - prison_player_sellall_multiplier(prison_psm, PlaceHolderFlags.PLAYER), + + + prison_player_health(prison_ph, PlaceholderFlags.PLAYER), + prison_player_health_max(prison_phm, PlaceholderFlags.PLAYER), + prison_player_air_max(prison_pam, PlaceholderFlags.PLAYER), + prison_player_air_remaining(prison_par, PlaceholderFlags.PLAYER), + prison_player_food_level(prison_pfl, PlaceholderFlags.PLAYER), + prison_player_food_saturation(prison_pfs, PlaceholderFlags.PLAYER), + prison_player_food_exhaustion(prison_pfe, PlaceholderFlags.PLAYER), + + prison_player_xp(prison_pxp, PlaceholderFlags.PLAYER), + prison_player_xp_to_level(prison_pxptl, PlaceholderFlags.PLAYER), + prison_player_level(prison_pl, PlaceholderFlags.PLAYER), + prison_player_walk_speed(prison_pws, PlaceholderFlags.PLAYER), +// prison_player_attack_speed(prison_pas, PlaceholderFlags.PLAYER), +// prison_player_movement_speed(prison_pms, PlaceholderFlags.PLAYER), + +/* */ // 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), - - prison_mb01_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS), - prison_mb02_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS), - prison_mb03_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS), - prison_mb04_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS), - prison_mb05_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS), - prison_mb06_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS), - prison_mb07_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS), - prison_mb08_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS), - prison_mb09_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS), - prison_mb10_minename(PlaceHolderFlags.MINES, PlaceHolderFlags.ALIAS), + + + 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), + +// prison_mb01_minename(PlaceholderFlags.MINES, PlaceholderFlags.ALIAS), +// prison_mb02_minename(PlaceholderFlags.MINES, PlaceholderFlags.ALIAS), +// prison_mb03_minename(PlaceholderFlags.MINES, PlaceholderFlags.ALIAS), +// prison_mb04_minename(PlaceholderFlags.MINES, PlaceholderFlags.ALIAS), +// prison_mb05_minename(PlaceholderFlags.MINES, PlaceholderFlags.ALIAS), +// prison_mb06_minename(PlaceholderFlags.MINES, PlaceholderFlags.ALIAS), +// prison_mb07_minename(PlaceholderFlags.MINES, PlaceholderFlags.ALIAS), +// prison_mb08_minename(PlaceholderFlags.MINES, PlaceholderFlags.ALIAS), +// prison_mb09_minename(PlaceholderFlags.MINES, PlaceholderFlags.ALIAS), +// prison_mb10_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), - - prison_mines_blocks_01_minename(prison_mb01_minename, PlaceHolderFlags.MINES), - prison_mines_blocks_02_minename(prison_mb02_minename, PlaceHolderFlags.MINES), - prison_mines_blocks_03_minename(prison_mb03_minename, PlaceHolderFlags.MINES), - prison_mines_blocks_04_minename(prison_mb04_minename, PlaceHolderFlags.MINES), - prison_mines_blocks_05_minename(prison_mb05_minename, PlaceHolderFlags.MINES), - prison_mines_blocks_06_minename(prison_mb06_minename, PlaceHolderFlags.MINES), - prison_mines_blocks_07_minename(prison_mb07_minename, PlaceHolderFlags.MINES), - prison_mines_blocks_08_minename(prison_mb08_minename, PlaceHolderFlags.MINES), - prison_mines_blocks_09_minename(prison_mb09_minename, PlaceHolderFlags.MINES), - prison_mines_blocks_10_minename(prison_mb10_minename, PlaceHolderFlags.MINES), + 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), + +// prison_mines_blocks_01_minename(prison_mb01_minename, PlaceholderFlags.MINES), +// prison_mines_blocks_02_minename(prison_mb02_minename, PlaceholderFlags.MINES), +// prison_mines_blocks_03_minename(prison_mb03_minename, PlaceholderFlags.MINES), +// prison_mines_blocks_04_minename(prison_mb04_minename, PlaceholderFlags.MINES), +// prison_mines_blocks_05_minename(prison_mb05_minename, PlaceholderFlags.MINES), +// prison_mines_blocks_06_minename(prison_mb06_minename, PlaceholderFlags.MINES), +// prison_mines_blocks_07_minename(prison_mb07_minename, PlaceholderFlags.MINES), +// prison_mines_blocks_08_minename(prison_mb08_minename, PlaceholderFlags.MINES), +// prison_mines_blocks_09_minename(prison_mb09_minename, PlaceholderFlags.MINES), +// prison_mines_blocks_10_minename(prison_mb10_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_mb01_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS), - prison_mb02_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS), - prison_mb03_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS), - prison_mb04_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS), - prison_mb05_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS), - prison_mb06_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS), - prison_mb07_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS), - prison_mb08_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS), - prison_mb09_pm(PlaceHolderFlags.PLAYERMINES, PlaceHolderFlags.ALIAS), - prison_mb10_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), - - prison_mines_blocks_01_playermines(prison_mb01_pm, PlaceHolderFlags.PLAYERMINES), - prison_mines_blocks_02_playermines(prison_mb02_pm, PlaceHolderFlags.PLAYERMINES), - prison_mines_blocks_03_playermines(prison_mb03_pm, PlaceHolderFlags.PLAYERMINES), - prison_mines_blocks_04_playermines(prison_mb04_pm, PlaceHolderFlags.PLAYERMINES), - prison_mines_blocks_05_playermines(prison_mb05_pm, PlaceHolderFlags.PLAYERMINES), - prison_mines_blocks_06_playermines(prison_mb06_pm, PlaceHolderFlags.PLAYERMINES), - prison_mines_blocks_07_playermines(prison_mb07_pm, PlaceHolderFlags.PLAYERMINES), - prison_mines_blocks_08_playermines(prison_mb08_pm, PlaceHolderFlags.PLAYERMINES), - prison_mines_blocks_09_playermines(prison_mb09_pm, PlaceHolderFlags.PLAYERMINES), - prison_mines_blocks_10_playermines(prison_mb10_pm, PlaceHolderFlags.PLAYERMINES), + prison_mn_pm(PlaceholderFlags.MINEPLAYERS, PlaceholderFlags.ALIAS), + prison_mt_pm(PlaceholderFlags.MINEPLAYERS, PlaceholderFlags.ALIAS), + prison_mi_pm(PlaceholderFlags.MINEPLAYERS, PlaceholderFlags.ALIAS), + prison_mif_pm(PlaceholderFlags.MINEPLAYERS, PlaceholderFlags.ALIAS), + prison_mtl_pm(PlaceholderFlags.MINEPLAYERS, PlaceholderFlags.ALIAS), + prison_mtlb_pm(PlaceholderFlags.MINEPLAYERS, PlaceholderFlags.ALIAS), + prison_mtlf_pm(PlaceholderFlags.MINEPLAYERS, PlaceholderFlags.ALIAS), + prison_ms_pm(PlaceholderFlags.MINEPLAYERS, PlaceholderFlags.ALIAS), + prison_mr_pm(PlaceholderFlags.MINEPLAYERS, PlaceholderFlags.ALIAS), + prison_mrb_pm(PlaceholderFlags.MINEPLAYERS, PlaceholderFlags.ALIAS), + prison_mp_pm(PlaceholderFlags.MINEPLAYERS, PlaceholderFlags.ALIAS), + prison_mpc_pm(PlaceholderFlags.MINEPLAYERS, PlaceholderFlags.ALIAS), + prison_mbm_pm(PlaceholderFlags.MINEPLAYERS, PlaceholderFlags.ALIAS), + prison_mrc_pm(PlaceholderFlags.MINEPLAYERS, PlaceholderFlags.ALIAS), + + + + prison_mines_name_playermines(prison_mn_pm, PlaceholderFlags.MINEPLAYERS), + prison_mines_tag_playermines(prison_mt_pm, PlaceholderFlags.MINEPLAYERS), + prison_mines_interval_playermines(prison_mi_pm, PlaceholderFlags.MINEPLAYERS), + prison_mines_interval_formatted_playermines(prison_mif_pm, PlaceholderFlags.MINEPLAYERS), + prison_mines_timeleft_playermines(prison_mtl_pm, PlaceholderFlags.MINEPLAYERS), + prison_mines_timeleft_bar_playermines(prison_mtlb_pm, PlaceholderFlags.MINEPLAYERS), + prison_mines_timeleft_formatted_playermines(prison_mtlf_pm, PlaceholderFlags.MINEPLAYERS), + prison_mines_size_playermines(prison_ms_pm, PlaceholderFlags.MINEPLAYERS), + prison_mines_remaining_playermines(prison_mr_pm, PlaceholderFlags.MINEPLAYERS), + prison_mines_remaining_bar_playermines(prison_mrb_pm, PlaceholderFlags.MINEPLAYERS), + prison_mines_percent_playermines(prison_mp_pm, PlaceholderFlags.MINEPLAYERS), + prison_mines_player_count_playermines(prison_mpc_pm, PlaceholderFlags.MINEPLAYERS), + prison_mines_blocks_mined_playermines(prison_mbm_pm, PlaceholderFlags.MINEPLAYERS), + prison_mines_reset_count_playermines(prison_mrc_pm, PlaceholderFlags.MINEPLAYERS), + - prison_r_n_rankname(PlaceHolderFlags.RANKS, PlaceHolderFlags.ALIAS), - prison_r_t_rankname(PlaceHolderFlags.RANKS, PlaceHolderFlags.ALIAS), - prison_r_l_rankname(PlaceHolderFlags.RANKS, PlaceHolderFlags.ALIAS), - prison_r_c_rankname(PlaceHolderFlags.RANKS, PlaceHolderFlags.ALIAS), - prison_r_cf_rankname(PlaceHolderFlags.RANKS, PlaceHolderFlags.ALIAS), - prison_r_cu_rankname(PlaceHolderFlags.RANKS, PlaceHolderFlags.ALIAS), - prison_r_id_rankname(PlaceHolderFlags.RANKS, PlaceHolderFlags.ALIAS), - prison_r_pc_rankname(PlaceHolderFlags.RANKS, PlaceHolderFlags.ALIAS), - prison_r_lm_rankname(PlaceHolderFlags.RANKS, PlaceHolderFlags.ALIAS), - - - prison_rank__name_rankname(prison_r_n_rankname, PlaceHolderFlags.RANKS), - prison_rank__tag_rankname(prison_r_t_rankname, PlaceHolderFlags.RANKS), - prison_rank__ladder_rankname(prison_r_l_rankname, PlaceHolderFlags.RANKS), - prison_rank__cost_rankname(prison_r_c_rankname, PlaceHolderFlags.RANKS), - prison_rank__cost_formatted_rankname(prison_r_cf_rankname, PlaceHolderFlags.RANKS), - prison_rank__currency_rankname(prison_r_cu_rankname, PlaceHolderFlags.RANKS), - prison_rank__id_rankname(prison_r_id_rankname, PlaceHolderFlags.RANKS), - prison_rank__player_count_rankname(prison_r_pc_rankname, PlaceHolderFlags.RANKS), - prison_rank__linked_mines_rankname(prison_r_lm_rankname, PlaceHolderFlags.RANKS), + prison_r_n_rankname(PlaceholderFlags.RANKS, PlaceholderFlags.ALIAS), + prison_r_t_rankname(PlaceholderFlags.RANKS, PlaceholderFlags.ALIAS), + prison_r_l_rankname(PlaceholderFlags.RANKS, PlaceholderFlags.ALIAS), + prison_r_lp_rankname(PlaceholderFlags.RANKS, PlaceholderFlags.ALIAS), + prison_r_c_rankname(PlaceholderFlags.RANKS, PlaceholderFlags.ALIAS), + prison_r_cf_rankname(PlaceholderFlags.RANKS, PlaceholderFlags.ALIAS), + prison_r_cm_rankname(PlaceholderFlags.RANKS, PlaceholderFlags.ALIAS), + prison_r_cu_rankname(PlaceholderFlags.RANKS, PlaceholderFlags.ALIAS), + prison_r_id_rankname(PlaceholderFlags.RANKS, PlaceholderFlags.ALIAS), + prison_r_pc_rankname(PlaceholderFlags.RANKS, PlaceholderFlags.ALIAS), + prison_r_lm_rankname(PlaceholderFlags.RANKS, PlaceholderFlags.ALIAS), + + + + + + prison_rank__name_rankname(prison_r_n_rankname, PlaceholderFlags.RANKS), + prison_rank__tag_rankname(prison_r_t_rankname, PlaceholderFlags.RANKS), + prison_rank__ladder_rankname(prison_r_l_rankname, PlaceholderFlags.RANKS), + prison_rank__ladder_position_rankname(prison_r_lp_rankname, PlaceholderFlags.RANKS), + prison_rank__cost_rankname(prison_r_c_rankname, PlaceholderFlags.RANKS), + prison_rank__cost_formatted_rankname(prison_r_cf_rankname, PlaceholderFlags.RANKS), + prison_rank__cost_multiplier_rankname(prison_r_cm_rankname, PlaceholderFlags.RANKS), + prison_rank__currency_rankname(prison_r_cu_rankname, PlaceholderFlags.RANKS), + prison_rank__id_rankname(prison_r_id_rankname, PlaceholderFlags.RANKS), + prison_rank__player_count_rankname(prison_r_pc_rankname, PlaceholderFlags.RANKS), + prison_rank__linked_mines_rankname(prison_r_lm_rankname, PlaceholderFlags.RANKS), + + + + + + + //prison_r_plp_rankname(PlaceHolderFlags.RANKPLAYERS, PlaceHolderFlags.ALIAS), + prison_r_pcst_rankname(PlaceholderFlags.RANKPLAYERS, PlaceholderFlags.ALIAS), + prison_r_pcf_rankname(PlaceholderFlags.RANKPLAYERS, PlaceholderFlags.ALIAS), + prison_r_pcr_rankname(PlaceholderFlags.RANKPLAYERS, PlaceholderFlags.ALIAS), + prison_r_pcrf_rankname(PlaceholderFlags.RANKPLAYERS, PlaceholderFlags.ALIAS), + prison_r_pcp_rankname(PlaceholderFlags.RANKPLAYERS, PlaceholderFlags.ALIAS), + prison_r_pcb_rankname(PlaceholderFlags.RANKPLAYERS, PlaceholderFlags.ALIAS), + + + //prison_rank__player_ladder_position_rankname(prison_r_plp_rankname, PlaceHolderFlags.RANKPLAYERS), + prison_rank__player_cost_rankname(prison_r_pcst_rankname, PlaceholderFlags.RANKPLAYERS), + prison_rank__player_cost_formatted_rankname(prison_r_pcf_rankname, PlaceholderFlags.RANKPLAYERS), + prison_rank__player_cost_remaining_rankname(prison_r_pcf_rankname, PlaceholderFlags.RANKPLAYERS), + prison_rank__player_cost_remaining_formatted_rankname(prison_r_pcf_rankname, PlaceholderFlags.RANKPLAYERS), + prison_rank__player_cost_percent_rankname(prison_r_pcp_rankname, PlaceholderFlags.RANKPLAYERS), + prison_rank__player_cost_bar_rankname(prison_r_pcb_rankname, PlaceholderFlags.RANKPLAYERS), + + + + + prison_tmbl_header_minename(PlaceholderFlags.MINES, PlaceholderFlags.ALIAS), + prison_tmbl_nnn_minename(PlaceholderFlags.STATSMINES, PlaceholderFlags.ALIAS), + prison_tmbl_totals_minename(PlaceholderFlags.MINES, PlaceholderFlags.ALIAS), + + prison_tmbn_nnn_minename(PlaceholderFlags.STATSMINES, PlaceholderFlags.ALIAS), + prison_tmbc_nnn_minename(PlaceholderFlags.STATSMINES, PlaceholderFlags.ALIAS), + prison_tmbpl_nnn_minename(PlaceholderFlags.STATSMINES, PlaceholderFlags.ALIAS), + prison_tmbr_nnn_minename(PlaceholderFlags.STATSMINES, PlaceholderFlags.ALIAS), + prison_tmbrb_nnn_minename(PlaceholderFlags.STATSMINES, PlaceholderFlags.ALIAS), + prison_tmbt_nnn_minename(PlaceholderFlags.STATSMINES, PlaceholderFlags.ALIAS), + + + prison_top_mine_block_line_header_minename(prison_tmbl_header_minename, PlaceholderFlags.MINES), + prison_top_mine_block_line_nnn_minename(prison_tmbl_nnn_minename, PlaceholderFlags.STATSMINES), + prison_top_mine_block_line_totals_minename(prison_tmbl_totals_minename, PlaceholderFlags.MINES), + + prison_top_mine_block_name_nnn_minename(prison_tmbn_nnn_minename, PlaceholderFlags.STATSMINES), + prison_top_mine_block_chance_nnn_minename(prison_tmbc_nnn_minename, PlaceholderFlags.STATSMINES), + prison_top_mine_block_placed_nnn_minename(prison_tmbpl_nnn_minename, PlaceholderFlags.STATSMINES), + prison_top_mine_block_remaing_nnn_minename(prison_tmbr_nnn_minename, PlaceholderFlags.STATSMINES), + prison_top_mine_block_remaing_bar_nnn_minename(prison_tmbrb_nnn_minename, PlaceholderFlags.STATSMINES), + prison_top_mine_block_total_nnn_minename(prison_tmbt_nnn_minename, PlaceholderFlags.STATSMINES), + + + prison_trbn_nnn_rankname(PlaceholderFlags.STATSRANKS, PlaceholderFlags.ALIAS), + prison_trbs_nnn_rankname(PlaceholderFlags.STATSRANKS, PlaceholderFlags.ALIAS), + prison_trbb_nnn_rankname(PlaceholderFlags.STATSRANKS, PlaceholderFlags.ALIAS), + + prison_top_rank_balance_name_nnn_rankname( prison_trbn_nnn_rankname, PlaceholderFlags.STATSRANKS ), + prison_top_rank_balance_score_nnn_rankname( prison_trbs_nnn_rankname, PlaceholderFlags.STATSRANKS ), + prison_top_rank_balance_balance_nnn_rankname( prison_trbb_nnn_rankname, PlaceholderFlags.STATSRANKS ), + ; private final PrisonPlaceHolders alias; - private final List flags; + private final List flags; private PrisonPlaceHolders() { this.flags = new ArrayList<>(); this.alias = null; } - private PrisonPlaceHolders(PlaceHolderFlags... flags) { + private PrisonPlaceHolders(PlaceholderFlags... flags) { this.alias = null; this.flags = getFlags(flags); } - private PrisonPlaceHolders(PrisonPlaceHolders alias, PlaceHolderFlags... flags) { + private PrisonPlaceHolders(PrisonPlaceHolders alias, PlaceholderFlags... flags) { this.alias = alias; this.flags = getFlags(flags); } - private List getFlags( PlaceHolderFlags[] flags ) { - List flagz = new ArrayList<>(); + private List getFlags( PlaceholderFlags[] flags ) { + List flagz = new ArrayList<>(); if ( flags != null ) { - for ( PlaceHolderFlags flag : flags ) { + for ( PlaceholderFlags flag : flags ) { flagz.add( flag ); } } @@ -381,17 +573,39 @@ public boolean hasAlias() { return alias != null; } public boolean isAlias() { - return flags.contains( PlaceHolderFlags.ALIAS ); + return flags.contains( PlaceholderFlags.ALIAS ); } public boolean isSuppressed() { - return flags.contains( PlaceHolderFlags.SUPRESS ); + return flags.contains( PlaceholderFlags.SUPRESS ); } - public boolean hasFlag( PlaceHolderFlags flag ) { + public boolean hasFlag( PlaceholderFlags flag ) { return flags.contains( flag ); } - public List getFlags() { + public List getFlags() { return flags; } + + /** + *

Some placeholders have a "sequence" of numbers as part of the + * placeholder name. This function, hasSequence(), is a quick way to + * identify if the placeholder contains a sequence so the special processing + * that is required for sequences can be performed. + *

+ * + * @return + */ + public boolean hasSequence() { + boolean results = false; + + for ( PlaceholderFlags placeholderFlags : flags ) { + if ( placeholderFlags.hasSequence() ) { + results = true; + break; + } + } + + return results; + } public static PrisonPlaceHolders fromString( String placeHolder ) { PrisonPlaceHolders result = no_match__; @@ -416,7 +630,7 @@ public static PrisonPlaceHolders fromString( String placeHolder ) { return result; } - public static List getTypes(PlaceHolderFlags flag) { + public static List getTypes(PlaceholderFlags flag) { List results = new ArrayList<>(); if ( flag != null ) { @@ -431,7 +645,7 @@ public static List getTypes(PlaceHolderFlags flag) { } public static List excludeTypes( - List list, PlaceHolderFlags flag) { + List list, PlaceholderFlags flag) { List results = new ArrayList<>(); if ( flag != null ) { @@ -464,21 +678,47 @@ public static List getAllChatList( boolean omitSuppressable) { boolean hasDeprecated = false; - for ( PrisonPlaceHolders ph : values() ) + int totalCount = 0; + for ( PlaceholderFlags type : PlaceholderFlags.values() ) { - if ( !omitSuppressable || omitSuppressable && !ph.isSuppressed() && !ph.isAlias() ) { - if ( !hasDeprecated && ph.isSuppressed() ) { - hasDeprecated = true; + if ( type == PlaceholderFlags.ALIAS || type == PlaceholderFlags.SUPRESS ) { + break; + } + + int pos = results.size(); + results.add( " &7" + type.name() ); + + + int count = 0; + for ( PrisonPlaceHolders ph : values() ) + { + if ( ph.getFlags().contains( type ) && + ( !omitSuppressable || + omitSuppressable && !ph.isSuppressed() && !ph.isAlias() )) { + + if ( !hasDeprecated && ph.isSuppressed() ) { + hasDeprecated = true; + } + + results.add( " " + ph.getChatText() ); + + count++; + totalCount++; } - - results.add( ph.getChatText() ); } + + results.set( pos, results.get( pos ) + + " (" + (count * 2) + ", " + count + " aliases):"); } + if ( hasDeprecated ) { results.add( " &2(&4*&2=&4suppressed&2)" ); } + results.add( 0, "&7Available PlaceHolders" + + " (" + (totalCount * 2) + ", " + totalCount + " aliases):"); + return results; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderResults.java b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderResults.java index 4fd35a73a..7b236ea3c 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderResults.java +++ b/prison-core/src/main/java/tech/mcprison/prison/placeholders/PlaceholderResults.java @@ -6,8 +6,13 @@ public class PlaceholderResults private String escapeLeft; private String esccapeRight; + private String numericSequencePattern; + private int numericSequence = -1; + private String identifier; + + public PlaceholderResults( PlaceHolderKey placeholder ) { super(); @@ -62,6 +67,20 @@ public void setIdentifier( String identifier ) { this.identifier = identifier; } + public String getNumericSequencePattern() { + return numericSequencePattern; + } + public void setNumericSequencePattern( String numericSequencePattern ) { + this.numericSequencePattern = numericSequencePattern; + } + + public int getNumericSequence() { + return numericSequence; + } + public void setNumericSequence( int numericSequence ) { + this.numericSequence = numericSequence; + } + public String getEscapeLeft() { return escapeLeft; } diff --git a/prison-core/src/main/java/tech/mcprison/prison/placeholders/Placeholders.java b/prison-core/src/main/java/tech/mcprison/prison/placeholders/Placeholders.java index 8c20a9743..331bd1849 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/placeholders/Placeholders.java +++ b/prison-core/src/main/java/tech/mcprison/prison/placeholders/Placeholders.java @@ -4,11 +4,11 @@ import java.util.Map; import java.util.UUID; -import tech.mcprison.prison.placeholders.PlaceholderManager.PlaceHolderFlags; +import tech.mcprison.prison.placeholders.PlaceholderManager.PlaceholderFlags; public interface Placeholders { - public Map getPlaceholderDetailCounts(); + public Map getPlaceholderDetailCounts(); public int getPlaceholderCount(); diff --git a/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTask.java b/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTask.java index 7cb236c7f..f0895ec1a 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTask.java +++ b/prison-core/src/main/java/tech/mcprison/prison/tasks/PrisonCommandTask.java @@ -78,6 +78,7 @@ public enum CustomPlaceholders { balanceInitial(CommandEnvironment.rank_commands), balanceFinal(CommandEnvironment.rank_commands), currency(CommandEnvironment.rank_commands), + originalRankCost(CommandEnvironment.rank_commands), rankupCost(CommandEnvironment.rank_commands), ladder(CommandEnvironment.rank_commands), diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/JumboTextFont.java b/prison-core/src/main/java/tech/mcprison/prison/util/JumboTextFont.java new file mode 100644 index 000000000..de6346734 --- /dev/null +++ b/prison-core/src/main/java/tech/mcprison/prison/util/JumboTextFont.java @@ -0,0 +1,187 @@ +package tech.mcprison.prison.util; + +import java.util.ArrayList; +import java.util.List; + +public enum JumboTextFont { + + A("A", 5, " A ", " A A ", "AAAAA", "A A", "A A" ), + B("B", 5, "BBBB ", "B B", "BBBB ", "B B", "BBBB " ), + C("C", 5, " CCC ", "C ", "C ", "C ", " CCC " ), + D("D", 5, "DDDD ", "D D", "D D", "D D", "DDDD " ), + E("E", 5, "EEEEE", "E ", "EEEE ", "E ", "EEEEE" ), + F("F", 5, "FFFFF", "F ", "FFF ", "F ", "F " ), + G("G", 5, " GGG ", "G ", "G GGG", "G G", " GGG " ), + H("H", 5, "H H", "H H", "HHHHH", "H H", "H H" ), + I("I", 3, "III", " I ", " I ", " I ", "III" ), + J("J", 5, "JJJJJ", " J ", " J ", "J J ", "JJJ " ), + + K("K", 5, "K K", "K K ", "KK ", "K K ", "K K" ), + L("L", 4, "L ", "L ", "L ", "L ", "LLLL" ), + M("M", 5, "M M", "MM MM", "M M M", "M M", "M M" ), + N("N", 5, "N N", "NN N", "N N N", "N NN", "N N" ), + O("O", 5, " OOO ", "O O", "O O", "O O", " OOO " ), + P("P", 5, "PPPP ", "P P", "PPPP ", "P ", "P "), + Q("Q", 5, " QQQ ", "Q Q", "Q \\ Q", "Q \\Q", " QQ \\" ), + R("R", 5, "RRRR ", "R R", "RRRR ", "R R ", "R R" ), + S("S", 5, " SSS ", "S ", " SSS ", " S", " SSS " ), + T("T", 5, "TTTTT", " T ", " T ", " T ", " T " ), + + U("U", 5, "U U", "U U", "U U", "U U", " UUU " ), + V("V", 5, "V V", "V V", "V V", " V V ", " V " ), + W("W", 5, "W W", "W W", "W W W", "WW WW", "W W" ), + X("X", 5, "X X", " X X ", " X ", " X X ", "X X" ), + Y("Y", 5, "Y Y", " Y Y ", " Y ", " Y ", " Y " ), + Z("Z", 5, "ZZZZZ", " Z ", " Z ", " Z ", "ZZZZZ" ), + + n1("1", 3, " 1 ", "11 ", " 1 ", " 1 ", "111" ), + n2("2", 5, " 222 ", "2 2", " 2 ", " 2 ", "22222" ), + n3("3", 5, " 3333", " 3", " 33 ", " 3", "33333" ), + n4("4", 5, " 4 ", " 4 4 ", "44444", " 4 ", " 4 " ), + n5("5", 5, "55555", "5 ", "5555 ", " 5", "5555 " ), + n6("6", 5, " 666 ", "6 ", "6666 ", "6 6", " 666 " ), + n7("7", 5, "77777", " 7 ", " 7 ", " 7 ", "7 " ), + n8("8", 5, " 888 ", "8 8", " 888 ", "8 8", " 888 " ), + n9("9", 5, " 999 ", "9 9", " 9999", " 9", " 999 " ), + n0("0", 5, " 000 ", "0 0", "0 0", "0 0", " 000 " ), + + space(" ", 2, " ", " ", " ", " ", " " ), + comma(",", 2, " ", " ", "##", " #", "# " ), + period(".", 2, " ", " ", " ", "##", "##" ), + exclaim("!", 1, "!", "!", "!", " ", "*" ), + question("?", 5, " ??? ", "? ?", " ? ", " ", " * " ), + slash("/", 5, " /", " / ", " / ", " / ", "/ " ), + backslash("\\", 5, "\\ ", " \\ ", " \\ ", " \\ ", " \\" ), + underscore("_", 5, " ", " ", " ", " ", "#####" ), + plus("+", 3, " ", " ", " + ", "+++", " + " ), + minus("-", 3, " ", " ", " ", "---", " " ), + equal("=", 3, " ", " ", "===", " ", "===" ), + + a("a", 5, " ", " ", " aaa ", "a aa", " aa a" ), + b("b", 5, "b ", "b ", "bbbb ", "b b", "bbbb " ), + c("c", 5, " ", " ", " ccc ", "c ", " ccc " ), + d("d", 5, " d", " d", " dddd", "d d", " dddd" ), + //e("e", 5, " ", " eee ", "e e", "eeeee", "e ", " eee " ) // bad lowercase + f("f", 4, " ff", " f ", "ffff", " f ", " f " ), + //g + h("h", 5, "h ", "h ", "hhhh ", "h h", "h h" ), + i("i", 1, "i", " ", "i", "i", "i" ), + j("j", 2, " j", " ", " j", " j", "jj" ), + k("k", 5, "k ", "k k", "k k ", "kk ", "k k " ), + l("l", 2, "l ", "l ", "l ", "l ", "ll" ), + //m + m("m", 5, " ", " ", "mm mm", "m m m", "m m m" ), + n("n", 5, " ", " ", "n nn ", "nn n", "n n" ), + o("o", 5, " ", " ", " ooo ", "o o", " ooo " ), + //p + //q + r("r", 4, " ", " ", "r rr", "rr ", "r " ), + //s + t("t", 5, " ", " t ", "ttttt", " t ", " t " ), + u("u", 5, " ", " ", "u u", "u u", " uuu " ), + v("v", 5, " ", " ", "v v", " v v ", " v " ), + w("w", 5, " ", " ", "w w w", "w w w", " w w " ), + x("x", 3, " ", " ", "x x", " x ", "x x" ), + //y + z("z", 3, " ", " ", "zzz", " z ", "zzz" ) + ; + + + private final String letter; + private final int width; + private final List fontRows; + private JumboTextFont( String letter, int width, String... font) { + this.letter = letter; + this.width = width; + this.fontRows = new ArrayList<>(); + + for ( String line : font ) + { +// line = (line.length() != 5 ? (line + " ").substring( 0, 5 ) : line ); + fontRows.add( line ); + } + } + + + public String getLetter() { + return letter; + } + public int getWidth() { + return width; + } + public List getFontRows() { + return fontRows; + } + + public static void makeJumboFontText( String text, StringBuilder sb ) { + +// // Temp until lowercase is added: +// text = text.toUpperCase(); + + List texts = JumboTextFont.textLines( text ); + + for ( StringBuilder sbLine : texts ) { + sb.append( sbLine ).append( "\n" ); + } + + } + + private static List textLines( String word ) { + List jtfs = JumboTextFont.buildJumboText( word ); + + int fontHeight = 5; + + List texts = new ArrayList<>(); + for ( int i = 0; i < fontHeight; i++ ) { + texts.add( new StringBuilder() ); + } + + for ( JumboTextFont jumboTextFont : jtfs ) { + + for ( int i = 0; i < 5; i++ ) { + String frow = jumboTextFont.getFontRows().get( i ); + texts.get( i ).append( frow ).append( " " ); + } + + } + + return texts; + } + + private static List buildJumboText( String word ) { + List results = new ArrayList<>(); + + for ( String letter : word.split("|") ) + { + JumboTextFont jtf = findMatch( letter ); + if ( jtf != null ) { + results.add( jtf ); + } + } + + return results; + } + + private static JumboTextFont findMatch( String letter ) { + JumboTextFont results = null; + + if ( letter != null ) { + + for ( JumboTextFont jtf : values() ) { + if ( jtf.getLetter().equals( letter ) ) { + results = jtf; + break; + } + } + } + + if ( results == null && Character.isLowerCase( letter.charAt( 0 ) ) ) { + // The letter is lowercase and could not hit on a lowercase character, + // so uppercase it and try again: + results = findMatch( letter.toUpperCase() ); + } + + return results; + } + +} diff --git a/prison-core/src/main/java/tech/mcprison/prison/util/Text.java b/prison-core/src/main/java/tech/mcprison/prison/util/Text.java index a724194b1..f0ec6f69c 100644 --- a/prison-core/src/main/java/tech/mcprison/prison/util/Text.java +++ b/prison-core/src/main/java/tech/mcprison/prison/util/Text.java @@ -27,6 +27,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import tech.mcprison.prison.Prison; + /** * Provides utilities for manipulating text. * @@ -346,9 +348,8 @@ public static String translateHexColorCodes( String text, char targetColorCode ) sb.append( translateHexColorCodesCore( text, targetColorCode ) ); } else { - while ( idxStart >= 0 ) { - sb.append( translateHexColorCodesCore( text.substring( 0, idxStart ), targetColorCode) ); + sb.append( translateHexColorCodesCore( text.substring( idxEnd + 1, idxStart ), targetColorCode) ); idxEnd = text.indexOf( "\\E", idxStart ); @@ -357,11 +358,14 @@ public static String translateHexColorCodes( String text, char targetColorCode ) idxStart = -1; } else { - sb.append( text.substring( idxStart, idxEnd ) ); + sb.append( text.substring( idxStart, idxEnd + 1 ) ); idxStart = text.indexOf( "\\Q", idxEnd ); } } + if ( idxEnd < text.length() ) { + sb.append( text.substring( idxEnd + 1 ) ); + } } } @@ -445,12 +449,15 @@ public static String titleize(String txt) { int eatLeft = (centerlen / 2) - balance; int eatRight = (centerlen - eatLeft) + balance; + String prisonVersion = " &5(" + Prison.get().getPlatform().getPluginVersion() + ")"; + if (eatLeft < pivot) { return translateAmpColorCodes( "&8" + (headingLine.substring(0, pivot - eatLeft)) + " " + center + " &8" - + (headingLine.substring(pivot + eatRight))); + + (headingLine.substring(pivot + eatRight))) + + prisonVersion; } else { - return center; + return center + prisonVersion; } } diff --git a/prison-core/src/main/resources/lang/core/de_DE.properties b/prison-core/src/main/resources/lang/core/de_DE.properties index ad31e2bec..4f1064e60 100644 --- a/prison-core/src/main/resources/lang/core/de_DE.properties +++ b/prison-core/src/main/resources/lang/core/de_DE.properties @@ -1,6 +1,6 @@ # # Prison ist ein Minecraft Plug-In für das Prison Spielmodus. -# Copyright (C) 2017 The Prison Team +# Copyright (C) 2021 The Prison Team # # Dieses Programm ist kostenlose Software: Sie können es # weiterverbreiten und/oder es modifizieren unter den @@ -18,6 +18,81 @@ # haben zusammen mit diesem Programm. Sollte dies nicht der # Fall sein, siehe http://gnu.org/licences/. # + +## +## Prison Supports Unicode (UTF-8) encoding in these properties files. BUt you must +## follow these instructions to ensure everything works properly. +## +## 1. You should only edit these files using a UTF-8 editor. On windows use NotePad, not WordPad. +## WordPad will save as plain text. To confirm the save was successful: save, close the editor, +## then reopen to confirm the encoding was preserved. +## +## 2. When running on Windows, you must enable utf-8 encoding in minecraft's console. Windows +## defaults to a characterpage 1252. To enable window's use of utf-8, you need to change the +## encoding prior to launching spigot/paper: +## chcp 65001 +## +## Full example of a windows script, which hooks for java debugging: +## rem Note: chcp 65001 enables utf-8 in windows, when normally windows uses characterpage 1252 +## chcp 65001 +## java -Dfile.encoding="UTF-8" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -Xms1g -Xmx4g -jar spigot-1.8.8.jar nogui --log-strip-color +## pause +## +## 3. When viewing the logs/latest.log files you must use an editor such as NotePad instead of WordPad. +## +## 4. Unicode is properly displayed in game, in console, in the logs, and with paste.helpch.at when using +## /prison support submit. +## + + +# NOTE: A messages__version is an arbitrary integer that will be manually incremented within Prison +# when there are changes to these messages. This value represents when message content is +# changed, fixed, or added to. This value may not be increased if the change is very small and +# insignificant, such as a space or a couple of letters. +# +# messages__auto_refresh=true indicates that this file will automatically be replaced if +# Prison detects a messages__version difference. The old file will be deleted (renamed) and +# a new copy will be placed in the directory to be used. If this value is set to false, then +# Prison will not refresh this file and there could be issues with the display of other messages. +# If auto refresh is set to false, we are not held responsible for possible issues that can +# arise from inaccurate messages. If set to false, then you are responsible for maintaining +# the messages on your own. +# +# If you make changes to this file, and you have messages__auto_refresh=false, then those +# changes will be replaced when this file is updated. Since the old file is renamed, and +# not deleted, you can manually merge your changes back in to the new update. The old +# renamed files will never be deleted by prison; you can remove them when you feel like it +# is safe to do so. +# +# Please consider helping Prison, and everyone else who may use Prison, by contributing all +# translations to other languages. They should be faithful translations, and not something +# for the sake of humor or changes just for cosmetic styling. If you have something you would +# like to share, please contact a staff member on our Discord server. +#Thanks for your contributions! +# +messages__version=1 +messages__auto_refresh=true + + +core_output__prefix_template=| %1 | &7 +core_output__prefix_template_prison=Prison +core_output__prefix_template_info=Info +core_output__prefix_template_warning=Warning +core_output__prefix_template_error=Error +core_output__prefix_template_debug=Debug + +core_output__color_code_info=&3 +core_output__color_code_warning=&c +core_output__color_code_error=&c +core_output__color_code_debug=&9 + +core_output__error_startup_failure=Prison: (Sending to System.err due to Output.log Logger failure): +core_output__error_incorrect_number_of_parameters=Log Failure (%1): Incorrect number of parameters: [%2] Original raw message: [%3] Arguments: %4 + + + +# The following are the original messages and they will eventually be replaced. + includeError=[%1] hat einen ungültigen Wert. excludeError=[%1] hat einen ungültigen Wert. cantAsConsole=Sie können dies nicht als Konsole machen. diff --git a/prison-core/src/main/resources/lang/core/en_GB.properties b/prison-core/src/main/resources/lang/core/en_GB.properties index 20612e68b..c3223f96a 100644 --- a/prison-core/src/main/resources/lang/core/en_GB.properties +++ b/prison-core/src/main/resources/lang/core/en_GB.properties @@ -1,6 +1,6 @@ # # Prison is a Minecraft plugin for the prison game mode. -# Copyright (C) 2017 The Prison Team +# Copyright (C) 2021 The Prison Team # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -15,6 +15,81 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # + +## +## Prison Supports Unicode (UTF-8) encoding in these properties files. BUt you must +## follow these instructions to ensure everything works properly. +## +## 1. You should only edit these files using a UTF-8 editor. On windows use NotePad, not WordPad. +## WordPad will save as plain text. To confirm the save was successful: save, close the editor, +## then reopen to confirm the encoding was preserved. +## +## 2. When running on Windows, you must enable utf-8 encoding in minecraft's console. Windows +## defaults to a characterpage 1252. To enable window's use of utf-8, you need to change the +## encoding prior to launching spigot/paper: +## chcp 65001 +## +## Full example of a windows script, which hooks for java debugging: +## rem Note: chcp 65001 enables utf-8 in windows, when normally windows uses characterpage 1252 +## chcp 65001 +## java -Dfile.encoding="UTF-8" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -Xms1g -Xmx4g -jar spigot-1.8.8.jar nogui --log-strip-color +## pause +## +## 3. When viewing the logs/latest.log files you must use an editor such as NotePad instead of WordPad. +## +## 4. Unicode is properly displayed in game, in console, in the logs, and with paste.helpch.at when using +## /prison support submit. +## + + +# NOTE: A messages__version is an arbitrary integer that will be manually incremented within Prison +# when there are changes to these messages. This value represents when message content is +# changed, fixed, or added to. This value may not be increased if the change is very small and +# insignificant, such as a space or a couple of letters. +# +# messages__auto_refresh=true indicates that this file will automatically be replaced if +# Prison detects a messages__version difference. The old file will be deleted (renamed) and +# a new copy will be placed in the directory to be used. If this value is set to false, then +# Prison will not refresh this file and there could be issues with the display of other messages. +# If auto refresh is set to false, we are not held responsible for possible issues that can +# arise from inaccurate messages. If set to false, then you are responsible for maintaining +# the messages on your own. +# +# If you make changes to this file, and you have messages__auto_refresh=false, then those +# changes will be replaced when this file is updated. Since the old file is renamed, and +# not deleted, you can manually merge your changes back in to the new update. The old +# renamed files will never be deleted by prison; you can remove them when you feel like it +# is safe to do so. +# +# Please consider helping Prison, and everyone else who may use Prison, by contributing all +# translations to other languages. They should be faithful translations, and not something +# for the sake of humor or changes just for cosmetic styling. If you have something you would +# like to share, please contact a staff member on our Discord server. +#Thanks for your contributions! +# +messages__version=1 +messages__auto_refresh=true + + +core_output__prefix_template=| %1 | &7 +core_output__prefix_template_prison=Prison +core_output__prefix_template_info=Info +core_output__prefix_template_warning=Warning +core_output__prefix_template_error=Error +core_output__prefix_template_debug=Debug + +core_output__color_code_info=&3 +core_output__color_code_warning=&c +core_output__color_code_error=&c +core_output__color_code_debug=&9 + +core_output__error_startup_failure=Prison: (Sending to System.err due to Output.log Logger failure): +core_output__error_incorrect_number_of_parameters=Log Failure (%1): Incorrect number of parameters: [%2] Original raw message: [%3] Arguments: %4 + + + +# The following are the original messages and they will eventually be replaced. + includeError=[%1] has an invalid value. excludeError=[%1] has an invalid value. cantAsConsole=You can't do this as console. diff --git a/prison-core/src/main/resources/lang/core/en_US.properties b/prison-core/src/main/resources/lang/core/en_US.properties index 20612e68b..3371cf072 100644 --- a/prison-core/src/main/resources/lang/core/en_US.properties +++ b/prison-core/src/main/resources/lang/core/en_US.properties @@ -1,6 +1,6 @@ # # Prison is a Minecraft plugin for the prison game mode. -# Copyright (C) 2017 The Prison Team +# Copyright (C) 2021 The Prison Team # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -15,6 +15,83 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # + +## +## Prison Supports Unicode (UTF-8) encoding in these properties files. BUt you must +## follow these instructions to ensure everything works properly. +## +## 1. You should only edit these files using a UTF-8 editor. On windows use NotePad, not WordPad. +## WordPad will save as plain text. To confirm the save was successful: save, close the editor, +## then reopen to confirm the encoding was preserved. +## +## 2. When running on Windows, you must enable utf-8 encoding in minecraft's console. Windows +## defaults to a characterpage 1252. To enable window's use of utf-8, you need to change the +## encoding prior to launching spigot/paper: +## chcp 65001 +## +## Full example of a windows script, which hooks for java debugging: +## rem Note: chcp 65001 enables utf-8 in windows, when normally windows uses characterpage 1252 +## chcp 65001 +## java -Dfile.encoding="UTF-8" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -Xms1g -Xmx4g -jar spigot-1.8.8.jar nogui --log-strip-color +## pause +## +## 3. When viewing the logs/latest.log files you must use an editor such as NotePad instead of WordPad. +## +## 4. Unicode is properly displayed in game, in console, in the logs, and with paste.helpch.at when using +## /prison support submit. +## + + +# NOTE: A messages__version is an arbitrary integer that will be manually incremented within Prison +# when there are changes to these messages. This value represents when message content is +# changed, fixed, or added to. This value may not be increased if the change is very small and +# insignificant, such as a space or a couple of letters. +# +# messages__auto_refresh=true indicates that this file will automatically be replaced if +# Prison detects a messages__version difference. The old file will be deleted (renamed) and +# a new copy will be placed in the directory to be used. If this value is set to false, then +# Prison will not refresh this file and there could be issues with the display of other messages. +# If auto refresh is set to false, we are not held responsible for possible issues that can +# arise from inaccurate messages. If set to false, then you are responsible for maintaining +# the messages on your own. +# +# If you make changes to this file, and you have messages__auto_refresh=false, then those +# changes will be replaced when this file is updated. Since the old file is renamed, and +# not deleted, you can manually merge your changes back in to the new update. The old +# renamed files will never be deleted by prison; you can remove them when you feel like it +# is safe to do so. +# +# Please consider helping Prison, and everyone else who may use Prison, by contributing all +# translations to other languages. They should be faithful translations, and not something +# for the sake of humor or changes just for cosmetic styling. If you have something you would +# like to share, please contact a staff member on our Discord server. +#Thanks for your contributions! +# +messages__version=2 +messages__auto_refresh=true + + +core_output__prefix_template=| %1 | &7 +core_output__prefix_template_prison=Prison +core_output__prefix_template_info=Info +core_output__prefix_template_warning=Warning +core_output__prefix_template_error=Error +core_output__prefix_template_debug=Debug + +core_output__color_code_info=&3 +core_output__color_code_warning=&c +core_output__color_code_error=&c +core_output__color_code_debug=&9 + +core_output__error_startup_failure=Prison: (Sending to System.err due to Output.log Logger failure): +core_output__error_incorrect_number_of_parameters=Log Failure (%1): Incorrect number of parameters: [%2] Original raw message: [%3] Arguments: %4 + + +core_prison_utf8_test=Привет! Давай поÑмотрим, работает ли? Test 01 + + +# The following are the original messages and they will eventually be replaced. + includeError=[%1] has an invalid value. excludeError=[%1] has an invalid value. cantAsConsole=You can't do this as console. diff --git a/prison-core/src/main/resources/lang/core/es_ES.properties b/prison-core/src/main/resources/lang/core/es_ES.properties index 24b65894a..2e5bbb6cd 100644 --- a/prison-core/src/main/resources/lang/core/es_ES.properties +++ b/prison-core/src/main/resources/lang/core/es_ES.properties @@ -1,6 +1,6 @@ # # Prison is a Minecraft plugin for the prison game mode. -# Copyright (C) 2017 The Prison Team +# Copyright (C) 2021 The Prison Team # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -15,6 +15,81 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # + +## +## Prison Supports Unicode (UTF-8) encoding in these properties files. BUt you must +## follow these instructions to ensure everything works properly. +## +## 1. You should only edit these files using a UTF-8 editor. On windows use NotePad, not WordPad. +## WordPad will save as plain text. To confirm the save was successful: save, close the editor, +## then reopen to confirm the encoding was preserved. +## +## 2. When running on Windows, you must enable utf-8 encoding in minecraft's console. Windows +## defaults to a characterpage 1252. To enable window's use of utf-8, you need to change the +## encoding prior to launching spigot/paper: +## chcp 65001 +## +## Full example of a windows script, which hooks for java debugging: +## rem Note: chcp 65001 enables utf-8 in windows, when normally windows uses characterpage 1252 +## chcp 65001 +## java -Dfile.encoding="UTF-8" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -Xms1g -Xmx4g -jar spigot-1.8.8.jar nogui --log-strip-color +## pause +## +## 3. When viewing the logs/latest.log files you must use an editor such as NotePad instead of WordPad. +## +## 4. Unicode is properly displayed in game, in console, in the logs, and with paste.helpch.at when using +## /prison support submit. +## + + +# NOTE: A messages__version is an arbitrary integer that will be manually incremented within Prison +# when there are changes to these messages. This value represents when message content is +# changed, fixed, or added to. This value may not be increased if the change is very small and +# insignificant, such as a space or a couple of letters. +# +# messages__auto_refresh=true indicates that this file will automatically be replaced if +# Prison detects a messages__version difference. The old file will be deleted (renamed) and +# a new copy will be placed in the directory to be used. If this value is set to false, then +# Prison will not refresh this file and there could be issues with the display of other messages. +# If auto refresh is set to false, we are not held responsible for possible issues that can +# arise from inaccurate messages. If set to false, then you are responsible for maintaining +# the messages on your own. +# +# If you make changes to this file, and you have messages__auto_refresh=false, then those +# changes will be replaced when this file is updated. Since the old file is renamed, and +# not deleted, you can manually merge your changes back in to the new update. The old +# renamed files will never be deleted by prison; you can remove them when you feel like it +# is safe to do so. +# +# Please consider helping Prison, and everyone else who may use Prison, by contributing all +# translations to other languages. They should be faithful translations, and not something +# for the sake of humor or changes just for cosmetic styling. If you have something you would +# like to share, please contact a staff member on our Discord server. +#Thanks for your contributions! +# +messages__version=1 +messages__auto_refresh=true + + +core_output__prefix_template=| %1 | &7 +core_output__prefix_template_prison=Prison +core_output__prefix_template_info=Info +core_output__prefix_template_warning=Warning +core_output__prefix_template_error=Error +core_output__prefix_template_debug=Debug + +core_output__color_code_info=&3 +core_output__color_code_warning=&c +core_output__color_code_error=&c +core_output__color_code_debug=&9 + +core_output__error_startup_failure=Prison: (Sending to System.err due to Output.log Logger failure): +core_output__error_incorrect_number_of_parameters=Log Failure (%1): Incorrect number of parameters: [%2] Original raw message: [%3] Arguments: %4 + + + +# The following are the original messages and they will eventually be replaced. + includeError=[%1] tiene un valor inválido. excludeError=[%1] tiene un valor inválido. cantAsConsole=No puedes realizar esto desde la consola. diff --git a/prison-core/src/main/resources/lang/core/hu_HU.properties b/prison-core/src/main/resources/lang/core/hu_HU.properties index 8a7e65158..3527eb069 100644 --- a/prison-core/src/main/resources/lang/core/hu_HU.properties +++ b/prison-core/src/main/resources/lang/core/hu_HU.properties @@ -1,6 +1,6 @@ # # A Prison Minecraft plugin a börtön játékmódhoz. -# Copyright (C) 2017 The Prison Team +# Copyright (C) 2021 The Prison Team # # Ez a program szabad szoftver: eloszthatja és/vagy módosíthatja # a GNU Ãltalános Nyilvános Licenc feltételei szerint @@ -15,6 +15,81 @@ # Meg kellett volna kapnia egy példányt a GNU General Public License-bÅ‘l # ezzel a programmal együtt. Ha nem, nézze meg . # + +## +## Prison Supports Unicode (UTF-8) encoding in these properties files. BUt you must +## follow these instructions to ensure everything works properly. +## +## 1. You should only edit these files using a UTF-8 editor. On windows use NotePad, not WordPad. +## WordPad will save as plain text. To confirm the save was successful: save, close the editor, +## then reopen to confirm the encoding was preserved. +## +## 2. When running on Windows, you must enable utf-8 encoding in minecraft's console. Windows +## defaults to a characterpage 1252. To enable window's use of utf-8, you need to change the +## encoding prior to launching spigot/paper: +## chcp 65001 +## +## Full example of a windows script, which hooks for java debugging: +## rem Note: chcp 65001 enables utf-8 in windows, when normally windows uses characterpage 1252 +## chcp 65001 +## java -Dfile.encoding="UTF-8" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -Xms1g -Xmx4g -jar spigot-1.8.8.jar nogui --log-strip-color +## pause +## +## 3. When viewing the logs/latest.log files you must use an editor such as NotePad instead of WordPad. +## +## 4. Unicode is properly displayed in game, in console, in the logs, and with paste.helpch.at when using +## /prison support submit. +## + + +# NOTE: A messages__version is an arbitrary integer that will be manually incremented within Prison +# when there are changes to these messages. This value represents when message content is +# changed, fixed, or added to. This value may not be increased if the change is very small and +# insignificant, such as a space or a couple of letters. +# +# messages__auto_refresh=true indicates that this file will automatically be replaced if +# Prison detects a messages__version difference. The old file will be deleted (renamed) and +# a new copy will be placed in the directory to be used. If this value is set to false, then +# Prison will not refresh this file and there could be issues with the display of other messages. +# If auto refresh is set to false, we are not held responsible for possible issues that can +# arise from inaccurate messages. If set to false, then you are responsible for maintaining +# the messages on your own. +# +# If you make changes to this file, and you have messages__auto_refresh=false, then those +# changes will be replaced when this file is updated. Since the old file is renamed, and +# not deleted, you can manually merge your changes back in to the new update. The old +# renamed files will never be deleted by prison; you can remove them when you feel like it +# is safe to do so. +# +# Please consider helping Prison, and everyone else who may use Prison, by contributing all +# translations to other languages. They should be faithful translations, and not something +# for the sake of humor or changes just for cosmetic styling. If you have something you would +# like to share, please contact a staff member on our Discord server. +#Thanks for your contributions! +# +messages__version=1 +messages__auto_refresh=true + + +core_output__prefix_template=| %1 | &7 +core_output__prefix_template_prison=Prison +core_output__prefix_template_info=Info +core_output__prefix_template_warning=Warning +core_output__prefix_template_error=Error +core_output__prefix_template_debug=Debug + +core_output__color_code_info=&3 +core_output__color_code_warning=&c +core_output__color_code_error=&c +core_output__color_code_debug=&9 + +core_output__error_startup_failure=Prison: (Sending to System.err due to Output.log Logger failure): +core_output__error_incorrect_number_of_parameters=Log Failure (%1): Incorrect number of parameters: [%2] Original raw message: [%3] Arguments: %4 + + + +# The following are the original messages and they will eventually be replaced. + includeError=[%1] érvénytelen értékkel rendelkezik. excludeError=[%1] érvénytelen értékkel rendelkezik. cantAsConsole=Ezt nem teheted konzolként. diff --git a/prison-core/src/main/resources/lang/core/it_IT.properties b/prison-core/src/main/resources/lang/core/it_IT.properties index e49aae8cf..4fca5a899 100644 --- a/prison-core/src/main/resources/lang/core/it_IT.properties +++ b/prison-core/src/main/resources/lang/core/it_IT.properties @@ -1,6 +1,6 @@ # # Prison is a Minecraft plugin for the prison game mode. -# Copyright (C) 2017 The Prison Team +# Copyright (C) 2021 The Prison Team # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -15,6 +15,81 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . # + +## +## Prison Supports Unicode (UTF-8) encoding in these properties files. BUt you must +## follow these instructions to ensure everything works properly. +## +## 1. You should only edit these files using a UTF-8 editor. On windows use NotePad, not WordPad. +## WordPad will save as plain text. To confirm the save was successful: save, close the editor, +## then reopen to confirm the encoding was preserved. +## +## 2. When running on Windows, you must enable utf-8 encoding in minecraft's console. Windows +## defaults to a characterpage 1252. To enable window's use of utf-8, you need to change the +## encoding prior to launching spigot/paper: +## chcp 65001 +## +## Full example of a windows script, which hooks for java debugging: +## rem Note: chcp 65001 enables utf-8 in windows, when normally windows uses characterpage 1252 +## chcp 65001 +## java -Dfile.encoding="UTF-8" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -Xms1g -Xmx4g -jar spigot-1.8.8.jar nogui --log-strip-color +## pause +## +## 3. When viewing the logs/latest.log files you must use an editor such as NotePad instead of WordPad. +## +## 4. Unicode is properly displayed in game, in console, in the logs, and with paste.helpch.at when using +## /prison support submit. +## + + +# NOTE: A messages__version is an arbitrary integer that will be manually incremented within Prison +# when there are changes to these messages. This value represents when message content is +# changed, fixed, or added to. This value may not be increased if the change is very small and +# insignificant, such as a space or a couple of letters. +# +# messages__auto_refresh=true indicates that this file will automatically be replaced if +# Prison detects a messages__version difference. The old file will be deleted (renamed) and +# a new copy will be placed in the directory to be used. If this value is set to false, then +# Prison will not refresh this file and there could be issues with the display of other messages. +# If auto refresh is set to false, we are not held responsible for possible issues that can +# arise from inaccurate messages. If set to false, then you are responsible for maintaining +# the messages on your own. +# +# If you make changes to this file, and you have messages__auto_refresh=false, then those +# changes will be replaced when this file is updated. Since the old file is renamed, and +# not deleted, you can manually merge your changes back in to the new update. The old +# renamed files will never be deleted by prison; you can remove them when you feel like it +# is safe to do so. +# +# Please consider helping Prison, and everyone else who may use Prison, by contributing all +# translations to other languages. They should be faithful translations, and not something +# for the sake of humor or changes just for cosmetic styling. If you have something you would +# like to share, please contact a staff member on our Discord server. +#Thanks for your contributions! +# +messages__version=1 +messages__auto_refresh=true + + +core_output__prefix_template=| %1 | &7 +core_output__prefix_template_prison=Prison +core_output__prefix_template_info=Info +core_output__prefix_template_warning=Warning +core_output__prefix_template_error=Error +core_output__prefix_template_debug=Debug + +core_output__color_code_info=&3 +core_output__color_code_warning=&c +core_output__color_code_error=&c +core_output__color_code_debug=&9 + +core_output__error_startup_failure=Prison: (Sending to System.err due to Output.log Logger failure): +core_output__error_incorrect_number_of_parameters=Log Failure (%1): Incorrect number of parameters: [%2] Original raw message: [%3] Arguments: %4 + + + +# The following are the original messages and they will eventually be replaced. + includeError=[%1] Ha un valore invalido. excludeError=[%1] Ha un valore invalido. cantAsConsole=Non puoi fare questo dalla console. diff --git a/prison-core/src/main/resources/lang/core/nl_BE.properties b/prison-core/src/main/resources/lang/core/nl_BE.properties index b146b393d..db095934e 100644 --- a/prison-core/src/main/resources/lang/core/nl_BE.properties +++ b/prison-core/src/main/resources/lang/core/nl_BE.properties @@ -1,6 +1,6 @@ # # Prison is een minecraft plugin voor het gevangenis spel -# Copyright (C) 2017 The Prison Team +# Copyright (C) 2021 The Prison Team # # Dit programa is gratis software: Je kan het doorgeven en/of aanpassen # onder de termen van de GNU General Public License die het heeft @@ -15,6 +15,81 @@ # Je zou een copy hebben moeten ontvangen van het GNU General Public License # samen met dit programa. Zo niet, zie . # + +## +## Prison Supports Unicode (UTF-8) encoding in these properties files. BUt you must +## follow these instructions to ensure everything works properly. +## +## 1. You should only edit these files using a UTF-8 editor. On windows use NotePad, not WordPad. +## WordPad will save as plain text. To confirm the save was successful: save, close the editor, +## then reopen to confirm the encoding was preserved. +## +## 2. When running on Windows, you must enable utf-8 encoding in minecraft's console. Windows +## defaults to a characterpage 1252. To enable window's use of utf-8, you need to change the +## encoding prior to launching spigot/paper: +## chcp 65001 +## +## Full example of a windows script, which hooks for java debugging: +## rem Note: chcp 65001 enables utf-8 in windows, when normally windows uses characterpage 1252 +## chcp 65001 +## java -Dfile.encoding="UTF-8" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -Xms1g -Xmx4g -jar spigot-1.8.8.jar nogui --log-strip-color +## pause +## +## 3. When viewing the logs/latest.log files you must use an editor such as NotePad instead of WordPad. +## +## 4. Unicode is properly displayed in game, in console, in the logs, and with paste.helpch.at when using +## /prison support submit. +## + + +# NOTE: A messages__version is an arbitrary integer that will be manually incremented within Prison +# when there are changes to these messages. This value represents when message content is +# changed, fixed, or added to. This value may not be increased if the change is very small and +# insignificant, such as a space or a couple of letters. +# +# messages__auto_refresh=true indicates that this file will automatically be replaced if +# Prison detects a messages__version difference. The old file will be deleted (renamed) and +# a new copy will be placed in the directory to be used. If this value is set to false, then +# Prison will not refresh this file and there could be issues with the display of other messages. +# If auto refresh is set to false, we are not held responsible for possible issues that can +# arise from inaccurate messages. If set to false, then you are responsible for maintaining +# the messages on your own. +# +# If you make changes to this file, and you have messages__auto_refresh=false, then those +# changes will be replaced when this file is updated. Since the old file is renamed, and +# not deleted, you can manually merge your changes back in to the new update. The old +# renamed files will never be deleted by prison; you can remove them when you feel like it +# is safe to do so. +# +# Please consider helping Prison, and everyone else who may use Prison, by contributing all +# translations to other languages. They should be faithful translations, and not something +# for the sake of humor or changes just for cosmetic styling. If you have something you would +# like to share, please contact a staff member on our Discord server. +#Thanks for your contributions! +# +messages__version=1 +messages__auto_refresh=true + + +core_output__prefix_template=| %1 | &7 +core_output__prefix_template_prison=Prison +core_output__prefix_template_info=Info +core_output__prefix_template_warning=Warning +core_output__prefix_template_error=Error +core_output__prefix_template_debug=Debug + +core_output__color_code_info=&3 +core_output__color_code_warning=&c +core_output__color_code_error=&c +core_output__color_code_debug=&9 + +core_output__error_startup_failure=Prison: (Sending to System.err due to Output.log Logger failure): +core_output__error_incorrect_number_of_parameters=Log Failure (%1): Incorrect number of parameters: [%2] Original raw message: [%3] Arguments: %4 + + + +# The following are the original messages and they will eventually be replaced. + includeError=[%1] heeft een onjuiste waarde. excludeError=[%1] heeft een onjuiste waarde. cantAsConsole=Dit kan je niet als console. diff --git a/prison-core/src/main/resources/lang/core/nl_NL.properties b/prison-core/src/main/resources/lang/core/nl_NL.properties index b146b393d..db095934e 100644 --- a/prison-core/src/main/resources/lang/core/nl_NL.properties +++ b/prison-core/src/main/resources/lang/core/nl_NL.properties @@ -1,6 +1,6 @@ # # Prison is een minecraft plugin voor het gevangenis spel -# Copyright (C) 2017 The Prison Team +# Copyright (C) 2021 The Prison Team # # Dit programa is gratis software: Je kan het doorgeven en/of aanpassen # onder de termen van de GNU General Public License die het heeft @@ -15,6 +15,81 @@ # Je zou een copy hebben moeten ontvangen van het GNU General Public License # samen met dit programa. Zo niet, zie . # + +## +## Prison Supports Unicode (UTF-8) encoding in these properties files. BUt you must +## follow these instructions to ensure everything works properly. +## +## 1. You should only edit these files using a UTF-8 editor. On windows use NotePad, not WordPad. +## WordPad will save as plain text. To confirm the save was successful: save, close the editor, +## then reopen to confirm the encoding was preserved. +## +## 2. When running on Windows, you must enable utf-8 encoding in minecraft's console. Windows +## defaults to a characterpage 1252. To enable window's use of utf-8, you need to change the +## encoding prior to launching spigot/paper: +## chcp 65001 +## +## Full example of a windows script, which hooks for java debugging: +## rem Note: chcp 65001 enables utf-8 in windows, when normally windows uses characterpage 1252 +## chcp 65001 +## java -Dfile.encoding="UTF-8" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -Xms1g -Xmx4g -jar spigot-1.8.8.jar nogui --log-strip-color +## pause +## +## 3. When viewing the logs/latest.log files you must use an editor such as NotePad instead of WordPad. +## +## 4. Unicode is properly displayed in game, in console, in the logs, and with paste.helpch.at when using +## /prison support submit. +## + + +# NOTE: A messages__version is an arbitrary integer that will be manually incremented within Prison +# when there are changes to these messages. This value represents when message content is +# changed, fixed, or added to. This value may not be increased if the change is very small and +# insignificant, such as a space or a couple of letters. +# +# messages__auto_refresh=true indicates that this file will automatically be replaced if +# Prison detects a messages__version difference. The old file will be deleted (renamed) and +# a new copy will be placed in the directory to be used. If this value is set to false, then +# Prison will not refresh this file and there could be issues with the display of other messages. +# If auto refresh is set to false, we are not held responsible for possible issues that can +# arise from inaccurate messages. If set to false, then you are responsible for maintaining +# the messages on your own. +# +# If you make changes to this file, and you have messages__auto_refresh=false, then those +# changes will be replaced when this file is updated. Since the old file is renamed, and +# not deleted, you can manually merge your changes back in to the new update. The old +# renamed files will never be deleted by prison; you can remove them when you feel like it +# is safe to do so. +# +# Please consider helping Prison, and everyone else who may use Prison, by contributing all +# translations to other languages. They should be faithful translations, and not something +# for the sake of humor or changes just for cosmetic styling. If you have something you would +# like to share, please contact a staff member on our Discord server. +#Thanks for your contributions! +# +messages__version=1 +messages__auto_refresh=true + + +core_output__prefix_template=| %1 | &7 +core_output__prefix_template_prison=Prison +core_output__prefix_template_info=Info +core_output__prefix_template_warning=Warning +core_output__prefix_template_error=Error +core_output__prefix_template_debug=Debug + +core_output__color_code_info=&3 +core_output__color_code_warning=&c +core_output__color_code_error=&c +core_output__color_code_debug=&9 + +core_output__error_startup_failure=Prison: (Sending to System.err due to Output.log Logger failure): +core_output__error_incorrect_number_of_parameters=Log Failure (%1): Incorrect number of parameters: [%2] Original raw message: [%3] Arguments: %4 + + + +# The following are the original messages and they will eventually be replaced. + includeError=[%1] heeft een onjuiste waarde. excludeError=[%1] heeft een onjuiste waarde. cantAsConsole=Dit kan je niet als console. diff --git a/prison-core/src/main/resources/lang/core/zh_TW.properties b/prison-core/src/main/resources/lang/core/zh_TW.properties new file mode 100644 index 000000000..4256a8016 --- /dev/null +++ b/prison-core/src/main/resources/lang/core/zh_TW.properties @@ -0,0 +1,90 @@ +# +# Prison is a Minecraft plugin for the prison game mode. +# Copyright (C) 2021 The Prison Team +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +## +## Prison Supports Unicode (UTF-8) encoding in these properties files. BUt you must +## follow these instructions to ensure everything works properly. +## +## 1. You should only edit these files using a UTF-8 editor. On windows use NotePad, not WordPad. +## WordPad will save as plain text. To confirm the save was successful: save, close the editor, +## then reopen to confirm the encoding was preserved. +## +## 2. When running on Windows, you must enable utf-8 encoding in minecraft's console. Windows +## defaults to a characterpage 1252. To enable window's use of utf-8, you need to change the +## encoding prior to launching spigot/paper: +## chcp 65001 +## +## Full example of a windows script, which hooks for java debugging: +## rem Note: chcp 65001 enables utf-8 in windows, when normally windows uses characterpage 1252 +## chcp 65001 +## java -Dfile.encoding="UTF-8" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -Xms1g -Xmx4g -jar spigot-1.8.8.jar nogui --log-strip-color +## pause +## +## 3. When viewing the logs/latest.log files you must use an editor such as NotePad instead of WordPad. +## +## 4. Unicode is properly displayed in game, in console, in the logs, and with paste.helpch.at when using +## /prison support submit. +## + + +# NOTE: A messages__version is an arbitrary integer that will be manually incremented within Prison +# when there are changes to these messages. This value represents when message content is +# changed, fixed, or added to. This value may not be increased if the change is very small and +# insignificant, such as a space or a couple of letters. +# +# messages__auto_refresh=true indicates that this file will automatically be replaced if +# Prison detects a messages__version difference. The old file will be deleted (renamed) and +# a new copy will be placed in the directory to be used. If this value is set to false, then +# Prison will not refresh this file and there could be issues with the display of other messages. +# If auto refresh is set to false, we are not held responsible for possible issues that can +# arise from inaccurate messages. If set to false, then you are responsible for maintaining +# the messages on your own. +# +# If you make changes to this file, and you have messages__auto_refresh=false, then those +# changes will be replaced when this file is updated. Since the old file is renamed, and +# not deleted, you can manually merge your changes back in to the new update. The old +# renamed files will never be deleted by prison; you can remove them when you feel like it +# is safe to do so. +# +# Please consider helping Prison, and everyone else who may use Prison, by contributing all +# translations to other languages. They should be faithful translations, and not something +# for the sake of humor or changes just for cosmetic styling. If you have something you would +# like to share, please contact a staff member on our Discord server. +#Thanks for your contributions! +# +messages__version=1 +messages__auto_refresh=true + + +includeError=[%1] 有一個無效值 +excludeError=[%1] 有一個無效值 +cantAsConsole=您ä¸èƒ½ä½œç‚ºæŽ§åˆ¶å°åŸ·è¡Œæ­¤æ“作 +missingArgument=爭議 [%1] 沒有定義 (它沒有默èªå€¼) +missingFlagArgument=標誌 -%1 沒有所需的åƒæ•¸ +undefinedFlagArgument=爭論 [%1] 到標誌 -%2 沒有定義 +internalErrorOccurred=嘗試執行此命令時發生內部錯誤 +noPermission=ä½ ç¼ºå°‘åŸ·è¡Œæ­¤å‘½ä»¤æ‰€éœ€çš„æ¬Šé™ +blockParseError=åƒæ•¸ [%1] ä¸æ˜¯æœ‰æ•ˆå€å¡Š +numberParseError=åƒæ•¸ [%1] ä¸æ˜¯ä¸€å€‹æ•¸å­— +numberTooLow=åƒæ•¸ [%1] 必須等於或大於 %2 +numberTooHigh=åƒæ•¸ [%1] 必須等於或å°æ–¼ %2 +numberRangeError=åƒæ•¸ [%1] 必須等於或大於 %2 並且å°æ–¼æˆ–等於 %3 +tooFewCharacters=åƒæ•¸ [%1] 必須等於或大於 %2 人物 +tooManyCharacters=åƒæ•¸ [%1] 必須等於或å°æ–¼ %2 人物 +playerNotOnline=玩家 %1 並未線上 +worldNotFound=世界 %1 無法找到 diff --git a/prison-core/src/main/resources/lang/mines/de_DE.properties b/prison-core/src/main/resources/lang/mines/de_DE.properties index 0a537d40c..03c93341b 100644 --- a/prison-core/src/main/resources/lang/mines/de_DE.properties +++ b/prison-core/src/main/resources/lang/mines/de_DE.properties @@ -1,3 +1,63 @@ +# NOTE: A messages__version is an arbitrary integer that will be manually incremented within Prison +# when there are changes to these messages. This value represents when message content is +# changed, fixed, or added to. This value may not be increased if the change is very small and +# insignificant, such as a space or a couple of letters. +# +# messages__auto_refresh=true indicates that this file will automatically be replaced if +# Prison detects a messages__version difference. The old file will be deleted (renamed) and +# a new copy will be placed in the directory to be used. If this value is set to false, then +# Prison will not refresh this file and there could be issues with the display of other messages. +# If auto refresh is set to false, we are not held responsible for possible issues that can +# arise from inaccurate messages. If set to false, then you are responsible for maintaining +# the messages on your own. +# +# If you make changes to this file, and you have messages__auto_refresh=false, then those +# changes will be replaced when this file is updated. Since the old file is renamed, and +# not deleted, you can manually merge your changes back in to the new update. The old +# renamed files will never be deleted by prison; you can remove them when you feel like it +# is safe to do so. +# +# Please consider helping Prison, and everyone else who may use Prison, by contributing all +# translations to other languages. They should be faithful translations, and not something +# for the sake of humor or changes just for cosmetic styling. If you have something you would +# like to share, please contact a staff member on our Discord server. +#Thanks for your contributions! +# + +## +## Prison Supports Unicode (UTF-8) encoding in these properties files. BUt you must +## follow these instructions to ensure everything works properly. +## +## 1. You should only edit these files using a UTF-8 editor. On windows use NotePad, not WordPad. +## WordPad will save as plain text. To confirm the save was successful: save, close the editor, +## then reopen to confirm the encoding was preserved. +## +## 2. When running on Windows, you must enable utf-8 encoding in minecraft's console. Windows +## defaults to a characterpage 1252. To enable window's use of utf-8, you need to change the +## encoding prior to launching spigot/paper: +## chcp 65001 +## +## Full example of a windows script, which hooks for java debugging: +## rem Note: chcp 65001 enables utf-8 in windows, when normally windows uses characterpage 1252 +## chcp 65001 +## java -Dfile.encoding="UTF-8" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -Xms1g -Xmx4g -jar spigot-1.8.8.jar nogui --log-strip-color +## pause +## +## 3. When viewing the logs/latest.log files you must use an editor such as NotePad instead of WordPad. +## +## 4. Unicode is properly displayed in game, in console, in the logs, and with paste.helpch.at when using +## /prison support submit. +## + + + +messages__version=1 +messages__auto_refresh=true + + + +# The following are the original messages and they will eventually be replaced. + reset_warning=&7Alle Minen %1 wurden zurückgesetzt in &3%2&7. reset_message=&7Alle Minen %1 wurden zurückgesetzt. not_allowed=&7Hier darfst du nicht verminen. diff --git a/prison-core/src/main/resources/lang/mines/en_US.properties b/prison-core/src/main/resources/lang/mines/en_US.properties index 14ccbcc4c..9f298827b 100644 --- a/prison-core/src/main/resources/lang/mines/en_US.properties +++ b/prison-core/src/main/resources/lang/mines/en_US.properties @@ -1,3 +1,63 @@ +# NOTE: A messages__version is an arbitrary integer that will be manually incremented within Prison +# when there are changes to these messages. This value represents when message content is +# changed, fixed, or added to. This value may not be increased if the change is very small and +# insignificant, such as a space or a couple of letters. +# +# messages__auto_refresh=true indicates that this file will automatically be replaced if +# Prison detects a messages__version difference. The old file will be deleted (renamed) and +# a new copy will be placed in the directory to be used. If this value is set to false, then +# Prison will not refresh this file and there could be issues with the display of other messages. +# If auto refresh is set to false, we are not held responsible for possible issues that can +# arise from inaccurate messages. If set to false, then you are responsible for maintaining +# the messages on your own. +# +# If you make changes to this file, and you have messages__auto_refresh=false, then those +# changes will be replaced when this file is updated. Since the old file is renamed, and +# not deleted, you can manually merge your changes back in to the new update. The old +# renamed files will never be deleted by prison; you can remove them when you feel like it +# is safe to do so. +# +# Please consider helping Prison, and everyone else who may use Prison, by contributing all +# translations to other languages. They should be faithful translations, and not something +# for the sake of humor or changes just for cosmetic styling. If you have something you would +# like to share, please contact a staff member on our Discord server. +#Thanks for your contributions! +# + +## +## Prison Supports Unicode (UTF-8) encoding in these properties files. BUt you must +## follow these instructions to ensure everything works properly. +## +## 1. You should only edit these files using a UTF-8 editor. On windows use NotePad, not WordPad. +## WordPad will save as plain text. To confirm the save was successful: save, close the editor, +## then reopen to confirm the encoding was preserved. +## +## 2. When running on Windows, you must enable utf-8 encoding in minecraft's console. Windows +## defaults to a characterpage 1252. To enable window's use of utf-8, you need to change the +## encoding prior to launching spigot/paper: +## chcp 65001 +## +## Full example of a windows script, which hooks for java debugging: +## rem Note: chcp 65001 enables utf-8 in windows, when normally windows uses characterpage 1252 +## chcp 65001 +## java -Dfile.encoding="UTF-8" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -Xms1g -Xmx4g -jar spigot-1.8.8.jar nogui --log-strip-color +## pause +## +## 3. When viewing the logs/latest.log files you must use an editor such as NotePad instead of WordPad. +## +## 4. Unicode is properly displayed in game, in console, in the logs, and with paste.helpch.at when using +## /prison support submit. +## + + + +messages__version=1 +messages__auto_refresh=true + + + +# The following are the original messages and they will eventually be replaced. + reset_warning=&7Mine %1 will reset in &3%2&7. reset_message=&7The mine %1 has been reset. not_allowed=&7You are not allowed to mine here. diff --git a/prison-core/src/main/resources/lang/mines/es_ES.properties b/prison-core/src/main/resources/lang/mines/es_ES.properties index 2dc813912..015de3856 100644 --- a/prison-core/src/main/resources/lang/mines/es_ES.properties +++ b/prison-core/src/main/resources/lang/mines/es_ES.properties @@ -1,3 +1,63 @@ +# NOTE: A messages__version is an arbitrary integer that will be manually incremented within Prison +# when there are changes to these messages. This value represents when message content is +# changed, fixed, or added to. This value may not be increased if the change is very small and +# insignificant, such as a space or a couple of letters. +# +# messages__auto_refresh=true indicates that this file will automatically be replaced if +# Prison detects a messages__version difference. The old file will be deleted (renamed) and +# a new copy will be placed in the directory to be used. If this value is set to false, then +# Prison will not refresh this file and there could be issues with the display of other messages. +# If auto refresh is set to false, we are not held responsible for possible issues that can +# arise from inaccurate messages. If set to false, then you are responsible for maintaining +# the messages on your own. +# +# If you make changes to this file, and you have messages__auto_refresh=false, then those +# changes will be replaced when this file is updated. Since the old file is renamed, and +# not deleted, you can manually merge your changes back in to the new update. The old +# renamed files will never be deleted by prison; you can remove them when you feel like it +# is safe to do so. +# +# Please consider helping Prison, and everyone else who may use Prison, by contributing all +# translations to other languages. They should be faithful translations, and not something +# for the sake of humor or changes just for cosmetic styling. If you have something you would +# like to share, please contact a staff member on our Discord server. +#Thanks for your contributions! +# + +## +## Prison Supports Unicode (UTF-8) encoding in these properties files. BUt you must +## follow these instructions to ensure everything works properly. +## +## 1. You should only edit these files using a UTF-8 editor. On windows use NotePad, not WordPad. +## WordPad will save as plain text. To confirm the save was successful: save, close the editor, +## then reopen to confirm the encoding was preserved. +## +## 2. When running on Windows, you must enable utf-8 encoding in minecraft's console. Windows +## defaults to a characterpage 1252. To enable window's use of utf-8, you need to change the +## encoding prior to launching spigot/paper: +## chcp 65001 +## +## Full example of a windows script, which hooks for java debugging: +## rem Note: chcp 65001 enables utf-8 in windows, when normally windows uses characterpage 1252 +## chcp 65001 +## java -Dfile.encoding="UTF-8" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -Xms1g -Xmx4g -jar spigot-1.8.8.jar nogui --log-strip-color +## pause +## +## 3. When viewing the logs/latest.log files you must use an editor such as NotePad instead of WordPad. +## +## 4. Unicode is properly displayed in game, in console, in the logs, and with paste.helpch.at when using +## /prison support submit. +## + + + +messages__version=1 +messages__auto_refresh=true + + + +# The following are the original messages and they will eventually be replaced. + reset_warning=&7Todas las minas %1 se reiniciarán en &3%2&7. reset_message=&7Todas las minas %1 han sido reiniciadas. not_allowed=&7No tienes permitido minar aquí. diff --git a/prison-core/src/main/resources/lang/mines/hu_HU.properties b/prison-core/src/main/resources/lang/mines/hu_HU.properties index ea5eb56f2..45893d91d 100644 --- a/prison-core/src/main/resources/lang/mines/hu_HU.properties +++ b/prison-core/src/main/resources/lang/mines/hu_HU.properties @@ -1,3 +1,63 @@ +# NOTE: A messages__version is an arbitrary integer that will be manually incremented within Prison +# when there are changes to these messages. This value represents when message content is +# changed, fixed, or added to. This value may not be increased if the change is very small and +# insignificant, such as a space or a couple of letters. +# +# messages__auto_refresh=true indicates that this file will automatically be replaced if +# Prison detects a messages__version difference. The old file will be deleted (renamed) and +# a new copy will be placed in the directory to be used. If this value is set to false, then +# Prison will not refresh this file and there could be issues with the display of other messages. +# If auto refresh is set to false, we are not held responsible for possible issues that can +# arise from inaccurate messages. If set to false, then you are responsible for maintaining +# the messages on your own. +# +# If you make changes to this file, and you have messages__auto_refresh=false, then those +# changes will be replaced when this file is updated. Since the old file is renamed, and +# not deleted, you can manually merge your changes back in to the new update. The old +# renamed files will never be deleted by prison; you can remove them when you feel like it +# is safe to do so. +# +# Please consider helping Prison, and everyone else who may use Prison, by contributing all +# translations to other languages. They should be faithful translations, and not something +# for the sake of humor or changes just for cosmetic styling. If you have something you would +# like to share, please contact a staff member on our Discord server. +#Thanks for your contributions! +# + +## +## Prison Supports Unicode (UTF-8) encoding in these properties files. BUt you must +## follow these instructions to ensure everything works properly. +## +## 1. You should only edit these files using a UTF-8 editor. On windows use NotePad, not WordPad. +## WordPad will save as plain text. To confirm the save was successful: save, close the editor, +## then reopen to confirm the encoding was preserved. +## +## 2. When running on Windows, you must enable utf-8 encoding in minecraft's console. Windows +## defaults to a characterpage 1252. To enable window's use of utf-8, you need to change the +## encoding prior to launching spigot/paper: +## chcp 65001 +## +## Full example of a windows script, which hooks for java debugging: +## rem Note: chcp 65001 enables utf-8 in windows, when normally windows uses characterpage 1252 +## chcp 65001 +## java -Dfile.encoding="UTF-8" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -Xms1g -Xmx4g -jar spigot-1.8.8.jar nogui --log-strip-color +## pause +## +## 3. When viewing the logs/latest.log files you must use an editor such as NotePad instead of WordPad. +## +## 4. Unicode is properly displayed in game, in console, in the logs, and with paste.helpch.at when using +## /prison support submit. +## + + + +messages__version=1 +messages__auto_refresh=true + + + +# The following are the original messages and they will eventually be replaced. + reset_warning=&7Minden %1 bánya újratöltve &3%2&7. reset_message=&7Az összes %1 bánya vissza lett állítva. not_allowed=&7A bányászás nem megengedett. diff --git a/prison-core/src/main/resources/lang/mines/it_IT.properties b/prison-core/src/main/resources/lang/mines/it_IT.properties index a5c964e2d..9b4359aa1 100644 --- a/prison-core/src/main/resources/lang/mines/it_IT.properties +++ b/prison-core/src/main/resources/lang/mines/it_IT.properties @@ -1,3 +1,63 @@ +# NOTE: A messages__version is an arbitrary integer that will be manually incremented within Prison +# when there are changes to these messages. This value represents when message content is +# changed, fixed, or added to. This value may not be increased if the change is very small and +# insignificant, such as a space or a couple of letters. +# +# messages__auto_refresh=true indicates that this file will automatically be replaced if +# Prison detects a messages__version difference. The old file will be deleted (renamed) and +# a new copy will be placed in the directory to be used. If this value is set to false, then +# Prison will not refresh this file and there could be issues with the display of other messages. +# If auto refresh is set to false, we are not held responsible for possible issues that can +# arise from inaccurate messages. If set to false, then you are responsible for maintaining +# the messages on your own. +# +# If you make changes to this file, and you have messages__auto_refresh=false, then those +# changes will be replaced when this file is updated. Since the old file is renamed, and +# not deleted, you can manually merge your changes back in to the new update. The old +# renamed files will never be deleted by prison; you can remove them when you feel like it +# is safe to do so. +# +# Please consider helping Prison, and everyone else who may use Prison, by contributing all +# translations to other languages. They should be faithful translations, and not something +# for the sake of humor or changes just for cosmetic styling. If you have something you would +# like to share, please contact a staff member on our Discord server. +#Thanks for your contributions! +# + +## +## Prison Supports Unicode (UTF-8) encoding in these properties files. BUt you must +## follow these instructions to ensure everything works properly. +## +## 1. You should only edit these files using a UTF-8 editor. On windows use NotePad, not WordPad. +## WordPad will save as plain text. To confirm the save was successful: save, close the editor, +## then reopen to confirm the encoding was preserved. +## +## 2. When running on Windows, you must enable utf-8 encoding in minecraft's console. Windows +## defaults to a characterpage 1252. To enable window's use of utf-8, you need to change the +## encoding prior to launching spigot/paper: +## chcp 65001 +## +## Full example of a windows script, which hooks for java debugging: +## rem Note: chcp 65001 enables utf-8 in windows, when normally windows uses characterpage 1252 +## chcp 65001 +## java -Dfile.encoding="UTF-8" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -Xms1g -Xmx4g -jar spigot-1.8.8.jar nogui --log-strip-color +## pause +## +## 3. When viewing the logs/latest.log files you must use an editor such as NotePad instead of WordPad. +## +## 4. Unicode is properly displayed in game, in console, in the logs, and with paste.helpch.at when using +## /prison support submit. +## + + + +messages__version=1 +messages__auto_refresh=true + + + +# The following are the original messages and they will eventually be replaced. + reset_warning=&7Tutte le miniere %1 stanno per essere resettate tra &3%2&7. reset_message=&7Tutte le miniere %1 sono state resettate. not_allowed=&7Non sei ammesso a scvare qua. diff --git a/prison-core/src/main/resources/lang/mines/nl_BE.properties b/prison-core/src/main/resources/lang/mines/nl_BE.properties index c165f1e2e..ed01bbabf 100644 --- a/prison-core/src/main/resources/lang/mines/nl_BE.properties +++ b/prison-core/src/main/resources/lang/mines/nl_BE.properties @@ -1,3 +1,63 @@ +# NOTE: A messages__version is an arbitrary integer that will be manually incremented within Prison +# when there are changes to these messages. This value represents when message content is +# changed, fixed, or added to. This value may not be increased if the change is very small and +# insignificant, such as a space or a couple of letters. +# +# messages__auto_refresh=true indicates that this file will automatically be replaced if +# Prison detects a messages__version difference. The old file will be deleted (renamed) and +# a new copy will be placed in the directory to be used. If this value is set to false, then +# Prison will not refresh this file and there could be issues with the display of other messages. +# If auto refresh is set to false, we are not held responsible for possible issues that can +# arise from inaccurate messages. If set to false, then you are responsible for maintaining +# the messages on your own. +# +# If you make changes to this file, and you have messages__auto_refresh=false, then those +# changes will be replaced when this file is updated. Since the old file is renamed, and +# not deleted, you can manually merge your changes back in to the new update. The old +# renamed files will never be deleted by prison; you can remove them when you feel like it +# is safe to do so. +# +# Please consider helping Prison, and everyone else who may use Prison, by contributing all +# translations to other languages. They should be faithful translations, and not something +# for the sake of humor or changes just for cosmetic styling. If you have something you would +# like to share, please contact a staff member on our Discord server. +#Thanks for your contributions! +# + +## +## Prison Supports Unicode (UTF-8) encoding in these properties files. BUt you must +## follow these instructions to ensure everything works properly. +## +## 1. You should only edit these files using a UTF-8 editor. On windows use NotePad, not WordPad. +## WordPad will save as plain text. To confirm the save was successful: save, close the editor, +## then reopen to confirm the encoding was preserved. +## +## 2. When running on Windows, you must enable utf-8 encoding in minecraft's console. Windows +## defaults to a characterpage 1252. To enable window's use of utf-8, you need to change the +## encoding prior to launching spigot/paper: +## chcp 65001 +## +## Full example of a windows script, which hooks for java debugging: +## rem Note: chcp 65001 enables utf-8 in windows, when normally windows uses characterpage 1252 +## chcp 65001 +## java -Dfile.encoding="UTF-8" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -Xms1g -Xmx4g -jar spigot-1.8.8.jar nogui --log-strip-color +## pause +## +## 3. When viewing the logs/latest.log files you must use an editor such as NotePad instead of WordPad. +## +## 4. Unicode is properly displayed in game, in console, in the logs, and with paste.helpch.at when using +## /prison support submit. +## + + + +messages__version=1 +messages__auto_refresh=true + + + +# The following are the original messages and they will eventually be replaced. + reset_warning=&Alle mijnen %1 worden hersteld in &3%2&7. reset_message=&7Alle mijnen %1 zijn hersteld. not_allowed=&7Je mag hier niet mijnen. diff --git a/prison-core/src/main/resources/lang/mines/nl_NL.properties b/prison-core/src/main/resources/lang/mines/nl_NL.properties index c165f1e2e..ed01bbabf 100644 --- a/prison-core/src/main/resources/lang/mines/nl_NL.properties +++ b/prison-core/src/main/resources/lang/mines/nl_NL.properties @@ -1,3 +1,63 @@ +# NOTE: A messages__version is an arbitrary integer that will be manually incremented within Prison +# when there are changes to these messages. This value represents when message content is +# changed, fixed, or added to. This value may not be increased if the change is very small and +# insignificant, such as a space or a couple of letters. +# +# messages__auto_refresh=true indicates that this file will automatically be replaced if +# Prison detects a messages__version difference. The old file will be deleted (renamed) and +# a new copy will be placed in the directory to be used. If this value is set to false, then +# Prison will not refresh this file and there could be issues with the display of other messages. +# If auto refresh is set to false, we are not held responsible for possible issues that can +# arise from inaccurate messages. If set to false, then you are responsible for maintaining +# the messages on your own. +# +# If you make changes to this file, and you have messages__auto_refresh=false, then those +# changes will be replaced when this file is updated. Since the old file is renamed, and +# not deleted, you can manually merge your changes back in to the new update. The old +# renamed files will never be deleted by prison; you can remove them when you feel like it +# is safe to do so. +# +# Please consider helping Prison, and everyone else who may use Prison, by contributing all +# translations to other languages. They should be faithful translations, and not something +# for the sake of humor or changes just for cosmetic styling. If you have something you would +# like to share, please contact a staff member on our Discord server. +#Thanks for your contributions! +# + +## +## Prison Supports Unicode (UTF-8) encoding in these properties files. BUt you must +## follow these instructions to ensure everything works properly. +## +## 1. You should only edit these files using a UTF-8 editor. On windows use NotePad, not WordPad. +## WordPad will save as plain text. To confirm the save was successful: save, close the editor, +## then reopen to confirm the encoding was preserved. +## +## 2. When running on Windows, you must enable utf-8 encoding in minecraft's console. Windows +## defaults to a characterpage 1252. To enable window's use of utf-8, you need to change the +## encoding prior to launching spigot/paper: +## chcp 65001 +## +## Full example of a windows script, which hooks for java debugging: +## rem Note: chcp 65001 enables utf-8 in windows, when normally windows uses characterpage 1252 +## chcp 65001 +## java -Dfile.encoding="UTF-8" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -Xms1g -Xmx4g -jar spigot-1.8.8.jar nogui --log-strip-color +## pause +## +## 3. When viewing the logs/latest.log files you must use an editor such as NotePad instead of WordPad. +## +## 4. Unicode is properly displayed in game, in console, in the logs, and with paste.helpch.at when using +## /prison support submit. +## + + + +messages__version=1 +messages__auto_refresh=true + + + +# The following are the original messages and they will eventually be replaced. + reset_warning=&Alle mijnen %1 worden hersteld in &3%2&7. reset_message=&7Alle mijnen %1 zijn hersteld. not_allowed=&7Je mag hier niet mijnen. diff --git a/prison-core/src/main/resources/lang/mines/zh_TW.properties b/prison-core/src/main/resources/lang/mines/zh_TW.properties new file mode 100644 index 000000000..1a521c308 --- /dev/null +++ b/prison-core/src/main/resources/lang/mines/zh_TW.properties @@ -0,0 +1,90 @@ +# NOTE: A messages__version is an arbitrary integer that will be manually incremented within Prison +# when there are changes to these messages. This value represents when message content is +# changed, fixed, or added to. This value may not be increased if the change is very small and +# insignificant, such as a space or a couple of letters. +# +# messages__auto_refresh=true indicates that this file will automatically be replaced if +# Prison detects a messages__version difference. The old file will be deleted (renamed) and +# a new copy will be placed in the directory to be used. If this value is set to false, then +# Prison will not refresh this file and there could be issues with the display of other messages. +# If auto refresh is set to false, we are not held responsible for possible issues that can +# arise from inaccurate messages. If set to false, then you are responsible for maintaining +# the messages on your own. +# +# If you make changes to this file, and you have messages__auto_refresh=false, then those +# changes will be replaced when this file is updated. Since the old file is renamed, and +# not deleted, you can manually merge your changes back in to the new update. The old +# renamed files will never be deleted by prison; you can remove them when you feel like it +# is safe to do so. +# +# Please consider helping Prison, and everyone else who may use Prison, by contributing all +# translations to other languages. They should be faithful translations, and not something +# for the sake of humor or changes just for cosmetic styling. If you have something you would +# like to share, please contact a staff member on our Discord server. +#Thanks for your contributions! +# + +## +## Prison Supports Unicode (UTF-8) encoding in these properties files. BUt you must +## follow these instructions to ensure everything works properly. +## +## 1. You should only edit these files using a UTF-8 editor. On windows use NotePad, not WordPad. +## WordPad will save as plain text. To confirm the save was successful: save, close the editor, +## then reopen to confirm the encoding was preserved. +## +## 2. When running on Windows, you must enable utf-8 encoding in minecraft's console. Windows +## defaults to a characterpage 1252. To enable window's use of utf-8, you need to change the +## encoding prior to launching spigot/paper: +## chcp 65001 +## +## Full example of a windows script, which hooks for java debugging: +## rem Note: chcp 65001 enables utf-8 in windows, when normally windows uses characterpage 1252 +## chcp 65001 +## java -Dfile.encoding="UTF-8" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -Xms1g -Xmx4g -jar spigot-1.8.8.jar nogui --log-strip-color +## pause +## +## 3. When viewing the logs/latest.log files you must use an editor such as NotePad instead of WordPad. +## +## 4. Unicode is properly displayed in game, in console, in the logs, and with paste.helpch.at when using +## /prison support submit. +## + + + +messages__version=2 +messages__auto_refresh=true + + + +# The following are the original messages and they will eventually be replaced. + +reset_warning=&7礦場 %1 將在 &3%2&7 分é˜å¾Œé‡ç½® +reset_message=&7礦場 %1 已經é‡ç½® +not_allowed=&7您沒有權é™åœ¨æ­¤æŒ–礦 +autosmelt_enable=&b自動冶煉 &7已被 &a啟用&7 +autosmelt_disable=&b自動冶煉 &7已被 &cåœç”¨&7 +autoblock_enable=&b自動åˆæˆæ–¹å¡Š &7已被 &a啟用&7 +autoblock_disable=&b自動åˆæˆæ–¹å¡Š &7已被 &cåœç”¨&7 +autopickup_enable=&bè‡ªå‹•æ‹¾å– &7已被 &a啟用&7 +autopickup_disable=&bè‡ªå‹•æ‹¾å– &7已被 &cåœç”¨&7 +teleported=&7正在傳é€åˆ° 礦場 &3%1&7 +mine_reset=&7礦場已經被é‡ç½® +mine_reset_fail=&7礦場é‡ç½®éŒ¯èª¤ã€‚ &8請打開 Console 查看細節 +mine_created=&7礦場 å·²æˆåŠŸ 建立 +mine_deleted=&7礦場 å·²æˆåŠŸ 刪除 +select_bounds=&7您必須è¦å…ˆé¸æ“‡ 礦場 çš„ 界線。 &8å¦‚æžœæƒ³è¦ è«‹è¼¸å…¥ /mines +world_diff=&7您ä¸èƒ½åœ¨å¤šå€‹ä¸–界中建立礦場 +mine_exists=&7此礦場å稱已經存在 +mine_does_not_exist=&7此礦場å稱並ä¸å­˜åœ¨ +spawn_set=&7礦場出生點 å·²æˆåŠŸ 設定 +spawnpoint_same_world=&7這個 &c出生點 &7必須與其他 礦場 在åŒä¸€å€‹ &c世界 +not_a_block=&c%1 &7ä¸æ˜¯ä¸€å€‹æ–¹å¡Š +block_already_added=&7此方塊已經被新增到礦場 +mine_full=&c此礦場已經滿了。 &7è«‹é™ä½Žç¤¦å ´ä¸­è©²æ–¹å¡Šæˆ–其他方塊的 百分比 以騰出更多空間 +block_added=&7將方塊 &3%1 &7加入到礦場 &3%2&7 +block_set=&7在礦場 &3%2&7 更改了方塊&3%1&7 +block_not_removed=&7此方塊並ä¸å­˜åœ¨æ­¤ç¤¦å ´ +block_deleted=&7將方塊 &3%1 &7從礦場 &3%2 &7中刪除 +mine_redefined=&7æˆåŠŸ &3é‡æ–°å®£å‘Š &7礦場 +missing_world=&7無法找到已經建立礦場的世界 +block_search_blank=&7請輸入值以æœç´¢æ–¹å¡Šã€‚&7 diff --git a/prison-core/src/main/resources/lang/ranks/en_US.properties b/prison-core/src/main/resources/lang/ranks/en_US.properties index 07a97c549..b510fd4e5 100644 --- a/prison-core/src/main/resources/lang/ranks/en_US.properties +++ b/prison-core/src/main/resources/lang/ranks/en_US.properties @@ -1,12 +1,57 @@ -# NOTE: A ranks_rankup__version is an arbitrary integer that will be manually incremented when there are -# changes to these messages. This can be used manually to indicate if any -# translations or customizations should be reviewed for needed updates. At this time, no automation -# of comparisons, or updates, will be attempted. -# Do not change this value in the en_US.properties file unless you are making changes to it. -# If you are not making changes to the en_US.properties file then it should be regenerated/refreshed. -# Update the version number in your customized files to reflect the en_US.properties changes. -ranks_messages__version=6 -ranks_messages__auto_refresh=true +# NOTE: A messages__version is an arbitrary integer that will be manually incremented within Prison +# when there are changes to these messages. This value represents when message content is +# changed, fixed, or added to. This value may not be increased if the change is very small and +# insignificant, such as a space or a couple of letters. +# +# messages__auto_refresh=true indicates that this file will automatically be replaced if +# Prison detects a messages__version difference. The old file will be deleted (renamed) and +# a new copy will be placed in the directory to be used. If this value is set to false, then +# Prison will not refresh this file and there could be issues with the display of other messages. +# If auto refresh is set to false, we are not held responsible for possible issues that can +# arise from inaccurate messages. If set to false, then you are responsible for maintaining +# the messages on your own. +# +# If you make changes to this file, and you have messages__auto_refresh=false, then those +# changes will be replaced when this file is updated. Since the old file is renamed, and +# not deleted, you can manually merge your changes back in to the new update. The old +# renamed files will never be deleted by prison; you can remove them when you feel like it +# is safe to do so. +# +# Please consider helping Prison, and everyone else who may use Prison, by contributing all +# translations to other languages. They should be faithful translations, and not something +# for the sake of humor or changes just for cosmetic styling. If you have something you would +# like to share, please contact a staff member on our Discord server. +#Thanks for your contributions! +# + +## +## Prison Supports Unicode (UTF-8) encoding in these properties files. BUt you must +## follow these instructions to ensure everything works properly. +## +## 1. You should only edit these files using a UTF-8 editor. On windows use NotePad, not WordPad. +## WordPad will save as plain text. To confirm the save was successful: save, close the editor, +## then reopen to confirm the encoding was preserved. +## +## 2. When running on Windows, you must enable utf-8 encoding in minecraft's console. Windows +## defaults to a characterpage 1252. To enable window's use of utf-8, you need to change the +## encoding prior to launching spigot/paper: +## chcp 65001 +## +## Full example of a windows script, which hooks for java debugging: +## rem Note: chcp 65001 enables utf-8 in windows, when normally windows uses characterpage 1252 +## chcp 65001 +## java -Dfile.encoding="UTF-8" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -Xms1g -Xmx4g -jar spigot-1.8.8.jar nogui --log-strip-color +## pause +## +## 3. When viewing the logs/latest.log files you must use an editor such as NotePad instead of WordPad. +## +## 4. Unicode is properly displayed in game, in console, in the logs, and with paste.helpch.at when using +## /prison support submit. +## + + +messages__version=21 +messages__auto_refresh=true ranks_rankup__rankup_no_player_name=You have ranks_rankup__rankup_no_player_name_broadcast=Someone @@ -27,6 +72,7 @@ ranks_rankup__rankup_rank_does_not_exist=The rank %1 does not exist on this serv ranks_rankup__rankup_rank_is_not_in_ladder=The rank %1 does not exist in the ladder %2. ranks_rankup__rankup_currency_is_not_supported=The currency, %1, is not supported by any loaded economies. ranks_rankup__rankup_ladder_removed=The ladder %1 was removed. +ranks_rankup__rankup_failure_removing_ladder=Rankup failed since the player could not be removed from the ladder %1. (Players cannot be removed from the 'default' ladder). ranks_rankup__rankup_in_progress_failure=Rankup failed to complete normally. No status was set. ranks_rankup__rankup_failure_to_get_rankplayer=You don't exist! The server has no records of you. Try rejoining, or contact a server administrator for help. @@ -37,6 +83,11 @@ ranks_rankup__cannot_run_from_console=&7Cannot run rankup from console. See &3/ ranks_rankup__internal_failure=&7Invalid rankup mode. Internal failure. Please report. ranks_rankup__error_no_default_ladder=&c[ERROR] There isn't a default ladder! Please report this to an admin! ranks_rankup__error_no_lower_rank=&c[ERROR] Can't get the lowest rank! Please report this to an admin! + +ranks_rankup__error_no_ladder=&c[ERROR] The ladder %1 does not exist! Please report this to an admin! +ranks_rankup__error_no_lower_rank_on_ladder=&c[ERROR] The ladder %1 has no ranks! Please report this to an admin! + +ranks_rankup__error_player_not_on_default_ladder=&c[ERROR] The player is not on the default ladder. Player: %1 ranks_rankup__not_at_last_rank=&cYou aren't at the last rank! ranks_rankup__not_able_to_prestige=&7[&3Sorry&7] &3You were not able to &6Prestige! ranks_rankup__not_able_to_reset_rank=&7Unable to reset your rank on the default ladder. @@ -54,6 +105,7 @@ ranks_rankutil__failure_saving_player_data=An error occurred while saving player ranks_firstJoinHandler__no_ranks_on_server=There are no ranks on the server! New player has no rank. ranks_firstJoinHandler__could_not_save_player=Could not save player files. +ranks_firstJoinHandler__success=Welcome! %1 just joined the server and was assigned the default ranks. ranks_prisonRanks__failure_no_economy_status=&cNo economy plugin @@ -77,9 +129,15 @@ ranks_prisonRanks__failure_with_ladder_save=save ranks_prisonRanks__failure_with_ladder_default=default ranks_prisonRanks__failure_with_ladder_prestiges=prestiges +ranks_prisonRanks__added_new_player=&7Prison: &cNew Player Added &7to Prison: &3%1 &7was found on the server. +ranks_prisonRanks__added_and_fixed_players=Prison Rank Loader: Added %1 players to prison. Fixed %2 players that did not have a rank on the default ladder. + ranks_rank__failure_loading_ranks=&aFailure: Loading Ranks! &7Exception parsing rank documents. Rank id= %1 name= %2 [%3] +ranks_rankManager__failure_loading_rankManager=&aFailure: loading ladder %1 (ladder id: %2): &7Unable to load the RankManager so unable to access any ranks. +ranks_rankManager__failure_duplicate_rank=&aFailure: RankLadder load failure: Rank '%1' was already linked to the ladder '%2', but was attempted to be added to the '%3' ladder. This rank will not be tied to the ladder '%4' + ranks_rankManager__remove_rank_warning=Remove Rank Warning: No fallback rank exists so players with the rank that is being removed will have no rank on that ladder. ranks_rankManager__cannot_save_player_file=RemoveRank: Couldn't save player file. @@ -99,9 +157,11 @@ ranks_playerManager__no_player_name_available= ranks_playerManager__cannot_load_player_file=Could not load player: %1 ranks_playerManager__failed_to_load_economy_currency=Failed to load Economy to get the balance for player %1 with a currency of %2. ranks_playerManager__failed_to_load_economy=Failed to load Economy to get the balance for player %1. +ranks_playerManager__last_rank_message_for__prison_rankup_rank_tag_default= +ranks_commandCommands__command_add_cannot_use_percent_symbols=&7Cannot use percent symbols as placeholder escape characters; must use { } instead. ranks_commandCommands__command_add_placeholders=&7Custom placeholders for rank commands are: &3%1 ranks_commandCommands__rank_does_not_exist=The rank '%1' does not exist. ranks_commandCommands__command_add_duplicate=Duplicate command '%1' was not added to the rank '%2'. @@ -114,8 +174,8 @@ ranks_commandCommands__command_list_contains_none=The rank '%1' contains no comm ranks_commandCommands__command_list_cmd_header=RankUpCommands for rank %1 ranks_commandCommands__command_list_click_cmd_to_remove=&8Click a command to remove it. ranks_commandCommands__command_list_click_to_remove=Click to remove. -ranks_commandCommands__command_list_add_button=&7[&a+&7] Add -ranks_commandCommands__command_list_add_new_command_tool_tip=&7Add a new command. +ranks_commandCommands__command_list_add_button=&7[&a+&7] Add a new Command +ranks_commandCommands__command_list_add_new_command_tool_tip=&7Add a new Command. ranks_commandCommands__command_row_number_must_be_greater_than_zero=&7Please provide a valid row number greater than zero. Was row=[&b%1&7] ranks_commandCommands__command_row_number_too_high=&7Please provide a valid row number no greater than &b%d&7. Was row=[&b%1&7] @@ -145,6 +205,7 @@ ranks_LadderCommands__ladder_added_rank=Added rank '%1' to ladder '%2' in positi ranks_LadderCommands__ladder_deleted=The ladder '%1' has been deleted. ranks_LadderCommands__ladder_cannot_delete_default=You cannot delete the default ladder. It's needed. ranks_LadderCommands__ladder_cannot_delete_prestiges=You cannot delete the prestiges ladder. It's needed. +ranks_LadderCommands__ladder_cannot_delete_with_ranks=Cannot delete a ladder if it still has ranks tied to it. Remove all ranks and try again. ranks_LadderCommands__ladder_error=An error occurred while removing your ladder. &8Check the console for details. ranks_LadderCommands__ladder_error_adding=An error occurred while adding a rank to your ladder. &8Check the console for details. ranks_LadderCommands__ladder_error_removing=An error occurred while removing a rank from your ladder. &8Check the console for details. @@ -157,11 +218,16 @@ ranks_LadderCommands__ladder_has_ranks=&7This ladder contains the following rank ranks_LadderCommands__ladder_default_rank=&b(&9Default Rank&b) &7- ranks_LadderCommands__ladder_see_ranks_list=&3See &f/ranks list &b[ladderName] &3for more details on ranks. ranks_LadderCommands__ladder_has_no_perms=&3The ladder '&7%1&3' contains no permissions or permission groups. +ranks_LadderCommands__ladder_set_rank_cost_multiplier=&3The ladder '&7%1&3' was saved. The Rank Cost Multiplier is now [%2]; was [%3]. +ranks_LadderCommands__ladder_rank_cost_multiplier_no_change=&3The ladder '&7%1&3' was not updated. The supplied Rank Cost Multiplier did not change.[%2] +ranks_LadderCommands__ladder_rank_cost_multiplier_out_of_range=&3The Rank Cost Multiplier is out of range. It must be between -100% and 100%. [%1] ranks_rankCommands__rank_already_exists=&3The rank named &7%1 &3already exists. Try a different name. ranks_rankCommands__rank_name_required=&3A rank name is required and cannot contain formatting codes. ranks_rankCommands__ladder_does_not_exist=&3A ladder by the name of '&7%1&3' does not exist. +ranks_rankCommands__ladder_has_no_ranks=&3The ladder '&7%1&3' does not have any ranks. +ranks_rankCommands__ladder_has_no_ranks_text=&3--- This ladder has no Ranks --- ranks_rankCommands__rank_does_not_exist=&3The rank '&7%1&3' does not exist. ranks_rankCommands__rank_cannot_be_created=&3The rank could not be created. ranks_rankCommands__rank_created_successfully=&3Your new rank, '&7%1&3', was created in the ladder '&7%2&3', using the tag value of '&7%3&3' @@ -169,7 +235,7 @@ ranks_rankCommands__error_saving_ladder=&3The '&7%1&3' ladder could not be saved ranks_rankCommands__error_writting_ladder=&3The '&7%1&3' ladder could not be saved to disk. Check the console for details. -ranks_rankCommands__auto_config_preexisting_warning=&3You should not run &7/ranks autoConfigure &3 with any ranks or mines already setup. Rank count = &7%1&3. Mine count = &7%2 Add the option 'force' to force it to run. If there is a conflict with a preexisting rank or mine, then they will be skipped with no configuration. +ranks_rankCommands__auto_config_preexisting_warning=&3You are trying to run &7/ranks autoConfigure&3 with ranks or mines already setup. Rank count = &7%1&3. Mine count = &7%2&3. Please run this command with the &7help&3 keyword for more information and other customization options: &7/ranks autoConfigure help&3. It's best to run this command from the &7console&3 due to the volume of data it generates. Add the option '&7force&3' to force this process to run. If there is a conflict with a preexisting rank or mine, this process will do it's best to merge the new ranks and mines with what already exist. There is the risk something may not merge correctly. When merging, all blocks will be replaced, but in the console the original block list will be printed for reference if you want to recreate them. Please backup your &7plugins/Prison/&3 directory before running to be safe. ranks_rankCommands__auto_config_force_warning=&aWarning! &3Running autoConfigure with &7force&3 enabled. Not responsible if mines or ranks collide. ranks_rankCommands__auto_config_invalid_options=&3Invalid options. Use %1&3. Was: &3%2 ranks_rankCommands__auto_config_skip_rank_warning=&aWarning! &3Rank &7%1 &3already exists and is being skipped along with generating the mine if enabled, along with all of the other features. @@ -177,6 +243,8 @@ ranks_rankCommands__auto_config_skip_rank_warning=&aWarning! &3Rank &7%1 &3alrea ranks_rankCommands__auto_config_no_ranks_created=Ranks autoConfigure: No ranks were created. ranks_rankCommands__auto_config_ranks_created=Ranks autoConfigure: %1 ranks were created. ranks_rankCommands__auto_config_no_rank_cmds_created=Ranks autoConfigure: No rank commands were created. +ranks_rankCommands__auto_config_ladder_rank_cost_multiplier_info=The 'prestiges' ladder has been enabled to apply a Base Rank Cost Multiplier of %1 that will be applied to 'all' rank costs. This multiplier will be increased with each rank on the ladder. +ranks_rankCommands__auto_config_ladder_rank_cost_multiplier_command_example=The Base Rank Cost Multiplier can be adjusted, or disabled, with the command: '/ranks ladder rankCostMultiplier ranks_rankCommands__auto_config_rank_cmds_created=Ranks autoConfigure: %1 rank commands were created. ranks_rankCommands__auto_config_no_mines_created=Ranks autoConfigure: No mines were created. @@ -191,9 +259,12 @@ ranks_rankCommands__rank_was_removed=The rank '%1' has been removed successfully ranks_rankCommands__rank_delete_error=The rank '%1' could not be deleted due to an error. -ranks_rankCommands__ranks_list_header=Ranks in %1 +ranks_rankCommands__ranks_list_header=&3Ranks in the &7%1 &3Ladder +ranks_rankCommands__ranks_list_ladder_cost_multplier=&3 Ladder Rank Cost Multiplier per Rank: &7%1 +ranks_rankCommands__ranks_list_ladder_edit_cost_multplier=Edit this Ladder's Rank Cost Multiplier. + ranks_rankCommands__ranks_list_click_to_edit=&7Click on a rank's name to view more info. -ranks_rankCommands__ranks_list_command_count= &7- Commands: &3%1 +ranks_rankCommands__ranks_list_command_count= &cCmds: &3%1 ranks_rankCommands__ranks_list_currency= &3Currency: &2%1 ranks_rankCommands__ranks_list_click_to_view=&7Click to view info. ranks_rankCommands__ranks_list_click_to_view2=&7Click to view. @@ -204,7 +275,7 @@ ranks_rankCommands__ranks_list_you_may_try=&8You may also try ranks_rankCommands__ranks_info_header=Rank %1 ranks_rankCommands__ranks_info_name=&3Rank Name: &7%1 -ranks_rankCommands__ranks_info_tag=&3Rank Tag: &7%1 &3Raw: &7\\Q%2\\E +ranks_rankCommands__ranks_info_tag=&3Rank Tag: &7%1 &3Raw: &7\Q%2\E ranks_rankCommands__ranks_info_ladder=&3Ladder: &7%1 ranks_rankCommands__ranks_info_not_linked_to_mines=&3This rank is not linked to any mines ranks_rankCommands__ranks_info_linked_mines=&3Mines linked to this rank: %1 @@ -233,7 +304,7 @@ ranks_rankCommands__set_tag_success=&cThe tag name was changed to %1 for the ran ranks_rankCommands__player_must_be_online=&3You must be a player in the game to run this command, and/or the player must be online. -ranks_rankCommands__player_ladder_info=&c%1&7: Ladder: &b%2 &7Current Rank: &b%3 +ranks_rankCommands__player_ladder_info=&7Ladder: &b%1 &7Current Rank: &b%2 ranks_rankCommands__player_ladder_highest_rank= It's the highest rank! ranks_rankCommands__player_ladder_next_rank=&7 Next rank: &b%1&7 &c$&b%2 ranks_rankCommands__player_ladder_next_rank_currency=&7 Currency: &2%1 diff --git a/prison-core/src/main/resources/lang/ranks/zh_TW.properties b/prison-core/src/main/resources/lang/ranks/zh_TW.properties new file mode 100644 index 000000000..087ee5488 --- /dev/null +++ b/prison-core/src/main/resources/lang/ranks/zh_TW.properties @@ -0,0 +1,313 @@ +# NOTE: A messages__version is an arbitrary integer that will be manually incremented within Prison +# when there are changes to these messages. This value represents when message content is +# changed, fixed, or added to. This value may not be increased if the change is very small and +# insignificant, such as a space or a couple of letters. +# +# messages__auto_refresh=true indicates that this file will automatically be replaced if +# Prison detects a messages__version difference. The old file will be deleted (renamed) and +# a new copy will be placed in the directory to be used. If this value is set to false, then +# Prison will not refresh this file and there could be issues with the display of other messages. +# If auto refresh is set to false, we are not held responsible for possible issues that can +# arise from inaccurate messages. If set to false, then you are responsible for maintaining +# the messages on your own. +# +# If you make changes to this file, and you have messages__auto_refresh=false, then those +# changes will be replaced when this file is updated. Since the old file is renamed, and +# not deleted, you can manually merge your changes back in to the new update. The old +# renamed files will never be deleted by prison; you can remove them when you feel like it +# is safe to do so. +# +# Please consider helping Prison, and everyone else who may use Prison, by contributing all +# translations to other languages. They should be faithful translations, and not something +# for the sake of humor or changes just for cosmetic styling. If you have something you would +# like to share, please contact a staff member on our Discord server. +#Thanks for your contributions! +# + +## +## Prison Supports Unicode (UTF-8) encoding in these properties files. BUt you must +## follow these instructions to ensure everything works properly. +## +## 1. You should only edit these files using a UTF-8 editor. On windows use NotePad, not WordPad. +## WordPad will save as plain text. To confirm the save was successful: save, close the editor, +## then reopen to confirm the encoding was preserved. +## +## 2. When running on Windows, you must enable utf-8 encoding in minecraft's console. Windows +## defaults to a characterpage 1252. To enable window's use of utf-8, you need to change the +## encoding prior to launching spigot/paper: +## chcp 65001 +## +## Full example of a windows script, which hooks for java debugging: +## rem Note: chcp 65001 enables utf-8 in windows, when normally windows uses characterpage 1252 +## chcp 65001 +## java -Dfile.encoding="UTF-8" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -Xms1g -Xmx4g -jar spigot-1.8.8.jar nogui --log-strip-color +## pause +## +## 3. When viewing the logs/latest.log files you must use an editor such as NotePad instead of WordPad. +## +## 4. Unicode is properly displayed in game, in console, in the logs, and with paste.helpch.at when using +## /prison support submit. +## + + +messages__version=2 +messages__auto_refresh=true + +ranks_rankup__rankup_no_player_name=您已經 +ranks_rankup__rankup_no_player_name_broadcast=æŸäºº +ranks_rankup__rankup_you_are=你是 +ranks_rankup__rankup_success=æ­å–œ! %1 您已å‡åˆ°ä¸‹å€‹éšŽç´š '%2' %3 +ranks_rankup__demote_success=抱歉, %1 您已é™å›žä¸Šå€‹éšŽç´š '%2' %3 +ranks_rankup__log_rank_change=%1 您的階級已改變: %2 +ranks_rankup__rankup_cant_afford=您沒有足夠的金錢到下個階級 åˆ°ä¸‹å€‹éšŽç´šéœ€è¦ %1 %2 +ranks_rankup__rankup_lowest=%1 已是最低階級! +ranks_rankup__rankup_highest=%1 已是最高階級! +ranks_rankup__rankup_failure=階級æå‡å¤±æ•— è«‹é‡æ–°æª¢æŸ¥ä¾†ç™¼ç¾å•é¡Œ +ranks_rankup__rankup_failed_to_load_player=玩家載入失敗 +ranks_rankup__rankup_failed_to_load_ladder=階級晉å‡å¤±æ•— +ranks_rankup__rankup_failed_to_assign_rank=分é…階級失敗 è«‹é‡æ–°æª¢æŸ¥ä¾†ç™¼ç¾å•é¡Œ +ranks_rankup__rankup_failed_to_save_player_file=無法檢索/寫入資料,您的資料å¯èƒ½å·²ç¶“æ壞,請通知伺æœå™¨ç®¡ç†å“¡ +ranks_rankup__rankup_no_ranks=這個階內沒有階級 +ranks_rankup__rankup_rank_does_not_exist=階級 %1 ä¸å­˜åœ¨ +ranks_rankup__rankup_rank_is_not_in_ladder=此階級 %1 ä¸å­˜åœ¨æ–¼éšŽ %2 之中 +ranks_rankup__rankup_currency_is_not_supported=這個貨幣, %1, 無法使用於此 +ranks_rankup__rankup_ladder_removed=階 %1 已經刪除 +ranks_rankup__rankup_in_progress_failure=無法正常的å‡ç´š. 此階級ä¸å­˜åœ¨ + +ranks_rankup__rankup_failure_to_get_rankplayer=您的資料ä¸å­˜åœ¨æˆ–伺æœå™¨æ²’有您的紀錄,請嘗試é‡æ–°åŠ å…¥,或å‘伺æœå™¨ç®¡ç†å“¡å–å¾—å”助 +ranks_rankup__rankup_failure_invalid_ladder=此階 '%1' ä¸å­˜åœ¨ +ranks_rankup__rankup_failure_must_be_online_player=&3您必須是玩家æ‰èƒ½ä½¿ç”¨é€™å€‹æŒ‡ä»¤æˆ–您必須在線上 +ranks_rankup__no_permission=您需è¦æ¬Šé™ %1 來å‡ç´šé€™å€‹éšŽ +ranks_rankup__cannot_run_from_console=&7console端ä¸èƒ½åŸ·è¡Œå‡éšŽç´šæŒ‡ä»¤ 請查看 &3/rankup help&7 +ranks_rankup__internal_failure=&7無效的å‡éšŽç´šæ¨¡å¼,內部錯誤,請通知管ç†å“¡ +ranks_rankup__error_no_default_ladder=&c[錯誤] 這邊ä¸æ˜¯é è¨­çš„階! 請通知管ç†å“¡! +ranks_rankup__error_no_lower_rank=&c[錯誤] 無法å–得最低等級! 請通知管ç†å“¡! +ranks_rankup__not_at_last_rank=&c你沒有在上個階級! +ranks_rankup__not_able_to_prestige=&7[&3抱歉&7] &3您ä¸èƒ½ä½¿ç”¨ &6è²æœ›! +ranks_rankup__not_able_to_reset_rank=&7無法é‡è£½æ‚¨çš„é è¨­éšŽ + +ranks_rankup__balance_set_to_zero=&72您的錢已設置為零 +ranks_rankup__prestige_successful=&7[&3æ­å–œ&7] &3您的 &6è²æœ›&3 å‡è‡³ %1&c! +ranks_rankup__prestige_failure=&7[&3抱歉&7] &3您的 &6è²æœ›&3 é™è‡³ %1&c! +ranks_rankup__invalid_charge_value=&3chargePlayer çš„ 值無效 有效值為: %1 %2 +ranks_rankup__invalid_refund_value=&3refundPlayer çš„ 值無效 有效值為: %1 %2 + + +ranks_rankutil__failure_internal=無法執行 rankupPlayerInternal 請檢查伺æœå™¨çš„ logs 以追蹤堆疊(stack trace): %1 +ranks_rankutil__failure_saving_player_data=在儲存玩家檔案時發生錯誤! + + +ranks_firstJoinHandler__no_ranks_on_server=沒有階級在這個伺æœå™¨ä¸Š! 新玩家將沒有階級 +ranks_firstJoinHandler__could_not_save_player=無法儲存玩家資料 +ranks_firstJoinHandler__success=æ­¡è¿Ž!玩家 %1 剛剛加入了伺æœå™¨å·²å°‡ä»–分é…至默èªéšŽç´š + + +ranks_prisonRanks__failure_no_economy_status=&c沒有經濟æ’件 +ranks_prisonRanks__failure_no_economy=PrisonRanks.enable() - 失敗 - 沒有任何支æ´çš„經濟æ’件 - %1 +ranks_prisonRanks__failure_loading_ranks_status=&c無法載入階級資料: %1 +ranks_prisonRanks__failure_loading_ranks=載入階級資料失敗. %1 +ranks_prisonRanks__failure_loading_ladders_status=&c無法載入階資料: %1 +ranks_prisonRanks__failure_loading_ladders=載入階級階失敗. %1 +ranks_prisonRanks__failure_loading_players_status=&c載入玩家資料失敗: %1 +ranks_prisonRanks__failure_loading_players=玩家資料資料失敗. %1 +ranks_prisonRanks__failed_loading_players=&c無法載入玩家: %1 +ranks_prisonRanks__failed_to_load_player_file=玩家資料載入失敗. %1 + +ranks_prisonRanks__status_loaded_ranks=載入 %1 階級 +ranks_prisonRanks__status_loaded_ladders=載入 %1 階 +ranks_prisonRanks__status_loaded_players=載入 %1 玩家 + +ranks_prisonRanks__failure_with_ladder=&c%1 至 %2 失敗, 之å‰çš„階找ä¸åˆ° +ranks_prisonRanks__failure_with_ladder_create=創造 +ranks_prisonRanks__failure_with_ladder_save=儲存 +ranks_prisonRanks__failure_with_ladder_default=é è¨­ +ranks_prisonRanks__failure_with_ladder_prestiges=è²æœ› + +ranks_prisonRanks__added_new_player=&7Prison:已在æœå‹™å™¨ä¸Šæ‰¾åˆ° &c新玩家 &3%1&7 ä¸¦å°‡ä»–æ·»åŠ è‡³ç›£ç„ +ranks_prisonRanks__added_and_fixed_players=&7Prison階級加載: 已將玩家 %1 æ·»åŠ è‡³ç›£ç„ ä¿®å¾©äº†åœ¨é è¨­éšŽç´šä¸Šç„¡æŽ’å的玩家 %2 + + +ranks_rank__failure_loading_ranks=&a失敗: 載入階級! &7無法讀å–文件. 階級代碼= %1 å稱= %2 [%3] + +ranks_rankManager__failure_loading_rankManager=&a失敗: 加載階 %1 (階 id: %2): &7無法加載 RankManager 因此無法訪å•ä»»ä½•ç­‰ç´š +ranks_rankManager__failure_duplicate_rank=&a失敗: RankLadder 加載失敗: 階級 '%1' 已經連çµåˆ°éšŽ '%2', 但試圖連接至階 '%3' 此階級ä¸æœƒèˆ‡éšŽ '%4' æœ‰æ‰€é—œè¯ + + +ranks_rankManager__remove_rank_warning=刪除階級警告: 階級ä¸å­˜åœ¨æ‰€ä»¥çŽ©å®¶åˆªé™¤å¾ŒçŽ©å®¶ä¸åœ¨éšŽ +ranks_rankManager__cannot_save_player_file=刪除階級: 無法儲存玩家資料 +ranks_rankManager__player_is_now=玩家 %1 ç¾åœ¨æ˜¯ %2 +ranks_rankManager__cannot_save_ladder_file=刪除階級: 無法儲存階 %1 +ranks_rankManager__failure_no_economy=經濟æ’件失敗: &7經濟æ’件&a%1&7已註冊於階級&a%2&7, 但ä¸æ”¯æŒä»»ä½•çµ„åˆ +ranks_rankManager__ranks_by_ladders=&7按階排å: + + +ranks_ladderManager__cannot_save_ladder_file=&cLadderManager.saveLadder: 儲存階失敗 &7%1 &3錯誤= [&7%2&3]" + + +ranks_playerManager__cannot_save_player_file=儲存玩家資料時發生錯誤: %1 +ranks_playerManager__cannot_add_new_player=PlayerManager.getPlayer(): 當新增玩家å稱時發生錯誤: %1. %2 +ranks_playerManager__cannot_save_new_player_file=為 %1 建立玩家資料時發生錯誤 該目標檔案為: %2 +ranks_playerManager__no_player_name_available=<沒有å稱å¯ä½¿ç”¨> +ranks_playerManager__cannot_load_player_file=無法載入玩家: %1 +ranks_playerManager__failed_to_load_economy_currency=玩家載入經濟æ’件失敗玩家載入經濟æ’件失敗 %1 貨幣 %2 +ranks_playerManager__failed_to_load_economy=玩家載入經濟æ’件失敗%1 + + + +ranks_commandCommands__command_add_placeholders=&7自訂 rank çš„ placeholders 指令為: &3%1 +ranks_commandCommands__rank_does_not_exist=階級 '%1' ä¸å­˜åœ¨ +ranks_commandCommands__command_add_duplicate=é‡è¤‡çš„指令 '%1' 沒有新增到 '%2' +ranks_commandCommands__command_add_success=å¢žåŠ æ¬Šé™ '%1' 在階級 '%2' + +ranks_commandCommands__command_remove_sucess='%1' 從階級'%2' 中刪除了指令 '%1' +ranks_commandCommands__command_remove_failed=此階級ä¸åŒ…å«è©²æŒ‡ä»¤,甚麼都沒改變 + +ranks_commandCommands__command_list_contains_none=等級 '%1' ä¸åŒ…å«ä»»ä½•æŒ‡ä»¤ +ranks_commandCommands__command_list_cmd_header=等級 %1 çš„å‡éšŽç´šæŒ‡ä»¤ +ranks_commandCommands__command_list_click_cmd_to_remove=&8點擊指令以刪除 +ranks_commandCommands__command_list_click_to_remove=點擊刪除. +ranks_commandCommands__command_list_add_button=&7[&a+&7] 新增 +ranks_commandCommands__command_list_add_new_command_tool_tip=&7新增新的指令 +ranks_commandCommands__command_row_number_must_be_greater_than_zero=&7請輸入一個大於0的有效 è¡Œ 的值,è¡Œ 是=[&b%1&7] +ranks_commandCommands__command_row_number_too_high=&7請輸入一個ä¸å¤§æ–¼ &b%d &7的有效 è¡Œ 的值,è¡Œ 是 [&b%1&7] + + + +ranks_commandCommands__ladder_command_add_placeholders=&7自訂 ladder çš„ placeholders 指令為: &3%1 +ranks_commandCommands__ladder_ladder_does_not_exist=階 '%1' ä¸å­˜åœ¨ +ranks_commandCommands__ladder_command_add_duplicate=複製的指令 '%1' 沒有增加至階級 '%2' +ranks_commandCommands__ladder_command_add_success=新增指令 '%1' 在階 '%2' + +ranks_commandCommands__ladder_command_remove_sucess=刪除指令 '%1' 在階 '%2' +ranks_commandCommands__ladder_command_remove_failed=階裡é¢æ²’有包å«é€™å€‹æŒ‡ä»¤,甚麼都沒改變 + +ranks_commandCommands__ladder_command_list_contains_none=階 '%1' ä¸åŒ…å«ä»»ä½•æŒ‡ä»¤ +ranks_commandCommands__ladder_command_list_cmd_header= %1 階的å‡éšŽç´šæŒ‡ä»¤ + + + +ranks_LadderCommands__ladder_already_exists=階å稱 '%1' 已經存在 +ranks_LadderCommands__ladder_creation_error創建階時發生錯誤 '%1' &8請查看console端以ç²å¾—更多資訊 +ranks_LadderCommands__ladder_created=階 '%1' 已創造 +ranks_LadderCommands__ladder_could_not_save=C無法儲存階 +ranks_LadderCommands__ladder_does_not_exist=階 '%1' ä¸å­˜åœ¨ +ranks_LadderCommands__rank_does_not_exist=階級 '%1' ä¸å­˜åœ¨ +ranks_LadderCommands__ladder_already_has_rank=階 '%1' 已經包å«éšŽç´š '%2' +ranks_LadderCommands__ladder_added_rank=新增 '%1' 至階 '%2' 在ä½ç½® %3 +ranks_LadderCommands__ladder_deleted=階 '%1' 已被刪除 +ranks_LadderCommands__ladder_cannot_delete_default=您無法刪除é è¨­éšŽ +ranks_LadderCommands__ladder_cannot_delete_prestiges=它是必須的,您ä¸èƒ½åˆªé™¤ è²æœ› 階 +ranks_LadderCommands__ladder_error=刪除階時發生錯誤. &8請查看console端以ç²å¾—更多資訊 +ranks_LadderCommands__ladder_error_adding=增加階級至階時發生錯誤. &8請查看console端以ç²å¾—更多資訊 +ranks_LadderCommands__ladder_error_removing=刪除階內的階級時發生錯誤. &8請查看console端以ç²å¾—更多資訊 +ranks_LadderCommands__ladder_error_saving=儲存階失敗 +ranks_LadderCommands__move_rank_notice=試圖從它的原始階中刪除指定的階級,然後它將被新增回指定ä½ç½®çš„目標階,階級ä¸æœƒè¢«åˆªé™¤/丟失 +ranks_LadderCommands__ladder_removed_rank_from_ladder=刪除階 '%2' 中的階級 '%1' + + +ranks_LadderCommands__ladder_has_ranks=&7此階包å«ä»¥ä¸‹çš„階級: +ranks_LadderCommands__ladder_default_rank=&b(&9é è¨­éšŽç´š&b) &7- +ranks_LadderCommands__ladder_see_ranks_list=&3ç€è¦½ &f/階級列表 &b[ladderName] &3以ç²å¾—更多階級細節 +ranks_LadderCommands__ladder_has_no_perms=&3階 '&7%1&3' 沒有包å«æ¬Šé™æˆ–權é™ç¾¤çµ„ + + +ranks_rankCommands__rank_already_exists=&3階級å稱&7%1 &3已經存在. 試著用別的å稱 +ranks_rankCommands__rank_name_required=&3一個階級å稱是必須的,而且ä¸èƒ½åŒ…å«æ ¼å¼åŒ–代碼 +ranks_rankCommands__ladder_does_not_exist=&3A 階å稱 '&7%1&3' ä¸å­˜åœ¨ +ranks_rankCommands__ladder_has_no_ranks=&3沒有任何階級在 階 '&7%1&3' å…§ +ranks_rankCommands__ladder_has_no_ranks_text=&3--- 此階沒有任何階級 --- +ranks_rankCommands__rank_does_not_exist=&3階級 '&7%1&3' ä¸å­˜åœ¨ +ranks_rankCommands__rank_cannot_be_created=&3階級沒有被創建 +ranks_rankCommands__rank_created_successfully=&3您的新階級, '&7%1&3', 已新增在階 '&7%2&3', 使用的標籤值為 '&7%3&3' +ranks_rankCommands__error_saving_ladder=&3階 '&7%1&3' 無法被儲存到硬碟中, 請查看console端以ç²å¾—更多資訊 +ranks_rankCommands__error_writting_ladder=&3階 '&7%1&3' 無法被儲存到硬碟中, 請查看console端以ç²å¾—更多資訊 + + +ranks_rankCommands__auto_config_preexisting_warning=&3您ä¸æ‡‰è©²åœ¨å·²ç¶“設置任何階級或礦場的情æ³ä¸‹åŸ·è¡Œ &7/ranks autoConfigure &3 階級目å‰æœ‰ &7%1&3 個. 礦場目å‰æœ‰ &7%2 個。您å¯ä»¥æ–°å¢žé¸é … 'force' 來強制執行,如果與已存在的階級/礦場è¡çª,é‚£éº¼ä»–å€‘å°‡è¢«è·³éŽ +ranks_rankCommands__auto_config_force_warning=&a警告! &3執行 autoConfigure 且 &7force&3 是啟用的, 如果發生è¡çª, 階級 或 礦場 å¯èƒ½æ²’有任何更動 +ranks_rankCommands__auto_config_invalid_options=&3無效的設定 使用 %1&3. Was: &3%2 +ranks_rankCommands__auto_config_skip_rank_warning=&a警告! &3階級7%1 &3已存在並且礦場已被啟用,或其他功能已啟用 + +ranks_rankCommands__auto_config_no_ranks_created=Ranks autoConfigure: 沒有建立任何階級 +ranks_rankCommands__auto_config_ranks_created=Ranks autoConfigure: %1 階級已被建立 +ranks_rankCommands__auto_config_no_rank_cmds_created=Ranks autoConfigure: 沒有建立任何階級指令 +ranks_rankCommands__auto_config_rank_cmds_created=Ranks autoConfigure: %1 階級指令已被建立 + +ranks_rankCommands__auto_config_no_mines_created=Ranks autoConfigure: 沒有建立任何礦場 +ranks_rankCommands__auto_config_mines_created=Ranks autoConfigure: %1 礦場已被建立 + +ranks_rankCommands__auto_config_no_linkage=Ranks autoConfigure: 沒有任何 礦場 與 éšŽç´šå·²è¢«é€£çµ +ranks_rankCommands__auto_config_linkage_count=Ranks autoConfigure: %1 階級 與 ç¤¦å ´å·²è¢«é€£çµ + + +ranks_rankCommands__rank_cannot_remove=您ä¸èƒ½ç§»é™¤æ­¤éšŽç´š,因為它是é è¨­éšŽä¸­çš„唯一 一個階級 +ranks_rankCommands__rank_was_removed=階級 '%1' 已刪除æˆåŠŸ +ranks_rankCommands__rank_delete_error=階級 '%1' 因出ç¾éŒ¯èª¤è€Œåˆªé™¤å¤±æ•— + + +ranks_rankCommands__ranks_list_header=%1 中的 階級 +ranks_rankCommands__ranks_list_click_to_edit=&7點擊階級å稱來ç€è¦½æ›´å¤šè³‡è¨Š +ranks_rankCommands__ranks_list_command_count= &7- 指令 &3%1 +ranks_rankCommands__ranks_list_currency= &3貨幣&2%1 +ranks_rankCommands__ranks_list_click_to_view=&7點擊ç€è¦½è³‡è¨Š +ranks_rankCommands__ranks_list_click_to_view2=&7點擊ç€è¦½ +ranks_rankCommands__ranks_list_create_new_rank=&7建立新的階級 +ranks_rankCommands__ranks_list_you_may_try=&8你也å¯ä»¥è©¦è©¦ + + + +ranks_rankCommands__ranks_info_header=階級 %1 +ranks_rankCommands__ranks_info_name=&3階級å稱: &7%1 +ranks_rankCommands__ranks_info_tag=&3階級標籤: &7%1 &3è¡Œ: &7%2 +ranks_rankCommands__ranks_info_ladder=&3階&7%1 +ranks_rankCommands__ranks_info_not_linked_to_mines=&3此階級沒有被連çµåˆ°ä»»ä½•ç¤¦å ´ +ranks_rankCommands__ranks_info_linked_mines=&3此階級: %1 已連çµåˆ°ç¤¦å ´ +ranks_rankCommands__ranks_info_cost=&3此階級所需金錢為: &7$%1 +ranks_rankCommands__ranks_info_currency=&3貨幣:&7<&a%1&7> +ranks_rankCommands__ranks_info_players_with_rank=&7在此階級有 %1 ä½çŽ©å®¶ +ranks_rankCommands__ranks_info_rank_id=&6階級 ID: &7%1 +ranks_rankCommands__ranks_info_rank_delete_message=&7[&c-&7] 點我刪除此階級 +ranks_rankCommands__ranks_info_rank_delete_tool_tip=&7點擊刪除這個階級 &cæ­¤æ“作ä¸èƒ½è¢«å–消 + + +ranks_rankCommands__rank_set_cost_success=æˆåŠŸç‚ºéšŽç´š '%1' 設定金錢: %2 + + +ranks_rankCommands__set_currency_not_specified=必須指定貨幣å稱,或必須為'none','%1'是無效值 +ranks_rankCommands__set_currency_no_currency_to_clear=此階級 '%1' 沒有金錢所以ä¸èƒ½è¢«æ¸…除 +ranks_rankCommands__set_currency_cleared=æˆåŠŸæ¸…除階級 '%1' 的貨幣,該階級ä¸å†æœ‰è‡ªå®šç¾©è²¨å¹£ +ranks_rankCommands__set_currency_no_active_support=沒有已啟用的經濟æ’件支æ´å為 '%1' 的貨幣 +ranks_rankCommands__set_currency_successful=æˆåŠŸå°‡éšŽç´š '%1' 的貨幣設置為 %2 + + +ranks_rankCommands__set_tag_invalid=&c標籤å稱必須是有效的值,如果è¦ç§»é™¤å®ƒ,請使用&anone&c +ranks_rankCommands__set_tag_no_change=&c新的標籤å稱與原來的å稱相åŒ,甚麼都沒改變 +ranks_rankCommands__set_tag_cleared=&c已清除階級 %1 的標籤å稱 +ranks_rankCommands__set_tag_success=&c階級 %2 的標籤å稱已變更為 %1 + + +ranks_rankCommands__player_must_be_online=&3您必須是玩家æ‰èƒ½åŸ·è¡Œé€™å€‹æŒ‡ä»¤, å’Œ/或玩家必須在線上 +ranks_rankCommands__player_ladder_info=&c%1&7: 階: &b%2 &7當å‰éšŽç´š: &b%3 +ranks_rankCommands__player_ladder_highest_rank= 這已經是最高階級了! +ranks_rankCommands__player_ladder_next_rank=&7 下個階級: &b%1&7 &c$&b%2 +ranks_rankCommands__player_ladder_next_rank_currency=&7 金錢: &2%1 +ranks_rankCommands__player_balance_default=&7Tç¾åœ¨çš„經濟æ’件屬於&b%1 &7是 &b%2 +ranks_rankCommands__player_balance_others=&7ç¾åœ¨çš„經濟æ’件屬於 &b%1 &7是 &b%2 &2%3 +ranks_rankCommands__player_perms_offline=&7 Notice: &3這個玩家ä¸åœ¨ç·šä¸Š,權é™ä¸å¯ç”¨ä¹Ÿä¸æº–確. +ranks_rankCommands__player_sellall_multiplier=&7 Sellall 乘數: &b%1 %2 +ranks_rankCommands__player_not_accurate=&5(&2ä¸æº–確的&5) +ranks_rankCommands__player_admin_only=&8[管ç†å“¡å°ˆå±¬] +ranks_rankCommands__player_past_names=&7通éŽçŽ©å®¶å字或日期修改: +ranks_rankCommands__player_perms=&7玩家權é™: +ranks_rankCommands__player_op=&cOP +ranks_rankCommands__player_player=&3玩家 +ranks_rankCommands__player_online=&3上線 +ranks_rankCommands__player_offline=&3下線 +ranks_rankCommands__player_prison_offline_player=&3下線監ç„玩家 +ranks_rankCommands__player_prison_player=&3監ç„玩家 +ranks_rankCommands__player_no_ranks_found=&3沒有找到階級 &c%1 + + +ranks_rankCommands__players_invalid_ladder=階 '%1' ä¸å­˜åœ¨, 或ä¸æ˜¯ 'ALL'. +ranks_rankCommands__players_invalid_action=æ“作 '%1' 無效. [players, all, full] + diff --git a/prison-core/src/main/resources/lang/spigot/en_US.properties b/prison-core/src/main/resources/lang/spigot/en_US.properties new file mode 100644 index 000000000..444d11ae0 --- /dev/null +++ b/prison-core/src/main/resources/lang/spigot/en_US.properties @@ -0,0 +1,59 @@ +# NOTE: A messages__version is an arbitrary integer that will be manually incremented within Prison +# when there are changes to these messages. This value represents when message content is +# changed, fixed, or added to. This value may not be increased if the change is very small and +# insignificant, such as a space or a couple of letters. +# +# messages__auto_refresh=true indicates that this file will automatically be replaced if +# Prison detects a messages__version difference. The old file will be deleted (renamed) and +# a new copy will be placed in the directory to be used. If this value is set to false, then +# Prison will not refresh this file and there could be issues with the display of other messages. +# If auto refresh is set to false, we are not held responsible for possible issues that can +# arise from inaccurate messages. If set to false, then you are responsible for maintaining +# the messages on your own. +# +# If you make changes to this file, and you have messages__auto_refresh=false, then those +# changes will be replaced when this file is updated. Since the old file is renamed, and +# not deleted, you can manually merge your changes back in to the new update. The old +# renamed files will never be deleted by prison; you can remove them when you feel like it +# is safe to do so. +# +# Please consider helping Prison, and everyone else who may use Prison, by contributing all +# translations to other languages. They should be faithful translations, and not something +# for the sake of humor or changes just for cosmetic styling. If you have something you would +# like to share, please contact a staff member on our Discord server. +#Thanks for your contributions! +# + +## +## Prison Supports Unicode (UTF-8) encoding in these properties files. BUt you must +## follow these instructions to ensure everything works properly. +## +## 1. You should only edit these files using a UTF-8 editor. On windows use NotePad, not WordPad. +## WordPad will save as plain text. To confirm the save was successful: save, close the editor, +## then reopen to confirm the encoding was preserved. +## +## 2. When running on Windows, you must enable utf-8 encoding in minecraft's console. Windows +## defaults to a characterpage 1252. To enable window's use of utf-8, you need to change the +## encoding prior to launching spigot/paper: +## chcp 65001 +## +## Full example of a windows script, which hooks for java debugging: +## rem Note: chcp 65001 enables utf-8 in windows, when normally windows uses characterpage 1252 +## chcp 65001 +## java -Dfile.encoding="UTF-8" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -Xms1g -Xmx4g -jar spigot-1.8.8.jar nogui --log-strip-color +## pause +## +## 3. When viewing the logs/latest.log files you must use an editor such as NotePad instead of WordPad. +## +## 4. Unicode is properly displayed in game, in console, in the logs, and with paste.helpch.at when using +## /prison support submit. +## + + +messages__version=1 +messages__auto_refresh=true + + +spigot___= + + diff --git a/prison-core/src/main/resources/lang/spigot/zh_TW.yml b/prison-core/src/main/resources/lang/spigot/zh_TW.yml new file mode 100644 index 000000000..da1d66e53 --- /dev/null +++ b/prison-core/src/main/resources/lang/spigot/zh_TW.yml @@ -0,0 +1,299 @@ +# NOTE: This file is not being used yet. +# This file is not hooked up to b auto refreshed. +# If changes are made to this file, please manually send them to RoyalBlueRanger so +# this file can be updated in the project. +# The location of where this file is actually used is as follows. +# /plugins/Prison/module_conf/lang/zh_TW.yml +# You will have to manually replace that file to update it, until it can be automated. + +Lore: + ActivateWithinMode: "&8啟用範åœå…§æ¨¡å¼" + ActivateRadiusMode: "&8啟用åŠå¾‘模å¼" + AutoPickupGuiManager: "&8自動拾å–" + AutoSmeltGuiManager: "&8自動冶煉" + AutoBlockGuiManager: "&8自動åˆæˆæ–¹å¡Š" + BlockType: "&3方塊類型: " + Blocks: "&3方塊:" + Blocks2: "&8管ç†ç¤¦å ´çš„方塊" + BackpackID: "&3背包 ID: " + ClickToAddBackpack: "&8按下以新增背包" + ClickToAddBackpackInst0: "&3說明: " + ClickToAddBackpackInst1: "&8請記得在背包內" + ClickToAddBackpackInst2: "&8新增一個物å“" + ClickToAddBackpackInst3: "&8來ä¿å­˜å®ƒ" + ClickToChoose: "&8按下以é¸æ“‡" + ClickToConfirm: "&8按下以確èª" + ClickToCancel: "&8按下以å–消" + ClickToDecrease: "&8按下以減少" + ClickToIncrease: "&8按下以增加" + ClickToManageRank: "&8管ç†é€™å€‹éšŽç´š" + ClickToManageCommands: "&8管ç†å‡ç´šéšŽç´šæŒ‡ä»¤" + ClickToOpen: "&8按下以開啟" + ClickToOpenBackpack: "&8按下以打開監ç„背包" + ClickToRename: "&8按下以é‡æ–°å‘½å" + ClickToTeleport: "&8按下以傳é€" + ClickToUse: "&8按下以使用" + ClickToRankup: "&8按下以å‡ç´šéšŽç´š" + ClickToEditBlock: "&8按下以修改百分比" + ClickToEdit: "&8按下以編輯" + ClickToClose: "&8按下以關閉GUI" + ClickToPriorPage: "&a按下以å‰å¾€ 上一é " + ClickToNextPage: "&a按下以å‰å¾€ 下一é " + ClickToStartBlockSetup: "&a按下以 設定方塊" + ClickToSelect: "&7按下以 é¸æ“‡" + ClickToAddBlock: "&a按下以 新增方塊" + ClickToEnable: "&a按下以啟用" + ClickToDisable: "&c按下以åœç”¨" + Chance: "&3機率: " + Command: "&3指令: &7" + ContainsTheRank: "&3階級 " + ContainsNoCommands: " &3ä¸åŒ…å«æŒ‡ä»¤" + DelaySellAll: "&3延é²: &8" + DisableNotifications: "&8關閉通知" + DisabledAll: "&3所有功能 &c關閉&3" + EnabledAll: "&a所有功能 é–‹å•Ÿ" + EmptyMultiplier: "&c[!] 沒有乘數!" + FullSoundEnabled: "&a所有è²éŸ³é€šçŸ¥ 啟用" + FullSoundDisabled: "&c所有è²éŸ³é€šçŸ¥ åœç”¨" + FullHologramEnabled: "&a所有全螢幕通知 啟用" + FullHologramDisabled: "&c所有全螢幕通知 åœç”¨" + Id: "&3階級 id: &7" + Info: "&8&l|&3訊æ¯&8|" + IfYouHaveEnoughMoney: "&8如果你有足夠的金錢" + LadderThereAre: "&8那裡有 &3" + LadderCommands: " &3階上的指令:" + LeftClickToConfirm: "&aå·¦éµä»¥ 確èª" + LeftClickToOpen: "&8å·¦éµä»¥ é–‹å•Ÿ" + LeftClickToReset: "&aå·¦éµä»¥ é‡è¨­" + LeftClickToEdit: "&aå·¦éµä»¥ 修改數值" + ManageResetTime: "&8管ç†ç¤¦å ´é‡ç½®æ™‚é–“" + MinesButton: "&8礦場GUI管ç†" + MineName: "&3礦場å稱: &f" + Multiplier: "&3乘數: &f" + Name: "&3階級å稱: &7" + Notifications: "&8編輯礦場通知" + Permission: "&3全縣: " + PlayerOwner: "&3背包æ“有者: " + PlayersWithTheRank: "&3在此階級的玩家: &7" + PrestigeWarning: "&3è²æœ›å°‡æœƒé‡ç½®: " + PrestigeWarning2: "&3 - &b階級" + PrestigeWarning3: "&3 - &b餘é¡" + PrestigeName: "&8è²æœ›å稱: &3" + PrestigeMultiplier: "&8乘數: &3" + PrestigeMultiplierInfoGUI: "&3ç®¡ç† ä¹˜æ•¸" + Price: "&3價格: &a$" + Price2: "&8價格: &a$" + Price3: "&3階級 價格: &a$" + Percentage: "&8百分比: " + PrisonTasksButton: "&8監ç„任務管ç†" + ResetTime: "&3é‡ç½®æ™‚é–“: &7" + Radius: "&8åŠå¾‘: " + RankupCommands: "&8&l|&3å‡ç´šéšŽç´šæŒ‡ä»¤&8| &8&l- &3" + Rankup: "&a階級å‡ç´š" + RanksButton: "&8階級GUI管ç†" + ResetButton: "&8é‡ç½®ç¤¦å ´." + RightClickToCancel: "&cå³éµä»¥ å–消" + RightClickToEnable: "&cå³éµä»¥ &a啟用&c" + RightClickToDisable: "&cå³éµä»¥ åœç”¨" + RightClickToToggle: "&3å³éµä»¥ 切æ›" + RightClickToDelete: "&cå³éµä»¥ 刪除" + RightClickToEdit: "&8å³éµä»¥ 編輯" + SpawnPoint: "&3出生點: &7" + StatusLockedMine: "&8狀態: &c上鎖" + StatusUnlockedMine: "&8狀態: &a解鎖" + SpawnPoint2: "&8設定礦場出生點" + SizeOfMine: "&3礦場的大å°: &7" + Selected: "&3å·²é¸æ“‡çš„" + ShowItem: "&3顯示 物å“: &7" + ShowItemDescription: "&7這是物å“" + ShowItemDescription2: "&7顯示在玩家的 GUI" + ShowItemDescription3: "&7或者礦場的 GUI" + SellAllDelayInfo: "&8指令 &3/sellall sell" + SellAllDelayInfo2: "&8還在冷å»ä¸­" + SellAllCurrencyInfo: "&3編輯 SellAll 貨幣" + SellAllActiveCurrency: "&3貨幣: &a" + ShiftAndRightClickToDelete: "&cShift + å³éµä»¥ 刪除" + ShiftAndRightClickToDisable: "&cShift + å³éµä»¥ åœç”¨" + ShiftAndRightClickToToggle: "&cShift + å³éµä»¥ 切æ›" + StatusEnabled: "&8啟用" + StatusDisabled: "&8åœç”¨" + SkipReset1: "&8如果沒有 " + SkipReset2: "&8挖到足夠的方塊 " + SkipReset3: "&8則跳éŽé‡ç½®" + Tp: "&8傳é€åˆ°ç¤¦å ´" + Tag: "&3標籤: &8" + Tag2: "&3階級標籤: &7" + Time: "&8時間: " + Volume: "&3é«”ç©: &7" + Value: "&3數值: &a$" + World: "&3世界: &7" + noRanksFoundSetup: "&3沒有找到任何階級!" + noRanksFoundSetup2: "&3如果你想è¦ç¹¼çºŒè¨­å®š" + noRanksFoundSetup3: "&3所有從 A 到 Z 的階級和礦場" + noRanksFoundSetup4: "&3都將使用 &aé è¨­ &3數值!" + noRanksFoundSetup5: "&3ä½ å¯ä»¥åŸ·è¡Œç›¸åŒçš„æ“作 通éŽä»¥ä¸‹æŒ‡ä»¤:" + noRanksFoundSetup6: "&1/ranks autoConfigure full !" + noRanksFoundSetup7: "&3啟用åˆå§‹åƒ¹æ ¼ å’Œ 乘數 æ›¿æ› X" + noRanksFoundSetup8: "&3é è¨­çš„åˆå§‹åƒ¹æ ¼ 為 50000, é è¨­çš„乘數 為 1.5" + ZeroBlocksReset1: "&8設定礦場的冷å»æ™‚é–“ " + ZeroBlocksReset2: "&8冷å»æ™‚é–“ " + ZeroBlocksReset3: "&8在礦場沒有任何方塊之å‰" +Message: + BackPackIsDisabled: 背包在 config.yml 中被åœç”¨, ä½ ä¸èƒ½ä½¿ç”¨é€™å€‹! + BackPackNeedPlayer: 請新增一個玩家å稱 + BackPackDeleteOperationSuccess: 背包應該...已經æˆåŠŸåˆªé™¤äº†! + BackPackDeleteOperationFail: 找ä¸åˆ°èƒŒåŒ… 或者出了甚麼å•é¡Œ...? + BackPackPlayerNotFound: 找ä¸åˆ°æ­¤çŽ©å®¶ + BackPackDoNotOwnAny: 抱歉,但您沒有任何背包, 請使用指令 /backpack <你想å–的任何ID> 來建立一個背包 + BackPackOwnLimitReached: 抱歉,您已é”到玩家所å…許的背包上é™! + BackPackResizeNotInt: 背包的大å°æ•¸å€¼ä¸æ˜¯ä¸€å€‹æ•´æ•¸ + BackPackResizeNotMultiple9: 背包的大å°å¿…須是 9 çš„å€æ•¸ ,最大值為 54 + BackPackResizeDone: 如果背包沒有éºå¤±,它的大å°å·²ç¶“æˆåŠŸèª¿æ•´! + BackPackLimitMissingParam: 您缺少設定背包é™åˆ¶æ‰€éœ€è¦çš„一些åƒæ•¸! + BackPackLimitNotNumber: 背包的é™åˆ¶ ä¸æ˜¯ä¸€å€‹æ•¸å­—! + BackPackLimitSuccess: 背包的é™åˆ¶ å·²æˆåŠŸä¿®æ”¹! + BackPackLimitDecrementFail: 背包的é™åˆ¶æ¸›åŽ»è©²å€¼å°‡æ˜¯è² æ•¸,您所åšçš„æ“作將被å–消! + BackPackListEmpty: 此伺æœå™¨æ²’有任何背包 + BackPackCantOwn: 抱歉,但看起來您ä¸èƒ½æ“有任何背包! + CantGetRanksAdmin: 無法å–得階級, å¯èƒ½ &c沒有階級&7 或者階級模組 已被 &cåœç”¨&7 + CantRunGUIFromConsole: GUI ä¸èƒ½åœ¨ console 端執行! + CantGiveItemFromConsole: ä½ ä¸èƒ½åœ¨ console 端å–得物å“! + DefaultLadderEmpty: é è¨­çš„階是 &c空的&7 + NoSellAllItems: 抱歉, &c沒有&7å¯é¡¯ç¤ºçš„ 販售全部 ç‰©å“ + EmptyGui: 抱歉, GUI 是 &c空的 + EnableAutoSellToUse: 抱歉, 自動賣出 &cåœç”¨&7, 請啟用它! + EnableSellDelayToUse: 抱歉, 販售全部 å†·å» æ˜¯ &cåœç”¨&7 çš„, 請啟用它! + EventCancelled: "&c事件å–消." + InvalidBooleanInput: 抱歉, 您必須在此輸入 &a-true-&7 或者 &c-false-&7 + MissingPermission: 抱歉, 您沒有 &c權é™&7 使用! + NoBlocksMine: 抱歉, 礦場是 &c空的&7 + NoMines: 抱歉,這裡 &c沒有 &7礦場å¯ä»¥é¡¯ç¤º + NoRankupCommands: 抱歉, 此階級 &c沒有 å‡éšŽç´šæŒ‡ä»¤&7! + NoLadders: 抱歉,這裡 &c沒有 &7階å¯ä»¥é¡¯ç¤º + NoRanksPrestigesLadder: -è²æœ›-階中&c沒有&7階級! + NoRanksFoundAdmin: 抱歉, 階是 &c空的&7! + NoRanksFound: 抱歉, 此階是 &c空的&7! + NoRanksFoundHelp1: 抱歉, 此階是 &c空的&7 或者 &7[ + NoRanksFoundHelp2: "] &cä¸å­˜åœ¨!" + LadderPrestigesNotFound: "&c找ä¸åˆ° &7-è²æœ›-階!" + TooManyBlocks: 抱歉, GUI &c太多&7 方塊 且最大值為 54 + TooManyLadders: 抱歉, GUI &c太多&7 階 且最大值為 54 + TooManyMines: 抱歉, GUI &c太多&7 礦場 且最大值為 54 + TooManyRankupCommands: 抱歉, GUI &c太多&7 å‡éšŽç´šæŒ‡ä»¤ 且最大值為 54 + TooManyRanks: 抱歉, GUI &c太多&7 階級 且最大值為 54 + TooManySellAllItems: 抱歉, GUI &c太多&7 ç‰©å“ ä¸”æœ€å¤§å€¼ç‚º 54 + mineNameRename: 請寫下您è¦ä½¿ç”¨çš„ &6礦場å稱 &7並&6é€å‡º&7 + mineNameRenameClose: 輸入 &cclose &7或 等待 &c30 秒&7來å–消 + mineNameRenameClosed: 礦場é‡æ–°å‘½å &cå–消&7! + mineOrGuiDisabled: GUI å’Œ/或 GUI Mines 是 &cåœç”¨&7çš„. 請檢查 GuiConfig.yml + mineMissingGuiPermission: 您缺少使用 GUI Mines çš„ &c權é™&7 + MineShowItemEditSuccess: 礦場顯示物å“編輯æˆåŠŸ + OutOfTimeNoChanges: 時間éŽä¹…,å·²&cå–消變更&7 + PrestigeCancelled: 編輯è²æœ› å·²&cå–消&7! + PrestigeCancelledWrongKeyword: "編輯è²æœ› å·²&cå–消&7, 您沒有輸入: &aconfirm&7" + PrestigeRanOutOfTime: 時間éŽä¹…, 編輯&cè²æœ› å·²å–消&7 + PrestigesDisabledDefault: è²æœ› é è¨­æ˜¯ &cåœç”¨&7çš„, 請在 config.yml 修改! + ConfirmPrestige: "&a確èª&7: 請輸入 &aconfirm&7 進行確èª" + CancelPrestige: "&cå–消&7: 請輸入 &ccancel&7 進行å–消, &c您有30秒å¯ä»¥é€²è¡Œæ­¤æ“作" + PrestigesAreDisabled: è²æœ› 是 &cåœç”¨&7çš„. 請檢查 config.yml + GuiOrPrestigesDisabled: GUI å’Œ/或 GUI Prestiges 是 &cåœç”¨&7çš„. 請檢查 GuiConfig.yml + GuiClosedWithSuccess: GUI 已關閉 + CantFindPrestiges: è²æœ›éšŽ &c沒有è²æœ›&7! + missingGuiPrestigesPermission: 您缺少 使用 GUI prestiges çš„ &c權é™&7 + rankTagRename: 請寫下您è¦ä½¿ç”¨çš„ &6標籤 &7並&6é€å‡º&7 + rankTagRenameClose: 請輸入 &cclose &7或 &cç­‰30秒&7 以å–消 + rankTagRenameClosed: 標籤é‡æ–°å‘½å &cå–消&7! + rankGuiDisabledOrAllGuiDisabled: GUI å’Œ/或 GUI Ranks 是 &cåœç”¨&7çš„ 請檢查 GuiConfig.yml (%s %s) + rankGuiMissingPermission: 您缺少使用 Ranks GUI çš„ &c權é™&7 + SellAllAutoSellEarnedMoney: "您因販售全部賺了: " + SellAllAutoSellEarnedMoneyCurrency: $ + SellAllAutoSellMissingPermission: 您沒有 &c權é™&7 編輯 AutoSell + SellAllAutoSellEnabled: 販售全部 已經 &a啟用&7 + SellAllAutoSellDisabled: 販售全部 已經 &cåœç”¨&7 + SellAllAutoSellAlreadyEnabled: 自動販售 已經 &a啟用&7! + SellAllAutoSellAlreadyDisabled: 自動販售 已經 &cåœç”¨&7! + SellAllAutoPerUserToggleableAlreadyEnabled: 自動販售 玩家切æ›é–‹é—œ 已經 &a啟用&7! + SellAllAutoPerUserToggleableAlreadyDisabled: 自動販售 玩家切æ›é–‹é—œ &cåœç”¨&7! + SellAllAutoPerUserToggleableEnabled: 販售全部 玩家切æ›é–‹é—œ 已經 &a啟用&7! + SellAllAutoPerUserToggleableDisabled: 販售全部 玩家切æ›é–‹é—œ &cåœç”¨&7! + SellAllCurrencyChat1: "&3開始為販售全部設置新的貨幣" + SellAllCurrencyChat2: 請輸入 &ccancel &7以å–消 + SellAllCurrencyChat3: 請輸入 &3default &7以使用é è¨­å€¼ + SellAllCurrencyChat4: 請輸入 &aCurrency name &7來設置新的貨幣 + SellAllCurrencyEditedSuccess: 販售全部貨幣編輯æˆåŠŸ! + SellAllCurrencyEditCancelled: 販售全部貨幣編輯 &cå–消&7 + SellAllCurrencyNotFound: 沒有已啟用的經濟æ’ä»¶æ”¯æ´ é€™å€‹åå« '%s' 的貨幣 + SellAllDefaultSuccess: é è¨­å€¼æ–°å¢ž &aæˆåŠŸ&7! + SellAllDefaultMissingPermission: 抱歉,但您缺少 &c權é™! + SellAllIsDisabled: 抱歉, 功能 販售全部 在 config.yml 是 &cåœç”¨&7çš„ + SellAllEditedWithSuccess: "&7] 編輯 &aæˆåŠŸ&7!" + SellAllSubCommandNotFound: å­å‘½ä»¤(sub-command) &c沒找到&7, 請輸入 /sellall help 了解更多! + SellAllMultipliersAreDisabled: 乘數 在 SellAll config 是 &c關閉&7çš„! + SellAllMultiplierWrongFormat: "&c錯誤的格å¼&7, 請輸入 /sellall multiplier add/delete <è²æœ›> <乘數>" + SellAllMissingPermission: 抱歉,但您沒有 &c權é™&7 + SellAllMissingPermissionToToggleAutoSell: "抱歉,但您缺少 &c權é™&7 使用此功能! " + SellAllRanksDisabled: 階級模組是 &c關閉的&7 或未找到 ! + SellAllPrestigeLadderNotFound: "&c找ä¸åˆ°&7 è²æœ›éšŽ, å¯èƒ½åœ¨ config.yml 是 &cåœç”¨&7çš„!" + SellAllCantFindPrestigeOrRank: "&c找ä¸åˆ°&7 è²æœ›/階級: " + SellAllRankNotFoundInPrestigeLadder: "-è²æœ›- 階 &cä¸åŒ…å«&7 在 階級: " + SellAllMultiplierNotANumber: 抱歉,輸入的乘數 &cä¸æ˜¯ä¸€å€‹æ•¸å­—&7! + SellAllMultiplierNotNumber2: " 這裡-> " + SellAllConfigSaveFail: 抱歉, 在儲存設定時&cæŸäº›æ±è¥¿ç™¼ç”ŸéŒ¯èª¤&7! + SellAllMultiplierEditSaveSuccess: 乘數 新增/編輯 &aæˆåŠŸ&7! + SellAllMultiplierFormat: "請使用此格å¼è¼¸å…¥: /sellall multiplier delete <è²æœ›>" + SellAllCantFindMultiplier: "&c找ä¸åˆ°&7 è²æœ›ä¸­çš„乘數 " + SellAllCantFindMultiplier2: " &7在 sellallconfig.yml" + SellAllMultiplierDeleteSuccess: 乘數 &c刪除 &aæˆåŠŸ&7! + SellAllWrongFormatCommand: "&c錯誤的個是&7, 請輸入 /sellall help 了解更多" + SellAllPleaseAddItem: "è«‹ &a加上&7 一個物å“ID [範例: /sellall add <價格>]" + SellAllAddPrice: "è«‹ç‚ºæ­¤ç‰©å“ &a新增&7 一個價格/價值 [範例: /sellall add 100]" + SellAllWrongID: 抱歉, &c物å“ID錯誤&7, 請檢查! + SellAllValueNotNumber: 抱歉, 價格/價值 &cä¸æ˜¯ä¸€å€‹æ•¸å­—&7! + SellAllMissingID: "è«‹ &a加上&7 一個物å“ID [範例: /sellall delete ]" + SellAllNotFoundStringConfig: " 在 config 中找ä¸åˆ° 或 已被 &c刪除&7" + SellAllNotFoundEdit: " 在 config 中找ä¸åˆ°!" + SellAllDeletedSuccess: " &c刪除&aæˆåŠŸ&7!" + SellAllAddSuccess: "] &a新增&7 &aæˆåŠŸ&7!" + SellAllAlreadyAdded: " &c之å‰å·²ç¶“新增éŽäº†&7, 請使用指令 /sellall edit 編輯它!" + SellAllCommandEditSuccess: "] &a編輯æˆåŠŸ&7!" + SellAllYouArentPlayer: 您 &cä¸æ˜¯&a一個玩家 + SellAllNothingToSell: 您 &c沒有æ±è¥¿&7å¯ä»¥è³£å‡º! + SellAllYouGotMoney: 您得到 &a$ + SellAllGUIDisabled: 抱歉,但 GUI 在 SellAllConfig.yml 是 &cåœç”¨&7 çš„ + SellAllAutoSell: 您的庫存已滿, &a自動販售 啟用&7! + SellAllSignOnly: 抱歉, 您åªèƒ½é€éŽå‘Šç¤ºç‰Œä¾†ä½¿ç”¨SellAll (or with the ByPass permission) + SellAllSignNotify: é€éŽå‘Šç¤ºç‰Œ 使用 &aSellAll æˆåŠŸ&7! + SellAllSignMissingPermission: 抱歉, 但您沒有 &c權é™&7 使用此功能! + SellAllEmpty: |- + &c沒有&7 ç‰©å“ åœ¨ sellall config, + 請新增一個 å’Œ/或 é‡å•Ÿä¼ºæœå™¨! + SellAllAutoEnabled: 自動-販售全部 &a啟用 æˆåŠŸ&7! + SellAllAutoDisabled: 自動-販售全部 &cåœç”¨ &aæˆåŠŸ&7! + SellAllWaitDelay: è«‹ &cç¨å€™&7 å†é‡æ–°ä½¿ç”¨æ­¤æŒ‡ä»¤! + SellAllDelayAlreadyEnabled: 販售全部 冷å»æ™‚é–“ 已經 &a啟用&7! + SellAllDelayAlreadyDisabled: 販售全部 冷å»æ™‚é–“ 已經 &cåœç”¨&7! + SellAllDelayEnabled: 販售全部 冷å»æ™‚é–“ &a啟用 æˆåŠŸ&7! + SellAllDelayDisabled: 販售全部 冷å»æ™‚é–“ &cåœç”¨ &aæˆåŠŸ&7! + SellAllDelayEditedWithSuccess: 販售全部 冷å»æ™‚é–“ 編輯 &aæˆåŠŸ&7! + SellAllDelayNotNumber: 冷å»æ™‚間的值 &cä¸æ˜¯&7 一個數字! + SellAllGUIEmpty: 抱歉,但這裡 &c沒有&7 方塊在 販售全部的商店! + SellAllGUIEmpty2: "&7[&cå°æ示&7] &7您å¯ä»¥ 使用指令 /sellall add &a新增&7 一個!" + SellAllTriggerAlreadyEnabled: 販售全部 的觸發開關 已經 &a啟用&7 + SellAllTriggerAlreadyDisabled: 販售全部 的觸發開關 已經 &cåœç”¨&7 + SellAllTriggerEnabled: 販售全部 的觸發開關 &a啟用&7 + SellAllTriggerDisabled: 販售全部 的觸發開關 &cåœç”¨&7 + SellAllTriggerIsDisabled: 販售全部 的觸發開關 在 SellAllConfig.yml 是 &cåœç”¨&7çš„ + SellAllTriggerMissingItem: 請為 販售全部 Shift+å³éµ 新增一個正確的物å“ID + SellAllTriggerItemAddSuccess: è²©å”®å…¨éƒ¨çš„è§¸ç™¼ç‰©å“ æ–°å¢ž &aæˆåŠŸ&7! + SellAllTriggerItemEditSuccess: è²©å”®å…¨éƒ¨çš„è§¸ç™¼ç‰©å“ ç·¨è¼¯ &aæˆåŠŸ&7! + SellAllTriggerItemDeleteSuccess: è²©å”®å…¨éƒ¨çš„è§¸ç™¼ç‰©å“ åˆªé™¤ &aæˆåŠŸ&7! + TooLowValue: "&c價值太低" + TooHighValue: "&c價值太高" + GUIReloadSuccess: GUI é‡æ–°è®€å–æˆåŠŸ! +Setup: + Message: + MissingPermission: 抱歉,您缺少 &c權é™&7 [-prison.setup- or -prison.admin-]! + WrongFormat: 您 &c缺少&7 後方åƒæ•¸ -礦場- or -階級-, / setup -礦場- 或 -階級- ! + WelcomeToRanksSetup: å—¨,歡迎來到階級設定, è«‹ &cç¨ç­‰&7 它將會自動完æˆ! + SuccessRanksSetup: 階級設定 &a完æˆ&7 且 &aæˆåŠŸ&7 且階級 &a新增&7 至é è¨­çš„階, 如果有甚麼æ±è¥¿ç¼ºå°‘ 請檢查 logs! + Aborted: 監ç„設定 &cå–消&7 diff --git a/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java b/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java index 7712882d7..a0b2b64fe 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestPlatform.java @@ -33,18 +33,20 @@ import tech.mcprison.prison.file.YamlFileIO; import tech.mcprison.prison.internal.CommandSender; import tech.mcprison.prison.internal.Player; +import tech.mcprison.prison.internal.PlayerUtil; import tech.mcprison.prison.internal.Scheduler; import tech.mcprison.prison.internal.World; import tech.mcprison.prison.internal.block.PrisonBlock; import tech.mcprison.prison.internal.block.PrisonBlockTypes; import tech.mcprison.prison.internal.platform.Capability; +import tech.mcprison.prison.internal.platform.HandlerList; import tech.mcprison.prison.internal.platform.Platform; import tech.mcprison.prison.internal.scoreboard.ScoreboardManager; import tech.mcprison.prison.modules.ModuleElement; import tech.mcprison.prison.modules.ModuleElementType; import tech.mcprison.prison.output.ChatDisplay; +import tech.mcprison.prison.placeholders.PlaceholderManager.PlaceholderFlags; import tech.mcprison.prison.placeholders.Placeholders; -import tech.mcprison.prison.placeholders.PlaceholderManager.PlaceHolderFlags; import tech.mcprison.prison.store.Storage; import tech.mcprison.prison.util.ChatColor; import tech.mcprison.prison.util.Location; @@ -82,7 +84,12 @@ public void getWorldLoadErrors( ChatDisplay display ) { @Override public List getOnlinePlayers() { return new ArrayList<>(); } - + @Override + public List getOfflinePlayers() { + List players = new ArrayList<>(); + return players; + } + @Override public Optional getOfflinePlayer( String name ) { return null; @@ -199,8 +206,8 @@ public void identifyRegisteredPlugins() { - public Map getPlaceholderDetailCounts() { - Map placeholderDetails = new TreeMap<>(); + public Map getPlaceholderDetailCounts() { + Map placeholderDetails = new TreeMap<>(); return placeholderDetails; } @@ -235,6 +242,11 @@ public String getConfigString( String key ) { return null; } + @Override + public String getConfigString( String key, String defaultValue ) { + return defaultValue; + } + @Override public boolean isUseNewPrisonBlockModel() { return false; @@ -313,12 +325,13 @@ public boolean isMineAccessibleByRank( Player player, ModuleElement mine ) { } @Override - public void autoCreateMineBlockAssignment( boolean forceKeepBlocks ) { + public void autoCreateMineBlockAssignment( List rankMineNames, boolean forceKeepBlocks ) { } @Override - public void autoCreateMineLinerAssignment() { + public void autoCreateMineLinerAssignment( List rankMineNames, + boolean forceLinersBottom, boolean forceLinersWalls ) { } @@ -334,18 +347,82 @@ public List getActiveFeatures() { } @Override - public void dumpEventListenersBlockBreakEvents() { + public String dumpEventListenersBlockBreakEvents() { + return ""; + } + + @Override + public String dumpEventListenersPlayerChatEvents() { + return ""; + } + + @Override + public void traceEventListenersBlockBreakEvents( CommandSender sender ) { } @Override - public void dumpEventListenersPlayerChatEvents() { + public void testPlayerUtil( UUID uuid ) { } @Override - public void traceEventListenersBlockBreakEvents( CommandSender sender ) { + public void saveResource( String string, boolean replace ) { } + @Override + public String getMinesListString() { + return ""; + } + + @Override + public String getRanksListString() { + return ""; + } + + public boolean isSuppressOutput() + { + return suppressOutput; + } + + public void setSuppressOutput( boolean suppressOutput ) + { + this.suppressOutput = suppressOutput; + } + + public void setPluginDirectory( File pluginDirectory ) + { + this.pluginDirectory = pluginDirectory; + } + + @Override + public PlayerUtil getPlayerUtil( UUID playerUuid ) { + return null; + } + + @Override + public List dumpEventListenersList( String eventType, HandlerList handlerList ) + { + return new ArrayList<>(); + } + + @Override + public ChatDisplay dumpEventListenersChatDisplay( String eventType, HandlerList handlerList ) + { + ChatDisplay chatDisplay = new ChatDisplay( "Test Event Listing" ); + return chatDisplay; + } + + /** + *

This only reloads the event listeners that auto features uses. This is called by + * the command "/prison reload autoFeatures". + *

+ * + * tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.reloadConfig() + * + */ + public void reloadAutoFeaturesEventListeners() { + + } } diff --git a/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java b/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java index 2d3512a47..52d75f24f 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestPlayer.java @@ -144,10 +144,10 @@ public boolean isPlayer() { return null; } - @Override - public void printDebugInventoryInformationToConsole() { - - } +// @Override +// public void printDebugInventoryInformationToConsole() { +// +// } public void recalculatePermissions() { @@ -187,4 +187,11 @@ public double getSellAllMultiplier() { return 1.0; } + @Override + public void setTitle( String title, String subtitle, int fadeIn, int stay, int fadeOut ) { + } + + @Override + public void setActionBar( String actionBar ) { + } } diff --git a/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java b/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java index bf17f16c7..a95546a19 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java +++ b/prison-core/src/test/java/tech/mcprison/prison/TestWorld.java @@ -18,13 +18,14 @@ package tech.mcprison.prison; +import java.util.List; + import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.internal.World; import tech.mcprison.prison.internal.block.Block; +import tech.mcprison.prison.internal.block.PrisonBlock; import tech.mcprison.prison.util.Location; -import java.util.List; - /** * @author Faizaan A. Datoo */ @@ -48,5 +49,7 @@ public TestWorld(String name) { return null; } - + @Override + public void setBlock( PrisonBlock block, int x, int y, int z ) { + } } diff --git a/prison-core/src/test/java/tech/mcprison/prison/discord/PrisonPasteChatTest.java b/prison-core/src/test/java/tech/mcprison/prison/discord/PrisonPasteChatTest.java new file mode 100644 index 000000000..6d6c6f85f --- /dev/null +++ b/prison-core/src/test/java/tech/mcprison/prison/discord/PrisonPasteChatTest.java @@ -0,0 +1,29 @@ +package tech.mcprison.prison.discord; + +import static org.junit.Assert.assertEquals; + +import java.util.TreeMap; + +import org.junit.Test; + +public class PrisonPasteChatTest + extends + PrisonPasteChat +{ + + public PrisonPasteChatTest() + { + super( "jUnitTextSupportName", new TreeMap() ); + } + + @Test + public final void test() + { + assertEquals( "", cleanText( "", true ) ); + + assertEquals( "test", cleanText( "test", true ) ); + assertEquals( "test &", cleanText( "test &", true ) ); + assertEquals( "test &7test&3 test", cleanText( "test &7test&3 test", true ) ); + } + +} diff --git a/prison-core/src/test/java/tech/mcprison/prison/util/JumboTextFontTest.java b/prison-core/src/test/java/tech/mcprison/prison/util/JumboTextFontTest.java new file mode 100644 index 000000000..16be5e644 --- /dev/null +++ b/prison-core/src/test/java/tech/mcprison/prison/util/JumboTextFontTest.java @@ -0,0 +1,45 @@ +package tech.mcprison.prison.util; + +import org.junit.Test; + +public class JumboTextFontTest +{ + + @Test + public final void test() + { + testPrint( "AaBbCcDd" ); + + testPrint( "ABCDEFGHIJ" ); + + testPrint( "KLMNOPQRST" ); + + testPrint( "UVWXYZ!?" ); + + testPrint( "1234567890" ); + + testPrint( "ABC Aa, Bb. Cd!" ); + + testPrint( "abcdefghij"); + + testPrint( "klmnopqrst" ); + + testPrint( "uvwxyz" ); + + testPrint( "aA/_-+=_\\Bb" ); + + } + + public void testPrint( String text ) { + + StringBuilder sb = new StringBuilder(); + + JumboTextFont.makeJumboFontText( text, sb ); + + System.out.println( text ); + System.out.println(); + System.out.println( sb.toString() ); + System.out.println(); + + } +} diff --git a/prison-core/src/test/java/tech/mcprison/prison/util/TextTest.java b/prison-core/src/test/java/tech/mcprison/prison/util/TextTest.java index de9c34a25..8dcea75b5 100644 --- a/prison-core/src/test/java/tech/mcprison/prison/util/TextTest.java +++ b/prison-core/src/test/java/tech/mcprison/prison/util/TextTest.java @@ -126,5 +126,9 @@ public void testHexColors() { assertEquals("This ^7is ^x^a^3^b^4^c^5 ^ra test ^x^1^2^3^4^5^6 test", replaceColorCodeWithx( translateAmpColorCodesAltHexCode("This &7is #a3b4c5 &Ra test #123456 test"), '^' )); + // Test with two complete quote: + assertEquals("This ^7is ^x^a^3^b^4^c^5 ^ra test #123456 test test2 #778899 test", replaceColorCodeWithx( + translateColorCodes("This &7is #a3b4c5 &Ra test \\Q#123456 test\\E test2 \\Q#778899 test\\E", '&'), '^' )); + } } diff --git a/prison-mines/build.gradle b/prison-mines/build.gradle index 978808f96..57678c339 100644 --- a/prison-mines/build.gradle +++ b/prison-mines/build.gradle @@ -2,6 +2,9 @@ group 'tech.mcprison' apply plugin: 'java' +compileJava.options.encoding = 'UTF-8' +compileTestJava.options.encoding = "UTF-8" + //sourceCompatibility = 1.8 repositories { diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/PrisonMines.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/PrisonMines.java index 178fda5f3..3111f2930 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/PrisonMines.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/PrisonMines.java @@ -235,7 +235,7 @@ public Mine findMineLocation( Player player ) { if ( mine != null && mine.isInMineIncludeTopBottomOfMine( player.getLocation() )) { results = mine; } - else { + else if ( player.getLocation() != null ) { // Look for the correct mine to use. // Set mine to null so if cannot find the right one it will return a null: results = findMineLocationIncludeTopBottomOfMine( player.getLocation() ); diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesBlockCommands.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesBlockCommands.java index c708c4b78..2f978af11 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesBlockCommands.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/commands/MinesBlockCommands.java @@ -273,34 +273,31 @@ private void addBlockStats( Mine mine, PrisonBlockStatusData block, DecimalForma String percent = dFmt.format( block.getChance() ) + "%"; - String text = String.format( "&7%s - %s", percent, block.getBlockName() ); - // Minor padding after the name and chance: - if ( text.length() < 30 ) - { - text += " ".substring( text.length() ); - } + String text = String.format( "&7%6s - %-20s ", percent, block.getBlockName() ); FancyMessage msg = new FancyMessage( text ) .suggest( "/mines block set " + mine.getName() + " " + block.getBlockName() + " %" ) .tooltip( "&7Click to edit the block's chance." ); row.addFancy( msg ); } - String text1 = formatStringPadRight( (totals ? " &b%s" : " &3Pl: &7%s"), 16, - iFmt.format( block.getResetBlockCount() ) ); + String text1 = String.format( (totals ? "&b%-7s " : "&3Pl: &7%-7s "), + iFmt.format( block.getBlockPlacedCount() ) ); FancyMessage msg1 = new FancyMessage( text1 ).tooltip( "&7Number of blocks of this type &3Pl&7aced in this mine." ); row.addFancy( msg1 ); - String text2 = formatStringPadRight( (totals ? " &b%s" : " &3Rm: &7%s"), 16, - iFmt.format( block.getResetBlockCount() - block.getBlockCountUnsaved() ) ); + + String text2 = String.format( (totals ? "&b%-7s " : "&3Rm: &7%-7s "), + iFmt.format( block.getBlockPlacedCount() - block.getBlockCountUnsaved() ) ); FancyMessage msg2 = new FancyMessage( text2 ).tooltip( "&7Number of blocks of this type &3R&7e&3m&7aining." ); row.addFancy( msg2 ); - FancyMessage msg3 = new FancyMessage( String.format( (totals ? " &b%s" : " &3T: &7%s"), + + FancyMessage msg3 = new FancyMessage( String.format( (totals ? "&b%-11s " : "&3T: &7%-11s"), PlaceholdersUtil.formattedKmbtSISize( 1.0d * block.getBlockCountTotal(), dFmt, "" ) ) ) .tooltip( "&3T&7otal blocks of this type that have been mined." ); row.addFancy( msg3 ); - FancyMessage msg4 = new FancyMessage( String.format( (totals ? " &b%s" : " &3S: &7%s"), + FancyMessage msg4 = new FancyMessage( String.format( (totals ? "&b%-9s" : " &3S: &7%-9s"), PlaceholdersUtil.formattedKmbtSISize( 1.0d * block.getBlockCountTotal(), dFmt, "" ) ) ) .tooltip( "&7Blocks of this type that have been mined since the server was &3S&7tarted." ); row.addFancy( msg4 ); 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 1faa5c6a9..286e2bc29 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 @@ -27,6 +27,7 @@ import java.util.TreeMap; import tech.mcprison.prison.Prison; +import tech.mcprison.prison.PrisonCommand; import tech.mcprison.prison.chat.FancyMessage; import tech.mcprison.prison.commands.Arg; import tech.mcprison.prison.commands.Command; @@ -47,6 +48,7 @@ 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.features.MineLinerData.LadderType; import tech.mcprison.prison.mines.managers.MineManager; import tech.mcprison.prison.mines.managers.MineManager.MineSortOrder; import tech.mcprison.prison.mines.tasks.MineTeleportWarmUpTask; @@ -59,11 +61,13 @@ import tech.mcprison.prison.output.RowComponent; import tech.mcprison.prison.placeholders.PlaceholdersUtil; import tech.mcprison.prison.selection.Selection; -import tech.mcprison.prison.tasks.PrisonCommandTask.TaskMode; import tech.mcprison.prison.tasks.PrisonCommandTask; +import tech.mcprison.prison.tasks.PrisonCommandTask.TaskMode; import tech.mcprison.prison.tasks.PrisonTaskSubmitter; import tech.mcprison.prison.util.Bounds; +import tech.mcprison.prison.util.JumboTextFont; import tech.mcprison.prison.util.Bounds.Edges; +import tech.mcprison.prison.util.Text; /** * @author Dylan M. Perks @@ -199,30 +203,38 @@ public void constraintsBlockCommand(CommandSender sender, - @Command(identifier = "mines create", description = "Creates a new mine, or even a virtual mine.", + @Command(identifier = "mines create", description = "Creates a new mine, or even a virtual mine. " + + "If the option 'virtual' is used, then you can create the mine offline within the console. " + + "You'll have to use `/mines set area help` later to position the in a world. If you are not " + + "creating a virtual mine, then you must be in game, and have already selected an area " + + "with the `/mines wand` tool. If an area is not selected, then this command will fail.", onlyPlayers = false, permissions = "mines.create") public void createCommand(CommandSender sender, - @Arg(name = "virtual", description = "Create a virtual mine in name only; no physical location. " + - "This allows the mine to be predefined before specifying the coordinates. Use [virtual]. ", - def = "") - String virtualMine, + @Arg(name = "mineName", description = "The name of the new mine.", def = " ") + String mineName, + @Wildcard(join=true) - @Arg(name = "mineName", description = "The name of the new mine.", def = " ") String mineName + @Arg(name = "options", def = " ", + description = "Options for mine creation. Use 'virtual' to create a virtual mine in " + + "name only; no physical location. This allows the mine to be predefined before " + + "specifying the coordinates. " + + "Use 'noPlaceholderUpdate' to prevent reloading all " + + "placeholders when creating this mine. This is useful if you have multiple mines " + + "you want to create. " + + "[virtual noPlaceholderUpdate]") String options ) { - boolean virtual = false; + options = options == null ? "" : options.trim(); - if ( virtualMine != null && virtualMine.trim().length() > 0 ) { - if ( "virtual".equalsIgnoreCase( virtualMine.trim()) ) { - virtual = true; - } - else { - // Combine virtualMine to the beginning of the mineName if it exists. It was not - // intended to be the virtualMine parameter. Yes, adding a space will be an error, but - // they added it any way. - mineName = virtualMine + (mineName == null ? "" : " " + mineName.trim() ).trim(); - } + boolean virtual = mineName.toLowerCase().contains( "virtual" ); + if ( virtual && !options.isEmpty() ) { + // The option virtual was used in the mineName. Swap fields. + mineName = options.contains( " " ) ? options.split( " " )[0] : options; } - + else { + virtual = options.toLowerCase().contains( "virtual" ); + } + boolean updatePlaceholders = !options.toLowerCase().contains( "noplaceholderupdate" ); + if ( mineName == null || mineName.contains( " " ) || mineName.trim().length() == 0 ) { sendMessage( sender, "&3Names cannot contain spaces or be empty. &b[&d" + mineName + "&b]" ); return; @@ -232,7 +244,8 @@ public void createCommand(CommandSender sender, Player player = getPlayer( sender ); if ( !virtual && (player == null || !player.isOnline())) { - sendMessage( sender, "&3You must be a player in the game to run this command." ); + sendMessage( sender, "&3You must be a player in the game to run this command. " + + "You also need to have selected an area with the `/mines wand` tool. " ); return; } @@ -271,9 +284,15 @@ public void createCommand(CommandSender sender, Mine mine = new Mine(mineName, selection); pMines.getMineManager().add(mine); + if ( updatePlaceholders ) { + + Prison.get().getPlatform().getPlaceholders().reloadPlaceholders(); + } + if ( mine.isVirtual() ) { sendMessage( sender, "&3Virtual mine created: use command " + - "&7/mines set area &3 to enable as a normal mine." ); + "&7'/mines set area help'&3 set an area within a world to " + + "enable as a normal mine." ); } else { pMines.getMinesMessages().getLocalizable("mine_created").sendTo(sender); @@ -328,6 +347,9 @@ public void renameCommand(CommandSender sender, pMines.getMineManager().rename(mine, newName); + Prison.get().getPlatform().getPlaceholders().reloadPlaceholders(); + + sender.sendMessage( String.format( "&3Mine &d%s &3was successfully renamed to &d%s&3.", mineName, newName) ); pMines.getMinesMessages().getLocalizable("mine_created").sendTo(sender); @@ -527,7 +549,8 @@ public void tagCommand(CommandSender sender, setLastMineReferenced(mineName); pMines.getMineManager().saveMine(mine); - + + if ( tag == null ) { sender.sendMessage( String.format( "&cThe tag name was cleared for the mine %s.", @@ -635,9 +658,14 @@ public void deleteCommand(CommandSender sender, setLastMineReferenced(null); + + Prison.get().getPlatform().getPlaceholders().reloadPlaceholders(); + + pMines.getMinesMessages().getLocalizable("mine_deleted").sendTo(sender); - } else if ( getConfirmTimestamp() == null || ((now - getConfirmTimestamp()) >= 1000 * 60 ) ) { + } + else if ( getConfirmTimestamp() == null || ((now - getConfirmTimestamp()) >= 1000 * 60 ) ) { setConfirmTimestamp( now ); ChatDisplay chatDisplay = new ChatDisplay("&cDelete " + mineName); @@ -735,13 +763,80 @@ public void infoCommand(CommandSender sender, - DecimalFormat dFmt = new DecimalFormat("#,##0"); + ChatDisplay chatDisplay = mineInfoDetails( sender, mMan.isMineStats(), m, cmdPageData ); + + + int blockSize = 0; + if ( m.isUseNewBlockModel() ) { + blockSize = m.getPrisonBlocks().size(); + } + else { + blockSize = m.getBlocks().size(); + } + + String message = blockSize != 0 ? null : " &cNo Blocks Defined"; + cmdPageData.generatePagedCommandFooter( chatDisplay, message ); + + chatDisplay.send(sender); + + // If show all, then include the mine's commands and blockEvents: + // These are different commands, so they will be in different chatDisplay objects + // so cannot weave them together: + // if ( cmdPageData.isShowAll() ) { + //commandList( sender, m.getName() ); + + //blockEventList( sender, m.getName() ); + // } + } + + public void allMinesInfoDetails( StringBuilder sb ) { + + PrisonMines pMines = PrisonMines.getInstance(); + MineManager mMan = pMines.getMineManager(); + + for ( Mine mine : mMan.getMines() ) { + + PrisonCommand.printFooter( sb ); + + JumboTextFont.makeJumboFontText( mine.getName(), sb ); + sb.append( "\n" ); + + CommandPagedData cmdPageData = new CommandPagedData( + "/mines info " + mine.getName(), mine.getPrisonBlocks().size(), + 1, "all" ); + + ChatDisplay chatDisplay = mineInfoDetails( null, mMan.isMineStats(), mine, cmdPageData ); + + sb.append( chatDisplay.toStringBuilder() ); + } + + PrisonCommand.printFooter( sb ); + } + + + private ChatDisplay mineInfoDetails( CommandSender sender, boolean isMineStats, Mine m, CommandPagedData cmdPageData ) + { + DecimalFormat dFmt = new DecimalFormat("#,##0"); DecimalFormat fFmt = new DecimalFormat("#,##0.00"); ChatDisplay chatDisplay = new ChatDisplay("&bMine: &3" + m.getName()); - chatDisplay.addText("&7Server runtime: %s", Prison.get().getServerRuntimeFormatted() );; - + { + RowComponent row = new RowComponent(); + row.addTextComponent("&7Server runtime: %s ", + Prison.get().getServerRuntimeFormatted() ); + + double tps = Prison.get().getPrisonTPS().getAverageTPS(); + String tpsFmt = tps >= 18.5 ? "&a" : + tps >= 16.0 ? "&e" : + tps >= 14.0 ? "&6" : + "&c"; + row.addTextComponent("&7TPS: %s%s", + tpsFmt, + fFmt.format( tps)); + + chatDisplay.addComponent( row ); + } // Display Mine Info only: if ( cmdPageData.getCurPage() == 1 ) { @@ -755,23 +850,26 @@ public void infoCommand(CommandSender sender, } - if ( m.isMineAccessByRank() && m.isTpAccessByRank() ) { + boolean mineAccessByRank = m.isMineAccessByRank(); + boolean tpAccessByRank = m.isTpAccessByRank(); + + if ( mineAccessByRank && tpAccessByRank ) { RowComponent row = new RowComponent(); row.addTextComponent( "&3Mine Access by Rank. TP Access by Rank." ); chatDisplay.addComponent( row ); } - else if ( !m.isMineAccessByRank() && m.isTpAccessByRank() ) { + else if ( !mineAccessByRank && tpAccessByRank ) { RowComponent row = new RowComponent(); row.addTextComponent( "&3TP Access by Rank." ); chatDisplay.addComponent( row ); } - if ( m.isMineAccessByRank() && !m.isTpAccessByRank() ) { + if ( mineAccessByRank && !tpAccessByRank ) { RowComponent row = new RowComponent(); row.addTextComponent( "&3Mine Access by Rank." ); chatDisplay.addComponent( row ); } - if ( !m.isMineAccessByRank() ) { + if ( !mineAccessByRank ) { RowComponent row = new RowComponent(); row.addTextComponent( "&3Mine Access Permission: &7%s &3(Should use Access by Rank)", ( m.getAccessPermission() == null ? "&2none" : m.getAccessPermission() ) ); @@ -779,40 +877,48 @@ else if ( !m.isMineAccessByRank() && m.isTpAccessByRank() ) { } - String noTagMessag = String.format( "&7(not set) &3Will default to mine name if used." ); - chatDisplay.addText("&3Tag: &7%s", m.getTag() == null ? noTagMessag : m.getTag()); - - if ( !m.isVirtual() ) { - String worldName = m.getWorld().isPresent() ? m.getWorld().get().getName() : "&cmissing"; - chatDisplay.addText("&3World: &7%s", worldName); + { + RowComponent row = new RowComponent(); + + String noTagMessag = String.format( "&7(not set)" ); + row.addTextComponent("&3Tag: &7%-11s ", + m.getTag() == null ? noTagMessag : m.getTag()); + + if ( m.getRank() == null ) { + row.addTextComponent( "&3No rank is linked to this mine." ); + } + else { + row.addTextComponent( "&3Rank: &7%s", m.getRank() ); + } + + + chatDisplay.addComponent( row ); } - if ( m.getRank() == null ) { - chatDisplay.addText( "&3No rank is linked to this mine." ); - } - else { - chatDisplay.addText( "&3Rank: &7%s", m.getRank() ); + if ( !m.isVirtual() ) { } if ( !m.isVirtual() ) { - String minCoords = m.getBounds().getMin().toBlockCoordinates(); - String maxCoords = m.getBounds().getMax().toBlockCoordinates(); - chatDisplay.addText("&3Bounds: &7%s &8to &7%s", minCoords, maxCoords); - Player player = getPlayer( sender ); - - chatDisplay.addText("&3Center: &7%s &3%s &7%s", + String worldName = m.getWorld().isPresent() ? m.getWorld().get().getName() : "&cmissing"; + Player player = sender == null ? null : getPlayer( sender ); + chatDisplay.addText("&3World: &7%-10s &3Center: &7%s &3%s &7%s", + worldName, m.getBounds().getCenter().toBlockCoordinates(), (player == null ? "" : "Distance:"), (player == null ? "" : fFmt.format( m.getBounds().getDistance3d( player.getLocation() ) )) ); + String minCoords = m.getBounds().getMin().toBlockCoordinates(); + String maxCoords = m.getBounds().getMax().toBlockCoordinates(); + chatDisplay.addText("&3Bounds: &7%s &8to &7%s", minCoords, maxCoords); + String spawnPoint = m.getSpawn() != null ? m.getSpawn().toBlockCoordinates() : "&cnot set"; chatDisplay.addText("&3Spawnpoint: &7%s", spawnPoint); - if ( cmdPageData.isShowAll() || mMan.isMineStats() ) { + if ( cmdPageData.isShowAll() || isMineStats ) { RowComponent rowStats = new RowComponent(); rowStats.addTextComponent( " -- &7 Stats :: " ); rowStats.addTextComponent( m.statsMessage() ); @@ -828,10 +934,10 @@ else if ( !m.isMineAccessByRank() && m.isTpAccessByRank() ) { if ( !m.isVirtual() ) { RowComponent row = new RowComponent(); - row.addTextComponent( "&3Size: &7%d&8x&7%d&8x&7%d", Math.round(m.getBounds().getWidth()), + row.addTextComponent( "&3Size: &7%d&8x&7%d&8x&7%d ", Math.round(m.getBounds().getWidth()), Math.round(m.getBounds().getHeight()), Math.round(m.getBounds().getLength()) ); - row.addTextComponent( " &3Volume: &7%s &3Blocks", + row.addTextComponent( "&3Volume: &7%s &3Blocks", dFmt.format( Math.round(m.getBounds().getTotalBlockCount())) ); chatDisplay.addComponent( row ); } @@ -856,23 +962,16 @@ else if ( !m.isMineAccessByRank() && m.isTpAccessByRank() ) { - { - RowComponent row = new RowComponent(); - row.addTextComponent( "&3Mine Command Count: &7%d", - m.getResetCommands().size() ); - chatDisplay.addComponent( row ); - } - - - - { + if ( !cmdPageData.isShowAll() ) { RowComponent row = new RowComponent(); - row.addTextComponent( "&3Mine BlockEvent Count: &7%d", + row.addTextComponent( "&3Mine Command Count: &7%d &3BlockEvent Count: &7%d", + m.getResetCommands().size(), m.getBlockEvents().size() ); chatDisplay.addComponent( row ); } + { RowComponent row = new RowComponent(); double rtMinutes = m.getResetTime() / 60.0D; @@ -889,7 +988,7 @@ else if ( !m.isMineAccessByRank() && m.isTpAccessByRank() ) { if ( m.isUsePagingOnReset() ) { row.addTextComponent( " &7-= &5Reset Paging Enabled &7=-" ); } - else { + else if ( cmdPageData.isShowAll() ) { row.addTextComponent( " &7-= &3Reset Paging Disabled &7=-" ); } @@ -926,17 +1025,12 @@ else if ( !m.isMineAccessByRank() && m.isTpAccessByRank() ) { chatDisplay.addComponent( row ); } - { + if ( m.isUseNotificationPermission() || + !m.isUseNotificationPermission() && cmdPageData.isShowAll() ) { RowComponent row = new RowComponent(); row.addTextComponent( "&3Notifications Filtered by Permissions: %s", - ( m.isUseNotificationPermission() ? "&2Enabled" : "&dDisabled" ) ); - chatDisplay.addComponent( row ); - } - - { - RowComponent row = new RowComponent(); - row.addTextComponent( "&3Notification Permission: &7%s", - m.getMineNotificationPermissionName() ); + ( m.isUseNotificationPermission() ? + m.getMineNotificationPermissionName() : "&dDisabled" ) ); chatDisplay.addComponent( row ); } @@ -945,10 +1039,14 @@ else if ( !m.isMineAccessByRank() && m.isTpAccessByRank() ) { { - RowComponent row = new RowComponent(); - if ( m.isZeroBlockResetDisabled() ) { + + if ( m.isZeroBlockResetDisabled() && cmdPageData.isShowAll() ) { + RowComponent row = new RowComponent(); row.addTextComponent( "&3Zero Blocks Reset Delay: &cDISABLED"); - } else { + chatDisplay.addComponent( row ); + } + else if ( !m.isZeroBlockResetDisabled() ) { + RowComponent row = new RowComponent(); if ( m.getResetThresholdPercent() == 0 ) { row.addTextComponent( "&3Zero Blocks Reset Delay: &7%s &3Seconds", fFmt.format( m.getZeroBlockResetDelaySec() )); @@ -957,26 +1055,29 @@ else if ( !m.isMineAccessByRank() && m.isTpAccessByRank() ) { row.addTextComponent( "&7Threshold &3Reset Delay: &7%s &3Seconds", fFmt.format( m.getZeroBlockResetDelaySec() )); } + chatDisplay.addComponent( row ); } - chatDisplay.addComponent( row ); } if ( !m.isVirtual() ) { - RowComponent row = new RowComponent(); - if ( m.getResetThresholdPercent() == 0 ) { + if ( m.getResetThresholdPercent() == 0 && cmdPageData.isShowAll() ) { + RowComponent row = new RowComponent(); row.addTextComponent( "&3Reset Threshold: &cDISABLED"); - } else { + chatDisplay.addComponent( row ); + } + else if ( m.getResetThresholdPercent() > 0 ) { + RowComponent row = new RowComponent(); double blocks = m.getBounds().getTotalBlockCount() * m.getResetThresholdPercent() / 100.0d; row.addTextComponent( "&3Reset Threshold: &7%s &3Percent (&7%s &3blocks)", fFmt.format( m.getResetThresholdPercent() ), dFmt.format( blocks ) ); + chatDisplay.addComponent( row ); } - chatDisplay.addComponent( row ); } @@ -992,7 +1093,8 @@ else if ( !m.isMineAccessByRank() && m.isTpAccessByRank() ) { dFmt.format( m.getSkipResetBypassCount() )); chatDisplay.addComponent( row2 ); } - } else { + } + else if ( cmdPageData.isShowAll() ) { RowComponent row = new RowComponent(); row.addTextComponent( "&3Skip Mine Reset if no Activity: &cnot set"); chatDisplay.addComponent( row ); @@ -1024,7 +1126,7 @@ else if ( !m.isMineAccessByRank() && m.isTpAccessByRank() ) { } } - else { + else if ( cmdPageData.isShowAll() ) { RowComponent row = new RowComponent(); row.addTextComponent( "&3Mine Sweeper: &cDisabled&3 "); chatDisplay.addComponent( row ); @@ -1052,12 +1154,11 @@ else if ( !m.isMineAccessByRank() && m.isTpAccessByRank() ) { } - { + if ( cmdPageData.isShowAll() ) { chatDisplay.addText( "&3Block model: &7%s", ( m.isUseNewBlockModel() ? "New" : "Old") ); } - int blockSize = 0; if ( cmdPageData.isShowAll() || cmdPageData.getCurPage() > 1 ) { // if ( cmdPageData.isDebug() ) { // chatDisplay.addText( "&3Block model: &7%s", @@ -1070,28 +1171,29 @@ else if ( !m.isMineAccessByRank() && m.isTpAccessByRank() ) { BulletedListComponent list = getBlocksList(m, cmdPageData, true ); chatDisplay.addComponent(list); } - - if ( m.isUseNewBlockModel() ) { - blockSize = m.getPrisonBlocks().size(); - } - else { - blockSize = m.getBlocks().size(); - } - String message = blockSize != 0 ? null : " &cNo Blocks Defined"; - cmdPageData.generatePagedCommandFooter( chatDisplay, message ); - - chatDisplay.send(sender); - - // If show all, then include the mine's commands and blockEvents: - // These are different commands, so they will be in different chatDisplay objects - // so cannot weave them together: if ( cmdPageData.isShowAll() ) { - commandList( sender, m.getName() ); - blockEventList( sender, m.getName() ); + // Include all the commands for this mine: + ChatDisplay commandDisplay = minesCommandList( m ); + chatDisplay.addChatDisplay( commandDisplay ); + + + // Include all the blockEvent commands: + ChatDisplay blockEventDisplay = new ChatDisplay("BlockEvent Commands for " + m.getTag()); + blockEventDisplay.addText("&8Hover over values for more information and clickable actions."); + + generateBlockEventListing( m, blockEventDisplay, false ); + + blockEventDisplay.addComponent(new FancyMessageComponent( + new FancyMessage("&7[&a+&7] Add").suggest("/mines blockEvent add " + m.getName() + " [chance] [perm] [cmd] /") + .tooltip("&7Add a new BockEvent command."))); + + chatDisplay.addChatDisplay( blockEventDisplay ); } - } + + return chatDisplay; + } @@ -1194,8 +1296,6 @@ public void listCommand(CommandSender sender, @Arg(name = "page", def = "1", description = "Page of search results (optional) [1-n, ALL]") String page ) { - ChatDisplay display = new ChatDisplay("Mines"); - display.addText("&8Click a mine's name to see more information."); Player player = getPlayer( sender ); MineSortOrder sortOrder = MineSortOrder.fromString( sort ); @@ -1224,7 +1324,20 @@ else if ( sort != null ) { } } - PrisonMines pMines = PrisonMines.getInstance(); + ChatDisplay display = new ChatDisplay("Mines"); + display.addText("&8Click a mine's name to see more information."); + + + getMinesList( display, sortOrder, page, player ); + + + + display.send(sender); + } + + public void getMinesList( ChatDisplay display, MineSortOrder sortOrder, String page, Player player ) + { + PrisonMines pMines = PrisonMines.getInstance(); MineManager mMan = pMines.getMineManager(); @@ -1252,18 +1365,17 @@ else if ( sort != null ) { CommandPagedData cmdPageData = new CommandPagedData( "/mines list " + sortOrder.name(), sortedMines.getSortedList().size(), - 0, page, 7 ); + 0, page, 14 ); BulletedListComponent list = getMinesLineItemList(sortedMines, player, cmdPageData, mMan.isMineStats()); display.addComponent(list); - - cmdPageData.generatePagedCommandFooter( display ); - - display.send(sender); - } + cmdPageData.generatePagedCommandFooter( display ); + + + } private BulletedListComponent getMinesLineItemList( PrisonSortableResults sortedMines, Player player, @@ -1271,6 +1383,7 @@ private BulletedListComponent getMinesLineItemList( PrisonSortableResults sorted { BulletedListComponent.BulletedListBuilder builder = new BulletedListComponent.BulletedListBuilder(); + DecimalFormat dFmt = new DecimalFormat("#,##0"); DecimalFormat fFmt = new DecimalFormat("#,##0.00"); @@ -1302,42 +1415,26 @@ private BulletedListComponent getMinesLineItemList( PrisonSortableResults sorted } + String name = m.getName(); + if ( name.length() < 6 ) { + name += " ".substring( 0, (6-name.length()) ); + } row.addFancy( - new FancyMessage( String.format("&7%s ", m.getTag()) ) + new FancyMessage( String.format("&7%s ", name) ) .command("/mines info " + m.getName()) .tooltip("&7Mine " + m.getTag() + ": Click to view more info.")); - if ( m.getTag() != null && m.getTag().trim().length() > 0 ) { - row.addTextComponent( "%s ", m.getTag() ); - } - boolean hasCmds = m.getResetCommands().size() > 0; - if ( hasCmds ) { - row.addFancy( - new FancyMessage( String.format(" &cCmds: &7%s ", - Integer.toString( m.getResetCommands().size() )) ) - .command("/mines commands list " + m.getName()) - .tooltip("&7Click to view commands.")); - } - - - - if ( m.isVirtual() ) { - row.addFancy( - new FancyMessage( "&cVIRTUAL " ) - .command("/mines set area " + m.getName()) - .tooltip("&7Click to set the mine's area to make it a real mine. ")); + if ( m.getTag() != null && m.getTag().trim().length() > 0 ) { + String tag = m.getTag(); + String tagNoColor = Text.stripColor( tag ); + if ( tagNoColor.length() < 6 ) { + tag += " ".substring( 0, (6 - tagNoColor.length()) ); + } + row.addTextComponent( "%s ", tag ); } - if ( !m.isEnabled() ) { - row.addFancy( - new FancyMessage( "&cDISABLED!! " ) - .command("/mines info " + m.getName()) - .tooltip("&7Click to view possible reason why the mine is " + - "disabled. World may not exist? ")); - } - if ( !m.isVirtual() ) { row.addFancy( new FancyMessage("&eTP ").command("/mines tp " + m.getName()) @@ -1345,13 +1442,6 @@ private BulletedListComponent getMinesLineItemList( PrisonSortableResults sorted } - if ( m.isUsePagingOnReset() ) { - row.addFancy( - new FancyMessage("&5Paged ") - .tooltip("&7Paging Used during Mine Reset")); - } - - row.addTextComponent( " &3(&2R: " ); if ( !m.isVirtual() ) { @@ -1382,40 +1472,95 @@ private BulletedListComponent getMinesLineItemList( PrisonSortableResults sorted } - builder.add(row.getFancy()); + //builder.add(row.getFancy()); + if ( m.isVirtual() ) { + + row.addTextComponent( "&6Virtual Mine" ); + } - if ( !m.isVirtual() ) { - RowComponent row2 = new RowComponent(); + else { +// RowComponent row2 = new RowComponent(); // row2.addTextComponent( " &3Rem: " ); // Right justify the total blocks mined, with 1000's separators: - String blocksMined = " " + dFmt.format( m.getTotalBlocksMined() ); - blocksMined = blocksMined.substring( blocksMined.length() - 10); + String blocksMined = " " + dFmt.format( m.getTotalBlocksMined() ); +// String blocksMined = " " + dFmt.format( m.getTotalBlocksMined() ); + blocksMined = blocksMined.substring( blocksMined.length() - 8); - row2.addFancy( + row.addFancy( new FancyMessage( String.format(" %s &3Rem: ", blocksMined)). tooltip( "Blocks mined" ) ); - row2.addFancy( + row.addFancy( new FancyMessage(fFmt.format(m.getPercentRemainingBlockCount())). tooltip( "Percent Blocks Remaining" ) ); - row2.addTextComponent( "%% &3RCnt: &7" ); + row.addTextComponent( "%% &3RCnt: &7" ); - row2.addFancy( + row.addFancy( new FancyMessage(dFmt.format(m.getResetCount())). tooltip( "Times the mine was reset." ) ); if ( !m.isVirtual() ) { - row2.addTextComponent( " &3 Vol: &7" ); - row2.addFancy( + row.addTextComponent( " &3 Vol: &7" ); + row.addFancy( new FancyMessage(dFmt.format(m.getBounds().getTotalBlockCount())). tooltip( "Volume in Blocks" ) ); } + + + + boolean hasCmds = m.getResetCommands().size() > 0; + if ( hasCmds ) { + row.addFancy( + new FancyMessage( String.format(" &cCmds: &7%s ", + Integer.toString( m.getResetCommands().size() )) ) + .command("/mines commands list " + m.getName()) + .tooltip("&7Click to view commands.")); + } + + + + boolean hasBlockEvents = m.getBlockEvents().size() > 0; + if ( hasBlockEvents ) { + row.addFancy( + new FancyMessage( String.format(" &cbEvs: &7%s ", + Integer.toString( m.getBlockEvents().size() )) ) + .command("/mines blockEvent list " + m.getName()) + .tooltip("&7Click to view blockEvents.")); + } + + + + if ( m.isVirtual() ) { + row.addFancy( + new FancyMessage( "&cVIRTUAL " ) + .command("/mines set area " + m.getName()) + .tooltip("&7Click to set the mine's area to make it a real mine. ")); + } + + + if ( !m.isEnabled() ) { + row.addFancy( + new FancyMessage( "&cDISABLED!! " ) + .command("/mines info " + m.getName()) + .tooltip("&7Click to view possible reason why the mine is " + + "disabled. World may not exist? ")); + } + + + if ( m.isUsePagingOnReset() ) { + row.addFancy( + new FancyMessage("&5Paged ") + .tooltip("&7Paging Used during Mine Reset")); + } + + + // String noteMode = m.getNotificationMode().name() + // ( m.getNotificationMode() == MineNotificationMode.radius ? // " " + dFmt.format( m.getNotificationRadius() ) : "" ); @@ -1429,10 +1574,10 @@ private BulletedListComponent getMinesLineItemList( PrisonSortableResults sorted // // row.addTextComponent( "&7 - &b"); - builder.add(row2.getFancy()); } + builder.add(row.getFancy()); if ( !m.isVirtual() && isMineStatsEnabled ) { @@ -2050,8 +2195,15 @@ public void redefineCommand(CommandSender sender, "which is useful in void worlds or when flying and can be enlarged with " + "&7/mines set size help&3 . &2[&7wand feet&2]", def = "wand") String source, - @Arg(name = "confirm", description = "If the mine is greater than 20k blocks you will have " + - "to confirm the area.", def = "---") String confirm + @Wildcard(join=true) + @Arg(name = "options", description = " " + + "Options and confirmation for large mines. " + + "When setting a mine's area, if you use 'feet' for a source, you can also " + + "specify the of the walls and the of the mine and the " + + " of the mine. " + + "If the mine is greater than 20k blocks you will have " + + "to confirm the area with 'confirm' or 'yes' to ensure it does not destroy builds.", + def = "---") String options ) { if (!performCheckMineExists(sender, mineName)) { @@ -2097,14 +2249,20 @@ else if ( source == null || "wand".equalsIgnoreCase( source ) ) { DecimalFormat dFmt = new DecimalFormat("#,##0"); Bounds selectedBounds = selection.asBounds(); - if ( selectedBounds.getTotalBlockCount() > 20000 && - (confirm == null || !"yes".equalsIgnoreCase( confirm ) )) { + if ( selectedBounds.getTotalBlockCount() > 25000 && + (options == null || !options.toLowerCase().contains( "confirm" ) || + !options.toLowerCase().contains( "yes" ))) { String message = String.format( "&7Warning: This mine has a size of %s. If this is " + - "intentional, then please re-submit this command with a confirmation of 'yes' " + - "as a final parameter. ", dFmt.format( selectedBounds.getTotalBlockCount() ) ); + "intentional, then please re-submit this command with adding the " + + "keyword of either 'confirm' or 'yes' to the end of the command. ", + dFmt.format( selectedBounds.getTotalBlockCount() ) ); sender.sendMessage( message ); return; } + else if ( options.toLowerCase().contains( "confirm" ) || + !options.toLowerCase().contains( "yes" ) ) { + options = options.replace( "(?i)confirm|yes", "" ).trim(); + } // TODO check to see if they are the same boundaries, if not, don't change... @@ -2138,6 +2296,44 @@ else if ( source == null || "wand".equalsIgnoreCase( source ) ) { // adjustSize to zero to reset set all liners: m.adjustSize( Edges.walls, 0 ); + + if ( options.length() > 0 ) { + String[] opts = options.split( " " ); + + // Try to set the size of the wall: Increase by: + if ( opts.length > 0 ) { + try { + int size = Integer.parseInt( opts[0] ); + setSizeCommand( sender, mineName, "walls", size ); + } + catch ( Exception e ) { + // ignore error + } + } + + // Try to set the size of the bottom: Increase by: + if ( opts.length > 1 ) { + try { + int size = Integer.parseInt( opts[1] ); + setSizeCommand( sender, mineName, "bottom", size ); + } + catch ( Exception e ) { + // ignore error + } + } + + // Try to set the size of the wall: Increase by: + if ( opts.length > 2 ) { + try { + int size = Integer.parseInt( opts[2] ); + setSizeCommand( sender, mineName, "top", size ); + } + catch ( Exception e ) { + // ignore error + } + } + + } } @@ -2253,38 +2449,54 @@ public void moveMineCommand(CommandSender sender, } @Command(identifier = "mines set liner", permissions = "mines.set", - description = "Change the blocks that line the mine.") + description = "Change the blocks that line the mine, or change the way the ladders are generated. " + + "The liner will only generate if there are blocks where the liner is trying to be placed; this " + + "allows the liner to stop at ground level if the mine is higher than the surrounding ground. " + + "If the mine is generated in air, or in a void world, the liner will not be generated unless the " + + "'force' option is specified.") public void setLinerCommand(CommandSender sender, - @Arg(name = "mineName", description = "The name of the mine") String mineName, - @Arg(name = "edge", description = "Edge to use [top, bottom, north, east, south, west, walls]", def = "walls") String edge, - //@Arg(name = "adjustment", description = "How to adust the size [smaller, larger]", def = "larger") String adjustment, + @Arg(name = "mineName", description = "The name of the mine, or '*all*' to apply to all mines.") String mineName, + @Arg(name = "edge", description = "Edge to use [top, bottom, north, east, south, west, walls] " + + "Use 'ladderType' for the Edge: &3[&7none normal wide jumbo full&3] Where 'normal' is " + + "1 to 3 ladders wide. 'Wide' is up to 5 wide. 'Jumbo' is up to 7 wide. And 'full' " + + "is the full width.", def = "walls") String edge, + //@Arg(name = "adjustment", description = "How to adjust the size [smaller, larger]", def = "larger") String adjustment, @Arg(name = "pattern", description = "pattern to use. '?' for a list of all patterns. " + "'repair' will attempt to repair missing blocks outside of the liner. " + - "'remove' will remove the liner from the mine. 'removeAll' removes alll liners. [?]", + "'remove' will remove the liner from the mine. 'removeAll' removes all liners from the mine. [?]", def = "bright") String pattern, @Arg(name = "force", description = "Force liner if air [force no]", def = "no") String force ) { - if (!performCheckMineExists(sender, mineName)) { - return; - } - - if ( pattern != null && "?".equals( pattern ) || edge != null && "?".equals( edge )) { + if ( mineName != null && "?".equals( mineName ) || + pattern != null && "?".equals( pattern ) || edge != null && "?".equals( edge )) { sender.sendMessage( "&cAvailable Edges: &3[&7top bottom north east south west walls&3]" ); sender.sendMessage( "&3Available Patterns: [&7" + LinerPatterns.toStringAll() + "&3]" ); + sender.sendMessage( "&cUse 'ladderType' for the Edge: &3[&7none normal wide jumbo full&3] Where 'normal' is " + + "1 to 3 ladders wide. 'Wide' is up to 5 wide. 'Jumbo' is up to 7 wide. And 'full' is the full width." ); + return; + } + + if ( !"*all*".equalsIgnoreCase( mineName ) && !performCheckMineExists(sender, mineName)) { return; } Edges e = Edges.fromString( edge ); - if ( e == null ) { + LinerPatterns linerPattern = LinerPatterns.fromString( pattern ); + LadderType ladderType = ( e == null && edge != null && edge.equalsIgnoreCase( "ladderType" ) ? + LadderType.fromString( pattern ) : null ); + + + + if ( e == null && ladderType == null ) { sender.sendMessage( "&cInvalid edge value. &3[&7top bottom north east south west walls&3]" ); + sender.sendMessage( "&cUse 'ladderType' for the Edge with &3[&7none normal wide jumbo full&3] as the patterns." ); return; } - LinerPatterns linerPattern = LinerPatterns.fromString( pattern ); - if ( linerPattern == null ) { + if ( linerPattern == null && ladderType == null ) { sender.sendMessage( "&cInvalid pattern.&3 Select one of these: [&7" + LinerPatterns.toStringAll() + "&3]" ); return; @@ -2301,28 +2513,56 @@ else if ( "force".equalsIgnoreCase( force ) ) { } PrisonMines pMines = PrisonMines.getInstance(); - Mine mine = pMines.getMine(mineName); -// if ( mine.isVirtual() ) { -// sender.sendMessage( "&cMine is a virtual mine.&7 Use &a/mines set area &7to enable the mine." ); -// return; -// } + List mines = new ArrayList<>(); - if ( linerPattern == LinerPatterns.removeAll ) { - - mine.getLinerData().removeAll(); - sender.sendMessage( "&7All liners have been removed from mine " + mine.getName() ); - } - else if ( linerPattern == LinerPatterns.remove ) { - mine.getLinerData().remove( e ); - sender.sendMessage( "&7The liner for the " + e.name() + " has been removed from mine " + mine.getName() ); + if ( "*all*".equalsIgnoreCase( mineName ) ) { + mines.addAll( pMines.getMines() ); } else { - mine.getLinerData().setLiner( e, linerPattern, isForced ); - new MineLinerBuilder( mine, e, linerPattern, isForced ); + mines.add( pMines.getMine(mineName) ); + } - pMines.getMineManager().saveMine( mine ); + for ( Mine mine : mines ) + { + boolean resetLiner = false; + +// if ( mine.isVirtual() ) { +// sender.sendMessage( "&cMine is a virtual mine.&7 Use &a/mines set area &7to enable the mine." ); +// return; +// } + if ( ladderType != null ) { + mine.getLinerData().setLadderType( ladderType ); + sender.sendMessage( "&7The liner's ladderType has been set to '" + ladderType.name() + + "' for mine " + mine.getName() ); + + resetLiner = true; + } + else if ( linerPattern == LinerPatterns.removeAll ) { + + mine.getLinerData().removeAll(); + sender.sendMessage( "&7All liners have been removed from mine " + mine.getName() ); + } + else if ( linerPattern == LinerPatterns.remove ) { + mine.getLinerData().remove( e ); + sender.sendMessage( "&7The liner for the " + e.name() + " has been removed from mine " + mine.getName() ); + } + else { + mine.getLinerData().setLiner( e, linerPattern, isForced ); + + resetLiner = true; + } + + pMines.getMineManager().saveMine( mine ); + + // Do not try to update the liner if it's a virtual mine: + if ( resetLiner && !mine.isVirtual() ) { + + new MineLinerBuilder( mine, e, linerPattern, isForced ); + } + + } } @@ -2813,14 +3053,14 @@ private void generateBlockEventListing( Mine m, ChatDisplay display, boolean inc DecimalFormat dFmt = new DecimalFormat("0.00000"); - int rowNumber = 1; + int rowNumber = 0; for (MineBlockEvent blockEvent : m.getBlockEvents()) { RowComponent row = new RowComponent(); String chance = dFmt.format( blockEvent.getChance() ); - row.addTextComponent( " &3Row: &d%d ", rowNumber++ ); + row.addTextComponent( " &3Row: &d%d ", ++rowNumber ); FancyMessage msgPercent = new FancyMessage( String.format( "&7%s%% ", chance ) ) .suggest( "/mines blockEvent percent " + m.getName() + " " + rowNumber + " [%]" ) @@ -2976,29 +3216,35 @@ public void blockEventRemove(CommandSender sender, - @Command(identifier = "mines blockEvent add", description = "Adds a BlockBreak command to a mine. " + + @Command(identifier = "mines blockEvent add", description = "Adds a BlockBreak command to a mine. " + + "For each block that is broke there will be a chance to run one of these commands. \n" + "To send messages use {msg} or {broadcast} followed by the formatted message. " + - "Can use placeholders {player} and {player_uid}. Use ; between multiple commands. " + - "Example: 'token give {player} 1;{msg} &7You got &31 &7token!;tpa a'", - onlyPlayers = false, permissions = "mines.set") + "Can use placeholders {player} and {player_uid}. Use ; between multiple commands. \n" + + "Example: &7\\Q'token give {player} 1;{msg} &7You got &31 &7token!;tpa a'\\E&3 \n" + + "This command defaults to no permission and 'sync' task mode; " + + "see '/mines blockEvent' for more blockEvent options.", + onlyPlayers = false, permissions = "mines.set", + docURLs = {"https://prisonteam.github.io/Prison/prison_docs_115_using_BlockEvents.html", + "https://prisonteam.github.io/Prison/prison_docs_111_mine_commands.html" } ) public void blockEventAdd(CommandSender sender, - @Arg(name = "mineName", description = "mine name, or 'placeholders' for a list of possible placeholders that " + + @Arg(name = "mineName", description = "mine name, '*all*' to apply to all mines, or " + + "'placeholders' for a list of possible placeholders that " + "you can use with blockEvents") String mineName, @Arg(name = "percent", def = "100.0", description = "Percent chance between 0.0000 and 100.0") Double chance, - @Arg(name = "permission", def = "none", - description = "Optional permission that the player must have, or [none] for no perm." - ) String perm, +// @Arg(name = "permission", def = "none", +// description = "Optional permission that the player must have, or [none] for no perm." +// ) String perm, // @Arg(name = "eventType", def = "eventTypeAll", // description = "EventType to trigger BlockEvent: [eventTypeAll, eventBlockBreak, eventTEXplosion]" // ) String eventType, // @Arg(name = "triggered", def = "none", // description = "TE Explosion Triggered sources. Requires TokenEnchant v18.11.0 or newer. [none, ...]" // ) String triggered, - @Arg(name = "taskMode", description = "Processing task mode to run the task as console. " + - "Player runs as player. " + - "[inline, inlinePlayer, sync, syncPlayer]", - def = "inline") String mode, +// @Arg(name = "taskMode", description = "Processing task mode to run the task as console. " + +// "Player runs as player. " + +// "[inline, inlinePlayer, sync, syncPlayer]", +// def = "inline") String mode, @Arg(name = "command") @Wildcard String command) { // Note: async is not an option since the bukkit dispatchCommand will run it as sync. @@ -3017,16 +3263,20 @@ public void blockEventAdd(CommandSender sender, String message = String.format( "Valid Placeholders that can be used with blockEvents: [%s]", placeholders ); - Output.get().logInfo( message ); + sender.sendMessage( message ); return; } + String perm = "none"; + String mode = "sync"; // "inline"; if (command.startsWith("/")) { command = command.replaceFirst("/", ""); } - if (!performCheckMineExists(sender, mineName)) { + if ( mineName == null && !performCheckMineExists(sender, mineName) || + mineName != null && !"*all*".equalsIgnoreCase( mineName ) && + !performCheckMineExists(sender, mineName)) { return; } @@ -3072,46 +3322,63 @@ public void blockEventAdd(CommandSender sender, // } - setLastMineReferenced(mineName); - - PrisonMines pMines = PrisonMines.getInstance(); -// MineManager mMan = pMines.getMineManager(); - Mine m = pMines.getMine(mineName); - if ( command == null || command.trim().length() == 0 ) { sender.sendMessage( String.format( "&7Please provide a valid BlockEvent command: command=[%s]", command) ); return; } - MineBlockEvent blockEvent = new MineBlockEvent( chance, perm, command, taskMode ); - m.getBlockEvents().add( blockEvent ); - - pMines.getMineManager().saveMine( m ); - Output.get().sendInfo(sender, "&7Added BlockEvent command '&b%s&7' " + - "&7to the mine '&b%s&7' with " + - "the optional permission %s. Using the mode %s.", - command, m.getTag(), - perm == null || perm.trim().length() == 0 ? "&3none&7" : "'&3" + perm + "&7'", - mode ); - - String.format("&7Notice: &3The default eventType has been set to &7all&3. If you need " + - "to change it to something else, then use the command &7/mines blockEvent eventType help&3. " + - "[all, blockBreak, TEXplosion] The event type is what causes the block to break. " + - "Token Enchant's Explosion events are covered and can be focused with the " + - "triggered parameter." ); - + PrisonMines pMines = PrisonMines.getInstance(); +// MineManager mMan = pMines.getMineManager(); + + List mines = new ArrayList<>(); + + if ( "*all*".equalsIgnoreCase( mineName ) ) { + mines.addAll( pMines.getMines() ); + } + else { + setLastMineReferenced(mineName); + + Mine m = pMines.getMine(mineName); + mines.add( m ); + } + for ( Mine m : mines ) + { + + MineBlockEvent blockEvent = new MineBlockEvent( chance, perm, command, taskMode ); + m.getBlockEvents().add( blockEvent ); + + pMines.getMineManager().saveMine( m ); + + Output.get().sendInfo(sender, "&7Added BlockEvent command '&b%s&7' " + + "&7to the mine '&b%s&7' with " + + "the optional permission %s. Using the mode %s.", + command, m.getTag(), + perm == null || perm.trim().length() == 0 ? "&3none&7" : "'&3" + perm + "&7'", + mode ); + +// String.format("&7Notice: &3The default eventType has been set to &7all&3. If you need " + +// "to change it to something else, then use the command &7/mines blockEvent eventType help&3. " + +// "[all, blockBreak, TEXplosion] The event type is what causes the block to break. " + +// "Token Enchant's Explosion events are covered and can be focused with the " + +// "triggered parameter." ); + + // if ( eType == BlockEventType.eventTEXplosion ) { // sender.sendMessage( "&7Notice: &3Since the event type is for TokenEnchant's eventTEXplosion, " + // "then you may set the value of &7triggered&7 with the command " + // "&7/mines blockEvent triggered help&3." ); // } + } - // Redisplay the event list: - blockEventList( sender, mineName ); + if ( !"*all*".equalsIgnoreCase( mineName ) ) { + + // Redisplay the event list: + blockEventList( sender, mineName ); + } } @@ -3874,37 +4141,44 @@ public void commandList(CommandSender sender, } - ChatDisplay display = new ChatDisplay("ResetCommand for " + m.getName()); - display.addText("&8Click a command to remove it."); - BulletedListComponent.BulletedListBuilder builder = - new BulletedListComponent.BulletedListBuilder(); + ChatDisplay display = minesCommandList( m ); + + display.send(sender); + } - int rowNumber = 1; - for (String command : m.getResetCommands()) { - - - RowComponent row = new RowComponent(); - - row.addTextComponent( " &3Row: &d%d ", rowNumber++ ); - - FancyMessage msg = new FancyMessage( "&a'&7" + command + "&a'" ); - row.addFancy( msg ); - - FancyMessage msgRemove = new FancyMessage( " &4Remove&3" ) - .suggest("/mines command remove " + m.getName() + " " + rowNumber ) - .tooltip("Click to Remove this Mine Command"); - row.addFancy( msgRemove ); - - builder.add( row ); +private ChatDisplay minesCommandList( Mine m ) +{ + ChatDisplay display = new ChatDisplay("ResetCommand for " + m.getName()); + display.addText("&8Click a command to remove it."); + BulletedListComponent.BulletedListBuilder builder = + new BulletedListComponent.BulletedListBuilder(); - } + int rowNumber = 1; + for (String command : m.getResetCommands()) { + + + RowComponent row = new RowComponent(); + + row.addTextComponent( " &3Row: &d%d ", rowNumber++ ); + + FancyMessage msg = new FancyMessage( "&a'&7" + command + "&a'" ); + row.addFancy( msg ); + + FancyMessage msgRemove = new FancyMessage( " &4Remove&3" ) + .suggest("/mines command remove " + m.getName() + " " + rowNumber ) + .tooltip("Click to Remove this Mine Command"); + row.addFancy( msgRemove ); - display.addComponent(builder.build()); - display.addComponent(new FancyMessageComponent( - new FancyMessage("&7[&a+&7] Add").suggest("/mines command add " + mineName + " /") - .tooltip("&7Add a new command."))); - display.send(sender); - } + builder.add( row ); + + } + + display.addComponent(builder.build()); + display.addComponent(new FancyMessageComponent( + new FancyMessage("&7[&a+&7] Add").suggest("/mines command add " + m.getName() + " /") + .tooltip("&7Add a new command."))); + return display; +} @Command(identifier = "mines command remove", description = "Removes a command from a mine.", @@ -3996,7 +4270,7 @@ public void commandAdd(CommandSender sender, String message = String.format( "Valid Placeholders that can be used with mine commands: [%s]", placeholders ); - Output.get().logInfo( message ); + sender.sendMessage( message ); return; } @@ -4032,8 +4306,9 @@ public void commandAdd(CommandSender sender, pMines.getMineManager().saveMine( m ); - Output.get().sendInfo(sender, "&7Added command '&b%s&7' to the mine '&b%s&7'.", - newComand, m.getTag()); + sender.sendMessage( + String.format( "&7Added command '&b%s&7' to the mine '&b%s&7'.", + newComand, m.getTag()) ); } diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java index 85aca88e6..a45907205 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineData.java @@ -141,6 +141,8 @@ public abstract class MineData private long mineSweeperTotalMs; private long mineSweeperBlocksChanged; + private transient boolean isDeleted = false; + public enum MineNotificationMode { disabled, @@ -705,7 +707,7 @@ public void resetUnsavedBlockCounts() { blockStats.setBlockCountUnsaved( 0 ); // Reset the block count for the reset event since the mine will be regenerated: - blockStats.setResetBlockCount( 0 ); + blockStats.setBlockPlacedCount( 0 ); } } @@ -714,13 +716,21 @@ public void resetResetBlockCounts() { for ( PrisonBlockStatusData block : getBlocks() ) { // Reset the block count for the reset event since the mine will be regenerated: - block.setResetBlockCount( 0 ); + block.setBlockPlacedCount( 0 ); + block.setRangeBlockCountLow( -1 ); + block.setRangeBlockCountHigh( -1 ); + block.setRangeBlockCountLowLimit( -1 ); + block.setRangeBlockCountHighLimit( -1 ); } for ( PrisonBlockStatusData block : getPrisonBlocks() ) { // Reset the block count for the reset event since the mine will be regenerated: - block.setResetBlockCount( 0 ); + block.setBlockPlacedCount( 0 ); + block.setRangeBlockCountLow( -1 ); + block.setRangeBlockCountHigh( -1 ); + block.setRangeBlockCountLowLimit( -1 ); + block.setRangeBlockCountHighLimit( -1 ); } // for ( PrisonBlockStatusData blockStats : getBlockStats().values() ) { @@ -1260,4 +1270,11 @@ public void setMineSweeperBlocksChanged( long mineSweeperBlocksChanged ) { this.mineSweeperBlocksChanged = mineSweeperBlocksChanged; } + public boolean isDeleted() { + return isDeleted; + } + public void setDeleted( boolean isDeleted ) { + this.isDeleted = isDeleted; + } + } diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineReset.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineReset.java index 680ffd0c9..541d3e6fb 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineReset.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/data/MineReset.java @@ -171,6 +171,12 @@ protected void initialize() { *

*/ protected void resetSynchonously() { + + if ( isDeleted() ) { + // if the mine is deleted, just return without doing anything. This will + // cancel the job. + return; + } long start = System.currentTimeMillis(); @@ -204,8 +210,9 @@ protected void resetSynchonously() { private void resetSynchonouslyInternal() { try { - if ( isVirtual() ) { + if ( isVirtual() || isDeleted() ) { // Mine is virtual and cannot be reset. Just skip this with no error messages. + // If the mine is deleted, just return without doing anything. return; } @@ -493,7 +500,7 @@ public int getPlayerCount() { */ protected void generateBlockListAsync() { - if ( isVirtual() ) { + if ( isVirtual() || isDeleted() ) { // ignore and generate no error messages: return; } @@ -520,6 +527,10 @@ protected void generateBlockListAsync() { resetResetBlockCounts(); + // setup the monitoring of the blocks that have constraints: + List constrainedBlocks = null; + + int airCount = 0; int currentLevel = 0; @@ -535,6 +546,9 @@ protected void generateBlockListAsync() { if ( isUseNewBlockModel() ) { + // track the constraints: + trackConstraints( currentLevel, constrainedBlocks ); + PrisonBlock prisonBlock = randomlySelectPrisonBlock( random, currentLevel ); // Increment the mine's block count. This block is one of the control blocks: @@ -589,7 +603,60 @@ protected void generateBlockListAsync() { } - /** + private void trackConstraints( int currentLevel, List constrainedBlocks ) + { + + // If the constrainedBlocks list has not be configured, set it up with the + // blocks that have constraints: + if ( constrainedBlocks == null ) { + + constrainedBlocks = new ArrayList<>(); + + for (PrisonBlock block : getPrisonBlocks()) { + if ( block.getConstraintExcludeTopLayers() > 0 || + block.getConstraintExcludeBottomLayers() > 0 ) { + + constrainedBlocks.add( block ); + } + } + } + + + // If there are any constrained blocks, then need to record + for ( PrisonBlockStatusData block : constrainedBlocks ) { + + // If exclude top layers is enabled, then only try to set the + // rangeBlockCountLowLimit once since we need the lowest possible + // value. The inital value for getRangeBlockCountLowLimit is -1. + if ( block.getConstraintExcludeTopLayers() > 0 && + block.getRangeBlockCountLowLimit() <= 0 && + currentLevel > block.getConstraintExcludeTopLayers() ) { + + int targetBlockPosition = getMineTargetPrisonBlocks().size(); + block.setRangeBlockCountLowLimit( targetBlockPosition ); + } + + // If exclude bottom layer is enabled, then we need to track every number + // until the currentLevel exceeds the getConstraintExcludeBottomLayers value. + // If exclude top layers, then do not record for the bottom layers until + // the top layers is cleared. + if ( (block.getConstraintExcludeTopLayers() > 0 && + currentLevel > block.getConstraintExcludeTopLayers() || + block.getConstraintExcludeTopLayers() == 0) && + + block.getConstraintExcludeBottomLayers() > 0 && + block.getConstraintExcludeBottomLayers() < currentLevel + ) { + + int targetBlockPosition = getMineTargetPrisonBlocks().size(); + block.setRangeBlockCountHighLimit( targetBlockPosition ); + + } + } + + } + + /** *

Yeah I know, it has async in the name of the function, but it still can only * be ran synchronously. The async part implies this is the reset "part" for the * async workflow. @@ -1353,43 +1420,48 @@ private void constraintsApplyMin( PrisonBlockStatusData block, boolean useNewBlo { if ( block.getConstraintMin() > 0 ) { - int maxAttempts = (block.getConstraintMin() - block.getResetBlockCount()) * 3; - for ( int i = 0; i < maxAttempts && block.getResetBlockCount() < block.getConstraintMin(); i++ ) { + int maxAttempts = (block.getConstraintMin() - block.getBlockPlacedCount()) * 3; + for ( int i = 0; i < maxAttempts && block.getBlockPlacedCount() < block.getConstraintMin(); i++ ) { // int maxSize = getMineTargetPrisonBlocks().size(); - int rangeLow = block.getRangeBlockCountLow(); - int rangeHigh = block.getRangeBlockCountHigh(); + int rangeLow = block.getRangeBlockCountLowLimit(); + int rangeHigh = block.getRangeBlockCountHighLimit(); +// int rangeLow = block.getRangeBlockCountLow(); +// int rangeHigh = block.getRangeBlockCountHigh(); // Each block has a valid range in which it can spawn in the mine. This range // is honored by using the rangeHigh and rangeLow values. int rndPos = ((int) Math.round( Math.random() * (rangeHigh - rangeLow) )) + rangeLow; - MineTargetPrisonBlock targetBlock = getMineTargetPrisonBlocks().get( rndPos ); - - if ( targetBlock != null && - targetBlock.getPrisonBlock().getConstraintMin() == 0 && - targetBlock.getPrisonBlock().getConstraintMax() == 0 && - !targetBlock.getPrisonBlock().getBlockName().equalsIgnoreCase( - block.getBlockName() ) ) { + if ( rndPos < getMineTargetPrisonBlocks().size() ) { + + MineTargetPrisonBlock targetBlock = getMineTargetPrisonBlocks().get( rndPos ); - // decrement the block count on the block being removed: - if ( targetBlock.getPrisonBlock().isAir() ) { + if ( targetBlock != null && + targetBlock.getPrisonBlock().getConstraintMin() == 0 && + targetBlock.getPrisonBlock().getConstraintMax() == 0 && + !targetBlock.getPrisonBlock().getBlockName().equalsIgnoreCase( + block.getBlockName() ) ) { - // Need to remove one from the air count fields: - setAirCountOriginal( getAirCountOriginal() - 1 ); - setAirCount( getAirCount() - 1 ); + // decrement the block count on the block being removed: + if ( targetBlock.getPrisonBlock().isAir() ) { + + // Need to remove one from the air count fields: + setAirCountOriginal( getAirCountOriginal() - 1 ); + setAirCount( getAirCount() - 1 ); + + } + else { + targetBlock.getPrisonBlock().decrementResetBlockCount(); + } + + // Add the new block and increment it's count: + targetBlock.setPrisonBlock( block ); + block.incrementResetBlockCount(); } - else { - targetBlock.getPrisonBlock().decrementResetBlockCount(); - } - - - // Add the new block and increment it's count: - targetBlock.setPrisonBlock( block ); - block.incrementResetBlockCount(); } } } 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 593b64926..1cea8ac3c 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 @@ -462,8 +462,11 @@ private void submitTask() { * */ public void terminateJob() { - getJobStack().clear(); + setDeleted( true ); + + getJobStack().clear(); + int taskId = getTaskId(); PrisonTaskSubmitter.cancelTask( taskId ); @@ -591,7 +594,7 @@ private void processBlockEventDetails( Player player, PrisonBlock prisonBlock, cmdTask.addCustomPlaceholder( CustomPlaceholders.blockChance, dFmt.format( originalBlock.getChance() ) ); - cmdTask.addCustomPlaceholder( CustomPlaceholders.blocksPlaced, Integer.toString( originalBlock.getResetBlockCount() )); + cmdTask.addCustomPlaceholder( CustomPlaceholders.blocksPlaced, Integer.toString( originalBlock.getBlockPlacedCount() )); cmdTask.addCustomPlaceholder( CustomPlaceholders.blockRemaining, Long.toString( originalBlock.getBlockCountUnsaved() )); cmdTask.addCustomPlaceholder( CustomPlaceholders.blocksMinedTotal, originalBlock.getBlockName() ); diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineBlockEvent.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineBlockEvent.java index dfb92b445..ea8cc5778 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineBlockEvent.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineBlockEvent.java @@ -28,10 +28,12 @@ public enum BlockEventType { blockBreak, TEXplosion, CEXplosion, + PEExplosive, // PrisonEnchant: Pulsi_'s plugin eventTypeAll( all ), eventBlockBreak( blockBreak ), - eventTEXplosion( TEXplosion ); + eventTEXplosion( TEXplosion ) + ; private final BlockEventType primaryEventType; diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineLinerBuilder.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineLinerBuilder.java index a3ab241b1..81aad5ad0 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineLinerBuilder.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineLinerBuilder.java @@ -2,12 +2,15 @@ import java.util.ArrayList; import java.util.List; +import java.util.Random; +import tech.mcprison.prison.Prison; import tech.mcprison.prison.internal.World; import tech.mcprison.prison.internal.block.Block; import tech.mcprison.prison.internal.block.BlockFace; import tech.mcprison.prison.internal.block.PrisonBlock; import tech.mcprison.prison.mines.data.Mine; +import tech.mcprison.prison.mines.features.MineLinerData.LadderType; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.util.BlockType; import tech.mcprison.prison.util.Bounds; @@ -30,32 +33,64 @@ public class MineLinerBuilder { public enum LinerPatterns { - bright, - white, + bright( 1, 8 ), + white( 1, 8 ), - blackAndWhite, - seaEchos, - obby, - bedrock, - glowingPlanks, - darkOakPrismarine, - beacon, - bricked, + blackAndWhite( 1, 8 ), + seaEchos( 1, 8 ), + obby( 1, 8 ), + bedrock( 1, 8 ), + glowstone( 1, 8 ), + glowingPlanks( 1, 8 ), + darkOakPrismarine( 1, 8 ), + beacon( 1, 8 ), + bricked( 1, 8 ), - darkForest, - theColors, + darkForest( 1, 8 ), + theColors( 1, 8 ), - stronghold, - ruins, - zaged, - crimsonWaste, - cryingGold, + stronghold( 1, 17 ), // deepslate_bricks + ruins( 1, 16 ), // blackstone + zaged( 1, 16 ), // crying_obsidian + crimsonWaste( 1, 16 ), // crimson_hyphae + cryingGold( 1, 16 ), // crying_obsidian repair, remove, removeAll ; + private final int versionMajor; + private final int versionMinor; + private final boolean pattern; + + private LinerPatterns( int versionMajor, int versionMinor ) { + + this.versionMajor = versionMajor; + this.versionMinor = versionMinor; + + this.pattern = true; + } + private LinerPatterns() { + + this.versionMajor = 1; + this.versionMinor = 8; + + this.pattern = false; + } + + public int getVersionMajor() { + return versionMajor; + } + + public int getVersionMinor() { + return versionMinor; + } + + public boolean isPattern() { + return pattern; + } + public static LinerPatterns fromString( String pattern ) { LinerPatterns results = null; @@ -70,21 +105,64 @@ public static LinerPatterns fromString( String pattern ) { return results; } + /** + *

This function will provide a list of all patterns available, filtered + * on compatible versions of the blocks used for the server version. This + * also include non-patterns too. + *

+ * + * @return + */ public static String toStringAll() { StringBuilder sb = new StringBuilder(); + List verMajMin = Prison.get().getMVersionMajMin(); + int versionMin = verMajMin.size() > 1 ? verMajMin.get(1) : 8; + for ( LinerPatterns pattern : values() ) { - if ( sb.length() > 0 ) { - sb.append( " " ); + if ( !pattern.isPattern() || + pattern.isPattern() && pattern.getVersionMinor() <= versionMin ) { + + if ( sb.length() > 0 ) { + sb.append( " " ); + } + + sb.append( pattern.name() ); } - - sb.append( pattern.name() ); } return sb.toString(); } + + /** + *

Will try to get a random liner pattern, filtered by + * non-patterns (repair, remove, removeAll) and for liners that + * would be incompatible for the given version of minecraft or spigot. + *

+ * + * @return + */ + public static LinerPatterns getRandomLinerPattern() { + LinerPatterns results = null; + + List verMajMin = Prison.get().getMVersionMajMin(); + int versionMin = verMajMin.size() > 1 ? verMajMin.get(1) : 8; + + int attempts = 0; + while ( results == null && attempts++ < 10 ) { + + int pos = new Random().nextInt( values().length ); + LinerPatterns temp = values()[pos]; + if ( temp.isPattern() && temp.getVersionMinor() <= versionMin ) { + results = temp; + } + } + + return results == null ? bright : results; + } + } /** @@ -403,8 +481,9 @@ else if ( isForced || * equal to min or max (the corners). *

* - *

If the mine on the edge is 3 blocks or less in width, have them all - * be ladders. + *

This now support multiple ladder types such as: none and full. And + * normal, wide, and jumbo. + *

* * @param curr * @param min @@ -415,6 +494,15 @@ private boolean isLadderBlock( int curr, int min, int max ) { boolean results = false; + if ( getLadderType() == LadderType.none ) { + return results; + } + + // Note: full ladder cannot include both ends since those are the other walls. + if ( getLadderType() == LadderType.full ) { + return curr > min && curr < max; + } + // Skip if the face or corners of liner. if ( min != max && curr != min && curr != max ) { @@ -426,24 +514,75 @@ private boolean isLadderBlock( int curr, int min, int max ) { // The following is actually 3 blocks since max and min are // skipped due to being corners. So if the min is 1 to 3 blocks // wide, always have ladders that wide. - results = len <= 5; - if ( len > 5 ) { - + int range = 1; + switch ( getLadderType() ) + { + case wide: + range = 2; + break; - if ( curr == (min + mid) ) { - results = true; - } - else { - results = isEven ? - // if distance is even, then next ladder position is mid - 1 - ( curr == min + mid + 1 ) : - // If odd, then one above and below mid: - ( curr == min + mid + 1 || curr == min + mid - 1); - } - + case jumbo: + range = 3; + break; + + case normal: + default: + range = 1; } - + + results = isEven ? + // if distance is even, then next ladder position is mid - range + 1 through mid + range + ( curr >= (min + mid - range + 1) && curr <= (min + mid + range ) ) : + + // If odd, then plus/minus range above and below mid: + ( curr >= (min + mid - range) && curr <= (min + mid + range)); + + +// if ( getLadderType() == LadderType.normal ) { +// +// results = len <= 5; +// +// if ( len > 5 ) { +// +// +// if ( curr == (min + mid) ) { +// results = true; +// } +// else { +// results = isEven ? +// // if distance is even, then next ladder position is mid - 1 +// ( curr == min + mid + 1 ) : +// // If odd, then one above and below mid: +// ( curr == min + mid + 1 || curr == min + mid - 1); +// } +// +// } +// +// } +// else if ( getLadderType() == LadderType.wide ) { +// +// results = len <= 7; +// +// if ( len > 7 ) { +// +// +// if ( curr == (min + mid) ) { +// results = true; +// } +// else { +// results = isEven ? +// // if distance is even, then next ladder position is mid - 1 through mid + 2 +// ( curr >= (min + mid - range + 1) && curr <= (min + mid + range ) ) : +// +// // If odd, then one above and below mid: +// ( curr >= (min + mid - range) && curr <= (min + mid + range)); +// } +// +// } +// } + + // Output.get().logInfo( "#### isLadderBlock: curr=%d min=%d max=%d " + // " len=%d mid=%d " + // "isEven=%s results=%s " + @@ -527,8 +666,8 @@ private void select2DPattern( Edges edge ) { case blackAndWhite: String[][] baw = { - { "obsidian", "pillar_quartz_block" }, - { "pillar_quartz_block", "coal_block" } + { "obsidian", "quartz_pillar" }, + { "quartz_pillar", "coal_block" } }; pattern2d = baw; break; @@ -537,9 +676,9 @@ private void select2DPattern( Edges edge ) { case seaEchos: String[][] seaEchos = { - { "pillar_quartz_block", "pillar_quartz_block", "pillar_quartz_block" }, - { "pillar_quartz_block", "obsidian", "obsidian" }, - { "pillar_quartz_block", "obsidian", "sea_lantern" }, + { "quartz_pillar", "quartz_pillar", "quartz_pillar" }, + { "quartz_pillar", "obsidian", "obsidian" }, + { "quartz_pillar", "obsidian", "sea_lantern" }, }; pattern2d = seaEchos; break; @@ -652,6 +791,15 @@ private void select2DPattern( Edges edge ) { break; + case glowstone: + String[][] glowstone = + { + { "glowstone" } + }; + pattern2d = glowstone; + break; + + case glowingPlanks: String[][] glowingPlanks = { @@ -869,6 +1017,33 @@ protected void apply2Dto3DPattern( Edges edge, String[][] pattern2d ) } + +// public boolean isPatternValidForSpigotVersion() { +// boolean results = true; +// +// try { +// +// String v = Prison.get().getMinecraftVersion(); +// +// String versionStr = v.substring( v.indexOf( "(MC:" ) + 4, v.lastIndexOf( "." ) ); +// +// +// Output.get().logInfo( "#### MineLinerBuilder : " + +// getPattern() + " " + getPatternMinVersion() + " : " + +// "Prison Version: " + v + " " + versionStr ); +// +// double version = Double.parseDouble( versionStr ); +// +// if ( version < getPatternMinVersion() ) { +// +// } +// } +// catch ( NumberFormatException e ) { +// // ignore... just use all patterns +// } +// +// return results; +// } public List>> getPattern3d() { return pattern3d; @@ -904,5 +1079,9 @@ public boolean isForced() { public void setForced( boolean isForced ) { this.isForced = isForced; } + + public LadderType getLadderType() { + return mine.getLinerData().getLadderType(); + } } diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineLinerData.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineLinerData.java index ad1d26b47..69492ca76 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineLinerData.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/features/MineLinerData.java @@ -25,6 +25,29 @@ public class MineLinerData { private boolean forceTop; private boolean forceBottom; + private LadderType ladderType; + + public enum LadderType { + none, + normal, + wide, + jumbo, + full; + + public static LadderType fromString( String value ) { + LadderType results = null; + + for ( LadderType ladder : values() ) + { + if ( ladder.name().equalsIgnoreCase( value ) ) { + results = ladder; + } + } + + return results; + } + } + public MineLinerData() { super(); @@ -48,6 +71,8 @@ public MineLinerData() { this.forceTop = false; this.forceBottom = false; + + this.ladderType = LadderType.normal; } public MineLinerData( String walls, String bottom ) { @@ -96,6 +121,8 @@ private String generateStringValue( String color1, String color2 ) { addSaveString( sb, Edges.top, getTop(), isForceTop(), color1, color2 ); addSaveString( sb, Edges.bottom, getBottom(), isForceBottom(), color1, color2 ); + addSaveString( sb, getLadderType(), color1, color2 ); + return sb.toString(); } @@ -125,8 +152,31 @@ private void addSaveString( StringBuilder sb, Edges edge, String value, } } + /** + *

This builds the entry for the ladderType. If the StringBuilder is + * empty, then do not generate the ladder entry. + *

+ * + * @param sb + * @param ladderType + * @param color1 + * @param color2 + */ + private void addSaveString( StringBuilder sb, LadderType ladderType, + String color1, String color2 ) { + + if ( sb.length() > 0 ) { + sb.append( "," ); + + sb.append( color1 ).append( "ladderType" ).append( ":" ) + .append( color2 ).append( ladderType.name() ); + } + + } + public static MineLinerData fromSaveString( String savedLiner ) { MineLinerData results = new MineLinerData(); + results.setLadderType( LadderType.normal ); if ( savedLiner != null && savedLiner.trim().length() > 0 ) { @@ -140,7 +190,17 @@ public static MineLinerData fromSaveString( String savedLiner ) { boolean forced = edgePatternName.length > 2 && "forced".equalsIgnoreCase( edgePatternName[2] ); - results.setLiner( edge, pattern, forced ); + if ( edge != null ) { + results.setLiner( edge, pattern, forced ); + } + else if ( "ladderType".equalsIgnoreCase( edgePatternName[0] ) ) { + LadderType lType = LadderType.fromString( pattern ); + if ( lType == null ) { + lType = LadderType.normal; + } + results.setLadderType( lType ); + } + } } } @@ -395,5 +455,11 @@ public void setForceBottom( boolean forceBottom ) { this.forceBottom = forceBottom; } + public LadderType getLadderType() { + return ladderType; + } + public void setLadderType( LadderType ladderType ) { + this.ladderType = ladderType; + } } diff --git a/prison-mines/src/main/java/tech/mcprison/prison/mines/managers/MineManager.java b/prison-mines/src/main/java/tech/mcprison/prison/mines/managers/MineManager.java index fb740b990..2db6049c3 100644 --- a/prison-mines/src/main/java/tech/mcprison/prison/mines/managers/MineManager.java +++ b/prison-mines/src/main/java/tech/mcprison/prison/mines/managers/MineManager.java @@ -24,13 +24,12 @@ import java.util.Set; import java.util.TreeMap; import java.util.UUID; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import tech.mcprison.prison.Prison; +import tech.mcprison.prison.cache.PlayerCache; import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.internal.World; -import tech.mcprison.prison.internal.block.PrisonBlockStatusData; +import tech.mcprison.prison.internal.block.PrisonBlock; import tech.mcprison.prison.mines.PrisonMines; import tech.mcprison.prison.mines.data.Mine; import tech.mcprison.prison.mines.data.MineScheduler.MineResetActions; @@ -43,8 +42,9 @@ import tech.mcprison.prison.placeholders.PlaceholderAttributeNumberFormat; import tech.mcprison.prison.placeholders.PlaceholderAttributeText; import tech.mcprison.prison.placeholders.PlaceholderManager; -import tech.mcprison.prison.placeholders.PlaceholderManager.PlaceHolderFlags; +import tech.mcprison.prison.placeholders.PlaceholderManager.PlaceholderFlags; import tech.mcprison.prison.placeholders.PlaceholderManager.PrisonPlaceHolders; +import tech.mcprison.prison.placeholders.PlaceholderResults; import tech.mcprison.prison.placeholders.PlaceholdersUtil; import tech.mcprison.prison.store.Collection; import tech.mcprison.prison.store.Document; @@ -75,7 +75,7 @@ public class MineManager private int mineResetCommandsCurrentTaskId = 0; private List mineResetActions; - private Pattern simpleNumberPattern = Pattern.compile("([0-9]+)"); + // private Pattern simpleNumberPattern = Pattern.compile("([0-9]+)"); /** *

These sort orders control how the mines are sorted, and which ones @@ -695,16 +695,21 @@ public String getTranslateMinesPlaceHolder( String identifier ) { } // placeholder Attributes: - PlaceholderManager pman = Prison.get().getPlaceholderManager(); - String placeholder = pman.extractPlaceholderString( identifier ); +// PlaceholderManager pman = Prison.get().getPlaceholderManager(); +// String placeholder = pman.extractPlaceholderString( identifier ); //PlaceholderAttribute attribute = pman.extractPlaceholderExtractAttribute( identifier ); + for ( PlaceHolderKey placeHolderKey : placeHolderKeys ) { - if ( placeHolderKey.getKey().equalsIgnoreCase( placeholder )) { + + PlaceholderResults phResults = placeHolderKey.getIdentifier( identifier ); + + if ( phResults != null && phResults.hasResults() ) { //Mine mine = getMine( placeHolderKey.getData() ); - results = getTranslateMinesPlaceHolder( placeHolderKey, identifier ); + results = getTranslateMinesPlaceHolder( placeHolderKey, + phResults.getIdentifier(), phResults.getNumericSequence() ); break; } } @@ -713,7 +718,7 @@ public String getTranslateMinesPlaceHolder( String identifier ) { } - public String getTranslateMinesPlaceHolder( PlaceHolderKey placeHolderKey, String identifier ) { + public String getTranslateMinesPlaceHolder( PlaceHolderKey placeHolderKey, String identifier, int sequence ) { String results = null; if ( placeHolderKey != null && identifier != null ) { @@ -730,33 +735,41 @@ public String getTranslateMinesPlaceHolder( PlaceHolderKey placeHolderKey, Strin Mine mine = getMine( placeHolderKey.getData() ); - results = getTranslateMinesPlaceHolder( placeHolderKey, mine, attribute ); + results = getTranslateMinesPlaceHolder( placeHolderKey, mine, attribute, sequence ); } return results; } - public String getTranslateMinesPlaceHolder( PlaceHolderKey placeHolderKey, PlaceholderAttribute attribute ) { + public String getTranslateMinesPlaceHolder( PlaceHolderKey placeHolderKey, PlaceholderAttribute attribute, + int sequence ) { Mine mine = getMine( placeHolderKey.getData() ); - return getTranslateMinesPlaceHolder( placeHolderKey, mine, attribute ); + return getTranslateMinesPlaceHolder( placeHolderKey, mine, attribute, sequence ); } private String getTranslateMinesPlaceHolder( PlaceHolderKey placeHolderKey, Mine mine, - PlaceholderAttribute attribute ) { + PlaceholderAttribute attribute, int sequence ) { + Player player = null; + return getTranslateMinesPlaceHolder( player, placeHolderKey, mine, attribute, sequence ); + + } + + private String getTranslateMinesPlaceHolder( Player player, PlaceHolderKey placeHolderKey, Mine mine, + PlaceholderAttribute attribute, int sequence ) { + String results = null; if ( placeHolderKey != null ) { // If the mine is not provided, try to get it from the placeholder data: - if ( mine == null && - placeHolderKey.getPlaceholder().hasFlag( PlaceHolderFlags.MINES ) && - placeHolderKey.getData() != null ) { + if ( mine == null && placeHolderKey.getData() != null ) { mine = getMine( placeHolderKey.getData() ); } if ( mine != null ) { DecimalFormat dFmt = new DecimalFormat("#,##0.00"); DecimalFormat iFmt = new DecimalFormat("#,##0"); +// DecimalFormat fFmt = new DecimalFormat("#,##0.00"); switch ( placeHolderKey.getPlaceholder() ) { case prison_mn_minename: @@ -817,6 +830,7 @@ private String getTranslateMinesPlaceHolder( PlaceHolderKey placeHolderKey, Mine case prison_mines_timeleft_playermines: // NOTE: timeleft can vary based upon server loads: + if ( !mine.isVirtual() ) { if ( attribute != null && attribute instanceof PlaceholderAttributeNumberFormat ) { PlaceholderAttributeNumberFormat attributeNF = @@ -834,8 +848,10 @@ private String getTranslateMinesPlaceHolder( PlaceHolderKey placeHolderKey, Mine case prison_mtlb_pm: case prison_mines_timeleft_bar_playermines: // NOTE: timeleft can vary based upon server loads: + if ( !mine.isVirtual() ) { + results = getRemainingTimeBar( mine, attribute ); + } - results = getRemainingTimeBar( mine, attribute ); break; case prison_mtlf_minename: @@ -844,6 +860,7 @@ private String getTranslateMinesPlaceHolder( PlaceHolderKey placeHolderKey, Mine case prison_mines_timeleft_formatted_playermines: // NOTE: timeleft can vary based upon server loads: + if ( !mine.isVirtual() ) { if ( attribute != null && attribute instanceof PlaceholderAttributeNumberFormat ) { PlaceholderAttributeNumberFormat attributeNF = @@ -861,6 +878,8 @@ private String getTranslateMinesPlaceHolder( PlaceHolderKey placeHolderKey, Mine case prison_mines_size_minename: case prison_ms_pm: case prison_mines_size_playermines: + + if ( !mine.isVirtual() ) { if ( attribute != null && attribute instanceof PlaceholderAttributeNumberFormat ) { PlaceholderAttributeNumberFormat attributeNF = @@ -879,17 +898,21 @@ private String getTranslateMinesPlaceHolder( PlaceHolderKey placeHolderKey, Mine case prison_mines_remaining_minename: case prison_mr_pm: case prison_mines_remaining_playermines: - int remainingBlocks = mine.getRemainingBlockCount(); - { - if ( attribute != null && attribute instanceof PlaceholderAttributeNumberFormat ) { - PlaceholderAttributeNumberFormat attributeNF = - (PlaceholderAttributeNumberFormat) attribute; - results = attributeNF.format( (long) remainingBlocks ); - } - else { - - results = iFmt.format( remainingBlocks ); - } + + if ( !mine.isVirtual() ) { + + int remainingBlocks = mine.getRemainingBlockCount(); + { + if ( attribute != null && attribute instanceof PlaceholderAttributeNumberFormat ) { + PlaceholderAttributeNumberFormat attributeNF = + (PlaceholderAttributeNumberFormat) attribute; + results = attributeNF.format( (long) remainingBlocks ); + } + else { + + results = iFmt.format( remainingBlocks ); + } + } } break; @@ -898,12 +921,16 @@ private String getTranslateMinesPlaceHolder( PlaceHolderKey placeHolderKey, Mine case prison_mines_remaining_bar_minename: case prison_mrb_pm: case prison_mines_remaining_bar_playermines: - int totalBlocks = mine.getBounds().getTotalBlockCount(); - int blocksRemaining = mine.getRemainingBlockCount(); - results = Prison.get().getPlaceholderManager(). + if ( !mine.isVirtual() ) { + + int totalBlocks = mine.getBounds().getTotalBlockCount(); + int blocksRemaining = mine.getRemainingBlockCount(); + + results = Prison.get().getPlaceholderManager(). getProgressBar( ((double) blocksRemaining), ((double) totalBlocks), false, attribute ); + } break; case prison_mp_minename: @@ -911,14 +938,19 @@ private String getTranslateMinesPlaceHolder( PlaceHolderKey placeHolderKey, Mine case prison_mp_pm: case prison_mines_percent_playermines: // mine.refreshAirCount(); // async & delayed : Very high cost - double percentRemaining = mine.getPercentRemainingBlockCount(); - results = dFmt.format( percentRemaining ); + + if ( !mine.isVirtual() ) { + + double percentRemaining = mine.getPercentRemainingBlockCount(); + results = dFmt.format( percentRemaining ); + } break; case prison_mpc_minename: case prison_mines_player_count_minename: case prison_mpc_pm: case prison_mines_player_count_playermines: + if ( !mine.isVirtual() ) { if ( attribute != null && attribute instanceof PlaceholderAttributeNumberFormat ) { PlaceholderAttributeNumberFormat attributeNF = @@ -936,6 +968,7 @@ private String getTranslateMinesPlaceHolder( PlaceHolderKey placeHolderKey, Mine case prison_mines_blocks_mined_minename: case prison_mbm_pm: case prison_mines_blocks_mined_playermines: + if ( !mine.isVirtual() ) { if ( attribute != null && attribute instanceof PlaceholderAttributeNumberFormat ) { PlaceholderAttributeNumberFormat attributeNF = @@ -967,79 +1000,254 @@ private String getTranslateMinesPlaceHolder( PlaceHolderKey placeHolderKey, Mine } break; + + + + case prison_top_mine_block_line_header_minename: + case prison_tmbl_header_minename: + if ( !mine.isVirtual() ) + { + results = "BlockName Chance Placed Remaining Totals"; + } + break; - case prison_mb01_minename: - case prison_mb02_minename: - case prison_mb03_minename: - case prison_mb04_minename: - case prison_mb05_minename: - case prison_mb06_minename: - case prison_mb07_minename: - case prison_mb08_minename: - case prison_mb09_minename: - case prison_mb10_minename: - case prison_mines_blocks_01_minename: - case prison_mines_blocks_02_minename: - case prison_mines_blocks_03_minename: - case prison_mines_blocks_04_minename: - case prison_mines_blocks_05_minename: - case prison_mines_blocks_06_minename: - case prison_mines_blocks_07_minename: - case prison_mines_blocks_08_minename: - case prison_mines_blocks_09_minename: - case prison_mines_blocks_10_minename: - case prison_mb01_pm: - case prison_mb02_pm: - case prison_mb03_pm: - case prison_mb04_pm: - case prison_mb05_pm: - case prison_mb06_pm: - case prison_mb07_pm: - case prison_mb08_pm: - case prison_mb09_pm: - case prison_mb10_pm: - case prison_mines_blocks_01_playermines: - case prison_mines_blocks_02_playermines: - case prison_mines_blocks_03_playermines: - case prison_mines_blocks_04_playermines: - case prison_mines_blocks_05_playermines: - case prison_mines_blocks_06_playermines: - case prison_mines_blocks_07_playermines: - case prison_mines_blocks_08_playermines: - case prison_mines_blocks_09_playermines: - case prison_mines_blocks_10_playermines: - Matcher matcher = simpleNumberPattern.matcher( - placeHolderKey.getPlaceholder().name() ); + case prison_top_mine_block_line_nnn_minename: + case prison_tmbl_nnn_minename: + if ( !mine.isVirtual() ) + { + List blocks = mine.getPrisonBlocks(); + if ( sequence > 0 && sequence <= blocks.size() ) { + PrisonBlock block = blocks.get( sequence - 1 ); + + if ( block != null ) { + + String message = String.format( + "%-13s %6.2f %7d %7d %8s", + + block.getBlockName(), + block.getChance(), + ((long) block.getBlockPlacedCount() ), + ((long) block.getBlockPlacedCount() - block.getBlockCountUnsaved() ), + + PlaceholdersUtil.formattedKmbtSISize( block.getBlockCountTotal(), iFmt, "" ) + ); + + results = message; + } + } + } + break; - // Should only be one number so just take the first one if there is one: - if ( matcher.find() ) { - String numStr = matcher.group(); + case prison_top_mine_block_line_totals_minename: + case prison_tmbl_totals_minename: + if ( !mine.isVirtual() ) + { + List blocks = mine.getPrisonBlocks(); + + double tChance = 0d; + int tPlaced = 0; + int tRemoved = 0; + long tTotals = 0; + + for ( PrisonBlock pBlock : blocks ) { + tChance += pBlock.getChance(); + + tPlaced += pBlock.getBlockPlacedCount(); + tRemoved += (pBlock.getBlockPlacedCount() - pBlock.getBlockCountUnsaved()); + tTotals += pBlock.getBlockCountTotal(); + } - if ( numStr != null ) { - int index = Integer.parseInt( numStr ) - 1; + String message = String.format( + " %6.2f %7d %7d %8s", + + tChance, + tPlaced, + tRemoved, + + PlaceholdersUtil.formattedKmbtSISize( tTotals, iFmt, "" ) + ); + + results = message; + } + break; + + + + case prison_top_mine_block_name_nnn_minename: + case prison_tmbn_nnn_minename: + if ( !mine.isVirtual() ) + { + List blocks = mine.getPrisonBlocks(); + if ( sequence > 0 && sequence <= blocks.size() ) { + PrisonBlock block = blocks.get( sequence - 1 ); + + if ( block != null ) { + results = block.getBlockName(); + } + } + } + break; + + case prison_top_mine_block_chance_nnn_minename: + case prison_tmbc_nnn_minename: + if ( !mine.isVirtual() ) + { + List blocks = mine.getPrisonBlocks(); + if ( sequence > 0 && sequence <= blocks.size() ) { + PrisonBlock block = blocks.get( sequence - 1 ); + + if ( block != null ) { + if ( attribute != null && attribute instanceof PlaceholderAttributeNumberFormat ) { + PlaceholderAttributeNumberFormat attributeNF = + (PlaceholderAttributeNumberFormat) attribute; + results = attributeNF.format( (long) block.getChance() ); + } + else { + + results = dFmt.format( block.getChance() ); + } + } + } + } + break; + + case prison_top_mine_block_placed_nnn_minename: + case prison_tmbpl_nnn_minename: + if ( !mine.isVirtual() ) + { + List blocks = mine.getPrisonBlocks(); + if ( sequence > 0 && sequence <= blocks.size() ) { + PrisonBlock block = blocks.get( sequence - 1 ); - PrisonBlockStatusData blockStats = null; + if ( block != null ) { + if ( attribute != null && attribute instanceof PlaceholderAttributeNumberFormat ) { + PlaceholderAttributeNumberFormat attributeNF = + (PlaceholderAttributeNumberFormat) attribute; + results = attributeNF.format( (long) block.getBlockPlacedCount() ); + } + else { + + results = iFmt.format( block.getBlockPlacedCount() ); + } + } + } + } + break; + + case prison_top_mine_block_remaing_nnn_minename: + case prison_tmbr_nnn_minename: + if ( !mine.isVirtual() ) + { + List blocks = mine.getPrisonBlocks(); + if ( sequence > 0 && sequence <= blocks.size() ) { + PrisonBlock block = blocks.get( sequence - 1 ); - // Only try to get the blocks if the index is within range: - if ( mine.isUseNewBlockModel() && mine.getPrisonBlocks().size() > index ) { - blockStats = mine.getPrisonBlocks().get( index ); + if ( block != null ) { + if ( attribute != null && attribute instanceof PlaceholderAttributeNumberFormat ) { + PlaceholderAttributeNumberFormat attributeNF = + (PlaceholderAttributeNumberFormat) attribute; + results = attributeNF.format( (long) + block.getBlockPlacedCount() - block.getBlockCountUnsaved() ); + } + else { + + results = iFmt.format( block.getBlockPlacedCount() - block.getBlockCountUnsaved() ); + } } - else if ( !mine.isUseNewBlockModel() && mine.getBlocks().size() > index ) { - blockStats = mine.getBlocks().get( index ); + } + } + break; + + case prison_top_mine_block_remaing_bar_nnn_minename: + case prison_tmbrb_nnn_minename: + if ( !mine.isVirtual() ) + { + List blocks = mine.getPrisonBlocks(); + if ( sequence > 0 && sequence <= blocks.size() ) { + PrisonBlock block = blocks.get( sequence - 1 ); + + if ( block != null ) { + int placed = block.getBlockPlacedCount(); + long removed = block.getBlockCountUnsaved(); + + results = Prison.get().getPlaceholderManager(). + getProgressBar( ((double) removed), ((double) placed), + false, attribute ); } + } + } + break; + + case prison_top_mine_block_total_nnn_minename: + case prison_tmbt_nnn_minename: + if ( !mine.isVirtual() ) + { + List blocks = mine.getPrisonBlocks(); + if ( sequence > 0 && sequence <= blocks.size() ) { + PrisonBlock block = blocks.get( sequence - 1 ); - if ( blockStats != null ) { - results = blockStats.toPlaceholderString(); + if ( block != null ) { + if ( attribute != null && attribute instanceof PlaceholderAttributeNumberFormat ) { + PlaceholderAttributeNumberFormat attributeNF = + (PlaceholderAttributeNumberFormat) attribute; + results = attributeNF.format( (long) block.getBlockCountTotal() ); + } + else { + + results = iFmt.format( block.getBlockCountTotal() ); + } } } } + break; + + + case prison_pbt: + case prison_player_blocks_total: + if ( !mine.isVirtual() ) + { + long blocksTotal = PlayerCache.getInstance().getPlayerBlocksTotal( player ); + + if ( attribute != null && attribute instanceof PlaceholderAttributeNumberFormat ) { + PlaceholderAttributeNumberFormat attributeNF = + (PlaceholderAttributeNumberFormat) attribute; + results = attributeNF.format( blocksTotal ); + } + else { + + results = iFmt.format( blocksTotal ); + } + } + break; + + + case prison_pbtm: + case prison_player_blocks_total_minename: + if ( !mine.isVirtual() ) + { + long blocksTotalByMine = PlayerCache.getInstance() + .getPlayerBlocksTotalByMine( player, mine.getName() ); + + if ( attribute != null && attribute instanceof PlaceholderAttributeNumberFormat ) { + PlaceholderAttributeNumberFormat attributeNF = + (PlaceholderAttributeNumberFormat) attribute; + results = attributeNF.format( blocksTotalByMine ); + } + else { + + results = iFmt.format( blocksTotalByMine ); + } + } + + break; + default: break; } - if ( attribute != null && attribute instanceof PlaceholderAttributeText ) { + if ( results != null && attribute != null && attribute instanceof PlaceholderAttributeText ) { PlaceholderAttributeText attributeText = (PlaceholderAttributeText) attribute; results = attributeText.format( results ); @@ -1052,6 +1260,42 @@ else if ( !mine.isUseNewBlockModel() && mine.getBlocks().size() > index ) { } +// private String xgetTranslateMinesPlaceHolder( Player player, PlaceHolderKey placeHolderKey, Mine mine, +// PlaceholderAttribute attribute, int sequence ) { +// String results = null; +// +// if ( placeHolderKey != null ) { +// +// // If the mine is not provided, try to get it from the placeholder data: +// if ( mine == null && +// placeHolderKey.getPlaceholder().hasFlag( PlaceholderFlags.MINES ) && +// placeHolderKey.getData() != null ) { +// mine = getMine( placeHolderKey.getData() ); +// } +// +// if ( mine != null ) { +// //DecimalFormat dFmt = new DecimalFormat("#,##0.00"); +// DecimalFormat iFmt = new DecimalFormat("#,##0"); +// //DecimalFormat fFmt = new DecimalFormat("#,##0.00"); +// +// switch ( placeHolderKey.getPlaceholder() ) { +// +// +// default: +// break; +// } +// +// if ( attribute != null && attribute instanceof PlaceholderAttributeText ) { +// PlaceholderAttributeText attributeText = (PlaceholderAttributeText) attribute; +// +// results = attributeText.format( results ); +// } +// } +// } +// +// return results; +// } + public String getTranslatePlayerMinesPlaceHolder( UUID playerUuid, String playerName, String identifier ) { String results = null; @@ -1069,20 +1313,54 @@ public String getTranslatePlayerMinesPlaceHolder( UUID playerUuid, String player String placeholder = pman.extractPlaceholderString( identifier ); PlaceholderAttribute attribute = pman.extractPlaceholderExtractAttribute( identifier ); + for ( PlaceHolderKey placeHolderKey : placeHolderKeys ) { if ( placeHolderKey.getKey().equalsIgnoreCase( placeholder )) { - results = getTranslatePlayerMinesPlaceHolder( playerUuid, playerName, placeHolderKey, attribute ); + + // Use this ONLY to get the numeric sequence!!! We already have the correct placeholder. + PlaceholderResults phResults = placeHolderKey.getIdentifier( placeholder ); + + results = getTranslatePlayerMinesPlaceHolder( playerUuid, playerName, + placeHolderKey, attribute, + phResults.getNumericSequence()); break; } + + + +// if ( phResults != null && phResults.hasResults() ) { +// +// //Mine mine = getMine( placeHolderKey.getData() ); +// +// results = getTranslatePlayerMinesPlaceHolder( playerUuid, playerName, +// placeHolderKey, attribute, +// phResults.getNumericSequence() ); +// break; +// } + +// if ( placeHolderKey.getKey().equalsIgnoreCase( placeholder )) { +// results = getTranslatePlayerMinesPlaceHolder( playerUuid, playerName, placeHolderKey, +// attribute, position ); +// break; +// } } } return results; } - + + /** + * + * @param playerUuid + * @param playerName + * @param placeHolderKey + * @param identifier + * @param position + * @return + */ public String getTranslatePlayerMinesPlaceHolder( UUID playerUuid, String playerName, - PlaceHolderKey placeHolderKey, String identifier ) { + PlaceHolderKey placeHolderKey, String identifier, int position ) { String results = null; identifier = identifier.toLowerCase(); @@ -1097,7 +1375,8 @@ public String getTranslatePlayerMinesPlaceHolder( UUID playerUuid, String player PlaceholderAttribute attribute = pman.extractPlaceholderExtractAttribute( identifier ); - results = getTranslatePlayerMinesPlaceHolder( playerUuid, playerName, placeHolderKey, attribute ); + results = getTranslatePlayerMinesPlaceHolder( playerUuid, playerName, placeHolderKey, + attribute, position ); if ( results == null ) { results = ""; @@ -1107,7 +1386,7 @@ public String getTranslatePlayerMinesPlaceHolder( UUID playerUuid, String player } /** - * We must have a player to process these placeholders. + * We must have a player to process these placeholders. * * @param playerUuid * @param playerName @@ -1115,22 +1394,25 @@ public String getTranslatePlayerMinesPlaceHolder( UUID playerUuid, String player * @return */ public String getTranslatePlayerMinesPlaceHolder( UUID playerUuid, String playerName, - PlaceHolderKey placeHolderKey, PlaceholderAttribute attribute ) { + PlaceHolderKey placeHolderKey, PlaceholderAttribute attribute, int position ) { String results = null; // there is no data stored for PLAYERMINES: // String data = placeHolderKey.getData(); + Player player = null; Mine mine = null; - if ( placeHolderKey.getPlaceholder().hasFlag( PlaceHolderFlags.MINES )) { + if ( placeHolderKey.getPlaceholder().hasFlag( PlaceholderFlags.MINES ) || + placeHolderKey.getPlaceholder().hasFlag( PlaceholderFlags.STATSMINES ) ) { + mine = getMine( placeHolderKey.getData() ); } else { - Player player = getPlayer(playerUuid, playerName); + player = getPlayer(playerUuid, playerName); - if ( player != null ) { + if ( player != null && player.getLocation() != null ) { mine = PrisonMines.getInstance().findMineLocation( player ); } @@ -1141,12 +1423,11 @@ public String getTranslatePlayerMinesPlaceHolder( UUID playerUuid, String player // (player == null ? "(null)" : player.getName()), placeHolderKey.getPlaceholder().name(), // player.getLocation().toBlockCoordinates() ); - if ( mine != null ) { - results = getTranslateMinesPlaceHolder( placeHolderKey, mine, attribute ); - } + results = getTranslateMinesPlaceHolder( player, placeHolderKey, mine, + attribute, position ); // If results is null, but a PLAYERMINES then must return an empty string: - if ( results == null && placeHolderKey.getPlaceholder().hasFlag( PlaceHolderFlags.PLAYERMINES ) ) { + if ( results == null && placeHolderKey.getPlaceholder().hasFlag( PlaceholderFlags.MINEPLAYERS ) ) { results = ""; } @@ -1165,16 +1446,33 @@ private Player getPlayer( UUID playerUuid, String playerName ) { Player player = null; Player playerAlt = null; - // First try to match on UUID - for ( Player p : Prison.get().getPlatform().getOnlinePlayers() ) { - if ( p.getUUID().compareTo( playerUuid ) == 0 ) { - player = p; - break; - } - else if ( p.getName().equalsIgnoreCase( playerName ) ) { - // If we get a hit on the name, save it as an alt... - playerAlt = p; + if ( playerUuid != null ) { + + // First try to match on UUID + for ( Player p : Prison.get().getPlatform().getOnlinePlayers() ) { + if ( p.getUUID().compareTo( playerUuid ) == 0 ) { + player = p; + break; + } + else if ( p.getName().equalsIgnoreCase( playerName ) ) { + // If we get a hit on the name, save it as an alt... + playerAlt = p; + } + } + } + + if ( player == null ) { + for ( Player p : Prison.get().getPlatform().getOfflinePlayers() ) { + if ( p.getUUID().compareTo( playerUuid ) == 0 ) { + player = p; + break; + } + else if ( p.getName().equalsIgnoreCase( playerName ) ) { + // If we get a hit on the name, save it as an alt... + playerAlt = p; + } } + } // if player is null, and we have a playerAlt, then use it: @@ -1212,10 +1510,10 @@ public List getTranslatedPlaceHolderKeys() { translatedPlaceHolderKeys = new ArrayList<>(); List placeHolders = - PrisonPlaceHolders.getTypes( PlaceHolderFlags.MINES ); -// PrisonPlaceHolders.excludeTypes( -// PrisonPlaceHolders.getTypes( PlaceHolderFlags.MINES ), -// PlaceHolderFlags.PLAYERMINES); + PrisonPlaceHolders.getTypes( PlaceholderFlags.MINES ); + + placeHolders.addAll( PrisonPlaceHolders.getTypes( PlaceholderFlags.STATSMINES ) ); + for ( Mine mine : getMines() ) { for ( PrisonPlaceHolders ph : placeHolders ) { @@ -1247,17 +1545,45 @@ public List getTranslatedPlaceHolderKeys() { // Next we need to register all the PLAYERMINES. The mines are dynamic, based upon which one // the player is in. So this is just a simple registration. List placeHoldersPM = - PrisonPlaceHolders.getTypes( PlaceHolderFlags.PLAYERMINES ); + PrisonPlaceHolders.getTypes( PlaceholderFlags.MINEPLAYERS ); for ( PrisonPlaceHolders ph : placeHoldersPM ) { String key = ph.name().toLowerCase(); - PlaceHolderKey placeholder = new PlaceHolderKey(key, ph ); - if ( ph.getAlias() != null ) { - String aliasName = ph.getAlias().name().toLowerCase(); - placeholder.setAliasName( aliasName ); + // There is a special condition when a MINEPLAYERS placeholder may have a suffix of + // _minename so they need to be expanded the same as a MINES placeholder. + if ( key.endsWith( PlaceholderManager.PRISON_PLACEHOLDER_MINENAME_SUFFIX ) ) { + + for ( Mine mine : getMines() ) { + String mineKey = ph.name().replace( + PlaceholderManager.PRISON_PLACEHOLDER_MINENAME_SUFFIX, "_" + mine.getName() ). + toLowerCase(); + + PlaceHolderKey placeholder = new PlaceHolderKey(mineKey, ph, mine.getName() ); + if ( ph.getAlias() != null ) { + String aliasName = ph.getAlias().name().replace( + PlaceholderManager.PRISON_PLACEHOLDER_MINENAME_SUFFIX, "_" + mine.getName() ). + toLowerCase(); + placeholder.setAliasName( aliasName ); + } + translatedPlaceHolderKeys.add( placeholder ); + } +// PlaceHolderKey placeholder = new PlaceHolderKey(key, ph ); +// if ( ph.getAlias() != null ) { +// String aliasName = ph.getAlias().name().toLowerCase(); +// placeholder.setAliasName( aliasName ); +// } +// translatedPlaceHolderKeys.add( placeholder ); + } + else { + + PlaceHolderKey placeholder = new PlaceHolderKey(key, ph ); + if ( ph.getAlias() != null ) { + String aliasName = ph.getAlias().name().toLowerCase(); + placeholder.setAliasName( aliasName ); + } + translatedPlaceHolderKeys.add( placeholder ); } - translatedPlaceHolderKeys.add( placeholder ); } } diff --git a/prison-ranks/build.gradle b/prison-ranks/build.gradle index 978808f96..57678c339 100644 --- a/prison-ranks/build.gradle +++ b/prison-ranks/build.gradle @@ -2,6 +2,9 @@ group 'tech.mcprison' apply plugin: 'java' +compileJava.options.encoding = 'UTF-8' +compileTestJava.options.encoding = "UTF-8" + //sourceCompatibility = 1.8 repositories { diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/ChatHandler.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/ChatHandler.java index 864773795..0400dc7f3 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/ChatHandler.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/ChatHandler.java @@ -60,52 +60,7 @@ public void onPlayerChat(PlayerChatEvent e) { e.setFormat( results ); -// PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); -// -// -// List placeholderKeys = pm.getTranslatedPlaceHolderKeys(); -// -// for ( PlaceHolderKey placeHolderKey : placeholderKeys ) { -// String key1 = "{" + placeHolderKey.getKey(); -// String key2 = "}"; -// -// int idx = newFormat.indexOf( key1 ); -// if ( idx > -1 && newFormat.indexOf( key2, idx ) > -1 ) { -// -// String identifier = newFormat.substring( idx + 1, newFormat.indexOf( key2, idx ) ); -// -//// // placeholder Attributes: -//// String placeholder = PlaceholderManager.extractPlaceholderString( identifier ); -//// PlaceholderAttribute attribute = PlaceholderManager.extractPlaceholderExtractAttribute( identifier ); -// -// newFormat = newFormat.replace( "{" + identifier + "}", Text.translateAmpColorCodes( -// pm.getTranslatePlayerPlaceHolder( player.getUUID(), player.getName(), identifier ) )); -// } -// } -// -//// String prefix = getPrefix(e.getPlayer().getUUID()); -//// String newFormat = e.getFormat().replace("{PRISON_RANK}", Text.translateAmpColorCodes(prefix)); -// e.setFormat(newFormat); } -// /* -// * Util -// */ -// -// private String getPrefix(UUID uid) { -// Optional player = -// PrisonRanks.getInstance().getPlayerManager().getPlayer(uid); -// String prefix = ""; -// -// if (player.isPresent() && !player.get().getRanks().isEmpty()) { -// StringBuilder builder = new StringBuilder(); -// for (Map.Entry entry : player.get().getRanks().entrySet()) { -// builder.append(entry.getValue().tag); -// } -// prefix = builder.toString(); -// } -// -// return prefix; -// } } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/FirstJoinHandler.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/FirstJoinHandler.java index 3e7e7da41..ca57dd184 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/FirstJoinHandler.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/FirstJoinHandler.java @@ -17,14 +17,9 @@ package tech.mcprison.prison.ranks; -import java.io.IOException; -import java.util.Optional; - import com.google.common.eventbus.Subscribe; import tech.mcprison.prison.Prison; -import tech.mcprison.prison.output.Output; -import tech.mcprison.prison.ranks.data.Rank; import tech.mcprison.prison.ranks.data.RankPlayer; import tech.mcprison.prison.ranks.events.FirstJoinEvent; @@ -51,27 +46,15 @@ public FirstJoinHandler() { @Subscribe public void onFirstJoin(FirstJoinEvent event) { RankPlayer player = event.getPlayer(); - Optional firstRank = PrisonRanks.getInstance().getDefaultLadder().getLowestRank(); - - if (firstRank.isPresent()) { - Rank rank = firstRank.get(); - - if ( !player.getLadderRanks().containsKey( rank.getLadder() ) ) { - - player.addRank( rank ); - - } - } else { - - Output.get().logWarn( firstJoinWarningNoRanksOnServer() ); - } + // Try to perform the first join processing to give them the default rank: + player.firstJoin(); - try { - PrisonRanks.getInstance().getPlayerManager().savePlayer(player); - } catch (IOException e) { - - Output.get().logError( firstJoinErrorCouldNotSavePlayer(), e ); - } + PrisonRanks.getInstance().getPlayerManager().savePlayer(player); +// try { +// } catch (IOException e) { +// +// Output.get().logError( firstJoinErrorCouldNotSavePlayer(), e ); +// } } } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/FirstJoinHandlerMessages.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/FirstJoinHandlerMessages.java index d3d1af3bd..4cd3cc3fd 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/FirstJoinHandlerMessages.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/FirstJoinHandlerMessages.java @@ -2,7 +2,7 @@ public class FirstJoinHandlerMessages { - protected String firstJoinWarningNoRanksOnServer() { + public String firstJoinWarningNoRanksOnServer() { return PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_firstJoinHandler__no_ranks_on_server" ) .localize(); @@ -14,4 +14,11 @@ protected String firstJoinErrorCouldNotSavePlayer() { .localize(); } + public String firstJoinSuccess( String playerName ) { + return PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_firstJoinHandler__success" ) + .withReplacements( playerName ) + .localize(); + } + } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/PrisonRanks.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/PrisonRanks.java index b93e34958..a1ee9fb89 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/PrisonRanks.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/PrisonRanks.java @@ -26,6 +26,7 @@ import tech.mcprison.prison.PrisonAPI; import tech.mcprison.prison.convert.ConversionManager; import tech.mcprison.prison.integration.IntegrationType; +import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.localization.LocaleManager; import tech.mcprison.prison.modules.ModuleStatus; import tech.mcprison.prison.output.LogLevel; @@ -34,7 +35,9 @@ import tech.mcprison.prison.ranks.commands.LadderCommands; import tech.mcprison.prison.ranks.commands.RankUpCommand; import tech.mcprison.prison.ranks.commands.RanksCommands; +import tech.mcprison.prison.ranks.data.Rank; import tech.mcprison.prison.ranks.data.RankLadder; +import tech.mcprison.prison.ranks.data.RankPlayer; import tech.mcprison.prison.ranks.managers.LadderManager; import tech.mcprison.prison.ranks.managers.PlayerManager; import tech.mcprison.prison.ranks.managers.RankManager; @@ -157,6 +160,7 @@ public void enable() { playerManager = new PlayerManager(initCollection("players")); + try { playerManager.loadPlayers(); } @@ -171,6 +175,13 @@ public void enable() { logStartupMessageError( prisonRanksFailedToLoadPlayFileMsg( e.getMessage() )); } + + + // Hook up all players to the ranks: + playerManager.connectPlayersToRanks(); + + + // Load up the commands CommandCommands rankCommandCommands = new CommandCommands(); @@ -188,6 +199,13 @@ public void enable() { Prison.get().getCommandHandler().registerCommands( rankupCommands ); Prison.get().getCommandHandler().registerCommands( ladderCommands ); + + + // Check all players to see if any need to join: + checkAllPlayersForJoin(); + + + // Load up all else new FirstJoinHandler(); @@ -210,6 +228,76 @@ public void enable() { } + public void checkAllPlayersForJoin() + { + + RankUpCommand rankupCommands = rankManager.getRankupCommands(); + + // If there is a default rank on the default ladder, then + // check to see if there are any players not in prison: add them: + RankLadder defaultLadder = getLadderManager().getLadder( "default" ); + if ( defaultLadder != null && defaultLadder.getRanks().size() > 0 ) { + int addedPlayers = 0; + int fixedPlayers = 0; + + for ( Player player : Prison.get().getPlatform().getOfflinePlayers() ) { + + // getPlayer() will add a player who does not exist: + RankPlayer rPlayer = playerManager.getPlayer( player ); + if ( rPlayer != null ) { + if ( rPlayer.checkName( player.getName() ) ) { + playerManager.savePlayer( rPlayer ); + addedPlayers++; + } + } + } + + + // If any player does not have a rank on the default ladder, then add the default + // ladder and rank: + Rank defaultRank = defaultLadder.getLowestRank().get(); + for ( RankPlayer rPlayer : playerManager.getPlayers() ) { + + @SuppressWarnings( "unused" ) + String rp = rPlayer.toString(); + + Rank rankOnDefault = null; + + if ( rPlayer.getRank( defaultLadder ) != null ) { + + rankOnDefault = rPlayer.getRank( defaultLadder ).getRank(); + +// Output.get().logInfo( "#### %s ladder = %s isRankNull= %s rank= %s %s [%s]" , +// rPlayer.getName(), +// defaultLadder.getName(), +// (rankOnDefault == null ? "true" : "false"), (rankOnDefault == null ? "null" : rankOnDefault.getName()), +// (rankOnDefaultStr == null ? "true" : "false"), (rankOnDefaultStr == null ? "null" : rankOnDefaultStr.getName()), +// rp ); + + } + if ( rankOnDefault == null ) { + + rankupCommands.setPlayerRank( rPlayer, defaultRank ); + + if ( rPlayer.getRank( defaultLadder ) != null ) { + + String message = prisonRankAddedNewPlayer( rPlayer.getName() ); + + Output.get().logInfo( message ); + } + + fixedPlayers++; + } + + } + if ( addedPlayers > 0 || fixedPlayers > 0 ) { + + Output.get().logInfo( prisonRankAddedAndFixedPlayers( addedPlayers, fixedPlayers ) ); + } + } + } + + /** * This function deferredStartup() will be called after the integrations have been * loaded. diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/PrisonRanksMessages.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/PrisonRanksMessages.java index d95b99440..899447ab9 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/PrisonRanksMessages.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/PrisonRanksMessages.java @@ -203,4 +203,24 @@ protected String prisonRanksFailureSavingPrestigeLadderMsg() { } + protected String prisonRankAddedNewPlayer( String playerName ) { + return PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_prisonRanks__added_new_player" ) + .withReplacements( + playerName + ) + .localize(); + } + + + protected String prisonRankAddedAndFixedPlayers( int addedPlayers, int fixedPLayers ) { + return PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_prisonRanks__added_and_fixed_players" ) + .withReplacements( + Integer.toString( addedPlayers ), + Integer.toString( fixedPLayers ) + ) + .localize(); + } + } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankUtil.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankUtil.java index dbe545a98..c857d320b 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankUtil.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankUtil.java @@ -17,7 +17,6 @@ package tech.mcprison.prison.ranks; -import java.io.IOException; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; @@ -28,6 +27,8 @@ import tech.mcprison.prison.integration.EconomyCurrencyIntegration; import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.output.Output.DebugTarget; +import tech.mcprison.prison.ranks.data.PlayerRank; import tech.mcprison.prison.ranks.data.Rank; import tech.mcprison.prison.ranks.data.RankLadder; import tech.mcprison.prison.ranks.data.RankPlayer; @@ -71,6 +72,7 @@ public enum RankupStatus { RANKUP_FAILURE_RANK_DOES_NOT_EXIST, RANKUP_FAILURE_RANK_IS_NOT_IN_LADDER, RANKUP_FAILURE_CURRENCY_IS_NOT_SUPPORTED, + RANKUP_FAILURE_NO_PLAYERRANK, RANKUP_EVENT_CANCELED, @@ -153,7 +155,9 @@ public enum RankupTransactions { demote_successful, failure_exception_caught_check_server_logs, - successfully_saved_player_rank_data + successfully_saved_player_rank_data, + + failure_orginal_playerRank_does_not_exist ; } @@ -230,7 +234,7 @@ private RankupResults rankupPlayer(RankupCommands command, Player player, RankPl String rankName, String playerName, String executorName, PromoteForceCharge pForceCharge ) { - RankupResults results = new RankupResults(command, playerName, executorName, ladderName, rankName); + RankupResults results = new RankupResults(command, rankPlayer, executorName, ladderName, rankName); switch ( command ) { case rankup: @@ -294,7 +298,7 @@ private RankupResults rankupPlayer(RankupCommands command, Player player, RankPl try { rankupPlayerInternal(results, command, player, rankPlayer, ladderName, - rankName, playerName, executorName, pForceCharge ); + rankName, pForceCharge ); } catch (Exception e ) { results.addTransaction( RankupTransactions.failure_exception_caught_check_server_logs ); @@ -317,31 +321,47 @@ private RankupResults rankupPlayer(RankupCommands command, Player player, RankPl */ private void rankupPlayerInternal(RankupResults results, RankupCommands command, Player prisonPlayer, RankPlayer rankPlayer, String ladderName, - String rankName, String playerName, String executorName, + String rankName, PromoteForceCharge pForceCharge) { - + Output.get().logDebug( DebugTarget.rankup, "Rankup: rankupPlayerInternal: "); + RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); if( ladder == null ) { results.addTransaction( RankupStatus.RANKUP_FAILURE_COULD_NOT_LOAD_LADDER, RankupTransactions.failed_ladder ); return; } + results.setLadder( ladder ); - Rank originalRank = rankPlayer.getRank(ladder.getName()); + // This should never be null, since if a player is not on this ladder, then they + // should never make it this far in to this code: + // Um... not true when performing a prestige for the first time.... lol + + PlayerRank originalRank = rankPlayer.getRank(ladder); + +// if ( originalRank == null && ladder.getName().equals( "default" ) ) { +// +// // Only default ladder should be logged as an error if there is no rank: +// results.addTransaction( RankupStatus.RANKUP_FAILURE_NO_PLAYERRANK, +// RankupTransactions.failure_orginal_playerRank_does_not_exist ); +// return; +// } + // Optional currentRankOptional = player.getRank(ladder); // Rank originalRank = currentRankOptional.orElse( null ); results.addTransaction( RankupTransactions.orginal_rank ); - results.setOriginalRank( originalRank ); - + results.setPlayerRankOriginal( originalRank ); + results.setOriginalRank( originalRank == null ? null : originalRank.getRank() ); /** - * calculate the target rank: + * calculate the target rank. In this function the original rank is updated within the + * results object, so from here on out, use the results object for original rank. */ - Rank targetRank = calculateTargetRank( command, results, originalRank, ladder, - ladderName, rankName ); + Rank targetRank = calculateTargetRank( command, results, rankName ); + if ( results.getStatus() != RankupStatus.IN_PROGRESS ) { // Failed while calculatingTargetRank so return now: return; @@ -379,23 +399,37 @@ private void rankupPlayerInternal(RankupResults results, // Target rank is still null, so something failed so terminate: if ( targetRank == null ) { - results.addTransaction( RankupStatus.RANKUP_FAILURE_UNABLE_TO_ASSIGN_RANK, RankupTransactions.failed_unable_to_assign_rank ); + results.addTransaction( RankupStatus.RANKUP_FAILURE_UNABLE_TO_ASSIGN_RANK, + RankupTransactions.failed_unable_to_assign_rank ); return; } - results.setTargetRank( targetRank ); + // This calculates the target rank, and takes in to consideration the player's existing rank: + PlayerRank pRankNext = PlayerRank.getTargetPlayerRankForPlayer( rankPlayer, targetRank ); +// new PlayerRank( targetRank, originalRank.getRankMultiplier() ); + + // If player does not have a rank on this ladder, then grab the first rank on the ladder since they need + // to be added to the ladder. + if ( pRankNext == null ) { + pRankNext = PlayerRank.getTargetPlayerRankForPlayer( rankPlayer, ladder.getLowestRank().get() ); + } + + + results.setPlayerRankTarget( pRankNext ); + results.setTargetRank( targetRank ); // String currency = ""; - double nextRankCost = targetRank.getCost(); - double currentRankCost = (originalRank == null ? 0 : originalRank.getCost()); + double nextRankCost = pRankNext.getRankCost(); + double currentRankCost = ( results.getPlayerRankOriginal() == null ? 0 : + results.getPlayerRankOriginal().getRankCost() ); results.addTransaction( RankupTransactions.fireRankupEvent ); // Fire the rankup event to see if it should be canceled. - RankUpEvent rankupEvent = new RankUpEvent(rankPlayer, originalRank, targetRank, nextRankCost, + RankUpEvent rankupEvent = new RankUpEvent(rankPlayer, results.getOriginalRank(), targetRank, nextRankCost, command, pForceCharge ); Prison.get().getEventBus().post(rankupEvent); @@ -444,8 +478,8 @@ private void rankupPlayerInternal(RankupResults results, if ( pForceCharge == PromoteForceCharge.refund_player) { results.addTransaction( RankupTransactions.player_balance_increased); - if ( originalRank != null ) { - rankPlayer.addBalance( originalRank.getCurrency(), currentRankCost ); + if ( results.getOriginalRank() != null ) { + rankPlayer.addBalance( results.getOriginalRank().getCurrency(), currentRankCost ); } } else { // Should never hit this code!! @@ -459,7 +493,10 @@ private void rankupPlayerInternal(RankupResults results, results.addTransaction( RankupTransactions.zero_cost_to_player ); } + // Actually apply the new rank here: rankPlayer.addRank(targetRank); + + if ( !savePlayerRank( results, rankPlayer ) ) { return; @@ -482,24 +519,34 @@ private void rankupPlayerInternal(RankupResults results, ( !cmd.contains( "{firstJoin}" ) || cmd.contains( "{firstJoin}" ) && command == RankupCommands.firstJoin ) ) { + PlayerRank opRank = results.getPlayerRankOriginal(); + PlayerRank tpRank = results.getPlayerRankTarget(); + + Rank oRank = results.getOriginalRank(); + Rank tRank = results.getTargetRank(); + PrisonCommandTask cmdTask = new PrisonCommandTask( command.name() ); cmdTask.addCustomPlaceholder( CustomPlaceholders.balanceInitial, Double.toString( results.getBalanceInitial()) ); cmdTask.addCustomPlaceholder( CustomPlaceholders.balanceFinal, Double.toString( results.getBalanceFinal()) ); cmdTask.addCustomPlaceholder( CustomPlaceholders.currency, results.getCurrency() ); - cmdTask.addCustomPlaceholder( CustomPlaceholders.rankupCost, Double.toString( results.getTargetRank().getCost() ) ); + cmdTask.addCustomPlaceholder( CustomPlaceholders.originalRankCost, + opRank == null ? "" : Double.toString( opRank.getRankCost() ) ); + cmdTask.addCustomPlaceholder( CustomPlaceholders.rankupCost, + tpRank == null ? "" : Double.toString( tpRank.getRankCost() ) ); cmdTask.addCustomPlaceholder( CustomPlaceholders.ladder, results.getLadderName() ); + cmdTask.addCustomPlaceholder( CustomPlaceholders.rank, - (results.getOriginalRank() == null ? "none" : results.getOriginalRank().getName()) ); + (oRank == null ? "none" : oRank.getName()) ); cmdTask.addCustomPlaceholder( CustomPlaceholders.rankTag, - (results.getOriginalRank() == null ? "none" : results.getOriginalRank().getTag()) ); + (oRank == null ? "none" : oRank.getTag()) ); cmdTask.addCustomPlaceholder( CustomPlaceholders.targetRank, - (results.getTargetRank() == null ? "none" : results.getTargetRank().getName()) ); + (tRank == null ? "none" : tRank.getName()) ); cmdTask.addCustomPlaceholder( CustomPlaceholders.targetRankTag, - (results.getTargetRank() == null ? "none" : results.getTargetRank().getTag()) ); + (tRank == null ? "none" : tRank.getTag()) ); if ( command == RankupCommands.firstJoin && cmd.contains( "{firstJoin}" ) ) { cmd = cmd.replace( "{firstJoin}", "" ); @@ -524,6 +571,13 @@ private void rankupPlayerInternal(RankupResults results, results.addTransaction( RankupTransactions.rankupCommandsCompleted ); + + // Recalculate the rankup cost multipliers to apply to the next rankup. + // This must be done AFTER the ranks commands sets up the placeholder + // values so they will reflect the correct amounts. + rankPlayer.recalculateRankMultipliers(); + + // results.addTransaction( RankupTransactions.fireRankupEvent ); // // // Nothing can cancel a RankUpEvent: @@ -546,40 +600,45 @@ private void rankupPlayerInternal(RankupResults results, private boolean savePlayerRank( RankupResults results, RankPlayer rankPlayer ) { boolean success = false; - try { +// try { PrisonRanks.getInstance().getPlayerManager().savePlayer(rankPlayer); results.addTransaction( RankupTransactions.successfully_saved_player_rank_data ); success = true; - } - catch (IOException e) { - - Output.get().logError( rankUtilFailureSavingPlayerMsg( e.getMessage() ), e ); - - results.addTransaction( RankupStatus.RANKUP_FAILURE_COULD_NOT_SAVE_PLAYER_FILE, - RankupTransactions.failure_cannot_save_player_file ); - } +// } +// catch (IOException e) { +// +// Output.get().logError( rankUtilFailureSavingPlayerMsg( e.getMessage() ), e ); +// +// results.addTransaction( RankupStatus.RANKUP_FAILURE_COULD_NOT_SAVE_PLAYER_FILE, +// RankupTransactions.failure_cannot_save_player_file ); +// } return success; } private Rank calculateTargetRank(RankupCommands command, RankupResults results, - Rank originalRank, RankLadder ladder, String ladderName, String rankName ) { + // Rank originalRank, // RankLadder ladder, String ladderName, + String rankName ) { Rank targetRank = null; // For all commands except for setrank, if the player does not have a current rank, then // set it to the default and skip all other rank processing: + + // NOTE: With new processing using PlayerRank, not sure if the default rank should be set to anything... + // I'm thinking no... - if ( originalRank == null && + if ( results.getOriginalRank() == null && ( command == RankupCommands.rankup || command == RankupCommands.promote || command == RankupCommands.demote )) { // Set the default rank: - Optional lowestRank = ladder.getByPosition(0); + Optional lowestRank = results.getLadder().getLowestRank(); +// Optional lowestRank = ladder.getByPosition(0); if (!lowestRank.isPresent()) { results.addTransaction( RankupStatus.RANKUP_NO_RANKS, RankupTransactions.no_ranks_found_on_ladder ); @@ -589,10 +648,10 @@ private Rank calculateTargetRank(RankupCommands command, RankupResults results, targetRank = lowestRank.get(); // need to set this to a valid value: - originalRank = lowestRank.get(); + results.setOriginalRank( lowestRank.get() ); } - if ( originalRank == null ) { + if ( results.getOriginalRank() == null ) { results.addTransaction( RankupTransactions.original_rank_is_null ); } @@ -608,8 +667,8 @@ private Rank calculateTargetRank(RankupCommands command, RankupResults results, return targetRank; } - else if ("default".equalsIgnoreCase( ladderName ) && rankName == null ) { - Optional lowestRank = ladder.getLowestRank(); + else if ("default".equalsIgnoreCase( results.getLadder().getName() ) && rankName == null ) { + Optional lowestRank = results.getLadder().getLowestRank(); if ( lowestRank.isPresent() ) { targetRank = lowestRank.get(); rankName = targetRank.getName(); @@ -625,7 +684,7 @@ else if ("default".equalsIgnoreCase( ladderName ) && rankName == null ) { if ( targetRank != null ) { - if ( !ladder.containsRank( targetRank.getId() )) { + if ( !results.getLadder().containsRank( targetRank )) { results.addTransaction( RankupStatus.RANKUP_FAILURE_RANK_IS_NOT_IN_LADDER, RankupTransactions.failed_rank_not_in_ladder ); return targetRank; @@ -651,26 +710,26 @@ else if ("default".equalsIgnoreCase( ladderName ) && rankName == null ) { // Trying to promote: // nextRankOptional = ladder.getNext(ladder.getPositionOfRank(currentRankOptional.get())); - if ( originalRank.getRankNext() == null ) { + if ( results.getOriginalRank().getRankNext() == null ) { // We're already at the highest rank. results.addTransaction( RankupStatus.RANKUP_HIGHEST, RankupTransactions.no_higher_rank_found ); return targetRank; } - targetRank = originalRank.getRankNext(); + targetRank = results.getOriginalRank().getRankNext(); results.addTransaction( RankupTransactions.set_to_next_higher_rank ); } else if ( command == RankupCommands.demote ) { // Trying to demote: // nextRankOptional = ladder.getPrevious(ladder.getPositionOfRank(currentRankOptional.get())); - if ( originalRank.getRankPrior() == null ) { + if ( results.getOriginalRank().getRankPrior() == null ) { // We're already at the lowest rank. results.addTransaction( RankupStatus.RANKUP_LOWEST, RankupTransactions.no_lower_rank_found ); return targetRank; } - targetRank = originalRank.getRankPrior(); + targetRank = results.getOriginalRank().getRankPrior(); results.addTransaction( RankupTransactions.set_to_prior_lower_rank ); } } @@ -696,7 +755,10 @@ private void logTransactionResults( RankupResults results ) DecimalFormat iFmt = new DecimalFormat("#,##0"); Rank oRank = results.getOriginalRank(); + PlayerRank opRank = results.getPlayerRankOriginal(); + Rank tRank = results.getTargetRank(); + PlayerRank tpRank = results.getPlayerRankTarget(); for ( RankupTransactions rt : RankupTransactions.values() ) { @@ -737,13 +799,13 @@ private void logTransactionResults( RankupResults results ) case player_balance_decreased: sb.append( "=" ); - sb.append( tRank == null ? "" : dFmt.format( tRank.getCost() ) ); + sb.append( tpRank == null ? "" : dFmt.format( tpRank.getRankCost() ) ); break; case player_balance_increased: sb.append( "=" ); - sb.append( tRank == null ? "" : dFmt.format( oRank.getCost() ) ); + sb.append( opRank == null ? "" : dFmt.format( opRank.getRankCost() ) ); break; @@ -780,7 +842,7 @@ private void logTransactionResults( RankupResults results ) "runtime=%s ms message=[%s] ", results.getCommand().name(), - results.getPlayer(), + results.getRankPlayer().getName(), (results.getExecutor() == null ? "(see player)" : results.getExecutor()), (results.getStatus() == null ? "" : results.getStatus().name()), @@ -789,11 +851,11 @@ private void logTransactionResults( RankupResults results ) (oRank == null ? "none" : oRank.getName()), - (oRank == null ? "" : " " + dFmt.format( oRank.getCost())), + (opRank == null ? "" : " " + dFmt.format( opRank.getRankCost() )), (oRank == null || oRank.getCurrency() == null ? "" : " " + oRank.getCurrency()), (tRank == null ? "none" : tRank.getName()), - (tRank == null ? "" : " " + dFmt.format( tRank.getCost())), + (tpRank == null ? "" : " " + dFmt.format( tpRank.getRankCost())), (tRank == null || tRank.getCurrency() == null ? "" : " " + tRank.getCurrency()), iFmt.format( results.getElapsedTime() ), diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankUtilMessages.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankUtilMessages.java index d67e55b78..4e2f379de 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankUtilMessages.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankUtilMessages.java @@ -6,7 +6,7 @@ protected String rankUtilFailureInternalMsg( String errorMessage ) { return PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankutil__failure_internal" ) .withReplacements( - errorMessage ) + errorMessage == null ? "--" : errorMessage ) .localize(); } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankupResults.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankupResults.java index b34c112e1..d703c213b 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankupResults.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/RankupResults.java @@ -6,18 +6,26 @@ import tech.mcprison.prison.ranks.RankUtil.RankupCommands; import tech.mcprison.prison.ranks.RankUtil.RankupStatus; import tech.mcprison.prison.ranks.RankUtil.RankupTransactions; +import tech.mcprison.prison.ranks.data.PlayerRank; import tech.mcprison.prison.ranks.data.Rank; +import tech.mcprison.prison.ranks.data.RankLadder; +import tech.mcprison.prison.ranks.data.RankPlayer; public class RankupResults { private RankupCommands command; - private String player; + RankPlayer rankPlayer; +// private String player; private String executor; private RankupStatus status; + + private RankLadder ladder; private String ladderName; private String rankName; + private PlayerRank playerRankOriginal; + private PlayerRank playerRankTarget; private Rank originalRank; private Rank targetRank; private String message; @@ -34,7 +42,7 @@ public class RankupResults { private long timestampStart = 0; private long timestampStop = 0; - public RankupResults(RankupCommands command, String playerName, String executorName, + public RankupResults(RankupCommands command, RankPlayer rankPlayer, String executorName, String ladderName, String rankName) { super(); @@ -43,7 +51,9 @@ public RankupResults(RankupCommands command, String playerName, String executorN this.transactions = new ArrayList<>(); this.command = command; - this.player = playerName; + + this.rankPlayer = rankPlayer; +// this.player = playerName; this.executor = executorName; this.ladderName = ladderName; @@ -81,12 +91,27 @@ public RankupCommands getCommand() { public void setCommand( RankupCommands command ) { this.command = command; } + + public RankPlayer getRankPlayer() { + return rankPlayer; + } + public void setRankPlayer( RankPlayer rankPlayer ) { + this.rankPlayer = rankPlayer; + } + +// public String getPlayer() { +// return player; +// } +// public void setPlayer( String player ) { +// this.player = player; +// } - public String getPlayer() { - return player; + + public RankLadder getLadder() { + return ladder; } - public void setPlayer( String player ) { - this.player = player; + public void setLadder( RankLadder ladder ) { + this.ladder = ladder; } public String getExecutor() { @@ -117,6 +142,37 @@ public void setStatus( RankupStatus status ) { this.status = status; } + public PlayerRank getPlayerRankOriginal() { + if ( playerRankOriginal == null && originalRank != null && rankPlayer != null ) { + PlayerRank pRank = rankPlayer.getRank( originalRank.getLadder() ); + playerRankOriginal = pRank; + } + return playerRankOriginal; + } + public void setPlayerRankOriginal( PlayerRank playerRankOriginal ) { + this.playerRankOriginal = playerRankOriginal; + } + + public PlayerRank getPlayerRankTarget() { + if ( playerRankTarget == null && + getOriginalRank() != null && getOriginalRank().getRankNext() != null && + targetRank != null ) { + + // This calculates the target rank, and takes in to consideration the player's existing rank: + playerRankTarget = PlayerRank.getTargetPlayerRankForPlayer( rankPlayer, targetRank ); + +// PlayerRank pRank = rankPlayer.getRank( originalRank.getLadder() ); +// PlayerRank pRankNext = new PlayerRank( targetRank, pRank.getRankMultiplier() ); + +// playerRankTarget = pRankNext; + } + return playerRankTarget; + } + public void setPlayerRankTarget( PlayerRank playerRankTarget ) { + this.playerRankTarget = playerRankTarget; + } + + public Rank getOriginalRank() { return originalRank; } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/CommandCommands.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/CommandCommands.java index 1ed194007..cf26dcd73 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/CommandCommands.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/CommandCommands.java @@ -11,7 +11,6 @@ import tech.mcprison.prison.output.ChatDisplay; import tech.mcprison.prison.output.FancyMessageComponent; import tech.mcprison.prison.output.LogLevel; -import tech.mcprison.prison.output.Output; import tech.mcprison.prison.output.RowComponent; import tech.mcprison.prison.ranks.PrisonRanks; import tech.mcprison.prison.ranks.data.Rank; @@ -50,6 +49,11 @@ public void commandAdd(CommandSender sender, command = command.replaceFirst("/", ""); } + if ( command.contains( "%" ) ) { + ranksCommandAddCannotUsePercentSymbols( sender ); + return; + } + if ( rankName != null && "placeholders".equalsIgnoreCase( rankName ) ) { String placeholders = @@ -62,7 +66,7 @@ public void commandAdd(CommandSender sender, String message = ranksCommandAddPlaceholdersMsg( placeholders ); - Output.get().logInfo( message ); + sender.sendMessage( message ); return; } @@ -159,7 +163,15 @@ public void commandList(CommandSender sender, boolean noRemoves = options != null && "noRemoves".equalsIgnoreCase( options ); - ChatDisplay display = new ChatDisplay( ranksCommandListCmdHeaderMsg( rank.getTag() )); + ChatDisplay display = commandListDetails( rank, noRemoves ); + display.send(sender); + } + + + + protected ChatDisplay commandListDetails( Rank rank, boolean noRemoves ) + { + ChatDisplay display = new ChatDisplay( ranksCommandListCmdHeaderMsg( rank.getTag() )); if ( !noRemoves ) { display.addText( ranksCommandListClickCmdToRemoveMsg() ); @@ -179,7 +191,7 @@ public void commandList(CommandSender sender, if ( !noRemoves ) { FancyMessage msgRemove = new FancyMessage( " &4Remove&3" ) - .suggest("/ranks command remove " + rankName + " " + rowNumber ) + .suggest("/ranks command remove " + rank.getName() + " " + rowNumber ) .tooltip( ranksCommandListClickToRemoveMsg() ); row.addFancy( msgRemove ); } @@ -191,10 +203,10 @@ public void commandList(CommandSender sender, display.addComponent(builder.build()); display.addComponent(new FancyMessageComponent( new FancyMessage( ranksCommandListAddButtonMsg() ) - .suggest("/ranks command add " + rankName + " /") + .suggest("/ranks command add " + rank.getName() + " /") .tooltip( ranksCommandListAddNewCommandToolTipMsg() ))); - display.send(sender); - } + return display; + } @@ -213,6 +225,11 @@ public void commandLadderAdd(CommandSender sender, if (command.startsWith("/")) { command = command.replaceFirst("/", ""); } + + if ( command.contains( "%" ) ) { + ranksCommandAddCannotUsePercentSymbols( sender ); + return; + } if ( ladderName != null && "placeholders".equalsIgnoreCase( ladderName ) ) { @@ -224,7 +241,7 @@ public void commandLadderAdd(CommandSender sender, String message = ladderCommandAddPlaceholdersMsg( placeholders ); - Output.get().logInfo( message ); + sender.sendMessage( message ); return; } @@ -321,7 +338,15 @@ public void commandLadderList(CommandSender sender, boolean noRemoves = options != null && "noRemoves".equalsIgnoreCase( options ); - ChatDisplay display = new ChatDisplay( ladderCommandListCmdHeaderMsg( ladder.getName() )); + ChatDisplay display = commandLadderListDetail( ladder, noRemoves ); + + + display.send(sender); + } + + protected ChatDisplay commandLadderListDetail( RankLadder ladder, boolean noRemoves ) + { + ChatDisplay display = new ChatDisplay( ladderCommandListCmdHeaderMsg( ladder.getName() )); if ( !noRemoves ) { display.addText( ranksCommandListClickCmdToRemoveMsg() ); } @@ -342,7 +367,7 @@ public void commandLadderList(CommandSender sender, if ( !noRemoves ) { FancyMessage msgRemove = new FancyMessage( " &4Remove&3" ) - .suggest("/ranks ladder command remove " + ladderName + " " + rowNumber ) + .suggest("/ranks ladder command remove " + ladder.getName() + " " + rowNumber ) .tooltip( ranksCommandListClickToRemoveMsg() ); row.addFancy( msgRemove ); } @@ -354,10 +379,10 @@ public void commandLadderList(CommandSender sender, display.addComponent(builder.build()); display.addComponent(new FancyMessageComponent( new FancyMessage( ranksCommandListAddButtonMsg() ) - .suggest("/ranks ladder command add " + ladderName + " /") + .suggest("/ranks ladder command add " + ladder.getName() + " /") .tooltip( ranksCommandListAddNewCommandToolTipMsg() ))); - display.send(sender); - } + return display; + } } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/CommandCommandsMessages.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/CommandCommandsMessages.java index fc92c6c4d..a369f60a9 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/CommandCommandsMessages.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/CommandCommandsMessages.java @@ -11,6 +11,12 @@ public CommandCommandsMessages( String cmdGroup ) { super( cmdGroup ); } + protected void ranksCommandAddCannotUsePercentSymbols( CommandSender sender ) { + PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_commandCommands__command_add_cannot_use_percent_symbols" ) + .sendTo( sender ); + } + protected String ranksCommandAddPlaceholdersMsg( String placeholders ) { return PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_commandCommands__command_add_placeholders" ) diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommands.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommands.java index fd7ff5032..1f16fcd72 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommands.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommands.java @@ -1,11 +1,13 @@ package tech.mcprison.prison.ranks.commands; +import tech.mcprison.prison.Prison; import tech.mcprison.prison.commands.Arg; import tech.mcprison.prison.commands.Command; import tech.mcprison.prison.internal.CommandSender; import tech.mcprison.prison.output.BulletedListComponent; import tech.mcprison.prison.output.ChatDisplay; import tech.mcprison.prison.ranks.PrisonRanks; +import tech.mcprison.prison.ranks.data.PlayerRankRefreshTask; import tech.mcprison.prison.ranks.data.Rank; import tech.mcprison.prison.ranks.data.RankLadder; @@ -40,6 +42,10 @@ public void ladderAdd(CommandSender sender, @Arg(name = "ladderName") String lad if ( PrisonRanks.getInstance().getLadderManager().save(rankLadder) ) { + + Prison.get().getPlatform().getPlaceholders().reloadPlaceholders(); + + ladderAddCreatedMsg( sender, ladderName ); } @@ -71,6 +77,11 @@ public void ladderRemove(CommandSender sender, @Arg(name = "ladderName") String return; } + if ( ladder.getRanks().size() > 0 ) { + ladderDeleteCannotDeleteWithRanksMsg( sender ); + return; + } + if ( PrisonRanks.getInstance().getLadderManager().removeLadder(ladder) ) { ladderDeletedMsg( sender, ladderName ); @@ -93,55 +104,66 @@ public void ladderList(CommandSender sender) { display.send(sender); } - @Command(identifier = "ranks ladder listranks", description = "Lists the ranks within a ladder.", - onlyPlayers = false, permissions = "ranks.ladder") - public void ladderInfo(CommandSender sender, @Arg(name = "ladderName") String ladderName) { - RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); - - if ( ladder == null ) { - ladderDoesNotExistsMsg( sender, ladderName ); - return; - } - - ChatDisplay display = new ChatDisplay(ladder.getName()); - display.addText( ladderHasRankMsg() ); - - BulletedListComponent.BulletedListBuilder builder = - new BulletedListComponent.BulletedListBuilder(); - - boolean first = true; - for (Rank rank : ladder.getRanks()) { -// Rank rank = PrisonRanks.getInstance().getRankManager().getRank(rankPos.getRankId()); - if ( rank == null ) { - continue; - } - -// Optional rankOptional = -// PrisonRanks.getInstance().getRankManager().getRankOptional(rankPos.getRankId()); -// if(!rankOptional.isPresent()) { -// continue; // Skip it -// } - - boolean defaultRank = ("default".equalsIgnoreCase( ladderName ) && first); - - String defaultRankValue = ladderDefaultRankMsg(); - - builder.add("&3(#%s) &8- &3%s %s", - Integer.toString( rank.getPosition() ), - rank.getName(), - (defaultRank ? defaultRankValue : "") - ); - first = false; - } - - String seeRanksList = ladderSeeRanksListMsg(); - - builder.add( seeRanksList ); - - display.addComponent(builder.build()); - - display.send(sender); - } +// @Command(identifier = "ranks ladder listranks", description = "Lists the ranks within a ladder.", +// onlyPlayers = false, permissions = "ranks.ladder") +// public void ladderInfo( +// CommandSender sender, +// @Arg(name = "ladderName", def = "default", +// description = "The ladder name to display the ranks on. " + +// "Defaults to the default ladder") String ladderName +// +// ) { +// RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); +// +// if ( ladder == null ) { +// ladderDoesNotExistsMsg( sender, ladderName ); +// return; +// } +// +// ChatDisplay display = new ChatDisplay(ladder.getName()); +// display.addText( ladderHasRankMsg() ); +// +// BulletedListComponent.BulletedListBuilder builder = +// new BulletedListComponent.BulletedListBuilder(); +// +// boolean first = true; +// for (Rank rank : ladder.getRanks()) { +//// Rank rank = PrisonRanks.getInstance().getRankManager().getRank(rankPos.getRankId()); +// if ( rank == null ) { +// continue; +// } +// +//// Optional rankOptional = +//// PrisonRanks.getInstance().getRankManager().getRankOptional(rankPos.getRankId()); +//// if(!rankOptional.isPresent()) { +//// continue; // Skip it +//// } +// +// boolean defaultRank = ("default".equalsIgnoreCase( ladderName ) && first); +// +// String defaultRankValue = ladderDefaultRankMsg(); +// +// builder.add("&3(#%s) &8- &3%s (rankId: %s%s%s) %s", +// Integer.toString( rank.getPosition() ), +// rank.getName(), +// +// Integer.toString( rank.getId() ), +// (rank.getRankPrior() == null ? "" : " -"), +// (rank.getRankNext() == null ? "" : " +"), +// +// (defaultRank ? defaultRankValue : "") +// ); +// first = false; +// } +// +// String seeRanksList = ladderSeeRanksListMsg(); +// +// builder.add( seeRanksList ); +// +// display.addComponent(builder.build()); +// +// display.send(sender); +// } @Command(identifier = "ranks ladder moveRank", description = "Moves a rank to a new " + "ladder position or a new ladder.", @@ -155,12 +177,12 @@ public void ladderMoveRank(CommandSender sender, ladderMoveRankNoticeMsg( sender ); - ladderRemoveRank( sender, ladderName, rankName ); + ladderRemoveRank( sender, rankName ); ladderAddRank(sender, ladderName, rankName, position ); } - @Command(identifier = "ranks ladder addrank", description = "Adds a rank to a ladder, or move a rank.", - onlyPlayers = false, permissions = "ranks.ladder") +// @Command(identifier = "ranks ladder addrank", description = "Adds a rank to a ladder, or move a rank.", +// onlyPlayers = false, permissions = "ranks.ladder") public void ladderAddRank(CommandSender sender, @Arg(name = "ladderName") String ladderName, @Arg(name = "rankName") String rankName, @@ -181,7 +203,7 @@ public void ladderAddRank(CommandSender sender, return; } - if (ladder.containsRank(rank.getId())) { + if (ladder.containsRank( rank )) { ladderAlreadyHasRankMsg( sender, ladderName, rankName ); return; } @@ -194,6 +216,13 @@ public void ladderAddRank(CommandSender sender, if ( PrisonRanks.getInstance().getLadderManager().save(ladder) ) { + Prison.get().getPlatform().getPlaceholders().reloadPlaceholders(); + + + // Recalculate the ladder's base rank cost multiplier: + PlayerRankRefreshTask rankRefreshTask = new PlayerRankRefreshTask(); + rankRefreshTask.submitAsyncTPSTask(); + ladderAddedRankMsg( sender, ladderName, rankName, position ); } else { @@ -204,16 +233,19 @@ public void ladderAddRank(CommandSender sender, } } - @Command(identifier = "ranks ladder delrank", description = "Removes a rank from a ladder.", - onlyPlayers = false, permissions = "ranks.ladder") - public void ladderRemoveRank(CommandSender sender, @Arg(name = "ladderName") String ladderName, - @Arg(name = "rankName") String rankName) { - RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); +// @Command(identifier = "ranks ladder delrank", description = "Removes a rank from a ladder.", +// onlyPlayers = false, permissions = "ranks.ladder") + public void ladderRemoveRank(CommandSender sender, +// @Arg(name = "ladderName", description = "Then intended ladder to remove the rank from. " + +// "But note, this is ignored and the real ladder used is the ladder tied to the rank.") String ladderName, +// @Arg(name = "rankName") + String rankName) { +// RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); - if ( ladder == null ) { - ladderDoesNotExistsMsg( sender, ladderName ); - return; - } +// if ( ladder == null ) { +// ladderDoesNotExistsMsg( sender, ladderName ); +// return; +// } Rank rank = PrisonRanks.getInstance().getRankManager().getRank(rankName); // Optional rank = PrisonRanks.getInstance().getRankManager().getRankOptional(rankName); @@ -222,12 +254,26 @@ public void ladderRemoveRank(CommandSender sender, @Arg(name = "ladderName") Str return; } - ladder.removeRank(ladder.getPositionOfRank(rank)); + RankLadder ladder = rank.getLadder(); + + ladder.removeRank( rank ); +// ladder.removeRank(ladder.getPositionOfRank(rank)); if ( PrisonRanks.getInstance().getLadderManager().save(ladder) ) { - ladderRemovedRankFromLadderMsg( sender, rankName, ladderName ); + PrisonRanks.getInstance().getRankManager().saveRank( rank ); + + + Prison.get().getPlatform().getPlaceholders().reloadPlaceholders(); + + + // Recalculate the ladder's base rank cost multiplier: + PlayerRankRefreshTask rankRefreshTask = new PlayerRankRefreshTask(); + rankRefreshTask.submitAsyncTPSTask(); + + + ladderRemovedRankFromLadderMsg( sender, rankName, ladder.getName() ); } else { ladderErrorRemovingingMsg( sender ); @@ -237,5 +283,66 @@ public void ladderRemoveRank(CommandSender sender, @Arg(name = "ladderName") Str } + @Command( identifier = "ranks ladder rankCostMultiplier", + description = "Sets or removes a ladder's Rank Cost Multiplier. Setting the " + + "value to zero will remove the multiplier from the calculations. The " + + "Rank Cost Multiplier from all ladders a player has active, will be " + + "summed together and applied to the cost of all of their ranks. The Rank " + + "Cost Multiplier represents a percentage, and can be either postive or " + + "negative. ", + onlyPlayers = false, permissions = "ranks.ladder" ) + public void ladderSetRankCostMultiplier( CommandSender sender, + @Arg( name = "ladderName" ) String ladderName, + @Arg( name = "rankCostMultiplier", def = "0", + description = "Sets the Rank Cost Multiplier for the ladder, which will be " + + "applied to each rank, multiplied by the position of the rank. " + + "A value of zero is disabled. The value is expressed in " + + "percentages.") Double rankCostMultiplier ) + { + RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder( ladderName ); + + if ( ladder == null ) + { + ladderDoesNotExistsMsg( sender, ladderName ); + return; + } + + if ( rankCostMultiplier == null ) { + // rankCostMultiplier may never be null? + } + + if ( ladder.getRankCostMultiplierPerRank() == rankCostMultiplier ) { + // No change: + + ladderSetRankCostMultiplierNoChangeMsg( sender, ladderName, rankCostMultiplier ); + + return; + } + + if ( rankCostMultiplier < -100d || rankCostMultiplier > 100d ) { + + ladderSetRankCostMultiplierOutOfRangeMsg( sender, rankCostMultiplier ); + return; + } + + double oldRankCostMultiplier = ladder.getRankCostMultiplierPerRank() * 100; + + ladder.setRankCostMultiplierPerRank( rankCostMultiplier / 100 ); + + if ( PrisonRanks.getInstance().getLadderManager().save( ladder ) ) + { + ladderSetRankCostMultiplierSavedMsg( sender, ladderName, + rankCostMultiplier, oldRankCostMultiplier ); + + // Recalculate the ladder's base rank cost multiplier: + PlayerRankRefreshTask rankRefreshTask = new PlayerRankRefreshTask(); + rankRefreshTask.submitAsyncTPSTask(); + } + else + { + ladderErrorSavingMsg( sender ); + } + } + } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommandsMessages.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommandsMessages.java index 02aae8bbf..0a1ca1aa6 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommandsMessages.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommandsMessages.java @@ -1,5 +1,7 @@ package tech.mcprison.prison.ranks.commands; +import java.text.DecimalFormat; + import tech.mcprison.prison.commands.BaseCommands; import tech.mcprison.prison.internal.CommandSender; import tech.mcprison.prison.ranks.PrisonRanks; @@ -62,6 +64,12 @@ protected void ladderDeleteCannotDeletePrestigesMsg( CommandSender sender ) { .getLocalizable( "ranks_LadderCommands__ladder_cannot_delete_prestiges" ) .sendTo( sender ); } + + protected void ladderDeleteCannotDeleteWithRanksMsg( CommandSender sender ) { + PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_LadderCommands__ladder_cannot_delete_with_ranks" ) + .sendTo( sender ); + } protected void ladderDeletedMsg( CommandSender sender, String ladderName ) { PrisonRanks.getInstance().getRanksMessages() @@ -166,7 +174,46 @@ protected void ladderRemovedRankFromLadderMsg( CommandSender sender, .sendTo( sender ); } + protected void ladderSetRankCostMultiplierSavedMsg( CommandSender sender, String ladderName, + double rankCostMultiplier, double oldRankCostMultiplier ) + { + + DecimalFormat fFmt = new DecimalFormat("#,##0.00000"); + + PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_LadderCommands__ladder_set_rank_cost_multiplier" ) + .withReplacements( + ladderName, + fFmt.format( rankCostMultiplier ), + fFmt.format( oldRankCostMultiplier) ) + .sendTo( sender ); + } + + protected void ladderSetRankCostMultiplierNoChangeMsg( CommandSender sender, String ladderName, + double rankCostMultiplier ) + { + + DecimalFormat fFmt = new DecimalFormat("#,##0.00000"); + + PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_LadderCommands__ladder_rank_cost_multiplier_no_change" ) + .withReplacements( + ladderName, + fFmt.format( rankCostMultiplier ) ) + .sendTo( sender ); + } - + protected void ladderSetRankCostMultiplierOutOfRangeMsg( CommandSender sender, + double rankCostMultiplier ) + { + + DecimalFormat fFmt = new DecimalFormat("#,##0.00000"); + + PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_LadderCommands__ladder_rank_cost_multiplier_out_of_range" ) + .withReplacements( + fFmt.format( rankCostMultiplier ) ) + .sendTo( sender ); + } } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommandsPerms.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommandsPerms.java index cf7bcc066..5f578064a 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommandsPerms.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/LadderCommandsPerms.java @@ -1,16 +1,5 @@ package tech.mcprison.prison.ranks.commands; -import tech.mcprison.prison.chat.FancyMessage; -import tech.mcprison.prison.commands.Arg; -import tech.mcprison.prison.internal.CommandSender; -import tech.mcprison.prison.output.BulletedListComponent; -import tech.mcprison.prison.output.ChatDisplay; -import tech.mcprison.prison.output.FancyMessageComponent; -import tech.mcprison.prison.output.Output; -import tech.mcprison.prison.output.RowComponent; -import tech.mcprison.prison.ranks.PrisonRanks; -import tech.mcprison.prison.ranks.data.RankLadder; - /** * Ladder perms that are not being used. May be added later, or just removed. * @@ -29,205 +18,205 @@ public LadderCommandsPerms( String cmdGroup ) // NOT USED: // @Command(identifier = "ranks ladder perms list", description = "Lists ladder permissions", // onlyPlayers = false, permissions = "ranks.set") - public void ladderPermsList(CommandSender sender, - @Arg(name = "ladderName", def = "default", - description = "Ladder name to list the permissions.") String ladderName - ){ - sender.sendMessage( "&cWarning: &3This feature is not yet functional." ); - - RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); - - if ( ladder == null ) { - ladderDoesNotExistsMsg( sender, ladderName ); - return; - } - - if ( ladder.getPermissions() == null ||ladder.getPermissions().size() == 0 && - ladder.getPermissionGroups() == null && ladder.getPermissionGroups().size() == 0 ) { - - PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( "ranks_LadderCommands__ladder_has_no_perms" ) - .withReplacements( - ladder.getName() ) - .sendTo( sender ); - return; - } - - - - ChatDisplay display = new ChatDisplay("Ladder Permissions and Groups for " + ladder.getName()); - display.addText("&8Click the 'Remove' tag to remove it."); - display.addText(" &3Placeholders: &7{rank}&3 - Rank Name"); - display.addText(" &3All Ladder perms will be applied automatically to all ladder ranks."); - - BulletedListComponent.BulletedListBuilder builder = - new BulletedListComponent.BulletedListBuilder(); - - - int rowNumber = 1; - - if ( ladder.getPermissions().size() > 0 ) { - builder.add( "&7Permissions:" ); - } - for (String perm : ladder.getPermissions() ) { - - RowComponent row = new RowComponent(); - - row.addTextComponent( " &3Row: &d%d ", rowNumber++ ); - - FancyMessage msgPermission = new FancyMessage( String.format( "&7%s ", perm ) ) - .command( "/ranks ladder perms edit " + ladder.getName() + " " + rowNumber + " " ) - .tooltip("Permission - Click to Edit"); - row.addFancy( msgPermission ); - - - FancyMessage msgRemove = new FancyMessage( String.format( " &cRemove " ) ) - .command( "/ranks ladder perms remove " + ladder.getName() + " " + rowNumber + " " ) - .tooltip("Remove Permission - Click to Delete"); - row.addFancy( msgRemove ); - - builder.add( row ); - } - - if ( ladder.getPermissionGroups().size() > 0 ) { - builder.add( "&7Permission Groups:" ); - } - for (String permGroup : ladder.getPermissionGroups() ) { - - RowComponent row = new RowComponent(); - - row.addTextComponent( " &3Row: &d%d ", rowNumber++ ); - - FancyMessage msgPermission = new FancyMessage( String.format( "&7%s ", permGroup ) ) - .command( "/ranks ladder perms edit " + ladder.getName() + " " + rowNumber + " " ) - .tooltip("Permission Group - Click to Edit"); - row.addFancy( msgPermission ); - - - FancyMessage msgRemove = new FancyMessage( String.format( " &cRemove " ) ) - .command( "/ranks ladder perms remove " + ladder.getName() + " " + rowNumber + " " ) - .tooltip("Remove Permission Group - Click to Delete"); - row.addFancy( msgRemove ); - - builder.add( row ); - } - - - display.addComponent(builder.build()); - display.addComponent(new FancyMessageComponent( - new FancyMessage("&7[&a+&7] Add Permission") - .suggest("/ranks ladder perms addPerm " + ladder.getName() + " [perm] /") - .tooltip("&7Add a new Permission."))); - display.addComponent(new FancyMessageComponent( - new FancyMessage("&7[&a+&7] Add Permission Group") - .suggest("/ranks ladder perms addPermGroup " + ladder.getName() + " [permGroup] /") - .tooltip("&7Add a new Permission Group."))); - - display.send(sender); - - } +// public void ladderPermsList(CommandSender sender, +// @Arg(name = "ladderName", def = "default", +// description = "Ladder name to list the permissions.") String ladderName +// ){ +// sender.sendMessage( "&cWarning: &3This feature is not yet functional." ); +// +// RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); +// +// if ( ladder == null ) { +// ladderDoesNotExistsMsg( sender, ladderName ); +// return; +// } +// +// if ( ladder.getPermissions() == null ||ladder.getPermissions().size() == 0 && +// ladder.getPermissionGroups() == null && ladder.getPermissionGroups().size() == 0 ) { +// +// PrisonRanks.getInstance().getRanksMessages() +// .getLocalizable( "ranks_LadderCommands__ladder_has_no_perms" ) +// .withReplacements( +// ladder.getName() ) +// .sendTo( sender ); +// return; +// } +// +// +// +// ChatDisplay display = new ChatDisplay("Ladder Permissions and Groups for " + ladder.getName()); +// display.addText("&8Click the 'Remove' tag to remove it."); +// display.addText(" &3Placeholders: &7{rank}&3 - Rank Name"); +// display.addText(" &3All Ladder perms will be applied automatically to all ladder ranks."); +// +// BulletedListComponent.BulletedListBuilder builder = +// new BulletedListComponent.BulletedListBuilder(); +// +// +// int rowNumber = 1; +// +// if ( ladder.getPermissions().size() > 0 ) { +// builder.add( "&7Permissions:" ); +// } +// for (String perm : ladder.getPermissions() ) { +// +// RowComponent row = new RowComponent(); +// +// row.addTextComponent( " &3Row: &d%d ", rowNumber++ ); +// +// FancyMessage msgPermission = new FancyMessage( String.format( "&7%s ", perm ) ) +// .command( "/ranks ladder perms edit " + ladder.getName() + " " + rowNumber + " " ) +// .tooltip("Permission - Click to Edit"); +// row.addFancy( msgPermission ); +// +// +// FancyMessage msgRemove = new FancyMessage( String.format( " &cRemove " ) ) +// .command( "/ranks ladder perms remove " + ladder.getName() + " " + rowNumber + " " ) +// .tooltip("Remove Permission - Click to Delete"); +// row.addFancy( msgRemove ); +// +// builder.add( row ); +// } +// +// if ( ladder.getPermissionGroups().size() > 0 ) { +// builder.add( "&7Permission Groups:" ); +// } +// for (String permGroup : ladder.getPermissionGroups() ) { +// +// RowComponent row = new RowComponent(); +// +// row.addTextComponent( " &3Row: &d%d ", rowNumber++ ); +// +// FancyMessage msgPermission = new FancyMessage( String.format( "&7%s ", permGroup ) ) +// .command( "/ranks ladder perms edit " + ladder.getName() + " " + rowNumber + " " ) +// .tooltip("Permission Group - Click to Edit"); +// row.addFancy( msgPermission ); +// +// +// FancyMessage msgRemove = new FancyMessage( String.format( " &cRemove " ) ) +// .command( "/ranks ladder perms remove " + ladder.getName() + " " + rowNumber + " " ) +// .tooltip("Remove Permission Group - Click to Delete"); +// row.addFancy( msgRemove ); +// +// builder.add( row ); +// } +// +// +// display.addComponent(builder.build()); +// display.addComponent(new FancyMessageComponent( +// new FancyMessage("&7[&a+&7] Add Permission") +// .suggest("/ranks ladder perms addPerm " + ladder.getName() + " [perm] /") +// .tooltip("&7Add a new Permission."))); +// display.addComponent(new FancyMessageComponent( +// new FancyMessage("&7[&a+&7] Add Permission Group") +// .suggest("/ranks ladder perms addPermGroup " + ladder.getName() + " [permGroup] /") +// .tooltip("&7Add a new Permission Group."))); +// +// display.send(sender); +// +// } //NOT USED: // @Command(identifier = "ranks ladder perms addPerm", // description = "Add a ladder permission. Valid placeholder: {rank}.", // onlyPlayers = false, permissions = "ranks.set") - public void ladderPermsAddPerm(CommandSender sender, - @Arg(name = "ladderName", def = "default", - description = "Ladder name to add the permission to.") String ladderName, - @Arg(name = "permission", description = "Permission") String permission - ){ - sender.sendMessage( "&cWarning: &3This feature is not yet functional." ); - - RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); - - if ( ladder == null ) { - Output.get().sendError(sender, "The ladder '%s' doesn't exist.", ladderName); - return; - } - - if ( permission == null || permission.trim().isEmpty() ) { - - Output.get().sendInfo(sender, "&3The &7permission &3parameter is required." ); - return; - } - - - if ( ladder.hasPermission( permission ) ) { - - Output.get().sendInfo(sender, "&3The permission &7%s &3already exists.", permission ); - return; - } - - ladder.getPermissions().add( permission ); - - boolean saved = PrisonRanks.getInstance().getLadderManager().save( ladder ); - - if ( saved ) { - - Output.get().sendInfo(sender, "&3The permission &7%s &3was successfully added " + - "to the ladder &7%s&3.", permission, ladder.getName() ); - } - else { - - Output.get().sendInfo(sender, "&cFailure: &3The permission &7%s &3was unable to " + - "be saved to the ladder &7%s&3. See the console for additional informatio.", - permission, ladder.getName() ); - } - - ladderPermsList( sender, ladder.getName() ); - } +// public void ladderPermsAddPerm(CommandSender sender, +// @Arg(name = "ladderName", def = "default", +// description = "Ladder name to add the permission to.") String ladderName, +// @Arg(name = "permission", description = "Permission") String permission +// ){ +// sender.sendMessage( "&cWarning: &3This feature is not yet functional." ); +// +// RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); +// +// if ( ladder == null ) { +// Output.get().sendError(sender, "The ladder '%s' doesn't exist.", ladderName); +// return; +// } +// +// if ( permission == null || permission.trim().isEmpty() ) { +// +// Output.get().sendInfo(sender, "&3The &7permission &3parameter is required." ); +// return; +// } +// +// +// if ( ladder.hasPermission( permission ) ) { +// +// Output.get().sendInfo(sender, "&3The permission &7%s &3already exists.", permission ); +// return; +// } +// +// ladder.getPermissions().add( permission ); +// +// boolean saved = PrisonRanks.getInstance().getLadderManager().save( ladder ); +// +// if ( saved ) { +// +// Output.get().sendInfo(sender, "&3The permission &7%s &3was successfully added " + +// "to the ladder &7%s&3.", permission, ladder.getName() ); +// } +// else { +// +// Output.get().sendInfo(sender, "&cFailure: &3The permission &7%s &3was unable to " + +// "be saved to the ladder &7%s&3. See the console for additional informatio.", +// permission, ladder.getName() ); +// } +// +// ladderPermsList( sender, ladder.getName() ); +// } //NOT USED: // @Command(identifier = "ranks ladder perms addGroup", // description = "Add a ladder permission group. Valid placeholder: {rank}.", // onlyPlayers = false, permissions = "ranks.set") - public void ladderPermsAddGroup(CommandSender sender, - @Arg(name = "ladderName", def = "default", - description = "Ladder name to add the permission group to.") String ladderName, - @Arg(name = "permissionGroup", description = "Permission Group") String permissionGroup - ){ - sender.sendMessage( "&cWarning: &3This feature is not yet functional." ); - - RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); - - if ( ladder == null ) { - Output.get().sendError(sender, "The ladder '%s' doesn't exist.", ladderName); - return; - } - - if ( permissionGroup == null || permissionGroup.trim().isEmpty() ) { - - Output.get().sendInfo(sender, "&3The &7permissionGroup &3parameter is required." ); - return; - } - - - if ( ladder.hasPermissionGroup( permissionGroup ) ) { - - Output.get().sendInfo(sender, "&3The permission group &7%s &3already exists.", - permissionGroup ); - return; - } - - ladder.getPermissionGroups().add( permissionGroup ); - - boolean saved = PrisonRanks.getInstance().getLadderManager().save( ladder ); - - if ( saved ) { - - Output.get().sendInfo(sender, "&3The permission group &7%s &3was successfully added " + - "to the ladder &7%s&3.", permissionGroup, ladder.getName() ); - } - else { - - Output.get().sendInfo(sender, "&cFailure: &3The permission group &7%s &3was unable to " + - "be saved to the ladder &7%s&3. See the console for additional information.", - permissionGroup, ladder.getName() ); - } - - ladderPermsList( sender, ladder.getName() ); - } +// public void ladderPermsAddGroup(CommandSender sender, +// @Arg(name = "ladderName", def = "default", +// description = "Ladder name to add the permission group to.") String ladderName, +// @Arg(name = "permissionGroup", description = "Permission Group") String permissionGroup +// ){ +// sender.sendMessage( "&cWarning: &3This feature is not yet functional." ); +// +// RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); +// +// if ( ladder == null ) { +// Output.get().sendError(sender, "The ladder '%s' doesn't exist.", ladderName); +// return; +// } +// +// if ( permissionGroup == null || permissionGroup.trim().isEmpty() ) { +// +// Output.get().sendInfo(sender, "&3The &7permissionGroup &3parameter is required." ); +// return; +// } +// +// +// if ( ladder.hasPermissionGroup( permissionGroup ) ) { +// +// Output.get().sendInfo(sender, "&3The permission group &7%s &3already exists.", +// permissionGroup ); +// return; +// } +// +// ladder.getPermissionGroups().add( permissionGroup ); +// +// boolean saved = PrisonRanks.getInstance().getLadderManager().save( ladder ); +// +// if ( saved ) { +// +// Output.get().sendInfo(sender, "&3The permission group &7%s &3was successfully added " + +// "to the ladder &7%s&3.", permissionGroup, ladder.getName() ); +// } +// else { +// +// Output.get().sendInfo(sender, "&cFailure: &3The permission group &7%s &3was unable to " + +// "be saved to the ladder &7%s&3. See the console for additional information.", +// permissionGroup, ladder.getName() ); +// } +// +// ladderPermsList( sender, ladder.getName() ); +// } // Since we are strictly dealing with a single value for perms, editing makes no sense; // just delete the 'bad' perm and re-add it. @@ -255,72 +244,72 @@ public void ladderPermsAddGroup(CommandSender sender, //NOT USED: // @Command(identifier = "ranks ladder perms remove", description = "Lists ladder permissions", // onlyPlayers = false, permissions = "ranks.set") - public void ladderPermsRemove(CommandSender sender, - @Arg(name = "ladderName", def = "default", - description = "Ladder name to list the permissions.") String ladderName, - @Arg(name = "row") Integer row - ){ - sender.sendMessage( "&cWarning: &3This feature is not yet functional." ); - - RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); - - if ( ladder == null ) { - Output.get().sendError(sender, "The ladder '%s' doesn't exist.", ladderName); - return; - } - - boolean dirty = false; - String removedPerm = ""; - boolean permGroup = false; - - if ( row == null || row <= 0 ) { - sender.sendMessage( - String.format("&7Please provide a valid row number greater than zero. " + - "Was row=[&b%d&7]", - (row == null ? "null" : row) )); - return; - } - - if ( row <= ladder.getPermissions().size() ) { - removedPerm = ladder.getPermissions().remove( row - 1 ); - dirty = true; - } - else { - // Remove from row the size of permissions so the row will align to the permissionGroups. - row -= ladder.getPermissions().size(); - - if ( row <= ladder.getPermissionGroups().size() ) { - - removedPerm = ladder.getPermissions().remove( row - 1 ); - dirty = true; - permGroup = true; - } - } - - if ( dirty ) { - boolean saved = PrisonRanks.getInstance().getLadderManager().save( ladder ); - - if ( saved ) { - - Output.get().sendInfo(sender, "&3The permission%s &7%s &3was successfully removed " + - "to the ladder &7%s&3.", - ( permGroup ? " group" : "" ), - removedPerm, ladder.getName() ); - } - else { - - Output.get().sendInfo(sender, "&cFailure: &3The permission%s &7%s &3was unable to " + - "be saved to the ladder &7%s&3. See the console for additional information.", - ( permGroup ? " group" : "" ), - removedPerm, ladder.getName() ); - } - } - else { - Output.get().sendInfo(sender, "&3The permission on row &7%s &3was unable to be removed " + - "from the &7%s &3ladder. " + - "Is that a valid row number?", - Integer.toString( row ), ladder.getName() ); - } - } +// public void ladderPermsRemove(CommandSender sender, +// @Arg(name = "ladderName", def = "default", +// description = "Ladder name to list the permissions.") String ladderName, +// @Arg(name = "row") Integer row +// ){ +// sender.sendMessage( "&cWarning: &3This feature is not yet functional." ); +// +// RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); +// +// if ( ladder == null ) { +// Output.get().sendError(sender, "The ladder '%s' doesn't exist.", ladderName); +// return; +// } +// +// boolean dirty = false; +// String removedPerm = ""; +// boolean permGroup = false; +// +// if ( row == null || row <= 0 ) { +// sender.sendMessage( +// String.format("&7Please provide a valid row number greater than zero. " + +// "Was row=[&b%d&7]", +// (row == null ? "null" : row) )); +// return; +// } +// +// if ( row <= ladder.getPermissions().size() ) { +// removedPerm = ladder.getPermissions().remove( row - 1 ); +// dirty = true; +// } +// else { +// // Remove from row the size of permissions so the row will align to the permissionGroups. +// row -= ladder.getPermissions().size(); +// +// if ( row <= ladder.getPermissionGroups().size() ) { +// +// removedPerm = ladder.getPermissions().remove( row - 1 ); +// dirty = true; +// permGroup = true; +// } +// } +// +// if ( dirty ) { +// boolean saved = PrisonRanks.getInstance().getLadderManager().save( ladder ); +// +// if ( saved ) { +// +// Output.get().sendInfo(sender, "&3The permission%s &7%s &3was successfully removed " + +// "to the ladder &7%s&3.", +// ( permGroup ? " group" : "" ), +// removedPerm, ladder.getName() ); +// } +// else { +// +// Output.get().sendInfo(sender, "&cFailure: &3The permission%s &7%s &3was unable to " + +// "be saved to the ladder &7%s&3. See the console for additional information.", +// ( permGroup ? " group" : "" ), +// removedPerm, ladder.getName() ); +// } +// } +// else { +// Output.get().sendInfo(sender, "&3The permission on row &7%s &3was unable to be removed " + +// "from the &7%s &3ladder. " + +// "Is that a valid row number?", +// Integer.toString( row ), ladder.getName() ); +// } +// } } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RankUpCommand.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RankUpCommand.java index ba8c7b545..eb9babf7c 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RankUpCommand.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RankUpCommand.java @@ -26,12 +26,14 @@ import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.internal.platform.Platform; import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.output.Output.DebugTarget; import tech.mcprison.prison.ranks.PrisonRanks; import tech.mcprison.prison.ranks.RankUtil; import tech.mcprison.prison.ranks.RankUtil.PromoteForceCharge; import tech.mcprison.prison.ranks.RankUtil.RankupModes; import tech.mcprison.prison.ranks.RankUtil.RankupStatus; import tech.mcprison.prison.ranks.RankupResults; +import tech.mcprison.prison.ranks.data.PlayerRank; import tech.mcprison.prison.ranks.data.Rank; import tech.mcprison.prison.ranks.data.RankLadder; import tech.mcprison.prison.ranks.data.RankPlayer; @@ -67,10 +69,18 @@ public void rankUpMax(CommandSender sender, ) { // Not supposed to check perms here... But it is a simple check, and it if works... - if ( sender.hasPermission("ranks.rankupmax." + ladder) || sender.hasPermission("ranks.rankupmax.prestiges")) { + if ( sender.hasPermission("ranks.rankupmax." + ladder) + // || sender.hasPermission("ranks.rankupmax.prestiges") + ) { + Output.get().logDebug( DebugTarget.rankup, + "Rankup: cmd '/rankupmax %s' Passed perm check: ranks.rankupmax.%s", + ladder, ladder ); rankUpPrivate(sender, ladder, RankupModes.MAX_RANKS, "ranks.rankupmax."); } else { + Output.get().logDebug( DebugTarget.rankup, + "Rankup: Failed: cmd '/rankupmax %s' Does not have the permission ranks.rankupmax.%s", + ladder, ladder ); rankupMaxNoPermissionMsg( sender, "ranks.rankupmax." + ladder ); } } @@ -85,6 +95,9 @@ public void rankUp(CommandSender sender, Output.get().logInfo( rankupCannotRunFromConsoleMsg() ); return; } + Output.get().logDebug( DebugTarget.rankup, + "Rankup: cmd '/rankup %s' Processing ranks.rankup.%s", + ladder, ladder ); rankUpPrivate(sender, ladder, RankupModes.ONE_RANK, "ranks.rankup." ); } @@ -99,6 +112,9 @@ private void rankUpPrivate(CommandSender sender, String ladder, RankupModes mode Prison.get().getPlatform().getConfigBooleanFalse( "prestige.enabled" ))) && !ladder.equalsIgnoreCase("default") && !sender.hasPermission(permission + ladder.toLowerCase())) { + + Output.get().logDebug( DebugTarget.rankup, + "Rankup: rankUpPrivate: failed rankup perm check"); rankupMaxNoPermissionMsg( sender, permission + ladder ); return; @@ -128,72 +144,109 @@ private void rankUpPrivate(CommandSender sender, String ladder, RankupModes mode return; } - RankPlayer rankPlayer = getRankPlayer( sender, player.getUUID(), player.getName() ); - Rank pRank = rankPlayer.getRank( ladder ); - // gets the rank on the default ladder. Used if ladder is not default. - Rank pRankSecond = rankPlayer.getRank("default"); - Rank pRankAfter = null; LadderManager lm = PrisonRanks.getInstance().getLadderManager(); - boolean canPrestige = false; + RankLadder targetLadder = lm.getLadder( ladder ); + + if ( targetLadder == null ){ + rankupErrorNoLadderMsg( sender, ladder ); + return; + } + + if (!targetLadder.getLowestRank().isPresent()){ + rankupErrorNoRankOnLadderMsg( sender, ladder ); + return; + } + - // If the player is trying to prestige, then the following must be ran to setup the prestige checks: - if (ladder.equalsIgnoreCase("prestiges")) { + RankPlayer rankPlayer = getRankPlayer( sender, player.getUUID(), player.getName() ); + PlayerRank playerRankCurrent = rankPlayer.getRank( ladder ); + PlayerRank playerRankTarget = + PlayerRank.getTargetPlayerRankForPlayer( rankPlayer, + playerRankCurrent == null ? targetLadder.getLowestRank().get() : + playerRankCurrent.getRank() + ); + + + Output.get().logDebug( DebugTarget.rankup, + "Rankup: rankUpPrivate: RankPlayer %s playerRankTarget %s", + (rankPlayer == null ? "null" : "true"), + (playerRankTarget == null ? "null" : "true") ); + + // If a player has a rank on the ladder get their rank, otherwise null: + Rank pRankTarget = playerRankTarget.getRank(); + + Rank pRankAfter = null; + boolean canPrestige = false; + + // If the player is trying to prestige, then the following must be ran to setup the prestige checks: + if (ladder.equalsIgnoreCase("prestiges")) { - RankLadder rankLadder = lm.getLadder("default"); - - if ( rankLadder == null ){ - - rankupErrorNoDefaultLadderMsg( sender ); - return; - } - if (!rankLadder.getLowestRank().isPresent()){ - rankupErrorNoLowerRankMsg( sender ); - return; - } - - Rank rank = rankLadder.getLowestRank().get(); - - while (rank.getRankNext() != null) { - rank = rank.getRankNext(); - } - - if (!(rank == pRankSecond)) { - rankupNotAtLastRankMsg( sender ); - return; - } - - // IF everything's ready, this will be true if and only if pRank is not null, - // and the prestige method will start - canPrestige = true; - } + RankLadder rankLadder = lm.getLadder("default"); + + if ( rankLadder == null ){ + rankupErrorNoDefaultLadderMsg( sender ); + return; + } + + if (!rankLadder.getLowestRank().isPresent()){ + rankupErrorNoLowerRankMsg( sender ); + return; + } + + // gets the rank on the default ladder. Used if ladder is not default. + PlayerRank pRankDefaultLadder = rankPlayer.getRank("default"); + if ( pRankDefaultLadder == null ) { + rankupErrorPlayerNotOnDefaultLadder( sender, rankPlayer ); + } + + Rank playersRankOnDefaultLadder = pRankDefaultLadder.getRank(); + // On the default ladder, the player must be at the last rank: + // The last rank will never have a rankNext (it will be null): + if ( playersRankOnDefaultLadder.getRankNext() != null ) { + rankupNotAtLastRankMsg( sender ); + return; + } + + // IF everything's ready, this will be true if and only if pRank is not null, + // and the prestige method will start + canPrestige = true; + } + // Get currency if it exists, otherwise it will be null if the Rank has no currency: - String currency = rankPlayer == null || pRank == null ? null : pRank.getCurrency(); - - boolean rankupWithSuccess = false; - + String currency = rankPlayer == null || pRankTarget == null ? null : pRankTarget.getCurrency(); + + boolean rankupWithSuccess = false; + if (rankPlayer != null ) { // Performs the actual rankup here: RankupResults results = new RankUtil().rankupPlayer(player, rankPlayer, ladder, sender.getName()); processResults( sender, player.getName(), results, null, ladder, currency ); - + // If the last rankup attempt was successful and they are trying to rankup as many times as possible: if (results.getStatus() == RankupStatus.RANKUP_SUCCESS && mode == RankupModes.MAX_RANKS && - !ladder.equals("prestiges")) { + !ladder.equals("prestiges")) { rankUpPrivate( sender, ladder, mode, permission ); } if (results.getStatus() == RankupStatus.RANKUP_SUCCESS){ rankupWithSuccess = true; - } - + } + + // Get the player rank after - pRankAfter = rankPlayer.getRank(ladder); - + PlayerRank playerRankAfter = rankPlayer.getRank( ladder ); - // Prestige method if canPrestige and a successful rankup. pRank cannot be the same as pRankAfter: - if ( canPrestige && rankupWithSuccess && pRankAfter != null && pRank != pRankAfter ) { + if ( playerRankAfter != null ) { + + pRankAfter = playerRankAfter.getRank(); + } + + // Prestige method if canPrestige and a successful rankup. + // pRankTarget now contains the target rank prior to processing the rankup. SO it should be + // the same as pRankAfter, but if it is wrong, then rankupWithSuccess will not be true. So ignore... + if ( canPrestige && rankupWithSuccess && pRankAfter != null ) { prestigePlayer( sender, player, rankPlayer, pRankAfter, lm ); } else if ( canPrestige ) { @@ -228,6 +281,8 @@ else if ( canPrestige ) { private void prestigePlayer(CommandSender sender, Player player, RankPlayer rankPlayer, Rank pRankAfter, LadderManager lm ) { + Output.get().logDebug( DebugTarget.rankup, "Rankup: prestigePlayer: "); + Platform platform = Prison.get().getPlatform(); boolean resetBalance = platform.getConfigBooleanTrue( "prestige.resetMoney" ); boolean resetDefaultLadder = platform.getConfigBooleanTrue( "prestige.resetDefaultLadder" ); @@ -246,10 +301,20 @@ private void prestigePlayer(CommandSender sender, Player player, RankPlayer rank // PrisonAPI.dispatchCommand("ranks set rank " + player.getName() + " " + // lm.getLadder("default").getLowestRank().get().getName() + " default"); // Get that rank - Rank pRankSecond = rankPlayer.getRank("default"); - // Check if the ranks match - - if (pRankSecond != lm.getLadder("default").getLowestRank().get()) { + + PlayerRank playerRankSecond = rankPlayer.getRank("default"); + if ( playerRankSecond != null ) { + + Rank pRankSecond = playerRankSecond.getRank(); + // Check if the ranks match + + if (pRankSecond != lm.getLadder("default").getLowestRank().get()) { + + rankupNotAbleToResetRankMsg( sender ); + success = false; + } + } + else { rankupNotAbleToResetRankMsg( sender ); success = false; @@ -304,18 +369,26 @@ public void promotePlayer(CommandSender sender, ladder = confirmLadder( sender, ladder ); RankPlayer rankPlayer = getRankPlayer( sender, playerUuid, player.getName() ); - Rank pRank = rankPlayer.getRank( ladder ); + PlayerRank playerRank = rankPlayer.getRank( ladder ); - // Get currency if it exists, otherwise it will be null if the Rank has no currency: - String currency = rankPlayer == null || pRank == null ? null : pRank.getCurrency(); - - - - if ( ladder != null && rankPlayer != null ) { - RankupResults results = new RankUtil().promotePlayer(player, rankPlayer, ladder, - player.getName(), sender.getName(), pForceCharge); + if ( playerRank != null ) { - processResults( sender, player.getName(), results, null, ladder, currency ); + Rank pRank = playerRank.getRank(); + + // Get currency if it exists, otherwise it will be null if the Rank has no currency: + String currency = rankPlayer == null || pRank == null ? null : pRank.getCurrency(); + + + + if ( ladder != null && rankPlayer != null ) { + RankupResults results = new RankUtil().promotePlayer(player, rankPlayer, ladder, + player.getName(), sender.getName(), pForceCharge); + + processResults( sender, player.getName(), results, null, ladder, currency ); + } + } + else { + // Message: Player is not on the ladder } } @@ -345,18 +418,30 @@ public void demotePlayer(CommandSender sender, UUID playerUuid = player.getUUID(); ladder = confirmLadder( sender, ladder ); + if ( ladder == null ) { + // Already displayed error message about ladder not existing: + return; + } RankPlayer rankPlayer = getRankPlayer( sender, playerUuid, player.getName() ); - Rank pRank = rankPlayer.getRank( ladder ); + PlayerRank playerRank = rankPlayer.getRank( ladder ); - // Get currency if it exists, otherwise it will be null if the Rank has no currency: - String currency = rankPlayer == null || pRank == null ? null : pRank.getCurrency(); - - if ( ladder != null && rankPlayer != null ) { - RankupResults results = new RankUtil().demotePlayer(player, rankPlayer, ladder, - player.getName(), sender.getName(), pForceCharge); + if ( playerRank != null ) { - processResults( sender, player.getName(), results, null, ladder, currency ); + Rank pRank = playerRank.getRank(); + + // Get currency if it exists, otherwise it will be null if the Rank has no currency: + String currency = rankPlayer == null || pRank == null ? null : pRank.getCurrency(); + + if ( ladder != null && rankPlayer != null ) { + RankupResults results = new RankUtil().demotePlayer(player, rankPlayer, ladder, + player.getName(), sender.getName(), pForceCharge); + + processResults( sender, player.getName(), results, null, ladder, currency ); + } + } + else { + // Message: Player is not on the ladder } } @@ -383,7 +468,15 @@ public void setRank(CommandSender sender, Player targetPlayer = getPlayer( null, player.getName() ); if ( targetPlayer != null ) { - String targetRank = rank.equalsIgnoreCase("*same*") ? player.getRank( ladder ).getName() : rank; + boolean isSameRank = rank.equalsIgnoreCase("*same*"); + + PlayerRank pRank = player.getRank( ladder ); + String rankNameCurrent = isSameRank && + pRank != null && + pRank.getRank() != null ? + pRank.getRank().getName() : ""; + + String targetRank = isSameRank ? rankNameCurrent : rank; setPlayerRank( targetPlayer, targetRank, ladder, sender ); } } @@ -403,7 +496,7 @@ public void setRank(CommandSender sender, } - @Command(identifier = "ranks remove rank", description = "Removes a player from a specified ladder " + + @Command(identifier = "ranks removeRank", description = "Removes a player from a specified ladder " + "(delete player rank). This is an alias for /ranks set rank -remove- .", permissions = "ranks.setrank", onlyPlayers = false) public void removeRank(CommandSender sender, @@ -415,22 +508,43 @@ public void removeRank(CommandSender sender, } - private void setPlayerRank( Player player, String rank, String ladder, CommandSender sender ) { + public void setPlayerRank( RankPlayer rankPlayer, Rank pRank ) { + + if ( rankPlayer != null ) { + RankupResults results = + new RankUtil().setRank(rankPlayer, rankPlayer, + pRank.getLadder().getName(), pRank.getName(), + rankPlayer.getName(), rankPlayer.getName()); + + processResults( rankPlayer, rankPlayer.getName(), results, + pRank.getName(), pRank.getLadder().getName(), + pRank.getCurrency() ); + } + } + + + private void setPlayerRank( Player player, String rank, String ladderName, CommandSender sender ) { UUID playerUuid = player.getUUID(); - ladder = confirmLadder( sender, ladder ); + Output.get().logDebug( DebugTarget.rankup, "Rankup: setPlayerRank: "); + + ladderName = confirmLadder( sender, ladderName ); RankPlayer rankPlayer = getRankPlayer( sender, playerUuid, player.getName() ); - Rank pRank = rankPlayer.getRank( ladder ); - // Get currency if it exists, otherwise it will be null if the Rank has no currency: - String currency = rankPlayer == null || pRank == null ? null : pRank.getCurrency(); + if ( ladderName != null && rankPlayer != null ) { - if ( ladder != null && rankPlayer != null ) { - RankupResults results = new RankUtil().setRank(player, rankPlayer, ladder, rank, - player.getName(), sender.getName()); +// RankLadder rLadder = PrisonRanks.getInstance().getLadderManager().getLadder( ladderName ); + + Rank pRank = PrisonRanks.getInstance().getRankManager().getRank( rank ); + + // Get currency if it exists, otherwise it will be null if the Rank has no currency: + String currency = rankPlayer == null || pRank == null ? null : pRank.getCurrency(); + + RankupResults results = new RankUtil().setRank(player, rankPlayer, ladderName, rank, + player.getName(), sender.getName()); - processResults( sender, player.getName(), results, rank, ladder, currency ); + processResults( sender, player.getName(), results, rank, ladderName, currency ); } } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RankUpCommandMessages.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RankUpCommandMessages.java index e07a51fca..b756c595c 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RankUpCommandMessages.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RankUpCommandMessages.java @@ -8,9 +8,12 @@ import tech.mcprison.prison.localization.Localizable; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.ranks.PrisonRanks; -import tech.mcprison.prison.ranks.RankupResults; import tech.mcprison.prison.ranks.RankUtil.PromoteForceCharge; import tech.mcprison.prison.ranks.RankUtil.RankupStatus; +import tech.mcprison.prison.ranks.RankupResults; +import tech.mcprison.prison.ranks.data.PlayerRank; +import tech.mcprison.prison.ranks.data.Rank; +import tech.mcprison.prison.ranks.data.RankPlayer; public class RankUpCommandMessages extends BaseCommands { @@ -52,6 +55,28 @@ protected void rankupErrorNoLowerRankMsg( CommandSender sender ) { .sendTo( sender ); } + protected void rankupErrorNoLadderMsg( CommandSender sender, String ladderName ) { + PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_rankup__error_no_ladder" ) + .withReplacements( ladderName ) + .sendTo( sender ); + } + + protected void rankupErrorNoRankOnLadderMsg( CommandSender sender, String ladderName ) { + PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_rankup__error_no_lower_rank_on_ladder" ) + .withReplacements( ladderName ) + .sendTo( sender ); + } + + protected void rankupErrorPlayerNotOnDefaultLadder( CommandSender sender, + RankPlayer rankPlayer ) { + PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_rankup__error_player_not_on_default_ladder" ) + .withReplacements( rankPlayer.getName() ) + .sendTo( sender ); + } + protected void rankupNotAtLastRankMsg( CommandSender sender ) { PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankup__not_at_last_rank" ) @@ -146,12 +171,16 @@ protected void ranksRankupSuccessMsg( CommandSender sender, String playerName, String messagNoPlayerName = PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankup__rankup_no_player_name" ).localize(); +// PlayerRank tpRank = results.getPlayerRankTarget(); + Rank tRank = results.getTargetRank(); + + Localizable localManager = PrisonRanks.getInstance().getRanksMessages() .getLocalizable( messageId ) .withReplacements( (playerName == null ? messagNoPlayerName : playerName), - (results.getTargetRank() == null ? "" : results.getTargetRank().getName()), + (tRank == null ? "" : tRank.getName()), (results.getMessage() != null ? results.getMessage() : "") ); @@ -173,7 +202,7 @@ protected void ranksRankupSuccessMsg( CommandSender sender, String playerName, .withReplacements( (playerName == null ? messagNoPlayerNameBroadcast : playerName), - (results.getTargetRank() == null ? "" : results.getTargetRank().getName()), + (tRank == null ? "" : tRank.getName()), (results.getMessage() != null ? results.getMessage() : "") ) .broadcast(); @@ -188,12 +217,15 @@ protected void ranksRankupCannotAffordMsg( CommandSender sender, DecimalFormat dFmt = new DecimalFormat("#,##0.00"); + PlayerRank tpRank = results.getPlayerRankTarget(); + Rank tRank = results.getTargetRank(); + PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankup__rankup_cant_afford" ) .withReplacements( - dFmt.format( results.getTargetRank() == null ? 0 : results.getTargetRank().getCost()), - results.getTargetRank().getCurrency() == null ? "" : results.getTargetRank().getCurrency() + dFmt.format( tpRank == null ? 0 : tpRank.getRankCost()), + tRank == null || tRank.getCurrency() == null ? "" : results.getTargetRank().getCurrency() ) .sendTo( sender ); } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java index 04f7e3697..05cf02d20 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommands.java @@ -8,10 +8,11 @@ import java.util.Map; import java.util.Optional; import java.util.Set; -import java.util.stream.Collectors; import tech.mcprison.prison.Prison; import tech.mcprison.prison.PrisonAPI; +import tech.mcprison.prison.PrisonCommand; +import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; import tech.mcprison.prison.chat.FancyMessage; import tech.mcprison.prison.commands.Arg; import tech.mcprison.prison.commands.Command; @@ -29,14 +30,19 @@ import tech.mcprison.prison.output.ChatDisplay; import tech.mcprison.prison.output.FancyMessageComponent; import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.output.RowComponent; import tech.mcprison.prison.ranks.PrisonRanks; +import tech.mcprison.prison.ranks.data.PlayerRank; +import tech.mcprison.prison.ranks.data.PlayerRankRefreshTask; import tech.mcprison.prison.ranks.data.Rank; import tech.mcprison.prison.ranks.data.RankLadder; import tech.mcprison.prison.ranks.data.RankPlayer; import tech.mcprison.prison.ranks.data.RankPlayerName; import tech.mcprison.prison.ranks.managers.LadderManager; import tech.mcprison.prison.ranks.managers.PlayerManager; +import tech.mcprison.prison.ranks.managers.RankManager; import tech.mcprison.prison.ranks.managers.RankManager.RanksByLadderOptions; +import tech.mcprison.prison.util.JumboTextFont; import tech.mcprison.prison.util.Text; /** @@ -47,6 +53,10 @@ public class RanksCommands private CommandCommands rankCommandCommands = null; + public RanksCommands() { + super( "RanksCommands" ); + } + public RanksCommands( CommandCommands rankCommandCommands ) { super( "RanksCommands" ); @@ -78,11 +88,11 @@ public void ranksPermsSubcommands(CommandSender sender) { sender.dispatchCommand( "ranks perms help" ); } - @Command(identifier = "ranks remove", - onlyPlayers = false, permissions = "prison.commands") - public void ranksRemoveSubcommands(CommandSender sender) { - sender.dispatchCommand( "ranks remove help" ); - } +// @Command(identifier = "ranks remove", +// onlyPlayers = false, permissions = "prison.commands") +// public void ranksRemoveSubcommands(CommandSender sender) { +// sender.dispatchCommand( "ranks remove help" ); +// } @Command(identifier = "ranks set", onlyPlayers = false, permissions = "prison.commands") @@ -97,10 +107,29 @@ public boolean createRank(CommandSender sender, @Arg(name = "cost", description = "The cost of this rank.") double cost, @Arg(name = "ladder", description = "The ladder to put this rank on.", def = "default") String ladder, + + @Arg(name = "tag", description = "The tag to use for this rank.", def = "none") + String tag, + @Wildcard(join=true) - @Arg(name = "tag", description = "The tag to use for this rank.", def = "none") - String tag) { + @Arg(name = "options", def = " ", + description = "Options for rank creation. " + + "Use 'noPlaceholderUpdate' to prevent reloading all placeholders when " + + "creating this rank. This is useful if you have multiple ranks " + + "you want to create. " + + "[noPlaceholderUpdate]") String options + ) { + + // The tag may actually bleed over in to options, so combine both together with one space: + if ( options != null && !options.trim().isEmpty() ) { + tag += " " + options; + } + boolean updatePlaceholders = !tag.toLowerCase().contains( "noplaceholderupdate" ); + if ( !updatePlaceholders ) { + tag = tag.replaceAll( "(?i)noPlaceholderUpdate", "" ).trim(); + } + boolean success = false; // Ensure a rank with the name doesn't already exist @@ -157,8 +186,19 @@ public boolean createRank(CommandSender sender, success = true; + if ( updatePlaceholders ) { + Prison.get().getPlatform().getPlaceholders().reloadPlaceholders(); + } + + + // Recalculate the ladder's base rank cost multiplier: + PlayerRankRefreshTask rankRefreshTask = new PlayerRankRefreshTask(); + rankRefreshTask.submitAsyncTPSTask(); + + // Tell the player the good news! rankCreatedSuccessfullyMsg( sender, name, ladder, tag ); + } else { errorCouldNotSaveLadderMsg( sender, rankLadder.getName() ); @@ -169,27 +209,47 @@ public boolean createRank(CommandSender sender, @Command(identifier = "ranks autoConfigure", description = "Auto configures Ranks and Mines using " + - "single letters A through Z for both the rank and mine names. If both ranks and mines are " + + "single letters A through Z for both the rank and mine names. Both ranks and mines are " + "generated, they will also be linked together automatically. To set the starting price use " + - "price=x. To set multiplier mult=x. Cannot autoConfigure if any ranks or mines are defined, " + - "but 'force' will attempt it but at your risk and will replace all blocks in preexisting " + + "price=x. To set multiplier mult=x. AutoConfigure will try to merge any preexsiting ranks " + + "and mines, but you must use the 'force' keyword in 'options'. Force will replace all blocks " + + "in preexisting " + "mines. To keep preexisting blocks, use 'forceKeepBlocks' with the 'force' option. " + "Default values [full price=50000 mult=1.5]", - onlyPlayers = false, permissions = "ranks.set") + onlyPlayers = false, permissions = "ranks.set", + aliases = {"prison autoConfigure"} ) public void autoConfigureRanks(CommandSender sender, @Wildcard(join=true) @Arg(name = "options", - description = "Options: [full ranks mines price=x mult=x force forceKeepBlocks]", + description = "Options: [full ranks mines price=x mult=x force forceKeepBlocks dontForceLinerWalls dontForceLinerBottoms]", def = "full") String options ) { - boolean forceKeepBlocks = options != null && options.contains( "forceKeepBlocks" ); - if ( forceKeepBlocks ) { - options = options.replace( "forceKeepBlocks", "" ).trim(); + // force options to lower case to work better with mixed case usage: + options = options == null ? "" : options.toLowerCase().trim(); + + boolean force = false; + boolean forceLinersWalls = true; + boolean forceLinersBottom = true; + boolean forceKeepBlocks = false; + + + if ( options.contains( "forcekeepblocks" ) ) { + forceKeepBlocks = true; + options = options.replace( "forcekeepblocks", "" ).trim(); } - boolean force = options != null && options.contains( "force" ); - if ( force ) { + if ( options.contains( "dontforcelinerwalls" ) ) { + forceLinersWalls = false; + options = options.replace( "dontforcelinerwalls", "" ).trim(); + } + if ( options.contains( "dontforcelinerbottoms" ) ) { + forceLinersBottom = false; + options = options.replace( "dontforcelinerbottoms", "" ).trim(); + } + + if ( options.contains( "force" ) ) { + force = true; options = options.replace( "force", "" ).trim(); } @@ -206,7 +266,7 @@ public void autoConfigureRanks(CommandSender sender, autoConfigForceWarningMsg( sender ); } - String optionHelp = "&b[&7full ranks mines price=&dx &7mult=&dx &7force forceKeepBlocks&b]"; + String optionHelp = "&b[&7full ranks mines price=&dx &7mult=&dx &7force forceKeepBlocks dontForceLinerWalls dontForceLinerBottoms&b]"; boolean ranks = false; boolean mines = false; double startingPrice = 50000; @@ -313,6 +373,8 @@ public void autoConfigureRanks(CommandSender sender, int countMinesForced = 0; int countLinked = 0; + List rankMineNames = new ArrayList<>(); + if ( ranks ) { int colorID = 1; @@ -322,6 +384,9 @@ public void autoConfigureRanks(CommandSender sender, for ( char cRank = 'A'; cRank <= 'Z'; cRank++) { String rankName = Character.toString( cRank ); + + rankMineNames.add( rankName ); + String tag = "&7[&" + Integer.toHexString((colorID++ % 15) + 1) + rankName + "&7]"; if ( firstRankName == null ) { @@ -333,7 +398,7 @@ public void autoConfigureRanks(CommandSender sender, boolean forceRank = force && PrisonRanks.getInstance().getRankManager().getRank( rankName ) != null; if ( forceRank || - createRank(sender, rankName, price, "default", tag) ) { + createRank(sender, rankName, price, "default", tag, "noPlaceholderUpdate") ) { if ( forceRank ) { countRanksForced++; @@ -414,10 +479,22 @@ public void autoConfigureRanks(CommandSender sender, } } + int prestigesCount = 0; + + // add in 10 prestiges at 1 billion each: + double prestigeCost = 1000000000; + + for ( int i = 0; i < 10; i++ ) { + String name = "P" + (i + 1); + String tag = "&5[&d+" + (i > 0 ? i + 1 : "" ) + "&5]"; + createRank(sender, name, (prestigeCost * (i + 1) ), "prestiges", tag, "noPlaceholderUpdate"); + prestigesCount++; + } + // If mines were created, go ahead and auto assign blocks to the mines: if ( countMines > 0 || countMinesForced > 0 ) { - Prison.get().getPlatform().autoCreateMineBlockAssignment( forceKeepBlocks ); - Prison.get().getPlatform().autoCreateMineLinerAssignment(); + Prison.get().getPlatform().autoCreateMineBlockAssignment( rankMineNames, forceKeepBlocks ); + Prison.get().getPlatform().autoCreateMineLinerAssignment( rankMineNames, forceLinersBottom, forceLinersWalls ); Prison.get().getPlatform().autoCreateConfigureMines(); } @@ -427,6 +504,20 @@ public void autoConfigureRanks(CommandSender sender, autoConfigNoRanksCreatedMsg( sender ); } else { + + // Set the prestiges ladder with a 10% base rank cost multiplier + double rankCostMultiplier = 0.10; + + RankLadder prestiges = PrisonRanks.getInstance().getLadderManager().getLadder( "prestiges" ); + prestiges.setRankCostMultiplierPerRank( rankCostMultiplier ); + PrisonRanks.getInstance().getLadderManager().save( prestiges ); + + // Log that the rank cost multiplier has been applied to the ladder + // with information on how to change it. + autoConfigLadderRankCostMultiplierInfoMsg( sender, rankCostMultiplier ); + autoConfigLadderRankCostMultiplierCmdMsg( sender ); + + autoConfigRanksCreatedMsg( sender, Integer.toString( countRanks ) ); if ( countRankCmds == 0 ) { @@ -436,6 +527,22 @@ public void autoConfigureRanks(CommandSender sender, autoConfigRankCmdsCreatedMsg( sender, Integer.toString( countRanks ) ); } } + + + // Reload the placeholders and autoFeatures: + Prison.get().getPlatform().getPlaceholders().reloadPlaceholders(); + + AutoFeaturesWrapper.getInstance().getAutoFeaturesConfig().reloadConfig(); + + + // Reset all player to the first rank on the default ladder: + PrisonRanks.getInstance().checkAllPlayersForJoin(); + +// RankLadder defaultLadder = PrisonRanks.getInstance().getLadderManager().getLadder( "default" ); +// Rank defaultRank = defaultLadder.getLowestRank().get(); +// PrisonRanks.getInstance().getRankManager().getRankupCommands() +// .setRank( sender, "*all*", "*join*", defaultLadder.getName() ); + if ( countRanksForced > 0 ) { // message about number of ranks that preexisting and were force: @@ -459,9 +566,14 @@ public void autoConfigureRanks(CommandSender sender, // message about number of mines that preexisting and were force: } + if ( prestigesCount > 0 ) { + sender.sendMessage( "Created " + prestigesCount + " prestige ranks (temp message)." ); + } + Output.get().logInfo( ""); + } private String extractParameter( String key, String options ) { @@ -496,30 +608,43 @@ public void removeRank(CommandSender sender, } if ( PrisonRanks.getInstance().getRankManager().removeRank(rank) ) { - rankWasRemovedMsg( sender, rankName ); + + Prison.get().getPlatform().getPlaceholders().reloadPlaceholders(); + + // Recalculate the ladder's base rank cost multiplier: + PlayerRankRefreshTask rankRefreshTask = new PlayerRankRefreshTask(); + rankRefreshTask.submitAsyncTPSTask(); + + rankWasRemovedMsg( sender, rankName ); } else { rankDeleteErrorMsg( sender, rankName ); } } - @Command(identifier = "ranks list", description = "Lists all the ranks on the server.", - onlyPlayers = false, altPermissions = "ranks.list" + @Command(identifier = "ranks list", description = "Lists all the ranks on the server by" + + "ladder. If 'all' is used instead of a ladder name, then it will print all " + + "ranks.", + onlyPlayers = false, altPermissions = "ranks.list" ) public void listRanks(CommandSender sender, - @Arg(name = "ladderName", def = "default") String ladderName) { + @Arg(name = "ladderName", def = "default", + description = "A ladder name, or 'all' to list all ranks by ladder.") String ladderName) { boolean hasPerm = sender.hasPermission("ranks.list") || - sender.isOp(); + sender.isOp() || !sender.isPlayer(); RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder(ladderName); - if ( ladder == null ) { + if ( ladder == null && !"all".equalsIgnoreCase( ladderName ) ) { ladderDoesNotExistMsg( sender, ladderName ); return; } - Rank rank = ladder.getLowestRank().orElse( null ); + + if ( ladder != null && ladder.getRanks().size() == 0 ) { + ladderHasNoRanksMsg( sender, ladderName ); + } // Rank rank = null; // for (Rank pRank : ladder.getPositionRanks()) { @@ -530,86 +655,24 @@ public void listRanks(CommandSender sender, // } // } - - String rankHeader = ranksListHeaderMsg( ladderName ); - ChatDisplay display = new ChatDisplay( rankHeader ); + RankPlayer rPlayer = + PrisonRanks.getInstance().getPlayerManager().getPlayer( getPlayer(sender) ); - if ( hasPerm ) { - display.addText( ranksListClickToEditMsg() ); - } + ChatDisplay display = null; - - BulletedListComponent.BulletedListBuilder builder = - new BulletedListComponent.BulletedListBuilder(); - - boolean first = true; - while ( rank != null ) { - - boolean defaultRank = ("default".equalsIgnoreCase( ladderName ) && first); - - String textRankName = ( hasPerm ? - String.format( "&3%s " , rank.getName() ) - : ""); - String textCmdCount = ( hasPerm ? - ranksListCommandCountMsg(rank.getRankUpCommands().size()) - : "" ); - String textCurrency = (rank.getCurrency() == null ? "" : - ranksListCurrencyMsg( rank.getCurrency() )); - - String text = - String.format("%s &9[&3%s&9] &7- %s&7%s%s%s", - textRankName, rank.getTag(), - (defaultRank ? "&b(&9Default&b) &7- " : ""), - Text.numberToDollars(rank.getCost()), - textCurrency, - textCmdCount ); - - String rankName = rank.getName(); - if ( rankName.contains( "&" ) ) { - rankName = rankName.replace( "&", "-" ); - } - FancyMessage msg = null; - if ( hasPerm ) { - msg = new FancyMessage(text).command("/ranks info " + rankName) - .tooltip( ranksListClickToViewMsg() ); - } - else { - msg = new FancyMessage(text); - } - - builder.add(msg); + if ( ladder != null ) { + display = listRanksOnLadder( ladder, hasPerm, rPlayer ); + } + else { + display = new ChatDisplay( "List ALL Ranks" ); - rank = rank.getRankNext(); - first = false; + listAllRanksByLadders( display, hasPerm, rPlayer ); } -// for (RankLadder.PositionRank pos : ranks) { -// Optional rankOptional = ladder.get().getByPosition(pos.getPosition()); -// if (!rankOptional.isPresent()) { -// continue; // Skip it -// } -// Rank rank = rankOptional.get(); -// -// boolean defaultRank = ("default".equalsIgnoreCase( ladderName ) && first); -// -// String text = -// String.format("&3%s &9[&3%s&9] &7- %s&7%s &7- Commands: &3%d", -// rank.name, rank.tag, -// (defaultRank ? "&b(&9Default&b) &7-" : ""), -// Text.numberToDollars(rank.cost), -// rank.rankUpCommands.size()); -// FancyMessage msg = new FancyMessage(text).command("/ranks info " + rank.name) -// .tooltip("&7Click to view info."); -// builder.add(msg); -// first = false; -// } - display.addComponent(builder.build()); if ( hasPerm ) { - display.addComponent(new FancyMessageComponent( - new FancyMessage("&7[&a+&7] Add").suggest("/ranks create ") - .tooltip( ranksListCreateNewRankMsg() ))); + List others = new ArrayList<>(); for (RankLadder other : PrisonRanks.getInstance().getLadderManager().getLadders()) { @@ -633,7 +696,7 @@ public void listRanks(CommandSender sender, msg.then(" &8and "); } msg.then("&7" + other).tooltip( ranksListClickToView2Msg() ).command(other); - msg.then(i == others.size() ? "&8." : "&8,"); + msg.then(i == others.size() ? "&8." : "&8, "); } display.addComponent(new FancyMessageComponent(msg)); } @@ -644,7 +707,363 @@ public void listRanks(CommandSender sender, } - @Command(identifier = "ranks info", description = "Information about a rank. Use of the option of 'ALL' then " + + public void listAllRanksByLadders( ChatDisplay display, boolean hasPerm, RankPlayer rPlayer ) + { +// List ladders = PrisonRanks.getInstance().getLadderManager().getLadders(); + +// for ( RankLadder rLadder : ladders ) { +// ChatDisplay cDisp = listRanksOnLadder( rLadder, hasPerm ); +// +// if ( display == null ) { +// display = cDisp; +// } +// else { +// display.addEmptyLine(); +// +// display.addChatDisplay( cDisp ); +// } +// +// } + + // Track which ranks were included in the ladders listed: + List ranksIncluded = new ArrayList<>(); + + for ( RankLadder ladder : PrisonRanks.getInstance().getLadderManager().getLadders() ) { + List ladderRanks = ladder.getRanks(); + ranksIncluded.addAll( ladderRanks ); + + ChatDisplay cDisp = listRanksOnLadder( ladder, hasPerm, rPlayer ); + + if ( display == null ) { + display = cDisp; + } + else { + display.addEmptyLine(); + + display.addChatDisplay( cDisp ); + } + + } + + // Next we need to get a list of all ranks that were not included. Create a temp ladder so they + // can be printed out with them: + List ranksExcluded = new ArrayList<>( PrisonRanks.getInstance().getRankManager().getRanks() ); + ranksExcluded.removeAll( ranksIncluded ); + + if ( ranksExcluded.size() > 0 ) { + RankLadder noLadder = new RankLadder( -1, "No Ladder" ); + + for ( Rank rank : ranksExcluded ) { + noLadder.addRank( rank ); + } + + ChatDisplay cDisp = listRanksOnLadder( noLadder, hasPerm, rPlayer ); + + if ( display == null ) { + display = cDisp; + } + else { + display.addEmptyLine(); + + display.addChatDisplay( cDisp ); + } + } + + } + + public void listAllRanksByInfo( StringBuilder sb ) + { + + // Track which ranks were included in the ladders listed: + List ranksIncluded = new ArrayList<>(); + + for ( RankLadder ladder : PrisonRanks.getInstance().getLadderManager().getLadders() ) { + List ladderRanks = ladder.getRanks(); + ranksIncluded.addAll( ladderRanks ); + + for ( Rank rank : ladderRanks ) + { + + PrisonCommand.printFooter( sb ); + + JumboTextFont.makeJumboFontText( rank.getName(), sb ); + sb.append( "\n" ); + + ChatDisplay chatDisplay = rankInfoDetails( null, rank, "all" ); + + sb.append( chatDisplay.toStringBuilder() ); + } + } + + + + // Next we need to get a list of all ranks that were not included. Create a temp ladder so they + // can be printed out with them: + List ranksExcluded = new ArrayList<>( PrisonRanks.getInstance().getRankManager().getRanks() ); + ranksExcluded.removeAll( ranksIncluded ); + + if ( ranksExcluded.size() > 0 ) { + + for ( Rank rank : ranksExcluded ) + { + + PrisonCommand.printFooter( sb ); + + JumboTextFont.makeJumboFontText( rank.getName(), sb ); + sb.append( "\n" ); + + ChatDisplay chatDisplay = rankInfoDetails( null, rank, "all" ); + + sb.append( chatDisplay.toStringBuilder() ); + } + + } + + } + + private ChatDisplay listRanksOnLadder( RankLadder ladder, boolean hasPerm, RankPlayer rPlayer ) + { + String rankHeader = ranksListHeaderMsg( ladder.getName() ); + ChatDisplay display = new ChatDisplay( rankHeader ); + + display.addText( ranksListLadderCostMultiplierMsg( + ladder.getRankCostMultiplierPerRank() ) ); + + if ( hasPerm ) { + display.addText( ranksListClickToEditMsg() ); + } + + + if ( ladder.getRanks().size() == 0 ) { + display.addText( ladderHasNoRanksTextMsg() ); + } + + BulletedListComponent.BulletedListBuilder builder = + new BulletedListComponent.BulletedListBuilder(); + + DecimalFormat fFmt = new DecimalFormat("#,##0.0000"); + + // Here's the deal... With color codes, Java's String.format() cannot detect the correct + // length of a tag. So go through all tags, strip the colors, and see how long they are. + // We need to know the max length so we can pad the others with periods to align all costs. + int maxRankNameSize = 0; + int maxRankTagNoColorSize = 0; + for (Rank rank : ladder.getRanks()) { + if ( rank.getName().length() > maxRankNameSize ) { + maxRankNameSize = rank.getName().length(); + } + String tag = rank.getTag() == null ? "" : rank.getTag(); + String tagNoColor = Text.stripColor( tag ); + if ( tagNoColor.length() > maxRankTagNoColorSize ) { + maxRankTagNoColorSize = tagNoColor.length(); + } + } + + + boolean first = true; + for (Rank rank : ladder.getRanks()) { + + boolean defaultRank = ("default".equalsIgnoreCase( ladder.getName() ) && first); + + + // Since the formatting gets confused with color formatting, we must + // strip the color codes and then inject them back in. So instead, this + // provides the formatting rules for both name and rank tag, thus + // taking in to consideration the color codes and if the hasPerms is + // true. To prevent variable space issues, the difference is filled in with periods. + String textRankNameString = padRankName( rank, maxRankNameSize, maxRankTagNoColorSize, hasPerm ); + +// // trick it to deal correctly with tags. Tags can have many colors, but +// // it will render as if it had the colors stripped. So first generate the +// // formatted text with tagNoColor, then replace the no color tag with the +// // normal tag. +// // If tag is null, show it as an empty String. Normally rank name will +// // be used, but at least this show's it is not set. +// String tag = rank.getTag() == null ? "" : rank.getTag(); +// String tagNoColor = Text.stripColor( tag ); + + + // If rank list is being generated for a console or op'd player, then show the ladder's rank multiplier, + // but if generating for a player, then show total multiplier accross all ladders. + PlayerRank pRank = null; + double rankCost = 0; + double rMulti = 0; + + if ( hasPerm || rPlayer == null ) { + + rankCost = PlayerRank.getRawRankCost( rank ); + rMulti = PlayerRank.getLadderBaseRankdMultiplier( rank ); + + } + else { + pRank = PlayerRank.getTargetPlayerRankForPlayer( rPlayer, rank ); + rankCost = pRank.getRankCost(); + + rMulti = pRank.getRankMultiplier(); + } + + + + String textCmdCount = ( hasPerm ? + ranksListCommandCountMsg(rank.getRankUpCommands().size()) + : "" ); + String textCurrency = (rank.getCurrency() == null ? "" : + ranksListCurrencyMsg( rank.getCurrency() )); + + String rankMultiplier = rMulti == 0d ? "" : fFmt.format( rMulti ); + + String players = rank.getPlayers().size() == 0 ? "" : + " &dPlayers: &3" + rank.getPlayers().size(); + + String rawRankId = ( hasPerm ? + String.format( "(rankId: %s%s%s)", + Integer.toString( rank.getId() ), + (rank.getRankPrior() == null ? "" : " -"), + (rank.getRankNext() == null ? "" : " +") ) + : ""); + + String text = + String.format("&3%s &7%-17s%s&7 &b%s &3%s %s&7 %s%s", + textRankNameString, + Text.numberToDollars( rankCost ), + (defaultRank ? "{def}" : ""), + + rankMultiplier, + + rawRankId, + + textCurrency, + textCmdCount, + players + ); + +// // Swap the color tag back in: +// text = text.replace( tagNoColor, tag ); + + if ( defaultRank ) { + // Swap out the default placeholder for the actual content: + text = text.replace( "{def}", "&c(&9Default&c)" ); + } + + String rankName = rank.getName(); + if ( rankName.contains( "&" ) ) { + rankName = rankName.replace( "&", "-" ); + } + FancyMessage msg = null; + if ( hasPerm ) { + msg = new FancyMessage(text).command("/ranks info " + rankName) + .tooltip( ranksListClickToViewMsg() ); + } + else { + msg = new FancyMessage(text); + } + + builder.add(msg); + +// rank = rank.getRankNext(); + first = false; + + } + + display.addComponent(builder.build()); + + + if ( hasPerm && !"No Ladder".equals( ladder.getName() ) ) { + + RowComponent row = new RowComponent(); + + row.addFancy( + new FancyMessage("&7[&a+&7] Add a new Rank") + .suggest("/ranks create " + ladder.getName() + " ") + .tooltip( ranksListCreateNewRankMsg() )); + + row.addTextComponent( " " ); + + row.addFancy( + new FancyMessage("&7[&a+&7] Edit Ladder Rank Cost Multiplier") + .suggest("/ranks ladder rankCostMultiplier " + + ladder.getName() + " " + ladder.getRankCostMultiplierPerRank()) + .tooltip( ranksListEditLadderCostMultiplierMsg() )); + + display.addComponent( row ); + + + // Include the listing of all ladder commands at the end of the list of ranks: + ChatDisplay cmdLadderDisplays = + getRankCommandCommands().commandLadderListDetail( ladder, true ); + + display.addChatDisplay( cmdLadderDisplays ); + + } + + if ( rPlayer != null && !"No Ladder".equals( ladder.getName() ) ) { + double ladderMultiplier = ladder.getRankCostMultiplierPerRank(); + double playerMultiplier = rPlayer.getRank( ladder ) != null ? rPlayer.getRank( ladder ).getRankMultiplier() : 0; + + if ( playerMultiplier == 0 ) { + display.addText( "&3You have no Ladder Rank Multipliers enabled. The rank costs are not adjusted." ); + } + else { + display.addText( "&3Your current total Rank Multiplier: &7%s.", + fFmt.format( playerMultiplier ) ); + + if ( ladderMultiplier == 0 ) { + display.addText( "&3This ladder has no Rank Multiplier so all ranks on this ladder " + + "have the same multiplier." ); + } + else { + display.addText( "&3This ladder has a Rank Multiplier so each rank has " + + "a differnt multiplier." ); + } + + Set ladders = rPlayer.getLadderRanks().keySet(); + for ( RankLadder rLadder : ladders ) { + if ( rLadder.getRankCostMultiplierPerRank() != 0d ) { + + Rank r = rPlayer.getLadderRanks().get( rLadder ).getRank(); + display.addText( "&3 BaseMult: &7%7s &3CurrMult: &7%7s &7%s &7%s ", + fFmt.format( rLadder.getRankCostMultiplierPerRank() ), + fFmt.format( PlayerRank.getLadderBaseRankdMultiplier( r )), + rLadder.getName(), + r.getTag() + ); + +// display.addText( "&3 Ladder: &7%-9s &3Rank: &7%-8s &3Base Mult: %7s", +// rLadder.getName(), +// rPlayer.getLadderRanks().get( rLadder ).getRank().getTag(), +// fFmt.format( rLadder.getRankCostMultiplierPerRank() ) ); + } + } + } + + } + + return display; + } + + private String padRankName( Rank rank, int maxRankNameSize, int maxRankTagNoColorSize, boolean hasPerm ) { + return padRankName( rank.getName(), rank.getTag(), maxRankNameSize, maxRankTagNoColorSize, hasPerm ); + } + protected String padRankName( String rankName, String rankTag, int maxRankNameSize, int maxRankTagNoColorSize, boolean hasPerm ) + { + StringBuilder sb = new StringBuilder(); + + int tLen = (hasPerm ? maxRankNameSize + 1 : 0) + maxRankTagNoColorSize; + String name = hasPerm ? rankName + " " : ""; + String tag = rankTag == null ? "" : rankTag; + String tagNoColor = Text.stripColor( tag ); + + sb.append( name ).append( tag ).append( "&8" ); + + int length = name.length() + tagNoColor.length(); + while ( length++ < tLen ) { + sb.append( "." ); + } + + return sb.toString(); + } + + @Command(identifier = "ranks info", description = "Information about a rank. Use of the option of 'ALL' then " + "rank commands will be included too.", onlyPlayers = false, permissions = "ranks.info", altPermissions = "ranks.admin" ) @@ -662,11 +1081,65 @@ public void infoCmd(CommandSender sender, } - ChatDisplay display = new ChatDisplay( ranksInfoHeaderMsg( rank.getTag() )); + ChatDisplay display = rankInfoDetails( sender, rank, options ); + + display.send(sender); + +// if ( options != null && "all".equalsIgnoreCase( options )) { + + //getRankCommandCommands().commandLadderList( sender, rank.getLadder().getName(), "noRemoves" ); + +// getRankCommandCommands().commandList( sender, rankName, "noRemoves" ); +// } + } + + + public void allRanksInfoDetails( StringBuilder sb ) { + + PrisonRanks pRanks = PrisonRanks.getInstance(); + RankManager rMan = pRanks.getRankManager(); + + for ( Rank rank : rMan.getRanks() ) { + + PrisonCommand.printFooter( sb ); + + JumboTextFont.makeJumboFontText( rank.getName(), sb ); + sb.append( "\n" ); + + ChatDisplay chatDisplay = rankInfoDetails( null, rank, "all" ); + + sb.append( chatDisplay.toStringBuilder() ); + } + + PrisonCommand.printFooter( sb ); + } + + + private ChatDisplay rankInfoDetails( CommandSender sender, Rank rank, String options ) + { + ChatDisplay display = new ChatDisplay( ranksInfoHeaderMsg( rank.getTag() )); + + boolean isOp = sender.isOp(); + boolean isConsole = !sender.isPlayer(); display.addText( ranksInfoNameMsg( rank.getName() )); display.addText( ranksInfoTagMsg( rank.getTag() )); - display.addText( ranksInfoLadderMsg( rank.getLadder().getName() )); + + + RowComponent row = new RowComponent(); + + row.addTextComponent( ranksInfoLadderMsg( rank.getLadder() != null ? + rank.getLadder().getName() : "(not linked to any ladder)" ) ); + + + if ( rank.getLadder() != null ) { + row.addTextComponent( " " ); + + row.addTextComponent( "&3Ladder Position: &7%d", rank.getPosition() ); + } + + display.addComponent( row ); + if ( rank.getMines().size() == 0 ) { display.addText( ranksInfoNotLinkedToMinesMsg() ); @@ -685,55 +1158,89 @@ public void infoCmd(CommandSender sender, display.addText( ranksInfoLinkedMinesMsg( sb.toString() )); } - display.addText( ranksInfoCostMsg( rank.getCost() )); + + + + // NOTE: Since rank info is NOT tied to a PlayerRank we cannot figure out the + // the actual cost, but we can calculate the ladder's multiplier. This + // will not be the player's total multiplier. + display.addText( ranksInfoCostMsg( PlayerRank.getRawRankCost( rank ) )); + + + + // Add the raw ladder rank multiplier here: + DecimalFormat fFmt = new DecimalFormat("#,##0.0000"); + + // The following is the rank adjusted rank multiplier + double rankCostMultiplier = PlayerRank.getLadderBaseRankdMultiplier( rank ); + double ladderBaseMultiplier = rank.getLadder() == null ? 0 : rank.getLadder().getRankCostMultiplierPerRank(); + + String cmdLadderRankCostMult = "/ranks ladder rankMultiplier " + rank.getName() + " " + ladderBaseMultiplier; + display.addComponent(new FancyMessageComponent( + new FancyMessage( + String.format( "&3Rank Cost Multiplier: &7%s &3Ladder Base Multiplier: &7%s", + fFmt.format( rankCostMultiplier ), + fFmt.format( ladderBaseMultiplier ) + )).suggest( cmdLadderRankCostMult ) + .tooltip( "Ladder Rank Cost Multiplier" ))); + + display.addText( ranksInfoCurrencyMsg( (rank.getCurrency() == null ? "&cdefault" : rank.getCurrency()) )); - List players = - PrisonRanks.getInstance().getPlayerManager().getPlayers().stream() - .filter(rankPlayer -> rankPlayer.getLadderRanks().values().contains(rank)) - .collect(Collectors.toList()); - display.addText( ranksInfoPlayersWithRankMsg( players.size() )); + int numberOfPlayersOnRank = rank.getPlayers().size(); + display.addText( ranksInfoPlayersWithRankMsg( numberOfPlayersOnRank )); - if (sender.hasPermission("ranks.admin")) { + if ( isOp || isConsole || sender == null || sender.hasPermission("ranks.admin")) { // This is admin-exclusive content // display.addText("&8[Admin Only]"); display.addText( ranksInfoRankIdMsg( rank.getId() )); - FancyMessage del = - new FancyMessage( ranksInfoRankDeleteMessageMsg() ).command("/ranks delete " + rank.getName()) - .tooltip( ranksInfoRankDeleteToolTipMsg() ); - display.addComponent(new FancyMessageComponent(del)); +// FancyMessage del = +// new FancyMessage( ranksInfoRankDeleteMessageMsg() ).command("/ranks delete " + rank.getName()) +// .tooltip( ranksInfoRankDeleteToolTipMsg() ); +// display.addComponent(new FancyMessageComponent(del)); } - - display.send(sender); - if ( options != null && "all".equalsIgnoreCase( options )) { + if ( isOp && options != null && "all".equalsIgnoreCase( options )) { - getRankCommandCommands().commandLadderList( sender, rank.getLadder().getName(), "noRemoves" ); + if ( rank.getLadder() != null ) { + + ChatDisplay cmdLadderDisplays = getRankCommandCommands().commandLadderListDetail( rank.getLadder(), true ); + display.addChatDisplay( cmdLadderDisplays ); + } - getRankCommandCommands().commandList( sender, rankName, "noRemoves" ); + ChatDisplay cmdLadderCmdsDisplays = getRankCommandCommands().commandListDetails( rank, true ); + display.addChatDisplay( cmdLadderCmdsDisplays ); } - } + + return display; + } - @Command(identifier = "ranks set cost", description = "Modifies a ranks cost", + @Command(identifier = "ranks set cost", description = "Sets a rank's raw cost. The ladder's rank cost " + + "multipliers are not applied to this value, and they will impact the actual price that a " + + "player will have to pay. Every player may have to pay a different price for this rank, if " + + "ladder rank multipiers are used, and players have different ranks in the ladders that " + + "have them enabled.", onlyPlayers = false, permissions = "ranks.set") public void setCost(CommandSender sender, @Arg(name = "rankName") String rankName, - @Arg(name = "cost", description = "The cost of this rank.") double cost){ + @Arg(name = "rawCost", description = "The raw cost of this rank.") double rawCost) { + Rank rank = PrisonRanks.getInstance().getRankManager().getRank(rankName); if ( rank == null ) { rankDoesNotExistMsg( sender, rankName ); return; } - rank.setCost( cost ); + + PlayerRank.setRawRankCost( rank, rawCost ); PrisonRanks.getInstance().getRankManager().saveRank(rank); - rankSetCostSuccessfulMsg( sender, rankName, cost ); + rankSetCostSuccessfulMsg( sender, rankName, rawCost ); } @@ -841,6 +1348,61 @@ public void setTag(CommandSender sender, +// @Command(identifier = "ranks import byPerms", description = "This resets 'all' player's ranks based " + +// "upon a series of permissions. An example of a permission may be 'permission.mine.A'. Basically " + +// "a standard prefix, followed by a rank name, or mine name. This is a very dangerous command to " + +// "run because it will reset many player's ranks. All ranks can be reset back to a " + +// "spcific rank with the command '/ranks set rank *all* A default`. " + +// "It is highly recommended to backup your server, and Prison's plugin folder. Plus you should" + +// "reset all your players to the default rank on the 'default' " + +// "ladder. Usually the default rank is 'a', but please confirm before resetting all ranks. " +// , +// onlyPlayers = false, aliases="ranks stats") + public void ranksImportByPermissions(CommandSender sender, + @Arg(name = "ladderName", def = "default", + description = "Ladder Name. Required: [default]") String ladderName, + + @Arg(name = "permission", description = "This is the full permission name, but use " + + "a '{rank}' placeholder to indicate where the rank name should be. ") String permission, + @Arg(name = "options", def = "", + description = "Work in progress.. options will be added in the future. " + + "[]") String options){ + + + if ( !ladderName.equalsIgnoreCase( "all" ) && + PrisonRanks.getInstance().getLadderManager().getLadder( ladderName ) == null ) { + ranksPlayersInvalidLadderMsg( sender, ladderName ); + return; + } + + +// RanksByLadderOptions option = RanksByLadderOptions.fromString( action ); +// if ( option == null ) { +// ranksPlayersInvalidActionMsg( sender, action ); +// return; +// } + +// boolean includeAll = action.equalsIgnoreCase( "all" ); +// PrisonRanks.getInstance().getRankManager().ranksByLadders( sender, ladderName, option ); + +// Output.get().logInfo( "Ranks by ladders:" ); +// +// for ( RankLadder ladder : PrisonRanks.getInstance().getLadderManager().getLadders() ) { +// if ( ladderName.equalsIgnoreCase( "all" ) || ladderName.equalsIgnoreCase( ladder.name ) ) { +// +// boolean includeAll = action.equalsIgnoreCase( "all" ); +// String ladderRanks = ladder.listAllRanks( includeAll ); +// +// sender.sendMessage( ladderRanks ); +// } +// +// } + + } + + + + @Command(identifier = "ranks player", description = "Shows a player their rank", onlyPlayers = false, altPermissions = "ranks.admin" ) public void rankPlayer(CommandSender sender, @@ -858,6 +1420,16 @@ public void rankPlayer(CommandSender sender, PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); RankPlayer rankPlayer = pm.getPlayer(player.getUUID(), player.getName()); + String msg1 = String.format( "&c%s:", rankPlayer.getName() ); + sendToPlayerAndConsole( sender, msg1 ); + + DecimalFormat fFmt = new DecimalFormat("0.0000"); + String msg2 = String.format( " &7Rank Cost Multiplier: &f", + fFmt.format( rankPlayer.getSellAllMultiplier() )); + sendToPlayerAndConsole( sender, msg2 ); + + + if ( rankPlayer != null ) { DecimalFormat dFmt = new DecimalFormat("#,##0.00"); @@ -872,15 +1444,21 @@ public void rankPlayer(CommandSender sender, } - Map rankLadders = rankPlayer.getLadderRanks(); + Map rankLadders = rankPlayer.getLadderRanks(); for ( RankLadder rankLadder : rankLadders.keySet() ) { - Rank rank = rankLadders.get( rankLadder ); + PlayerRank pRank = rankLadders.get( rankLadder ); + Rank rank = pRank.getRank(); Rank nextRank = rank.getRankNext(); + // This calculates the target rank, and takes in to consideration the player's existing rank: + PlayerRank nextPRank = PlayerRank.getTargetPlayerRankForPlayer( rankPlayer, nextRank ); + +// PlayerRank nextPRank = nextRank == null ? null : +// new PlayerRank( nextRank, pRank.getRankMultiplier() ); + String messageRank = ranksPlayerLadderInfoMsg( - player.getDisplayName(), rankLadder.getName(), rank.getName() ); @@ -889,7 +1467,8 @@ public void rankPlayer(CommandSender sender, } else { messageRank += ranksPlayerLadderNextRankMsg( nextRank.getName(), - dFmt.format( nextRank.getCost() ) ); + ( nextRank == null ? "0" : dFmt.format( nextPRank.getRankCost()) ) ); +// dFmt.format( nextRank.getCost() ) ); if ( nextRank.getCurrency() != null ) { messageRank += ranksPlayerLadderNextRankCurrencyMsg( nextRank.getCurrency() ); @@ -1011,9 +1590,10 @@ public void rankPlayer(CommandSender sender, // } // sender.sendMessage( message ); - } else { - ranksPlayerNoRanksFoundMsg( sender, player.getDisplayName() ); } +// else { +// ranksPlayerNoRanksFoundMsg( sender, player.getDisplayName() ); +// } } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommandsMessages.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommandsMessages.java index 004b0b5c2..eca72d87b 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommandsMessages.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommandsMessages.java @@ -40,6 +40,20 @@ protected void ladderDoesNotExistMsg( CommandSender sender, String ladderName ) .sendTo( sender ); } + protected void ladderHasNoRanksMsg( CommandSender sender, String ladderName ) { + PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_rankCommands__ladder_has_no_ranks" ) + .withReplacements( + ladderName ) + .sendTo( sender ); + } + + protected String ladderHasNoRanksTextMsg() { + return PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_rankCommands__ladder_has_no_ranks_text" ) + .localize(); + } + protected void rankDoesNotExistMsg( CommandSender sender, String rankName ) { PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankCommands__rank_does_not_exist" ) @@ -122,6 +136,23 @@ protected void autoConfigNoRanksCreatedMsg( CommandSender sender ) { .sendTo( sender ); } + protected void autoConfigLadderRankCostMultiplierInfoMsg( CommandSender sender, + double rankCostMultiplier ) { + DecimalFormat dFmt = new DecimalFormat("0.0000"); + + PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_rankCommands__auto_config_ladder_rank_cost_multiplier_info" ) + .withReplacements( + dFmt.format( rankCostMultiplier ) ) + .sendTo( sender ); + } + + protected void autoConfigLadderRankCostMultiplierCmdMsg( CommandSender sender ) { + PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_rankCommands__auto_config_ladder_rank_cost_multiplier_command_example" ) + .sendTo( sender ); + } + protected void autoConfigRanksCreatedMsg( CommandSender sender, String value) { PrisonRanks.getInstance().getRanksMessages() @@ -212,6 +243,24 @@ protected String ranksListHeaderMsg( String ladderName) { .localize(); } + protected String ranksListLadderCostMultiplierMsg( double multiplier ) { + + DecimalFormat fFmt = new DecimalFormat("#,##0.0000"); + + return PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_rankCommands__ranks_list_ladder_cost_multplier" ) + .withReplacements( + fFmt.format( multiplier ) ) + .localize(); + } + + protected String ranksListEditLadderCostMultiplierMsg() { + + return PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_rankCommands__ranks_list_ladder_edit_cost_multplier" ) + .localize(); + } + protected String ranksListClickToEditMsg() { return PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankCommands__ranks_list_click_to_edit" ) @@ -448,12 +497,12 @@ protected void ranksPlayerOnlineMsg( CommandSender sender ) { .sendTo( sender ); } - protected String ranksPlayerLadderInfoMsg( String playerName, + protected String ranksPlayerLadderInfoMsg( String ladderName, String rankName ) { return PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankCommands__player_ladder_info" ) .withReplacements( - playerName, ladderName, rankName ) + ladderName, rankName ) .localize(); } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommandsPerms.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommandsPerms.java index ff402476a..68cff60fe 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommandsPerms.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/commands/RanksCommandsPerms.java @@ -1,18 +1,5 @@ package tech.mcprison.prison.ranks.commands; -import tech.mcprison.prison.chat.FancyMessage; -import tech.mcprison.prison.commands.Arg; -import tech.mcprison.prison.internal.CommandSender; -import tech.mcprison.prison.internal.Player; -import tech.mcprison.prison.output.BulletedListComponent; -import tech.mcprison.prison.output.ChatDisplay; -import tech.mcprison.prison.output.FancyMessageComponent; -import tech.mcprison.prison.output.Output; -import tech.mcprison.prison.output.RowComponent; -import tech.mcprison.prison.ranks.PrisonRanks; -import tech.mcprison.prison.ranks.data.Rank; -import tech.mcprison.prison.ranks.data.RankLadder; - /** * NOTE: Rank permissions is not functional because of some major limitations of bukkit and * Vault. @@ -32,313 +19,313 @@ public RanksCommandsPerms( String cmdGroup ) { // @Command(identifier = "ranks perms list", description = "Lists rank permissions", // onlyPlayers = false, permissions = "ranks.set") - public void rankPermsList(CommandSender sender, - @Arg(name = "rankName") String rankName - ){ - sender.sendMessage( "&cWarning: &3This feature is not yet functional." ); - - Rank rank = PrisonRanks.getInstance().getRankManager().getRank(rankName); - if ( rank == null ) { - rankDoesNotExistMsg( sender, rankName ); - return; - } - - - if ( rank.getPermissions() == null ||rank.getPermissions().size() == 0 && - rank.getPermissionGroups() == null && rank.getPermissionGroups().size() == 0 ) { - - Output.get().sendInfo(sender, "The Rank '%s' contains no permissions or " + - "permission groups.", rank.getName()); - return; - } - - RankLadder ladder = rank.getLadder(); - - ChatDisplay display = new ChatDisplay("Rank Permissions and Groups for " + rank.getName()); - display.addText("&8Click a Permission to remove it."); - BulletedListComponent.BulletedListBuilder builder = - new BulletedListComponent.BulletedListBuilder(); - - listLadderPerms( ladder, builder ); - - int rowNumber = 1; - - if ( rank.getPermissions().size() > 0 ) { - builder.add( "&7Permissions:" ); - } - for (String perm : rank.getPermissions() ) { - - RowComponent row = new RowComponent(); - - row.addTextComponent( " &3Row: &d%d ", rowNumber++ ); - - FancyMessage msgPermission = new FancyMessage( String.format( "&7%s ", perm ) ) - .command( "/ranks perms edit " + rank.getName() + " " + rowNumber + " " ) - .tooltip("Permission - Click to Edit"); - row.addFancy( msgPermission ); - - - FancyMessage msgRemove = new FancyMessage( String.format( " &cRemove " ) ) - .command( "/ranks perms remove " + rank.getName() + " " + rowNumber + " " ) - .tooltip("Remove Permission - Click to Delete"); - row.addFancy( msgRemove ); - - builder.add( row ); - } - - if ( rank.getPermissionGroups().size() > 0 ) { - builder.add( "&7Permission Groups:" ); - } - for (String permGroup : rank.getPermissionGroups() ) { - - RowComponent row = new RowComponent(); - - row.addTextComponent( " &3Row: &d%d ", rowNumber++ ); - - FancyMessage msgPermission = new FancyMessage( String.format( "&7%s ", permGroup ) ) - .command( "/ranks perms edit " + rank.getName() + " " + rowNumber + " " ) - .tooltip("Permission Group - Click to Edit"); - row.addFancy( msgPermission ); - - - FancyMessage msgRemove = new FancyMessage( String.format( " &cRemove " ) ) - .command( "/ranks perms remove " + rank.getName() + " " + rowNumber + " " ) - .tooltip("Remove Permission Group - Click to Delete"); - row.addFancy( msgRemove ); - - builder.add( row ); - } - - - display.addComponent(builder.build()); - display.addComponent(new FancyMessageComponent( - new FancyMessage("&7[&a+&7] Add Permission") - .suggest("/ranks perms addPerm " + rank.getName() + " [perm] /") - .tooltip("&7Add a new Permission."))); - display.addComponent(new FancyMessageComponent( - new FancyMessage("&7[&a+&7] Add Permission Group") - .suggest("/ranks perms addPermGroup " + rank.getName() + " [permGroup] /") - .tooltip("&7Add a new Permission Group."))); - - display.send(sender); - - } +// public void rankPermsList(CommandSender sender, +// @Arg(name = "rankName") String rankName +// ){ +// sender.sendMessage( "&cWarning: &3This feature is not yet functional." ); +// +// Rank rank = PrisonRanks.getInstance().getRankManager().getRank(rankName); +// if ( rank == null ) { +// rankDoesNotExistMsg( sender, rankName ); +// return; +// } +// +// +// if ( rank.getPermissions() == null ||rank.getPermissions().size() == 0 && +// rank.getPermissionGroups() == null && rank.getPermissionGroups().size() == 0 ) { +// +// Output.get().sendInfo(sender, "The Rank '%s' contains no permissions or " + +// "permission groups.", rank.getName()); +// return; +// } +// +// RankLadder ladder = rank.getLadder(); +// +// ChatDisplay display = new ChatDisplay("Rank Permissions and Groups for " + rank.getName()); +// display.addText("&8Click a Permission to remove it."); +// BulletedListComponent.BulletedListBuilder builder = +// new BulletedListComponent.BulletedListBuilder(); +// +// listLadderPerms( ladder, builder ); +// +// int rowNumber = 1; +// +// if ( rank.getPermissions().size() > 0 ) { +// builder.add( "&7Permissions:" ); +// } +// for (String perm : rank.getPermissions() ) { +// +// RowComponent row = new RowComponent(); +// +// row.addTextComponent( " &3Row: &d%d ", rowNumber++ ); +// +// FancyMessage msgPermission = new FancyMessage( String.format( "&7%s ", perm ) ) +// .command( "/ranks perms edit " + rank.getName() + " " + rowNumber + " " ) +// .tooltip("Permission - Click to Edit"); +// row.addFancy( msgPermission ); +// +// +// FancyMessage msgRemove = new FancyMessage( String.format( " &cRemove " ) ) +// .command( "/ranks perms remove " + rank.getName() + " " + rowNumber + " " ) +// .tooltip("Remove Permission - Click to Delete"); +// row.addFancy( msgRemove ); +// +// builder.add( row ); +// } +// +// if ( rank.getPermissionGroups().size() > 0 ) { +// builder.add( "&7Permission Groups:" ); +// } +// for (String permGroup : rank.getPermissionGroups() ) { +// +// RowComponent row = new RowComponent(); +// +// row.addTextComponent( " &3Row: &d%d ", rowNumber++ ); +// +// FancyMessage msgPermission = new FancyMessage( String.format( "&7%s ", permGroup ) ) +// .command( "/ranks perms edit " + rank.getName() + " " + rowNumber + " " ) +// .tooltip("Permission Group - Click to Edit"); +// row.addFancy( msgPermission ); +// +// +// FancyMessage msgRemove = new FancyMessage( String.format( " &cRemove " ) ) +// .command( "/ranks perms remove " + rank.getName() + " " + rowNumber + " " ) +// .tooltip("Remove Permission Group - Click to Delete"); +// row.addFancy( msgRemove ); +// +// builder.add( row ); +// } +// +// +// display.addComponent(builder.build()); +// display.addComponent(new FancyMessageComponent( +// new FancyMessage("&7[&a+&7] Add Permission") +// .suggest("/ranks perms addPerm " + rank.getName() + " [perm] /") +// .tooltip("&7Add a new Permission."))); +// display.addComponent(new FancyMessageComponent( +// new FancyMessage("&7[&a+&7] Add Permission Group") +// .suggest("/ranks perms addPermGroup " + rank.getName() + " [permGroup] /") +// .tooltip("&7Add a new Permission Group."))); +// +// display.send(sender); +// +// } - private void listLadderPerms( RankLadder ladder, - BulletedListComponent.BulletedListBuilder builder ) { - - if ( ladder.getPermissions().size() > 0 ) { - builder.add( "&3Ladder &7%s &3Permissions:", ladder.getName() ); - } - for (String perm : ladder.getPermissions() ) { - - RowComponent row = new RowComponent(); - - row.addTextComponent( " " ); - - FancyMessage msgPermission = new FancyMessage( String.format( "&7%s ", perm ) ) - .command( "/ranks ladder perms list " + ladder.getName() ) - .tooltip("Ladder Permission - Click to List Ladder"); - row.addFancy( msgPermission ); - - builder.add( row ); - } - - if ( ladder.getPermissionGroups().size() > 0 ) { - builder.add( "&3Ladder &7%s &3Permission Groups:", ladder.getName() ); - } - for (String permGroup : ladder.getPermissionGroups() ) { - - RowComponent row = new RowComponent(); - - row.addTextComponent( " " ); - - FancyMessage msgPermission = new FancyMessage( String.format( "&7%s ", permGroup ) ) - .command( "/ranks ladder perms list " + ladder.getName() ) - .tooltip("Ladder Permission Group - Click to List Ladder"); - row.addFancy( msgPermission ); - - builder.add( row ); - } - - } +// private void listLadderPerms( RankLadder ladder, +// BulletedListComponent.BulletedListBuilder builder ) { +// +// if ( ladder.getPermissions().size() > 0 ) { +// builder.add( "&3Ladder &7%s &3Permissions:", ladder.getName() ); +// } +// for (String perm : ladder.getPermissions() ) { +// +// RowComponent row = new RowComponent(); +// +// row.addTextComponent( " " ); +// +// FancyMessage msgPermission = new FancyMessage( String.format( "&7%s ", perm ) ) +// .command( "/ranks ladder perms list " + ladder.getName() ) +// .tooltip("Ladder Permission - Click to List Ladder"); +// row.addFancy( msgPermission ); +// +// builder.add( row ); +// } +// +// if ( ladder.getPermissionGroups().size() > 0 ) { +// builder.add( "&3Ladder &7%s &3Permission Groups:", ladder.getName() ); +// } +// for (String permGroup : ladder.getPermissionGroups() ) { +// +// RowComponent row = new RowComponent(); +// +// row.addTextComponent( " " ); +// +// FancyMessage msgPermission = new FancyMessage( String.format( "&7%s ", permGroup ) ) +// .command( "/ranks ladder perms list " + ladder.getName() ) +// .tooltip("Ladder Permission Group - Click to List Ladder"); +// row.addFancy( msgPermission ); +// +// builder.add( row ); +// } +// +// } // @Command(identifier = "ranks perms addPerm", // description = "Add a ladder permission. Valid placeholder: {rank}.", // onlyPlayers = false, permissions = "ranks.set") - public void rankPermsAddPerm(CommandSender sender, - @Arg(name = "rankName", - description = "Rank name to add the permission to.") String rankName, - @Arg(name = "permission", description = "Permission") String permission - ){ - - sender.sendMessage( "&cWarning: &3This feature is not yet functional." ); - - Rank rank = PrisonRanks.getInstance().getRankManager().getRank(rankName); - if ( rank == null ) { - rankDoesNotExistMsg( sender, rankName ); - return; - } - - - if ( permission == null || permission.trim().isEmpty() ) { - - Output.get().sendInfo(sender, "&3The &7permission &3parameter is required." ); - return; - } - - - if ( rank.hasPermission( permission ) ) { - - Output.get().sendInfo(sender, "&3The permission &7%s &3already exists.", permission ); - return; - } - - rank.getPermissions().add( permission ); - - - PrisonRanks.getInstance().getRankManager().saveRank(rank); - - Output.get().sendInfo(sender, "&3The permission &7%s &3was successfully added " + - "to the rank &7%s&3.", permission, rank.getName() ); - - rankPermsList( sender, rank.getName() ); - } +// public void rankPermsAddPerm(CommandSender sender, +// @Arg(name = "rankName", +// description = "Rank name to add the permission to.") String rankName, +// @Arg(name = "permission", description = "Permission") String permission +// ){ +// +// sender.sendMessage( "&cWarning: &3This feature is not yet functional." ); +// +// Rank rank = PrisonRanks.getInstance().getRankManager().getRank(rankName); +// if ( rank == null ) { +// rankDoesNotExistMsg( sender, rankName ); +// return; +// } +// +// +// if ( permission == null || permission.trim().isEmpty() ) { +// +// Output.get().sendInfo(sender, "&3The &7permission &3parameter is required." ); +// return; +// } +// +// +// if ( rank.hasPermission( permission ) ) { +// +// Output.get().sendInfo(sender, "&3The permission &7%s &3already exists.", permission ); +// return; +// } +// +// rank.getPermissions().add( permission ); +// +// +// PrisonRanks.getInstance().getRankManager().saveRank(rank); +// +// Output.get().sendInfo(sender, "&3The permission &7%s &3was successfully added " + +// "to the rank &7%s&3.", permission, rank.getName() ); +// +// rankPermsList( sender, rank.getName() ); +// } // @Command(identifier = "ranks perms addGroup", // description = "Add a ladder permission. Valid placeholder: {rank}.", // onlyPlayers = false, permissions = "ranks.set") - public void rankPermsAddPermGroup(CommandSender sender, - @Arg(name = "rankName", - description = "Rank name to add the permission to.") String rankName, - @Arg(name = "permissionGroup", description = "Permission Group") String permissionGroup - ){ - - sender.sendMessage( "&cWarning: &3This feature is not yet functional." ); - - Rank rank = PrisonRanks.getInstance().getRankManager().getRank(rankName); - if ( rank == null ) { - rankDoesNotExistMsg( sender, rankName ); - return; - } - - - if ( permissionGroup == null || permissionGroup.trim().isEmpty() ) { - - Output.get().sendInfo(sender, "&3The &7permission group &3parameter is required." ); - return; - } - - - if ( rank.hasPermissionGroup( permissionGroup ) ) { - - Output.get().sendInfo(sender, "&3The permission Group &7%s &3already exists.", permissionGroup ); - return; - } - - rank.getPermissionGroups().add( permissionGroup ); - - - PrisonRanks.getInstance().getRankManager().saveRank(rank); - - Output.get().sendInfo(sender, "&3The permission group &7%s &3was successfully added " + - "to the rank &7%s&3.", permissionGroup, rank.getName() ); - - rankPermsList( sender, rank.getName() ); - } +// public void rankPermsAddPermGroup(CommandSender sender, +// @Arg(name = "rankName", +// description = "Rank name to add the permission to.") String rankName, +// @Arg(name = "permissionGroup", description = "Permission Group") String permissionGroup +// ){ +// +// sender.sendMessage( "&cWarning: &3This feature is not yet functional." ); +// +// Rank rank = PrisonRanks.getInstance().getRankManager().getRank(rankName); +// if ( rank == null ) { +// rankDoesNotExistMsg( sender, rankName ); +// return; +// } +// +// +// if ( permissionGroup == null || permissionGroup.trim().isEmpty() ) { +// +// Output.get().sendInfo(sender, "&3The &7permission group &3parameter is required." ); +// return; +// } +// +// +// if ( rank.hasPermissionGroup( permissionGroup ) ) { +// +// Output.get().sendInfo(sender, "&3The permission Group &7%s &3already exists.", permissionGroup ); +// return; +// } +// +// rank.getPermissionGroups().add( permissionGroup ); +// +// +// PrisonRanks.getInstance().getRankManager().saveRank(rank); +// +// Output.get().sendInfo(sender, "&3The permission group &7%s &3was successfully added " + +// "to the rank &7%s&3.", permissionGroup, rank.getName() ); +// +// rankPermsList( sender, rank.getName() ); +// } // @Command(identifier = "ranks perms remove", description = "Remove rank permissions", // onlyPlayers = false, permissions = "ranks.set") - public void rankPermsRemove(CommandSender sender, - @Arg(name = "rankName", def = "default", - description = "Rank name to list the permissions.") String rankName, - @Arg(name = "row") Integer row - ){ - sender.sendMessage( "&cWarning: &3This feature is not yet functional." ); - - - Rank rank = PrisonRanks.getInstance().getRankManager().getRank(rankName); - if ( rank == null ) { - rankDoesNotExistMsg( sender, rankName ); - return; - } - - - boolean dirty = false; - String removedPerm = ""; - boolean permGroup = false; - - if ( row == null || row <= 0 ) { - sender.sendMessage( - String.format("&7Please provide a valid row number greater than zero. " + - "Was row=[&b%d&7]", - (row == null ? "null" : row) )); - return; - } - - if ( row <= rank.getPermissions().size() ) { - removedPerm = rank.getPermissions().remove( row - 1 ); - dirty = true; - } - else { - // Remove from row the size of permissions so the row will align to the permissionGroups. - row -= rank.getPermissions().size(); - - if ( row <= rank.getPermissionGroups().size() ) { - - removedPerm = rank.getPermissions().remove( row - 1 ); - dirty = true; - permGroup = true; - } - } - - if ( dirty ) { - PrisonRanks.getInstance().getRankManager().saveRank(rank); - - Output.get().sendInfo(sender, "&3The permission%s &7%s &3was successfully removed " + - "to the rank &7%s&3.", - ( permGroup ? " group" : "" ), - removedPerm, rank.getName() ); - - } - else { - Output.get().sendInfo(sender, "&3The permission on row &7%s &3was unable to be removed " + - "from the &7%s &3rank. " + - "Is that a valid row number?", - Integer.toString( row ), rank.getName() ); - } - } +// public void rankPermsRemove(CommandSender sender, +// @Arg(name = "rankName", def = "default", +// description = "Rank name to list the permissions.") String rankName, +// @Arg(name = "row") Integer row +// ){ +// sender.sendMessage( "&cWarning: &3This feature is not yet functional." ); +// +// +// Rank rank = PrisonRanks.getInstance().getRankManager().getRank(rankName); +// if ( rank == null ) { +// rankDoesNotExistMsg( sender, rankName ); +// return; +// } +// +// +// boolean dirty = false; +// String removedPerm = ""; +// boolean permGroup = false; +// +// if ( row == null || row <= 0 ) { +// sender.sendMessage( +// String.format("&7Please provide a valid row number greater than zero. " + +// "Was row=[&b%d&7]", +// (row == null ? "null" : row) )); +// return; +// } +// +// if ( row <= rank.getPermissions().size() ) { +// removedPerm = rank.getPermissions().remove( row - 1 ); +// dirty = true; +// } +// else { +// // Remove from row the size of permissions so the row will align to the permissionGroups. +// row -= rank.getPermissions().size(); +// +// if ( row <= rank.getPermissionGroups().size() ) { +// +// removedPerm = rank.getPermissions().remove( row - 1 ); +// dirty = true; +// permGroup = true; +// } +// } +// +// if ( dirty ) { +// PrisonRanks.getInstance().getRankManager().saveRank(rank); +// +// Output.get().sendInfo(sender, "&3The permission%s &7%s &3was successfully removed " + +// "to the rank &7%s&3.", +// ( permGroup ? " group" : "" ), +// removedPerm, rank.getName() ); +// +// } +// else { +// Output.get().sendInfo(sender, "&3The permission on row &7%s &3was unable to be removed " + +// "from the &7%s &3rank. " + +// "Is that a valid row number?", +// Integer.toString( row ), rank.getName() ); +// } +// } // @Command(identifier = "ranks playerInventory", permissions = "mines.set", // description = "For listing what's in a player's inventory by dumping it // to console.", // onlyPlayers = false ) - public void ranksPlayerInventoryCommand( CommandSender sender, - @Arg( name = "player", def = "", description = "Player name" ) String playerName ) - { - - Player player = getPlayer( sender, playerName ); - - if ( player == null ) - { - sender.sendMessage( "&3You must be a player in the game to run this command, and/or the player must be online." ); - return; - } - - // Player player = getPlayer( sender ); - // - // if (player == null || !player.isOnline()) { - // sender.sendMessage( "&3You must be a player in the game to run this - // command." ); - // return; - // } - - player.printDebugInventoryInformationToConsole(); - } +// public void ranksPlayerInventoryCommand( CommandSender sender, +// @Arg( name = "player", def = "", description = "Player name" ) String playerName ) +// { +// +// Player player = getPlayer( sender, playerName ); +// +// if ( player == null ) +// { +// sender.sendMessage( "&3You must be a player in the game to run this command, and/or the player must be online." ); +// return; +// } +// +// // Player player = getPlayer( sender ); +// // +// // if (player == null || !player.isOnline()) { +// // sender.sendMessage( "&3You must be a player in the game to run this +// // command." ); +// // return; +// // } +// +// player.printDebugInventoryInformationToConsole(); +// } } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/PlayerRank.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/PlayerRank.java new file mode 100644 index 000000000..a095bc354 --- /dev/null +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/PlayerRank.java @@ -0,0 +1,114 @@ +package tech.mcprison.prison.ranks.data; + +public class PlayerRank +{ + + private final Rank rank; + + private Double rankMultiplier = null; + private Double rankCost = null; + + public PlayerRank( Rank rank ) { + super(); + + this.rank = rank; + + double rankMultiplier = getLadderBasedRankMultiplier(); + + setRankCost( rankMultiplier ); +// this.rankCost = rank.getCost() * (1.0 + rankMultiplier); + } + + private PlayerRank( Rank rank, double rankMultiplier ) { + this( rank ); + + this.rankMultiplier = rankMultiplier; + + setRankCost( rankMultiplier ); +// this.rankCost = rank.getCost() * (1.0 + rankMultiplier); + } + + public void applyMultiplier( double rankMultiplier ) { + + this.rankMultiplier = rankMultiplier; + + setRankCost( rankMultiplier ); +// this.rankCost = rank.getCost() * (1.0 + rankMultiplier); + } + + private void setRankCost( double rankMultiplier ) { + + this.rankCost = rank.getCost() * (1.0 + rankMultiplier); + } + + public double getLadderBasedRankMultiplier() { + + return getLadderBaseRankdMultiplier( getRank() ); + } + + public static double getLadderBaseRankdMultiplier( Rank rank ) { + double rankMultiplier = 0; + + if ( rank != null && rank.getLadder() != null ) { + double ladderMultiplier = rank.getLadder().getRankCostMultiplierPerRank(); + + // Because it's zero based... so add a 1 + rankMultiplier = ladderMultiplier * (1 + rank.getPosition()); + } + + return rankMultiplier; + } + public static double getRawRankCost( Rank rank ) { + return rank.getCost(); + } + public static void setRawRankCost( Rank rank, double rawCost ) { + rank.setCost( rawCost ); + } + + public static PlayerRank getTargetPlayerRankForPlayer( RankPlayer player, Rank targetRank ) { + PlayerRank targetPlayerRank = null; + + if ( targetRank != null ) { + + double targetRankMultiplier = getLadderBaseRankdMultiplier( targetRank ); + + PlayerRank pRankForPLayer = player.getRank( targetRank.getLadder() ); + double existingRankMultiplier = pRankForPLayer == null ? 0 : + getLadderBaseRankdMultiplier( pRankForPLayer.getRank() ); + + // Get the player's total rankMultiplier from the default ladder + // because they will always have a rank there: + PlayerRank pRank = player.getRank( "default" ); + double playerMultipler = pRank == null ? 0 : pRank.getRankMultiplier(); + + // So the actual rank multiplier that needs to be used, is based upon the + // Player's current multiplier PLUS the multiplier for the target rank + // AND MINUS the multiplier for the current rank the player has within the + // target rank's ladder. + double rankMultiplier = playerMultipler + targetRankMultiplier - existingRankMultiplier; + + targetPlayerRank = new PlayerRank( targetRank, rankMultiplier ); + } + + return targetPlayerRank; + } + + public Rank getRank() { + return rank; + } + + public Double getRankMultiplier() { + return rankMultiplier; + } +// public void setRankMultiplier( Double rankMultiplier ) { +// this.rankMultiplier = rankMultiplier; +// } + + public Double getRankCost() { + return rankCost; + } +// public void setRankCost( Double rankCost ) { +// this.rankCost = rankCost; +// } + +} diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/PlayerRankRefreshTask.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/PlayerRankRefreshTask.java new file mode 100644 index 000000000..d7c87d59a --- /dev/null +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/PlayerRankRefreshTask.java @@ -0,0 +1,39 @@ +package tech.mcprison.prison.ranks.data; + +import tech.mcprison.prison.ranks.PrisonRanks; +import tech.mcprison.prison.ranks.managers.PlayerManager; +import tech.mcprison.prison.tasks.PrisonRunnable; +import tech.mcprison.prison.tasks.PrisonTaskSubmitter; + +/** + *

This task will process all players and recalculate their rank multipliers. + * This task should be ran whenever a ladder's base rank multiplier changes, + * or if a rank is added or removed from a ladder. + *

+ * + *

This should not be ran when a player ranks up since only that player should + * have it's multipliers recalculated, and all the other players shouldn't + * have no reason to be recalculated. + *

+ * + */ +public class PlayerRankRefreshTask + implements PrisonRunnable +{ + + public void submitAsyncTPSTask() { + + PrisonTaskSubmitter.runTaskLaterAsync( this, 1 ); + } + + + public void run() { + + PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); + + for ( RankPlayer rPlayer : pm.getPlayers() ) { + + rPlayer.recalculateRankMultipliers(); + } + } +} diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/Rank.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/Rank.java index 5d7585f86..a21e0d7c6 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/Rank.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/Rank.java @@ -38,12 +38,8 @@ public class Rank implements PrisonSortable, ModuleElement { - /* - * Fields & Constants - */ - - // This is to help eliminate RankLadder.PositionRank object: - private int position; +// // This is to help eliminate RankLadder.PositionRank object: + private transient int position = -1; // The unique identifier used to distinguish this rank from others - this never changes. private int id; @@ -69,9 +65,11 @@ public class Rank // The commands that are run when this rank is attained. private List rankUpCommands; - - private List permissions; - private List permissionGroups; + + // permissions in ranks is obsolete and is being removed. It can never work with vault. + // And Access by Ranks replaces this. +// private List permissions; +// private List permissionGroups; private transient Rank rankPrior; @@ -84,9 +82,10 @@ public class Rank private transient RankLadder ladder; - /* - * Document-related - */ + private transient final List players; + + private transient final StatsRankPlayerBalance statsPlayerBlance; + public Rank() { super(); @@ -96,15 +95,19 @@ public Rank() { this.mines = new ArrayList<>(); this.mineStrings = new ArrayList<>(); - this.permissions = new ArrayList<>(); - this.permissionGroups = new ArrayList<>(); +// this.permissions = new ArrayList<>(); +// this.permissionGroups = new ArrayList<>(); + + this.players = new ArrayList<>(); + + this.statsPlayerBlance = new StatsRankPlayerBalance( this ); } - public Rank( int position, int id, String name, String tag, double cost ) { + public Rank( int id, String name, String tag, double cost ) { this(); - this.position = position; +// this.position = position; this.id = id; this.name = name; @@ -121,7 +124,9 @@ public Rank( int position, int id, String name, String tag, double cost ) { * @param name */ protected Rank( String name ) { - this.position = 0; + this(); + +// this.position = 0; this.id = 0; this.name = name; } @@ -132,8 +137,8 @@ public Rank(Document document) { try { - Object pos = document.get("position"); - this.position = RankUtil.doubleToInt( pos == null ? 0.0d : pos ); +// Object pos = document.get("position"); +// this.position = RankUtil.doubleToInt( pos == null ? 0.0d : pos ); this.id = RankUtil.doubleToInt(document.get("id")); this.name = (String) document.get("name"); @@ -168,24 +173,24 @@ public Rank(Document document) { } - getPermissions().clear(); - Object perms = document.get( "permissions" ); - if ( perms != null ) { - List permissions = (List) perms; - for ( String permission : permissions ) { - getPermissions().add( permission ); - } - } - - - getPermissionGroups().clear(); - Object permsGroups = document.get( "permissionGroups" ); - if ( perms != null ) { - List permissionGroups = (List) permsGroups; - for ( String permissionGroup : permissionGroups ) { - getPermissionGroups().add( permissionGroup ); - } - } +// getPermissions().clear(); +// Object perms = document.get( "permissions" ); +// if ( perms != null ) { +// List permissions = (List) perms; +// for ( String permission : permissions ) { +// getPermissions().add( permission ); +// } +// } +// +// +// getPermissionGroups().clear(); +// Object permsGroups = document.get( "permissionGroups" ); +// if ( perms != null ) { +// List permissionGroups = (List) permsGroups; +// for ( String permissionGroup : permissionGroups ) { +// getPermissionGroups().add( permissionGroup ); +// } +// } } catch ( Exception e ) @@ -200,7 +205,7 @@ public Rank(Document document) { public Document toDocument() { Document ret = new Document(); - ret.put("position", this.position ); +// ret.put("position", this.position ); ret.put("id", this.id); ret.put("name", this.name); ret.put("tag", this.tag); @@ -226,55 +231,84 @@ public Document toDocument() { } ret.put("mines", mineStrings); - ret.put( "permissions", getPermissions() ); - ret.put( "permissionGroups", getPermissionGroups() ); +// ret.put( "permissions", getPermissions() ); +// ret.put( "permissionGroups", getPermissionGroups() ); return ret; } - /** - *

Identifies of the Ladder contains a permission. - *

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

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

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

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

+// * +// * @param permissionGroup +// * @return +// */ +// public boolean hasPermissionGroup( String permissionGroup ) { +// boolean results = false; +// +// for ( String perm : getPermissionGroups() ) { +// if ( perm.equalsIgnoreCase( permissionGroup ) ) { +// results = true; +// break; +// } +// } +// +// return results; +// } + + + public StatsRankPlayerBalance getStatsPlayerBlance() { + return statsPlayerBlance; + } + + /** - *

Identifies if the Ladder contains a permission group. + *

This adds players to this rank. It prevents duplicates. *

* - * @param permissionGroup - * @return + * @param player */ - public boolean hasPermissionGroup( String permissionGroup ) { - boolean results = false; + public void addPlayer( RankPlayer player ) { - for ( String perm : getPermissionGroups() ) { - if ( perm.equalsIgnoreCase( permissionGroup ) ) { - results = true; - break; - } + if ( !getPlayers().contains( player ) ) { + getPlayers().add( player ); + + getStatsPlayerBlance().addPlayer( player ); } - - return results; } - + public void removePlayer( RankPlayer player ) { + + if ( getPlayers().contains( player ) ) { + getPlayers().remove( player ); + + getStatsPlayerBlance().removePlayer( player ); + } + } + @Override public String toString() { return "Rank: " + id + " " + name; @@ -297,10 +331,15 @@ public void setLadder( RankLadder ladder ) { this.ladder = ladder; } - /* - * equals() and hashCode() - */ + /** + * The test of equality should only be done upon the rank id. + * This function is pretty much useless since you can only have + * one rank with the same rank ID and with the same name. So it + * is sufficient to only check if the rank.id matches. + * The other fields, such as name, cost, currency, and tag + * are pretty much meaningless to use in this test. + */ @Override public boolean equals(Object o) { if (this == o) { @@ -312,23 +351,26 @@ public boolean equals(Object o) { Rank rank = (Rank) o; - if (id != rank.id) { - return false; - } - if (Double.compare(rank.cost, cost) != 0) { - return false; - } + // Rank.id is unique and there should never be two with the same rank. - if ( currency != null && rank.currency == null || - currency != null && rank.currency != null && - !currency.equals( rank.currency ) ) { - return false; - } - - if (!name.equals(rank.name)) { - return false; - } - return tag != null ? tag.equals(rank.tag) : rank.tag == null; + return id == rank.id; +// if (id != rank.id) { +// return false; +// } +// if (Double.compare(rank.cost, cost) != 0) { +// return false; +// } +// +// if ( currency != null && rank.currency == null || +// currency != null && rank.currency != null && +// !currency.equals( rank.currency ) ) { +// return false; +// } +// +// if (!name.equals(rank.name)) { +// return false; +// } +// return tag != null ? tag.equals(rank.tag) : rank.tag == null; } @Override @@ -344,13 +386,40 @@ public int hashCode() { return result; } - + /** + * This new implementation of position is lazy loaded and should never be saved. + * This is to provide a quick reference to the position within the ladder's rank's + * ArrayList. This should never be used to access a rank or to refer to a rank; the + * actual objects should be used for that. + * + * @return + */ public int getPosition() { + if ( position == -1 && getLadder() != null ) { + + position = 0; + for ( Rank r : getLadder().getRanks() ) { + if ( r == this ) { + break; + } + position++; + } + + } return position; } - public void setPosition( int position ) { - this.position = position; + /** + * This will force the rank's position to be reset the next time it is + * accessed. + * + */ + public void resetPosition() { + position = -1; } + +// public void setPosition( int position ) { +// this.position = position; +// } public int getId() { return id; @@ -373,10 +442,10 @@ public void setTag( String tag ) { this.tag = tag; } - public double getCost() { + protected double getCost() { return cost; } - public void setCost( double cost ) { + protected void setCost( double cost ) { this.cost = cost; } @@ -397,19 +466,19 @@ public void setRankUpCommands( List rankUpCommands ) { this.rankUpCommands = rankUpCommands; } - public List getPermissions() { - return permissions; - } - public void setPermissions( List permissions ) { - this.permissions = permissions; - } - - public List getPermissionGroups() { - return permissionGroups; - } - public void setPermissionGroups( List permissionGroups ) { - this.permissionGroups = permissionGroups; - } +// public List getPermissions() { +// return permissions; +// } +// public void setPermissions( List permissions ) { +// this.permissions = permissions; +// } +// +// public List getPermissionGroups() { +// return permissionGroups; +// } +// public void setPermissionGroups( List permissionGroups ) { +// this.permissionGroups = permissionGroups; +// } public Rank getRankPrior() { return rankPrior; @@ -449,6 +518,9 @@ public List getMineStrings() { public void setMineStrings( List mineStrings ) { this.mineStrings = mineStrings; } - - + + public List getPlayers() { + return players; + } + } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankLadder.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankLadder.java index 0448a458c..8864a5a0c 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankLadder.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankLadder.java @@ -36,7 +36,7 @@ * @author Faizaan A. Datoo */ public class RankLadder - implements PrisonSortable { + implements PrisonSortable, Comparable { /* * Fields & Constants @@ -45,24 +45,23 @@ public class RankLadder private int id; private String name; private List ranks; -// private List ranks; - private int maxPrestige; +// private int maxPrestige; - private List permissions; - private List permissionGroups; +// private List permissions; +// private List permissionGroups; // The commands that are run when this rank is attained. private List rankUpCommands; + private double rankCostMultiplierPerRank = 0.0d; + + private boolean dirty = false; - /* - * Document-related - */ public RankLadder() { super(); @@ -71,8 +70,8 @@ public RankLadder() { this.ranks = new ArrayList<>(); - this.permissions = new ArrayList<>(); - this.permissionGroups = new ArrayList<>(); +// this.permissions = new ArrayList<>(); +// this.permissionGroups = new ArrayList<>(); } @@ -87,11 +86,20 @@ public RankLadder( int id, String name ) { public RankLadder(Document document, PrisonRanks prisonRanks) { this(); + boolean isDirty = false; + + this.id = RankUtil.doubleToInt(document.get("id")); + this.name = (String) document.get("name"); + RankManager rankManager = prisonRanks.getRankManager(); - this.id = RankUtil.doubleToInt(document.get("id")); - this.name = (String) document.get("name"); - + if ( rankManager == null ) { + + RankMessages rMessages = new RankMessages(); + rMessages.rankFailureLoadingRankManagerMsg( getName(), getId() ); + + return; + } List> ranksLocal = (List>) document.get("ranks"); @@ -118,23 +126,28 @@ public RankLadder(Document document, PrisonRanks prisonRanks) { // The only real field that is important here is rankId to tie the // rank back to this ladder. Name helps clarify the contents of the - // Ladder file. Position is redundant (its now in Rank), but - // it identifies the load order. - int rPos = RankUtil.doubleToInt(rank.get("position")); + // Ladder file. int rRankId = RankUtil.doubleToInt((rank.get("rankId"))); String rRankName = (String) rank.get( "rankName" ); - Rank rankPrison = null; + Rank rankPrison = rankManager.getRank( rRankId ); - if ( rankManager != null && - rankManager.getRank( rRankId ) != null) { + if ( rankPrison != null && rankPrison.getLadder() != null ) { + + RankMessages rMessages = new RankMessages(); + rMessages.rankFailureLoadingDuplicateRankMsg( + rankPrison.getName(), rankPrison.getLadder().getName(), + getName() ); + + isDirty = true; + } + else if ( rankPrison != null) { - rankPrison = rankManager.getRank( rRankId ); addRank( rankPrison ); // Output.get().logInfo( "RankLadder load : " + getName() + // " rank= " + rankPrison.getName() + " " + rankPrison.getId() + -// " " + rankPrison.getPosition() ); +// ); // // if null look it up from loaded ranks: // if ( rRankName == null ) { @@ -146,9 +159,11 @@ public RankLadder(Document document, PrisonRanks prisonRanks) { // Rank not found. Try to create it? The name maybe wrong. String rankName = rRankName != null && !rRankName.trim().isEmpty() ? rRankName : "Rank " + rRankId; + + // NOTE: The following is valid use of getCost(): double cost = getRanks().size() == 0 ? 0 : getRanks().get( getRanks().size() - 1 ).getCost() * 3; - Rank newRank = new Rank(rPos, rRankId, rankName, null, cost ); + Rank newRank = new Rank( rRankId, rankName, null, cost ); addRank( newRank ); @@ -159,29 +174,36 @@ public RankLadder(Document document, PrisonRanks prisonRanks) { // Output.get().logError( message ); } -// ranks.add(new PositionRank( rPos, rRankId, rRankName, rankPrison )); } - this.maxPrestige = RankUtil.doubleToInt(document.get("maxPrestige")); +// this.maxPrestige = RankUtil.doubleToInt(document.get("maxPrestige")); - - getPermissions().clear(); - Object perms = document.get( "permissions" ); - if ( perms != null ) { - List permissions = (List) perms; - for ( String permission : permissions ) { - getPermissions().add( permission ); - } - } + + Double rankCostMultiplier = (Double) document.get( "rankCostMultiplierPerRank" ); + setRankCostMultiplierPerRank( rankCostMultiplier == null ? 0 : rankCostMultiplier ); - getPermissionGroups().clear(); - Object permsGroups = document.get( "permissionGroups" ); - if ( perms != null ) { - List permissionGroups = (List) permsGroups; - for ( String permissionGroup : permissionGroups ) { - getPermissionGroups().add( permissionGroup ); - } +// getPermissions().clear(); +// Object perms = document.get( "permissions" ); +// if ( perms != null ) { +// List permissions = (List) perms; +// for ( String permission : permissions ) { +// getPermissions().add( permission ); +// } +// } +// +// +// getPermissionGroups().clear(); +// Object permsGroups = document.get( "permissionGroups" ); +// if ( perms != null ) { +// List permissionGroups = (List) permsGroups; +// for ( String permissionGroup : permissionGroups ) { +// getPermissionGroups().add( permissionGroup ); +// } +// } + + if ( isDirty ) { + PrisonRanks.getInstance().getLadderManager().save( this ); } } @@ -206,8 +228,8 @@ public Document toDocument() { for ( Rank rank : getRanks() ) { LinkedTreeMap rnk = new LinkedTreeMap(); - rnk.put( "position", Double.valueOf( (double) rank.getPosition() )); - rnk.put( "rankId", Double.valueOf( (double) rank.getId() )); +// rnk.put( "position", rank.getPosition() ); + rnk.put( "rankId", rank.getId() ); rnk.put( "rankName", rank.getName()); ranksLocal.add( rnk ); @@ -216,10 +238,12 @@ public Document toDocument() { // ret.put("ranks", this.ranks); - ret.put("maxPrestige", this.maxPrestige); + ret.put( "rankCostMultiplierPerRank", getRankCostMultiplierPerRank() ); + +// ret.put("maxPrestige", this.maxPrestige); - ret.put( "permissions", getPermissions() ); - ret.put( "permissionGroups", getPermissionGroups() ); +// ret.put( "permissions", getPermissions() ); +// ret.put( "permissionGroups", getPermissionGroups() ); return ret; } @@ -231,31 +255,19 @@ public String toString() { public List getRanks() { return ranks; - -// List rankz = new ArrayList<>(); -// -// RankManager rankManager = PrisonRanks.getInstance().getRankManager(); -// -// for ( PositionRank rank : ranks ) { -// -// if ( rank != null && rank.rank == null ) { -// // -// Rank rnk = rankManager.getRank( rank.rankId ); -// if ( rnk != null ) { -// rank.rank = rnk; -// } -// else { -// Output.get().logWarn( "RankLadder.listAllRanks(): " + -// "Could not get Rank from rankId: " + rank.rankId ); -// } -// } -// rankz.add( rank.rank ); -// } -// -// return rankz; } - /** + @Override + public int compareTo( RankLadder rl ) + { + int results = -1; + if ( rl != null ) { + results = getName().compareTo( rl.getName() ); + } + return results; + } + + /** * Add a rank to this ladder. * * @param position The place in line to put this rank, beginning at 0. The player will be taken @@ -268,24 +280,17 @@ public void addRank(int position, Rank rank) { position = 0; } else if ( position > getRanks().size() ) { - position = getRanks().size(); + getRanks().add( rank ); + } + else { + getRanks().add( position, rank ); } -// position = Math.min(position, -// getRanks().size() + 1); // Make sure to cap it off at the upper limit or else problems -// int finalPosition = position; -// ranks.stream().filter(positionRank -> positionRank.getPosition() >= finalPosition) -// .forEach(positionRank -> positionRank.setPosition(positionRank.getPosition() + 1)); - rank.setPosition( position ); - getRanks().add( position, rank ); - rank.setLadder( this ); -// ranks.add(new PositionRank(position, rank.getId(), rank.getName(), rank)); + rank.setLadder( this ); // Update the rank positions along with next and prior: connectRanks(); -// // Reset the rank relationships: -// PrisonRanks.getInstance().getRankManager().connectRanks(); } @@ -298,8 +303,8 @@ else if ( position > getRanks().size() ) { * @param rank The {@link Rank} to add. */ public void addRank(Rank rank) { - int position = getRanks().size(); - rank.setPosition( position ); +// int position = getRanks().size(); +// rank.setPosition( position ); rank.setLadder( this ); getRanks().add( rank ); @@ -313,37 +318,18 @@ public void addRank(Rank rank) { // PrisonRanks.getInstance().getRankManager().connectRanks(); } - /** - * Removes a rank from this ladder. - * - * @param position The position of the rank to be removed. The positions of the rest of the - * ranks will be downshifted to fill the gap. - */ - public void removeRank(int position) { - - Rank rank = getRanks().remove( position ); - - rank.setLadder( null ); - // Update the rank positions along with next and prior: - connectRanks(); + public void removeRank( Rank rank ) { -// ranks.stream().filter(positionRank -> positionRank.getPosition() > position).forEach( -// positionRank -> positionRank.setPosition(positionRank.getPosition() - 1) -// ); -// -// Iterator iter = ranks.iterator(); -// while (iter.hasNext()) { -// PositionRank rank = iter.next(); -// if (rank.getPosition() == position) { -// iter.remove(); -// break; -// } -// } - -// // Reset the rank relationships: -// PrisonRanks.getInstance().getRankManager().connectRanks(); + boolean success = getRanks().remove( rank ); + + if ( success ) { + rank.setLadder( null ); + + // Update the rank positions along with next and prior: + connectRanks(); + } } /** @@ -366,9 +352,12 @@ private void connectRanks() { // update their position value: for ( int i = 0; i < getRanks().size(); i++ ) { Rank rank = getRanks().get( i ); - if ( rank.getPosition() != i ) { - rank.setPosition( i ); - } + + rank.resetPosition(); + +// if ( rank.getPosition() != i ) { +// rank.setPosition( i ); +// } // reset the rankPrior and rankNext in case there are no hookups: // Important if ranks are removed, or inserted, or moved: @@ -405,112 +394,13 @@ private void connectRanks() { */ /** - * Returns true if this ladder contains a rank with a specified ID. - * - * @param rankId The ID of the rank to search for. + * Returns true if this ladder contains the Rank. + * + * @param the rank to search for. * @return True if the rank was found, false otherwise. */ - public boolean containsRank(int rankId) { - return ranks.stream().anyMatch(rank -> rank.getId() == rankId); - } - - /** - * Returns the position of the specified {@link Rank} in this ladder. - * - * @param rank The {@link Rank} to retrieve the position of. - * @return The position of the rank, or -1 if the rank was not found. - */ - public int getPositionOfRank(Rank rank) { - - return getRanks().contains( rank ) ? rank.getPosition() : -1; - -// for (PositionRank rankEntry : ranks) { -// if (rankEntry.getRankId() == rank.getId()) { -// return rankEntry.getPosition(); -// } -// } -// -// return -1; - } - - /** - * Returns the next highest rank in the ladder. - * - * @param after The position of the current rank. - * @return An optional containing either the rank if there is a next rank in the ladder, or - * empty if there isn't or if the rank does not exist anymore. - */ - public Optional getNext(int after) { - Rank results = null; - - if ( getRanks().size() >= after ) { - results = getRanks().get( after ).getRankNext(); - } - - return results == null ? Optional.empty() : Optional.of( results ); -// List positions = -// ranks.stream().map(PositionRank::getPosition).sorted().collect(Collectors.toList()); -// -// int newIndex = positions.indexOf(after) + 1; -// if (newIndex >= positions.size()) { -// return Optional.empty(); -// } -// -// int nextPosition = positions.get(newIndex); -// return getByPosition(nextPosition); - } - - /** - * Returns the next lowest rank in the ladder. - * - * @param before The position of the current rank. - * @return An optional containing either the rank if there is a previous rank in the ladder, or - * empty if there isn't or if the rank does not exist anymore. - */ - public Optional getPrevious(int before) { - Rank results = null; - - if ( getRanks().size() >= before ) { - results = getRanks().get( before ).getRankPrior(); - } - - return results == null ? Optional.empty() : Optional.of( results ); - -// List positions = -// ranks.stream().map(PositionRank::getPosition).sorted().collect(Collectors.toList()); -// -// int newIndex = positions.indexOf(before) - 1; -// if (newIndex < 0) { -// return Optional.empty(); -// } -// -// int previousPosition = positions.get(newIndex); -// return getByPosition(previousPosition); - } - - /** - * Searches for and returns a rank in the ladder, depending on the position in the ladder. - * - * @param position The position to search for. - * @return An optional containing the rank if it was found, or empty if it wasn't. - */ - public Optional getByPosition(int position) { - Rank results = null; - - if ( getRanks().size() > position ) { - results = getRanks().get( position ); - } - - return results == null ? Optional.empty() : Optional.of( results ); -// -// -// for (PositionRank posRank : ranks) { -// if (posRank.getPosition() == position) { -// return PrisonRanks.getInstance().getRankManager().getRankOptional(posRank.getRankId()); -// } -// } -// -// return Optional.empty(); + public boolean containsRank( Rank rank ) { + return ranks.contains( rank ); } // This next method is sort of precautionary. Sure, positions start at 0, but if the user decides @@ -526,57 +416,19 @@ public Optional getByPosition(int position) { public Optional getLowestRank() { Rank results = null; - for ( Rank r : getRanks() ) { - if ( results == null || r.getPosition() < results.getPosition() ) { - results = r; - } - } + if ( getRanks().size() > 0 ) { + results = getRanks().get( 0 ); + } - return results == null ? Optional.empty() : Optional.of( results ); -// -// -// if (ranks.isEmpty()) return Optional.empty(); -// -// PositionRank lowest = ranks.get(0); -// for (PositionRank posRank : ranks) { -// if (posRank.getPosition() < lowest.getPosition()) { -// lowest = posRank; -// } -// } -// -// return PrisonRanks.getInstance().getRankManager().getRankOptional(lowest.getRankId()); - } - -// /** -// * Returns the next available position for a rank, by finding the highest one. -// * -// * @return The open position. -// */ -// private int getNextAvailablePosition() { -// Rank results = null; -// // for ( Rank r : getRanks() ) { -// if ( results == null || r.getPosition() > results.getPosition() ) { +// if ( results == null || r.getPosition() < results.getPosition() ) { // results = r; // } // } -// -// return results == null ? -1 : results.getPosition() + 1; -// -//// if (ranks.size() == 0) { -//// return 0; // obviously, if it's empty, we want to start at the bottom -//// } -//// -//// //orderRanksByPosition(); -//// // Reset the rank relationships: -//// PrisonRanks.getInstance().getRankManager().connectRanks(); -//// -//// return ranks.get(ranks.size() - 1).getPosition() + 1; -// } + + return results == null ? Optional.empty() : Optional.of( results ); + } - /* - * equals() and hashCode() - */ @Override public boolean equals(Object o) { @@ -599,107 +451,47 @@ public int hashCode() { return result; } -// public class PositionRank { -// -// private int position; -// private int rankId; -// private String rankName; -// -// /** -// * Adds a link to the actual Rank. This will save a lot of busy -// * work and can reduce the complexity of a lot of code. -// */ -// private transient Rank rank; -// -// /** -// * -// * @param position -// * @param rankId -// * @param rankName rankName is never used but makes it easier to read the saved files -// */ -// public PositionRank(int position, int rankId, String rankName, Rank rank ) { -// this.position = position; -// this.rankId = rankId; -// this.rankName = rankName; -// } -// -// public int getPosition() { -// return position; -// } -// -// public void setPosition(int position) { -// this.position = position; -// } -// -// public int getRankId() { -// return rankId; -// } -// -// public void setRankId(int rankId) { -// this.rankId = rankId; -// } -// -// public String getRankName() -// { -// return rankName; -// } -// -// public void setRankName( String rankName ) -// { -// this.rankName = rankName; -// } -// -// public Rank getRank() -// { -// return rank; -// } -// -// public void setRank( Rank rank ) -// { -// this.rank = rank; -// } -// } - /** - *

Identifies of the Ladder contains a permission. - *

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

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

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

Identifies if the Ladder contains a permission group. - *

- * - * @param permissionGroup - * @return - */ - public boolean hasPermissionGroup( String permissionGroup ) { - boolean results = false; - - for ( String perm : getPermissionGroups() ) { - if ( perm.equalsIgnoreCase( permissionGroup ) ) { - results = true; - break; - } - } - - return results; - } +// /** +// *

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

+// * +// * @param permissionGroup +// * @return +// */ +// public boolean hasPermissionGroup( String permissionGroup ) { +// boolean results = false; +// +// for ( String perm : getPermissionGroups() ) { +// if ( perm.equalsIgnoreCase( permissionGroup ) ) { +// results = true; +// break; +// } +// } +// +// return results; +// } public int getId() { return id; @@ -715,20 +507,13 @@ public void setName( String name ) { this.name = name; } - public int getMaxPrestige() { - return maxPrestige; - } - public void setMaxPrestige( int maxPrestige ) { - this.maxPrestige = maxPrestige; - } - -// public List getPositionRanks() { -// return ranks; +// public int getMaxPrestige() { +// return maxPrestige; // } -// public void setPositionRanks( List ranks ) { -// this.ranks = ranks; +// public void setMaxPrestige( int maxPrestige ) { +// this.maxPrestige = maxPrestige; // } - + public List getRankUpCommands() { if ( rankUpCommands == null ) { rankUpCommands = new ArrayList<>(); @@ -739,19 +524,26 @@ public void setRankUpCommands( List rankUpCommands ) { this.rankUpCommands = rankUpCommands; } - public List getPermissions() { - return permissions; - } - - public void setPermissions( List permissions ) { - this.permissions = permissions; - } +// public List getPermissions() { +// return permissions; +// } +// +// public void setPermissions( List permissions ) { +// this.permissions = permissions; +// } +// +// public List getPermissionGroups() { +// return permissionGroups; +// } +// public void setPermissionGroups( List permissionGroups ) { +// this.permissionGroups = permissionGroups; +// } - public List getPermissionGroups() { - return permissionGroups; + public double getRankCostMultiplierPerRank() { + return rankCostMultiplierPerRank; } - public void setPermissionGroups( List permissionGroups ) { - this.permissionGroups = permissionGroups; + public void setRankCostMultiplierPerRank( double rankCostMultiplierPerRank ) { + this.rankCostMultiplierPerRank = rankCostMultiplierPerRank; } public boolean isDirty() { diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankMessages.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankMessages.java index 08b0bac1a..60044242f 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankMessages.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankMessages.java @@ -1,5 +1,6 @@ package tech.mcprison.prison.ranks.data; +import tech.mcprison.prison.output.Output; import tech.mcprison.prison.ranks.PrisonRanks; public class RankMessages { @@ -13,4 +14,24 @@ protected String rankFailureLoadingRanksMsg( String id, String name, String erro .localize(); } + protected void rankFailureLoadingRankManagerMsg( String ladderName, int ladderId ) { + String message = PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_rankManager__failure_loading_rankManager" ) + .withReplacements( + ladderName, + Integer.toString( ladderId ) ) + .localize(); + Output.get().logError( message ); + } + + protected void rankFailureLoadingDuplicateRankMsg( String rankName, String ladderName, + String badLadderName ) { + String message = PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_rankManager__failure_duplicate_rank" ) + .withReplacements( + rankName, ladderName, badLadderName, badLadderName ) + .localize(); + Output.get().logError( message ); + } + } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayer.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayer.java index a7d9f2a11..a4b44bfc8 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayer.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/RankPlayer.java @@ -22,6 +22,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.TreeMap; import java.util.UUID; @@ -37,8 +38,10 @@ import tech.mcprison.prison.internal.inventory.Inventory; import tech.mcprison.prison.internal.scoreboard.Scoreboard; import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.ranks.FirstJoinHandlerMessages; import tech.mcprison.prison.ranks.PrisonRanks; import tech.mcprison.prison.ranks.RankUtil; +import tech.mcprison.prison.ranks.events.FirstJoinEvent; import tech.mcprison.prison.ranks.top.RankPlayerBalance; import tech.mcprison.prison.store.Document; import tech.mcprison.prison.util.Gamemode; @@ -59,7 +62,7 @@ public class RankPlayer private UUID uid; - private HashMap ladderRanks; + private TreeMap ladderRanks; // ranks is the storage structure used to save the player's ladder & ranks: private HashMap ranksRefs; // @@ -85,7 +88,7 @@ public class RankPlayer public RankPlayer() { super(); - this.ladderRanks = new HashMap<>(); + this.ladderRanks = new TreeMap<>(); this.ranksRefs = new HashMap<>(); //this.prestige = new HashMap<>(); @@ -167,9 +170,23 @@ public Document toDocument() { return ret; } - /* - * Methods - */ + + @Override + public String toString() { + return getName() + " " + getRanks(); + } + + public String getRanks() { + StringBuilder sb = new StringBuilder(); + + for ( PlayerRank rank : getLadderRanks().values() ) { + + sb.append( rank.getRank().getLadder() == null ? "--" : rank.getRank().getLadder().getName() ) + .append( ":" ).append( rank.getRank().getName() ).append( " " ); + } + + return sb.toString(); + } public UUID getUUID() { return uid; @@ -212,7 +229,8 @@ public boolean checkName( String playerName ) { String name = getLastName(); // Check if the last name in the list is not the same as the name passed: - if ( name != null && !name.equalsIgnoreCase( playerName ) ) { + if ( name == null || + name != null && !name.equalsIgnoreCase( playerName ) ) { RankPlayerName rpn = new RankPlayerName( playerName, System.currentTimeMillis() ); getNames().add( rpn ); @@ -263,11 +281,49 @@ public String filename() } + /** + *

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

+ * + *

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

+ * + *

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

+ */ + public void firstJoin() { + + RankLadder defaultLadder = PrisonRanks.getInstance().getDefaultLadder(); + + if ( !getLadderRanks().containsKey( defaultLadder ) ) { + + Optional firstRank = defaultLadder.getLowestRank(); + + if ( firstRank.isPresent() ) { + Rank rank = firstRank.get(); + + addRank( rank ); + + Prison.get().getEventBus().post(new FirstJoinEvent( this )); + + FirstJoinHandlerMessages messages = new FirstJoinHandlerMessages(); + Output.get().logWarn( messages.firstJoinSuccess( getName() ) ); + + } else { + + FirstJoinHandlerMessages messages = new FirstJoinHandlerMessages(); + Output.get().logWarn( messages.firstJoinWarningNoRanksOnServer() ); + } + } + + } + /** * Add a rank to this player. * If a rank on this ladder is already attached, it will automatically be removed and replaced with this new one. * - * @param ladder The {@link RankLadder} that this rank belongs to. * @param rank The {@link Rank} to add. * @throws IllegalArgumentException If the rank specified is not on this ladder. */ @@ -288,9 +344,39 @@ public void addRank( Rank rank) { } ranksRefs.put(ladderName, rank.getId()); - ladderRanks.put( rank.getLadder(), rank ); + + PlayerRank pRank = new PlayerRank( rank ); + + ladderRanks.put( rank.getLadder(), pRank ); + + // Calculate and apply the rank multipliers: + recalculateRankMultipliers(); } + public void recalculateRankMultipliers() { + double multiplier = 0; + + // First gather and calculate the multipliers: + Set keys = ladderRanks.keySet(); + for ( RankLadder rankLadder : keys ) + { + PlayerRank pRank = ladderRanks.get( rankLadder ); + + double rankMultiplier = pRank.getLadderBasedRankMultiplier(); + multiplier += rankMultiplier; + } + + // We now have the multipliers, so apply them to all ranks: + for ( RankLadder rankLadder : keys ) + { + PlayerRank pRank = ladderRanks.get( rankLadder ); + + pRank.applyMultiplier( multiplier ); +// pRank.setRankCost( pRank.getRank().getCost() * (1.0 + multiplier) ); + } + + } + /** * Remove a rank from this player. * This will also remove the ladder from this player. @@ -356,13 +442,21 @@ public boolean removeLadder(String ladderName) { * @param ladder The ladder to check. * @return An optional containing the {@link Rank} if found, or empty if there isn't a rank by that ladder for this player. */ - public Rank getRank(RankLadder ladder) { + public PlayerRank getRank(RankLadder ladder) { + PlayerRank results = null; - if ( ladder == null || !ladderRanks.containsKey( ladder ) ) { - return null; + if ( ladder != null ) { + + Set keys = ladderRanks.keySet(); + for ( RankLadder key : keys ) + { + if ( key != null && key.getName().equalsIgnoreCase( ladder.getName() ) ) { + results = ladderRanks.get( key ); + } + } } - - return ladderRanks.get( ladder ); + + return results; // if (!ranksRefs.containsKey(ladder.getName())) { // return null; @@ -377,7 +471,7 @@ public Rank getRank(RankLadder ladder) { * @param ladder The ladder name to check. * @return The {@link Rank} if found, otherwise null; */ - public Rank getRank( String ladderName ) { + public PlayerRank getRank( String ladderName ) { RankLadder ladder = PrisonRanks.getInstance().getLadderManager().getLadder( ladderName ); return getRank( ladder ); @@ -408,7 +502,7 @@ public void setRanks( HashMap ranks ) { * * @return The map containing this data. */ - public Map getLadderRanks() { + public Map getLadderRanks() { if ( ladderRanks.isEmpty() && !ranksRefs.isEmpty() ) { @@ -425,8 +519,13 @@ public Map getLadderRanks() { continue; // Skip it } - ladderRanks.put(ladder, rank); + PlayerRank pRank = new PlayerRank( rank ); + + ladderRanks.put(ladder, pRank); } + + // Need to recalculate all rank multipliers: + recalculateRankMultipliers(); } return ladderRanks; @@ -449,17 +548,21 @@ public boolean hasAccessToRank( Rank targetRank ) { if ( targetRank != null && targetRank.getLadder() != null ) { - Rank rank = getRank( targetRank.getLadder() ); - if ( rank != null && - rank.getLadder().equals( targetRank.getLadder() ) ) { + PlayerRank pRank = getRank( targetRank.getLadder() ); + if ( pRank != null ) { - hasAccess = rank.equals( targetRank ); - Rank priorRank = rank.getRankPrior(); - - while ( !hasAccess && priorRank != null ) { + Rank rank = pRank.getRank(); + if ( rank != null && + rank.getLadder().equals( targetRank.getLadder() ) ) { + + hasAccess = rank.equals( targetRank ); + Rank priorRank = rank.getRankPrior(); - hasAccess = priorRank.equals( targetRank ); - priorRank = priorRank.getRankPrior(); + while ( !hasAccess && priorRank != null ) { + + hasAccess = priorRank.equals( targetRank ); + priorRank = priorRank.getRankPrior(); + } } } } @@ -611,10 +714,10 @@ public Inventory getInventory() { return null; } - @Override - public void printDebugInventoryInformationToConsole() { - - } +// @Override +// public void printDebugInventoryInformationToConsole() { +// +// } /** *

Player is not cached in this class, so if using it in a function @@ -889,4 +992,12 @@ public List getPermissionsIntegrations( boolean detailed ) { return results; } + + @Override + public void setTitle( String title, String subtitle, int fadeIn, int stay, int fadeOut ) { + } + + @Override + public void setActionBar( String actionBar ) { + } } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/StatsRankPlayerBalance.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/StatsRankPlayerBalance.java new file mode 100644 index 000000000..802f71289 --- /dev/null +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/StatsRankPlayerBalance.java @@ -0,0 +1,73 @@ +package tech.mcprison.prison.ranks.data; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import tech.mcprison.prison.Prison; + +public class StatsRankPlayerBalance +{ + public static final long REFRESH_INTERVAL = 5 * 60 * 1000; // 5 minutes + private final Rank rank; + private long lastRefresh = 0; + + private transient final List playerStats; + + public StatsRankPlayerBalance( Rank rank ) { + super(); + + this.rank = rank; + + this.playerStats = new ArrayList<>(); + } + + public void refresh() { + long current = System.currentTimeMillis(); + if ( current > lastRefresh + REFRESH_INTERVAL ) { + + boolean penalty = isHesitancyDelayPenaltyEnabled(); + // refresh time: + for ( StatsRankPlayerBalanceData playerStats : playerStats ) { + playerStats.recalc( penalty ); + } + + Collections.sort( playerStats ); + } + } + + public void addPlayer( RankPlayer player ) { + + StatsRankPlayerBalanceData pStats = new StatsRankPlayerBalanceData( rank, + player, isHesitancyDelayPenaltyEnabled() ); + if ( !playerStats.contains( pStats ) ) { + playerStats.add( pStats ); + } + } + + public void removePlayer( RankPlayer player ) { + + StatsRankPlayerBalanceData pStats = new StatsRankPlayerBalanceData( rank, + player, isHesitancyDelayPenaltyEnabled() ); + if ( playerStats.contains( pStats ) ) { + playerStats.remove( pStats ); + } + } + + public StatsRankPlayerBalanceData getTopStats( int position ) { + StatsRankPlayerBalanceData stats = null; + if ( position > 0 && position <= playerStats.size() ) { + + // check to see if the stats should be refreshed: + refresh(); + + playerStats.get( position - 1 ); + } + return stats; + } + + public boolean isHesitancyDelayPenaltyEnabled() { + return Prison.get().getPlatform() + .getConfigBooleanTrue( "top-stats.rank-players.hesitancy-delay-penalty" ); + } +} diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/StatsRankPlayerBalanceData.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/StatsRankPlayerBalanceData.java new file mode 100644 index 000000000..fa09e0030 --- /dev/null +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/data/StatsRankPlayerBalanceData.java @@ -0,0 +1,121 @@ +package tech.mcprison.prison.ranks.data; + +public class StatsRankPlayerBalanceData + implements Comparable +{ + private final Rank rank; + private final RankPlayer player; + + private double score = 0; + private double penalty = 0; + + public StatsRankPlayerBalanceData( Rank rank, RankPlayer player, boolean isPleanltyEnabled ) { + super(); + + this.rank = rank; + this.player = player; + + recalc( isPleanltyEnabled ); + } + + public StatsRankPlayerBalanceData() { + super(); + + this.rank = null; + this.player = null; + } + + public void recalc( boolean isPenaltyEnabled ) { + double balance = player.getBalance( rank.getCurrency() ); + double score = balance; + + // The "cost" should be the cost of the next rank. If the next rank does not exist, + // then it should be the current rank. + PlayerRank pRank = player.getRank( rank.getLadder() ); + if ( pRank != null ) { + + double cost = pRank.getRankCost(); // This is the fallback value if nextRank doesn't exist. + + if ( rank.getRankNext() != null ) { + + // This calculates the target rank, and takes in to consideration the player's existing rank: + PlayerRank pRankNext = PlayerRank.getTargetPlayerRankForPlayer( player, rank.getRankNext() ); + + //PlayerRank pRankNext = new PlayerRank( rank.getRankNext(), pRank.getRankMultiplier() ); + cost = pRankNext.getRankCost(); + } +// double cost = rank.getRankNext() == null ? rank.getCost() : rank.getRankNext().getCost(); + double penalty = 0d; + + // Do not apply the penalty if cost is zero: + if ( isPenaltyEnabled && cost > 0 ) { + score = balance > cost ? cost : score; + + double excess = balance > cost ? balance - cost : 0d; + penalty = excess * 0.2d; + } + + score = (score - penalty); + + if ( cost > 0 ) { + score /= cost * 100.0d; + } + } + + setScore( score ); + setPenalty( penalty ); + } + + + + @Override + public boolean equals( Object obj ) + { + boolean results = obj != null && obj instanceof StatsRankPlayerBalanceData && + getPlayer().equals( ((StatsRankPlayerBalanceData) obj).getPlayer() ); + + return results; + } + + @Override + public int compareTo( StatsRankPlayerBalanceData statsData ) + { + int results = 0; + + if ( statsData == null ) { + results = 1; + } + else if ( getScore() < statsData.getScore() ) { + results = -1; + } + else if ( getScore() > statsData.getScore() ) { + results = 1; + } + + return results; + } + + + public Rank getRank() { + return rank; + } + + public RankPlayer getPlayer() { + return player; + } + + public double getScore() { + return score; + } + public void setScore( double score ) { + this.score = score; + } + + public double getPenalty() { + return penalty; + } + public void setPenalty( double penalty ) { + this.penalty = penalty; + } + +} diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/LadderManager.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/LadderManager.java index 8509e289b..dced2b207 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/LadderManager.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/LadderManager.java @@ -284,16 +284,22 @@ public List getLadders() { * @param rankId The ID of the rank to check each ladder against. * @return A list of {@link RankLadder}s with the matched criteria. */ - public List getLaddersWithRank(int rankId) { - return loadedLadders.stream().filter(rankLadder -> rankLadder.containsRank(rankId)) - .collect(Collectors.toList()); - } +// public List getLaddersWithRank(int rankId) { +// return loadedLadders.stream().filter(rankLadder -> rankLadder.containsRank(rankId)) +// .collect(Collectors.toList()); +// } + /** + *

This returns the ladder that has the specified rank. The ladder + * should already be tied to the rank + * @param rank + * @return + */ public RankLadder getLadder( Rank rank ) { RankLadder results = null; for ( RankLadder rankLadder : loadedLadders ) { - if ( rankLadder.containsRank( rank.getId() )) { + if ( rankLadder.containsRank( rank )) { results = rankLadder; break; } diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java index 3058bf087..9412847e4 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManager.java @@ -30,10 +30,9 @@ import com.google.common.eventbus.Subscribe; import tech.mcprison.prison.Prison; -import tech.mcprison.prison.PrisonAPI; -import tech.mcprison.prison.integration.EconomyCurrencyIntegration; -import tech.mcprison.prison.integration.EconomyIntegration; +import tech.mcprison.prison.cache.PlayerCache; import tech.mcprison.prison.internal.Player; +import tech.mcprison.prison.internal.PlayerUtil; import tech.mcprison.prison.internal.events.player.PlayerJoinEvent; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.placeholders.ManagerPlaceholders; @@ -42,17 +41,15 @@ import tech.mcprison.prison.placeholders.PlaceholderAttributeNumberFormat; import tech.mcprison.prison.placeholders.PlaceholderAttributeText; import tech.mcprison.prison.placeholders.PlaceholderManager; -import tech.mcprison.prison.placeholders.PlaceholderManager.PlaceHolderFlags; +import tech.mcprison.prison.placeholders.PlaceholderManager.PlaceholderFlags; import tech.mcprison.prison.placeholders.PlaceholderManager.PrisonPlaceHolders; import tech.mcprison.prison.placeholders.PlaceholderResults; import tech.mcprison.prison.placeholders.PlaceholdersUtil; import tech.mcprison.prison.ranks.PrisonRanks; -import tech.mcprison.prison.ranks.RankUtil; -import tech.mcprison.prison.ranks.RankupResults; +import tech.mcprison.prison.ranks.data.PlayerRank; import tech.mcprison.prison.ranks.data.Rank; import tech.mcprison.prison.ranks.data.RankLadder; import tech.mcprison.prison.ranks.data.RankPlayer; -import tech.mcprison.prison.ranks.events.FirstJoinEvent; import tech.mcprison.prison.store.Collection; import tech.mcprison.prison.store.Document; import tech.mcprison.prison.tasks.PrisonTaskSubmitter; @@ -122,7 +119,10 @@ public void loadPlayer(String playerFile) throws IOException { */ public void loadPlayers() throws IOException { List players = collection.getAll(); - players.forEach(document -> this.players.add(new RankPlayer(document))); + players.forEach( + document -> + this.players.add( + new RankPlayer(document))); } /** @@ -138,8 +138,16 @@ public void savePlayer(RankPlayer player, String playerFile) throws IOException // collection.insert(playerFile, player.toDocument()); } - public void savePlayer(RankPlayer player) throws IOException { - this.savePlayer(player, player.filename()); + public void savePlayer(RankPlayer player) { + try { + this.savePlayer(player, player.filename()); + } + catch (IOException e) { + + String errorMessage = cannotSaveNewPlayerFile( player.getName(), player.filename() ); + + Output.get().logError( errorMessage, e); + } } /** @@ -169,6 +177,22 @@ public void savePlayers() throws IOException { } } } + + /** + *

This function will add all the players to all of the ranks they + * are associated with. + *

+ * + */ + public void connectPlayersToRanks() { + for ( RankPlayer player : players ) { + + for ( PlayerRank pRank : player.getLadderRanks().values() ) { + + pRank.getRank().addPlayer( player ); + } + } + } /* * Getters & Setters @@ -206,7 +230,7 @@ public RankPlayer getPlayer(UUID uid, String playerName) { for ( RankPlayer rankPlayer : players ) { if ( uid != null && rankPlayer.getUUID().equals(uid) || - uid == null && playerName != null && playerName.trim().length() > 0 && + uid == null && playerName != null && playerName.trim().isEmpty() && rankPlayer.getDisplayName() != null && rankPlayer.getDisplayName().equalsIgnoreCase( playerName ) ) { @@ -235,19 +259,19 @@ public RankPlayer getPlayer(UUID uid, String playerName) { // Save if dirty (change or new): if ( dirty && results != null ) { - try { - savePlayer( results ); - } - catch ( IOException e ) { - - String errorMessage = cannotAddNewPlayer( playerName, e.getMessage() ); - - if ( !getPlayerErrors().contains( errorMessage ) ) { - - getPlayerErrors().add( errorMessage ); - Output.get().logError( errorMessage ); - } - } + savePlayer( results ); +// try { +// } +// catch ( IOException e ) { +// +// String errorMessage = cannotAddNewPlayer( playerName, e.getMessage() ); +// +// if ( !getPlayerErrors().contains( errorMessage ) ) { +// +// getPlayerErrors().add( errorMessage ); +// Output.get().logError( errorMessage ); +// } +// } } @@ -263,6 +287,10 @@ public RankPlayer getPlayer( Player player ) { } + public RankPlayer addPlayer( Player player ) { + return addPlayer( player.getUUID(), player.getName() ); + } + private RankPlayer addPlayer( UUID uid, String playerName ) { RankPlayer results = null; @@ -303,33 +331,23 @@ protected RankPlayer addPlayerSyncTask( UUID uid, String playerName ) { newPlayer = new RankPlayer( uid, playerName ); newPlayer.checkName( playerName ); + newPlayer.firstJoin(); + players.add(newPlayer); getPlayersByName().put( playerName, newPlayer ); - try { - savePlayer(newPlayer); - - Player player = getPlayer( null, playerName, uid ); - - // Assign the player to the default rank: - String ladder = null; // will set to the "default" ladder - String rank = null; // will set to the "default" rank - - // Set the rank to the default ladder and the default rank. The results are logged - // before the results are returned, so can ignore the results: - @SuppressWarnings( "unused" ) - RankupResults results = new RankUtil().setRank(player, newPlayer, ladder, rank, - playerName, "FirstJoinEvent"); - - - Prison.get().getEventBus().post(new FirstJoinEvent(newPlayer)); - } - catch (IOException e) { - - String errorMessage = cannotSaveNewPlayerFile( playerName, newPlayer.filename() ); - - Output.get().logError( errorMessage, e); - } + savePlayer(newPlayer); + + +// try { +// +// } +// catch (IOException e) { +// +// String errorMessage = cannotSaveNewPlayerFile( playerName, newPlayer.filename() ); +// +// Output.get().logError( errorMessage, e); +// } } } @@ -360,14 +378,14 @@ public String getPlayerRankName( RankPlayer rankPlayer, String ladderName ) { StringBuilder sb = new StringBuilder(); if ( !rankPlayer.getLadderRanks().isEmpty()) { - for (Map.Entry entry : rankPlayer.getLadderRanks().entrySet()) { + for (Map.Entry entry : rankPlayer.getLadderRanks().entrySet()) { if ( ladderName == null || ladderName != null && entry.getKey().getName().equalsIgnoreCase( ladderName )) { if ( sb.length() > 0 ) { sb.append(" "); } - sb.append(entry.getValue().getName()); + sb.append(entry.getValue().getRank().getName()); } } } @@ -381,7 +399,7 @@ public String getPlayerRankNumber( RankPlayer rankPlayer, String ladderName, StringBuilder sb = new StringBuilder(); if ( !rankPlayer.getLadderRanks().isEmpty()) { - for (Map.Entry entry : rankPlayer.getLadderRanks().entrySet()) { + for (Map.Entry entry : rankPlayer.getLadderRanks().entrySet()) { if ( ladderName == null || ladderName != null && entry.getKey().getName().equalsIgnoreCase( ladderName )) { @@ -389,7 +407,7 @@ public String getPlayerRankNumber( RankPlayer rankPlayer, String ladderName, sb.append(" "); } - int rankNumber = rankNumber(entry.getValue()); + int rankNumber = rankNumber(entry.getValue().getRank()); if ( attribute != null && attribute instanceof PlaceholderAttributeNumberFormat ) { PlaceholderAttributeNumberFormat attributeNF = @@ -430,14 +448,14 @@ public String getPlayerRankTag( RankPlayer rankPlayer, String ladderName ) { StringBuilder sb = new StringBuilder(); if ( !rankPlayer.getLadderRanks().isEmpty()) { - for (Map.Entry entry : rankPlayer.getLadderRanks().entrySet()) { + for (Map.Entry entry : rankPlayer.getLadderRanks().entrySet()) { if ( ladderName == null || ladderName != null && entry.getKey().getName().equalsIgnoreCase( ladderName )) { // if ( sb.length() > 0 ) { // sb.append(" "); // } - sb.append(entry.getValue().getTag()); + sb.append(entry.getValue().getRank().getTag()); } } } @@ -449,8 +467,8 @@ public List getPlayerRanks( RankPlayer rankPlayer ) { List results = new ArrayList<>(); if ( !rankPlayer.getLadderRanks().isEmpty()) { - for (Map.Entry entry : rankPlayer.getLadderRanks().entrySet()) { - results.add( entry.getValue() ); + for (Map.Entry entry : rankPlayer.getLadderRanks().entrySet()) { + results.add( entry.getValue().getRank() ); } } @@ -461,14 +479,14 @@ public List getPlayerNextRanks( RankPlayer rankPlayer ) { List results = new ArrayList<>(); if ( !rankPlayer.getLadderRanks().isEmpty()) { - for (Map.Entry entry : rankPlayer.getLadderRanks().entrySet()) { + for ( RankLadder ladder : rankPlayer.getLadderRanks().keySet() ) { - RankLadder key = entry.getKey(); - if(key.getNext(key.getPositionOfRank(entry.getValue())).isPresent()) { - - Rank nextRank = key.getNext(key.getPositionOfRank(entry.getValue())).get(); - results.add( nextRank ); - } + Rank rank = rankPlayer.getRank( ladder ).getRank(); + if ( rank != null && rank.getRankNext() != null ) { + Rank nextRank = rank.getRankNext(); + + results.add( nextRank ); + } } } @@ -481,24 +499,33 @@ public String getPlayerNextRankCost( RankPlayer rankPlayer, String ladderName, if ( !rankPlayer.getLadderRanks().isEmpty()) { DecimalFormat dFmt = new DecimalFormat("#,##0"); - for (Map.Entry entry : rankPlayer.getLadderRanks().entrySet()) { - RankLadder key = entry.getKey(); + + for ( RankLadder ladder : rankPlayer.getLadderRanks().keySet() ) { + if ( ladderName == null || - ladderName != null && key.getName().equalsIgnoreCase( ladderName )) { + ladderName != null && ladder.getName().equalsIgnoreCase( ladderName )) { - if(key.getNext(key.getPositionOfRank(entry.getValue())).isPresent()) { + PlayerRank pRank = rankPlayer.getRank( ladder ); + if ( pRank != null && pRank.getRank().getRankNext() != null ) { + Rank nextRank = pRank.getRank().getRankNext(); + + // This calculates the target rank, and takes in to consideration the player's existing rank: + PlayerRank nextPRank = PlayerRank.getTargetPlayerRankForPlayer( rankPlayer, nextRank ); + + //PlayerRank nextPRank = new PlayerRank( nextRank, pRank.getRankMultiplier() ); + if ( sb.length() > 0 ) { sb.append(", "); } - double cost = key.getNext(key.getPositionOfRank(entry.getValue())).get().getCost(); + double cost = nextPRank.getRankCost(); - if ( attribute != null && attribute instanceof PlaceholderAttributeNumberFormat ) { - PlaceholderAttributeNumberFormat attributeNF = - (PlaceholderAttributeNumberFormat) attribute; - sb.append( attributeNF.format( cost ) ); - } - else if ( formatted ) { + if ( attribute != null && attribute instanceof PlaceholderAttributeNumberFormat ) { + PlaceholderAttributeNumberFormat attributeNF = + (PlaceholderAttributeNumberFormat) attribute; + sb.append( attributeNF.format( cost ) ); + } + else if ( formatted ) { sb.append( PlaceholdersUtil.formattedMetricSISize( cost )); } else { @@ -507,6 +534,7 @@ else if ( formatted ) { } } } + } return sb.toString(); @@ -515,35 +543,45 @@ else if ( formatted ) { public String getPlayerNextRankCostPercent( RankPlayer rankPlayer, String ladderName ) { StringBuilder sb = new StringBuilder(); - Player prisonPlayer = PrisonAPI.getPlayer(rankPlayer.getUUID()).orElse(null); - if( prisonPlayer == null ) { - - String errorMessage = cannotLoadPlayerFile( rankPlayer.getUUID().toString() ); - - String message = "getPlayerNextRankCostPercent: " + errorMessage; - - if ( !getPlayerErrors().contains( message ) ) { - getPlayerErrors().add( message ); - Output.get().logError( message ); - } - return "0"; - } +// Player prisonPlayer = PrisonAPI.getPlayer(rankPlayer.getUUID()).orElse(null); +// if( prisonPlayer == null ) { +// +// String errorMessage = cannotLoadPlayerFile( rankPlayer.getUUID().toString() ); +// +// String message = "getPlayerNextRankCostPercent: " + errorMessage; +// +// if ( !getPlayerErrors().contains( message ) ) { +// getPlayerErrors().add( message ); +// Output.get().logError( message ); +// } +//// return "0"; +// } if ( !rankPlayer.getLadderRanks().isEmpty()) { DecimalFormat dFmt = new DecimalFormat("#,##0"); - for (Map.Entry entry : rankPlayer.getLadderRanks().entrySet()) { - RankLadder key = entry.getKey(); + + for ( RankLadder ladder : rankPlayer.getLadderRanks().keySet() ) { + if ( ladderName == null || - ladderName != null && key.getName().equalsIgnoreCase( ladderName )) { + ladderName != null && ladder.getName().equalsIgnoreCase( ladderName )) { - if(key.getNext(key.getPositionOfRank(entry.getValue())).isPresent()) { + PlayerRank pRank = rankPlayer.getRank( ladder ); + if ( pRank != null && pRank.getRank().getRankNext() != null ) { + Rank nextRank = pRank.getRank().getRankNext(); + + // This calculates the target rank, and takes in to consideration the player's existing rank: + PlayerRank nextPRank = PlayerRank.getTargetPlayerRankForPlayer( rankPlayer, nextRank ); + +// PlayerRank nextPRank = new PlayerRank( nextRank, pRank.getRankMultiplier() ); + if ( sb.length() > 0 ) { sb.append(", "); } - Rank rank = key.getNext(key.getPositionOfRank(entry.getValue())).get(); - double cost = rank.getCost(); - double balance = getPlayerBalance(prisonPlayer,rank); +// Rank rank = key.getNext(key.getPositionOfRank(entry.getValue())).get(); + double cost = nextPRank.getRankCost(); + double balance = rankPlayer.getBalance( pRank.getRank().getCurrency() ); +// double balance = getPlayerBalance(prisonPlayer,nextRank); double percent = (balance < 0 ? 0 : (cost == 0.0d || balance > cost ? 100.0 : @@ -562,42 +600,52 @@ public String getPlayerNextRankCostBar( RankPlayer rankPlayer, String ladderName PlaceholderAttribute attribute ) { StringBuilder sb = new StringBuilder(); - Player prisonPlayer = PrisonAPI.getPlayer(rankPlayer.getUUID()).orElse(null); - if( prisonPlayer == null ) { - - String errorMessage = cannotLoadPlayerFile( rankPlayer.getUUID().toString() ); - - String message = "getPlayerNextRankCostBar: " + errorMessage; - - if ( !getPlayerErrors().contains( message ) ) { - getPlayerErrors().add( message ); - Output.get().logError( message ); - } - - return "0"; - } +// Player prisonPlayer = PrisonAPI.getPlayer(rankPlayer.getUUID()).orElse(null); +// if( prisonPlayer == null ) { +// +// String errorMessage = cannotLoadPlayerFile( rankPlayer.getUUID().toString() ); +// +// String message = "getPlayerNextRankCostBar: " + errorMessage; +// +// if ( !getPlayerErrors().contains( message ) ) { +// getPlayerErrors().add( message ); +// Output.get().logError( message ); +// } +// +// // return "0"; +// } if ( !rankPlayer.getLadderRanks().isEmpty()) { // DecimalFormat dFmt = new DecimalFormat("#,##0.00"); - for (Map.Entry entry : rankPlayer.getLadderRanks().entrySet()) { - RankLadder key = entry.getKey(); + + for ( RankLadder ladder : rankPlayer.getLadderRanks().keySet() ) { + if ( ladderName == null || - ladderName != null && key.getName().equalsIgnoreCase( ladderName )) { + ladderName != null && ladder.getName().equalsIgnoreCase( ladderName )) { - if(key.getNext(key.getPositionOfRank(entry.getValue())).isPresent()) { + PlayerRank pRank = rankPlayer.getRank( ladder ); + Rank rank = pRank.getRank(); + if ( rank != null && rank.getRankNext() != null ) { + Rank nextRank = rank.getRankNext(); + + // This calculates the target rank, and takes in to consideration the player's existing rank: + PlayerRank nextPRank = PlayerRank.getTargetPlayerRankForPlayer( rankPlayer, nextRank ); + +// PlayerRank nextPRank = new PlayerRank( nextRank, pRank.getRankMultiplier() ); + if ( sb.length() > 0 ) { sb.append(", "); } - Rank rank = key.getNext(key.getPositionOfRank(entry.getValue())).get(); - double cost = rank.getCost(); - double balance = getPlayerBalance(prisonPlayer,rank); + double cost = nextPRank.getRankCost(); + double balance = rankPlayer.getBalance( rank.getCurrency() ); +// double balance = getPlayerBalance(prisonPlayer,nextRank); + + + sb.append( Prison.get().getPlaceholderManager(). + getProgressBar( balance, cost, false, attribute )); - - sb.append( Prison.get().getPlaceholderManager(). - getProgressBar( balance, cost, false, attribute )); - } } } @@ -622,39 +670,49 @@ public String getPlayerNextRankCostRemaining( RankPlayer rankPlayer, String ladd boolean formatted, PlaceholderAttribute attribute ) { StringBuilder sb = new StringBuilder(); - Player prisonPlayer = PrisonAPI.getPlayer(rankPlayer.getUUID()).orElse(null); - if( prisonPlayer == null ) { - - String errorMessage = cannotLoadPlayerFile( rankPlayer.getUUID().toString() ); - - String message = "getPlayerNextRankCostRemaining: " + errorMessage; - - if ( !getPlayerErrors().contains( message ) ) { - getPlayerErrors().add( message ); - Output.get().logError( message ); - } - - return "0"; - } +// Player prisonPlayer = PrisonAPI.getPlayer(rankPlayer.getUUID()).orElse(null); +// if( prisonPlayer == null ) { +// +// String errorMessage = cannotLoadPlayerFile( rankPlayer.getUUID().toString() ); +// +// String message = "getPlayerNextRankCostRemaining: " + errorMessage; +// +// if ( !getPlayerErrors().contains( message ) ) { +// getPlayerErrors().add( message ); +// Output.get().logError( message ); +// } +// +//// return "0"; +// } if ( !rankPlayer.getLadderRanks().isEmpty()) { DecimalFormat dFmt = new DecimalFormat("#,##0"); - for (Map.Entry entry : rankPlayer.getLadderRanks().entrySet()) { - RankLadder key = entry.getKey(); + + for ( RankLadder ladder : rankPlayer.getLadderRanks().keySet() ) { + if ( ladderName == null || - ladderName != null && key.getName().equalsIgnoreCase( ladderName )) { + ladderName != null && ladder.getName().equalsIgnoreCase( ladderName )) { - if(key.getNext(key.getPositionOfRank(entry.getValue())).isPresent()) { + PlayerRank pRank = rankPlayer.getRank( ladder ); + Rank rank = pRank.getRank(); + if ( rank != null && rank.getRankNext() != null ) { + Rank nextRank = rank.getRankNext(); + + // This calculates the target rank, and takes in to consideration the player's existing rank: + PlayerRank nextPRank = PlayerRank.getTargetPlayerRankForPlayer( rankPlayer, nextRank ); + +// PlayerRank nextPRank = new PlayerRank( nextRank, pRank.getRankMultiplier() ); + if ( sb.length() > 0 ) { sb.append(", "); } - Rank rank = key.getNext(key.getPositionOfRank(entry.getValue())).get(); - double cost = rank.getCost(); - double balance = getPlayerBalance(prisonPlayer,rank); + double cost = nextPRank.getRankCost(); + double balance = rankPlayer.getBalance( rank.getCurrency() ); +// double balance = getPlayerBalance(prisonPlayer,nextRank); double remaining = cost - balance; - + // Without the following, if the player has more money than what the rank will cost, // then it would result in a negative amount, which is wrong. // This is cost remaining... once they are able to afford a rankup, then remaining @@ -663,13 +721,13 @@ public String getPlayerNextRankCostRemaining( RankPlayer rankPlayer, String ladd remaining = 0; } - if ( attribute != null && attribute instanceof PlaceholderAttributeNumberFormat ) { - PlaceholderAttributeNumberFormat attributeNF = - (PlaceholderAttributeNumberFormat) attribute; - sb.append( attributeNF.format( remaining ) ); - } - - else if ( formatted ) { + if ( attribute != null && attribute instanceof PlaceholderAttributeNumberFormat ) { + PlaceholderAttributeNumberFormat attributeNF = + (PlaceholderAttributeNumberFormat) attribute; + sb.append( attributeNF.format( remaining ) ); + } + + else if ( formatted ) { sb.append( PlaceholdersUtil.formattedMetricSISize( remaining )); } else { @@ -687,38 +745,48 @@ else if ( formatted ) { public String getPlayerNextRankCostRemainingPercent( RankPlayer rankPlayer, String ladderName ) { StringBuilder sb = new StringBuilder(); - Player prisonPlayer = PrisonAPI.getPlayer(rankPlayer.getUUID()).orElse(null); - if( prisonPlayer == null ) { - - String errorMessage = cannotLoadPlayerFile( rankPlayer.getUUID().toString() ); - - String message = "getPlayerNextRankCostPercent: " + errorMessage; - - if ( !getPlayerErrors().contains( message ) ) { - getPlayerErrors().add( message ); - Output.get().logError( message ); - } - return "0"; - } +// Player prisonPlayer = PrisonAPI.getPlayer(rankPlayer.getUUID()).orElse(null); +// if( prisonPlayer == null ) { +// +// String errorMessage = cannotLoadPlayerFile( rankPlayer.getUUID().toString() ); +// +// String message = "getPlayerNextRankCostPercent: " + errorMessage; +// +// if ( !getPlayerErrors().contains( message ) ) { +// getPlayerErrors().add( message ); +// Output.get().logError( message ); +// } +//// return "0"; +// } if ( !rankPlayer.getLadderRanks().isEmpty()) { DecimalFormat dFmt = new DecimalFormat("#,##0"); - for (Map.Entry entry : rankPlayer.getLadderRanks().entrySet()) { - RankLadder key = entry.getKey(); - if ( ladderName == null || - ladderName != null && key.getName().equalsIgnoreCase( ladderName )) { - - if(key.getNext(key.getPositionOfRank(entry.getValue())).isPresent()) { - if ( sb.length() > 0 ) { - sb.append(", "); - } - - Rank rank = key.getNext(key.getPositionOfRank(entry.getValue())).get(); - double cost = rank.getCost(); - double balance = getPlayerBalance(prisonPlayer,rank); - - double remaining = cost - balance; - + + for ( RankLadder ladder : rankPlayer.getLadderRanks().keySet() ) { + + if ( ladderName == null || + ladderName != null && ladder.getName().equalsIgnoreCase( ladderName )) { + + PlayerRank pRank = rankPlayer.getRank( ladder ); + Rank rank = pRank.getRank(); + if ( rank != null && rank.getRankNext() != null ) { + Rank nextRank = rank.getRankNext(); + + // This calculates the target rank, and takes in to consideration the player's existing rank: + PlayerRank nextPRank = PlayerRank.getTargetPlayerRankForPlayer( rankPlayer, nextRank ); + +// PlayerRank nextPRank = new PlayerRank( nextRank, pRank.getRankMultiplier() ); + + if ( sb.length() > 0 ) { + sb.append(", "); + } + + double cost = nextPRank.getRankCost(); + double balance = rankPlayer.getBalance( rank.getCurrency() ); +// double balance = getPlayerBalance(prisonPlayer,nextRank); + + double remaining = cost - balance; + // Without the following, if the player has more money than what the rank will cost, // then it would result in a negative amount, which is wrong. // This is cost remaining... once they are able to afford a rankup, then remaining @@ -726,55 +794,66 @@ public String getPlayerNextRankCostRemainingPercent( RankPlayer rankPlayer, Stri if ( remaining < 0 ) { remaining = 0; } - double percent = (remaining < 0 ? 0.0 : - (cost == 0.0d || remaining > cost ? 100.0 : - remaining / cost * 100.0 ) - ); - sb.append( dFmt.format( percent )); - } - } - } + double percent = (remaining < 0 ? 0.0 : + (cost == 0.0d || remaining > cost ? 100.0 : + remaining / cost * 100.0 ) + ); + sb.append( dFmt.format( percent )); + } + } + } } return sb.toString(); } public String getPlayerNextRankCostRemainingBar( RankPlayer rankPlayer, String ladderName, - PlaceholderAttribute attribute ) { + PlaceholderAttribute attribute ) { StringBuilder sb = new StringBuilder(); - - Player prisonPlayer = PrisonAPI.getPlayer(rankPlayer.getUUID()).orElse(null); - if( prisonPlayer == null ) { - - String errorMessage = cannotLoadPlayerFile( rankPlayer.getUUID().toString() ); - - String message = "getPlayerNextRankCostPercent: " + errorMessage; - - if ( !getPlayerErrors().contains( message ) ) { - getPlayerErrors().add( message ); - Output.get().logError( message ); - } - return "0"; - } - + +// Player prisonPlayer = PrisonAPI.getPlayer(rankPlayer.getUUID()).orElse(null); +// if( prisonPlayer == null ) { +// +// String errorMessage = cannotLoadPlayerFile( rankPlayer.getUUID().toString() ); +// +// String message = "getPlayerNextRankCostPercent: " + errorMessage; +// +// if ( !getPlayerErrors().contains( message ) ) { +// getPlayerErrors().add( message ); +// Output.get().logError( message ); +// } +//// return "0"; +// } + if ( !rankPlayer.getLadderRanks().isEmpty()) { -// DecimalFormat dFmt = new DecimalFormat("#,##0"); - for (Map.Entry entry : rankPlayer.getLadderRanks().entrySet()) { - RankLadder key = entry.getKey(); + // DecimalFormat dFmt = new DecimalFormat("#,##0"); + + for ( RankLadder ladder : rankPlayer.getLadderRanks().keySet() ) { + if ( ladderName == null || - ladderName != null && key.getName().equalsIgnoreCase( ladderName )) { - - if(key.getNext(key.getPositionOfRank(entry.getValue())).isPresent()) { + ladderName != null && ladder.getName().equalsIgnoreCase( ladderName )) { + + PlayerRank pRank = rankPlayer.getRank( ladder ); + Rank rank = pRank.getRank(); + if ( rank != null && rank.getRankNext() != null ) { + + Rank nextRank = rank.getRankNext(); + + // This calculates the target rank, and takes in to consideration the player's existing rank: + PlayerRank nextPRank = PlayerRank.getTargetPlayerRankForPlayer( rankPlayer, nextRank ); + +// PlayerRank nextPRank = new PlayerRank( nextRank, pRank.getRankMultiplier() ); + if ( sb.length() > 0 ) { sb.append(", "); } - - Rank rank = key.getNext(key.getPositionOfRank(entry.getValue())).get(); - double cost = rank.getCost(); - double balance = getPlayerBalance(prisonPlayer,rank); - + + double cost = nextPRank.getRankCost(); + double balance = rankPlayer.getBalance( rank.getCurrency() ); +// double balance = getPlayerBalance(prisonPlayer,nextRank); + double remaining = cost - balance; - + // Without the following, if the player has more money than what the rank will cost, // then it would result in a negative amount, which is wrong. // This is cost remaining... once they are able to afford a rankup, then remaining @@ -782,19 +861,21 @@ public String getPlayerNextRankCostRemainingBar( RankPlayer rankPlayer, String l if ( remaining < 0 ) { remaining = 0; } -// double percent = (remaining < 0 ? 0.0 : -// (cost == 0.0d || remaining > cost ? 100.0 : -// remaining / cost * 100.0 ) -// ); -// sb.append( dFmt.format( percent )); - + // double percent = (remaining < 0 ? 0.0 : + // (cost == 0.0d || remaining > cost ? 100.0 : + // remaining / cost * 100.0 ) + // ); + // sb.append( dFmt.format( percent )); + sb.append( Prison.get().getPlaceholderManager(). - getProgressBar( remaining, cost, false, attribute )); + getProgressBar( remaining, cost, false, attribute )); } + } } + } - + return sb.toString(); } @@ -814,43 +895,46 @@ private String getPlayerBalance( RankPlayer rankPlayer, String ladderName, boolean formatted, PlaceholderAttribute attribute ) { StringBuilder sb = new StringBuilder(); - Player prisonPlayer = PrisonAPI.getPlayer(rankPlayer.getUUID()).orElse(null); - if( prisonPlayer == null ) { - - String errorMessage = cannotLoadPlayerFile( rankPlayer.getUUID().toString() ); - - String message = "getPlayerBalance: " + errorMessage; - - if ( !getPlayerErrors().contains( message ) ) { - getPlayerErrors().add( message ); - Output.get().logError( message ); - } - - return "0"; - } +// Player prisonPlayer = PrisonAPI.getPlayer(rankPlayer.getUUID()).orElse(null); +// if( prisonPlayer == null ) { +// +// String errorMessage = cannotLoadPlayerFile( rankPlayer.getUUID().toString() ); +// +// String message = "getPlayerBalance: " + errorMessage; +// +// if ( !getPlayerErrors().contains( message ) ) { +// getPlayerErrors().add( message ); +// Output.get().logError( message ); +// } +// +//// return "0"; +// } if ( !rankPlayer.getLadderRanks().isEmpty()) { DecimalFormat dFmt = new DecimalFormat("#,##0"); - for (Map.Entry entry : rankPlayer.getLadderRanks().entrySet()) { - RankLadder key = entry.getKey(); + + for ( RankLadder ladder : rankPlayer.getLadderRanks().keySet() ) { + if ( ladderName == null || - ladderName != null && key.getName().equalsIgnoreCase( ladderName )) { + ladderName != null && ladder.getName().equalsIgnoreCase( ladderName )) { - if(key.getNext(key.getPositionOfRank(entry.getValue())).isPresent()) { + PlayerRank pRank = rankPlayer.getRank( ladder ); + Rank rank = pRank.getRank(); + if ( rank != null ) { if ( sb.length() > 0 ) { sb.append(", "); } - Rank rank = key.getNext(key.getPositionOfRank(entry.getValue())).get(); - double balance = getPlayerBalance(prisonPlayer,rank); + double balance = rankPlayer.getBalance( rank.getCurrency() ); +// double balance = getPlayerBalance(prisonPlayer,rank); - if ( attribute != null && attribute instanceof PlaceholderAttributeNumberFormat ) { - PlaceholderAttributeNumberFormat attributeNF = - (PlaceholderAttributeNumberFormat) attribute; - sb.append( attributeNF.format( balance ) ); - } - - else if ( formatted ) { + if ( attribute != null && attribute instanceof PlaceholderAttributeNumberFormat ) { + PlaceholderAttributeNumberFormat attributeNF = + (PlaceholderAttributeNumberFormat) attribute; + sb.append( attributeNF.format( balance ) ); + } + + else if ( formatted ) { sb.append( PlaceholdersUtil.formattedMetricSISize( balance )); } else { @@ -863,74 +947,111 @@ else if ( formatted ) { return sb.toString(); } - - /** - *

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

- * - * @param player - * @param rank - * @return - */ - private double getPlayerBalance(Player player, Rank rank) { - double playerBalance = 0; - - if ( rank != null && rank.getCurrency() != null ) { - EconomyCurrencyIntegration currencyEcon = PrisonAPI.getIntegrationManager() - .getEconomyForCurrency( rank.getCurrency() ); - if ( currencyEcon != null ) { - playerBalance = currencyEcon.getBalance( player, rank.getCurrency() ); - } else { - - String errorMessage = cannotLoadEconomyCurrency( player.getName(), rank.getCurrency() ); - - if ( !getPlayerErrors().contains( errorMessage ) ) { - getPlayerErrors().add( errorMessage ); - Output.get().logError( errorMessage ); - } - - } + private String getPlayerAverageEarningsPerMinute( RankPlayer rankPlayer, String ladderName, + boolean formatted, PlaceholderAttribute attribute ) { + StringBuilder sb = new StringBuilder(); + + + if ( !rankPlayer.getLadderRanks().isEmpty()) { + DecimalFormat dFmt = new DecimalFormat("#,##0"); - } else { + double epm = PlayerCache.getInstance().getPlayerEarningsPerMinute( rankPlayer ); - EconomyIntegration economy = PrisonAPI.getIntegrationManager().getEconomy(); - - if ( economy != null ) { - playerBalance = economy.getBalance( player ); - } else { - - String errorMessage = cannotLoadEconomy( player.getName() ); - - if ( !getPlayerErrors().contains( errorMessage ) ) { - - getPlayerErrors().add( errorMessage ); - Output.get().logError( errorMessage ); - } - + if ( attribute != null && attribute instanceof PlaceholderAttributeNumberFormat ) { + PlaceholderAttributeNumberFormat attributeNF = + (PlaceholderAttributeNumberFormat) attribute; + sb.append( attributeNF.format( epm ) ); + } + + else if ( formatted ) { + sb.append( PlaceholdersUtil.formattedMetricSISize( epm )); + } + else { + sb.append( dFmt.format( epm )); } + } - - return playerBalance; + + return sb.toString(); } + + + +// /** +// *

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

+// * +// * @param player +// * @param rank +// * @return +// */ +// public double getPlayerBalance(Player player, Rank rank) { +// double playerBalance = 0; +// +// if ( player != null ) { +// +// if ( rank != null && rank.getCurrency() != null ) { +// EconomyCurrencyIntegration currencyEcon = PrisonAPI.getIntegrationManager() +// .getEconomyForCurrency( rank.getCurrency() ); +// if ( currencyEcon != null ) { +// playerBalance = currencyEcon.getBalance( player, rank.getCurrency() ); +// } else { +// +// String errorMessage = cannotLoadEconomyCurrency( player.getName(), rank.getCurrency() ); +// +// if ( !getPlayerErrors().contains( errorMessage ) ) { +// getPlayerErrors().add( errorMessage ); +// Output.get().logError( errorMessage ); +// } +// +// } +// +// } else { +// +// EconomyIntegration economy = PrisonAPI.getIntegrationManager().getEconomy(); +// +// if ( economy != null ) { +// playerBalance = economy.getBalance( player ); +// } else { +// +// String errorMessage = cannotLoadEconomy( player.getName() ); +// +// if ( !getPlayerErrors().contains( errorMessage ) ) { +// +// getPlayerErrors().add( errorMessage ); +// Output.get().logError( errorMessage ); +// } +// +// } +// } +// } +// +// return playerBalance; +// } public String getPlayerNextRankName( RankPlayer rankPlayer, String ladderName ) { StringBuilder sb = new StringBuilder(); if ( !rankPlayer.getLadderRanks().isEmpty()) { - for (Map.Entry entry : rankPlayer.getLadderRanks().entrySet()) { - RankLadder key = entry.getKey(); + for ( RankLadder ladder : rankPlayer.getLadderRanks().keySet() ) { + if ( ladderName == null || - ladderName != null && key.getName().equalsIgnoreCase( ladderName )) { - - if(key.getNext(key.getPositionOfRank(entry.getValue())).isPresent()) { - if ( sb.length() > 0 ) { - sb.append(" "); - } - sb.append(key.getNext(key.getPositionOfRank(entry.getValue())).get().getName()); - } + ladderName != null && ladder.getName().equalsIgnoreCase( ladderName )) { + + PlayerRank pRank = rankPlayer.getRank( ladder ); + Rank rank = pRank.getRank(); + + if ( rank != null && rank.getRankNext() != null ) { + Rank nextRank = rank.getRankNext(); + + if ( sb.length() > 0 ) { + sb.append(" "); + } + sb.append( nextRank.getName( )); + } } } } @@ -942,21 +1063,40 @@ public String getPlayerNextRankTag( RankPlayer rankPlayer, String ladderName ) { StringBuilder sb = new StringBuilder(); if ( !rankPlayer.getLadderRanks().isEmpty()) { - for (Map.Entry entry : rankPlayer.getLadderRanks().entrySet()) { - RankLadder key = entry.getKey(); + + for ( RankLadder ladder : rankPlayer.getLadderRanks().keySet() ) { + if ( ladderName == null || - ladderName != null && key.getName().equalsIgnoreCase( ladderName )) { - - if(key.getNext(key.getPositionOfRank(entry.getValue())).isPresent()) { + ladderName != null && ladder.getName().equalsIgnoreCase( ladderName )) { + + PlayerRank pRank = rankPlayer.getRank( ladder ); + Rank rank = pRank.getRank(); + if ( rank != null && rank.getRankNext() != null ) { + Rank nextRank = rank.getRankNext(); + // if ( sb.length() > 0 ) { // sb.append(", "); // } - sb.append(key.getNext(key.getPositionOfRank(entry.getValue())).get().getTag()); - } + + sb.append( nextRank.getTag() ); + } } } } + + // NOTE: Only for the last rank on the default ladder, use the text value + // from the language file to display in the place of the empty tag. + // The idea is that if prestiges is enabled, then this is a way to + // indicate the player could prestige as the next step. + if ( sb.length() == 0 && "default".equalsIgnoreCase( ladderName ) ) { + String replacementText = lastRankMessageForDefaultLadder(); + if ( replacementText != null && !replacementText.trim().isEmpty() ) { + + sb.append( replacementText ); + } + } + return sb.toString(); } @@ -1087,6 +1227,21 @@ public String getTranslatePlayerPlaceHolder( UUID playerUuid, String playerName, results = getPlayerRankTag( rankPlayer, ladderName ); break; + case prison_rank_ladder_position: + case prison_rlp: + case prison_rank_ladder_position_laddername: + case prison_rlp_laddername: + { + // rank may be null: + PlayerRank pRank = rankPlayer.getRank( ladderName ); + if ( pRank != null ) { + Rank rank = pRank.getRank(); + + results = rank == null ? "" : Integer.toString( rank.getPosition() ); + } + } + break; + case prison_rc: case prison_rankup_cost: case prison_rc_laddername: @@ -1166,11 +1321,251 @@ public String getTranslatePlayerPlaceHolder( UUID playerUuid, String playerName, results = getPlayerBalance( rankPlayer, ladderName, false, attribute ); break; + case prison_pb_epm: + case prison_player_balance_earnings_per_minute: + + results = getPlayerAverageEarningsPerMinute( rankPlayer, ladderName, false, attribute ); + break; + + case prison_pb_epmf: + case prison_player_balance_earnings_per_minute_formatted: + + results = getPlayerAverageEarningsPerMinute( rankPlayer, ladderName, true, attribute ); + break; + case prison_psm: case prison_player_sellall_multiplier: results = getPlayerSellallMultiplier( rankPlayer, attribute ); break; + + + + case prison_player_tool_id: + case prison_ptid: + { + + PlayerUtil pUtil = Prison.get().getPlatform().getPlayerUtil( playerUuid ); + results = pUtil.getItemInHandDisplayID(); + } + break; + + case prison_player_tool_name: + case prison_ptn: + { + + PlayerUtil pUtil = Prison.get().getPlatform().getPlayerUtil( playerUuid ); + results = pUtil.getItemInHandDisplayName(); + } + break; + + case prison_player_tool_material_type: + case prison_ptmt: + { + PlayerUtil pUtil = Prison.get().getPlatform().getPlayerUtil( playerUuid ); + results = pUtil.getItemInHandItemMaterial(); + } + break; + + case prison_player_tool_type: + case prison_ptt: + { + PlayerUtil pUtil = Prison.get().getPlatform().getPlayerUtil( playerUuid ); + results = pUtil.getItemInHandItemType(); + } + break; + + case prison_player_tool_data: + case prison_ptdata: + + break; + + case prison_player_tool_lore: + case prison_ptlore: + + break; + + + case prison_player_tool_durability_used: + case prison_ptdu: + { + PlayerUtil pUtil = Prison.get().getPlatform().getPlayerUtil( playerUuid ); + results = Integer.toString( pUtil.getItemInHandDurabilityUsed() ); + } + break; + + case prison_player_tool_durability_max: + case prison_ptdm: + { + PlayerUtil pUtil = Prison.get().getPlatform().getPlayerUtil( playerUuid ); + results = Integer.toString( pUtil.getItemInHandDurabilityMax() ); + } + break; + + case prison_player_tool_durability_remaining: + case prison_ptdr: + { + PlayerUtil pUtil = Prison.get().getPlatform().getPlayerUtil( playerUuid ); + results = Integer.toString( pUtil.getItemInHandDurabilityRemaining() ); + } + break; + case prison_player_tool_durability_percent: + case prison_ptdp: + { + PlayerUtil pUtil = Prison.get().getPlatform().getPlayerUtil( playerUuid ); + results = Double.toString( pUtil.getItemInHandDurabilityPercent() ); + } + break; + case prison_player_tool_durability_bar: + case prison_ptdb: + { + PlayerUtil pUtil = Prison.get().getPlatform().getPlayerUtil( playerUuid ); + + int max = pUtil.getItemInHandDurabilityMax(); + int used = pUtil.getItemInHandDurabilityUsed(); + + results = Prison.get().getPlaceholderManager(). + getProgressBar( used, max, false, attribute ); + } + break; + + case prison_player_tool_enchantment_fortune: + case prison_ptef: + { + PlayerUtil pUtil = Prison.get().getPlatform().getPlayerUtil( playerUuid ); + results = Integer.toString( pUtil.getItemInHandEnchantmentFortune() ); + } + break; + + case prison_player_tool_enchantment_efficency: + case prison_ptee: + { + PlayerUtil pUtil = Prison.get().getPlatform().getPlayerUtil( playerUuid ); + results = Integer.toString( pUtil.getItemInHandEnchantmentEfficency() ); + } + break; + + case prison_player_tool_enchantment_silktouch: + case prison_ptes: + { + PlayerUtil pUtil = Prison.get().getPlatform().getPlayerUtil( playerUuid ); + results = Integer.toString( pUtil.getItemInHandEnchantmentSilkTouch() ); + } + break; + + case prison_player_tool_enchantment_unbreaking: + case prison_pteu: + { + PlayerUtil pUtil = Prison.get().getPlatform().getPlayerUtil( playerUuid ); + results = Integer.toString( pUtil.getItemInHandEnchantmentUnbreaking() ); + } + break; + + case prison_player_tool_enchantment_luck: + case prison_ptel: + { + PlayerUtil pUtil = Prison.get().getPlatform().getPlayerUtil( playerUuid ); + results = Integer.toString( pUtil.getItemInHandEnchantmentLuck() ); + } + break; + + case prison_player_tool_enchantment_mending: + case prison_ptem: + { + PlayerUtil pUtil = Prison.get().getPlatform().getPlayerUtil( playerUuid ); + results = Integer.toString( pUtil.getItemInHandEnchantmentMending() ); + } + break; + + case prison_player_health: + case prison_ph: + { + PlayerUtil pUtil = Prison.get().getPlatform().getPlayerUtil( playerUuid ); + results = Double.toString( pUtil.getHealth() ); + } + break; + + case prison_player_health_max: + case prison_phm: + { + PlayerUtil pUtil = Prison.get().getPlatform().getPlayerUtil( playerUuid ); + results = Double.toString( pUtil.getMaxHealth() ); + } + break; + + case prison_player_air_max: + case prison_pam: + { + PlayerUtil pUtil = Prison.get().getPlatform().getPlayerUtil( playerUuid ); + results = Integer.toString( pUtil.getMaximumAir() ); + } + break; + + case prison_player_air_remaining: + case prison_par: + { + PlayerUtil pUtil = Prison.get().getPlatform().getPlayerUtil( playerUuid ); + results = Integer.toString( pUtil.getRemainingAir() ); + } + break; + + case prison_player_food_level: + case prison_pfl: + { + PlayerUtil pUtil = Prison.get().getPlatform().getPlayerUtil( playerUuid ); + results = Integer.toString( pUtil.getFoodLevel() ); + } + break; + + case prison_player_food_exhaustion: + case prison_pfe: + { + PlayerUtil pUtil = Prison.get().getPlatform().getPlayerUtil( playerUuid ); + results = Double.toString( pUtil.getFoodExhaustion() ); + } + break; + + case prison_player_food_saturation: + case prison_pfs: + { + PlayerUtil pUtil = Prison.get().getPlatform().getPlayerUtil( playerUuid ); + results = Double.toString( pUtil.getFoodSaturation() ); + } + break; + + case prison_player_level: + case prison_pl: + { + PlayerUtil pUtil = Prison.get().getPlatform().getPlayerUtil( playerUuid ); + results = Integer.toString( pUtil.getLevel() ); + } + break; + + case prison_player_walk_speed: + case prison_pws: + { + PlayerUtil pUtil = Prison.get().getPlatform().getPlayerUtil( playerUuid ); + results = Double.toString( pUtil.getWalkSpeed() ); + } + break; + + case prison_player_xp: + case prison_pxp: + { + PlayerUtil pUtil = Prison.get().getPlatform().getPlayerUtil( playerUuid ); + results = Double.toString( pUtil.getExp() ); + } + break; + + case prison_player_xp_to_level: + case prison_pxptl: + { + PlayerUtil pUtil = Prison.get().getPlatform().getPlayerUtil( playerUuid ); + results = Double.toString( pUtil.getExpToLevel() ); + } + break; + + default: break; } @@ -1194,7 +1589,7 @@ public List getTranslatedPlaceHolderKeys() { translatedPlaceHolderKeys = new ArrayList<>(); // This generates all of the placeholders for the player ranks: - List placeHolders = PrisonPlaceHolders.getTypes( PlaceHolderFlags.PLAYER ); + List placeHolders = PrisonPlaceHolders.getTypes( PlaceholderFlags.PLAYER ); for ( PrisonPlaceHolders ph : placeHolders ) { PlaceHolderKey placeholder = new PlaceHolderKey(ph.name(), ph ); if ( ph.getAlias() != null ) { @@ -1215,7 +1610,7 @@ public List getTranslatedPlaceHolderKeys() { // This generates all of the placeholders for the ladders: - placeHolders = PrisonPlaceHolders.getTypes( PlaceHolderFlags.LADDERS ); + placeHolders = PrisonPlaceHolders.getTypes( PlaceholderFlags.LADDERS ); List ladders = PrisonRanks.getInstance().getLadderManager().getLadders(); for ( RankLadder ladder : ladders ) { diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManagerMessages.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManagerMessages.java index 974716a49..03a075179 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManagerMessages.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/PlayerManagerMessages.java @@ -78,6 +78,15 @@ protected String cannotLoadEconomy( String playerName ) { .localize(); } + + protected String lastRankMessageForDefaultLadder() { + + return PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_playerManager__last_rank_message_for__" + + "prison_rankup_rank_tag_default" ) + .localize(); + } + diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/RankManager.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/RankManager.java index 70c9267d7..c2d93b33c 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/RankManager.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/managers/RankManager.java @@ -23,7 +23,7 @@ import java.util.List; import java.util.Optional; import java.util.TreeMap; -import java.util.stream.Collectors; +import java.util.UUID; import tech.mcprison.prison.Prison; import tech.mcprison.prison.PrisonAPI; @@ -38,7 +38,7 @@ import tech.mcprison.prison.placeholders.PlaceholderAttributeNumberFormat; import tech.mcprison.prison.placeholders.PlaceholderAttributeText; import tech.mcprison.prison.placeholders.PlaceholderManager; -import tech.mcprison.prison.placeholders.PlaceholderManager.PlaceHolderFlags; +import tech.mcprison.prison.placeholders.PlaceholderManager.PlaceholderFlags; import tech.mcprison.prison.placeholders.PlaceholderManager.PrisonPlaceHolders; import tech.mcprison.prison.placeholders.PlaceholdersUtil; import tech.mcprison.prison.ranks.PrisonRanks; @@ -46,9 +46,11 @@ import tech.mcprison.prison.ranks.commands.LadderCommands; import tech.mcprison.prison.ranks.commands.RankUpCommand; import tech.mcprison.prison.ranks.commands.RanksCommands; +import tech.mcprison.prison.ranks.data.PlayerRank; import tech.mcprison.prison.ranks.data.Rank; import tech.mcprison.prison.ranks.data.RankLadder; import tech.mcprison.prison.ranks.data.RankPlayer; +import tech.mcprison.prison.ranks.data.StatsRankPlayerBalanceData; import tech.mcprison.prison.store.Collection; import tech.mcprison.prison.store.Document; @@ -127,9 +129,6 @@ public RankManager(Collection collection) { this.ranksById = new TreeMap<>(); } - /* - * Methods & Getters & Setters - */ private void addRank( Rank rank ) { if ( rank != null ) { @@ -137,6 +136,10 @@ private void addRank( Rank rank ) { String rankName = rank.getName(); getRanksByName().put( rankName.toLowerCase(), rank ); getRanksById().put( rank.getId(), rank ); + + // Do not have to reset position number since the new rank is + // added to the end of the ladder's rank List, and therefore + // no other rank is impacted. } } @@ -145,11 +148,26 @@ private void removeRankFromCollections( Rank rank ) { getLoadedRanks().remove( rank ); getRanksByName().remove( rank.getName().toLowerCase() ); getRanksById().remove( rank.getId() ); + + // Since the removal of a rank could shift the position of + // more than one rank, then all positions should be reset. + + resetRankPositions( rank ); } } + private void resetRankPositions( Rank rank ) { + + if ( rank != null && rank.getLadder() != null ) { + + for ( Rank r : rank.getLadder().getRanks() ) { + r.resetPosition(); + } + } + } + /** * Loads a rank from a file into the loaded ranks list. @@ -225,14 +243,11 @@ public void saveRanks() { */ public Optional createRank(String name, String tag, double cost) { - int position = getRanks().size(); - // Set the default values... - Rank newRank = new Rank( position, getNextAvailableId(), name, tag, cost ); + Rank newRank = new Rank( getNextAvailableId(), name, tag, cost ); // ... add it to the list... addRank(newRank); -// loadedRanks.add(newRank); // // Reset the rank relationships: // connectRanks(); @@ -326,43 +341,51 @@ public boolean removeRank(Rank rank) { } - final boolean[] success = {true}; - for (RankLadder ladder : PrisonRanks.getInstance().getLadderManager() - .getLaddersWithRank(rank.getId())) { + boolean success = true; + + RankLadder ladder = rank.getLadder(); + +// for (RankLadder ladder : PrisonRanks.getInstance().getLadderManager() .getLadder( rank )) + { // Move each player in this ladder to the new rank PrisonRanks.getInstance().getPlayerManager().getPlayers().forEach(rankPlayer -> { - Rank curRank = rankPlayer.getRank(ladder.getName()); - if ( curRank != null && rank.equals( curRank ) ) { - rankPlayer.removeRank(curRank); - if ( newRank != null ) { - rankPlayer.addRank(newRank); - } - - try { - PrisonRanks.getInstance().getPlayerManager().savePlayer(rankPlayer); - } catch (IOException e) { - Localizable localManagerLog = PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( "ranks_rankManager__cannot_save_player_file" ); - - Output.get().logError( localManagerLog.localize() ); - } - - Localizable localManagerLog = PrisonRanks.getInstance().getRanksMessages() - .getLocalizable( "ranks_rankManager__cannot_save_player_file" ) - .withReplacements( - rankPlayer.getName(), - newRank.getName() ); - PrisonAPI.debug( localManagerLog.localize() ); - } + PlayerRank pRank = rankPlayer.getRank(ladder); + if ( pRank != null && pRank.getRank() != null ) { + + Rank curRank = pRank.getRank(); + if ( curRank != null && rank.equals( curRank ) ) { + rankPlayer.removeRank(curRank); + if ( newRank != null ) { + rankPlayer.addRank(newRank); + } + + PrisonRanks.getInstance().getPlayerManager().savePlayer(rankPlayer); +// try { +// } catch (IOException e) { +// Localizable localManagerLog = PrisonRanks.getInstance().getRanksMessages() +// .getLocalizable( "ranks_rankManager__cannot_save_player_file" ); +// +// Output.get().logError( localManagerLog.localize() ); +// } + + Localizable localManagerLog = PrisonRanks.getInstance().getRanksMessages() + .getLocalizable( "ranks_rankManager__cannot_save_player_file" ) + .withReplacements( + rankPlayer.getName(), + newRank.getName() ); + PrisonAPI.debug( localManagerLog.localize() ); + } + } }); // ... remove it from each ladder it was in... - ladder.removeRank(ladder.getPositionOfRank(rank)); + ladder.removeRank( rank ); +// ladder.removeRank(ladder.getPositionOfRank(rank)); if ( !PrisonRanks.getInstance().getLadderManager().save(ladder) ) { - success[0] = false; + success = false; Localizable localManagerLog = PrisonRanks.getInstance().getRanksMessages() .getLocalizable( "ranks_rankManager__cannot_save_ladder_file" ) @@ -373,20 +396,19 @@ public boolean removeRank(Rank rank) { } - if(!success[0]) { - return false; - } + if( success ) { - // Remove it from the list... - removeRankFromCollections( rank ); -// loadedRanks.remove(rank); - -// // Reset the rank relationships: -// connectRanks(); + // Remove it from the list... + removeRankFromCollections( rank ); + + // Reset the rank relationships: + // connectRanks(); + + // ... and remove the rank's save files. + collection.delete(rank.filename()); + } - // ... and remove the rank's save files. - collection.delete(rank.filename()); - return true; + return success; } // /** @@ -497,16 +519,18 @@ public void identifyAllRankCurrencies( List prisonStartupDetails ) { public String listAllRanks( String ladderName, List ranks, RanksByLadderOptions option ) { StringBuilder sb = new StringBuilder(); - PlayerManager playerManager = PrisonRanks.getInstance().getPlayerManager(); +// PlayerManager playerManager = PrisonRanks.getInstance().getPlayerManager(); for (Rank rank : ranks ) { + int players = rank.getPlayers().size(); + // Get the players per rank!! - List playersList = - playerManager.getPlayers().stream() - .filter(rankPlayer -> rankPlayer.getLadderRanks().values().contains(rank)) - .collect(Collectors.toList()); - int players = playersList.size(); +// List playersList = +// playerManager.getPlayers().stream() +// .filter(rankPlayer -> rankPlayer.getLadderRanks().values().contains(rank)) +// .collect(Collectors.toList()); +// int players = playersList.size(); if ( option == RanksByLadderOptions.allRanks || option == RanksByLadderOptions.full || players > 0 ) { @@ -524,7 +548,7 @@ public String listAllRanks( String ladderName, List ranks, RanksByLadderOp if ( option == RanksByLadderOptions.full ) { sb.append( "[" ); - for ( RankPlayer rankPlayer : playersList ) + for ( RankPlayer rankPlayer : rank.getPlayers() ) { if ( rankPlayer.getName() != null ) { @@ -616,7 +640,7 @@ private void rankByLadderOutput( CommandSender sender, String ranksByLadder ) { private String getRankCost( Rank rank, PlaceholderAttribute attribute, boolean formatted ) { - double cost = rank.getCost(); + double cost = PlayerRank.getRawRankCost( rank ); String resultsx = null; DecimalFormat dFmt = new DecimalFormat("#,##0"); @@ -635,8 +659,67 @@ else if ( formatted ) { } + public String getTranslateRankPlayersPlaceHolder( UUID playerUuid, String playerName, String identifier ) { + String results = null; + + if ( playerUuid != null && identifier != null ) { + + List placeHolderKeys = getTranslatedPlaceHolderKeys(); + + identifier = identifier.toLowerCase(); + + if ( !identifier.startsWith( PlaceholderManager.PRISON_PLACEHOLDER_PREFIX_EXTENDED )) { + identifier = PlaceholderManager.PRISON_PLACEHOLDER_PREFIX_EXTENDED + identifier; + } + + // placeholder Attributes: + PlaceholderManager pman = Prison.get().getPlaceholderManager(); + String placeholder = pman.extractPlaceholderString( identifier ); + PlaceholderAttribute attribute = pman.extractPlaceholderExtractAttribute( identifier ); + + for ( PlaceHolderKey placeHolderKey : placeHolderKeys ) { + if ( placeHolderKey.getKey().equalsIgnoreCase( placeholder )) { + results = getTranslateRankPlayersPlaceHolder( playerUuid, playerName, placeHolderKey, attribute ); + break; + } + } + } + + return results; + } + + public String getTranslateRanksPlaceHolder( String identifier ) { + String results = null; + List placeHolderKeys = getTranslatedPlaceHolderKeys(); + + if ( !identifier.startsWith( PlaceholderManager.PRISON_PLACEHOLDER_PREFIX_EXTENDED )) { + identifier = PlaceholderManager.PRISON_PLACEHOLDER_PREFIX_EXTENDED + identifier; + } + + // placeholder Attributes: + PlaceholderManager pman = Prison.get().getPlaceholderManager(); + String placeholder = pman.extractPlaceholderString( identifier ); + //PlaceholderAttribute attribute = pman.extractPlaceholderExtractAttribute( identifier ); + + for ( PlaceHolderKey placeHolderKey : placeHolderKeys ) { + if ( placeHolderKey.getKey().equalsIgnoreCase( placeholder )) { + + //Mine mine = getMine( placeHolderKey.getData() ); + + results = getTranslateRanksPlaceHolder( placeHolderKey, identifier ); + break; + } + } + + return results; + } + public String getTranslateRanksPlaceHolder( PlaceHolderKey placeHolderKey, String identifier ) { String results = null; + + if ( identifier == null ) { + identifier = placeHolderKey.getKey(); + } if ( placeHolderKey != null && identifier != null ) { @@ -666,6 +749,8 @@ public String getTranslateRanksPlaceHolder( PlaceHolderKey placeHolderKey, PrisonPlaceHolders placeHolder = placeHolderKey.getPlaceholder(); + DecimalFormat dFmt = new DecimalFormat("#,##0"); + if ( rank != null ) { switch ( placeHolder ) { @@ -683,10 +768,13 @@ public String getTranslateRanksPlaceHolder( PlaceHolderKey placeHolderKey, case prison_rank__ladder_rankname: case prison_r_l_rankname: - results = rank.getLadder().getName(); + results = rank.getLadder() == null ? "" : rank.getLadder().getName(); break; - + case prison_rank__ladder_position_rankname: + case prison_r_lp_rankname: + results = Integer.toString( rank.getPosition() ); + break; case prison_rank__cost_rankname: case prison_r_c_rankname: @@ -698,6 +786,12 @@ public String getTranslateRanksPlaceHolder( PlaceHolderKey placeHolderKey, results = getRankCost( rank, attribute, true ); break; + case prison_rank__cost_multiplier_rankname: + case prison_r_cm_rankname: + results = Double.toString( PlayerRank.getLadderBaseRankdMultiplier( rank ) ); + break; + + case prison_rank__currency_rankname: case prison_r_cu_rankname: results = rank.getCurrency() == null ? "default" : rank.getCurrency(); @@ -710,12 +804,14 @@ public String getTranslateRanksPlaceHolder( PlaceHolderKey placeHolderKey, case prison_rank__player_count_rankname: case prison_r_pc_rankname: - List players = - PrisonRanks.getInstance().getPlayerManager().getPlayers().stream() - .filter(rPlayer -> rPlayer.getLadderRanks().values().contains(rank)) - .collect(Collectors.toList()); + int playerCount = rank.getPlayers().size(); - results = Integer.toString( players.size() ); +// List players = +// PrisonRanks.getInstance().getPlayerManager().getPlayers().stream() +// .filter(rPlayer -> rPlayer.getLadderRanks().values().contains(rank)) +// .collect(Collectors.toList()); + + results = Integer.toString( playerCount ); break; case prison_rank__linked_mines_rankname: @@ -731,6 +827,54 @@ public String getTranslateRanksPlaceHolder( PlaceHolderKey placeHolderKey, results = sb.toString(); break; + + case prison_top_rank_balance_name_nnn_rankname: + case prison_trbn_nnn_rankname: + { + StatsRankPlayerBalanceData stats = rank.getStatsPlayerBlance().getTopStats( 1 ); + if ( stats != null ) { + + results = stats.getPlayer() == null ? "" : stats.getPlayer().getName(); + } + else { + results = ""; + } + } + + break; + + case prison_top_rank_balance_score_nnn_rankname: + case prison_trbs_nnn_rankname: + { + StatsRankPlayerBalanceData stats = rank.getStatsPlayerBlance().getTopStats( 1 ); + if ( stats != null ) { + + results = dFmt.format( stats.getScore()); + } + else { + results = ""; + } + } + + break; + + case prison_top_rank_balance_balance_nnn_rankname: + case prison_trbb_nnn_rankname: + { + StatsRankPlayerBalanceData stats = rank.getStatsPlayerBlance().getTopStats( 1 ); + if ( stats != null ) { + + results = stats.getPlayer() == null ? "" : + dFmt.format( stats.getPlayer().getBalance( rank.getCurrency()) ); + } + else { + results = ""; + } + } + + break; + + default: break; } @@ -745,6 +889,188 @@ public String getTranslateRanksPlaceHolder( PlaceHolderKey placeHolderKey, return results; } + + public String getTranslateRankPlayersPlaceHolder(UUID playerUuid, String playerName, + PlaceHolderKey placeHolderKey, PlaceholderAttribute attribute) { + String results = null; + + PrisonPlaceHolders placeHolder = placeHolderKey.getPlaceholder(); + + String rankName = placeHolderKey.getData(); + Rank rank = PrisonRanks.getInstance().getRankManager().getRank( rankName ); + + + PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); + RankPlayer rankPlayer = pm.getPlayer(playerUuid, playerName); + + DecimalFormat dFmt = new DecimalFormat("#,##0"); + + if ( rank != null && rankPlayer != null ) { + + switch ( placeHolder ) { + + case prison_rank__player_cost_rankname: + case prison_r_pcst_rankname: + { + double cost = calculateRankCost( rankPlayer, rank ); + + if ( attribute != null && attribute instanceof PlaceholderAttributeNumberFormat ) { + PlaceholderAttributeNumberFormat attributeNF = + (PlaceholderAttributeNumberFormat) attribute; + results = attributeNF.format( cost ); + } + else { + + results = dFmt.format( cost ); + } + } + break; + + case prison_rank__player_cost_formatted_rankname: + case prison_r_pcf_rankname: + { + double cost = calculateRankCost( rankPlayer, rank ); + + if ( attribute != null && attribute instanceof PlaceholderAttributeNumberFormat ) { + PlaceholderAttributeNumberFormat attributeNF = + (PlaceholderAttributeNumberFormat) attribute; + results = attributeNF.format( cost ); + } + else { + + results = PlaceholdersUtil.formattedMetricSISize( cost ); + } + } + break; + + + case prison_rank__player_cost_remaining_rankname: + case prison_r_pcr_rankname: + { + double cost = calculateRankCost( rankPlayer, rank ); + double balance = rankPlayer.getBalance( rank.getCurrency() ); +// double balance = pm.getPlayerBalance( rankPlayer, rank); + + double remaining = cost - balance; + + if ( remaining < 0 ) { + remaining = 0; + } + + if ( attribute != null && attribute instanceof PlaceholderAttributeNumberFormat ) { + PlaceholderAttributeNumberFormat attributeNF = + (PlaceholderAttributeNumberFormat) attribute; + results = attributeNF.format( remaining ); + } + else { + + results = dFmt.format( remaining ); + } + } + break; + + case prison_rank__player_cost_remaining_formatted_rankname: + case prison_r_pcrf_rankname: + { + double cost = calculateRankCost( rankPlayer, rank ); + double balance = rankPlayer.getBalance( rank.getCurrency() ); +// double balance = pm.getPlayerBalance( rankPlayer, rank); + + double remaining = cost - balance; + + if ( remaining < 0 ) { + remaining = 0; + } + + if ( attribute != null && attribute instanceof PlaceholderAttributeNumberFormat ) { + PlaceholderAttributeNumberFormat attributeNF = + (PlaceholderAttributeNumberFormat) attribute; + results = attributeNF.format( remaining ); + } + else { + + results = PlaceholdersUtil.formattedMetricSISize( remaining ); + } + + } + break; + + + + + case prison_rank__player_cost_percent_rankname: + case prison_r_pcp_rankname: + { + double cost = calculateRankCost( rankPlayer, rank ); + double balance = rankPlayer.getBalance( rank.getCurrency() ); +// double balance = pm.getPlayerBalance( rankPlayer, rank); + + double percent = (balance < 0 ? 0 : + (cost == 0.0d || balance > cost ? 100.0 : + balance / cost * 100.0 ) + ); + results = dFmt.format( percent ); + } + break; + + case prison_rank__player_cost_bar_rankname: + case prison_r_pcb_rankname: + { + double cost = calculateRankCost( rankPlayer, rank ); + double balance = rankPlayer.getBalance( rank.getCurrency() ); +// double balance = pm.getPlayerBalance( rankPlayer, rank); + + results = Prison.get().getPlaceholderManager(). + getProgressBar( balance, cost, false, attribute ); + } + break; + + + default: + break; + } + + if ( attribute != null && attribute instanceof PlaceholderAttributeText ) { + PlaceholderAttributeText attributeText = (PlaceholderAttributeText) attribute; + + results = attributeText.format( results ); + } + } + + return results; + } + + private double calculateRankCost( RankPlayer rankPlayer, Rank rank ) + { + double cost = 0; + // Get player's rank: + PlayerRank playerRank = rankPlayer.getRank( rank.getLadder() ); + if ( playerRank != null ) { + + + // If the player is at a higher rank, then the cost will be + // zero for the rank that is being passed in, since the player has + // already paid for that rank. + if ( rank.getPosition() < playerRank.getRank().getPosition() ) { + cost = 0; + } + else { + cost = playerRank.getRankCost(); + Rank nextRank = playerRank.getRank(); + + while ( nextRank != null && + nextRank.getPosition() < rank.getPosition() ) { + + // Need to calculate the next PlayerRank value for the next rank: + playerRank = new PlayerRank(nextRank); + + cost += playerRank.getRankCost(); + nextRank = nextRank.getRankNext(); + } + } + } + return cost; + } @@ -754,7 +1080,12 @@ public List getTranslatedPlaceHolderKeys() { translatedPlaceHolderKeys = new ArrayList<>(); // This generates all the placeholders for all ranks: - List placeHolders = PrisonPlaceHolders.getTypes( PlaceHolderFlags.RANKS ); + List placeHolders = PrisonPlaceHolders.getTypes( PlaceholderFlags.RANKS ); + + placeHolders.addAll( PrisonPlaceHolders.getTypes( PlaceholderFlags.RANKPLAYERS ) ); + + placeHolders.addAll( PrisonPlaceHolders.getTypes( PlaceholderFlags.STATSRANKS ) ); + List ranks = PrisonRanks.getInstance().getRankManager().getRanks(); for ( Rank rank : ranks ) { diff --git a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/top/RankPlayerSortableLadderRankBalance.java b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/top/RankPlayerSortableLadderRankBalance.java index 9bf184305..78e8858d1 100644 --- a/prison-ranks/src/main/java/tech/mcprison/prison/ranks/top/RankPlayerSortableLadderRankBalance.java +++ b/prison-ranks/src/main/java/tech/mcprison/prison/ranks/top/RankPlayerSortableLadderRankBalance.java @@ -3,6 +3,7 @@ import java.util.Comparator; import tech.mcprison.prison.ranks.PrisonRanks; +import tech.mcprison.prison.ranks.data.PlayerRank; import tech.mcprison.prison.ranks.data.Rank; import tech.mcprison.prison.ranks.data.RankLadder; import tech.mcprison.prison.ranks.data.RankPlayer; @@ -84,8 +85,10 @@ else if ( rp2 == null ) { results = 1; } else { - Rank r1 = rp1.getRank( getLadder().getName() ); - Rank r2 = rp2.getRank( getLadder().getName() ); + Rank r1 = rp1.getRank( getLadder() ) == null ? + null : rp1.getRank( getLadder() ).getRank(); + Rank r2 = rp2.getRank( getLadder() ) == null ? + null : rp2.getRank( getLadder() ).getRank(); if ( r1 == null ) { results = -1; @@ -95,39 +98,38 @@ else if ( r2 == null ) { } else { - // If ladder is not null, then compare the rank positions: - if ( getLadder() != null ) { - - // compare the Ranks' position. Ranks with higher position are greater: - - int pos1 = getLadder().getPositionOfRank( r1 ); - int pos2 = getLadder().getPositionOfRank( r2 ); - - results = Integer.compare( pos1, pos2 ); + if ( r1.equals( r2 ) ) { + results = 0; } - // results == 0 then so far the two RankPlayers share the same rank: - if ( results == 0 ) { - // Need to compare the player's balance: - - String currency = r1.getCurrency(); - - - RankPlayerBalance bal1 = rp1.getCachedRankPlayerBalance( currency ); - RankPlayerBalance bal2 = rp2.getCachedRankPlayerBalance( currency ); - - double topScore1 = calculateTopScore( r1, bal1.getBalance() ); - double topScore2 = calculateTopScore( r2, bal2.getBalance() ); + else { - results = Double.compare( topScore1, topScore2 ); + // compare the Ranks' position. Ranks with higher position are greater: + results = Integer.compare( r1.getPosition(), r2.getPosition() ); + + // results == 0 then so far the two RankPlayers share the same rank: if ( results == 0 ) { - results = rp1.getName().compareToIgnoreCase( rp2.getName() ); + // Need to compare the player's balance: + + String currency = r1.getCurrency(); + + + RankPlayerBalance bal1 = rp1.getCachedRankPlayerBalance( currency ); + RankPlayerBalance bal2 = rp2.getCachedRankPlayerBalance( currency ); + + double topScore1 = calculateTopScore( rp1, r1, bal1.getBalance() ); + double topScore2 = calculateTopScore( rp2, r2, bal2.getBalance() ); + + results = Double.compare( topScore1, topScore2 ); + + if ( results == 0 ) { + results = rp1.getName().compareToIgnoreCase( rp2.getName() ); + } + } - } - } } @@ -151,13 +153,21 @@ else if ( r2 == null ) { * @param balance * @return */ - private double calculateTopScore( Rank rank, double balance ) { + private double calculateTopScore( RankPlayer rp1, Rank rank, double balance ) { double topScore = 0; if ( balance != 0 ) { Rank nextRank = rank.getRankNext(); - double nextRankCost = nextRank == null ? rank.getCost() : nextRank.getCost(); + PlayerRank pRank = rp1.getRank( rank.getLadder() ); + + // This calculates the target rank, and takes in to consideration the player's existing rank: + PlayerRank pRankNext = PlayerRank.getTargetPlayerRankForPlayer( rp1, nextRank ); + +// PlayerRank pRankNext = nextRank == null ? null : +// new PlayerRank( nextRank, pRank.getRankMultiplier() ); + + double nextRankCost = nextRank == null ? pRank.getRankCost() : pRankNext.getRankCost(); topScore = nextRankCost / balance; diff --git a/prison-ranks/src/test/java/tech/mcprison/prison/ranks/commands/RanksCommandsTest.java b/prison-ranks/src/test/java/tech/mcprison/prison/ranks/commands/RanksCommandsTest.java new file mode 100644 index 000000000..59714b317 --- /dev/null +++ b/prison-ranks/src/test/java/tech/mcprison/prison/ranks/commands/RanksCommandsTest.java @@ -0,0 +1,28 @@ +package tech.mcprison.prison.ranks.commands; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public class RanksCommandsTest + extends RanksCommands +{ + + @Test + public final void testPadRankName() { + + assertEquals("A A&8......", padRankName("A", "A", 3, 5, true) ); + assertEquals("A [A]&8....", padRankName("A", "[A]", 3, 5, true) ); + assertEquals("A &7[&3A&7]&8....", padRankName("A", "&7[&3A&7]", 3, 5, true) ); + assertEquals("Aa &7[&3Aa&7]&8..", padRankName("Aa", "&7[&3Aa&7]", 3, 5, true) ); + assertEquals("Aaa &7[&3Aaa&7]&8", padRankName("Aaa", "&7[&3Aaa&7]", 3, 5, true) ); + + assertEquals("A&8....", padRankName("A", "A", 3, 5, false) ); + assertEquals("[A]&8..", padRankName("A", "[A]", 3, 5, false) ); + assertEquals("&7[&3A&7]&8..", padRankName("A", "&7[&3A&7]", 3, 5, false) ); + assertEquals("&7[&3Aa&7]&8.", padRankName("Aa", "&7[&3Aa&7]", 3, 5, false) ); + assertEquals("&7[&3Aaa&7]&8", padRankName("Aaa", "&7[&3Aaa&7]", 3, 5, false) ); + + } + +} diff --git a/prison-spigot/build.gradle b/prison-spigot/build.gradle index dcf5293c0..388480ab2 100644 --- a/prison-spigot/build.gradle +++ b/prison-spigot/build.gradle @@ -20,6 +20,9 @@ group 'tech.mcprison' apply plugin: 'java' +compileJava.options.encoding = 'UTF-8' +compileTestJava.options.encoding = "UTF-8" + //sourceCompatibility = 1.8 repositories { @@ -50,12 +53,7 @@ repositories { includeGroup 'me.clip' } } - maven { - url = 'https://mvnrepository.com/artifact/org.apache.commons/commons-lang3' - content { - includeGroup 'org.apache.commons' - } - } + maven { url = "https://mvnrepository.com/artifact/org.apache.commons/commons-lang3/" } maven { @@ -107,14 +105,8 @@ dependencies { // implementation 'com.github.cryptomorin:xseries:b95d195482' // https://mvnrepository.com/artifact/com.github.cryptomorin/XSeries - implementation 'com.github.cryptomorin:XSeries:8.1.0' + implementation 'com.github.cryptomorin:XSeries:8.3.0' -// implementation 'com.github.cryptomorin:XSeries:7.9.1.1' -// implementation 'com.github.cryptomorin:XSeries:7.8.0' -// implementation 'com.github.cryptomorin:XSeries:7.6.0.0.1' -// implementation 'com.github.cryptomorin:XSeries:7.5.4' -// implementation 'com.github.cryptomorin:XSeries:7.2.1' -// implementation 'com.github.cryptomorin:XSeries:6.3.2.1' // This includes 535KB when all we need is 1 class! @@ -188,7 +180,6 @@ processResources { shadowJar { dependencies { include(dependency('org.apache.commons:commons-lang3:3.12.0')) -// include(dependency('org.apache.commons:commons-lang3:3.10')) include(dependency('com.google.code.gson:gson:2.8.6')) include(dependency('org.bstats:bstats-base:2.2.1')) @@ -196,8 +187,7 @@ shadowJar { include(dependency('me.clip:placeholderapi:2.10.9')) -// include(dependency('com.github.cryptomorin:xseries:b95d195482')) - include(dependency('com.github.cryptomorin:XSeries:8.1.0')) + include(dependency('com.github.cryptomorin:XSeries:8.3.0')) //include(dependency('org.inventivetalent.spiget-update:bukkit:1.4.2-SNAPSHOT')) //include(dependency('me.badbones69:crazyenchantments-plugin:1.8-Dev-Build-v8')) diff --git a/prison-spigot/lib/PrisonEnchants-API-1.0.jar b/prison-spigot/lib/PrisonEnchants-API-1.0.jar new file mode 100644 index 000000000..839d83d28 Binary files /dev/null and b/prison-spigot/lib/PrisonEnchants-API-1.0.jar differ diff --git a/prison-spigot/lib/old/PrisonEnchants-1.0.0-API.jar b/prison-spigot/lib/old/PrisonEnchants-1.0.0-API.jar new file mode 100644 index 000000000..dd19b3d6e Binary files /dev/null and b/prison-spigot/lib/old/PrisonEnchants-1.0.0-API.jar differ diff --git a/prison-spigot/lib/old/PrisonEnchants-API-1.0.0.jar b/prison-spigot/lib/old/PrisonEnchants-API-1.0.0.jar new file mode 100644 index 000000000..c7aba3419 Binary files /dev/null and b/prison-spigot/lib/old/PrisonEnchants-API-1.0.0.jar differ diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotListener.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotListener.java index d736b7356..2436295f4 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotListener.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotListener.java @@ -18,9 +18,11 @@ package tech.mcprison.prison.spigot; +import org.bukkit.Bukkit; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -36,13 +38,22 @@ import org.bukkit.event.player.PlayerPickupItemEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.world.WorldLoadEvent; +import org.bukkit.plugin.EventExecutor; +import org.bukkit.plugin.PluginManager; import tech.mcprison.prison.Prison; +import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; import tech.mcprison.prison.internal.events.Cancelable; import tech.mcprison.prison.internal.events.player.PlayerChatEvent; import tech.mcprison.prison.internal.events.player.PlayerPickUpItemEvent; import tech.mcprison.prison.internal.events.player.PlayerSuffocationEvent; import tech.mcprison.prison.internal.events.world.PrisonWorldLoadEvent; +import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerBlockBreakEvents.AutoManagerBlockBreakEventListener; +import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerBlockBreakEvents.OnBlockBreakEventListenerNormal; +import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerBlockBreakEvents.OnBlockBreakEventListenerNormalMonitor; +import tech.mcprison.prison.spigot.block.OnBlockBreakEventListener; +import tech.mcprison.prison.spigot.block.OnBlockBreakEventListener.BlockBreakPriority; import tech.mcprison.prison.spigot.compat.Compatibility; import tech.mcprison.prison.spigot.game.SpigotPlayer; import tech.mcprison.prison.spigot.game.SpigotWorld; @@ -66,33 +77,85 @@ public class SpigotListener implements Listener { public SpigotListener() { super(); + + initialize(); } + public void initialize() { + + // Check to see if the class BlockBreakEvent even exists: + try { + + Output.get().logInfo( "SpigotListener: Trying to register events" ); + + SpigotPrison prison = SpigotPrison.getInstance(); + PluginManager pm = Bukkit.getServer().getPluginManager(); + + + String chatEventPriorityString = Prison.get().getPlatform().getConfigString( + "prison-events.AsyncPlayerChatEvent.priority", BlockBreakPriority.NORMAL.name() ); + + + BlockBreakPriority chatEventPriority = BlockBreakPriority.fromString( chatEventPriorityString ); + + if ( chatEventPriority != BlockBreakPriority.DISABLED ) { + + EventPriority ePriority = EventPriority.valueOf( chatEventPriority.name().toUpperCase() ); + + OnPlayerChatListener chatListener = new OnPlayerChatListener(); + // onPlayerChat + + pm.registerEvent(AsyncPlayerChatEvent.class, chatListener, ePriority, + new EventExecutor() { + public void execute(Listener l, Event e) { + if ( l instanceof OnPlayerChatListener && + e instanceof AsyncPlayerChatEvent ) { + ((OnPlayerChatListener)l) + .onPlayerChat( (AsyncPlayerChatEvent) e ); + } + } + }, + prison); + //prison.getRegisteredListeners().add( chatListener ); + + } + + } + catch ( Exception e ) { + Output.get().logInfo( "AutoManager: BlockBreakEvent failed to load. [%s]", e.getMessage() ); + } + } + + // Do not use this init() function since it is non-standard in how // prison is registering events. See SpigotPrison.onEnable(). // public void init() { // Bukkit.getServer().getPluginManager().registerEvents(this, SpigotPrison.getInstance()); // } - @EventHandler public void onPlayerJoin(PlayerJoinEvent e) { + @EventHandler + public void onPlayerJoin(PlayerJoinEvent e) { Prison.get().getEventBus().post( new tech.mcprison.prison.internal.events.player.PlayerJoinEvent( new SpigotPlayer(e.getPlayer()))); } - @EventHandler public void onPlayerQuit(PlayerQuitEvent e) { + @EventHandler + public void onPlayerQuit(PlayerQuitEvent e) { Prison.get().getEventBus().post( new tech.mcprison.prison.internal.events.player.PlayerQuitEvent( new SpigotPlayer(e.getPlayer()))); } - @EventHandler public void onPlayerKicked(PlayerKickEvent e) { + @EventHandler + public void onPlayerKicked(PlayerKickEvent e) { Prison.get().getEventBus().post( new tech.mcprison.prison.internal.events.player.PlayerKickEvent( new SpigotPlayer(e.getPlayer()), e.getReason())); } - @EventHandler public void onPlayerSuffocation( EntityDamageEvent e ) { + @EventHandler + public void onPlayerSuffocation( EntityDamageEvent e ) { Entity entity = e.getEntity(); if ( entity instanceof Player && e.getCause().equals( @@ -107,7 +170,8 @@ public SpigotListener() { } } - @EventHandler public void onBlockPlace(BlockPlaceEvent e) { + @EventHandler + public void onBlockPlace(BlockPlaceEvent e) { org.bukkit.Location block = e.getBlockPlaced().getLocation(); BlockType blockType = SpigotUtil.blockToBlockType( e.getBlock() ); @@ -119,7 +183,8 @@ public SpigotListener() { Prison.get().getEventBus().post(event); doCancelIfShould(event, e); } - @EventHandler public void onBlockBreak(BlockBreakEvent e) { + @EventHandler + public void onBlockBreak(BlockBreakEvent e) { org.bukkit.Location block = e.getBlock().getLocation(); BlockType blockType = SpigotUtil.blockToBlockType( e.getBlock() ); @@ -147,7 +212,8 @@ public void onWorldLoadEvent( WorldLoadEvent e ) { Prison.get().getEventBus().post(pwlEvent); } - @EventHandler public void onPlayerInteract(PlayerInteractEvent e) { + @EventHandler + public void onPlayerInteract(PlayerInteractEvent e) { // TODO Accept air events (block is null when air is clicked...) // Check to see if we support the Action @@ -179,7 +245,8 @@ public void onWorldLoadEvent( WorldLoadEvent e ) { doCancelIfShould(event, e); } - @EventHandler public void onPlayerDropItem(PlayerDropItemEvent e) { + @EventHandler + public void onPlayerDropItem(PlayerDropItemEvent e) { tech.mcprison.prison.internal.events.player.PlayerDropItemEvent event = new tech.mcprison.prison.internal.events.player.PlayerDropItemEvent( new SpigotPlayer(e.getPlayer()), @@ -192,7 +259,8 @@ public void onWorldLoadEvent( WorldLoadEvent e ) { // PlayerPickupItemEvent was deprecated and may not exist in newer releases. // Need to research this and find an alternative and push this back in to // the compatibility classes. - @EventHandler public void onPlayerPickUpItem(PlayerPickupItemEvent e) { + @EventHandler + public void onPlayerPickUpItem(PlayerPickupItemEvent e) { PlayerPickUpItemEvent event = new PlayerPickUpItemEvent(new SpigotPlayer(e.getPlayer()), SpigotUtil.bukkitItemStackToPrison(e.getItem().getItemStack())); Prison.get().getEventBus().post(event); @@ -208,16 +276,35 @@ public void manipulate(PlayerArmorStandManipulateEvent e) { } } - @EventHandler(priority=EventPriority.LOW) - public void onPlayerChat(AsyncPlayerChatEvent e) { - PlayerChatEvent event = - new PlayerChatEvent(new SpigotPlayer(e.getPlayer()), e.getMessage(), e.getFormat()); - Prison.get().getEventBus().post(event); - e.setFormat(ChatColor.translateAlternateColorCodes('&', event.getFormat() + "&r")); - e.setMessage(event.getMessage()); - doCancelIfShould(event, e); - } +// @EventHandler(priority=EventPriority.LOW) +// public void onPlayerChat(AsyncPlayerChatEvent e) { +// PlayerChatEvent event = +// new PlayerChatEvent(new SpigotPlayer(e.getPlayer()), e.getMessage(), e.getFormat()); +// Prison.get().getEventBus().post(event); +// e.setFormat(ChatColor.translateAlternateColorCodes('&', event.getFormat() + "&r")); +// e.setMessage(event.getMessage()); +// doCancelIfShould(event, e); +// } + + + public class OnPlayerChatListener + implements Listener { + + @EventHandler(priority=EventPriority.NORMAL) + public void onPlayerChat(AsyncPlayerChatEvent e) { + PlayerChatEvent event = + new PlayerChatEvent(new SpigotPlayer(e.getPlayer()), e.getMessage(), e.getFormat()); + + Prison.get().getEventBus().post(event); + + e.setFormat(ChatColor.translateAlternateColorCodes('&', event.getFormat() + "&r")); + e.setMessage(event.getMessage()); + + doCancelIfShould(event, e); + } + } + private void doCancelIfShould(Cancelable ours, Cancellable theirs) { if(ours.isCanceled()) { // We shouldn't set this to false, because some event handlers check for that. diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java index eb8caca4c..7d260aaf7 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPlatform.java @@ -25,7 +25,6 @@ import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.Random; import java.util.UUID; import java.util.stream.Collectors; @@ -41,8 +40,6 @@ import org.bukkit.command.ConsoleCommandSender; import org.bukkit.command.SimpleCommandMap; import org.bukkit.event.EventPriority; -import org.bukkit.event.HandlerList; -import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.event.player.PlayerChatEvent; import org.bukkit.plugin.Plugin; @@ -62,14 +59,17 @@ import tech.mcprison.prison.file.FileStorage; import tech.mcprison.prison.file.YamlFileIO; import tech.mcprison.prison.internal.Player; +import tech.mcprison.prison.internal.PlayerUtil; import tech.mcprison.prison.internal.Scheduler; import tech.mcprison.prison.internal.World; import tech.mcprison.prison.internal.block.PrisonBlock; import tech.mcprison.prison.internal.block.PrisonBlockTypes; import tech.mcprison.prison.internal.platform.Capability; +import tech.mcprison.prison.internal.platform.HandlerList; import tech.mcprison.prison.internal.platform.Platform; import tech.mcprison.prison.internal.scoreboard.ScoreboardManager; import tech.mcprison.prison.mines.PrisonMines; +import tech.mcprison.prison.mines.commands.MinesCommands; import tech.mcprison.prison.mines.data.Mine; import tech.mcprison.prison.mines.features.MineLinerBuilder.LinerPatterns; import tech.mcprison.prison.mines.managers.MineManager; @@ -81,15 +81,24 @@ import tech.mcprison.prison.output.LogLevel; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.ranks.PrisonRanks; +import tech.mcprison.prison.ranks.commands.RanksCommands; +import tech.mcprison.prison.ranks.data.PlayerRank; import tech.mcprison.prison.ranks.data.Rank; import tech.mcprison.prison.ranks.data.RankPlayer; import tech.mcprison.prison.ranks.managers.PlayerManager; import tech.mcprison.prison.ranks.managers.RankManager; +import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerBlockBreakEvents; +import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerCrazyEnchants; +import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerPrisonEnchants; +import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerTokenEnchant; +import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerZenchantments; import tech.mcprison.prison.spigot.block.OnBlockBreakEventListener.BlockBreakPriority; import tech.mcprison.prison.spigot.commands.PrisonSpigotSellAllCommands; import tech.mcprison.prison.spigot.game.SpigotCommandSender; +import tech.mcprison.prison.spigot.game.SpigotHandlerList; import tech.mcprison.prison.spigot.game.SpigotOfflinePlayer; import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.game.SpigotPlayerUtil; import tech.mcprison.prison.spigot.game.SpigotWorld; import tech.mcprison.prison.spigot.placeholder.SpigotPlaceholders; import tech.mcprison.prison.spigot.scoreboard.SpigotScoreboardManager; @@ -278,6 +287,21 @@ public Optional getOfflinePlayer(String name) { public Optional getOfflinePlayer(UUID uuid) { return getOfflinePlayer(null, uuid); } + + @Override + public List getOfflinePlayers() { + List players = new ArrayList<>(); + + for ( OfflinePlayer oPlayer : Bukkit.getOfflinePlayers() ) { + if ( oPlayer != null ) { + + players.add( new SpigotOfflinePlayer( oPlayer ) ); + } + } + + return players; + } + private Optional getOfflinePlayer(String name, UUID uuid) { Player player = null; @@ -778,6 +802,11 @@ public String getConfigString( String key ) { return SpigotPrison.getInstance().getConfig().getString( key ); } + @Override + public String getConfigString( String key, String defaultValue ) { + return SpigotPrison.getInstance().getConfig().getString( key, defaultValue ); + } + /** *

This returns the boolean value that is associated with the key. * It has to match on true to return a true value. If the key does @@ -1131,7 +1160,7 @@ public ModuleElement createModuleElement( tech.mcprison.prison.internal.CommandS MineManager mm = PrisonMines.getInstance().getMineManager(); Mine mine = mm.getMine( name ); if ( mine == null ) { - PrisonMines.getInstance().getMinesCommands().createCommand( sender, "virtual", name ); + PrisonMines.getInstance().getMinesCommands().createCommand( sender, name, "virtual noPlaceholderUpdate" ); mine = mm.getMine( name ); mine.setTag( tag ); @@ -1145,7 +1174,7 @@ public ModuleElement createModuleElement( tech.mcprison.prison.internal.CommandS else if ( elementType == ModuleElementType.RANK && PrisonRanks.getInstance() != null && PrisonRanks.getInstance().isEnabled() ) { RankManager rm = PrisonRanks.getInstance().getRankManager(); - rm.getRanksCommands().createRank( sender, name, 0, "default", tag ); + rm.getRanksCommands().createRank( sender, name, 0, "default", tag, "" ); Rank rank = rm.getRank( name ); @@ -1228,8 +1257,10 @@ public ModuleElement getPlayerDefaultMine( tech.mcprison.prison.internal.Command Player player = pm.getPlayer( sender ); RankPlayer rankPlayer = pm.getPlayer( player ); - if ( rankPlayer != null ) { - Rank rank = rankPlayer.getRank( "default" ); + if ( rankPlayer != null && rankPlayer.getRank( "default" ) != null ) { + PlayerRank pRank = rankPlayer.getRank( "default" ); + + Rank rank = pRank.getRank(); if ( rank != null ) { @@ -1323,6 +1354,11 @@ public boolean isMineAccessibleByRank( Player player, ModuleElement mine ) { return isAccessible; } + /** + * This function will try to enable Access by Rank on all mines that are linked to ranks. + * This will be applied to mines and ranks that would not normally be generated by + * the autoConfigure process. + */ @Override public void autoCreateConfigureMines() { @@ -1366,7 +1402,7 @@ public void autoCreateConfigureMines() { * */ @Override - public void autoCreateMineBlockAssignment( boolean forceKeepBlocks ) { + public void autoCreateMineBlockAssignment( List rankMineNames, boolean forceKeepBlocks ) { List blockList = new ArrayList<>(); @@ -1405,7 +1441,7 @@ public void autoCreateMineBlockAssignment( boolean forceKeepBlocks ) { } MineManager mm = PrisonMines.getInstance().getMineManager(); - List mines = mm.getMines(); + //List mines = mm.getMines(); List percents = new ArrayList<>(); percents.add(5d); @@ -1417,7 +1453,9 @@ public void autoCreateMineBlockAssignment( boolean forceKeepBlocks ) { int mineBlockSize = percents.size(); int startPos = 1; - for ( Mine mine : mines ) { + for ( String mineName : rankMineNames ) { + + Mine mine = mm.getMine( mineName ); boolean hasBlocks = mine.getPrisonBlocks().size() > 0 || mine.getBlocks().size() > 0; @@ -1517,19 +1555,22 @@ else if ( hasBlocks && forceKeepBlocks ) { } @Override - public void autoCreateMineLinerAssignment() { + public void autoCreateMineLinerAssignment( List rankMineNames, + boolean forceLinersBottom, boolean forceLinersWalls ) { MineManager mm = PrisonMines.getInstance().getMineManager(); - List mines = mm.getMines(); +// List mines = mm.getMines(); - for ( Mine mine : mines ) { + for ( String mineName : rankMineNames ) { + Mine mine = mm.getMine( mineName ); + String mineLinerData = mine.getLinerData().toSaveString(); boolean createLiner = mineLinerData.trim().isEmpty(); if ( createLiner ) { - mine.getLinerData().setLiner( Edges.walls, getRandomLinerType(), true ); - mine.getLinerData().setLiner( Edges.bottom, getRandomLinerType(), true ); + mine.getLinerData().setLiner( Edges.walls, getRandomLinerType(), forceLinersWalls ); + mine.getLinerData().setLiner( Edges.bottom, getRandomLinerType(), forceLinersBottom ); mineLinerData = mine.getLinerData().toSaveString(); @@ -1545,11 +1586,23 @@ public void autoCreateMineLinerAssignment() { } private LinerPatterns getRandomLinerType() { - LinerPatterns[] liners = LinerPatterns.values(); - // Exclude the last LinerPattern since it is "repair". - int pos = new Random().nextInt( liners.length - 1 ); - return liners[pos]; + // Get a random pattern, filtered for this version of spigot: + LinerPatterns results = LinerPatterns.getRandomLinerPattern(); + +// LinerPatterns[] liners = LinerPatterns.values(); +// +// // Exclude the last 3 LinerPatterns since they are "repair", "remove" and "removeAll". +// int pos = new Random().nextInt( liners.length - 3 ); +// LinerPatterns liner = liners[pos]; +// +// // Just in case any of these are selected, choose another: +// if ( liner ==LinerPatterns.remove || liner == LinerPatterns.removeAll || liner == LinerPatterns.repair ) { +// liner = getRandomLinerType(); +// } +// return liner; + + return results; } /** @@ -1805,19 +1858,40 @@ public List getActiveFeatures() { blockBreakPriority.name() ) ); String tebePriority = afw.getMessage( AutoFeatures.TokenEnchantBlockExplodeEventPriority ); + boolean isTebeEnabled = afw.isBoolean( AutoFeatures.isProcessTokensEnchantExplosiveEvents ); BlockBreakPriority tebEventPriority = BlockBreakPriority.fromString( tebePriority ); - results.add( String.format(". Token Enchant BlockExplodeEvent Priority:&b %s", - tebEventPriority.name() ) ); + results.add( String.format("%s. Token Enchant BlockExplodeEvent Priority:&b %s %s", + (isTebeEnabled ? "" : "+" ), + tebEventPriority.name(), + (isTebeEnabled ? "&2Enabled" : "&cDisabled") + ) ); String cebuePriority = afw.getMessage( AutoFeatures.CrazyEnchantsBlastUseEventPriority ); + boolean isCebueEnabled = afw.isBoolean( AutoFeatures.isProcessCrazyEnchantsBlockExplodeEvents ); BlockBreakPriority cebuEventPriority = BlockBreakPriority.fromString( cebuePriority ); - results.add( String.format(". Crazy Enchant BlastUseEvent Priority:&b %s", - cebuEventPriority.name() ) ); + results.add( String.format("%s. Crazy Enchant BlastUseEvent Priority:&b %s %s", + (isCebueEnabled ? "" : "+" ), + cebuEventPriority.name(), + (isCebueEnabled ? "&2Enabled" : "&cDisabled") + ) ); String zbsePriority = afw.getMessage( AutoFeatures.ZenchantmentsBlockShredEventPriority ); + boolean isZbseEnabled = afw.isBoolean( AutoFeatures.isProcessZenchantsBlockExplodeEvents ); BlockBreakPriority zbsEventPriority = BlockBreakPriority.fromString( zbsePriority ); - results.add( String.format(". Zenchantments BlockShredEvent Priority:&b %s", - zbsEventPriority.name() ) ); + results.add( String.format("%s. Zenchantments BlockShredEvent Priority:&b %s %s", + (isZbseEnabled ? "" : "+" ), + zbsEventPriority.name(), + (isZbseEnabled ? "&2Enabled" : "&cDisabled") + ) ); + + String peeePriority = afw.getMessage( AutoFeatures.PrisonEnchantsExplosiveEventPriority ); + boolean isPeeeeEnabled = afw.isBoolean( AutoFeatures.isProcessPrisonEnchantsExplosiveEvents ); + BlockBreakPriority peeEventPriority = BlockBreakPriority.fromString( peeePriority ); + results.add( String.format("%s. PrisonEnchants BlockExplodeEvent Priority:&b %s %s", + (isPeeeeEnabled ? "" : "+" ), + peeEventPriority.name(), + (isPeeeeEnabled ? "&2Enabled" : "&cDisabled") + ) ); results.add( " " ); @@ -1830,55 +1904,69 @@ public List getActiveFeatures() { afw.isBoolean( AutoFeatures.autoBlockEnabled ))) ); - results.add( String.format(". Handle Normal Drops:&b %s", (isAutoPickup ? "disabled by AutoPickup" : - afw.isBoolean( AutoFeatures.handleNormalDropsEvents ))) ); - results.add( String.format(". Normal Drop Smelt:&b %s", (isAutoPickup ? "disabled" : - afw.isBoolean( AutoFeatures.normalDropSmelt ))) ); - results.add( String.format(". Normal Drop Block:&b %s", (isAutoPickup ? "disabled" : - afw.isBoolean( AutoFeatures.normalDropBlock ))) ); + results.add( String.format("%s. Handle Normal Drops:&b %s %s", + (isAutoPickup ? "+" : ""), + (afw.isBoolean( AutoFeatures.handleNormalDropsEvents ) ? "&2Enabled" : "&cDisabled" ), + (isAutoPickup ? "&d[disabled by Exended Bukkit Fortune]" : "") ) ); + results.add( String.format("%s. Normal Drop Smelt:&b %s", + (isAutoPickup ? "+" : ""), + (afw.isBoolean( AutoFeatures.normalDropSmelt ) ? "&2Enabled" : "&cDisabled" ), + (isAutoPickup ? "&d[disabled by Exended Bukkit Fortune]" : "") ) ); + + results.add( String.format("%s. Normal Drop Block:&b %s", + (isAutoPickup ? "+" : ""), + (afw.isBoolean( AutoFeatures.normalDropBlock ) ? "&2Enabled" : "&cDisabled" ), + (isAutoPickup ? "&d[disabled by Exended Bukkit Fortune]" : "") ) ); results.add( " " ); - results.add( String.format("+. Calculate Durability:&b %s", - afw.isBoolean( AutoFeatures.isCalculateDurabilityEnabled )) ); + boolean isDurabilityEnabled = afw.isBoolean( AutoFeatures.isCalculateDurabilityEnabled ); + results.add( String.format("%s. Calculate Durability:&b %s", + (isDurabilityEnabled ? "" : "+"), + isDurabilityEnabled) ); boolean isCalcFortune = afw.isBoolean( AutoFeatures.isCalculateFortuneEnabled ); results.add( String.format(". Calculate Fortune:&b %s", isCalcFortune) ); - results.add( String.format("+. . Max Fortune Multiplier:&b %s", + results.add( String.format("+. . Max Fortune Level:&b %s &3(0 = no max Level)", afw.getInteger( AutoFeatures.fortuneMultiplierMax )) ); boolean isExtendedBukkitFortune = afw.isBoolean( AutoFeatures.isExtendBukkitFortuneCalculationsEnabled ); results.add( String.format(". . Extended Bukkit Fortune Enabled:&b %s", isExtendedBukkitFortune) ); + results.add( String.format("+. . Extended Bukkit Fortune Factor Percent Range Low:&b %s", afw.getInteger( AutoFeatures.extendBukkitFortuneFactorPercentRangeLow )) ); results.add( String.format("+. . Extended Bukkit Fortune Factor Percent Range High:&b %s", afw.getInteger( AutoFeatures.extendBukkitFortuneFactorPercentRangeHigh )) ); - results.add( String.format(". . Calculate Alt Fortune Enabled:&b %s", ( isExtendedBukkitFortune ? "disabled" : - afw.isBoolean( AutoFeatures.isCalculateAltFortuneEnabled ))) ); - results.add( String.format("+. . Calculate Alt Fortune on all Blocks:&b %s", - afw.isBoolean( AutoFeatures.isCalculateAltFortuneOnAllBlocksEnabled )) ); + results.add( "+&3NOTE: If you enable Extended Bukkit Fortune, then it auto disables the following Alt Fortune Cals." ); + results.add( "+&3NOTE: First try Extended Bukkit Fortune and if it does not work, then disable it and use " + + "Alt Fortune." ); + results.add( String.format("%s. . Calculate Alt Fortune Enabled:&b %s %s", + (isExtendedBukkitFortune ? "+" : "" ), + ( afw.isBoolean( AutoFeatures.isCalculateAltFortuneEnabled) ? "&2Enabled" : "&cDisabled"), + ( isExtendedBukkitFortune ? "&d[disabled by Exended Bukkit Fortune]" : "")) ); + results.add( String.format("%s. . Calculate Alt Fortune on all Blocks:&b %s %s", + (isExtendedBukkitFortune ? "+" : "" ), + ( afw.isBoolean( AutoFeatures.isCalculateAltFortuneOnAllBlocksEnabled) ? "&2Enabled" : "&cDisabled"), + ( isExtendedBukkitFortune ? "&d[disabled by Exended Bukkit Fortune]" : "")) ); results.add( " " ); - results.add( String.format("+. Calculate XP:&b %s", - afw.isBoolean( AutoFeatures.isCalculateXPEnabled )) ); - results.add( String.format("+. Drop XP as Orbs:&b %s", + boolean isXpEnabled = afw.isBoolean( AutoFeatures.isCalculateXPEnabled ); + results.add( String.format("%s. Calculate XP:&b %s", + (isXpEnabled ? "" : "+"), + isXpEnabled ) ); + results.add( String.format("%s. Drop XP as Orbs:&b %s", + (isXpEnabled ? "" : "+"), afw.isBoolean( AutoFeatures.givePlayerXPAsOrbDrops )) ); - results.add( String.format("+. Process TokensEnchant Explosive Events:&b %s", - afw.isBoolean( AutoFeatures.isProcessTokensEnchantExplosiveEvents )) ); - results.add( String.format("+. Process Crazy Enchants Block Explode Events:&b %s", - afw.isBoolean( AutoFeatures.isProcessCrazyEnchantsBlockExplodeEvents )) ); - results.add( String.format("+. Process McMMO BlockBreakEvents:&b %s", - afw.isBoolean( AutoFeatures.isProcessMcMMOBlockBreakEvents )) ); @@ -1920,33 +2008,73 @@ public List getActiveFeatures() { } + @Override + public PlayerUtil getPlayerUtil( UUID playerUuid ) { + return new SpigotPlayerUtil( playerUuid ); + } + @Override - public void dumpEventListenersBlockBreakEvents() { + public String dumpEventListenersBlockBreakEvents() { + StringBuilder sb = new StringBuilder(); + + // Dump the event listeners for the following events if they are active on the server: + + AutoManagerBlockBreakEvents blockEvents = new AutoManagerBlockBreakEvents(); + blockEvents.dumpEventListeners( sb ); + - dumpEventListeners( "BlockBreakEvent", BlockBreakEvent.getHandlerList() ); + sb.append( "\n" ); + sb.append( "&2NOTE: Prison Block Event Listeners:\n" ); - Output.get().logInfo( "&2NOTE: Prison Block Event Listeners:" ); + sb.append( "&2. . Prison Internal BlockBreakEvents: " + + "tech.mcprison.prison.spigot.SpigotListener\n" ); + sb.append( "&2. . Auto Feature Core: Non-AutoManager: " + + "OnBlockBreakEventListeners$OnBlockBreakEventListener*\n" ); + sb.append( "&2. . Prison MONITOR Events manages block counts, " + + "Mine Sweeper, and zero block conditions.\n" ); + sb.append( "&2. . AutoManager and enchantment event listeners are " + + "identified by their class names.\n" ); + sb.append( "\n" ); - Output.get().logInfo( "&2. . Prison Internal BlockBreakEvents: " + - "tech.mcprison.prison.spigot.SpigotListener" ); - Output.get().logInfo( "&2. . Auto Feature Core: Non-AutoManager: " + - "OnBlockBreakEventListeners$OnBlockBreakEventListener*" ); - Output.get().logInfo( "&2. . Prison MONITOR Events manages block counts, " + - "Mine Sweeper, and zero block conditions." ); - Output.get().logInfo( "&2. . AutoManager and enchantment event listeners are " + - "identified by their class names." ); + + AutoManagerCrazyEnchants crazyEnchants = new AutoManagerCrazyEnchants(); + crazyEnchants.dumpEventListeners( sb ); + + AutoManagerPrisonEnchants prisonEnchants = new AutoManagerPrisonEnchants(); + prisonEnchants.dumpEventListeners( sb ); + + AutoManagerTokenEnchant tokenEnchant = new AutoManagerTokenEnchant(); + tokenEnchant.dumpEventListeners( sb ); + + AutoManagerZenchantments zenchantments = new AutoManagerZenchantments(); + zenchantments.dumpEventListeners( sb ); + + return sb.toString(); } @Override - public void dumpEventListenersPlayerChatEvents() { - - dumpEventListeners( "AsyncPlayerChatEvent", AsyncPlayerChatEvent.getHandlerList() ); + public String dumpEventListenersPlayerChatEvents() { + StringBuilder sb = new StringBuilder(); + + ChatDisplay eventDisplay = dumpEventListenersChatDisplay( + "AsyncPlayerChatEvent", + new SpigotHandlerList( AsyncPlayerChatEvent.getHandlerList()) ); + if ( eventDisplay != null ) { + sb.append( eventDisplay.toStringBuilder() ); + } if ( new BluesSpigetSemVerComparator().compareMCVersionTo("1.17.0") < 0 ) { - dumpEventListeners( "PlayerChatEvent", PlayerChatEvent.getHandlerList() ); + eventDisplay = dumpEventListenersChatDisplay( + "PlayerChatEvent", + new SpigotHandlerList( PlayerChatEvent.getHandlerList()) ); + if ( eventDisplay != null ) { + sb.append( eventDisplay.toStringBuilder() ); + } } + + return sb.toString(); } /** @@ -1967,25 +2095,72 @@ public void dumpEventListenersPlayerChatEvents() { * @param eventType * @param handlerList */ - private void dumpEventListeners( String eventType, HandlerList handlerList ) { + @Override + public List dumpEventListenersList( String eventType, HandlerList handlerList ) { + List results = new ArrayList<>(); - RegisteredListener[] listeners = handlerList.getRegisteredListeners(); + RegisteredListener[] listeners = ((SpigotHandlerList) handlerList).getRegisteredListeners(); - ChatDisplay display = new ChatDisplay("Event Dump: " + eventType ); - display.addText("&8All registered EventListeners (%d):", listeners.length ); + // Set the title in position 0: + results.add( "Event Dump: " + eventType ); + + results.add( String.format( "&8All registered EventListeners (%d):", listeners.length )); for ( RegisteredListener eventListner : listeners ) { String plugin = eventListner.getPlugin().getName(); EventPriority priority = eventListner.getPriority(); String listener = eventListner.getListener().getClass().getName(); - String message = String.format( "&3 Plugin: &7%s %s &3(%s)", + String message = String.format( "&3. Plugin: &7%s %s &3(%s)", plugin, priority.name(), listener); - display.addText( message ); + results.add( message ); + } + + return results; + } + + @Override + public ChatDisplay dumpEventListenersChatDisplay( String eventType, HandlerList handlerList ) { + ChatDisplay display = null; + + List details = dumpEventListenersList( eventType, handlerList ); + + if ( details.size() > 0 ) { + + // Title is the first entry: + display = new ChatDisplay( details.get( 0 ) ); + + for ( int x = 1; x < details.size(); x++ ) { + display.addText( details.get( x ) ); + } } - display.toLog( LogLevel.DEBUG ); + // display.toLog( LogLevel.DEBUG ); + + return display; + } + + /** + *

This only reloads the event listeners that auto features uses. This is called by + * the command "/prison reload autoFeatures". + *

+ * + * tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.reloadConfig() + * + */ + public void reloadAutoFeaturesEventListeners() { + + AutoManagerBlockBreakEvents autoFeaturesEvents = new AutoManagerBlockBreakEvents(); + + // NOTE: The unregisterListeners() will remove ALL auto features events that were + // registered, no matter which listeners were enabled. + autoFeaturesEvents.unregisterListeners(); + + // NOTE: The registerEvents() will register all event listeners based upon what's + // in the auto features configuration file. + autoFeaturesEvents.registerEvents(); + } /** @@ -1999,7 +2174,100 @@ private void dumpEventListeners( String eventType, HandlerList handlerList ) { public void traceEventListenersBlockBreakEvents( tech.mcprison.prison.internal.CommandSender sender ) { // TODO Auto-generated method stub + Output.get().logInfo( "This feature is not enabled yet." ); + } + + @Override + public void testPlayerUtil( UUID uuid ) + { + SpigotPlayerUtil playerUtil = new SpigotPlayerUtil( uuid ); + + Output.get().logInfo("Player UUID: %s", playerUtil.getPlayerUuid() ); + + Output.get().logInfo("Player Level: %d", playerUtil.getLevel() ); + Output.get().logInfo("Player XP: %s", Double.toString( playerUtil.getExp() )); + Output.get().logInfo("Player Air Max: %d", playerUtil.getMaximumAir() ); + Output.get().logInfo("Player Air Remaining: %d", playerUtil.getRemainingAir() ); + + + Output.get().logInfo("Player Food Level: %d", playerUtil.getFoodLevel() ); + Output.get().logInfo("Player Food Exhaustion: %s", Double.toString( playerUtil.getFoodExhaustion() )); + Output.get().logInfo("Player Food Saturation: %s", Double.toString( playerUtil.getFoodSaturation() )); + + Output.get().logInfo("Player Health Max: %s", Double.toString( playerUtil.getMaxHealth() )); + Output.get().logInfo("Player Health Current: %s", Double.toString( playerUtil.getHealth() )); + Output.get().logInfo("Player Walk Speed: %s", Double.toString( playerUtil.getWalkSpeed() )); + + + Output.get().logInfo("Player Tool Name: %s", playerUtil.getItemInHandName() ); + Output.get().logInfo("Player Tool Display Name: %s", playerUtil.getItemInHandDisplayName() ); + + Output.get().logInfo("Player Tool Item Type: %s", playerUtil.getItemInHandItemType() ); + Output.get().logInfo("Player Tool Item Material: %s", playerUtil.getItemInHandItemMaterial() ); + + Output.get().logInfo("Player Tool Durability Used: %s", playerUtil.getItemInHandDurabilityUsed() ); + Output.get().logInfo("Player Tool Durability Max: %s", playerUtil.getItemInHandDurabilityMax() ); + Output.get().logInfo("Player Tool Durability Remaining: %s", playerUtil.getItemInHandDurabilityRemaining() ); + + + Output.get().logInfo("Player Tool Enchantment Efficency: %s", playerUtil.getItemInHandEnchantmentEfficency() ); + Output.get().logInfo("Player Tool Enchantment Fortune: %s", playerUtil.getItemInHandEnchantmentFortune() ); + Output.get().logInfo("Player Tool Enchantment Luck: %s", playerUtil.getItemInHandEnchantmentLuck() ); + Output.get().logInfo("Player Tool Enchantment Mending: %s", playerUtil.getItemInHandEnchantmentMending() ); + Output.get().logInfo("Player Tool Enchantment Silk Touch: %s", playerUtil.getItemInHandEnchantmentSilkTouch() ); + + } + + @Override + public void saveResource( String fileName, boolean replace ) { + SpigotPrison.getInstance().saveResource( fileName, replace ); + } + + + @Override + public String getMinesListString() { + + + MinesCommands mc = PrisonMines.getInstance().getMinesCommands(); + + + ChatDisplay display = new ChatDisplay("Mines"); + mc.getMinesList( display, MineManager.MineSortOrder.sortOrder, "all", null ); + + StringBuilder sb = display.toStringBuilder(); + + sb.append( "\n" ); + + mc.allMinesInfoDetails( sb ); + + return sb.toString(); +// return Text.stripColor( sb.toString() ); + } + + @Override + public String getRanksListString() { + + RanksCommands rc = + PrisonRanks.getInstance().getRankManager().getRanksCommands(); + + + ChatDisplay display = new ChatDisplay("Ranks"); + + RankPlayer rPlayer = null; + rc.listAllRanksByLadders( display, true, rPlayer ); + + StringBuilder sb = display.toStringBuilder(); + + sb.append( "\n" ); + + rc.listAllRanksByInfo( sb ); +// rc.allRanksInfoDetails( sb ); + + return sb.toString(); +// return Text.stripColor( sb.toString() ); } + + } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java index 479835e86..bf39354bc 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/SpigotPrison.java @@ -20,7 +20,9 @@ import java.io.File; import java.lang.reflect.Field; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Optional; import java.util.concurrent.Callable; @@ -34,6 +36,7 @@ import org.bukkit.command.SimpleCommandMap; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.event.Listener; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; import org.inventivetalent.update.spiget.SpigetUpdate; @@ -56,8 +59,8 @@ import tech.mcprison.prison.ranks.PrisonRanks; import tech.mcprison.prison.ranks.data.Rank; import tech.mcprison.prison.ranks.managers.RankManager; -import tech.mcprison.prison.spigot.autofeatures.AutoManager; import tech.mcprison.prison.spigot.autofeatures.AutoManagerFeatures; +import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerBlockBreakEvents; import tech.mcprison.prison.spigot.backpacks.BackpacksListeners; import tech.mcprison.prison.spigot.block.OnBlockBreakEventListener; import tech.mcprison.prison.spigot.commands.PrisonSpigotBackpackCommands; @@ -119,6 +122,9 @@ public class SpigotPrison extends JavaPlugin { private PrisonBlockTypes prisonBlockTypes; private static boolean isBackPacksEnabled = false; + + + private List registeredBlockListeners; public static SpigotPrison getInstance(){ return config; @@ -128,6 +134,8 @@ public SpigotPrison() { super(); config = this; + + this.registeredBlockListeners = new ArrayList<>(); } @Override @@ -173,7 +181,11 @@ public void onEnable() { // Create the core directory structure if it is missing: initDataDir(); - // Setup some of the key data structures and object requried to be in place +// // Setup the localManager (when instantiating Prison) and set the default language: +// Prison.get().getLocaleManager().setDefaultLocale( +// getConfig().getString("default-language", "en_US")); + + // Setup some of the key data structures and object required to be in place // prior to starting up: initCommandMap(); this.scheduler = new SpigotScheduler(this); @@ -182,8 +194,6 @@ public void onEnable() { Prison.get() .init(new SpigotPlatform(this), Bukkit.getVersion()); - Prison.get().getLocaleManager().setDefaultLocale( - getConfig().getString("default-language", "en_US")); this.compatibility = SpigotCompatibility.getInstance(); // initCompatibility(); Obsolete... @@ -219,7 +229,10 @@ public void onEnableStartup() { Bukkit.getPluginManager().registerEvents(new ListenersPrisonManager(),this); - Bukkit.getPluginManager().registerEvents(new SlimeBlockFunEventListener(), this); + if ( getConfig().getBoolean( "slime-fun" ) ) { + Bukkit.getPluginManager().registerEvents(new SlimeBlockFunEventListener(), this); + } + Bukkit.getPluginManager().registerEvents(new SpigotListener(), this); try { @@ -345,7 +358,7 @@ public AutoManagerFeatures getAutoFeatures() { // been setup. The following line will allow it to be setup so the setting can be accessed. // The proper way to access the settings are through... // AutoFeaturesWrapper.getInstance().getAutoFeaturesConfig() - autoFeatures = new AutoManager(); + autoFeatures = new AutoManagerBlockBreakEvents(); } return autoFeatures; @@ -734,7 +747,27 @@ private void linkMinesAndRanks() { private void applyDeferredIntegrationInitializations() { for ( Integration deferredIntegration : PrisonAPI.getIntegrationManager().getDeferredIntegrations() ) { - deferredIntegration.deferredInitialization(); + + try { + if ( deferredIntegration.isRegistered() && deferredIntegration.hasIntegrated() ) { + + deferredIntegration.deferredInitialization(); + } + } + catch ( Exception e ) { + + + PrisonAPI.getIntegrationManager().removeIntegration( deferredIntegration ); + + Output.get().logWarn( + String.format( "Warning: An integration failed during deferred integration. " + + "Disabling the integration to protect Prison: %s %s %s[%s]", + deferredIntegration.getKeyName(), deferredIntegration.getVersion(), + (deferredIntegration.getDebugInfo() == null ? + "no debug info" : deferredIntegration.getDebugInfo()) )); + + } + } } @@ -801,4 +834,8 @@ public PrisonBlockTypes getPrisonBlockTypes() { return prisonBlockTypes; } + + public List getRegisteredBlockListeners() { + return registeredBlockListeners; + } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/ExplosiveBlockBreakEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/ExplosiveBlockBreakEvent.java new file mode 100644 index 000000000..493030918 --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/ExplosiveBlockBreakEvent.java @@ -0,0 +1,113 @@ +package tech.mcprison.prison.spigot.api; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.event.block.BlockBreakEvent; + +/** + *

This is an example of an explosive event that should be used for + * enchantments that will break more than one block at a time. + *

+ * + *

The main block that is provided should be "the block" that the + * player mined and broke. That should be the same block as included + * in the standard bukkit BlockBreakEvent. + *

+ * + *

The player object is the same as found in the standard bukkit + * BlockBreakEvent. + *

+ * + *

The blocks in explodedBlocks List should be all of the blocks that + * are included within the explosion, or the enchantment effects, but + * must exclude the block that was broke. These blocks do not have to be + * constrained to a physical mine, since prison will validate each block + * that is included, and will only process the blocks that are within the + * actual mines. All blocks outside of the mine will be ignored. + *

+ * + *

The field triggeredBy is optional, but really should identify + * what enchantment was used that triggered this event. The value of + * this field will serve as a filter on blockBreak events so users can + * setup filters to take action when specific enchantments are used. + *

+ * + * + * @author RoyalBlueRanger + * + */ +public class ExplosiveBlockBreakEvent + extends BlockBreakEvent +{ + private static final HandlerList handlers = new HandlerList(); + + private List explodedBlocks; + + private String triggeredBy; + + public ExplosiveBlockBreakEvent( Block theBlock, Player player, + List explodedBlocks, String triggeredBy ) { + super( theBlock, player ); + + this.explodedBlocks = explodedBlocks; + this.triggeredBy = triggeredBy; + } + public ExplosiveBlockBreakEvent( Block theBlock, Player player, + List explodedBlocks ) { + this( theBlock, player, explodedBlocks, null ); + } + public ExplosiveBlockBreakEvent( Block theBlock, Player player ) { + this( theBlock, player, new ArrayList<>(), null ); + + } + + /** + * This is strictly a non-function example of how to fire this event. Make sure you load up the + * parameters correctly, of which this example is passing nulls for block and player, and an + * empty explodedBlocks list. The only purpose for this dummy function is to show you how + * to use it in your plugin. + */ + public void sampleUsage() { + + Block block = null; + Player player = null; + List explodedBlocks = new ArrayList<>(); + String triggeredBy = "sampleUsage"; + + ExplosiveBlockBreakEvent ebbe = new ExplosiveBlockBreakEvent( block, player, explodedBlocks, triggeredBy ); + + Bukkit.getServer().getPluginManager().callEvent( ebbe ); + + if ( !ebbe.isCancelled() ) { + // Go ahead and break the blocks in your plugin. The fact that it's not canceled implies + // that no other plugin was able to process this event. + } + } + + public List getExplodedBlocks() { + return explodedBlocks; + } + public void setExplodedBlocks( List explodedBlocks ) { + this.explodedBlocks = explodedBlocks; + } + + public String getTriggeredBy() { + return triggeredBy; + } + public void setTriggeredBy( String triggeredBy ) { + this.triggeredBy = triggeredBy; + } + + @Override + public HandlerList getHandlers(){ + return handlers; + } + public static HandlerList getHandlersList(){ + return handlers; + } +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonMinesBlockBreakEvent.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonMinesBlockBreakEvent.java index 632d4b270..ba5811ce2 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonMinesBlockBreakEvent.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/api/PrisonMinesBlockBreakEvent.java @@ -1,5 +1,6 @@ package tech.mcprison.prison.spigot.api; +import java.util.ArrayList; import java.util.List; import org.bukkit.block.Block; @@ -11,6 +12,7 @@ import tech.mcprison.prison.mines.features.MineBlockEvent.BlockEventType; import tech.mcprison.prison.mines.features.MineTargetPrisonBlock; import tech.mcprison.prison.spigot.block.SpigotBlock; +import tech.mcprison.prison.spigot.game.SpigotPlayer; /** *

This is an event that prison calls before processing the blocks that @@ -54,15 +56,45 @@ public class PrisonMinesBlockBreakEvent private static final HandlerList handlers = new HandlerList(); private Mine mine; + private SpigotBlock spigotBlock; - + private SpigotPlayer spigotPlayer; + //private SpigotBlock overRideSpigotBlock; private List explodedBlocks; private BlockEventType blockEventType; private String triggered; + + private boolean cancelOriginalEvent = false; + private boolean monitor = false; + private boolean blockEventsOnly = false; + + private List unprocessedRawBlocks; + + public PrisonMinesBlockBreakEvent( Block theBlock, Player player, + SpigotBlock spigotBlock, SpigotPlayer spigotPlayer, + boolean monitor, boolean blockEventsOnly, + BlockEventType blockEventType, String triggered) { + + super( theBlock, player ); + + this.spigotBlock = spigotBlock; + this.spigotPlayer = spigotPlayer; + + this.monitor = monitor; + this.blockEventsOnly = blockEventsOnly; + + this.blockEventType = blockEventType; + this.triggered = triggered; + + this.explodedBlocks = new ArrayList<>(); + this.unprocessedRawBlocks = new ArrayList<>(); + + } + public PrisonMinesBlockBreakEvent( Block theBlock, Player player, Mine mine, SpigotBlock spigotBlock, List explodedBlocks, @@ -145,6 +177,13 @@ public void setSpigotBlock( SpigotBlock spigotBlock ) { this.spigotBlock = spigotBlock; } + public SpigotPlayer getSpigotPlayer() { + return spigotPlayer; + } + public void setSpigotPlayer( SpigotPlayer spigotPlayer ) { + this.spigotPlayer = spigotPlayer; + } + public List getExplodedBlocks() { return explodedBlocks; } @@ -173,6 +212,34 @@ public void setTriggered( String triggered ) { // this.overRideSpigotBlock = overRideSpigotBlock; // } + public boolean isCancelOriginalEvent() { + return cancelOriginalEvent; + } + public void setCancelOriginalEvent( boolean cancelOriginalEvent ) { + this.cancelOriginalEvent = cancelOriginalEvent; + } + + public boolean isMonitor() { + return monitor; + } + public void setMonitor( boolean monitor ) { + this.monitor = monitor; + } + + public boolean isBlockEventsOnly() { + return blockEventsOnly; + } + public void setBlockEventsOnly( boolean blockEventsOnly ) { + this.blockEventsOnly = blockEventsOnly; + } + + public List getUnprocessedRawBlocks() { + return unprocessedRawBlocks; + } + public void setUnprocessedRawBlocks( List unprocessedRawBlocks ) { + this.unprocessedRawBlocks = unprocessedRawBlocks; + } + @Override public HandlerList getHandlers() { return handlers; diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManager.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManager.java deleted file mode 100644 index 9b0a81d7c..000000000 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManager.java +++ /dev/null @@ -1,383 +0,0 @@ -package tech.mcprison.prison.spigot.autofeatures; - -import org.bukkit.Bukkit; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.block.BlockBreakEvent; - -import me.badbones69.crazyenchantments.api.events.BlastUseEvent; -import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; -import tech.mcprison.prison.output.Output; -import tech.mcprison.prison.spigot.SpigotPrison; -import tech.mcprison.prison.spigot.block.OnBlockBreakEventListener.BlockBreakPriority; -import zedly.zenchantments.BlockShredEvent; - - -/** - * @author GABRYCA - * @author RoyalBlueRanger - */ -public class AutoManager - extends AutoManagerFeatures - { - - public AutoManager() { - super(); - - // NOTE: Set in SpigotPrison. -// // Save this instance within the SpigotPrison instance so it can be accessed -// // from non-event listeners: -// SpigotPrison.getInstance().setAutoFeatures( this ); - } - - - public void registerBlockBreakEvents(SpigotPrison spigotPrison ) { - - - String bbePriority = getMessage( AutoFeatures.blockBreakEventPriority ); - BlockBreakPriority blockBreakPriority = BlockBreakPriority.fromString( bbePriority ); - - switch ( blockBreakPriority ) - { - case LOWEST: - Bukkit.getPluginManager().registerEvents( - new AutoManagerEventListenerLowest(), spigotPrison); - break; - - case LOW: - Bukkit.getPluginManager().registerEvents( - new AutoManagerEventListenerLow(), spigotPrison); - break; - - case NORMAL: - Bukkit.getPluginManager().registerEvents( - new AutoManagerEventListenerNormal(), spigotPrison); - break; - - case HIGH: - Bukkit.getPluginManager().registerEvents( - new AutoManagerEventListenerHigh(), spigotPrison); - break; - - case HIGHEST: - Bukkit.getPluginManager().registerEvents( - new AutoManagerEventListenerHighest(), spigotPrison); - break; - - case DISABLED: - Output.get().logInfo( "AutoManager BlockBreakEvent handling has been DISABLED." ); - break; - - default: - break; - } - - - boolean isTEBlockExplosiveEnabled = isBoolean( AutoFeatures.isProcessTokensEnchantExplosiveEvents ); - - if ( isTEBlockExplosiveEnabled ) { - - try { - Class.forName("com.vk2gpz.tokenenchant.event.TEBlockExplodeEvent"); - - AutoManagerTokenEnchant tokenEnchant = new AutoManagerTokenEnchant(); - tokenEnchant.registerBlockBreakEvents( spigotPrison ); - -// OnBlockBreakEventTokenEnchant bbTokenEnchant = new OnBlockBreakEventTokenEnchant(); -// bbTokenEnchant.registerBlockBreakEvents( spigotPrison ); - -// Bukkit.getPluginManager().registerEvents(new AutoManagerTokenEnchant(), spigotPrison); -// Bukkit.getPluginManager().registerEvents(new OnBlockBreakEventTokenEnchant(), spigotPrison); - - } - catch (ClassNotFoundException e) { - // TokenEnchant is not available on this server which is not an error. Just - // ignore this situation and do not register the TE explosion events. - } - } - - - - - boolean isCEBlockExplodeEnabled = isBoolean( AutoFeatures.isProcessCrazyEnchantsBlockExplodeEvents ); - - if ( isCEBlockExplodeEnabled ) { - AutoManagerCrazyEnchants amCE = new AutoManagerCrazyEnchants(); - amCE.registerBlastUseEvents( spigotPrison ); - } - - - - boolean isZenBlockExplodeEnabled = isBoolean( AutoFeatures.isProcessZenchantsBlockExplodeEvents ); - - if ( isZenBlockExplodeEnabled ) { - - AutoManagerZenchantments zenBlockEvents = new AutoManagerZenchantments(); - zenBlockEvents.registerBlockBreakEvents( spigotPrison ); - } - - -// switch ( blockShredPriority ) -// { -// case LOWEST: -// Bukkit.getPluginManager().registerEvents( -// new AutoManagerBlockShredEventListenerLowest(), spigotPrison); -// break; -// -// case LOW: -// Bukkit.getPluginManager().registerEvents( -// new AutoManagerBlockShredEventListenerLow(), spigotPrison); -// break; -// -// case NORMAL: -// Bukkit.getPluginManager().registerEvents( -// new AutoManagerBlockShredEventListenerNormal(), spigotPrison); -// break; -// -// case HIGH: -// Bukkit.getPluginManager().registerEvents( -// new AutoManagerBlockShredEventListenerHigh(), spigotPrison); -// break; -// -// case HIGHEST: -// Bukkit.getPluginManager().registerEvents( -// new AutoManagerBlockShredEventListenerHighest(), spigotPrison); -// break; -// -// case DISABLED: -// Output.get().logInfo( "AutoManager Zenchantments BlockShredEvent handling has been DISABLED." ); -// break; -// -// default: -// break; -// } - - } - - -// /** -// *

Had to set to a EventPriorty.LOW so other plugins can work with the blocks. -// * The other plugins were EZBlock & SellAll. This function was canceling the -// * event after it auto picked it up, so the other plugins were not registering -// * the blocks as being broken. -// *

-// * -// * @param e -// */ -// @EventHandler(priority=EventPriority.LOW) -// public void onBlockBreak(BlockBreakEvent e) { -// -// if ( !e.isCancelled() && e.getBlock().getType() != null) { -// -// // Get the player objects: Spigot and the Prison player: -// Player p = e.getPlayer(); -// // SpigotPlayer player = new SpigotPlayer( p ); -// -// // Validate that the event is happening within a mine since the -// // onBlockBreak events here are only valid within the mines: -// Optional mmOptional = Prison.get().getModuleManager().getModule( PrisonMines.MODULE_NAME ); -// if ( mmOptional.isPresent() && mmOptional.get().isEnabled() ) { -// PrisonMines mineManager = (PrisonMines) mmOptional.get(); -// -// for ( Mine mine : mineManager.getMines() ) { -// SpigotBlock block = new SpigotBlock(e.getBlock()); -// if ( mine.isInMine( block.getLocation() ) ) { -// -// applyAutoEvents( e, mine, p ); -// break; -// } -// } -// } -// } -// } - - /** - *

The optimized logic on how an BlockBreakEvent is handled is within the OnBlockBreakEventListener - * class and optimizes mine reuse. - *

- * - *

Had to set to a EventPriorty.LOW so other plugins can work with the blocks. - * The other plugins were EZBlock & SellAll. This function was canceling the - * event after it auto picked it up, so the other plugins were not registering - * the blocks as being broken. - *

- * - * - */ - public void onBlockBreak(BlockBreakEvent e) { - - genericBlockEventAutoManager( e, !isBoolean(AutoFeatures.isAutoManagerEnabled) ); - } - - /** - *

The use of e.getBlock != null is added to "use" the BlockShredEvent to prevent - * the complier from falsely triggering a Not Used warning. - *

- */ - public void onBlockShredBreak(BlockShredEvent e) { - - genericBlockEventAutoManager( e, !( isBoolean(AutoFeatures.isAutoManagerEnabled) && e.getBlock() != null ) ); - } - -// @EventHandler(priority=EventPriority.LOW) -// public void onTEBlockExplodeLow(TEBlockExplodeEvent e) { -// if ( !e.isCancelled() ) { -// -// genericBlockExplodeEventAutoManager( e, !isBoolean(AutoFeatures.isAutoManagerEnabled) ); -// } -// } -// - - - public void onCrazyEnchantsBlockExplodeLow( Object obj ) { - BlastUseEvent e = (BlastUseEvent) obj; - if ( !e.isCancelled() ) { - genericBlockExplodeEventAutoManager( e, !isBoolean(AutoFeatures.isAutoManagerEnabled) ); - } - } - - - - public class AutoManagerEventListenerLowest - extends AutoManager - implements Listener { - - @EventHandler(priority=EventPriority.LOWEST) - public void onBlockBreak(BlockBreakEvent e) { - super.onBlockBreak( e ); - } - -// @EventHandler(priority=EventPriority.LOWEST) -// public void onBlockShredBreak(BlockShredEvent e) { -// super.onBlockShredBreak( e ); -// } - } - - public class AutoManagerEventListenerLow - extends AutoManager - implements Listener { - - @EventHandler(priority=EventPriority.LOW) - public void onBlockBreak(BlockBreakEvent e) { - super.onBlockBreak( e ); - } - -// @EventHandler(priority=EventPriority.LOW) -// public void onBlockShredBreak(BlockShredEvent e) { -// super.onBlockShredBreak( e ); -// } - } - - public class AutoManagerEventListenerNormal - extends AutoManager - implements Listener { - - @EventHandler(priority=EventPriority.NORMAL) - public void onBlockBreak(BlockBreakEvent e) { - super.onBlockBreak( e ); - } - -// @EventHandler(priority=EventPriority.NORMAL) -// public void onBlockShredBreak(BlockShredEvent e) { -// super.onBlockShredBreak( e ); -// } - } - - public class AutoManagerEventListenerHigh - extends AutoManager - implements Listener { - - @EventHandler(priority=EventPriority.HIGH) - public void onBlockBreak(BlockBreakEvent e) { - super.onBlockBreak( e ); - } - -// @EventHandler(priority=EventPriority.HIGH) -// public void onBlockShredBreak(BlockShredEvent e) { -// super.onBlockShredBreak( e ); -// } - } - - public class AutoManagerEventListenerHighest - extends AutoManager - implements Listener { - - @EventHandler(priority=EventPriority.HIGHEST) - public void onBlockBreak(BlockBreakEvent e) { - super.onBlockBreak( e ); - } - -// @EventHandler(priority=EventPriority.HIGHEST) -// public void onBlockShredBreak(BlockShredEvent e) { -// super.onBlockShredBreak( e ); -// } - } - - - - -// -// public class AutoManagerBlockShredEventListenerMonitor -// extends AutoManager -// implements Listener { -// -// @EventHandler(priority=EventPriority.MONITOR) -// public void onBlockShredBreakMonitor(BlockShredEvent e) { -// super.genericBlockEventMonitor( e ); -// } -// } -// -// public class AutoManagerBlockShredEventListenerLowest -// extends AutoManager -// implements Listener { -// -// @EventHandler(priority=EventPriority.LOWEST) -// public void onBlockShredBreak(BlockShredEvent e) { -// super.onBlockShredBreak( e ); -// } -// } -// -// public class AutoManagerBlockShredEventListenerLow -// extends AutoManager -// implements Listener { -// -// @EventHandler(priority=EventPriority.LOW) -// public void onBlockShredBreak(BlockShredEvent e) { -// super.onBlockShredBreak( e ); -// } -// } -// -// public class AutoManagerBlockShredEventListenerNormal -// extends AutoManager -// implements Listener { -// -// @EventHandler(priority=EventPriority.NORMAL) -// public void onBlockShredBreak(BlockShredEvent e) { -// super.onBlockShredBreak( e ); -// } -// } -// -// public class AutoManagerBlockShredEventListenerHigh -// extends AutoManager -// implements Listener { -// -// @EventHandler(priority=EventPriority.HIGH) -// public void onBlockShredBreak(BlockShredEvent e) { -// super.onBlockShredBreak( e ); -// } -// } -// -// public class AutoManagerBlockShredEventListenerHighest -// extends AutoManager -// implements Listener { -// -// @EventHandler(priority=EventPriority.HIGHEST) -// public void onBlockShredBreak(BlockShredEvent e) { -// super.onBlockShredBreak( e ); -// } -// } - - - -} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerCrazyEnchants.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerCrazyEnchants.java deleted file mode 100644 index 8faaa8ed3..000000000 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerCrazyEnchants.java +++ /dev/null @@ -1,137 +0,0 @@ -package tech.mcprison.prison.spigot.autofeatures; - -import org.bukkit.Bukkit; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; - -import me.badbones69.crazyenchantments.api.events.BlastUseEvent; -import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; -import tech.mcprison.prison.output.Output; -import tech.mcprison.prison.spigot.SpigotPrison; -import tech.mcprison.prison.spigot.block.OnBlockBreakEventListener.BlockBreakPriority; - -public class AutoManagerCrazyEnchants - extends AutoManagerFeatures -{ - - public AutoManagerCrazyEnchants() { - super(); - } - - public void registerBlastUseEvents( SpigotPrison spigotPrison ) { - - boolean isCEBlockExplodeEnabled = isBoolean( AutoFeatures.isProcessCrazyEnchantsBlockExplodeEvents ); - - if ( !isCEBlockExplodeEnabled ) { - return; - } - - // Check to see if the class BlastUseEvent even exists: - try { - Output.get().logInfo( "AutoManager: checking if loaded: CrazyEnchants" ); - - Class.forName( "me.badbones69.crazyenchantments.api.events.BlastUseEvent", false, - this.getClass().getClassLoader() ); - - Output.get().logInfo( "AutoManager: Trying to register CrazyEnchants" ); - - String cePriority = getMessage( AutoFeatures.CrazyEnchantsBlastUseEventPriority ); - BlockBreakPriority crazyEnchantsPriority = BlockBreakPriority.fromString( cePriority ); - - switch ( crazyEnchantsPriority ) - { - case LOWEST: - Bukkit.getPluginManager().registerEvents( - new AutoManagerBlastUseEventListenerLowest(), spigotPrison); - break; - - case LOW: - Bukkit.getPluginManager().registerEvents( - new AutoManagerBlastUseEventListenerLow(), spigotPrison); - break; - - case NORMAL: - Bukkit.getPluginManager().registerEvents( - new AutoManagerBlastUseEventListenerNormal(), spigotPrison); - break; - - case HIGH: - Bukkit.getPluginManager().registerEvents( - new AutoManagerBlastUseEventListenerHigh(), spigotPrison); - break; - - case HIGHEST: - Bukkit.getPluginManager().registerEvents( - new AutoManagerBlastUseEventListenerHighest(), spigotPrison); - break; - case DISABLED: - Output.get().logInfo( "AutoManager Crazy Enchant's BlastUseEvent handling has been DISABLED." ); - break; - - - default: - break; - } - - } - catch ( ClassNotFoundException e ) { - // CrazyEnchants is not loaded... so ignore. - Output.get().logInfo( "AutoManager: CrazyEnchants is not loaded" ); - } - } - - - - public class AutoManagerBlastUseEventListenerLowest - extends AutoManager - implements Listener { - - @EventHandler(priority=EventPriority.LOWEST) - public void onCrazyEnchantsBlockExplodeLow(BlastUseEvent e) { - super.onCrazyEnchantsBlockExplodeLow( e ); - } - } - - public class AutoManagerBlastUseEventListenerLow - extends AutoManager - implements Listener { - - @EventHandler(priority=EventPriority.LOW) - public void onCrazyEnchantsBlockExplodeLow(BlastUseEvent e) { - super.onCrazyEnchantsBlockExplodeLow( e ); - } - } - - public class AutoManagerBlastUseEventListenerNormal - extends AutoManager - implements Listener { - - @EventHandler(priority=EventPriority.NORMAL) - public void onCrazyEnchantsBlockExplodeLow(BlastUseEvent e) { - super.onCrazyEnchantsBlockExplodeLow( e ); - } - } - - public class AutoManagerBlastUseEventListenerHigh - extends AutoManager - implements Listener { - - @EventHandler(priority=EventPriority.HIGH) - public void onCrazyEnchantsBlockExplodeLow(BlastUseEvent e) { - super.onCrazyEnchantsBlockExplodeLow( e ); - } - } - - public class AutoManagerBlastUseEventListenerHighest - extends AutoManager - implements Listener { - - @EventHandler(priority=EventPriority.HIGHEST) - public void onCrazyEnchantsBlockExplodeLow(BlastUseEvent e) { - super.onCrazyEnchantsBlockExplodeLow( e ); - } - } - - -} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java index ad138370e..6a913240f 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerFeatures.java @@ -37,8 +37,8 @@ import tech.mcprison.prison.spigot.block.OnBlockBreakEventCore; import tech.mcprison.prison.spigot.block.SpigotBlock; import tech.mcprison.prison.spigot.block.SpigotItemStack; -import tech.mcprison.prison.spigot.game.SpigotPlayer; import tech.mcprison.prison.spigot.commands.PrisonSpigotSellAllCommands; +import tech.mcprison.prison.spigot.game.SpigotPlayer; import tech.mcprison.prison.spigot.spiget.BluesSpigetSemVerComparator; import tech.mcprison.prison.util.BlockType; import tech.mcprison.prison.util.Text; @@ -155,9 +155,9 @@ protected short getFortune(SpigotItemStack itemInHand){ @Override - public boolean doAction( SpigotBlock block, Mine mine, Player player ) { + public boolean doAction( SpigotBlock block, Mine mine, Player player, StringBuilder debugInfo ) { - return applyAutoEvents( block, player, mine ); + return processAutoEvents( block, player, mine, debugInfo ); } @@ -169,16 +169,18 @@ public boolean doAction( SpigotBlock block, Mine mine, Player player ) { */ @Override public boolean doAction( Mine mine, Player player, List explodedBlocks, - BlockEventType blockEventType, String triggered ) { - return applyAutoEvents( player, mine, explodedBlocks, blockEventType, triggered ); + BlockEventType blockEventType, String triggered, + StringBuilder debugInfo ) { + return applyAutoEvents( player, mine, explodedBlocks, blockEventType, triggered, debugInfo ); } - private boolean applyAutoEvents( SpigotBlock spigotBlock, Player player, Mine mine) { + private boolean processAutoEvents( SpigotBlock spigotBlock, Player player, Mine mine, StringBuilder debugInfo ) { boolean cancel = false; - if (isBoolean(AutoFeatures.isAutoManagerEnabled) && - !spigotBlock.isEmpty() ) { + if (isBoolean(AutoFeatures.isAutoManagerEnabled) && !spigotBlock.isEmpty() ) { + + debugInfo.append( "(processAutoEvent) " ); // Output.get().logInfo( "#### AutoManager.applyAutoEvents: BlockBreakEvent: :: " + mine.getName() + " " + // " blocks remaining= " + @@ -187,18 +189,16 @@ private boolean applyAutoEvents( SpigotBlock spigotBlock, Player player, Mine mi SpigotItemStack itemInHand = SpigotPrison.getInstance().getCompatibility().getPrisonItemInMainHand( player ); - int count = applyAutoEvents( player, spigotBlock, mine ); + int count = applyAutoEvents( player, spigotBlock, mine, debugInfo ); if ( count > 0 ) { processBlockBreakage( spigotBlock, mine, player, count, BlockEventType.blockBreak, - null, itemInHand ); + null, itemInHand, true, debugInfo ); cancel = true; } - if ( mine != null ) { - checkZeroBlockReset( mine ); - } + checkZeroBlockReset( mine ); } @@ -208,7 +208,7 @@ private boolean applyAutoEvents( SpigotBlock spigotBlock, Player player, Mine mi - private int applyAutoEvents( Player player, SpigotBlock block, Mine mine ) { + private int applyAutoEvents( Player player, SpigotBlock block, Mine mine, StringBuilder debugInfo ) { int count = 0; SpigotItemStack itemInHand = SpigotPrison.getInstance().getCompatibility().getPrisonItemInMainHand( player ); @@ -220,20 +220,62 @@ private int applyAutoEvents( Player player, SpigotBlock block, Mine mine ) { boolean loreSmelt = isLoreEnabled && checkLore( itemInHand, getMessage( AutoFeatures.loreSmeltValue) ); boolean loreBlock = isLoreEnabled && checkLore( itemInHand, getMessage( AutoFeatures.loreBlockValue ) ); + boolean permPickup = player.isPermissionSet( getMessage( AutoFeatures.permissionAutoPickup )); + boolean permSmelt = player.isPermissionSet( getMessage( AutoFeatures.permissionAutoSmelt )); + boolean permBlock = player.isPermissionSet( getMessage( AutoFeatures.permissionAutoBlock )); + + boolean configPickup = isBoolean( AutoFeatures.autoPickupEnabled ); + boolean configSmelt = isBoolean( AutoFeatures.autoSmeltEnabled ); + boolean configBlock = isBoolean( AutoFeatures.autoBlockEnabled ); - boolean isAutoPickup = lorePickup || isBoolean( AutoFeatures.autoPickupEnabled ) || - player.isPermissionSet( getMessage( AutoFeatures.permissionAutoPickup )); + boolean limit2minesPickup = isBoolean( AutoFeatures.pickupLimitToMines ); + boolean limit2minesSmelt = isBoolean( AutoFeatures.smeltLimitToMines ); + boolean limit2minesBlock = isBoolean( AutoFeatures.blockLimitToMines ); - boolean isAutoSmelt = loreSmelt || isBoolean( AutoFeatures.autoSmeltEnabled ) || - player.isPermissionSet( getMessage( AutoFeatures.permissionAutoPickup )); - isAutoSmelt = (mine != null || mine == null && !isBoolean( AutoFeatures.smeltLimitToMines )) && - isAutoSmelt; + boolean isAutoPickup = lorePickup || configPickup || permPickup; - boolean isAutoBlock = loreBlock || isBoolean( AutoFeatures.autoBlockEnabled ) || - player.isPermissionSet( getMessage( AutoFeatures.permissionAutoBlock )); - isAutoBlock = (mine != null || mine == null && !isBoolean( AutoFeatures.autoBlockLimitToMines )) && - isAutoBlock; + isAutoPickup = (mine != null || mine == null && !limit2minesPickup) && isAutoPickup; + boolean isAutoSmelt = loreSmelt || configSmelt || permSmelt; + + isAutoSmelt = (mine != null || mine == null && !limit2minesSmelt) && isAutoSmelt; + + boolean isAutoBlock = loreBlock || configBlock || permBlock; + + isAutoBlock = (mine != null || mine == null && !limit2minesBlock) && isAutoBlock; + + if ( Output.get().isDebug( DebugTarget.blockBreak ) ) { + + debugInfo.append( "(applyAutoEvents: " ) + .append( block.getBlockName() ) + + .append( " Pickup [") + .append( isAutoPickup ? "enabled: " : "disabled:" ) + .append( lorePickup ? "lore " : "" ) + .append( permPickup ? "perm " : "" ) + .append( configPickup ? "config " : "" ) + .append( limit2minesPickup ? "limit2mines" : "noLimit" ) + .append( "] ") + + .append( " Smelt [") + .append( isAutoSmelt ? "enabled: " : "disabled:" ) + .append( loreSmelt ? "lore " : "" ) + .append( permSmelt ? "perm " : "" ) + .append( configSmelt ? "config " : "" ) + .append( limit2minesSmelt ? "limit2mines" : "noLimit" ) + .append( "] ") + + .append( " Block [") + .append( isAutoBlock ? "enabled: " : "disabled:" ) + .append( loreBlock ? "lore " : "" ) + .append( permBlock ? "perm " : "" ) + .append( configBlock ? "config " : "" ) + .append( limit2minesBlock ? "limit2mines" : "noLimit" ) + .append( "] ") + + + .append( ")" ); + } // NOTE: Using isPermissionSet so players that are op'd to not auto enable everything. // Ops will have to have the perms set to actually use them. @@ -242,7 +284,7 @@ private int applyAutoEvents( Player player, SpigotBlock block, Mine mine ) { if ( (mine != null || mine == null && !isBoolean( AutoFeatures.pickupLimitToMines )) && isAutoPickup ) { - count = autoFeaturePickup( block, player, itemInHand, isAutoSmelt, isAutoBlock ); + count = autoFeaturePickup( block, player, itemInHand, isAutoSmelt, isAutoBlock, debugInfo ); // Cannot set to air yet, or auto smelt and auto block will only get AIR: // autoPickupCleanup( block, count ); @@ -321,26 +363,31 @@ private int applyAutoEvents( Player player, SpigotBlock block, Mine mine ) { */ private boolean applyAutoEvents( Player player, Mine mine, List explodedBlocks, BlockEventType blockEventType, - String triggered ) { + String triggered, StringBuilder debugInfo ) { boolean cancel = false; int totalCount = 0; - SpigotItemStack itemInHand = SpigotPrison.getInstance().getCompatibility().getPrisonItemInMainHand( player ); + SpigotItemStack itemInHand = SpigotPrison.getInstance().getCompatibility() + .getPrisonItemInMainHand( player ); + debugInfo.append( "(applyAutoEvents multi-blocks: " + explodedBlocks.size() ); // The explodedBlocks list have already been validated as being within the mine: + boolean applyExhaustion = true; for ( SpigotBlock spigotBlock : explodedBlocks ) { if ( spigotBlock != null && !spigotBlock.isEmpty() ) { - int drop = applyAutoEvents( player, spigotBlock, mine ); + int drop = applyAutoEvents( player, spigotBlock, mine, debugInfo ); totalCount += drop; if ( drop > 0 ) { processBlockBreakage( spigotBlock, mine, player, drop, - blockEventType, triggered, itemInHand ); + blockEventType, triggered, itemInHand, + applyExhaustion, debugInfo ); + applyExhaustion = false; } } } @@ -365,78 +412,83 @@ private boolean applyAutoEvents( Player player, Mine mine, * For older versions, a good way to get the right drops would be to use * BlockDropItemEvent.getItems(), but it's deprecated * */ - protected int autoPickup( boolean autoPickup, Player player, + protected int autoPickup( Player player, SpigotItemStack itemInHand, SpigotBlock block, - boolean isAutoSmelt, boolean isAutoBlock ) { + boolean isAutoSmelt, boolean isAutoBlock, StringBuilder debugInfo ) { //, BlockBreakEvent e ) { int count = 0; - if (autoPickup) { - - // The following may not be the correct drops for all versions of spigot, - // plus there are some extra items, such as flint, that will never be dropped. - List drops = new ArrayList<>( SpigotUtil.getDrops(block, itemInHand) ); + // The following may not be the correct drops for all versions of spigot, + // plus there are some extra items, such as flint, that will never be dropped. + List drops = new ArrayList<>( SpigotUtil.getDrops(block, itemInHand) ); + + + if (drops != null && drops.size() > 0 ) { - if (drops != null && drops.size() > 0 ) { - - // Need better drop calculation that is not using the getDrops function. + // Need better drop calculation that is not using the getDrops function. + + calculateSilkTouch( itemInHand, drops ); + + // Adds in additional drop items: Add Flint with gravel drops: + calculateDropAdditions( itemInHand, drops ); + + + // Add fortune to the items in the inventory + if ( isBoolean( AutoFeatures.isCalculateFortuneEnabled ) ) { short fortuneLevel = getFortune(itemInHand); - calculateSilkTouch( itemInHand, drops ); + debugInfo.append( "(calculateFortune: fort " + fortuneLevel + ")" ); - // Adds in additional drop items: Add Flint with gravel drops: - calculateDropAdditions( itemInHand, drops ); - - - // Add fortune to the items in the inventory - if ( isBoolean( AutoFeatures.isCalculateFortuneEnabled ) ) { - - for ( SpigotItemStack itemStack : drops ) { - - // calculateFortune directly modifies the quantity on the blocks ItemStack: - calculateFortune( itemStack, fortuneLevel ); - } - } - - - // NOTE: This should be done after applying fortune, otherwise it will get misreadings. - // Merge drops so each item is only represented once before adding to the player's inventory - drops = mergeDrops( drops ); - - - // Smelt - if ( isAutoSmelt ) { - normalDropSmelt( drops ); + for ( SpigotItemStack itemStack : drops ) { + + // calculateFortune directly modifies the quantity on the blocks ItemStack: + calculateFortune( itemStack, fortuneLevel ); } + } + + + // NOTE: This should be done after applying fortune, otherwise it will get misreadings. + // Merge drops so each item is only represented once before adding to the player's inventory + drops = mergeDrops( drops ); + + + // Smelt + if ( isAutoSmelt ) { + debugInfo.append( "(smelting: itemStacks)" ); + normalDropSmelt( drops ); + } + + + // Block + if ( isAutoBlock ) { + debugInfo.append( "(blocking: itemStacks)" ); + normalDropBlock( drops ); + } + + + for ( SpigotItemStack itemStack : drops ) { + count += itemStack.getAmount(); - // Block - if ( isAutoBlock ) { - normalDropBlock( drops ); - } + HashMap extras = SpigotUtil.addItemToPlayerInventory( player, itemStack ); - - for ( SpigotItemStack itemStack : drops ) { - - count += itemStack.getAmount(); - - HashMap extras = SpigotUtil.addItemToPlayerInventory( player, itemStack ); - - dropExtra( extras, player ); + dropExtra( extras, player ); // dropExtra( player.getInventory().addItem(itemStack), player, block ); - - } - - autosellPerBlockBreak( player ); -// autoPickupCleanup( player, itemInHand, count ); } + + autosellPerBlockBreak( player ); + +// autoPickupCleanup( player, itemInHand, count ); } return count; } + + + public int calculateNormalDrop( SpigotItemStack itemInHand, SpigotBlock block ) { int count = 0; @@ -527,15 +579,34 @@ public void playerSmelt( SpigotPlayer player ) { smelts.add( XMaterial.COBBLESTONE ); smelts.add( XMaterial.GOLD_ORE ); smelts.add( XMaterial.NETHER_GOLD_ORE ); + smelts.add( XMaterial.DEEPSLATE_GOLD_ORE ); + smelts.add( XMaterial.RAW_GOLD ); + smelts.add( XMaterial.IRON_ORE ); + smelts.add( XMaterial.DEEPSLATE_IRON_ORE ); + smelts.add( XMaterial.RAW_IRON ); + smelts.add( XMaterial.COAL_ORE ); + smelts.add( XMaterial.DEEPSLATE_COAL_ORE ); + smelts.add( XMaterial.DIAMOND_ORE ); + smelts.add( XMaterial.DEEPSLATE_DIAMOND_ORE ); + smelts.add( XMaterial.EMERALD_ORE ); + smelts.add( XMaterial.DEEPSLATE_EMERALD_ORE ); + smelts.add( XMaterial.LAPIS_ORE ); + smelts.add( XMaterial.DEEPSLATE_LAPIS_ORE ); + smelts.add( XMaterial.REDSTONE_ORE ); + smelts.add( XMaterial.DEEPSLATE_REDSTONE_ORE ); + smelts.add( XMaterial.NETHER_QUARTZ_ORE ); smelts.add( XMaterial.ANCIENT_DEBRIS ); + smelts.add( XMaterial.COPPER_ORE ); + smelts.add( XMaterial.DEEPSLATE_COPPER_ORE ); + smelts.add( XMaterial.RAW_COPPER ); for ( XMaterial xMat : smelts ) { @@ -960,10 +1031,11 @@ protected double getLoreValue( SpigotItemStack itemInHand, String loreValue ) { * @param block * @param p * @param itemInHand + * @param debugInfo * @return */ protected int autoFeaturePickup( SpigotBlock block, Player p, SpigotItemStack itemInHand, - boolean isAutoSmelt, boolean isAutoBlock ) { + boolean isAutoSmelt, boolean isAutoBlock, StringBuilder debugInfo ) { int count = 0; @@ -975,14 +1047,14 @@ protected int autoFeaturePickup( SpigotBlock block, Player p, SpigotItemStack it isBoolean( AutoFeatures.pickupBlockNameListEnabled ) ? getListString( AutoFeatures.pickupBlockNameList ) : null; - if (isBoolean(AutoFeatures.pickupAllBlocks)) { - count += autoPickup( true, p, itemInHand, block, isAutoSmelt, isAutoBlock ); + if ( isAll ) { + count += autoPickup( p, itemInHand, block, isAutoSmelt, isAutoBlock, debugInfo ); } else if ( isBoolean( AutoFeatures.pickupBlockNameListEnabled ) && pickupBlockNameList.size() > 0 && pickupBlockNameList.contains( prisonBlock.getBlockName() ) ) { - count += autoPickup( true, p, itemInHand, block, isAutoSmelt, isAutoBlock ); + count += autoPickup( p, itemInHand, block, isAutoSmelt, isAutoBlock, debugInfo ); } else { @@ -990,55 +1062,70 @@ else if ( isBoolean( AutoFeatures.pickupBlockNameListEnabled ) && pickupBlockNam switch ( prisonBlock.getBlockName() ) { case "cobblestone": - count += autoPickup( isAll || isBoolean( AutoFeatures.pickupCobbleStone ), p, itemInHand, block, isAutoSmelt, isAutoBlock ); + count += autoPickup( p, itemInHand, block, isAutoSmelt, isAutoBlock, debugInfo ); break; case "stone": - count += autoPickup( isAll || isBoolean( AutoFeatures.pickupStone ), p, itemInHand, block, isAutoSmelt, isAutoBlock ); + count += autoPickup( p, itemInHand, block, isAutoSmelt, isAutoBlock, debugInfo ); break; case "gold_ore": - count += autoPickup( isAll || isBoolean( AutoFeatures.pickupGoldOre ), p, itemInHand, block, isAutoSmelt, isAutoBlock ); + case "nether_gold_ore": + case "deepslate_gold_ore": + case "raw_gold": + count += autoPickup( p, itemInHand, block, isAutoSmelt, isAutoBlock, debugInfo ); break; case "iron_ore": - count += autoPickup( isAll || isBoolean( AutoFeatures.pickupIronOre ), p, itemInHand, block, isAutoSmelt, isAutoBlock ); + case "deepslate_iron_ore": + case "raw_iron": + count += autoPickup( p, itemInHand, block, isAutoSmelt, isAutoBlock, debugInfo ); break; case "coal_ore": - count += autoPickup( isAll || isBoolean( AutoFeatures.pickupCoalOre ), p, itemInHand, block, isAutoSmelt, isAutoBlock ); + case "deepslate_coal_ore": + count += autoPickup( p, itemInHand, block, isAutoSmelt, isAutoBlock, debugInfo ); break; case "diamond_ore": - count += autoPickup( isAll || isBoolean( AutoFeatures.pickupDiamondOre ), p, itemInHand, block, isAutoSmelt, isAutoBlock ); + case "deepslate_diamond_ore": + count += autoPickup( p, itemInHand, block, isAutoSmelt, isAutoBlock, debugInfo ); break; case "redstone_ore": - count += autoPickup( isAll || isBoolean( AutoFeatures.pickupRedStoneOre ), p, itemInHand, block, isAutoSmelt, isAutoBlock ); + case "deepslate_redstone_ore": + count += autoPickup( p, itemInHand, block, isAutoSmelt, isAutoBlock, debugInfo ); break; case "emerald_ore": - count += autoPickup( isAll || isBoolean( AutoFeatures.pickupEmeraldOre ), p, itemInHand, block, isAutoSmelt, isAutoBlock ); + case "deepslate_emerald_ore": + count += autoPickup( p, itemInHand, block, isAutoSmelt, isAutoBlock, debugInfo ); break; case "quartz_ore": - count += autoPickup( isAll || isBoolean( AutoFeatures.pickupQuartzOre ), p, itemInHand, block, isAutoSmelt, isAutoBlock ); + count += autoPickup( p, itemInHand, block, isAutoSmelt, isAutoBlock, debugInfo ); break; case "lapis_ore": - count += autoPickup( isAll || isBoolean( AutoFeatures.pickupLapisOre ), p, itemInHand, block, isAutoSmelt, isAutoBlock ); + case "deepslate_lapis_ore": + count += autoPickup( p, itemInHand, block, isAutoSmelt, isAutoBlock, debugInfo ); break; case "snow_ball": - count += autoPickup( isAll || isBoolean( AutoFeatures.pickupSnowBall ), p, itemInHand, block, isAutoSmelt, isAutoBlock ); + count += autoPickup( p, itemInHand, block, isAutoSmelt, isAutoBlock, debugInfo ); break; case "glowstone_dust": // works 1.15.2 - count += autoPickup( isAll || isBoolean( AutoFeatures.pickupGlowstoneDust ), p, itemInHand, block, isAutoSmelt, isAutoBlock ); + count += autoPickup( p, itemInHand, block, isAutoSmelt, isAutoBlock, debugInfo ); break; + case "copper_ore": + case "deepslate_copper_ore": + case "raw_copper": + count += autoPickup( p, itemInHand, block, isAutoSmelt, isAutoBlock, debugInfo ); + break; + default: - count += autoPickup(isAll, p, itemInHand, block, isAutoSmelt, isAutoBlock ); break; } } @@ -1056,6 +1143,7 @@ else if ( isBoolean( AutoFeatures.pickupBlockNameListEnabled ) && pickupBlockNam return count; } + protected XMaterial autoFeatureSmelt( Player p, XMaterial source ) { XMaterial results = source; @@ -1074,36 +1162,45 @@ protected XMaterial autoFeatureSmelt( Player p, XMaterial source ) case GOLD_ORE: case NETHER_GOLD_ORE: + case DEEPSLATE_GOLD_ORE: + case RAW_GOLD: autoSmelt( isAll || isBoolean( AutoFeatures.smeltGoldOre ), source, XMaterial.GOLD_INGOT, p ); results = XMaterial.GOLD_INGOT; break; case IRON_ORE: + case DEEPSLATE_IRON_ORE: + case RAW_IRON: autoSmelt( isAll || isBoolean( AutoFeatures.smeltIronOre ), source, XMaterial.IRON_INGOT, p ); results = XMaterial.IRON_INGOT; break; case COAL_ORE: + case DEEPSLATE_COAL_ORE: autoSmelt( isAll || isBoolean( AutoFeatures.smeltCoalOre ), source, XMaterial.COAL, p ); results = XMaterial.COAL; break; case DIAMOND_ORE: + case DEEPSLATE_DIAMOND_ORE: autoSmelt( isAll || isBoolean( AutoFeatures.smeltDiamondlOre ), source, XMaterial.DIAMOND, p ); results = XMaterial.DIAMOND; break; case EMERALD_ORE: + case DEEPSLATE_EMERALD_ORE: autoSmelt( isAll || isBoolean( AutoFeatures.smeltEmeraldOre ), source, XMaterial.EMERALD, p ); results = XMaterial.EMERALD; break; case LAPIS_ORE: + case DEEPSLATE_LAPIS_ORE: autoSmelt( isAll || isBoolean( AutoFeatures.smeltLapisOre ), source, XMaterial.LAPIS_LAZULI, p ); results = XMaterial.LAPIS_LAZULI; break; case REDSTONE_ORE: + case DEEPSLATE_REDSTONE_ORE: autoSmelt( isAll || isBoolean( AutoFeatures.smeltRedstoneOre ), source, XMaterial.REDSTONE, p ); results = XMaterial.REDSTONE; break; @@ -1120,6 +1217,8 @@ protected XMaterial autoFeatureSmelt( Player p, XMaterial source ) // v1.17 !! case COPPER_ORE: + case DEEPSLATE_COPPER_ORE: + case RAW_COPPER: autoSmelt( isAll || isBoolean( AutoFeatures.smeltCopperOre ), source, XMaterial.COPPER_INGOT, p ); results = XMaterial.COPPER_INGOT; break; @@ -1145,62 +1244,62 @@ protected void autoFeatureBlock( Player p, XMaterial source ) { switch ( source ) { case GOLD_INGOT: - autoBlock( isAll || isBoolean( AutoFeatures.autoBlockGoldBlock ), source, XMaterial.GOLD_BLOCK, p ); + autoBlock( isAll || isBoolean( AutoFeatures.blockGoldBlock ), source, XMaterial.GOLD_BLOCK, p ); break; case IRON_INGOT: - autoBlock( isAll || isBoolean( AutoFeatures.autoBlockIronBlock ), source, XMaterial.IRON_BLOCK, p ); + autoBlock( isAll || isBoolean( AutoFeatures.blockIronBlock ), source, XMaterial.IRON_BLOCK, p ); break; case COAL: - autoBlock( isAll || isBoolean( AutoFeatures.autoBlockCoalBlock ), source, XMaterial.COAL_BLOCK, p ); + autoBlock( isAll || isBoolean( AutoFeatures.blockCoalBlock ), source, XMaterial.COAL_BLOCK, p ); break; case DIAMOND: - autoBlock( isAll || isBoolean( AutoFeatures.autoBlockDiamondBlock ), source, XMaterial.DIAMOND_BLOCK, p ); + autoBlock( isAll || isBoolean( AutoFeatures.blockDiamondBlock ), source, XMaterial.DIAMOND_BLOCK, p ); break; case REDSTONE: - autoBlock( isAll || isBoolean( AutoFeatures.autoBlockRedstoneBlock ), source,XMaterial.REDSTONE_BLOCK, p ); + autoBlock( isAll || isBoolean( AutoFeatures.blockRedstoneBlock ), source,XMaterial.REDSTONE_BLOCK, p ); break; case EMERALD: - autoBlock( isAll || isBoolean( AutoFeatures.autoBlockEmeraldBlock ), source, XMaterial.EMERALD_BLOCK, p ); + autoBlock( isAll || isBoolean( AutoFeatures.blockEmeraldBlock ), source, XMaterial.EMERALD_BLOCK, p ); break; case QUARTZ: - autoBlock( isAll || isBoolean( AutoFeatures.autoBlockQuartzBlock ), source, XMaterial.QUARTZ_BLOCK, 4, p ); + autoBlock( isAll || isBoolean( AutoFeatures.blockQuartzBlock ), source, XMaterial.QUARTZ_BLOCK, 4, p ); break; case PRISMARINE_SHARD: - autoBlock( isAll || isBoolean( AutoFeatures.autoBlockPrismarineBlock ), source, XMaterial.PRISMARINE, 4, p ); + autoBlock( isAll || isBoolean( AutoFeatures.blockPrismarineBlock ), source, XMaterial.PRISMARINE, 4, p ); break; case SNOWBALL: - autoBlock( isAll || isBoolean( AutoFeatures.autoBlockSnowBlock ), source, XMaterial.SNOW_BLOCK, 4, p ); + autoBlock( isAll || isBoolean( AutoFeatures.blockSnowBlock ), source, XMaterial.SNOW_BLOCK, 4, p ); break; case GLOWSTONE_DUST: - autoBlock( isAll || isBoolean( AutoFeatures.autoBlockGlowstone ), source, XMaterial.GLOWSTONE, 4, p ); + autoBlock( isAll || isBoolean( AutoFeatures.blockGlowstone ), source, XMaterial.GLOWSTONE, 4, p ); break; case LAPIS_LAZULI: - autoBlock( isAll || isBoolean( AutoFeatures.autoBlockLapisBlock ), source, XMaterial.LAPIS_BLOCK, p ); + autoBlock( isAll || isBoolean( AutoFeatures.blockLapisBlock ), source, XMaterial.LAPIS_BLOCK, p ); break; case COPPER_INGOT: - autoBlock( isAll || isBoolean( AutoFeatures.autoBlockCopperBlock ), source, XMaterial.COPPER_BLOCK, p ); + autoBlock( isAll || isBoolean( AutoFeatures.blockCopperBlock ), source, XMaterial.COPPER_BLOCK, p ); break; @@ -1221,6 +1320,8 @@ protected void autoFeatureBlock( Player p, XMaterial source ) { */ protected void normalDropSmelt( List drops ) { + boolean isAll = isBoolean( AutoFeatures.smeltAllBlocks ); + Set xMats = new HashSet<>(); for ( SpigotItemStack sItemStack : drops ) { XMaterial source = XMaterial.matchXMaterial( sItemStack.getBukkitStack() ); @@ -1237,49 +1338,94 @@ protected void normalDropSmelt( List drops ) { switch ( source ) { case COBBLESTONE: - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.STONE, 1 ); + if ( isAll || isBoolean( AutoFeatures.smeltCobblestone ) ) { + + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.STONE, 1 ); + } break; case GOLD_ORE: case NETHER_GOLD_ORE: - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.GOLD_INGOT, 1 ); + case DEEPSLATE_GOLD_ORE: + case RAW_GOLD: + + if ( isAll || isBoolean( AutoFeatures.smeltGoldOre ) ) { + + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.GOLD_INGOT, 1 ); + } break; case IRON_ORE: - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.IRON_INGOT, 1 ); + case DEEPSLATE_IRON_ORE: + case RAW_IRON: + if ( isAll || isBoolean( AutoFeatures.smeltIronOre ) ) { + + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.IRON_INGOT, 1 ); + } break; case COAL_ORE: - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.COAL,11 ); + case DEEPSLATE_COAL_ORE: + if ( isAll || isBoolean( AutoFeatures.smeltCoalOre ) ) { + + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.COAL,11 ); + } break; case DIAMOND_ORE: - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.DIAMOND, 1 ); + case DEEPSLATE_DIAMOND_ORE: + if ( isAll || isBoolean( AutoFeatures.smeltDiamondlOre ) ) { + + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.DIAMOND, 1 ); + } break; case EMERALD_ORE: - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.EMERALD, 1 ); + case DEEPSLATE_EMERALD_ORE: + if ( isAll || isBoolean( AutoFeatures.smeltEmeraldOre ) ) { + + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.EMERALD, 1 ); + } break; case LAPIS_ORE: - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.LAPIS_LAZULI, 1 ); + case DEEPSLATE_LAPIS_ORE: + if ( isAll || isBoolean( AutoFeatures.smeltLapisOre ) ) { + + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.LAPIS_LAZULI, 1 ); + } break; case REDSTONE_ORE: - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.REDSTONE, 1 ); + case DEEPSLATE_REDSTONE_ORE: + if ( isAll || isBoolean( AutoFeatures.smeltRedstoneOre ) ) { + + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.REDSTONE, 1 ); + } break; case NETHER_QUARTZ_ORE: - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.QUARTZ, 1 ); + if ( isAll || isBoolean( AutoFeatures.smeltNetherQuartzOre ) ) { + + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.QUARTZ, 1 ); + } break; case ANCIENT_DEBRIS: - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.NETHERITE_SCRAP, 1 ); + if ( isAll || isBoolean( AutoFeatures.smeltAncientDebris ) ) { + + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.NETHERITE_SCRAP, 1 ); + } break; // v1.17 !! case COPPER_ORE: - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.COPPER_INGOT, 1); + case DEEPSLATE_COPPER_ORE: + case RAW_COPPER: + if ( isAll || isBoolean( AutoFeatures.smeltCopperOre ) ) { + + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.COPPER_INGOT, 1); + } break; default: @@ -1299,6 +1445,8 @@ protected void normalDropSmelt( List drops ) { */ protected void normalDropBlock( List drops ) { + boolean isAll = isBoolean( AutoFeatures.smeltAllBlocks ); + Set xMats = new HashSet<>(); for ( SpigotItemStack sItemStack : drops ) { XMaterial source = XMaterial.matchXMaterial( sItemStack.getBukkitStack() ); @@ -1314,63 +1462,87 @@ protected void normalDropBlock( List drops ) { switch ( source ) { case GOLD_INGOT: - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.GOLD_BLOCK, 9 ); - + if ( isAll || isBoolean( AutoFeatures.blockGoldBlock ) ) { + + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.GOLD_BLOCK, 9 ); + } break; case IRON_INGOT: - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.IRON_BLOCK, 9 ); - + if ( isAll || isBoolean( AutoFeatures.blockIronBlock ) ) { + + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.IRON_BLOCK, 9 ); + } break; case COAL: - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.COAL_BLOCK, 9 ); - + if ( isAll || isBoolean( AutoFeatures.blockCoalBlock ) ) { + + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.COAL_BLOCK, 9 ); + } break; case DIAMOND: - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.DIAMOND_BLOCK, 9 ); - + if ( isAll || isBoolean( AutoFeatures.blockDiamondBlock ) ) { + + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.DIAMOND_BLOCK, 9 ); + } break; case REDSTONE: - SpigotUtil.itemStackReplaceItems( drops, source,XMaterial.REDSTONE_BLOCK, 9 ); - + if ( isAll || isBoolean( AutoFeatures.blockRedstoneBlock ) ) { + + SpigotUtil.itemStackReplaceItems( drops, source,XMaterial.REDSTONE_BLOCK, 9 ); + } break; case EMERALD: - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.EMERALD_BLOCK, 9 ); - + if ( isAll || isBoolean( AutoFeatures.blockEmeraldBlock ) ) { + + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.EMERALD_BLOCK, 9 ); + } break; case QUARTZ: - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.QUARTZ_BLOCK, 4 ); - + if ( isAll || isBoolean( AutoFeatures.blockQuartzBlock ) ) { + + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.QUARTZ_BLOCK, 4 ); + } break; case PRISMARINE_SHARD: - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.PRISMARINE, 4 ); - + if ( isAll || isBoolean( AutoFeatures.blockPrismarineBlock ) ) { + + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.PRISMARINE, 4 ); + } break; case SNOWBALL: - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.SNOW_BLOCK, 4 ); - + if ( isAll || isBoolean( AutoFeatures.blockSnowBlock ) ) { + + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.SNOW_BLOCK, 4 ); + } break; case GLOWSTONE_DUST: - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.GLOWSTONE, 4 ); - + if ( isAll || isBoolean( AutoFeatures.blockGlowstone ) ) { + + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.GLOWSTONE, 4 ); + } break; - case LAPIS_LAZULI: - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.LAPIS_BLOCK, 9 ); - + case LAPIS_LAZULI: + if ( isAll || isBoolean( AutoFeatures.blockLapisBlock ) ) { + + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.LAPIS_BLOCK, 9 ); + } break; - case COPPER_INGOT: - SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.COPPER_BLOCK, 9 ); - + case COPPER_INGOT: + if ( isAll || isBoolean( AutoFeatures.blockCopperBlock ) ) { + + SpigotUtil.itemStackReplaceItems( drops, source, XMaterial.COPPER_BLOCK, 9 ); + } break; default: @@ -1491,41 +1663,41 @@ protected void calculateFortune(SpigotItemStack blocks, int fortuneLevel) { // Due to variations with gold and wood PickAxe need to use a dynamic // Material name selection which will fit for the version of MC that is // being ran. - BlockType block = blocks.getMaterial(); + + XMaterial xMat = XMaterial.matchXMaterial( blocks.getBukkitStack() ); // These need to be processed first due to special drop amounts for these items, and // in the next group there is the isCalculateAltFortuneOnAllBlocksEnabled setting that // would override these values if it were to be processed first. - if ( block == BlockType.GLOWSTONE || - block == BlockType.GLOWSTONE_DUST || - block == BlockType.REDSTONE || - block == BlockType.SEA_LANTERN || - block == BlockType.GLOWING_REDSTONE_ORE || - block == BlockType.REDSTONE_ORE || - block == BlockType.PRISMARINE || + if ( xMat == XMaterial.GLOWSTONE || + xMat == XMaterial.GLOWSTONE_DUST || + xMat == XMaterial.REDSTONE || + xMat == XMaterial.SEA_LANTERN || + xMat == XMaterial.REDSTONE_ORE || + xMat == XMaterial.PRISMARINE || - block == BlockType.BEETROOT_SEEDS || - block == BlockType.CARROT || - block == BlockType.MELON || - block == BlockType.MELON_SEEDS || - block == BlockType.NETHER_WART || - block == BlockType.POTATO || - block == BlockType.GRASS || - block == BlockType.WHEAT ) { + xMat == XMaterial.BEETROOT_SEEDS || + xMat == XMaterial.CARROT || + xMat == XMaterial.MELON || + xMat == XMaterial.MELON_SEEDS || + xMat == XMaterial.NETHER_WART || + xMat == XMaterial.POTATO || + xMat == XMaterial.GRASS || + xMat == XMaterial.WHEAT ) { multiplier = getRandom().nextInt( fortuneLevel ); // limits slightly greater than standard: - if (block == BlockType.GLOWSTONE) { + if ( xMat == XMaterial.GLOWSTONE) { // standard: 4 if (multiplier > 5) { multiplier = 5; } - } else if (block == BlockType.SEA_LANTERN) { + } else if ( xMat == XMaterial.SEA_LANTERN) { // standard: 5 if (multiplier > 6) { multiplier = 6; } - } else if (block == BlockType.MELON) { + } else if ( xMat == XMaterial.MELON) { // standard: 9 if (multiplier > 11) { multiplier = 11; @@ -1548,34 +1720,54 @@ protected void calculateFortune(SpigotItemStack blocks, int fortuneLevel) { else if ( isBoolean( AutoFeatures.isCalculateAltFortuneOnAllBlocksEnabled ) || - block == BlockType.COAL_ORE || - block == BlockType.DIAMOND_ORE || - block == BlockType.EMERALD_ORE || - block == BlockType.IRON_ORE || - block == BlockType.LAPIS_LAZULI_ORE || - block == BlockType.LAPIS_ORE || - block == BlockType.GOLD_ORE || - block == BlockType.NETHER_GOLD_ORE || - block == BlockType.NETHER_QUARTZ_ORE || - block == BlockType.BLOCK_OF_COAL || - block == BlockType.COAL || - block == BlockType.COAL_BLOCK || - block == BlockType.DIAMOND || - block == BlockType.DIAMOND_BLOCK || - block == BlockType.EMERALD || - block == BlockType.EMERALD_BLOCK || - block == BlockType.GOLD_BLOCK || - block == BlockType.IRON_BLOCK || - block == BlockType.LAPIS_BLOCK || - block == BlockType.LAPIS_LAZULI_BLOCK || - block == BlockType.NETHER_WART_BLOCK || - block == BlockType.NETHERITE_BLOCK || - block == BlockType.PURPUR_BLOCK || - block == BlockType.QUARTZ_BLOCK || - block == BlockType.REDSTONE_BLOCK || - block == BlockType.SLIME_BLOCK || - block == BlockType.SNOW_BLOCK + xMat == XMaterial.GOLD_ORE || + xMat == XMaterial.NETHER_GOLD_ORE || + xMat == XMaterial.DEEPSLATE_GOLD_ORE || + xMat == XMaterial.RAW_GOLD || + xMat == XMaterial.GOLD_BLOCK || + + xMat == XMaterial.IRON_ORE || + xMat == XMaterial.DEEPSLATE_IRON_ORE || + xMat == XMaterial.RAW_IRON || + xMat == XMaterial.IRON_BLOCK || + + xMat == XMaterial.COAL_ORE || + xMat == XMaterial.DEEPSLATE_COAL_ORE || + xMat == XMaterial.COAL || + xMat == XMaterial.COAL_BLOCK || + + xMat == XMaterial.DIAMOND_ORE || + xMat == XMaterial.DEEPSLATE_DIAMOND_ORE || + xMat == XMaterial.DIAMOND || + xMat == XMaterial.DIAMOND_BLOCK || + + xMat == XMaterial.EMERALD_ORE || + xMat == XMaterial.DEEPSLATE_EMERALD_ORE || + xMat == XMaterial.EMERALD || + xMat == XMaterial.EMERALD_BLOCK || + + xMat == XMaterial.LAPIS_ORE || + xMat == XMaterial.DEEPSLATE_LAPIS_ORE || + xMat == XMaterial.LAPIS_BLOCK || + + xMat == XMaterial.NETHER_QUARTZ_ORE || + xMat == XMaterial.QUARTZ_BLOCK || + + xMat == XMaterial.REDSTONE_ORE || + xMat == XMaterial.REDSTONE_BLOCK || + xMat == XMaterial.DEEPSLATE_REDSTONE_ORE || + + xMat == XMaterial.COPPER_ORE || + xMat == XMaterial.DEEPSLATE_COPPER_ORE || + xMat == XMaterial.RAW_COPPER || + + + xMat == XMaterial.NETHER_WART_BLOCK || + xMat == XMaterial.NETHERITE_BLOCK || + xMat == XMaterial.PURPUR_BLOCK || + xMat == XMaterial.SLIME_BLOCK || + xMat == XMaterial.SNOW_BLOCK ) { multiplier = calculateFortuneMultiplier( fortuneLevel, multiplier ); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerTokenEnchant.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerTokenEnchant.java deleted file mode 100644 index 031659a5c..000000000 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerTokenEnchant.java +++ /dev/null @@ -1,127 +0,0 @@ -package tech.mcprison.prison.spigot.autofeatures; - -import org.bukkit.Bukkit; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; - -import com.vk2gpz.tokenenchant.event.TEBlockExplodeEvent; - -import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; -import tech.mcprison.prison.output.Output; -import tech.mcprison.prison.spigot.SpigotPrison; -import tech.mcprison.prison.spigot.block.OnBlockBreakEventListener.BlockBreakPriority; - -public class AutoManagerTokenEnchant - extends AutoManagerFeatures - { - - public AutoManagerTokenEnchant() { - super(); - - } - - - public void registerBlockBreakEvents(SpigotPrison spigotPrison ) { - - - String bbePriority = getMessage( AutoFeatures.TokenEnchantBlockExplodeEventPriority ); - BlockBreakPriority blockBreakPriority = BlockBreakPriority.fromString( bbePriority ); - - switch ( blockBreakPriority ) - { - case LOWEST: - Bukkit.getPluginManager().registerEvents( - new AutoManagerTokenEnchantEventLowest(), spigotPrison); - break; - - case LOW: - Bukkit.getPluginManager().registerEvents( - new AutoManagerTokenEnchantEventLow(), spigotPrison); - break; - - case NORMAL: - Bukkit.getPluginManager().registerEvents( - new AutoManagerTokenEnchantEventNormal(), spigotPrison); - break; - - case HIGH: - Bukkit.getPluginManager().registerEvents( - new AutoManagerTokenEnchantEventHigh(), spigotPrison); - break; - - case HIGHEST: - Bukkit.getPluginManager().registerEvents( - new AutoManagerTokenEnchantEventHighest(), spigotPrison); - break; - - case DISABLED: - Output.get().logInfo( "AutoManager TokenEnchant BlockExplodeEvent handling has been DISABLED." ); - break; - - default: - break; - } - - } - - - public void onTEBlockExplode(TEBlockExplodeEvent e) { - if ( !e.isCancelled() ) { - - genericBlockExplodeEventAutoManager( e, !isBoolean(AutoFeatures.isAutoManagerEnabled) ); - } - } - - - public class AutoManagerTokenEnchantEventLowest - extends AutoManagerTokenEnchant - implements Listener { - - @EventHandler(priority=EventPriority.LOWEST) - public void onTEBlockExplodeLow(TEBlockExplodeEvent e) { - super.onTEBlockExplode( e ); - } - } - - public class AutoManagerTokenEnchantEventLow - extends AutoManagerTokenEnchant - implements Listener { - - @EventHandler(priority=EventPriority.LOW) - public void onTEBlockExplodeLow(TEBlockExplodeEvent e) { - super.onTEBlockExplode( e ); - } - } - - public class AutoManagerTokenEnchantEventNormal - extends AutoManagerTokenEnchant - implements Listener { - - @EventHandler(priority=EventPriority.NORMAL) - public void onTEBlockExplodeLow(TEBlockExplodeEvent e) { - super.onTEBlockExplode( e ); - } - } - - public class AutoManagerTokenEnchantEventHigh - extends AutoManagerTokenEnchant - implements Listener { - - @EventHandler(priority=EventPriority.HIGH) - public void onTEBlockExplodeLow(TEBlockExplodeEvent e) { - super.onTEBlockExplode( e ); - } - } - - public class AutoManagerTokenEnchantEventHighest - extends AutoManagerTokenEnchant - implements Listener { - - @EventHandler(priority=EventPriority.HIGHEST) - public void onTEBlockExplodeLow(TEBlockExplodeEvent e) { - super.onTEBlockExplode( e ); - } - } - -} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerZenchantments.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerZenchantments.java deleted file mode 100644 index 7a138553f..000000000 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/AutoManagerZenchantments.java +++ /dev/null @@ -1,134 +0,0 @@ -package tech.mcprison.prison.spigot.autofeatures; - -import org.bukkit.Bukkit; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; - -import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; -import tech.mcprison.prison.output.Output; -import tech.mcprison.prison.spigot.SpigotPrison; -import tech.mcprison.prison.spigot.block.OnBlockBreakEventListener.BlockBreakPriority; -import zedly.zenchantments.BlockShredEvent; - -public class AutoManagerZenchantments - extends AutoManagerFeatures { - - public AutoManagerZenchantments() { - super(); - } - - - public void registerBlockBreakEvents(SpigotPrison spigotPrison ) { - - - String zbsPriority = getMessage( AutoFeatures.ZenchantmentsBlockShredEventPriority ); - BlockBreakPriority blockShredPriority = BlockBreakPriority.fromString( zbsPriority ); - - if ( blockShredPriority != BlockBreakPriority.DISABLED ) { - - // Always register the monitor event: - Bukkit.getPluginManager().registerEvents( - new AutoManagerBlockShredEventListenerMonitor(), spigotPrison); - } - - - switch ( blockShredPriority ) - { - case LOWEST: - Bukkit.getPluginManager().registerEvents( - new AutoManagerBlockShredEventListenerLowest(), spigotPrison); - break; - - case LOW: - Bukkit.getPluginManager().registerEvents( - new AutoManagerBlockShredEventListenerLow(), spigotPrison); - break; - - case NORMAL: - Bukkit.getPluginManager().registerEvents( - new AutoManagerBlockShredEventListenerNormal(), spigotPrison); - break; - - case HIGH: - Bukkit.getPluginManager().registerEvents( - new AutoManagerBlockShredEventListenerHigh(), spigotPrison); - break; - - case HIGHEST: - Bukkit.getPluginManager().registerEvents( - new AutoManagerBlockShredEventListenerHighest(), spigotPrison); - break; - - case DISABLED: - Output.get().logInfo( "AutoManager Zenchantments BlockShredEvent handling has been DISABLED." ); - break; - - default: - break; - } - - } - - - public class AutoManagerBlockShredEventListenerMonitor - extends AutoManager - implements Listener { - - @EventHandler(priority=EventPriority.MONITOR) - public void onBlockShredBreakMonitor(BlockShredEvent e) { - super.genericBlockEventMonitor( e ); - } - } - - public class AutoManagerBlockShredEventListenerLowest - extends AutoManager - implements Listener { - - @EventHandler(priority=EventPriority.LOWEST) - public void onBlockShredBreak(BlockShredEvent e) { - super.onBlockShredBreak( e ); - } - } - - public class AutoManagerBlockShredEventListenerLow - extends AutoManager - implements Listener { - - @EventHandler(priority=EventPriority.LOW) - public void onBlockShredBreak(BlockShredEvent e) { - super.onBlockShredBreak( e ); - } - } - - public class AutoManagerBlockShredEventListenerNormal - extends AutoManager - implements Listener { - - @EventHandler(priority=EventPriority.NORMAL) - public void onBlockShredBreak(BlockShredEvent e) { - super.onBlockShredBreak( e ); - } - } - - public class AutoManagerBlockShredEventListenerHigh - extends AutoManager - implements Listener { - - @EventHandler(priority=EventPriority.HIGH) - public void onBlockShredBreak(BlockShredEvent e) { - super.onBlockShredBreak( e ); - } - } - - public class AutoManagerBlockShredEventListenerHighest - extends AutoManager - implements Listener { - - @EventHandler(priority=EventPriority.HIGHEST) - public void onBlockShredBreak(BlockShredEvent e) { - super.onBlockShredBreak( e ); - } - } - -} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java new file mode 100644 index 000000000..a0e901f1d --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerBlockBreakEvents.java @@ -0,0 +1,217 @@ +package tech.mcprison.prison.spigot.autofeatures.events; + +import org.bukkit.Bukkit; +import org.bukkit.event.Event; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.plugin.EventExecutor; +import org.bukkit.plugin.PluginManager; + +import tech.mcprison.prison.Prison; +import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; +import tech.mcprison.prison.output.ChatDisplay; +import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.spigot.SpigotPrison; +import tech.mcprison.prison.spigot.block.OnBlockBreakEventListener; +import tech.mcprison.prison.spigot.block.OnBlockBreakEventListener.BlockBreakPriority; +import tech.mcprison.prison.spigot.game.SpigotHandlerList; + + +public class AutoManagerBlockBreakEvents + extends AutoManagerEventsManager + { + + public AutoManagerBlockBreakEvents() { + super(); + + } + + + @Override + public void registerEvents() { + + + initialize(); + + + new AutoManagerCrazyEnchants().registerEvents(); + new AutoManagerPrisonEnchants().registerEvents(); + new AutoManagerTokenEnchant().registerEvents(); + new AutoManagerZenchantments().registerEvents(); + + } + + + public class AutoManagerBlockBreakEventListener + extends AutoManagerBlockBreakEvents + implements Listener { + + @EventHandler(priority=EventPriority.NORMAL) + public void onBlockBreak(BlockBreakEvent e) { + genericBlockEventAutoManager( e ); + } + } + + public class OnBlockBreakEventListenerNormal + extends OnBlockBreakEventListener + implements Listener { + + @EventHandler(priority=EventPriority.NORMAL) + public void onBlockBreak(BlockBreakEvent e) { + genericBlockEvent( e ); + } + } + + public class OnBlockBreakEventListenerNormalMonitor + extends OnBlockBreakEventListener + implements Listener { + + @EventHandler(priority=EventPriority.MONITOR) + public void onBlockBreak(BlockBreakEvent e) { + genericBlockEventMonitor( e ); + } + } + + public void initialize() { + + // Check to see if the class BlockBreakEvent even exists: + try { + + Output.get().logInfo( "AutoManager: Trying to register BlockBreakEvent" ); + + String eP = getMessage( AutoFeatures.blockBreakEventPriority ); + BlockBreakPriority eventPriority = BlockBreakPriority.fromString( eP ); + + if ( eventPriority != BlockBreakPriority.DISABLED ) { + + EventPriority ePriority = EventPriority.valueOf( eventPriority.name().toUpperCase() ); + + + + OnBlockBreakEventListenerNormalMonitor normalListenerMonitor = + new OnBlockBreakEventListenerNormalMonitor(); + + + SpigotPrison prison = SpigotPrison.getInstance(); + + PluginManager pm = Bukkit.getServer().getPluginManager(); + + if ( eventPriority != BlockBreakPriority.MONITOR ) { + + if ( isBoolean( AutoFeatures.isAutoFeaturesEnabled )) { + + AutoManagerBlockBreakEventListener autoManagerlListener = + new AutoManagerBlockBreakEventListener(); + + pm.registerEvent(BlockBreakEvent.class, autoManagerlListener, ePriority, + new EventExecutor() { + public void execute(Listener l, Event e) { + if ( l instanceof AutoManagerBlockBreakEventListener && + e instanceof BlockBreakEvent ) { + ((AutoManagerBlockBreakEventListener)l) + .onBlockBreak((BlockBreakEvent)e); + } + } + }, + prison); + prison.getRegisteredBlockListeners().add( autoManagerlListener ); + } + + OnBlockBreakEventListenerNormal normalListener = + new OnBlockBreakEventListenerNormal(); + + pm.registerEvent(BlockBreakEvent.class, normalListener, ePriority, + new EventExecutor() { + public void execute(Listener l, Event e) { + if ( l instanceof OnBlockBreakEventListenerNormal && + e instanceof BlockBreakEvent ) { + ((OnBlockBreakEventListenerNormal)l) + .onBlockBreak((BlockBreakEvent)e); + } + } + }, + prison); + prison.getRegisteredBlockListeners().add( normalListener ); + + } + + + pm.registerEvent(BlockBreakEvent.class, normalListenerMonitor, EventPriority.MONITOR, + new EventExecutor() { + public void execute(Listener l, Event e) { + if ( l instanceof OnBlockBreakEventListenerNormalMonitor && + e instanceof BlockBreakEvent ) { + ((OnBlockBreakEventListenerNormalMonitor)l) + .onBlockBreak((BlockBreakEvent)e); + } + } + }, + prison); + prison.getRegisteredBlockListeners().add( normalListenerMonitor ); + + } + + } + catch ( Exception e ) { + Output.get().logInfo( "AutoManager: BlockBreakEvent failed to load. [%s]", e.getMessage() ); + } + } + + + /** + *

If one BlockBreak related event needs to be unregistered, then this function will + * unregisters all of them that has been registered through the auto features. If + * this function is called by different functions, the results will be the same. If + * they are ran back-to-back, then only the first call will remove all the Listeners + * and the other calls will do nothing since the source ArrayList will be emptied + * and there would be nothing to remove. + *

+ * + */ + @Override + public void unregisterListeners() { + + super.unregisterListeners(); + } + + + @Override + public void dumpEventListeners() { + + StringBuilder sb = new StringBuilder(); + + dumpEventListeners( sb ); + + if ( sb.length() > 0 ) { + + + for ( String line : sb.toString().split( "\n" ) ) { + + Output.get().logInfo( line ); + } + } + + } + + @Override + public void dumpEventListeners( StringBuilder sb ) { + + // Check to see if the class BlockBreakEvent even exists: + try { + + ChatDisplay eventDisplay = Prison.get().getPlatform().dumpEventListenersChatDisplay( + "BlockBreakEvent", + new SpigotHandlerList( BlockBreakEvent.getHandlerList()) ); + + if ( eventDisplay != null ) { + sb.append( eventDisplay.toStringBuilder() ); + } + } + catch ( Exception e ) { + Output.get().logInfo( "AutoManager: BlockBreakEvent failed to load. [%s]", e.getMessage() ); + } + } + +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerCrazyEnchants.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerCrazyEnchants.java new file mode 100644 index 000000000..720d6663c --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerCrazyEnchants.java @@ -0,0 +1,220 @@ +package tech.mcprison.prison.spigot.autofeatures.events; + +import org.bukkit.Bukkit; +import org.bukkit.event.Event; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.plugin.EventExecutor; +import org.bukkit.plugin.PluginManager; + +import me.badbones69.crazyenchantments.api.events.BlastUseEvent; +import tech.mcprison.prison.Prison; +import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; +import tech.mcprison.prison.output.ChatDisplay; +import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.spigot.SpigotPrison; +import tech.mcprison.prison.spigot.block.OnBlockBreakEventListener.BlockBreakPriority; +import tech.mcprison.prison.spigot.game.SpigotHandlerList; + +public class AutoManagerCrazyEnchants + extends AutoManagerEventsManager +{ + + public AutoManagerCrazyEnchants() { + super(); + } + + @Override + public void registerEvents() { + + initialize(); + + } + + + public class AutoManagerBlastUseEventListener + extends AutoManagerCrazyEnchants + implements Listener { + + @EventHandler(priority=EventPriority.NORMAL) + public void onCrazyEnchantsBlockExplode(BlastUseEvent e) { + genericBlockExplodeEventAutoManager( e ); + } + } + + public class OnBlockBreakBlastUseEventListener + extends AutoManagerCrazyEnchants + implements Listener { + + @EventHandler(priority=EventPriority.NORMAL) + public void onCrazyEnchantsBlockExplode(BlastUseEvent e) { + genericBlockExplodeEvent( e ); + } + } + + public class OnBlockBreakBlastUseEventListenerMonitor + extends AutoManagerCrazyEnchants + implements Listener { + + @EventHandler(priority=EventPriority.MONITOR) + public void onCrazyEnchantsBlockExplode(BlastUseEvent e) { + genericBlockExplodeEventMonitor( e ); + } + } + + + @Override + public void initialize() { + boolean isEventEnabled = isBoolean( AutoFeatures.isProcessCrazyEnchantsBlockExplodeEvents ); + + if ( !isEventEnabled ) { + return; + } + + // Check to see if the class BlastUseEvent even exists: + try { + Output.get().logInfo( "AutoManager: checking if loaded: CrazyEnchants" ); + + Class.forName( "me.badbones69.crazyenchantments.api.events.BlastUseEvent", false, + this.getClass().getClassLoader() ); + + Output.get().logInfo( "AutoManager: Trying to register CrazyEnchants" ); + + String eP = getMessage( AutoFeatures.CrazyEnchantsBlastUseEventPriority ); + BlockBreakPriority eventPriority = BlockBreakPriority.fromString( eP ); + + if ( eventPriority != BlockBreakPriority.DISABLED ) { + + EventPriority ePriority = EventPriority.valueOf( eventPriority.name().toUpperCase() ); + + + OnBlockBreakBlastUseEventListenerMonitor normalListenerMonitor = + new OnBlockBreakBlastUseEventListenerMonitor(); + + + SpigotPrison prison = SpigotPrison.getInstance(); + + PluginManager pm = Bukkit.getServer().getPluginManager(); + + if ( eventPriority != BlockBreakPriority.MONITOR ) { + + if ( isBoolean( AutoFeatures.isAutoFeaturesEnabled )) { + + AutoManagerBlastUseEventListener autoManagerlListener = + new AutoManagerBlastUseEventListener(); + + pm.registerEvent(BlastUseEvent.class, autoManagerlListener, ePriority, + new EventExecutor() { + public void execute(Listener l, Event e) { + ((AutoManagerBlastUseEventListener)l) + .onCrazyEnchantsBlockExplode((BlastUseEvent)e); + } + }, + prison); + prison.getRegisteredBlockListeners().add( autoManagerlListener ); + } + + OnBlockBreakBlastUseEventListener normalListener = + new OnBlockBreakBlastUseEventListener(); + + pm.registerEvent(BlastUseEvent.class, normalListener, ePriority, + new EventExecutor() { + public void execute(Listener l, Event e) { + ((OnBlockBreakBlastUseEventListener)l) + .onCrazyEnchantsBlockExplode((BlastUseEvent)e); + } + }, + prison); + prison.getRegisteredBlockListeners().add( normalListener ); + } + + pm.registerEvent(BlastUseEvent.class, normalListenerMonitor, EventPriority.MONITOR, + new EventExecutor() { + public void execute(Listener l, Event e) { + ((OnBlockBreakBlastUseEventListenerMonitor)l) + .onCrazyEnchantsBlockExplode((BlastUseEvent)e); + } + }, + prison); + prison.getRegisteredBlockListeners().add( normalListenerMonitor ); + + } + + // The following is paper code: +// var executor = EventExecutor +// .create( AutoManagerBlastUseEventListener.class +// .getDeclaredMethod( "onCrazyEnchantsBlockExplode", BlastUseEvent.class ), +// BlastUseEvent.class ); +// +// Bukkit.getServer().getPluginManager() +// .register( BlastUseEvent.class, this, EventPriority.LOW, executor, SpigotPrison.getInstance() ); + } + catch ( ClassNotFoundException e ) { + // CrazyEnchants is not loaded... so ignore. + Output.get().logInfo( "AutoManager: CrazyEnchants is not loaded" ); + } + catch ( Exception e ) { + Output.get().logInfo( "AutoManager: CrazyEnchants failed to load. [%s]", e.getMessage() ); + } + } + + + @Override + public void unregisterListeners() { + + super.unregisterListeners(); + + } + + @Override + public void dumpEventListeners() { + + StringBuilder sb = new StringBuilder(); + + dumpEventListeners( sb ); + + if ( sb.length() > 0 ) { + + + for ( String line : sb.toString().split( "\n" ) ) { + + Output.get().logInfo( line ); + } + } + + } + + + @Override + public void dumpEventListeners( StringBuilder sb ) { + boolean isEventEnabled = isBoolean( AutoFeatures.isProcessCrazyEnchantsBlockExplodeEvents ); + + if ( !isEventEnabled ) { + return; + } + + // Check to see if the class BlastUseEvent even exists: + try { + + Class.forName( "me.badbones69.crazyenchantments.api.events.BlastUseEvent", false, + this.getClass().getClassLoader() ); + + + ChatDisplay eventDisplay = Prison.get().getPlatform().dumpEventListenersChatDisplay( + "BlastUseEvent", + new SpigotHandlerList( BlastUseEvent.getHandlerList()) ); + + if ( eventDisplay != null ) { + sb.append( eventDisplay.toStringBuilder() ); + } + } + catch ( ClassNotFoundException e ) { + // CrazyEnchants is not loaded... so ignore. + } + catch ( Exception e ) { + Output.get().logInfo( "AutoManager: CrazyEnchants failed to load. [%s]", e.getMessage() ); + } + } + +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerEventsManager.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerEventsManager.java new file mode 100644 index 000000000..d45e4a53c --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerEventsManager.java @@ -0,0 +1,50 @@ +package tech.mcprison.prison.spigot.autofeatures.events; + +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; + +import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.spigot.SpigotPrison; +import tech.mcprison.prison.spigot.autofeatures.AutoManagerFeatures; + +public abstract class AutoManagerEventsManager + extends AutoManagerFeatures + implements PrisonEventManager +{ + + public AutoManagerEventsManager() { + super(); + + } + + /** + *

If one BlockBreak related event needs to be unregistered, then this function will + * unregisters all of them that has been registered through the auto features. If + * this function is called by different functions, the results will be the same. If + * they are ran back-to-back, then only the first call will remove all the Listeners + * and the other calls will do nothing since the source ArrayList will be emptied + * and there would be nothing to remove. + *

+ * + */ + @Override + public void unregisterListeners() { + + SpigotPrison prison = SpigotPrison.getInstance(); + + int count = 0; + while ( prison.getRegisteredBlockListeners().size() > 0 ) { + Listener listener = prison.getRegisteredBlockListeners().remove( 0 ); + + if ( listener != null ) { + + HandlerList.unregisterAll( listener ); + count++; + } + } + + Output.get().logInfo( "AutoManagerEventsManager: unregistered a total of %d event listeners.", + count ); + } + +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonEnchants.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonEnchants.java new file mode 100644 index 000000000..39a3e6172 --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonEnchants.java @@ -0,0 +1,220 @@ +package tech.mcprison.prison.spigot.autofeatures.events; + +import org.bukkit.Bukkit; +import org.bukkit.event.Event; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.plugin.EventExecutor; +import org.bukkit.plugin.PluginManager; + +import me.pulsi_.prisonenchants.events.PEExplosionEvent; +import tech.mcprison.prison.Prison; +import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; +import tech.mcprison.prison.output.ChatDisplay; +import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.spigot.SpigotPrison; +import tech.mcprison.prison.spigot.block.OnBlockBreakEventListener; +import tech.mcprison.prison.spigot.block.OnBlockBreakEventListener.BlockBreakPriority; +import tech.mcprison.prison.spigot.game.SpigotHandlerList; + +public class AutoManagerPrisonEnchants + extends AutoManagerEventsManager { + + public AutoManagerPrisonEnchants() { + super(); + } + + + @Override + public void registerEvents() { + + initialize(); + + } + + + public class AutoManagerExplosiveEventListener + extends AutoManagerBlockBreakEvents + implements Listener { + + @EventHandler(priority=EventPriority.NORMAL) + public void onPrisonEnchantsExplosiveEvent(PEExplosionEvent e) { + +// me.pulsi_.prisonenchants.events.PEExplosionEvent + + genericBlockExplodeEventAutoManager( e ); + } + } + + public class OnBlockBreakExplosiveEventListener + extends OnBlockBreakEventListener + implements Listener { + + @EventHandler(priority=EventPriority.NORMAL) + public void onPrisonEnchantsExplosiveEvent(PEExplosionEvent e) { + genericBlockExplodeEvent( e ); + } + } + + public class OnBlockBreakExplosiveEventListenerMonitor + extends OnBlockBreakEventListener + implements Listener { + + @EventHandler(priority=EventPriority.MONITOR) + public void onPrisonEnchantsExplosiveEvent(PEExplosionEvent e) { + genericBlockExplodeEventMonitor( e ); + } + } + + @Override + public void initialize() { + boolean isEventEnabled = isBoolean( AutoFeatures.isProcessPrisonEnchantsExplosiveEvents ); + + if ( !isEventEnabled ) { + return; + } + + // Check to see if the class ExplosiveEvent even exists: + try { + Output.get().logInfo( "AutoManager: checking if loaded: PrisonEnchants" ); + + Class.forName( "me.pulsi_.prisonenchants.enchantments.custom.explosive.PEExplosionEvent", false, + this.getClass().getClassLoader() ); + + Output.get().logInfo( "AutoManager: Trying to register PrisonEnchants" ); + + + String eP = getMessage( AutoFeatures.PrisonEnchantsExplosiveEventPriority ); + BlockBreakPriority eventPriority = BlockBreakPriority.fromString( eP ); + + if ( eventPriority != BlockBreakPriority.DISABLED ) { + + EventPriority ePriority = EventPriority.valueOf( eventPriority.name().toUpperCase() ); + + + OnBlockBreakExplosiveEventListenerMonitor normalListenerMonitor = + new OnBlockBreakExplosiveEventListenerMonitor(); + + + SpigotPrison prison = SpigotPrison.getInstance(); + + + PluginManager pm = Bukkit.getServer().getPluginManager(); + + if ( eventPriority != BlockBreakPriority.MONITOR ) { + + if ( isBoolean( AutoFeatures.isAutoFeaturesEnabled )) { + + AutoManagerExplosiveEventListener autoManagerlListener = + new AutoManagerExplosiveEventListener(); + + pm.registerEvent(PEExplosionEvent.class, autoManagerlListener, ePriority, + new EventExecutor() { + public void execute(Listener l, Event e) { + ((AutoManagerExplosiveEventListener)l) + .onPrisonEnchantsExplosiveEvent((PEExplosionEvent)e); + } + }, + prison); + prison.getRegisteredBlockListeners().add( autoManagerlListener ); + } + + OnBlockBreakExplosiveEventListener normalListener = + new OnBlockBreakExplosiveEventListener(); + + pm.registerEvent(PEExplosionEvent.class, normalListener, ePriority, + new EventExecutor() { + public void execute(Listener l, Event e) { + ((OnBlockBreakExplosiveEventListener)l) + .onPrisonEnchantsExplosiveEvent((PEExplosionEvent)e); + } + }, + prison); + prison.getRegisteredBlockListeners().add( normalListener ); + } + + pm.registerEvent(PEExplosionEvent.class, normalListenerMonitor, EventPriority.MONITOR, + new EventExecutor() { + public void execute(Listener l, Event e) { + ((OnBlockBreakExplosiveEventListenerMonitor)l) + .onPrisonEnchantsExplosiveEvent((PEExplosionEvent)e); + } + }, + prison); + prison.getRegisteredBlockListeners().add( normalListenerMonitor ); + + + } + + } + catch ( ClassNotFoundException e ) { + // PrisonEnchants is not loaded... so ignore. + Output.get().logInfo( "AutoManager: PrisonEnchants is not loaded" ); + } + catch ( Exception e ) { + Output.get().logInfo( "AutoManager: PrisonEnchants failed to load. [%s]", e.getMessage() ); + } + } + + + + @Override + public void unregisterListeners() { + + super.unregisterListeners(); + + } + + @Override + public void dumpEventListeners() { + + StringBuilder sb = new StringBuilder(); + + dumpEventListeners( sb ); + + if ( sb.length() > 0 ) { + + + for ( String line : sb.toString().split( "\n" ) ) { + + Output.get().logInfo( line ); + } + } + + } + + + @Override + public void dumpEventListeners( StringBuilder sb ) { + boolean isEventEnabled = isBoolean( AutoFeatures.isProcessPrisonEnchantsExplosiveEvents ); + + if ( !isEventEnabled ) { + return; + } + + // Check to see if the class ExplosiveEvent even exists: + try { + + Class.forName( "me.pulsi_.prisonenchants.enchantments.custom.explosive.PEExplosionEvent", false, + this.getClass().getClassLoader() ); + + + ChatDisplay eventDisplay = Prison.get().getPlatform().dumpEventListenersChatDisplay( + "PEExplosionEvent", + new SpigotHandlerList( PEExplosionEvent.getHandlerList()) ); + + if ( eventDisplay != null ) { + sb.append( eventDisplay.toStringBuilder() ); + } + } + catch ( ClassNotFoundException e ) { + // PrisonEnchants is not loaded... so ignore. + } + catch ( Exception e ) { + Output.get().logInfo( "AutoManager: PrisonEnchants failed to load. [%s]", e.getMessage() ); + } + } + + +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonsExplosiveBlockBreakEvents.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonsExplosiveBlockBreakEvents.java new file mode 100644 index 000000000..3b1d4de72 --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerPrisonsExplosiveBlockBreakEvents.java @@ -0,0 +1,204 @@ +package tech.mcprison.prison.spigot.autofeatures.events; + +import org.bukkit.Bukkit; +import org.bukkit.event.Event; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.plugin.EventExecutor; +import org.bukkit.plugin.PluginManager; + +import tech.mcprison.prison.Prison; +import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; +import tech.mcprison.prison.output.ChatDisplay; +import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.spigot.SpigotPrison; +import tech.mcprison.prison.spigot.api.ExplosiveBlockBreakEvent; +import tech.mcprison.prison.spigot.block.OnBlockBreakEventListener; +import tech.mcprison.prison.spigot.block.OnBlockBreakEventListener.BlockBreakPriority; +import tech.mcprison.prison.spigot.game.SpigotHandlerList; + +public class AutoManagerPrisonsExplosiveBlockBreakEvents + extends AutoManagerEventsManager { + + + public AutoManagerPrisonsExplosiveBlockBreakEvents() { + super(); + } + + + @Override + public void registerEvents() { + + initialize(); + + } + + + public class AutoManagerExplosiveBlockBreakEventListener + extends AutoManagerBlockBreakEvents + implements Listener { + + @EventHandler(priority=EventPriority.NORMAL) + public void onPrisonsExplosiveBlockBreakEvent(ExplosiveBlockBreakEvent e) { + +// me.pulsi_.prisonenchants.events.PEExplosionEvent + + genericBlockExplodeEventAutoManager( e ); + } + } + + public class OnBlockBreakExplosiveBlockBreakEventListener + extends OnBlockBreakEventListener + implements Listener { + + @EventHandler(priority=EventPriority.NORMAL) + public void onPrisonExplosiveBlockBreakEvent(ExplosiveBlockBreakEvent e) { + genericBlockExplodeEvent( e ); + } + } + + public class OnBlockBreakExplosiveBlockBreakEventListenerMonitor + extends OnBlockBreakEventListener + implements Listener { + + @EventHandler(priority=EventPriority.MONITOR) + public void onPrisonExplosiveBlockBreakEventMonitor(ExplosiveBlockBreakEvent e) { + genericBlockExplodeEventMonitor( e ); + } + } + + @Override + public void initialize() { + boolean isEventEnabled = isBoolean( AutoFeatures.isProcessPrisons_ExplosiveBlockBreakEvents ); + + if ( !isEventEnabled ) { + return; + } + + try { + + Output.get().logInfo( "AutoManager: Trying to register ExplosiveBlockBreakEvent Listener" ); + + + String eP = getMessage( AutoFeatures.ProcessPrisons_ExplosiveBlockBreakEvents ); + BlockBreakPriority eventPriority = BlockBreakPriority.fromString( eP ); + + if ( eventPriority != BlockBreakPriority.DISABLED ) { + + EventPriority ePriority = EventPriority.valueOf( eventPriority.name().toUpperCase() ); + + + OnBlockBreakExplosiveBlockBreakEventListenerMonitor normalListenerMonitor = + new OnBlockBreakExplosiveBlockBreakEventListenerMonitor(); + + + SpigotPrison prison = SpigotPrison.getInstance(); + + + PluginManager pm = Bukkit.getServer().getPluginManager(); + + if ( eventPriority != BlockBreakPriority.MONITOR ) { + + if ( isBoolean( AutoFeatures.isAutoFeaturesEnabled )) { + + AutoManagerExplosiveBlockBreakEventListener autoManagerlListener = + new AutoManagerExplosiveBlockBreakEventListener(); + + pm.registerEvent(ExplosiveBlockBreakEvent.class, autoManagerlListener, ePriority, + new EventExecutor() { + public void execute(Listener l, Event e) { + ((AutoManagerExplosiveBlockBreakEventListener)l) + .onPrisonsExplosiveBlockBreakEvent((ExplosiveBlockBreakEvent)e); + } + }, + prison); + prison.getRegisteredBlockListeners().add( autoManagerlListener ); + } + + OnBlockBreakExplosiveBlockBreakEventListener normalListener = + new OnBlockBreakExplosiveBlockBreakEventListener(); + + pm.registerEvent(ExplosiveBlockBreakEvent.class, normalListener, ePriority, + new EventExecutor() { + public void execute(Listener l, Event e) { + ((OnBlockBreakExplosiveBlockBreakEventListener)l) + .onPrisonExplosiveBlockBreakEvent((ExplosiveBlockBreakEvent)e); + } + }, + prison); + prison.getRegisteredBlockListeners().add( normalListener ); + } + + pm.registerEvent(ExplosiveBlockBreakEvent.class, normalListenerMonitor, EventPriority.MONITOR, + new EventExecutor() { + public void execute(Listener l, Event e) { + ((OnBlockBreakExplosiveBlockBreakEventListenerMonitor)l) + .onPrisonExplosiveBlockBreakEventMonitor((ExplosiveBlockBreakEvent)e); + } + }, + prison); + prison.getRegisteredBlockListeners().add( normalListenerMonitor ); + + + } + + } + catch ( Exception e ) { + Output.get().logInfo( "AutoManager: Prison's own ExplosiveBlockBreakEvent failed to load. [%s]", e.getMessage() ); + } + } + + + + @Override + public void unregisterListeners() { + + super.unregisterListeners(); + + } + + @Override + public void dumpEventListeners() { + + StringBuilder sb = new StringBuilder(); + + dumpEventListeners( sb ); + + if ( sb.length() > 0 ) { + + + for ( String line : sb.toString().split( "\n" ) ) { + + Output.get().logInfo( line ); + } + } + + } + + + @Override + public void dumpEventListeners( StringBuilder sb ) { + boolean isEventEnabled = isBoolean( AutoFeatures.isProcessPrisonEnchantsExplosiveEvents ); + + if ( !isEventEnabled ) { + return; + } + + // Check to see if the class ExplosiveEvent even exists: + try { + + ChatDisplay eventDisplay = Prison.get().getPlatform().dumpEventListenersChatDisplay( + "ExplosiveBlockBreakEvent", + new SpigotHandlerList( ExplosiveBlockBreakEvent.getHandlerList()) ); + + if ( eventDisplay != null ) { + sb.append( eventDisplay.toStringBuilder() ); + } + } + catch ( Exception e ) { + Output.get().logInfo( "AutoManager: PrisonEnchants failed to load. [%s]", e.getMessage() ); + } + } + +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerTokenEnchant.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerTokenEnchant.java new file mode 100644 index 000000000..608278a2e --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerTokenEnchant.java @@ -0,0 +1,215 @@ +package tech.mcprison.prison.spigot.autofeatures.events; + +import org.bukkit.Bukkit; +import org.bukkit.event.Event; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.plugin.EventExecutor; +import org.bukkit.plugin.PluginManager; + +import com.vk2gpz.tokenenchant.event.TEBlockExplodeEvent; + +import tech.mcprison.prison.Prison; +import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; +import tech.mcprison.prison.output.ChatDisplay; +import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.spigot.SpigotPrison; +import tech.mcprison.prison.spigot.block.OnBlockBreakEventListener.BlockBreakPriority; +import tech.mcprison.prison.spigot.game.SpigotHandlerList; + +public class AutoManagerTokenEnchant + extends AutoManagerEventsManager { + + public AutoManagerTokenEnchant() { + super(); + + } + + + @Override + public void registerEvents() { + + initialize(); + + } + + + public class AutoManagerTokenEnchantEventListener + extends AutoManagerTokenEnchant + implements Listener { + + @EventHandler(priority=EventPriority.LOW) + public void onTEBlockExplode(TEBlockExplodeEvent e) { + genericBlockExplodeEventAutoManager( e ); + } + } + + public class OnBlockBreakEventTokenEnchantEventListener + extends AutoManagerTokenEnchant + implements Listener { + + @EventHandler(priority=EventPriority.NORMAL) + public void onTEBlockExplode(TEBlockExplodeEvent e) { + genericBlockExplodeEvent( e ); + } + } + + public class OnBlockBreakEventTokenEnchantEventListenerMonitor + extends AutoManagerTokenEnchant + implements Listener { + + @EventHandler(priority=EventPriority.MONITOR) + public void onTEBlockExplode(TEBlockExplodeEvent e) { + genericBlockExplodeEventMonitor( e ); + } + } + + @Override + public void initialize() { + boolean isEventEnabled = isBoolean( AutoFeatures.isProcessTokensEnchantExplosiveEvents ); + + if ( !isEventEnabled ) { + return; + } + + // Check to see if the class TEBlockExplodeEvent even exists: + try { + Output.get().logInfo( "AutoManager: checking if loaded: TokenEnchant" ); + + Class.forName( "com.vk2gpz.tokenenchant.event.TEBlockExplodeEvent", false, + this.getClass().getClassLoader() ); + + Output.get().logInfo( "AutoManager: Trying to register TokenEnchant" ); + + + String eP = getMessage( AutoFeatures.TokenEnchantBlockExplodeEventPriority ); + BlockBreakPriority eventPriority = BlockBreakPriority.fromString( eP ); + + if ( eventPriority != BlockBreakPriority.DISABLED ) { + + EventPriority ePriority = EventPriority.valueOf( eventPriority.name().toUpperCase() ); + + + OnBlockBreakEventTokenEnchantEventListenerMonitor normalListenerMonitor = + new OnBlockBreakEventTokenEnchantEventListenerMonitor(); + + + SpigotPrison prison = SpigotPrison.getInstance(); + + PluginManager pm = Bukkit.getServer().getPluginManager(); + + if ( eventPriority != BlockBreakPriority.MONITOR ) { + + if ( isBoolean( AutoFeatures.isAutoFeaturesEnabled )) { + + AutoManagerTokenEnchantEventListener autoManagerlListener = + new AutoManagerTokenEnchantEventListener(); + + pm.registerEvent(TEBlockExplodeEvent.class, autoManagerlListener, ePriority, + new EventExecutor() { + public void execute(Listener l, Event e) { + ((AutoManagerTokenEnchantEventListener)l) + .onTEBlockExplode((TEBlockExplodeEvent)e); + } + }, + prison); + prison.getRegisteredBlockListeners().add( autoManagerlListener ); + } + + OnBlockBreakEventTokenEnchantEventListener normalListener = + new OnBlockBreakEventTokenEnchantEventListener(); + + pm.registerEvent(TEBlockExplodeEvent.class, normalListener, ePriority, + new EventExecutor() { + public void execute(Listener l, Event e) { + ((OnBlockBreakEventTokenEnchantEventListener)l) + .onTEBlockExplode((TEBlockExplodeEvent)e); + } + }, + prison); + prison.getRegisteredBlockListeners().add( normalListener ); + } + + pm.registerEvent(TEBlockExplodeEvent.class, normalListenerMonitor, EventPriority.MONITOR, + new EventExecutor() { + public void execute(Listener l, Event e) { + ((OnBlockBreakEventTokenEnchantEventListenerMonitor)l) + .onTEBlockExplode((TEBlockExplodeEvent)e); + } + }, + prison); + prison.getRegisteredBlockListeners().add( normalListenerMonitor ); + } + + } + catch ( ClassNotFoundException e ) { + // TokenEnchant is not loaded... so ignore. + Output.get().logInfo( "AutoManager: TokenEnchant is not loaded" ); + } + catch ( Exception e ) { + Output.get().logInfo( "AutoManager: TokenEnchant failed to load. [%s]", e.getMessage() ); + } + } + + + @Override + public void unregisterListeners() { + + super.unregisterListeners(); + + } + + + @Override + public void dumpEventListeners() { + + StringBuilder sb = new StringBuilder(); + + dumpEventListeners( sb ); + + if ( sb.length() > 0 ) { + + + for ( String line : sb.toString().split( "\n" ) ) { + + Output.get().logInfo( line ); + } + } + + } + + + @Override + public void dumpEventListeners( StringBuilder sb ) { + boolean isEventEnabled = isBoolean( AutoFeatures.isProcessTokensEnchantExplosiveEvents ); + + if ( !isEventEnabled ) { + return; + } + + // Check to see if the class TEBlockExplodeEvent even exists: + try { + + Class.forName( "com.vk2gpz.tokenenchant.event.TEBlockExplodeEvent", false, + this.getClass().getClassLoader() ); + + + ChatDisplay eventDisplay = Prison.get().getPlatform().dumpEventListenersChatDisplay( + "TEBlockExplodeEvent", + new SpigotHandlerList( TEBlockExplodeEvent.getHandlerList()) ); + + if ( eventDisplay != null ) { + sb.append( eventDisplay.toStringBuilder() ); + } + } + catch ( ClassNotFoundException e ) { + // TokenEnchant is not loaded... so ignore. + } + catch ( Exception e ) { + Output.get().logInfo( "AutoManager: TokenEnchant failed to load. [%s]", e.getMessage() ); + } + } + + +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerZenchantments.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerZenchantments.java new file mode 100644 index 000000000..1eb311a92 --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/AutoManagerZenchantments.java @@ -0,0 +1,227 @@ +package tech.mcprison.prison.spigot.autofeatures.events; + +import org.bukkit.Bukkit; +import org.bukkit.event.Event; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.plugin.EventExecutor; +import org.bukkit.plugin.PluginManager; + +import tech.mcprison.prison.Prison; +import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; +import tech.mcprison.prison.output.ChatDisplay; +import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.spigot.SpigotPrison; +import tech.mcprison.prison.spigot.block.OnBlockBreakEventListener; +import tech.mcprison.prison.spigot.block.OnBlockBreakEventListener.BlockBreakPriority; +import tech.mcprison.prison.spigot.game.SpigotHandlerList; +import zedly.zenchantments.BlockShredEvent; + +public class AutoManagerZenchantments + extends AutoManagerEventsManager { + + public AutoManagerZenchantments() { + super(); + } + + + @Override + public void registerEvents() { + + initialize(); + + } + + + public class AutoManagerBlockShredEventListener + extends AutoManagerBlockBreakEvents + implements Listener { + + @EventHandler(priority=EventPriority.NORMAL) + public void onBlockShredBreak(BlockShredEvent e) { + genericBlockEventAutoManager( e ); + } + } + + public class OnBlockBreakBlockShredEventListener + extends OnBlockBreakEventListener + implements Listener { + + @EventHandler(priority=EventPriority.NORMAL) + public void onBlockShredBreak(BlockShredEvent e) { + genericBlockEvent( e ); + } + } + + public class OnBlockBreakBlockShredEventListenerMonitor + extends OnBlockBreakEventListener + implements Listener { + + @EventHandler(priority=EventPriority.MONITOR) + public void onBlockShredBreakMonitor(BlockShredEvent e) { + genericBlockEventMonitor( e ); + } + } + + + @Override + public void initialize() { + boolean isEventEnabled = isBoolean( AutoFeatures.isProcessZenchantsBlockExplodeEvents ); + + if ( !isEventEnabled ) { + return; + } + + // Check to see if the class BlastUseEvent even exists: + try { + Output.get().logInfo( "AutoManager: checking if loaded: Zenchantments" ); + + Class.forName( "zedly.zenchantments.BlockShredEvent", false, + this.getClass().getClassLoader() ); + + Output.get().logInfo( "AutoManager: Trying to register Zenchantments" ); + + + String eP = getMessage( AutoFeatures.ZenchantmentsBlockShredEventPriority ); + BlockBreakPriority eventPriority = BlockBreakPriority.fromString( eP ); + + if ( eventPriority != BlockBreakPriority.DISABLED ) { + + EventPriority ePriority = EventPriority.valueOf( eventPriority.name().toUpperCase() ); + + + OnBlockBreakBlockShredEventListenerMonitor normalListenerMonitor = + new OnBlockBreakBlockShredEventListenerMonitor(); + + + SpigotPrison prison = SpigotPrison.getInstance(); + + PluginManager pm = Bukkit.getServer().getPluginManager(); + + if ( eventPriority != BlockBreakPriority.MONITOR ) { + + if ( isBoolean( AutoFeatures.isAutoFeaturesEnabled )) { + + AutoManagerBlockShredEventListener autoManagerlListener = + new AutoManagerBlockShredEventListener(); + + pm.registerEvent(BlockShredEvent.class, autoManagerlListener, ePriority, + new EventExecutor() { + public void execute(Listener l, Event e) { + if ( l instanceof OnBlockBreakBlockShredEventListenerMonitor && + e instanceof BlockShredEvent ) { + OnBlockBreakBlockShredEventListenerMonitor lmon = + (OnBlockBreakBlockShredEventListenerMonitor) l; + BlockShredEvent event = (BlockShredEvent) e; + lmon.onBlockShredBreakMonitor( event ); + } + } + }, + prison); + prison.getRegisteredBlockListeners().add( autoManagerlListener ); + } + + OnBlockBreakBlockShredEventListener normalListener = + new OnBlockBreakBlockShredEventListener(); + + pm.registerEvent(BlockShredEvent.class, normalListener, ePriority, + new EventExecutor() { + public void execute(Listener l, Event e) { + if ( l instanceof OnBlockBreakBlockShredEventListenerMonitor && + e instanceof BlockShredEvent ) { + OnBlockBreakBlockShredEventListenerMonitor lmon = + (OnBlockBreakBlockShredEventListenerMonitor) l; + BlockShredEvent event = (BlockShredEvent) e; + lmon.onBlockShredBreakMonitor( event ); + } + } + }, + prison); + prison.getRegisteredBlockListeners().add( normalListener ); + } + + pm.registerEvent(BlockShredEvent.class, normalListenerMonitor, EventPriority.MONITOR, + new EventExecutor() { + public void execute(Listener l, Event e) { + if ( l instanceof OnBlockBreakBlockShredEventListenerMonitor && + e instanceof BlockShredEvent ) { + OnBlockBreakBlockShredEventListenerMonitor lmon = + (OnBlockBreakBlockShredEventListenerMonitor) l; + BlockShredEvent event = (BlockShredEvent) e; + lmon.onBlockShredBreakMonitor( event ); + } + } + }, + prison); + prison.getRegisteredBlockListeners().add( normalListenerMonitor ); + } + + } + catch ( ClassNotFoundException e ) { + // Zenchantments is not loaded... so ignore. + Output.get().logInfo( "AutoManager: Zenchantments is not loaded" ); + } + catch ( Exception e ) { + Output.get().logInfo( "AutoManager: Zenchantments failed to load. [%s]", e.getMessage() ); + } + } + + @Override + public void unregisterListeners() { + + super.unregisterListeners(); + + } + + @Override + public void dumpEventListeners() { + + StringBuilder sb = new StringBuilder(); + + dumpEventListeners( sb ); + + if ( sb.length() > 0 ) { + + + for ( String line : sb.toString().split( "\n" ) ) { + + Output.get().logInfo( line ); + } + } + + } + + + @Override + public void dumpEventListeners( StringBuilder sb ) { + boolean isEventEnabled = isBoolean( AutoFeatures.isProcessZenchantsBlockExplodeEvents ); + + if ( !isEventEnabled ) { + return; + } + + // Check to see if the class BlastUseEvent even exists: + try { + + Class.forName( "zedly.zenchantments.BlockShredEvent", false, + this.getClass().getClassLoader() ); + + + ChatDisplay eventDisplay = Prison.get().getPlatform().dumpEventListenersChatDisplay( + "BlockShredEvent", + new SpigotHandlerList( BlockShredEvent.getHandlerList()) ); + + if ( eventDisplay != null ) { + sb.append( eventDisplay.toStringBuilder() ); + } + } + catch ( ClassNotFoundException e ) { + // Zenchantments is not loaded... so ignore. + } + catch ( Exception e ) { + Output.get().logInfo( "AutoManager: zenchantments failed to load. [%s]", e.getMessage() ); + } + } + +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/PrisonEventManager.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/PrisonEventManager.java new file mode 100644 index 000000000..68909e5d1 --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/autofeatures/events/PrisonEventManager.java @@ -0,0 +1,20 @@ +package tech.mcprison.prison.spigot.autofeatures.events; + +public interface PrisonEventManager +{ + + public void registerEvents(); + + + public void initialize(); + + + public void unregisterListeners(); + + + public void dumpEventListeners(); + + + public void dumpEventListeners( StringBuilder sb ); + +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java index 372a857ac..d6cf03fba 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCore.java @@ -18,10 +18,12 @@ import com.vk2gpz.tokenenchant.event.TEBlockExplodeEvent; import me.badbones69.crazyenchantments.api.events.BlastUseEvent; +import me.pulsi_.prisonenchants.events.PEExplosionEvent; import tech.mcprison.prison.Prison; import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig; import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; import tech.mcprison.prison.autofeatures.AutoFeaturesWrapper; +import tech.mcprison.prison.cache.PlayerCache; import tech.mcprison.prison.internal.block.PrisonBlock; import tech.mcprison.prison.mines.PrisonMines; import tech.mcprison.prison.mines.data.Mine; @@ -31,12 +33,14 @@ import tech.mcprison.prison.output.Output; import tech.mcprison.prison.output.Output.DebugTarget; import tech.mcprison.prison.spigot.SpigotPrison; +import tech.mcprison.prison.spigot.api.ExplosiveBlockBreakEvent; import tech.mcprison.prison.spigot.api.PrisonMinesBlockBreakEvent; import tech.mcprison.prison.spigot.autofeatures.AutoManagerFeatures; import tech.mcprison.prison.spigot.compat.Compatibility; import tech.mcprison.prison.spigot.game.SpigotPlayer; import tech.mcprison.prison.spigot.integrations.IntegrationCrazyEnchantmentsPickaxes; import tech.mcprison.prison.spigot.utils.BlockUtils; +import tech.mcprison.prison.spigot.utils.PrisonUtilsTitles; import tech.mcprison.prison.util.Text; public class OnBlockBreakEventCore @@ -163,48 +167,119 @@ protected void genericBlockEvent( BlockBreakEvent e ) { genericBlockEvent( e, false, false, false ); } - protected void genericBlockEventAutoManager( BlockBreakEvent e, boolean blockEventsOnly ) { + protected void genericBlockEventAutoManager( BlockBreakEvent e ) { + // NOTE: If autoManager is turned off, then process only the blockEvents: + boolean blockEventsOnly = !isBoolean(AutoFeatures.isAutoManagerEnabled); genericBlockEvent( e, false, blockEventsOnly, true ); } + protected void genericBlockExplodeEventMonitor( TEBlockExplodeEvent e ) { genericBlockExplodeEvent( e, true, false, false ); } - protected void genericBlockExplodeEvent( TEBlockExplodeEvent e, boolean blockEventsOnly ) { + protected void genericBlockExplodeEvent( TEBlockExplodeEvent e ) { + // NOTE: If autoManager is turned off, then process only the blockEvents: + boolean blockEventsOnly = !isBoolean(AutoFeatures.isAutoManagerEnabled); genericBlockExplodeEvent( e, false, blockEventsOnly, false ); } - protected void genericBlockExplodeEventAutoManager( TEBlockExplodeEvent e, boolean blockEventsOnly ) { + protected void genericBlockExplodeEventAutoManager( TEBlockExplodeEvent e ) { + // NOTE: If autoManager is turned off, then process only the blockEvents: + boolean blockEventsOnly = !isBoolean(AutoFeatures.isAutoManagerEnabled); genericBlockExplodeEvent( e, false, blockEventsOnly, true ); } protected void genericBlockExplodeEventMonitor( BlastUseEvent e ) { - genericBlockExplodeEvent( e, true, false, false ); + genericBlastUseEvent( e, true, false, false ); } - protected void genericBlockExplodeEvent( BlastUseEvent e, boolean blockEventsOnly ) { - genericBlockExplodeEvent( e, false, blockEventsOnly, false ); + protected void genericBlockExplodeEvent( BlastUseEvent e ) { + // NOTE: If autoManager is turned off, then process only the blockEvents: + boolean blockEventsOnly = !isBoolean(AutoFeatures.isAutoManagerEnabled); + genericBlastUseEvent( e, false, blockEventsOnly, false ); } - protected void genericBlockExplodeEventAutoManager( BlastUseEvent e, boolean blockEventsOnly ) { - genericBlockExplodeEvent( e, true, blockEventsOnly, true ); + protected void genericBlockExplodeEventAutoManager( BlastUseEvent e ) { + // NOTE: If autoManager is turned off, then process only the blockEvents: + boolean blockEventsOnly = !isBoolean(AutoFeatures.isAutoManagerEnabled); + genericBlastUseEvent( e, true, blockEventsOnly, true ); + } + + + /** + * For Pulsi_'s PrisonEnchants plugin: + * + * @param e + */ + protected void genericBlockExplodeEventMonitor( PEExplosionEvent e ) { + genericExplosiveEvent( e, true, false, false ); + } + + /** + * For Pulsi_'s PrisonEnchants plugin: + * + * @param e + */ + protected void genericBlockExplodeEvent( PEExplosionEvent e ) { + // NOTE: If autoManager is turned off, then process only the blockEvents: + boolean blockEventsOnly = !isBoolean(AutoFeatures.isAutoManagerEnabled); + genericExplosiveEvent( e, false, blockEventsOnly, false ); + } + + /** + * For Pulsi_'s PrisonEnchants plugin: + * + * @param e + */ + protected void genericBlockExplodeEventAutoManager( PEExplosionEvent e ) { + // NOTE: If autoManager is turned off, then process only the blockEvents: + boolean blockEventsOnly = !isBoolean(AutoFeatures.isAutoManagerEnabled); + genericExplosiveEvent( e, true, blockEventsOnly, true ); + } + + + + + /** + * For Prison's very own ExplosiveBlockBreakEvent: + * + * @param e + */ + protected void genericBlockExplodeEventMonitor( ExplosiveBlockBreakEvent e ) { + genericExplosiveEvent( e, true, false, false ); } + /** + * For Prison's very own ExplosiveBlockBreakEvent: + * + * @param e + */ + protected void genericBlockExplodeEvent( ExplosiveBlockBreakEvent e ) { + // NOTE: If autoManager is turned off, then process only the blockEvents: + boolean blockEventsOnly = !isBoolean(AutoFeatures.isAutoManagerEnabled); + genericExplosiveEvent( e, false, blockEventsOnly, false ); + } + + /** + * For Prison's very own ExplosiveBlockBreakEvent: + * + * @param e + */ + protected void genericBlockExplodeEventAutoManager( ExplosiveBlockBreakEvent e ) { + // NOTE: If autoManager is turned off, then process only the blockEvents: + boolean blockEventsOnly = !isBoolean(AutoFeatures.isAutoManagerEnabled); + genericExplosiveEvent( e, true, blockEventsOnly, true ); + } + + /** *

This genericBlockEvent handles the basics of a BlockBreakEvent to see if it has happened * within a mine or not. If it is happening within a mine, then we process it with the doAction() * function. *

* - *

For this class only. the doAction() is only counting the block break event, but does - * nothing with the actual block such that there is no need to have knowledge as to if - * it is a custom block. In other doAction() functions that would exist in other classes - * that extend from this one, it may need that information. The hooks to find the custom - * blocks is within the Block's getPrisonBlock() function. - *

- * * @param e * @param montior Identifies that a monitor event called this function. A monitor should only record * block break counts. @@ -219,120 +294,346 @@ protected void genericBlockEvent( BlockBreakEvent e, boolean monitor, boolean bl // Register all external events such as mcMMO and EZBlocks: OnBlockBreakExternalEvents.getInstance().registerAllExternalEvents(); + StringBuilder debugInfo = new StringBuilder(); - String debugInfo = String.format( "### ** genericBlockEvent ** ### %s%s%s%s ", + debugInfo.append( String.format( "### ** genericBlockEvent ** ### %s%s%s%s ", (autoManager ? "autoManager " : ""), (e.isCancelled() ? "CANCELED " : ""), - (monitor ? "MONITOR " : ""), (blockEventsOnly ? "BlockEventsOnly" : "" )); + (monitor ? "MONITOR " : ""), (blockEventsOnly ? "BlockEventsOnly" : "" )) ); // NOTE that check for auto manager has happened prior to accessing this function. if ( !monitor && !e.isCancelled() || monitor ) { - -// boolean isAir = e.getBlock().getType() == null || e.getBlock().getType() == Material.AIR; // Need to wrap in a Prison block so it can be used with the mines: - SpigotBlock block = new SpigotBlock(e.getBlock()); + SpigotBlock sBlock = new SpigotBlock(e.getBlock()); + SpigotPlayer sPlayer = new SpigotPlayer(e.getPlayer()); - Long playerUUIDLSB = Long.valueOf( e.getPlayer().getUniqueId().getLeastSignificantBits() ); + BlockEventType eventType = BlockEventType.blockBreak; + String triggered = null; - // Get the cached mine, if it exists: - Mine mine = getPlayerCache().get( playerUUIDLSB ); + PrisonMinesBlockBreakEvent pmEvent = new PrisonMinesBlockBreakEvent( e.getBlock(), e.getPlayer(), + sBlock, sPlayer, monitor, blockEventsOnly, eventType, triggered ); - if ( mine == null || !mine.isInMineExact( block.getLocation() ) ) { - // Look for the correct mine to use. - // Set mine to null so if cannot find the right one it will return a null: - mine = findMineLocation( block ); + if ( !validateEvent( pmEvent, debugInfo ) ) { - // Store the mine in the player cache if not null: - if ( mine != null ) { - getPlayerCache().put( playerUUIDLSB, mine ); + // The event has not passed validation. All logging and Errors have been recorded + // so do nothing more. This is to just prevent normal processing from occurring. + + if ( pmEvent.isCancelOriginalEvent() ) { + + e.setCancelled( true ); } } - debugInfo += "mine=" + (mine == null ? "none" : mine.getName()) + " "; - - - if ( mine != null && BlockUtils.getInstance().isUnbreakable( block ) ) { - // The block is unbreakable because a utility has it locked: - - e.setCancelled( true ); - debugInfo += "UNBREAKABLE_BLOCK_UTILS (event canceled) "; - } - else if ( mine != null && (mine.isMineAccessByRank() || mine.isAccessPermissionEnabled()) && - !mine.hasMiningAccess( new SpigotPlayer( e.getPlayer() ) ) ) { - // The player does not have permission to access this mine, so do not process - // - - e.setCancelled( true ); - debugInfo += "ACCESS_DENIED (event canceled) "; - } - else if ( blockEventsOnly ) { - - String triggered = null; - - doActionBlockEventOnly( block, mine, e.getPlayer(), BlockEventType.blockBreak, triggered ); +// boolean isAir = e.getBlock().getType() == null || e.getBlock().getType() == Material.AIR; - debugInfo += "(actionBlockEventOnly) "; - } - else if ( monitor && mine == null ) { - // bypass all processing since the block break is outside any mine: - - debugInfo += "(bypassed monitor no mine) "; - } - else if ( monitor && mine != null ) { - - doActionMonitor( block, mine ); - - debugInfo += "(monitor) "; - } + +// Long playerUUIDLSB = Long.valueOf( pmEvent.getPlayer().getUniqueId().getLeastSignificantBits() ); +// +// // Get the cached mine, if it exists: +// Mine mine = getPlayerCache().get( playerUUIDLSB ); +// +// if ( mine == null || !mine.isInMineExact( pmEvent.getSpigotBlock().getLocation() ) ) { +// // Look for the correct mine to use. +// // Set mine to null so if cannot find the right one it will return a null: +// mine = findMineLocation( pmEvent.getSpigotBlock() ); +// +// // Store the mine in the player cache if not null: +// if ( mine != null ) { +// getPlayerCache().put( playerUUIDLSB, mine ); +// } +// } +// pmEvent.setMine( mine ); +// +// debugInfo.append( "mine=" + (mine == null ? "none" : mine.getName()) + " " ); +// +// +// if ( isToolDisabled( e.getPlayer() ) ) { +// +// PrisonUtilsTitles uTitles = new PrisonUtilsTitles(); +// uTitles.utilsTitlesActionBar( pmEvent.getSpigotPlayer(), "", +// "&cYour tool is worn-out and cannot be used." ); +// +// e.setCancelled( true ); +// debugInfo.append( "UNUSABLE_TOOL__WORN_OUT (event canceled) " ); +// } +// else if ( mine != null && BlockUtils.getInstance().isUnbreakable( sBlock ) ) { +// // The block is unbreakable because a utility has it locked: +// +// e.setCancelled( true ); +// debugInfo.append( "UNBREAKABLE_BLOCK_UTILS (event canceled) " ); +// } +// else if ( mine != null && (mine.isMineAccessByRank() || mine.isAccessPermissionEnabled()) && +// !mine.hasMiningAccess( pmEvent.getSpigotPlayer() ) ) { +// // The player does not have permission to access this mine, so do not process +// // +// +// e.setCancelled( true ); +// debugInfo.append( "ACCESS_DENIED (event canceled) " ); +// } +// else if ( blockEventsOnly ) { +// +// String triggered = null; +// +// doActionBlockEventOnly( sBlock, mine, e.getPlayer(), BlockEventType.blockBreak, triggered ); +// +// debugInfo.append( "(actionBlockEventOnly) " ); +// } +// else if ( monitor && mine == null ) { +// // bypass all processing since the block break is outside any mine: +// +// debugInfo.append( "(bypassed monitor no mine) " ); +// } +// else if ( monitor && mine != null ) { +// +// doActionMonitor( sBlock, mine ); +// +// debugInfo.append( "(monitor) " ); +// } // This is where the processing actually happens: - else if ( mine != null || mine == null && !isBoolean( AutoFeatures.pickupLimitToMines ) ) { + else if ( pmEvent.getMine() != null || pmEvent.getMine() == null && + !isBoolean( AutoFeatures.pickupLimitToMines ) ) { + debugInfo.append( "(normal processing initiating) " ); // Set the mine's PrisonBlockTypes for the block. Used to identify custom blocks. // Needed since processing of the block will lose track of which mine it came from. - if ( mine != null ) { - block.setPrisonBlockTypes( mine.getPrisonBlockTypes() ); + if ( pmEvent.getMine() != null ) { + sBlock.setPrisonBlockTypes( pmEvent.getMine().getPrisonBlockTypes() ); } // check all external events such as mcMMO and EZBlocks: OnBlockBreakExternalEvents.getInstance().checkAllExternalEvents( e ); List explodedBlocks = new ArrayList<>(); - String triggered = null; + pmEvent.setExplodedBlocks( explodedBlocks ); +// String triggered = null; - PrisonMinesBlockBreakEvent pmbbEvent = new PrisonMinesBlockBreakEvent( e.getBlock(), e.getPlayer(), - mine, block, explodedBlocks, BlockEventType.blockBreak, triggered ); - Bukkit.getServer().getPluginManager().callEvent(pmbbEvent); - if ( pmbbEvent.isCancelled() ) { - debugInfo += "(normal processing: PrisonMinesBlockBreakEvent canceld) "; +// PrisonMinesBlockBreakEvent pmbbEvent = new PrisonMinesBlockBreakEvent( e.getBlock(), e.getPlayer(), +// pmEvent.getMine(), sBlock, explodedBlocks, BlockEventType.blockBreak, triggered ); + Bukkit.getServer().getPluginManager().callEvent( pmEvent ); + if ( pmEvent.isCancelled() ) { + debugInfo.append( "(normal processing: PrisonMinesBlockBreakEvent was canceled) " ); } else { // doAction returns a boolean that indicates if the event should be canceled or not: - if ( doAction( block, mine, e.getPlayer() ) && - !isBoolean( AutoFeatures.isDebugSupressOnBlockBreakEventCancels )) { + if ( doAction( sBlock, pmEvent.getMine(), pmEvent.getPlayer(), debugInfo ) ) { + + if ( !isBoolean( AutoFeatures.isDebugSupressOnBlockBreakEventCancels ) ) { + e.setCancelled( true ); + } + else { + + debugInfo.append( "(event was not canceled) " ); + } - e.setCancelled( true ); } + else { + + debugInfo.append( "(doAction failed without details) " ); + } + } - debugInfo += "(normal processing) "; + debugInfo.append( "(normal processing completed) " ); } else { - debugInfo += "(logic bypass) "; + debugInfo.append( "(logic bypass) " ); } } - Output.get().logDebug( DebugTarget.blockBreak, debugInfo ); + Output.get().logDebug( DebugTarget.blockBreak, debugInfo.toString() ); } + /** + *

This function an attempt to provide a uniform procedure to validate if the event should + * be processed. This will eliminate a lot of duplicate code, and will make supporting other + * plugin events easier to implement. + *

+ * + *

This is using the PrisonMinesBlockBreakEvent object to act as the vehicle for carrying + * all of the possible parameters that are needed for appropriate processing. + *

+ * + * @param pmEvent + * @param debugInfo + * @return + */ + private boolean validateEvent( PrisonMinesBlockBreakEvent pmEvent, StringBuilder debugInfo ) + { + boolean results = true; + + Long playerUUIDLSB = Long.valueOf( pmEvent.getPlayer().getUniqueId().getLeastSignificantBits() ); + + // Get the cached mine, if it exists: + Mine mine = getPlayerCache().get( playerUUIDLSB ); + + if ( mine == null || !mine.isInMineExact( pmEvent.getSpigotBlock().getLocation() ) ) { + // Look for the correct mine to use. + // Set mine to null so if cannot find the right one it will return a null: + mine = findMineLocation( pmEvent.getSpigotBlock() ); + + // Thanks to CrazyEnchant, where they do not identify the block the player breaks, we + // have to go through all of the unprecessedRawBlocks to see if any are within a mine. + // If we find a block that's in a mine, then use that block as the primary block. + for ( Block bBlock : pmEvent.getUnprocessedRawBlocks() ) + { + SpigotBlock sBlock = new SpigotBlock( bBlock ); + mine = findMineLocation( sBlock ); + if ( mine != null ) { + pmEvent.setSpigotBlock( sBlock ); + break; + } + } + + // Store the mine in the player cache if not null: + if ( mine != null ) { + getPlayerCache().put( playerUUIDLSB, mine ); + } + } + pmEvent.setMine( mine ); + + debugInfo.append( "mine=" + (mine == null ? "none" : mine.getName()) + " " ); + + + // validate the blocks, if there are some. Add them to the exploded blocks list + if ( mine != null && pmEvent.getUnprocessedRawBlocks().size() > 0 ) { + int unbreakable = 0; + int outsideOfMine = 0; + + for ( Block bukkitBlock : pmEvent.getUnprocessedRawBlocks() ) + { + SpigotBlock sBlock = new SpigotBlock( bukkitBlock ); + + // Thanks to CrazyEnchant, there is no telling which block was actually hit, so + // if using CrazyEnchant one of the unprocessedRawBlocks may be the same as the + // pmEvent.getSpigotBlock(), so ignore if both are the same. + if ( !sBlock.equals( pmEvent.getSpigotBlock() ) ) { + + if ( BlockUtils.getInstance().isUnbreakable( sBlock ) ) { + + unbreakable++; + } + else if ( mine.isInMineExact( sBlock.getLocation() ) ) { + + pmEvent.getExplodedBlocks().add( sBlock ); + } + else { + outsideOfMine++; + } + } + + + } + + if ( pmEvent.getExplodedBlocks().size() > 0 ) { + + debugInfo.append( "VALIDATED_BLOCKS_IN_EXPLOSION (" + + pmEvent.getExplodedBlocks().size() + + " blocks) " ); + } + if ( unbreakable > 0 ) { + + debugInfo.append( "UNBREAKABLE_BLOCK_UTILS (" + unbreakable + + " blocks, event not canceled) " ); + } + if ( outsideOfMine > 0 ) { + + debugInfo.append( "BLOCKS_OUTSIDE_OF_MINE (" + outsideOfMine + + " blocks, event not canceled) " ); + } + } + + + + if ( isToolDisabled( pmEvent.getPlayer() ) ) { + + PrisonUtilsTitles uTitles = new PrisonUtilsTitles(); + uTitles.utilsTitlesActionBar( pmEvent.getSpigotPlayer(), "", + "&cYour tool is worn-out and cannot be used." ); + + pmEvent.setCancelOriginalEvent( true ); + debugInfo.append( "UNUSABLE_TOOL__WORN_OUT (event canceled) " ); + results = false; + } + else if ( mine != null && BlockUtils.getInstance().isUnbreakable( pmEvent.getSpigotBlock() ) ) { + // The block is unbreakable because a utility has it locked: + + pmEvent.setCancelOriginalEvent( true ); + debugInfo.append( "UNBREAKABLE_BLOCK_UTILS (event canceled) " ); + results = false; + } + else if ( mine != null && (mine.isMineAccessByRank() || mine.isAccessPermissionEnabled()) && + !mine.hasMiningAccess( pmEvent.getSpigotPlayer() ) ) { + // The player does not have permission to access this mine, so do not process + // + + pmEvent.setCancelOriginalEvent( true ); + debugInfo.append( "ACCESS_DENIED (event canceled) " ); + results = false; + } + else if ( pmEvent.isBlockEventsOnly() ) { + + String triggered = null; + + doActionBlockEventOnly( pmEvent.getSpigotBlock(), mine, pmEvent.getPlayer(), + BlockEventType.blockBreak, triggered ); + + debugInfo.append( "(actionBlockEventOnly singluar) " ); + + if ( pmEvent.getExplodedBlocks().size() > 0 ) { + + for ( SpigotBlock sBlock : pmEvent.getExplodedBlocks() ) { + + doActionBlockEventOnly( sBlock, mine, pmEvent.getPlayer(), + pmEvent.getBlockEventType(), pmEvent.getTriggered() ); + } + + debugInfo.append( "(actionBlockEventOnly - " + + pmEvent.getExplodedBlocks().size() + + " Exploded Blocks - finalized) " ); + } + + results = false; + } + else if ( pmEvent.isMonitor() && mine == null ) { + // bypass all processing since the block break is outside any mine: + + debugInfo.append( "(bypassed monitor no mine) " ); + results = false; + } + else if ( pmEvent.isMonitor() && mine != null ) { + + doActionMonitor( pmEvent.getSpigotBlock(), mine ); + + debugInfo.append( "(monitor - singular) " ); + + if ( pmEvent.getExplodedBlocks().size() > 0 ) { + + for ( SpigotBlock sBlock : pmEvent.getExplodedBlocks() ) { + + doActionMonitor( sBlock, mine ); + } + + debugInfo.append( "(monitor - " + + pmEvent.getExplodedBlocks().size() + + " Exploded Blocks - finalized) " ); + } + + results = false; + } + + + return results; + } + /** *

Since there are multiple blocks associated with this event, pull out the player first and * get the mine, then loop through those blocks to make sure they are within the mine. @@ -351,177 +652,289 @@ private void genericBlockExplodeEvent( TEBlockExplodeEvent e, boolean monitor, b // Register all external events such as mcMMO and EZBlocks: OnBlockBreakExternalEvents.getInstance().registerAllExternalEvents(); + StringBuilder debugInfo = new StringBuilder(); - String debugInfo = String.format( "### ** genericBlockExplodeEvent(TEBlockExplodeEvent) ** ### %s%s%s%s ", + debugInfo.append( String.format( "### ** genericBlockExplodeEvent(TEBlockExplodeEvent) ** ### %s%s%s%s ", (autoManager ? "autoManager " : ""), (e.isCancelled() ? "CANCELED " : ""), - (monitor ? "MONITOR " : ""), (blockEventsOnly ? "BlockEventsOnly" : "" )); + (monitor ? "MONITOR " : ""), (blockEventsOnly ? "BlockEventsOnly" : "" )) ); // NOTE that check for auto manager has happened prior to accessing this function. if ( !monitor && !e.isCancelled() || monitor ) { - List explodedBlocks = new ArrayList<>(); + boolean isTEExplosiveEnabled = isBoolean( AutoFeatures.isProcessTokensEnchantExplosiveEvents ); - // Need to wrap in a Prison block so it can be used with the mines: - SpigotBlock block = new SpigotBlock(e.getBlock()); + // Need to wrap in a Prison block so it can be used with the mines: + SpigotBlock sBlock = new SpigotBlock(e.getBlock()); + SpigotPlayer sPlayer = new SpigotPlayer(e.getPlayer()); - // long startNano = System.nanoTime(); - Long playerUUIDLSB = Long.valueOf( e.getPlayer().getUniqueId().getLeastSignificantBits() ); + BlockEventType eventType = BlockEventType.TEXplosion; + String triggered = checkCEExplosionTriggered( e ); - // Get the cached mine, if it exists: - Mine mine = getPlayerCache().get( playerUUIDLSB ); + PrisonMinesBlockBreakEvent pmEvent = new PrisonMinesBlockBreakEvent( e.getBlock(), e.getPlayer(), + sBlock, sPlayer, monitor, blockEventsOnly, eventType, triggered ); - if ( mine == null || !mine.isInMineExact( block.getLocation() ) ) { - - - // Look for the correct mine to use. - // Set mine to null so if cannot find the right one it will return a null: - mine = findMineLocation( block ); - - // Store the mine in the player cache if not null: - if ( mine != null ) { - getPlayerCache().put( playerUUIDLSB, mine ); - - // we found the mine! - } - - } - - debugInfo += "mine=" + (mine == null ? "none" : mine.getName()) + " "; - - boolean isTEExplosiveEnabled = isBoolean( AutoFeatures.isProcessTokensEnchantExplosiveEvents ); + pmEvent.setUnprocessedRawBlocks( e.blockList() ); - if ( mine != null && BlockUtils.getInstance().isUnbreakable( block ) ) { - // The block is unbreakable because a utility has it locked: + if ( !validateEvent( pmEvent, debugInfo ) ) { - e.setCancelled( true ); - debugInfo += "UNBREAKABLE_BLOCK_UTILS (event canceled) "; - } - else if ( mine != null && (mine.isMineAccessByRank() || mine.isAccessPermissionEnabled()) && - !mine.hasMiningAccess( new SpigotPlayer( e.getPlayer() ) ) ) { - // The player does not have permission to access this mine, so do not process - // - - e.setCancelled( true ); - debugInfo += "ACCESS_DENIED (event canceled) "; - } - else if ( blockEventsOnly ) { + // The event has not passed validation. All logging and Errors have been recorded + // so do nothing more. This is to just prevent normal processing from occurring. - if ( mine != null ) { - - String triggered = null; - - doActionBlockEventOnly( block, mine, e.getPlayer(), BlockEventType.blockBreak, triggered ); - - // All other blocks in the explosion: - for ( Block blk : e.blockList() ) { - - // Need to wrap in a Prison block so it can be used with the mines. - // Since this is a monitor, there is no need to check to see if the - // block is in a mine since the getTargetPrisonBlock function will - // perform that check indirectly. - SpigotBlock sBlock = new SpigotBlock(blk); - - if ( !BlockUtils.getInstance().isUnbreakable( sBlock ) ) { - - doActionBlockEventOnly( sBlock, mine, e.getPlayer(), BlockEventType.blockBreak, triggered ); - } - } - - } - - debugInfo += "(actionBlockEventOnly) "; - } - else if ( monitor && mine == null ) { - // bypass all processing since the block break is outside any mine: - - debugInfo += "(bypassed monitor no mine) "; - } - else if ( monitor && mine != null ) { - - // Initial block that was hit: - doActionMonitor( block, mine ); - - // All other blocks in the explosion: - for ( Block blk : e.blockList() ) { - - // Need to wrap in a Prison block so it can be used with the mines. - // Since this is a monitor, there is no need to check to see if the - // block is in a mine since the getTargetPrisonBlock function will - // perform that check indirectly. - SpigotBlock sBlock = new SpigotBlock(blk); + if ( pmEvent.isCancelOriginalEvent() ) { - if ( !BlockUtils.getInstance().isUnbreakable( sBlock ) ) { - - doActionMonitor( sBlock, mine ); - } + e.setCancelled( true ); } - - debugInfo += "(monitor) "; } + + +// List explodedBlocks = new ArrayList<>(); + +// // Need to wrap in a Prison block so it can be used with the mines: +// SpigotBlock block = new SpigotBlock(e.getBlock()); +// +// // long startNano = System.nanoTime(); +// Long playerUUIDLSB = Long.valueOf( e.getPlayer().getUniqueId().getLeastSignificantBits() ); +// +// // Get the cached mine, if it exists: +// Mine mine = getPlayerCache().get( playerUUIDLSB ); +// +// if ( mine == null || !mine.isInMineExact( block.getLocation() ) ) { +// +// +// // Look for the correct mine to use. +// // Set mine to null so if cannot find the right one it will return a null: +// mine = findMineLocation( block ); +// +// // Store the mine in the player cache if not null: +// if ( mine != null ) { +// getPlayerCache().put( playerUUIDLSB, mine ); +// +// // we found the mine! +// } +// +// } +// +// debugInfo.append( "mine=" + (mine == null ? "none" : mine.getName()) + " " ); + + +// if ( isToolDisabled( e.getPlayer() ) ) { +// +// PrisonUtilsTitles uTitles = new PrisonUtilsTitles(); +// uTitles.utilsTitlesActionBar( new SpigotPlayer( e.getPlayer() ), "", +// "&cYour tool is worn-out and cannot be used." ); +// +// e.setCancelled( true ); +// debugInfo.append( "UNUSABLE_TOOL__WORN_OUT (event canceled) " ); +// } +// else if ( mine != null && BlockUtils.getInstance().isUnbreakable( block ) ) { +// // The block is unbreakable because a utility has it locked: +// +// e.setCancelled( true ); +// debugInfo.append( "UNBREAKABLE_BLOCK_UTILS (event canceled) " ); +// } +// else if ( mine != null && (mine.isMineAccessByRank() || mine.isAccessPermissionEnabled()) && +// !mine.hasMiningAccess( new SpigotPlayer( e.getPlayer() ) ) ) { +// // The player does not have permission to access this mine, so do not process +// // +// +// e.setCancelled( true ); +// debugInfo.append( "ACCESS_DENIED (event canceled) " ); +// } +// else if ( blockEventsOnly ) { +// int unbreakable = 0; +// int outsideOfMine = 0; +// +// if ( mine != null ) { +// +// String triggered = null; +// +// // This was already checked to ensure it's breakable: +// doActionBlockEventOnly( block, mine, e.getPlayer(), BlockEventType.blockBreak, triggered ); +// +// // All other blocks in the explosion: +// for ( Block blk : e.blockList() ) { +// +// // Need to wrap in a Prison block so it can be used with the mines. +// // Since this is a monitor, there is no need to check to see if the +// // block is in a mine since the getTargetPrisonBlock function will +// // perform that check indirectly. +// SpigotBlock sBlock = new SpigotBlock(blk); +// +// if ( BlockUtils.getInstance().isUnbreakable( sBlock ) ) { +// +// unbreakable++; +// } +// else if ( mine.isInMineExact( sBlock.getLocation() ) ) { +// +// doActionBlockEventOnly( sBlock, mine, e.getPlayer(), BlockEventType.blockBreak, triggered ); +// } +// else { +// outsideOfMine++; +// } +// +// } +// +// } +// +// if ( unbreakable > 0 ) { +// +// // e.setCancelled( true ); +// debugInfo.append( "UNBREAKABLE_BLOCK_UTILS (" + unbreakable + +// " blocks, event not canceled) " ); +// } +// if ( outsideOfMine > 0 ) { +// +// debugInfo.append( "BLOCKS_OUTSIDE_OF_MINE (" + outsideOfMine + +// " blocks, event not canceled) " ); +// } +// +// debugInfo.append( "(actionBlockEventOnly) " ); +// } +// else if ( monitor && mine == null ) { +// // bypass all processing since the block break is outside any mine: +// +// debugInfo.append( "(bypassed monitor no mine) " ); +// } +// else if ( monitor && mine != null ) { +// int unbreakable = 0; +// int outsideOfMine = 0; +// +// // Initial block that was hit: +// doActionMonitor( block, mine ); +// +// // All other blocks in the explosion: +// for ( Block blk : e.blockList() ) { +// +// // Need to wrap in a Prison block so it can be used with the mines. +// // Since this is a monitor, there is no need to check to see if the +// // block is in a mine since the getTargetPrisonBlock function will +// // perform that check indirectly. +// SpigotBlock sBlock = new SpigotBlock(blk); +// +// if ( BlockUtils.getInstance().isUnbreakable( new SpigotBlock( blk ) ) ) { +// +// unbreakable++; +// } +// else if ( mine.isInMineExact( sBlock.getLocation() ) ) { +// +// doActionMonitor( sBlock, mine ); +// } +// else { +// outsideOfMine++; +// } +// } +// +// if ( unbreakable > 0 ) { +// +// // e.setCancelled( true ); +// debugInfo.append( "UNBREAKABLE_BLOCK_UTILS (" + unbreakable + +// " blocks, event not canceled) " ); +// } +// if ( outsideOfMine > 0 ) { +// +// debugInfo.append( "BLOCKS_OUTSIDE_OF_MINE (" + outsideOfMine + +// " blocks, event not canceled) " ); +// } +// debugInfo.append( "(monitor) " ); +// } // now process all blocks (non-monitor): else if ( isTEExplosiveEnabled && - ( mine != null || mine == null && !isBoolean( AutoFeatures.pickupLimitToMines )) ) { + ( pmEvent.getMine() != null || pmEvent.getMine() == null && + !isBoolean( AutoFeatures.pickupLimitToMines )) ) { +// int unbreakable = 0; +// int outsideOfMine = 0; // have to go through all blocks since some blocks may be outside the mine. // but terminate search upon first find: - for ( Block blk : e.blockList() ) { - //boolean isAir = blk.getType() != null && blk.getType() == Material.AIR; - - // Need to wrap in a Prison block so it can be used with the mines: - SpigotBlock sBlock = new SpigotBlock(blk); - - - if ( !BlockUtils.getInstance().isUnbreakable( sBlock ) && - mine.isInMineExact( sBlock.getLocation() ) ) { - - explodedBlocks.add( sBlock ); - - - // check all external events such as mcMMO and EZBlocks: - OnBlockBreakExternalEvents.getInstance().checkAllExternalEvents( e.getPlayer(), blk ); - } - - } +// for ( Block blk : e.blockList() ) { +// //boolean isAir = blk.getType() != null && blk.getType() == Material.AIR; +// +// // Need to wrap in a Prison block so it can be used with the mines: +//// SpigotBlock sBlock = new SpigotBlock(blk); +// +// +// if ( BlockUtils.getInstance().isUnbreakable( pmEvent.getSpigotBlock() ) ) { +// +// unbreakable++; +// } +// else if ( pmEvent.getMine().isInMineExact( sBlock.getLocation() ) ) { +// +// pmEvent.getExplodedBlocks().add( sBlock ); +// +// +// // check all external events such as mcMMO and EZBlocks: +// OnBlockBreakExternalEvents.getInstance().checkAllExternalEvents( e.getPlayer(), blk ); +// } +// else { +// outsideOfMine++; +// } +// +// } - if ( explodedBlocks.size() > 0 ) { + if ( pmEvent.getExplodedBlocks().size() > 0 ) { - String triggered = checkCEExplosionTriggered( e ); - - - PrisonMinesBlockBreakEvent pmbbEvent = new PrisonMinesBlockBreakEvent( e.getBlock(), e.getPlayer(), - mine, block, explodedBlocks, BlockEventType.TEXplosion, triggered ); - Bukkit.getServer().getPluginManager().callEvent(pmbbEvent); - if ( pmbbEvent.isCancelled() ) { - debugInfo += "(normal processing: PrisonMinesBlockBreakEvent canceld) "; +// String triggered = checkCEExplosionTriggered( e ); +// +// +// PrisonMinesBlockBreakEvent pmbbEvent = new PrisonMinesBlockBreakEvent( e.getBlock(), e.getPlayer(), +// mine, block, explodedBlocks, BlockEventType.TEXplosion, triggered ); + Bukkit.getServer().getPluginManager().callEvent( pmEvent ); + if ( pmEvent.isCancelled() ) { + debugInfo.append( "(normal processing: PrisonMinesBlockBreakEvent was canceled) " ); } else { // This is where the processing actually happens: - if ( doAction( mine, e.getPlayer(), explodedBlocks, BlockEventType.TEXplosion, triggered ) && - !isBoolean( AutoFeatures.isDebugSupressOnTEExplodeEventCancels )) { + if ( doAction( pmEvent.getMine(), pmEvent.getPlayer(), + pmEvent.getExplodedBlocks(), BlockEventType.TEXplosion, triggered, debugInfo ) ) { - e.setCancelled( true ); + if ( !isBoolean( AutoFeatures.isDebugSupressOnTEExplodeEventCancels ) ) { + + e.setCancelled( true ); + } + else { + + debugInfo.append( "(event was not canceled) " ); + } } + + else { + + debugInfo.append( "(doAction failed without details) " ); + } + } } - debugInfo += "(normal processing) "; +// if ( unbreakable > 0 ) { +// +// // e.setCancelled( true ); +// debugInfo.append( "UNBREAKABLE_BLOCK_UTILS (" + unbreakable + +// " blocks, event not canceled) " ); +// } +// if ( outsideOfMine > 0 ) { +// +// debugInfo.append( "BLOCKS_OUTSIDE_OF_MINE (" + outsideOfMine + +// " blocks, event not canceled) " ); +// } + + debugInfo.append( "(normal processing) " ); } else { - debugInfo += "(logic bypass) "; + debugInfo.append( "(logic bypass) " ); } } - Output.get().logDebug( DebugTarget.blockBreak, debugInfo ); + Output.get().logDebug( DebugTarget.blockBreak, debugInfo.toString() ); } @@ -570,212 +983,550 @@ private String checkCEExplosionTriggered( TEBlockExplodeEvent e ) * * @param e */ - protected void genericBlockExplodeEvent( BlastUseEvent e, boolean monitor, boolean blockEventsOnly, + protected void genericBlastUseEvent( BlastUseEvent e, boolean monitor, boolean blockEventsOnly, boolean autoManager ) { // Register all external events such as mcMMO and EZBlocks: OnBlockBreakExternalEvents.getInstance().registerAllExternalEvents(); + StringBuilder debugInfo = new StringBuilder(); - String debugInfo = String.format( "### ** genericBlockExplodeEvent(BlastUseEvent) ** ### %s%s%s%s ", + debugInfo.append( String.format( "### ** genericBlastUseEvent(BlastUseEvent) ** ### %s%s%s%s ", (autoManager ? "autoManager " : ""), (e.isCancelled() ? "CANCELED " : ""), - (monitor ? "MONITOR " : ""), (blockEventsOnly ? "BlockEventsOnly" : "" )); + (monitor ? "MONITOR " : ""), (blockEventsOnly ? "BlockEventsOnly" : "" )) ); // NOTE that check for auto manager has happened prior to accessing this function. if ( (!monitor && !e.isCancelled() || monitor) && e.getBlockList().size() > 0 ) { - - List explodedBlocks = new ArrayList<>(); - - - // long startNano = System.nanoTime(); - Long playerUUIDLSB = Long.valueOf( e.getPlayer().getUniqueId().getLeastSignificantBits() ); - - // Get the cached mine, if it exists: - Mine mine = getPlayerCache().get( playerUUIDLSB ); - - if ( mine == null ) { - - - // NOTE: The crazy enchantment's blast use event does not identify the block that - // was hit, so will have to check them all. - - // have to go through all blocks since some blocks may be outside the mine. - // but terminate search upon first find: - for ( Block blk : e.getBlockList() ) { - // Need to wrap in a Prison block so it can be used with the mines: - SpigotBlock block = new SpigotBlock(blk); - - // Look for the correct mine to use. - // Set mine to null so if cannot find the right one it will return a null: - mine = findMineLocation( block ); - - // Store the mine in the player cache if not null: - if ( mine != null ) { - getPlayerCache().put( playerUUIDLSB, mine ); - - // we found the mine! - break; - } - } - } - else { - - // NOTE: Just because the mine is not null, does not mean that the block was tested to be - // within the mine. The mine from the player cache could be a different mine - // altogether. The block must be tested. - - // have to go through all blocks since some blocks may be outside the mine. - // but terminate search upon first find: - for ( Block blk : e.getBlockList() ) { - // Need to wrap in a Prison block so it can be used with the mines: - SpigotBlock block = new SpigotBlock(blk); - - // Look for the correct mine to use. - // Set mine to null so if cannot find the right one it will return a null: - mine = findMineLocation( block ); - - // Store the mine in the player cache if not null: - if ( mine != null ) { - getPlayerCache().put( playerUUIDLSB, mine ); - - // we found the mine! - break; - } - } - - } - debugInfo += "mine=" + (mine == null ? "none" : mine.getName()) + " "; - - boolean isCEBlockExplodeEnabled = isBoolean( AutoFeatures.isProcessCrazyEnchantsBlockExplodeEvents ); + boolean isCEBlockExplodeEnabled = isBoolean( AutoFeatures.isProcessCrazyEnchantsBlockExplodeEvents ); + + Block bukkitBlock = e.getBlockList().get( 0 ); + + // Need to wrap in a Prison block so it can be used with the mines: + SpigotBlock sBlock = new SpigotBlock( bukkitBlock ); + SpigotPlayer sPlayer = new SpigotPlayer(e.getPlayer()); + + BlockEventType eventType = BlockEventType.CEXplosion; + String triggered = null; - if ( mine != null && (mine.isMineAccessByRank() || mine.isAccessPermissionEnabled()) && - !mine.hasMiningAccess( new SpigotPlayer( e.getPlayer() ) ) ) { - // The player does not have permission to access this mine, so do not process - // - - e.setCancelled( true ); - debugInfo += "ACCESS_DENIED (event canceled) "; - } - else if ( blockEventsOnly ) { - - if ( mine != null ) { - - String triggered = null; - - // All other blocks in the explosion: - for ( Block blk : e.getBlockList() ) { - - // Need to wrap in a Prison block so it can be used with the mines. - // Since this is a monitor, there is no need to check to see if the - // block is in a mine since the getTargetPrisonBlock function will - // perform that check indirectly. - SpigotBlock sBlock = new SpigotBlock(blk); - - if ( !BlockUtils.getInstance().isUnbreakable( sBlock ) ) { - - doActionBlockEventOnly( sBlock, mine, e.getPlayer(), BlockEventType.CEXplosion, triggered ); - } - } - } - debugInfo += "(actionBlockEventOnly) "; + PrisonMinesBlockBreakEvent pmEvent = new PrisonMinesBlockBreakEvent( bukkitBlock, e.getPlayer(), + sBlock, sPlayer, monitor, blockEventsOnly, eventType, triggered ); + + + for ( int i = 1; i < e.getBlockList().size(); i++ ) { + pmEvent.getUnprocessedRawBlocks().add( e.getBlockList().get( i ) ); } - else if ( monitor && mine == null ) { - // bypass all processing since the block break is outside any mine: + + + if ( !validateEvent( pmEvent, debugInfo ) ) { - debugInfo += "(bypassed monitor no mine) "; - } - else if ( monitor && mine != null ) { - - // Initial block that was hit: CrazyE does not have the main block: - // doActionMonitor( block, mine ); + // The event has not passed validation. All logging and Errors have been recorded + // so do nothing more. This is to just prevent normal processing from occurring. - // All other blocks in the explosion: - for ( Block blk : e.getBlockList() ) { + if ( pmEvent.isCancelOriginalEvent() ) { - // Need to wrap in a Prison block so it can be used with the mines. - // Since this is a monitor, there is no need to check to see if the - // block is in a mine since the getTargetPrisonBlock function will - // perform that check indirectly. - SpigotBlock sBlock = new SpigotBlock(blk); - - if ( !BlockUtils.getInstance().isUnbreakable( sBlock ) ) { - - doActionMonitor( sBlock, mine ); - } + e.setCancelled( true ); } - - debugInfo += "(monitor) "; } + +// +// List explodedBlocks = new ArrayList<>(); +// +// +// // long startNano = System.nanoTime(); +// Long playerUUIDLSB = Long.valueOf( e.getPlayer().getUniqueId().getLeastSignificantBits() ); +// +// // Get the cached mine, if it exists: +// Mine mine = getPlayerCache().get( playerUUIDLSB ); +// +// if ( mine == null ) { +// +// +// // NOTE: The crazy enchantment's blast use event does not identify the block that +// // was hit, so will have to check them all. +// +// // have to go through all blocks since some blocks may be outside the mine. +// // but terminate search upon first find: +// for ( Block blk : e.getBlockList() ) { +// // Need to wrap in a Prison block so it can be used with the mines: +// SpigotBlock block = new SpigotBlock(blk); +// +// // Look for the correct mine to use. +// // Set mine to null so if cannot find the right one it will return a null: +// mine = findMineLocation( block ); +// +// // Store the mine in the player cache if not null: +// if ( mine != null ) { +// getPlayerCache().put( playerUUIDLSB, mine ); +// +// // we found the mine! +// break; +// } +// } +// } +// else { +// +// // NOTE: Just because the mine is not null, does not mean that the block was tested to be +// // within the mine. The mine from the player cache could be a different mine +// // altogether. The block must be tested. +// +// // have to go through all blocks since some blocks may be outside the mine. +// // but terminate search upon first find: +// for ( Block blk : e.getBlockList() ) { +// // Need to wrap in a Prison block so it can be used with the mines: +// SpigotBlock block = new SpigotBlock(blk); +// +// // Look for the correct mine to use. +// // Set mine to null so if cannot find the right one it will return a null: +// mine = findMineLocation( block ); +// +// // Store the mine in the player cache if not null: +// if ( mine != null ) { +// getPlayerCache().put( playerUUIDLSB, mine ); +// +// // we found the mine! +// break; +// } +// } +// +// } +// +// debugInfo.append( "mine=" + (mine == null ? "none" : mine.getName()) + " " ); +// +// boolean isCEBlockExplodeEnabled = isBoolean( AutoFeatures.isProcessCrazyEnchantsBlockExplodeEvents ); +// +// if ( isToolDisabled( e.getPlayer() ) ) { +// +// PrisonUtilsTitles uTitles = new PrisonUtilsTitles(); +// uTitles.utilsTitlesActionBar( new SpigotPlayer( e.getPlayer() ), "", +// "&cYour tool is worn-out and cannot be used." ); +// +// e.setCancelled( true ); +// debugInfo.append( "UNUSABLE_TOOL__WORN_OUT (event canceled) " ); +// } +//// else if ( mine != null && BlockUtils.getInstance().isUnbreakable( block ) ) { +//// // The block is unbreakable because a utility has it locked: +//// +//// e.setCancelled( true ); +//// debugInfo += "UNBREAKABLE_BLOCK_UTILS (event canceled) "; +//// } +// else if ( mine != null && (mine.isMineAccessByRank() || mine.isAccessPermissionEnabled()) && +// !mine.hasMiningAccess( new SpigotPlayer( e.getPlayer() ) ) ) { +// // The player does not have permission to access this mine, so do not process +// // +// +// e.setCancelled( true ); +// debugInfo.append( "ACCESS_DENIED (event canceled) " ); +// } +// else if ( blockEventsOnly ) { +// int unbreakable = 0; +// int outsideOfMine = 0; +// +// if ( mine != null ) { +// +// String triggered = null; +// +// // All other blocks in the explosion: +// for ( Block blk : e.getBlockList() ) { +// +// +// // Need to wrap in a Prison block so it can be used with the mines. +// // Since this is a monitor, there is no need to check to see if the +// // block is in a mine since the getTargetPrisonBlock function will +// // perform that check indirectly. +// SpigotBlock sBlock = new SpigotBlock(blk); +// +// if ( BlockUtils.getInstance().isUnbreakable( new SpigotBlock( blk ) ) ) { +// +// unbreakable++; +// } +// else if ( mine.isInMineExact( sBlock.getLocation() ) ) { +// +// doActionBlockEventOnly( sBlock, mine, e.getPlayer(), BlockEventType.CEXplosion, triggered ); +// } +// else { +// outsideOfMine++; +// } +// +// } +// } +// +// if ( unbreakable > 0 ) { +// +// // e.setCancelled( true ); +// debugInfo.append( "UNBREAKABLE_BLOCK_UTILS (" + unbreakable + +// " blocks, event not canceled) " ); +// } +// if ( outsideOfMine > 0 ) { +// +// debugInfo.append( "BLOCKS_OUTSIDE_OF_MINE (" + outsideOfMine + +// " blocks, event not canceled) " ); +// } +// +// debugInfo.append( "(actionBlockEventOnly) " ); +// } +// else if ( monitor && mine == null ) { +// // bypass all processing since the block break is outside any mine: +// +// debugInfo.append( "(bypassed monitor no mine) " ); +// } +// else if ( monitor && mine != null ) { +// int unbreakable = 0; +// int outsideOfMine = 0; +// +// // Initial block that was hit: CrazyE does not have the main block: +// // doActionMonitor( block, mine ); +// +// // All other blocks in the explosion: +// for ( Block blk : e.getBlockList() ) { +// +// // Need to wrap in a Prison block so it can be used with the mines. +// // Since this is a monitor, there is no need to check to see if the +// // block is in a mine since the getTargetPrisonBlock function will +// // perform that check indirectly. +// SpigotBlock sBlock = new SpigotBlock(blk); +// +// if ( BlockUtils.getInstance().isUnbreakable( new SpigotBlock( blk ) ) ) { +// +// unbreakable++; +// } +// else if ( mine.isInMineExact( sBlock.getLocation() ) ) { +// +// doActionMonitor( sBlock, mine ); +// } +// else { +// outsideOfMine++; +// } +// +// } +// +// if ( unbreakable > 0 ) { +// +// // e.setCancelled( true ); +// debugInfo.append( "UNBREAKABLE_BLOCK_UTILS (" + unbreakable + +// " blocks, event not canceled) " ); +// } +// if ( outsideOfMine > 0 ) { +// +// debugInfo.append( "BLOCKS_OUTSIDE_OF_MINE (" + outsideOfMine + +// " blocks, event not canceled) " ); +// } +// +// debugInfo.append( "(monitor) " ); +// } + // now process all blocks (non-monitor): else if ( isCEBlockExplodeEnabled && - ( mine != null || mine == null && !isBoolean( AutoFeatures.pickupLimitToMines )) ) { + ( pmEvent.getMine() != null || pmEvent.getMine() == null && !isBoolean( AutoFeatures.pickupLimitToMines )) ) { +// int unbreakable = 0; +// int outsideOfMine = 0; // have to go through all blocks since some blocks may be outside the mine. // but terminate search upon first find: - for ( Block blk : e.getBlockList() ) { - - // Need to wrap in a Prison block so it can be used with the mines: - SpigotBlock sBlock = new SpigotBlock(blk); - - if ( !BlockUtils.getInstance().isUnbreakable( sBlock ) && - mine.isInMineExact( sBlock.getLocation() ) ) { - - explodedBlocks.add( sBlock ); - - - // check all external events such as mcMMO and EZBlocks: - OnBlockBreakExternalEvents.getInstance().checkAllExternalEvents( e.getPlayer(), blk ); - } - - } - if ( explodedBlocks.size() > 0 ) { +// for ( Block blk : e.getBlockList() ) { +// +// // Need to wrap in a Prison block so it can be used with the mines: +// SpigotBlock sBlock = new SpigotBlock(blk); +// +// if ( BlockUtils.getInstance().isUnbreakable( new SpigotBlock( blk ) ) ) { +// +// unbreakable++; +// } +// else if ( mine.isInMineExact( sBlock.getLocation() ) ) { +// +// explodedBlocks.add( sBlock ); +// +// // check all external events such as mcMMO and EZBlocks: +// OnBlockBreakExternalEvents.getInstance().checkAllExternalEvents( e.getPlayer(), blk ); +// } +// else { +// outsideOfMine++; +// } +// +// } + if ( pmEvent.getExplodedBlocks().size() > 0 ) { - String triggered = null; +// String triggered = null; // Warning: BlastUseEvent does not identify the block the player actually hit, so the dummyBlock // is just a random first block from the explodedBlocks list and may not be the block // that initiated the explosion event. - SpigotBlock dummyBlock = explodedBlocks.get( 0 ); +// SpigotBlock dummyBlock = explodedBlocks.get( 0 ); - PrisonMinesBlockBreakEvent pmbbEvent = new PrisonMinesBlockBreakEvent( dummyBlock.getWrapper(), e.getPlayer(), - mine, dummyBlock, explodedBlocks, BlockEventType.CEXplosion, triggered ); - Bukkit.getServer().getPluginManager().callEvent(pmbbEvent); - if ( pmbbEvent.isCancelled() ) { - debugInfo += "(normal processing: PrisonMinesBlockBreakEvent canceld) "; +// PrisonMinesBlockBreakEvent pmbbEvent = new PrisonMinesBlockBreakEvent( dummyBlock.getWrapper(), e.getPlayer(), +// mine, dummyBlock, explodedBlocks, BlockEventType.CEXplosion, triggered ); + Bukkit.getServer().getPluginManager().callEvent(pmEvent); + if ( pmEvent.isCancelled() ) { + debugInfo.append( "(normal processing: PrisonMinesBlockBreakEvent was canceled) " ); } else { - // This is where the processing actually happens: - if ( doAction( mine, e.getPlayer(), explodedBlocks, BlockEventType.CEXplosion, triggered ) && - !isBoolean( AutoFeatures.isDebugSupressOnCEBlastUseEventCancels )) { + if ( doAction( pmEvent.getMine(), e.getPlayer(), pmEvent.getExplodedBlocks(), + BlockEventType.CEXplosion, triggered, debugInfo ) ) { + + if ( !isBoolean( AutoFeatures.isDebugSupressOnCEBlastUseEventCancels ) ) { + + e.setCancelled( true ); + } + else { + + debugInfo.append( "(event was not canceled) " ); + } + } + + else { + + debugInfo.append( "(doAction failed without details) " ); + } + + } + } + +// if ( unbreakable > 0 ) { +// +// // e.setCancelled( true ); +// debugInfo.append( "UNBREAKABLE_BLOCK_UTILS (" + unbreakable + +// " blocks, event not canceled) " ); +// } +// if ( outsideOfMine > 0 ) { +// +// debugInfo.append( "BLOCKS_OUTSIDE_OF_MINE (" + outsideOfMine + +// " blocks, event not canceled) " ); +// } + + debugInfo.append( "(normal processing) " ); + } + else { + + debugInfo.append( "(logic bypass) " ); + } + + } + + Output.get().logDebug( DebugTarget.blockBreak, debugInfo.toString() ); + + } + + + + /** + *

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

+ * + *

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

+ * + * @param e + */ + protected void genericExplosiveEvent( PEExplosionEvent e, boolean monitor, boolean blockEventsOnly, + boolean autoManager ) { + + // Register all external events such as mcMMO and EZBlocks: + OnBlockBreakExternalEvents.getInstance().registerAllExternalEvents(); + + StringBuilder debugInfo = new StringBuilder(); + + debugInfo.append( String.format( "### ** genericExplosiveEvent(PrisonEnchants - ExplosiveEvent) ** ### %s%s%s%s ", + (autoManager ? "autoManager " : ""), + (e.isCancelled() ? "CANCELED " : ""), + (monitor ? "MONITOR " : ""), (blockEventsOnly ? "BlockEventsOnly" : "" )) ); + + + + // NOTE that check for auto manager has happened prior to accessing this function. + if ( !monitor && !e.isCancelled() || monitor ) { + + + boolean isPEExplosiveEnabled = isBoolean( AutoFeatures.isProcessPrisonEnchantsExplosiveEvents ); + + + // Need to wrap in a Prison block so it can be used with the mines: + SpigotBlock sBlock = new SpigotBlock(e.getBlock()); + SpigotPlayer sPlayer = new SpigotPlayer(e.getPlayer()); + + BlockEventType eventType = BlockEventType.PEExplosive; + String triggered = e.getTriggeredBy(); + + PrisonMinesBlockBreakEvent pmEvent = new PrisonMinesBlockBreakEvent( e.getBlock(), e.getPlayer(), + sBlock, sPlayer, monitor, blockEventsOnly, eventType, triggered ); + + pmEvent.setUnprocessedRawBlocks( e.getExplodedBlocks() ); + + if ( !validateEvent( pmEvent, debugInfo ) ) { + + // The event has not passed validation. All logging and Errors have been recorded + // so do nothing more. This is to just prevent normal processing from occurring. + + if ( pmEvent.isCancelOriginalEvent() ) { + + e.setCancelled( true ); + } + } + + + + + // now process all blocks (non-monitor): + else if ( isPEExplosiveEnabled && + ( pmEvent.getMine() != null || pmEvent.getMine() == null && !isBoolean( AutoFeatures.pickupLimitToMines )) ) { + if ( pmEvent.getExplodedBlocks().size() > 0 ) { + +// String triggered = null; + + +// PrisonMinesBlockBreakEvent pmbbEvent = new PrisonMinesBlockBreakEvent( dummyBlock.getWrapper(), e.getPlayer(), +// mine, dummyBlock, explodedBlocks, BlockEventType.PEExplosive, triggered ); + Bukkit.getServer().getPluginManager().callEvent(pmEvent); + if ( pmEvent.isCancelled() ) { + debugInfo.append( "(normal processing: PrisonMinesBlockBreakEvent was canceled) " ); + } + else { + + if ( doAction( pmEvent.getMine(), e.getPlayer(), pmEvent.getExplodedBlocks(), + BlockEventType.PEExplosive, triggered, debugInfo ) ) { + + if ( !isBoolean( AutoFeatures.isDebugSupressOnPEExplosiveEventCancels ) ) { + + e.setCancelled( true ); + } + else { + + debugInfo.append( "(event was not canceled) " ); + } + } + + else { - e.setCancelled( true ); + debugInfo.append( "(doAction failed without details) " ); } } } - debugInfo += "(normal processing) "; + + + debugInfo.append( "(normal processing) " ); } else { - debugInfo += "(logic bypass) "; + debugInfo.append( "(logic bypass) " ); } } - Output.get().logDebug( DebugTarget.blockBreak, debugInfo ); + Output.get().logDebug( DebugTarget.blockBreak, debugInfo.toString() ); } + protected void genericExplosiveEvent( ExplosiveBlockBreakEvent e, boolean monitor, boolean blockEventsOnly, + boolean autoManager ) { + + // Register all external events such as mcMMO and EZBlocks: + OnBlockBreakExternalEvents.getInstance().registerAllExternalEvents(); + + StringBuilder debugInfo = new StringBuilder(); + + debugInfo.append( String.format( "### ** genericExplosiveEvent(Prison's - ExplosiveBlockBreakEvent) ** ### %s%s%s%s ", + (autoManager ? "autoManager " : ""), + (e.isCancelled() ? "CANCELED " : ""), + (monitor ? "MONITOR " : ""), (blockEventsOnly ? "BlockEventsOnly" : "" )) ); + + + + // NOTE that check for auto manager has happened prior to accessing this function. + if ( !monitor && !e.isCancelled() || monitor ) { + + + boolean isPEExplosiveEnabled = isBoolean( AutoFeatures.isProcessPrisonEnchantsExplosiveEvents ); + + + // Need to wrap in a Prison block so it can be used with the mines: + SpigotBlock sBlock = new SpigotBlock(e.getBlock()); + SpigotPlayer sPlayer = new SpigotPlayer(e.getPlayer()); + + BlockEventType eventType = BlockEventType.PEExplosive; + String triggered = e.getTriggeredBy(); + + PrisonMinesBlockBreakEvent pmEvent = new PrisonMinesBlockBreakEvent( e.getBlock(), e.getPlayer(), + sBlock, sPlayer, monitor, blockEventsOnly, eventType, triggered ); + + pmEvent.setUnprocessedRawBlocks( e.getExplodedBlocks() ); + + if ( !validateEvent( pmEvent, debugInfo ) ) { + + // The event has not passed validation. All logging and Errors have been recorded + // so do nothing more. This is to just prevent normal processing from occurring. + + if ( pmEvent.isCancelOriginalEvent() ) { + + e.setCancelled( true ); + } + } + + + + // now process all blocks (non-monitor): + else if ( isPEExplosiveEnabled && + ( pmEvent.getMine() != null || pmEvent.getMine() == null && !isBoolean( AutoFeatures.pickupLimitToMines )) ) { + if ( pmEvent.getExplodedBlocks().size() > 0 ) { + +// String triggered = null; + + +// PrisonMinesBlockBreakEvent pmbbEvent = new PrisonMinesBlockBreakEvent( dummyBlock.getWrapper(), e.getPlayer(), +// mine, dummyBlock, explodedBlocks, BlockEventType.PEExplosive, triggered ); + Bukkit.getServer().getPluginManager().callEvent(pmEvent); + if ( pmEvent.isCancelled() ) { + debugInfo.append( "(normal processing: PrisonMinesBlockBreakEvent was canceled) " ); + } + else { + + if ( doAction( pmEvent.getMine(), e.getPlayer(), pmEvent.getExplodedBlocks(), + BlockEventType.PEExplosive, triggered, debugInfo ) ) { + + if ( !isBoolean( AutoFeatures.isDebugSupressOnPEExplosiveEventCancels ) ) { + + e.setCancelled( true ); + } + else { + + debugInfo.append( "(event was not canceled) " ); + } + } + + else { + + debugInfo.append( "(doAction failed without details) " ); + } + + } + } + + + debugInfo.append( "(normal processing) " ); + } + else { + + debugInfo.append( "(logic bypass) " ); + } + + } + + Output.get().logDebug( DebugTarget.blockBreak, debugInfo.toString() ); + + } + + public void doActionMonitor( SpigotBlock block, Mine mine ) { if ( mine != null ) { @@ -814,14 +1565,17 @@ public void doActionBlockEventOnly( SpigotBlock spigotBlock, Mine mine, Player p PrisonBlock prisonBlock = spigotBlock.getPrisonBlock(); + PlayerCache.getInstance().addPlayerBlocks( sPlayer, mine.getName(), targetBlock.getPrisonBlock(), 1 ); + mine.processBlockBreakEventCommands( prisonBlock, targetBlock, sPlayer, blockEventType, triggered ); } } } - public boolean doAction( SpigotBlock spigotBlock, Mine mine, Player player ) { + public boolean doAction( SpigotBlock spigotBlock, Mine mine, Player player, StringBuilder debugInfo ) { boolean cancel = false; + debugInfo.append( "(doAction: starting EventCore) " ); SpigotItemStack itemInHand = SpigotPrison.getInstance().getCompatibility().getPrisonItemInMainHand( player ); @@ -832,29 +1586,26 @@ public boolean doAction( SpigotBlock spigotBlock, Mine mine, Player player ) { // boolean isAutoManagerEnabled = aMan.isBoolean( AutoFeatures.isAutoManagerEnabled ); boolean isProcessNormalDropsEnabled = isBoolean( AutoFeatures.handleNormalDropsEvents ); + int drop = 1; if ( isProcessNormalDropsEnabled ) { - // Drop the contents of the individual block breaks - int drop = aMan.calculateNormalDrop( itemInHand, spigotBlock ); + debugInfo.append( "(doAction calculateNormalDrop) " ); - if ( drop > 0 ) { - - aMan.processBlockBreakage( spigotBlock, mine, player, drop, BlockEventType.blockBreak, - null, itemInHand ); - - cancel = true; - - aMan.autosellPerBlockBreak( player ); - } + // Drop the contents of the individual block breaks + drop = aMan.calculateNormalDrop( itemInHand, spigotBlock ); } - else { + + if ( drop > 0 ) { + debugInfo.append( "(doAction processBlockBreakage) " ); - aMan.processBlockBreakage( spigotBlock, mine, player, 1, BlockEventType.blockBreak, null, - itemInHand ); + aMan.processBlockBreakage( spigotBlock, mine, player, drop, BlockEventType.blockBreak, + null, itemInHand, true, debugInfo ); cancel = true; + + aMan.autosellPerBlockBreak( player ); } if ( mine != null ) { @@ -876,7 +1627,7 @@ public boolean doAction( SpigotBlock spigotBlock, Mine mine, Player player ) { * @param teExplosiveBlocks */ public boolean doAction( Mine mine, Player player, List explodedBlocks, - BlockEventType blockEventType, String triggered ) { + BlockEventType blockEventType, String triggered, StringBuilder debugInfo ) { boolean cancel = false; int totalCount = 0; @@ -885,10 +1636,13 @@ public boolean doAction( Mine mine, Player player, List explodedBlo AutoManagerFeatures aMan = SpigotPrison.getInstance().getAutoFeatures(); + debugInfo.append( "(doAction multi-blocks: " + explodedBlocks.size() ); // The explodedBlocks list have already been validated as being within the mine: + boolean applyExhaustion = true; for ( SpigotBlock spigotBlock : explodedBlocks ) { + // Drop the contents of the individual block breaks int drop = aMan.calculateNormalDrop( itemInHand, spigotBlock ); totalCount += drop; @@ -896,7 +1650,9 @@ public boolean doAction( Mine mine, Player player, List explodedBlo if ( drop > 0 ) { aMan.processBlockBreakage( spigotBlock, mine, player, drop, - blockEventType, triggered, itemInHand ); + blockEventType, triggered, itemInHand, + applyExhaustion, debugInfo ); + applyExhaustion = false; aMan.autosellPerBlockBreak( player ); } @@ -1000,7 +1756,8 @@ public boolean doAction( Mine mine, Player player, List explodedBlo public void processBlockBreakage( SpigotBlock spigotBlock, Mine mine, Player player, int count, - BlockEventType blockEventType, String triggered, SpigotItemStack itemInHand ) + BlockEventType blockEventType, String triggered, SpigotItemStack itemInHand, + boolean applyExhaustion, StringBuilder debugInfo ) { MineTargetPrisonBlock targetBlock = null; @@ -1013,10 +1770,13 @@ public void processBlockBreakage( SpigotBlock spigotBlock, // and wasn't originally air, then process the breakage: if ( mine == null || targetBlock != null && !targetBlock.isAirBroke() ) { + String targetBlockName = mine == null ? spigotBlock.getPrisonBlock().getBlockName() : targetBlock.getPrisonBlock().getBlockName(); + debugInfo.append( "(processBlockBreakage targetBlock: " + targetBlockName + ")" ); + // Process mine block break events: SpigotPlayer sPlayer = new SpigotPlayer( player ); @@ -1024,7 +1784,7 @@ public void processBlockBreakage( SpigotBlock spigotBlock, int bonusXp = checkCrazyEnchant( player, spigotBlock.getWrapper(), ( itemInHand == null ? null : itemInHand.getBukkitStack()) ); // Calculate XP on block break if enabled: - calculateAndGivePlayerXP( sPlayer, targetBlockName, count, bonusXp ); + calculateAndGivePlayerXP( sPlayer, targetBlockName, count, bonusXp, debugInfo ); // calculate durability impact: Include item durability resistance. if ( isBoolean( AutoFeatures.isCalculateDurabilityEnabled ) ) { @@ -1039,6 +1799,9 @@ public void processBlockBreakage( SpigotBlock spigotBlock, calculateAndApplyDurability( player, itemInHand, durabilityResistance ); } + if ( applyExhaustion && isBoolean( AutoFeatures.isCalculateFoodExhustion ) ) { + sPlayer.incrementFoodExhaustionBlockBreak(); + } // A block was broke... so record that event on the tool: itemLoreCounter( itemInHand, getMessage( AutoFeatures.loreBlockBreakCountName ), 1 ); @@ -1050,6 +1813,8 @@ public void processBlockBreakage( SpigotBlock spigotBlock, PrisonBlock prisonBlock = spigotBlock.getPrisonBlock(); + PlayerCache.getInstance().addPlayerBlocks( sPlayer, mine.getName(), targetBlock.getPrisonBlock(), 1 ); + mine.processBlockBreakEventCommands( prisonBlock, targetBlock, sPlayer, blockEventType, triggered ); } @@ -1058,8 +1823,10 @@ public void processBlockBreakage( SpigotBlock spigotBlock, } protected void calculateAndGivePlayerXP(SpigotPlayer player, String blockName, - int count, int bonusXp ) { + int count, int bonusXp, StringBuilder debugInfo ) { + int totalXp = 0; + if (isBoolean(AutoFeatures.isCalculateXPEnabled) && blockName != null ) { // String blockName = block.getPrisonBlock() == null ? null : block.getPrisonBlock().getBlockName(); @@ -1073,6 +1840,7 @@ protected void calculateAndGivePlayerXP(SpigotPlayer player, String blockName, if (xp > 0) { + totalXp += xp; if ( isBoolean( AutoFeatures.givePlayerXPAsOrbDrops )) { player.dropXPOrbs( xp ); @@ -1085,6 +1853,26 @@ protected void calculateAndGivePlayerXP(SpigotPlayer player, String blockName, } } } + + if ( Output.get().isDebug() || Output.get().isDebug( DebugTarget.blockBreak ) || + Output.get().isDebug( DebugTarget.blockBreakXpCalcs )) { + + String message = String.format( "XP calculations: %s %s blocks: %d xp: %d bonusXp: %d " + + " isCalculateXPEnabled: %s givePlayerXPAsOrbDrops %s ", + player.getName(), blockName, count, totalXp, bonusXp, + Boolean.toString( isBoolean(AutoFeatures.isCalculateXPEnabled) ), + Boolean.toString( isBoolean( AutoFeatures.givePlayerXPAsOrbDrops ) ) ); + + if ( Output.get().isDebug() || Output.get().isDebug( DebugTarget.blockBreak ) ) { + debugInfo.append( "(" ).append( message ).append( ")" ); + + } + if ( Output.get().isDebug( DebugTarget.blockBreakXpCalcs ) ) { + + Output.get().logDebug( DebugTarget.blockBreakXpCalcs, message ); + } + + } } @@ -1111,26 +1899,44 @@ private int calculateXP( String blockName ) { int xp = 0; switch (blockName.toLowerCase()) { + + case "gold_ore": + case "nether_gold_ore": + case "deepslate_gold_ore": + case "raw_gold": + + case "iron_ore": + case "deepslate_iron_ore": + case "raw_iron": + + case "copper_ore": + case "deepslate_copper_ore": + case "raw_copper": + xp = getRandom().nextInt( 1 ); + break; + case "coal_ore": + case "deepslate_coal_ore": case "coal": xp = getRandom().nextInt( 2 ); break; - case "nether_gold_ore": - xp = getRandom().nextInt( 1 ); - break; case "diamond_ore": + case "deepslate_diamond_ore": case "emerald_ore": + case "deepslate_emerald_ore": xp = getRandom().nextInt( 4 ) + 3; break; case "lapis_ore": case "nether_quartz_ore": + case "deepslate_lapis_ore": xp = getRandom().nextInt( 3 ) + 2; break; case "redstone_ore": + case "deepslate_redstone_ore": xp = getRandom().nextInt( 4 ) + 1; break; @@ -1211,7 +2017,43 @@ else if ( results < 0 ) { return results; } - + /** + *

This function will check to see the feature + *

isDisableToolWhenWornOutPreventBreakage
is enabled, and if so, + * then it this will return a value of true if the tool in the hand of the player + * is has a maxDurability greater than zero and the current durability level is + * equal to or greater than the maxDurability. + *

+ * + *

This function actually does not apply to just tools, but could apply to anything + * that may be used for breaking a block and has durability. + *

+ * + * @param player + * @return + */ + private boolean isToolDisabled( Player player ) { + boolean results = false; + + if ( isBoolean( AutoFeatures.isPreventToolBreakage ) ) { + + SpigotItemStack itemInHand = + SpigotPrison.getInstance().getCompatibility().getPrisonItemInMainHand( player ); + + if ( itemInHand != null && !itemInHand.isAir() ) { + int breakageThreshold = getInteger( AutoFeatures.preventToolBreakageThreshold ); + + Compatibility compat = SpigotPrison.getInstance().getCompatibility(); + int maxDurability = compat.getDurabilityMax( itemInHand ); + int durability = compat.getDurability( itemInHand ); + + results = ( maxDurability > 0 && + (durability + breakageThreshold) >= maxDurability ); + } + } + + return results; + } /** *

This should calculate and apply the durability consumption on the tool. @@ -1304,7 +2146,7 @@ protected void calculateAndApplyDurability(Player player, SpigotItemStack itemIn } - if ( Output.get().isDebug( DebugTarget.durability ) ) { + if ( Output.get().isDebug( DebugTarget.blockBreakDurability ) ) { String message = String.format( "calculateAndApplyDurability: %s: maxDurability= %d " + "durability: %d damage: %d durResistance: %d toolDurabilityLvl: %d %s", @@ -1312,7 +2154,11 @@ protected void calculateAndApplyDurability(Player player, SpigotItemStack itemIn durabilityResistance, durabilityLevel, (toolBreak ? "[Broke]" : "") ); - Output.get().logDebug( DebugTarget.durability, message ); +// if ( Output.get().isDebug() || Output.get().isDebug( DebugTarget.blockBreak ) ) { +// debugInfo.append( "(" ).append( message ).append( ")" ); +// +// } + Output.get().logDebug( DebugTarget.blockBreakDurability, message ); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCrazyEnchants.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCrazyEnchants.java deleted file mode 100644 index ef83be5d7..000000000 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventCrazyEnchants.java +++ /dev/null @@ -1,154 +0,0 @@ -package tech.mcprison.prison.spigot.block; - -import org.bukkit.Bukkit; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; - -import me.badbones69.crazyenchantments.api.events.BlastUseEvent; -import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; -import tech.mcprison.prison.output.Output; -import tech.mcprison.prison.spigot.SpigotPrison; - -public class OnBlockBreakEventCrazyEnchants - extends OnBlockBreakEventListener -{ - public OnBlockBreakEventCrazyEnchants() { - super(); - } - - - public void registerBlastUseEvents( SpigotPrison spigotPrison ) { - - boolean isCEBlockExplodeEnabled = isBoolean( AutoFeatures.isProcessCrazyEnchantsBlockExplodeEvents ); - - if ( !isCEBlockExplodeEnabled ) { - return; - } - - // Check to see if the class BlastUseEvent even exists: - try { - Output.get().logInfo( "OnBlockBreakEventListener: checking if loaded: CrazyEnchants" ); - - Class.forName( "me.badbones69.crazyenchantments.api.events.BlastUseEvent", false, - this.getClass().getClassLoader() ); - - Output.get().logInfo( "OnBlockBreakEventListener: Trying to register CrazyEnchants" ); - - - String cePriority = getMessage( AutoFeatures.CrazyEnchantsBlastUseEventPriority ); - BlockBreakPriority crazyEnchantsPriority = BlockBreakPriority.fromString( cePriority ); - - // always register a monitor event: - if ( crazyEnchantsPriority != BlockBreakPriority.DISABLED ) { - Bukkit.getPluginManager().registerEvents( - new OnBlockBreakBlastUseEventListenerMonitor(), spigotPrison); - } - - switch ( crazyEnchantsPriority ) - { - case LOWEST: - Bukkit.getPluginManager().registerEvents( - new OnBlockBreakBlastUseEventListenerLowest(), spigotPrison); - break; - - case LOW: - Bukkit.getPluginManager().registerEvents( - new OnBlockBreakBlastUseEventListenerLow(), spigotPrison); - break; - - case NORMAL: - Bukkit.getPluginManager().registerEvents( - new OnBlockBreakBlastUseEventListenerNormal(), spigotPrison); - break; - - case HIGH: - Bukkit.getPluginManager().registerEvents( - new OnBlockBreakBlastUseEventListenerHigh(), spigotPrison); - break; - - case HIGHEST: - Bukkit.getPluginManager().registerEvents( - new OnBlockBreakBlastUseEventListenerHighest(), spigotPrison); - break; - case DISABLED: - Output.get().logInfo( "OnBlockBreakEventLisenters Crazy Enchant's BlastUseEvent " + - "handling has been DISABLED." ); - break; - - - default: - break; - } - - } - catch ( ClassNotFoundException e ) { - // CrazyEnchants is not loaded... so ignore. - Output.get().logInfo( "OnBlockBreakEventListener: CrazyEnchants is not loaded" ); - } - } - - - - - public class OnBlockBreakBlastUseEventListenerMonitor - extends OnBlockBreakEventListener - implements Listener { - - @EventHandler(priority=EventPriority.MONITOR) - public void onCrazyEnchantsBlockExplodeLow(BlastUseEvent e) { - super.onCrazyEnchantsBlockExplodeLow( e ); - } - } - - public class OnBlockBreakBlastUseEventListenerLowest - extends OnBlockBreakEventListener - implements Listener { - - @EventHandler(priority=EventPriority.LOWEST) - public void onCrazyEnchantsBlockExplodeLow(BlastUseEvent e) { - super.onCrazyEnchantsBlockExplodeLow( e ); - } - } - - public class OnBlockBreakBlastUseEventListenerLow - extends OnBlockBreakEventListener - implements Listener { - - @EventHandler(priority=EventPriority.LOW) - public void onCrazyEnchantsBlockExplodeLow(BlastUseEvent e) { - super.onCrazyEnchantsBlockExplodeLow( e ); - } - } - - public class OnBlockBreakBlastUseEventListenerNormal - extends OnBlockBreakEventListener - implements Listener { - - @EventHandler(priority=EventPriority.NORMAL) - public void onCrazyEnchantsBlockExplodeLow(BlastUseEvent e) { - super.onCrazyEnchantsBlockExplodeLow( e ); - } - } - - public class OnBlockBreakBlastUseEventListenerHigh - extends OnBlockBreakEventListener - implements Listener { - - @EventHandler(priority=EventPriority.HIGH) - public void onCrazyEnchantsBlockExplodeLow(BlastUseEvent e) { - super.onCrazyEnchantsBlockExplodeLow( e ); - } - } - - public class OnBlockBreakBlastUseEventListenerHighest - extends OnBlockBreakEventListener - implements Listener { - - @EventHandler(priority=EventPriority.HIGHEST) - public void onCrazyEnchantsBlockExplodeLow(BlastUseEvent e) { - super.onCrazyEnchantsBlockExplodeLow( e ); - } - } - -} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventListener.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventListener.java index 0b2e05342..f481196cc 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventListener.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventListener.java @@ -1,13 +1,8 @@ package tech.mcprison.prison.spigot.block; -import org.bukkit.event.block.BlockBreakEvent; - -import me.badbones69.crazyenchantments.api.events.BlastUseEvent; -import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotPrison; -import tech.mcprison.prison.spigot.autofeatures.AutoManager; -import zedly.zenchantments.BlockShredEvent; +import tech.mcprison.prison.spigot.autofeatures.events.AutoManagerBlockBreakEvents; /** *

This is a pivotal class that "monitors" onBlockBreak events so it can @@ -103,7 +98,9 @@ public enum BlockBreakPriority { LOW, NORMAL, HIGH, - HIGHEST; + HIGHEST, + MONITOR + ; public static BlockBreakPriority fromString( String value ) { BlockBreakPriority results = BlockBreakPriority.LOW; @@ -129,23 +126,12 @@ public void registerAllBlockBreakEvents(SpigotPrison spigotPrison ) { if ( isEnabled() ) { - // AutoManager should be registered first: - // Only register Auto Manager if it is enabled: - if ( isBoolean(AutoFeatures.isAutoManagerEnabled) ) { - - AutoManager autoManager = new AutoManager(); - autoManager.registerBlockBreakEvents( spigotPrison ); - } - - - // Registers all of the non-AutoManager block events: - OnBlockBreakEventListeners listeners = new OnBlockBreakEventListeners(); - listeners.registerBlockBreakEvents( spigotPrison ); - - + // This will register all events that should be enabled, for both + // auto manager and the normal events too. + new AutoManagerBlockBreakEvents().registerEvents(); + -// Bukkit.getPluginManager().registerEvents(new OnBlockBreakEventListener(), spigotPrison); } else { @@ -155,99 +141,5 @@ public void registerAllBlockBreakEvents(SpigotPrison spigotPrison ) { } -// -// /** -// *

The EventPriorty.MONITOR means that the state of the event is OVER AND DONE, -// * so this function CANNOT do anything with the block, other than "monitor" what -// * happened. That is all we need to do, is to just count the number of blocks within -// * a mine that have been broken. -// *

-// * -// *

Note: Because this is a MONITOR event, we cannot do anything with the -// * target block here. Mostly because everything has already been done with it, and -// * this is only intended to MONITOR the final results. -// *

-// * -// *

One interesting fact about this monitoring is that we know that a block was broken, -// * not because of what is left (should be air), but because this function was called. -// * There is a chance that the event was canceled and the block remains unbroken, which -// * is what WorldGuard would do. But the event will also be canceled when auto pickup is -// * enabled, and at that point the BlockType will be air. -// *

-// * -// *

If the event is canceled it's important to check to see that the BlockType is Air, -// * since something already broke the block and took the drop. -// * If it is not canceled we still need to count it since it will be a normal drop. -// *

-// * -// * @param e -// */ -// @EventHandler(priority=EventPriority.MONITOR) -// public void onBlockBreakMonitor(BlockBreakEvent e) { -// -// genericBlockEventMonitor( e ); -// } -// -// @EventHandler(priority=EventPriority.MONITOR) -// public void onBlockShredBreakMonitor(BlockShredEvent e) { -// genericBlockEventMonitor( e ); -// } -// -//// @EventHandler(priority=EventPriority.MONITOR) -//// public void onTEBlockExplodeMonitor(TEBlockExplodeEvent e) { -//// -//// genericBlockExplodeEventMonitor( e ); -//// } -// -// @EventHandler(priority=EventPriority.MONITOR) -// public void onCrazyEnchantsBlockExplodeMonitor( BlastUseEvent e ) { -// -// genericBlockExplodeEventMonitor( e ); -// } -// - - - public void onBlockBreak(BlockBreakEvent e) { - - if ( isBoolean(AutoFeatures.isAutoManagerEnabled) ) { - genericBlockEvent( e ); - } - } - - public void onBlockShredBreak(BlockShredEvent e) { - - if ( isBoolean(AutoFeatures.isAutoManagerEnabled) ) { - genericBlockEvent( e, false, false, false ); - } - else { - genericBlockEvent( e, false, true, false ); - } - } - - - public void onCrazyEnchantsBlockExplodeLow( Object obj ) { - - boolean isCEBlockExplodeEnabled = isBoolean( AutoFeatures.isProcessCrazyEnchantsBlockExplodeEvents ); - - if ( isCEBlockExplodeEnabled ) { - BlastUseEvent e = (BlastUseEvent) obj; - - genericBlockExplodeEvent( e, !isBoolean(AutoFeatures.isAutoManagerEnabled) ); - } - } - -//// @EventHandler(priority=EventPriority.LOW) -//// public void onTEBlockExplodeLow(TEBlockExplodeEvent e) { -//// -//// boolean isTEExplosiveEnabled = isBoolean( AutoFeatures.isProcessTokensEnchantExplosiveEvents ); -//// -//// if ( isTEExplosiveEnabled ) { -//// -//// genericBlockExplodeEvent( e, !isBoolean(AutoFeatures.isAutoManagerEnabled) ); -//// } -//// } - - - } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventListeners.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventListeners.java deleted file mode 100644 index 5abb4a0a4..000000000 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventListeners.java +++ /dev/null @@ -1,279 +0,0 @@ -package tech.mcprison.prison.spigot.block; - -import org.bukkit.Bukkit; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.block.BlockBreakEvent; - -import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; -import tech.mcprison.prison.output.Output; -import tech.mcprison.prison.spigot.SpigotPrison; - -public class OnBlockBreakEventListeners - extends OnBlockBreakEventListener -{ - - - public void registerBlockBreakEvents(SpigotPrison spigotPrison ) { - - - String bbePriority = getMessage( AutoFeatures.blockBreakEventPriority ); - BlockBreakPriority blockBreakPriority = BlockBreakPriority.fromString( bbePriority ); - - if ( blockBreakPriority != BlockBreakPriority.DISABLED ) { - - // Always register the monitor event: - Bukkit.getPluginManager().registerEvents( - new OnBlockBreakEventListenerMonitor(), spigotPrison); - } - - switch ( blockBreakPriority ) - { - case LOWEST: - Bukkit.getPluginManager().registerEvents( - new OnBlockBreakEventListenerLowest(), spigotPrison); - break; - - case LOW: - Bukkit.getPluginManager().registerEvents( - new OnBlockBreakEventListenerLow(), spigotPrison); - break; - - case NORMAL: - Bukkit.getPluginManager().registerEvents( - new OnBlockBreakEventListenerNormal(), spigotPrison); - break; - - case HIGH: - Bukkit.getPluginManager().registerEvents( - new OnBlockBreakEventListenerHigh(), spigotPrison); - break; - - case HIGHEST: - Bukkit.getPluginManager().registerEvents( - new OnBlockBreakEventListenerHighest(), spigotPrison); - break; - - case DISABLED: - Output.get().logInfo( "BlockBreakEvent handling and monitoring has been DISABLED." ); - break; - - default: - break; - } - - - - boolean isTEBlockExplosiveEnabled = isBoolean( AutoFeatures.isProcessTokensEnchantExplosiveEvents ); - - if ( isTEBlockExplosiveEnabled ) { - - try { - Class.forName("com.vk2gpz.tokenenchant.event.TEBlockExplodeEvent"); - -// AutoManagerTokenEnchant tokenEnchant = new AutoManagerTokenEnchant(); -// tokenEnchant.registerBlockBreakEvents( spigotPrison ); - - OnBlockBreakEventTokenEnchant bbTokenEnchant = new OnBlockBreakEventTokenEnchant(); - bbTokenEnchant.registerBlockBreakEvents( spigotPrison ); - -// Bukkit.getPluginManager().registerEvents(new AutoManagerTokenEnchant(), spigotPrison); -// Bukkit.getPluginManager().registerEvents(new OnBlockBreakEventTokenEnchant(), spigotPrison); - - } - catch (ClassNotFoundException e) { - // TokenEnchant is not available on this server which is not an error. Just - // ignore this situation and do not register the TE explosion events. - } - } - - - - boolean isCEBlockExplodeEnabled = isBoolean( AutoFeatures.isProcessCrazyEnchantsBlockExplodeEvents ); - - if ( isCEBlockExplodeEnabled ) { - OnBlockBreakEventCrazyEnchants bbeCE = new OnBlockBreakEventCrazyEnchants(); - bbeCE.registerBlastUseEvents( spigotPrison ); - } - - - - boolean isZenBlockExplodeEnabled = isBoolean( AutoFeatures.isProcessZenchantsBlockExplodeEvents ); - - if ( isZenBlockExplodeEnabled ) { - - OnBlockBreakEventZenchantments zenBlockEvents = new OnBlockBreakEventZenchantments(); - zenBlockEvents.registerBlockBreakEvents( spigotPrison ); - } - - } - - - - - public class OnBlockBreakEventListenerMonitor - extends OnBlockBreakEventListener - implements Listener { - - - /** - *

The EventPriorty.MONITOR means that the state of the event is OVER AND DONE, - * so this function CANNOT do anything with the block, other than "monitor" what - * happened. That is all we need to do, is to just count the number of blocks within - * a mine that have been broken. - *

- * - *

Note: Because this is a MONITOR event, we cannot do anything with the - * target block here. Mostly because everything has already been done with it, and - * this is only intended to MONITOR the final results. - *

- * - *

One interesting fact about this monitoring is that we know that a block was broken, - * not because of what is left (should be air), but because this function was called. - * There is a chance that the event was canceled and the block remains unbroken, which - * is what WorldGuard would do. But the event will also be canceled when auto pickup is - * enabled, and at that point the BlockType will be air. - *

- * - *

If the event is canceled it's important to check to see that the BlockType is Air, - * since something already broke the block and took the drop. - * If it is not canceled we still need to count it since it will be a normal drop. - *

- * - * @param e - */ - @EventHandler(priority=EventPriority.MONITOR) - public void onBlockBreakMonitor(BlockBreakEvent e) { - - genericBlockEventMonitor( e ); - } - -// @EventHandler(priority=EventPriority.MONITOR) -// public void onBlockShredBreakMonitor(BlockShredEvent e) { -// genericBlockEventMonitor( e ); -// } - -// @EventHandler(priority=EventPriority.MONITOR) -// public void onTEBlockExplodeMonitor(TEBlockExplodeEvent e) { - // -// genericBlockExplodeEventMonitor( e ); -// } - -// @EventHandler(priority=EventPriority.MONITOR) -// public void onCrazyEnchantsBlockExplodeMonitor( BlastUseEvent e ) { -// -// genericBlockExplodeEventMonitor( e ); -// } - - - } - - - public class OnBlockBreakEventListenerLowest - extends OnBlockBreakEventListener - implements Listener { - - @EventHandler(priority=EventPriority.LOWEST) - public void onBlockBreak(BlockBreakEvent e) { - super.onBlockBreak( e ); - } - -// @EventHandler(priority=EventPriority.LOWEST) -// public void onBlockShredBreak(BlockShredEvent e) { -// super.onBlockShredBreak( e ); -// } - -// @EventHandler(priority=EventPriority.LOWEST) -// public void onCrazyEnchantsBlockExplodeLow(BlastUseEvent e) { -// super.onCrazyEnchantsBlockExplodeLow( e ); -// } - } - - - public class OnBlockBreakEventListenerLow - extends OnBlockBreakEventListener - implements Listener { - - @EventHandler(priority=EventPriority.LOW) - public void onBlockBreak(BlockBreakEvent e) { - super.onBlockBreak( e ); - } - -// @EventHandler(priority=EventPriority.LOW) -// public void onBlockShredBreak(BlockShredEvent e) { -// super.onBlockShredBreak( e ); -// } - -// @EventHandler(priority=EventPriority.LOW) -// public void onCrazyEnchantsBlockExplodeLow(BlastUseEvent e) { -// super.onCrazyEnchantsBlockExplodeLow( e ); -// } - } - - - public class OnBlockBreakEventListenerNormal - extends OnBlockBreakEventListener - implements Listener { - - @EventHandler(priority=EventPriority.NORMAL) - public void onBlockBreak(BlockBreakEvent e) { - super.onBlockBreak( e ); - } - -// @EventHandler(priority=EventPriority.NORMAL) -// public void onBlockShredBreak(BlockShredEvent e) { -// super.onBlockShredBreak( e ); -// } - -// @EventHandler(priority=EventPriority.NORMAL) -// public void onCrazyEnchantsBlockExplodeLow(BlastUseEvent e) { -// super.onCrazyEnchantsBlockExplodeLow( e ); -// } - } - - - public class OnBlockBreakEventListenerHigh - extends OnBlockBreakEventListener - implements Listener { - - @EventHandler(priority=EventPriority.HIGH) - public void onBlockBreak(BlockBreakEvent e) { - super.onBlockBreak( e ); - } - -// @EventHandler(priority=EventPriority.HIGH) -// public void onBlockShredBreak(BlockShredEvent e) { -// super.onBlockShredBreak( e ); -// } - -// @EventHandler(priority=EventPriority.HIGH) -// public void onCrazyEnchantsBlockExplodeLow(BlastUseEvent e) { -// super.onCrazyEnchantsBlockExplodeLow( e ); -// } - } - - - public class OnBlockBreakEventListenerHighest - extends OnBlockBreakEventListener - implements Listener { - - @EventHandler(priority=EventPriority.HIGHEST) - public void onBlockBreak(BlockBreakEvent e) { - super.onBlockBreak( e ); - } - -// @EventHandler(priority=EventPriority.HIGHEST) -// public void onBlockShredBreak(BlockShredEvent e) { -// super.onBlockShredBreak( e ); -// } - -// @EventHandler(priority=EventPriority.HIGHEST) -// public void onCrazyEnchantsBlockExplodeLow(BlastUseEvent e) { -// super.onCrazyEnchantsBlockExplodeLow( e ); -// } - } - - - -} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventTokenEnchant.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventTokenEnchant.java deleted file mode 100644 index 79638e5c3..000000000 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventTokenEnchant.java +++ /dev/null @@ -1,153 +0,0 @@ -package tech.mcprison.prison.spigot.block; - -import org.bukkit.Bukkit; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; - -import com.vk2gpz.tokenenchant.event.TEBlockExplodeEvent; - -import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; -import tech.mcprison.prison.output.Output; -import tech.mcprison.prison.spigot.SpigotPrison; -import tech.mcprison.prison.spigot.autofeatures.AutoManagerFeatures; -import tech.mcprison.prison.spigot.block.OnBlockBreakEventListener.BlockBreakPriority; - -public class OnBlockBreakEventTokenEnchant - extends AutoManagerFeatures - { - - public OnBlockBreakEventTokenEnchant() { - super(); - - } - - - public void registerBlockBreakEvents(SpigotPrison spigotPrison ) { - - - String bbePriority = getMessage( AutoFeatures.TokenEnchantBlockExplodeEventPriority ); - BlockBreakPriority blockBreakPriority = BlockBreakPriority.fromString( bbePriority ); - - if ( blockBreakPriority != BlockBreakPriority.DISABLED ) { - - // Always register the event Monitor - Bukkit.getPluginManager().registerEvents( - new OnBlockBreakEventTokenEnchantMonitor(), spigotPrison); - } - - - switch ( blockBreakPriority ) - { - case LOWEST: - Bukkit.getPluginManager().registerEvents( - new OnBlockBreakEventTokenEnchantLowest(), spigotPrison); - break; - - case LOW: - Bukkit.getPluginManager().registerEvents( - new OnBlockBreakEventTokenEnchantLow(), spigotPrison); - break; - - case NORMAL: - Bukkit.getPluginManager().registerEvents( - new OnBlockBreakEventTokenEnchantNormal(), spigotPrison); - break; - - case HIGH: - Bukkit.getPluginManager().registerEvents( - new OnBlockBreakEventTokenEnchantHigh(), spigotPrison); - break; - - case HIGHEST: - Bukkit.getPluginManager().registerEvents( - new OnBlockBreakEventTokenEnchantHighest(), spigotPrison); - break; - - case DISABLED: - Output.get().logInfo( "TokenEnchant BlockExplodeEvent handling and monitoring has been DISABLED." ); - break; - - default: - break; - } - - } - - - - - public void onTEBlockExplodeLow(TEBlockExplodeEvent e) { - - boolean isTEExplosiveEnabled = isBoolean( AutoFeatures.isProcessTokensEnchantExplosiveEvents ); - - if ( isTEExplosiveEnabled ) { - - genericBlockExplodeEvent( e, !isBoolean(AutoFeatures.isAutoManagerEnabled) ); - } - } - - - public class OnBlockBreakEventTokenEnchantMonitor - extends OnBlockBreakEventTokenEnchant - implements Listener { - - @EventHandler(priority=EventPriority.MONITOR) - public void onTEBlockExplodeMonitor(TEBlockExplodeEvent e) { - - genericBlockExplodeEventMonitor( e ); - } - } - - - public class OnBlockBreakEventTokenEnchantLowest - extends OnBlockBreakEventTokenEnchant - implements Listener { - - @EventHandler(priority=EventPriority.LOWEST) - public void onTEBlockExplodeLow(TEBlockExplodeEvent e) { - super.onTEBlockExplodeLow( e ); - } - } - - public class OnBlockBreakEventTokenEnchantLow - extends OnBlockBreakEventTokenEnchant - implements Listener { - - @EventHandler(priority=EventPriority.LOW) - public void onTEBlockExplodeLow(TEBlockExplodeEvent e) { - super.onTEBlockExplodeLow( e ); - } - } - - public class OnBlockBreakEventTokenEnchantNormal - extends OnBlockBreakEventTokenEnchant - implements Listener { - - @EventHandler(priority=EventPriority.NORMAL) - public void onTEBlockExplodeLow(TEBlockExplodeEvent e) { - super.onTEBlockExplodeLow( e ); - } - } - - public class OnBlockBreakEventTokenEnchantHigh - extends OnBlockBreakEventTokenEnchant - implements Listener { - - @EventHandler(priority=EventPriority.HIGH) - public void onTEBlockExplodeLow(TEBlockExplodeEvent e) { - super.onTEBlockExplodeLow( e ); - } - } - - public class OnBlockBreakEventTokenEnchantHighest - extends OnBlockBreakEventTokenEnchant - implements Listener { - - @EventHandler(priority=EventPriority.HIGHEST) - public void onTEBlockExplodeLow(TEBlockExplodeEvent e) { - super.onTEBlockExplodeLow( e ); - } - } - -} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventZenchantments.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventZenchantments.java deleted file mode 100644 index ff6634664..000000000 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/block/OnBlockBreakEventZenchantments.java +++ /dev/null @@ -1,134 +0,0 @@ -package tech.mcprison.prison.spigot.block; - -import org.bukkit.Bukkit; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; - -import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; -import tech.mcprison.prison.output.Output; -import tech.mcprison.prison.spigot.SpigotPrison; -import zedly.zenchantments.BlockShredEvent; - -public class OnBlockBreakEventZenchantments - extends OnBlockBreakEventListener -{ - public OnBlockBreakEventZenchantments() { - super(); - } - - - - public void registerBlockBreakEvents(SpigotPrison spigotPrison ) { - - - String zbsPriority = getMessage( AutoFeatures.ZenchantmentsBlockShredEventPriority ); - BlockBreakPriority blockShredPriority = BlockBreakPriority.fromString( zbsPriority ); - - if ( blockShredPriority != BlockBreakPriority.DISABLED ) { - - // Always register the monitor event: - Bukkit.getPluginManager().registerEvents( - new OnBlockBreakBlockShredEventListenerMonitor(), spigotPrison); - } - - - switch ( blockShredPriority ) - { - case LOWEST: - Bukkit.getPluginManager().registerEvents( - new OnBlockBreakBlockShredEventListenerLowest(), spigotPrison); - break; - - case LOW: - Bukkit.getPluginManager().registerEvents( - new OnBlockBreakBlockShredEventListenerLow(), spigotPrison); - break; - - case NORMAL: - Bukkit.getPluginManager().registerEvents( - new OnBlockBreakBlockShredEventListenerNormal(), spigotPrison); - break; - - case HIGH: - Bukkit.getPluginManager().registerEvents( - new OnBlockBreakBlockShredEventListenerHigh(), spigotPrison); - break; - - case HIGHEST: - Bukkit.getPluginManager().registerEvents( - new OnBlockBreakBlockShredEventListenerHighest(), spigotPrison); - break; - - case DISABLED: - Output.get().logInfo( "OnBlockBreak Zenchantments BlockShredEvent handling has been DISABLED." ); - break; - - default: - break; - } - - } - - - public class OnBlockBreakBlockShredEventListenerMonitor - extends OnBlockBreakEventListener - implements Listener { - - @EventHandler(priority=EventPriority.MONITOR) - public void onBlockShredBreakMonitor(BlockShredEvent e) { - super.genericBlockEventMonitor( e ); - } - } - - public class OnBlockBreakBlockShredEventListenerLowest - extends OnBlockBreakEventListener - implements Listener { - - @EventHandler(priority=EventPriority.LOWEST) - public void onBlockShredBreak(BlockShredEvent e) { - super.onBlockShredBreak( e ); - } - } - - public class OnBlockBreakBlockShredEventListenerLow - extends OnBlockBreakEventListener - implements Listener { - - @EventHandler(priority=EventPriority.LOW) - public void onBlockShredBreak(BlockShredEvent e) { - super.onBlockShredBreak( e ); - } - } - - public class OnBlockBreakBlockShredEventListenerNormal - extends OnBlockBreakEventListener - implements Listener { - - @EventHandler(priority=EventPriority.NORMAL) - public void onBlockShredBreak(BlockShredEvent e) { - super.onBlockShredBreak( e ); - } - } - - public class OnBlockBreakBlockShredEventListenerHigh - extends OnBlockBreakEventListener - implements Listener { - - @EventHandler(priority=EventPriority.HIGH) - public void onBlockShredBreak(BlockShredEvent e) { - super.onBlockShredBreak( e ); - } - } - - public class OnBlockBreakBlockShredEventListenerHighest - extends OnBlockBreakEventListener - implements Listener { - - @EventHandler(priority=EventPriority.HIGHEST) - public void onBlockShredBreak(BlockShredEvent e) { - super.onBlockShredBreak( e ); - } - } - -} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/bombs/GeometricShapes.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/bombs/GeometricShapes.java new file mode 100644 index 000000000..c19bf203f --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/bombs/GeometricShapes.java @@ -0,0 +1,287 @@ +package tech.mcprison.prison.spigot.bombs; + +import tech.mcprison.prison.internal.World; +import tech.mcprison.prison.internal.block.PrisonBlock; + +/** + *

These functions were basically copied from the following post. They have + * been modified to allow them to work using Prison components. + *

+ * + * https://www.minecraftforum.net/forums/archive/tutorials/931256-map-generation-advanced-shapes-code + * + *

Overall these functions are not usable by prison directly, but they can be + * used indirectly as templates on how to generate these kind of shapes. + *

+ * + */ +public class GeometricShapes +{ + + public static double getDistance( int x1, int z1, int x2, int z2 ) + { + int dx = x1 - x2; + int dz = z1 - z2; + return Math.sqrt( (dx * dx + dz * dz) ); + } + + public static void drawCircle( PrisonBlock block, World world, int xi, int yi, int zi, int radius ) + { + int r = radius; + for ( int x = xi - r; x <= xi + r; x++ ) + { + for ( int z = zi - r; z <= zi + r; z++ ) + { + if ( (int) (getDistance( x, z, xi, zi )) == r ) + { + world.setBlock( block, x, yi, z ); +// world.setBlock( x, yi, z, Block.stone.blockID ); + } + } + } + } + + public static void drawFilledCircle( PrisonBlock block, World world, int xi, int yi, int zi, int radius ) + { + int r = radius; + for ( int x = xi - r; x <= xi + r; x++ ) + { + for ( int z = zi - r; z <= zi + r; z++ ) + { + if ( (int) (getDistance( x, z, xi, zi )) <= r ) + { + world.setBlock( block, x, yi, z ); +// world.setBlock( x, yi, z, Block.stone.blockID ); + } + } + } + } + + public static void drawDisk( PrisonBlock block, World world, int xi, int yi, int zi, int innerRadius, int outerRadius ) + { + int r = outerRadius; + for ( int x = xi - r; x <= xi + r; x++ ) + { + for ( int z = zi - r; z <= zi + r; z++ ) + { + int dist = (int) (getDistance( x, z, xi, zi )); + if ( dist < outerRadius && dist >= innerRadius ) + { + world.setBlock( block, x, yi, z ); +// world.setBlock( x, yi, z, Block.stone.blockID ); + } + } + } + } + + public static void drawCylinder( PrisonBlock block, World world, int xi, int yi, int zi ) + { + int radius = 9 + (int) (Math.random() * 7); + if ( radius % 2 == 0 ) + radius++; + + int initialh = yi; + int height = 5 + (int) (Math.random() * 16); + for ( ; yi < initialh + height; yi++ ) + drawCircle( block, world, xi, yi, zi, radius ); + } + + public static void drawCone( PrisonBlock block, World world, int xi, int yi, int zi ) + { + int height = 18 + (int) (Math.random() * 15); + int radius = 7 + (int) (Math.random() * 10); + double slope = -height / radius; + + for ( int h = yi; h < yi + height; h++ ) + { + int r = (int) ((h - height) / slope); + drawFilledCircle( block, world, xi, h, zi, r ); + } + } + + public static double getDistance( int x1, int y1, int z1, int x2, int y2, int z2 ) + { + int dx = x1 - x2; + int dy = y1 - y2; + int dz = z1 - z2; + return Math.sqrt( (dx * dx + dy * dy + dz * dz) ); + } + + + /** + * NOTE: This function is not complete, or at least only draws a hollow sphere. + * + * @param block + * @param world + * @param xi + * @param yi + * @param zi + */ + public static void drawSphere( PrisonBlock block, World world, int xi, int yi, int zi ) + { + + int r = 24 + (int) (Math.random() * 12); + if ( r % 2 != 0 ) + r++; + + for ( int x = xi - r; x <= xi + r; x++ ) + { + for ( int z = zi - r; z <= zi + r; z++ ) + { + for ( int y = yi - r; y <= yi + r; y++ ) + { + if ( (int) (getDistance( x, y, z, xi, yi, zi )) == r ) { + world.setBlock( block, x, y, z ); + } + // >= + // for + // solid +// world.setBlock( x, y, z, Block.stone.blockID ); + // else if( (int)(getDistance(x,y,z,xi,yi,zi) )== r-1 && yi + // <= y) + // world.setBlock(x,y,z,Block.glowStone.blockID); + } + } + } + } + + public static void wireFrameCube( PrisonBlock block, World world, int xi, int yi, int zi, int wid, int hei, int dep ) + { + int width = wid;// x + int height = hei;// y + int depth = dep; // z + //int id = Block.stone.blockID; + for ( int i = xi; i < xi + width; i++ ) + { + + world.setBlock( block, i, yi, zi ); + world.setBlock( block, i, yi + height - 1, zi ); + world.setBlock( block, i, yi, zi + depth - 1 ); + world.setBlock( block, i, yi + height - 1, zi + depth - 1 ); + +// world.setBlock( i, yi, zi, id ); +// world.setBlock( i, yi + height - 1, zi, id ); +// world.setBlock( i, yi, zi + depth - 1, id ); +// world.setBlock( i, yi + height - 1, zi + depth - 1, id ); + } + for ( int i = yi; i < yi + height; i++ ) + { + world.setBlock( block, xi, i, zi ); + world.setBlock( block, xi + width - 1, i, zi ); + world.setBlock( block, xi, i, zi + depth - 1 ); + world.setBlock( block, xi + width - 1, i, zi + depth - 1 ); + +// world.setBlock( xi, i, zi, id ); +// world.setBlock( xi + width - 1, i, zi, id ); +// world.setBlock( xi, i, zi + depth - 1, id ); +// world.setBlock( xi + width - 1, i, zi + depth - 1, id ); + } + for ( int i = zi; i < zi + depth; i++ ) + { + world.setBlock( block, xi, yi, i ); + world.setBlock( block, xi, yi + height - 1, i ); + world.setBlock( block, xi + width - 1, yi, i ); + world.setBlock( block, xi + width - 1, yi + height - 1, i ); + +// world.setBlock( xi, yi, i, id ); +// world.setBlock( xi, yi + height - 1, i, id ); +// world.setBlock( xi + width - 1, yi, i, id ); +// world.setBlock( xi + width - 1, yi + height - 1, i, id ); + } + } + + public static void drawParaboloid( PrisonBlock block, World world, int xi, int yi, int zi ) + { + int height = 29; + int initialh = yi; + for ( ; yi < initialh + height; yi++ ) + { + int radius = (int) (3 * Math.sqrt( initialh + height - yi )); + drawFilledCircle( block, world, xi, yi, zi, radius ); + } + } + + public static void drawHyperbloid( PrisonBlock block, World world, int xi, int yi, int zi ) + { + int height = 15 + (int) (Math.random() * 10); + int minR = 5 + (int) Math.random() * 9; + int maxR = 9 + (int) (Math.random() * 11); + double csq = (height * height) / (((double) (maxR * maxR) / (minR * minR)) - 1); + + int initialh = yi + height; + for ( ; yi <= initialh + height; yi++ ) + { + int h = yi - initialh; + int radius = (int) Math.sqrt( ((1 + ((h * h) / csq)) * (minR * minR)) ); + + drawCircle( block, world, xi, yi + 1, zi, radius ); + } + } + + public static void drawTorus( PrisonBlock block, World world, int xi, int yi, int zi ) + { + int majorRadius = 21; + int minorRadius = 7; + + for ( int h = -minorRadius; h <= minorRadius; h++ ) + { + double theta = Math.asin( h / (double) minorRadius ); + int localRadius = (int) Math.abs( (double) minorRadius * Math.cos( theta ) ); + drawDisk( block, world, xi, yi + h, zi, majorRadius - localRadius, majorRadius + localRadius ); + } + } + +// public void someMethod() +// { +// { +// { +// +// int rad = 20; +// double theta = 0; +// int color = 0; +// for ( int s = 0; s < 21; s++ ) +// { +// wireFrameCube( world, (int) (xi + (rad * Math.cos( theta ))), yi, (int) (zi + (rad * Math.sin( theta ))), 10, +// 10, 10, color ); +// theta += 3.14159 / 4; +// yi += 8; +// color++; +// } +// } +// } // mop null +// +// return itemstack; +// } +// +// public void wireFrameCube( World world, int xi, int yi, int zi, int wid, int hei, int dep, int col ) +// { +// int width = wid;// x +// int height = hei;// y +// int depth = dep; // z +// int id = Block.cloth.blockID; +// for ( int i = xi; i < xi + width; i++ ) +// { +// world.setBlockAndMetadata( i, yi, zi, id, col ); +// world.setBlockAndMetadata( i, yi + height - 1, zi, id, col ); +// world.setBlockAndMetadata( i, yi, zi + depth - 1, id, col ); +// world.setBlockAndMetadata( i, yi + height - 1, zi + depth - 1, id, col ); +// } +// for ( int i = yi; i < yi + height; i++ ) +// { +// world.setBlockAndMetadata( xi, i, zi, id, col ); +// world.setBlockAndMetadata( xi + width - 1, i, zi, id, col ); +// world.setBlockAndMetadata( xi, i, zi + depth - 1, id, col ); +// world.setBlockAndMetadata( xi + width - 1, i, zi + depth - 1, id, col ); +// } +// for ( int i = zi; i < zi + depth; i++ ) +// { +// world.setBlockAndMetadata( xi, yi, i, id, col ); +// world.setBlockAndMetadata( xi, yi + height - 1, i, id, col ); +// world.setBlockAndMetadata( xi + width - 1, yi, i, id, col ); +// world.setBlockAndMetadata( xi + width - 1, yi + height - 1, i, id, col ); +// +// } +// +// } + +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/bombs/MineBombData.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/bombs/MineBombData.java new file mode 100644 index 000000000..93950d8a7 --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/bombs/MineBombData.java @@ -0,0 +1,48 @@ +package tech.mcprison.prison.spigot.bombs; + +import java.util.List; + +import com.cryptomorin.xseries.XMaterial; + +public class MineBombData { + + private String name; + + + /** + *

The String name of an XMaterial item to use as the "bomb". + *

+ */ + private String itemType; + + /* + *

A transient reference to the actual XMaterial item that is used + * for the bomb. This is converted from the String itemType. + *

+ */ + private transient XMaterial item; + + + private List lore; + + /** + *

The radius identifies how large the blast should be. + *

+ */ + private int radius = 1; + + /** + *

The chance of complete removal. So if the radius includes + * 100 blocks, but the chance is only 50%, each block will be given + * a chance if it is to be included, or excluded. + *

+ */ + private double chance; + + + private String explosionShape; + + + + +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/bombs/MineBombs.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/bombs/MineBombs.java new file mode 100644 index 000000000..c41d94dd0 --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/bombs/MineBombs.java @@ -0,0 +1,51 @@ +package tech.mcprison.prison.spigot.bombs; + +import java.util.ArrayList; +import java.util.List; + +import tech.mcprison.prison.util.Location; + +public class MineBombs +{ + + public enum ExplosionShape { + sphere, + sphereHollow + ; + + } + + public List calculateSphere( Location loc, int radius, boolean hollow ) { + List results = new ArrayList<>(); + + if ( loc != null && radius > 0 ) { + int cenX = loc.getBlockX(); + int cenY = loc.getBlockY(); + int cenZ = loc.getBlockZ(); + + double radiusSqr = radius * radius; + double radiusHSqr = (radius - 1) * (radius - 1); + + for ( int x = cenX - radius ; x <= cenX + radius ; x++ ) { + double xSqr = (cenX - x) * (cenX - x); + for ( int y = cenY - radius ; y <= cenY + radius ; y++ ) { + double ySqr = (cenY - y) * (cenY - y); + for ( int z = cenZ - radius ; z <= cenZ + radius ; z++ ) { + double zSqr = (cenZ - z) * (cenZ - z); + + double distSqr = xSqr + ySqr + zSqr; + + if ( distSqr <= radiusSqr && + (!hollow || + hollow && distSqr >= radiusHSqr )) { + + Location l = new Location( loc.getWorld(), x, y, z ); + results.add( l ); + } + } + } + } + } + return results; + } +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotPrestigeCommands.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotPrestigeCommands.java index 7b194ba9d..9da1d7658 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotPrestigeCommands.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotPrestigeCommands.java @@ -44,7 +44,7 @@ public void prestigesGUICommand(CommandSender sender) { public void prestigesPrestigeCommand(CommandSender sender) { if ( isPrisonConfig( "prestiges" ) || isPrisonConfig( "prestige.enabled" ) ) { - sender.dispatchCommand("rankup prestiges"); + prisonManagerPrestige(sender); } } @@ -52,7 +52,7 @@ public void prestigesPrestigeCommand(CommandSender sender) { aliases = {"prisonmanager prestige"} ) public void prisonManagerPrestige(CommandSender sender ) { - if ( isPrisonConfig("prestiges") || isPrisonConfig( "prestige.enabled" ) ) { + if ( isPrisonConfig( "prestige.enabled" ) ) { if ( PrisonRanks.getInstance().getLadderManager().getLadder("prestiges") == null ) { Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "ranks ladder create prestiges"); @@ -89,7 +89,7 @@ public void prisonManagerPrestige(CommandSender sender ) { } - if ( isPrisonConfig( "prestige-confirm-gui") ) { + if ( isPrisonConfig( "prestige.confirmation-enabled") && isPrisonConfig( "prestige.prestige-confirm-gui") ) { try { Player player = getSpigotPlayer( sender ); @@ -100,12 +100,18 @@ public void prisonManagerPrestige(CommandSender sender ) { prestigeByChat( sender ); } } - else { + else if ( isPrisonConfig( "prestige.confirmation-enabled") ) { prestigeByChat( sender ); } - + else { + // Bypassing prestige confirmations: + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "rankup prestiges"); + } } } + else { + sender.sendMessage( "Prestiges are disabled. Refresh and then reconfigure config.yml and try again." ); + } } private void prestigeByChat(CommandSender sender) { @@ -113,12 +119,12 @@ private void prestigeByChat(CommandSender sender) { ListenersPrisonManager listenersPrisonManager = ListenersPrisonManager.get(); listenersPrisonManager.chatEventActivator(); - Output.get().sendInfo(sender, SpigotPrison.format(getPrisonConfig("Lore.PrestigeWarning") + + sender.sendMessage( SpigotPrison.format(getPrisonConfig("Lore.PrestigeWarning") + getPrisonConfig("Lore.PrestigeWarning2") + getPrisonConfig("Lore.PrestigeWarning3"))); - Output.get().sendInfo(sender, SpigotPrison.format(messages.getString("Message.ConfirmPrestige"))); - Output.get().sendInfo(sender, SpigotPrison.format(messages.getString("Message.CancelPrestige"))); + sender.sendMessage( SpigotPrison.format(messages.getString("Message.ConfirmPrestige"))); + sender.sendMessage( SpigotPrison.format(messages.getString("Message.CancelPrestige"))); final Player player = getSpigotPlayer( sender ); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java index 386b07386..8208feb18 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/commands/PrisonSpigotSellAllCommands.java @@ -255,12 +255,12 @@ public void sellAllSellWithDelayCommand(CommandSender sender){ } if (!getBoolean(sellAllUtil.sellAllConfig.getString("Options.Full_Inv_AutoSell_EarnedMoneyNotificationDelay_Enabled"))){ - sellAllSellCommand(sender, ""); + sellAllSellCommand(sender, "silent"); return; } SellAllUtil.get().addToAutoSellTask(p); - sellAllSellCommand(sender, ""); + sellAllSellCommand(sender, "silent"); } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/CompatibilityBlocks.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/CompatibilityBlocks.java index ff5d8bf25..1e52c4660 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/CompatibilityBlocks.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/CompatibilityBlocks.java @@ -19,6 +19,8 @@ public interface CompatibilityBlocks public XMaterial getXMaterial( Block spigotBlock ); + public XMaterial getXMaterial( PrisonBlock prisonBlock ); + public XMaterial getXMaterial( BlockType blockType ); public void updateSpigotBlock( BlockType blockType, Block spigotBlock ); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/CompatibilityPlayer.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/CompatibilityPlayer.java index 0346c4cf2..aeab9747e 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/CompatibilityPlayer.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/CompatibilityPlayer.java @@ -8,4 +8,37 @@ public interface CompatibilityPlayer { public void setMaxHealth( Player player, double maxHealth ); + + /** + * + * org.bukkit.Player Titles + *
    + *
  • Bukkit 1.8 - no method
  • + *
  • Bukkit 1.8.8 - deprecated: sendTitle( title, subtitle), deprecated: resetTitle()
  • + *
  • Bukkit 1.9 - deprecated: sendTitle( title, subtitle), deprecated: resetTitle()
  • + *
  • Bukkit 1.10 - deprecated: sendTitle( title, subtitle), deprecated: resetTitle(), + * sendTitle(title, subtitle, fadeIn, stay, fadeOut), resetTitle()
  • + *
  • Bukkit 1.11 - same
  • + *
  • Bukkit 1.12 - same, hideTitle(), sendTitle(), deprecated: setTitleTimes(), updateTitle()
  • + *
  • Bukkit 1.13 - same
  • + *
  • Bukkit 1.14 - same
  • + *
  • Bukkit 1.15 - same
  • + *
  • Bukkit 1.16 - same
  • + *
  • Bukkit 1.17 - same
  • + *
+ * + *

NOTE: For actionBar, it is Paper only or bungee, starting with 1.12 with sendActionBar(). Then with + * 1.15 it was deprecated and suggested to use Audience.sendActionBar(). There is no comparable + * function for bukkit.

+ * + * @param title + * @param subtitle + * @param fadeIn + * @param stay + * @param fadeOut + */ + public void sendTitle( Player player, String title, String subtitle, int fadeIn, int stay, int fadeOut ); + + public void sendActionBar( Player player, String actionBar ); + } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot110.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot110.java new file mode 100644 index 000000000..f08aba417 --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot110.java @@ -0,0 +1,17 @@ +package tech.mcprison.prison.spigot.compat; + +/** + * Important note: Spigot 1.10 support is represented in Spigot110 and is + * identical to Spigot19 except for two spigot 1.10 functions: sendTitle() + * and sendActionBar(). Therefore, all that needs to be done is to have + * the class Spigot110Player extend Spigot19 and then Override + * those two functons. + * + */ +public class Spigot110 + extends Spigot110Player + implements Compatibility { + + + +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot110Player.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot110Player.java new file mode 100644 index 000000000..0062bcca9 --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot110Player.java @@ -0,0 +1,23 @@ +package tech.mcprison.prison.spigot.compat; + +import org.bukkit.entity.Player; + +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.TextComponent; + +public abstract class Spigot110Player + extends Spigot19 +{ + @Override + public void sendTitle( Player player, String title, String subtitle, int fadeIn, int stay, int fadeOut ) { + player.sendTitle( title, subtitle, fadeIn, stay, fadeOut ); + } + + @Override + public void sendActionBar( Player player, String actionBar ) { + player.spigot().sendMessage( ChatMessageType.ACTION_BAR, + new TextComponent( actionBar ) ); + +// player.sendTitle( null, actionBar ); + } +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot113.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot113.java index fe1066b4b..9fa5562de 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot113.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot113.java @@ -40,10 +40,12 @@ public ItemStack getItemInMainHand(PlayerInventory playerInventory) { return playerInventory.getItemInMainHand(); } + @Override public SpigotItemStack getPrisonItemInMainHand(PlayerInteractEvent e) { return SpigotUtil.bukkitItemStackToPrison( getItemInMainHand( e ) ); } + @Override public SpigotItemStack getPrisonItemInMainHand(Player player) { return SpigotUtil.bukkitItemStackToPrison( getItemInMainHand( player ) ); } @@ -58,6 +60,7 @@ public ItemStack getItemInOffHand(Player player ) { return getItemInOffHand(player.getInventory()); } + @Override public ItemStack getItemInOffHand(PlayerInventory playerInventory) { return playerInventory.getItemInOffHand(); } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot113Blocks.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot113Blocks.java index 27d5d2b24..dec668754 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot113Blocks.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot113Blocks.java @@ -18,9 +18,10 @@ import tech.mcprison.prison.util.BlockType; public abstract class Spigot113Blocks - extends Spigot19Player + extends Spigot110Player implements CompatibilityBlocks { + @Override public BlockType getBlockType(Block spigotBlock) { BlockType results = getCachedBlockType( spigotBlock, NO_DATA_VALUE ); @@ -44,6 +45,7 @@ public BlockType getBlockType(Block spigotBlock) { return results == BlockType.NULL_BLOCK ? null : results; } + @Override public PrisonBlock getPrisonBlock(Block spigotBlock) { PrisonBlock pBlock = null; @@ -58,6 +60,7 @@ public PrisonBlock getPrisonBlock(Block spigotBlock) { return pBlock; } + @Override public BlockType getBlockType(ItemStack spigotStack) { BlockType results = getCachedBlockType( spigotStack, NO_DATA_VALUE ); @@ -73,6 +76,7 @@ public BlockType getBlockType(ItemStack spigotStack) { return results == BlockType.NULL_BLOCK ? null : results; } + @Override public XMaterial getXMaterial( Block spigotBlock ) { XMaterial results = NULL_TOKEN; @@ -100,6 +104,7 @@ public XMaterial getXMaterial( Block spigotBlock ) { } + @Override public XMaterial getXMaterial( PrisonBlock prisonBlock ) { XMaterial results = NULL_TOKEN; @@ -129,6 +134,7 @@ public XMaterial getXMaterial( PrisonBlock prisonBlock ) { * @param blockType * @return */ + @Override public XMaterial getXMaterial( BlockType blockType ) { XMaterial results = getCachedXMaterial( blockType, NO_DATA_VALUE ); @@ -162,6 +168,7 @@ public XMaterial getXMaterial( BlockType blockType ) { } + @Override public void updateSpigotBlock( BlockType blockType, Block spigotBlock ) { if ( blockType != null && blockType != BlockType.IGNORE && spigotBlock != null ) { @@ -173,6 +180,7 @@ public void updateSpigotBlock( BlockType blockType, Block spigotBlock ) { } + @Override public void updateSpigotBlock( PrisonBlock prisonBlock, Block spigotBlock ) { if ( prisonBlock != null && @@ -189,6 +197,7 @@ public void updateSpigotBlock( PrisonBlock prisonBlock, Block spigotBlock ) { } + @Override public void updateSpigotBlock( XMaterial xMat, Block spigotBlock ) { if ( xMat != null ) { @@ -216,6 +225,7 @@ public void updateSpigotBlock( XMaterial xMat, Block spigotBlock ) { * * @return */ + @Override public BlockTestStats testCountAllBlockTypes() { BlockTestStats stats = new BlockTestStats(); @@ -242,6 +252,7 @@ else if ( mat.isItem() ) { } + @Override public int getDurabilityMax( SpigotItemStack itemInHand ) { return itemInHand.getBukkitStack().getType().getMaxDurability(); } @@ -308,6 +319,7 @@ public boolean setDurability( SpigotItemStack itemInHand, int newDamage ) { * org.bukkit.block.BlockFace.SOUTH. Not sure why it has to be the * opposite, which is unlike v1.8.8? */ + @Override public void setBlockFace( Block spigotBlock, BlockFace blockFace ) { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18.java index c3410176d..4061d664e 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18.java @@ -147,4 +147,5 @@ public void breakItemInMainHand( Player player ) { } } + } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18Blocks.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18Blocks.java index ee7ad615f..0d5d9b90f 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18Blocks.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18Blocks.java @@ -37,6 +37,7 @@ public abstract class Spigot18Blocks * @return */ @SuppressWarnings( "deprecation" ) + @Override public BlockType getBlockType(Block spigotBlock) { BlockType results = BlockType.NULL_BLOCK; @@ -77,7 +78,7 @@ public BlockType getBlockType(Block spigotBlock) { return results == BlockType.NULL_BLOCK ? null : results; } - + @Override public PrisonBlock getPrisonBlock(Block spigotBlock) { PrisonBlock pBlock = null; @@ -95,6 +96,7 @@ public PrisonBlock getPrisonBlock(Block spigotBlock) { @SuppressWarnings( "deprecation" ) + @Override public BlockType getBlockType( ItemStack spigotStack ) { BlockType results = BlockType.NULL_BLOCK; @@ -198,6 +200,7 @@ private XMaterial xMatMatchXMaterial( ItemStack spigotStack ) { } @SuppressWarnings( "deprecation" ) + @Override public XMaterial getXMaterial( Block spigotBlock ) { XMaterial results = NULL_TOKEN; @@ -246,6 +249,7 @@ public XMaterial getXMaterial( Block spigotBlock ) { return results == NULL_TOKEN ? null : results; } + @Override public XMaterial getXMaterial( PrisonBlock prisonBlock ) { XMaterial results = NULL_TOKEN; @@ -266,7 +270,7 @@ public XMaterial getXMaterial( PrisonBlock prisonBlock ) { } - + @Override public XMaterial getXMaterial( BlockType blockType ) { XMaterial results = NULL_TOKEN; @@ -346,7 +350,7 @@ public XMaterial getXMaterial( BlockType blockType ) { // } - + @Override public void updateSpigotBlock( BlockType blockType, Block spigotBlock ) { if ( blockType != null && blockType != BlockType.IGNORE && spigotBlock != null ) { @@ -361,6 +365,7 @@ public void updateSpigotBlock( BlockType blockType, Block spigotBlock ) { } + @Override public void updateSpigotBlock( PrisonBlock prisonBlock, Block spigotBlock ) { if ( prisonBlock != null && @@ -377,6 +382,7 @@ public void updateSpigotBlock( PrisonBlock prisonBlock, Block spigotBlock ) { } @SuppressWarnings( "deprecation" ) + @Override public void updateSpigotBlock( XMaterial xMat, Block spigotBlock ) { if ( xMat != null ) { @@ -428,6 +434,7 @@ public void updateSpigotBlock( XMaterial xMat, Block spigotBlock ) { * * @return */ + @Override public BlockTestStats testCountAllBlockTypes() { BlockTestStats stats = new BlockTestStats(); @@ -462,7 +469,7 @@ public BlockTestStats testCountAllBlockTypes() { } - + @Override public int getDurabilityMax( SpigotItemStack itemInHand ) { int results = 0; @@ -518,7 +525,7 @@ public boolean setDurability( SpigotItemStack itemStack, int damage ) { // } - + @Override public void setBlockFace( Block spigotBlock, BlockFace blockFace ) { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18Player.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18Player.java index e2dd98c0d..bfd4e9896 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18Player.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot18Player.java @@ -25,4 +25,41 @@ public void setMaxHealth( Player player, double maxHealth ) { } } + /** + * Provides display of the Player's title and subtitles. Spigot 1.8 and 1.9 did not + * support the fadeIn, stay, and fadeOut parameters. + * + * @param player + * @param title + * @param subtitle + * @param fadeIn - parameter ignored + * @param stay - parameter ignored + * @param fadeOut - parameter ignored + */ + @Override + @SuppressWarnings( "deprecation" ) + public void sendTitle( Player player, String title, String subtitle, int fadeIn, int stay, int fadeOut ) { + player.sendTitle( title, subtitle ); + } + + /** + * Provides pseudo-actionBar, which did not exist on spigot 1.8.8, so this instead uses + * the subtitle. Limitation is that you cannot then use actionBar and title and subtitle + * at the same time, but not much uses these components yet. + * + * @param player + * @param actionBar + */ + @SuppressWarnings( "deprecation" ) + @Override + public void sendActionBar( Player player, String actionBar ) { + + player.sendTitle( "", actionBar ); + + // The following class does not exist under spigot 1.8.8 +// player.spigot().sendMessage( ChatMessageType.ACTION_BAR, +// new TextComponent( actionBar ) ); + } + + } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot19.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot19.java index 3bd607747..efc6757fe 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot19.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot19.java @@ -63,10 +63,12 @@ public ItemStack getItemInMainHand(PlayerInventory playerInventory) { return playerInventory.getItemInMainHand(); } + @Override public SpigotItemStack getPrisonItemInMainHand(PlayerInteractEvent e) { return SpigotUtil.bukkitItemStackToPrison( getItemInMainHand( e ) ); } + @Override public SpigotItemStack getPrisonItemInMainHand(Player player) { return SpigotUtil.bukkitItemStackToPrison( getItemInMainHand( player ) ); } @@ -81,6 +83,7 @@ public ItemStack getItemInOffHand(Player player ) { return getItemInOffHand(player.getInventory()); } + @Override public ItemStack getItemInOffHand(PlayerInventory playerInventory) { return playerInventory.getItemInOffHand(); } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot19GUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot19GUI.java index e62efc4f7..3268e52ad 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot19GUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot19GUI.java @@ -3,7 +3,7 @@ import org.bukkit.event.inventory.InventoryEvent; public class Spigot19GUI - extends Spigot18Blocks + extends Spigot19Player implements CompatibilityGUI { @Override diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot19Player.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot19Player.java index add7c36ef..52fbdfe59 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot19Player.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/Spigot19Player.java @@ -4,9 +4,11 @@ import org.bukkit.attribute.AttributeInstance; import org.bukkit.entity.Player; +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.TextComponent; + public abstract class Spigot19Player - extends CompatibilityCache - implements CompatibilityPlayer + extends Spigot18Blocks { public void setMaxHealth( Player player, double maxHealth ) { @@ -31,4 +33,18 @@ public double getMaxHealth( Player player ) { return maxHealth; } + + @Override + @SuppressWarnings( "deprecation" ) + public void sendTitle( Player player, String title, String subtitle, int fadeIn, int stay, int fadeOut ) { + player.sendTitle( title, subtitle ); + } + + @Override + public void sendActionBar( Player player, String actionBar ) { + player.spigot().sendMessage( ChatMessageType.ACTION_BAR, + new TextComponent( actionBar ) ); + +// player.sendTitle( "", actionBar ); + } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/SpigotCompatibility.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/SpigotCompatibility.java index 738d08e09..c6824ed01 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/SpigotCompatibility.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/compat/SpigotCompatibility.java @@ -37,10 +37,14 @@ private static synchronized void setup() { results = new Spigot18(); } - else if ( svData.compareTo( new BluesSemanticVersionData( "1.13.0" ) ) < 0 ) { + else if ( svData.compareTo( new BluesSemanticVersionData( "1.10.0" ) ) < 0 ) { results = new Spigot19(); } + else if ( svData.compareTo( new BluesSemanticVersionData( "1.13.0" ) ) < 0 ) { + + results = new Spigot110(); + } else { results = new Spigot113(); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/configs/MessagesConfig.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/configs/MessagesConfig.java index f9c829883..ab85f886d 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/configs/MessagesConfig.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/configs/MessagesConfig.java @@ -125,7 +125,7 @@ private void values(){ dataConfig("Lore.LeftClickToReset","&aLeft Click to reset"); dataConfig("Lore.LeftClickToEdit", "&aLeft-Click to edit value"); dataConfig("Lore.ManageResetTime","&8Manage the reset time of Mine."); - dataConfig("Lore.MinesButton","&8Mines GUI manager."); + dataConfig("Lore.MinesButton","&3Mines GUI manager."); dataConfig("Lore.MineName", "&3Mine Name: &f"); dataConfig("Lore.Multiplier", "&3Multiplier: &f"); dataConfig("Lore.Name","&3Rank Name: &7"); @@ -143,12 +143,12 @@ private void values(){ dataConfig("Lore.Price2","&8Price: &a$"); dataConfig("Lore.Price3","&3Rank Price: &a$"); dataConfig("Lore.Percentage", "&8Percentage: "); - dataConfig("Lore.PrisonTasksButton","&8Prison Tasks Manager."); + dataConfig("Lore.PrisonTasksButton","&3Prison Tasks Manager."); dataConfig("Lore.ResetTime","&3Reset time(s): &7"); dataConfig("Lore.Radius","&8Radius: "); dataConfig("Lore.RankupCommands","&8&l|&3RankUPCommands&8| &8&l- &3"); dataConfig("Lore.Rankup","&aRankup"); - dataConfig("Lore.RanksButton","&8Ranks GUI manager."); + dataConfig("Lore.RanksButton","&3Ranks GUI manager."); dataConfig("Lore.ResetButton","&8Resets the mine."); dataConfig("Lore.RightClickToCancel","&cRight-Click to cancel."); dataConfig("Lore.RightClickToEnable","&cRight-Click to &aenable&c."); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/EssentialsEconomy.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/EssentialsEconomy.java index 87ad28755..484f421f9 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/EssentialsEconomy.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/EssentialsEconomy.java @@ -128,7 +128,12 @@ public boolean canAfford(Player player, double amount) { public boolean hasIntegrated() { return wrapper != null; } - + + @Override + public void disableIntegration() { + wrapper = null; + } + @Override public String getDisplayName() { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/GemsEconomy.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/GemsEconomy.java index 6f63a829a..819e85693 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/GemsEconomy.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/GemsEconomy.java @@ -142,6 +142,11 @@ public boolean hasIntegrated() { return wrapper != null; } + @Override + public void disableIntegration() { + wrapper = null; + } + @Override public String getDisplayName() { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/SaneEconomy.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/SaneEconomy.java index 010892d42..66040d397 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/SaneEconomy.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/SaneEconomy.java @@ -63,9 +63,14 @@ public boolean canAfford(Player player, double amount) { @Override public boolean hasIntegrated() { - return false; + return econWrapper != null; } - + + @Override + public void disableIntegration() { + econWrapper = null; + } + @Override public String getDisplayName() { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/VaultEconomy.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/VaultEconomy.java index 25d10cc40..319b7256d 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/VaultEconomy.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/economies/VaultEconomy.java @@ -102,7 +102,12 @@ public String getDisplayName() public boolean hasIntegrated() { return econWrapper != null && econWrapper.isEnabled(); } - + + @Override + public void disableIntegration() { + econWrapper = null; + } + @Override public String getPluginSourceURL() { return "https://www.spigotmc.org/resources/vault.34315/"; diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotCommandSender.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotCommandSender.java index e2107bbd5..b89ea0601 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotCommandSender.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotCommandSender.java @@ -55,7 +55,8 @@ public SpigotCommandSender(org.bukkit.command.CommandSender sender) { // return uuid; // } - @Override public String getName() { + @Override + public String getName() { return bukkitSender.getName(); } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotHandlerList.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotHandlerList.java new file mode 100644 index 000000000..3baf662b1 --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotHandlerList.java @@ -0,0 +1,20 @@ +package tech.mcprison.prison.spigot.game; + +import org.bukkit.plugin.RegisteredListener; + +public class SpigotHandlerList + implements tech.mcprison.prison.internal.platform.HandlerList +{ + private org.bukkit.event.HandlerList handlerList; + + public SpigotHandlerList( org.bukkit.event.HandlerList bukkitHandlerList ) { + super(); + + this.handlerList = bukkitHandlerList; + } + + public RegisteredListener[] getRegisteredListeners() { + return handlerList.getRegisteredListeners(); + } + +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java index fe5c03a74..e47f16db8 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotOfflinePlayer.java @@ -32,6 +32,12 @@ public String getName() { return offlinePlayer.getName(); } + @Override + public String toString() { + return getName(); + } + + @Override public void dispatchCommand( String command ) { @@ -104,7 +110,7 @@ public void give( ItemStack itemStack ) { @Override public Location getLocation() { - Output.get().logError( "SpigotOfflinePlayer.getLocation: Offline players have no location." ); +// Output.get().logError( "SpigotOfflinePlayer.getLocation: Offline players have no location." ); return null; } @@ -161,10 +167,10 @@ public Inventory getInventory() { return null; } - @Override - public void printDebugInventoryInformationToConsole() { - - } +// @Override +// public void printDebugInventoryInformationToConsole() { +// +// } public OfflinePlayer getWrapper() { return offlinePlayer; @@ -287,4 +293,12 @@ public double getSellAllMultiplier() { return results; } + @Override + public void setTitle( String title, String subtitle, int fadeIn, int stay, int fadeOut ) { + } + + @Override + public void setActionBar( String actionBar ) { + } + } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayer.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayer.java index f120c05a9..73e62b68c 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayer.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayer.java @@ -505,4 +505,116 @@ public void setMaxHealth( double maxHealth ) { .setMaxHealth( getWrapper(), maxHealth ); } } + + public int getMaximumAir() { + int results = 0; + + if ( getWrapper() != null ) { + results = getWrapper().getMaximumAir(); + } + + return results; + } + + public int getRemainingAir() { + int results = 0; + + if ( getWrapper() != null ) { + results = getWrapper().getRemainingAir(); + } + + return results; + } + + public int getFoodLevel() { + int results = 0; + + if ( getWrapper() != null ) { + results = getWrapper().getFoodLevel(); + } + + return results; + } + + public double getFoodExhaustion() { + double results = 0; + + if ( getWrapper() != null ) { + results = getWrapper().getExhaustion(); + } + + return results; + } + + /** + *

This increments the player's exhaustion level each time they + * break a block. The exhaustion level should increase only by + * 0.005 per block.

+ * + *

Since the player is swinging the pickaxe, the hunger should only apply + * when they break a target block that they actually hit, not all of the + * blocks that are the product of an enchantment, or an explosion. + *

+ * + * https://minecraft.fandom.com/wiki/Hunger + */ + public void incrementFoodExhaustionBlockBreak() { + float exhaustion = getWrapper().getExhaustion(); + getWrapper().setExhaustion( exhaustion + 0.005f ); + } + + public double getFoodSaturation() { + double results = 0; + if ( getWrapper() != null ) { + results = getWrapper().getSaturation(); + } + return results; + } + + public double getExp() { + double results = 0; + + if ( getWrapper() != null ) { + results = getWrapper().getExp(); + } + + return results; + } + + public int getLevel() { + int results = 0; + + if ( getWrapper() != null ) { + results = getWrapper().getLevel(); + } + + return results; + } + + + public double getWalkSpeed() { + double results = 0; + + if ( getWrapper() != null ) { + results = getWrapper().getWalkSpeed(); + } + + return results; + } + + @Override + public void setTitle( String title, String subtitle, int fadeIn, int stay, int fadeOut ) { + if ( getWrapper() != null) { + SpigotPrison.getInstance().getCompatibility() + .sendTitle( getWrapper(), title, subtitle, fadeIn, stay, fadeOut ); + } + } + + @Override + public void setActionBar( String actionBar ) { + if ( getWrapper() != null) { + SpigotPrison.getInstance().getCompatibility() + .sendActionBar( getWrapper(), actionBar ); + } + } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayerUtil.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayerUtil.java new file mode 100644 index 000000000..fd9952514 --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotPlayerUtil.java @@ -0,0 +1,407 @@ +package tech.mcprison.prison.spigot.game; + +import java.util.UUID; + +import org.bukkit.enchantments.Enchantment; + +import tech.mcprison.prison.Prison; +import tech.mcprison.prison.internal.ItemStack; +import tech.mcprison.prison.internal.PlayerUtil; +import tech.mcprison.prison.spigot.SpigotPrison; +import tech.mcprison.prison.spigot.block.SpigotItemStack; +import tech.mcprison.prison.spigot.compat.Compatibility; + +public class SpigotPlayerUtil + extends PlayerUtil +{ + private SpigotPlayer spigotPlayer = null; + + public SpigotPlayerUtil( UUID playerUuid ) { + super( playerUuid ); + + Object p = Prison.get().getPlatform().getPlayer( playerUuid ).orElse( null ); + if ( p != null && p instanceof SpigotPlayer ) { + this.spigotPlayer = (SpigotPlayer) p; + } + } + + @Override + public boolean isActive() { + return spigotPlayer != null; + } + + @Override + public double getHealth() { + double results = 0; + if ( isActive() ) { + results = spigotPlayer.getWrapper().getHealth(); + } + return results; + } + + @Override + public double getMaxHealth() { + double results = 0; + if ( isActive() ) { + results = spigotPlayer.getMaxHealth(); + } + return results; + } + + @Override + public void setMaxHealth( double maxHealth ) { + if ( isActive() ) { + spigotPlayer.setMaxHealth( maxHealth ); + } + } + + @Override + public int getMaximumAir() { + int results = 0; + if ( isActive() ) { + results = spigotPlayer.getMaximumAir(); + } + return results; + } + + @Override + public int getRemainingAir() { + int results = 0; + if ( isActive() ) { + results = spigotPlayer.getRemainingAir(); + } + return results; + } + + @Override + public int getFoodLevel() { + int results = 0; + if ( isActive() ) { + results = spigotPlayer.getFoodLevel(); + } + return results; + } + + @Override + public void setFoodLevel( int foodLevel ) { + if ( isActive() ) { + spigotPlayer.getWrapper().setFoodLevel( foodLevel ); + } + } + + @Override + public double getFoodExhaustion() { + double results = 0; + if ( isActive() ) { + results = spigotPlayer.getFoodExhaustion(); + } + return results; + } + + + /** + *

This increments the player's exhaustion level each time they + * break a block. The exhaustion level should increase only by + * 0.005 per block.

+ * + *

Since the player is swinging the pickaxe, the hunger should only apply + * when they break a target block that they actually hit, not all of the + * blocks that are the product of an enchantment, or an explosion. + *

+ * + * https://minecraft.fandom.com/wiki/Hunger + */ + @Override + public void incrementFoodExhaustionBlockBreak() { + if ( isActive() ) { + spigotPlayer.incrementFoodExhaustionBlockBreak(); + } + } + + @Override + public double getFoodSaturation() { + double results = 0; + if ( isActive() ) { + results = spigotPlayer.getWrapper().getSaturation(); + } + return results; + } + + @Override + public double getExp() { + double results = 0; + if ( isActive() ) { + results = spigotPlayer.getExp(); + } + return results; + } + + @Override + public int getExpToLevel() { + int results = 0; + if ( isActive() ) { + results = spigotPlayer.getWrapper().getExpToLevel(); + } + return results; + } + + @Override + public int getLevel() { + int results = 0; + if ( isActive() ) { + results = spigotPlayer.getLevel(); + } + return results; + } + + @Override + public double getWalkSpeed() { + double results = 0; + if ( isActive() ) { + results = spigotPlayer.getExp(); + } + return results; + } + + public SpigotItemStack getItemInHand() { + SpigotItemStack itemInHand = null; + + if ( isActive() && spigotPlayer.getWrapper() != null ) { + itemInHand = SpigotPrison.getInstance().getCompatibility() + .getPrisonItemInMainHand( spigotPlayer.getWrapper() ); + } + return itemInHand; + } + + @Override + public ItemStack getPrisonItemStack() { + return getItemInHand(); + } + + @Override + public String getItemInHandDisplayID() + { + String results = ""; + + SpigotItemStack itemStack = getItemInHand(); + + if ( itemStack != null ) { + results = itemStack.getBukkitStack().getType().name(); + } + + return results; + } + + @Override + public String getItemInHandName() { + String results = ""; + + SpigotItemStack itemStack = getItemInHand(); + + if ( itemStack != null ) { + results = itemStack.getName(); + } + + return results; + } + + @Override + public String getItemInHandDisplayName() { + String results = ""; + + SpigotItemStack itemStack = getItemInHand(); + + if ( itemStack != null && itemStack.getDisplayName() != null ) { + results = itemStack.getDisplayName(); + } + + return results; + } + + /** + *

This will return the item type of what the player is holding in their main hand, + * such as pickaxe, shovel, + * axe, boots, bow, shears, etc... If what is in the player's main is not one of + * these item types, then it will return an empty string. + *

+ * + * @return + */ + @Override + public String getItemInHandItemType() { + String results = ""; + + SpigotItemStack itemStack = getItemInHand(); + + if ( itemStack != null ) { + ItemType iType = ItemType.fromString( itemStack.getName() ); + if ( iType != null ) { + results = iType.name(); + } + } + + return results; + } + + /* + *

The item material is the material type that an item is made from. + * This will only return a value if getItemInHandItemType() returns a + * value, otherwise this will return an empty String. + *

+ * + */ + @Override + public String getItemInHandItemMaterial() { + String results = ""; + + SpigotItemStack itemStack = getItemInHand(); + + if ( itemStack != null ) { + ItemMaterial iMaterial = ItemMaterial.fromString( itemStack.getName() ); + if ( iMaterial != null ) { + results = iMaterial.name(); + } + } + + return results; + } + + @Override + public int getItemInHandDurabilityUsed() { + int results = 0; + + SpigotItemStack itemStack = getItemInHand(); + + if ( itemStack != null ) { + Compatibility compat = SpigotPrison.getInstance().getCompatibility(); + results = compat.getDurability( itemStack ); + } + + return results; + } + + @Override + public int getItemInHandDurabilityMax() { + int results = 0; + + SpigotItemStack itemStack = getItemInHand(); + + if ( itemStack != null ) { + Compatibility compat = SpigotPrison.getInstance().getCompatibility(); + results = compat.getDurabilityMax( itemStack ); + } + + return results; + } + + @Override + public int getItemInHandDurabilityRemaining() { + int results = 0; + + SpigotItemStack itemStack = getItemInHand(); + + if ( itemStack != null ) { + Compatibility compat = SpigotPrison.getInstance().getCompatibility(); + int durabilityUsed = compat.getDurability( itemStack ); + int durabilityMax = compat.getDurabilityMax( itemStack ); + results = durabilityMax - durabilityUsed; + } + + return results; + } + + @Override + public double getItemInHandDurabilityPercent() { + double results = 0; + + SpigotItemStack itemStack = getItemInHand(); + + if ( itemStack != null ) { + Compatibility compat = SpigotPrison.getInstance().getCompatibility(); + int durabilityUsed = compat.getDurability( itemStack ); + int durabilityMax = compat.getDurabilityMax( itemStack ); + + results = (durabilityUsed / (double) durabilityMax) * 100.0d; + } + + return results; + } + + + private int getEnchantment( String enchant ) { + int results = 0; + + Enchantment enchantment = null; + + for ( Enchantment e : Enchantment.values() ) { + if ( e.getKey().getKey().equalsIgnoreCase( enchant ) ) { + enchantment = e; + break; + } + } + + if ( enchantment != null ) { + + SpigotItemStack itemStack = getItemInHand(); + + if ( itemStack != null && itemStack.getBukkitStack() != null) { + try { + if ( itemStack.getBukkitStack().containsEnchantment( enchantment ) && + itemStack.getBukkitStack().getEnchantments() != null ) { + results = itemStack.getBukkitStack() + .getEnchantmentLevel(enchantment); + } + } + catch ( NullPointerException e ) { + // Ignore. This happens when a TokeEnchanted tool is used when TE is not installed anymore. + // It throws this exception: Caused by: java.lang.NullPointerException: null key in entry: null=5 + } + } + } + + return results; + } + + @Override + public int getItemInHandEnchantmentFortune() { + return getEnchantment( "LOOT_BONUS_BLOCKS" ); + } + + @Override + public int getItemInHandEnchantmentEfficency() { + return getEnchantment( "DIG_SPEED" ); + } + + @Override + public int getItemInHandEnchantmentSilkTouch() { + return getEnchantment( "SILK_TOUCH" ); + } + + @Override + public int getItemInHandEnchantmentUnbreaking() { + return getEnchantment( "UNBREAKING" ); + } + + @Override + public int getItemInHandEnchantmentMending() { + return getEnchantment( "MENDING" ); + } + + @Override + public int getItemInHandEnchantmentLuck() { + return getEnchantment( "LUCK" ); + } + + + + + public SpigotPlayer getSpigotPlayer() { + return spigotPlayer; + } + public void setSpigotPlayer( SpigotPlayer spigotPlayer ) { + this.spigotPlayer = spigotPlayer; + } + + + +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java index 4d5ad8479..95d06bcdf 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/game/SpigotWorld.java @@ -22,8 +22,10 @@ import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.internal.World; import tech.mcprison.prison.internal.block.Block; +import tech.mcprison.prison.internal.block.PrisonBlock; import tech.mcprison.prison.spigot.SpigotUtil; import tech.mcprison.prison.spigot.block.SpigotBlock; +import tech.mcprison.prison.spigot.compat.SpigotCompatibility; import tech.mcprison.prison.util.Location; import java.util.List; @@ -59,9 +61,18 @@ public Block getBlockAt(Location location) { return new SpigotBlock( bukkitWorld.getBlockAt(SpigotUtil.prisonLocationToBukkit(location))); } + + @Override + public void setBlock( PrisonBlock block, int x, int y, int z ) { + + Location loc = new Location( this, x, y, z ); + org.bukkit.block.Block bukkitBlock = + bukkitWorld.getBlockAt(SpigotUtil.prisonLocationToBukkit(loc)); + + SpigotCompatibility.getInstance().updateSpigotBlock( block, bukkitBlock ); + } public org.bukkit.World getWrapper() { return bukkitWorld; } - } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/ListenersPrisonManager.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/ListenersPrisonManager.java index 38ae74957..97d5fb1bf 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/ListenersPrisonManager.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/ListenersPrisonManager.java @@ -34,9 +34,12 @@ import tech.mcprison.prison.mines.data.Mine; import tech.mcprison.prison.modules.Module; import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.output.Output.DebugTarget; import tech.mcprison.prison.ranks.PrisonRanks; +import tech.mcprison.prison.ranks.data.PlayerRank; import tech.mcprison.prison.ranks.data.Rank; import tech.mcprison.prison.ranks.data.RankLadder; +import tech.mcprison.prison.ranks.data.RankPlayer; import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.SpigotUtil; import tech.mcprison.prison.spigot.backpacks.BackpacksUtil; @@ -69,6 +72,7 @@ import tech.mcprison.prison.spigot.gui.sellall.SellAllAdminBlocksGUI; import tech.mcprison.prison.spigot.gui.sellall.SellAllAdminGUI; import tech.mcprison.prison.spigot.gui.sellall.SellAllDelayGUI; +import tech.mcprison.prison.spigot.gui.sellall.SellAllPlayerGUI; import tech.mcprison.prison.spigot.gui.sellall.SellAllPrestigesMultiplierGUI; import tech.mcprison.prison.spigot.gui.sellall.SellAllPrestigesSetMultiplierGUI; import tech.mcprison.prison.spigot.gui.sellall.SellAllPriceGUI; @@ -256,7 +260,7 @@ public void onPlayerInteractEvent(PlayerInteractEvent e){ if (sign.getLine(0).equalsIgnoreCase(SpigotPrison.format(signTag))) { if (sellAllConfig.getString("Options.SellAll_Sign_Use_Permission_Enabled").equalsIgnoreCase("true") && !p.hasPermission(sellAllConfig.getString("Options.SellAll_Sign_Use_Permission"))) { - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.SellAllSignMissingPermission") + " [&3" + sellAllConfig.getString("Options.SellAll_Sign_Use_Permission") + "&7]")); + Output.get().sendWarn(new SpigotPlayer(p), messages.getString("Message.SellAllSignMissingPermission") + " [&3" + sellAllConfig.getString("Options.SellAll_Sign_Use_Permission") + "&7]"); return; } @@ -267,7 +271,7 @@ public void onPlayerInteractEvent(PlayerInteractEvent e){ // } if (sellAllConfig.getString("Options.SellAll_Sign_Notify").equalsIgnoreCase("true")) { - Output.get().sendInfo(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.SellAllSignNotify"))); + Output.get().sendInfo(new SpigotPlayer(p), messages.getString("Message.SellAllSignNotify")); } // Execute the sellall command @@ -357,7 +361,7 @@ public void chatInteractData(Player p, ChatMode activeMode) { id = Bukkit.getScheduler().scheduleSyncDelayedTask(SpigotPrison.getInstance(), () -> { if (isChatEventActive) { removeChatEventPlayer(p); - Output.get().sendInfo(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.OutOfTimeNoChanges"))); + Output.get().sendInfo(new SpigotPlayer(p), messages.getString("Message.OutOfTimeNoChanges")); isChatEventActive = false; } mode = null; @@ -418,7 +422,7 @@ public void onClick(InventoryClickEvent e){ // Close GUI button globally. if (buttonNameMain.equalsIgnoreCase("Close")) { - Output.get().sendInfo(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.GuiClosedWithSuccess"))); + Output.get().sendInfo(new SpigotPlayer(p), messages.getString("Message.GuiClosedWithSuccess")); p.closeInventory(); return; } @@ -601,7 +605,7 @@ public void onClick(InventoryClickEvent e){ // Check the title and do the actions. case "SellAll -> Blocks": { - sellAllAdminBlocksGUI(e, p, buttonNameMain); + sellAllAdminBlocksGUI(e, p, parts); break; } @@ -663,8 +667,7 @@ public void onClick(InventoryClickEvent e){ // Check the title and do the actions. case "Prison -> SellAll-Player": { - p.closeInventory(); - e.setCancelled(true); + sellAllPlayerGUI(e, p, parts); break; } @@ -734,6 +737,27 @@ public void onClick(InventoryClickEvent e){ } } + private void sellAllPlayerGUI(InventoryClickEvent e, Player p, String[] parts) { + if (parts[0].equalsIgnoreCase("Prior")){ + + SellAllPlayerGUI gui = new SellAllPlayerGUI(p, Integer.parseInt(parts[1])); + gui.open(); + + e.setCancelled(true); + return; + } else if (parts[0].equalsIgnoreCase("Next")){ + + SellAllPlayerGUI gui = new SellAllPlayerGUI(p, Integer.parseInt(parts[1])); + gui.open(); + + e.setCancelled(true); + return; + } + + p.closeInventory(); + e.setCancelled(true); + } + private void backpacksAdmin(InventoryClickEvent e, Player p, String buttonNameMain) { if(buttonNameMain.equalsIgnoreCase("Backpacks-List")){ @@ -742,7 +766,7 @@ private void backpacksAdmin(InventoryClickEvent e, Player p, String buttonNameMa } else if(buttonNameMain.equalsIgnoreCase("Backpack-Settings")){ p.closeInventory(); - Output.get().sendInfo(new SpigotPlayer(p), SpigotPrison.format("&6Coming Soon...")); + Output.get().sendInfo(new SpigotPlayer(p), "&6Coming Soon..."); } e.setCancelled(true); @@ -802,12 +826,12 @@ private void showBlock(InventoryClickEvent e, Player p, String[] parts) { conf.set("Options.Mines.MaterialType." + parts[1], parts[0]); conf.save(sellAllFile); } catch (IOException ex){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.SellAllConfigSaveFail"))); + Output.get().sendWarn(new SpigotPlayer(p), messages.getString("Message.SellAllConfigSaveFail")); ex.printStackTrace(); return; } - Output.get().sendInfo(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.MineShowItemEditSuccess") + " [" + parts[0] + "]")); + Output.get().sendInfo(new SpigotPlayer(p), messages.getString("Message.MineShowItemEditSuccess") + " [" + parts[0] + "]"); p.closeInventory(); } @@ -848,7 +872,7 @@ private void setSellAllPrestigeMultiplier(InventoryClickEvent e, Player p, Strin } else if (e.isRightClick()){ // Send a message to the player - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cEvent cancelled.")); + Output.get().sendWarn(new SpigotPlayer(p), "&cEvent cancelled."); e.setCancelled(true); @@ -880,7 +904,7 @@ private void setSellAllPrestigeMultiplier(InventoryClickEvent e, Player p, Strin } else { // Tell to the player that the value's too low - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.TooLowValue"))); + Output.get().sendWarn(new SpigotPlayer(p), messages.getString("Message.TooLowValue")); e.setCancelled(true); @@ -906,7 +930,7 @@ private void setSellAllPrestigeMultiplier(InventoryClickEvent e, Player p, Strin } else { // Close the GUI and tell it to the player - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.TooHighValue"))); + Output.get().sendWarn(new SpigotPlayer(p), messages.getString("Message.TooHighValue")); e.setCancelled(true); p.closeInventory(); return; @@ -990,7 +1014,7 @@ private void sellAllDelayGUI(InventoryClickEvent e, Player p, String[] parts) { } else if (e.isRightClick()){ // Send a message to the player - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.EventCancelled"))); + Output.get().sendWarn(new SpigotPlayer(p), messages.getString("Message.EventCancelled")); e.setCancelled(true); @@ -1022,7 +1046,7 @@ private void sellAllDelayGUI(InventoryClickEvent e, Player p, String[] parts) { } else { // Tell to the player that the value's too low - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.TooLowValue"))); + Output.get().sendWarn(new SpigotPlayer(p), messages.getString("Message.TooLowValue")); e.setCancelled(true); @@ -1048,7 +1072,7 @@ private void sellAllDelayGUI(InventoryClickEvent e, Player p, String[] parts) { } else { // Close the GUI and tell it to the player - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.TooHighValue"))); + Output.get().sendWarn(new SpigotPlayer(p), messages.getString("Message.TooHighValue")); e.setCancelled(true); p.closeInventory(); return; @@ -1112,7 +1136,7 @@ private void sellAllAdminGUI(InventoryClickEvent e, Player p, String buttonNameM case "Blocks-Shop":{ - SellAllAdminBlocksGUI gui = new SellAllAdminBlocksGUI(p); + SellAllAdminBlocksGUI gui = new SellAllAdminBlocksGUI(p, 0); gui.open(); break; } @@ -1140,7 +1164,7 @@ private void sellAllAdminGUI(InventoryClickEvent e, Player p, String buttonNameM SellAllAdminGUI gui = new SellAllAdminGUI(p); gui.open(); } else { - Output.get().sendInfo(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.EnableAutoSellToUse"))); + Output.get().sendInfo(new SpigotPlayer(p), messages.getString("Message.EnableAutoSellToUse")); } break; } @@ -1182,7 +1206,7 @@ private void sellAllAdminGUI(InventoryClickEvent e, Player p, String buttonNameM SellAllAdminGUI gui = new SellAllAdminGUI(p); gui.open(); } else { - Output.get().sendInfo(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.EnableSellDelayToUse"))); + Output.get().sendInfo(new SpigotPlayer(p), messages.getString("Message.EnableSellDelayToUse")); } break; } @@ -1190,10 +1214,10 @@ private void sellAllAdminGUI(InventoryClickEvent e, Player p, String buttonNameM case "SellAll-Currency":{ // Send messages to the player - Output.get().sendInfo(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.SellAllCurrencyChat1"))); - Output.get().sendInfo(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.SellAllCurrencyChat2"))); - Output.get().sendInfo(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.SellAllCurrencyChat3"))); - Output.get().sendInfo(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.SellAllCurrencyChat4"))); + Output.get().sendInfo(new SpigotPlayer(p), messages.getString("Message.SellAllCurrencyChat1")); + Output.get().sendInfo(new SpigotPlayer(p), messages.getString("Message.SellAllCurrencyChat2")); + Output.get().sendInfo(new SpigotPlayer(p), messages.getString("Message.SellAllCurrencyChat3")); + Output.get().sendInfo(new SpigotPlayer(p), messages.getString("Message.SellAllCurrencyChat4")); chatInteractData(p, ChatMode.SellAll_Currency); p.closeInventory(); @@ -1206,13 +1230,13 @@ private void sellAllAdminGUI(InventoryClickEvent e, Player p, String buttonNameM boolean multiplierEnabled = getBoolean(sellAllConfig.getString("Options.Multiplier_Enabled")); if (!multiplierEnabled){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.SellAllMultipliersAreDisabled"))); + Output.get().sendWarn(new SpigotPlayer(p), messages.getString("Message.SellAllMultipliersAreDisabled")); return; } else { if (sellAllConfig.getConfigurationSection("Multiplier").getKeys(false).size() == 0) { - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.EmptyGui"))); + Output.get().sendWarn(new SpigotPlayer(p), messages.getString("Message.EmptyGui")); e.setCancelled(true); return; } else { @@ -1255,7 +1279,7 @@ private void prisonSetupConfirmGUI(InventoryClickEvent e, Player p, String[] par if (parts[0].equalsIgnoreCase("Confirm:")){ Bukkit.dispatchCommand(p, "ranks autoConfigure"); } else if (parts[0].equalsIgnoreCase("Cancel:")){ - Output.get().sendInfo(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Setup.Message.Aborted"))); + Output.get().sendInfo(new SpigotPlayer(p), messages.getString("Setup.Message.Aborted")); } p.closeInventory(); e.setCancelled(true); @@ -1289,14 +1313,32 @@ private void blocksListGUI(InventoryClickEvent e, Player p, String[] parts) { private void mineBlockPercentage(InventoryClickEvent e, Player p, String[] parts) { + if (parts[0].equalsIgnoreCase("Close")){ + p.closeInventory(); + return; + } + // Rename the parts - String part1 = parts[0]; - String part2 = parts[1]; - String part3 = parts[2]; + String part1; + String part2; + String part3; + + try{ + + part1 = parts[0]; + part2 = parts[1]; + part3 = parts[2]; + + } catch (ArrayIndexOutOfBoundsException ex){ + return; + } // If Close, part 4 won't be defined so handle the close first. - if (part1.equalsIgnoreCase( "Close" )) { - int pos = 0; + + // What? + /*if (part1.equalsIgnoreCase( "Close" )) { + + int pos = 0; try { pos = Integer.parseInt( part3 ); } @@ -1308,9 +1350,12 @@ private void mineBlockPercentage(InventoryClickEvent e, Player p, String[] parts gui.open(); return; - } + }*/ - String part4 = parts[3]; + String part4 = null; + try{ + part4 = parts[3]; + } catch(ArrayIndexOutOfBoundsException ignored){} // Initialize the variable double decreaseOrIncreaseValue = 0; @@ -1335,7 +1380,9 @@ private void mineBlockPercentage(InventoryClickEvent e, Player p, String[] parts if (e.isLeftClick()){ // Execute the command - Bukkit.dispatchCommand(p,"mines block set " + part2 + " " + part3 + " " + part4); + if (part4 != null) { + Bukkit.dispatchCommand(p, "mines block set " + part2 + " " + part3 + " " + part4); + } // Cancel the event e.setCancelled(true); @@ -1349,7 +1396,7 @@ private void mineBlockPercentage(InventoryClickEvent e, Player p, String[] parts } else if (e.isRightClick()){ // Send a message to the player - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cEvent cancelled.")); + Output.get().sendWarn(new SpigotPlayer(p), "&cEvent cancelled."); // Cancel the event e.setCancelled(true); @@ -1370,7 +1417,7 @@ private void mineBlockPercentage(InventoryClickEvent e, Player p, String[] parts double val = Double.parseDouble(part3); // Check the calculator symbol - if (part4.equals("-")){ + if (part4 != null && part4.equals("-")){ // Check if the value's already too low if (!((val - decreaseOrIncreaseValue) < 0)) { @@ -1382,7 +1429,7 @@ private void mineBlockPercentage(InventoryClickEvent e, Player p, String[] parts } else { // Tell to the player that the value's too low - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cToo low, under 0%!")); + Output.get().sendWarn(new SpigotPlayer(p), "&cToo low, under 0%!"); // Cancel the event e.setCancelled(true); @@ -1398,7 +1445,7 @@ private void mineBlockPercentage(InventoryClickEvent e, Player p, String[] parts gui.open(); // Check the calculator symbol - } else if (part4.equals("+")) { + } else if (part4 != null && part4.equals("+")) { // Check if the value isn't too high if (!((val + decreaseOrIncreaseValue) > 100)) { @@ -1410,7 +1457,7 @@ private void mineBlockPercentage(InventoryClickEvent e, Player p, String[] parts } else { // Close the GUI and tell it to the player - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cToo high, exceed 100%!")); + Output.get().sendWarn(new SpigotPlayer(p), "&cToo high, exceed 100%!"); // Cancel the event e.setCancelled(true); @@ -1463,7 +1510,7 @@ private void sellAllItemValue(InventoryClickEvent e, Player p, String[] parts) { } else if (e.isRightClick()){ // Send a message to the player - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cEvent cancelled.")); + Output.get().sendWarn(new SpigotPlayer(p), "&cEvent cancelled."); e.setCancelled(true); @@ -1495,7 +1542,7 @@ private void sellAllItemValue(InventoryClickEvent e, Player p, String[] parts) { } else { // Tell to the player that the value's too low - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cToo low value.")); + Output.get().sendWarn(new SpigotPlayer(p), "&cToo low value."); e.setCancelled(true); @@ -1521,7 +1568,7 @@ private void sellAllItemValue(InventoryClickEvent e, Player p, String[] parts) { } else { // Close the GUI and tell it to the player - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cToo high value.")); + Output.get().sendWarn(new SpigotPlayer(p), "&cToo high value."); e.setCancelled(true); p.closeInventory(); return; @@ -1534,19 +1581,35 @@ private void sellAllItemValue(InventoryClickEvent e, Player p, String[] parts) { } } - private void sellAllAdminBlocksGUI(InventoryClickEvent e, Player p, String buttonNameMain) { + private void sellAllAdminBlocksGUI(InventoryClickEvent e, Player p, String[] parts) { + + if (parts[0].equalsIgnoreCase("Prior")){ + + SellAllAdminBlocksGUI gui = new SellAllAdminBlocksGUI(p, Integer.parseInt(parts[1])); + gui.open(); + + e.setCancelled(true); + return; + } else if (parts[0].equalsIgnoreCase("Next")){ + + SellAllAdminBlocksGUI gui = new SellAllAdminBlocksGUI(p, Integer.parseInt(parts[1])); + gui.open(); + + e.setCancelled(true); + return; + } if (e.isRightClick()){ String registeredCmd = Prison.get().getCommandHandler().findRegisteredCommand( "sellall delete" ); - Bukkit.dispatchCommand(p, registeredCmd + " " + buttonNameMain); + Bukkit.dispatchCommand(p, registeredCmd + " " + parts[0]); p.closeInventory(); } else if (e.isLeftClick()){ - String valueString = sellAllConfig.getString("Items." + buttonNameMain + ".ITEM_VALUE"); + String valueString = sellAllConfig.getString("Items." + parts[0] + ".ITEM_VALUE"); if (valueString != null) { - SellAllPriceGUI gui = new SellAllPriceGUI(p, Double.parseDouble(valueString), buttonNameMain); + SellAllPriceGUI gui = new SellAllPriceGUI(p, Double.parseDouble(valueString), parts[0]); gui.open(); } } @@ -1572,7 +1635,7 @@ private void prisonManagerGUI(InventoryClickEvent e, Player p, String buttonName SpigotAutoFeaturesGUI gui = new SpigotAutoFeaturesGUI(p); gui.open(); } else { - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("Can't find an autofeatures config, maybe they're disabled.")); + Output.get().sendWarn(new SpigotPlayer(p), "Can't find an autofeatures config, maybe they're disabled."); } break; } @@ -1605,7 +1668,7 @@ private void laddersGUI(InventoryClickEvent e, Player p, String buttonNameMain, // Check if the Ranks module's loaded. if(!(module instanceof PrisonRanks)){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("The GUI can't open because the &3Rank module &cisn't loaded")); + Output.get().sendWarn(new SpigotPlayer(p), "The GUI can't open because the &3Rank module &cisn't loaded"); p.closeInventory(); e.setCancelled(true); return; @@ -1661,7 +1724,7 @@ private void ranksGUI(InventoryClickEvent e, Player p, String buttonNameMain, St // Check if the rank exist. if (rank == null) { - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cThe rank " + buttonNameMain + " does not exist.")); + Output.get().sendWarn(new SpigotPlayer(p), "&cThe rank " + buttonNameMain + " does not exist."); return; } @@ -1706,13 +1769,19 @@ private void prestigeConfirmationGUI(InventoryClickEvent e, Player p, String but // Check the button name and do the actions. if (buttonNameMain.equalsIgnoreCase("Confirm: Prestige")){ - // Execute the command. - Bukkit.dispatchCommand(p, "rankup prestiges"); + Output.get().logDebug( DebugTarget.rankup, "rankup: GUI: 'Confirm: Prestige' calling: '/rankup prestiges'" ); + + // Execute the command. + String registeredCmd = Prison.get().getCommandHandler().findRegisteredCommand( "rankup" ); + + Bukkit.dispatchCommand(p, registeredCmd + " prestiges"); // Close the inventory. p.closeInventory(); } else if (buttonNameMain.equalsIgnoreCase("Cancel: Don't Prestige")){ - // Send a message to the player. - Output.get().sendInfo(new SpigotPlayer(p), SpigotPrison.format("&cCancelled")); + Output.get().logDebug( DebugTarget.rankup, "rankup: GUI/: 'Cancel: Don't Prestige' sendInfo: 'cancelled'" ); + + // Send a message to the player. + Output.get().sendInfo(new SpigotPlayer(p), "&cCancelled"); // Close the inventory. p.closeInventory(); } @@ -1736,14 +1805,14 @@ private void rankManagerGUI(InventoryClickEvent e, Player p, String[] parts) { // Check if the rank exist. if (rank == null) { // Send a message to the player. - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cThe rank " + rankName + " does not exist.")); + Output.get().sendWarn(new SpigotPlayer(p), "&cThe rank " + rankName + " does not exist."); return; } // Check the rankupCommand of the Rank. if (rank.getRankUpCommands() == null) { // Send a message to the player. - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cThere aren't commands for this rank anymore.")); + Output.get().sendWarn(new SpigotPlayer(p), "&cThere aren't commands for this rank anymore."); } // Open the GUI of commands. @@ -1757,7 +1826,10 @@ private void rankManagerGUI(InventoryClickEvent e, Player p, String[] parts) { // Check and open a GUI. if(rank != null) { - SpigotRankPriceGUI gui = new SpigotRankPriceGUI(p, (int) rank.getCost(), rank.getName()); + RankPlayer rankPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer( new SpigotPlayer(p) ); + PlayerRank pRank = rankPlayer.getRank( rank.getLadder() ); + + SpigotRankPriceGUI gui = new SpigotRankPriceGUI(p, pRank.getRankCost().intValue(), rank.getName()); gui.open(); } @@ -1765,8 +1837,8 @@ private void rankManagerGUI(InventoryClickEvent e, Player p, String[] parts) { } else if (buttonName.equalsIgnoreCase("RankTag")){ // Send messages to the player. - Output.get().sendInfo(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.rankTagRename"))); - Output.get().sendInfo(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.rankTagRenameClose"))); + Output.get().sendInfo(new SpigotPlayer(p), messages.getString("Message.rankTagRename")); + Output.get().sendInfo(new SpigotPlayer(p), messages.getString("Message.rankTagRenameClose")); // Start the async task. tempChatVariable = rankName; chatInteractData(p, ChatMode.RankName); @@ -1841,7 +1913,7 @@ private void rankPriceGUI(InventoryClickEvent e, Player p, String[] parts) { } else if (e.isRightClick()){ // Send a message to the player. - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cEvent cancelled.")); + Output.get().sendWarn(new SpigotPlayer(p), "&cEvent cancelled."); e.setCancelled(true); @@ -1873,7 +1945,7 @@ private void rankPriceGUI(InventoryClickEvent e, Player p, String[] parts) { } else { // Tell to the player that the value's too low. - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cToo low value.")); + Output.get().sendWarn(new SpigotPlayer(p), "&cToo low value."); e.setCancelled(true); @@ -1899,7 +1971,7 @@ private void rankPriceGUI(InventoryClickEvent e, Player p, String[] parts) { } else { // Close the GUI and tell it to the player. - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cToo high value.")); + Output.get().sendWarn(new SpigotPlayer(p), "&cToo high value."); e.setCancelled(true); p.closeInventory(); return; @@ -2053,8 +2125,8 @@ private void mineInfoGUI(InventoryClickEvent e, Player p, String[] parts) { case "Mine_Name:": { // Send messages to the player - Output.get().sendInfo(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.mineNameRename"))); - Output.get().sendInfo(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.mineNameRenameClose"))); + Output.get().sendInfo(new SpigotPlayer(p), messages.getString("Message.mineNameRename")); + Output.get().sendInfo(new SpigotPlayer(p), messages.getString("Message.mineNameRenameClose")); // Start the async task tempChatVariable = mineName; @@ -2182,7 +2254,7 @@ private void resetTimeGUI(InventoryClickEvent e, Player p, String[] parts) { } else if (e.isRightClick()){ // Send a message to the player - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cEvent cancelled.")); + Output.get().sendWarn(new SpigotPlayer(p), "&cEvent cancelled."); // Cancel the event e.setCancelled(true); @@ -2215,7 +2287,7 @@ private void resetTimeGUI(InventoryClickEvent e, Player p, String[] parts) { } else { // Tell to the player that the value's too low - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cToo low value.")); + Output.get().sendWarn(new SpigotPlayer(p), "&cToo low value."); // Cancel the event e.setCancelled(true); @@ -2243,7 +2315,7 @@ private void resetTimeGUI(InventoryClickEvent e, Player p, String[] parts) { } else { // Close the GUI and tell it to the player - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cToo high value.")); + Output.get().sendWarn(new SpigotPlayer(p), "&cToo high value."); // Cancel the event e.setCancelled(true); @@ -2362,7 +2434,7 @@ private void radiusGUI(InventoryClickEvent e, Player p, String[] parts) { } else if (e.isRightClick()){ // Close the inventory - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cEvent cancelled.")); + Output.get().sendWarn(new SpigotPlayer(p), "&cEvent cancelled."); // Cancel the event e.setCancelled(true); @@ -2395,7 +2467,7 @@ private void radiusGUI(InventoryClickEvent e, Player p, String[] parts) { } else { // Close the inventory and tell it the player - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cToo low value.")); + Output.get().sendWarn(new SpigotPlayer(p), "&cToo low value."); // Cancel the event e.setCancelled(true); @@ -2422,7 +2494,7 @@ private void radiusGUI(InventoryClickEvent e, Player p, String[] parts) { } else { // Close the inventory and tell it to the player - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cToo high value.")); + Output.get().sendWarn(new SpigotPlayer(p), "&cToo high value."); // Cancel the inventory e.setCancelled(true); @@ -2644,62 +2716,62 @@ private void autoBlockGUI(InventoryClickEvent e, Player p, String[] parts) { switch (buttonname){ case "Gold_Block":{ - afConfig.setFeature( AutoFeatures.autoBlockGoldBlock, !enabled ); + afConfig.setFeature( AutoFeatures.blockGoldBlock, !enabled ); saveConfigBlock(e, p); break; } case "Iron_Block":{ - afConfig.setFeature( AutoFeatures.autoBlockIronBlock, !enabled ); + afConfig.setFeature( AutoFeatures.blockIronBlock, !enabled ); saveConfigBlock(e, p); break; } case "Coal_Block":{ - afConfig.setFeature( AutoFeatures.autoBlockCoalBlock, !enabled ); + afConfig.setFeature( AutoFeatures.blockCoalBlock, !enabled ); saveConfigBlock(e, p); break; } case "Diamond_Block":{ - afConfig.setFeature( AutoFeatures.autoBlockDiamondBlock, !enabled ); + afConfig.setFeature( AutoFeatures.blockDiamondBlock, !enabled ); saveConfigBlock(e, p); break; } case "Redstone_Block":{ - afConfig.setFeature( AutoFeatures.autoBlockRedstoneBlock, !enabled ); + afConfig.setFeature( AutoFeatures.blockRedstoneBlock, !enabled ); saveConfigBlock(e, p); break; } case "Emerald_Block":{ - afConfig.setFeature( AutoFeatures.autoBlockEmeraldBlock, !enabled ); + afConfig.setFeature( AutoFeatures.blockEmeraldBlock, !enabled ); saveConfigBlock(e, p); break; } case "Quartz_Block":{ - afConfig.setFeature( AutoFeatures.autoBlockQuartzBlock, !enabled ); + afConfig.setFeature( AutoFeatures.blockQuartzBlock, !enabled ); saveConfigBlock(e, p); break; } case "Prismarine_Block":{ - afConfig.setFeature( AutoFeatures.autoBlockPrismarineBlock, !enabled ); + afConfig.setFeature( AutoFeatures.blockPrismarineBlock, !enabled ); saveConfigBlock(e, p); break; } case "Lapis_Block":{ - afConfig.setFeature( AutoFeatures.autoBlockLapisBlock, !enabled ); + afConfig.setFeature( AutoFeatures.blockLapisBlock, !enabled ); saveConfigBlock(e, p); break; } case "Snow_Block":{ - afConfig.setFeature( AutoFeatures.autoBlockSnowBlock, !enabled ); + afConfig.setFeature( AutoFeatures.blockSnowBlock, !enabled ); saveConfigBlock(e, p); break; } case "Glowstone_Block":{ - afConfig.setFeature( AutoFeatures.autoBlockGlowstone, !enabled ); + afConfig.setFeature( AutoFeatures.blockGlowstone, !enabled ); saveConfigBlock(e, p); break; } case "All_Blocks":{ - afConfig.setFeature( AutoFeatures.autoBlockAllBlocks, !enabled ); + afConfig.setFeature( AutoFeatures.blockAllBlocks, !enabled ); saveConfigBlock(e, p); break; } @@ -2741,7 +2813,7 @@ private void sellAllCurrencyChat(AsyncPlayerChatEvent e, Player p, String messag // Check message and do the action String registeredCmd = Prison.get().getCommandHandler().findRegisteredCommand( "sellall set currency" ); if (message.equalsIgnoreCase("cancel")){ - Output.get().sendInfo(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.SellAllCurrencyEditCancelled"))); + Output.get().sendInfo(new SpigotPlayer(p), messages.getString("Message.SellAllCurrencyEditCancelled")); } else if (message.equalsIgnoreCase("default")){ Bukkit.getScheduler().runTask(SpigotPrison.getInstance(), () -> Bukkit.getServer().dispatchCommand(p, registeredCmd + " default")); } else { @@ -2758,11 +2830,11 @@ private void prestigeAction(AsyncPlayerChatEvent e, Player p, String message) { // Check the chat message and do the actions if (message.equalsIgnoreCase("cancel")) { - Output.get().sendInfo(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.PrestigeCancelled"))); + Output.get().sendInfo(new SpigotPlayer(p), messages.getString("Message.PrestigeCancelled")); } else if (message.equalsIgnoreCase("confirm")) { Bukkit.getScheduler().runTask(SpigotPrison.getInstance(), () -> Bukkit.getServer().dispatchCommand(p, "rankup prestiges")); } else { - Output.get().sendInfo(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.PrestigeCancelledWrongKeyword"))); + Output.get().sendInfo(new SpigotPlayer(p), messages.getString("Message.PrestigeCancelledWrongKeyword")); } // Cancel the event e.setCancelled(true); @@ -2774,7 +2846,7 @@ private void mineAction(AsyncPlayerChatEvent e, Player p, String message) { // Check the chat message and do the action if (message.equalsIgnoreCase("close")) { - Output.get().sendInfo(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.mineNameRenameClosed"))); + Output.get().sendInfo(new SpigotPlayer(p), messages.getString("Message.mineNameRenameClosed")); } else { Bukkit.getScheduler().runTask(SpigotPrison.getInstance(), () -> Bukkit.getServer().dispatchCommand(p, "mines rename " + tempChatVariable + " " + message)); } @@ -2786,7 +2858,7 @@ private void mineAction(AsyncPlayerChatEvent e, Player p, String message) { private void rankAction(AsyncPlayerChatEvent e, Player p, String message) { // Check the chat message and do the action if (message.equalsIgnoreCase("close")) { - Output.get().sendInfo(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.rankTagRenameClosed"))); + Output.get().sendInfo(new SpigotPlayer(p), messages.getString("Message.rankTagRenameClosed")); } else { Bukkit.getScheduler().runTask(SpigotPrison.getInstance(), () -> Bukkit.getServer().dispatchCommand(p, "ranks set tag " + tempChatVariable + " " + message)); } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/PrisonSetupGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/PrisonSetupGUI.java index b4f854e54..c3ce8c842 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/PrisonSetupGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/PrisonSetupGUI.java @@ -1,19 +1,12 @@ package tech.mcprison.prison.spigot.gui; import com.cryptomorin.xseries.XMaterial; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import tech.mcprison.prison.output.Output; -import tech.mcprison.prison.spigot.SpigotPrison; -import tech.mcprison.prison.spigot.game.SpigotPlayer; import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; -import java.util.List; - /** * @author GABRYCA */ @@ -30,9 +23,8 @@ public void open(){ // Create Prison GUI. PrisonGUI gui = new PrisonGUI(p, 9, "&3Prison Setup -> Confirmation"); - // Add button. - gui.addButton(new Button(2, XMaterial.EMERALD_BLOCK, createLore( - messages.getString("Lore.ClickToConfirm"), + // Create lore. + ButtonLore lore = new ButtonLore(createLore(messages.getString("Lore.ClickToConfirm")), createLore( messages.getString("Lore.noRanksFoundSetup"), messages.getString("Lore.noRanksFoundSetup1"), messages.getString("Lore.noRanksFoundSetup2"), @@ -41,8 +33,10 @@ public void open(){ messages.getString("Lore.noRanksFoundSetup5"), messages.getString("Lore.noRanksFoundSetup6"), messages.getString("Lore.noRanksFoundSetup7"), - messages.getString("Lore.noRanksFoundSetup8") - ), "&3" + "Confirm: Setup")); + messages.getString("Lore.noRanksFoundSetup8"))); + + // Add button. + gui.addButton(new Button(2, XMaterial.EMERALD_BLOCK, lore, "&3" + "Confirm: Setup")); // Add button. gui.addButton(new Button(6, XMaterial.REDSTONE_BLOCK, createLore( diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/SpigotPrisonGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/SpigotPrisonGUI.java index 15002c611..01269ece8 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/SpigotPrisonGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/SpigotPrisonGUI.java @@ -1,26 +1,19 @@ package tech.mcprison.prison.spigot.gui; import com.cryptomorin.xseries.XMaterial; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotPrison; -import tech.mcprison.prison.spigot.game.SpigotPlayer; import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; -import java.util.List; - /** * @author GABRYCA */ public class SpigotPrisonGUI extends SpigotGUIComponents { private final Player p; - private final int dimension = 45; public SpigotPrisonGUI(Player p){ this.p = p; @@ -29,29 +22,16 @@ public SpigotPrisonGUI(Player p){ public void open() { // Create PrisonGUI, it requires Player (who will open the GUI), size and title. + int dimension = 45; PrisonGUI gui = new PrisonGUI(p, dimension, "&3PrisonManager"); // Create and add buttons. - gui.addButton(new Button(10, XMaterial.TRIPWIRE_HOOK, createLore( - messages.getString("Lore.RanksButton"), - messages.getString("Lore.ClickToOpen")), "&3" + "Ranks - Ladders")); - - gui.addButton(new Button(13, XMaterial.IRON_PICKAXE, createLore( - messages.getString("Lore.PrisonTasksButton"), - messages.getString("Lore.ClickToOpen")), SpigotPrison.format("&3" + "AutoManager"))); - - gui.addButton(new Button(16, XMaterial.DIAMOND_ORE, createLore( - messages.getString("Lore.MinesButton"), - messages.getString("Lore.ClickToOpen")), SpigotPrison.format("&3" + "Mines"))); - - gui.addButton(new Button(29, XMaterial.CHEST, createLore( - messages.getString("Lore.ClickToOpen")), SpigotPrison.format("&3" + "SellAll"))); - - gui.addButton(new Button(33, XMaterial.CHEST_MINECART, createLore( - messages.getString("Lore.ClickToOpen")), SpigotPrison.format("&3" + "Backpacks"))); - - gui.addButton(new Button(44, XMaterial.RED_STAINED_GLASS_PANE, createLore( - messages.getString("Lore.ClickToClose")), SpigotPrison.format("&c" + "Close"))); + gui.addButton(new Button(10, XMaterial.TRIPWIRE_HOOK, new ButtonLore(messages.getString("Lore.ClickToOpen"), messages.getString("Lore.RanksButton")), "&3" + "Ranks - Ladders")); + gui.addButton(new Button(13, XMaterial.IRON_PICKAXE, new ButtonLore(messages.getString("Lore.ClickToOpen"), messages.getString("Lore.PrisonTasksButton")), SpigotPrison.format("&3" + "AutoManager"))); + gui.addButton(new Button(16, XMaterial.DIAMOND_ORE, new ButtonLore(messages.getString("Lore.ClickToOpen"), messages.getString("Lore.MinesButton")), SpigotPrison.format("&3" + "Mines"))); + gui.addButton(new Button(29, XMaterial.CHEST, new ButtonLore(messages.getString("Lore.ClickToOpen"), null), SpigotPrison.format("&3" + "SellAll"))); + gui.addButton(new Button(33, XMaterial.CHEST_MINECART, new ButtonLore(messages.getString("Lore.ClickToOpen"), null), SpigotPrison.format("&3" + "Backpacks"))); + gui.addButton(new Button(44, XMaterial.RED_STAINED_GLASS_PANE, new ButtonLore(messages.getString("Lore.ClickToClose"), null), SpigotPrison.format("&c" + "Close"))); gui.open(); } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/autofeatures/SpigotAutoBlockGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/autofeatures/SpigotAutoBlockGUI.java index 3ff1660a6..c507954c4 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/autofeatures/SpigotAutoBlockGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/autofeatures/SpigotAutoBlockGUI.java @@ -1,19 +1,13 @@ package tech.mcprison.prison.spigot.gui.autofeatures; -import java.util.List; - import com.cryptomorin.xseries.XMaterial; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig; import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; -import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotPrison; -import tech.mcprison.prison.spigot.game.SpigotPlayer; import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; @@ -34,87 +28,81 @@ public void open() { // Create the inventory and set up the owner, dimensions or number of slots, and title PrisonGUI gui = new PrisonGUI(p, 36, "&3AutoFeatures -> AutoBlock"); - List enabledLore = createLore( - messages.getString("Lore.ShiftAndRightClickToDisable") - ); - List disabledLore = createLore( - messages.getString("Lore.RightClickToEnable") - ); - List closeGUILore = createLore( - messages.getString("Lore.ClickToClose") - ); + // Lores + ButtonLore enabledLore = new ButtonLore(messages.getString("Lore.ShiftAndRightClickToDisable"), null); + ButtonLore disabledLore = new ButtonLore(messages.getString("Lore.RightClickToEnable"), null); - gui.addButton(new Button(35, XMaterial.RED_STAINED_GLASS_PANE, closeGUILore, SpigotPrison.format("&c" + "Close"))); + gui.addButton(new Button(35, XMaterial.RED_STAINED_GLASS_PANE, new ButtonLore(messages.getString("Lore.ClickToClose"), null), SpigotPrison.format("&c" + "Close"))); if (afConfig != null) { - if (afConfig.isFeatureBoolean(AutoFeatures.autoBlockAllBlocks)) { + if (afConfig.isFeatureBoolean(AutoFeatures.blockAllBlocks)) { gui.addButton(new Button(null, XMaterial.LIME_STAINED_GLASS_PANE, enabledLore, SpigotPrison.format("&a" + "All_Blocks Enabled"))); } else { gui.addButton(new Button(null, XMaterial.RED_STAINED_GLASS_PANE, disabledLore, SpigotPrison.format("&c" + "All_Blocks Disabled"))); } - if (afConfig.isFeatureBoolean(AutoFeatures.autoBlockGoldBlock)) { + if (afConfig.isFeatureBoolean(AutoFeatures.blockGoldBlock)) { gui.addButton(new Button(null, XMaterial.GOLD_BLOCK, enabledLore, SpigotPrison.format("&a" + "Gold_Block Enabled"))); } else { gui.addButton(new Button(null, XMaterial.GOLD_BLOCK, disabledLore, SpigotPrison.format("&c" + "Gold_Block Disabled"))); } - if (afConfig.isFeatureBoolean(AutoFeatures.autoBlockIronBlock)) { + if (afConfig.isFeatureBoolean(AutoFeatures.blockIronBlock)) { gui.addButton(new Button(null, XMaterial.IRON_BLOCK, enabledLore, SpigotPrison.format("&a" + "Iron_Block Enabled"))); } else { gui.addButton(new Button(null, XMaterial.IRON_BLOCK, disabledLore, SpigotPrison.format("&c" + "Iron_Block Disabled"))); } - if (afConfig.isFeatureBoolean(AutoFeatures.autoBlockCoalBlock)) { + if (afConfig.isFeatureBoolean(AutoFeatures.blockCoalBlock)) { gui.addButton(new Button(null, XMaterial.COAL_BLOCK, enabledLore, SpigotPrison.format("&a" + "Coal_Block Enabled"))); } else { gui.addButton(new Button(null, XMaterial.COAL_BLOCK, disabledLore, SpigotPrison.format("&c" + "Coal_Block Disabled"))); } - if (afConfig.isFeatureBoolean(AutoFeatures.autoBlockDiamondBlock)) { + if (afConfig.isFeatureBoolean(AutoFeatures.blockDiamondBlock)) { gui.addButton(new Button(null, XMaterial.DIAMOND_BLOCK, enabledLore, SpigotPrison.format("&a" + "Diamond_Block Enabled"))); } else { gui.addButton(new Button(null, XMaterial.DIAMOND_BLOCK, disabledLore, SpigotPrison.format("&c" + "Diamond_Block Disabled"))); } - if (afConfig.isFeatureBoolean(AutoFeatures.autoBlockRedstoneBlock)) { + if (afConfig.isFeatureBoolean(AutoFeatures.blockRedstoneBlock)) { gui.addButton(new Button(null, XMaterial.REDSTONE_BLOCK, enabledLore, SpigotPrison.format("&a" + "Redstone_Block Enabled"))); } else { gui.addButton(new Button(null, XMaterial.REDSTONE_BLOCK, disabledLore, SpigotPrison.format("&c" + "Redstone_Block Disabled"))); } - if (afConfig.isFeatureBoolean(AutoFeatures.autoBlockEmeraldBlock)) { + if (afConfig.isFeatureBoolean(AutoFeatures.blockEmeraldBlock)) { gui.addButton(new Button(null, XMaterial.EMERALD_BLOCK, enabledLore, SpigotPrison.format("&a" + "Emerald_Block Enabled"))); } else { gui.addButton(new Button(null, XMaterial.EMERALD_BLOCK, disabledLore, SpigotPrison.format("&c" + "Emerald_Block Disabled"))); } - if (afConfig.isFeatureBoolean(AutoFeatures.autoBlockQuartzBlock)) { + if (afConfig.isFeatureBoolean(AutoFeatures.blockQuartzBlock)) { gui.addButton(new Button(null, XMaterial.QUARTZ_BLOCK, enabledLore, SpigotPrison.format("&a" + "Quartz_Block Enabled"))); } else { gui.addButton(new Button(null, XMaterial.QUARTZ_BLOCK, disabledLore, SpigotPrison.format("&c" + "Quartz_Block Disabled"))); } - if (afConfig.isFeatureBoolean(AutoFeatures.autoBlockPrismarineBlock)) { + if (afConfig.isFeatureBoolean(AutoFeatures.blockPrismarineBlock)) { gui.addButton(new Button(null, XMaterial.PRISMARINE, enabledLore, SpigotPrison.format("&a" + "Prismarine_Block Enabled"))); } else { gui.addButton(new Button(null, XMaterial.PRISMARINE, disabledLore, SpigotPrison.format("&c" + "Prismarine_Block Disabled"))); } - if (afConfig.isFeatureBoolean(AutoFeatures.autoBlockLapisBlock)) { + if (afConfig.isFeatureBoolean(AutoFeatures.blockLapisBlock)) { gui.addButton(new Button(null, XMaterial.LAPIS_BLOCK, enabledLore, SpigotPrison.format("&a" + "Lapis_Block Enabled"))); } else { gui.addButton(new Button(null, XMaterial.LAPIS_BLOCK, disabledLore, SpigotPrison.format("&c" + "Lapis_Block Disabled"))); } - if (afConfig.isFeatureBoolean(AutoFeatures.autoBlockSnowBlock)) { + if (afConfig.isFeatureBoolean(AutoFeatures.blockSnowBlock)) { gui.addButton(new Button(null, XMaterial.SNOW_BLOCK, enabledLore, SpigotPrison.format("&a" + "Snow_Block Enabled"))); } else { gui.addButton(new Button(null, XMaterial.SNOW_BLOCK, disabledLore, SpigotPrison.format("&c" + "Snow_Block Disabled"))); } - if (afConfig.isFeatureBoolean(AutoFeatures.autoBlockGlowstone)) { + if (afConfig.isFeatureBoolean(AutoFeatures.blockGlowstone)) { gui.addButton(new Button(null, XMaterial.GLOWSTONE, enabledLore, SpigotPrison.format("&a" + "Glowstone_Block Enabled"))); } else { gui.addButton(new Button(null, XMaterial.GLOWSTONE, disabledLore, SpigotPrison.format("&c" + "Glowstone_Block Disabled"))); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/autofeatures/SpigotAutoFeaturesGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/autofeatures/SpigotAutoFeaturesGUI.java index 04a918017..d4d3f8365 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/autofeatures/SpigotAutoFeaturesGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/autofeatures/SpigotAutoFeaturesGUI.java @@ -1,20 +1,14 @@ package tech.mcprison.prison.spigot.gui.autofeatures; -import java.util.List; - -import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; import com.cryptomorin.xseries.XMaterial; import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig; import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; -import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotPrison; -import tech.mcprison.prison.spigot.game.SpigotPlayer; import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; @@ -36,13 +30,12 @@ public void open() { PrisonGUI gui; - // Close GUI button lore. - List closeGUILore = createLore( - messages.getString("Lore.ClickToClose") - ); - + ButtonLore closeGUILore = new ButtonLore(messages.getString("Lore.ClickToClose"), null); if (afConfig != null && afConfig.isFeatureBoolean(AutoFeatures.isAutoManagerEnabled)) { + + ButtonLore disable = new ButtonLore(messages.getString("Lore.ShiftAndRightClickToDisable"), null); + ButtonLore enable = new ButtonLore(messages.getString("Lore.RightClickToEnable"), null); gui = new PrisonGUI(p, dimension, "&3PrisonManager -> AutoFeatures"); @@ -50,141 +43,90 @@ public void open() { if (afConfig.isFeatureBoolean(AutoFeatures.playSoundIfInventoryIsFull)) { - List EnabledOrDisabledLore = createLore( - messages.getString("Lore.FullSoundEnabled"), - messages.getString("Lore.ShiftAndRightClickToDisable")); - gui.addButton(new Button(0, XMaterial.LIME_STAINED_GLASS_PANE, EnabledOrDisabledLore, SpigotPrison.format("&a" + "Full-Inventory-Sound Enabled"))); + disable.setLoreDescription(messages.getString("Lore.FullSoundEnabled")); + gui.addButton(new Button(0, XMaterial.LIME_STAINED_GLASS_PANE, disable, SpigotPrison.format("&a" + "Full-Inventory-Sound Enabled"))); } else { - List EnabledOrDisabledLore = createLore( - messages.getString("Lore.FullSoundDisabled"), - messages.getString("Lore.RightClickToEnable")); - gui.addButton(new Button(0, XMaterial.RED_STAINED_GLASS_PANE, EnabledOrDisabledLore, SpigotPrison.format("&c" + "Full-Inventory-Sound Disabled"))); + enable.setLoreDescription(messages.getString("Lore.FullSoundDisabled")); + gui.addButton(new Button(0, XMaterial.RED_STAINED_GLASS_PANE, enable, SpigotPrison.format("&c" + "Full-Inventory-Sound Disabled"))); } if (afConfig.isFeatureBoolean(AutoFeatures.hologramIfInventoryIsFull)) { - List EnabledOrDisabledLore = createLore( - messages.getString("Lore.FullHologramEnabled"), - messages.getString("Lore.ShiftAndRightClickToDisable")); - gui.addButton(new Button(8, XMaterial.LIME_STAINED_GLASS_PANE, EnabledOrDisabledLore, SpigotPrison.format("&a" + "Full-Inventory-Hologram Enabled"))); + disable.setLoreDescription(messages.getString("Lore.FullHologramEnabled")); + gui.addButton(new Button(8, XMaterial.LIME_STAINED_GLASS_PANE, disable, SpigotPrison.format("&a" + "Full-Inventory-Hologram Enabled"))); } else { - List EnabledOrDisabledLore = createLore( - messages.getString("Lore.FullHologramDisabled"), - messages.getString("Lore.RightClickToEnable")); - gui.addButton(new Button(8, XMaterial.RED_STAINED_GLASS_PANE, EnabledOrDisabledLore, SpigotPrison.format("&c" + "Full-Inventory-Hologram Disabled"))); + enable.setLoreDescription(messages.getString("Lore.FullHologramDisabled")); + gui.addButton(new Button(8, XMaterial.RED_STAINED_GLASS_PANE, enable, SpigotPrison.format("&c" + "Full-Inventory-Hologram Disabled"))); } if (afConfig.isFeatureBoolean(AutoFeatures.isAutoManagerEnabled)) { - List EnabledOrDisabledLore = createLore( - messages.getString("Lore.EnabledAll"), - messages.getString("Lore.ShiftAndRightClickToDisable")); - gui.addButton(new Button(18, XMaterial.LIME_STAINED_GLASS_PANE, EnabledOrDisabledLore, SpigotPrison.format("&a" + "All Enabled"))); + disable.setLoreDescription(messages.getString("Lore.EnabledAll")); + gui.addButton(new Button(18, XMaterial.LIME_STAINED_GLASS_PANE, disable, SpigotPrison.format("&a" + "All Enabled"))); } else { - List EnabledOrDisabledLore = createLore( - messages.getString("Lore.DisabledAll"), - messages.getString("Lore.RightClickToEnable")); - gui.addButton(new Button(18, XMaterial.RED_STAINED_GLASS_PANE, EnabledOrDisabledLore, SpigotPrison.format("&c" + "All Disabled"))); + enable.setLoreDescription(messages.getString("Lore.DisabledAll")); + gui.addButton(new Button(18, XMaterial.RED_STAINED_GLASS_PANE, enable, SpigotPrison.format("&c" + "All Disabled"))); } + disable.setLoreAction(createLore( + messages.getString("Lore.LeftClickToOpen"), + messages.getString("Lore.ShiftAndRightClickToDisable") + )); + + enable.setLoreAction(createLore( + messages.getString("Lore.LeftClickToOpen"), + messages.getString("Lore.RightClickToEnable") + )); + if (afConfig.isFeatureBoolean(AutoFeatures.autoPickupEnabled)) { - // Lore of the button - List autoPickupLore = createLore( - "&8-----------------------", - " ", - messages.getString("Lore.AutoPickupGuiManager"), - messages.getString("Lore.ShiftAndRightClickToDisable"), - messages.getString("Lore.LeftClickToOpen"), - " ", - "&8-----------------------" - ); - gui.addButton(new Button(11, XMaterial.CHEST, autoPickupLore, SpigotPrison.format("&3" + "AutoPickup Enabled"))); + + disable.setLoreDescription(messages.getString("Lore.AutoPickupGuiManager")); + gui.addButton(new Button(11, XMaterial.CHEST, disable, SpigotPrison.format("&3" + "AutoPickup Enabled"))); } else { - // Lore of the button - List autoPickupLore = createLore( - "&8-----------------------", - " ", - messages.getString("Lore.AutoPickupGuiManager"), - messages.getString("Lore.RightClickToEnable"), - messages.getString("Lore.LeftClickToOpen"), - " ", - "&8-----------------------" - ); - gui.addButton(new Button(11, XMaterial.CHEST, autoPickupLore, SpigotPrison.format("&c" + "AutoPickup Disabled"))); + + enable.setLoreDescription(messages.getString("Lore.AutoPickupGuiManager")); + gui.addButton(new Button(11, XMaterial.CHEST, enable, SpigotPrison.format("&c" + "AutoPickup Disabled"))); } if (afConfig.isFeatureBoolean(AutoFeatures.autoSmeltEnabled)) { - // Lore of the button - List autoSmeltLore = createLore( - "&8-----------------------", - " ", - messages.getString("Lore.AutoSmeltGuiManager"), - messages.getString("Lore.ShiftAndRightClickToDisable"), - messages.getString("Lore.LeftClickToOpen"), - " ", - "&8-----------------------" - ); - gui.addButton(new Button(13, XMaterial.FURNACE, autoSmeltLore, SpigotPrison.format("&3" + "AutoSmelt Enabled"))); + + disable.setLoreDescription(messages.getString("Lore.AutoSmeltGuiManager")); + gui.addButton(new Button(13, XMaterial.FURNACE, disable, SpigotPrison.format("&3" + "AutoSmelt Enabled"))); } else { - // Lore of the button - List autoSmeltLore = createLore( - "&8-----------------------", - " ", - messages.getString("Lore.AutoSmeltGuiManager"), - messages.getString("Lore.RightClickToEnable"), - messages.getString("Lore.LeftClickToOpen"), - " ", - "&8-----------------------" - ); - gui.addButton(new Button(13, XMaterial.FURNACE, autoSmeltLore, SpigotPrison.format("&c" + "AutoSmelt Disabled"))); + + enable.setLoreDescription(messages.getString("Lore.AutoSmeltGuiManager")); + gui.addButton(new Button(13, XMaterial.FURNACE, enable, SpigotPrison.format("&c" + "AutoSmelt Disabled"))); } if (afConfig.isFeatureBoolean(AutoFeatures.autoBlockEnabled)) { - // Lore of the button - List autoBlockLore = createLore( - "&8-----------------------", - " ", - messages.getString("Lore.AutoBlockGuiManager"), - messages.getString("Lore.ShiftAndRightClickToDisable"), - messages.getString("Lore.LeftClickToOpen"), - " ", - "&8-----------------------" - ); - gui.addButton(new Button(15, XMaterial.CRAFTING_TABLE, autoBlockLore, SpigotPrison.format("&3" + "AutoBlock Enabled"))); + + disable.setLoreDescription(messages.getString("Lore.AutoBlockGuiManager")); + gui.addButton(new Button(15, XMaterial.CRAFTING_TABLE, disable, SpigotPrison.format("&3" + "AutoBlock Enabled"))); } else { - // Lore of the button - List autoBlockLore = createLore( - "&8-----------------------", - " ", - messages.getString("Lore.AutoBlockGuiManager"), - messages.getString("Lore.RightClickToEnable"), - messages.getString("Lore.LeftClickToOpen"), - " ", - "&8-----------------------" - ); - gui.addButton(new Button(15, XMaterial.CRAFTING_TABLE, autoBlockLore, SpigotPrison.format("&c" + "AutoBlock Disabled"))); + + enable.setLoreDescription(messages.getString("Lore.AutoBlockGuiManager")); + gui.addButton(new Button(15, XMaterial.CRAFTING_TABLE, enable, SpigotPrison.format("&c" + "AutoBlock Disabled"))); } } else { gui = new PrisonGUI(p, 9, "&3PrisonManager -> AutoFeatures"); - List EnabledOrDisabledLore = createLore( - messages.getString("Lore.DisabledAll"), - messages.getString("Lore.RightClickToEnable")); - Button enabledOrDisabled = new Button(2, XMaterial.LIME_STAINED_GLASS_PANE, EnabledOrDisabledLore, SpigotPrison.format("&c" + "All Disabled")); + ButtonLore lore = new ButtonLore(messages.getString("Lore.RightClickToEnable"), messages.getString("Lore.DisabledAll")); + + Button enabledOrDisabled = new Button(2, XMaterial.LIME_STAINED_GLASS_PANE, lore, SpigotPrison.format("&c" + "All Disabled")); gui.addButton(enabledOrDisabled); gui.addButton(new Button(6,XMaterial.RED_STAINED_GLASS_PANE, closeGUILore, SpigotPrison.format("&c" + "Close"))); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/autofeatures/SpigotAutoPickupGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/autofeatures/SpigotAutoPickupGUI.java index cc7383a98..a04b7322c 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/autofeatures/SpigotAutoPickupGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/autofeatures/SpigotAutoPickupGUI.java @@ -1,21 +1,18 @@ package tech.mcprison.prison.spigot.gui.autofeatures; import com.cryptomorin.xseries.XMaterial; -import org.bukkit.Bukkit; -import org.bukkit.Material; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig; import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; -import java.util.List; - /** * @author GABRYCA */ @@ -30,154 +27,97 @@ public SpigotAutoPickupGUI(Player p){ public void open() { - // Create the inventory and set up the owner, dimensions or number of slots, and title int dimension = 36; - Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format("&3AutoFeatures -> AutoPickup")); - - if (guiBuilder(inv)) return; - - openGUI(p, inv); - } - - private boolean guiBuilder(Inventory inv) { - try { - buttonsSetup(inv); - } catch (NullPointerException ex){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cThere's a null value in the GuiConfig.yml [broken]")); - ex.printStackTrace(); - return true; - } - return false; - } - - private void buttonsSetup(Inventory inv) { - - - List enabledLore = createLore( - messages.getString("Lore.ShiftAndRightClickToDisable") - ); - - List disabledLore = createLore( - messages.getString("Lore.RightClickToEnable") - ); - - List closeGUILore = createLore( - messages.getString("Lore.ClickToClose") - ); - - ItemStack closeGUI = createButton(XMaterial.RED_STAINED_GLASS_PANE.parseItem(), closeGUILore, SpigotPrison.format("&c" + "Close")); - inv.setItem(35, closeGUI); - - if ( afConfig.isFeatureBoolean( AutoFeatures.pickupAllBlocks ) ) { - ItemStack Enabled = createButton(XMaterial.LIME_STAINED_GLASS_PANE.parseItem(), enabledLore, SpigotPrison.format("&a" + "All_Blocks Enabled")); - inv.addItem(Enabled); - } else { - ItemStack Disabled = createButton(XMaterial.RED_STAINED_GLASS_PANE.parseItem(), disabledLore, SpigotPrison.format("&c" + "All_Blocks Disabled")); - inv.addItem(Disabled); - } - - if ( afConfig.isFeatureBoolean( AutoFeatures.pickupCobbleStone ) ) { - ItemStack Enabled = createButton(XMaterial.COBBLESTONE.parseItem(), enabledLore, SpigotPrison.format("&a" + "Cobblestone Enabled")); - inv.addItem(Enabled); - } else { - ItemStack Disabled = createButton(XMaterial.COBBLESTONE.parseItem(), disabledLore, SpigotPrison.format("&c" + "Cobblestone Disabled")); - inv.addItem(Disabled); - } - - if ( afConfig.isFeatureBoolean( AutoFeatures.pickupStone ) ) { - ItemStack Enabled = createButton(XMaterial.STONE.parseItem(), enabledLore, SpigotPrison.format("&a" + "Stone Enabled")); - inv.addItem(Enabled); - } else { - ItemStack Disabled = createButton(XMaterial.STONE.parseItem(), disabledLore, SpigotPrison.format("&c" + "Stone Disabled")); - inv.addItem(Disabled); - } - - if ( afConfig.isFeatureBoolean( AutoFeatures.pickupGoldOre ) ) { - ItemStack Enabled = createButton(XMaterial.GOLD_ORE.parseItem(), enabledLore, SpigotPrison.format("&a" + "Gold_Ore Enabled")); - inv.addItem(Enabled); - } else { - ItemStack Disabled = createButton(XMaterial.GOLD_ORE.parseItem(), disabledLore, SpigotPrison.format("&c" + "Gold_Ore Disabled")); - inv.addItem(Disabled); - } - - if ( afConfig.isFeatureBoolean( AutoFeatures.pickupIronOre ) ) { - ItemStack Enabled = createButton(XMaterial.IRON_ORE.parseItem(), enabledLore, SpigotPrison.format("&a" + "Iron_Ore Enabled")); - inv.addItem(Enabled); + PrisonGUI gui = new PrisonGUI(p, dimension, "&3AutoFeatures -> AutoPickup"); + + ButtonLore enabledLore = new ButtonLore(messages.getString("Lore.ShiftAndRightClickToDisable"), null); + ButtonLore disabledLore = new ButtonLore(messages.getString("Lore.RightClickToEnable"), null); + ButtonLore closeGUILore = new ButtonLore(messages.getString("Lore.ClickToClose"), null); + + gui.addButton(new Button(35, XMaterial.RED_STAINED_GLASS_PANE, closeGUILore, SpigotPrison.format("&c" + "Close"))); + + if (afConfig != null) { + if (afConfig.isFeatureBoolean(AutoFeatures.pickupAllBlocks)) { + gui.addButton(new Button(null, XMaterial.LIME_STAINED_GLASS_PANE, enabledLore, SpigotPrison.format("&a" + "All_Blocks Enabled"))); + } else { + gui.addButton(new Button(null, XMaterial.RED_STAINED_GLASS_PANE, disabledLore, SpigotPrison.format("&c" + "All_Blocks Disabled"))); + } + + if (afConfig.isFeatureBoolean(AutoFeatures.pickupCobbleStone)) { + gui.addButton(new Button(null, XMaterial.COBBLESTONE, enabledLore, SpigotPrison.format("&a" + "Cobblestone Enabled"))); + } else { + gui.addButton(new Button(null, XMaterial.COBBLESTONE, disabledLore, SpigotPrison.format("&c" + "Cobblestone Disabled"))); + } + + if (afConfig.isFeatureBoolean(AutoFeatures.pickupStone)) { + gui.addButton(new Button(null, XMaterial.STONE, enabledLore, SpigotPrison.format("&a" + "Stone Enabled"))); + } else { + gui.addButton(new Button(null, XMaterial.STONE, disabledLore, SpigotPrison.format("&c" + "Stone Disabled"))); + } + + if (afConfig.isFeatureBoolean(AutoFeatures.pickupGoldOre)) { + gui.addButton(new Button(null, XMaterial.GOLD_ORE, enabledLore, SpigotPrison.format("&a" + "Gold_Ore Enabled"))); + } else { + gui.addButton(new Button(null, XMaterial.GOLD_ORE, disabledLore, SpigotPrison.format("&c" + "Gold_Ore Disabled"))); + } + + if (afConfig.isFeatureBoolean(AutoFeatures.pickupIronOre)) { + gui.addButton(new Button(null, XMaterial.IRON_ORE, enabledLore, SpigotPrison.format("&a" + "Iron_Ore Enabled"))); + } else { + gui.addButton(new Button(null, XMaterial.IRON_ORE, disabledLore, SpigotPrison.format("&c" + "Iron_Ore Disabled"))); + } + + if (afConfig.isFeatureBoolean(AutoFeatures.pickupCoalOre)) { + gui.addButton(new Button(null, XMaterial.COAL_ORE, enabledLore, SpigotPrison.format("&a" + "Coal_Ore Enabled"))); + } else { + gui.addButton(new Button(null, XMaterial.COAL_ORE, disabledLore, SpigotPrison.format("&c" + "Coal_Ore Disabled"))); + } + + if (afConfig.isFeatureBoolean(AutoFeatures.pickupDiamondOre)) { + gui.addButton(new Button(null, XMaterial.DIAMOND_ORE, enabledLore, SpigotPrison.format("&a" + "Diamond_Ore Enabled"))); + } else { + gui.addButton(new Button(null, XMaterial.DIAMOND_ORE, disabledLore, SpigotPrison.format("&c" + "Diamond_Ore Disabled"))); + } + + if (afConfig.isFeatureBoolean(AutoFeatures.pickupRedStoneOre)) { + gui.addButton(new Button(null, XMaterial.REDSTONE_ORE, enabledLore, SpigotPrison.format("&a" + "Redstone_Ore Enabled"))); + } else { + gui.addButton(new Button(null, XMaterial.REDSTONE_ORE, disabledLore, SpigotPrison.format("&c" + "Redstone_Ore Disabled"))); + } + + if (afConfig.isFeatureBoolean(AutoFeatures.pickupEmeraldOre)) { + gui.addButton(new Button(null, XMaterial.EMERALD_ORE, enabledLore, SpigotPrison.format("&a" + "Emerald_Ore Enabled"))); + } else { + gui.addButton(new Button(null, XMaterial.EMERALD_ORE, disabledLore, SpigotPrison.format("&c" + "Emerald_Ore Disabled"))); + } + + if (afConfig.isFeatureBoolean(AutoFeatures.pickupQuartzOre)) { + gui.addButton(new Button(null, XMaterial.NETHER_QUARTZ_ORE, 1, enabledLore, SpigotPrison.format("&a" + "Quartz_Ore Enabled"))); + } else { + gui.addButton(new Button(null, XMaterial.NETHER_QUARTZ_ORE, 1, disabledLore, SpigotPrison.format("&c" + "Quartz_Ore Disabled"))); + } + + if (afConfig.isFeatureBoolean(AutoFeatures.pickupLapisOre)) { + gui.addButton(new Button(null, XMaterial.LAPIS_ORE, enabledLore, SpigotPrison.format("&a" + "Lapis_Ore Enabled"))); + } else { + gui.addButton(new Button(null, XMaterial.LAPIS_ORE, disabledLore, SpigotPrison.format("&c" + "Lapis_Ore Disabled"))); + } + + if (afConfig.isFeatureBoolean(AutoFeatures.pickupSnowBall)) { + gui.addButton(new Button(null, XMaterial.SNOWBALL, 1, enabledLore, SpigotPrison.format("&a" + "Snow_Ball Enabled"))); + } else { + gui.addButton(new Button(null, XMaterial.SNOWBALL, 1, disabledLore, SpigotPrison.format("&c" + "Snow_Ball Disabled"))); + } + + if (afConfig.isFeatureBoolean(AutoFeatures.pickupGlowstoneDust)) { + gui.addButton(new Button(null, XMaterial.GLOWSTONE_DUST, enabledLore, SpigotPrison.format("&a" + "Glowstone_Dust Enabled"))); + } else { + gui.addButton(new Button(null, XMaterial.GLOWSTONE_DUST, disabledLore, SpigotPrison.format("&c" + "Glowstone_Dust Disabled"))); + } } else { - ItemStack Disabled = createButton(XMaterial.IRON_ORE.parseItem(), disabledLore, SpigotPrison.format("&c" + "Iron_Ore Disabled")); - inv.addItem(Disabled); + Output.get().sendError(new SpigotPlayer(p), "An error occurred, the AutoFeatures Config is broken or missing!"); } - if ( afConfig.isFeatureBoolean( AutoFeatures.pickupCoalOre ) ) { - ItemStack Enabled = createButton(XMaterial.COAL_ORE.parseItem(), enabledLore, SpigotPrison.format("&a" + "Coal_Ore Enabled")); - inv.addItem(Enabled); - } else { - ItemStack Disabled = createButton(XMaterial.COAL_ORE.parseItem(), disabledLore, SpigotPrison.format("&c" + "Coal_Ore Disabled")); - inv.addItem(Disabled); - } - - if ( afConfig.isFeatureBoolean( AutoFeatures.pickupDiamondOre ) ) { - ItemStack Enabled = createButton(XMaterial.DIAMOND_ORE.parseItem(), enabledLore, SpigotPrison.format("&a" + "Diamond_Ore Enabled")); - inv.addItem(Enabled); - } else { - ItemStack Disabled = createButton(XMaterial.DIAMOND_ORE.parseItem(), disabledLore, SpigotPrison.format("&c" + "Diamond_Ore Disabled")); - inv.addItem(Disabled); - } - - if ( afConfig.isFeatureBoolean( AutoFeatures.pickupRedStoneOre ) ) { - ItemStack Enabled = createButton(XMaterial.REDSTONE_ORE.parseItem(), enabledLore, SpigotPrison.format("&a" + "Redstone_Ore Enabled")); - inv.addItem(Enabled); - } else { - ItemStack Disabled = createButton(XMaterial.REDSTONE_ORE.parseItem(), disabledLore, SpigotPrison.format("&c" + "Redstone_Ore Disabled")); - inv.addItem(Disabled); - } - - if ( afConfig.isFeatureBoolean( AutoFeatures.pickupEmeraldOre ) ) { - ItemStack Enabled = createButton(XMaterial.EMERALD_ORE.parseItem(), enabledLore, SpigotPrison.format("&a" + "Emerald_Ore Enabled")); - inv.addItem(Enabled); - } else { - ItemStack Disabled = createButton(XMaterial.EMERALD_ORE.parseItem(), disabledLore, SpigotPrison.format("&c" + "Emerald_Ore Disabled")); - inv.addItem(Disabled); - } - - Material quartzOre = Material.matchMaterial( "quartz_ore" ); - if ( quartzOre == null ) { - quartzOre = Material.matchMaterial( "nether_quartz_ore" ); - } - if ( afConfig.isFeatureBoolean( AutoFeatures.pickupQuartzOre ) ) { - ItemStack Enabled = createButton(quartzOre, 1, enabledLore, SpigotPrison.format("&a" + "Quartz_Ore Enabled")); - inv.addItem(Enabled); - } else { - ItemStack Disabled = createButton(quartzOre, 1, disabledLore, SpigotPrison.format("&c" + "Quartz_Ore Disabled")); - inv.addItem(Disabled); - } - - if ( afConfig.isFeatureBoolean( AutoFeatures.pickupLapisOre ) ) { - ItemStack Enabled = createButton(XMaterial.LAPIS_ORE.parseItem(), enabledLore, SpigotPrison.format("&a" + "Lapis_Ore Enabled")); - inv.addItem(Enabled); - } else { - ItemStack Disabled = createButton(XMaterial.LAPIS_ORE.parseItem(), disabledLore, SpigotPrison.format("&c" + "Lapis_Ore Disabled")); - inv.addItem(Disabled); - } - - Material snowBall = Material.matchMaterial( "snow_ball" ); - if ( snowBall == null ) { - snowBall = Material.matchMaterial( "snowball" ); - } - if ( afConfig.isFeatureBoolean( AutoFeatures.pickupSnowBall ) ) { - ItemStack Enabled = createButton(snowBall, 1, enabledLore, SpigotPrison.format("&a" + "Snow_Ball Enabled")); - inv.addItem(Enabled); - } else { - ItemStack Disabled = createButton(snowBall, 1, disabledLore, SpigotPrison.format("&c" + "Snow_Ball Disabled")); - inv.addItem(Disabled); - } - - if ( afConfig.isFeatureBoolean( AutoFeatures.pickupGlowstoneDust ) ) { - ItemStack Enabled = createButton(XMaterial.GLOWSTONE_DUST.parseItem(), enabledLore, SpigotPrison.format("&a" + "Glowstone_Dust Enabled")); - inv.addItem(Enabled); - } else { - ItemStack Disabled = createButton(XMaterial.GLOWSTONE_DUST.parseItem(), disabledLore, SpigotPrison.format("&c" + "Glowstone_Dust Disabled")); - inv.addItem(Disabled); - } + gui.open(); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/autofeatures/SpigotAutoSmeltGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/autofeatures/SpigotAutoSmeltGUI.java index 104e2d5b3..17468ac4b 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/autofeatures/SpigotAutoSmeltGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/autofeatures/SpigotAutoSmeltGUI.java @@ -1,20 +1,18 @@ package tech.mcprison.prison.spigot.gui.autofeatures; import com.cryptomorin.xseries.XMaterial; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig; import tech.mcprison.prison.autofeatures.AutoFeaturesFileConfig.AutoFeatures; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; -import java.util.List; - /** * @author GABRYCA */ @@ -29,63 +27,37 @@ public SpigotAutoSmeltGUI(Player p){ public void open() { - // Create the inventory and set up the owner, dimensions or number of slots, and title int dimension = 36; - Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format("&3AutoFeatures -> AutoSmelt")); - - if (guiBuilder(inv)) return; - - openGUI(p, inv); - } - - private boolean guiBuilder(Inventory inv) { - try { - buttonsSetup(inv); - } catch (NullPointerException ex){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cThere's a null value in the GuiConfig.yml [broken]")); - ex.printStackTrace(); - return true; - } - return false; - } - - private void buttonsSetup(Inventory inv) { - - List enabledLore = createLore( - messages.getString("Lore.ShiftAndRightClickToDisable") - ); - List disabledLore = createLore( - messages.getString("Lore.RightClickToEnable") - ); - List closeGUILore = createLore( - messages.getString("Lore.ClickToClose") - ); - - ItemStack closeGUI = createButton(XMaterial.RED_STAINED_GLASS_PANE.parseItem(), closeGUILore, SpigotPrison.format("&c" + "Close")); - inv.setItem(35, closeGUI); - - if ( afConfig.isFeatureBoolean( AutoFeatures.smeltAllBlocks ) ) { - ItemStack Enabled = createButton(XMaterial.LIME_STAINED_GLASS_PANE.parseItem(), enabledLore, SpigotPrison.format("&a" + "All_Ores Enabled")); - inv.addItem(Enabled); - } else { - ItemStack Disabled = createButton(XMaterial.RED_STAINED_GLASS_PANE.parseItem(), disabledLore, SpigotPrison.format("&c" + "All_Ores Disabled")); - inv.addItem(Disabled); - } - - if ( afConfig.isFeatureBoolean( AutoFeatures.smeltGoldOre ) ) { - ItemStack Enabled = createButton(XMaterial.GOLD_ORE.parseItem(), enabledLore, SpigotPrison.format("&a" + "Gold_Ore Enabled")); - inv.addItem(Enabled); + PrisonGUI gui = new PrisonGUI(p, dimension, "&3AutoFeatures -> AutoSmelt"); + + ButtonLore enabledLore = new ButtonLore(messages.getString("Lore.ShiftAndRightClickToDisable"), null); + ButtonLore disabledLore = new ButtonLore(messages.getString("Lore.RightClickToEnable"), null); + ButtonLore closeGUILore = new ButtonLore(messages.getString("Lore.ClickToClose"), null); + + gui.addButton(new Button(35, XMaterial.RED_STAINED_GLASS_PANE, closeGUILore, SpigotPrison.format("&c" + "Close"))); + + if(afConfig != null) { + if (afConfig.isFeatureBoolean(AutoFeatures.smeltAllBlocks)) { + gui.addButton(new Button(null, XMaterial.LIME_STAINED_GLASS_PANE, enabledLore, SpigotPrison.format("&a" + "All_Ores Enabled"))); + } else { + gui.addButton(new Button(null, XMaterial.RED_STAINED_GLASS_PANE, disabledLore, SpigotPrison.format("&c" + "All_Ores Disabled"))); + } + + if (afConfig.isFeatureBoolean(AutoFeatures.smeltGoldOre)) { + gui.addButton(new Button(null, XMaterial.GOLD_ORE, enabledLore, SpigotPrison.format("&a" + "Gold_Ore Enabled"))); + } else { + gui.addButton(new Button(null, XMaterial.GOLD_ORE, disabledLore, SpigotPrison.format("&c" + "Gold_Ore Disabled"))); + } + + if (afConfig.isFeatureBoolean(AutoFeatures.smeltIronOre)) { + gui.addButton(new Button(null, XMaterial.IRON_ORE, enabledLore, SpigotPrison.format("&a" + "Iron_Ore Enabled"))); + } else { + gui.addButton(new Button(null, XMaterial.IRON_ORE, disabledLore, SpigotPrison.format("&c" + "Iron_Ore Disabled"))); + } } else { - ItemStack Disabled = createButton(XMaterial.GOLD_ORE.parseItem(), disabledLore, SpigotPrison.format("&c" + "Gold_Ore Disabled")); - inv.addItem(Disabled); + Output.get().sendError(new SpigotPlayer(p), "An error occurred, the AutoFeatures Config is broken or missing!"); } - if ( afConfig.isFeatureBoolean( AutoFeatures.smeltIronOre ) ) { - ItemStack Enabled = createButton(XMaterial.IRON_ORE.parseItem(), enabledLore, SpigotPrison.format("&a" + "Iron_Ore Enabled")); - inv.addItem(Enabled); - } else { - ItemStack Disabled = createButton(XMaterial.IRON_ORE.parseItem(), disabledLore, SpigotPrison.format("&c" + "Iron_Ore Disabled")); - inv.addItem(Disabled); - } + gui.open(); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/backpacks/BackpacksAdminGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/backpacks/BackpacksAdminGUI.java index d8666c8b2..9878a3d5f 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/backpacks/BackpacksAdminGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/backpacks/BackpacksAdminGUI.java @@ -1,18 +1,18 @@ package tech.mcprison.prison.spigot.gui.backpacks; import com.cryptomorin.xseries.XMaterial; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; import tech.mcprison.prison.output.Output; -import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.backpacks.BackpacksUtil; import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; -import java.util.List; - +/** + * @author anonymousGCA (GABRYCA) + * */ public class BackpacksAdminGUI extends SpigotGUIComponents { private final Player p; @@ -24,31 +24,20 @@ public BackpacksAdminGUI(Player p) { public void open(){ if (!BackpacksUtil.isEnabled()){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.BackPackIsDisabled"))); + Output.get().sendWarn(new SpigotPlayer(p), messages.getString("Message.BackPackIsDisabled")); p.closeInventory(); return; } int dimension = 27; - Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format("&3" + "Backpacks-Admin")); - - // List Button. - List lore = createLore( - messages.getString("Lore.ClickToOpen") - ); - ItemStack listButton = createButton(XMaterial.CHEST.parseItem(), lore, "&3Backpacks-List"); - - ItemStack settingsButton = createButton(XMaterial.PAPER.parseItem(), lore, "&3Backpack-Settings"); + PrisonGUI gui = new PrisonGUI(p, dimension, "&3" + "Backpacks-Admin"); - List closeGUILore = createLore( - messages.getString("Lore.ClickToClose") - ); + ButtonLore lore = new ButtonLore(messages.getString("Lore.ClickToOpen"), null); - ItemStack closeGUI = createButton(XMaterial.RED_STAINED_GLASS_PANE.parseItem(), closeGUILore, SpigotPrison.format("&c" + "Close")); - inv.setItem(dimension-1, closeGUI); + gui.addButton(new Button(11, XMaterial.CHEST, lore, "&3Backpacks-List")); + gui.addButton(new Button(15, XMaterial.PAPER, lore, "&3Backpack-Settings")); + gui.addButton(new Button(dimension -1, XMaterial.RED_STAINED_GLASS_PANE, new ButtonLore(messages.getString("Lore.ClickToClose"), null), "&c" + "Close")); - inv.setItem(11, listButton); - inv.setItem(15, settingsButton); - openGUI(p, inv); + gui.open(); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/backpacks/BackpacksAdminListGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/backpacks/BackpacksAdminListGUI.java index be60c5dd4..9809d9eff 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/backpacks/BackpacksAdminListGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/backpacks/BackpacksAdminListGUI.java @@ -1,18 +1,19 @@ package tech.mcprison.prison.spigot.gui.backpacks; import com.cryptomorin.xseries.XMaterial; -import org.bukkit.Bukkit; import org.bukkit.configuration.Configuration; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.backpacks.BackpacksUtil; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; -import java.util.List; import java.util.Set; +/** + * @author AnonymousGCA (GABRYCA) + * */ public class BackpacksAdminListGUI extends SpigotGUIComponents { private final Player p; @@ -31,7 +32,7 @@ public BackpacksAdminListGUI(Player p, String playerBackpackName){ public void open(){ int dimension = 54; - Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format("&3" + "Backpacks-Admin-List")); + PrisonGUI gui = new PrisonGUI(p, dimension, "&3" + "Backpacks-Admin-List"); Set playerUUID = backpacksData.getConfigurationSection("Inventories").getKeys(false); @@ -55,28 +56,22 @@ public void open(){ } } if (id != null) { - List backpacksLore = createLore( - loreShiftAndRightClickToDelete, - "&8----------------", - " ", + + ButtonLore backpacksLore = new ButtonLore(createLore(loreShiftAndRightClickToDelete), createLore( loreInfo, lorePlayerOwner + name, - loreBackpackID + id, - " ", - "&8----------------" - ); + loreBackpackID + id)); - ItemStack backpackButton = createButton(XMaterial.CHEST.parseItem(), backpacksLore, "&3" + "Backpack " + name + " " + id); - inv.setItem(backpacksFound, backpackButton); + gui.addButton(new Button(backpacksFound, XMaterial.CHEST, backpacksLore, "&3" + "Backpack " + name + " " + id)); backpacksFound++; } } else { - openGUI(p, inv); + gui.open(); return; } } } } - openGUI(p, inv); + gui.open(); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/backpacks/BackpacksAdminPlayerListGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/backpacks/BackpacksAdminPlayerListGUI.java index a85fda609..5720ba444 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/backpacks/BackpacksAdminPlayerListGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/backpacks/BackpacksAdminPlayerListGUI.java @@ -1,20 +1,21 @@ package tech.mcprison.prison.spigot.gui.backpacks; import com.cryptomorin.xseries.XMaterial; -import org.bukkit.Bukkit; import org.bukkit.configuration.Configuration; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; import tech.mcprison.prison.output.Output; -import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.backpacks.BackpacksUtil; import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; -import java.util.List; import java.util.Set; +/** + * @author AnonymousGCA (GABRYCA) + * */ public class BackpacksAdminPlayerListGUI extends SpigotGUIComponents { private final Player p; @@ -28,11 +29,10 @@ public BackpacksAdminPlayerListGUI(Player p){ public void open(){ int dimension = 54; - Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format("&3" + "Backpacks-Admin-Players")); - + PrisonGUI gui = new PrisonGUI(p, dimension, "&3" + "Backpacks-Admin-Players"); if (backpacksData.getConfigurationSection("Inventories") == null){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.BackPackListEmpty"))); + Output.get().sendWarn(new SpigotPlayer(p), messages.getString("Message.BackPackListEmpty")); return; } @@ -40,13 +40,11 @@ public void open(){ try { playerUUID = backpacksData.getConfigurationSection("Inventories").getKeys(false); } catch (NullPointerException ex){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.BackPackListEmpty"))); + Output.get().sendWarn(new SpigotPlayer(p), messages.getString("Message.BackPackListEmpty")); return; } - List backpackLore = createLore( - clickToOpen - ); + ButtonLore backpackLore = new ButtonLore(clickToOpen, null); int playersFound = 0; for (String uuid : playerUUID) { @@ -61,17 +59,15 @@ public void open(){ if (playersFound < 54) { if (name != null) { - - ItemStack playerButton = createButton(XMaterial.PAPER.parseItem(), backpackLore, "&3Backpacks " + name); - - inv.setItem(playersFound, playerButton); + gui.addButton(new Button(playersFound, XMaterial.PAPER, backpackLore, "&3Backpacks " + name)); playersFound++; } + } else { - openGUI(p, inv); + gui.open(); return; } } - openGUI(p, inv); + gui.open(); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/backpacks/BackpacksListPlayerGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/backpacks/BackpacksListPlayerGUI.java index aa93dc898..4e7c07e03 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/backpacks/BackpacksListPlayerGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/backpacks/BackpacksListPlayerGUI.java @@ -1,18 +1,19 @@ package tech.mcprison.prison.spigot.gui.backpacks; import com.cryptomorin.xseries.XMaterial; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.backpacks.BackpacksUtil; import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; -import java.util.List; - +/** + * @author AnonymousGCA (GABRYCA) + * */ public class BackpacksListPlayerGUI extends SpigotGUIComponents { private final Player p; @@ -24,25 +25,17 @@ public BackpacksListPlayerGUI(Player p) { public void open(){ if (BackpacksUtil.get().getBackpacksLimit(p) == 0){ - Output.get().sendInfo(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.BackPackCantOwn"))); + Output.get().sendInfo(new SpigotPlayer(p), messages.getString("Message.BackPackCantOwn")); return; } int dimension = 54; - Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format("&3" + p.getName() + " -> Backpacks")); + PrisonGUI gui = new PrisonGUI(p, dimension, "&3" + p.getName() + " -> Backpacks"); - List loreAddBackpackButton = createLore( - messages.getString("Lore.ClickToAddBackpack"), - " ", - "&8-----------------------", - " ", - messages.getString("Lore.ClickToAddBackpackInst0"), + ButtonLore loreAddBackpackButton = new ButtonLore(createLore(messages.getString("Lore.ClickToAddBackpack")), createLore(messages.getString("Lore.ClickToAddBackpackInst0"), messages.getString("Lore.ClickToAddBackpackInst1"), messages.getString("Lore.ClickToAddBackpackInst2"), - messages.getString("Lore.ClickToAddBackpackInst3"), - " ", - "&8-----------------------" - ); + messages.getString("Lore.ClickToAddBackpackInst3"))); // Global Strings. String loreClickToOpen = messages.getString("Lore.ClickToOpen"); @@ -50,17 +43,16 @@ public void open(){ if (!BackpacksUtil.get().getBackpacksIDs(p).isEmpty()) { int slot = 0; for (String id : BackpacksUtil.get().getBackpacksIDs(p)) { - List lore = createLore( - loreClickToOpen, - " " - ); + + ButtonLore lore = new ButtonLore(loreClickToOpen, null); + if (slot < 45) { if (id != null) { - lore.add(SpigotPrison.format("&3/backpack " + id)); - inv.setItem(slot, createButton(XMaterial.CHEST.parseItem(), lore, SpigotPrison.format("&3Backpack-" + id))); + lore.setLoreDescription(SpigotPrison.format("&3/backpack " + id)); + gui.addButton(new Button(slot, XMaterial.CHEST, lore, "&3Backpack-" + id)); } else { - lore.add(SpigotPrison.format("&3/backpack")); - inv.setItem(slot, createButton(XMaterial.CHEST.parseItem(), lore, SpigotPrison.format("&3Backpack"))); + lore.setLoreDescription(SpigotPrison.format("&3/backpack")); + gui.addButton(new Button(slot, XMaterial.CHEST, lore, "&3Backpack")); } slot++; } @@ -68,16 +60,11 @@ public void open(){ } if (BackpacksUtil.get().getBackpacksIDs(p).isEmpty() || !BackpacksUtil.get().reachedBackpacksLimit(p)) { - inv.setItem(49, createButton(XMaterial.EMERALD_BLOCK.parseItem(), loreAddBackpackButton, SpigotPrison.format("&aNew Backpack"))); + gui.addButton(new Button(49, XMaterial.EMERALD_BLOCK, loreAddBackpackButton, "&aNew Backpack")); } - List closeGUILore = createLore( - messages.getString("Lore.ClickToClose") - ); - - ItemStack closeGUI = createButton(XMaterial.RED_STAINED_GLASS_PANE.parseItem(), closeGUILore, SpigotPrison.format("&c" + "Close")); - inv.setItem(dimension-1, closeGUI); + gui.addButton(new Button(dimension-1, XMaterial.RED_STAINED_GLASS_PANE, new ButtonLore(messages.getString("Lore.ClickToClose"), null), "&c" + "Close")); - openGUI(p, inv); + gui.open(); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/guiutility/Button.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/guiutility/Button.java index 6648b045c..10804cda3 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/guiutility/Button.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/guiutility/Button.java @@ -2,7 +2,9 @@ import com.cryptomorin.xseries.XMaterial; import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.ItemStack; +import tech.mcprison.prison.spigot.SpigotPrison; import java.util.List; @@ -25,7 +27,7 @@ public class Button extends SpigotGUIComponents{ public Button(Integer position, XMaterial buttonItem, List lore, String title){ if (position == null || position < 54) { this.position = position; - this.buttonItem = createButton(buttonItem.parseItem(), lore, title); + this.buttonItem = createButton(buttonItem.parseItem(), lore, SpigotPrison.format(title)); } } @@ -39,7 +41,7 @@ public Button(Integer position, XMaterial buttonItem, List lore, String public Button(Integer position, ItemStack buttonItem, String title){ if (position == null || position < 54) { this.position = position; - this.buttonItem = createButton(buttonItem, null, title); + this.buttonItem = createButton(buttonItem, null, SpigotPrison.format(title)); } } @@ -53,7 +55,7 @@ public Button(Integer position, ItemStack buttonItem, String title){ public Button(Integer position, XMaterial buttonItem, String title){ if (position == null || position < 54) { this.position = position; - this.buttonItem = createButton(buttonItem.parseItem(), null, title); + this.buttonItem = createButton(buttonItem.parseItem(), null, SpigotPrison.format(title)); } } @@ -69,7 +71,7 @@ public Button(Integer position, XMaterial buttonItem, String title){ public Button(Integer position, XMaterial buttonItem, int amount, List lore, String title){ if (position == null || position < 54) { this.position = position; - this.buttonItem = createButton(buttonItem.parseMaterial(), amount, lore, title); + this.buttonItem = createButton(buttonItem.parseMaterial(), amount, lore, SpigotPrison.format(title)); } } @@ -97,7 +99,7 @@ public Button(Integer position, ItemStack buttonItem){ public Button(Integer position, XMaterial buttonMaterial, int amount, String title){ if ((position == null || position < 54) && amount <= 64) { this.position = position; - this.buttonItem = createButton(buttonMaterial.parseMaterial(), amount, null, title); + this.buttonItem = createButton(buttonMaterial.parseMaterial(), amount, null, SpigotPrison.format(title)); } } @@ -112,7 +114,38 @@ public Button(Integer position, XMaterial buttonMaterial, int amount, String tit public Button(Integer position, Material buttonMaterial, int amount, String title){ if ((position == null || position < 54) && amount <= 64) { this.position = position; - this.buttonItem = createButton(buttonMaterial, amount, null, title); + this.buttonItem = createButton(buttonMaterial, amount, null, SpigotPrison.format(title)); + } + } + + /** + * Create button. + * + * @param position - int. + * @param buttonMaterial - Material. + * @param amount - int. + * @param lore - ButtonLore. + * @param title - String. + * */ + public Button(Integer position, XMaterial buttonMaterial, int amount, ButtonLore lore, String title){ + if (position == null || position < 54) { + this.position = position; + this.buttonItem = createButton(buttonMaterial.parseMaterial(), amount, lore.getLore(), SpigotPrison.format(title)); + } + } + + /** + * Create button. + * + * @param position - int. + * @param buttonMaterial - Material. + * @param lore - ButtonLore. + * @param title - String. + * */ + public Button(Integer position, XMaterial buttonMaterial, ButtonLore lore, String title){ + if (position == null || position < 54) { + this.position = position; + this.buttonItem = createButton(buttonMaterial.parseItem(), lore.getLore(), SpigotPrison.format(title)); } } @@ -158,7 +191,7 @@ public int getButtonQuantity(){ /** * Set button lore. * - * @param lore - List + * @param lore - List * */ public void setButtonLore(List lore){ if (buttonItem.getItemMeta() != null) { @@ -168,19 +201,44 @@ public void setButtonLore(List lore){ } } + /** + * Set button lore. + * + * @param lore - ButtonLore. + * */ + public void setButtonLore(ButtonLore lore){ + if (buttonItem.getItemMeta() != null) { + buttonItem = createButton(buttonItem, lore.getLore(), buttonItem.getItemMeta().getDisplayName()); + } else { + buttonItem = createButton(buttonItem, lore.getLore(), buttonItem.getType().name()); + } + } + /** * Add line to button lore. * * @param line - String. * */ public void addButtonLoreLine(String line){ - if (buttonItem.getItemMeta() != null && buttonItem.getItemMeta().getLore() != null){ - buttonItem.getItemMeta().getLore().add(line); + if (getButtonLore() != null){ + List lore = getButtonLore(); + lore.add(SpigotPrison.format(line)); + setButtonLore(lore); } else { - setButtonLore(createLore(line)); + setButtonLore(createLore(SpigotPrison.format(line))); } } + /** + * Add an unsafe enchantment to the button. + * + * @param enchant - Enchantment. + * @param level - int. + * */ + public void addUnsafeEnchantment(Enchantment enchant, int level){ + buttonItem.addUnsafeEnchantment(enchant, level); + } + /** * Get button lore. * diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/guiutility/ButtonLore.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/guiutility/ButtonLore.java new file mode 100644 index 000000000..68754f71a --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/guiutility/ButtonLore.java @@ -0,0 +1,242 @@ +package tech.mcprison.prison.spigot.gui.guiutility; + +import tech.mcprison.prison.spigot.SpigotPrison; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author AnonymousGCA (GABRYCA) + * */ +public class ButtonLore extends SpigotGUIComponents{ + + private List descriptionAction = new ArrayList<>(); + private List description = new ArrayList<>(); + private String colorIDBracket = "&8"; + private String colorIDAction = "&8"; + private String colorIDDescription = "&3"; + private String bracketDef = "--------------------"; + + /** + * Initialize a button lore with basic info (can also be empty). + * + * The final format, if all requirements are met, is as follow: + * + * &8descriptionAction + * + * &8---------------------------- + * &3description + * &8---------------------------- + * + * @param descriptionAction - List + * @param description - List + * */ + public ButtonLore(List descriptionAction, List description){ + if (!descriptionAction.isEmpty()) { + for (String dAction : descriptionAction) { + this.descriptionAction.add(SpigotPrison.format(colorIDAction + dAction)); + } + } + + if (!description.isEmpty()) { + for (String descriptionLore : description) { + this.description.add(SpigotPrison.format(colorIDDescription + descriptionLore)); + } + } + } + + public ButtonLore(){} + + /** + * Initialize a button lore with basic info (can also be empty). + * + * The final format, if all requirements are met, is as follow: + * + * &8descriptionAction + * + * &8---------------------------- + * &3description + * &8---------------------------- + * + * @param descriptionAction - String. + * @param description - String. + * */ + public ButtonLore(String descriptionAction, String description){ + if (descriptionAction != null) { + this.descriptionAction.add(SpigotPrison.format(colorIDAction + descriptionAction)); + } + + if (description != null) { + this.description.add(SpigotPrison.format(colorIDDescription + description)); + } + } + + /** + * Set description action. + * + * @param descriptionAction - List. + * */ + public void setLoreAction(List descriptionAction){ + this.descriptionAction.clear(); + for (String dAction : descriptionAction) { + this.descriptionAction.add(SpigotPrison.format(colorIDAction + dAction)); + } + } + + /** + * Set description action. + * + * @param descriptionAction - String. + * */ + public void setLoreAction(String descriptionAction){ + this.descriptionAction.clear(); + this.descriptionAction.add(SpigotPrison.format(colorIDAction + descriptionAction)); + } + + /** + * Add line to action lore. + * + * @param line - String. + * */ + public void addLineLoreAction(String line){ + this.descriptionAction.add(SpigotPrison.format(line)); + } + + /** + * Set description. + * + * @param description - List. + * */ + public void setLoreDescription(List description){ + this.description.clear(); + for (String descriptionLore : description) { + this.description.add(SpigotPrison.format(colorIDDescription + descriptionLore)); + } + } + + /** + * Set description. + * + * @param description - String. + * */ + public void setLoreDescription(String description){ + this.description.clear(); + this.description.add(SpigotPrison.format(colorIDDescription + description)); + } + + /** + * Add line to description lore. + * + * @param line - String. + * */ + public void addLineLoreDescription(String line){ + this.description.add(SpigotPrison.format(line)); + } + + /** + * Set color ID of the bracket. + * + * Default value: &8 (or defined by config). + * + * Please add color IDs using "&". + * + * @param colorID - String. + * */ + public void setColorIDBracket(String colorID){ + this.colorIDBracket = colorID; + } + + /** + * Set color ID of the action description. + * + * Default value: &8 (or defined by config). + * + * Please add color IDs using "&". + * + * @param colorID - String. + * */ + public void setColorIDAction(String colorID){ + this.colorIDAction = colorID; + } + + /** + * Set color ID of the description. + * + * Default value: &3 (or defined by config). + * + * Please add color IDs using "&". + * + * @param colorID - String. + * */ + public void setColorIDDescription(String colorID){ + this.colorIDDescription = colorID; + } + + /** + * Add bracket, this may in the feature become customizable trough a config. + * + * Usually the bracket looks like this: + * + * &8---------------------------- + * + * And is formatted like this (editable). + * + * colorID + brackedDefDivider + * + * @return bracket - String. + * */ + private String addBracket(){ + return colorIDBracket + bracketDef; + } + + /** + * Get button lore description. + * */ + public List getLoreDescription(){ + return description; + } + + /** + * Get button lore action. + * */ + public List getLoreAction(){ + return descriptionAction; + } + + /** + * This will return the lore with the global format: + * + * &8descriptionAction + * + * &8---------------------------- + * description + * &8---------------------------- + * + * + * For example: + * + * &8Click to open + * + * &8---------------------------- + * &3This will open a GUI. + * &8---------------------------- + * + * @return lore - List + * */ + public List getLore(){ + + List lore = new ArrayList<>(); + + if (!descriptionAction.isEmpty()) { + lore.addAll(descriptionAction); + } + + if (!description.isEmpty()) { + lore.add(""); + lore.add(SpigotPrison.format(addBracket())); + lore.addAll(description); + lore.add(SpigotPrison.format(addBracket())); + } + return lore; + } +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/guiutility/PrisonGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/guiutility/PrisonGUI.java index 9da3af62c..a2bf845b9 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/guiutility/PrisonGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/guiutility/PrisonGUI.java @@ -98,7 +98,7 @@ public void open(){ openGUI(p, inv); } else { SpigotPlayer spigotPlayer = new SpigotPlayer(p); - Output.get().sendWarn(spigotPlayer, SpigotPrison.format("Sorry, you don't have the permission! [" + permission + "]")); + Output.get().sendWarn(spigotPlayer, "Sorry, you don't have the permission! [" + permission + "]"); } } else { openGUI(p, inv); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/guiutility/SpigotGUIComponents.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/guiutility/SpigotGUIComponents.java index 0c5abad52..b2b02a5b3 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/guiutility/SpigotGUIComponents.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/guiutility/SpigotGUIComponents.java @@ -22,6 +22,7 @@ import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.game.SpigotPlayer; import tech.mcprison.prison.spigot.gui.ListenersPrisonManager; +import tech.mcprison.prison.spigot.sellall.SellAllUtil; /** * @author rbluer RoyalBlueRanger @@ -118,7 +119,7 @@ protected List createLore( String... lores ) { protected boolean checkRanks(Player p){ Module module = Prison.get().getModuleManager().getModule( PrisonRanks.MODULE_NAME ).orElse( null ); if(!(module instanceof PrisonRanks)){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&c[ERROR] The GUI can't open because the &3Ranks module &cisn't loaded")); + Output.get().sendWarn(new SpigotPlayer(p), "&c[ERROR] The GUI can't open because the &3Ranks module &cisn't loaded"); p.closeInventory(); } return module instanceof PrisonRanks; @@ -173,8 +174,9 @@ public static void updateMessages(){ * Reload sellall config for GUIs. * */ public static void updateSellAllConfig(){ - File file = new File(SpigotPrison.getInstance().getDataFolder() + "/SellAllConfig.yml"); - sellAllConfig = YamlConfiguration.loadConfiguration(file); + SellAllUtil util = SellAllUtil.get(); + util.updateSellAllConfig(); + sellAllConfig = util.getSellAllConfig(); } public static void updateGUIConfig(){ diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotBlocksListGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotBlocksListGUI.java index 52eaf8f1e..e4a6fefac 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotBlocksListGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotBlocksListGUI.java @@ -2,19 +2,17 @@ import java.util.List; -import org.bukkit.Bukkit; -import org.bukkit.Material; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; import com.cryptomorin.xseries.XMaterial; import tech.mcprison.prison.Prison; import tech.mcprison.prison.internal.block.PrisonBlock; import tech.mcprison.prison.internal.block.PrisonBlockTypes; -import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.SpigotUtil; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; /** @@ -39,12 +37,9 @@ public void open(){ int pageSize = 45; // Create the inventory - Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format("&3Mines -> BlocksList")); + PrisonGUI gui = new PrisonGUI(p, dimension, "&3Mines -> BlocksList"); - // Lore of block setup - List blockLoreSetup = createLore( - messages.getString("Lore.ClickToStartBlockSetup") - ); + ButtonLore lore = new ButtonLore(messages.getString("Lore.ClickToStartBlockSetup"), null); // This will skip all BlockTypes that are invalid for the versions of MC that the server is running: PrisonBlockTypes prisonBlockTypes = Prison.get().getPlatform().getPrisonBlockTypes(); @@ -63,27 +58,19 @@ public void open(){ if ( xMat == null ) { xMat = XMaterial.STONE; } - - ItemStack button = createButton( xMat.parseItem(), blockLoreSetup, SpigotPrison.format("&a" + - prisonBlock.getBlockName().toUpperCase() + " &0" + mineName + " " + counter)); - inv.addItem(button); + + gui.addButton(new Button(null, xMat, lore, "&a" + + prisonBlock.getBlockName().toUpperCase() + " &0" + mineName + " " + counter)); } if ( i < blockTypes.size() ) { - List nextPageLore = createLore( messages.getString("Lore.ClickToNextPage") ); - - ItemStack nextPageButton = createButton(Material.BOOK, 1, nextPageLore, "&7Next &0" + mineName + " " + (i + 1) ); - inv.setItem(53, nextPageButton); + gui.addButton(new Button(53, XMaterial.BOOK, new ButtonLore(messages.getString("Lore.ClickToNextPage"), null), "&7Next &0" + mineName + " " + (i + 1))); } if ( i >= (pageSize * 2) ) { - List priorPageLore = createLore( messages.getString("Lore.ClickToPriorPage") ); - - ItemStack priorPageButton = createButton(Material.BOOK, 1, priorPageLore, - "&7Prior &0" + mineName + " " + (i - (pageSize * 2) - 1) ); - inv.setItem(51, priorPageButton); + gui.addButton(new Button(51, XMaterial.BOOK, new ButtonLore(messages.getString("Lore.ClickToPriorPage"), null), "&7Prior &0" + mineName + " " + (i - (pageSize * 2) - 1))); } // Open the inventory - openGUI(p, inv); + gui.open(); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotBlocksMineListGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotBlocksMineListGUI.java index 7f9ca5302..db8ea3918 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotBlocksMineListGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotBlocksMineListGUI.java @@ -1,16 +1,14 @@ package tech.mcprison.prison.spigot.gui.mine; import com.cryptomorin.xseries.XMaterial; -import org.bukkit.Bukkit; -import org.bukkit.Material; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; import tech.mcprison.prison.Prison; import tech.mcprison.prison.internal.block.PrisonBlock; import tech.mcprison.prison.internal.block.PrisonBlockTypes; -import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.SpigotUtil; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; import java.util.List; @@ -37,12 +35,9 @@ public void open(){ int pageSize = 45; // Create the inventory - Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format("&3Select -> ShowBlock")); + PrisonGUI gui = new PrisonGUI(p, dimension, "&3Select -> ShowBlock"); - // Lore of block setup - List blockLoreSetup = createLore( - messages.getString("Lore.ClickToSelect") - ); + ButtonLore lore = new ButtonLore(messages.getString("Lore.ClickToSelect"), null); // This will skip all BlockTypes that are invalid for the versions of MC that the server is running: PrisonBlockTypes prisonBlockTypes = Prison.get().getPlatform().getPrisonBlockTypes(); @@ -62,25 +57,17 @@ public void open(){ xMat = XMaterial.STONE; } - ItemStack button = createButton( xMat.parseItem(), blockLoreSetup, SpigotPrison.format("&3" + + gui.addButton(new Button(null, xMat, lore, "&3" + prisonBlock.getBlockName().toUpperCase() + " " + mineName + " " + counter)); - inv.addItem(button); } if ( i < blockTypes.size() ) { - List nextPageLore = createLore( messages.getString("Lore.ClickToNextPage") ); - - ItemStack nextPageButton = createButton(Material.BOOK, 1, nextPageLore, "&7Next " + mineName + " " + (i + 1) ); - inv.setItem(53, nextPageButton); + gui.addButton(new Button(53, XMaterial.BOOK, new ButtonLore(messages.getString("Lore.ClickToNextPage"), null), "&7Next " + mineName + " " + (i + 1))); } if ( i >= (pageSize * 2) ) { - List priorPageLore = createLore( messages.getString("Lore.ClickToPriorPage") ); - - ItemStack priorPageButton = createButton(Material.BOOK, 1, priorPageLore, - "&7Prior " + mineName + " " + (i - (pageSize * 2) - 1) ); - inv.setItem(51, priorPageButton); + gui.addButton(new Button(51, XMaterial.BOOK, new ButtonLore(messages.getString("Lore.ClickToPriorPage"), null), "&7Prior " + mineName + " " + (i - (pageSize * 2) - 1))); } // Open the inventory - openGUI(p, inv); + gui.open(); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMineBlockPercentageGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMineBlockPercentageGUI.java index 3be145b75..8a430f6bd 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMineBlockPercentageGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMineBlockPercentageGUI.java @@ -1,24 +1,20 @@ package tech.mcprison.prison.spigot.gui.mine; -import org.bukkit.Bukkit; -import org.bukkit.Material; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; import com.cryptomorin.xseries.XMaterial; import tech.mcprison.prison.internal.block.PrisonBlock; -import tech.mcprison.prison.output.Output; -import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.SpigotUtil; -import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; import java.util.List; /** - * @author GABRYCA + * @author GABRYCA (AnonymousGCA) */ public class SpigotMineBlockPercentageGUI extends SpigotGUIComponents { @@ -37,100 +33,46 @@ public SpigotMineBlockPercentageGUI(Player p, Double val, String mineName, Strin } public void open() { - - // Create a new inventory int dimension = 45; - Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format("&3MineInfo -> BlockPercentage")); - - if (guiBuilder(inv)) return; - - // Open the inventory - openGUI(p, inv); - } - - private boolean guiBuilder(Inventory inv) { - try { - buttonsSetup(inv); - } catch (NullPointerException ex){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cThere's a null value in the GuiConfig.yml [broken]")); - ex.printStackTrace(); - return true; - } - return false; - } + PrisonGUI gui = new PrisonGUI(p, dimension, "&3MineInfo -> BlockPercentage"); - private void buttonsSetup(Inventory inv) { + ButtonLore changeDecreaseValueLore = new ButtonLore(messages.getString("Lore.ClickToDecrease"), null); + ButtonLore confirmButtonLore = new ButtonLore(createLore(messages.getString("Lore.LeftClickToConfirm"), messages.getString("Lore.RightClickToCancel")), createLore(messages.getString("Lore.Percentage") + val)); + ButtonLore changeIncreaseValueLore = new ButtonLore(messages.getString("Lore.ClickToIncrease"), null); - - // Create a new lore - List changeDecreaseValueLore = createLore( - messages.getString("Lore.ClickToDecrease") - ); - List confirmButtonLore = createLore( - messages.getString("Lore.LeftClickToConfirm"), - messages.getString("Lore.Percentage") + val, - messages.getString("Lore.RightClickToCancel") - ); - List changeIncreaseValueLore = createLore( - messages.getString("Lore.ClickToIncrease") - ); - - Material decreaseMat = XMaterial.REDSTONE_BLOCK.parseMaterial(); - ItemStack decreaseStack = XMaterial.REDSTONE_BLOCK.parseItem(); + XMaterial decreaseMaterial = XMaterial.REDSTONE_BLOCK; // Decrease button - ItemStack decreaseOf1 = createButton(decreaseStack, changeDecreaseValueLore, SpigotPrison.format("&3" + mineName + " " + blockName + " " + val + " - 1" + " &0" + counter)); - inv.setItem(1, decreaseOf1); - ItemStack decreaseOf5 = createButton(new ItemStack(decreaseMat, 5), changeDecreaseValueLore, SpigotPrison.format("&3" + mineName + " " + blockName + " " + val + " - 5" + " &0" + counter)); - inv.setItem(10, decreaseOf5); - ItemStack decreaseOf10 = createButton(new ItemStack(decreaseMat, 10), changeDecreaseValueLore, SpigotPrison.format("&3" + mineName + " " + blockName + " " + val + " - 10" + " &0" + counter)); - inv.setItem(19, decreaseOf10); - ItemStack decreaseOf50 = createButton(new ItemStack(decreaseMat, 50), changeDecreaseValueLore, SpigotPrison.format("&3" + mineName + " " + blockName + " " + val + " - 50" + " &0" + counter)); - inv.setItem(28, decreaseOf50); - ItemStack decreaseOf100 = createButton(decreaseStack, changeDecreaseValueLore, SpigotPrison.format("&3" + mineName + " " + blockName + " " + val + " - 100" + " &0" + counter)); - inv.setItem(37, decreaseOf100); - - - // Create a button and set the position - Material watch = Material.matchMaterial( "watch" ); - if ( watch == null ) { - watch = Material.matchMaterial( "legacy_watch" ); - } if ( watch == null ) { - watch = Material.matchMaterial( "clock" ); - } - ItemStack confirmButton = createButton(watch, 1, confirmButtonLore, SpigotPrison.format("&3" + "Confirm: " + mineName + " " + blockName + " " + val + " &0" + counter)); - inv.setItem(22, confirmButton); + gui.addButton(new Button(1, decreaseMaterial, changeDecreaseValueLore, "&3" + mineName + " " + blockName + " " + val + " - 1" + " &0" + counter)); + gui.addButton(new Button(10, decreaseMaterial, 5, changeDecreaseValueLore, "&3" + mineName + " " + blockName + " " + val + " - 5" + " &0" + counter)); + gui.addButton(new Button(19, decreaseMaterial, 10, changeDecreaseValueLore, "&3" + mineName + " " + blockName + " " + val + " - 10" + " &0" + counter)); + gui.addButton(new Button(28, decreaseMaterial, 50, changeDecreaseValueLore, "&3" + mineName + " " + blockName + " " + val + " - 50" + " &0" + counter)); + gui.addButton(new Button(37, decreaseMaterial, changeDecreaseValueLore, "&3" + mineName + " " + blockName + " " + val + " - 100" + " &0" + counter)); + + gui.addButton(new Button(22, XMaterial.CLOCK, 1, confirmButtonLore, "&3" + "Confirm: " + mineName + " " + blockName + " " + val + " &0" + counter)); - Material increaseMat = XMaterial.EMERALD_BLOCK.parseMaterial(); - ItemStack increaseStack = XMaterial.EMERALD_BLOCK.parseItem(); + XMaterial increaseMat = XMaterial.EMERALD_BLOCK; // Increase button - ItemStack increseOf1 = createButton(increaseStack, changeIncreaseValueLore, SpigotPrison.format("&3" + mineName + " " + blockName + " " + val + " + 1" + " &0" + counter )); - inv.setItem(7, increseOf1); - ItemStack increaseOf5 = createButton(new ItemStack(increaseMat, 5), changeIncreaseValueLore, SpigotPrison.format("&3" + mineName + " " + blockName + " " + val + " + 5" + " &0" + counter)); - inv.setItem(16, increaseOf5); - ItemStack increaseOf10 = createButton(new ItemStack(increaseMat, 10), changeIncreaseValueLore, SpigotPrison.format("&3" + mineName + " " + blockName + " " + val + " + 10" + " &0" + counter)); - inv.setItem(25, increaseOf10); - ItemStack increaseOf50 = createButton(new ItemStack(increaseMat, 50), changeIncreaseValueLore, SpigotPrison.format("&3" + mineName + " " + blockName + " " + val + " + 50" + " &0" + counter)); - inv.setItem(34, increaseOf50); - ItemStack increaseOf100 = createButton(increaseStack, changeIncreaseValueLore, SpigotPrison.format("&3" + mineName + " " + blockName + " " + val + " + 100" + " &0" + counter)); - inv.setItem(43, increaseOf100); - - // Return to prior screen: - List closeGUILore = createLore( messages.getString("Lore.ClickToClose") ); - ItemStack closeGUI = createButton(XMaterial.RED_STAINED_GLASS_PANE.parseItem(), closeGUILore, SpigotPrison.format("&c" + "Close" + " &0" + mineName + " " + counter)); - inv.setItem(40, closeGUI); + gui.addButton(new Button(7, increaseMat, changeIncreaseValueLore, "&3" + mineName + " " + blockName + " " + val + " + 1" + " &0" + counter)); + gui.addButton(new Button(16, increaseMat, 5, changeIncreaseValueLore, "&3" + mineName + " " + blockName + " " + val + " + 5" + " &0" + counter)); + gui.addButton(new Button(25, increaseMat, 10, changeIncreaseValueLore, "&3" + mineName + " " + blockName + " " + val + " + 10" + " &0" + counter)); + gui.addButton(new Button(34, increaseMat, 50, changeIncreaseValueLore, "&3" + mineName + " " + blockName + " " + val + " + 50" + " &0" + counter)); + gui.addButton(new Button(43, increaseMat, changeIncreaseValueLore, "&3" + mineName + " " + blockName + " " + val + " + 100" + " &0" + counter)); + // Close gui: + gui.addButton(new Button(40, XMaterial.RED_STAINED_GLASS_PANE, new ButtonLore(messages.getString("Lore.ClickToClose"), null), "&c" + "Close" + " &0" + mineName + " " + counter)); // Show the selected block at the top center position: - XMaterial xMat = SpigotUtil.getXMaterial( blockName ); - if ( PrisonBlock.IGNORE.getBlockName().equalsIgnoreCase( blockName )) { - xMat = XMaterial.BARRIER; - } - if ( xMat == null ) { - xMat = XMaterial.STONE; - } - inv.setItem(4, xMat.parseItem()); - + XMaterial xMat = SpigotUtil.getXMaterial( blockName ); + if ( PrisonBlock.IGNORE.getBlockName().equalsIgnoreCase( blockName )) { + xMat = XMaterial.BARRIER; + } + if ( xMat == null ) { + xMat = XMaterial.STONE; + } + gui.addButton(new Button(4, xMat, 1, "&3" + xMat)); + + gui.open(); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMineInfoGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMineInfoGUI.java index 9a5e67179..3b8397aa2 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMineInfoGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMineInfoGUI.java @@ -3,17 +3,14 @@ import java.util.List; import com.cryptomorin.xseries.XMaterial; -import org.bukkit.Bukkit; -import org.bukkit.Material; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; import tech.mcprison.prison.mines.data.Mine; -import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.SpigotUtil; -import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; /** @@ -24,6 +21,7 @@ public class SpigotMineInfoGUI extends SpigotGUIComponents { private final Player p; private final Mine mine; private final String mineName; + int dimension = 45; public SpigotMineInfoGUI(Player p, Mine mine, String mineName){ this.p = p; @@ -33,97 +31,37 @@ public SpigotMineInfoGUI(Player p, Mine mine, String mineName){ public void open(){ - int dimension = 45; - Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format("&3Mines -> MineInfo")); + PrisonGUI gui = new PrisonGUI(p, dimension, SpigotPrison.format("&3Mines -> MineInfo")); - if (guiBuilder(inv)) return; - - // Opens the inventory - openGUI(p, inv); - } - - private boolean guiBuilder(Inventory inv) { - try { - buttonsSetup(inv); - } catch (NullPointerException ex){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cThere's a null value in the GuiConfig.yml [broken]")); - ex.printStackTrace(); - return true; - } - return false; - } - - private void buttonsSetup(Inventory inv) { - - - // The Reset Mine button and lore - List resetMineLore = createLore( + ButtonLore resetMineLore = new ButtonLore(createLore( messages.getString("Lore.LeftClickToReset"), - "", messages.getString("Lore.RightClickToToggle"), - messages.getString("Lore.SkipReset1"), - messages.getString("Lore.SkipReset2"), - messages.getString("Lore.SkipReset3"), - "", - messages.getString("Lore.ShiftAndRightClickToToggle"), - messages.getString("Lore.ZeroBlocksReset1"), - messages.getString("Lore.ZeroBlocksReset2"), - messages.getString("Lore.ZeroBlocksReset3") - ); - List MineSpawnLore = createLore( - messages.getString("Lore.ClickToUse"), - messages.getString("Lore.SpawnPoint2") - ); - List MinesNotificationsLore = createLore( - messages.getString("Lore.ClickToOpen"), - messages.getString("Lore.Notifications") - ); - List MinesTpLore = createLore( - messages.getString("Lore.ClickToTeleport"), - messages.getString("Lore.Tp") - ); - List blocksOfTheMineLore = createLore( - messages.getString("Lore.ClickToOpen"), - messages.getString("Lore.Blocks2")); - List mineResetTimeLore = createLore( - messages.getString("Lore.ClickToOpen"), - messages.getString("Lore.ManageResetTime"), - messages.getString("Lore.ResetTime") + mine.getResetTime()); - List mineRenameLore = createLore( - messages.getString("Lore.ClickToRename"), - messages.getString("Lore.MineName") + mineName - ); - - List closeGUILore = createLore( - messages.getString("Lore.ClickToClose") - ); + messages.getString("Lore.ShiftAndRightClickToToggle")), + createLore(messages.getString("Lore.SkipReset1"), + messages.getString("Lore.SkipReset2"), + messages.getString("Lore.SkipReset3"), + messages.getString("Lore.ZeroBlocksReset1"), + messages.getString("Lore.ZeroBlocksReset2"), + messages.getString("Lore.ZeroBlocksReset3"))); + + ButtonLore mineSpawnLore = new ButtonLore(messages.getString("Lore.ClickToUse"), messages.getString("Lore.SpawnPoint2")); + ButtonLore minesNotificationsLore = new ButtonLore(messages.getString("Lore.ClickToOpen"), messages.getString("Lore.Notifications")); + ButtonLore minesTpLore = new ButtonLore(messages.getString("Lore.ClickToTeleport"), messages.getString("Lore.Tp")); + ButtonLore blocksOfTheMineLore = new ButtonLore(messages.getString("Lore.ClickToOpen"), messages.getString("Lore.Blocks2")); + ButtonLore mineResetTimeLore = new ButtonLore(createLore(messages.getString("Lore.ClickToOpen")), createLore(messages.getString("Lore.ManageResetTime"), + messages.getString("Lore.ResetTime") + mine.getResetTime())); + ButtonLore mineRenameLore = new ButtonLore(messages.getString("Lore.ClickToRename"), messages.getString("Lore.MineName") + mineName); + ButtonLore closeGUILore = new ButtonLore(messages.getString("Lore.ClickToClose"), null); // Create the button, set the material, amount, lore and name - ItemStack closeGUI = createButton(XMaterial.RED_STAINED_GLASS_PANE.parseItem(), closeGUILore, SpigotPrison.format("&c" + "Close")); - ItemStack resetMine = createButton(XMaterial.EMERALD_BLOCK.parseItem(), resetMineLore, SpigotPrison.format("&3" + "Reset_Mine: " + mineName)); - ItemStack MineSpawn = createButton(XMaterial.COMPASS.parseItem(), MineSpawnLore, SpigotPrison.format("&3" + "Mine_Spawn: " + mineName)); - ItemStack MinesNotifications = createButton(new ItemStack(Material.SIGN, 1), MinesNotificationsLore, SpigotPrison.format("&3" + "Mine_notifications: " + mineName)); - - // Create the button - Material bed = Material.matchMaterial( "bed" ); - if ( bed == null ) { - bed = Material.matchMaterial( "Red_Bed" ); - } - ItemStack MinesTP = createButton(bed, 1, MinesTpLore, SpigotPrison.format("&3" + "TP_to_the_Mine: " + mineName)); - - // Create the button, set up the material, amount, lore and name - ItemStack blocksOfTheMine = createButton(XMaterial.COAL_ORE.parseItem(), blocksOfTheMineLore, SpigotPrison.format("&3" + "Blocks_of_the_Mine: " + mineName)); - - // Create the button, set up the material, amount, lore and name - Material watch = Material.matchMaterial( "watch" ); - if ( watch == null ) { - watch = Material.matchMaterial( "legacy_watch" ); - } if ( watch == null ) { - watch = Material.matchMaterial( "clock" ); - } - ItemStack mineResetTime = createButton(watch, 1, mineResetTimeLore, SpigotPrison.format("&3" + "Reset_Time: " + mineName)); - - ItemStack mineRename = createButton(XMaterial.FEATHER.parseItem(), mineRenameLore, SpigotPrison.format("&3" + "Mine_Name: " + mineName)); + gui.addButton(new Button(dimension-1, XMaterial.RED_STAINED_GLASS_PANE, closeGUILore, SpigotPrison.format("&c" + "Close"))); + gui.addButton(new Button(10, XMaterial.EMERALD_BLOCK, resetMineLore, SpigotPrison.format("&3" + "Reset_Mine: " + mineName))); + gui.addButton(new Button(12, XMaterial.COMPASS, mineSpawnLore, SpigotPrison.format("&3" + "Mine_Spawn: " + mineName))); + gui.addButton(new Button(14, XMaterial.OAK_SIGN, minesNotificationsLore, SpigotPrison.format("&3" + "Mine_notifications: " + mineName))); + gui.addButton(new Button(16, XMaterial.ARROW, minesTpLore, SpigotPrison.format("&3" + "TP_to_the_Mine: " + mineName))); + gui.addButton(new Button(28, XMaterial.COAL_ORE, blocksOfTheMineLore, SpigotPrison.format("&3" + "Blocks_of_the_Mine: " + mineName))); + gui.addButton(new Button(30, XMaterial.CLOCK, 1, mineResetTimeLore, SpigotPrison.format("&3" + "Reset_Time: " + mineName))); + gui.addButton(new Button(32 ,XMaterial.FEATHER, mineRenameLore, SpigotPrison.format("&3" + "Mine_Name: " + mineName))); // Mine show Item of Player's GUI aka /gui mines. XMaterial xMaterial = XMaterial.COAL_ORE; @@ -136,27 +74,17 @@ private void buttonsSetup(Inventory inv) { } // Lore - List mineShowItemLore = createLore( - messages.getString("Lore.ClickToEdit"), + ButtonLore mineShowItemLore = new ButtonLore(createLore(messages.getString("Lore.ClickToEdit")), createLore( messages.getString("Lore.ShowItem") + xMaterial.name(), - "", messages.getString("Lore.ShowItemDescription"), messages.getString("Lore.ShowItemDescription2"), messages.getString("Lore.ShowItemDescription3") - ); + )); // ItemStack - ItemStack mineShowItem = createButton(xMaterial.parseItem(), mineShowItemLore, SpigotPrison.format("&3Mine_Show_Item: ") + mineName); + gui.addButton(new Button(34, xMaterial, mineShowItemLore, SpigotPrison.format("&3Mine_Show_Item: ") + mineName)); - // Position of the button - inv.setItem(10, resetMine); - inv.setItem(12, MineSpawn); - inv.setItem(14, MinesNotifications); - inv.setItem(16, MinesTP); - inv.setItem(28, blocksOfTheMine); - inv.setItem(30, mineResetTime); - inv.setItem(32, mineRename); - inv.setItem(34, mineShowItem); - inv.setItem(44, closeGUI); + // Opens the inventory + gui.open(); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMineNotificationRadiusGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMineNotificationRadiusGUI.java index 27b5fe8e0..103939aa2 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMineNotificationRadiusGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMineNotificationRadiusGUI.java @@ -1,20 +1,14 @@ package tech.mcprison.prison.spigot.gui.mine; import com.cryptomorin.xseries.XMaterial; -import org.bukkit.Bukkit; -import org.bukkit.Material; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import tech.mcprison.prison.output.Output; -import tech.mcprison.prison.spigot.SpigotPrison; -import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; -import java.util.List; - /** - * @author GABRYCA + * @author GABRYCA (AnonymousGCA) */ public class SpigotMineNotificationRadiusGUI extends SpigotGUIComponents { @@ -32,82 +26,39 @@ public SpigotMineNotificationRadiusGUI(Player p, Long val, String typeNotificati public void open() { - // Create a new inventory + // Create GUI. int dimension = 45; - Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format("&3MineNotifications -> Radius")); - - if (guiBuilder(inv)) return; - - // Open the inventory - openGUI(p, inv); - } - - private boolean guiBuilder(Inventory inv) { - try { - buttonsSetup(inv); - } catch (NullPointerException ex){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cThere's a null value in the GuiConfig.yml [broken]")); - ex.printStackTrace(); - return true; - } - return false; - } - - private void buttonsSetup(Inventory inv) { + PrisonGUI gui = new PrisonGUI(p, dimension, "&3MineNotifications -> Radius"); - - // Create new lore - List changeDecreaseValueLore = createLore( - messages.getString("Lore.ClickToDecrease") - ); - List confirmButtonLore = createLore( - messages.getString("Lore.LeftClickToConfirm"), + ButtonLore changeDecreaseValueLore = new ButtonLore(messages.getString("Lore.ClickToDecrease"), null); + ButtonLore confirmButtonLore = new ButtonLore(createLore(messages.getString("Lore.LeftClickToConfirm")), createLore( messages.getString("Lore.Radius") + val, - messages.getString("Lore.RightClickToCancel") - ); - List changeIncreaseValueLore = createLore( - messages.getString("Lore.ClickToIncrease") - ); - - Material decreaseMat = XMaterial.REDSTONE_BLOCK.parseMaterial(); - ItemStack decreaseStack = XMaterial.REDSTONE_BLOCK.parseItem(); - - // Decrease buttons - ItemStack decreaseOf1 = createButton(decreaseStack, changeDecreaseValueLore, SpigotPrison.format("&3" + mineName + " " + val + " - 1 " + typeNotification )); - inv.setItem(1, decreaseOf1); - ItemStack decreaseOf5 = createButton(new ItemStack(decreaseMat, 5), changeDecreaseValueLore, SpigotPrison.format("&3" + mineName + " " + val + " - 5 " + typeNotification)); - inv.setItem(10, decreaseOf5); - ItemStack decreaseOf10 = createButton(new ItemStack(decreaseMat, 10), changeDecreaseValueLore, SpigotPrison.format("&3" + mineName + " " + val + " - 10 " + typeNotification)); - inv.setItem(19, decreaseOf10); - ItemStack decreaseOf50 = createButton(new ItemStack(decreaseMat, 50), changeDecreaseValueLore, SpigotPrison.format("&3" + mineName + " " + val + " - 50 " + typeNotification)); - inv.setItem(28, decreaseOf50); - ItemStack decreaseOf100 = createButton(decreaseStack, changeDecreaseValueLore, SpigotPrison.format("&3" + mineName + " " + val + " - 100 " + typeNotification)); - inv.setItem(37, decreaseOf100); - - - // Create a button and set the position of it - Material watch = Material.matchMaterial( "watch" ); - if ( watch == null ) { - watch = Material.matchMaterial( "legacy_watch" ); - } if ( watch == null ) { - watch = Material.matchMaterial( "clock" ); - } - ItemStack confirmButton = createButton(watch, 1, confirmButtonLore, SpigotPrison.format("&3" + "Confirm: " + mineName + " " + val + " " + typeNotification)); - inv.setItem(22, confirmButton); - - Material increaseMat = XMaterial.EMERALD_BLOCK.parseMaterial(); - ItemStack increaseStack = XMaterial.EMERALD_BLOCK.parseItem(); - - // Increase buttons - ItemStack increaseOf1 = createButton(increaseStack, changeIncreaseValueLore, SpigotPrison.format("&3" + mineName + " " + val + " + 1 " + typeNotification)); - inv.setItem(7, increaseOf1); - ItemStack increaseOf5 = createButton(new ItemStack(increaseMat, 5), changeIncreaseValueLore, SpigotPrison.format("&3" + mineName + " " + val + " + 5 " + typeNotification)); - inv.setItem(16, increaseOf5); - ItemStack increaseOf10 = createButton(new ItemStack(increaseMat, 10), changeIncreaseValueLore, SpigotPrison.format("&3" + mineName + " " + val + " + 10 " + typeNotification)); - inv.setItem(25, increaseOf10); - ItemStack increaseOf50 = createButton(new ItemStack(increaseMat, 50), changeIncreaseValueLore, SpigotPrison.format("&3" + mineName + " " + val + " + 50 " + typeNotification)); - inv.setItem(34, increaseOf50); - ItemStack increaseOf100 = createButton(increaseStack, changeIncreaseValueLore, SpigotPrison.format("&3" + mineName + " " + val + " + 100 " + typeNotification)); - inv.setItem(43, increaseOf100); + messages.getString("Lore.RightClickToCancel"))); + ButtonLore changeIncreaseValueLore = new ButtonLore(messages.getString("Lore.ClickToIncrease"), null); + + // XMaterials. + XMaterial decreaseMat = XMaterial.REDSTONE_BLOCK; + XMaterial increaseMat = XMaterial.EMERALD_BLOCK; + XMaterial watch = XMaterial.CLOCK; + + // Decrease buttons. + gui.addButton(new Button(1, decreaseMat, changeDecreaseValueLore, "&3" + mineName + " " + val + " - 1 " + typeNotification)); + gui.addButton(new Button(10, decreaseMat, 5, changeDecreaseValueLore, "&3" + mineName + " " + val + " - 5 " + typeNotification)); + gui.addButton(new Button(19, decreaseMat, 10, changeDecreaseValueLore, "&3" + mineName + " " + val + " - 10 " + typeNotification)); + gui.addButton(new Button(28, decreaseMat, 50, changeDecreaseValueLore, "&3" + mineName + " " + val + " - 50 " + typeNotification)); + gui.addButton(new Button(37, decreaseMat, changeDecreaseValueLore, "&3" + mineName + " " + val + " - 100 " + typeNotification)); + + // Confirm button. + gui.addButton(new Button(22, watch, confirmButtonLore, "&3" + "Confirm: " + mineName + " " + val + " " + typeNotification)); + + // Increase buttons. + gui.addButton(new Button(7, increaseMat, changeIncreaseValueLore, "&3" + mineName + " " + val + " + 1 " + typeNotification)); + gui.addButton(new Button(16, increaseMat, 5, changeIncreaseValueLore, "&3" + mineName + " " + val + " + 5 " + typeNotification)); + gui.addButton(new Button(25, increaseMat, 10, changeIncreaseValueLore, "&3" + mineName + " " + val + " + 10 " + typeNotification)); + gui.addButton(new Button(34, increaseMat, 50, changeIncreaseValueLore, "&3" + mineName + " " + val + " + 50 " + typeNotification)); + gui.addButton(new Button(43, increaseMat, 100, changeIncreaseValueLore, "&3" + mineName + " " + val + " + 100 " + typeNotification)); + + // Open GUI. + gui.open(); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMineNotificationsGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMineNotificationsGUI.java index 2f653fc22..fc8059fa9 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMineNotificationsGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMineNotificationsGUI.java @@ -1,21 +1,16 @@ package tech.mcprison.prison.spigot.gui.mine; import com.cryptomorin.xseries.XMaterial; -import org.bukkit.Bukkit; -import org.bukkit.Material; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; import tech.mcprison.prison.mines.PrisonMines; import tech.mcprison.prison.mines.data.Mine; -import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotPrison; -import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; -import java.util.List; - /** * @author GABRYCA */ @@ -31,111 +26,76 @@ public SpigotMineNotificationsGUI(Player p, String mineName){ public void open() { - // Create a new inventory + // Create GUI. int dimension = 27; - Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format("&3MineInfo -> MineNotifications")); + PrisonGUI gui = new PrisonGUI(p, dimension, "&3MineInfo -> MineNotifications"); // Init variables PrisonMines pMines = PrisonMines.getInstance(); Mine m = pMines.getMine(mineName); String enabledOrDisabled = m.getNotificationMode().name(); - if (guiBuilder(inv, enabledOrDisabled)) return; - - // Opens the inventory - openGUI(p, inv); - } - - private boolean guiBuilder(Inventory inv, String enabledOrDisabled) { - try { - buttonsSetup(inv, enabledOrDisabled); - } catch (NullPointerException ex){ - Output.get().sendWarn(new SpigotPlayer(p),SpigotPrison.format("&cThere's a null value in the GuiConfig.yml [broken]")); - ex.printStackTrace(); - return true; - } - return false; - } - - private void buttonsSetup(Inventory inv, String enabledOrDisabled) { - - - // Create a new lore - List modeWithinLore = createLore( - messages.getString("Lore.ClickToChoose"), - messages.getString("Lore.ActivateWithinMode")); - List modeRadiusLore = createLore( - messages.getString("Lore.ClickToChoose"), - messages.getString("Lore.ActivateRadiusMode")); - List disabledModeLore = createLore( - messages.getString("Lore.ClickToChoose"), - messages.getString("Lore.DisableNotifications")); - List closeGUILore = createLore( - messages.getString("Lore.ClickToClose") - ); + ButtonLore modeWithinLore = new ButtonLore(messages.getString("Lore.ClickToChoose"), messages.getString("Lore.ActivateWithinMode")); + ButtonLore modeRadiusLore = new ButtonLore(messages.getString("Lore.ClickToChoose"), messages.getString("Lore.ActivateRadiusMode")); + ButtonLore disabledModeLore = new ButtonLore(messages.getString("Lore.ClickToChoose"), messages.getString("Lore.DisableNotifications")); + ButtonLore closeGUILore = new ButtonLore(messages.getString("Lore.ClickToClose"), null); - ItemStack closeGUI = createButton(XMaterial.RED_STAINED_GLASS_PANE.parseItem(), closeGUILore, SpigotPrison.format("&c" + "Close")); - inv.setItem(26, closeGUI); + // Add button. + gui.addButton(new Button(26, XMaterial.RED_STAINED_GLASS_PANE, closeGUILore, "&c" + "Close")); // Add the selected lore to the mode used if (enabledOrDisabled.equalsIgnoreCase("disabled")){ // Add the selected lore - disabledModeLore.add(SpigotPrison.format(messages.getString("Lore.Selected"))); + disabledModeLore.addLineLoreDescription(SpigotPrison.format(messages.getString("Lore.Selected"))); } else if (enabledOrDisabled.equalsIgnoreCase("within")){ // Add the selected lore - modeWithinLore.add(SpigotPrison.format(messages.getString("Lore.Selected"))); + modeWithinLore.addLineLoreDescription(SpigotPrison.format(messages.getString("Lore.Selected"))); } else if (enabledOrDisabled.equalsIgnoreCase("radius")){ // Add the selected lore - modeRadiusLore.add(SpigotPrison.format(messages.getString("Lore.Selected"))); + modeRadiusLore.addLineLoreDescription(SpigotPrison.format(messages.getString("Lore.Selected"))); } // Create a button - ItemStack modeWithin = createButton(XMaterial.IRON_DOOR.parseItem(), modeWithinLore, SpigotPrison.format("&3Within_Mode: " + mineName)); - - // Create a button - Material fence = Material.matchMaterial( "fence" ); - if ( fence == null ) { - fence = Material.matchMaterial( "oak_fence" ); - } - ItemStack radiusMode = createButton(fence, 1, modeRadiusLore, SpigotPrison.format("&3Radius_Mode: " + mineName)); - - // Create a button - ItemStack disabledMode = createButton(XMaterial.REDSTONE_BLOCK.parseItem(), disabledModeLore, SpigotPrison.format("&3Disabled_Mode: " + mineName)); + Button modeWithin = new Button(11, XMaterial.IRON_DOOR, modeWithinLore, "&3Within_Mode: " + mineName); + Button radiusMode = new Button(13, XMaterial.OAK_FENCE, modeRadiusLore, "&3Radius_Mode: " + mineName); + Button disabledMode = new Button(15, XMaterial.REDSTONE_BLOCK, disabledModeLore, "&3Disabled_Mode: " + mineName); // Check which buttons should be added, based on the mode already in use of the Mine Notifications if (enabledOrDisabled.equalsIgnoreCase("disabled")){ // Add a button to the inventory - inv.setItem( 11, modeWithin); - inv.setItem(13, radiusMode); + gui.addButton(modeWithin); + gui.addButton(radiusMode); // Add an enchantment effect to the button disabledMode.addUnsafeEnchantment(Enchantment.LUCK, 1); - inv.setItem(15, disabledMode); + gui.addButton(disabledMode); - // Check which buttons should be added, based on the mode already in use of the Mine Notifications + // Check which buttons should be added, based on the mode already in use of the Mine Notifications } else if (enabledOrDisabled.equalsIgnoreCase("within")){ // Add a button to the inventory modeWithin.addUnsafeEnchantment(Enchantment.LUCK, 1); - inv.setItem(11, modeWithin); - inv.setItem(13, radiusMode); - inv.setItem(15, disabledMode); + gui.addButton(modeWithin); + gui.addButton(radiusMode); + gui.addButton(disabledMode); - // Check which buttons should be added, based on the mode already in use of the Mine Notifications + // Check which buttons should be added, based on the mode already in use of the Mine Notifications } else if (enabledOrDisabled.equalsIgnoreCase("radius")){ // Add a button to the inventory - inv.setItem( 11, modeWithin); + gui.addButton(modeWithin); radiusMode.addUnsafeEnchantment(Enchantment.LUCK, 1); - inv.setItem( 13, radiusMode); - inv.setItem(15, disabledMode); - + gui.addButton(radiusMode); + gui.addButton(disabledMode); } + + // Open GUI. + gui.open(); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMineResetTimeGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMineResetTimeGUI.java index ed362490d..f37fffcc1 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMineResetTimeGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMineResetTimeGUI.java @@ -1,18 +1,12 @@ package tech.mcprison.prison.spigot.gui.mine; import com.cryptomorin.xseries.XMaterial; -import org.bukkit.Bukkit; -import org.bukkit.Material; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import tech.mcprison.prison.output.Output; -import tech.mcprison.prison.spigot.SpigotPrison; -import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; -import java.util.List; - /** * @author GABRYCA */ @@ -30,81 +24,38 @@ public SpigotMineResetTimeGUI(Player p, Integer val, String mineName){ public void open() { - // Create a new inventory + // Create GUI. int dimension = 45; - Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format("&3MineInfo -> ResetTime")); - - if (guiBuilder(inv)) return; - - // Open the inventory - openGUI(p, inv); - } + PrisonGUI gui = new PrisonGUI(p, dimension, "&3MineInfo -> ResetTime"); - private boolean guiBuilder(Inventory inv) { - try { - buttonsSetup(inv); - } catch (NullPointerException ex){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cThere's a null value in the GuiConfig.yml [broken]")); - ex.printStackTrace(); - return true; - } - return false; - } - - private void buttonsSetup(Inventory inv) { + ButtonLore changeDecreaseValueLore = new ButtonLore(messages.getString("Lore.ClickToDecrease"), null); + ButtonLore confirmButtonLore = new ButtonLore(createLore(messages.getString("Lore.LeftClickToConfirm"), messages.getString("Lore.RightClickToCancel")), createLore(messages.getString("Lore.Time") + val)); + ButtonLore changeIncreaseValueLore = new ButtonLore(messages.getString("Lore.ClickToIncrease"), null); - // Create a new lore - List changeDecreaseValueLore = createLore( - messages.getString("Lore.ClickToDecrease") - ); - List confirmButtonLore = createLore( - messages.getString("Lore.LeftClickToConfirm"), - messages.getString("Lore.Time") + val, - messages.getString("Lore.RightClickToCancel") - ); - List changeIncreaseValueLore = createLore( - messages.getString("Lore.ClickToIncrease") - ); - - Material decreaseMat = XMaterial.REDSTONE_BLOCK.parseMaterial(); - ItemStack decreaseStack = XMaterial.REDSTONE_BLOCK.parseItem(); + // XMaterials. + XMaterial decreaseMat = XMaterial.REDSTONE_BLOCK; + XMaterial increaseMat = XMaterial.REDSTONE_BLOCK; + XMaterial watch = XMaterial.CLOCK; // Decrease button - ItemStack decreaseOf1 = createButton(decreaseStack, changeDecreaseValueLore, SpigotPrison.format("&3" + mineName + " " + val + " - 1" )); - inv.setItem(1, decreaseOf1); - ItemStack decreaseOf5 = createButton(new ItemStack(decreaseMat, 5), changeDecreaseValueLore, SpigotPrison.format("&3" + mineName + " " + val + " - 5")); - inv.setItem(10, decreaseOf5); - ItemStack decreaseOf10 = createButton(new ItemStack(decreaseMat, 10), changeDecreaseValueLore, SpigotPrison.format("&3" + mineName + " " + val + " - 10")); - inv.setItem(19, decreaseOf10); - ItemStack decreaseOf50 = createButton(new ItemStack(decreaseMat, 50), changeDecreaseValueLore, SpigotPrison.format("&3" + mineName + " " + val + " - 50")); - inv.setItem(28, decreaseOf50); - ItemStack decreaseOf100 = createButton(decreaseStack, changeDecreaseValueLore, SpigotPrison.format("&3" + mineName + " " + val + " - 100")); - inv.setItem(37, decreaseOf100); + gui.addButton(new Button(1, decreaseMat, changeDecreaseValueLore, "&3" + mineName + " " + val + " - 1")); + gui.addButton(new Button(10, decreaseMat, 5, changeDecreaseValueLore, "&3" + mineName + " " + val + " - 5")); + gui.addButton(new Button(19, decreaseMat, 10, changeDecreaseValueLore, "&3" + mineName + " " + val + " - 10")); + gui.addButton(new Button(28, decreaseMat, 50, changeDecreaseValueLore, "&3" + mineName + " " + val + " - 50")); + gui.addButton(new Button(37, decreaseMat, changeDecreaseValueLore, "&3" + mineName + " " + val + " - 100")); // Create a button and set the position - Material watch = Material.matchMaterial( "watch" ); - if ( watch == null ) { - watch = Material.matchMaterial( "legacy_watch" ); - } if ( watch == null ) { - watch = Material.matchMaterial( "clock" ); - } - ItemStack confirmButton = createButton(watch, 1, confirmButtonLore, SpigotPrison.format("&3" + "Confirm: " + mineName + " " + val)); - inv.setItem(22, confirmButton); - - Material increaseMat = XMaterial.REDSTONE_BLOCK.parseMaterial(); - ItemStack increaseStack = XMaterial.REDSTONE_BLOCK.parseItem(); + gui.addButton(new Button(22, watch, confirmButtonLore, "&3" + "Confirm: " + mineName + " " + val)); // Increase button - ItemStack increaseOf1 = createButton(increaseStack, changeIncreaseValueLore, SpigotPrison.format("&3" + mineName + " " + val + " + 1" )); - inv.setItem(7, increaseOf1); - ItemStack increaseOf5 = createButton(new ItemStack(increaseMat, 5), changeIncreaseValueLore, SpigotPrison.format("&3" + mineName + " " + val + " + 5")); - inv.setItem(16, increaseOf5); - ItemStack increaseOf10 = createButton(new ItemStack(increaseMat, 10), changeIncreaseValueLore, SpigotPrison.format("&3" + mineName + " " + val + " + 10")); - inv.setItem(25, increaseOf10); - ItemStack increaseOf50 = createButton(new ItemStack(increaseMat, 50), changeIncreaseValueLore, SpigotPrison.format("&3" + mineName + " " + val + " + 50")); - inv.setItem(34, increaseOf50); - ItemStack increaseOf100 = createButton(increaseStack, changeIncreaseValueLore, SpigotPrison.format("&3" + mineName + " " + val + " + 100")); - inv.setItem(43, increaseOf100); + gui.addButton(new Button(7, increaseMat, changeIncreaseValueLore, "&3" + mineName + " " + val + " + 1")); + gui.addButton(new Button(16, increaseMat, 5, changeIncreaseValueLore, "&3" + mineName + " " + val + " + 5")); + gui.addButton(new Button(25, increaseMat, 10, changeIncreaseValueLore, "&3" + mineName + " " + val + " + 10")); + gui.addButton(new Button(34, increaseMat, 50, changeIncreaseValueLore, "&3" + mineName + " " + val + " + 50")); + gui.addButton(new Button(43, increaseMat, changeIncreaseValueLore, "&3" + mineName + " " + val + " + 100")); + + // Open GUI. + gui.open(); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMinesBlocksGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMinesBlocksGUI.java index 640e7016b..ea300cd77 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMinesBlocksGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMinesBlocksGUI.java @@ -3,20 +3,17 @@ import java.util.List; import com.cryptomorin.xseries.XMaterial; -import org.bukkit.Bukkit; -import org.bukkit.Material; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; import tech.mcprison.prison.Prison; import tech.mcprison.prison.internal.block.PrisonBlock; import tech.mcprison.prison.mines.PrisonMines; -import tech.mcprison.prison.mines.data.BlockOld; import tech.mcprison.prison.mines.data.Mine; -import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotPrison; -import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.SpigotUtil; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; /** @@ -42,27 +39,20 @@ public SpigotMinesBlocksGUI(Player p, String mineName){ public void open(){ + int dimension = 54; + PrisonGUI gui = new PrisonGUI(p, dimension, "&3MineInfo -> Blocks"); + // Get Mine Mine m = PrisonMines.getInstance().getMine(mineName); - - // Get the dimensions and if needed increases them - int dimension = 54; - boolean useNewBlockModel = Prison.get().getPlatform().isUseNewPrisonBlockModel(); - // Create the inventory - Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format("&3MineInfo -> Blocks")); - - List addBlockLore = createLore( - messages.getString("Lore.ClickToAddBlock") - ); + ButtonLore addBlockLore = new ButtonLore(messages.getString("Lore.ClickToAddBlock"), null); - // Add the button to the inventory - ItemStack addBlockButton = createButton(XMaterial.LIME_STAINED_GLASS_PANE.parseItem(), addBlockLore, SpigotPrison.format("&a" + "Add" + " " + mineName)); - inv.setItem(dimension - 1, addBlockButton); + // Add the button to the GUI. + gui.addButton(new Button(dimension - 1, XMaterial.LIME_STAINED_GLASS_PANE, addBlockLore, "&a" + "Add" + " " + mineName)); if (useNewBlockModel) { - + // For every block makes a button for (PrisonBlock block : m.getPrisonBlocks()) { @@ -75,114 +65,69 @@ public void open(){ blockmaterial = "BARRIER"; blockmaterialdisplay = blockmaterial; } - - if (guiBuilder(inv, block, blockmaterial, blockmaterialdisplay)) return; + + // Get XMaterial. + XMaterial xMat = SpigotUtil.getXMaterial(blockmaterial); + if (PrisonBlock.IGNORE.getBlockName().equalsIgnoreCase(blockmaterial)) { + xMat = XMaterial.BARRIER; + } + if (xMat == null ) { + xMat = XMaterial.STONE; + } + + ButtonLore blocksLore = new ButtonLore(createLore(loreClickToEditBlock, loreShiftRightClickToDelete), createLore(loreInfo)); + + // Add a lore + blocksLore.addLineLoreDescription(SpigotPrison.format(loreChance + block.getChance() + "%")); + blocksLore.addLineLoreDescription(SpigotPrison.format(loreBlockType + blockmaterial)); + + // Add the button to the GUI. + gui.addButton(new Button(null, xMat, blocksLore, "&3" + blockmaterialdisplay + " " + mineName + " " + block.getChance())); } - } else { - + } /*else { + // For every block makes a button for (BlockOld block : m.getBlocks()) { - + // Get the block material as a string and displayname String blockmaterial = block.getType().name(); String blockmaterialdisplay = blockmaterial; - + // Check if a block's air and changed the item of it to BARRIER if (blockmaterial.equalsIgnoreCase("air")){ blockmaterial = "BARRIER"; blockmaterialdisplay = blockmaterial; } - - if (guiBuilder(inv, block, blockmaterial, blockmaterialdisplay)) return; + + // Create the lore + List blockslore = createLore( + loreShiftRightClickToDelete, + loreClickToEditBlock, + "", + loreInfo + ); + + boolean isEnum = true; + try { + Material.valueOf(blockmaterial); + } catch (Exception e) { + isEnum = false; + } + + if (!(isEnum)) { + blockmaterial = "BARRIER"; + } + + // Add a lore + blockslore.add(SpigotPrison.format(loreChance + block.getChance() + "%")); + blockslore.add(SpigotPrison.format(loreBlockType + blockmaterial)); + + // Add the button to the GUI. + gui.addButton(new Button(null, XMaterial.valueOf(blockmaterial), blockslore, "&3" + blockmaterialdisplay + " " + mineName + " " + block.getChance())); } - } + }*/ // Open the inventory - openGUI(p, inv); - } - - private boolean guiBuilder(Inventory inv, PrisonBlock block, String blockmaterial, String blockmaterialdisplay) { - try { - buttonsSetup(inv, block, blockmaterial, blockmaterialdisplay); - } catch (NullPointerException ex){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cThere's a null value in the GuiConfig.yml [broken]")); - ex.printStackTrace(); - return true; - } - return false; - } - - private boolean guiBuilder(Inventory inv, BlockOld block, String blockmaterial, String blockmaterialdisplay) { - try { - buttonsSetup(inv, block, blockmaterial, blockmaterialdisplay); - } catch (NullPointerException ex){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cThere's a null value in the GuiConfig.yml [broken]")); - ex.printStackTrace(); - return true; - } - return false; - } - - private void buttonsSetup(Inventory inv, PrisonBlock block, String blockmaterial, String blockmaterialdisplay) { - - // Create the lore - List blockslore = createLore( - loreShiftRightClickToDelete, - loreClickToEditBlock, - "", - loreInfo - ); - - - boolean isEnum = true; - try { - Material.valueOf(blockmaterial); - } catch (Exception e) { - isEnum = false; - } - - if (!(isEnum)) { - blockmaterial = "BARRIER"; - } - - // Add a lore - blockslore.add(SpigotPrison.format(loreChance + block.getChance() + "%")); - blockslore.add(SpigotPrison.format(loreBlockType + blockmaterial)); - - // Make the item - ItemStack block1 = createButton(XMaterial.valueOf(blockmaterial).parseItem(), blockslore, SpigotPrison.format("&3" + blockmaterialdisplay + " " + mineName + " " + block.getChance())); - inv.addItem(block1); - } - - private void buttonsSetup(Inventory inv, BlockOld block, String blockmaterial, String blockmaterialdisplay) { - - // Create the lore - List blockslore = createLore( - loreShiftRightClickToDelete, - loreClickToEditBlock, - "", - loreInfo - ); - - boolean isEnum = true; - try { - Material.valueOf(blockmaterial); - } catch (Exception e) { - isEnum = false; - } - - if (!(isEnum)) { - blockmaterial = "BARRIER"; - } - - // Add a lore - blockslore.add(SpigotPrison.format(loreChance + block.getChance() + "%")); - blockslore.add(SpigotPrison.format(loreBlockType + blockmaterial)); - - // Make the item - ItemStack block1 = createButton(XMaterial.valueOf(blockmaterial).parseItem(), blockslore, SpigotPrison.format("&3" + blockmaterialdisplay + " " + mineName + " " + block.getChance())); - - // Add the item to the inventory - inv.addItem(block1); + gui.open(); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMinesConfirmGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMinesConfirmGUI.java index ff4cada54..cf08ec495 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMinesConfirmGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMinesConfirmGUI.java @@ -1,17 +1,12 @@ package tech.mcprison.prison.spigot.gui.mine; import com.cryptomorin.xseries.XMaterial; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import tech.mcprison.prison.output.Output; -import tech.mcprison.prison.spigot.SpigotPrison; -import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; -import java.util.List; - /** * @author GABRYCA */ @@ -27,41 +22,19 @@ public SpigotMinesConfirmGUI(Player p, String mineName) { public void open(){ - // Create the inventory + // Create GUI. int dimension = 9; - Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format("&3Mines -> Delete")); - - if (guiBuilder(inv)) return; - - // Open the inventory - openGUI(p, inv); - } + PrisonGUI gui = new PrisonGUI(p, dimension, "&3Mines -> Delete"); - private boolean guiBuilder(Inventory inv) { - try { - buttonsSetup(inv); - } catch (NullPointerException ex){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cThere's a null value in the GuiConfig.yml [broken]")); - ex.printStackTrace(); - return true; - } - return false; - } - - private void buttonsSetup(Inventory inv) { + ButtonLore confirmLore = new ButtonLore(messages.getString("Lore.ClickToConfirm"), null); + ButtonLore cancelLore = new ButtonLore(messages.getString("Lore.ClickToCancel"), null); - // Blocks of the mine - List confirmLore = createLore( - messages.getString("Lore.ClickToConfirm")); - List cancelLore = createLore( - messages.getString("Lore.ClickToCancel")); - - // Create the button, set up the material, amount, lore and name - ItemStack confirm = createButton(XMaterial.EMERALD_BLOCK.parseItem(), confirmLore, SpigotPrison.format("&3" + "Confirm: " + mineName)); - ItemStack cancel = createButton(XMaterial.REDSTONE_BLOCK.parseItem(), cancelLore, SpigotPrison.format("&3" + "Cancel: " + mineName)); // Position of the button - inv.setItem(2, confirm); - inv.setItem(6, cancel); + gui.addButton(new Button(2, XMaterial.EMERALD_BLOCK, confirmLore, "&3" + "Confirm: " + mineName)); + gui.addButton(new Button(6, XMaterial.REDSTONE_BLOCK, cancelLore, "&3" + "Cancel: " + mineName)); + + // Open GUI. + gui.open(); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMinesGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMinesGUI.java index 667db875d..b9103df84 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMinesGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotMinesGUI.java @@ -2,20 +2,17 @@ import com.cryptomorin.xseries.XMaterial; import org.apache.commons.lang3.StringUtils; -import org.bukkit.Bukkit; -import org.bukkit.Material; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; import tech.mcprison.prison.Prison; import tech.mcprison.prison.internal.block.PrisonBlock; import tech.mcprison.prison.mines.PrisonMines; -import tech.mcprison.prison.mines.data.BlockOld; import tech.mcprison.prison.mines.data.Mine; import tech.mcprison.prison.mines.data.PrisonSortableResults; import tech.mcprison.prison.mines.managers.MineManager.MineSortOrder; -import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.gui.PrisonSetupGUI; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; import java.text.DecimalFormat; @@ -40,7 +37,6 @@ public void open(){ // Get the mines - In sort order, minus any marked as suppressed PrisonSortableResults mines = PrisonMines.getInstance().getMines( MineSortOrder.sortOrder ); - // If the inventory is empty if (mines.getSortedList().size() == 0){ p.closeInventory(); @@ -49,12 +45,13 @@ public void open(){ return; } + // Get the dimensions and if needed increases them int dimension = 54; int pageSize = 45; - // Create the inventory and set up the owner, dimensions or number of slots, and title - Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format("&3MinesManager -> Mines")); + // Create GUI. + PrisonGUI gui = new PrisonGUI(p, dimension, "&3MinesManager -> Mines"); // Global Strings. String loreLeftClickOpen = messages.getString("Lore.LeftClickToOpen"); @@ -76,28 +73,25 @@ public void open(){ Mine m = mines.getSortedList().get(i); - // Init the lore array with default values for ladders - List minesLore = createLore( + ButtonLore minesLore = new ButtonLore(createLore( loreLeftClickOpen, - loreShiftRightClickToDelete, - "", - loreInfo - ); + loreShiftRightClickToDelete + ), createLore(loreInfo)); // Add a lore - minesLore.add(SpigotPrison.format(loreWorld + m.getWorldName())); + minesLore.addLineLoreDescription(loreWorld + m.getWorldName()); String spawnPoint = m.getSpawn() != null ? m.getSpawn().toBlockCoordinates() : "&cnot set"; - minesLore.add(SpigotPrison.format(loreSpawnPoint + spawnPoint)); - minesLore.add(SpigotPrison.format(loreResetTime + m.getResetTime())); + minesLore.addLineLoreDescription(loreSpawnPoint + spawnPoint); + minesLore.addLineLoreDescription(loreResetTime + m.getResetTime()); if (!m.isVirtual()) { // Add a lore - minesLore.add(SpigotPrison.format(loreSizeOfMine + m.getBounds().getDimensions())); - minesLore.add(SpigotPrison.format(loreVolume + m.getBounds().getTotalBlockCount())); + minesLore.addLineLoreDescription(loreSizeOfMine + m.getBounds().getDimensions()); + minesLore.addLineLoreDescription(loreVolume + m.getBounds().getTotalBlockCount()); } // Add a lore - minesLore.add(SpigotPrison.format(loreBlocks)); + minesLore.addLineLoreDescription(loreBlocks); // Init some variables and do the actions DecimalFormat dFmt = new DecimalFormat("##0.00"); @@ -111,9 +105,9 @@ public void open(){ String blockName = StringUtils.capitalize(block.getBlockName().replaceAll("_", " ").toLowerCase()); - minesLore.add(SpigotPrison.format("&7" + chance + "% - " + block.getBlockName() + " (" + blockName + ")")); + minesLore.addLineLoreDescription("&7" + chance + "% - " + block.getBlockName() + " (" + blockName + ")"); } - } else { + } /*else { for (BlockOld block : m.getBlocks()) { double chance = Math.round(block.getChance() * 100.0d) / 100.0d; @@ -122,32 +116,23 @@ public void open(){ StringUtils.capitalize(block.getType().name().replaceAll("_", " ").toLowerCase()); minesLore.add(SpigotPrison.format("&7" + chance + "% - " + block.getType().name() + " (" + blockName + ")")); } - } + }*/ if (totalChance < 100.0d) { - minesLore.add(SpigotPrison.format("&e " + dFmt.format(100.0d - totalChance) + "% - Air")); + minesLore.addLineLoreDescription("&e " + dFmt.format(100.0d - totalChance) + "% - Air"); } - // Create the button - ItemStack itemMines = createButton(XMaterial.COAL_ORE.parseItem(), minesLore, SpigotPrison.format("&3" + m.getName())); - inv.addItem(itemMines); + gui.addButton(new Button(null, XMaterial.COAL_ORE, minesLore, "&3" + m.getName())); } if (i < mines.getSortedList().size()) { - List nextPageLore = createLore(messages.getString("Lore.ClickToNextPage")); - - ItemStack nextPageButton = createButton(Material.BOOK, 1, nextPageLore, "&7Next " + (i + 1)); - inv.setItem(53, nextPageButton); + gui.addButton(new Button(53, XMaterial.BOOK, new ButtonLore(messages.getString("Lore.ClickToNextPage"), null), "&7Next " + (i + 1))); } if (i >= (pageSize * 2)) { - List priorPageLore = createLore(messages.getString("Lore.ClickToPriorPage")); - - ItemStack priorPageButton = createButton(Material.BOOK, 1, priorPageLore, - "&7Prior " + (i - (pageSize * 2) - 1)); - inv.setItem(51, priorPageButton); + gui.addButton(new Button(51, XMaterial.BOOK, new ButtonLore(messages.getString("Lore.ClickToPriorPage"), null), "&7Prior " + (i - (pageSize * 2) - 1))); } - // Open the inventory - openGUI(p, inv); + // Open the GUI. + gui.open(); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotPlayerMinesGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotPlayerMinesGUI.java index abedf67fb..75e82358d 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotPlayerMinesGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/mine/SpigotPlayerMinesGUI.java @@ -1,12 +1,7 @@ package tech.mcprison.prison.spigot.gui.mine; -import java.util.List; - -import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; import com.cryptomorin.xseries.XMaterial; @@ -19,6 +14,9 @@ import tech.mcprison.prison.spigot.SpigotUtil; import tech.mcprison.prison.spigot.configs.GuiConfig; import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; /** @@ -48,115 +46,93 @@ public void open(){ // Get the dimensions and if needed increases them int dimension = (int) Math.ceil(mines.getSortedList().size() / 9D) * 9; - // Load config - // If the inventory is empty if (dimension == 0){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.NoMines"))); + Output.get().sendWarn(new SpigotPlayer(p), messages.getString("Message.NoMines")); p.closeInventory(); return; } // If the dimension's too big, don't open the GUI if (dimension > 54){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.TooManyMines"))); + Output.get().sendWarn(new SpigotPlayer(p), messages.getString("Message.TooManyMines")); p.closeInventory(); return; } - // Create the inventory and set up the owner, dimensions or number of slots, and title - Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format(guiConfig.getString("Options.Titles.PlayerMinesGUI"))); + // Create GUI. + PrisonGUI gui = new PrisonGUI(p, dimension, guiConfig.getString("Options.Titles.PlayerMinesGUI")); // Make the buttons for every Mine with info for (Mine m : mines.getSortedList()) { - if (guiBuilder(inv, m)) return; - } - - // Open the inventory - openGUI(p, inv); - } - - private boolean guiBuilder(Inventory inv, Mine m) { - try { - buttonsSetup(inv, m); - } catch (NullPointerException ex){ - Output.get().sendWarn(new SpigotPlayer(p),"&cThere's a null value in the GuiConfig.yml [broken]"); - ex.printStackTrace(); - return true; - } - return false; - } + // Init the lore array with default values for ladders + ButtonLore minesLore = new ButtonLore(); + + Material material; + + GuiConfig guiConfigClass = new GuiConfig(); + guiConfig = guiConfigClass.getFileGuiConfig(); + String permission = SpigotPrison.format(permissionWarpPlugin); + + // Get Mine Name. + String mineName = m.getName(); + + // Add mineName lore for TP. + minesLore.addLineLoreAction(SpigotPrison.format("&3" + mineName)); + + // The valid names to use for Options.Mines.MaterialType. must be + // based upon the XMaterial enumeration name, or supported past names. + Material mineMaterial = null; + String materialTypeStr = guiConfig.getString("Options.Mines.MaterialType." + m.getName()); + if ( materialTypeStr != null && materialTypeStr.trim().length() > 0 ) { + XMaterial mineXMaterial = SpigotUtil.getXMaterial( materialTypeStr ); + if ( mineXMaterial != null ) { + mineMaterial = mineXMaterial.parseMaterial(); + } + else { + Output.get().logInfo( "Warning: A block was specified for mine %s but it was " + + "unable to be mapped to an XMaterial type. Key = " + + "[Options.Mines.MaterialType.%s] value = " + + "[%s] Please use valid material names as found in the XMaterial " + + "source on git hub: " + + "https://github.com/CryptoMorin/XSeries/blob/master/src/main/java/" + + "com/cryptomorin/xseries/XMaterial.java ", + m.getName(), m.getName(), mineXMaterial ); + } + } - private void buttonsSetup(Inventory inv, Mine m) { - - // Init the lore array with default values for ladders - List minesLore = createLore( - ); - - ItemStack itemMines; - Material material; - - GuiConfig guiConfigClass = new GuiConfig(); - guiConfig = guiConfigClass.getFileGuiConfig(); - String permission = SpigotPrison.format(permissionWarpPlugin); - - // Get Mine Name. - String mineName = m.getName(); - - // Add mineName lore for TP. - minesLore.add(SpigotPrison.format("&3" + mineName)); - - // The valid names to use for Options.Mines.MaterialType. must be - // based upon the XMaterial enumeration name, or supported past names. - Material mineMaterial = null; - String materialTypeStr = guiConfig.getString("Options.Mines.MaterialType." + m.getName()); - if ( materialTypeStr != null && materialTypeStr.trim().length() > 0 ) { - XMaterial mineXMaterial = SpigotUtil.getXMaterial( materialTypeStr ); - if ( mineXMaterial != null ) { - mineMaterial = mineXMaterial.parseMaterial(); - } - else { - Output.get().logInfo( "Warning: A block was specified for mine %s but it was " + - "unable to be mapped to an XMaterial type. Key = " + - "[Options.Mines.MaterialType.%s] value = " + - "[%s] Please use valid material names as found in the XMaterial " + - "source on git hub: " + - "https://github.com/CryptoMorin/XSeries/blob/master/src/main/java/" + - "com/cryptomorin/xseries/XMaterial.java ", - m.getName(), m.getName(), mineXMaterial ); - } - } + if (m.hasMiningAccess(spigotPlayer) || p.hasPermission(permission + m.getName()) || + p.hasPermission(permission.substring(0, permission.length() - 1))){ + material = ( mineMaterial == null ? Material.COAL_ORE : mineMaterial); + minesLore.addLineLoreDescription(SpigotPrison.format(statusUnlockedMine)); + minesLore.addLineLoreDescription(SpigotPrison.format(clickToTeleport)); + } else { + material = XMaterial.REDSTONE_BLOCK.parseMaterial(); + minesLore.addLineLoreDescription(SpigotPrison.format(statusLockedMine)); + } - if (m.hasMiningAccess(spigotPlayer) || p.hasPermission(permission + m.getName()) || - p.hasPermission(permission.substring(0, permission.length() - 1))){ - material = ( mineMaterial == null ? Material.COAL_ORE : mineMaterial); - minesLore.add(SpigotPrison.format(statusUnlockedMine)); - minesLore.add(SpigotPrison.format(clickToTeleport)); - } else { - material = XMaterial.REDSTONE_BLOCK.parseMaterial(); - minesLore.add(SpigotPrison.format(statusLockedMine)); - } + // Get mine Tag. + String mineTag = m.getTag(); - // Get mine Tag. - String mineTag = m.getTag(); + // Check if mineName's null (which shouldn't be) and do actions. + if (mineName != null) { - // Check if mineName's null (which shouldn't be) and do actions. - if (mineName != null) { + if (mineTag == null || mineTag.equalsIgnoreCase("null")){ + mineTag = mineName; + } - if (mineTag == null || mineTag.equalsIgnoreCase("null")){ - mineTag = mineName; - } + if (material == null){ + material = Material.COAL_ORE; + } - if (material == null){ - material = Material.COAL_ORE; + // Add the button to the inventory. + gui.addButton(new Button(null, XMaterial.matchXMaterial(material), minesLore, "&3" + mineTag)); } - // Create the button. - itemMines = createButton(new ItemStack(material, 1), minesLore, SpigotPrison.format("&3" + mineTag)); - - // Add the button to the inventory. - inv.addItem(itemMines); } + + // Open the GUI. + gui.open(); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotConfirmPrestigeGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotConfirmPrestigeGUI.java index b77b081af..a91862405 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotConfirmPrestigeGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotConfirmPrestigeGUI.java @@ -1,17 +1,13 @@ package tech.mcprison.prison.spigot.gui.rank; import com.cryptomorin.xseries.XMaterial; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotPrison; -import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; -import java.util.List; - /** * @author GABRYCA */ @@ -27,45 +23,20 @@ public void open(){ // Create the inventory int dimension = 9; - Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format("&3Prestige -> Confirmation")); - - if (guiBuilder(inv)) return; - - // Open the inventory - openGUI(p, inv); - } + PrisonGUI gui = new PrisonGUI(p, dimension, "&3Prestige -> Confirmation"); - private boolean guiBuilder(Inventory inv) { - try { - buttonsSetup(inv); - } catch (NullPointerException ex){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cThere's a null value in the GuiConfig.yml [broken]")); - ex.printStackTrace(); - return true; - } - return false; - } - - private void buttonsSetup(Inventory inv) { - - // Blocks of the mine - List confirmLore = createLore( - messages.getString("Lore.ClickToConfirm"), + ButtonLore confirmLore = new ButtonLore(createLore(messages.getString("Lore.ClickToConfirm")), createLore( messages.getString("Lore.PrestigeWarning"), messages.getString("Lore.PrestigeWarning2"), - messages.getString("Lore.PrestigeWarning3") - ); + messages.getString("Lore.PrestigeWarning3"))); + + ButtonLore cancelLore = new ButtonLore(messages.getString("Lore.ClickToCancel"), null); - // Blocks of the mine - List cancelLore = createLore( - messages.getString("Lore.ClickToCancel")); // Create the button, set up the material, amount, lore and name - ItemStack confirm = createButton(XMaterial.EMERALD_BLOCK.parseItem(), confirmLore, SpigotPrison.format("&3" + "Confirm: Prestige")); - ItemStack cancel = createButton(XMaterial.REDSTONE_BLOCK.parseItem(), cancelLore, SpigotPrison.format("&3" + "Cancel: Don't Prestige")); + gui.addButton(new Button(2, XMaterial.EMERALD_BLOCK, confirmLore, SpigotPrison.format("&3" + "Confirm: Prestige"))); + gui.addButton(new Button(6, XMaterial.REDSTONE_BLOCK, cancelLore, SpigotPrison.format("&3" + "Cancel: Don't Prestige"))); - // Position of the button - inv.setItem(2, confirm); - inv.setItem(6, cancel); + gui.open(); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotLaddersGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotLaddersGUI.java index 79188acef..ba29381a2 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotLaddersGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotLaddersGUI.java @@ -1,21 +1,18 @@ package tech.mcprison.prison.spigot.gui.rank; import com.cryptomorin.xseries.XMaterial; -import org.bukkit.Bukkit; -import org.bukkit.Material; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.ranks.PrisonRanks; import tech.mcprison.prison.ranks.data.RankLadder; import tech.mcprison.prison.ranks.managers.LadderManager; import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; -import java.util.List; - /** * @author GABRYCA */ @@ -39,10 +36,9 @@ public void open(){ // Init variable LadderManager lm = PrisonRanks.getInstance().getLadderManager(); - // If the inventory is empty if (lm.getLadders().size() == 0){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.NoLadders"))); + Output.get().sendWarn(new SpigotPlayer(p), messages.getString("Message.NoLadders")); p.closeInventory(); return; } @@ -51,14 +47,9 @@ public void open(){ int dimension = 54; int pageSize = 45; + PrisonGUI gui = new PrisonGUI(p, dimension, "&3RanksManager -> Ladders"); - // Create the inventory and set up the owner, dimensions or number of slots, and title - Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format("&3RanksManager -> Ladders")); - - // Global ladders lore. - List laddersLore = createLore( - messages.getString("Lore.ClickToOpen"), - messages.getString("Lore.ShiftAndRightClickToDelete")); + ButtonLore laddersLore = new ButtonLore(messages.getString("Lore.ClickToOpen"), messages.getString("Lore.ShiftAndRightClickToDelete")); // Only loop over the blocks that we need to show: int i = counter; @@ -66,28 +57,19 @@ public void open(){ RankLadder ladder = lm.getLadder(i); - // Create the button - ItemStack itemLadder = createButton(XMaterial.LADDER.parseItem(), laddersLore, SpigotPrison.format("&3" + ladder.getName())); - // Add the button to the inventory - inv.addItem(itemLadder); + gui.addButton(new Button(null, XMaterial.LADDER, laddersLore, SpigotPrison.format("&3" + ladder.getName()))); } if (i < lm.getLadders().size()) { - List nextPageLore = createLore(messages.getString("Lore.ClickToNextPage")); - - ItemStack nextPageButton = createButton(Material.BOOK, 1, nextPageLore, "&7Next " + (i + 1)); - inv.setItem(53, nextPageButton); + gui.addButton(new Button(53, XMaterial.BOOK, 1, new ButtonLore(messages.getString("Lore.ClickToNextPage"), null), "&7Next " + (i + 1))); } if (i >= (pageSize * 2)) { - List priorPageLore = createLore(messages.getString("Lore.ClickToPriorPage")); - - ItemStack priorPageButton = createButton(Material.BOOK, 1, priorPageLore, - "&7Prior " + (i - (pageSize * 2) - 1)); - inv.setItem(51, priorPageButton); + gui.addButton(new Button(51, XMaterial.BOOK, 1, new ButtonLore(messages.getString("Lore.ClickToPriorPage"), null), + "&7Prior " + (i - (pageSize * 2) - 1))); } // Open the inventory - openGUI(p, inv); + gui.open(); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotPlayerPrestigesGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotPlayerPrestigesGUI.java index 0952fe855..58f69fc15 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotPlayerPrestigesGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotPlayerPrestigesGUI.java @@ -1,14 +1,9 @@ package tech.mcprison.prison.spigot.gui.rank; -import java.util.List; - import org.bukkit.Bukkit; -import org.bukkit.Material; import org.bukkit.Server; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.Plugin; import com.cryptomorin.xseries.XMaterial; @@ -19,6 +14,7 @@ import tech.mcprison.prison.modules.ModuleManager; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.ranks.PrisonRanks; +import tech.mcprison.prison.ranks.data.PlayerRank; import tech.mcprison.prison.ranks.data.Rank; import tech.mcprison.prison.ranks.data.RankLadder; import tech.mcprison.prison.ranks.data.RankPlayer; @@ -26,6 +22,9 @@ import tech.mcprison.prison.ranks.managers.PlayerManager; import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; /** @@ -50,7 +49,7 @@ public SpigotPlayerPrestigesGUI(Player player) { rankPlugin = (PrisonRanks) module; if (rankPlugin == null){ - Output.get().sendWarn(new SpigotPlayer(player), SpigotPrison.format("&3Looks like the Ranks module's disabled")); + Output.get().sendWarn(new SpigotPlayer(player), "&3Looks like the Ranks module's disabled"); return; } @@ -118,47 +117,28 @@ public void open() { // Create the inventory and set up the owner, dimensions or number of slots, and title int dimension = (int) (Math.ceil(ladder.getRanks().size() / 9D) * 9) + 9; - // Create an inventory - Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format(guiConfig.getString("Options.Titles.PlayerPrestigesGUI"))); - - // guiBuilder and validation - if (guiBuilder(ladder, dimension, inv)) return; - - // Open the inventory - openGUI(getPlayer(), inv); - } - - private boolean guiBuilder(RankLadder ladder, int dimension, Inventory inv) { - try { - buttonsSetup(ladder, dimension, inv); - } catch (NullPointerException ex){ - Output.get().sendWarn(new SpigotPlayer(getPlayer()), SpigotPrison.format("&cThere's a null value in the GuiConfig.yml [broken]")); - ex.printStackTrace(); - return true; - } - return false; - } - - private void buttonsSetup(RankLadder ladder, int dimension, Inventory inv) { - + PrisonGUI gui = new PrisonGUI(getPlayer(), dimension, guiConfig.getString("Options.Titles.PlayerPrestigesGUI")); - if ( ladder == null ){ - Output.get().sendWarn(new SpigotPlayer(player), SpigotPrison.format(messages.getString("Message.LadderPrestigesNotFound"))); - return; - } + // dead code: +// if ( ladder == null ){ +// Output.get().sendWarn(new SpigotPlayer(player), messages.getString("Message.LadderPrestigesNotFound")); +// return; +// } if (!ladder.getLowestRank().isPresent()){ - Output.get().sendWarn(new SpigotPlayer(player), SpigotPrison.format(messages.getString("Message.NoRanksPrestigesLadder"))); + Output.get().sendWarn(new SpigotPlayer(player), messages.getString("Message.NoRanksPrestigesLadder")); return; } Rank rank = ladder.getLowestRank().get(); + + PlayerRank prestigePlayerRank = getRankPlayer().getRank("prestiges"); - Rank playerRank = getRankPlayer().getRank("prestiges"); + Rank playerRank = prestigePlayerRank == null ? null : prestigePlayerRank.getRank(); // Not sure how you want to represent this: - Material materialHas = Material.getMaterial(guiConfig.getString("Options.Ranks.Item_gotten_rank")); - Material materialHasNot = Material.getMaterial(guiConfig.getString("Options.Ranks.Item_not_gotten_rank")); + XMaterial materialHas = XMaterial.valueOf(guiConfig.getString("Options.Ranks.Item_gotten_rank")); + XMaterial materialHasNot = XMaterial.valueOf(guiConfig.getString("Options.Ranks.Item_not_gotten_rank")); // Variables. boolean playerHasThisRank = true; @@ -174,21 +154,21 @@ private void buttonsSetup(RankLadder ladder, int dimension, Inventory inv) { int amount = 1; while ( rank != null ) { - List ranksLore = createLore( - loreInfo, - lorePrice3 + rank.getCost() - ); + // Need to create a new PlayerRank specifically for the player which takes in to consideration + // all of their multipliers. + PlayerRank targetPlayerRank = PlayerRank.getTargetPlayerRankForPlayer( rankPlayer, rank ); + double cost = targetPlayerRank == null ? -1 : targetPlayerRank.getRankCost(); + + ButtonLore ranksLore = new ButtonLore(loreInfo, lorePrice3 + cost ); if (placeholderAPINotNull) { if (hackyCounterEnchant == 1) { hackyCounterEnchant++; - ranksLore.add(SpigotPrison.format(PlaceholderAPI.setPlaceholders(Bukkit.getOfflinePlayer(player.getUniqueId()), "%prison_rcb_prestiges%"))); + ranksLore.addLineLoreDescription(SpigotPrison.format(PlaceholderAPI.setPlaceholders(Bukkit.getOfflinePlayer(player.getUniqueId()), "%prison_rcb_prestiges%"))); } } - ItemStack itemrank = createButton( - (playerHasThisRank ? materialHas : materialHasNot), - amount++, ranksLore, SpigotPrison.format(rank.getTag())); + Button itemrank = new Button(null, playerHasThisRank ? materialHas : materialHasNot, amount++, ranksLore, rank.getTag()); if (playerRank != null && playerRank.equals( rank )){ playerHasThisRank = false; } @@ -200,17 +180,17 @@ private void buttonsSetup(RankLadder ladder, int dimension, Inventory inv) { } } } - inv.addItem(itemrank); + gui.addButton(itemrank); rank = rank.getRankNext(); } - List rankupLore = createLore( - messages.getString("Lore.IfYouHaveEnoughMoney"), - messages.getString("Lore.ClickToRankup") - ); + ButtonLore rankupLore = new ButtonLore(messages.getString("Lore.ClickToRankup"), messages.getString("Lore.IfYouHaveEnoughMoney")); + + // Add button to GUI. + gui.addButton(new Button(dimension - 5, XMaterial.EMERALD_BLOCK, rankupLore, SpigotPrison.format("&aPrestige"))); - ItemStack rankupButton = createButton(XMaterial.EMERALD_BLOCK.parseItem(), rankupLore, SpigotPrison.format("&aPrestige")); - inv.setItem(dimension - 5, rankupButton); + // Open GUI. + gui.open(); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotPlayerRanksGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotPlayerRanksGUI.java index b8de5d084..0ec63ded1 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotPlayerRanksGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotPlayerRanksGUI.java @@ -1,16 +1,12 @@ package tech.mcprison.prison.spigot.gui.rank; import java.text.DecimalFormat; -import java.util.ArrayList; import java.util.List; import org.bukkit.Bukkit; -import org.bukkit.Material; import org.bukkit.Server; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.Plugin; import com.cryptomorin.xseries.XMaterial; @@ -22,6 +18,7 @@ import tech.mcprison.prison.output.Output; import tech.mcprison.prison.placeholders.PlaceholdersUtil; import tech.mcprison.prison.ranks.PrisonRanks; +import tech.mcprison.prison.ranks.data.PlayerRank; import tech.mcprison.prison.ranks.data.Rank; import tech.mcprison.prison.ranks.data.RankLadder; import tech.mcprison.prison.ranks.data.RankPlayer; @@ -29,6 +26,9 @@ import tech.mcprison.prison.ranks.managers.PlayerManager; import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; /** @@ -60,12 +60,12 @@ public SpigotPlayerRanksGUI(Player player) { } if (rankPlugin == null){ - Output.get().sendWarn(new SpigotPlayer(player), SpigotPrison.format("&c: rankPlugin == null.")); + Output.get().sendWarn(new SpigotPlayer(player), "&c: rankPlugin == null."); return; } if (rankPlugin.getPlayerManager() == null) { - Output.get().sendWarn(new SpigotPlayer(player), SpigotPrison.format("&c: rankPlugin.getPlayerManager() == null.")); + Output.get().sendWarn(new SpigotPlayer(player), "&c: rankPlugin.getPlayerManager() == null."); return; } @@ -109,57 +109,37 @@ public void open() { // Ensure ladder is present and that it has a rank: if ( ladder == null || !ladder.getLowestRank().isPresent()){ - Output.get().sendWarn(new SpigotPlayer(getPlayer()), SpigotPrison.format(messages.getString("Message.NoRanksFoundHelp1") + guiConfig.getString("Options.Ranks.Ladder") + messages.getString("Message.NoRanksFoundHelp2"))); + Output.get().sendWarn(new SpigotPlayer(getPlayer()), messages.getString("Message.NoRanksFoundHelp1") + guiConfig.getString("Options.Ranks.Ladder") + messages.getString("Message.NoRanksFoundHelp2")); getPlayer().closeInventory(); return; } // Get the dimensions and if needed increases them if (ladder.getRanks().size() == 0) { - Output.get().sendWarn(new SpigotPlayer(getPlayer()), SpigotPrison.format(messages.getString("Message.NoRanksFound"))); + Output.get().sendWarn(new SpigotPlayer(getPlayer()), messages.getString("Message.NoRanksFound")); return; } // Create the inventory and set up the owner, dimensions or number of slots, and title int dimension = (int) (Math.ceil(ladder.getRanks().size() / 9D) * 9) + 9; - // Create the inventory - Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format(guiConfig.getString("Options.Titles.PlayerRanksGUI"))); - // Get many parameters Rank rank = ladder.getLowestRank().get(); - Rank playerRank = getRankPlayer().getRank(guiConfig.getString("Options.Ranks.Ladder")); - - // Call the whole GUI and build it - if (guiBuilder(dimension, inv, rank, playerRank)) return; - - // Open the inventory - openGUI(getPlayer(), inv); - } - - private boolean guiBuilder( int dimension, Inventory inv, Rank rank, Rank playerRank) { - try { - buttonsSetup(dimension, inv, rank, playerRank); - } catch (NullPointerException ex){ - Output.get().sendWarn(new SpigotPlayer(getPlayer()), SpigotPrison.format("&cThere's a null value in the GuiConfig.yml [broken]")); - ex.printStackTrace(); - return true; - } - return false; - } + PlayerRank playerRankRank = getRankPlayer().getRank(guiConfig.getString("Options.Ranks.Ladder")); + + Rank playerRank = playerRankRank == null ? null : playerRankRank.getRank(); - private void buttonsSetup(int dimension, Inventory inv, Rank rank, Rank playerRank) { + PrisonGUI gui = new PrisonGUI(getPlayer(), dimension, guiConfig.getString("Options.Titles.PlayerRanksGUI")); // Not sure how you want to represent this: - Material materialHas = Material.getMaterial(guiConfig.getString("Options.Ranks.Item_gotten_rank")); - Material materialHasNot = Material.getMaterial(guiConfig.getString("Options.Ranks.Item_not_gotten_rank")); + XMaterial materialHas = XMaterial.valueOf(guiConfig.getString("Options.Ranks.Item_gotten_rank")); + XMaterial materialHasNot = XMaterial.valueOf(guiConfig.getString("Options.Ranks.Item_not_gotten_rank")); // Variables boolean playerHasThisRank = true; int hackyCounterEnchant = 0; int amount = 1; - // Global booleans. boolean enchantmentEffectEnabled = getBoolean(guiConfig.getString("Options.Ranks.Enchantment_effect_current_rank")); @@ -168,20 +148,21 @@ private void buttonsSetup(int dimension, Inventory inv, Rank rank, Rank playerRa while (rank != null) { - List ranksLore = new ArrayList<>(); + ButtonLore ranksLore = new ButtonLore(); + for (String stringValue : configCustomLore) { - stringValue = stringValue.replace("{rankPrice}", PlaceholdersUtil.formattedKmbtSISize(rank.getCost(), formatDecimal, "")); + PlayerRank pRank = getRankPlayer().getRank( rank.getLadder() ); + stringValue = stringValue.replace("{rankPrice}", PlaceholdersUtil.formattedKmbtSISize(pRank.getRankCost(), formatDecimal, "")); stringValue = stringValue.replace("{rankName}", rank.getName()); stringValue = stringValue.replace("{rankTag}", SpigotPrison.format(rank.getTag())); - ranksLore.add(SpigotPrison.format(stringValue)); + ranksLore.addLineLoreAction(stringValue); } if (placeholderAPINotNull){ - ranksLore = PlaceholderAPI.setPlaceholders(Bukkit.getOfflinePlayer(player.getUniqueId()), ranksLore); + ranksLore.setLoreAction(PlaceholderAPI.setPlaceholders(Bukkit.getOfflinePlayer(player.getUniqueId()), ranksLore.getLoreAction())); } - ItemStack itemRank; boolean showNumber = getBoolean(guiConfig.getString("Options.Ranks.Number_of_Rank_Player_GUI")); - itemRank = createButton((playerHasThisRank ? materialHas : materialHasNot), (showNumber ? amount : 1), ranksLore, SpigotPrison.format(rank.getTag())); + Button itemRank = new Button(null, playerHasThisRank ? materialHas : materialHasNot, showNumber ? amount : 1, ranksLore, SpigotPrison.format(rank.getTag())); amount++; @@ -198,16 +179,16 @@ private void buttonsSetup(int dimension, Inventory inv, Rank rank, Rank playerRa } } - inv.addItem(itemRank); + gui.addButton(itemRank); rank = rank.getRankNext(); } - List rankupLore = createLore( - messages.getString("Lore.IfYouHaveEnoughMoney"), - messages.getString("Lore.ClickToRankup") - ); + ButtonLore rankupLore = new ButtonLore(messages.getString("Lore.ClickToRankup"), messages.getString("Lore.IfYouHaveEnoughMoney")); + + // Add button. + gui.addButton(new Button(dimension - 5, XMaterial.EMERALD_BLOCK, rankupLore, SpigotPrison.format(messages.getString("Lore.Rankup")))); - ItemStack rankupButton = createButton(XMaterial.EMERALD_BLOCK.parseItem(), rankupLore, SpigotPrison.format(messages.getString("Lore.Rankup"))); - inv.setItem(dimension - 5, rankupButton); + // Open GUI. + gui.open(); } } \ No newline at end of file diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotRankManagerGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotRankManagerGUI.java index 308c1d7d8..96509e3cc 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotRankManagerGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotRankManagerGUI.java @@ -1,21 +1,23 @@ package tech.mcprison.prison.spigot.gui.rank; -import com.cryptomorin.xseries.XMaterial; -import org.bukkit.Bukkit; -import org.bukkit.Material; +import java.text.DecimalFormat; + import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import tech.mcprison.prison.output.Output; + +import com.cryptomorin.xseries.XMaterial; + import tech.mcprison.prison.placeholders.PlaceholdersUtil; +import tech.mcprison.prison.ranks.PrisonRanks; +import tech.mcprison.prison.ranks.data.PlayerRank; import tech.mcprison.prison.ranks.data.Rank; +import tech.mcprison.prison.ranks.data.RankPlayer; import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; -import java.text.DecimalFormat; -import java.util.List; - /** * @author GABRYCA */ @@ -36,84 +38,34 @@ public void open() { return; } - // Create the inventory and set up the owner, dimensions or number of slots, and title int dimension = 27; - Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format("&3" + "Ranks -> RankManager")); - - if (guiBuilder(inv)) return; - - // Open the inventory - openGUI(p, inv); - } + PrisonGUI gui = new PrisonGUI(p, dimension, "&3" + "Ranks -> RankManager"); - private boolean guiBuilder(Inventory inv) { - try { - buttonsSetup(inv); - } catch (NullPointerException ex){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cThere's a null value in the GuiConfig.yml [broken]")); - ex.printStackTrace(); - return true; - } - return false; - } - - private void buttonsSetup(Inventory inv) { - - // Create the lore - List rankupCommandsLore = createLore( - messages.getString("Lore.ClickToOpen") - ); - - // SpigotRanksGUI.getCommands(rankupCommandsLore, rank); + ButtonLore rankupCommandsLore = new ButtonLore(messages.getString("Lore.ClickToOpen"), null); // Decimal Rank cost format. DecimalFormat formatDecimal = new DecimalFormat("###,##0.00"); - // Create the lore - List editPriceLore = createLore( - messages.getString("Lore.ClickToOpen"), - "", - "&8-----------------------", - " ", - messages.getString("Lore.Info"), - messages.getString("Lore.Price") + PlaceholdersUtil.formattedKmbtSISize(rank.getCost(), formatDecimal, ""), - " ", - "&8-----------------------" - ); - - List editTagLore = createLore( - messages.getString("Lore.ClickToOpen"), - "", - "&8-----------------------", - " ", + RankPlayer rankPlayer = PrisonRanks.getInstance().getPlayerManager().getPlayer( new SpigotPlayer(p) ); + PlayerRank pRank = rankPlayer.getRank( rank.getLadder() ); + + ButtonLore editPriceLore = new ButtonLore(createLore(messages.getString("Lore.ClickToOpen")), createLore( messages.getString("Lore.Info"), - messages.getString("Lore.Tag") + rank.getTag(), - " ", - "&8-----------------------" - ); + messages.getString("Lore.Price") + PlaceholdersUtil.formattedKmbtSISize(pRank.getRankCost(), formatDecimal, ""))); - // Create the button - Material commandMinecart = Material.matchMaterial( "command_minecart" ); - if ( commandMinecart == null ) { - commandMinecart = Material.matchMaterial( "command_block_minecart" ); - } + ButtonLore editTagLore = new ButtonLore(createLore(messages.getString("Lore.ClickToOpen")), createLore( + messages.getString("Lore.Info"), + messages.getString("Lore.Tag") + rank.getTag())); - List closeGUILore = createLore( - messages.getString("Lore.ClickToClose") - ); + ButtonLore closeGUILore = new ButtonLore(messages.getString("Lore.ClickToClose"), null); // Create the button - ItemStack closeGUI = createButton(XMaterial.RED_STAINED_GLASS_PANE.parseItem(), closeGUILore, SpigotPrison.format("&c" + "Close")); - ItemStack rankupCommands = createButton(XMaterial.matchXMaterial(commandMinecart).parseItem(), rankupCommandsLore, SpigotPrison.format("&3" + "RankupCommands" + " " + rank.getName())); - ItemStack rankPrice = createButton(XMaterial.GOLD_NUGGET.parseItem(), editPriceLore, SpigotPrison.format("&3" + "RankPrice" + " " + rank.getName())); - ItemStack rankTag = createButton(XMaterial.NAME_TAG.parseItem(), editTagLore, SpigotPrison.format("&3" + "RankTag" + " " + rank.getName())); - - // Set the position and add it to the inventory - inv.setItem(10, rankupCommands); - inv.setItem(13, rankPrice); - inv.setItem(16, rankTag); - inv.setItem(26, closeGUI); - } + gui.addButton(new Button(26, XMaterial.RED_STAINED_GLASS_PANE, closeGUILore, SpigotPrison.format("&c" + "Close"))); + gui.addButton(new Button(10, XMaterial.COMMAND_BLOCK_MINECART, rankupCommandsLore, SpigotPrison.format("&3" + "RankupCommands" + " " + rank.getName()))); + gui.addButton(new Button(13, XMaterial.GOLD_NUGGET, editPriceLore, SpigotPrison.format("&3" + "RankPrice" + " " + rank.getName()))); + gui.addButton(new Button(16, XMaterial.NAME_TAG, editTagLore, SpigotPrison.format("&3" + "RankTag" + " " + rank.getName()))); + gui.open(); + } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotRankPriceGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotRankPriceGUI.java index 4e130b758..9a2320694 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotRankPriceGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotRankPriceGUI.java @@ -1,18 +1,13 @@ package tech.mcprison.prison.spigot.gui.rank; import com.cryptomorin.xseries.XMaterial; -import org.bukkit.Bukkit; -import org.bukkit.Material; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotPrison; -import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; -import java.util.List; - /** * @author GABRYCA */ @@ -35,78 +30,34 @@ public void open() { return; } - // Create a new inventory int dimension = 45; - Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format("&3RankManager -> RankPrice")); - - if (guiBuilder(inv)) return; - - // Open the inventory - openGUI(p, inv); - } - - private boolean guiBuilder(Inventory inv) { - try { - buttonsSetup(inv); - } catch (NullPointerException ex){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cThere's a null value in the GuiConfig.yml [broken]")); - ex.printStackTrace(); - return true; - } - return false; - } - - private void buttonsSetup(Inventory inv) { - + PrisonGUI gui = new PrisonGUI(p, dimension, "&3RankManager -> RankPrice"); - // Create a new lore - List changeDecreaseValueLore = createLore( - messages.getString("Lore.ClickToDecrease") - ); - List confirmButtonLore; - confirmButtonLore = createLore( - messages.getString("Lore.LeftClickToConfirm"), - messages.getString("Lore.Price2") + val, - messages.getString("Lore.RightClickToCancel") - ); - List changeIncreaseValueLore = createLore( - messages.getString("Lore.ClickToIncrease") - ); + ButtonLore changeDecreaseValueLore = new ButtonLore(messages.getString("Lore.ClickToDecrease"), null); + ButtonLore confirmButtonLore = new ButtonLore(createLore(messages.getString("Lore.LeftClickToConfirm"), messages.getString("Lore.RightClickToCancel")), createLore(messages.getString("Lore.Price2") + val)); + ButtonLore changeIncreaseValueLore = new ButtonLore(messages.getString("Lore.ClickToIncrease"), null); - Material decreaseMat = XMaterial.REDSTONE_BLOCK.parseMaterial(); - ItemStack decreaseStack = XMaterial.REDSTONE_BLOCK.parseItem(); + XMaterial decreaseMat = XMaterial.REDSTONE_BLOCK; // Decrease button - ItemStack decreaseOf1 = createButton(decreaseStack, changeDecreaseValueLore, SpigotPrison.format("&3" + rankName + " " + val + " - 1" )); - inv.setItem(1, decreaseOf1); - ItemStack decreaseOf5 = createButton(new ItemStack(decreaseMat, 10), changeDecreaseValueLore, SpigotPrison.format("&3" + rankName + " " + val + " - 10")); - inv.setItem(10, decreaseOf5); - ItemStack decreaseOf10 = createButton(decreaseStack, changeDecreaseValueLore, SpigotPrison.format("&3" + rankName + " " + val + " - 100")); - inv.setItem(19, decreaseOf10); - ItemStack decreaseOf50 = createButton(decreaseStack, changeDecreaseValueLore, SpigotPrison.format("&3" + rankName + " " + val + " - 1000")); - inv.setItem(28, decreaseOf50); - ItemStack decreaseOf100 = createButton(decreaseStack, changeDecreaseValueLore, SpigotPrison.format("&3" + rankName + " " + val + " - 10000")); - inv.setItem(37, decreaseOf100); - + gui.addButton(new Button(1, decreaseMat, changeDecreaseValueLore, SpigotPrison.format("&3" + rankName + " " + val + " - 1" ))); + gui.addButton(new Button(10, decreaseMat, 10, changeDecreaseValueLore, SpigotPrison.format("&3" + rankName + " " + val + " - 10"))); + gui.addButton(new Button(19, decreaseMat, changeDecreaseValueLore, SpigotPrison.format("&3" + rankName + " " + val + " - 100"))); + gui.addButton(new Button(28, decreaseMat, changeDecreaseValueLore, SpigotPrison.format("&3" + rankName + " " + val + " - 1000"))); + gui.addButton(new Button(37, decreaseMat, changeDecreaseValueLore, SpigotPrison.format("&3" + rankName + " " + val + " - 10000"))); // Create a button and set the position - ItemStack confirmButton = createButton(XMaterial.TRIPWIRE_HOOK.parseItem(), confirmButtonLore, SpigotPrison.format("&3" + "Confirm: " + rankName + " " + val)); - inv.setItem(22, confirmButton); + gui.addButton(new Button(22, XMaterial.TRIPWIRE_HOOK, confirmButtonLore, SpigotPrison.format("&3" + "Confirm: " + rankName + " " + val))); - Material increaseMat = XMaterial.EMERALD_BLOCK.parseMaterial(); - ItemStack increaseStack = XMaterial.EMERALD_BLOCK.parseItem(); + XMaterial increaseMat = XMaterial.EMERALD_BLOCK; // Increase button - ItemStack increaseOf1 = createButton(increaseStack, changeIncreaseValueLore, SpigotPrison.format("&3" + rankName + " " + val + " + 1" )); - inv.setItem(7, increaseOf1); - ItemStack increaseOf5 = createButton(new ItemStack(increaseMat, 10), changeIncreaseValueLore, SpigotPrison.format("&3" + rankName + " " + val + " + 10")); - inv.setItem(16, increaseOf5); - ItemStack increaseOf10 = createButton(increaseStack, changeIncreaseValueLore, SpigotPrison.format("&3" + rankName + " " + val + " + 100")); - inv.setItem(25, increaseOf10); - ItemStack increaseOf50 = createButton(increaseStack, changeIncreaseValueLore, SpigotPrison.format("&3" + rankName + " " + val + " + 1000")); - inv.setItem(34, increaseOf50); - ItemStack increaseOf100 = createButton(increaseStack, changeIncreaseValueLore, SpigotPrison.format("&3" + rankName + " " + val + " + 10000")); - inv.setItem(43, increaseOf100); - } + gui.addButton(new Button(7, increaseMat, changeIncreaseValueLore, SpigotPrison.format("&3" + rankName + " " + val + " + 1" ))); + gui.addButton(new Button(16, increaseMat, 10, changeIncreaseValueLore, SpigotPrison.format("&3" + rankName + " " + val + " + 10"))); + gui.addButton(new Button(25, increaseMat, changeIncreaseValueLore, SpigotPrison.format("&3" + rankName + " " + val + " + 100"))); + gui.addButton(new Button(34, increaseMat, changeIncreaseValueLore, SpigotPrison.format("&3" + rankName + " " + val + " + 1000"))); + gui.addButton(new Button(43, increaseMat, changeIncreaseValueLore, SpigotPrison.format("&3" + rankName + " " + val + " + 10000"))); + gui.open(); + } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotRankUPCommandsGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotRankUPCommandsGUI.java index 839b5c4ca..9fa59f57a 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotRankUPCommandsGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotRankUPCommandsGUI.java @@ -1,17 +1,15 @@ package tech.mcprison.prison.spigot.gui.rank; -import java.util.List; - import com.cryptomorin.xseries.XMaterial; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.ranks.data.Rank; import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; /** @@ -40,68 +38,42 @@ public void open() { } if (rank.getRankUpCommands().size() == 0){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.NoRankupCommands"))); + Output.get().sendWarn(new SpigotPlayer(p), messages.getString("Message.NoRankupCommands")); return; } // Get the dimensions and if needed increases them int dimension = (int) Math.ceil(rank.getRankUpCommands().size() / 9D) * 9; - - // If the inventory is empty if (dimension == 0){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.EmptyGui"))); + Output.get().sendWarn(new SpigotPlayer(p), messages.getString("Message.EmptyGui")); p.closeInventory(); return; } // If the dimension's too big, don't open the GUI if (dimension > 54){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.TooManyRankupCommands"))); + Output.get().sendWarn(new SpigotPlayer(p), messages.getString("Message.TooManyRankupCommands")); p.closeInventory(); return; } - // Create the inventory and set up the owner, dimensions or number of slots, and title - Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format("&3RankManager -> RankUPCommands")); + PrisonGUI gui = new PrisonGUI(p, dimension, "&3RankManager -> RankUPCommands"); // For every command make a button for (String command : rank.getRankUpCommands()) { - if (guiBuilder(inv, command)) return; + ButtonLore commandsLore = new ButtonLore(shiftRightClickToDelete, loreInfo); - } + commandsLore.addLineLoreDescription(SpigotPrison.format(loreCommand + command)); - // Open the inventory - openGUI(p, inv); - } + // Add the button to the inventory + gui.addButton(new Button(null, XMaterial.TRIPWIRE_HOOK, commandsLore, SpigotPrison.format("&3" + rank.getName() + " " + command))); - private boolean guiBuilder(Inventory inv, String command) { - try { - buttonsSetup(inv, command); - } catch (NullPointerException ex){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cThere's a null value in the GuiConfig.yml [broken]")); - ex.printStackTrace(); - return true; } - return false; - } - - private void buttonsSetup(Inventory inv, String command) { - - ItemStack itemCommand; - // Init the lore array with default values for ladders - List commandsLore = createLore( - shiftRightClickToDelete, - "", - loreInfo); - commandsLore.add(SpigotPrison.format(loreCommand + command)); - - // Make the button with materials, amount, lore and name - itemCommand = createButton(XMaterial.TRIPWIRE_HOOK.parseItem(), commandsLore, SpigotPrison.format("&3" + rank.getName() + " " + command)); - // Add the button to the inventory - inv.addItem(itemCommand); + // Open the GUI. + gui.open(); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotRanksGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotRanksGUI.java index 915a6047a..9503fe16f 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotRanksGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/rank/SpigotRanksGUI.java @@ -1,27 +1,25 @@ package tech.mcprison.prison.spigot.gui.rank; -import com.cryptomorin.xseries.XMaterial; -import org.bukkit.Bukkit; +import java.text.DecimalFormat; +import java.util.Optional; + import org.bukkit.ChatColor; -import org.bukkit.Material; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; + +import com.cryptomorin.xseries.XMaterial; + import tech.mcprison.prison.output.Output; import tech.mcprison.prison.placeholders.PlaceholdersUtil; -import tech.mcprison.prison.ranks.PrisonRanks; +import tech.mcprison.prison.ranks.data.PlayerRank; import tech.mcprison.prison.ranks.data.Rank; import tech.mcprison.prison.ranks.data.RankLadder; -import tech.mcprison.prison.ranks.data.RankPlayer; import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; -import java.text.DecimalFormat; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - /** * @author GABRYCA */ @@ -46,7 +44,7 @@ public void open(){ // Get the dimensions and if needed increases them if (!ladder.isPresent() || ladder.get().getRanks().size() == 0) { - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.NoRanksFoundAdmin"))); + Output.get().sendWarn(new SpigotPlayer(p), messages.getString("Message.NoRanksFoundAdmin")); return; } @@ -54,8 +52,7 @@ public void open(){ int dimension = 54; int pageSize = 45; - // Create the inventory and set up the owner, dimensions or number of slots, and title - Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format("&3" + "Ladders -> Ranks")); + PrisonGUI gui = new PrisonGUI(p, dimension, "&3" + "Ladders -> Ranks"); // Global Strings. String loreShiftRightClickDelete = messages.getString("Lore.ShiftAndRightClickToDelete"); @@ -74,54 +71,47 @@ public void open(){ int i = counter; for ( ; i < ladder.get().getRanks().size() && i < counter + pageSize; i++ ) { - // Init the lore array with default values for ladders - List ranksLore = createLore( + ButtonLore ranksLore = new ButtonLore(createLore( loreShiftRightClickDelete, - loreClickToManageRank, - "", - loreInfo); + loreClickToManageRank), createLore(loreInfo)); Rank rank = ladder.get().getRanks().get(i); + // Can only use the raw rank costs since this is not tied to a player: + double rawRankCost = PlayerRank.getRawRankCost( rank ); + // NOTE: The following ladderBaseRankMultiplier is just for the current ladder, but the player's + // adjusted rank cost is the sum of all ladder's multipliers applied to each raw rank cost. +// double ladderBaseRankMultiplier = PlayerRank.getLadderBaseRankdMultiplier( rank ); + // Add the RankID Lore - ranksLore.add(SpigotPrison.format(loreId + rank.getId())); - ranksLore.add(SpigotPrison.format(loreName + rank.getName())); - ranksLore.add(SpigotPrison.format(loreTag2 + ChatColor.translateAlternateColorCodes('&', rank.getTag()))); - ranksLore.add(SpigotPrison.format(lorePrice3 + PlaceholdersUtil.formattedKmbtSISize(rank.getCost(), formatDecimal, ""))); + ranksLore.addLineLoreDescription(SpigotPrison.format(loreId + rank.getId())); + ranksLore.addLineLoreDescription(SpigotPrison.format(loreName + rank.getName())); + ranksLore.addLineLoreDescription(SpigotPrison.format(loreTag2 + ChatColor.translateAlternateColorCodes('&', rank.getTag()))); + ranksLore.addLineLoreDescription(SpigotPrison.format(lorePrice3 + PlaceholdersUtil.formattedKmbtSISize(rawRankCost, formatDecimal, ""))); // Init a variable - List players = - PrisonRanks.getInstance().getPlayerManager().getPlayers().stream() - .filter(rankPlayer -> rankPlayer.getLadderRanks().containsValue(rank)) - .collect(Collectors.toList()); + int playerCount = rank.getPlayers().size(); +// List players = +// PrisonRanks.getInstance().getPlayerManager().getPlayers().stream() +// .filter(rankPlayer -> rankPlayer.getLadderRanks().containsValue(rank)) +// .collect(Collectors.toList()); // Add the number of players with this rank - ranksLore.add(SpigotPrison.format(lorePlayersWithRank + players.size())); - ranksLore.add(""); - //getCommands(ranksLore, rank); - - // Make the button with materials, amount, lore and name - ItemStack itemRank = createButton(XMaterial.TRIPWIRE_HOOK.parseItem(), ranksLore, SpigotPrison.format("&3" + rank.getName())); + ranksLore.addLineLoreDescription(SpigotPrison.format(lorePlayersWithRank + playerCount)); // Add the button to the inventory - inv.setItem(i - counter, itemRank); + gui.addButton(new Button(i - counter, XMaterial.TRIPWIRE_HOOK, ranksLore, SpigotPrison.format("&3" + rank.getName()))); } if (i < ladder.get().getRanks().size()) { - List nextPageLore = createLore(messages.getString("Lore.ClickToNextPage")); - - ItemStack nextPageButton = createButton(Material.BOOK, 1, nextPageLore, "&7Next " + (i + 1)); - inv.setItem(53, nextPageButton); + gui.addButton(new Button(53, XMaterial.BOOK, 1, new ButtonLore(messages.getString("Lore.ClickToNextPage"), null), "&7Next " + (i + 1))); } if (i >= (pageSize * 2)) { - List priorPageLore = createLore(messages.getString("Lore.ClickToPriorPage")); - - ItemStack priorPageButton = createButton(Material.BOOK, 1, priorPageLore, - "&7Prior " + (i - (pageSize * 2) - 1)); - inv.setItem(51, priorPageButton); + gui.addButton(new Button(51, XMaterial.BOOK, 1, new ButtonLore(messages.getString("Lore.ClickToPriorPage"), null), + "&7Prior " + (i - (pageSize * 2) - 1))); } - // Open the inventory - openGUI(p, inv); + // Open the GUI. + gui.open(); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllAdminAutoSellGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllAdminAutoSellGUI.java index bd0fd1e43..0cc736297 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllAdminAutoSellGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllAdminAutoSellGUI.java @@ -1,17 +1,13 @@ package tech.mcprison.prison.spigot.gui.sellall; import com.cryptomorin.xseries.XMaterial; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotPrison; -import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; -import java.util.List; - /** * @author GABRYCA */ @@ -28,65 +24,35 @@ public void open() { updateSellAllConfig(); - Inventory inv = buttonsSetup(); - - openGUI(p, inv); - } - - private Inventory buttonsSetup() { - - Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format("&3SellAll -> AutoSell")); + PrisonGUI gui = new PrisonGUI(p, dimension, "&3SellAll -> AutoSell"); - List closeGUILore = createLore( - messages.getString("Lore.ClickToClose") - ); + ButtonLore closeGUILore = new ButtonLore(messages.getString("Lore.ClickToClose"), null); + ButtonLore perUserToggleableLore = new ButtonLore(); + ButtonLore enableDisableLore = new ButtonLore(); - List perUserToggleableLore; - List enableDisableLore; - - ItemStack perUserToggleableButton; - ItemStack enableDisableButton; + Button perUserToggleableButton; + Button enableDisableButton; if (sellAllConfig.getString("Options.Full_Inv_AutoSell_perUserToggleable").equalsIgnoreCase("true")){ - perUserToggleableLore = createLore( - messages.getString("Lore.ClickToDisable") - ); - perUserToggleableButton = createButton(XMaterial.LIME_STAINED_GLASS_PANE.parseItem(), perUserToggleableLore, "&3PerUserToggleable"); + perUserToggleableLore.setLoreAction(messages.getString("Lore.ClickToDisable")); + perUserToggleableButton = new Button(11, XMaterial.LIME_STAINED_GLASS_PANE, perUserToggleableLore, "&3PerUserToggleable"); } else { - perUserToggleableLore = createLore( - messages.getString("Lore.ClickToEnable") - ); - perUserToggleableButton = createButton(XMaterial.RED_STAINED_GLASS_PANE.parseItem(), perUserToggleableLore, "&cPerUserToggleable-Disabled"); + perUserToggleableLore.setLoreAction(messages.getString("Lore.ClickToEnable")); + perUserToggleableButton = new Button(11, XMaterial.RED_STAINED_GLASS_PANE, perUserToggleableLore, "&cPerUserToggleable-Disabled"); } if (sellAllConfig.getString("Options.Full_Inv_AutoSell").equalsIgnoreCase("true")){ - enableDisableLore = createLore( - messages.getString("Lore.ClickToDisable") - ); - enableDisableButton = createButton(XMaterial.LIME_STAINED_GLASS_PANE.parseItem(), enableDisableLore, "&3AutoSell"); + enableDisableLore.setLoreAction(messages.getString("Lore.ClickToDisable")); + enableDisableButton = new Button(15, XMaterial.LIME_STAINED_GLASS_PANE, enableDisableLore, "&3AutoSell"); } else { - enableDisableLore = createLore( - messages.getString("Lore.ClickToEnable") - ); - enableDisableButton = createButton(XMaterial.RED_STAINED_GLASS_PANE.parseItem(), enableDisableLore, "&cAutoSell-Disabled"); + enableDisableLore.setLoreAction(messages.getString("Lore.ClickToEnable")); + enableDisableButton = new Button(15, XMaterial.RED_STAINED_GLASS_PANE, enableDisableLore, "&cAutoSell-Disabled"); } - ItemStack closeGUI = createButton(XMaterial.RED_STAINED_GLASS_PANE.parseItem(), closeGUILore, SpigotPrison.format("&c" + "Close")); - - inv.setItem(11, perUserToggleableButton); - inv.setItem(15, enableDisableButton); - inv.setItem(dimension - 1, closeGUI); - return inv; - } + gui.addButton(new Button(dimension-1, XMaterial.RED_STAINED_GLASS_PANE, closeGUILore, SpigotPrison.format("&c" + "Close"))); + gui.addButton(perUserToggleableButton); + gui.addButton(enableDisableButton); - private boolean guiBuilder() { - try { - buttonsSetup(); - } catch (NullPointerException ex){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cThere's a null value in the GuiConfig.yml [broken]")); - ex.printStackTrace(); - return true; - } - return false; + gui.open(); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllAdminBlocksGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllAdminBlocksGUI.java index 723ae7177..6ee1c3cee 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllAdminBlocksGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllAdminBlocksGUI.java @@ -1,16 +1,16 @@ package tech.mcprison.prison.spigot.gui.sellall; -import org.bukkit.Bukkit; +import com.cryptomorin.xseries.XMaterial; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.SpigotUtil; import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; -import java.util.List; import java.util.Set; /** @@ -19,69 +19,42 @@ public class SellAllAdminBlocksGUI extends SpigotGUIComponents { private final Player p; - boolean itemsNotNull = true; + private final int startingItem; - public SellAllAdminBlocksGUI(Player p){ + public SellAllAdminBlocksGUI(Player p, int startingItem){ this.p = p; + this.startingItem = startingItem; } public void open() { updateSellAllConfig(); - Inventory inv = buttonsSetup(); - if (inv == null && !itemsNotNull) { - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.SellAllGUIEmpty"))); - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.SellAllGUIEmpty2"))); - return; - } else if (inv == null){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.TooManySellAllItems"))); - return; - } - - openGUI(p, inv); - } - - private Inventory buttonsSetup() { + PrisonGUI gui = new PrisonGUI(p, 54, "&3SellAll -> Blocks"); boolean emptyInv = false; - int dimension = 9; try { if (sellAllConfig.getConfigurationSection("Items") == null) { emptyInv = true; } + if (sellAllConfig.getConfigurationSection("Items").getKeys(false).size() == 0){ + emptyInv = true; + } } catch (NullPointerException e){ emptyInv = true; } if (emptyInv){ - p.closeInventory(); - return null; + SpigotPlayer spigotPlayer = new SpigotPlayer(p); + Output.get().sendWarn(spigotPlayer, messages.getString("Message.SellAllGUIEmpty")); + Output.get().sendWarn(spigotPlayer, messages.getString("Message.SellAllGUIEmpty2")); + return; } // Get the Items config section Set items = sellAllConfig.getConfigurationSection("Items").getKeys(false); - if (items.size() == 0){ - itemsNotNull = false; - p.closeInventory(); - return null; - } - - // Get the dimensions and if needed increases them - dimension = (int) Math.ceil(items.size() / 9D) * 9; - - // Check if there're too many blocks. - if (dimension > 54){ - itemsNotNull = true; - p.closeInventory(); - return null; - } - - // Inventory of GUI. - Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format("&3SellAll -> Blocks")); - // Global strings. String loreLine1 = messages.getString("Lore.RightClickToDelete"); String loreLine2 = messages.getString("Lore.LeftClickToEdit"); @@ -91,32 +64,32 @@ private Inventory buttonsSetup() { boolean sellAllPerBlockPermissionEnabled = getBoolean(sellAllConfig.getString("Options.Sell_Per_Block_Permission_Enabled")); + int itemsAdded = 0, itemsRead = 0; for (String key : items) { - List itemsLore = createLore( - loreLine1, - loreLine2, - loreValue + sellAllConfig.getString("Items." + key + ".ITEM_VALUE") - ); - - if (sellAllPerBlockPermissionEnabled){ - itemsLore.add(""); - itemsLore.add(SpigotPrison.format(lorePermission + "&7" + permissionSellAllBlock + sellAllConfig.getString("Items." + key + ".ITEM_ID"))); - } + itemsRead++; - ItemStack item = createButton(SpigotUtil.getItemStack(SpigotUtil.getXMaterial(sellAllConfig.getString("Items." + key + ".ITEM_ID")), 1), itemsLore, SpigotPrison.format("&3" + sellAllConfig.getString("Items." + key + ".ITEM_ID"))); - inv.addItem(item); - } - return inv; - } + if (itemsRead >= startingItem) { - private boolean guiBuilder() { - try { - buttonsSetup(); - } catch (NullPointerException ex){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cThere's a null value in the GuiConfig.yml [broken]")); - ex.printStackTrace(); - return true; + if (startingItem != 0){ + gui.addButton(new Button(45, XMaterial.BOOK, new ButtonLore(messages.getString("Lore.ClickToPriorPage"), null), "&7Prior " + (startingItem - 45))); + } + + if (itemsAdded >= 45){ + gui.addButton(new Button(53, XMaterial.BOOK, new ButtonLore(messages.getString("Lore.ClickToNextPage"), null), "&7Next " + (startingItem + itemsAdded))); + } + + if (itemsAdded < 45) { + ButtonLore itemsLore = new ButtonLore(createLore(loreLine1, loreLine2), createLore(loreValue + sellAllConfig.getString("Items." + key + ".ITEM_VALUE"))); + + if (sellAllPerBlockPermissionEnabled) { + itemsLore.addLineLoreDescription(SpigotPrison.format(lorePermission + "&7" + permissionSellAllBlock + sellAllConfig.getString("Items." + key + ".ITEM_ID"))); + } + + gui.addButton(new Button(null, SpigotUtil.getXMaterial(sellAllConfig.getString("Items." + key + ".ITEM_ID")), itemsLore, "&3" + sellAllConfig.getString("Items." + key + ".ITEM_ID"))); + itemsAdded++; + } + } } - return false; + gui.open(); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllAdminGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllAdminGUI.java index 952a4bb4e..05cce65ef 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllAdminGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllAdminGUI.java @@ -1,17 +1,15 @@ package tech.mcprison.prison.spigot.gui.sellall; import com.cryptomorin.xseries.XMaterial; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; -import java.util.List; - /** * @author GABRYCA */ @@ -26,119 +24,77 @@ public SellAllAdminGUI(Player p) { public void open() { - if (!SpigotPrison.getInstance().getConfig().getString("sellall").equalsIgnoreCase("true")){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.SellAllIsDisabled"))); + Output.get().sendWarn(new SpigotPlayer(p), messages.getString("Message.SellAllIsDisabled")); return; } updateSellAllConfig(); - Inventory inv = buttonsSetup(); - - openGUI(p, inv); - } - - - private boolean guiBuilder() { - try { - buttonsSetup(); - } catch (NullPointerException ex){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cThere's a null value in the GuiConfig.yml [broken]")); - ex.printStackTrace(); - return true; - } - return false; - } - - private Inventory buttonsSetup() { + PrisonGUI gui = new PrisonGUI(p, dimension, "&3Prison -> SellAll-Admin"); - Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format("&3Prison -> SellAll-Admin")); + ButtonLore blocksLore = new ButtonLore(messages.getString("Lore.ClickToOpen"), null); + ButtonLore closeGUILore = new ButtonLore(messages.getString("Lore.ClickToClose"), null); + ButtonLore setCurrencyLore = new ButtonLore(createLore(messages.getString("Lore.ClickToEdit")), createLore( + messages.getString("Lore.SellAllActiveCurrency") + sellAllConfig.getString("Options.SellAll_Currency"), + messages.getString("Lore.SellAllCurrencyInfo"))); + ButtonLore multipliersLore = new ButtonLore(messages.getString("Lore.ClickToOpen"), messages.getString("Lore.PrestigeMultiplierInfoGUI")); + ButtonLore autoSellLore = new ButtonLore(); + ButtonLore sellAllDelayLore = new ButtonLore(); - List blocksLore = createLore( - messages.getString("Lore.ClickToOpen") - ); + Button autoSellButton; + Button sellAllDelayButton; - ItemStack autoSellButton; - List autoSellLore; if (sellAllConfig.getString("Options.Full_Inv_AutoSell").equalsIgnoreCase("true")){ - autoSellLore = createLore( + autoSellLore.setLoreAction(createLore( messages.getString("Lore.ClickToOpen"), messages.getString("Lore.RightClickToDisable") - ); - autoSellButton = createButton(XMaterial.CHEST.parseItem(), autoSellLore, "&3AutoSell"); + )); + + autoSellButton = new Button(13, XMaterial.CHEST, autoSellLore, "&3AutoSell"); } else { - autoSellLore = createLore( - messages.getString("Lore.RightClickToEnable") - ); - autoSellButton = createButton(XMaterial.CHEST.parseItem(), autoSellLore, "&cAutoSell-Disabled"); + autoSellLore.setLoreAction(messages.getString("Lore.RightClickToEnable")); + autoSellButton = new Button(13, XMaterial.CHEST, autoSellLore, "&cAutoSell-Disabled"); } - List closeGUILore = createLore( - messages.getString("Lore.ClickToClose") - ); - - ItemStack sellAllDelayButton; - List sellAllDelayLore; if (sellAllConfig.getString("Options.Sell_Delay_Enabled").equalsIgnoreCase("true")){ - sellAllDelayLore = createLore( + sellAllDelayLore.setLoreAction(createLore( messages.getString("Lore.ClickToOpen"), messages.getString("Lore.DelaySellAll") + sellAllConfig.getString("Options.Sell_Delay_Seconds") + "s", - messages.getString("Lore.RightClickToDisable"), - "", + messages.getString("Lore.RightClickToDisable"))); + sellAllDelayLore.setLoreDescription(createLore( messages.getString("Lore.SellAllDelayInfo"), - messages.getString("Lore.SellAllDelayInfo2") - ); + messages.getString("Lore.SellAllDelayInfo2"))); - sellAllDelayButton = createButton(XMaterial.CLOCK.parseItem(), sellAllDelayLore, "&3Delay-Enabled"); + sellAllDelayButton = new Button(11, XMaterial.CLOCK, sellAllDelayLore, "&3Delay-Enabled"); } else { - sellAllDelayLore = createLore( - messages.getString("Lore.RightClickToEnable"), - "", + sellAllDelayLore.setLoreAction(messages.getString("Lore.RightClickToEnable")); + sellAllDelayLore.setLoreDescription(createLore( messages.getString("Lore.SellAllDelayInfo"), - messages.getString("Lore.SellAllDelayInfo2") - ); + messages.getString("Lore.SellAllDelayInfo2"))); - sellAllDelayButton = createButton(XMaterial.CLOCK.parseItem(), sellAllDelayLore, "&cDelay-Disabled"); + sellAllDelayButton = new Button(11, XMaterial.CLOCK, sellAllDelayLore, "&cDelay-Disabled"); } - List setCurrencyLore = createLore( - messages.getString("Lore.SellAllActiveCurrency") + sellAllConfig.getString("Options.SellAll_Currency"), - messages.getString("Lore.ClickToEdit"), - "", - messages.getString("Lore.SellAllCurrencyInfo") - ); - - List multipliersLore = createLore( - messages.getString("Lore.ClickToOpen"), - "", - messages.getString("Lore.PrestigeMultiplierInfoGUI") - ); - try { if (sellAllConfig.getConfigurationSection("Multiplier") == null) { - multipliersLore.add(SpigotPrison.format(messages.getString("Lore.EmptyMultiplier"))); + multipliersLore.addLineLoreDescription(SpigotPrison.format(messages.getString("Lore.EmptyMultiplier"))); } else if (sellAllConfig.getConfigurationSection("Multiplier").getKeys(false).size() == 0) { - multipliersLore.add(SpigotPrison.format(messages.getString("Lore.EmptyMultiplier"))); + multipliersLore.addLineLoreDescription(SpigotPrison.format(messages.getString("Lore.EmptyMultiplier"))); } } catch (NullPointerException ex){ - multipliersLore.add(SpigotPrison.format(messages.getString("Lore.EmptyMultiplier"))); + multipliersLore.addLineLoreDescription(SpigotPrison.format(messages.getString("Lore.EmptyMultiplier"))); } - ItemStack setCurrencyButton = createButton(XMaterial.EMERALD.parseItem(), setCurrencyLore, SpigotPrison.format("&3SellAll-Currency")); - ItemStack multipliersButton = createButton(XMaterial.PAPER.parseItem(), multipliersLore, SpigotPrison.format("&3Prestige-Multipliers")); - ItemStack blocksButton = createButton(XMaterial.DIAMOND_ORE.parseItem(), blocksLore, "&3Blocks-Shop"); - ItemStack closeGUI = createButton(XMaterial.RED_STAINED_GLASS_PANE.parseItem(), closeGUILore, SpigotPrison.format("&c" + "Close")); - - inv.setItem(0, blocksButton); - inv.setItem(8, multipliersButton); - inv.setItem(11, sellAllDelayButton); - inv.setItem(13, autoSellButton); - inv.setItem(15, setCurrencyButton); - inv.setItem(dimension - 1, closeGUI); + gui.addButton(new Button(15, XMaterial.EMERALD, setCurrencyLore, SpigotPrison.format("&3SellAll-Currency"))); + gui.addButton(new Button(8, XMaterial.PAPER, multipliersLore, SpigotPrison.format("&3Prestige-Multipliers"))); + gui.addButton(new Button(0, XMaterial.DIAMOND_ORE, blocksLore, "&3Blocks-Shop")); + gui.addButton(new Button(dimension-1, XMaterial.RED_STAINED_GLASS_PANE, closeGUILore, SpigotPrison.format("&c" + "Close"))); + gui.addButton(sellAllDelayButton); + gui.addButton(autoSellButton); - return inv; + gui.open(); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllDelayGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllDelayGUI.java index d8b51578c..eae2665d3 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllDelayGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllDelayGUI.java @@ -1,18 +1,13 @@ package tech.mcprison.prison.spigot.gui.sellall; import com.cryptomorin.xseries.XMaterial; -import org.bukkit.Bukkit; -import org.bukkit.Material; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotPrison; -import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; -import java.util.List; - /** * @author GABRYCA */ @@ -20,8 +15,6 @@ public class SellAllDelayGUI extends SpigotGUIComponents { private final Player p; private final int val; - private int dimension = 45; - private Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format("&3SellAll -> Delay")); public SellAllDelayGUI(Player p, int val){ @@ -33,72 +26,33 @@ public void open() { updateSellAllConfig(); - if (guiBuilder()) return; - - // Open the inventory - openGUI(p, inv); - } - - private boolean guiBuilder() { - try { - buttonsSetup(); - } catch (NullPointerException ex){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cThere's a null value in the GuiConfig.yml [broken]")); - ex.printStackTrace(); - return true; - } - return false; - } + int dimension = 45; + PrisonGUI gui = new PrisonGUI(p, dimension, "&3SellAll -> Delay"); - private void buttonsSetup() { + ButtonLore changeDecreaseValueLore = new ButtonLore(messages.getString("Lore.ClickToDecrease"), null); + ButtonLore confirmButtonLore = new ButtonLore(createLore(messages.getString("Lore.LeftClickToConfirm"), messages.getString("Lore.RightClickToCancel")), createLore(messages.getString("Lore.DelaySellAll") + val + "s")); + ButtonLore changeIncreaseValueLore = new ButtonLore(messages.getString("Lore.ClickToIncrease"), null); - // Create a new lore - List changeDecreaseValueLore; - changeDecreaseValueLore = createLore( - messages.getString("Lore.ClickToDecrease") - ); - List confirmButtonLore = createLore( - messages.getString("Lore.LeftClickToConfirm"), - messages.getString("Lore.DelaySellAll") + val + "s", - messages.getString("Lore.RightClickToCancel") - ); - List changeIncreaseValueLore = createLore( - messages.getString("Lore.ClickToIncrease") - ); - - Material decreaseMat = XMaterial.REDSTONE_BLOCK.parseMaterial(); - ItemStack decreaseStack = XMaterial.REDSTONE_BLOCK.parseItem(); + XMaterial decreaseMat = XMaterial.REDSTONE_BLOCK; + XMaterial increaseMat = XMaterial.EMERALD_BLOCK; // Decrease button - ItemStack decreaseOf1 = createButton(decreaseStack, changeDecreaseValueLore, SpigotPrison.format("&3Delay " + + val + " - 1" )); - inv.setItem(1, decreaseOf1); - ItemStack decreaseOf5 = createButton(new ItemStack(decreaseMat, 10), changeDecreaseValueLore, SpigotPrison.format("&3Delay " + val + " - 10")); - inv.setItem(10, decreaseOf5); - ItemStack decreaseOf10 = createButton(decreaseStack, changeDecreaseValueLore, SpigotPrison.format("&3Delay " + val + " - 100")); - inv.setItem(19, decreaseOf10); - ItemStack decreaseOf50 = createButton(decreaseStack, changeDecreaseValueLore, SpigotPrison.format("&3Delay " + val + " - 1000")); - inv.setItem(28, decreaseOf50); - ItemStack decreaseOf100 = createButton(decreaseStack, changeDecreaseValueLore, SpigotPrison.format("&3Delay " + val + " - 10000")); - inv.setItem(37, decreaseOf100); - + gui.addButton(new Button(1, decreaseMat, changeDecreaseValueLore, SpigotPrison.format("&3Delay " + + val + " - 1" ))); + gui.addButton(new Button(10, decreaseMat, 10, changeDecreaseValueLore, SpigotPrison.format("&3Delay " + val + " - 10"))); + gui.addButton(new Button(19, decreaseMat, changeDecreaseValueLore, "&3Delay " + val + " - 100")); + gui.addButton(new Button(28, decreaseMat, changeDecreaseValueLore, "&3Delay " + val + " - 1000")); + gui.addButton(new Button(37, decreaseMat, changeDecreaseValueLore, "&3Delay " + val + " - 10000")); // Create a button and set the position - ItemStack confirmButton = createButton(XMaterial.CLOCK.parseItem(), confirmButtonLore, SpigotPrison.format("&3Confirm: Delay " + val)); - inv.setItem(22, confirmButton); - - Material increaseMat = XMaterial.EMERALD_BLOCK.parseMaterial(); - ItemStack increaseStack = XMaterial.EMERALD_BLOCK.parseItem(); + gui.addButton(new Button(22, XMaterial.CLOCK, confirmButtonLore, "&3Confirm: Delay " + val)); // Increase button - ItemStack increseOf1 = createButton(increaseStack, changeIncreaseValueLore, SpigotPrison.format("&3Delay " + val + " + 1" )); - inv.setItem(7, increseOf1); - ItemStack increaseOf5 = createButton(new ItemStack(increaseMat, 10), changeIncreaseValueLore, SpigotPrison.format("&3Delay " + val + " + 10")); - inv.setItem(16, increaseOf5); - ItemStack increaseOf10 = createButton(increaseStack, changeIncreaseValueLore, SpigotPrison.format("&3Delay " + val + " + 100")); - inv.setItem(25, increaseOf10); - ItemStack increaseOf50 = createButton(increaseStack, changeIncreaseValueLore, SpigotPrison.format("&3Delay " + val + " + 1000")); - inv.setItem(34, increaseOf50); - ItemStack increaseOf100 = createButton(increaseStack, changeIncreaseValueLore, SpigotPrison.format("&3Delay " + val + " + 10000")); - inv.setItem(43, increaseOf100); + gui.addButton(new Button(7, increaseMat, changeIncreaseValueLore, "&3Delay " + val + " + 1")); + gui.addButton(new Button(16, increaseMat, 10, changeIncreaseValueLore, "&3Delay " + val + " + 10")); + gui.addButton(new Button(25, increaseMat, changeIncreaseValueLore,"&3Delay " + val + " + 100")); + gui.addButton(new Button(34, increaseMat, changeIncreaseValueLore, "&3Delay " + val + " + 1000")); + gui.addButton(new Button(43, increaseMat, changeIncreaseValueLore, "&3Delay " + val + " + 10000")); + + gui.open(); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllPlayerGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllPlayerGUI.java index 733036f05..5238edd6b 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllPlayerGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllPlayerGUI.java @@ -1,16 +1,15 @@ package tech.mcprison.prison.spigot.gui.sellall; -import org.bukkit.Bukkit; +import com.cryptomorin.xseries.XMaterial; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; import tech.mcprison.prison.output.Output; -import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.SpigotUtil; import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; -import java.util.List; import java.util.Set; /** @@ -19,76 +18,60 @@ public class SellAllPlayerGUI extends SpigotGUIComponents { private final Player p; + private final int startingItem; - public SellAllPlayerGUI(Player p){ + public SellAllPlayerGUI(Player p, int startingItem){ this.p = p; + this.startingItem = startingItem; } public void open() { - updateSellAllConfig(); - - Inventory inv = buttonsSetup(); - if (inv == null) return; - - openGUI(p, inv); - } - - private Inventory buttonsSetup() { + PrisonGUI gui = new PrisonGUI(p, 54, "&3Prison -> SellAll-Player"); boolean emptyInv = false; - try { if (sellAllConfig.getConfigurationSection("Items") == null) { emptyInv = true; } + if (sellAllConfig.getConfigurationSection("Items").getKeys(false).size() == 0){ + emptyInv = true; + } } catch (NullPointerException e){ emptyInv = true; } if (emptyInv){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.NoSellAllItems"))); - p.closeInventory(); - return null; + Output.get().sendWarn(new SpigotPlayer(p), messages.getString("Message.NoSellAllItems")); + return; } // Get the Items config section Set items = sellAllConfig.getConfigurationSection("Items").getKeys(false); - // Get the dimensions and if needed increases them - int dimension = (int) Math.ceil(items.size() / 9D) * 9; - - if (dimension > 54){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format(messages.getString("Message.TooManySellAllItems"))); - return null; - } - - // Inventory GUI. - Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format("&3Prison -> SellAll-Player")); - // Global strings. String loreValue = messages.getString("Lore.Value"); + int itemsAdded = 0, itemsRead = 0; for (String key : items) { - List itemsLore = createLore( - loreValue + sellAllConfig.getString("Items." + key + ".ITEM_VALUE") - ); + itemsRead++; - ItemStack item = createButton(SpigotUtil.getItemStack(SpigotUtil.getXMaterial(sellAllConfig.getString("Items." + key + ".ITEM_ID")), 1), itemsLore, SpigotPrison.format("&3" + sellAllConfig.getString("Items." + key + ".ITEM_ID"))); - inv.addItem(item); - } - return inv; - } + if (itemsRead >= startingItem) { - private boolean guiBuilder() { - try { - buttonsSetup(); - } catch (NullPointerException ex){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cThere's a null value in the GuiConfig.yml [broken]")); - ex.printStackTrace(); - return true; + if (startingItem != 0){ + gui.addButton(new Button(45, XMaterial.BOOK, new ButtonLore(messages.getString("Lore.ClickToPriorPage"), null), "&7Prior " + (startingItem - 45))); + } + + if (itemsAdded >= 45){ + gui.addButton(new Button(53, XMaterial.BOOK, new ButtonLore(messages.getString("Lore.ClickToNextPage"), null), "&7Next " + (startingItem + itemsAdded))); + } + + if (itemsAdded < 45) { + gui.addButton(new Button(null, SpigotUtil.getXMaterial(sellAllConfig.getString("Items." + key + ".ITEM_ID")), new ButtonLore(null, loreValue + sellAllConfig.getString("Items." + key + ".ITEM_VALUE")), "&3" + sellAllConfig.getString("Items." + key + ".ITEM_ID"))); + itemsAdded++; + } + } } - return false; + gui.open(); } - } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllPrestigesMultiplierGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllPrestigesMultiplierGUI.java index 66ec4df75..a0f219efb 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllPrestigesMultiplierGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllPrestigesMultiplierGUI.java @@ -1,14 +1,10 @@ package tech.mcprison.prison.spigot.gui.sellall; import com.cryptomorin.xseries.XMaterial; -import org.bukkit.Bukkit; -import org.bukkit.Material; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import tech.mcprison.prison.output.Output; -import tech.mcprison.prison.spigot.SpigotPrison; -import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; import java.util.List; @@ -20,8 +16,6 @@ public class SellAllPrestigesMultiplierGUI extends SpigotGUIComponents { private final Player p; private int counter; - private int dimension = 45; - private Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format("&3SellAll -> Multipliers")); public SellAllPrestigesMultiplierGUI(Player p, int counter){ this.p = p; @@ -32,24 +26,8 @@ public void open() { updateSellAllConfig(); - if (guiBuilder()) return; - - // Open the inventory - openGUI(p, inv); - } - - private boolean guiBuilder() { - try { - buttonsSetup(); - } catch (NullPointerException ex){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cThere's a null value in the GuiConfig.yml [broken]")); - ex.printStackTrace(); - return true; - } - return false; - } - - private void buttonsSetup() { + int dimension = 45; + PrisonGUI gui = new PrisonGUI(p, dimension, "&3SellAll -> Multipliers"); // Page elements. int pageSize = 45; @@ -68,34 +46,26 @@ private void buttonsSetup() { for (String prestige : sellAllConfig.getConfigurationSection("Multiplier").getKeys(false)) { if (flagValue == i) { - List loreMult = createLore( - lorePrestigeName + sellAllConfig.getString("Multiplier." + prestige + ".PRESTIGE_NAME"), - lorePrestigeMultiplier + sellAllConfig.getString("Multiplier." + prestige + ".MULTIPLIER"), - "", - loreClickToEdit, - loreClickToDelete - ); - ItemStack prestMultiplierButton = createButton(XMaterial.PAPER.parseItem(), loreMult, sellAllConfig.getString("Multiplier." + prestige + ".PRESTIGE_NAME")); + ButtonLore loreMult = new ButtonLore(createLore( + loreClickToEdit, + loreClickToDelete), createLore( + lorePrestigeName + sellAllConfig.getString("Multiplier." + prestige + ".PRESTIGE_NAME"), + lorePrestigeMultiplier + sellAllConfig.getString("Multiplier." + prestige + ".MULTIPLIER"))); - inv.addItem(prestMultiplierButton); + gui.addButton(new Button(null, XMaterial.PAPER, loreMult, sellAllConfig.getString("Multiplier." + prestige + ".PRESTIGE_NAME"))); } flagValue++; } } if (i < sellAllConfig.getConfigurationSection("Multiplier").getKeys(false).size()) { - List nextPageLore = createLore(messages.getString("Lore.ClickToNextPage")); - - ItemStack nextPageButton = createButton(Material.BOOK, 1, nextPageLore, "&7Next " + (i + 1)); - inv.setItem(53, nextPageButton); + gui.addButton(new Button(53, XMaterial.BOOK, new ButtonLore(messages.getString("Lore.ClickToNextPage"), null), "&7Next " + (i + 1))); } if (i >= (pageSize * 2)) { - List priorPageLore = createLore(messages.getString("Lore.ClickToPriorPage")); - - ItemStack priorPageButton = createButton(Material.BOOK, 1, priorPageLore, - "&7Prior " + (i - (pageSize * 2) - 1)); - inv.setItem(51, priorPageButton); + gui.addButton(new Button(51, XMaterial.BOOK, new ButtonLore(messages.getString("Lore.ClickToPriorPage"), null), "&7Prior " + (i - (pageSize * 2) - 1))); } + + gui.open(); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllPrestigesSetMultiplierGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllPrestigesSetMultiplierGUI.java index 1c470bc07..00fc1d507 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllPrestigesSetMultiplierGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllPrestigesSetMultiplierGUI.java @@ -1,18 +1,13 @@ package tech.mcprison.prison.spigot.gui.sellall; import com.cryptomorin.xseries.XMaterial; -import org.bukkit.Bukkit; -import org.bukkit.Material; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotPrison; -import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; -import java.util.List; - /** * @author GABRYCA */ @@ -21,8 +16,6 @@ public class SellAllPrestigesSetMultiplierGUI extends SpigotGUIComponents { private final Player p; private final double val; private final String prestigeName; - private int dimension = 45; - private Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format("&3Edit -> Multiplier")); public SellAllPrestigesSetMultiplierGUI(Player p, double val, String prestigeName){ this.p = p; @@ -34,73 +27,36 @@ public void open() { updateSellAllConfig(); - if (guiBuilder()) return; - - // Open the inventory - openGUI(p, inv); - } - - private boolean guiBuilder() { - try { - buttonsSetup(); - } catch (NullPointerException ex){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cThere's a null value in the GuiConfig.yml [broken]")); - ex.printStackTrace(); - return true; - } - return false; - } + int dimension = 45; + PrisonGUI gui = new PrisonGUI(p, dimension, "&3Edit -> Multiplier"); - private void buttonsSetup() { - - // Create a new lore - List changeDecreaseValueLore; - changeDecreaseValueLore = createLore( - messages.getString("Lore.ClickToDecrease") - ); - List confirmButtonLore = createLore( + ButtonLore changeDecreaseValueLore = new ButtonLore(messages.getString("Lore.ClickToDecrease"), null); + ButtonLore confirmButtonLore = new ButtonLore(createLore( messages.getString("Lore.LeftClickToConfirm"), - messages.getString("Lore.Multiplier") + "x" + val, - messages.getString("Lore.RightClickToCancel") - ); - List changeIncreaseValueLore = createLore( - messages.getString("Lore.ClickToIncrease") - ); + messages.getString("Lore.RightClickToCancel")), createLore(messages.getString("Lore.Multiplier") + "x" + val)); + ButtonLore changeIncreaseValueLore = new ButtonLore(messages.getString("Lore.ClickToIncrease"), null); - Material decreaseMat = XMaterial.REDSTONE_BLOCK.parseMaterial(); - ItemStack decreaseStack = XMaterial.REDSTONE_BLOCK.parseItem(); + XMaterial decreaseMat = XMaterial.REDSTONE_BLOCK; + XMaterial increaseMat = XMaterial.EMERALD_BLOCK; // Decrease button - ItemStack decreaseOf1 = createButton(decreaseStack, changeDecreaseValueLore, SpigotPrison.format("&3" + prestigeName + " " + val + " - 0.1" )); - inv.setItem(1, decreaseOf1); - ItemStack decreaseOf5 = createButton(new ItemStack(decreaseMat, 10), changeDecreaseValueLore, SpigotPrison.format("&3" + prestigeName + " " + val + " - 0.5")); - inv.setItem(10, decreaseOf5); - ItemStack decreaseOf10 = createButton(decreaseStack, changeDecreaseValueLore, SpigotPrison.format("&3" + prestigeName + " " + val + " - 1")); - inv.setItem(19, decreaseOf10); - ItemStack decreaseOf50 = createButton(decreaseStack, changeDecreaseValueLore, SpigotPrison.format("&3" + prestigeName + " " + val + " - 2")); - inv.setItem(28, decreaseOf50); - ItemStack decreaseOf100 = createButton(decreaseStack, changeDecreaseValueLore, SpigotPrison.format("&3" + prestigeName + " " + val + " - 5")); - inv.setItem(37, decreaseOf100); + gui.addButton(new Button(1, decreaseMat, changeDecreaseValueLore, SpigotPrison.format("&3" + prestigeName + " " + val + " - 0.1" ))); + gui.addButton(new Button(10, decreaseMat, 10, changeDecreaseValueLore, SpigotPrison.format("&3" + prestigeName + " " + val + " - 0.5"))); + gui.addButton(new Button(19, decreaseMat, changeDecreaseValueLore, SpigotPrison.format("&3" + prestigeName + " " + val + " - 1"))); + gui.addButton(new Button(28, decreaseMat, changeDecreaseValueLore, SpigotPrison.format("&3" + prestigeName + " " + val + " - 2"))); + gui.addButton(new Button(37, decreaseMat, changeDecreaseValueLore, SpigotPrison.format("&3" + prestigeName + " " + val + " - 5"))); // Create a button and set the position - ItemStack confirmButton = createButton(XMaterial.CLOCK.parseItem(), confirmButtonLore, SpigotPrison.format("&3Confirm: " + prestigeName + " " + val)); - inv.setItem(22, confirmButton); - - Material increaseMat = XMaterial.EMERALD_BLOCK.parseMaterial(); - ItemStack increaseStack = XMaterial.EMERALD_BLOCK.parseItem(); + gui.addButton(new Button(22, XMaterial.CLOCK, confirmButtonLore, SpigotPrison.format("&3Confirm: " + prestigeName + " " + val))); // Increase button - ItemStack increseOf1 = createButton(increaseStack, changeIncreaseValueLore, SpigotPrison.format("&3" + prestigeName + " " + val + " + 0.1" )); - inv.setItem(7, increseOf1); - ItemStack increaseOf5 = createButton(new ItemStack(increaseMat, 10), changeIncreaseValueLore, SpigotPrison.format("&3" + prestigeName + " " + val + " + 0.5")); - inv.setItem(16, increaseOf5); - ItemStack increaseOf10 = createButton(increaseStack, changeIncreaseValueLore, SpigotPrison.format("&3" + prestigeName + " " + val + " + 1")); - inv.setItem(25, increaseOf10); - ItemStack increaseOf50 = createButton(increaseStack, changeIncreaseValueLore, SpigotPrison.format("&3" + prestigeName + " " + val + " + 2")); - inv.setItem(34, increaseOf50); - ItemStack increaseOf100 = createButton(increaseStack, changeIncreaseValueLore, SpigotPrison.format("&3" + prestigeName + " " + val + " + 5")); - inv.setItem(43, increaseOf100); - } + gui.addButton(new Button(7, increaseMat, changeIncreaseValueLore, SpigotPrison.format("&3" + prestigeName + " " + val + " + 0.1" ))); + gui.addButton(new Button(16, increaseMat, 10, changeIncreaseValueLore, SpigotPrison.format("&3" + prestigeName + " " + val + " + 0.5"))); + gui.addButton(new Button(25, increaseMat, changeIncreaseValueLore, SpigotPrison.format("&3" + prestigeName + " " + val + " + 1"))); + gui.addButton(new Button(43, increaseMat, changeIncreaseValueLore, SpigotPrison.format("&3" + prestigeName + " " + val + " + 2"))); + gui.addButton(new Button(54, increaseMat, changeIncreaseValueLore, SpigotPrison.format("&3" + prestigeName + " " + val + " + 5"))); + gui.open(); + } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllPriceGUI.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllPriceGUI.java index 55de60a67..f50300764 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllPriceGUI.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/gui/sellall/SellAllPriceGUI.java @@ -1,14 +1,11 @@ package tech.mcprison.prison.spigot.gui.sellall; import com.cryptomorin.xseries.XMaterial; -import org.bukkit.Bukkit; -import org.bukkit.Material; import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import tech.mcprison.prison.output.Output; import tech.mcprison.prison.spigot.SpigotPrison; -import tech.mcprison.prison.spigot.game.SpigotPlayer; +import tech.mcprison.prison.spigot.gui.guiutility.Button; +import tech.mcprison.prison.spigot.gui.guiutility.ButtonLore; +import tech.mcprison.prison.spigot.gui.guiutility.PrisonGUI; import tech.mcprison.prison.spigot.gui.guiutility.SpigotGUIComponents; import java.util.List; @@ -21,8 +18,6 @@ public class SellAllPriceGUI extends SpigotGUIComponents { private final Player p; private final String itemID; private final Double val; - private int dimension = 45; - private Inventory inv = Bukkit.createInventory(null, dimension, SpigotPrison.format("&3SellAll -> ItemValue")); public SellAllPriceGUI(Player p, Double val, String itemID){ this.p = p; @@ -34,72 +29,34 @@ public void open() { updateSellAllConfig(); - if (guiBuilder()) return; + int dimension = 45; + PrisonGUI gui = new PrisonGUI(p, dimension, "&3SellAll -> ItemValue"); - // Open the inventory - openGUI(p, inv); - } - - private boolean guiBuilder() { - try { - buttonsSetup(); - } catch (NullPointerException ex){ - Output.get().sendWarn(new SpigotPlayer(p), SpigotPrison.format("&cThere's a null value in the GuiConfig.yml [broken]")); - ex.printStackTrace(); - return true; - } - return false; - } - - private void buttonsSetup() { + ButtonLore changeDecreaseValueLore = new ButtonLore(messages.getString("Lore.ClickToDecrease"), null); + ButtonLore confirmButtonLore = new ButtonLore(createLore( + messages.getString("Lore.LeftClickToConfirm"), messages.getString("Lore.RightClickToCancel")), createLore(messages.getString("Lore.Price2") + val)); + ButtonLore changeIncreaseValueLore = new ButtonLore(messages.getString("Lore.ClickToIncrease"), null); - // Create a new lore - List changeDecreaseValueLore; - changeDecreaseValueLore = createLore( - messages.getString("Lore.ClickToDecrease") - ); - List confirmButtonLore = createLore( - messages.getString("Lore.LeftClickToConfirm"), - messages.getString("Lore.Price2") + val, - messages.getString("Lore.RightClickToCancel") - ); - List changeIncreaseValueLore = createLore( - messages.getString("Lore.ClickToIncrease") - ); - - Material decreaseMat = XMaterial.REDSTONE_BLOCK.parseMaterial(); - ItemStack decreaseStack = XMaterial.REDSTONE_BLOCK.parseItem(); + XMaterial decreaseMat = XMaterial.REDSTONE_BLOCK; + XMaterial increaseMat = XMaterial.EMERALD_BLOCK; // Decrease button - ItemStack decreaseOf1 = createButton(decreaseStack, changeDecreaseValueLore, SpigotPrison.format("&3" + itemID + " " + val + " - 1" )); - inv.setItem(1, decreaseOf1); - ItemStack decreaseOf5 = createButton(new ItemStack(decreaseMat, 10), changeDecreaseValueLore, SpigotPrison.format("&3" + itemID + " " + val + " - 10")); - inv.setItem(10, decreaseOf5); - ItemStack decreaseOf10 = createButton(decreaseStack, changeDecreaseValueLore, SpigotPrison.format("&3" + itemID + " " + val + " - 100")); - inv.setItem(19, decreaseOf10); - ItemStack decreaseOf50 = createButton(decreaseStack, changeDecreaseValueLore, SpigotPrison.format("&3" + itemID + " " + val + " - 1000")); - inv.setItem(28, decreaseOf50); - ItemStack decreaseOf100 = createButton(decreaseStack, changeDecreaseValueLore, SpigotPrison.format("&3" + itemID + " " + val + " - 10000")); - inv.setItem(37, decreaseOf100); - + gui.addButton(new Button(1, decreaseMat, changeDecreaseValueLore, SpigotPrison.format("&3" + itemID + " " + val + " - 1" ))); + gui.addButton(new Button(10, decreaseMat, 10, changeDecreaseValueLore, SpigotPrison.format("&3" + itemID + " " + val + " - 10"))); + gui.addButton(new Button(19, decreaseMat, changeDecreaseValueLore, SpigotPrison.format("&3" + itemID + " " + val + " - 100"))); + gui.addButton(new Button(28, decreaseMat, changeDecreaseValueLore, SpigotPrison.format("&3" + itemID + " " + val + " - 1000"))); + gui.addButton(new Button(37, decreaseMat, changeDecreaseValueLore, SpigotPrison.format("&3" + itemID + " " + val + " - 10000"))); // Create a button and set the position - ItemStack confirmButton = createButton(XMaterial.TRIPWIRE_HOOK.parseItem(), confirmButtonLore, SpigotPrison.format("&3" + "Confirm: " + itemID + " " + val)); - inv.setItem(22, confirmButton); - - Material increaseMat = XMaterial.EMERALD_BLOCK.parseMaterial(); - ItemStack increaseStack = XMaterial.EMERALD_BLOCK.parseItem(); + gui.addButton(new Button(22, XMaterial.TRIPWIRE_HOOK, confirmButtonLore, SpigotPrison.format("&3" + "Confirm: " + itemID + " " + val))); // Increase button - ItemStack increseOf1 = createButton(increaseStack, changeIncreaseValueLore, SpigotPrison.format("&3" + itemID + " " + val + " + 1" )); - inv.setItem(7, increseOf1); - ItemStack increaseOf5 = createButton(new ItemStack(increaseMat, 10), changeIncreaseValueLore, SpigotPrison.format("&3" + itemID + " " + val + " + 10")); - inv.setItem(16, increaseOf5); - ItemStack increaseOf10 = createButton(increaseStack, changeIncreaseValueLore, SpigotPrison.format("&3" + itemID + " " + val + " + 100")); - inv.setItem(25, increaseOf10); - ItemStack increaseOf50 = createButton(increaseStack, changeIncreaseValueLore, SpigotPrison.format("&3" + itemID + " " + val + " + 1000")); - inv.setItem(34, increaseOf50); - ItemStack increaseOf100 = createButton(increaseStack, changeIncreaseValueLore, SpigotPrison.format("&3" + itemID + " " + val + " + 10000")); - inv.setItem(43, increaseOf100); + gui.addButton(new Button(7, increaseMat, changeIncreaseValueLore, SpigotPrison.format("&3" + itemID + " " + val + " + 1" ))); + gui.addButton(new Button(16, increaseMat, 10, changeIncreaseValueLore, SpigotPrison.format("&3" + itemID + " " + val + " + 10"))); + gui.addButton(new Button(25, increaseMat, changeIncreaseValueLore, SpigotPrison.format("&3" + itemID + " " + val + " + 100"))); + gui.addButton(new Button(34, increaseMat, changeIncreaseValueLore, SpigotPrison.format("&3" + itemID + " " + val + " + 1000"))); + gui.addButton(new Button(43, increaseMat, changeIncreaseValueLore, SpigotPrison.format("&3" + itemID + " " + val + " + 10000"))); + + gui.open(); } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/LuckPermissions.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/LuckPermissions.java index 7790693fc..7b80a6102 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/LuckPermissions.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/LuckPermissions.java @@ -102,7 +102,11 @@ public List getPermissions(Player holder, boolean detailed) { public boolean hasIntegrated() { return (permsWrapper != null); } - + + @Override + public void disableIntegration() { + permsWrapper = null; + } @Override public String getPluginSourceURL() { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/LuckPermissionsWrapper.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/LuckPermissionsWrapper.java index 242c53aa6..39975c8e7 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/LuckPermissionsWrapper.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/LuckPermissionsWrapper.java @@ -51,7 +51,8 @@ protected void removeGroupPermission(Player holder, String permission) { editPermission(holder.getUUID(), permission, LPPermissionType.PERM_GROUP_REMOVE ); } - protected void editPermission(UUID uuid, String permission, LPPermissionType permissionType) { + @SuppressWarnings( "deprecation" ) + protected void editPermission(UUID uuid, String permission, LPPermissionType permissionType) { // get the user User user = api.getUser(uuid); if (user == null) { diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/LuckPerms5.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/LuckPerms5.java index 531c27935..02c8ef482 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/LuckPerms5.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/LuckPerms5.java @@ -94,7 +94,12 @@ public List getPermissions(Player holder, boolean detailed) { public boolean hasIntegrated() { return (permsWrapper != null); } - + + @Override + public void disableIntegration() { + permsWrapper = null; + } + @Override public String getPluginSourceURL() { return "https://luckperms.net/"; diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/VaultPermissions.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/VaultPermissions.java index 0cf68dd7d..b00bb10b1 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/VaultPermissions.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/permissions/VaultPermissions.java @@ -26,6 +26,7 @@ import tech.mcprison.prison.integration.PermissionIntegration; import tech.mcprison.prison.internal.Player; +import tech.mcprison.prison.internal.World; import tech.mcprison.prison.spigot.game.SpigotPlayer; /** @@ -92,7 +93,12 @@ public String getDisplayName() { @Override public boolean hasIntegrated() { return permissions != null; } - + + @Override + public void disableIntegration() { + permissions = null; + } + /** *

Vault is unable to return a list of permissions for the players when they * are offline. Vault can only return lists of groups the player is in. And @@ -107,7 +113,7 @@ public List getPermissions( Player holder, boolean detailed ) { boolean hasGroupSupport = permissions.hasGroupSupport(); - if ( holder.isOnline() ) { + if ( holder.isOnline() && holder instanceof SpigotPlayer ) { results.add( String.format( "[vault: Group support is %senabled.]", (hasGroupSupport ? "" : "NOT ")) ); @@ -116,12 +122,22 @@ public List getPermissions( Player holder, boolean detailed ) { for ( String group : groups ) { results.add( group ); } + + } + + else { + results.add( "[vault: Player is offline. Perms cannot be accessed.]" ); } -// else { -// results.add( "[vault: Player is offline. Perms cannot be accessed.]" ); -// } return results; } + + public boolean checkPermission( Player holder, World world, String permission ) { + + SpigotPlayer player = (SpigotPlayer) holder; + + return permissions.playerHas( world.getName(), player.getWrapper(), permission ); + + } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/MVdWPlaceholderIntegration.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/MVdWPlaceholderIntegration.java index 383191dfc..0f20ca184 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/MVdWPlaceholderIntegration.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/MVdWPlaceholderIntegration.java @@ -9,6 +9,7 @@ import tech.mcprison.prison.internal.Player; import tech.mcprison.prison.mines.PrisonMines; import tech.mcprison.prison.mines.managers.MineManager; +import tech.mcprison.prison.output.Output; import tech.mcprison.prison.placeholders.PlaceHolderKey; import tech.mcprison.prison.placeholders.PlaceholderAttribute; import tech.mcprison.prison.placeholders.PlaceholderIntegration; @@ -46,13 +47,30 @@ public void integrate() { if ( isRegistered()) { try { if ( Bukkit.getPluginManager().isPluginEnabled(getProviderName())) { - placeholderWrapper = new MVdWPlaceholderIntegrationWrapper(getProviderName()); + + + // The integration was written for MVdW v3.0.0, but if used with older versions + // it will fail. + + // This will fail if the version of mvdw is v2.x.x, which is what we want: + Class.forName("be.maximvdw.placeholderapi.PlaceholderAPI", false, getClass().getClassLoader()); + + MVdWPlaceholderIntegrationWrapper wrap = new MVdWPlaceholderIntegrationWrapper(getProviderName()); + + placeholderWrapper = wrap; PrisonAPI.getIntegrationManager().addDeferredInitialization( this ); } } - catch ( NoClassDefFoundError | IllegalStateException e ) { + catch ( NoClassDefFoundError e ) { // ignore this exception since it means the plugin was not loaded + Output.get().logWarn( "Attempted to enable the MVdWPlaceholderIntegration but it failed to find the " + + "class 'be.maximvdw.placeholderapi.PlaceholderAPI'. This could happen when using " + + "MVdWPlaceholderApi v2.x.x. Prison ONLY support MVdW v3.x.x. " + + "&c****&7 Try using PlaceholderAPI (papi) instead. &c****" ); + } + catch ( IllegalStateException e ) { + // ignore ... plugin is not loaded } catch ( Exception e ) { e.printStackTrace(); @@ -100,7 +118,8 @@ public void deferredInitialization() if ( !placeHolderKey.getPlaceholder().isSuppressed() ) { registerPlaceholder(placeHolderKey.getKey(), player -> Text.translateAmpColorCodes( - mm.getTranslateMinesPlaceHolder( placeHolderKey, (PlaceholderAttribute) null ) + mm.getTranslateMinesPlaceHolder( placeHolderKey, + (PlaceholderAttribute) null, -1 ) )); if ( !registered ) { registered = true; @@ -132,6 +151,11 @@ public boolean hasIntegrated() { return (placeholderWrapper != null); } + @Override + public void disableIntegration() { + placeholderWrapper = null; + } + @Override public String getAlternativeInformation() { return null; diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/PlaceHolderAPIIntegration.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/PlaceHolderAPIIntegration.java index d60cb9b12..786643943 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/PlaceHolderAPIIntegration.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/PlaceHolderAPIIntegration.java @@ -58,7 +58,12 @@ public void deferredInitialization() { public boolean hasIntegrated() { return (placeHolderWrapper != null); } - + + @Override + public void disableIntegration() { + placeHolderWrapper = null; + } + @Override public String getAlternativeInformation() { return null; diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/SpigotPlaceholders.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/SpigotPlaceholders.java index 7677ffa56..a10274ecd 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/SpigotPlaceholders.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/placeholder/SpigotPlaceholders.java @@ -14,7 +14,7 @@ import tech.mcprison.prison.output.Output; import tech.mcprison.prison.placeholders.PlaceHolderKey; import tech.mcprison.prison.placeholders.PlaceholderAttribute; -import tech.mcprison.prison.placeholders.PlaceholderManager.PlaceHolderFlags; +import tech.mcprison.prison.placeholders.PlaceholderManager.PlaceholderFlags; import tech.mcprison.prison.placeholders.PlaceholderManager.PrisonPlaceHolders; import tech.mcprison.prison.placeholders.PlaceholderResults; import tech.mcprison.prison.placeholders.Placeholders; @@ -28,8 +28,8 @@ public class SpigotPlaceholders @Override - public Map getPlaceholderDetailCounts() { - Map placeholderDetails = new TreeMap<>(); + public Map getPlaceholderDetailCounts() { + Map placeholderDetails = new TreeMap<>(); List placeholders = new ArrayList<>(); @@ -39,6 +39,10 @@ public Map getPlaceholderDetailCounts() { if ( pm != null ) { placeholders.addAll( pm.getTranslatedPlaceHolderKeys() ); } + RankManager rm = PrisonRanks.getInstance().getRankManager(); + if ( rm != null ) { + placeholders.addAll( rm.getTranslatedPlaceHolderKeys() ); + } } if ( PrisonMines.getInstance() != null && PrisonMines.getInstance().isEnabled() ) { @@ -49,7 +53,7 @@ public Map getPlaceholderDetailCounts() { } for ( PlaceHolderKey phKey : placeholders ) { - for ( PlaceHolderFlags flag : phKey.getPlaceholder().getFlags() ) { + for ( PlaceholderFlags flag : phKey.getPlaceholder().getFlags() ) { int count = 0; @@ -75,6 +79,12 @@ public int getPlaceholderCount() { placeholdersRawCount += placeholderPlayerKeys.size(); } + RankManager rm = PrisonRanks.getInstance().getRankManager(); + if ( rm != null ) { + List placeholderPlayerKeys = rm.getTranslatedPlaceHolderKeys(); + placeholdersRawCount += placeholderPlayerKeys.size(); + + } } @@ -106,6 +116,17 @@ public int getPlaceholderRegistrationCount() { } } } + RankManager rm = PrisonRanks.getInstance().getRankManager(); + if ( rm != null ) { + List placeholderPlayerKeys = rm.getTranslatedPlaceHolderKeys(); + + for ( PlaceHolderKey placeHolderKey : placeholderPlayerKeys ) { + if ( !placeHolderKey.getPlaceholder().isSuppressed() ) { + placeholdersRegistered++; + } + } + } + } @@ -133,6 +154,10 @@ public int getPlaceholderRegistrationCount() { * but it is strictly just the placeholder. *

* + *

NOTE: Not sure if this can include a placeholder attribute??? + *

+ * + * *

This is a centrally located placeholder translator that is able * to access both the PlayerManager (ranks) and the MineManager (mines). *

@@ -156,6 +181,15 @@ public String placeholderTranslate(UUID playerUuid, String playerName, String id if ( pm != null ) { results = pm.getTranslatePlayerPlaceHolder( playerUuid, playerName, identifier ); } + + RankManager rm = PrisonRanks.getInstance().getRankManager(); + if ( rm != null && results == null ) { + results = rm.getTranslateRanksPlaceHolder( identifier ); + + if ( results == null ) { + results = rm.getTranslateRankPlayersPlaceHolder( playerUuid, playerName, identifier ); + } + } } // If it did not match on a player placeholder, then try mines: @@ -201,35 +235,16 @@ public String placeholderTranslateText( String text) { for ( PlaceHolderKey placeHolderKey : placeholderKeys ) { - String key1 = "{" + placeHolderKey.getKey(); - String key2 = "}"; + PlaceholderResults identifier = placeHolderKey.getIdentifier( results ); - int idx = results.indexOf( key1 ); - int idx2 = idx == -1 ? -1 : results.indexOf( key2, idx ); - if ( idx > -1 && idx2 > -1 ) { - - String identifier = results.substring( idx + 1, idx2 ); - -// String msg = "&a##^^## &7key1=" + key1 + " key2=" + key2 + " idx=" + idx + -// "idx2= " + idx2 + " identifier=[" + identifier + "] "; -// Output.get().logInfo( msg ); - - String replacement = mm.getTranslateMinesPlaceHolder( placeHolderKey, identifier ); - if ( replacement == null ) { - replacement = ""; - } - - - results = placeholderReplace( results, "{" + identifier + "}", replacement ); -// results = results.replace("{" + identifier + "}", replacement ); + + if ( results != null && identifier != null && identifier.hasResults() ) { + + results = placeholderReplace( results, identifier.getEscapedIdentifier(), + mm.getTranslateMinesPlaceHolder( placeHolderKey, + identifier.getIdentifier(), identifier.getNumericSequence() ) ); + } - } - - //String key = "{" + placeHolderKey.getKey() + "}"; -// if ( results.contains( key )) { -// results = results.replace(key, -// mm.getTranslateMinesPlaceHolder( placeHolderKey ) ); -// } } } } @@ -272,7 +287,8 @@ public String placeholderTranslateText( String text) { */ private String placeholderReplace( String text, String placeholder, String target ) { - return text.replaceAll( "(?i)" + Pattern.quote(placeholder) , target ); + return text == null || placeholder == null || target == null ? + text : text.replaceAll( "(?i)" + Pattern.quote(placeholder) , target ); } @@ -298,7 +314,6 @@ public String placeholderTranslateText( UUID playerUuid, String playerName, Stri PrisonRanks.getInstance().isEnabled() && playerUuid != null ) { PlayerManager pm = PrisonRanks.getInstance().getPlayerManager(); - List placeholderKeys = pm.getTranslatedPlaceHolderKeys(); for ( PlaceHolderKey placeHolderKey : placeholderKeys ) { @@ -310,37 +325,23 @@ public String placeholderTranslateText( UUID playerUuid, String playerName, Stri results = placeholderReplace( results, identifier.getEscapedIdentifier(), pm.getTranslatePlayerPlaceHolder( playerUuid, playerName, identifier.getIdentifier() ) ); -// results = results.replace( identifier.getEscapedIdentifier(), -// pm.getTranslatePlayerPlaceHolder( playerUuid, playerName, identifier.getIdentifier() ) ); } + } + + + RankManager rm = PrisonRanks.getInstance().getRankManager(); + placeholderKeys = rm.getTranslatedPlaceHolderKeys(); + + for ( PlaceHolderKey placeHolderKey : placeholderKeys ) { -// // Rank in to an issue with placeholders: prison_mbm_minename and prison_mbm_pm, -// // because the mine P has a placeholder prison_mbm_p which gets hit for the -// // prison_mbm_pm. So to zero in on the correct placeholder, but bracket the end -// // of the placeholder with either } or :: to ensure the correct association. -// String test1 = "{" + placeHolderKey.getKey().toLowerCase() + "}"; -// String test2 = "{" + placeHolderKey.getKey().toLowerCase() + -// PlaceholderManager.PRISON_PLACEHOLDER_ATTRIBUTE_SEPARATOR; -// -// String resultsLowercase = results.toLowerCase(); -// if ( resultsLowercase.contains( test1 ) || resultsLowercase.contains( test2 ) ) { -// -// // The key1 and key2 helps ensure that the full placeholder, -// // including the attribute, is replaced: -// String key1 = "{" + placeHolderKey.getKey().toLowerCase(); -// String key2 = "}"; -// -// int idx = resultsLowercase.indexOf( key1 ); -// int idx2 = ( idx == -1 ? -1 : resultsLowercase.indexOf( key2, idx + key1.length() - 1 ) ); -// if ( idx > -1 && idx2 > -1 ) { -// -// String identifier = results.substring( idx + 1, idx2 ); -// -// results = results.replace("{" + identifier + "}", -// pm.getTranslatePlayerPlaceHolder( playerUuid, playerName, identifier ) ); -// } -// } - + PlaceholderResults identifier = placeHolderKey.getIdentifier( results ); + + if ( results != null && identifier != null && identifier.hasResults() ) { + + + results = placeholderReplace( results, identifier.getEscapedIdentifier(), + rm.getTranslateRankPlayersPlaceHolder( playerUuid, playerName, identifier.getIdentifier() ) ); + } } } @@ -362,42 +363,11 @@ public String placeholderTranslateText( UUID playerUuid, String playerName, Stri results = placeholderReplace( results, identifier.getEscapedIdentifier(), mm.getTranslatePlayerMinesPlaceHolder( playerUuid, playerName, - placeHolderKey, identifier.getIdentifier() ) ); + placeHolderKey, identifier.getIdentifier(), + identifier.getNumericSequence() ) ); -// results = results.replace( identifier.getEscapedIdentifier(), -// mm.getTranslatePlayerMinesPlaceHolder( playerUuid, playerName, -// placeHolderKey, identifier.getIdentifier() ) ); } - -// // Rank in to an issue with placeholders: prison_mbm_minename and prison_mbm_pm, -// // because the mine P has a placeholder prison_mbm_p which gets hit for the -// // prison_mbm_pm. So to zero in on the correct placeholder, but bracket the end -// // of the placeholder with either } or :: to ensure the correct association. -// String test1 = "{" + placeHolderKey.getKey() + "}"; -// String test2 = "{" + placeHolderKey.getKey() + -// PlaceholderManager.PRISON_PLACEHOLDER_ATTRIBUTE_SEPARATOR; -// if ( results.contains( test1 ) || results.contains( test2 ) ) { -// -// // The key1 and key2 helps ensure that the full placeholder, -// // including the attribute, is replaced: -// String key1 = "{" + placeHolderKey.getKey(); -// String key2 = "}"; -// -// int idx = results.indexOf( key1 ); -// if ( idx > -1 && results.indexOf( key2, idx ) > -1 ) { -// -// String identifier = results.substring( idx + 1, results.indexOf( key2, idx ) ); -// String target = "{" + identifier + "}"; -// -// String replacement = mm.getTranslatePlayerMinesPlaceHolder( -// playerUuid, playerName, placeHolderKey, identifier ); -// -// results = results.replace( target, -// (replacement == null ? "" : replacement) ); -// } -// } - } } @@ -455,19 +425,29 @@ public List placeholderSearch( UUID playerUuid, String playerName, Strin String value = null; + // Note: STATSMINES will not work here since the sequence is not being addressed. - if ( mm != null && (placeHolderKey.getPlaceholder().hasFlag( PlaceHolderFlags.MINES ) || - placeHolderKey.getPlaceholder().hasFlag( PlaceHolderFlags.PLAYERMINES ))) { + if ( mm != null && (placeHolderKey.getPlaceholder().hasFlag( PlaceholderFlags.MINES ) || + placeHolderKey.getPlaceholder().hasFlag( PlaceholderFlags.STATSMINES ))) { PlaceholderAttribute attribute = null; - value = mm.getTranslateMinesPlaceHolder( placeHolderKey, attribute ); + value = mm.getTranslateMinesPlaceHolder( placeHolderKey, attribute, -1 ); } - else if ( pm != null && (placeHolderKey.getPlaceholder().hasFlag( PlaceHolderFlags.PLAYER ) || - placeHolderKey.getPlaceholder().hasFlag( PlaceHolderFlags.LADDERS ))) { + if ( mm != null && (placeHolderKey.getPlaceholder().hasFlag( PlaceholderFlags.MINEPLAYERS ))) { + PlaceholderAttribute attribute = null; + value = mm.getTranslatePlayerMinesPlaceHolder( playerUuid, playerName, placeHolderKey, + attribute, -1 ); + } + else if ( pm != null && (placeHolderKey.getPlaceholder().hasFlag( PlaceholderFlags.PLAYER ) || + placeHolderKey.getPlaceholder().hasFlag( PlaceholderFlags.LADDERS ))) { value = pm.getTranslatePlayerPlaceHolder( playerUuid, playerName, placeHolderKey, null ); } - else if ( rm != null && (placeHolderKey.getPlaceholder().hasFlag( PlaceHolderFlags.RANKS )) ) { + else if ( rm != null && placeHolderKey.getPlaceholder().hasFlag( PlaceholderFlags.RANKS ) ) { value = rm.getTranslateRanksPlaceHolder( placeHolderKey, null ); } + else if ( rm != null && (placeHolderKey.getPlaceholder().hasFlag( PlaceholderFlags.RANKPLAYERS ) || + placeHolderKey.getPlaceholder().hasFlag( PlaceholderFlags.STATSRANKS )) ) { + value = rm.getTranslateRankPlayersPlaceHolder( playerUuid, playerName, placeHolderKey, null ); + } String placeholderAlias = ( placeHolderKey.getAliasName() == null ? null : "{" + placeHolderKey.getAliasName() + "}"); @@ -565,8 +545,8 @@ public void printPlaceholderStats() { Output.get().logInfo( "Total placeholders generated: %d", getPlaceholderCount() ); - Map phDetails = getPlaceholderDetailCounts(); - for ( PlaceHolderFlags key : phDetails.keySet() ) { + Map phDetails = getPlaceholderDetailCounts(); + for ( PlaceholderFlags key : phDetails.keySet() ) { Output.get().logInfo( " %s: %d", key.name(), phDetails.get( key ) ); diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java index 6fd383835..463178e6a 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/sellall/SellAllUtil.java @@ -4,7 +4,13 @@ import java.io.File; import java.io.IOException; import java.text.DecimalFormat; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; import org.bukkit.Bukkit; import org.bukkit.Material; @@ -21,12 +27,15 @@ import at.pcgamingfreaks.Minepacks.Bukkit.API.Backpack; import tech.mcprison.prison.Prison; import tech.mcprison.prison.PrisonAPI; +import tech.mcprison.prison.cache.PlayerCache; import tech.mcprison.prison.integration.EconomyCurrencyIntegration; import tech.mcprison.prison.modules.Module; import tech.mcprison.prison.modules.ModuleManager; import tech.mcprison.prison.output.Output; import tech.mcprison.prison.placeholders.PlaceholdersUtil; import tech.mcprison.prison.ranks.PrisonRanks; +import tech.mcprison.prison.ranks.data.PlayerRank; +import tech.mcprison.prison.ranks.data.Rank; import tech.mcprison.prison.ranks.data.RankPlayer; import tech.mcprison.prison.spigot.SpigotPrison; import tech.mcprison.prison.spigot.backpacks.BackpacksUtil; @@ -44,7 +53,7 @@ public class SellAllUtil { private static SellAllUtil instance; - private final boolean isEnabled = isEnabled(); +// private final boolean isEnabled = isEnabled(); private File sellAllFile = new File(SpigotPrison.getInstance().getDataFolder() + "/SellAllConfig.yml"); public Configuration sellAllConfig = SpigotPrison.getInstance().updateSellAllConfig(); public static List activePlayerDelay = new ArrayList<>(); @@ -1510,7 +1519,7 @@ private boolean sellAllPlayerGUI(Player p) { // Check if the sender has the required permission. String permission = sellAllConfig.getString("Options.Player_GUI_Permission"); if (permission != null && p.hasPermission(permission)) { - SellAllPlayerGUI gui = new SellAllPlayerGUI(p); + SellAllPlayerGUI gui = new SellAllPlayerGUI(p, 0); gui.open(); // If missing will send a missing permission error message. } else { @@ -1518,7 +1527,7 @@ private boolean sellAllPlayerGUI(Player p) { } // Because a permission isn't required, it'll open directly the GUI. } else { - SellAllPlayerGUI gui = new SellAllPlayerGUI(p); + SellAllPlayerGUI gui = new SellAllPlayerGUI(p, 0); gui.open(); } return true; @@ -1572,7 +1581,7 @@ private boolean addMultiplierConditions(String prestige) { return true; } - boolean isInPrestigeLadder = rankPlugin.getLadderManager().getLadder("prestiges").containsRank(rankPlugin.getRankManager().getRank(prestige).getId()); + boolean isInPrestigeLadder = rankPlugin.getLadderManager().getLadder("prestiges").containsRank(rankPlugin.getRankManager().getRank(prestige)); if (!isInPrestigeLadder) { return true; } @@ -1582,10 +1591,14 @@ private boolean addMultiplierConditions(String prestige) { private double getMultiplierByRank(SpigotPlayer sPlayer, Module module, double multiplier) { if (module != null) { PrisonRanks rankPlugin = (PrisonRanks) module; - if (rankPlugin.getPlayerManager().getPlayer(sPlayer.getUUID(), sPlayer.getName()) != null) { + if (rankPlugin.getPlayerManager().getPlayer(sPlayer) != null) { String playerRankName; try { - playerRankName = rankPlugin.getPlayerManager().getPlayer(sPlayer.getUUID(), sPlayer.getName()).getRank("prestiges").getName(); + RankPlayer rankPlayer = rankPlugin.getPlayerManager().getPlayer(sPlayer); + PlayerRank pRank = rankPlayer == null ? null : rankPlayer.getRank("prestiges"); + Rank rank = pRank == null ? null : pRank.getRank(); + + playerRankName = rank == null ? null : rank.getName(); } catch (NullPointerException ex) { playerRankName = null; } @@ -1667,6 +1680,10 @@ private double getMoneyFinal(Player player, boolean removeItems) { moneyToGive = moneyToGive * getMultiplier(sPlayer); } + // Log the amount of money earned to generate the average earned per minute for the player: + if ( moneyToGive > 0 ) { + PlayerCache.getInstance().addPlayerEarnings( sPlayer, moneyToGive ); + } return moneyToGive; } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtils.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtils.java index 55598fb36..34e5b59fa 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtils.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtils.java @@ -194,21 +194,19 @@ protected int intValue( String value, int defaultValue, int rangeLow, int rangeH int results = defaultValue; if ( value != null && !value.trim().isEmpty() ) { + try { + results = Integer.parseInt( value ); + } + catch ( NumberFormatException e ) { + // Not a valid number so ignore + } - } - - try { - results = Integer.parseInt( value ); - } - catch ( NumberFormatException e ) { - // Not a valid number so ignore - } - - if ( results < rangeLow ) { - results = rangeLow; - } - else if ( results > rangeHigh ) { - results = rangeHigh; + if ( results < rangeLow ) { + results = rangeLow; + } + else if ( results > rangeHigh ) { + results = rangeHigh; + } } return results; @@ -229,6 +227,71 @@ public int parseInt(String s){ return number; } + /** + *

Parses a value to a float. It uses the supplied default value and + * also constrains the results by the parameters. + *

+ * + * @param value + * @param defaultValue + * @param rangeLow + * @param rangeHigh + * @return + */ + protected float floatValue( String value, float defaultValue, float rangeLow, float rangeHigh ) { + float results = defaultValue; + + if ( value != null && !value.trim().isEmpty() ) { + try { + results = Float.parseFloat( value ); + } + catch ( NumberFormatException e ) { + // Not a valid number so ignore + } + + if ( results < rangeLow ) { + results = rangeLow; + } + else if ( results > rangeHigh ) { + results = rangeHigh; + } + } + + return results; + } + /** + *

Parses a value to a double. It uses the supplied default value and + * also constrains the results by the parameters. + *

+ * + * @param value + * @param defaultValue + * @param rangeLow + * @param rangeHigh + * @return + */ + protected double doubleValue( String value, double defaultValue, double rangeLow, double rangeHigh ) { + double results = defaultValue; + + if ( value != null && !value.trim().isEmpty() ) { + try { + results = Double.parseDouble( value ); + } + catch ( NumberFormatException e ) { + // Not a valid number so ignore + } + + if ( results < rangeLow ) { + results = rangeLow; + } + else if ( results > rangeHigh ) { + results = rangeHigh; + } + } + + return results; + } + public String getPluginName() { return pluginName; } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsModule.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsModule.java index 9e65294c4..b85a4ea4c 100644 --- a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsModule.java +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsModule.java @@ -97,6 +97,31 @@ public void enable() { } + if ( isEnabled( "utils.sounds.enabled", true ) ) { + + PrisonUtilsSounds utils = new PrisonUtilsSounds(); + + utils.setEnableSoundEffects( isEnabled( "utils.sounds.playSound", true ) ); + + Prison.get().getCommandHandler().registerCommands( utils ); + + } + + if ( isEnabled( "utils.titles.enabled", true ) ) { + + PrisonUtilsTitles utils = new PrisonUtilsTitles(); + + utils.setEnableTitlesTitle( isEnabled( "utils.titles.title", true ) ); + utils.setEnableTitlesSubtitle( isEnabled( "utils.titles.subtitle", true ) ); + utils.setEnableTitlesActionBar( isEnabled( "utils.titles.actionBar", true ) ); + utils.setEnableTitlesClear( isEnabled( "utils.titles.clear", true ) ); + utils.setEnableTitlesReset( isEnabled( "utils.titles.reset", true ) ); + utils.setEnableTitlesTimes( isEnabled( "utils.titles.times", true ) ); + + Prison.get().getCommandHandler().registerCommands( utils ); + + } + } } diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsSounds.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsSounds.java new file mode 100644 index 000000000..1b5d23cb9 --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsSounds.java @@ -0,0 +1,170 @@ +package tech.mcprison.prison.spigot.utils; + +import java.util.Arrays; + +import org.bukkit.Sound; +import org.bukkit.entity.LivingEntity; + +import tech.mcprison.prison.commands.Arg; +import tech.mcprison.prison.commands.Command; +import tech.mcprison.prison.internal.CommandSender; +import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.spigot.game.SpigotPlayer; + +public class PrisonUtilsSounds + extends PrisonUtils +{ + private boolean enableSoundEffects = false; + + public PrisonUtilsSounds() { + super(); + + } + + /** + *

There is no initialization needed for these commands. + *

+ * + *

This function must return a value of true to indicate that this + * set of commands are enabled. If it is set to false, then these + * commands will not be registered when prison is loaded. + *

+ * + * @return + */ + @Override + protected Boolean initialize() + { + return true; + } + + + @Command(identifier = "prison utils sounds", + description = "Plays a sound effect to a player", + onlyPlayers = false, + permissions = "prison.utils.sounds", + altPermissions = "prison.utils.sounds.others") + public void utilPotionEffects( CommandSender sender, + @Arg(name = "playerName", description = "Player name") String playerName, + @Arg(name = "soundName", description = "A sound name. Use 'list ' to " + + "get a list of availble sounds (50 per page).", def = "list") String soundName, + + @Arg(name = "volume", description = "Volume of a sound. " + + "Optional. Default 10.0. (0.0 to 100.0).", def = "10.0") String volumeValue, + @Arg(name = "pitch", description = "Pitch of a sound. " + + "Optional. Default 1.0. (0.0 to 10.0)", def = "1.0") String pitchValue + +// , +// @Wildcard(join=true) +// @Arg(name = "options", +// description = "Options [op1 op2]", +// def = "") String options + ) { + + if ( !isEnableSoundEffects() ) { + + Output.get().logInfo( "Prison's utils command sound is disabled in modules.yml." ); + } + else { + + + if ( "list".equalsIgnoreCase( playerName ) || "list".equalsIgnoreCase( soundName ) ) { + + int page = intValue( soundName, -1, 1, 100 ); + if ( page == -1 ) { + page = intValue( volumeValue, 1, 1, 100 ); + + } + + StringBuilder sb = new StringBuilder(); + + int totalCount = Sound.values().length; + int pageSize = 50; + int start = (page - 1) * pageSize + 1; + int end = start + pageSize - 1; + int maxPage = (int) Math.ceil( totalCount / pageSize ); + + Sound[] sounds = Arrays.copyOfRange( Sound.values(), start, end ); + + for ( Sound sound : sounds ) { + sb.append( sound.name().toLowerCase() ).append( ' ' ); + } + + sender.sendMessage( String.format( "&7Valid sound names. Page %d of %d of %s: %s", + page, maxPage, totalCount, sb.toString() ) ); + + return; + } + + // First try to get the sound from the player name. Try playerName + // first since that's where it will be if playerName is not provided. + Sound sound = soundFromString( playerName ); + if ( sound == null ) { + // Try from potionName: + sound = soundFromString( soundName ); + } + else { + // if sound was in playerName, then need to shift all parameters + // over by one. +// options = options == null ? duration : options + " " + duration; + pitchValue = volumeValue; + volumeValue = soundName; + soundName = playerName; + playerName = null; + } + + if ( soundName == null ) { + sender.sendMessage( + "&7Unable to play a sound without a sound name. Please select " + + "one and try again. Use 'list ' to see what's available." ); + + return; + } + + SpigotPlayer player = checkPlayerPerms( sender, playerName, + "prison.utils.sound", "prison.utils.sound.others" ); + + + /** + * The volume of the sound. This will range from a range of 0.0 to 100.0, with + * a default value of 10.0. + * + */ + float volume = floatValue( volumeValue, 10.0f, 0.0f, 100.0f ); + + + /** + * The pitch of the sound. This will range from 0.0 to 10.0, with the + * default value of 1.0. + */ + float pitch = floatValue( pitchValue, 1.0f, 0.0f, 10.0f ); + + + LivingEntity entity = player.getWrapper(); + + entity.getWorld().playSound( entity.getLocation(), sound, volume, pitch ); + + } + } + + + public Sound soundFromString( String soundName ) { + Sound results = null; + + for ( Sound sound : Sound.values() ) { + if ( sound.name().equalsIgnoreCase( soundName ) ) { + results = sound; + } + } + + return results; + } + + public boolean isEnableSoundEffects() { + return enableSoundEffects; + } + public void setEnableSoundEffects( boolean enableSoundEffects ) { + this.enableSoundEffects = enableSoundEffects; + } + +} diff --git a/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsTitles.java b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsTitles.java new file mode 100644 index 000000000..ae1968a7b --- /dev/null +++ b/prison-spigot/src/main/java/tech/mcprison/prison/spigot/utils/PrisonUtilsTitles.java @@ -0,0 +1,309 @@ +package tech.mcprison.prison.spigot.utils; + +import tech.mcprison.prison.commands.Arg; +import tech.mcprison.prison.commands.Command; +import tech.mcprison.prison.commands.Wildcard; +import tech.mcprison.prison.internal.CommandSender; +import tech.mcprison.prison.output.Output; +import tech.mcprison.prison.spigot.game.SpigotPlayer; + + +/** + * + * https://javadoc.io/doc/net.md-5/bungeecord-chat/1.16-R0.3/net/md_5/bungee/api/ChatMessageType.html + * + * Player#spigot().sendMessage(ChatMessageType.ACTIONBAR, new TextComponent("Some message")) + * Instead creating a new TextComponent, even better is TextComponent.fromLegacyText("Some message") + * + * https://www.spigotmc.org/threads/send-actionbar.418827/ + * + */ +public class PrisonUtilsTitles + extends PrisonUtils +{ + private boolean enableTitlesTitle = false; + private boolean enableTitlesSubtitle = false; + private boolean enableTitlesActionBar = false; + private boolean enableTitlesClear = false; + private boolean enableTitlesReset = false; + private boolean enableTitlesTimes = false; + + + public PrisonUtilsTitles() { + super(); + + } + + /** + *

There is no initialization needed for these commands. + *

+ * + *

This function must return a value of true to indicate that this + * set of commands are enabled. If it is set to false, then these + * commands will not be registered when prison is loaded. + *

+ * + * @return + */ + @Override + protected Boolean initialize() + { + return true; + } + + + @Command(identifier = "prison utils titles title", + description = "Displays a Title on the player's screen. " + + "If the title is too large, it will overflow on the " + + "sides and will not wrap or be reduced in size. To include a subtitle, " + + "and/or an actionBar message, use a double colon between each section. " + + "For example: 'Hello Title!::Subtitle is Here!::I'm on an actionBar!'", + onlyPlayers = false, + permissions = "prison.utils.titles.title", + altPermissions = "prison.utils.titles.title.others") + public void utilsTitlesTitle( CommandSender sender, + @Arg(name = "playerName", description = "Player name") String playerName, + + @Wildcard(join=true) + @Arg(name = "message", + description = "The message to display in the title.") String message + ) { + + if ( !isEnableTitlesTitle() ) { + + Output.get().logInfo( "Prison's utils command titles title is disabled in modules.yml." ); + } + else { + + SpigotPlayer player = checkPlayerPerms( sender, playerName, + "prison.utils.titles.title", "prison.utils.titles.title.others" ); + + if ( player != null ) { + + if ( playerName != null && !playerName.equalsIgnoreCase( player.getName() ) ) { + // Need to shift the player's name over to the message: + + message = playerName + " " + message; + playerName = null; + } + + String[] messages = message.split( "::" ); + + String title = ( messages.length > 0 ? messages[0] : ""); + String subtitle = ( messages.length > 1 ? messages[1] : ""); + String actionBar = ( messages.length > 2 ? messages[2] : ""); + + player.setTitle( title, subtitle, -1, -1, -1 ); + + if ( actionBar != null && !actionBar.isEmpty() ) { + + player.setActionBar( actionBar ); + } + } + } + } + + + @Command(identifier = "prison utils titles actionBar", + description = "Displays an actionBar text on the player's screen. The actionBar is " + + "located directly above the hot bar. ActionBar may not work on older " + + "versions of spigot.", + onlyPlayers = false, + permissions = "prison.utils.titles.actionbar", + altPermissions = "prison.utils.titles.actionbar.others") + public void utilsTitlesActionBar( CommandSender sender, + @Arg(name = "playerName", description = "Player name") String playerName, + + @Wildcard(join=true) + @Arg(name = "message", + description = "The message to display in the action bar.") String message + ) { + + if ( !isEnableTitlesTitle() ) { + + Output.get().logInfo( "Prison's utils command titles action bar is disabled in modules.yml." ); + } + else { + + SpigotPlayer player = checkPlayerPerms( sender, playerName, + "prison.utils.titles.actionbar", "prison.utils.titles.actionbar.others" ); + + if ( player != null ) { + + + +// Player#spigot().sendMessage(ChatMessageType.ACTIONBAR, new TextComponent("Some message")) + + if ( playerName != null && !playerName.equalsIgnoreCase( player.getName() ) ) { + // Need to shift the player's name over to the message: + + message = playerName + " " + message; + playerName = null; + } + + player.setActionBar( message ); + +// String titleJson = String.format( +// "title %s actionBar {\"text\": \"%s\"}", +// player.getName(), message ); +// +// dispatchCommand( titleJson ); + } + } + } + +// @Command(identifier = "prison utils titles clear", +// description = "Clears the screen title from the screens of the specified player.", +// onlyPlayers = false, +// permissions = "prison.utils.titles.clear", +// altPermissions = "prison.utils.titles.clear.others") +// public void utilsTitlesClear( CommandSender sender, +// @Arg(name = "playerName", description = "Player name") String playerName +// +// ) { +// +// if ( !isEnableTitlesTitle() ) { +// +// Output.get().logInfo( "Prison's utils command titles clear is disabled in modules.yml." ); +// } +// else { +// +// SpigotPlayer player = checkPlayerPerms( sender, playerName, +// "prison.utils.titles.clear", "prison.utils.titles.clear.others" ); +// +// if ( player != null ) { +// +// String titleJson = String.format( +// "title %s clear", +// player.getName() ); +// +// dispatchCommand( titleJson ); +// } +// +// } +// } + + +// @Command(identifier = "prison utils titles reset", +// description = "Resets the subtitle text for the specified player to blank text, " + +// "and the fade-in, stay and fade-out times to their default values " + +// "(defaults to fadeIn 10 ticks, stay 70 ticks, and fadeOut 20 ticks).", +// onlyPlayers = false, +// permissions = "prison.utils.titles.reset", +// altPermissions = "prison.utils.titles.reset.others") +// public void utilsTitlesReset( CommandSender sender, +// @Arg(name = "playerName", description = "Player name") String playerName +// +// ) { +// +// if ( !isEnableTitlesTitle() ) { +// +// Output.get().logInfo( "Prison's utils command titles reset is disabled in modules.yml." ); +// } +// else { +// +// SpigotPlayer player = checkPlayerPerms( sender, playerName, +// "prison.utils.titles.reset", "prison.utils.titles.reset.others" ); +// +// if ( player != null ) { +// +// String titleJson = String.format( +// "title %s reset", +// player.getName() ); +// +// dispatchCommand( titleJson ); +// } +// +// } +// } + + +// @Command(identifier = "prison utils titles times ", +// description = "Resets the player's title times for fade in, stay and fade out. " + +// "These settings will change the client's settings and they will stay in effect " + +// "until they are changed. A value of -1 will use the prior value for that setting. " + +// "This change will apply to all future titles for the player, until it is changed. " + +// "Use 'titles clear' to remove the titles, or 'titles reset' to restore the default " + +// "timings for the fadeIn, stay, and fadeOut values.", +// onlyPlayers = false, +// permissions = "prison.utils.titles.fadein", +// altPermissions = "prison.utils.titles.fadein.others") +// public void utilsTitlesFadeIn( CommandSender sender, +// @Arg(name = "playerName", description = "Player name") String playerName, +// @Arg(name = "fadeIn", description = "The the fade in time, in ticks. " + +// "A value of -1 will use the prior value. [-1]", def= "-1") int fadeIn, +// @Arg(name = "stay", description = "The the fade in time, in ticks. " + +// "A value of -1 will use the prior value. [-1]", def= "-1") int stay, +// @Arg(name = "fadeOut", description = "The the fade out time, in ticks. " + +// "A value of -1 will use the prior value. [-1]", def= "-1") int fadeOut +// +// ) { +// +// if ( !isEnableTitlesTimes() ) { +// +// Output.get().logInfo( "Prison's utils command titles times is disabled in modules.yml." ); +// } +// else { +// +// SpigotPlayer player = checkPlayerPerms( sender, playerName, +// "prison.utils.titles.fadein", "prison.utils.titles.fadein.others" ); +// +// if ( player != null ) { +// +// String titleJson = String.format( +// "title %s times %d %d %d", +// player.getName(), fadeIn, stay, fadeOut ); +// +// dispatchCommand( titleJson ); +// } +// +// } +// } + +// private void dispatchCommand( String command ) { +// Prison.get().getPlatform().dispatchCommand( Text.translateAmpColorCodes( command ) ); +// } + + public boolean isEnableTitlesTitle() { + return enableTitlesTitle; + } + public void setEnableTitlesTitle( boolean enableTitlesTitle ) { + this.enableTitlesTitle = enableTitlesTitle; + } + + public boolean isEnableTitlesSubtitle() { + return enableTitlesSubtitle; + } + public void setEnableTitlesSubtitle( boolean enableTitlesSubtitle ) { + this.enableTitlesSubtitle = enableTitlesSubtitle; + } + + public boolean isEnableTitlesActionBar() { + return enableTitlesActionBar; + } + public void setEnableTitlesActionBar( boolean enableTitlesActionBar ) { + this.enableTitlesActionBar = enableTitlesActionBar; + } + + public boolean isEnableTitlesClear() { + return enableTitlesClear; + } + public void setEnableTitlesClear( boolean enableTitlesClear ) { + this.enableTitlesClear = enableTitlesClear; + } + + public boolean isEnableTitlesReset() { + return enableTitlesReset; + } + public void setEnableTitlesReset( boolean enableTitlesReset ) { + this.enableTitlesReset = enableTitlesReset; + } + + public boolean isEnableTitlesTimes() { + return enableTitlesTimes; + } + public void setEnableTitlesTimes( boolean enableTitlesTimes ) { + this.enableTitlesTimes = enableTitlesTimes; + } + +} diff --git a/prison-spigot/src/main/resources/config.yml b/prison-spigot/src/main/resources/config.yml index b4f690254..591153644 100644 --- a/prison-spigot/src/main/resources/config.yml +++ b/prison-spigot/src/main/resources/config.yml @@ -1,8 +1,8 @@ -# == == == == == === == == == == == # -# Prison 3 Configuration # -# Be sure to check your formatting! # -# This must be valid yml. # -# == == == == == === == == == == == # +# == == == == == == ==== == == == == == # +# Prison 3.2.x Configuration # +# Be sure to check your formatting! # +# This must be valid yml. # +# == == == == == == ==== == == == == == # # # New features have been recently added to prison. These new features # can add a lot of value to your server, but they may also be in the @@ -34,15 +34,21 @@ send-metrics: true # If an alert is being shown, it can be disabled online by acknowledging it. show-alerts: true -# NEW: Prison now has prestiges! -# https://github.com/PrisonTeam/Prison/blob/bleeding/docs/prison_docs_107_setting_up_prestiges.md -# Note: "prestiges: true" is deprecated and will be removed in the future. -prestiges: true +# # Prestige related configuration settings: +# +# Options to reset the money, and/or reset the default ladder. +# Confirmation requires action from the player. If GUI is disabled, then it will use +# the command based confiration. If confirm-enabled is false, then no confirmation +# will be used. prestige: enabled: true resetMoney: true resetDefaultLadder: true + confirmation-enabled: true + prestige-confirm-gui: true + + # NEW: This enables new physics to be applied when jumpping on slime blocks. # When holding different items, like some block types or picks, the player can @@ -54,10 +60,6 @@ slime-fun: false # Access with /gui prison-gui-enabled: true -# NEW: /prestige will open a confirmation GUI if this's on true, if on false -# will use a chat confirmation instead. -prestige-confirm-gui: true - # There're more options for the GUIs, please edit the GuiConfig.yml @@ -115,6 +117,21 @@ storageType: "json" +# Hesitancy Delay Penalty - The purpose of the Hesitancy Delay Penalty is to encourage players +# to rankup to the next rank. Once a player exceeds the rankup cost, they start to incurr a +# rankup penalty. The penalty would be based upon the amount over the rankup cost. So if a player +# has 1.1 million, then only 0.1 million will be subject to the penalty and the penalty will be 20%. +# The max value a player can achieve for a rank will be the rankup cost, then the Hesitancy +# Delay Penalty will be subtracted from that amount. +# For example, if the rankup cost would be 1.0 million and a player has 1.1 million, then their +# max "score" they can achieve is 1.0 million, but the 20% penalty on the 0.1 million will be +# subtracted from the "score". So their adjusted score would be: +# 1.0 million - 0.1 million * 0.2 = 1.0 m - 20,000 = 0.8 m +# +top-stats: + rank-players: + hesitancy-delay-penalty: true + # NEW: # Prison mines reset gap is the number of milliseconds that are used to @@ -165,6 +182,9 @@ prison-mines: # # It's an all or nothing situation when you enable this feature. # +# It's been reported that the correct value to use for CMI is: Economy_CMI +# Vault may report CMIEconomy but that is wrong. +# # Warning: Other plugins that depend upon and use Prison may fail. If they do fail # because of a delayed start, then that is beyond the scope of support that can # be provided by Prison. Delayed start is provided to get CMI working. @@ -192,5 +212,14 @@ delayedPrisonStartup: inspect-vault: true triggers: vault: true - vault-economy-name: Economy_Essentials + vault-economy-name: Economy_CMI +# vault-economy-name: Economy_Essentials + + +# The following changes the event priority for prison's listener for the +# given events. +# Currently, only AsyncPlayerChatEvent is able to be set. Default is LOW. +prison-events: + AsyncPlayerChatEvent: + priority: LOW diff --git a/prison-spigot/src/main/resources/modules.yml b/prison-spigot/src/main/resources/modules.yml index 30302b047..981e149e3 100644 --- a/prison-spigot/src/main/resources/modules.yml +++ b/prison-spigot/src/main/resources/modules.yml @@ -34,3 +34,14 @@ utils: obby: true rainbow: true blocks: true + sounds: + enabled: true + playSound: true + titles: + enabled: true + title: true + subtitle: true + actionBar: true + clear: true + reset: true + times: true diff --git a/prison-spigot/src/main/resources/plugin.yml b/prison-spigot/src/main/resources/plugin.yml index af8aefc1e..6af87c59f 100644 --- a/prison-spigot/src/main/resources/plugin.yml +++ b/prison-spigot/src/main/resources/plugin.yml @@ -3,7 +3,7 @@ main: tech.mcprison.prison.spigot.SpigotPrison version: "${version}" description: Prison is an all-in-one plugin for the Minecraft prison game mode. website: https://prison.jar-mc.com -softdepend: [Essentials, Vault, ProtocolLib, LuckPerms, WorldEdit, WorldGuard, Multiverse-Core, Multiworld, MVdWPlaceholderAPI, PlaceholderAPI, PermissionsEx, GroupManagerX, GemsEconomy, TokenEnchant, CMI, CMILib, CMIEInjector, CMIPaperLib, mcMMO, PlotSquared, Multiverse, FastAsyncWorldEdit] +softdepend: [Essentials, Vault, ProtocolLib, LuckPerms, WorldEdit, WorldGuard, Multiverse-Core, Multiworld, MVdWPlaceholderAPI, PlaceholderAPI, PermissionsEx, GroupManagerX, GemsEconomy, TokenEnchant, CMI, CMILib, CMIEInjector, CMIPaperLib, Economy_CMI, mcMMO, PlotSquared, Multiverse, FastAsyncWorldEdit] # Older versions than 1.13 will ignore this, but this will allow 1.13 and up to use newer block types? api-version: 1.13