Merge master into endgame branch to prepare merge for beta 2.2.000 update

This commit is contained in:
nossr50 2022-12-04 15:58:23 -08:00
commit bb44e56bdb
283 changed files with 24630 additions and 17228 deletions

View File

@ -31,12 +31,13 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v2
# 2. Setup Java 1.8 JDK
- name: Java 1.8 setup
uses: actions/setup-java@v1.4.3
# 2. Setup Java 17 JDK (Adopt)
- name: Java 17 setup
uses: actions/setup-java@v2
with:
distribution: 'adopt'
java-package: jdk
java-version: 1.8
java-version: '17'
# 3. Setup local Maven package cache to speed up building
- name: Cache Maven packages

View File

@ -1,5 +1,4 @@
Version 2.1.176
Added another measure to prevent item stacks from reaching 65 from double smelt
Version 2.2.000
Updated Adventure (our text dependency) fixes some errors when using color codes in party/admin chat (thanks TheBusyBiscuit)
Added some support for negative Y values in anticipation of 1.17 world height changes (thanks t00thpick1)
(API) Many skills with RNG elements now send out a SubSkillEvent (which can be used to modify probability or cancel the results), some skills without RNG still send out this event when activated, this event is cancellable so it can be used to make a skill fail
@ -57,10 +56,577 @@ Version 2.1.176
New Power Level Command
This power level command gives you a view of all your current masteries, it also provides a summary of your power level.
Version 2.1.218
Fixed locale pt_BR type (thanks MrPowerGamerBR)
Updated Russian Locale (thanks imDaniX)
Harvest Lumber checks main hand enchantments when delivering bonuses (thanks destro174)
Fixed bug where players could use inspect to determine if vanished players were online (thanks DarkKnights22)
Version 2.1.217
Tree Feller will now break blocks within the limit instead of refusing to fell the entire tree (partial big tree destruction)
Mangrove trees resulting from growth are now marked as natural (existing trees marked unnatural before this update will not be retroactively fixed)
Fixed a bug removing comments from configs (see notes)
Fixed mouse-hover tooltip windows (thanks Greymagic27)
NOTES:
Regarding the secure chat feature Minecraft rolled out, once APIs have updated I will look into rolling support for that into admin/party chat.
Comments should no longer get removed from config but I haven't added any code to add missing comments back in, for now if you want comments you can delete the config file to regenerate it (sorry for the inconvenience)
Version 2.1.216
Reverted Unarmed changes from 2.1.215 (fixes block breaker/beserk active at all time for all players)
Added Sculk_* blocks to Mining XP
You can use Hoe(s) to gain mining XP, Hoe(s) won't benefit from Super Breaker nor will they activate it (see notes)
NOTES:
Hoe's being able to gain Mining XP is primarily for Sculk blocks which have Hoe as the fastest tool yet to me feel like Mining blocks, let me know what you think
The Sculk blocks don't quite fit perfectly as mining-related, especially since hoes are the fastest tool to use for them. Let me know what you think.
Version 2.1.215
Fixed Coal Blocks and potentially other fuel sources not showing burning animation to players (see notes)
Level up broadcasts from level milestones will now be visible to the player who achieved them
Fixed a bug where hovering over skill descriptions did not display anything (thanks Greymagic27)
Added Dripstone to experience.yml (thanks Greymagic27)
Added Mangrove_Log to experience.yml (should fix behavior for tree-feller etc)
Item in main hand is now used for Tree Feller drops (thanks destro174)
NOTES:
The burning animation bug is actually in Spigot, it takes an int for setBurnTime when it really should only take a short as the game is expecting a short value, I implemented a hacky workaround via Math.min
There is a bug where you may lose your config comments, this will be complex to solve, for now you can check our GitHub for the configs with comments.
Version 2.1.214
Temporarily removed FakePlayerAnimationEvent (see notes)
Players can now see their own level up broadcasts
NOTES:
Spigot updated PlayerAnimationEvent with an API break between versions 1.18 and 1.19, as a temporary fix for mcMMO to be able to support both of these
Minecraft versions I have temporarily removed FakePlayerAnimationEvent. I am working on a fix to dynamically use the correct API depending on the version of MC
as many people will likely be stuck on 1.18 for a while.
FakePlayerAnimationEvent existed to circumvent false positives on anti-cheat plugins such as NoCheat, however
I am unsure if it is still needed and removing it may have no ill effects.. however I cannot be certain.
Anti-cheat plugin authors should be informed to update if you run into false positives with mcMMO after this update so they can make the appropriate changes.
Version 2.1.213
Updated various mechanics to recognize and understand the new blocks
Added 'Packed_Mud' to mining xp
Added 'Mud_Bricks' to mining xp
Added 'Reinforced_Deepslate' to mining xp
Added 'Mud' to excavation xp
Added 'Muddy Mangrove Roots' to excavation xp
Added 'Mangrove_Roots' to woodcutting xp
Added 'Stripped_Mangrove_Log' to woodcutting xp
Added 'Stripped_Crimson_Stem' to woodcutting xp
Added 'Stripped_Warped_Stem' to woodcutting xp
Added 'Allay' to combat experience
Added 'Frog' to combat experience and taming experience
Added 'Tadpole' to combat experience
Added 'Warden' to combat experience
Changes to excavation treasures (requires manual editing or regenerating the config)
Added Mud as a block which can drop various treasures (see notes)
Added Muddy_Mangrove_Roots as a block which can drop various treasures (see notes)
Added Stick as a new excavation drop, which drops from mud and muddy mangrove roots (see notes)
Added Potato as a new excavation drop, which drops from mud and dirt (see notes)
Added Feather as a new excavation drop, which drops from mud (see notes)
Added Spyglass as a new excavation drop, which drops rarely from mud and dirt (see notes)
Added Trident as a new excavation drop, which drops somewhat rarely from mud, muddy mangrove roots, and clay (see notes)
Added Heart of the Sea as a new excavation drop, which drops very rarely from mud and requires a very high excavation level to appear
NOTES:
To get the new excavation drop list, the easiest way is to delete treasures.yml and mcMMO will regenerate it with the newest version
I'll likely be tweaking the treasures list in the near future, leave feedback on discord if you have suggestions
Version 2.1.212
An herbalism exploit has been patched (thanks WhatsTheBadNews)
Added 'ExploitFix.Combat.XPCeiling.Enabled' to experience.yml
Added 'ExploitFix.Combat.XPCeiling.Damage_Limit' to experience.yml
Single instances of combat damage above 100 give are capped to give the same reward as 100 by default (100 is a lot, but you can change this in settings)
NOTES: The damage ceiling won't affect server that don't have mobs running around with abnormally high health, if your server does you'll want to adjust this limit or disable it.
Version 2.1.211
Added /mmodebug info for players hitting other players
Fixed Immortal Player bug
Removed all of Spigot's buggy and deprecated DamageModifier API, this fixes the bug where players would become immortal when using certain other plugins
Rupture is back to doing "pure" damage (due to the above change)
NOTES:
Rupture damage will be tweaked based on feedback as it is dealing "pure" damage
Version 2.1.210
Fixed a memory leak involving mob metadata
Fixed a potential null pointer exception in InventoryListener
NOTES:
If you're having issues with "immortal players" this is a known plugin incompatibility between mcMMO and another plugin, I need more info on what plugins need to be present to cause it. Please post info to GitHub issues or tag me on discord.
There was a big rewrite in this update relating to how various types of metadata were being tracked/stored/retrieved
If you run into issues with this version of mcMMO, please post about it on GitHub
Version 2.1.209
Fixed a bug where some config files did not get trimmed completely
NOTES:
This should fix the issue for everyone, let me know if you still run into trouble!
Don't be afraid to ping me on discord
Version 2.1.208
Significantly rewrote to how mcMMO loads/updates config files
Fixed a bug where huge config files caused the server to take forever to start/shutdown
Fixed config files duplicating comments and updated their code to use Spigot API (thanks the456gamer)
mcMMO now repairs config files (removing duplicate comments, see notes)
Updated lithuanian locale (thanks dexasz)
NOTES:
Due to a change in Spigot mcMMO started growing config files at an alarming rate until they became so big they wouldn't load, and well before they got to that stage they slowed down loading the server
mcMMO now uses the Spigot API in a smarter way for config files
Version 2.1.207
Fixed an IndexOutOfBounds exception with our BlockTracker
Fixed a bug where leveling up a party at level cap would spam the chat with messages
mcMMO will no longer use enchanted repair materials (thanks JeBobs)
Added an option to allow enchanted repair materials 'Skills.Repair.Use_Enchanted_Materials' in config.yml
Temporarily rolling required Java version back to 16
Added unicode (UTF-8) support to locale files (no more UTF-16 codes needed)
Added locale key 'Scoreboard.Disabled' to en_US
Added locale key 'Scoreboard.NotSetupYet' to en_US
Fixed a bug where Salvage sent messages even though the event was cancelled (Thanks TheBusyBiscuit)
Version 2.1.206
Fixed a memory leak involving Herbalism under specific circumstances
Fixed a memory leak involving Rupture under specific circumstances
Fixed a memory leak involving Dodge
Fixed a memory leak involving Endermen and block pickups
Fixed a memory leak from plugin conflicts when double drops get activated
Fixed a memory leak that required a specific config.yml setup with mob health bars
You can no longer set mob health bars to -1 in config.yml to set it to display permanently (this was problematic behavior)
Fixed a bug preventing Action Bar messages from showing
Fixed a bug where Alchemy XP wasn't being granted
Lowered the default volume of level up from .75 to .3 in sounds.yml (delete sounds.yml to get this change automagically)
Updated adventure platform dependency
Updated to use Java 17
NOTES:
mcMMO will target the newest version of MC moving forward, any backwards compatibility with prior versions of Minecraft should be considered a side effect rather than intended.
Version 2.1.205
Fixed yet another exception preventing Alchemy from working (thanks NemuruYama)
Added some code to cleanup potential memory leaks
NOTES:
Sorry for the delay in this patch, I have had a terrible cold all weekend, feeling better now
Version 2.1.204
Fixed IndexOutOfBounds exception (thanks gecko10000) (related to Alchemy)
Added double smelt to copper ingot and netherite scrap (thanks Lyther)
Version 2.1.203
mcMMO now requires Java 16
mcMMO now requires the newest version of Minecraft (currently 1.17.1)
Fixed several API breaks (mostly affected Alchemy)
Fixed a bug relating to Shake percentages (thanks Lyther)
Fixed hexcolors not displaying correctly in level up milestone broadcasts (thanks gecko10000)
(API) Added deprecated constructors for PlayerProfile (thanks PikaMug)
mcMMO has had many of its dependencies updated to newer builds
NOTES:
If you want to play mcMMO on older versions, simply use 2.1.202 instead
Keeping mcMMO backwards compatible with older versions is getting messy, and I'd rather be able to focus my attention at newer features than having to make an elaborate build process (or alternatively hacky code) to support older versions of the game
Furthermore, it seems most people are playing 1.17.1 by a wide margin
You may have trouble compiling the source code if your maven is not setup to run JDK16, if you get any errors when compiling this is likely the reason
The data from bstats went into making this decision (shoutout to Qixils for typing this up too)
71.9% of servers are running 1.17.X
97.9% of servers are running ≥1.16
99.3% of servers are running ≥1.15
Version 2.1.202
Fixed a bug where mcMMO didn't reward XP for Kelp
Fixed a bug where mcMMO marked bonemealed Azalea trees as unnatural (and thus did not give XP or get affected by Tree Feller)
Added Amethyst_Block to experience.yml for Mining
Added Flowering Azalea Leaves to Tree Feller's white list
Fixed a bug where mcMMO didn't appropriately flag blocks as natural in some tree growing events
(SQL) Added more MySQL/MariaDB settings (allowPublicKeyRetrieval - thanks rosaage)
(API) Added CREATED_PARTY and DISBANDED_PARTY to EventReason (used in some party events - thanks PikaMug )
Party member name matching is no longer case sensitive (thanks Wariorrrr)
Updated zh_CN locale (thanks GhostDC)
Added some settings for over fishing (Settings are in experience.yml under Fishing_ExploitFix_Options - thanks tunagohan)
NOTES:
This means tree feller will correctly traverse flowering azalea leaves during its ability
Version 2.1.201
Tweaked the visual/audio effect for Rupture
(API) TNT is set as the source in Blast Mining (1.16.1 and up)
Fixed an exploit related to Ability Buffs remaining on tools
Blast Mining no longer drops Budding Amethyst since its not legal to obtain this item through normal gameplay
Added mcinspect and mmoinspect aliases to inspect command
Portuguese translation of Woodcutting changed back to Lenhador
Updated zh_CN (Chinese) locale, thanks GhostDC!
Major changes to zh_TW locale, thanks gregman98
Added '/skill keep' shortcut (for example /mining keep) thanks GriffinCodes
Impact is now more balanced as the formula has been changed (see notes) thanks emanondev
NOTES:
Impact will deal less durability damage to armors without unbreaking, and more to armors with unbreaking
Version 2.1.200
Fixed a major 1.17 exploit
Dodge will no longer trigger while blocking
Action Bar messages can now be disabled (thanks TheBusyBiscuit)
mcMMO is better at MC version parsing now (thanks stepech & TheBusyBiscuit)
Version 2.1.199
Fixed IndexOutOfBounds error for servers running 1.17 or higher
Fixed a bug that caused MySQL/MariaDB to malfunction for 1.17 (see notes)
Renamed Deepslate Lapis Lazuli Ore to Deepslate Lapis Ore in experience.yml and config.yml
Added some code to prevent mcMMO from breaking if it doesn't recognize the version of the game
Optimized CompatibilitySupportLayer - this handles some of the logic for supporting multiple versions of the game
Added Unit Tests for MinecraftGameVersion
NOTES:
I have temporarily disabled SSL for MySQL/MariaDB for 1.17 ( proper fix coming soon )
Version 2.1.198
Fixed a bug where Smelting didn't work with the new 1.17 materials
Updated dependency Adventure to 4.8.0 (thanks TheBusyBiscuit)
Version 2.1.197
This update adds compatibility for new mobs and blocks from 1.17
This build of mcMMO should be more compatible with certain versions of ViaVersion
Players are no longer launched from Minecarts when using a Fishing Rod (they are still dismounted) thanks lexikiq
Updated Japanese locale (thanks ViaSnake)
Updated Brazil Portuguese (pt_BR) locale (thanks Paulo Guilherme)
Added Goat to experience.yml for combat and taming
Added Axolotl to experience.yml for combat and taming
Added Glow_Squid to experience.yml for combat and taming
Added Glow Berries to Farmer's Diet
Updated Super Breaker to recognize the new pick-axe appropriate blocks
Updated Tree Feller to recognize Azalea Leaves
Added Rooted Dirt to experience.yml for Excavation
Added Small Dripleaf to experience.yml for Herbalism
Added Big Dripleaf to experience.yml for Herbalism
Added Moss Block to experience.yml for Herbalism
Added Cave Vines to experience.yml for Herbalism
Added Cave Vines Plant to experience.yml for Herbalism
Added Glow Lichen to experience.yml for Herbalism
Added Tuff to experience.yml for Mining
Added Calcite to experience.yml for Mining
Added Smooth Basalt to experience.yml for Mining
Added Block_Of_Amethyst to experience.yml for Mining
Added Budding Amethyst to experience.yml for Mining
Added Small_Amethyst_Bud to experience.yml for Mining
Added Medium Amethyst Bud to experience.yml for Mining
Added Large Amethyst Bud to experience.yml for Mining
Added Amethyst Cluster to experience.yml for Mining
Added Deepslate to experience.yml for Mining
Added Cobbled Deepslate to experience.yml for Mining
Added Copper Ore to experience.yml for Mining
Added Deepslate Redstone Ore to experience.yml for Mining
Added Deepslate Copper Ore to experience.yml for Mining
Added Deepslate Coal Ore to experience.yml for Mining
Added Deepslate Diamond Ore to experience.yml for Mining
Added Deepslate Emerald Ore to experience.yml for Mining
Added Deepslate Iron Ore to experience.yml for Mining
Added Deepslate Gold Ore to experience.yml for Mining
Added Deepslate Lapis Lazuli Ore to experience.yml for Mining
Added Lapis Lazuli Ore to experience.yml for Mining (was missing)
Added Moss Block to Bonus Drops for Herbalism in config.yml
Added Glow Berries to Bonus Drops for Herbalism in config.yml
Added Cave Vines to Bonus Drops for Herbalism in config.yml
Added Cave Vines Plant to Bonus Drops for Herbalism in config.yml
Added Tuff to Bonus Drops for Mining in config.yml
Added Amethyst Shard to Bonus Drops for Mining in config.yml
Added Calcite to Bonus Drops for Mining in config.yml
Added Smooth Basalt to Bonus Drops for Mining in config.yml
Added Block_Of_Amethyst to Bonus Drops for Mining in config.yml
Added Budding Amethyst to Bonus Drops for Mining in config.yml
Added Small_Amethyst_Bud to Bonus Drops for Mining in config.yml
Added Medium Amethyst Bud to Bonus Drops for Mining in config.yml
Added Large Amethyst Bud to Bonus Drops for Mining in config.yml
Added Amethyst Cluster to Bonus Drops for Mining in config.yml
Added Deepslate to Bonus Drops for Mining in config.yml
Added Cobbled Deepslate to Bonus Drops for Mining in config.yml
Added Raw Iron to Bonus Drops for Mining in config.yml
Added Raw Gold to Bonus Drops for Mining in config.yml
Added Raw Copper to Bonus Drops for Mining in config.yml
Added Copper Ore to Bonus Drops for Mining in config.yml
Added Deepslate Redstone Ore to Bonus Drops for Mining in config.yml
Added Deepslate Copper Ore to Bonus Drops for Mining in config.yml
Added Deepslate Coal Ore to Bonus Drops for Mining in config.yml
Added Deepslate Diamond Ore to Bonus Drops for Mining in config.yml
Added Deepslate Emerald Ore to Bonus Drops for Mining in config.yml
Added Deepslate Iron Ore to Bonus Drops for Mining in config.yml
Added Deepslate Gold Ore to Bonus Drops for Mining in config.yml
Added Deepslate Lapis Lazuli Ore to Bonus Drops for Mining in config.yml
Added Lapis Lazuli Ore to Bonus Drops for Mining in config.yml (was missing)
Added Cobbled Deepslate to experience.yml for Smelting
Added Raw Copper to experience.yml for Smelting
Added Raw Iron to experience.yml for Smelting
Added Raw Gold to experience.yml for Smelting
Added Copper Ore to experience.yml for Smelting
Added Deepslate Redstone Ore to experience.yml for Smelting
Added Deepslate Copper Ore to experience.yml for Smelting
Added Deepslate Coal Ore to experience.yml for Smelting
Added Deepslate Diamond Ore to experience.yml for Smelting
Added Deepslate Emerald Ore to experience.yml for Smelting
Added Deepslate Iron Ore to experience.yml for Smelting
Added Deepslate Gold Ore to experience.yml for Smelting
Added Deepslate Lapis Lazuli Ore to experience.yml for Smelting
Added Lapis Lazuli Ore to experience.yml for Smelting (was missing)
NOTES:
Another patch will follow this one shortly to add more 1.17 support, I am waiting on the Spigot API to test some stuff which isn't out yet.
You shouldn't need to edit your configs for this update, your configs should update automatically.
Expect some patches following this update for Axolotl and other new entities, waiting on the Spigot API to become available
If you run into any issues with ViaVersion or ViaBackwards, use the latest dev builds for each.
Version 2.1.196
Removed the explosion from Rupture
Adjusted Rupture to play its particle effect less often
Fixed a bug where Rupture never applied to additional targets during Serrated Strikes
Fixed a bug where players without Rupture permission could use Rupture during Serrated Strikes
Fixed a possible null error for our SelfListener
Added locale string 'Swords.Combat.Rupture.Note.Update.One'
Updated locale string 'Guides.Swords.Section.1'
Crossbows can now be fished up with enchantments
(API) Added McMMOEntityDamageByRuptureEvent (thanks qixils)
NOTES:
For now Rupture is non-lethal, I may add back a lethal component at the end of its damage
Rupture will be in a state of change for a while as I receive feedback (give me feedback in Discord!)
Crossbows is not in the default fishing loot list, you'd have to add it yourself.
For Devs: McMMOEntityDamageByRuptureEvent extends EntityDamageByEntityEvent and uses CUSTOM type damage
Version 2.1.195
Fixed a null connection error which affected some SQL users
Version 2.1.194
Fixed an XP exploit
Updated SQL to not throw errors if upgrades.yml was reset for any reason
Updated SQL to use the newest driver path (and fall back to the old one if the new one doesn't exist on the server)
Locale override files are now named locale_override.properties (converted automatically/generated automatically)
Existing in use locale override files will be renamed to locale_override.properties and have some useful text put in them
mcMMO will now generate a locale override file with some detailed instructions if one doesn't exist (will be found in /plugins/mcMMO/locales/locale_override.properties)
NOTES:
If you were overriding locale before this update mcMMO will just rename the existing override file to locale_override.properties add some useful text and then load it
Remember you can use /mcreloadlocale to swap the edits in without restarting the server
Version 2.1.193
Fixed another bug where mcrank/mctop/leaderboards weren't loading
Fixed a bug where override locales weren't being loaded (but worked after a reloadlocale command)
(Unit Tests) Added a test to make sure leaderboards for FlatFile were working
Fixed blocks being dropped from blast mining even if yield was set to 0 (thanks Warriorrrr)
Fixed Tree feller not working entirely if one fake block break event is cancelled. (thanks Warriorrrr)
Fixes no woodcutting xp being rewarded if a tree is too big while using tree feller. (thanks Warriorrrr)
Updated pl locale (thanks Mich3l3k)
Version 2.1.192
Removed some debug messages from FlatFileDatabaseManager
Fixed another bug where player names could be saved as null for FlatFileDB (they will update on the players next login at the next save interval)
(API) Removed deprecation from com.gmail.nossr50.api.ExperienceAPI.getOfflineProfile(java.lang.String)
(API) Added com.gmail.nossr50.api.DatabaseAPI.doesPlayerExistInDB(org.bukkit.OfflinePlayer)
(API) Added com.gmail.nossr50.api.ExperienceAPI.getOfflineProfile(org.bukkit.OfflinePlayer)
(API) Added com.gmail.nossr50.api.ExperienceAPI.getOfflineXP(org.bukkit.OfflinePlayer, java.lang.String)
(API) Added com.gmail.nossr50.api.ExperienceAPI.getOfflineXPRaw(org.bukkit.OfflinePlayer, com.gmail.nossr50.datatypes.skills.PrimarySkillType)
(API) Added com.gmail.nossr50.api.ExperienceAPI.getOfflineXPRaw(org.bukkit.OfflinePlayer, java.lang.String)
(API) Added com.gmail.nossr50.api.ExperienceAPI.getOfflineXPToNextLevel(org.bukkit.OfflinePlayer, java.lang.String)
(API) Added com.gmail.nossr50.api.DatabaseAPI.doesPlayerExistInDB(java.lang.String)
(Unit Tests) Added some more unit tests to FlatFileDB
Version 2.1.191
Fixed a bug related to our blocktracker
Fixed a bug that prevented the leaderboards from working on FlatFile in some circumstances
Some minor optimizations to our Block events
(Unit Tests) Added a test for initializing the leaderboard on FlatFile
Version 2.1.190
Fixed a null error in BitSetChunkStore
Version 2.1.189
Fixed a bug that would remove components from death messages when players were killed by mobs (thanks lexikiq)
Rewrote how FlatFileDatabase verifies data integrity
FlatFileDatabase has much better data validation and will repair broken/invalid data much better
Fixed a bug where FlatFileDatabase users could have their names saved as "null" (names will be fixed the next time the player logs in)
Added 20~ unit tests for FlatFileDatabaseManager (see notes)
FlatFileDB now stores the last login of users again (was completely non functional for a while)
Newly created flat file databases (mcmmo.users file) will have a comment line at the top noting the date the database was created
Minor performance optimizations to FlatFile database
mcMMO will once again purge old users if the config option is on (see notes)
Fixed a bug where FlatFileDatabaseManager didn't properly upgrade older database entries to the newest schema
The setting to disable the mcMMO user block tracker has been moved from our "hidden config" to persistent_data.yml
Added 'mcMMO_Region_System.Enabled' to persistent_data.yml (don't touch this setting unless you know what you are doing)
Removed MHD command (it didn't do anything for a while now)
Removed UltraPermissions warning
Updated pl locale (Thanks Mich3l3k)
Fixed an IllegalPluginAccessException error that could happen during server shutdown
Minor performance optimizations to misc parts of the codebase
(API) Added com.gmail.nossr50.database.DatabaseManager.loadPlayerProfile(org.bukkit.OfflinePlayer)
(API) Deprecated com.gmail.nossr50.database.DatabaseManager.loadPlayerProfile(java.util.UUID, java.lang.String)
(API) Removed com.gmail.nossr50.database.DatabaseManager.newUser(java.lang.String, java.util.UUID)
(API) PrimarySkillType will soon be just an enum with nothing special going on
(API) Deprecated the members of PrimarySkillType use mcMMO::getSkillTools instead, deprecated members will be removed in Tridents & Crossbows (due soon)
(API) Some members of PrimarySkillType were removed and not deprecated (such as the field constants)
NOTES:
I spent over 26 hours refactoring FlatFileDB and writing unit tests for it, this will ensure that any changes in the code that could break the database are caught at compile time (so long as we have enough tests, could probably use more)
Regarding purging old users on the FlatFileDB, since this wasn't functioning for a while, the last login of users has been reset and if mcMMO hasn't seen that user since this update, it won't purge them as it has no way to know if they are truly an old user
I'm likely going to add SQLite DB as an option in the future, I spent time to fix up the FlatFileDB as some Unit Testing practice.
Ultra Permissions is SAFE to use with mcMMO, disregard previous messages stating otherwise
After getting in contact with the UltraPermissions devs and exhaustive testing, I have concluded that using UltraPermissions is completely safe with mcMMO. The users who had an issue with performance currently have an unknown cause, potentially it is from a plugin using the UltraPermissions API I really can't say without more data. My apologies to the UltraPermissions team for reporting an issue between our two plugins directly, as that is not the case. I would have tested it myself sooner but UltraPermissions was closed source and premium so I wasn't particularly motivated to do so, however I have been given access to the binaries so now I can do all the testing I want if future issues ever arise which I have zero expectations that they will.
Version 2.1.188
Updated default entries in treasures.yml to use "Level_Requirement" instead of "Drop_Level"
Fixed a bug where excavation treasures only required level 0 instead of loading the value from the config
Fixed a bug where /fishing was showing the wrong shake chance
Default Shake chance increased from 15% to 30% (update advanced.yml manually or delete the file to regenerate it and receive these changes)
Removed entries for ranks 2-8 of Shake from advanced.yml (Shake only has one rank, the extra entries were a mistake)
Modified the warning about UltraPermissions
Removed the debug message about potentially unused keys (only shown if you had debug mode enabled in config.yml)
NOTES:
This update makes changes to treasures.yml automatically to apply the fix, you don't need to do anything
UltraPermissions devs are working on a fix for the performance issue bug
Version 2.1.187
Fixed a ClassCastException error involving Rupture
Version 2.1.186
Rupture has been reworked to solve a few outstanding issues (see notes)
Fixed an exploit involving enchantments (thanks TheBusyBiscuit)
Fixed a very small memory leak that would only happen in very rare situations
Fixed a bug where XP wasn't granted while sneaking and interacting with a berry bush
Gore no longer applies Rupture
Gore no longer sends a message to the Wolf owner when it triggers
Gore no longer sends a message to players that are hit by it
Rupture no longer sends a message telling you that your target is bleeding
Updated locale string 'Swords.SubSkill.Rupture.Description'
Updated locale string 'Swords.SubSkill.Rupture.Stat.Extra'
Updated locale string 'Swords.Combat.Rupture.Note'
Added locale string 'Swords.SubSkill.Rupture.Stat.TickDamage'
Added locale string 'Swords.SubSkill.Rupture.Stat.ExplosionDamage'
Added 'Skills.Swords.Rupture.Rupture_Mechanics.Chance_To_Apply_On_Hit' to advanced.yml
Added 'Skills.Swords.Rupture.Rupture_Mechanics.Duration_In_Seconds.Against_Players' to advanced.yml
Added 'Skills.Swords.Rupture.Rupture_Mechanics.Duration_In_Seconds.Against_Mobs' to advanced.yml
Added 'Skills.Swords.Rupture.Rupture_Mechanics.Tick_Interval_Damage.Against_Players' to advanced.yml
Added 'Skills.Swords.Rupture.Rupture_Mechanics.Tick_Interval_Damage.Against_Mobs' to advanced.yml
Added 'Skills.Swords.Rupture.Rupture_Mechanics.Explosion_Damage.Against_Players' to advanced.yml
Added 'Skills.Swords.Rupture.Rupture_Mechanics.Explosion_Damage.Against_Mobs' to advanced.yml
Removed 'Skills.Swords.Rupture.ChanceMax' from advanced.yml
Removed 'Skills.Swords.Rupture.MaxBonusLevel.Standard' from advanced.yml
Removed 'Skills.Swords.Rupture.MaxBonusLevel.RetroMode' from advanced.yml
Removed 'Skills.Swords.Rupture.MaxTicks' from advanced.yml
Removed 'Skills.Swords.Rupture.BaseTicks' from advanced.yml
Removed 'Skills.Swords.Rupture.DamagePlayer' from advanced.yml
Removed 'Skills.Swords.Rupture.DamageMobs' from advanced.yml
NOTES:
The old Rupture would constantly interfere with your ability to do a Sweep Attack/Swipe with swords, the new one solves this problem
Targets will bleed and take "pure" damage while bleeding, this never kills the target. It will reduce them to 0.01 HP.
After 5 seconds of not applying Rupture on the target Rupture explodes dealing a large amount of damage, this damage is not pure and is affected by armor etc.
Rupture no longer tells you that you that you applied it to the target, it should be obvious from the sounds/particle effects
The new Rupture no longer constantly interferes with the vanilla Swipe (the AOE attack built into Minecraft)
The new Rupture has not had a fine tuned balance pass, I will be balancing it frequently after this patch, it may be too weak or too strong in its current form
Rupture does not stack between players, whoever applied Rupture first determines its strength, this will change in the future (Stronger Ruptures will overwrite weaker ones)
When you reapply rupture it immediately triggers a damage tick
Version 2.1.185
Fixed an exploit for Herbalism
Version 2.1.184
Removed April Fools event
Fixed a bug where the default treasures.yml file had incorrect keys (see notes)
NOTES:
mcMMO will fix bad config files automatically, you don't need to do anything
Version 2.1.183
Players now gain Acrobatics XP from falling even if they don't have the Roll permission node (checks for Acrobatics skill permission)
treasures.yml now has separate settings for Drop_Level for Standard/Retro mode (see notes / this change is automatic)
Updated Russian locale (thanks ImDaniX)
Added Donkeys to beat lore (thanks QuantumToasted)
Alchemy guide now correctly labels Rabbit's foot for potion of leaping (thanks mldriscoll)
Fixed a bug where sweet berry bushes would give XP in situations where they shouldn't
The /mmoinfo for Roll is removed for the time being, it will return in a future update (see notes)
NOTES:
Previously treasures.yml would take drop_level and multiply it by 10 if you were on Retro Mode, this is confusing so it has been changed
treasures.yml will update old entries to follow the new format automatically, please review them to make sure they match expected values, and if not edit them and save then reboot your server
Roll is actually the only skill that had an /mmoinfo, its one big mess, I'll fix it in the future
Version 2.1.182
Players now receive XP from harvesting Sweet Berry bushes (double XP for harvesting fully grown berries)
Fixed an error when using mcMMO with Featherboard that broke mcMMO skill boards when using certain commands
Fixed a NPE with Scoreboards enabled when trying to update scoreboards
Added 'Scoreboard.Recovery' locale key
Sweet Berry Bush will no longer ready tools for Super Abilities
You can now use '.all' (for example: mcmmo.perks.xp.customboost.all) to give an XP perk to all skills
Removed hardcore and vampirism commands, these commands are dangerous, just modify the config file if you want to use hardcore / vampirism
Fixed several errors in de locale (Thanks TheBusyBiscuit & w1tcherrr)
Fixed a bug where double smelt never succeeded if the furnace was empty (but worked normally afterwards)
Added some safety so that mcMMO automatic save interval is never more frequent than 1 minute
Removed a few silent exceptions for scoreboards & mcMMO
Added warning about UltraPermissions to mcMMO
Fixed a potential NPE in McMMOPlayerExperienceEvent
Added Sweet Berry Bush to config.yml bonus drops for Herbalism
NOTES:
Sweet Berry Bushes won't give double drops for now, looking into an elegant solution
mcMMO will do a better job reporting if something went wrong with scoreboards, which may lead to improved plugin compatibility between mcMMO and other plugins touching scoreboards.
Version 2.1.181
mcMMO no longer pointlessly tries to check for missing UUIDs for FlatFile database
Removed the "name change detected" message as some plugins (such as Plan) invoke API calls which spams the console with this message
Refactored code related to loading player data from the database
(API) Added DatabaseManager::loadPlayerProfile(String)
(API) Removed DatabaseManager::loadPlayerProfile(String, UUID, boolean)
(API) Removed DatabaseManager::loadPlayerProfile(String, boolean)
Version 2.1.180
mcMMO will now automatically remove corrupted data from mcmmo.users instead of catastrophic failure
When using FlatFile database (the default) mcMMO will try its best to inform you which players had corrupted data when it does repairs
Various minor optimizations and tweaks to the FlatFile database
mcMMO is now much more verbose when things go wrong with the FlatFile database (removed some silent errors, added more error messages/warnings)
mcMMO now uses UTF-8 compliant encoding for SQL databases (utf8mb4)
Fixed a bug where mcMMO could in some circumstances fail to update SQL schema and mark it as successful
Renamed updates.yml to updates_overhaul.yml to avoid some potential issues when upgrading from classic
NOTES:
This update was tested pretty thoroughly so it should be pretty safe, let me know if you have issues in the mcMMO discord or GitHub issues page for mcMMO!
Version 2.1.179
Fixed a bug for FlatFile databases where some players with changed nicknames would have their levels not loaded upon login (possibly wiping their data)
NOTES:
Players affected by this bug (introduced in 2.1.177) may have their data lost, but this patch reverts the change which caused this bug.
I suspect their data isn't lost and may be restored after this patch is loaded up, however if it is lost mcMMO makes regular backups so you can load one of those (check <Server Directory>/plugins/mcMMO/) or manually edit their levels via MMOEDIT as a solution of sorts.
Version 2.1.178
Item replacement in vanilla fishing override back to SALMON from AIR (see notes)
NOTES:
Apparently can't set items to AIR, my bad. I'll look into another solution for fishing plugin compatibility soon.
Version 2.1.177
Environmentally aware will now protect Wolves from Magma blocks
Fixed a bug where mcMMO would fail to update a players name when it detected a name change
mcMMO will treat vanished players as if they are offline when using the inspect command on them now (see notes)
mcMMO now listens to PlayerFishEvent at HIGH event priority instead of HIGHEST
Changed how vanilla fishing treasures are overridden (AIR instead of SALMON)
(API) Added McMMOReplaceVanillaTreasureEvent -- see notes
NOTES:
A few changes were made to the inspect command, it used to reject you when used on vanished players, now it will be processed as if they are offline.
Additionally if you do inspect a vanished player, it will not use their display name (consistent with offline players) as that would give them away for being online
McMMOReplaceVanillaTreasureEvent is an event which is fired when mcMMO replaces a vanilla treasure with AIR if the server config file is set to override vanilla treasures, this causes some issues for other fishing plugins so this event helps those plugins be more compatible
Version 2.1.176
Another fix for Double Smelt bringing item stack size to illegal values
Version 2.1.175
Fixed a bug where mcMMO would occasionally give a 65 item stack from a double smelt on a furnace
Fixed a bug where arrows could be duped when fired from a crossbow with piercing enchantment
Added setting to enable or disable Green Thumb automatically replanting crops per crop to config.yml under 'Green_Thumb_Replanting_Crops' section
Updated Adventure (our text dependency) fixes some errors when using color codes in party/admin chat (thanks TheBusyBiscuit)
Added some support for negative Y values in anticipation of 1.17 world height changes (thanks t00thpick1)
Version 2.1.174
Some legacy color codes in our locale file were swapped to &-code equivalents (thanks ViaSnake)

145
pom.xml
View File

@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.gmail.nossr50.mcMMO</groupId>
<artifactId>mcMMO</artifactId>
<version>2.1.176-SNAPSHOT</version>
<version>2.1.218</version>
<name>mcMMO</name>
<url>https://github.com/mcMMO-Dev/mcMMO</url>
<scm>
@ -11,11 +11,29 @@
<developerConnection>scm:git:git@github.com:mcMMO-Dev/mcMMO.git</developerConnection>
<tag>HEAD</tag>
</scm>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
<java.version>16</java.version>
</properties>
<issueManagement>
<url>https://github.com/mcMMO-Dev/mcMMO/issues</url>
<system>GitHub</system>
</issueManagement>
<packaging>jar</packaging>
<distributionManagement>
<repository>
<id>neetgames</id>
<url>https://nexus.neetgames.com/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>neetgames</id>
<url>https://nexus.neetgames.com/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
<build>
<finalName>${project.artifactId}</finalName>
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
@ -55,21 +73,39 @@
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M7</version>
<configuration>
<junitArtifactName>org.junit.jupiter:junit-jupiter</junitArtifactName>
<trimStackTrace>false</trimStackTrace>
</configuration>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.0.0-M7</version>
<configuration>
<junitArtifactName>org.junit.jupiter:junit-jupiter</junitArtifactName>
<trimStackTrace>false</trimStackTrace>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.2</version>
<version>3.0.0-M6</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<version>3.10.1</version>
<configuration>
<release>16</release>
<compilerArgs>
<arg>-parameters</arg> <!-- used for ACF syntax stuff -->
</compilerArgs>
<source>1.8</source>
<target>1.8</target>
<excludes>
</excludes>
</configuration>
@ -94,7 +130,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.3</version>
<version>3.3.0</version>
<configuration>
<artifactSet>
<includes>
@ -107,7 +143,6 @@
<include>net.kyori:adventure-text-serializer-gson</include>
<include>net.kyori:adventure-platform-bukkit</include>
<include>net.kyori:adventure-platform-api</include>
<include>net.kyori:adventure-platform-common</include>
<include>net.kyori:adventure-platform-viaversion</include>
<include>net.kyori:adventure-platform-facet</include>
<include>net.kyori:adventure-nbt</include>
@ -121,11 +156,10 @@
<include>co.aikar:acf-bukkit</include>
</includes>
</artifactSet>
<!-- <dependencyReducedPomLocation>${project.build.directory}/dependency-reduced-pom.xml</dependencyReducedPomLocation>-->
<relocations>
<relocation>
<pattern>net.kyori.examination</pattern>
<shadedPattern>com.gmail.nossr50.kyori.examination</shadedPattern>
<shadedPattern>com.gmail.nossr50.mcmmo.kyori.examination</shadedPattern>
</relocation>
<relocation>
<pattern>net.kyori.adventure</pattern>
@ -171,10 +205,17 @@
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-file</artifactId>
<version>2.2</version>
<version>3.5.2</version>
</extension>
</extensions>
</build>
<pluginRepositories>
<pluginRepository>
<id>maven-snapshots</id>
<url>https://repository.apache.org/content/repositories/snapshots/</url>
</pluginRepository>
</pluginRepositories>
<repositories>
<repository>
<id>spigot-repo</id>
@ -185,88 +226,87 @@
<url>https://repo.codemc.org/repository/maven-public</url>
</repository>
<repository>
<id>sk89q-repo</id>
<url>https://maven.sk89q.com/repo/</url>
<id>enginehub-repo</id>
<url>https://maven.enginehub.org/repo/</url>
</repository>
<repository> <!-- for development builds -->
<id>sonatype-oss</id>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</repository>
<repository>
<id>aikar</id>
<url>https://repo.aikar.co/content/groups/aikar/</url>
</repository>
<!-- ... -->
<repository> <!-- for development builds -->
<id>sonatype-oss</id>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
<repository>
<id>sonatype-oss-snapshots1</id>
<url>https://s01.oss.sonatype.org/content/repositories/snapshots/</url>
</repository>
<!-- ... -->
<!-- ... -->
</repositories>
<dependencies>
<dependency>
<groupId>co.aikar</groupId>
<artifactId>acf-bukkit</artifactId> <!-- Don't forget to replace this -->
<version>0.5.0-SNAPSHOT</version> <!-- Replace this as well -->
<version>0.5.1-SNAPSHOT</version> <!-- Replace this as well -->
</dependency>
<!-- adventure-api, adventure-text-serializer-gson, adventure-platform-bukkit-->
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-serializer-gson</artifactId>
<version>4.5.1</version>
<version>4.11.0</version>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-api</artifactId>
<version>4.5.1</version>
<version>4.11.0</version>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-nbt</artifactId>
<version>4.5.1</version>
<version>4.11.0</version>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-key</artifactId>
<version>4.5.1</version>
<version>4.11.0</version>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-serializer-gson-legacy-impl</artifactId>
<version>4.5.1</version>
<version>4.11.0</version>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-platform-bukkit</artifactId>
<version>4.0.0-SNAPSHOT</version>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-platform-api</artifactId>
<version>4.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-platform-common</artifactId>
<version>4.0.0-SNAPSHOT</version>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-provider-gitexe</artifactId>
<version>1.9.4</version>
<version>2.0.0-M1</version>
</dependency>
<dependency>
<groupId>org.bstats</groupId>
<artifactId>bstats-bukkit</artifactId>
<version>2.2.1</version>
<version>3.0.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.16.5-R0.1-SNAPSHOT</version>
<version>1.19.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sk89q.worldguard</groupId>
<artifactId>worldguard-core</artifactId>
<version>7.0.1-SNAPSHOT</version>
<version>7.0.7</version>
<exclusions>
<exclusion>
<!-- We use jetbrains instead. Excluding this -->
@ -288,42 +328,39 @@
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit-dep</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>2.0.7</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>2.0.7</version>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.9.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.8.0</version>
<version>4.6.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>4.6.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
<version>7.0.52</version>
<version>10.1.0-M17</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>19.0.0</version>
<version>23.0.0</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version> <!-- At this time Spigot is including 29.0 Guava classes that we are using -->
<scope>compile</scope>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>

View File

@ -2,7 +2,7 @@ package com.gmail.nossr50.api;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
import com.gmail.nossr50.runnables.skills.BleedTimerTask;
import com.gmail.nossr50.util.MetadataConstants;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
@ -83,6 +83,12 @@ public final class AbilityAPI {
}
public static boolean isBleeding(LivingEntity entity) {
return BleedTimerTask.isBleeding(entity);
if(entity.isValid()) {
if(entity.hasMetadata(MetadataConstants.METADATA_KEY_RUPTURE)) {
return true;
}
}
return false;
}
}

View File

@ -2,6 +2,8 @@ package com.gmail.nossr50.api;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.mcMMO;
import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull;
import java.util.UUID;
@ -9,20 +11,38 @@ public class DatabaseAPI {
/**
* Checks if a player exists in the mcMMO Database
* @param uuid player UUID
* @param offlinePlayer target player
* @return true if the player exists in the DB, false if they do not
*/
public boolean doesPlayerExistInDB(String uuid) {
return doesPlayerExistInDB(UUID.fromString(uuid));
public boolean doesPlayerExistInDB(@NotNull OfflinePlayer offlinePlayer) {
PlayerProfile playerProfile = mcMMO.getDatabaseManager().loadPlayerProfile(offlinePlayer);
return playerProfile.isLoaded();
}
/**
* Checks if a player exists in the mcMMO Database
* @param uuid player UUID
* @param uuid target player
* @return true if the player exists in the DB, false if they do not
*/
public boolean doesPlayerExistInDB(UUID uuid) {
PlayerProfile playerProfile = mcMMO.getDatabaseManager().loadPlayerProfile(uuid);
public boolean doesPlayerExistInDB(@NotNull UUID uuid) {
PlayerProfile playerProfile = null;
try {
playerProfile = mcMMO.getDatabaseManager().loadPlayerProfile(uuid);
} catch (Exception e) {
return false;
}
return playerProfile.isLoaded();
}
/**
* Checks if a player exists in the mcMMO Database
* @param playerName target player
* @return true if the player exists in the DB, false if they do not
*/
public boolean doesPlayerExistInDB(@NotNull String playerName) {
PlayerProfile playerProfile = mcMMO.getDatabaseManager().loadPlayerProfile(playerName);
return playerProfile.isLoaded();
}

View File

@ -1,7 +1,6 @@
package com.gmail.nossr50.api;
import com.gmail.nossr50.api.exceptions.*;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.datatypes.experience.FormulaType;
import com.gmail.nossr50.datatypes.experience.XPGainReason;
@ -13,9 +12,12 @@ import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.child.FamilyTree;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.skills.CombatUtils;
import com.gmail.nossr50.util.skills.SkillTools;
import org.bukkit.OfflinePlayer;
import org.bukkit.block.BlockState;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Set;
@ -33,8 +35,8 @@ public final class ExperienceAPI {
* @param skillType A string that may or may not be a skill
* @return true if this is a valid mcMMO skill
*/
public static boolean isValidSkillType(String skillType) {
return PrimarySkillType.getSkill(skillType) != null;
public static boolean isValidSkillType(@NotNull String skillType) {
return mcMMO.p.getSkillTools().matchSkill(skillType) != null;
}
/**
@ -77,9 +79,9 @@ public final class ExperienceAPI {
* @return true if this is a valid, non-child mcMMO skill
*/
public static boolean isNonChildSkill(String skillType) {
PrimarySkillType skill = PrimarySkillType.getSkill(skillType);
PrimarySkillType skill = mcMMO.p.getSkillTools().matchSkill(skillType);
return skill != null && !skill.isChildSkill();
return skill != null && !SkillTools.isChildSkill(skill);
}
@Deprecated
@ -293,11 +295,12 @@ public final class ExperienceAPI {
PrimarySkillType skill = getSkillType(skillType);
if (isUnshared) {
getPlayer(player).beginUnsharedXpGain(skill, (int) (XP / skill.getXpModifier() * ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier()), getXPGainReason(xpGainReason), XPGainSource.CUSTOM);
getPlayer(player).beginUnsharedXpGain(skill,
(int) (XP / ExperienceConfig.getInstance().getFormulaSkillModifier(skill) * ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier()), getXPGainReason(xpGainReason), XPGainSource.CUSTOM);
return;
}
getPlayer(player).applyXpGain(skill, (int) (XP / skill.getXpModifier() * ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier()), getXPGainReason(xpGainReason), XPGainSource.CUSTOM);
getPlayer(player).applyXpGain(skill, (int) (XP / ExperienceConfig.getInstance().getFormulaSkillModifier(skill) * ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier()), getXPGainReason(xpGainReason), XPGainSource.CUSTOM);
}
/**
@ -316,7 +319,7 @@ public final class ExperienceAPI {
public static void addModifiedXPOffline(String playerName, String skillType, int XP) {
PrimarySkillType skill = getSkillType(skillType);
addOfflineXP(playerName, skill, (int) (XP / skill.getXpModifier() * ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier()));
addOfflineXP(playerName, skill, (int) (XP / ExperienceConfig.getInstance().getFormulaSkillModifier(skill) * ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier()));
}
/**
@ -429,6 +432,23 @@ public final class ExperienceAPI {
return getOfflineProfile(uuid).getSkillXpLevel(getNonChildSkillType(skillType));
}
/**
* Get the amount of XP an offline player has in a specific skill.
* </br>
* This function is designed for API usage.
*
* @param offlinePlayer The player to get XP for
* @param skillType The skill to get XP for
* @return the amount of XP in a given skill
*
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidPlayerException if the given player does not exist in the database
* @throws UnsupportedOperationException if the given skill is a child skill
*/
public static int getOfflineXP(@NotNull OfflinePlayer offlinePlayer, @NotNull String skillType) throws InvalidPlayerException {
return getOfflineProfile(offlinePlayer).getSkillXpLevel(getNonChildSkillType(skillType));
}
/**
* Get the raw amount of XP a player has in a specific skill.
* </br>
@ -480,6 +500,30 @@ public final class ExperienceAPI {
return getOfflineProfile(uuid).getSkillXpLevelRaw(getNonChildSkillType(skillType));
}
/**
* Get the raw amount of XP an offline player has in a specific skill.
* </br>
* This function is designed for API usage.
*
* @param offlinePlayer The player to get XP for
* @param skillType The skill to get XP for
* @return the amount of XP in a given skill
*
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidPlayerException if the given player does not exist in the database
* @throws UnsupportedOperationException if the given skill is a child skill
*/
public static float getOfflineXPRaw(@NotNull OfflinePlayer offlinePlayer, @NotNull String skillType) throws InvalidPlayerException, UnsupportedOperationException, InvalidSkillException {
return getOfflineProfile(offlinePlayer).getSkillXpLevelRaw(getNonChildSkillType(skillType));
}
public static float getOfflineXPRaw(@NotNull OfflinePlayer offlinePlayer, @NotNull PrimarySkillType skillType) throws InvalidPlayerException, UnsupportedOperationException {
if(SkillTools.isChildSkill(skillType))
throw new UnsupportedOperationException();
return getOfflineProfile(offlinePlayer).getSkillXpLevelRaw(skillType);
}
/**
* Get the total amount of XP needed to reach the next level.
* </br>
@ -527,10 +571,27 @@ public final class ExperienceAPI {
* @throws InvalidPlayerException if the given player does not exist in the database
* @throws UnsupportedOperationException if the given skill is a child skill
*/
public static int getOfflineXPToNextLevel(UUID uuid, String skillType) {
public static int getOfflineXPToNextLevel(@NotNull UUID uuid, @NotNull String skillType) {
return getOfflineProfile(uuid).getXpToLevel(getNonChildSkillType(skillType));
}
/**
* Get the total amount of XP an offline player needs to reach the next level.
* </br>
* This function is designed for API usage.
*
* @param offlinePlayer The player to get XP for
* @param skillType The skill to get XP for
* @return the total amount of XP needed to reach the next level
*
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidPlayerException if the given player does not exist in the database
* @throws UnsupportedOperationException if the given skill is a child skill
*/
public static int getOfflineXPToNextLevel(@NotNull OfflinePlayer offlinePlayer, @NotNull String skillType) throws UnsupportedOperationException, InvalidSkillException, InvalidPlayerException {
return getOfflineProfile(offlinePlayer).getXpToLevel(getNonChildSkillType(skillType));
}
/**
* Get the amount of XP remaining until the next level.
* </br>
@ -592,6 +653,26 @@ public final class ExperienceAPI {
return profile.getXpToLevel(skill) - profile.getSkillXpLevelRaw(skill);
}
/**
* Get the amount of XP an offline player has left before leveling up.
* </br>
* This function is designed for API usage.
*
* @param offlinePlayer The player to get XP for
* @param skillType The skill to get XP for
* @return the amount of XP needed to reach the next level
*
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidPlayerException if the given player does not exist in the database
* @throws UnsupportedOperationException if the given skill is a child skill
*/
public static float getOfflineXPRemaining(OfflinePlayer offlinePlayer, String skillType) throws InvalidSkillException, InvalidPlayerException, UnsupportedOperationException {
PrimarySkillType skill = getNonChildSkillType(skillType);
PlayerProfile profile = getOfflineProfile(offlinePlayer);
return profile.getXpToLevel(skill) - profile.getSkillXpLevelRaw(skill);
}
/**
* Add levels to a skill.
* </br>
@ -624,7 +705,7 @@ public final class ExperienceAPI {
PlayerProfile profile = getOfflineProfile(playerName);
PrimarySkillType skill = getSkillType(skillType);
if (skill.isChildSkill()) {
if (SkillTools.isChildSkill(skill)) {
Set<PrimarySkillType> parentSkills = FamilyTree.getParents(skill);
for (PrimarySkillType parentSkill : parentSkills) {
@ -655,7 +736,7 @@ public final class ExperienceAPI {
PlayerProfile profile = getOfflineProfile(uuid);
PrimarySkillType skill = getSkillType(skillType);
if (skill.isChildSkill()) {
if (SkillTools.isChildSkill(skill)) {
Set<PrimarySkillType> parentSkills = FamilyTree.getParents(skill);
for (PrimarySkillType parentSkill : parentSkills) {
@ -714,7 +795,6 @@ public final class ExperienceAPI {
* @throws InvalidSkillException if the given skill is not valid
* @throws InvalidPlayerException if the given player does not exist in the database
*/
@Deprecated
public static int getLevelOffline(String playerName, String skillType) {
return getOfflineProfile(playerName).getSkillLevel(getSkillType(skillType));
}
@ -762,7 +842,7 @@ public final class ExperienceAPI {
int powerLevel = 0;
PlayerProfile profile = getOfflineProfile(playerName);
for (PrimarySkillType type : PrimarySkillType.NON_CHILD_SKILLS) {
for (PrimarySkillType type : SkillTools.NON_CHILD_SKILLS) {
powerLevel += profile.getSkillLevel(type);
}
@ -783,7 +863,7 @@ public final class ExperienceAPI {
int powerLevel = 0;
PlayerProfile profile = getOfflineProfile(uuid);
for (PrimarySkillType type : PrimarySkillType.NON_CHILD_SKILLS) {
for (PrimarySkillType type : SkillTools.NON_CHILD_SKILLS) {
powerLevel += profile.getSkillLevel(type);
}
@ -801,7 +881,7 @@ public final class ExperienceAPI {
* @throws InvalidSkillException if the given skill is not valid
*/
public static int getLevelCap(String skillType) {
return Config.getInstance().getLevelCap(getSkillType(skillType));
return mcMMO.p.getSkillTools().getLevelCap(getSkillType(skillType));
}
/**
@ -812,7 +892,7 @@ public final class ExperienceAPI {
* @return the overall power level cap
*/
public static int getPowerLevelCap() {
return Config.getInstance().getPowerLevelCap();
return mcMMO.p.getGeneralConfig().getPowerLevelCap();
}
/**
@ -1126,25 +1206,22 @@ public final class ExperienceAPI {
}
}
// Utility methods follow.
private static void addOfflineXP(UUID playerUniqueId, PrimarySkillType skill, int XP) {
private static void addOfflineXP(@NotNull UUID playerUniqueId, @NotNull PrimarySkillType skill, int XP) {
PlayerProfile profile = getOfflineProfile(playerUniqueId);
profile.addXp(skill, XP);
profile.save(true);
}
@Deprecated
private static void addOfflineXP(String playerName, PrimarySkillType skill, int XP) {
private static void addOfflineXP(@NotNull String playerName, @NotNull PrimarySkillType skill, int XP) {
PlayerProfile profile = getOfflineProfile(playerName);
profile.addXp(skill, XP);
profile.scheduleAsyncSave();
}
private static PlayerProfile getOfflineProfile(UUID uuid) {
private static @NotNull PlayerProfile getOfflineProfile(@NotNull UUID uuid) throws InvalidPlayerException {
PlayerProfile profile = mcMMO.getDatabaseManager().loadPlayerProfile(uuid);
if (!profile.isLoaded()) {
@ -1154,10 +1231,18 @@ public final class ExperienceAPI {
return profile;
}
@Deprecated
private static PlayerProfile getOfflineProfile(String playerName) {
UUID uuid = mcMMO.p.getServer().getOfflinePlayer(playerName).getUniqueId();
PlayerProfile profile = mcMMO.getDatabaseManager().loadPlayerProfile(uuid);
private static @NotNull PlayerProfile getOfflineProfile(@NotNull OfflinePlayer offlinePlayer) throws InvalidPlayerException {
PlayerProfile profile = mcMMO.getDatabaseManager().loadPlayerProfile(offlinePlayer);
if (!profile.isLoaded()) {
throw new InvalidPlayerException();
}
return profile;
}
private static @NotNull PlayerProfile getOfflineProfile(@NotNull String playerName) throws InvalidPlayerException {
PlayerProfile profile = mcMMO.getDatabaseManager().loadPlayerProfile(playerName);
if (!profile.isLoaded()) {
throw new InvalidPlayerException();
@ -1167,7 +1252,7 @@ public final class ExperienceAPI {
}
private static PrimarySkillType getSkillType(String skillType) throws InvalidSkillException {
PrimarySkillType skill = PrimarySkillType.getSkill(skillType);
PrimarySkillType skill = mcMMO.p.getSkillTools().matchSkill(skillType);
if (skill == null) {
throw new InvalidSkillException();
@ -1179,7 +1264,7 @@ public final class ExperienceAPI {
private static PrimarySkillType getNonChildSkillType(String skillType) throws InvalidSkillException, UnsupportedOperationException {
PrimarySkillType skill = getSkillType(skillType);
if (skill.isChildSkill()) {
if (SkillTools.isChildSkill(skill)) {
throw new UnsupportedOperationException("Child skills do not have XP");
}

View File

@ -1,6 +1,5 @@
package com.gmail.nossr50.api;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.interactions.NotificationType;
import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.datatypes.party.PartyLeader;
@ -108,7 +107,7 @@ public final class PartyAPI {
*/
public static int getMaxPartySize()
{
return Config.getInstance().getPartyMaxSize();
return mcMMO.p.getGeneralConfig().getPartyMaxSize();
}
/**

View File

@ -1,6 +1,8 @@
package com.gmail.nossr50.api;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.skills.SkillTools;
import java.util.ArrayList;
import java.util.Arrays;
@ -30,7 +32,7 @@ public final class SkillAPI {
* @return a list of strings with valid skill names
*/
public static List<String> getNonChildSkills() {
return getListFromEnum(PrimarySkillType.NON_CHILD_SKILLS);
return getListFromEnum(SkillTools.NON_CHILD_SKILLS);
}
/**
@ -42,7 +44,7 @@ public final class SkillAPI {
* @return a list of strings with valid skill names
*/
public static List<String> getChildSkills() {
return getListFromEnum(PrimarySkillType.CHILD_SKILLS);
return getListFromEnum(mcMMO.p.getSkillTools().CHILD_SKILLS);
}
/**
@ -54,7 +56,7 @@ public final class SkillAPI {
* @return a list of strings with valid skill names
*/
public static List<String> getCombatSkills() {
return getListFromEnum(PrimarySkillType.COMBAT_SKILLS);
return getListFromEnum(mcMMO.p.getSkillTools().COMBAT_SKILLS);
}
/**
@ -66,7 +68,7 @@ public final class SkillAPI {
* @return a list of strings with valid skill names
*/
public static List<String> getGatheringSkills() {
return getListFromEnum(PrimarySkillType.GATHERING_SKILLS);
return getListFromEnum(mcMMO.p.getSkillTools().GATHERING_SKILLS);
}
/**
@ -78,7 +80,7 @@ public final class SkillAPI {
* @return a list of strings with valid skill names
*/
public static List<String> getMiscSkills() {
return getListFromEnum(PrimarySkillType.MISC_SKILLS);
return getListFromEnum(mcMMO.p.getSkillTools().MISC_SKILLS);
}
private static List<String> getListFromEnum(List<PrimarySkillType> skillsTypes) {

View File

@ -7,6 +7,6 @@ public class McMMOPlayerNotFoundException extends RuntimeException {
private static final long serialVersionUID = 761917904993202836L;
public McMMOPlayerNotFoundException(@NotNull Player player) {
super("McMMOPlayer object was not found for [NOTE: This can mean the profile is not loaded yet!] : " + player.getName() + " " + player.getUniqueId());
super("McMMOPlayer object was not found for [NOTE: This can mean the profile is not loaded yet! : " + player.getName() + " " + player.getUniqueId());
}
}

View File

@ -23,8 +23,7 @@ public class SamePartyPredicate<T extends CommandSender> implements Predicate<T>
if(t instanceof ConsoleCommandSender) {
return false; //Party audiences are special, we exclude console from them to avoid double messaging since we send a more verbose version to consoles
} else {
if(t instanceof Player) {
Player player = (Player) t;
if(t instanceof Player player) {
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
if(mcMMOPlayer != null) {
return mcMMOPlayer.getParty() == party;

View File

@ -1,46 +0,0 @@
package com.gmail.nossr50.commands;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.database.FlatfileDatabaseManager;
import com.gmail.nossr50.database.SQLDatabaseManager;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.player.UserManager;
import com.google.common.collect.ImmutableList;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class MHDCommand implements TabExecutor {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
if (mcMMO.getDatabaseManager() instanceof SQLDatabaseManager) {
SQLDatabaseManager m = (SQLDatabaseManager) mcMMO.getDatabaseManager();
m.resetMobHealthSettings();
for (McMMOPlayer player : UserManager.getPlayers()) {
player.getProfile().setMobHealthbarType(Config.getInstance().getMobHealthbarDefault());
}
sender.sendMessage("Mob health reset");
return true;
}
if (mcMMO.getDatabaseManager() instanceof FlatfileDatabaseManager) {
FlatfileDatabaseManager m = (FlatfileDatabaseManager) mcMMO.getDatabaseManager();
m.resetMobHealthSettings();
for (McMMOPlayer player : UserManager.getPlayers()) {
player.getProfile().setMobHealthbarType(Config.getInstance().getMobHealthbarDefault());
}
sender.sendMessage("Mob health reset");
return true;
}
return false;
}
@Override
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
return ImmutableList.of();
}
}

View File

@ -1,7 +1,6 @@
package com.gmail.nossr50.commands;
import com.gmail.nossr50.commands.party.PartySubcommandType;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.Permissions;
@ -26,7 +25,7 @@ public class McmmoCommand implements CommandExecutor {
sender.sendMessage(mcSplit);
sender.sendMessage(LocaleLoader.getString("mcMMO.Description.FormerDevs"));
if (Config.getInstance().getDonateMessageEnabled()) {
if (mcMMO.p.getGeneralConfig().getDonateMessageEnabled()) {
sender.sendMessage(LocaleLoader.getString("MOTD.Donate"));
sender.sendMessage(ChatColor.GOLD + " - " + ChatColor.GREEN + "nossr50@gmail.com" + ChatColor.GOLD + " Paypal");
}
@ -35,7 +34,7 @@ public class McmmoCommand implements CommandExecutor {
sender.sendMessage(LocaleLoader.getString("MOTD.Version", mcMMO.p.getDescription().getVersion()));
}
mcMMO.getHolidayManager().anniversaryCheck(sender);
// mcMMO.getHolidayManager().anniversaryCheck(sender);
return true;
case 1:

View File

@ -1,7 +1,7 @@
package com.gmail.nossr50.commands;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
import com.google.common.collect.ImmutableList;
@ -23,6 +23,16 @@ public class McscoreboardCommand implements TabExecutor {
return true;
}
if(!mcMMO.p.getGeneralConfig().getScoreboardsEnabled()) {
sender.sendMessage(LocaleLoader.getString("Scoreboard.Disabled"));
return true;
}
if(!ScoreboardManager.isPlayerBoardSetup(sender.getName())) {
sender.sendMessage(LocaleLoader.getString("Scoreboard.NotSetupYet"));
return true;
}
switch (args.length) {
case 1:
if (args[0].equalsIgnoreCase("clear") || args[0].equalsIgnoreCase("reset")) {
@ -32,7 +42,7 @@ public class McscoreboardCommand implements TabExecutor {
}
if (args[0].equalsIgnoreCase("keep")) {
if (!Config.getInstance().getAllowKeepBoard() || !Config.getInstance().getScoreboardsEnabled()) {
if (!mcMMO.p.getGeneralConfig().getAllowKeepBoard() || !mcMMO.p.getGeneralConfig().getScoreboardsEnabled()) {
sender.sendMessage(LocaleLoader.getString("Commands.Disabled"));
return true;
}

View File

@ -1,7 +1,5 @@
package com.gmail.nossr50.commands;
import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.datatypes.notifications.SensitiveCommandType;
import com.gmail.nossr50.locale.LocaleLoader;
@ -39,7 +37,7 @@ public class XprateCommand implements TabExecutor {
if (mcMMO.p.isXPEventEnabled()) {
if(AdvancedConfig.getInstance().useTitlesForXPEvent())
if(mcMMO.p.getAdvancedConfig().useTitlesForXPEvent())
{
NotificationManager.broadcastTitle(mcMMO.p.getServer(),
LocaleLoader.getString("Commands.Event.Stop"),
@ -47,7 +45,7 @@ public class XprateCommand implements TabExecutor {
10, 10*20, 20);
}
if(Config.getInstance().broadcastEventMessages())
if(mcMMO.p.getGeneralConfig().broadcastEventMessages())
{
mcMMO.p.getServer().broadcastMessage(LocaleLoader.getString("Commands.Event.Stop"));
mcMMO.p.getServer().broadcastMessage(LocaleLoader.getString("Commands.Event.Stop.Subtitle"));
@ -92,7 +90,7 @@ public class XprateCommand implements TabExecutor {
ExperienceConfig.getInstance().setExperienceGainsGlobalMultiplier(newXpRate);
if(AdvancedConfig.getInstance().useTitlesForXPEvent())
if(mcMMO.p.getAdvancedConfig().useTitlesForXPEvent())
{
NotificationManager.broadcastTitle(mcMMO.p.getServer(),
LocaleLoader.getString("Commands.Event.Start"),
@ -100,7 +98,7 @@ public class XprateCommand implements TabExecutor {
10, 10*20, 20);
}
if(Config.getInstance().broadcastEventMessages())
if(mcMMO.p.getGeneralConfig().broadcastEventMessages())
{
mcMMO.p.getServer().broadcastMessage(LocaleLoader.getString("Commands.Event.Start"));
mcMMO.p.getServer().broadcastMessage(LocaleLoader.getString("Commands.Event.XP", newXpRate));

View File

@ -27,7 +27,11 @@ public class ConvertDatabaseCommand implements CommandExecutor {
return true;
}
DatabaseManager oldDatabase = DatabaseManagerFactory.createDatabaseManager(previousType);
DatabaseManager oldDatabase = DatabaseManagerFactory.createDatabaseManager(previousType, mcMMO.getUsersFilePath(), mcMMO.p.getLogger(), mcMMO.p.getPurgeTime(), mcMMO.p.getAdvancedConfig().getStartingLevel());
if(oldDatabase == null) {
sender.sendMessage("Unable to load the old database! Check your log for errors.");
return true;
}
if (previousType == DatabaseType.CUSTOM) {
Class<?> clazz;
@ -54,7 +58,7 @@ public class ConvertDatabaseCommand implements CommandExecutor {
UserManager.clearAll();
for (Player player : mcMMO.p.getServer().getOnlinePlayers()) {
PlayerProfile profile = oldDatabase.loadPlayerProfile(player.getUniqueId());
PlayerProfile profile = oldDatabase.loadPlayerProfile(player);
if (profile.isLoaded()) {
mcMMO.getDatabaseManager().saveUser(profile);

View File

@ -1,6 +1,5 @@
package com.gmail.nossr50.commands.database;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.google.common.collect.ImmutableList;
@ -17,7 +16,7 @@ public class McpurgeCommand implements TabExecutor {
if (args.length == 0) {
mcMMO.getDatabaseManager().purgePowerlessUsers();
if (Config.getInstance().getOldUsersCutoff() != -1) {
if (mcMMO.p.getGeneralConfig().getOldUsersCutoff() != -1) {
mcMMO.getDatabaseManager().purgeOldUsers();
}

View File

@ -22,7 +22,7 @@ public class McremoveCommand implements TabExecutor {
if (args.length == 1) {
String playerName = CommandUtils.getMatchedPlayerName(args[0]);
if (UserManager.getOfflinePlayer(playerName) == null && CommandUtils.unloadedProfile(sender, mcMMO.getDatabaseManager().loadPlayerProfile(playerName, false))) {
if (UserManager.getOfflinePlayer(playerName) == null && CommandUtils.unloadedProfile(sender, mcMMO.getDatabaseManager().loadPlayerProfile(playerName))) {
return true;
}

View File

@ -1,8 +1,8 @@
package com.gmail.nossr50.commands.database;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.database.DatabaseManagerFactory;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.google.common.collect.ImmutableList;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@ -22,7 +22,7 @@ public class MmoshowdbCommand implements TabExecutor {
return true;
}
sender.sendMessage(LocaleLoader.getString("Commands.mmoshowdb", (Config.getInstance().getUseMySQL() ? "sql" : "flatfile")));
sender.sendMessage(LocaleLoader.getString("Commands.mmoshowdb", (mcMMO.p.getGeneralConfig().getUseMySQL() ? "sql" : "flatfile")));
return true;
}
return false;

View File

@ -5,6 +5,7 @@ import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.EventUtils;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
@ -55,6 +56,6 @@ public class AddlevelsCommand extends ExperienceCommand {
if(isSilent)
return;
player.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardSkill.1", value, skill.getName()));
player.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardSkill.1", value, mcMMO.p.getSkillTools().getLocalizedSkillName(skill)));
}
}

View File

@ -5,6 +5,7 @@ import com.gmail.nossr50.datatypes.experience.XPGainSource;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.command.CommandSender;
@ -49,6 +50,6 @@ public class AddxpCommand extends ExperienceCommand {
if(isSilent)
return;
player.sendMessage(LocaleLoader.getString("Commands.addxp.AwardSkill", value, skill.getName()));
player.sendMessage(LocaleLoader.getString("Commands.addxp.AwardSkill", value, mcMMO.p.getSkillTools().getLocalizedSkillName(skill)));
}
}

View File

@ -7,8 +7,8 @@ import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.skills.SkillTools;
import com.google.common.collect.ImmutableList;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
@ -18,7 +18,6 @@ import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public abstract class ExperienceCommand implements TabExecutor {
@Override
@ -44,13 +43,13 @@ public abstract class ExperienceCommand implements TabExecutor {
return true;
}
skill = PrimarySkillType.getSkill(args[0]);
skill = mcMMO.p.getSkillTools().matchSkill(args[0]);
if (args[1].equalsIgnoreCase("all")) {
skill = null;
}
if (skill != null && skill.isChildSkill())
if (skill != null && SkillTools.isChildSkill(skill))
{
sender.sendMessage(LocaleLoader.getString("Commands.Skill.ChildSkill"));
return true;
@ -77,13 +76,13 @@ public abstract class ExperienceCommand implements TabExecutor {
return true;
}
skill = PrimarySkillType.getSkill(args[1]);
skill = mcMMO.p.getSkillTools().matchSkill(args[1]);
if (args[1].equalsIgnoreCase("all")) {
skill = null;
}
if (skill != null && skill.isChildSkill())
if (skill != null && SkillTools.isChildSkill(skill))
{
sender.sendMessage(LocaleLoader.getString("Commands.Skill.ChildSkill"));
return true;
@ -96,15 +95,18 @@ public abstract class ExperienceCommand implements TabExecutor {
// If the mcMMOPlayer doesn't exist, create a temporary profile and check if it's present in the database. If it's not, abort the process.
if (mcMMOPlayer == null) {
UUID uuid = null;
OfflinePlayer player = mcMMO.p.getServer().getOfflinePlayer(playerName);
if (player != null) {
uuid = player.getUniqueId();
}
PlayerProfile profile = mcMMO.getDatabaseManager().loadPlayerProfile(playerName, uuid, false);
PlayerProfile profile;
profile = mcMMO.getDatabaseManager().loadPlayerProfile(playerName);
//Check loading by UUID
if (CommandUtils.unloadedProfile(sender, profile)) {
return true;
//Check loading by name
profile = mcMMO.getDatabaseManager().loadPlayerProfile(playerName);
if(CommandUtils.unloadedProfile(sender, profile)) {
return true;
}
}
editValues(null, profile, skill, value, isSilent(args));
@ -138,7 +140,7 @@ public abstract class ExperienceCommand implements TabExecutor {
List<String> playerNames = CommandUtils.getOnlinePlayerNames(sender);
return StringUtil.copyPartialMatches(args[0], playerNames, new ArrayList<>(playerNames.size()));
case 2:
return StringUtil.copyPartialMatches(args[1], PrimarySkillType.SKILL_NAMES, new ArrayList<>(PrimarySkillType.SKILL_NAMES.size()));
return StringUtil.copyPartialMatches(args[1], mcMMO.p.getSkillTools().LOCALIZED_SKILL_NAMES, new ArrayList<>(mcMMO.p.getSkillTools().LOCALIZED_SKILL_NAMES.size()));
default:
return ImmutableList.of();
}
@ -159,13 +161,13 @@ public abstract class ExperienceCommand implements TabExecutor {
sender.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardAll.2", playerName));
}
else {
sender.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardSkill.2", skill.getName(), playerName));
sender.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardSkill.2", mcMMO.p.getSkillTools().getLocalizedSkillName(skill), playerName));
}
}
protected void editValues(Player player, PlayerProfile profile, PrimarySkillType skill, int value, boolean isSilent) {
if (skill == null) {
for (PrimarySkillType primarySkillType : PrimarySkillType.NON_CHILD_SKILLS) {
for (PrimarySkillType primarySkillType : SkillTools.NON_CHILD_SKILLS) {
handleCommand(player, profile, primarySkillType, value);
}

View File

@ -5,6 +5,7 @@ import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.EventUtils;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
@ -61,6 +62,6 @@ public class MmoeditCommand extends ExperienceCommand {
if(isSilent)
return;
player.sendMessage(LocaleLoader.getString("Commands.mmoedit.Modified.1", skill.getName(), value));
player.sendMessage(LocaleLoader.getString("Commands.mmoedit.Modified.1", mcMMO.p.getSkillTools().getLocalizedSkillName(skill), value));
}
}

View File

@ -10,6 +10,7 @@ import com.gmail.nossr50.util.EventUtils;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.skills.SkillTools;
import com.google.common.collect.ImmutableList;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command;
@ -21,7 +22,6 @@ import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* This class mirrors the structure of ExperienceCommand, except the
@ -50,7 +50,7 @@ public class SkillresetCommand implements TabExecutor {
skill = null;
}
else {
skill = PrimarySkillType.getSkill(args[0]);
skill = mcMMO.p.getSkillTools().matchSkill(args[0]);
}
editValues((Player) sender, UserManager.getPlayer(sender.getName()).getProfile(), skill);
@ -70,7 +70,7 @@ public class SkillresetCommand implements TabExecutor {
skill = null;
}
else {
skill = PrimarySkillType.getSkill(args[1]);
skill = mcMMO.p.getSkillTools().matchSkill(args[1]);
}
String playerName = CommandUtils.getMatchedPlayerName(args[0]);
@ -78,15 +78,18 @@ public class SkillresetCommand implements TabExecutor {
// If the mcMMOPlayer doesn't exist, create a temporary profile and check if it's present in the database. If it's not, abort the process.
if (mcMMOPlayer == null) {
UUID uuid = null;
OfflinePlayer player = mcMMO.p.getServer().getOfflinePlayer(playerName);
if (player != null) {
uuid = player.getUniqueId();
}
PlayerProfile profile = mcMMO.getDatabaseManager().loadPlayerProfile(playerName, uuid, false);
OfflinePlayer offlinePlayer = mcMMO.p.getServer().getOfflinePlayer(playerName);
PlayerProfile profile = mcMMO.getDatabaseManager().loadPlayerProfile(offlinePlayer);
//Check loading by UUID
if (CommandUtils.unloadedProfile(sender, profile)) {
return true;
//Didn't find it by UUID so try to find it by name
profile = mcMMO.getDatabaseManager().loadPlayerProfile(playerName);
//Check if it was present in DB
if(CommandUtils.unloadedProfile(sender, profile)) {
return true;
}
}
editValues(null, profile, skill);
@ -110,7 +113,7 @@ public class SkillresetCommand implements TabExecutor {
List<String> playerNames = CommandUtils.getOnlinePlayerNames(sender);
return StringUtil.copyPartialMatches(args[0], playerNames, new ArrayList<>(playerNames.size()));
case 2:
return StringUtil.copyPartialMatches(args[1], PrimarySkillType.SKILL_NAMES, new ArrayList<>(PrimarySkillType.SKILL_NAMES.size()));
return StringUtil.copyPartialMatches(args[1], mcMMO.p.getSkillTools().LOCALIZED_SKILL_NAMES, new ArrayList<>(mcMMO.p.getSkillTools().LOCALIZED_SKILL_NAMES.size()));
default:
return ImmutableList.of();
}
@ -143,7 +146,7 @@ public class SkillresetCommand implements TabExecutor {
}
protected void handlePlayerMessageSkill(Player player, PrimarySkillType skill) {
player.sendMessage(LocaleLoader.getString("Commands.Reset.Single", skill.getName()));
player.sendMessage(LocaleLoader.getString("Commands.Reset.Single", mcMMO.p.getSkillTools().getLocalizedSkillName(skill)));
}
private boolean validateArguments(CommandSender sender, String skillName) {
@ -155,13 +158,13 @@ public class SkillresetCommand implements TabExecutor {
sender.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardAll.2", playerName));
}
else {
sender.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardSkill.2", skill.getName(), playerName));
sender.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardSkill.2", mcMMO.p.getSkillTools().getLocalizedSkillName(skill), playerName));
}
}
protected void editValues(Player player, PlayerProfile profile, PrimarySkillType skill) {
if (skill == null) {
for (PrimarySkillType primarySkillType : PrimarySkillType.NON_CHILD_SKILLS) {
for (PrimarySkillType primarySkillType : SkillTools.NON_CHILD_SKILLS) {
handleCommand(player, profile, primarySkillType);
}

View File

@ -1,64 +1,64 @@
package com.gmail.nossr50.commands.hardcore;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.Permissions;
import org.bukkit.command.CommandSender;
public class HardcoreCommand extends HardcoreModeCommand {
@Override
protected boolean checkTogglePermissions(CommandSender sender) {
return Permissions.hardcoreToggle(sender);
}
@Override
protected boolean checkModifyPermissions(CommandSender sender) {
return Permissions.hardcoreModify(sender);
}
@Override
protected boolean checkEnabled(PrimarySkillType skill) {
if (skill == null) {
for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
if (!primarySkillType.getHardcoreStatLossEnabled()) {
return false;
}
}
return true;
}
return skill.getHardcoreStatLossEnabled();
}
@Override
protected void enable(PrimarySkillType skill) {
toggle(true, skill);
}
@Override
protected void disable(PrimarySkillType skill) {
toggle(false, skill);
}
@Override
protected void modify(CommandSender sender, double newPercentage) {
Config.getInstance().setHardcoreDeathStatPenaltyPercentage(newPercentage);
sender.sendMessage(LocaleLoader.getString("Hardcore.DeathStatLoss.PercentageChanged", percent.format(newPercentage / 100.0D)));
}
private void toggle(boolean enable, PrimarySkillType skill) {
if (skill == null) {
for (PrimarySkillType primarySkillType : PrimarySkillType.NON_CHILD_SKILLS) {
primarySkillType.setHardcoreStatLossEnabled(enable);
}
}
else {
skill.setHardcoreStatLossEnabled(enable);
}
mcMMO.p.getServer().broadcastMessage(LocaleLoader.getString("Hardcore.Mode." + (enable ? "Enabled" : "Disabled"), LocaleLoader.getString("Hardcore.DeathStatLoss.Name"), (skill == null ? "all skills" : skill.getName())));
}
}
//package com.gmail.nossr50.commands.hardcore;
//
//import com.gmail.nossr50.config.Config;
//import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
//import com.gmail.nossr50.locale.LocaleLoader;
//import com.gmail.nossr50.mcMMO;
//import com.gmail.nossr50.util.Permissions;
//import org.bukkit.command.CommandSender;
//
//public class HardcoreCommand extends HardcoreModeCommand {
// @Override
// protected boolean checkTogglePermissions(CommandSender sender) {
// return Permissions.hardcoreToggle(sender);
// }
//
// @Override
// protected boolean checkModifyPermissions(CommandSender sender) {
// return Permissions.hardcoreModify(sender);
// }
//
// @Override
// protected boolean checkEnabled(PrimarySkillType skill) {
// if (skill == null) {
// for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
// if (!primarySkillType.getHardcoreStatLossEnabled()) {
// return false;
// }
// }
//
// return true;
// }
//
// return skill.getHardcoreStatLossEnabled();
// }
//
// @Override
// protected void enable(PrimarySkillType skill) {
// toggle(true, skill);
// }
//
// @Override
// protected void disable(PrimarySkillType skill) {
// toggle(false, skill);
// }
//
// @Override
// protected void modify(CommandSender sender, double newPercentage) {
// Config.getInstance().setHardcoreDeathStatPenaltyPercentage(newPercentage);
// sender.sendMessage(LocaleLoader.getString("Hardcore.DeathStatLoss.PercentageChanged", percent.format(newPercentage / 100.0D)));
// }
//
// private void toggle(boolean enable, PrimarySkillType skill) {
// if (skill == null) {
// for (PrimarySkillType primarySkillType : SkillTools.NON_CHILD_SKILLS) {
// primarySkillType.setHardcoreStatLossEnabled(enable);
// }
// }
// else {
// skill.setHardcoreStatLossEnabled(enable);
// }
//
// mcMMO.p.getServer().broadcastMessage(LocaleLoader.getString("Hardcore.Mode." + (enable ? "Enabled" : "Disabled"), LocaleLoader.getString("Hardcore.DeathStatLoss.Name"), (skill == null ? "all skills" : mcMMO.p.getSkillTools().getLocalizedSkillName(skill))));
// }
//}

View File

@ -1,129 +1,129 @@
package com.gmail.nossr50.commands.hardcore;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.text.StringUtils;
import com.google.common.collect.ImmutableList;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.util.StringUtil;
import org.jetbrains.annotations.NotNull;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
public abstract class HardcoreModeCommand implements TabExecutor {
protected final DecimalFormat percent = new DecimalFormat("##0.00%");
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
switch (args.length) {
case 0:
if (!checkTogglePermissions(sender)) {
sender.sendMessage(command.getPermissionMessage());
return true;
}
if (checkEnabled(null)) {
disable(null);
}
else {
enable(null);
}
return true;
case 1:
if (CommandUtils.shouldEnableToggle(args[0])) {
if (!Permissions.hardcoreToggle(sender)) {
sender.sendMessage(command.getPermissionMessage());
return true;
}
enable(null);
return true;
}
if (CommandUtils.shouldDisableToggle(args[0])) {
if (!Permissions.hardcoreToggle(sender)) {
sender.sendMessage(command.getPermissionMessage());
return true;
}
disable(null);
return true;
}
if (CommandUtils.isInvalidDouble(sender, args[0])) {
return true;
}
if (!Permissions.hardcoreModify(sender)) {
sender.sendMessage(command.getPermissionMessage());
return true;
}
modify(sender, Double.parseDouble(args[0]));
return true;
case 2:
if (CommandUtils.isInvalidSkill(sender, args[0])) {
return true;
}
PrimarySkillType skill = PrimarySkillType.getSkill(args[0]);
if (!CommandUtils.isChildSkill(sender, skill)) {
return true;
}
if (CommandUtils.shouldEnableToggle(args[1])) {
if (!Permissions.hardcoreToggle(sender)) {
sender.sendMessage(command.getPermissionMessage());
return true;
}
enable(skill);
return true;
}
if (CommandUtils.shouldDisableToggle(args[1])) {
if (!Permissions.hardcoreToggle(sender)) {
sender.sendMessage(command.getPermissionMessage());
return true;
}
enable(skill);
return true;
}
return true;
default:
return false;
}
}
@Override
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
if (args.length == 1) {
if (StringUtils.isDouble(args[0])) {
return ImmutableList.of();
}
return StringUtil.copyPartialMatches(args[0], CommandUtils.TRUE_FALSE_OPTIONS, new ArrayList<>(CommandUtils.TRUE_FALSE_OPTIONS.size()));
}
return ImmutableList.of();
}
protected abstract boolean checkTogglePermissions(CommandSender sender);
protected abstract boolean checkModifyPermissions(CommandSender sender);
protected abstract boolean checkEnabled(PrimarySkillType skill);
protected abstract void enable(PrimarySkillType skill);
protected abstract void disable(PrimarySkillType skill);
protected abstract void modify(CommandSender sender, double newPercentage);
}
//package com.gmail.nossr50.commands.hardcore;
//
//import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
//import com.gmail.nossr50.util.Permissions;
//import com.gmail.nossr50.util.commands.CommandUtils;
//import com.gmail.nossr50.util.text.StringUtils;
//import com.google.common.collect.ImmutableList;
//import org.bukkit.command.Command;
//import org.bukkit.command.CommandSender;
//import org.bukkit.command.TabExecutor;
//import org.bukkit.util.StringUtil;
//import org.jetbrains.annotations.NotNull;
//
//import java.text.DecimalFormat;
//import java.util.ArrayList;
//import java.util.List;
//
//public abstract class HardcoreModeCommand implements TabExecutor {
// protected final DecimalFormat percent = new DecimalFormat("##0.00%");
//
// @Override
// public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
// switch (args.length) {
// case 0:
// if (!checkTogglePermissions(sender)) {
// sender.sendMessage(command.getPermissionMessage());
// return true;
// }
//
// if (checkEnabled(null)) {
// disable(null);
// }
// else {
// enable(null);
// }
//
// return true;
//
// case 1:
// if (CommandUtils.shouldEnableToggle(args[0])) {
// if (!Permissions.hardcoreToggle(sender)) {
// sender.sendMessage(command.getPermissionMessage());
// return true;
// }
//
// enable(null);
// return true;
// }
//
// if (CommandUtils.shouldDisableToggle(args[0])) {
// if (!Permissions.hardcoreToggle(sender)) {
// sender.sendMessage(command.getPermissionMessage());
// return true;
// }
//
// disable(null);
// return true;
// }
//
// if (CommandUtils.isInvalidDouble(sender, args[0])) {
// return true;
// }
//
// if (!Permissions.hardcoreModify(sender)) {
// sender.sendMessage(command.getPermissionMessage());
// return true;
// }
//
// modify(sender, Double.parseDouble(args[0]));
// return true;
//
//
// case 2:
// if (CommandUtils.isInvalidSkill(sender, args[0])) {
// return true;
// }
//
// PrimarySkillType skill = PrimarySkillType.getSkill(args[0]);
//
// if (!CommandUtils.isChildSkill(sender, skill)) {
// return true;
// }
//
// if (CommandUtils.shouldEnableToggle(args[1])) {
// if (!Permissions.hardcoreToggle(sender)) {
// sender.sendMessage(command.getPermissionMessage());
// return true;
// }
//
// enable(skill);
// return true;
// }
//
// if (CommandUtils.shouldDisableToggle(args[1])) {
// if (!Permissions.hardcoreToggle(sender)) {
// sender.sendMessage(command.getPermissionMessage());
// return true;
// }
//
// enable(skill);
// return true;
// }
//
// return true;
//
// default:
// return false;
// }
// }
//
// @Override
// public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
// if (args.length == 1) {
// if (StringUtils.isDouble(args[0])) {
// return ImmutableList.of();
// }
//
// return StringUtil.copyPartialMatches(args[0], CommandUtils.TRUE_FALSE_OPTIONS, new ArrayList<>(CommandUtils.TRUE_FALSE_OPTIONS.size()));
// }
// return ImmutableList.of();
// }
//
// protected abstract boolean checkTogglePermissions(CommandSender sender);
// protected abstract boolean checkModifyPermissions(CommandSender sender);
// protected abstract boolean checkEnabled(PrimarySkillType skill);
// protected abstract void enable(PrimarySkillType skill);
// protected abstract void disable(PrimarySkillType skill);
// protected abstract void modify(CommandSender sender, double newPercentage);
//}

View File

@ -1,64 +1,64 @@
package com.gmail.nossr50.commands.hardcore;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.Permissions;
import org.bukkit.command.CommandSender;
public class VampirismCommand extends HardcoreModeCommand {
@Override
protected boolean checkTogglePermissions(CommandSender sender) {
return Permissions.vampirismToggle(sender);
}
@Override
protected boolean checkModifyPermissions(CommandSender sender) {
return Permissions.vampirismModify(sender);
}
@Override
protected boolean checkEnabled(PrimarySkillType skill) {
if (skill == null) {
for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
if (!primarySkillType.getHardcoreVampirismEnabled()) {
return false;
}
}
return true;
}
return skill.getHardcoreVampirismEnabled();
}
@Override
protected void enable(PrimarySkillType skill) {
toggle(true, skill);
}
@Override
protected void disable(PrimarySkillType skill) {
toggle(false, skill);
}
@Override
protected void modify(CommandSender sender, double newPercentage) {
Config.getInstance().setHardcoreVampirismStatLeechPercentage(newPercentage);
sender.sendMessage(LocaleLoader.getString("Hardcore.Vampirism.PercentageChanged", percent.format(newPercentage / 100.0D)));
}
private void toggle(boolean enable, PrimarySkillType skill) {
if (skill == null) {
for (PrimarySkillType primarySkillType : PrimarySkillType.NON_CHILD_SKILLS) {
primarySkillType.setHardcoreVampirismEnabled(enable);
}
}
else {
skill.setHardcoreVampirismEnabled(enable);
}
mcMMO.p.getServer().broadcastMessage(LocaleLoader.getString("Hardcore.Mode." + (enable ? "Enabled" : "Disabled"), LocaleLoader.getString("Hardcore.Vampirism.Name"), (skill == null ? "all skills" : skill)));
}
}
//package com.gmail.nossr50.commands.hardcore;
//
//import com.gmail.nossr50.config.Config;
//import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
//import com.gmail.nossr50.locale.LocaleLoader;
//import com.gmail.nossr50.mcMMO;
//import com.gmail.nossr50.util.Permissions;
//import org.bukkit.command.CommandSender;
//
//public class VampirismCommand extends HardcoreModeCommand {
// @Override
// protected boolean checkTogglePermissions(CommandSender sender) {
// return Permissions.vampirismToggle(sender);
// }
//
// @Override
// protected boolean checkModifyPermissions(CommandSender sender) {
// return Permissions.vampirismModify(sender);
// }
//
// @Override
// protected boolean checkEnabled(PrimarySkillType skill) {
// if (skill == null) {
// for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
// if (!primarySkillType.getHardcoreVampirismEnabled()) {
// return false;
// }
// }
//
// return true;
// }
//
// return skill.getHardcoreVampirismEnabled();
// }
//
// @Override
// protected void enable(PrimarySkillType skill) {
// toggle(true, skill);
// }
//
// @Override
// protected void disable(PrimarySkillType skill) {
// toggle(false, skill);
// }
//
// @Override
// protected void modify(CommandSender sender, double newPercentage) {
// Config.getInstance().setHardcoreVampirismStatLeechPercentage(newPercentage);
// sender.sendMessage(LocaleLoader.getString("Hardcore.Vampirism.PercentageChanged", percent.format(newPercentage / 100.0D)));
// }
//
// private void toggle(boolean enable, PrimarySkillType skill) {
// if (skill == null) {
// for (PrimarySkillType primarySkillType : SkillTools.NON_CHILD_SKILLS) {
// primarySkillType.setHardcoreVampirismEnabled(enable);
// }
// }
// else {
// skill.setHardcoreVampirismEnabled(enable);
// }
//
// mcMMO.p.getServer().broadcastMessage(LocaleLoader.getString("Hardcore.Mode." + (enable ? "Enabled" : "Disabled"), LocaleLoader.getString("Hardcore.Vampirism.Name"), (skill == null ? "all skills" : skill)));
// }
//}

View File

@ -1,6 +1,7 @@
package com.gmail.nossr50.commands.party;
import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.events.party.McMMOPartyChangeEvent.EventReason;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.party.PartyManager;
@ -15,13 +16,14 @@ public class PartyDisbandCommand implements CommandExecutor {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
if (args.length == 1) {
if (UserManager.getPlayer((Player) sender) == null) {
final McMMOPlayer mcMMOPlayer = UserManager.getPlayer((Player) sender);
if (mcMMOPlayer == null) {
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
return true;
}
Party playerParty = UserManager.getPlayer((Player) sender).getParty();
String partyName = playerParty.getName();
final Party playerParty = mcMMOPlayer.getParty();
final String partyName = playerParty.getName();
for (Player member : playerParty.getOnlineMembers()) {
if (!PartyManager.handlePartyChangeEvent(member, partyName, null, EventReason.KICKED_FROM_PARTY)) {
@ -31,7 +33,7 @@ public class PartyDisbandCommand implements CommandExecutor {
member.sendMessage(LocaleLoader.getString("Party.Disband"));
}
PartyManager.disbandParty(playerParty);
PartyManager.disbandParty(mcMMOPlayer, playerParty);
return true;
}
sender.sendMessage(LocaleLoader.getString("Commands.Usage.1", "party", "disband"));

View File

@ -1,11 +1,11 @@
package com.gmail.nossr50.commands.party;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.datatypes.party.PartyFeature;
import com.gmail.nossr50.datatypes.party.ShareMode;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.party.PartyManager;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.ChatColor;
@ -85,7 +85,7 @@ public class PartyInfoCommand implements CommandExecutor {
}
private boolean isUnlockedFeature(Party party, PartyFeature partyFeature) {
return party.getLevel() >= Config.getInstance().getPartyFeatureUnlockLevel(partyFeature);
return party.getLevel() >= mcMMO.p.getGeneralConfig().getPartyFeatureUnlockLevel(partyFeature);
}
private void displayShareModeInfo(Player player, Party party) {

View File

@ -1,9 +1,9 @@
package com.gmail.nossr50.commands.party;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.party.PartyManager;
import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.player.UserManager;
@ -53,7 +53,7 @@ public class PartyInviteCommand implements CommandExecutor {
Party playerParty = mcMMOPlayer.getParty();
if (PartyManager.isPartyFull(target, playerParty)) {
player.sendMessage(LocaleLoader.getString("Commands.Party.PartyFull.Invite", target.getName(), playerParty.toString(), Config.getInstance().getPartyMaxSize()));
player.sendMessage(LocaleLoader.getString("Commands.Party.PartyFull.Invite", target.getName(), playerParty.toString(), mcMMO.p.getGeneralConfig().getPartyMaxSize()));
return true;
}

View File

@ -1,11 +1,11 @@
package com.gmail.nossr50.commands.party;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.party.ItemShareType;
import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.datatypes.party.PartyFeature;
import com.gmail.nossr50.datatypes.party.ShareMode;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.text.StringUtils;
@ -28,7 +28,7 @@ public class PartyItemShareCommand implements CommandExecutor {
Party party = UserManager.getPlayer((Player) sender).getParty();
if (party.getLevel() < Config.getInstance().getPartyFeatureUnlockLevel(PartyFeature.ITEM_SHARE)) {
if (party.getLevel() < mcMMO.p.getGeneralConfig().getPartyFeatureUnlockLevel(PartyFeature.ITEM_SHARE)) {
sender.sendMessage(LocaleLoader.getString("Party.Feature.Disabled.4"));
return true;
}

View File

@ -1,10 +1,10 @@
package com.gmail.nossr50.commands.party;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.datatypes.party.PartyFeature;
import com.gmail.nossr50.datatypes.party.ShareMode;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.text.StringUtils;
@ -25,7 +25,7 @@ public class PartyXpShareCommand implements CommandExecutor {
Party party = UserManager.getPlayer((Player) sender).getParty();
if (party.getLevel() < Config.getInstance().getPartyFeatureUnlockLevel(PartyFeature.XP_SHARE)) {
if (party.getLevel() < mcMMO.p.getGeneralConfig().getPartyFeatureUnlockLevel(PartyFeature.XP_SHARE)) {
sender.sendMessage(LocaleLoader.getString("Party.Feature.Disabled.5"));
return true;
}

View File

@ -1,10 +1,10 @@
package com.gmail.nossr50.commands.party.alliance;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.datatypes.party.PartyFeature;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.party.PartyManager;
import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.player.UserManager;
@ -51,7 +51,7 @@ public class PartyAllianceCommand implements TabExecutor {
switch (args.length) {
case 1:
if (playerParty.getLevel() < Config.getInstance().getPartyFeatureUnlockLevel(PartyFeature.ALLIANCE)) {
if (playerParty.getLevel() < mcMMO.p.getGeneralConfig().getPartyFeatureUnlockLevel(PartyFeature.ALLIANCE)) {
sender.sendMessage(LocaleLoader.getString("Party.Feature.Disabled.3"));
return true;
}
@ -69,7 +69,7 @@ public class PartyAllianceCommand implements TabExecutor {
case 2:
case 3:
if (playerParty.getLevel() < Config.getInstance().getPartyFeatureUnlockLevel(PartyFeature.ALLIANCE)) {
if (playerParty.getLevel() < mcMMO.p.getGeneralConfig().getPartyFeatureUnlockLevel(PartyFeature.ALLIANCE)) {
sender.sendMessage(LocaleLoader.getString("Party.Feature.Disabled.3"));
return true;
}

View File

@ -1,8 +1,8 @@
package com.gmail.nossr50.commands.party.teleport;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.party.PartyTeleportRecord;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.skills.SkillUtils;
@ -35,7 +35,7 @@ public class PtpAcceptCommand implements CommandExecutor {
return true;
}
if (SkillUtils.cooldownExpired(ptpRecord.getTimeout(), Config.getInstance().getPTPCommandTimeout())) {
if (SkillUtils.cooldownExpired(ptpRecord.getTimeout(), mcMMO.p.getGeneralConfig().getPTPCommandTimeout())) {
ptpRecord.removeRequest();
player.sendMessage(LocaleLoader.getString("Commands.ptp.RequestExpired"));
return true;
@ -48,7 +48,7 @@ public class PtpAcceptCommand implements CommandExecutor {
return true;
}
if (Config.getInstance().getPTPCommandWorldPermissions()) {
if (mcMMO.p.getGeneralConfig().getPTPCommandWorldPermissions()) {
World targetWorld = target.getWorld();
World playerWorld = player.getWorld();

View File

@ -1,6 +1,5 @@
package com.gmail.nossr50.commands.party.teleport;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.WorldBlacklist;
import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.datatypes.party.PartyFeature;
@ -76,7 +75,7 @@ public class PtpCommand implements TabExecutor {
Party party = mcMMOPlayer.getParty();
if (party.getLevel() < Config.getInstance().getPartyFeatureUnlockLevel(PartyFeature.TELEPORT)) {
if (party.getLevel() < mcMMO.p.getGeneralConfig().getPartyFeatureUnlockLevel(PartyFeature.TELEPORT)) {
sender.sendMessage(LocaleLoader.getString("Party.Feature.Disabled.2"));
return true;
}
@ -91,7 +90,7 @@ public class PtpCommand implements TabExecutor {
}
long recentlyHurt = mcMMOPlayer.getRecentlyHurt();
int hurtCooldown = Config.getInstance().getPTPCommandRecentlyHurtCooldown();
int hurtCooldown = mcMMO.p.getGeneralConfig().getPTPCommandRecentlyHurtCooldown();
if (hurtCooldown > 0) {
int timeRemaining = SkillUtils.calculateTimeLeft(recentlyHurt * Misc.TIME_CONVERSION_FACTOR, hurtCooldown, player);
@ -111,7 +110,7 @@ public class PtpCommand implements TabExecutor {
return true;
}
int ptpCooldown = Config.getInstance().getPTPCommandCooldown();
int ptpCooldown = mcMMO.p.getGeneralConfig().getPTPCommandCooldown();
long ptpLastUse = mcMMOPlayer.getPartyTeleportRecord().getLastUse();
if (ptpCooldown > 0) {
@ -165,7 +164,7 @@ public class PtpCommand implements TabExecutor {
Player target = mcMMOTarget.getPlayer();
if (Config.getInstance().getPTPCommandWorldPermissions()) {
if (mcMMO.p.getGeneralConfig().getPTPCommandWorldPermissions()) {
World targetWorld = target.getWorld();
World playerWorld = player.getWorld();
@ -194,7 +193,7 @@ public class PtpCommand implements TabExecutor {
player.sendMessage(LocaleLoader.getString("Commands.Invite.Success"));
target.sendMessage(LocaleLoader.getString("Commands.ptp.Request1", player.getName()));
target.sendMessage(LocaleLoader.getString("Commands.ptp.Request2", Config.getInstance().getPTPCommandTimeout()));
target.sendMessage(LocaleLoader.getString("Commands.ptp.Request2", mcMMO.p.getGeneralConfig().getPTPCommandTimeout()));
}
protected static boolean canTeleport(CommandSender sender, Player player, String targetName) {
@ -245,7 +244,7 @@ public class PtpCommand implements TabExecutor {
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(teleportingPlayer);
McMMOPlayer mcMMOTarget = UserManager.getPlayer(targetPlayer);
long warmup = Config.getInstance().getPTPCommandWarmup();
long warmup = mcMMO.p.getGeneralConfig().getPTPCommandWarmup();
mcMMOPlayer.actualizeTeleportCommenceLocation(teleportingPlayer);

View File

@ -1,6 +1,5 @@
package com.gmail.nossr50.commands.player;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
@ -30,16 +29,18 @@ public class InspectCommand implements TabExecutor {
// If the mcMMOPlayer doesn't exist, create a temporary profile and check if it's present in the database. If it's not, abort the process.
if (mcMMOPlayer == null) {
PlayerProfile profile = mcMMO.getDatabaseManager().loadPlayerProfile(playerName, false); // Temporary Profile
PlayerProfile profile = mcMMO.getDatabaseManager().loadPlayerProfile(playerName); // Temporary Profile
if (!CommandUtils.isLoaded(sender, profile)) {
return true;
}
if (Config.getInstance().getScoreboardsEnabled() && sender instanceof Player && Config.getInstance().getInspectUseBoard()) {
if (mcMMO.p.getGeneralConfig().getScoreboardsEnabled()
&& sender instanceof Player
&& mcMMO.p.getGeneralConfig().getInspectUseBoard()) {
ScoreboardManager.enablePlayerInspectScoreboard((Player) sender, profile);
if (!Config.getInstance().getInspectUseChat()) {
if (!mcMMO.p.getGeneralConfig().getInspectUseChat()) {
return true;
}
}
@ -47,43 +48,56 @@ public class InspectCommand implements TabExecutor {
sender.sendMessage(LocaleLoader.getString("Inspect.OfflineStats", playerName));
sender.sendMessage(LocaleLoader.getString("Stats.Header.Gathering"));
for (PrimarySkillType skill : PrimarySkillType.GATHERING_SKILLS) {
for (PrimarySkillType skill : mcMMO.p.getSkillTools().GATHERING_SKILLS) {
sender.sendMessage(CommandUtils.displaySkill(profile, skill));
}
sender.sendMessage(LocaleLoader.getString("Stats.Header.Combat"));
for (PrimarySkillType skill : PrimarySkillType.COMBAT_SKILLS) {
for (PrimarySkillType skill : mcMMO.p.getSkillTools().COMBAT_SKILLS) {
sender.sendMessage(CommandUtils.displaySkill(profile, skill));
}
sender.sendMessage(LocaleLoader.getString("Stats.Header.Misc"));
for (PrimarySkillType skill : PrimarySkillType.MISC_SKILLS) {
for (PrimarySkillType skill : mcMMO.p.getSkillTools().MISC_SKILLS) {
sender.sendMessage(CommandUtils.displaySkill(profile, skill));
}
} else {
Player target = mcMMOPlayer.getPlayer();
boolean isVanished = false;
if (CommandUtils.hidden(sender, target, Permissions.inspectHidden(sender))) {
sender.sendMessage(LocaleLoader.getString("Inspect.Offline"));
return true;
} else if (CommandUtils.tooFar(sender, target, Permissions.inspectFar(sender))) {
isVanished = true;
}
//Only distance check players who are online and not vanished
if (!isVanished && CommandUtils.tooFar(sender, target, Permissions.inspectFar(sender))) {
return true;
}
if (Config.getInstance().getScoreboardsEnabled() && sender instanceof Player && Config.getInstance().getInspectUseBoard()) {
ScoreboardManager.enablePlayerInspectScoreboard((Player) sender, mcMMOPlayer.getProfile());
if (mcMMO.p.getGeneralConfig().getScoreboardsEnabled()
&& sender instanceof Player
&& mcMMO.p.getGeneralConfig().getInspectUseBoard()) {
ScoreboardManager.enablePlayerInspectScoreboard((Player) sender, mcMMOPlayer);
if (!Config.getInstance().getInspectUseChat()) {
if (!mcMMO.p.getGeneralConfig().getInspectUseChat()) {
return true;
}
}
sender.sendMessage(LocaleLoader.getString("Inspect.Stats", target.getName()));
if (isVanished) {
sender.sendMessage(LocaleLoader.getString("Inspect.OfflineStats", playerName));
} else {
sender.sendMessage(LocaleLoader.getString("Inspect.Stats", target.getName()));
}
CommandUtils.printGatheringSkills(target, sender);
CommandUtils.printCombatSkills(target, sender);
CommandUtils.printMiscSkills(target, sender);
sender.sendMessage(LocaleLoader.getString("Commands.PowerLevel", mcMMOPlayer.getPowerLevel()));
if (!isVanished) {
sender.sendMessage(LocaleLoader.getString("Commands.PowerLevel", mcMMOPlayer.getPowerLevel()));
}
}
return true;

View File

@ -1,9 +1,9 @@
package com.gmail.nossr50.commands.player;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
@ -30,10 +30,10 @@ public class MccooldownCommand implements TabExecutor {
if (args.length == 0) {
Player player = (Player) sender;
if (Config.getInstance().getScoreboardsEnabled() && Config.getInstance().getCooldownUseBoard()) {
if (mcMMO.p.getGeneralConfig().getScoreboardsEnabled() && mcMMO.p.getGeneralConfig().getCooldownUseBoard()) {
ScoreboardManager.enablePlayerCooldownScoreboard(player);
if (!Config.getInstance().getCooldownUseChat()) {
if (!mcMMO.p.getGeneralConfig().getCooldownUseChat()) {
return true;
}
}

View File

@ -1,10 +1,10 @@
package com.gmail.nossr50.commands.player;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.runnables.commands.McrankCommandAsyncTask;
import com.gmail.nossr50.util.MetadataConstants;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.player.UserManager;
@ -91,25 +91,25 @@ public class McrankCommand implements TabExecutor {
return;
}
long cooldownMillis = Math.min(Config.getInstance().getDatabasePlayerCooldown(), 1750);
long cooldownMillis = Math.min(mcMMO.p.getGeneralConfig().getDatabasePlayerCooldown(), 1750);
if (mcMMOPlayer.getDatabaseATS() + cooldownMillis > System.currentTimeMillis()) {
sender.sendMessage(LocaleLoader.getString("Commands.Database.CooldownMS", getCDSeconds(mcMMOPlayer, cooldownMillis)));
return;
}
if (((Player) sender).hasMetadata(mcMMO.databaseCommandKey)) {
if (((Player) sender).hasMetadata(MetadataConstants.METADATA_KEY_DATABASE_COMMAND)) {
sender.sendMessage(LocaleLoader.getString("Commands.Database.Processing"));
return;
} else {
((Player) sender).setMetadata(mcMMO.databaseCommandKey, new FixedMetadataValue(mcMMO.p, null));
((Player) sender).setMetadata(MetadataConstants.METADATA_KEY_DATABASE_COMMAND, new FixedMetadataValue(mcMMO.p, null));
}
mcMMOPlayer.actualizeDatabaseATS();
}
boolean useBoard = Config.getInstance().getScoreboardsEnabled() && (sender instanceof Player) && (Config.getInstance().getRankUseBoard());
boolean useChat = !useBoard || Config.getInstance().getRankUseChat();
boolean useBoard = mcMMO.p.getGeneralConfig().getScoreboardsEnabled() && (sender instanceof Player) && (mcMMO.p.getGeneralConfig().getRankUseBoard());
boolean useChat = !useBoard || mcMMO.p.getGeneralConfig().getRankUseChat();
new McrankCommandAsyncTask(playerName, sender, useBoard, useChat).runTaskAsynchronously(mcMMO.p);
}

View File

@ -1,7 +1,7 @@
package com.gmail.nossr50.commands.player;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
@ -33,10 +33,10 @@ public class McstatsCommand implements TabExecutor {
Player player = (Player) sender;
if (Config.getInstance().getStatsUseBoard() && Config.getInstance().getScoreboardsEnabled()) {
if (mcMMO.p.getGeneralConfig().getStatsUseBoard() && mcMMO.p.getGeneralConfig().getScoreboardsEnabled()) {
ScoreboardManager.enablePlayerStatsScoreboard(player);
if (!Config.getInstance().getStatsUseChat()) {
if (!mcMMO.p.getGeneralConfig().getStatsUseChat()) {
return true;
}
}
@ -48,7 +48,7 @@ public class McstatsCommand implements TabExecutor {
CommandUtils.printCombatSkills(player);
CommandUtils.printMiscSkills(player);
int powerLevelCap = Config.getInstance().getPowerLevelCap();
int powerLevelCap = mcMMO.p.getGeneralConfig().getPowerLevelCap();
if (powerLevelCap != Integer.MAX_VALUE) {
player.sendMessage(LocaleLoader.getString("Commands.PowerLevel.Capped", UserManager.getPlayer(player).getPowerLevel(), powerLevelCap));

View File

@ -1,11 +1,11 @@
package com.gmail.nossr50.commands.player;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.runnables.commands.MctopCommandAsyncTask;
import com.gmail.nossr50.util.MetadataConstants;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.player.UserManager;
@ -69,7 +69,7 @@ public class MctopCommand implements TabExecutor {
@Override
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
if (args.length == 1) {
return StringUtil.copyPartialMatches(args[0], PrimarySkillType.SKILL_NAMES, new ArrayList<>(PrimarySkillType.SKILL_NAMES.size()));
return StringUtil.copyPartialMatches(args[0], mcMMO.p.getSkillTools().LOCALIZED_SKILL_NAMES, new ArrayList<>(mcMMO.p.getSkillTools().LOCALIZED_SKILL_NAMES.size()));
}
return ImmutableList.of();
}
@ -86,7 +86,7 @@ public class MctopCommand implements TabExecutor {
}
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(sender.getName());
long cooldownMillis = Math.max(Config.getInstance().getDatabasePlayerCooldown(), 1750);
long cooldownMillis = Math.max(mcMMO.p.getGeneralConfig().getDatabasePlayerCooldown(), 1750);
if (mcMMOPlayer.getDatabaseATS() + cooldownMillis > System.currentTimeMillis()) {
double seconds = ((mcMMOPlayer.getDatabaseATS() + cooldownMillis) - System.currentTimeMillis()) / 1000.0D;
@ -98,11 +98,11 @@ public class MctopCommand implements TabExecutor {
return;
}
if (((Player) sender).hasMetadata(mcMMO.databaseCommandKey)) {
if (((Player) sender).hasMetadata(MetadataConstants.METADATA_KEY_DATABASE_COMMAND)) {
sender.sendMessage(LocaleLoader.getString("Commands.Database.Processing"));
return;
} else {
((Player) sender).setMetadata(mcMMO.databaseCommandKey, new FixedMetadataValue(mcMMO.p, null));
((Player) sender).setMetadata(MetadataConstants.METADATA_KEY_DATABASE_COMMAND, new FixedMetadataValue(mcMMO.p, null));
}
mcMMOPlayer.actualizeDatabaseATS();
@ -112,8 +112,8 @@ public class MctopCommand implements TabExecutor {
}
private void display(int page, PrimarySkillType skill, CommandSender sender) {
boolean useBoard = (sender instanceof Player) && (Config.getInstance().getTopUseBoard());
boolean useChat = !useBoard || Config.getInstance().getTopUseChat();
boolean useBoard = (sender instanceof Player) && (mcMMO.p.getGeneralConfig().getTopUseBoard());
boolean useChat = !useBoard || mcMMO.p.getGeneralConfig().getTopUseChat();
new MctopCommandAsyncTask(page, skill, sender, useBoard, useChat).runTaskAsynchronously(mcMMO.p);
}
@ -123,7 +123,7 @@ public class MctopCommand implements TabExecutor {
return null;
}
PrimarySkillType skill = PrimarySkillType.getSkill(skillName);
PrimarySkillType skill = mcMMO.p.getSkillTools().matchSkill(skillName);
if (CommandUtils.isChildSkill(sender, skill)) {
return null;

View File

@ -2,6 +2,7 @@ package com.gmail.nossr50.commands.player;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.experience.ExperienceBarManager;
import com.gmail.nossr50.util.player.NotificationManager;
import com.gmail.nossr50.util.player.UserManager;
@ -51,7 +52,7 @@ public class XPBarCommand implements TabExecutor {
if(SkillUtils.isSkill(skillName)) {
PrimarySkillType targetSkill = PrimarySkillType.getSkill(skillName);
PrimarySkillType targetSkill = mcMMO.p.getSkillTools().matchSkill(skillName);
//Target setting
String option = args[0].toLowerCase();
@ -103,7 +104,7 @@ public class XPBarCommand implements TabExecutor {
return StringUtil.copyPartialMatches(args[0], options, new ArrayList<>(ExperienceBarManager.XPBarSettingTarget.values().length));
case 2:
if(!args[0].equalsIgnoreCase(ExperienceBarManager.XPBarSettingTarget.RESET.toString()))
return StringUtil.copyPartialMatches(args[1], PrimarySkillType.SKILL_NAMES, new ArrayList<>(PrimarySkillType.SKILL_NAMES.size()));
return StringUtil.copyPartialMatches(args[1], mcMMO.p.getSkillTools().LOCALIZED_SKILL_NAMES, new ArrayList<>(mcMMO.p.getSkillTools().LOCALIZED_SKILL_NAMES.size()));
default:
return ImmutableList.of();
}

View File

@ -1,199 +1,199 @@
package com.gmail.nossr50.commands.skills;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.util.HolidayManager.FakeSkillType;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.text.StringUtils;
import com.google.common.collect.ImmutableList;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
public class AprilCommand implements TabExecutor {
private String skillName;
protected DecimalFormat percent = new DecimalFormat("##0.00%");
protected DecimalFormat decimal = new DecimalFormat("##0.00");
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
if (CommandUtils.noConsoleUsage(sender)) {
return true;
}
skillName = StringUtils.getCapitalized(label);
if (args.length == 0) {
Player player = (Player) sender;
FakeSkillType fakeSkillType = FakeSkillType.getByName(skillName);
float skillValue = Misc.getRandom().nextInt(99);
player.sendMessage(LocaleLoader.getString("Skills.Header", skillName));
player.sendMessage(LocaleLoader.getString("Commands.XPGain", getXPGainString(fakeSkillType)));
player.sendMessage(LocaleLoader.getString("Effects.Level", (int) skillValue, Misc.getRandom().nextInt(1000), 1000 + Misc.getRandom().nextInt(1000)));
List<String> effectMessages = effectsDisplay(fakeSkillType);
if (!effectMessages.isEmpty()) {
player.sendMessage(LocaleLoader.getString("Skills.Header", LocaleLoader.getString("Effects.Effects")));
for (String message : effectMessages) {
player.sendMessage(message);
}
}
List<String> statsMessages = statsDisplay(fakeSkillType);
if (!statsMessages.isEmpty()) {
player.sendMessage(LocaleLoader.getString("Skills.Header", LocaleLoader.getString("Commands.Stats.Self")));
for (String message : statsMessages) {
player.sendMessage(message);
}
}
player.sendMessage(LocaleLoader.formatString("[[DARK_AQUA]]Guide for {0} available - type /APRIL FOOLS ! :D", skillName));
return true;
}
return true;
}
private String getXPGainString(FakeSkillType fakeSkillType) {
switch (fakeSkillType) {
case MACHO:
return "Get beaten up";
case JUMPING:
return "Kris Kross will make ya Jump Jump";
case THROWING:
return "Chuck your items on the floor";
case WRECKING:
return "I'M GONNA WRECK IT!";
case CRAFTING:
return "Craft apple pies";
case WALKING:
return "Walk around the park";
case SWIMMING:
return "Like a fish on a bicycle";
case FALLING:
return "Faceplant the floor, headbutt the ground";
case CLIMBING:
return "Climb the highest mountain";
case FLYING:
return "I believe I can fly";
case DIVING:
return "Scuba club 4000";
case PIGGY:
return "OINK! OINK!";
default:
return "Sit and wait?";
}
}
@Override
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
if (args.length == 1) {
return ImmutableList.of("?");
}
return ImmutableList.of();
}
private List<String> effectsDisplay(FakeSkillType fakeSkillType) {
List<String> messages = new ArrayList<>();
switch (fakeSkillType) {
case MACHO:
messages.add(LocaleLoader.getString("Effects.Template", "Punching bag", "Absorb damage, like a bag of sand"));
break;
case JUMPING:
messages.add(LocaleLoader.getString("Effects.Template", "Jump", "PRESS SPACE TO JUMP"));
messages.add(LocaleLoader.getString("Effects.Template", "Jump Twice", "PRESS SPACE TWICE TO JUMP TWICE"));
break;
case THROWING:
messages.add(LocaleLoader.getString("Effects.Template", "Drop Item", "Randomly drop items, at random"));
break;
case WRECKING:
messages.add(LocaleLoader.getString("Effects.Template", "Ralphinator", "Smash windows with your fists"));
break;
case CRAFTING:
messages.add(LocaleLoader.getString("Effects.Template", "Crafting", "Chance of successful craft"));
break;
case WALKING:
messages.add(LocaleLoader.getString("Effects.Template", "Walk", "Traveling gracefully by foot"));
break;
case SWIMMING:
messages.add(LocaleLoader.getString("Effects.Template", "Swim", "Just keep swimming, swimming, swimming"));
break;
case FALLING:
messages.add(LocaleLoader.getString("Effects.Template", "Skydiving", "Go jump of a cliff. No, seriously."));
break;
case CLIMBING:
messages.add(LocaleLoader.getString("Effects.Template", "Rock Climber", "Use string to climb mountains faster"));
break;
case FLYING:
messages.add(LocaleLoader.getString("Effects.Template", "Fly", "Throw yourself at the ground and miss"));
break;
case DIVING:
messages.add(LocaleLoader.getString("Effects.Template", "Hold Breath", "Press shift to hold your breath longer"));
break;
case PIGGY:
messages.add(LocaleLoader.getString("Effects.Template", "Carrot Turbo", "Supercharge your pigs with carrots"));
break;
}
return messages;
}
private List<String> statsDisplay(FakeSkillType fakeSkillType) {
List<String> messages = new ArrayList<>();
switch (fakeSkillType) {
case MACHO:
messages.add(LocaleLoader.formatString("&cDamage Taken: &e{0}%", decimal.format(Misc.getRandom().nextInt(77))));
break;
case JUMPING:
messages.add(LocaleLoader.formatString("&cDouble Jump Chance: &e{0}%", decimal.format(Misc.getRandom().nextInt(27))));
break;
case THROWING:
messages.add(LocaleLoader.formatString("&cDrop Item Chance: &e{0}%", decimal.format(Misc.getRandom().nextInt(87))));
break;
case WRECKING:
messages.add(LocaleLoader.formatString("&cWrecking Chance: &e{0}%", decimal.format(Misc.getRandom().nextInt(14))));
break;
case CRAFTING:
messages.add(LocaleLoader.formatString("&cCrafting Success: &e{0}%", decimal.format(Misc.getRandom().nextInt(27))));
break;
case WALKING:
messages.add(LocaleLoader.formatString("&cWalk Chance: &e{0}%", decimal.format(Misc.getRandom().nextInt(27))));
break;
case SWIMMING:
messages.add(LocaleLoader.formatString("&cSwim Chance: &e{0}%", decimal.format(Misc.getRandom().nextInt(27))));
break;
case FALLING:
messages.add(LocaleLoader.formatString("&cSkydiving Success: &e{0}%", decimal.format(Misc.getRandom().nextInt(37))));
break;
case CLIMBING:
messages.add(LocaleLoader.formatString("&cRock Climber Chance: &e{0}%", decimal.format(Misc.getRandom().nextInt(27))));
break;
case FLYING:
messages.add(LocaleLoader.formatString("&cFly Chance: &e{0}%", decimal.format(Misc.getRandom().nextInt(27))));
break;
case DIVING:
messages.add(LocaleLoader.formatString("&cHold Breath Chance: &e{0}%", decimal.format(Misc.getRandom().nextInt(27))));
break;
case PIGGY:
messages.add(LocaleLoader.formatString("&cCarrot Turbo Boost: &e{0}%", decimal.format(Misc.getRandom().nextInt(80)) + 10));
break;
}
return messages;
}
}
//package com.gmail.nossr50.commands.skills;
//
//import com.gmail.nossr50.locale.LocaleLoader;
//import com.gmail.nossr50.util.HolidayManager.FakeSkillType;
//import com.gmail.nossr50.util.Misc;
//import com.gmail.nossr50.util.commands.CommandUtils;
//import com.gmail.nossr50.util.text.StringUtils;
//import com.google.common.collect.ImmutableList;
//import org.bukkit.command.Command;
//import org.bukkit.command.CommandSender;
//import org.bukkit.command.TabExecutor;
//import org.bukkit.entity.Player;
//import org.jetbrains.annotations.NotNull;
//
//import java.text.DecimalFormat;
//import java.util.ArrayList;
//import java.util.List;
//
//public class AprilCommand implements TabExecutor {
// private String skillName;
//
// protected DecimalFormat percent = new DecimalFormat("##0.00%");
// protected DecimalFormat decimal = new DecimalFormat("##0.00");
//
// @Override
// public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
// if (CommandUtils.noConsoleUsage(sender)) {
// return true;
// }
//
// skillName = StringUtils.getCapitalized(label);
//
// if (args.length == 0) {
// Player player = (Player) sender;
// FakeSkillType fakeSkillType = FakeSkillType.getByName(skillName);
//
// float skillValue = Misc.getRandom().nextInt(99);
//
// player.sendMessage(LocaleLoader.getString("Skills.Header", skillName));
// player.sendMessage(LocaleLoader.getString("Commands.XPGain", getXPGainString(fakeSkillType)));
// player.sendMessage(LocaleLoader.getString("Effects.Level", (int) skillValue, Misc.getRandom().nextInt(1000), 1000 + Misc.getRandom().nextInt(1000)));
//
//
// List<String> effectMessages = effectsDisplay(fakeSkillType);
//
// if (!effectMessages.isEmpty()) {
// player.sendMessage(LocaleLoader.getString("Skills.Header", LocaleLoader.getString("Effects.Effects")));
//
// for (String message : effectMessages) {
// player.sendMessage(message);
// }
// }
//
// List<String> statsMessages = statsDisplay(fakeSkillType);
//
// if (!statsMessages.isEmpty()) {
// player.sendMessage(LocaleLoader.getString("Skills.Header", LocaleLoader.getString("Commands.Stats.Self")));
//
// for (String message : statsMessages) {
// player.sendMessage(message);
// }
// }
//
// player.sendMessage(LocaleLoader.formatString("[[DARK_AQUA]]Guide for {0} available - type /APRIL FOOLS ! :D", skillName));
// return true;
// }
// return true;
// }
//
// private String getXPGainString(FakeSkillType fakeSkillType) {
// switch (fakeSkillType) {
// case MACHO:
// return "Get beaten up";
// case JUMPING:
// return "Kris Kross will make ya Jump Jump";
// case THROWING:
// return "Chuck your items on the floor";
// case WRECKING:
// return "I'M GONNA WRECK IT!";
// case CRAFTING:
// return "Craft apple pies";
// case WALKING:
// return "Walk around the park";
// case SWIMMING:
// return "Like a fish on a bicycle";
// case FALLING:
// return "Faceplant the floor, headbutt the ground";
// case CLIMBING:
// return "Climb the highest mountain";
// case FLYING:
// return "I believe I can fly";
// case DIVING:
// return "Scuba club 4000";
// case PIGGY:
// return "OINK! OINK!";
// default:
// return "Sit and wait?";
// }
// }
//
// @Override
// public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
// if (args.length == 1) {
// return ImmutableList.of("?");
// }
// return ImmutableList.of();
// }
//
// private List<String> effectsDisplay(FakeSkillType fakeSkillType) {
// List<String> messages = new ArrayList<>();
//
// switch (fakeSkillType) {
// case MACHO:
// messages.add(LocaleLoader.getString("Effects.Template", "Punching bag", "Absorb damage, like a bag of sand"));
// break;
// case JUMPING:
// messages.add(LocaleLoader.getString("Effects.Template", "Jump", "PRESS SPACE TO JUMP"));
// messages.add(LocaleLoader.getString("Effects.Template", "Jump Twice", "PRESS SPACE TWICE TO JUMP TWICE"));
// break;
// case THROWING:
// messages.add(LocaleLoader.getString("Effects.Template", "Drop Item", "Randomly drop items, at random"));
// break;
// case WRECKING:
// messages.add(LocaleLoader.getString("Effects.Template", "Ralphinator", "Smash windows with your fists"));
// break;
// case CRAFTING:
// messages.add(LocaleLoader.getString("Effects.Template", "Crafting", "Chance of successful craft"));
// break;
// case WALKING:
// messages.add(LocaleLoader.getString("Effects.Template", "Walk", "Traveling gracefully by foot"));
// break;
// case SWIMMING:
// messages.add(LocaleLoader.getString("Effects.Template", "Swim", "Just keep swimming, swimming, swimming"));
// break;
// case FALLING:
// messages.add(LocaleLoader.getString("Effects.Template", "Skydiving", "Go jump of a cliff. No, seriously."));
// break;
// case CLIMBING:
// messages.add(LocaleLoader.getString("Effects.Template", "Rock Climber", "Use string to climb mountains faster"));
// break;
// case FLYING:
// messages.add(LocaleLoader.getString("Effects.Template", "Fly", "Throw yourself at the ground and miss"));
// break;
// case DIVING:
// messages.add(LocaleLoader.getString("Effects.Template", "Hold Breath", "Press shift to hold your breath longer"));
// break;
// case PIGGY:
// messages.add(LocaleLoader.getString("Effects.Template", "Carrot Turbo", "Supercharge your pigs with carrots"));
// break;
// }
//
// return messages;
// }
//
// private List<String> statsDisplay(FakeSkillType fakeSkillType) {
// List<String> messages = new ArrayList<>();
//
// switch (fakeSkillType) {
// case MACHO:
// messages.add(LocaleLoader.formatString("&cDamage Taken: &e{0}%", decimal.format(Misc.getRandom().nextInt(77))));
// break;
// case JUMPING:
// messages.add(LocaleLoader.formatString("&cDouble Jump Chance: &e{0}%", decimal.format(Misc.getRandom().nextInt(27))));
// break;
// case THROWING:
// messages.add(LocaleLoader.formatString("&cDrop Item Chance: &e{0}%", decimal.format(Misc.getRandom().nextInt(87))));
// break;
// case WRECKING:
// messages.add(LocaleLoader.formatString("&cWrecking Chance: &e{0}%", decimal.format(Misc.getRandom().nextInt(14))));
// break;
// case CRAFTING:
// messages.add(LocaleLoader.formatString("&cCrafting Success: &e{0}%", decimal.format(Misc.getRandom().nextInt(27))));
// break;
// case WALKING:
// messages.add(LocaleLoader.formatString("&cWalk Chance: &e{0}%", decimal.format(Misc.getRandom().nextInt(27))));
// break;
// case SWIMMING:
// messages.add(LocaleLoader.formatString("&cSwim Chance: &e{0}%", decimal.format(Misc.getRandom().nextInt(27))));
// break;
// case FALLING:
// messages.add(LocaleLoader.formatString("&cSkydiving Success: &e{0}%", decimal.format(Misc.getRandom().nextInt(37))));
// break;
// case CLIMBING:
// messages.add(LocaleLoader.formatString("&cRock Climber Chance: &e{0}%", decimal.format(Misc.getRandom().nextInt(27))));
// break;
// case FLYING:
// messages.add(LocaleLoader.formatString("&cFly Chance: &e{0}%", decimal.format(Misc.getRandom().nextInt(27))));
// break;
// case DIVING:
// messages.add(LocaleLoader.formatString("&cHold Breath Chance: &e{0}%", decimal.format(Misc.getRandom().nextInt(27))));
// break;
// case PIGGY:
// messages.add(LocaleLoader.formatString("&cCarrot Turbo Boost: &e{0}%", decimal.format(Misc.getRandom().nextInt(80)) + 10));
// break;
// }
//
// return messages;
// }
//}

View File

@ -3,6 +3,7 @@ package com.gmail.nossr50.commands.skills;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.skills.SkillUtils;
@ -90,10 +91,10 @@ public class HerbalismCommand extends SkillCommand {
protected void permissionsCheck(Player player) {
hasHylianLuck = Permissions.canUseSubSkill(player, SubSkillType.HERBALISM_HYLIAN_LUCK);
canGreenTerra = Permissions.greenTerra(player);
canGreenThumbPlants = RankUtils.hasUnlockedSubskill(player, SubSkillType.HERBALISM_GREEN_THUMB) && (Permissions.greenThumbPlant(player, Material.WHEAT) || Permissions.greenThumbPlant(player, Material.CARROT) || Permissions.greenThumbPlant(player, Material.POTATO) || Permissions.greenThumbPlant(player, Material.BEETROOT) || Permissions.greenThumbPlant(player, Material.NETHER_WART) || Permissions.greenThumbPlant(player, Material.COCOA));
canGreenThumbPlants = RankUtils.hasUnlockedSubskill(player, SubSkillType.HERBALISM_GREEN_THUMB) && (Permissions.greenThumbPlant(player, Material.WHEAT) || Permissions.greenThumbPlant(player, Material.CARROT) || Permissions.greenThumbPlant(player, Material.POTATO) || Permissions.greenThumbPlant(player, Material.BEETROOTS) || Permissions.greenThumbPlant(player, Material.NETHER_WART) || Permissions.greenThumbPlant(player, Material.COCOA));
canGreenThumbBlocks = RankUtils.hasUnlockedSubskill(player, SubSkillType.HERBALISM_GREEN_THUMB) && (Permissions.greenThumbBlock(player, Material.DIRT) || Permissions.greenThumbBlock(player, Material.COBBLESTONE) || Permissions.greenThumbBlock(player, Material.COBBLESTONE_WALL) || Permissions.greenThumbBlock(player, Material.STONE_BRICKS));
canFarmersDiet = Permissions.canUseSubSkill(player, SubSkillType.HERBALISM_FARMERS_DIET);
canDoubleDrop = Permissions.canUseSubSkill(player, SubSkillType.HERBALISM_DOUBLE_DROPS) && !skill.getDoubleDropsDisabled();
canDoubleDrop = Permissions.canUseSubSkill(player, SubSkillType.HERBALISM_DOUBLE_DROPS) && !mcMMO.p.getGeneralConfig().getDoubleDropsDisabled(skill);
canShroomThumb = Permissions.canUseSubSkill(player, SubSkillType.HERBALISM_SHROOM_THUMB);
}

View File

@ -1,10 +1,9 @@
package com.gmail.nossr50.commands.skills;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.datatypes.skills.subskills.AbstractSubSkill;
import com.gmail.nossr50.listeners.InteractionManager;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.text.TextComponentFactory;
import com.google.common.collect.ImmutableList;
@ -28,12 +27,11 @@ public class MmoInfoCommand implements TabExecutor {
/*
* Only allow players to use this command
*/
if(commandSender instanceof Player)
if(commandSender instanceof Player player)
{
if(args.length < 1)
return false;
Player player = (Player) commandSender;
if(Permissions.mmoinfo(player))
{
if(args == null || args[0] == null)
@ -46,7 +44,7 @@ public class MmoInfoCommand implements TabExecutor {
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.DetailsHeader"));
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.Mystery"));
return true;
} else if(InteractionManager.getAbstractByName(args[0]) != null || PrimarySkillType.SUBSKILL_NAMES.contains(args[0]))
} else if(InteractionManager.getAbstractByName(args[0]) != null || mcMMO.p.getSkillTools().EXACT_SUBSKILL_NAMES.contains(args[0]))
{
displayInfo(player, args[0]);
return true;
@ -64,29 +62,17 @@ public class MmoInfoCommand implements TabExecutor {
@Override
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
if (args.length == 1) {
return StringUtil.copyPartialMatches(args[0], PrimarySkillType.SUBSKILL_NAMES, new ArrayList<>(PrimarySkillType.SUBSKILL_NAMES.size()));
return StringUtil.copyPartialMatches(args[0], mcMMO.p.getSkillTools().EXACT_SUBSKILL_NAMES, new ArrayList<>(mcMMO.p.getSkillTools().EXACT_SUBSKILL_NAMES.size()));
}
return ImmutableList.of();
}
private void displayInfo(Player player, String subSkillName)
{
//Check to see if the skill exists in the new system
AbstractSubSkill abstractSubSkill = InteractionManager.getAbstractByName(subSkillName);
if(abstractSubSkill != null)
{
/* New System Skills are programmable */
abstractSubSkill.printInfo(player);
//TextComponentFactory.sendPlayerUrlHeader(player);
} else {
/*
* Skill is only in the old system
*/
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.Header"));
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.SubSkillHeader", subSkillName));
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.DetailsHeader"));
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.OldSkill"));
}
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.Header"));
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.SubSkillHeader", subSkillName));
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.DetailsHeader"));
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.OldSkill"));
for(SubSkillType subSkillType : SubSkillType.values())
{

View File

@ -1,18 +1,21 @@
package com.gmail.nossr50.commands.skills;
import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.child.FamilyTree;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.player.NotificationManager;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.random.RandomChanceUtil;
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
import com.gmail.nossr50.util.skills.PerksUtils;
import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.skills.SkillActivationType;
import com.gmail.nossr50.util.skills.SkillTools;
import com.gmail.nossr50.util.text.StringUtils;
import com.gmail.nossr50.util.text.TextComponentFactory;
import com.google.common.collect.ImmutableList;
@ -42,7 +45,7 @@ public abstract class SkillCommand implements TabExecutor {
public SkillCommand(PrimarySkillType skill) {
this.skill = skill;
skillName = skill.getName();
skillName = mcMMO.p.getSkillTools().getLocalizedSkillName(skill);
skillGuideCommand = new SkillGuideCommand(skill);
}
@ -56,26 +59,24 @@ public abstract class SkillCommand implements TabExecutor {
return true;
}
if(UserManager.getPlayer((Player) sender) == null)
{
Player player = (Player) sender;
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
if (mcMMOPlayer == null) {
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
return true;
}
if (args.length == 0) {
Player player = (Player) sender;
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
boolean isLucky = Permissions.lucky(player, skill);
boolean hasEndurance = (PerksUtils.handleActivationPerks(player, 0, 0) != 0);
boolean hasEndurance = PerksUtils.handleActivationPerks(player, 0, 0) != 0;
float skillValue = mcMMOPlayer.getSkillLevel(skill);
//Send the players a few blank lines to make finding the top of the skill command easier
if (AdvancedConfig.getInstance().doesSkillCommandSendBlankLines()) {
if (mcMMO.p.getAdvancedConfig().doesSkillCommandSendBlankLines())
for (int i = 0; i < 2; i++) {
player.sendMessage("");
}
}
permissionsCheck(player);
dataCalculations(player, skillValue);
@ -104,18 +105,31 @@ public abstract class SkillCommand implements TabExecutor {
//Link Header
if (Config.getInstance().getUrlLinksEnabled()) {
if (mcMMO.p.getGeneralConfig().getUrlLinksEnabled()) {
player.sendMessage(LocaleLoader.getString("Overhaul.mcMMO.Header"));
TextComponentFactory.sendPlayerUrlHeader(player);
}
if (Config.getInstance().getScoreboardsEnabled() && Config.getInstance().getSkillUseBoard()) {
if (mcMMO.p.getGeneralConfig().getScoreboardsEnabled() && mcMMO.p.getGeneralConfig().getSkillUseBoard()) {
ScoreboardManager.enablePlayerSkillScoreboard(player, skill);
}
return true;
} else if ("keep".equals(args[0].toLowerCase())) {
if (!mcMMO.p.getGeneralConfig().getAllowKeepBoard()
|| !mcMMO.p.getGeneralConfig().getScoreboardsEnabled()
|| !mcMMO.p.getGeneralConfig().getSkillUseBoard()) {
sender.sendMessage(LocaleLoader.getString("Commands.Disabled"));
return true;
}
ScoreboardManager.enablePlayerSkillScoreboard(player, skill);
ScoreboardManager.keepBoard(sender.getName());
sender.sendMessage(LocaleLoader.getString("Commands.Scoreboard.Keep"));
return true;
}
return skillGuideCommand.onCommand(sender, command, label, args);
}
@ -134,13 +148,14 @@ public abstract class SkillCommand implements TabExecutor {
}
private void sendSkillCommandHeader(Player player, McMMOPlayer mcMMOPlayer, int skillValue) {
// ChatColor hd1 = ChatColor.DARK_AQUA;
// ChatColor c1 = ChatColor.GOLD;
// ChatColor c2 = ChatColor.RED;
ChatColor hd1 = ChatColor.DARK_AQUA;
ChatColor c1 = ChatColor.GOLD;
ChatColor c2 = ChatColor.RED;
player.sendMessage(LocaleLoader.getString("Skills.Overhaul.Header", skillName));
if(!skill.isChildSkill())
if(!SkillTools.isChildSkill(skill))
{
/*
* NON-CHILD SKILLS
@ -170,10 +185,10 @@ public abstract class SkillCommand implements TabExecutor {
{
if(i+1 < parentList.size())
{
parentMessage.append(LocaleLoader.getString("Effects.Child.ParentList", parentList.get(i).getName(), mcMMOPlayer.getSkillLevel(parentList.get(i))));
parentMessage.append(LocaleLoader.getString("Effects.Child.ParentList", mcMMO.p.getSkillTools().getLocalizedSkillName(parentList.get(i)), mcMMOPlayer.getSkillLevel(parentList.get(i))));
parentMessage.append(ChatColor.GRAY).append(", ");
} else {
parentMessage.append(LocaleLoader.getString("Effects.Child.ParentList", parentList.get(i).getName(), mcMMOPlayer.getSkillLevel(parentList.get(i))));
parentMessage.append(LocaleLoader.getString("Effects.Child.ParentList", mcMMO.p.getSkillTools().getLocalizedSkillName(parentList.get(i)), mcMMOPlayer.getSkillLevel(parentList.get(i))));
}
}
@ -186,7 +201,7 @@ public abstract class SkillCommand implements TabExecutor {
}
/*
if (!skill.isChildSkill()) {
if (!SkillTools.isChildSkill(skill)) {
player.sendMessage(LocaleLoader.getString("Skills.Header", skillName));
player.sendMessage(LocaleLoader.getString("Commands.XPGain", LocaleLoader.getString("Commands.XPGain." + StringUtils.getCapitalized(skill.toString()))));
player.sendMessage(LocaleLoader.getString("Effects.Level", skillValue, mcMMOPlayer.getSkillXpLevel(skill), mcMMOPlayer.getXpToLevel(skill)));
@ -208,7 +223,7 @@ public abstract class SkillCommand implements TabExecutor {
@Override
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
if (args.length == 1) {
return ImmutableList.of("?");
return ImmutableList.of("?", "keep");
}
return ImmutableList.of();
}
@ -217,10 +232,14 @@ public abstract class SkillCommand implements TabExecutor {
return Math.min((int) skillValue, maxLevel) / rankChangeLevel;
}
protected String[] getAbilityDisplayValues(SkillActivationType skillActivationType, Player player, SubSkillType subSkill) {
return RandomChanceUtil.calculateAbilityDisplayValues(skillActivationType, player, subSkill);
}
protected String[] calculateLengthDisplayValues(Player player, float skillValue) {
int maxLength = skill.getAbility().getMaxLength();
int abilityLengthVar = AdvancedConfig.getInstance().getAbilityLength();
int abilityLengthCap = AdvancedConfig.getInstance().getAbilityLengthCap();
int maxLength = mcMMO.p.getSkillTools().getSuperAbilityMaxLength(mcMMO.p.getSkillTools().getSuperAbility(skill));
int abilityLengthVar = mcMMO.p.getAdvancedConfig().getAbilityLength();
int abilityLengthCap = mcMMO.p.getAdvancedConfig().getAbilityLengthCap();
int length;
@ -261,7 +280,7 @@ public abstract class SkillCommand implements TabExecutor {
}
protected String getLimitBreakDescriptionParameter() {
if(AdvancedConfig.getInstance().canApplyLimitBreakPVE()) {
if(mcMMO.p.getAdvancedConfig().canApplyLimitBreakPVE()) {
return "(PVP/PVE)";
} else {
return "(PVP)";
@ -278,4 +297,14 @@ public abstract class SkillCommand implements TabExecutor {
protected abstract List<Component> getTextComponents(Player player);
/**
* Checks if a player can use a skill
* @param player target player
* @param subSkillType target subskill
* @return true if the player has permission and has the skill unlocked
*/
protected boolean canUseSubskill(Player player, SubSkillType subSkillType)
{
return Permissions.isSubSkillEnabled(player, subSkillType) && RankUtils.hasUnlockedSubskill(player, subSkillType);
}
}

View File

@ -2,6 +2,7 @@ package com.gmail.nossr50.commands.skills;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.text.StringUtils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
@ -18,7 +19,7 @@ public class SkillGuideCommand implements CommandExecutor {
private final String invalidPage = LocaleLoader.getString("Guides.Page.Invalid");
public SkillGuideCommand(PrimarySkillType skill) {
header = LocaleLoader.getString("Guides.Header", skill.getName());
header = LocaleLoader.getString("Guides.Header", mcMMO.p.getSkillTools().getLocalizedSkillName(skill));
guide = getGuide(skill);
}

View File

@ -1,14 +1,15 @@
package com.gmail.nossr50.commands.skills;
import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.skills.CombatUtils;
import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.skills.SkillUtils;
import com.gmail.nossr50.util.skills.SkillUtils;
import com.gmail.nossr50.util.text.TextComponentFactory;
import net.kyori.adventure.text.Component;
import org.bukkit.entity.Player;
@ -19,15 +20,16 @@ import java.util.List;
public class SwordsCommand extends SkillCommand {
private String counterChance;
private String counterChanceLucky;
private int bleedLength;
private String bleedChance;
private String bleedChanceLucky;
private String serratedStrikesLength;
private String serratedStrikesLengthEndurance;
private String rupturePureTickDamageAgainstPlayers, rupturePureTickDamageAgainstMobs,
ruptureExplosionDamageAgainstPlayers, ruptureExplosionDamageAgainstMobs,
ruptureLengthSecondsAgainstPlayers, ruptureLengthSecondsAgainstMobs, ruptureChanceToApply, ruptureChanceToApplyLucky;
private boolean canCounter;
private boolean canSerratedStrike;
private boolean canBleed;
private boolean canRupture;
public SwordsCommand() {
super(PrimarySkillType.SWORDS);
@ -43,12 +45,19 @@ public class SwordsCommand extends SkillCommand {
}
// SWORDS_RUPTURE
if (canBleed) {
bleedLength = UserManager.getPlayer(player).getSwordsManager().getRuptureBleedTicks();
if (canRupture) {
int ruptureRank = RankUtils.getRank(player, SubSkillType.SWORDS_RUPTURE);
ruptureLengthSecondsAgainstPlayers = String.valueOf(mcMMO.p.getAdvancedConfig().getRuptureDurationSeconds(true));
ruptureLengthSecondsAgainstMobs = String.valueOf(mcMMO.p.getAdvancedConfig().getRuptureDurationSeconds(false));
String[] bleedStrings = SkillUtils.getRNGDisplayValues(player, SubSkillType.SWORDS_RUPTURE);
bleedChance = bleedStrings[0];
bleedChanceLucky = bleedStrings[1];
rupturePureTickDamageAgainstPlayers = String.valueOf(mcMMO.p.getAdvancedConfig().getRuptureTickDamage(true, ruptureRank));
rupturePureTickDamageAgainstMobs = String.valueOf(mcMMO.p.getAdvancedConfig().getRuptureTickDamage(false, ruptureRank));
ruptureExplosionDamageAgainstPlayers = String.valueOf(mcMMO.p.getAdvancedConfig().getRuptureExplosionDamage(true, ruptureRank));
ruptureExplosionDamageAgainstMobs = String.valueOf(mcMMO.p.getAdvancedConfig().getRuptureExplosionDamage(false, ruptureRank));
ruptureChanceToApply = String.valueOf(mcMMO.p.getAdvancedConfig().getRuptureChanceToApplyOnHit(ruptureRank) + "%");
ruptureChanceToApplyLucky = String.valueOf(mcMMO.p.getAdvancedConfig().getRuptureChanceToApplyOnHit(ruptureRank) * 1.33);
}
// SERRATED STRIKES
@ -61,8 +70,8 @@ public class SwordsCommand extends SkillCommand {
@Override
protected void permissionsCheck(Player player) {
canBleed = Permissions.canUseSubSkill(player, SubSkillType.SWORDS_RUPTURE);
canCounter = Permissions.canUseSubSkill(player, SubSkillType.SWORDS_COUNTER_ATTACK);
canRupture = canUseSubskill(player, SubSkillType.SWORDS_RUPTURE);
canCounter = canUseSubskill(player, SubSkillType.SWORDS_COUNTER_ATTACK);
canSerratedStrike = RankUtils.hasUnlockedSubskill(player, SubSkillType.SWORDS_SERRATED_STRIKES) && Permissions.serratedStrikes(player);
}
@ -70,24 +79,22 @@ public class SwordsCommand extends SkillCommand {
protected List<String> statsDisplay(Player player, float skillValue, boolean hasEndurance, boolean isLucky) {
List<String> messages = new ArrayList<>();
int ruptureTicks = UserManager.getPlayer(player).getSwordsManager().getRuptureBleedTicks();
double ruptureDamagePlayers = RankUtils.getRank(player, SubSkillType.SWORDS_RUPTURE) >= 3 ? AdvancedConfig.getInstance().getRuptureDamagePlayer() * 1.5D : AdvancedConfig.getInstance().getRuptureDamagePlayer();
double ruptureDamageMobs = RankUtils.getRank(player, SubSkillType.SWORDS_RUPTURE) >= 3 ? AdvancedConfig.getInstance().getRuptureDamageMobs() * 1.5D : AdvancedConfig.getInstance().getRuptureDamageMobs();
if (canCounter) {
messages.add(getStatMessage(SubSkillType.SWORDS_COUNTER_ATTACK, counterChance)
+ (isLucky ? LocaleLoader.getString("Perks.Lucky.Bonus", counterChanceLucky) : ""));
}
if (canBleed) {
messages.add(getStatMessage(SubSkillType.SWORDS_RUPTURE, bleedChance)
+ (isLucky ? LocaleLoader.getString("Perks.Lucky.Bonus", bleedChanceLucky) : ""));
if (canRupture) {
messages.add(getStatMessage(SubSkillType.SWORDS_RUPTURE, ruptureChanceToApply)
+ (isLucky ? LocaleLoader.getString("Perks.Lucky.Bonus", ruptureChanceToApplyLucky) : ""));
messages.add(getStatMessage(true, true, SubSkillType.SWORDS_RUPTURE,
String.valueOf(ruptureTicks),
String.valueOf(ruptureDamagePlayers),
String.valueOf(ruptureDamageMobs)));
ruptureLengthSecondsAgainstPlayers,
ruptureLengthSecondsAgainstMobs));
messages.add(LocaleLoader.getString("Swords.Combat.Rupture.Note"));
messages.add(LocaleLoader.getString("Swords.SubSkill.Rupture.Stat.TickDamage", rupturePureTickDamageAgainstPlayers, rupturePureTickDamageAgainstMobs));
// messages.add(LocaleLoader.getString("Swords.SubSkill.Rupture.Stat.ExplosionDamage", ruptureExplosionDamageAgainstPlayers, ruptureExplosionDamageAgainstMobs));
messages.add(LocaleLoader.getString("Swords.Combat.Rupture.Note.Update.One"));
}
if (canSerratedStrike) {
@ -95,13 +102,13 @@ public class SwordsCommand extends SkillCommand {
+ (hasEndurance ? LocaleLoader.getString("Perks.ActivationTime.Bonus", serratedStrikesLengthEndurance) : ""));
}
if(Permissions.canUseSubSkill(player, SubSkillType.SWORDS_STAB))
if(canUseSubskill(player, SubSkillType.SWORDS_STAB))
{
messages.add(getStatMessage(SubSkillType.SWORDS_STAB,
String.valueOf(UserManager.getPlayer(player).getSwordsManager().getStabDamage())));
}
if(Permissions.canUseSubSkill(player, SubSkillType.SWORDS_SWORDS_LIMIT_BREAK)) {
if(canUseSubskill(player, SubSkillType.SWORDS_SWORDS_LIMIT_BREAK)) {
messages.add(getStatMessage(SubSkillType.SWORDS_SWORDS_LIMIT_BREAK,
String.valueOf(CombatUtils.getLimitBreakDamageAgainstQuality(player, SubSkillType.SWORDS_SWORDS_LIMIT_BREAK, 1000))));
}

View File

@ -3,6 +3,7 @@ package com.gmail.nossr50.commands.skills;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.skills.SkillUtils;
@ -26,9 +27,6 @@ public class WoodcuttingCommand extends SkillCommand {
private boolean canDoubleDrop;
private boolean canTripleDrop;
private boolean canKnockOnWood;
// private boolean canSplinter;
// private boolean canBarkSurgeon;
// private boolean canNaturesBounty;
public WoodcuttingCommand() {
super(PrimarySkillType.WOODCUTTING);
@ -47,7 +45,7 @@ public class WoodcuttingCommand extends SkillCommand {
tripleDropChance = tripleDropStrings[0];
tripleDropChanceLucky = tripleDropStrings[1];
}
// TREE FELLER
if (canTreeFell) {
String[] treeFellerStrings = calculateLengthDisplayValues(player, skillValue);
@ -65,13 +63,12 @@ public class WoodcuttingCommand extends SkillCommand {
@Override
protected void permissionsCheck(Player player) {
canTreeFell = RankUtils.hasUnlockedSubskill(player, SubSkillType.WOODCUTTING_TREE_FELLER) && Permissions.treeFeller(player);
canDoubleDrop = Permissions.canUseSubSkill(player, SubSkillType.WOODCUTTING_HARVEST_LUMBER) && !skill.getDoubleDropsDisabled();
canTripleDrop = Permissions.canUseSubSkill(player, SubSkillType.WOODCUTTING_CLEAN_CUTS) && !skill.getDoubleDropsDisabled();
canDoubleDrop = !mcMMO.p.getGeneralConfig().getDoubleDropsDisabled(skill)
&& Permissions.canUseSubSkill(player, SubSkillType.WOODCUTTING_HARVEST_LUMBER)
&& RankUtils.getRank(player, SubSkillType.WOODCUTTING_HARVEST_LUMBER) >= 1;
canTripleDrop = !mcMMO.p.getGeneralConfig().getDoubleDropsDisabled(skill) && Permissions.canUseSubSkill(player, SubSkillType.WOODCUTTING_CLEAN_CUTS);
canLeafBlow = Permissions.canUseSubSkill(player, SubSkillType.WOODCUTTING_LEAF_BLOWER);
canKnockOnWood = canTreeFell && Permissions.canUseSubSkill(player, SubSkillType.WOODCUTTING_KNOCK_ON_WOOD);
/*canSplinter = canUseSubskill(player, SubSkillType.WOODCUTTING_SPLINTER);
canBarkSurgeon = canUseSubskill(player, SubSkillType.WOODCUTTING_BARK_SURGEON);
canNaturesBounty = canUseSubskill(player, SubSkillType.WOODCUTTING_NATURES_BOUNTY);*/
}
@Override

View File

@ -6,23 +6,20 @@ import com.gmail.nossr50.datatypes.skills.subskills.AbstractSubSkill;
import com.gmail.nossr50.mcMMO;
import net.md_5.bungee.api.ChatColor;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class AdvancedConfig extends AutoUpdateConfigLoader {
private static AdvancedConfig instance;
public class AdvancedConfig extends BukkitConfig {
private AdvancedConfig() {
super("advanced.yml");
public AdvancedConfig(File dataFolder) {
super("advanced.yml", dataFolder);
validate();
}
public static AdvancedConfig getInstance() {
if (instance == null) {
instance = new AdvancedConfig();
}
return instance;
@Override
public void initDefaults() {
config.addDefault("Skills.General.StartingLevel", 0);
}
@Override
@ -68,15 +65,6 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
reason.add("Skills.Acrobatics.GracefulRoll.DamageThreshold should be at least 0!");
}
/* ALCHEMY */
/*if (getCatalysisUnlockLevel() < 0) {
reason.add("Skills.Alchemy.Catalysis.UnlockLevel should be at least 0!");
}
if (getCatalysisMaxBonusLevel() <= getCatalysisUnlockLevel()) {
reason.add("Skills.Alchemy.Catalysis.MaxBonusLevel should be greater than Skills.Alchemy.Catalysis.UnlockLevel!");
}*/
if (getCatalysisMinSpeed() <= 0) {
reason.add("Skills.Alchemy.Catalysis.MinSpeed must be greater than 0!");
}
@ -85,21 +73,6 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
reason.add("Skills.Alchemy.Catalysis.MaxSpeed should be at least Skills.Alchemy.Catalysis.MinSpeed!");
}
/*List<Alchemy.Tier> alchemyTierList = Arrays.asList(Alchemy.Tier.values());
for (Alchemy.Tier tier : alchemyTierList) {
if (getConcoctionsTierLevel(tier) < 0) {
reason.add("Skills.Alchemy.Rank_Levels.Rank_" + rank + " should be at least 0!");
}
if (tier != Alchemy.Tier.fromNumerical(Alchemy.Tier.values().length)) {
Alchemy.Tier nextTier = alchemyTierList.get(alchemyTierList.indexOf(tier) - 1);
if (getConcoctionsTierLevel(tier) > getConcoctionsTierLevel(nextTier)) {
reason.add("Skills.Alchemy.Rank_Levels.Rank_" + rank + " should be less than or equal to Skills.Alchemy.Rank_Levels.Rank_" + nextrank + "!");
}
}
}*/
/* ARCHERY */
if (getSkillShotRankDamageMultiplier() <= 0) {
@ -131,8 +104,7 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
}
/* AXES */
if(getAxeMasteryRankDamageMultiplier() < 0)
{
if (getAxeMasteryRankDamageMultiplier() < 0) {
reason.add("Skills.Axes.AxeMastery.RankDamageMultiplier should be at least 0!");
}
@ -310,25 +282,6 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
}
/* SWORDS */
if (getMaximumProbability(SubSkillType.SWORDS_RUPTURE) < 1) {
reason.add("Skills.Swords.Rupture.ChanceMax should be at least 1!");
}
if (getMaxBonusLevel(SubSkillType.SWORDS_RUPTURE) < 1) {
reason.add("Skills.Swords.Rupture.MaxBonusLevel should be at least 1!");
}
if (getRuptureMaxTicks() < 1) {
reason.add("Skills.Swords.Rupture.MaxTicks should be at least 1!");
}
if (getRuptureMaxTicks() < getRuptureBaseTicks()) {
reason.add("Skills.Swords.Rupture.MaxTicks should be at least Skills.Swords.Rupture.BaseTicks!");
}
if (getRuptureBaseTicks() < 1) {
reason.add("Skills.Swords.Rupture.BaseTicks should be at least 1!");
}
if (getMaximumProbability(SubSkillType.SWORDS_COUNTER_ATTACK) < 1) {
reason.add("Skills.Swords.CounterAttack.ChanceMax should be at least 1!");
@ -455,12 +408,18 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
}
@Override
protected void loadKeys() {}
protected void loadKeys() {
}
/* GENERAL */
public boolean canApplyLimitBreakPVE() { return config.getBoolean("Skills.General.LimitBreak.AllowPVE", false); }
public int getStartingLevel() { return config.getInt("Skills.General.StartingLevel", 1); }
public boolean canApplyLimitBreakPVE() {
return config.getBoolean("Skills.General.LimitBreak.AllowPVE", false);
}
public int getStartingLevel() {
return config.getInt("Skills.General.StartingLevel", 1);
}
public boolean allowPlayerTips() {
return config.getBoolean("Feedback.PlayerTips", true);
@ -469,10 +428,11 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
/**
* This returns the maximum level at which superabilities will stop lengthening from scaling alongside skill level.
* It returns a different value depending on whether or not the server is in retro mode
*
* @return the level at which abilities stop increasing in length
*/
public int getAbilityLengthCap() {
if(!mcMMO.isRetroModeEnabled())
if (!mcMMO.isRetroModeEnabled())
return config.getInt("Skills.General.Ability.Length.Standard.CapLevel", 50);
else
return config.getInt("Skills.General.Ability.Length.RetroMode.CapLevel", 500);
@ -481,27 +441,32 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
/**
* This returns the frequency at which abilities will increase in length
* It returns a different value depending on whether or not the server is in retro mode
*
* @return the number of levels required per ability length increase
*/
public int getAbilityLength() {
if(!mcMMO.isRetroModeEnabled())
if (!mcMMO.isRetroModeEnabled())
return config.getInt("Skills.General.Ability.Length.Standard.IncreaseLevel", 5);
else
return config.getInt("Skills.General.Ability.Length.RetroMode.IncreaseLevel", 50);
}
public int getEnchantBuff() { return config.getInt("Skills.General.Ability.EnchantBuff", 5); }
public int getEnchantBuff() {
return config.getInt("Skills.General.Ability.EnchantBuff", 5);
}
/**
* Grabs the max bonus level for a skill used in RNG calculations
* All max level values in the config are multiplied by 10 if the server is in retro mode as the values in the config are based around the new 1-100 skill system scaling
* A value of 10 in the file will be returned as 100 for retro mode servers to accommodate the change in scaling
*
* @param subSkillType target subskill
*
* @return the level at which this skills max benefits will be reached on the curve
*/
public int getMaxBonusLevel(SubSkillType subSkillType) {
String keyPath = subSkillType.getAdvConfigAddress() + ".MaxBonusLevel.";
return mcMMO.isRetroModeEnabled() ? config.getInt(keyPath+"RetroMode", 1000) : config.getInt(keyPath+"Standard", 100);
return mcMMO.isRetroModeEnabled() ? config.getInt(keyPath + "RetroMode", 1000) : config.getInt(keyPath + "Standard", 100);
}
public int getMaxBonusLevel(AbstractSubSkill abstractSubSkill) {
@ -513,35 +478,29 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
return config.getDouble(subSkillType.getAdvConfigAddress() + ".ChanceMax", 100.0D);
}
public double getMaximumProbability(AbstractSubSkill abstractSubSkill)
{
public double getMaximumProbability(AbstractSubSkill abstractSubSkill) {
return getMaximumProbability(abstractSubSkill.getSubSkillType());
}
/* Notification Settings */
public boolean doesSkillCommandSendBlankLines()
{
public boolean doesSkillCommandSendBlankLines() {
return config.getBoolean("Feedback.SkillCommand.BlankLinesAboveHeader", true);
}
public boolean doesNotificationUseActionBar(NotificationType notificationType)
{
return config.getBoolean("Feedback.ActionBarNotifications."+notificationType.toString()+".Enabled", true);
public boolean doesNotificationUseActionBar(NotificationType notificationType) {
return config.getBoolean("Feedback.ActionBarNotifications." + notificationType.toString() + ".Enabled", true);
}
public boolean doesNotificationSendCopyToChat(NotificationType notificationType)
{
return config.getBoolean("Feedback.ActionBarNotifications."+notificationType.toString()+".SendCopyOfMessageToChat", false);
public boolean doesNotificationSendCopyToChat(NotificationType notificationType) {
return config.getBoolean("Feedback.ActionBarNotifications." + notificationType.toString() + ".SendCopyOfMessageToChat", false);
}
public boolean useTitlesForXPEvent()
{
public boolean useTitlesForXPEvent() {
return config.getBoolean("Feedback.Events.XP.SendTitles", true);
}
public boolean sendAbilityNotificationToOtherPlayers()
{
public boolean sendAbilityNotificationToOtherPlayers() {
return config.getBoolean("Feedback.Events.AbilityActivation.SendNotificationToOtherPlayers", true);
}
@ -560,6 +519,7 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
/**
* Used to color our details header in our JSON Hover Object tooltips
*
* @return the ChatColor for this element
*/
/*public ChatColor getJSONStatHoverDetailsColor()
@ -608,7 +568,6 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
{
return getChatColor(config.getString("Style.JSON.Notification."+notificationType.toString()+".Color"));
}*/
private ChatColor getChatColorFromKey(String keyLocation) {
String colorName = config.getString(keyLocation);
@ -649,174 +608,334 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
/**
* Some SubSkills have the ability to retain classic functionality
*
* @param subSkillType SubSkillType with classic functionality
*
* @return true if the subskill is in classic mode
*/
public boolean isSubSkillClassic(SubSkillType subSkillType)
{
return config.getBoolean(subSkillType.getAdvConfigAddress()+".Classic");
public boolean isSubSkillClassic(SubSkillType subSkillType) {
return config.getBoolean(subSkillType.getAdvConfigAddress() + ".Classic");
}
/* ACROBATICS */
public double getDodgeDamageModifier() { return config.getDouble("Skills.Acrobatics.Dodge.DamageModifier", 2.0D); }
public double getDodgeDamageModifier() {
return config.getDouble("Skills.Acrobatics.Dodge.DamageModifier", 2.0D);
}
public double getRollDamageThreshold() { return config.getDouble("Skills.Acrobatics.Roll.DamageThreshold", 7.0D); }
public double getRollDamageThreshold() {
return config.getDouble("Skills.Acrobatics.Roll.DamageThreshold", 7.0D);
}
public double getGracefulRollDamageThreshold() { return config.getDouble("Skills.Acrobatics.GracefulRoll.DamageThreshold", 14.0D); }
public double getGracefulRollDamageThreshold() {
return config.getDouble("Skills.Acrobatics.GracefulRoll.DamageThreshold", 14.0D);
}
/* ALCHEMY */
/*public int getCatalysisUnlockLevel() { return config.getInt("Skills.Alchemy.Catalysis.UnlockLevel", 100); }*/
public int getCatalysisMaxBonusLevel() { return config.getInt("Skills.Alchemy.Catalysis.MaxBonusLevel", 1000); }
public int getCatalysisMaxBonusLevel() {
return config.getInt("Skills.Alchemy.Catalysis.MaxBonusLevel", 1000);
}
public double getCatalysisMinSpeed() { return config.getDouble("Skills.Alchemy.Catalysis.MinSpeed", 1.0D); }
public double getCatalysisMaxSpeed() { return config.getDouble("Skills.Alchemy.Catalysis.MaxSpeed", 4.0D); }
public double getCatalysisMinSpeed() {
return config.getDouble("Skills.Alchemy.Catalysis.MinSpeed", 1.0D);
}
public double getCatalysisMaxSpeed() {
return config.getDouble("Skills.Alchemy.Catalysis.MaxSpeed", 4.0D);
}
//public int getConcoctionsTierLevel(Alchemy.Tier tier) { return config.getInt("Skills.Alchemy.Rank_Levels.Rank_" + rank); }
/* ARCHERY */
public double getSkillShotRankDamageMultiplier() { return config.getDouble("Skills.Archery.SkillShot.RankDamageMultiplier", 10.0D); }
public double getSkillShotDamageMax() { return config.getDouble("Skills.Archery.SkillShot.MaxDamage", 9.0D); }
public double getSkillShotRankDamageMultiplier() {
return config.getDouble("Skills.Archery.SkillShot.RankDamageMultiplier", 10.0D);
}
public double getDazeBonusDamage() { return config.getDouble("Skills.Archery.Daze.BonusDamage", 4.0D); }
public double getSkillShotDamageMax() {
return config.getDouble("Skills.Archery.SkillShot.MaxDamage", 9.0D);
}
public double getForceMultiplier() { return config.getDouble("Skills.Archery.ForceMultiplier", 2.0D); }
public double getDazeBonusDamage() {
return config.getDouble("Skills.Archery.Daze.BonusDamage", 4.0D);
}
public double getForceMultiplier() {
return config.getDouble("Skills.Archery.ForceMultiplier", 2.0D);
}
/* AXES */
public double getAxeMasteryRankDamageMultiplier() { return config.getDouble("Skills.Axes.AxeMastery.RankDamageMultiplier", 1.0D); }
public double getAxeMasteryRankDamageMultiplier() {
return config.getDouble("Skills.Axes.AxeMastery.RankDamageMultiplier", 1.0D);
}
public double getCriticalStrikesPVPModifier() { return config.getDouble("Skills.Axes.CriticalStrikes.PVP_Modifier", 1.5D); }
public double getCriticalStrikesPVEModifier() { return config.getDouble("Skills.Axes.CriticalStrikes.PVE_Modifier", 2.0D); }
public double getCriticalStrikesPVPModifier() {
return config.getDouble("Skills.Axes.CriticalStrikes.PVP_Modifier", 1.5D);
}
public double getGreaterImpactChance() { return config.getDouble("Skills.Axes.GreaterImpact.Chance", 25.0D); }
public double getGreaterImpactModifier() { return config.getDouble("Skills.Axes.GreaterImpact.KnockbackModifier", 1.5D); }
public double getGreaterImpactBonusDamage() { return config.getDouble("Skills.Axes.GreaterImpact.BonusDamage", 2.0D); }
public double getCriticalStrikesPVEModifier() {
return config.getDouble("Skills.Axes.CriticalStrikes.PVE_Modifier", 2.0D);
}
public double getImpactChance() { return config.getDouble("Skills.Axes.ArmorImpact.Chance", 25.0D); }
public double getImpactDurabilityDamageMultiplier() { return config.getDouble("Skills.Axes.ArmorImpact.DamagePerRank", 6.5D); }
public double getGreaterImpactChance() {
return config.getDouble("Skills.Axes.GreaterImpact.Chance", 25.0D);
}
public double getSkullSplitterModifier() { return config.getDouble("Skills.Axes.SkullSplitter.DamageModifier", 2.0D); }
public double getGreaterImpactModifier() {
return config.getDouble("Skills.Axes.GreaterImpact.KnockbackModifier", 1.5D);
}
public double getGreaterImpactBonusDamage() {
return config.getDouble("Skills.Axes.GreaterImpact.BonusDamage", 2.0D);
}
public double getImpactChance() {
return config.getDouble("Skills.Axes.ArmorImpact.Chance", 25.0D);
}
public double getImpactDurabilityDamageMultiplier() {
return config.getDouble("Skills.Axes.ArmorImpact.DamagePerRank", 6.5D);
}
public double getSkullSplitterModifier() {
return config.getDouble("Skills.Axes.SkullSplitter.DamageModifier", 2.0D);
}
/* EXCAVATION */
//Nothing to configure, everything is already configurable in config.yml
/* FISHING */
//public int getFishingTierLevel(int rank) { return config.getInt("Skills.Fishing.Rank_Levels.Rank_" + rank); }
public double getShakeChance(int rank) { return config.getDouble("Skills.Fishing.ShakeChance.Rank_" + rank); }
public int getFishingVanillaXPModifier(int rank) { return config.getInt("Skills.Fishing.VanillaXPMultiplier.Rank_" + rank); }
public double getShakeChance(int rank) {
return config.getDouble("Skills.Fishing.ShakeChance.Rank_" + rank);
}
public int getFishingReductionMinWaitTicks() { return config.getInt("Skills.Fishing.MasterAngler.Tick_Reduction_Per_Rank.Min_Wait", 10);}
public int getFishingReductionMaxWaitTicks() { return config.getInt("Skills.Fishing.MasterAngler.Tick_Reduction_Per_Rank.Max_Wait", 30);}
public int getFishingBoatReductionMinWaitTicks() { return config.getInt("Skills.Fishing.MasterAngler.Boat_Tick_Reduction.Min_Wait", 10);}
public int getFishingBoatReductionMaxWaitTicks() { return config.getInt("Skills.Fishing.MasterAngler.Boat_Tick_Reduction.Max_Wait", 30);}
public int getFishingReductionMinWaitCap() { return config.getInt("Skills.Fishing.MasterAngler.Tick_Reduction_Caps.Min_Wait", 40);}
public int getFishingReductionMaxWaitCap() { return config.getInt("Skills.Fishing.MasterAngler.Tick_Reduction_Caps.Max_Wait", 100);}
public int getFishermanDietRankChange() { return config.getInt("Skills.Fishing.FishermansDiet.RankChange", 200); }
public int getFishingVanillaXPModifier(int rank) {
return config.getInt("Skills.Fishing.VanillaXPMultiplier.Rank_" + rank);
}
/*public int getIceFishingUnlockLevel() { return config.getInt("Skills.Fishing.IceFishing.UnlockLevel", 50); }
public int getFishingReductionMinWaitTicks() {
return config.getInt("Skills.Fishing.MasterAngler.Tick_Reduction_Per_Rank.Min_Wait", 10);
}
public int getMasterAnglerUnlockLevel() {return config.getInt("Skills.Fishing.MasterAngler.UnlockLevel", 125); }*/
public double getMasterAnglerBoatModifier() {return config.getDouble("Skills.Fishing.MasterAngler.BoatModifier", 2.0); }
public double getMasterAnglerBiomeModifier() {return config.getDouble("Skills.Fishing.MasterAngler.BiomeModifier", 2.0); }
public int getFishingReductionMaxWaitTicks() {
return config.getInt("Skills.Fishing.MasterAngler.Tick_Reduction_Per_Rank.Max_Wait", 30);
}
public int getFishingBoatReductionMinWaitTicks() {
return config.getInt("Skills.Fishing.MasterAngler.Boat_Tick_Reduction.Min_Wait", 10);
}
public int getFishingBoatReductionMaxWaitTicks() {
return config.getInt("Skills.Fishing.MasterAngler.Boat_Tick_Reduction.Max_Wait", 30);
}
public int getFishingReductionMinWaitCap() {
return config.getInt("Skills.Fishing.MasterAngler.Tick_Reduction_Caps.Min_Wait", 40);
}
public int getFishingReductionMaxWaitCap() {
return config.getInt("Skills.Fishing.MasterAngler.Tick_Reduction_Caps.Max_Wait", 100);
}
public int getFishermanDietRankChange() {
return config.getInt("Skills.Fishing.FishermansDiet.RankChange", 200);
}
public double getMasterAnglerBoatModifier() {
return config.getDouble("Skills.Fishing.MasterAngler.BoatModifier", 2.0);
}
public double getMasterAnglerBiomeModifier() {
return config.getDouble("Skills.Fishing.MasterAngler.BiomeModifier", 2.0);
}
/* HERBALISM */
public int getFarmerDietRankChange() { return config.getInt("Skills.Herbalism.FarmersDiet.RankChange", 200); }
public int getFarmerDietRankChange() {
return config.getInt("Skills.Herbalism.FarmersDiet.RankChange", 200);
}
public int getGreenThumbStageChange() { return config.getInt("Skills.Herbalism.GreenThumb.StageChange", 200); }
public int getGreenThumbStageChange() {
return config.getInt("Skills.Herbalism.GreenThumb.StageChange", 200);
}
/* MINING */
public boolean getDoubleDropSilkTouchEnabled() { return config.getBoolean("Skills.Mining.DoubleDrops.SilkTouch", true); }
public boolean getAllowMiningTripleDrops() { return config.getBoolean("Skills.Mining.SuperBreaker.AllowTripleDrops", true); }
public int getBlastMiningRankLevel(int rank) { return config.getInt("Skills.Mining.BlastMining.Rank_Levels.Rank_" + rank); }
public double getBlastDamageDecrease(int rank) { return config.getDouble("Skills.Mining.BlastMining.BlastDamageDecrease.Rank_" + rank); }
public double getOreBonus(int rank) { return config.getDouble("Skills.Mining.BlastMining.OreBonus.Rank_" + rank); }
public double getDebrisReduction(int rank) { return config.getDouble("Skills.Mining.BlastMining.DebrisReduction.Rank_" + rank); }
public int getDropMultiplier(int rank) { return config.getInt("Skills.Mining.BlastMining.DropMultiplier.Rank_" + rank); }
public double getBlastRadiusModifier(int rank) { return config.getDouble("Skills.Mining.BlastMining.BlastRadiusModifier.Rank_" + rank); }
public boolean getDoubleDropSilkTouchEnabled() {
return config.getBoolean("Skills.Mining.DoubleDrops.SilkTouch", true);
}
public boolean getAllowMiningTripleDrops() {
return config.getBoolean("Skills.Mining.SuperBreaker.AllowTripleDrops", true);
}
public int getBlastMiningRankLevel(int rank) {
return config.getInt("Skills.Mining.BlastMining.Rank_Levels.Rank_" + rank);
}
public double getBlastDamageDecrease(int rank) {
return config.getDouble("Skills.Mining.BlastMining.BlastDamageDecrease.Rank_" + rank);
}
public double getOreBonus(int rank) {
return config.getDouble("Skills.Mining.BlastMining.OreBonus.Rank_" + rank);
}
public double getDebrisReduction(int rank) {
return config.getDouble("Skills.Mining.BlastMining.DebrisReduction.Rank_" + rank);
}
public int getDropMultiplier(int rank) {
return config.getInt("Skills.Mining.BlastMining.DropMultiplier.Rank_" + rank);
}
public double getBlastRadiusModifier(int rank) {
return config.getDouble("Skills.Mining.BlastMining.BlastRadiusModifier.Rank_" + rank);
}
/* REPAIR */
public double getRepairMasteryMaxBonus() { return config.getDouble("Skills.Repair.RepairMastery.MaxBonusPercentage", 200.0D); }
public int getRepairMasteryMaxLevel() { return config.getInt("Skills.Repair.RepairMastery.MaxBonusLevel", 100); }
public double getRepairMasteryMaxBonus() {
return config.getDouble("Skills.Repair.RepairMastery.MaxBonusPercentage", 200.0D);
}
/* Arcane Forging */
//public int getArcaneForgingRankLevel(int rank) { return config.getInt("Skills.Repair.ArcaneForging.Rank_Levels.Rank_" + rank); }
public int getRepairMasteryMaxLevel() {
return config.getInt("Skills.Repair.RepairMastery.MaxBonusLevel", 100);
}
public boolean getArcaneForgingEnchantLossEnabled() { return config.getBoolean("Skills.Repair.ArcaneForging.May_Lose_Enchants", true); }
public double getArcaneForgingKeepEnchantsChance(int rank) { return config.getDouble("Skills.Repair.ArcaneForging.Keep_Enchants_Chance.Rank_" + rank); }
public boolean getAllowEnchantedRepairMaterials() {
return config.getBoolean("Skills.Repair.Use_Enchanted_Materials", false);
}
public boolean getArcaneForgingDowngradeEnabled() { return config.getBoolean("Skills.Repair.ArcaneForging.Downgrades_Enabled", true); }
public double getArcaneForgingDowngradeChance(int rank) { return config.getDouble("Skills.Repair.ArcaneForging.Downgrades_Chance.Rank_" + rank); }
public boolean getArcaneForgingEnchantLossEnabled() {
return config.getBoolean("Skills.Repair.ArcaneForging.May_Lose_Enchants", true);
}
/* SALVAGE */
//public double getSalvageMaxPercentage() { return config.getDouble("Skills.Salvage.MaxPercentage", 100.0D); }
//public int getSalvageMaxPercentageLevel() { return config.getInt("Skills.Salvage.MaxPercentageLevel", 1000); }
public double getArcaneForgingKeepEnchantsChance(int rank) {
return config.getDouble("Skills.Repair.ArcaneForging.Keep_Enchants_Chance.Rank_" + rank);
}
public boolean getArcaneSalvageEnchantDowngradeEnabled() { return config.getBoolean("Skills.Salvage.ArcaneSalvage.EnchantDowngradeEnabled", true); }
public boolean getArcaneSalvageEnchantLossEnabled() { return config.getBoolean("Skills.Salvage.ArcaneSalvage.EnchantLossEnabled", true); }
public boolean getArcaneForgingDowngradeEnabled() {
return config.getBoolean("Skills.Repair.ArcaneForging.Downgrades_Enabled", true);
}
//public int getArcaneSalvageRankLevel(int rank) { return config.getInt("Skills.Salvage.ArcaneSalvage.Rank_Levels.Rank_" + rank); }
public double getArcaneSalvageExtractFullEnchantsChance(int rank) { return config.getDouble("Skills.Salvage.ArcaneSalvage.ExtractFullEnchant.Rank_" + rank); }
public double getArcaneSalvageExtractPartialEnchantsChance(int rank) { return config.getDouble("Skills.Salvage.ArcaneSalvage.ExtractPartialEnchant.Rank_" + rank); }
public double getArcaneForgingDowngradeChance(int rank) {
return config.getDouble("Skills.Repair.ArcaneForging.Downgrades_Chance.Rank_" + rank);
}
public boolean getArcaneSalvageEnchantDowngradeEnabled() {
return config.getBoolean("Skills.Salvage.ArcaneSalvage.EnchantDowngradeEnabled", true);
}
public boolean getArcaneSalvageEnchantLossEnabled() {
return config.getBoolean("Skills.Salvage.ArcaneSalvage.EnchantLossEnabled", true);
}
public double getArcaneSalvageExtractFullEnchantsChance(int rank) {
return config.getDouble("Skills.Salvage.ArcaneSalvage.ExtractFullEnchant.Rank_" + rank);
}
public double getArcaneSalvageExtractPartialEnchantsChance(int rank) {
return config.getDouble("Skills.Salvage.ArcaneSalvage.ExtractPartialEnchant.Rank_" + rank);
}
/* SMELTING */
public int getBurnModifierMaxLevel() {
if(mcMMO.isRetroModeEnabled())
if (mcMMO.isRetroModeEnabled())
return config.getInt("Skills.Smelting.FuelEfficiency.RetroMode.MaxBonusLevel", 1000);
else
return config.getInt("Skills.Smelting.FuelEfficiency.Standard.MaxBonusLevel", 100);
}
/*public int getFluxMiningUnlockLevel() { return config.getInt("Skills.Smelting.FluxMining.UnlockLevel", 250); }*/
public double getFluxMiningChance() { return config.getDouble("Skills.Smelting.FluxMining.Chance", 33.0D); }
public int getSmeltingRankLevel(int rank) { return config.getInt("Skills.Smelting.Rank_Levels.Rank_" + rank); }
public int getSmeltingVanillaXPBoostMultiplier(int rank) { return config.getInt("Skills.Smelting.VanillaXPMultiplier.Rank_" + rank); }
public double getFluxMiningChance() {
return config.getDouble("Skills.Smelting.FluxMining.Chance", 33.0D);
}
/* SWORDS */
public double getRuptureDamagePlayer() { return config.getDouble("Skills.Swords.Rupture.DamagePlayer", 1.0); }
public double getRuptureDamageMobs() { return config.getDouble("Skills.Swords.Rupture.DamageMobs", 2.0); }
public double getRuptureTickDamage(boolean isTargetPlayer, int rank) {
String root = "Skills.Swords.Rupture.Rupture_Mechanics.Tick_Interval_Damage.Against_";
String targetType = isTargetPlayer ? "Players" : "Mobs";
String key = root + targetType + ".Rank_" + rank;
public int getRuptureMaxTicks() { return config.getInt("Skills.Swords.Rupture.MaxTicks", 8); }
public int getRuptureBaseTicks() { return config.getInt("Skills.Swords.Rupture.BaseTicks", 2); }
return config.getDouble(key, 1.0D);
}
public double getCounterModifier() { return config.getDouble("Skills.Swords.CounterAttack.DamageModifier", 2.0D); }
public int getRuptureDurationSeconds(boolean isTargetPlayer) {
String root = "Skills.Swords.Rupture.Rupture_Mechanics.Duration_In_Seconds.Against_";
String targetType = isTargetPlayer ? "Players" : "Mobs";
return config.getInt(root + targetType, 5);
}
public double getSerratedStrikesModifier() { return config.getDouble("Skills.Swords.SerratedStrikes.DamageModifier", 4.0D); }
public int getSerratedStrikesTicks() { return config.getInt("Skills.Swords.SerratedStrikes.RuptureTicks", 5); }
public double getRuptureExplosionDamage(boolean isTargetPlayer, int rank) {
String root = "Skills.Swords.Rupture.Rupture_Mechanics.Explosion_Damage.Against_";
String targetType = isTargetPlayer ? "Players" : "Mobs";
String key = root + targetType + ".Rank_" + rank;
return config.getDouble(key, 40.0D);
}
public double getRuptureChanceToApplyOnHit(int rank) {
String root = "Skills.Swords.Rupture.Rupture_Mechanics.Chance_To_Apply_On_Hit.Rank_";
return config.getDouble(root + rank, 33);
}
public double getCounterModifier() {
return config.getDouble("Skills.Swords.CounterAttack.DamageModifier", 2.0D);
}
public double getSerratedStrikesModifier() {
return config.getDouble("Skills.Swords.SerratedStrikes.DamageModifier", 4.0D);
}
public int getSerratedStrikesTicks() {
return config.getInt("Skills.Swords.SerratedStrikes.RuptureTicks", 5);
}
/* TAMING */
//public int getGoreRuptureTicks() { return config.getInt("Skills.Taming.Gore.RuptureTicks", 2); }
public double getGoreModifier() { return config.getDouble("Skills.Taming.Gore.Modifier", 2.0D); }
public double getGoreModifier() {
return config.getDouble("Skills.Taming.Gore.Modifier", 2.0D);
}
/*public int getFastFoodUnlock() { return config.getInt("Skills.Taming.FastFood.UnlockLevel", 50); }*/
public double getFastFoodChance() { return config.getDouble("Skills.Taming.FastFoodService.Chance", 50.0D); }
public double getPummelChance() { return config.getDouble("Skills.Taming.Pummel.Chance", 10.0D); }
public double getFastFoodChance() {
return config.getDouble("Skills.Taming.FastFoodService.Chance", 50.0D);
}
//public int getEnviromentallyAwareUnlock() { return config.getInt("Skills.Taming.EnvironmentallyAware.UnlockLevel", 100); }
public double getPummelChance() {
return config.getDouble("Skills.Taming.Pummel.Chance", 10.0D);
}
/*public int getThickFurUnlock() { return config.getInt("Skills.Taming.ThickFur.UnlockLevel", 250); }*/
public double getThickFurModifier() { return config.getDouble("Skills.Taming.ThickFur.Modifier", 2.0D); }
public double getThickFurModifier() {
return config.getDouble("Skills.Taming.ThickFur.Modifier", 2.0D);
}
/*public int getHolyHoundUnlock() {return config.getInt("Skills.Taming.HolyHound.UnlockLevel", 375); }*/
public double getShockProofModifier() {
return config.getDouble("Skills.Taming.ShockProof.Modifier", 6.0D);
}
/*public int getShockProofUnlock() { return config.getInt("Skills.Taming.ShockProof.UnlockLevel", 500); }*/
public double getShockProofModifier() { return config.getDouble("Skills.Taming.ShockProof.Modifier", 6.0D); }
public double getSharpenedClawsBonus() {
return config.getDouble("Skills.Taming.SharpenedClaws.Bonus", 2.0D);
}
/*public int getSharpenedClawsUnlock() { return config.getInt("Skills.Taming.SharpenedClaws.UnlockLevel", 750); }*/
public double getSharpenedClawsBonus() { return config.getDouble("Skills.Taming.SharpenedClaws.Bonus", 2.0D); }
public double getMinHorseJumpStrength() {
return config.getDouble("Skills.Taming.CallOfTheWild.MinHorseJumpStrength", 0.7D);
}
public double getMinHorseJumpStrength() { return config.getDouble("Skills.Taming.CallOfTheWild.MinHorseJumpStrength", 0.7D); }
public double getMaxHorseJumpStrength() { return config.getDouble("Skills.Taming.CallOfTheWild.MaxHorseJumpStrength", 2.0D); }
public double getMaxHorseJumpStrength() {
return config.getDouble("Skills.Taming.CallOfTheWild.MaxHorseJumpStrength", 2.0D);
}
/* UNARMED */
public boolean isSteelArmDamageCustom() { return config.getBoolean("Skills.Unarmed.SteelArmStyle.Damage_Override", false); }
public boolean isSteelArmDamageCustom() {
return config.getBoolean("Skills.Unarmed.SteelArmStyle.Damage_Override", false);
}
public double getSteelArmOverride(int rank, double def) {
String key = "Rank_" + rank;
return config.getDouble("Skills.Unarmed.SteelArmStyle.Override." + key, def);
}
public boolean getDisarmProtected() { return config.getBoolean("Skills.Unarmed.Disarm.AntiTheft", false); }
public boolean getDisarmProtected() {
return config.getBoolean("Skills.Unarmed.Disarm.AntiTheft", false);
}
/* WOODCUTTING */
public boolean isKnockOnWoodXPOrbEnabled() { return config.getBoolean("Skills.Woodcutting.TreeFeller.Knock_On_Wood.Add_XP_Orbs_To_Drops", true); }
public boolean isKnockOnWoodXPOrbEnabled() {
return config.getBoolean("Skills.Woodcutting.TreeFeller.Knock_On_Wood.Add_XP_Orbs_To_Drops", true);
}
}

View File

@ -1,27 +1,38 @@
package com.gmail.nossr50.config;
import com.gmail.nossr50.mcMMO;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import java.io.*;
import java.util.HashMap;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Set;
public abstract class AutoUpdateConfigLoader extends ConfigLoader {
public AutoUpdateConfigLoader(String relativePath, String fileName, File dataFolder) {
super(relativePath, fileName, dataFolder);
}
public AutoUpdateConfigLoader(String fileName, File dataFolder) {
super(fileName, dataFolder);
}
@Deprecated
public AutoUpdateConfigLoader(String relativePath, String fileName) {
super(relativePath, fileName);
}
@Deprecated
public AutoUpdateConfigLoader(String fileName) {
super(fileName);
}
protected void saveConfig() {
try {
plugin.getLogger().info("Saving changes to config file - "+fileName);
mcMMO.p.getLogger().info("Saving changes to config file - " + fileName);
config.options().indent(2);
config.save(configFile);
} catch (IOException e) {
e.printStackTrace();
@ -29,119 +40,64 @@ public abstract class AutoUpdateConfigLoader extends ConfigLoader {
}
protected @NotNull FileConfiguration getInternalConfig() {
return YamlConfiguration.loadConfiguration(plugin.getResourceAsReader(fileName));
return YamlConfiguration.loadConfiguration(mcMMO.p.getResourceAsReader(fileName));
}
@Override
protected void loadFile() {
super.loadFile();
FileConfiguration internalConfig = YamlConfiguration.loadConfiguration(plugin.getResourceAsReader(fileName));
FileConfiguration internalConfig = YamlConfiguration.loadConfiguration(mcMMO.p.getResourceAsReader(fileName));
Set<String> configKeys = config.getKeys(true);
Set<String> internalConfigKeys = internalConfig.getKeys(true);
boolean needSave = false;
// keys present in current config file that are not in the template
Set<String> oldKeys = new HashSet<>(configKeys);
oldKeys.removeAll(internalConfigKeys);
if (!oldKeys.isEmpty()) {
mcMMO.p.debug("old key(s) in \"" + fileName + "\"");
for (String key : oldKeys) {
mcMMO.p.debug(" old-key:" + key);
}
}
// keys present in template that are not in current file
Set<String> newKeys = new HashSet<>(internalConfigKeys);
newKeys.removeAll(configKeys);
// Don't need a re-save if we have old keys sticking around?
// Would be less saving, but less... correct?
if (!newKeys.isEmpty() || !oldKeys.isEmpty()) {
if (!newKeys.isEmpty()) {
needSave = true;
}
for (String key : oldKeys) {
plugin.debug("Detected potentially unused key: " + key);
//config.set(key, null);
}
for (String key : newKeys) {
plugin.debug("Adding new key: " + key + " = " + internalConfig.get(key));
mcMMO.p.debug("Adding new key: " + key + " = " + internalConfig.get(key));
config.set(key, internalConfig.get(key));
}
if (needSave) {
// Get Bukkit's version of an acceptable config with new keys, and no old keys
String output = config.saveToString();
// Convert to the superior 4 space indentation
output = output.replace(" ", " ");
// Rip out Bukkit's attempt to save comments at the top of the file
while (output.replaceAll("[//s]", "").startsWith("#")) {
output = output.substring(output.indexOf('\n', output.indexOf('#')) + 1);
}
// Read the internal config to get comments, then put them in the new one
try {
// Read internal
BufferedReader reader = new BufferedReader(new InputStreamReader(plugin.getResource(fileName)));
LinkedHashMap<String, String> comments = new LinkedHashMap<>();
StringBuilder temp = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
if (line.contains("#")) {
temp.append(line).append("\n");
}
else if (line.contains(":")) {
line = line.substring(0, line.indexOf(":") + 1);
if (temp.length() > 0) {
if(comments.containsKey(line)) {
int index = 0;
while(comments.containsKey(line + index)) {
index++;
}
line = line + index;
}
comments.put(line, temp.toString());
temp = new StringBuilder();
}
}
}
// Dump to the new one
HashMap<String, Integer> indexed = new HashMap<>();
for (String key : comments.keySet()) {
String actualkey = key.substring(0, key.indexOf(":") + 1);
int index = 0;
if(indexed.containsKey(actualkey)) {
index = indexed.get(actualkey);
}
boolean isAtTop = !output.contains("\n" + actualkey);
index = output.indexOf((isAtTop ? "" : "\n") + actualkey, index);
if (index >= 0) {
output = output.substring(0, index) + "\n" + comments.get(key) + output.substring(isAtTop ? index : index + 1);
indexed.put(actualkey, index + comments.get(key).length() + actualkey.length() + 1);
}
}
}
catch (Exception e) {
e.printStackTrace();
}
// Save it
if (dataFolder == null) {
mcMMO.p.getLogger().severe("Data folder should never be null!");
return;
}
try {
String saveName = fileName;
// At this stage we cannot guarantee that Config has been loaded, so we do the check directly here
if (!plugin.getConfig().getBoolean("General.Config_Update_Overwrite", true)) {
if (!mcMMO.p.getConfig().getBoolean("General.Config_Update_Overwrite", true)) {
saveName += ".new";
}
BufferedWriter writer = new BufferedWriter(new FileWriter(new File(plugin.getDataFolder(), saveName)));
writer.write(output);
writer.flush();
writer.close();
}
catch (Exception e) {
File newSaveFile = new File(dataFolder, saveName);
YamlConfiguration yamlConfiguration = config;
yamlConfiguration.options().indent(4);
yamlConfiguration.save(newSaveFile);
} catch (Exception e) {
e.printStackTrace();
}
}

View File

@ -0,0 +1,220 @@
package com.gmail.nossr50.config;
import com.gmail.nossr50.mcMMO;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import java.io.*;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public abstract class BukkitConfig {
public static final String CONFIG_PATCH_PREFIX = "ConfigPatchVersion:";
public static final String CURRENT_CONFIG_PATCH_VER = "ConfigPatchVersion: 2";
public static final char COMMENT_PREFIX = '#';
protected final String fileName;
protected final File configFile;
protected YamlConfiguration config;
protected @NotNull
final File dataFolder;
public BukkitConfig(@NotNull String fileName, @NotNull File dataFolder) {
mcMMO.p.getLogger().info("[config] Initializing config: " + fileName);
this.fileName = fileName;
this.dataFolder = dataFolder;
configFile = new File(dataFolder, fileName);
// purgeComments(true);
this.config = initConfig();
initDefaults();
updateFile();
mcMMO.p.getLogger().info("[config] Config initialized: " + fileName);
}
@Deprecated
public BukkitConfig(@NotNull String fileName) {
this(fileName, mcMMO.p.getDataFolder());
}
/**
* Initialize default values for the config
*/
public void initDefaults() {}
/**
* Update the file on the disk by copying out any new and missing defaults
*/
public void updateFile() {
try {
config.save(configFile);
} catch (IOException e) {
e.printStackTrace();
}
}
private YamlConfiguration initConfig() {
if (!configFile.exists()) {
mcMMO.p.getLogger().info("[config] User config file not found, copying a default config to disk: " + fileName);
mcMMO.p.saveResource(fileName, false);
}
mcMMO.p.getLogger().info("[config] Loading config from disk: " + fileName);
YamlConfiguration config = new YamlConfiguration();
config.options().indent(4);
try {
config.options().parseComments(true);
} catch (NoSuchMethodError e) {
//e.printStackTrace();
// mcMMO.p.getLogger().severe("Your Spigot/CraftBukkit API is out of date, update your server software!");
}
config.options().copyDefaults(true);
try {
config.load(configFile);
} catch (IOException | InvalidConfigurationException e) {
e.printStackTrace();
}
return config;
}
protected abstract void loadKeys();
protected boolean validateKeys() {
return true;
}
protected boolean noErrorsInConfig(List<String> issues) {
for (String issue : issues) {
mcMMO.p.getLogger().warning(issue);
}
return issues.isEmpty();
}
protected void validate() {
if (validateKeys()) {
mcMMO.p.debug("No errors found in " + fileName + "!");
} else {
mcMMO.p.getLogger().warning("Errors were found in " + fileName + "! mcMMO was disabled!");
mcMMO.p.getServer().getPluginManager().disablePlugin(mcMMO.p);
mcMMO.p.noErrorsInConfigFiles = false;
}
}
public void backup() {
mcMMO.p.getLogger().severe("You are using an old version of the " + fileName + " file.");
mcMMO.p.getLogger().severe("Your old file has been renamed to " + fileName + ".old and has been replaced by an updated version.");
configFile.renameTo(new File(configFile.getPath() + ".old"));
if (mcMMO.p.getResource(fileName) != null) {
mcMMO.p.saveResource(fileName, true);
}
mcMMO.p.getLogger().warning("Reloading " + fileName + " with new values...");
initConfig();
loadKeys();
}
public File getFile() {
return configFile;
}
// /**
// * Somewhere between December 2021-January 2022 Spigot updated their
// * SnakeYAML dependency/API and due to our own crappy legacy code
// * this introduced a very problematic bug where comments got duplicated
// * <p>
// * This method hotfixes the problem by just deleting any existing comments
// * it's ugly, but it gets the job done
// *
// * @param silentFail when true mcMMO will report errors during the patch process or debug information
// * the option to have it fail silently is because mcMMO wants to check files before they are parsed as a file with a zillion comments will fail to even load
// */
// private void purgeComments(boolean silentFail) {
// if(!configFile.exists())
// return;
//
// int dupedLines = 0, lineCount = 0, lineCountAfter = 0;
// try (FileReader fileReader = new FileReader(configFile);
// BufferedReader bufferedReader = new BufferedReader(fileReader)) {
// StringBuilder stringBuilder = new StringBuilder();
// String line;
// Set<String> seenBefore = new HashSet<>();
//
// stringBuilder.append(CURRENT_CONFIG_PATCH_VER).append(System.lineSeparator());
// boolean noPatchNeeded = false;
//
// // While not at the end of the file
// while ((line = bufferedReader.readLine()) != null) {
// lineCount++;
//
// if(line.startsWith(CURRENT_CONFIG_PATCH_VER)) {
// noPatchNeeded = true;
// break;
// }
//
// //Older version, don't append this line
// if(line.startsWith(CONFIG_PATCH_PREFIX))
// continue;
//
// if (isFirstCharAsciiCharacter(line, COMMENT_PREFIX)) {
// if(seenBefore.contains(line))
// dupedLines++;
// else
// seenBefore.add(line);
//
// continue; //Delete the line by not appending it
// }
//
// stringBuilder
// .append(line) //Convert existing files into two-spaced format
// .append(System.lineSeparator());
// lineCountAfter++;
// }
//
// if(noPatchNeeded)
// return;
//
// if(lineCount == 0 && !silentFail) {
// mcMMO.p.getLogger().info("[config patcher] Config line count: " + lineCount);
// throw new InvalidConfigurationException("[config patcher] Patching of config file resulted in an empty file, this will not be saved. Contact the mcMMO devs!");
// }
//
// if(dupedLines > 0 && !silentFail) {
// mcMMO.p.getLogger().info("[config patcher] Found "+dupedLines+" duplicate comments in config file: " + configFile.getName());
// mcMMO.p.getLogger().info("[config patcher] Purging the duplicate comments... (Nothing is broken, this is just info used for debugging)");
// mcMMO.p.getLogger().info("[config patcher] Line count before: "+lineCount);
// mcMMO.p.getLogger().info("[config patcher] Line count after: "+lineCountAfter);
// }
//
// // Write out the *patched* file
// // AKA the file without any comments
// try (FileWriter fileWriter = new FileWriter(configFile)) {
// fileWriter.write(stringBuilder.toString());
// }
// } catch (IOException | InvalidConfigurationException ex) {
// mcMMO.p.getLogger().severe("Failed to patch config file: " + configFile.getName());
// ex.printStackTrace();
// }
// }
private boolean isFirstCharAsciiCharacter(String line, char character) {
if(line == null || line.isEmpty()) {
return true;
}
for(Character c : line.toCharArray()) {
if(c.equals(' '))
continue;
return c.equals(character);
}
return false;
}
}

View File

@ -4,7 +4,7 @@ import com.gmail.nossr50.datatypes.chat.ChatChannel;
import com.gmail.nossr50.util.text.StringUtils;
import org.jetbrains.annotations.NotNull;
public class ChatConfig extends AutoUpdateConfigLoader {
public class ChatConfig extends BukkitConfig {
private static ChatConfig instance;
private ChatConfig() {
@ -41,7 +41,9 @@ public class ChatConfig extends AutoUpdateConfigLoader {
/**
* Whether or not to use display names for players in target {@link ChatChannel}
*
* @param chatChannel target chat channel
*
* @return true if display names should be used
*/
public boolean useDisplayNames(@NotNull ChatChannel chatChannel) {

View File

@ -1,43 +1,59 @@
package com.gmail.nossr50.config;
import com.gmail.nossr50.mcMMO;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.List;
public abstract class ConfigLoader {
protected static final mcMMO plugin = mcMMO.p;
protected String fileName;
protected final File configFile;
protected FileConfiguration config;
protected final @NotNull File dataFolder;
protected String fileName;
protected YamlConfiguration config;
public ConfigLoader(String relativePath, String fileName) {
public ConfigLoader(String relativePath, String fileName, @NotNull File dataFolder) {
this.fileName = fileName;
configFile = new File(plugin.getDataFolder(), relativePath + File.separator + fileName);
this.dataFolder = dataFolder;
configFile = new File(dataFolder, relativePath + File.separator + fileName);
loadFile();
}
public ConfigLoader(String fileName, @NotNull File dataFolder) {
this.fileName = fileName;
this.dataFolder = dataFolder;
configFile = new File(dataFolder, fileName);
loadFile();
}
@Deprecated
public ConfigLoader(String relativePath, String fileName) {
this.fileName = fileName;
configFile = new File(mcMMO.p.getDataFolder(), relativePath + File.separator + fileName);
this.dataFolder = mcMMO.p.getDataFolder();
loadFile();
}
@Deprecated
public ConfigLoader(String fileName) {
this.fileName = fileName;
configFile = new File(plugin.getDataFolder(), fileName);
configFile = new File(mcMMO.p.getDataFolder(), fileName);
this.dataFolder = mcMMO.p.getDataFolder();
loadFile();
}
protected void loadFile() {
if (!configFile.exists()) {
plugin.debug("Creating mcMMO " + fileName + " File...");
mcMMO.p.getLogger().info("Creating mcMMO " + fileName + " File...");
try {
plugin.saveResource(fileName, false); // Normal files
mcMMO.p.saveResource(fileName, false); // Normal files
} catch (IllegalArgumentException ex) {
mcMMO.p.saveResource(configFile.getParentFile().getName() + File.separator + fileName, false); // Mod files
}
catch (IllegalArgumentException ex) {
plugin.saveResource(configFile.getParentFile().getName() + File.separator + fileName, false); // Mod files
}
}
else {
plugin.debug("Loading mcMMO " + fileName + " File...");
} else {
mcMMO.p.getLogger().info("Loading mcMMO " + fileName + " File...");
}
config = YamlConfiguration.loadConfiguration(configFile);
@ -51,7 +67,7 @@ public abstract class ConfigLoader {
protected boolean noErrorsInConfig(List<String> issues) {
for (String issue : issues) {
plugin.getLogger().warning(issue);
mcMMO.p.getLogger().warning(issue);
}
return issues.isEmpty();
@ -59,12 +75,11 @@ public abstract class ConfigLoader {
protected void validate() {
if (validateKeys()) {
plugin.debug("No errors found in " + fileName + "!");
}
else {
plugin.getLogger().warning("Errors were found in " + fileName + "! mcMMO was disabled!");
plugin.getServer().getPluginManager().disablePlugin(plugin);
plugin.noErrorsInConfigFiles = false;
mcMMO.p.debug("No errors found in " + fileName + "!");
} else {
mcMMO.p.getLogger().warning("Errors were found in " + fileName + "! mcMMO was disabled!");
mcMMO.p.getServer().getPluginManager().disablePlugin(mcMMO.p);
mcMMO.p.noErrorsInConfigFiles = false;
}
}
@ -73,16 +88,16 @@ public abstract class ConfigLoader {
}
public void backup() {
plugin.getLogger().warning("You are using an old version of the " + fileName + " file.");
plugin.getLogger().warning("Your old file has been renamed to " + fileName + ".old and has been replaced by an updated version.");
mcMMO.p.getLogger().warning("You are using an old version of the " + fileName + " file.");
mcMMO.p.getLogger().warning("Your old file has been renamed to " + fileName + ".old and has been replaced by an updated version.");
configFile.renameTo(new File(configFile.getPath() + ".old"));
if (plugin.getResource(fileName) != null) {
plugin.saveResource(fileName, true);
if (mcMMO.p.getResource(fileName) != null) {
mcMMO.p.saveResource(fileName, true);
}
plugin.getLogger().warning("Reloading " + fileName + " with new values...");
mcMMO.p.getLogger().warning("Reloading " + fileName + " with new values...");
loadFile();
loadKeys();
}

View File

@ -4,28 +4,26 @@ import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.subskills.AbstractSubSkill;
import com.gmail.nossr50.util.text.StringUtils;
public class CoreSkillsConfig extends AutoUpdateConfigLoader {
public class CoreSkillsConfig extends BukkitConfig {
private static CoreSkillsConfig instance;
public CoreSkillsConfig()
{
public CoreSkillsConfig() {
super("coreskills.yml");
validate();
}
public static CoreSkillsConfig getInstance() {
if (instance == null)
instance = new CoreSkillsConfig();
return instance;
}
@Override
protected void loadKeys() {
}
public static CoreSkillsConfig getInstance()
{
if(instance == null)
return new CoreSkillsConfig();
return instance;
}
@Override
protected boolean validateKeys() {
@ -39,21 +37,23 @@ public class CoreSkillsConfig extends AutoUpdateConfigLoader {
/**
* Whether or not a skill is enabled
* Defaults true
*
* @param abstractSubSkill SubSkill definition to check
*
* @return true if subskill is enabled
*/
public boolean isSkillEnabled(AbstractSubSkill abstractSubSkill)
{
return config.getBoolean(StringUtils.getCapitalized(abstractSubSkill.getPrimarySkill().toString())+"."+ abstractSubSkill.getConfigKeyName()+".Enabled", true);
public boolean isSkillEnabled(AbstractSubSkill abstractSubSkill) {
return config.getBoolean(StringUtils.getCapitalized(abstractSubSkill.getPrimarySkill().toString()) + "." + abstractSubSkill.getConfigKeyName() + ".Enabled", true);
}
/**
* Whether or not this primary skill is enabled
*
* @param primarySkillType target primary skill
*
* @return true if enabled
*/
public boolean isPrimarySkillEnabled(PrimarySkillType primarySkillType)
{
return config.getBoolean(StringUtils.getCapitalized(primarySkillType.toString())+".Enabled", true);
public boolean isPrimarySkillEnabled(PrimarySkillType primarySkillType) {
return config.getBoolean(StringUtils.getCapitalized(primarySkillType.toString()) + ".Enabled", true);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,6 @@ public class HiddenConfig {
private static HiddenConfig instance;
private final String fileName;
private YamlConfiguration config;
private boolean chunkletsEnabled;
private int conversionRate;
private boolean useEnchantmentBuffs;
@ -30,15 +29,11 @@ public class HiddenConfig {
InputStreamReader reader = mcMMO.p.getResourceAsReader(fileName);
if (reader != null) {
config = YamlConfiguration.loadConfiguration(reader);
chunkletsEnabled = config.getBoolean("Options.Chunklets", true);
conversionRate = config.getInt("Options.ConversionRate", 1);
useEnchantmentBuffs = config.getBoolean("Options.EnchantmentBuffs", true);
}
}
public boolean getChunkletsEnabled() {
return chunkletsEnabled;
}
public int getConversionRate() {
return conversionRate;

View File

@ -1,8 +1,8 @@
package com.gmail.nossr50.config;
import com.gmail.nossr50.util.compat.layers.persistentdata.MobMetaFlagType;
import com.gmail.nossr50.metadata.MobMetaFlagType;
public class PersistentDataConfig extends AutoUpdateConfigLoader {
public class PersistentDataConfig extends BukkitConfig {
private static PersistentDataConfig instance;
private PersistentDataConfig() {
@ -34,4 +34,9 @@ public class PersistentDataConfig extends AutoUpdateConfigLoader {
return config.getBoolean(key, false);
}
public boolean useBlockTracker() {
return config.getBoolean("mcMMO_Region_System.Enabled", true);
}
}

View File

@ -2,6 +2,7 @@ package com.gmail.nossr50.config;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.datatypes.skills.subskills.AbstractSubSkill;
import com.gmail.nossr50.mcMMO;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@ -11,26 +12,24 @@ import java.util.List;
public class RankConfig extends AutoUpdateConfigLoader {
private static RankConfig instance;
public RankConfig()
{
public RankConfig() {
super("skillranks.yml");
validate();
instance = this;
}
@Override
protected void loadKeys() {
}
public static RankConfig getInstance()
{
if(instance == null)
public static RankConfig getInstance() {
if (instance == null)
return new RankConfig();
return instance;
}
@Override
protected void loadKeys() {
}
@Override
protected boolean validateKeys() {
List<String> reason = new ArrayList<>();
@ -45,12 +44,13 @@ public class RankConfig extends AutoUpdateConfigLoader {
/**
* Returns the unlock level for a subskill depending on the gamemode
*
* @param subSkillType target subskill
* @param rank the rank we are checking
* @param rank the rank we are checking
*
* @return the level requirement for a subskill at this particular rank
*/
public int getSubSkillUnlockLevel(SubSkillType subSkillType, int rank)
{
public int getSubSkillUnlockLevel(SubSkillType subSkillType, int rank) {
String key = subSkillType.getRankConfigAddress();
return findRankByRootAddress(rank, key);
@ -58,37 +58,41 @@ public class RankConfig extends AutoUpdateConfigLoader {
/**
* Returns the unlock level for a subskill depending on the gamemode
*
* @param subSkillType target subskill
* @param rank the rank we are checking
* @param rank the rank we are checking
*
* @return the level requirement for a subskill at this particular rank
*/
public int getSubSkillUnlockLevel(SubSkillType subSkillType, int rank, boolean retroMode)
{
public int getSubSkillUnlockLevel(SubSkillType subSkillType, int rank, boolean retroMode) {
String key = getRankAddressKey(subSkillType, rank, retroMode);
return config.getInt(key, getInternalConfig().getInt(key));
}
/**
* Returns the unlock level for a subskill depending on the gamemode
*
* @param abstractSubSkill target subskill
* @param rank the rank we are checking
* @param rank the rank we are checking
*
* @return the level requirement for a subskill at this particular rank
*/
public int getSubSkillUnlockLevel(AbstractSubSkill abstractSubSkill, int rank)
{
String key = abstractSubSkill.getPrimaryKeyName()+"."+abstractSubSkill.getConfigKeyName();
public int getSubSkillUnlockLevel(AbstractSubSkill abstractSubSkill, int rank) {
String key = abstractSubSkill.getPrimaryKeyName() + "." + abstractSubSkill.getConfigKeyName();
return findRankByRootAddress(rank, key);
}
/**
* Returns the unlock level for a subskill depending on the gamemode
* @param key root address of the subskill in the rankskills.yml file
*
* @param key root address of the subskill in the rankskills.yml file
* @param rank the rank we are checking
*
* @return the level requirement for a subskill at this particular rank
*/
private int findRankByRootAddress(int rank, String key) {
String scalingKey = Config.getInstance().getIsRetroMode() ? ".RetroMode." : ".Standard.";
String scalingKey = mcMMO.p.getGeneralConfig().getIsRetroMode() ? ".RetroMode." : ".Standard.";
String targetRank = "Rank_" + rank;
@ -126,60 +130,55 @@ public class RankConfig extends AutoUpdateConfigLoader {
String key = getRankAddressKey(subSkillType, rank, retroMode);
int defaultValue = getInternalConfig().getInt(key);
config.set(key, defaultValue);
plugin.getLogger().info(key +" SET -> " + defaultValue);
mcMMO.p.getLogger().info(key + " SET -> " + defaultValue);
}
/**
* Checks for valid keys for subskill ranks
*/
private void checkKeys(@NotNull List<String> reasons)
{
private void checkKeys(@NotNull List<String> reasons) {
HashSet<SubSkillType> badSkillSetup = new HashSet<>();
//For now we will only check ranks of stuff I've overhauled
checkConfig(reasons, badSkillSetup, true);
checkConfig(reasons, badSkillSetup, false);
//Fix bad entries
if(badSkillSetup.isEmpty())
if (badSkillSetup.isEmpty())
return;
plugin.getLogger().info("(FIXING CONFIG) mcMMO is correcting a few mistakes found in your skill rank config setup");
mcMMO.p.getLogger().info("(FIXING CONFIG) mcMMO is correcting a few mistakes found in your skill rank config setup");
for(SubSkillType subSkillType : badSkillSetup) {
plugin.getLogger().info("(FIXING CONFIG) Resetting rank config settings for skill named - "+subSkillType.toString());
for (SubSkillType subSkillType : badSkillSetup) {
mcMMO.p.getLogger().info("(FIXING CONFIG) Resetting rank config settings for skill named - " + subSkillType.toString());
fixBadEntries(subSkillType);
}
}
private void checkConfig(@NotNull List<String> reasons, @NotNull HashSet<SubSkillType> badSkillSetup, boolean retroMode) {
for(SubSkillType subSkillType : SubSkillType.values())
{
for (SubSkillType subSkillType : SubSkillType.values()) {
//Keeping track of the rank requirements and making sure there are no logical errors
int curRank = 0;
int prevRank = 0;
for(int x = 0; x < subSkillType.getNumRanks(); x++)
{
int index = x+1;
for (int x = 0; x < subSkillType.getNumRanks(); x++) {
int index = x + 1;
if(curRank > 0)
if (curRank > 0)
prevRank = curRank;
curRank = getSubSkillUnlockLevel(subSkillType, index, retroMode);
//Do we really care if its below 0? Probably not
if(curRank < 0)
{
reasons.add("(CONFIG ISSUE) " + subSkillType.toString() + " should not have any ranks that require a negative level!");
if (curRank < 0) {
reasons.add("(CONFIG ISSUE) " + subSkillType + " should not have any ranks that require a negative level!");
badSkillSetup.add(subSkillType);
continue;
}
if(prevRank > curRank)
{
if (prevRank > curRank) {
//We're going to allow this but we're going to warn them
plugin.getLogger().info("(CONFIG ISSUE) You have the ranks for the subskill "+ subSkillType.toString()+" set up poorly, sequential ranks should have ascending requirements");
mcMMO.p.getLogger().info("(CONFIG ISSUE) You have the ranks for the subskill " + subSkillType + " set up poorly, sequential ranks should have ascending requirements");
badSkillSetup.add(subSkillType);
}
}
@ -187,9 +186,8 @@ public class RankConfig extends AutoUpdateConfigLoader {
}
private void fixBadEntries(@NotNull SubSkillType subSkillType) {
for(int x = 0; x < subSkillType.getNumRanks(); x++)
{
int index = x+1;
for (int x = 0; x < subSkillType.getNumRanks(); x++) {
int index = x + 1;
//Reset Retromode entries
resetRankValue(subSkillType, index, true);

View File

@ -1,46 +1,41 @@
package com.gmail.nossr50.config;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.sounds.SoundType;
public class SoundConfig extends AutoUpdateConfigLoader {
public class SoundConfig extends BukkitConfig {
private static SoundConfig instance;
public SoundConfig()
{
public SoundConfig() {
super("sounds.yml");
validate();
instance = this;
}
public static SoundConfig getInstance() {
if (instance == null)
return new SoundConfig();
return instance;
}
@Override
protected void loadKeys() {
}
public static SoundConfig getInstance()
{
if(instance == null)
return new SoundConfig();
return instance;
}
@Override
protected boolean validateKeys() {
for(SoundType soundType : SoundType.values())
{
if(config.getDouble("Sounds."+soundType.toString()+".Volume") < 0)
{
plugin.getLogger().info("[mcMMO] Sound volume cannot be below 0 for "+soundType.toString());
for (SoundType soundType : SoundType.values()) {
if (config.getDouble("Sounds." + soundType.toString() + ".Volume") < 0) {
mcMMO.p.getLogger().info("[mcMMO] Sound volume cannot be below 0 for " + soundType);
return false;
}
//Sounds with custom pitching don't use pitch values
if(!soundType.usesCustomPitch())
{
if(config.getDouble("Sounds."+soundType.toString()+".Pitch") < 0)
{
plugin.getLogger().info("[mcMMO] Sound pitch cannot be below 0 for "+soundType.toString());
if (!soundType.usesCustomPitch()) {
if (config.getDouble("Sounds." + soundType + ".Pitch") < 0) {
mcMMO.p.getLogger().info("[mcMMO] Sound pitch cannot be below 0 for " + soundType);
return false;
}
}
@ -48,23 +43,22 @@ public class SoundConfig extends AutoUpdateConfigLoader {
return true;
}
public float getMasterVolume() { return (float) config.getDouble("Sounds.MasterVolume", 1.0); }
public float getMasterVolume() {
return (float) config.getDouble("Sounds.MasterVolume", 1.0);
}
public float getVolume(SoundType soundType)
{
String key = "Sounds."+soundType.toString()+".Volume";
public float getVolume(SoundType soundType) {
String key = "Sounds." + soundType.toString() + ".Volume";
return (float) config.getDouble(key);
}
public float getPitch(SoundType soundType)
{
String key = "Sounds."+soundType.toString()+".Pitch";
public float getPitch(SoundType soundType) {
String key = "Sounds." + soundType.toString() + ".Pitch";
return (float) config.getDouble(key);
}
public boolean getIsEnabled(SoundType soundType)
{
String key = "Sounds."+soundType.toString()+".Enabled";
public boolean getIsEnabled(SoundType soundType) {
String key = "Sounds." + soundType.toString() + ".Enabled";
return config.getBoolean(key, true);
}
}

View File

@ -15,20 +15,28 @@ public class WorldBlacklist {
private final String blackListFileName = "world_blacklist.txt";
public WorldBlacklist(mcMMO plugin)
{
public WorldBlacklist(mcMMO plugin) {
this.plugin = plugin;
blacklist = new ArrayList<>();
init();
}
public void init()
{
public static boolean isWorldBlacklisted(World world) {
for (String s : blacklist) {
if (world.getName().equalsIgnoreCase(s))
return true;
}
return false;
}
public void init() {
//Make the blacklist file if it doesn't exist
File blackListFile = new File(plugin.getDataFolder() + File.separator + blackListFileName);
try {
if(!blackListFile.exists())
if (!blackListFile.exists())
blackListFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
@ -48,12 +56,11 @@ public class WorldBlacklist {
String currentLine;
while((currentLine = bufferedReader.readLine()) != null)
{
if(currentLine.length() == 0)
while ((currentLine = bufferedReader.readLine()) != null) {
if (currentLine.length() == 0)
continue;
if(!blacklist.contains(currentLine))
if (!blacklist.contains(currentLine))
blacklist.add(currentLine);
}
@ -66,11 +73,11 @@ public class WorldBlacklist {
closeRead(fileReader);
}
plugin.getLogger().info(blacklist.size()+" entries in mcMMO World Blacklist");
plugin.getLogger().info(blacklist.size() + " entries in mcMMO World Blacklist");
}
private void closeRead(Reader reader) {
if(reader != null) {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
@ -78,16 +85,4 @@ public class WorldBlacklist {
}
}
}
public static boolean isWorldBlacklisted(World world)
{
for(String s : blacklist)
{
if(world.getName().equalsIgnoreCase(s))
return true;
}
return false;
}
}

View File

@ -1,6 +1,6 @@
package com.gmail.nossr50.config.experience;
import com.gmail.nossr50.config.AutoUpdateConfigLoader;
import com.gmail.nossr50.config.BukkitConfig;
import com.gmail.nossr50.datatypes.experience.FormulaType;
import com.gmail.nossr50.datatypes.skills.MaterialType;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
@ -17,7 +17,7 @@ import org.bukkit.entity.EntityType;
import java.util.ArrayList;
import java.util.List;
public class ExperienceConfig extends AutoUpdateConfigLoader {
public class ExperienceConfig extends BukkitConfig {
private static ExperienceConfig instance;
private ExperienceConfig() {
@ -25,6 +25,12 @@ public class ExperienceConfig extends AutoUpdateConfigLoader {
validate();
}
@Override
public void initDefaults() {
config.addDefault("ExploitFix.Combat.XPCeiling.Enabled", true);
config.addDefault("ExploitFix.Combat.XPCeiling.Damage_Limit", 100);
}
public static ExperienceConfig getInstance() {
if (instance == null) {
instance = new ExperienceConfig();
@ -34,7 +40,8 @@ public class ExperienceConfig extends AutoUpdateConfigLoader {
}
@Override
protected void loadKeys() {}
protected void loadKeys() {
}
@Override
protected boolean validateKeys() {
@ -139,81 +146,182 @@ public class ExperienceConfig extends AutoUpdateConfigLoader {
return noErrorsInConfig(reason);
}
public boolean isEarlyGameBoostEnabled() { return config.getBoolean("EarlyGameBoost.Enabled", true); }
public boolean isEarlyGameBoostEnabled() {
return config.getBoolean("EarlyGameBoost.Enabled", true);
}
/*
* FORMULA SETTINGS
*/
/* EXPLOIT TOGGLES */
public boolean isSnowExploitPrevented() { return config.getBoolean("ExploitFix.SnowGolemExcavation", true); }
public boolean isEndermanEndermiteFarmingPrevented() { return config.getBoolean("ExploitFix.EndermanEndermiteFarms", true); }
public boolean isPistonCheatingPrevented() { return config.getBoolean("ExploitFix.PistonCheating", true); }
public boolean isPistonExploitPrevented() { return config.getBoolean("ExploitFix.Pistons", false); }
public boolean allowUnsafeEnchantments() { return config.getBoolean("ExploitFix.UnsafeEnchantments", false); }
public boolean isCOTWBreedingPrevented() { return config.getBoolean("ExploitFix.COTWBreeding", true); }
public boolean isNPCInteractionPrevented() { return config.getBoolean("ExploitFix.PreventPluginNPCInteraction", true); }
public boolean isSnowExploitPrevented() {
return config.getBoolean("ExploitFix.SnowGolemExcavation", true);
}
public boolean isFishingExploitingPrevented() { return config.getBoolean("ExploitFix.Fishing", true); }
public boolean isAcrobaticsExploitingPrevented() { return config.getBoolean("ExploitFix.Acrobatics", true); }
public boolean isTreeFellerXPReduced() { return config.getBoolean("ExploitFix.TreeFellerReducedXP", true); }
public boolean isEndermanEndermiteFarmingPrevented() {
return config.getBoolean("ExploitFix.EndermanEndermiteFarms", true);
}
public boolean isPistonCheatingPrevented() {
return config.getBoolean("ExploitFix.PistonCheating", true);
}
public boolean isPistonExploitPrevented() {
return config.getBoolean("ExploitFix.Pistons", false);
}
public boolean allowUnsafeEnchantments() {
return config.getBoolean("ExploitFix.UnsafeEnchantments", false);
}
public boolean isCOTWBreedingPrevented() {
return config.getBoolean("ExploitFix.COTWBreeding", true);
}
public boolean isNPCInteractionPrevented() {
return config.getBoolean("ExploitFix.PreventPluginNPCInteraction", true);
}
public boolean isFishingExploitingPrevented() {
return config.getBoolean("ExploitFix.Fishing", true);
}
public int getFishingExploitingOptionMoveRange() {
return config.getInt("Fishing_ExploitFix_Options.MoveRange", 3);
}
public int getFishingExploitingOptionOverFishLimit() {
return config.getInt("Fishing_ExploitFix_Options.OverFishLimit", 10);
}
public boolean isAcrobaticsExploitingPrevented() {
return config.getBoolean("ExploitFix.Acrobatics", true);
}
public boolean isTreeFellerXPReduced() {
return config.getBoolean("ExploitFix.TreeFellerReducedXP", true);
}
/* Curve settings */
public FormulaType getFormulaType() { return FormulaType.getFormulaType(config.getString("Experience_Formula.Curve")); }
public boolean getCumulativeCurveEnabled() { return config.getBoolean("Experience_Formula.Cumulative_Curve", false); }
public FormulaType getFormulaType() {
return FormulaType.getFormulaType(config.getString("Experience_Formula.Curve"));
}
public boolean getCumulativeCurveEnabled() {
return config.getBoolean("Experience_Formula.Cumulative_Curve", false);
}
/* Curve values */
public double getMultiplier(FormulaType type) { return config.getDouble("Experience_Formula." + StringUtils.getCapitalized(type.toString()) + "_Values.multiplier"); }
public int getBase(FormulaType type) { return config.getInt("Experience_Formula." + StringUtils.getCapitalized(type.toString()) + "_Values.base"); }
public double getExponent(FormulaType type) { return config.getDouble("Experience_Formula." + StringUtils.getCapitalized(type.toString()) + "_Values.exponent"); }
public double getMultiplier(FormulaType type) {
return config.getDouble("Experience_Formula." + StringUtils.getCapitalized(type.toString()) + "_Values.multiplier");
}
public int getBase(FormulaType type) {
return config.getInt("Experience_Formula." + StringUtils.getCapitalized(type.toString()) + "_Values.base");
}
public double getExponent(FormulaType type) {
return config.getDouble("Experience_Formula." + StringUtils.getCapitalized(type.toString()) + "_Values.exponent");
}
/* Global modifier */
public double getExperienceGainsGlobalMultiplier() { return config.getDouble("Experience_Formula.Multiplier.Global", 1.0); }
public void setExperienceGainsGlobalMultiplier(double value) { config.set("Experience_Formula.Multiplier.Global", value); }
public double getExperienceGainsGlobalMultiplier() {
return config.getDouble("Experience_Formula.Multiplier.Global", 1.0);
}
public void setExperienceGainsGlobalMultiplier(double value) {
config.set("Experience_Formula.Multiplier.Global", value);
}
/* PVP modifier */
public double getPlayerVersusPlayerXP() { return config.getDouble("Experience_Formula.Multiplier.PVP", 1.0); }
public double getPlayerVersusPlayerXP() {
return config.getDouble("Experience_Formula.Multiplier.PVP", 1.0);
}
/* Spawned Mob modifier */
public double getSpawnedMobXpMultiplier() { return config.getDouble("Experience_Formula.Mobspawners.Multiplier", 0.0); }
public double getEggXpMultiplier() { return config.getDouble("Experience_Formula.Eggs.Multiplier", 0.0); }
public double getTamedMobXpMultiplier() { return config.getDouble("Experience_Formula.Player_Tamed.Multiplier", 0.0); }
public double getNetherPortalXpMultiplier() { return config.getDouble("Experience_Formula.Nether_Portal.Multiplier", 0.0); }
public double getBredMobXpMultiplier() { return config.getDouble("Experience_Formula.Breeding.Multiplier", 1.0); }
public double getSpawnedMobXpMultiplier() {
return config.getDouble("Experience_Formula.Mobspawners.Multiplier", 0.0);
}
public double getEggXpMultiplier() {
return config.getDouble("Experience_Formula.Eggs.Multiplier", 0.0);
}
public double getTamedMobXpMultiplier() {
return config.getDouble("Experience_Formula.Player_Tamed.Multiplier", 0.0);
}
public double getNetherPortalXpMultiplier() {
return config.getDouble("Experience_Formula.Nether_Portal.Multiplier", 0.0);
}
public double getBredMobXpMultiplier() {
return config.getDouble("Experience_Formula.Breeding.Multiplier", 1.0);
}
/* Skill modifiers */
public double getFormulaSkillModifier(PrimarySkillType skill) { return config.getDouble("Experience_Formula.Modifier." + StringUtils.getCapitalized(skill.toString())); }
public double getFormulaSkillModifier(PrimarySkillType skill) {
return config.getDouble("Experience_Formula.Modifier." + StringUtils.getCapitalized(skill.toString()));
}
/* Custom XP perk */
public double getCustomXpPerkBoost() { return config.getDouble("Experience_Formula.Custom_XP_Perk.Boost", 1.25); }
public double getCustomXpPerkBoost() {
return config.getDouble("Experience_Formula.Custom_XP_Perk.Boost", 1.25);
}
/* Diminished Returns */
public float getDiminishedReturnsCap() { return (float) config.getDouble("Dimished_Returns.Guaranteed_Minimum_Percentage", 0.05D); }
public boolean getDiminishedReturnsEnabled() { return config.getBoolean("Diminished_Returns.Enabled", false); }
public int getDiminishedReturnsThreshold(PrimarySkillType skill) { return config.getInt("Diminished_Returns.Threshold." + StringUtils.getCapitalized(skill.toString()), 20000); }
public int getDiminishedReturnsTimeInterval() { return config.getInt("Diminished_Returns.Time_Interval", 10); }
public float getDiminishedReturnsCap() {
return (float) config.getDouble("Dimished_Returns.Guaranteed_Minimum_Percentage", 0.05D);
}
public boolean getDiminishedReturnsEnabled() {
return config.getBoolean("Diminished_Returns.Enabled", false);
}
public int getDiminishedReturnsThreshold(PrimarySkillType skill) {
return config.getInt("Diminished_Returns.Threshold." + StringUtils.getCapitalized(skill.toString()), 20000);
}
public int getDiminishedReturnsTimeInterval() {
return config.getInt("Diminished_Returns.Time_Interval", 10);
}
/* Conversion */
public double getExpModifier() { return config.getDouble("Conversion.Exp_Modifier", 1); }
public double getExpModifier() {
return config.getDouble("Conversion.Exp_Modifier", 1);
}
/*
* XP SETTINGS
*/
/* General Settings */
public boolean getExperienceGainsPlayerVersusPlayerEnabled() { return config.getBoolean("Experience_Values.PVP.Rewards", true); }
public boolean getExperienceGainsPlayerVersusPlayerEnabled() {
return config.getBoolean("Experience_Values.PVP.Rewards", true);
}
/* Combat XP Multipliers */
public double getCombatXP(EntityType entity) { return config.getDouble("Experience_Values.Combat.Multiplier." + StringUtils.getPrettyEntityTypeString(entity).replace(" ", "_")); }
public double getAnimalsXP(EntityType entity) { return config.getDouble("Experience_Values.Combat.Multiplier." + StringUtils.getPrettyEntityTypeString(entity).replace(" ", "_"), getAnimalsXP()); }
public double getAnimalsXP() { return config.getDouble("Experience_Values.Combat.Multiplier.Animals", 1.0); }
public boolean hasCombatXP(EntityType entity) {return config.contains("Experience_Values.Combat.Multiplier." + StringUtils.getPrettyEntityTypeString(entity).replace(" ", "_")); }
public double getCombatXP(EntityType entity) {
return config.getDouble("Experience_Values.Combat.Multiplier." + StringUtils.getPrettyEntityTypeString(entity).replace(" ", "_"));
}
public double getAnimalsXP(EntityType entity) {
return config.getDouble("Experience_Values.Combat.Multiplier." + StringUtils.getPrettyEntityTypeString(entity).replace(" ", "_"), getAnimalsXP());
}
public double getAnimalsXP() {
return config.getDouble("Experience_Values.Combat.Multiplier.Animals", 1.0);
}
public boolean hasCombatXP(EntityType entity) {
return config.contains("Experience_Values.Combat.Multiplier." + StringUtils.getPrettyEntityTypeString(entity).replace(" ", "_"));
}
/* Materials */
public int getXp(PrimarySkillType skill, Material material)
{
public int getXp(PrimarySkillType skill, Material material) {
//TODO: Temporary measure to fix an exploit caused by a yet to be fixed Spigot bug (as of 7/3/2020)
if(material.toString().equalsIgnoreCase("LILY_PAD"))
if (material.toString().equalsIgnoreCase("LILY_PAD"))
return 0;
String baseString = "Experience_Values." + StringUtils.getCapitalized(skill.toString()) + ".";
@ -230,8 +338,7 @@ public class ExperienceConfig extends AutoUpdateConfigLoader {
}
/* Materials */
public int getXp(PrimarySkillType skill, BlockState blockState)
{
public int getXp(PrimarySkillType skill, BlockState blockState) {
Material data = blockState.getType();
String baseString = "Experience_Values." + StringUtils.getCapitalized(skill.toString()) + ".";
@ -248,8 +355,7 @@ public class ExperienceConfig extends AutoUpdateConfigLoader {
}
/* Materials */
public int getXp(PrimarySkillType skill, Block block)
{
public int getXp(PrimarySkillType skill, Block block) {
Material data = block.getType();
String baseString = "Experience_Values." + StringUtils.getCapitalized(skill.toString()) + ".";
@ -266,8 +372,7 @@ public class ExperienceConfig extends AutoUpdateConfigLoader {
}
/* Materials */
public int getXp(PrimarySkillType skill, BlockData data)
{
public int getXp(PrimarySkillType skill, BlockData data) {
String baseString = "Experience_Values." + StringUtils.getCapitalized(skill.toString()) + ".";
String explicitString = baseString + StringUtils.getExplicitConfigBlockDataString(data);
if (config.contains(explicitString))
@ -281,8 +386,7 @@ public class ExperienceConfig extends AutoUpdateConfigLoader {
return 0;
}
public boolean doesBlockGiveSkillXP(PrimarySkillType skill, Material data)
{
public boolean doesBlockGiveSkillXP(PrimarySkillType skill, Material data) {
String baseString = "Experience_Values." + StringUtils.getCapitalized(skill.toString()) + ".";
String explicitString = baseString + StringUtils.getExplicitConfigMaterialString(data);
if (config.contains(explicitString))
@ -294,8 +398,7 @@ public class ExperienceConfig extends AutoUpdateConfigLoader {
return config.contains(wildcardString);
}
public boolean doesBlockGiveSkillXP(PrimarySkillType skill, BlockData data)
{
public boolean doesBlockGiveSkillXP(PrimarySkillType skill, BlockData data) {
String baseString = "Experience_Values." + StringUtils.getCapitalized(skill.toString()) + ".";
String explicitString = baseString + StringUtils.getExplicitConfigBlockDataString(data);
if (config.contains(explicitString))
@ -311,32 +414,42 @@ public class ExperienceConfig extends AutoUpdateConfigLoader {
* Experience Bar Stuff
*/
public boolean isPartyExperienceBarsEnabled()
{
public boolean isPartyExperienceBarsEnabled() {
return config.getBoolean("Experience_Bars.Update.Party", true);
}
public boolean isPassiveGainsExperienceBarsEnabled()
{
public boolean isPassiveGainsExperienceBarsEnabled() {
return config.getBoolean("Experience_Bars.Update.Passive", true);
}
public boolean getDoExperienceBarsAlwaysUpdateTitle()
{
public boolean getDoExperienceBarsAlwaysUpdateTitle() {
return config.getBoolean("Experience_Bars.ThisMayCauseLag.AlwaysUpdateTitlesWhenXPIsGained.Enable", false) || getAddExtraDetails();
}
public boolean getAddExtraDetails() { return config.getBoolean("Experience_Bars.ThisMayCauseLag.AlwaysUpdateTitlesWhenXPIsGained.ExtraDetails", false);}
public boolean isExperienceBarsEnabled() { return config.getBoolean("Experience_Bars.Enable", true); }
public boolean isExperienceBarEnabled(PrimarySkillType primarySkillType) { return config.getBoolean("Experience_Bars."+StringUtils.getCapitalized(primarySkillType.toString())+".Enable", true);}
public boolean getAddExtraDetails() {
return config.getBoolean("Experience_Bars.ThisMayCauseLag.AlwaysUpdateTitlesWhenXPIsGained.ExtraDetails", false);
}
public boolean useCombatHPCeiling() {
return config.getBoolean("ExploitFix.Combat.XPCeiling.Enabled", true);
}
public BarColor getExperienceBarColor(PrimarySkillType primarySkillType)
{
String colorValueFromConfig = config.getString("Experience_Bars."+StringUtils.getCapitalized(primarySkillType.toString())+".Color");
public int getCombatHPCeiling() {
return config.getInt("ExploitFix.Combat.XPCeiling.HP_Modifier_Limit", 100);
}
for(BarColor barColor : BarColor.values())
{
if(barColor.toString().equalsIgnoreCase(colorValueFromConfig))
public boolean isExperienceBarsEnabled() {
return config.getBoolean("Experience_Bars.Enable", true);
}
public boolean isExperienceBarEnabled(PrimarySkillType primarySkillType) {
return config.getBoolean("Experience_Bars." + StringUtils.getCapitalized(primarySkillType.toString()) + ".Enable", true);
}
public BarColor getExperienceBarColor(PrimarySkillType primarySkillType) {
String colorValueFromConfig = config.getString("Experience_Bars." + StringUtils.getCapitalized(primarySkillType.toString()) + ".Color");
for (BarColor barColor : BarColor.values()) {
if (barColor.toString().equalsIgnoreCase(colorValueFromConfig))
return barColor;
}
@ -344,13 +457,11 @@ public class ExperienceConfig extends AutoUpdateConfigLoader {
return BarColor.WHITE;
}
public BarStyle getExperienceBarStyle(PrimarySkillType primarySkillType)
{
String colorValueFromConfig = config.getString("Experience_Bars."+StringUtils.getCapitalized(primarySkillType.toString())+".BarStyle");
public BarStyle getExperienceBarStyle(PrimarySkillType primarySkillType) {
String colorValueFromConfig = config.getString("Experience_Bars." + StringUtils.getCapitalized(primarySkillType.toString()) + ".BarStyle");
for(BarStyle barStyle : BarStyle.values())
{
if(barStyle.toString().equalsIgnoreCase(colorValueFromConfig))
for (BarStyle barStyle : BarStyle.values()) {
if (barStyle.toString().equalsIgnoreCase(colorValueFromConfig))
return barStyle;
}
@ -359,29 +470,51 @@ public class ExperienceConfig extends AutoUpdateConfigLoader {
}
/* Acrobatics */
public int getDodgeXPModifier() { return config.getInt("Experience_Values.Acrobatics.Dodge", 120); }
public int getRollXPModifier() { return config.getInt("Experience_Values.Acrobatics.Roll", 80); }
public int getFallXPModifier() { return config.getInt("Experience_Values.Acrobatics.Fall", 120); }
public int getDodgeXPModifier() {
return config.getInt("Experience_Values.Acrobatics.Dodge", 120);
}
public double getFeatherFallXPModifier() { return config.getDouble("Experience_Values.Acrobatics.FeatherFall_Multiplier", 2.0); }
public int getRollXPModifier() {
return config.getInt("Experience_Values.Acrobatics.Roll", 80);
}
public int getFallXPModifier() {
return config.getInt("Experience_Values.Acrobatics.Fall", 120);
}
public double getFeatherFallXPModifier() {
return config.getDouble("Experience_Values.Acrobatics.FeatherFall_Multiplier", 2.0);
}
/* Alchemy */
public double getPotionXP(PotionStage stage) { return config.getDouble("Experience_Values.Alchemy.Potion_Stage_" + stage.toNumerical(), 10D); }
public double getPotionXP(PotionStage stage) {
return config.getDouble("Experience_Values.Alchemy.Potion_Stage_" + stage.toNumerical(), 10D);
}
/* Archery */
public double getArcheryDistanceMultiplier() { return config.getDouble("Experience_Values.Archery.Distance_Multiplier", 0.025); }
public double getArcheryDistanceMultiplier() {
return config.getDouble("Experience_Values.Archery.Distance_Multiplier", 0.025);
}
public int getFishingShakeXP() { return config.getInt("Experience_Values.Fishing.Shake", 50); }
public int getFishingShakeXP() {
return config.getInt("Experience_Values.Fishing.Shake", 50);
}
/* Repair */
public double getRepairXPBase() { return config.getDouble("Experience_Values.Repair.Base", 1000.0); }
public double getRepairXP(MaterialType repairMaterialType) { return config.getDouble("Experience_Values.Repair." + StringUtils.getCapitalized(repairMaterialType.toString())); }
public double getRepairXPBase() {
return config.getDouble("Experience_Values.Repair.Base", 1000.0);
}
public double getRepairXP(MaterialType repairMaterialType) {
return config.getDouble("Experience_Values.Repair." + StringUtils.getCapitalized(repairMaterialType.toString()));
}
/* Taming */
public int getTamingXP(EntityType type)
{
public int getTamingXP(EntityType type) {
return config.getInt("Experience_Values.Taming.Animal_Taming." + StringUtils.getPrettyEntityTypeString(type));
}
public boolean preventStoneLavaFarming() { return config.getBoolean("ExploitFix.LavaStoneAndCobbleFarming", true);}
public boolean preventStoneLavaFarming() {
return config.getBoolean("ExploitFix.LavaStoneAndCobbleFarming", true);
}
}

View File

@ -3,6 +3,7 @@ package com.gmail.nossr50.config.mods;
import com.gmail.nossr50.config.ConfigLoader;
import com.gmail.nossr50.datatypes.skills.ItemType;
import com.gmail.nossr50.datatypes.skills.MaterialType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.repair.repairables.Repairable;
import com.gmail.nossr50.skills.repair.repairables.RepairableFactory;
import org.bukkit.Material;
@ -13,14 +14,12 @@ import java.util.List;
import java.util.Set;
public class CustomArmorConfig extends ConfigLoader {
private boolean needsUpdate = false;
public List<Material> customBoots = new ArrayList<>();
public List<Material> customBoots = new ArrayList<>();
public List<Material> customChestplates = new ArrayList<>();
public List<Material> customHelmets = new ArrayList<>();
public List<Material> customLeggings = new ArrayList<>();
public List<Material> customHelmets = new ArrayList<>();
public List<Material> customLeggings = new ArrayList<>();
public List<Repairable> repairables = new ArrayList<>();
private boolean needsUpdate = false;
protected CustomArmorConfig(String fileName) {
super("mods", fileName);
@ -62,7 +61,7 @@ public class CustomArmorConfig extends ConfigLoader {
Material armorMaterial = Material.matchMaterial(armorName);
if (armorMaterial == null) {
plugin.getLogger().warning("Invalid material name. This item will be skipped. - " + armorName);
mcMMO.p.getLogger().warning("Invalid material name. This item will be skipped. - " + armorName);
continue;
}
@ -70,7 +69,7 @@ public class CustomArmorConfig extends ConfigLoader {
Material repairMaterial = Material.matchMaterial(config.getString(armorType + "." + armorName + ".Repair_Material", ""));
if (repairable && (repairMaterial == null)) {
plugin.getLogger().warning("Incomplete repair information. This item will be unrepairable. - " + armorName);
mcMMO.p.getLogger().warning("Incomplete repair information. This item will be unrepairable. - " + armorName);
repairable = false;
}

View File

@ -2,6 +2,7 @@ package com.gmail.nossr50.config.mods;
import com.gmail.nossr50.config.ConfigLoader;
import com.gmail.nossr50.datatypes.mods.CustomBlock;
import com.gmail.nossr50.mcMMO;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
@ -11,17 +12,15 @@ import java.util.List;
import java.util.Set;
public class CustomBlockConfig extends ConfigLoader {
private boolean needsUpdate = false;
public List<Material> customExcavationBlocks = new ArrayList<>();
public List<Material> customHerbalismBlocks = new ArrayList<>();
public List<Material> customMiningBlocks = new ArrayList<>();
public List<Material> customOres = new ArrayList<>();
public List<Material> customLogs = new ArrayList<>();
public List<Material> customLeaves = new ArrayList<>();
public List<Material> customAbilityBlocks = new ArrayList<>();
public List<Material> customExcavationBlocks = new ArrayList<>();
public List<Material> customHerbalismBlocks = new ArrayList<>();
public List<Material> customMiningBlocks = new ArrayList<>();
public List<Material> customOres = new ArrayList<>();
public List<Material> customLogs = new ArrayList<>();
public List<Material> customLeaves = new ArrayList<>();
public List<Material> customAbilityBlocks = new ArrayList<>();
public HashMap<Material, CustomBlock> customBlockMap = new HashMap<>();
private boolean needsUpdate = false;
protected CustomBlockConfig(String fileName) {
super("mods", fileName);
@ -66,7 +65,7 @@ public class CustomBlockConfig extends ConfigLoader {
Material blockMaterial = Material.matchMaterial(blockInfo[0]);
if (blockMaterial == null) {
plugin.getLogger().warning("Invalid material name. This item will be skipped. - " + blockInfo[0]);
mcMMO.p.getLogger().warning("Invalid material name. This item will be skipped. - " + blockInfo[0]);
continue;
}
@ -84,12 +83,10 @@ public class CustomBlockConfig extends ConfigLoader {
if (skillType.equals("Mining") && config.getBoolean(skillType + "." + blockName + ".Is_Ore")) {
customOres.add(blockMaterial);
smeltingXp = config.getInt(skillType + "." + blockName + ".Smelting_XP_Gain", xp / 10);
}
else if (skillType.equals("Woodcutting")) {
} else if (skillType.equals("Woodcutting")) {
if (config.getBoolean(skillType + "." + blockName + ".Is_Log")) {
customLogs.add(blockMaterial);
}
else {
} else {
customLeaves.add(blockMaterial);
xp = 0; // Leaves don't grant XP
}

View File

@ -2,6 +2,7 @@ package com.gmail.nossr50.config.mods;
import com.gmail.nossr50.config.ConfigLoader;
import com.gmail.nossr50.datatypes.mods.CustomEntity;
import com.gmail.nossr50.mcMMO;
import org.apache.commons.lang.ClassUtils;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
@ -10,7 +11,7 @@ import java.util.HashMap;
public class CustomEntityConfig extends ConfigLoader {
public HashMap<String, CustomEntity> customEntityClassMap = new HashMap<>();
public HashMap<String, CustomEntity> customEntityTypeMap = new HashMap<>();
public HashMap<String, CustomEntity> customEntityTypeMap = new HashMap<>();
protected CustomEntityConfig(String fileName) {
super("mods", fileName);
@ -30,10 +31,9 @@ public class CustomEntityConfig extends ConfigLoader {
try {
clazz = ClassUtils.getClass(className);
}
catch (ClassNotFoundException e) {
plugin.getLogger().warning("Invalid class (" + className + ") detected for " + entityName + ".");
plugin.getLogger().warning("This custom entity may not function properly.");
} catch (ClassNotFoundException e) {
mcMMO.p.getLogger().warning("Invalid class (" + className + ") detected for " + entityName + ".");
mcMMO.p.getLogger().warning("This custom entity may not function properly.");
}
String entityTypeName = entityName.replace("_", ".");
@ -48,7 +48,7 @@ public class CustomEntityConfig extends ConfigLoader {
int callOfTheWildAmount = config.getInt(entityName + ".COTW_Material_Amount");
if (canBeSummoned && (callOfTheWildMaterial == null || callOfTheWildAmount == 0)) {
plugin.getLogger().warning("Incomplete Call of the Wild information. This entity will not be able to be summoned by Call of the Wild.");
mcMMO.p.getLogger().warning("Incomplete Call of the Wild information. This entity will not be able to be summoned by Call of the Wild.");
canBeSummoned = false;
}

View File

@ -4,6 +4,7 @@ import com.gmail.nossr50.config.ConfigLoader;
import com.gmail.nossr50.datatypes.mods.CustomTool;
import com.gmail.nossr50.datatypes.skills.ItemType;
import com.gmail.nossr50.datatypes.skills.MaterialType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.repair.repairables.Repairable;
import com.gmail.nossr50.skills.repair.repairables.RepairableFactory;
import org.bukkit.Material;
@ -15,18 +16,15 @@ import java.util.List;
import java.util.Set;
public class CustomToolConfig extends ConfigLoader {
private boolean needsUpdate = false;
public List<Material> customAxes = new ArrayList<>();
public List<Material> customBows = new ArrayList<>();
public List<Material> customHoes = new ArrayList<>();
public List<Material> customAxes = new ArrayList<>();
public List<Material> customBows = new ArrayList<>();
public List<Material> customHoes = new ArrayList<>();
public List<Material> customPickaxes = new ArrayList<>();
public List<Material> customShovels = new ArrayList<>();
public List<Material> customSwords = new ArrayList<>();
public List<Material> customShovels = new ArrayList<>();
public List<Material> customSwords = new ArrayList<>();
public HashMap<Material, CustomTool> customToolMap = new HashMap<>();
public List<Repairable> repairables = new ArrayList<>();
private boolean needsUpdate = false;
protected CustomToolConfig(String fileName) {
super("mods", fileName);
@ -70,7 +68,7 @@ public class CustomToolConfig extends ConfigLoader {
Material toolMaterial = Material.matchMaterial(toolName);
if (toolMaterial == null) {
plugin.getLogger().warning("Invalid material name. This item will be skipped. - " + toolName);
mcMMO.p.getLogger().warning("Invalid material name. This item will be skipped. - " + toolName);
continue;
}
@ -78,7 +76,7 @@ public class CustomToolConfig extends ConfigLoader {
Material repairMaterial = Material.matchMaterial(config.getString(toolType + "." + toolName + ".Repair_Material", ""));
if (repairable && (repairMaterial == null)) {
plugin.getLogger().warning("Incomplete repair information. This item will be unrepairable. - " + toolName);
mcMMO.p.getLogger().warning("Incomplete repair information. This item will be unrepairable. - " + toolName);
repairable = false;
}

View File

@ -1,13 +1,13 @@
package com.gmail.nossr50.config.party;
import com.gmail.nossr50.config.ConfigLoader;
import com.gmail.nossr50.config.BukkitConfig;
import com.gmail.nossr50.util.text.StringUtils;
import org.bukkit.Material;
import java.util.HashSet;
import java.util.Locale;
public class ItemWeightConfig extends ConfigLoader {
public class ItemWeightConfig extends BukkitConfig {
private static ItemWeightConfig instance;
private ItemWeightConfig() {
@ -40,5 +40,6 @@ public class ItemWeightConfig extends ConfigLoader {
}
@Override
protected void loadKeys() {}
protected void loadKeys() {
}
}

View File

@ -95,8 +95,7 @@ public class PotionConfig extends ConfigLoader {
if (potion != null) {
potionMap.put(potionName, potion);
pass++;
}
else {
} else {
fail++;
}
}
@ -114,13 +113,13 @@ public class PotionConfig extends ConfigLoader {
*/
private AlchemyPotion loadPotion(ConfigurationSection potion_section) {
try {
String name = potion_section.getString("Name");
if (name != null) {
name = ChatColor.translateAlternateColorCodes('&', name);
}
PotionData data;
if (!potion_section.contains("PotionData")) { // Backwards config compatability
short dataValue = Short.parseShort(potion_section.getName());
@ -130,7 +129,7 @@ public class PotionConfig extends ConfigLoader {
ConfigurationSection potionData = potion_section.getConfigurationSection("PotionData");
data = new PotionData(PotionType.valueOf(potionData.getString("PotionType", "WATER")), potionData.getBoolean("Extended", false), potionData.getBoolean("Upgraded", false));
}
Material material = Material.POTION;
String mat = potion_section.getString("Material", null);
if (mat != null) {
@ -155,18 +154,16 @@ public class PotionConfig extends ConfigLoader {
if (type != null) {
effects.add(new PotionEffect(type, duration, amplifier));
}
else {
} else {
mcMMO.p.getLogger().warning("Failed to parse effect for potion " + name + ": " + effect);
}
}
}
Color color;
if (potion_section.contains("Color")) {
color = Color.fromRGB(potion_section.getInt("Color"));
}
else {
} else {
color = this.generateColor(effects);
}
@ -176,16 +173,14 @@ public class PotionConfig extends ConfigLoader {
ItemStack ingredient = loadIngredient(child);
if (ingredient != null) {
children.put(ingredient, potion_section.getConfigurationSection("Children").getString(child));
}
else {
} else {
mcMMO.p.getLogger().warning("Failed to parse child for potion " + name + ": " + child);
}
}
}
return new AlchemyPotion(material, data, name, lore, effects, color, children);
}
catch (Exception e) {
} catch (Exception e) {
mcMMO.p.getLogger().warning("Failed to load Alchemy potion: " + potion_section.getName());
return null;
}
@ -243,7 +238,7 @@ public class PotionConfig extends ConfigLoader {
public AlchemyPotion getPotion(String name) {
return potionMap.get(name);
}
public AlchemyPotion getPotion(ItemStack item) {
for (AlchemyPotion potion : potionMap.values()) {
if (potion.isSimilar(item)) {
@ -252,7 +247,7 @@ public class PotionConfig extends ConfigLoader {
}
return null;
}
public Color generateColor(List<PotionEffect> effects) {
if (effects != null && !effects.isEmpty()) {
List<Color> colors = new ArrayList<>();
@ -270,7 +265,7 @@ public class PotionConfig extends ConfigLoader {
}
return null;
}
public Color calculateAverageColor(List<Color> colors) {
int red = 0;
int green = 0;
@ -280,7 +275,7 @@ public class PotionConfig extends ConfigLoader {
green += color.getGreen();
blue += color.getBlue();
}
return Color.fromRGB(red/colors.size(), green/colors.size(), blue/colors.size());
return Color.fromRGB(red / colors.size(), green / colors.size(), blue / colors.size());
}
}

View File

@ -1,6 +1,6 @@
package com.gmail.nossr50.config.skills.repair;
import com.gmail.nossr50.config.ConfigLoader;
import com.gmail.nossr50.config.BukkitConfig;
import com.gmail.nossr50.datatypes.skills.ItemType;
import com.gmail.nossr50.datatypes.skills.MaterialType;
import com.gmail.nossr50.mcMMO;
@ -13,9 +13,9 @@ import org.bukkit.inventory.ItemStack;
import java.util.*;
public class RepairConfig extends ConfigLoader {
private List<Repairable> repairables;
public class RepairConfig extends BukkitConfig {
private final HashSet<String> notSupported;
private List<Repairable> repairables;
public RepairConfig(String fileName) {
super(fileName);
@ -62,33 +62,25 @@ public class RepairConfig extends ConfigLoader {
if (ItemUtils.isWoodTool(repairItem)) {
repairMaterialType = MaterialType.WOOD;
}
else if (ItemUtils.isStoneTool(repairItem)) {
} else if (ItemUtils.isStoneTool(repairItem)) {
repairMaterialType = MaterialType.STONE;
}
else if (ItemUtils.isStringTool(repairItem)) {
} else if (ItemUtils.isStringTool(repairItem)) {
repairMaterialType = MaterialType.STRING;
}
else if (ItemUtils.isLeatherArmor(repairItem)) {
} else if (ItemUtils.isLeatherArmor(repairItem)) {
repairMaterialType = MaterialType.LEATHER;
}
else if (ItemUtils.isIronArmor(repairItem) || ItemUtils.isIronTool(repairItem)) {
} else if (ItemUtils.isIronArmor(repairItem) || ItemUtils.isIronTool(repairItem)) {
repairMaterialType = MaterialType.IRON;
}
else if (ItemUtils.isGoldArmor(repairItem) || ItemUtils.isGoldTool(repairItem)) {
} else if (ItemUtils.isGoldArmor(repairItem) || ItemUtils.isGoldTool(repairItem)) {
repairMaterialType = MaterialType.GOLD;
}
else if (ItemUtils.isDiamondArmor(repairItem) || ItemUtils.isDiamondTool(repairItem)) {
} else if (ItemUtils.isDiamondArmor(repairItem) || ItemUtils.isDiamondTool(repairItem)) {
repairMaterialType = MaterialType.DIAMOND;
} else if (ItemUtils.isNetheriteArmor(repairItem) || ItemUtils.isNetheriteTool(repairItem)) {
repairMaterialType = MaterialType.NETHERITE;
}
}
else {
} else {
try {
repairMaterialType = MaterialType.valueOf(repairMaterialTypeString);
}
catch (IllegalArgumentException ex) {
} catch (IllegalArgumentException ex) {
reason.add(key + " has an invalid MaterialType of " + repairMaterialTypeString);
}
}
@ -122,16 +114,13 @@ public class RepairConfig extends ConfigLoader {
if (ItemUtils.isMinecraftTool(repairItem)) {
repairItemType = ItemType.TOOL;
}
else if (ItemUtils.isArmor(repairItem)) {
} else if (ItemUtils.isArmor(repairItem)) {
repairItemType = ItemType.ARMOR;
}
}
else {
} else {
try {
repairItemType = ItemType.valueOf(repairItemTypeString);
}
catch (IllegalArgumentException ex) {
} catch (IllegalArgumentException ex) {
reason.add(key + " has an invalid ItemType of " + repairItemTypeString);
}
}
@ -146,7 +135,7 @@ public class RepairConfig extends ConfigLoader {
// Minimum Quantity
int minimumQuantity = config.getInt("Repairables." + key + ".MinimumQuantity");
if(minimumQuantity == 0) {
if (minimumQuantity == 0) {
minimumQuantity = -1;
}
@ -158,13 +147,13 @@ public class RepairConfig extends ConfigLoader {
//Report unsupported
StringBuilder stringBuilder = new StringBuilder();
if(notSupported.size() > 0) {
if (notSupported.size() > 0) {
stringBuilder.append("mcMMO found the following materials in the Repair config that are not supported by the version of Minecraft running on this server: ");
for (Iterator<String> iterator = notSupported.iterator(); iterator.hasNext(); ) {
String unsupportedMaterial = iterator.next();
if(!iterator.hasNext()) {
if (!iterator.hasNext()) {
stringBuilder.append(unsupportedMaterial);
} else {
stringBuilder.append(unsupportedMaterial).append(", ");
@ -182,7 +171,7 @@ public class RepairConfig extends ConfigLoader {
private boolean noErrorsInRepairable(List<String> issues) {
for (String issue : issues) {
plugin.getLogger().warning(issue);
mcMMO.p.getLogger().warning(issue);
}
return issues.isEmpty();

View File

@ -1,28 +1,28 @@
package com.gmail.nossr50.config.skills.repair;
import com.gmail.nossr50.datatypes.database.UpgradeType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.repair.repairables.Repairable;
import com.gmail.nossr50.util.FixSpellingNetheriteUtil;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Collection;
import java.util.HashSet;
import java.util.regex.Pattern;
public class RepairConfigManager {
private final List<Repairable> repairables = new ArrayList<>();
public static final String REPAIR_VANILLA_YML = "repair.vanilla.yml";
private static final Collection<Repairable> repairables = new HashSet<>();
public RepairConfigManager(mcMMO plugin) {
Pattern pattern = Pattern.compile("repair\\.(?:.+)\\.yml");
File dataFolder = plugin.getDataFolder();
File vanilla = new File(dataFolder, "repair.vanilla.yml");
if (!vanilla.exists()) {
plugin.saveResource("repair.vanilla.yml", false);
}
RepairConfig mainRepairConfig = new RepairConfig(REPAIR_VANILLA_YML);
repairables.addAll(mainRepairConfig.getLoadedRepairables());
for (String fileName : dataFolder.list()) {
if(fileName.equals(REPAIR_VANILLA_YML))
continue;
if (!pattern.matcher(fileName).matches()) {
continue;
}
@ -33,19 +33,12 @@ public class RepairConfigManager {
continue;
}
if(mcMMO.getUpgradeManager().shouldUpgrade(UpgradeType.FIX_SPELLING_NETHERITE_REPAIR)) {
//Check spelling mistakes (early versions of 1.16 support had Netherite misspelled)
plugin.getLogger().info("Checking for certain invalid material names in Repair config...");
FixSpellingNetheriteUtil.processFileCheck(mcMMO.p, fileName, UpgradeType.FIX_SPELLING_NETHERITE_REPAIR);
}
RepairConfig rConfig = new RepairConfig(fileName);
repairables.addAll(rConfig.getLoadedRepairables());
}
}
public List<Repairable> getLoadedRepairables() {
public Collection<Repairable> getLoadedRepairables() {
return repairables;
}
}

View File

@ -1,6 +1,6 @@
package com.gmail.nossr50.config.skills.salvage;
import com.gmail.nossr50.config.ConfigLoader;
import com.gmail.nossr50.config.BukkitConfig;
import com.gmail.nossr50.datatypes.database.UpgradeType;
import com.gmail.nossr50.datatypes.skills.ItemType;
import com.gmail.nossr50.datatypes.skills.MaterialType;
@ -16,9 +16,9 @@ import org.bukkit.inventory.ItemStack;
import java.io.IOException;
import java.util.*;
public class SalvageConfig extends ConfigLoader {
private List<Salvageable> salvageables;
public class SalvageConfig extends BukkitConfig {
private final HashSet<String> notSupported;
private Set<Salvageable> salvageables;
public SalvageConfig(String fileName) {
super(fileName);
@ -28,7 +28,7 @@ public class SalvageConfig extends ConfigLoader {
@Override
protected void loadKeys() {
salvageables = new ArrayList<>();
salvageables = new HashSet<>();
if (!config.isConfigurationSection("Salvageables")) {
mcMMO.p.getLogger().severe("Could not find Salvageables section in " + fileName);
@ -40,10 +40,10 @@ public class SalvageConfig extends ConfigLoader {
//Original version of 1.16 support had maximum quantities that were bad, this fixes it
if(mcMMO.getUpgradeManager().shouldUpgrade(UpgradeType.FIX_NETHERITE_SALVAGE_QUANTITIES)) {
if (mcMMO.getUpgradeManager().shouldUpgrade(UpgradeType.FIX_NETHERITE_SALVAGE_QUANTITIES)) {
mcMMO.p.getLogger().info("Fixing incorrect Salvage quantities on Netherite gear, this will only run once...");
for(String namespacedkey : mcMMO.getMaterialMapStore().getNetheriteArmor()) {
config.set("Salvageables." + namespacedkey.toUpperCase() + ".MaximumQuantity", 4);
for (String namespacedkey : mcMMO.getMaterialMapStore().getNetheriteArmor()) {
config.set("Salvageables." + namespacedkey.toUpperCase() + ".MaximumQuantity", 4); //TODO: Doesn't make sense to default to 4 for everything
}
try {
@ -78,33 +78,25 @@ public class SalvageConfig extends ConfigLoader {
if (ItemUtils.isWoodTool(salvageItem)) {
salvageMaterialType = MaterialType.WOOD;
}
else if (ItemUtils.isStoneTool(salvageItem)) {
} else if (ItemUtils.isStoneTool(salvageItem)) {
salvageMaterialType = MaterialType.STONE;
}
else if (ItemUtils.isStringTool(salvageItem)) {
} else if (ItemUtils.isStringTool(salvageItem)) {
salvageMaterialType = MaterialType.STRING;
}
else if (ItemUtils.isLeatherArmor(salvageItem)) {
} else if (ItemUtils.isLeatherArmor(salvageItem)) {
salvageMaterialType = MaterialType.LEATHER;
}
else if (ItemUtils.isIronArmor(salvageItem) || ItemUtils.isIronTool(salvageItem)) {
} else if (ItemUtils.isIronArmor(salvageItem) || ItemUtils.isIronTool(salvageItem)) {
salvageMaterialType = MaterialType.IRON;
}
else if (ItemUtils.isGoldArmor(salvageItem) || ItemUtils.isGoldTool(salvageItem)) {
} else if (ItemUtils.isGoldArmor(salvageItem) || ItemUtils.isGoldTool(salvageItem)) {
salvageMaterialType = MaterialType.GOLD;
}
else if (ItemUtils.isDiamondArmor(salvageItem) || ItemUtils.isDiamondTool(salvageItem)) {
} else if (ItemUtils.isDiamondArmor(salvageItem) || ItemUtils.isDiamondTool(salvageItem)) {
salvageMaterialType = MaterialType.DIAMOND;
} else if (ItemUtils.isNetheriteTool(salvageItem) || ItemUtils.isNetheriteArmor(salvageItem)) {
salvageMaterialType = MaterialType.NETHERITE;
}
}
else {
} else {
try {
salvageMaterialType = MaterialType.valueOf(salvageMaterialTypeString.replace(" ", "_").toUpperCase(Locale.ENGLISH));
}
catch (IllegalArgumentException ex) {
} catch (IllegalArgumentException ex) {
reason.add(key + " has an invalid MaterialType of " + salvageMaterialTypeString);
}
}
@ -130,16 +122,13 @@ public class SalvageConfig extends ConfigLoader {
if (ItemUtils.isMinecraftTool(salvageItem)) {
salvageItemType = ItemType.TOOL;
}
else if (ItemUtils.isArmor(salvageItem)) {
} else if (ItemUtils.isArmor(salvageItem)) {
salvageItemType = ItemType.ARMOR;
}
}
else {
} else {
try {
salvageItemType = ItemType.valueOf(salvageItemTypeString.replace(" ", "_").toUpperCase(Locale.ENGLISH));
}
catch (IllegalArgumentException ex) {
} catch (IllegalArgumentException ex) {
reason.add(key + " has an invalid ItemType of " + salvageItemTypeString);
}
}
@ -176,13 +165,13 @@ public class SalvageConfig extends ConfigLoader {
//Report unsupported
StringBuilder stringBuilder = new StringBuilder();
if(notSupported.size() > 0) {
if (notSupported.size() > 0) {
stringBuilder.append("mcMMO found the following materials in the Salvage config that are not supported by the version of Minecraft running on this server: ");
for (Iterator<String> iterator = notSupported.iterator(); iterator.hasNext(); ) {
String unsupportedMaterial = iterator.next();
if(!iterator.hasNext()) {
if (!iterator.hasNext()) {
stringBuilder.append(unsupportedMaterial);
} else {
stringBuilder.append(unsupportedMaterial).append(", ");
@ -194,18 +183,18 @@ public class SalvageConfig extends ConfigLoader {
}
}
protected List<Salvageable> getLoadedSalvageables() {
return salvageables == null ? new ArrayList<>() : salvageables;
protected Collection<Salvageable> getLoadedSalvageables() {
return salvageables == null ? new HashSet<>() : salvageables;
}
private boolean noErrorsInSalvageable(List<String> issues) {
if (!issues.isEmpty()) {
plugin.getLogger().warning("Errors have been found in: " + fileName);
plugin.getLogger().warning("The following issues were found:");
mcMMO.p.getLogger().warning("Errors have been found in: " + fileName);
mcMMO.p.getLogger().warning("The following issues were found:");
}
for (String issue : issues) {
plugin.getLogger().warning(issue);
mcMMO.p.getLogger().warning(issue);
}
return issues.isEmpty();

View File

@ -1,9 +1,7 @@
package com.gmail.nossr50.config.skills.salvage;
import com.gmail.nossr50.datatypes.database.UpgradeType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.salvage.salvageables.Salvageable;
import com.gmail.nossr50.util.FixSpellingNetheriteUtil;
import java.io.File;
import java.util.ArrayList;
@ -11,18 +9,21 @@ import java.util.List;
import java.util.regex.Pattern;
public class SalvageConfigManager {
private final List<Salvageable> salvageables = new ArrayList<>();
public static final String SALVAGE_VANILLA_YML = "salvage.vanilla.yml";
private final List<Salvageable> salvageables = new ArrayList<>(); //TODO: Collision checking, make the list a set
public SalvageConfigManager(mcMMO plugin) {
Pattern pattern = Pattern.compile("salvage\\.(?:.+)\\.yml");
File dataFolder = plugin.getDataFolder();
File vanilla = new File(dataFolder, "salvage.vanilla.yml");
if (!vanilla.exists()) {
plugin.saveResource("salvage.vanilla.yml", false);
}
SalvageConfig mainSalvageConfig = new SalvageConfig(SALVAGE_VANILLA_YML);
salvageables.addAll(mainSalvageConfig.getLoadedSalvageables());
for (String fileName : dataFolder.list()) {
if(fileName.equals(SALVAGE_VANILLA_YML))
continue;
if (!pattern.matcher(fileName).matches()) {
continue;
}
@ -33,20 +34,12 @@ public class SalvageConfigManager {
continue;
}
if(mcMMO.getUpgradeManager().shouldUpgrade(UpgradeType.FIX_SPELLING_NETHERITE_SALVAGE)) {
//Check spelling mistakes (early versions of 1.16 support had Netherite misspelled)
plugin.getLogger().info("Checking for certain invalid material names in Salvage config...");
FixSpellingNetheriteUtil.processFileCheck(mcMMO.p, fileName, UpgradeType.FIX_SPELLING_NETHERITE_SALVAGE);
}
SalvageConfig salvageConfig = new SalvageConfig(fileName);
salvageables.addAll(salvageConfig.getLoadedSalvageables());
}
}
public List<Salvageable> getLoadedSalvageables() {
return salvageables;
return new ArrayList<>(salvageables);
}
}

View File

@ -1,6 +1,6 @@
package com.gmail.nossr50.config.treasure;
import com.gmail.nossr50.config.ConfigLoader;
import com.gmail.nossr50.config.BukkitConfig;
import com.gmail.nossr50.datatypes.treasure.*;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.EnchantmentUtils;
@ -18,14 +18,14 @@ import org.jetbrains.annotations.NotNull;
import java.util.*;
public class FishingTreasureConfig extends ConfigLoader {
public class FishingTreasureConfig extends BukkitConfig {
public static final String FILENAME = "fishing_treasures.yml";
private static FishingTreasureConfig instance;
public @NotNull HashMap<Rarity, List<FishingTreasure>> fishingRewards = new HashMap<>();
public @NotNull HashMap<Rarity, List<FishingTreasure>> fishingRewards = new HashMap<>();
public @NotNull HashMap<Rarity, List<EnchantmentTreasure>> fishingEnchantments = new HashMap<>();
public @NotNull HashMap<EntityType, List<ShakeTreasure>> shakeMap = new HashMap<>();
public @NotNull HashMap<EntityType, List<ShakeTreasure>> shakeMap = new HashMap<>();
private FishingTreasureConfig() {
super(FILENAME);
@ -45,33 +45,39 @@ public class FishingTreasureConfig extends ConfigLoader {
protected boolean validateKeys() {
// Validate all the settings!
List<String> reason = new ArrayList<>();
for (String tier : config.getConfigurationSection("Enchantment_Drop_Rates").getKeys(false)) {
double totalEnchantDropRate = 0;
double totalItemDropRate = 0;
ConfigurationSection enchantment_drop_rates = config.getConfigurationSection("Enchantment_Drop_Rates");
for (Rarity rarity : Rarity.values()) {
double enchantDropRate = config.getDouble("Enchantment_Drop_Rates." + tier + "." + rarity.toString());
double itemDropRate = config.getDouble("Item_Drop_Rates." + tier + "." + rarity.toString());
if(enchantment_drop_rates != null) {
for (String tier : enchantment_drop_rates.getKeys(false)) {
double totalEnchantDropRate = 0;
double totalItemDropRate = 0;
if ((enchantDropRate < 0.0 || enchantDropRate > 100.0)) {
reason.add("The enchant drop rate for " + tier + " items that are " + rarity.toString() + "should be between 0.0 and 100.0!");
for (Rarity rarity : Rarity.values()) {
double enchantDropRate = config.getDouble("Enchantment_Drop_Rates." + tier + "." + rarity.toString());
double itemDropRate = config.getDouble("Item_Drop_Rates." + tier + "." + rarity);
if ((enchantDropRate < 0.0 || enchantDropRate > 100.0)) {
reason.add("The enchant drop rate for " + tier + " items that are " + rarity + "should be between 0.0 and 100.0!");
}
if (itemDropRate < 0.0 || itemDropRate > 100.0) {
reason.add("The item drop rate for " + tier + " items that are " + rarity + "should be between 0.0 and 100.0!");
}
totalEnchantDropRate += enchantDropRate;
totalItemDropRate += itemDropRate;
}
if (itemDropRate < 0.0 || itemDropRate > 100.0) {
reason.add("The item drop rate for " + tier + " items that are " + rarity.toString() + "should be between 0.0 and 100.0!");
if (totalEnchantDropRate < 0 || totalEnchantDropRate > 100.0) {
reason.add("The total enchant drop rate for " + tier + " should be between 0.0 and 100.0!");
}
totalEnchantDropRate += enchantDropRate;
totalItemDropRate += itemDropRate;
}
if (totalEnchantDropRate < 0 || totalEnchantDropRate > 100.0) {
reason.add("The total enchant drop rate for " + tier + " should be between 0.0 and 100.0!");
}
if (totalItemDropRate < 0 || totalItemDropRate > 100.0) {
reason.add("The total item drop rate for " + tier + " should be between 0.0 and 100.0!");
if (totalItemDropRate < 0 || totalItemDropRate > 100.0) {
reason.add("The total item drop rate for " + tier + " should be between 0.0 and 100.0!");
}
}
} else {
mcMMO.p.getLogger().warning("Your fishing treasures config is empty, is this intentional? Delete it to regenerate.");
}
return noErrorsInConfig(reason);
@ -89,7 +95,7 @@ public class FishingTreasureConfig extends ConfigLoader {
for (EntityType entity : EntityType.values()) {
if (entity.isAlive()) {
loadTreasures("Shake." + entity.toString());
loadTreasures("Shake." + entity);
}
}
}
@ -164,7 +170,7 @@ public class FishingTreasureConfig extends ConfigLoader {
}
if (dropLevel < 0) {
reason.add(treasureName + " has an invalid Drop_Level: " + dropLevel);
reason.add("Fishing Config: " + treasureName + " has an invalid Drop_Level: " + dropLevel);
}
/*
@ -175,7 +181,7 @@ public class FishingTreasureConfig extends ConfigLoader {
if (isFishing) {
String rarityStr = config.getString(type + "." + treasureName + ".Rarity");
if(rarityStr != null) {
if (rarityStr != null) {
rarity = Rarity.getRarity(rarityStr);
} else {
mcMMO.p.getLogger().severe("Please edit your config and add a Rarity definition for - " + treasureName);
@ -192,7 +198,7 @@ public class FishingTreasureConfig extends ConfigLoader {
String customName = null;
if(hasCustomName(type, treasureName)) {
if (hasCustomName(type, treasureName)) {
customName = config.getString(type + "." + treasureName + ".Custom_Name");
}
@ -204,7 +210,7 @@ public class FishingTreasureConfig extends ConfigLoader {
item = new ItemStack(mat, amount, data);
PotionMeta itemMeta = (PotionMeta) item.getItemMeta();
if(itemMeta == null) {
if (itemMeta == null) {
mcMMO.p.getLogger().severe("Item meta when adding potion to fishing treasure was null, contact the mcMMO devs!");
continue;
}
@ -232,7 +238,7 @@ public class FishingTreasureConfig extends ConfigLoader {
}
item.setItemMeta(itemMeta);
}
} else if(material == Material.ENCHANTED_BOOK) {
} else if (material == Material.ENCHANTED_BOOK) {
//If any whitelisted enchants exist we use whitelist-based matching
item = new ItemStack(material, 1);
ItemMeta itemMeta = item.getItemMeta();
@ -276,7 +282,6 @@ public class FishingTreasureConfig extends ConfigLoader {
}
if (noErrorsInConfig(reason)) {
if (isFishing) {
addFishingTreasure(rarity, new FishingTreasure(item, xp));
@ -307,26 +312,27 @@ public class FishingTreasureConfig extends ConfigLoader {
/**
* Matches enchantments on a list (user provided string) to known enchantments in the Spigot API
* Any matches are added to the passed set
*
* @param enchantListStr the users string list of enchantments
* @param permissiveList the permissive list of enchantments
*/
private void matchAndFillSet(@NotNull List<String> enchantListStr, @NotNull Set<Enchantment> permissiveList) {
if(enchantListStr.isEmpty()) {
if (enchantListStr.isEmpty()) {
return;
}
for(String str : enchantListStr) {
for (String str : enchantListStr) {
boolean foundMatch = false;
for(Enchantment enchantment : Enchantment.values()) {
if(enchantment.getKey().getKey().equalsIgnoreCase(str)) {
for (Enchantment enchantment : Enchantment.values()) {
if (enchantment.getKey().getKey().equalsIgnoreCase(str)) {
permissiveList.add(enchantment);
foundMatch = true;
break;
}
}
if(!foundMatch) {
mcMMO.p.getLogger().info("[Fishing Treasure Init] Could not find any enchantments which matched the user defined enchantment named: "+str);
if (!foundMatch) {
mcMMO.p.getLogger().info("[Fishing Treasure Init] Could not find any enchantments which matched the user defined enchantment named: " + str);
}
}
}
@ -344,11 +350,11 @@ public class FishingTreasureConfig extends ConfigLoader {
}
for (String enchantmentName : enchantmentSection.getKeys(false)) {
int level = config.getInt("Enchantments_Rarity." + rarity.toString() + "." + enchantmentName);
int level = config.getInt("Enchantments_Rarity." + rarity + "." + enchantmentName);
Enchantment enchantment = EnchantmentUtils.getByName(enchantmentName);
if (enchantment == null) {
plugin.getLogger().warning("Skipping invalid enchantment in " + FILENAME + ": " + enchantmentName);
mcMMO.p.getLogger().warning("Skipping invalid enchantment in " + FILENAME + ": " + enchantmentName);
continue;
}
@ -374,10 +380,10 @@ public class FishingTreasureConfig extends ConfigLoader {
}
public double getItemDropRate(int tier, @NotNull Rarity rarity) {
return config.getDouble("Item_Drop_Rates.Tier_" + tier + "." + rarity.toString());
return config.getDouble("Item_Drop_Rates.Tier_" + tier + "." + rarity);
}
public double getEnchantmentDropRate(int tier, @NotNull Rarity rarity) {
return config.getDouble("Enchantment_Drop_Rates.Tier_" + tier + "." + rarity.toString());
return config.getDouble("Enchantment_Drop_Rates.Tier_" + tier + "." + rarity);
}
}

View File

@ -1,8 +1,9 @@
package com.gmail.nossr50.config.treasure;
import com.gmail.nossr50.config.ConfigLoader;
import com.gmail.nossr50.config.BukkitConfig;
import com.gmail.nossr50.datatypes.treasure.ExcavationTreasure;
import com.gmail.nossr50.datatypes.treasure.HylianTreasure;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.text.StringUtils;
import org.bukkit.ChatColor;
import org.bukkit.Material;
@ -14,17 +15,24 @@ import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.potion.PotionData;
import org.bukkit.potion.PotionType;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class TreasureConfig extends ConfigLoader {
public class TreasureConfig extends BukkitConfig {
public static final String FILENAME = "treasures.yml";
public static final String LEVEL_REQUIREMENT_RETRO_MODE = ".Level_Requirement.Retro_Mode";
public static final String LEVEL_REQUIREMENT_STANDARD_MODE = ".Level_Requirement.Standard_Mode";
public static final String WRONG_KEY_VALUE_STANDARD = ".Drop_Level.Standard_Mode";
public static final String WRONG_KEY_VALUE_RETRO = ".Drop_Level.Retro_Mode";
public static final String LEGACY_DROP_LEVEL = ".Drop_Level";
public static final String WRONG_KEY_ROOT = ".Drop_Level";
private static TreasureConfig instance;
public HashMap<String, List<ExcavationTreasure>> excavationMap = new HashMap<>();
public HashMap<String, List<HylianTreasure>> hylianMap = new HashMap<>();
public HashMap<String, List<HylianTreasure>> hylianMap = new HashMap<>();
private TreasureConfig() {
super(FILENAME);
@ -60,6 +68,7 @@ public class TreasureConfig extends ConfigLoader {
}
private void loadTreasures(String type) {
boolean shouldWeUpdateFile = false;
boolean isExcavation = type.equals("Excavation");
boolean isHylian = type.equals("Hylian_Luck");
@ -103,7 +112,39 @@ public class TreasureConfig extends ConfigLoader {
int xp = config.getInt(type + "." + treasureName + ".XP");
double dropChance = config.getDouble(type + "." + treasureName + ".Drop_Chance");
int dropLevel = config.getInt(type + "." + treasureName + ".Drop_Level");
DropLevelKeyConversionType conversionType;
//Check for legacy drop level values and convert
if (getWrongKeyValue(type, treasureName, DropLevelKeyConversionType.LEGACY) != -1) {
//Legacy Drop level, needs to be converted
shouldWeUpdateFile = processAutomaticKeyConversion(type, shouldWeUpdateFile, treasureName, DropLevelKeyConversionType.LEGACY);
}
//Check for a bad key that was accidentally shipped out to some users
if (getWrongKeyValue(type, treasureName, DropLevelKeyConversionType.WRONG_KEY_STANDARD) != -1) {
//Partially converted to the new system, I had a dyslexic moment so some configs have this
shouldWeUpdateFile = processAutomaticKeyConversion(type, shouldWeUpdateFile, treasureName, DropLevelKeyConversionType.WRONG_KEY_STANDARD);
}
//Check for a bad key that was accidentally shipped out to some users
if (getWrongKeyValue(type, treasureName, DropLevelKeyConversionType.WRONG_KEY_RETRO) != -1) {
//Partially converted to the new system, I had a dyslexic moment so some configs have this
shouldWeUpdateFile = processAutomaticKeyConversion(type, shouldWeUpdateFile, treasureName, DropLevelKeyConversionType.WRONG_KEY_RETRO);
}
int dropLevel = -1;
if (mcMMO.isRetroModeEnabled()) {
dropLevel = config.getInt(type + "." + treasureName + LEVEL_REQUIREMENT_RETRO_MODE, -1);
} else {
dropLevel = config.getInt(type + "." + treasureName + LEVEL_REQUIREMENT_STANDARD_MODE, -1);
}
if (dropLevel == -1) {
mcMMO.p.getLogger().severe("Could not find a Level_Requirement entry for treasure " + treasureName);
mcMMO.p.getLogger().severe("Skipping treasure");
continue;
}
if (xp < 0) {
reason.add(treasureName + " has an invalid XP value: " + xp);
@ -113,10 +154,6 @@ public class TreasureConfig extends ConfigLoader {
reason.add(treasureName + " has an invalid Drop_Chance: " + dropChance);
}
if (dropLevel < 0) {
reason.add(treasureName + " has an invalid Drop_Level: " + dropLevel);
}
/*
* Itemstack
*/
@ -219,6 +256,62 @@ public class TreasureConfig extends ConfigLoader {
}
}
}
//Apply our fix
if (shouldWeUpdateFile) {
try {
config.save(getFile());
} catch (IOException e) {
e.printStackTrace();
}
}
}
private boolean processAutomaticKeyConversion(String type, boolean shouldWeUpdateTheFile, String treasureName, DropLevelKeyConversionType conversionType) {
switch (conversionType) {
case LEGACY:
int legacyDropLevel = getWrongKeyValue(type, treasureName, conversionType); //Legacy only had one value, Retro Mode didn't have a setting
//Config needs to be updated to be more specific
mcMMO.p.getLogger().info("(" + treasureName + ") [Fixing bad address: Legacy] Converting Drop_Level to Level_Requirement in treasures.yml for treasure to match new expected format");
config.set(type + "." + treasureName + LEGACY_DROP_LEVEL, null); //Remove legacy entry
config.set(type + "." + treasureName + LEVEL_REQUIREMENT_RETRO_MODE, legacyDropLevel * 10); //Multiply by 10 for Retro
config.set(type + "." + treasureName + LEVEL_REQUIREMENT_STANDARD_MODE, legacyDropLevel);
shouldWeUpdateTheFile = true;
break;
case WRONG_KEY_STANDARD:
mcMMO.p.getLogger().info("(" + treasureName + ") [Fixing bad address: STANDARD] Converting Drop_Level to Level_Requirement in treasures.yml for treasure to match new expected format");
int wrongKeyValueStandard = getWrongKeyValue(type, treasureName, conversionType);
config.set(type + "." + treasureName + WRONG_KEY_ROOT, null); //We also kill the Retro key here as we have enough information for setting in values if needed
if (wrongKeyValueStandard != -1) {
config.set(type + "." + treasureName + LEVEL_REQUIREMENT_STANDARD_MODE, wrongKeyValueStandard);
config.set(type + "." + treasureName + LEVEL_REQUIREMENT_RETRO_MODE, wrongKeyValueStandard * 10); //Multiply by 10 for Retro
}
shouldWeUpdateTheFile = true;
break;
case WRONG_KEY_RETRO:
mcMMO.p.getLogger().info("(" + treasureName + ") [Fixing bad address: RETRO] Converting Drop_Level to Level_Requirement in treasures.yml for treasure to match new expected format");
int wrongKeyValueRetro = getWrongKeyValue(type, treasureName, conversionType);
config.set(type + "." + treasureName + WRONG_KEY_ROOT, null); //We also kill the Retro key here as we have enough information for setting in values if needed
if (wrongKeyValueRetro != -1) {
config.set(type + "." + treasureName + LEVEL_REQUIREMENT_RETRO_MODE, wrongKeyValueRetro);
}
shouldWeUpdateTheFile = true;
break;
}
return shouldWeUpdateTheFile;
}
private int getWrongKeyValue(String type, String treasureName, DropLevelKeyConversionType dropLevelKeyConversionType) {
return switch (dropLevelKeyConversionType) {
case LEGACY -> config.getInt(type + "." + treasureName + LEGACY_DROP_LEVEL, -1);
case WRONG_KEY_STANDARD -> config.getInt(type + "." + treasureName + WRONG_KEY_VALUE_STANDARD, -1);
case WRONG_KEY_RETRO -> config.getInt(type + "." + treasureName + WRONG_KEY_VALUE_RETRO, -1);
};
}
private void AddHylianTreasure(String dropper, HylianTreasure treasure) {
@ -226,4 +319,10 @@ public class TreasureConfig extends ConfigLoader {
hylianMap.put(dropper, new ArrayList<>());
hylianMap.get(dropper).add(treasure);
}
private enum DropLevelKeyConversionType {
LEGACY,
WRONG_KEY_STANDARD,
WRONG_KEY_RETRO
}
}

View File

@ -1,11 +1,12 @@
package com.gmail.nossr50.database;
import com.gmail.nossr50.api.exceptions.InvalidSkillException;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.database.DatabaseType;
import com.gmail.nossr50.datatypes.database.PlayerStat;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -14,15 +15,13 @@ import java.util.Map;
import java.util.UUID;
public interface DatabaseManager {
// One month in milliseconds
long PURGE_TIME = 2630000000L * Config.getInstance().getOldUsersCutoff();
// During convertUsers, how often to output a status
int progressInterval = 200;
/**
* Purge users with 0 power level from the database.
*/
void purgePowerlessUsers();
int purgePowerlessUsers();
/**
* Purge users who haven't logged on in over a certain time frame from the database.
@ -77,45 +76,26 @@ public interface DatabaseManager {
/**
* Add a new user to the database.
*
* @param playerName The name of the player to be added to the database
* @param playerName The name of the player to be added to the database
* @param uuid The uuid of the player to be added to the database
* @return
*/
void newUser(String playerName, UUID uuid);
@NotNull PlayerProfile newUser(String playerName, UUID uuid);
@NotNull PlayerProfile newUser(@NotNull Player player);
/**
* Load a player from the database.
*
* @deprecated replaced by {@link #loadPlayerProfile(String playerName, UUID uuid, boolean createNew)}
*
* @param playerName The name of the player to load from the database
* @param createNew Whether to create a new record if the player is not
* found
* @return The player's data, or an unloaded PlayerProfile if not found
* and createNew is false
*/
@Deprecated
PlayerProfile loadPlayerProfile(String playerName, boolean createNew);
@NotNull PlayerProfile loadPlayerProfile(@NotNull String playerName);
/**
* Load a player from the database.
*
* @param uuid The uuid of the player to load from the database
* @return The player's data, or an unloaded PlayerProfile if not found
*/
PlayerProfile loadPlayerProfile(UUID uuid);
@NotNull PlayerProfile loadPlayerProfile(@NotNull OfflinePlayer offlinePlayer);
/**
* Load a player from the database. Attempt to use uuid, fall back on playername
*
* @param playerName The name of the player to load from the database
* @param uuid The uuid of the player to load from the database
* @param createNew Whether to create a new record if the player is not
* found
* @return The player's data, or an unloaded PlayerProfile if not found
* and createNew is false
*/
PlayerProfile loadPlayerProfile(String playerName, UUID uuid, boolean createNew);
@NotNull PlayerProfile loadPlayerProfile(@NotNull UUID uuid);
/**
* Get all users currently stored in the database.

View File

@ -1,13 +1,16 @@
package com.gmail.nossr50.database;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.database.DatabaseType;
import com.gmail.nossr50.mcMMO;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.logging.Logger;
public class DatabaseManagerFactory {
private static Class<? extends DatabaseManager> customManager = null;
public static DatabaseManager getDatabaseManager() {
public static DatabaseManager getDatabaseManager(@NotNull String userFilePath, @NotNull Logger logger, long purgeTime, int startingLevel) {
if (customManager != null) {
try {
return createDefaultCustomDatabaseManager();
@ -20,10 +23,10 @@ public class DatabaseManagerFactory {
mcMMO.p.debug("Failed to create custom database manager");
e.printStackTrace();
}
mcMMO.p.debug("Falling back on " + (Config.getInstance().getUseMySQL() ? "SQL" : "Flatfile") + " database");
mcMMO.p.debug("Falling back on " + (mcMMO.p.getGeneralConfig().getUseMySQL() ? "SQL" : "Flatfile") + " database");
}
return Config.getInstance().getUseMySQL() ? new SQLDatabaseManager() : new FlatfileDatabaseManager();
return mcMMO.p.getGeneralConfig().getUseMySQL() ? new SQLDatabaseManager() : new FlatFileDatabaseManager(userFilePath, logger, purgeTime, startingLevel);
}
/**
@ -56,11 +59,11 @@ public class DatabaseManagerFactory {
return customManager;
}
public static DatabaseManager createDatabaseManager(DatabaseType type) {
public static @Nullable DatabaseManager createDatabaseManager(@NotNull DatabaseType type, @NotNull String userFilePath, @NotNull Logger logger, long purgeTime, int startingLevel) {
switch (type) {
case FLATFILE:
mcMMO.p.getLogger().info("Using FlatFile Database");
return new FlatfileDatabaseManager();
return new FlatFileDatabaseManager(userFilePath, logger, purgeTime, startingLevel);
case SQL:
mcMMO.p.getLogger().info("Using SQL Database");
@ -80,7 +83,7 @@ public class DatabaseManagerFactory {
}
}
public static DatabaseManager createDefaultCustomDatabaseManager() throws Throwable {
private static DatabaseManager createDefaultCustomDatabaseManager() throws Throwable {
return customManager.getConstructor().newInstance();
}

View File

@ -0,0 +1,13 @@
package com.gmail.nossr50.database;
public enum ExpectedType {
STRING,
INTEGER,
LONG,
BOOLEAN,
FLOAT,
DOUBLE,
UUID,
IGNORED,
OUT_OF_RANGE
}

View File

@ -0,0 +1,13 @@
package com.gmail.nossr50.database;
public enum FlatFileDataFlag {
INCOMPLETE,
BAD_VALUES,
LAST_LOGIN_SCHEMA_UPGRADE,
MISSING_NAME,
DUPLICATE_NAME,
DUPLICATE_UUID,
BAD_UUID_DATA, //Can be because it is missing, null, or corrupted or some other reason
TOO_INCOMPLETE,
CORRUPTED_OR_UNRECOGNIZABLE,
}

View File

@ -0,0 +1,345 @@
package com.gmail.nossr50.database;
import com.gmail.nossr50.database.flatfile.FlatFileDataBuilder;
import com.gmail.nossr50.database.flatfile.FlatFileDataContainer;
import com.gmail.nossr50.database.flatfile.FlatFileDataUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.logging.Logger;
import static com.gmail.nossr50.database.FlatFileDatabaseManager.*;
public class FlatFileDataProcessor {
private final @NotNull List<FlatFileDataContainer> flatFileDataContainers;
private final @NotNull List<FlatFileDataFlag> flatFileDataFlags;
private final @NotNull Logger logger;
private final HashSet<String> names;
private final HashSet<UUID> uuids;
private int uniqueProcessingID; //TODO: Not being used, should we use it?
boolean corruptDataFound;
public FlatFileDataProcessor(@NotNull Logger logger) {
this.logger = logger;
flatFileDataContainers = new ArrayList<>();
flatFileDataFlags = new ArrayList<>();
names = new HashSet<>();
uuids = new HashSet<>();
uniqueProcessingID = 0;
}
public void processData(@NotNull String lineData) {
assert !lineData.isEmpty();
//Make sure the data line is "correct"
if(lineData.charAt(lineData.length() - 1) != ':') {
// Length checks depend on last rawSplitData being ':'
// We add it here if it is missing
lineData = lineData.concat(":");
}
//Split the data into an array
String[] splitDataLine = lineData.split(":");
FlatFileDataBuilder builder = new FlatFileDataBuilder(splitDataLine, uniqueProcessingID);
uniqueProcessingID++;
boolean[] badDataValues = new boolean[DATA_ENTRY_COUNT];
boolean anyBadData = false;
//This is the minimum size of the split array needed to be considered proper data
if(splitDataLine.length < getMinimumSplitDataLength()) {
//Data is considered junk
if(!corruptDataFound) {
logger.severe("Some corrupt data was found in mcmmo.users and has been repaired, it is possible that some player data has been lost in this process.");
corruptDataFound = true;
}
//Flag as junk (corrupt)
builder.appendFlag(FlatFileDataFlag.CORRUPTED_OR_UNRECOGNIZABLE);
//TODO: This block here is probably pointless
if(splitDataLine.length >= 10 //The value here is kind of arbitrary, it shouldn't be too low to avoid false positives, but also we aren't really going to correctly identify when player data has been corrupted or not with 100% accuracy ever
&& splitDataLine[0] != null && !splitDataLine[0].isEmpty()) {
if(splitDataLine[0].length() <= 16 && splitDataLine[0].length() >= 3) {
logger.severe("Not enough data found to recover corrupted player data for user: "+splitDataLine[0]);
registerData(builder.appendFlag(FlatFileDataFlag.TOO_INCOMPLETE));
return;
}
}
registerData(builder.appendFlag(FlatFileDataFlag.CORRUPTED_OR_UNRECOGNIZABLE));
return;
}
/*
* Check for duplicate names
*/
boolean invalidUUID = false;
String name = splitDataLine[USERNAME_INDEX];
String strOfUUID = splitDataLine[UUID_INDEX];
if(name.isEmpty()) {
reportBadDataLine("No name found for data", "[MISSING NAME]", lineData);
builder.appendFlag(FlatFileDataFlag.MISSING_NAME);
anyBadData = true;
badDataValues[USERNAME_INDEX] = true;
}
if(strOfUUID.isEmpty() || strOfUUID.equalsIgnoreCase("NULL")) {
invalidUUID = true;
badDataValues[UUID_INDEX] = true;
reportBadDataLine("Empty/null UUID for user", "Empty/null", lineData);
builder.appendFlag(FlatFileDataFlag.BAD_UUID_DATA);
anyBadData = true;
}
UUID uuid = null;
try {
uuid = UUID.fromString(strOfUUID);
} catch (IllegalArgumentException e) {
//UUID does not conform
invalidUUID = true;
badDataValues[UUID_INDEX] = true;
reportBadDataLine("Invalid UUID data found for user", strOfUUID, lineData);
builder.appendFlag(FlatFileDataFlag.BAD_UUID_DATA);
}
//Duplicate UUID is no good, reject them
if(!invalidUUID && uuid != null && uuids.contains(uuid)) {
registerData(builder.appendFlag(FlatFileDataFlag.DUPLICATE_UUID));
return;
}
uuids.add(uuid);
if(names.contains(name)) {
builder.appendFlag(FlatFileDataFlag.DUPLICATE_NAME);
anyBadData = true;
badDataValues[USERNAME_INDEX] = true;
}
if(!name.isEmpty())
names.add(name);
//Make sure the data is up to date schema wise, if it isn't we adjust it to the correct size and flag it for repair
splitDataLine = isDataSchemaUpToDate(splitDataLine, builder, badDataValues);
/*
* After establishing this data has at least an identity we check for bad data
* Bad Value checks
*/
//Check each data for bad values
for(int i = 0; i < DATA_ENTRY_COUNT; i++) {
if(shouldNotBeEmpty(splitDataLine[i], i)) {
if(i == OVERHAUL_LAST_LOGIN) {
builder.appendFlag(FlatFileDataFlag.LAST_LOGIN_SCHEMA_UPGRADE);
}
badDataValues[i] = true;
anyBadData = true;
continue;
}
boolean isCorrectType = isOfExpectedType(splitDataLine[i], getExpectedValueType(i));
if(!isCorrectType) {
anyBadData = true;
badDataValues[i] = true;
}
}
if(anyBadData) {
builder.appendFlag(FlatFileDataFlag.BAD_VALUES);
builder.appendBadDataValues(badDataValues);
}
registerData(builder);
}
public @NotNull String[] isDataSchemaUpToDate(@NotNull String[] splitDataLine, @NotNull FlatFileDataBuilder builder, boolean[] badDataValues) {
assert splitDataLine.length <= DATA_ENTRY_COUNT; //should NEVER be higher
if(splitDataLine.length < DATA_ENTRY_COUNT) {
int oldLength = splitDataLine.length;
splitDataLine = Arrays.copyOf(splitDataLine, DATA_ENTRY_COUNT);
int newLength = splitDataLine.length;
//TODO: Test this
for(int i = oldLength; i < (newLength - 1); i++){
badDataValues[i] = true;
}
builder.appendFlag(FlatFileDataFlag.INCOMPLETE);
builder.setSplitStringData(splitDataLine);
}
return splitDataLine;
}
public boolean shouldNotBeEmpty(@Nullable String data, int index) {
if(getExpectedValueType(index) == ExpectedType.IGNORED) {
return false;
} else {
return data == null || data.isEmpty();
}
}
public boolean isOfExpectedType(@NotNull String data, @NotNull ExpectedType expectedType) {
switch(expectedType) {
case STRING:
return true;
case INTEGER:
try {
Integer.valueOf(data);
return true;
} catch (Exception e) {
return false;
}
case BOOLEAN:
return data.equalsIgnoreCase("true") || data.equalsIgnoreCase("false");
case FLOAT:
try {
Float.valueOf(data);
return true;
} catch (NumberFormatException e) {
return false;
}
case DOUBLE:
try {
Double.valueOf(data);
return true;
} catch (NumberFormatException e) {
return false;
}
case UUID:
try {
UUID.fromString(data);
return true;
} catch (IllegalArgumentException e) {
return false;
}
case OUT_OF_RANGE:
throw new ArrayIndexOutOfBoundsException("Value matched type OUT_OF_RANGE, this should never happen.");
case IGNORED:
default:
return true;
}
}
private void reportBadDataLine(String warning, String context, String dataLine) {
logger.warning("FlatFileDatabaseBuilder Warning: " + warning + " - " + context);
logger.warning("FlatFileDatabaseBuilder: (Line Data) - " + dataLine);
logger.warning("mcMMO will repair this data if automatically (if it is possible).");
}
private int getMinimumSplitDataLength() {
return UUID_INDEX + 1;
}
private void registerData(@NotNull FlatFileDataBuilder builder) {
FlatFileDataContainer flatFileDataContainer = builder.build();
flatFileDataContainers.add(flatFileDataContainer);
if(flatFileDataContainer.getDataFlags() != null)
flatFileDataFlags.addAll(flatFileDataContainer.getDataFlags());
}
public static @NotNull ExpectedType getExpectedValueType(int dataIndex) throws IndexOutOfBoundsException {
switch(dataIndex) {
case USERNAME_INDEX:
return ExpectedType.STRING;
case 2: //Assumption: Used to be for something, no longer used
case 3: //Assumption: Used to be for something, no longer used
case 23: //Assumption: Used to be used for something, no longer used
case 33: //Assumption: Used to be used for something, no longer used
case HEALTHBAR:
case LEGACY_LAST_LOGIN:
return ExpectedType.IGNORED;
case SKILLS_MINING:
case SKILLS_REPAIR:
case SKILLS_UNARMED:
case SKILLS_HERBALISM:
case SKILLS_EXCAVATION:
case SKILLS_ARCHERY:
case SKILLS_SWORDS:
case SKILLS_AXES:
case SKILLS_WOODCUTTING:
case SKILLS_ACROBATICS:
case SKILLS_TAMING:
case SKILLS_FISHING:
case SKILLS_ALCHEMY:
case COOLDOWN_BERSERK:
case COOLDOWN_GIGA_DRILL_BREAKER:
case COOLDOWN_TREE_FELLER:
case COOLDOWN_GREEN_TERRA:
case COOLDOWN_SERRATED_STRIKES:
case COOLDOWN_SKULL_SPLITTER:
case COOLDOWN_SUPER_BREAKER:
case COOLDOWN_BLAST_MINING:
case SCOREBOARD_TIPS:
case COOLDOWN_CHIMAERA_WING:
return ExpectedType.INTEGER;
case EXP_MINING:
case EXP_WOODCUTTING:
case EXP_REPAIR:
case EXP_UNARMED:
case EXP_HERBALISM:
case EXP_EXCAVATION:
case EXP_ARCHERY:
case EXP_SWORDS:
case EXP_AXES:
case EXP_ACROBATICS:
case EXP_TAMING:
case EXP_FISHING:
case EXP_ALCHEMY:
return ExpectedType.FLOAT;
case UUID_INDEX:
return ExpectedType.UUID;
case OVERHAUL_LAST_LOGIN:
return ExpectedType.LONG;
}
throw new IndexOutOfBoundsException();
}
public @NotNull List<FlatFileDataContainer> getFlatFileDataContainers() {
return flatFileDataContainers;
}
public @NotNull List<FlatFileDataFlag> getFlatFileDataFlags() {
return flatFileDataFlags;
}
public int getDataFlagCount() {
return flatFileDataFlags.size();
}
public @NotNull StringBuilder processDataForSave() {
StringBuilder stringBuilder = new StringBuilder();
//Fix our data if needed and prepare it to be saved
for(FlatFileDataContainer dataContainer : flatFileDataContainers) {
String[] splitData = FlatFileDataUtil.getPreparedSaveDataLine(dataContainer);
if(splitData == null)
continue;
//We add a trailing : as it is needed for some reason (is it?)
//TODO: Is the trailing ":" actually necessary?
String fromSplit = org.apache.commons.lang.StringUtils.join(splitData, ":") + ":";
stringBuilder.append(fromSplit).append("\r\n");
}
return stringBuilder;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,6 @@
package com.gmail.nossr50.database;
import com.gmail.nossr50.api.exceptions.InvalidSkillException;
import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.MobHealthbarType;
import com.gmail.nossr50.datatypes.database.DatabaseType;
import com.gmail.nossr50.datatypes.database.PlayerStat;
@ -14,8 +12,11 @@ import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.runnables.database.UUIDUpdateAsyncTask;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.skills.SkillTools;
import org.apache.tomcat.jdbc.pool.DataSource;
import org.apache.tomcat.jdbc.pool.PoolProperties;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -26,7 +27,12 @@ import java.util.concurrent.locks.ReentrantLock;
public final class SQLDatabaseManager implements DatabaseManager {
private static final String ALL_QUERY_VERSION = "total";
private final String tablePrefix = Config.getInstance().getMySQLTablePrefix();
public static final String MOBHEALTHBAR_VARCHAR = "VARCHAR(50)";
public static final String UUID_VARCHAR = "VARCHAR(36)";
public static final String USER_VARCHAR = "VARCHAR(40)";
public static final int CHILD_SKILLS_SIZE = 2;
public static final String LEGACY_DRIVER_PATH = "com.mysql.jdbc.Driver";
private final String tablePrefix = mcMMO.p.getGeneralConfig().getMySQLTablePrefix();
private final Map<UUID, Integer> cachedUserIDs = new HashMap<>();
@ -38,11 +44,15 @@ public final class SQLDatabaseManager implements DatabaseManager {
private final ReentrantLock massUpdateLock = new ReentrantLock();
protected SQLDatabaseManager() {
String connectionString = "jdbc:mysql://" + Config.getInstance().getMySQLServerName()
+ ":" + Config.getInstance().getMySQLServerPort() + "/" + Config.getInstance().getMySQLDatabaseName();
private final String CHARSET_SQL = "utf8mb4"; //This is compliant with UTF-8 while "utf8" is not, confusing but this is how it is.
private String driverPath = "com.mysql.cj.jdbc.Driver"; //modern driver
if(Config.getInstance().getMySQLSSL())
protected SQLDatabaseManager() {
String connectionString = "jdbc:mysql://" + mcMMO.p.getGeneralConfig().getMySQLServerName()
+ ":" + mcMMO.p.getGeneralConfig().getMySQLServerPort() + "/" + mcMMO.p.getGeneralConfig().getMySQLDatabaseName();
if(!mcMMO.getCompatibilityManager().getMinecraftGameVersion().isAtLeast(1, 17, 0) //Temporary hack for SQL and 1.17 support
&& mcMMO.p.getGeneralConfig().getMySQLSSL())
connectionString +=
"?verifyServerCertificate=false"+
"&useSSL=true"+
@ -51,26 +61,36 @@ public final class SQLDatabaseManager implements DatabaseManager {
connectionString+=
"?useSSL=false";
if(mcMMO.p.getGeneralConfig().getMySQLPublicKeyRetrieval()) {
connectionString+=
"&allowPublicKeyRetrieval=true";
}
try {
// Force driver to load if not yet loaded
Class.forName("com.mysql.jdbc.Driver");
}
catch (ClassNotFoundException e) {
e.printStackTrace();
return;
Class.forName(driverPath);
} catch (ClassNotFoundException e) {
try {
driverPath = LEGACY_DRIVER_PATH; //fall on deprecated path if new path isn't found
Class.forName(driverPath);
} catch (ClassNotFoundException ex) {
e.printStackTrace();
ex.printStackTrace();
mcMMO.p.getLogger().severe("Neither driver found");
return;
}
//throw e; // aborts onEnable() Riking if you want to do this, fully implement it.
}
debug = Config.getInstance().getMySQLDebug();
debug = mcMMO.p.getGeneralConfig().getMySQLDebug();
PoolProperties poolProperties = new PoolProperties();
poolProperties.setDriverClassName("com.mysql.jdbc.Driver");
poolProperties.setDriverClassName(driverPath);
poolProperties.setUrl(connectionString);
poolProperties.setUsername(Config.getInstance().getMySQLUserName());
poolProperties.setPassword(Config.getInstance().getMySQLUserPassword());
poolProperties.setMaxIdle(Config.getInstance().getMySQLMaxPoolSize(PoolIdentifier.MISC));
poolProperties.setMaxActive(Config.getInstance().getMySQLMaxConnections(PoolIdentifier.MISC));
poolProperties.setUsername(mcMMO.p.getGeneralConfig().getMySQLUserName());
poolProperties.setPassword(mcMMO.p.getGeneralConfig().getMySQLUserPassword());
poolProperties.setMaxIdle(mcMMO.p.getGeneralConfig().getMySQLMaxPoolSize(PoolIdentifier.MISC));
poolProperties.setMaxActive(mcMMO.p.getGeneralConfig().getMySQLMaxConnections(PoolIdentifier.MISC));
poolProperties.setInitialSize(0);
poolProperties.setMaxWait(-1);
poolProperties.setRemoveAbandoned(true);
@ -80,13 +100,13 @@ public final class SQLDatabaseManager implements DatabaseManager {
poolProperties.setValidationInterval(30000);
miscPool = new DataSource(poolProperties);
poolProperties = new PoolProperties();
poolProperties.setDriverClassName("com.mysql.jdbc.Driver");
poolProperties.setDriverClassName(driverPath);
poolProperties.setUrl(connectionString);
poolProperties.setUsername(Config.getInstance().getMySQLUserName());
poolProperties.setPassword(Config.getInstance().getMySQLUserPassword());
poolProperties.setUsername(mcMMO.p.getGeneralConfig().getMySQLUserName());
poolProperties.setPassword(mcMMO.p.getGeneralConfig().getMySQLUserPassword());
poolProperties.setInitialSize(0);
poolProperties.setMaxIdle(Config.getInstance().getMySQLMaxPoolSize(PoolIdentifier.SAVE));
poolProperties.setMaxActive(Config.getInstance().getMySQLMaxConnections(PoolIdentifier.SAVE));
poolProperties.setMaxIdle(mcMMO.p.getGeneralConfig().getMySQLMaxPoolSize(PoolIdentifier.SAVE));
poolProperties.setMaxActive(mcMMO.p.getGeneralConfig().getMySQLMaxConnections(PoolIdentifier.SAVE));
poolProperties.setMaxWait(-1);
poolProperties.setRemoveAbandoned(true);
poolProperties.setRemoveAbandonedTimeout(60);
@ -95,13 +115,13 @@ public final class SQLDatabaseManager implements DatabaseManager {
poolProperties.setValidationInterval(30000);
savePool = new DataSource(poolProperties);
poolProperties = new PoolProperties();
poolProperties.setDriverClassName("com.mysql.jdbc.Driver");
poolProperties.setDriverClassName(driverPath);
poolProperties.setUrl(connectionString);
poolProperties.setUsername(Config.getInstance().getMySQLUserName());
poolProperties.setPassword(Config.getInstance().getMySQLUserPassword());
poolProperties.setUsername(mcMMO.p.getGeneralConfig().getMySQLUserName());
poolProperties.setPassword(mcMMO.p.getGeneralConfig().getMySQLUserPassword());
poolProperties.setInitialSize(0);
poolProperties.setMaxIdle(Config.getInstance().getMySQLMaxPoolSize(PoolIdentifier.LOAD));
poolProperties.setMaxActive(Config.getInstance().getMySQLMaxConnections(PoolIdentifier.LOAD));
poolProperties.setMaxIdle(mcMMO.p.getGeneralConfig().getMySQLMaxPoolSize(PoolIdentifier.LOAD));
poolProperties.setMaxActive(mcMMO.p.getGeneralConfig().getMySQLMaxConnections(PoolIdentifier.LOAD));
poolProperties.setMaxWait(-1);
poolProperties.setRemoveAbandoned(true);
poolProperties.setRemoveAbandonedTimeout(60);
@ -113,7 +133,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
checkStructure();
}
public void purgePowerlessUsers() {
public int purgePowerlessUsers() {
massUpdateLock.lock();
mcMMO.p.getLogger().info("Purging powerless users...");
@ -146,11 +166,12 @@ public final class SQLDatabaseManager implements DatabaseManager {
}
mcMMO.p.getLogger().info("Purged " + purged + " users from the database.");
return purged;
}
public void purgeOldUsers() {
massUpdateLock.lock();
mcMMO.p.getLogger().info("Purging inactive users older than " + (PURGE_TIME / 2630000000L) + " months...");
mcMMO.p.getLogger().info("Purging inactive users older than " + (mcMMO.p.getPurgeTime() / 2630000000L) + " months...");
Connection connection = null;
Statement statement = null;
@ -165,12 +186,11 @@ public final class SQLDatabaseManager implements DatabaseManager {
"JOIN " + tablePrefix + "huds h ON (u.id = h.user_id) " +
"JOIN " + tablePrefix + "skills s ON (u.id = s.user_id) " +
"JOIN " + tablePrefix + "cooldowns c ON (u.id = c.user_id) " +
"WHERE ((UNIX_TIMESTAMP() - lastlogin) > " + PURGE_TIME + ")");
"WHERE ((UNIX_TIMESTAMP() - lastlogin) > " + mcMMO.p.getPurgeTime() + ")");
}
catch (SQLException ex) {
printErrors(ex);
}
finally {
} finally {
tryClose(statement);
tryClose(connection);
massUpdateLock.unlock();
@ -266,7 +286,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
statement.setInt(12, profile.getSkillLevel(PrimarySkillType.FISHING));
statement.setInt(13, profile.getSkillLevel(PrimarySkillType.ALCHEMY));
int total = 0;
for (PrimarySkillType primarySkillType : PrimarySkillType.NON_CHILD_SKILLS)
for (PrimarySkillType primarySkillType : SkillTools.NON_CHILD_SKILLS)
total += profile.getSkillLevel(primarySkillType);
statement.setInt(14, total);
statement.setInt(15, id);
@ -325,7 +345,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
}
statement = connection.prepareStatement("UPDATE " + tablePrefix + "huds SET mobhealthbar = ?, scoreboardtips = ? WHERE user_id = ?");
statement.setString(1, profile.getMobHealthbarType() == null ? Config.getInstance().getMobHealthbarDefault().name() : profile.getMobHealthbarType().name());
statement.setString(1, MobHealthbarType.HEARTS.name());
statement.setInt(2, profile.getScoreboardTipsShown());
statement.setInt(3, id);
success = (statement.executeUpdate() != 0);
@ -350,7 +370,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
List<PlayerStat> stats = new ArrayList<>();
//Fix for a plugin that people are using that is throwing SQL errors
if(skill != null && skill.isChildSkill()) {
if(skill != null && SkillTools.isChildSkill(skill)) {
mcMMO.p.getLogger().severe("A plugin hooking into mcMMO is being naughty with our database commands, update all plugins that hook into mcMMO and contact their devs!");
throw new InvalidSkillException("A plugin hooking into mcMMO that you are using is attempting to read leaderboard skills for child skills, child skills do not have leaderboards! This is NOT an mcMMO error!");
}
@ -399,7 +419,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
try {
connection = getConnection(PoolIdentifier.MISC);
for (PrimarySkillType primarySkillType : PrimarySkillType.NON_CHILD_SKILLS) {
for (PrimarySkillType primarySkillType : SkillTools.NON_CHILD_SKILLS) {
String skillName = primarySkillType.name().toLowerCase(Locale.ENGLISH);
// Get count of all users with higher skill level than player
String sql = "SELECT COUNT(*) AS 'rank' FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE " + skillName + " > 0 " +
@ -486,19 +506,37 @@ public final class SQLDatabaseManager implements DatabaseManager {
return skills;
}
public void newUser(String playerName, UUID uuid) {
public @NotNull PlayerProfile newUser(String playerName, UUID uuid) {
Connection connection = null;
try {
connection = getConnection(PoolIdentifier.MISC);
newUser(connection, playerName, uuid);
}
catch (SQLException ex) {
} catch (SQLException ex) {
printErrors(ex);
}
finally {
} finally {
tryClose(connection);
}
return new PlayerProfile(playerName, uuid, true, mcMMO.p.getAdvancedConfig().getStartingLevel());
}
@Override
public @NotNull PlayerProfile newUser(@NotNull Player player) {
try {
Connection connection = getConnection(PoolIdentifier.SAVE);
int id = newUser(connection, player.getName(), player.getUniqueId());
if (id == -1) {
return new PlayerProfile(player.getName(), player.getUniqueId(), false, mcMMO.p.getAdvancedConfig().getStartingLevel());
} else {
return loadPlayerProfile(player);
}
} catch (SQLException e) {
e.printStackTrace();
}
return new PlayerProfile(player.getName(), player.getUniqueId(), false, mcMMO.p.getAdvancedConfig().getStartingLevel());
}
private int newUser(Connection connection, String playerName, UUID uuid) {
@ -539,20 +577,35 @@ public final class SQLDatabaseManager implements DatabaseManager {
return -1;
}
@Deprecated
public PlayerProfile loadPlayerProfile(String playerName, boolean create) {
return loadPlayerProfile(playerName, null, false, true);
public @NotNull PlayerProfile loadPlayerProfile(@NotNull String playerName) {
try {
return loadPlayerFromDB(null, playerName);
} catch (RuntimeException e) {
e.printStackTrace();
return new PlayerProfile(playerName, false, mcMMO.p.getAdvancedConfig().getStartingLevel());
}
}
public PlayerProfile loadPlayerProfile(UUID uuid) {
return loadPlayerProfile("", uuid, false, true);
@Override
public @NotNull PlayerProfile loadPlayerProfile(@NotNull OfflinePlayer offlinePlayer) {
return loadPlayerFromDB(offlinePlayer.getUniqueId(), offlinePlayer.getName());
}
public PlayerProfile loadPlayerProfile(String playerName, UUID uuid, boolean create) {
return loadPlayerProfile(playerName, uuid, create, true);
public @NotNull PlayerProfile loadPlayerProfile(@NotNull UUID uuid, @Nullable String playerName) {
return loadPlayerFromDB(uuid, playerName);
}
private PlayerProfile loadPlayerProfile(String playerName, UUID uuid, boolean create, boolean retry) {
@Override
public @NotNull PlayerProfile loadPlayerProfile(@NotNull UUID uuid) {
return loadPlayerFromDB(uuid, null);
}
private PlayerProfile loadPlayerFromDB(@Nullable UUID uuid, @Nullable String playerName) throws RuntimeException {
if(uuid == null && playerName == null) {
throw new RuntimeException("Error looking up player, both UUID and playerName are null and one must not be.");
}
PreparedStatement statement = null;
Connection connection = null;
ResultSet resultSet = null;
@ -562,16 +615,8 @@ public final class SQLDatabaseManager implements DatabaseManager {
int id = getUserID(connection, playerName, uuid);
if (id == -1) {
// There is no such user
if (create) {
id = newUser(connection, playerName, uuid);
create = false;
if (id == -1) {
return new PlayerProfile(playerName, false);
}
} else {
return new PlayerProfile(playerName, false);
}
// There is no such user
return new PlayerProfile(playerName, mcMMO.p.getAdvancedConfig().getStartingLevel());
}
// There is such a user
writeMissingRows(connection, id);
@ -599,7 +644,10 @@ public final class SQLDatabaseManager implements DatabaseManager {
resultSet.close();
statement.close();
if (!playerName.isEmpty() && !playerName.equalsIgnoreCase(name) && uuid != null) {
if (playerName != null
&& !playerName.isEmpty()
&& !playerName.equalsIgnoreCase(name)
&& uuid != null) {
statement = connection.prepareStatement(
"UPDATE `" + tablePrefix + "users` "
+ "SET user = ? "
@ -636,15 +684,8 @@ public final class SQLDatabaseManager implements DatabaseManager {
tryClose(connection);
}
// Problem, nothing was returned
// return unloaded profile
if (!retry) {
return new PlayerProfile(playerName, false);
}
// Retry, and abort on re-failure
return loadPlayerProfile(playerName, uuid, create, false);
//Return empty profile
return new PlayerProfile(playerName, mcMMO.p.getAdvancedConfig().getStartingLevel());
}
public void convertUsers(DatabaseManager destination) {
@ -802,7 +843,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
statement = connection.prepareStatement("SELECT table_name FROM INFORMATION_SCHEMA.TABLES"
+ " WHERE table_schema = ?"
+ " AND table_name = ?");
statement.setString(1, Config.getInstance().getMySQLDatabaseName());
statement.setString(1, mcMMO.p.getGeneralConfig().getMySQLDatabaseName());
statement.setString(2, tablePrefix + "users");
resultSet = statement.executeQuery();
if (!resultSet.next()) {
@ -814,25 +855,25 @@ public final class SQLDatabaseManager implements DatabaseManager {
+ "`lastlogin` int(32) unsigned NOT NULL,"
+ "PRIMARY KEY (`id`),"
+ "INDEX(`user`(20) ASC),"
+ "UNIQUE KEY `uuid` (`uuid`)) DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;");
+ "UNIQUE KEY `uuid` (`uuid`)) DEFAULT CHARSET=" + CHARSET_SQL + " AUTO_INCREMENT=1;");
tryClose(createStatement);
}
tryClose(resultSet);
statement.setString(1, Config.getInstance().getMySQLDatabaseName());
statement.setString(1, mcMMO.p.getGeneralConfig().getMySQLDatabaseName());
statement.setString(2, tablePrefix + "huds");
resultSet = statement.executeQuery();
if (!resultSet.next()) {
createStatement = connection.createStatement();
createStatement.executeUpdate("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "huds` ("
+ "`user_id` int(10) unsigned NOT NULL,"
+ "`mobhealthbar` varchar(50) NOT NULL DEFAULT '" + Config.getInstance().getMobHealthbarDefault() + "',"
+ "`mobhealthbar` varchar(50) NOT NULL DEFAULT '" + mcMMO.p.getGeneralConfig().getMobHealthbarDefault() + "',"
+ "`scoreboardtips` int(10) NOT NULL DEFAULT '0',"
+ "PRIMARY KEY (`user_id`)) "
+ "DEFAULT CHARSET=latin1;");
+ "DEFAULT CHARSET=" + CHARSET_SQL + ";");
tryClose(createStatement);
}
tryClose(resultSet);
statement.setString(1, Config.getInstance().getMySQLDatabaseName());
statement.setString(1, mcMMO.p.getGeneralConfig().getMySQLDatabaseName());
statement.setString(2, tablePrefix + "cooldowns");
resultSet = statement.executeQuery();
if (!resultSet.next()) {
@ -853,16 +894,16 @@ public final class SQLDatabaseManager implements DatabaseManager {
+ "`blast_mining` int(32) unsigned NOT NULL DEFAULT '0',"
+ "`chimaera_wing` int(32) unsigned NOT NULL DEFAULT '0',"
+ "PRIMARY KEY (`user_id`)) "
+ "DEFAULT CHARSET=latin1;");
+ "DEFAULT CHARSET=" + CHARSET_SQL + ";");
tryClose(createStatement);
}
tryClose(resultSet);
statement.setString(1, Config.getInstance().getMySQLDatabaseName());
statement.setString(1, mcMMO.p.getGeneralConfig().getMySQLDatabaseName());
statement.setString(2, tablePrefix + "skills");
resultSet = statement.executeQuery();
if (!resultSet.next()) {
String startingLevel = "'" + AdvancedConfig.getInstance().getStartingLevel() + "'";
String totalLevel = "'" + (AdvancedConfig.getInstance().getStartingLevel() * (PrimarySkillType.values().length - PrimarySkillType.CHILD_SKILLS.size())) + "'";
String startingLevel = "'" + mcMMO.p.getAdvancedConfig().getStartingLevel() + "'";
String totalLevel = "'" + (mcMMO.p.getAdvancedConfig().getStartingLevel() * (PrimarySkillType.values().length - CHILD_SKILLS_SIZE)) + "'";
createStatement = connection.createStatement();
createStatement.executeUpdate("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "skills` ("
+ "`user_id` int(10) unsigned NOT NULL,"
@ -881,11 +922,11 @@ public final class SQLDatabaseManager implements DatabaseManager {
+ "`alchemy` int(10) unsigned NOT NULL DEFAULT "+startingLevel+","
+ "`total` int(10) unsigned NOT NULL DEFAULT "+totalLevel+","
+ "PRIMARY KEY (`user_id`)) "
+ "DEFAULT CHARSET=latin1;");
+ "DEFAULT CHARSET=" + CHARSET_SQL + ";");
tryClose(createStatement);
}
tryClose(resultSet);
statement.setString(1, Config.getInstance().getMySQLDatabaseName());
statement.setString(1, mcMMO.p.getGeneralConfig().getMySQLDatabaseName());
statement.setString(2, tablePrefix + "experience");
resultSet = statement.executeQuery();
if (!resultSet.next()) {
@ -906,7 +947,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
+ "`fishing` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`alchemy` int(10) unsigned NOT NULL DEFAULT '0',"
+ "PRIMARY KEY (`user_id`)) "
+ "DEFAULT CHARSET=latin1;");
+ "DEFAULT CHARSET=" + CHARSET_SQL + ";");
tryClose(createStatement);
}
tryClose(resultSet);
@ -916,9 +957,9 @@ public final class SQLDatabaseManager implements DatabaseManager {
checkDatabaseStructure(connection, updateType);
}
if (Config.getInstance().getTruncateSkills()) {
for (PrimarySkillType skill : PrimarySkillType.NON_CHILD_SKILLS) {
int cap = Config.getInstance().getLevelCap(skill);
if (mcMMO.p.getGeneralConfig().getTruncateSkills()) {
for (PrimarySkillType skill : SkillTools.NON_CHILD_SKILLS) {
int cap = mcMMO.p.getSkillTools().getLevelCap(skill);
if (cap != Integer.MAX_VALUE) {
statement = connection.prepareStatement("UPDATE `" + tablePrefix + "skills` SET `" + skill.name().toLowerCase(Locale.ENGLISH) + "` = " + cap + " WHERE `" + skill.name().toLowerCase(Locale.ENGLISH) + "` > " + cap);
statement.executeUpdate();
@ -991,7 +1032,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
break;
case ADD_SQL_INDEXES:
checkUpgradeAddSQLIndexes(statement);
// checkUpgradeAddSQLIndexes(statement);
break;
case ADD_MOB_HEALTHBARS:
@ -1029,12 +1070,14 @@ public final class SQLDatabaseManager implements DatabaseManager {
checkUpgradeAddUniqueChimaeraWing(statement);
break;
case SQL_CHARSET_UTF8MB4:
updateCharacterSet(statement);
break;
default:
break;
}
mcMMO.getUpgradeManager().setUpgradeCompleted(upgrade);
}
catch (SQLException ex) {
printErrors(ex);
@ -1065,7 +1108,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
statement = connection.prepareStatement("INSERT IGNORE INTO " + tablePrefix + "huds (user_id, mobhealthbar, scoreboardtips) VALUES (?, ?, ?)");
statement.setInt(1, id);
statement.setString(2, Config.getInstance().getMobHealthbarDefault().name());
statement.setString(2, mcMMO.p.getGeneralConfig().getMobHealthbarDefault().name());
statement.setInt(3, 0);
statement.execute();
statement.close();
@ -1135,14 +1178,6 @@ public final class SQLDatabaseManager implements DatabaseManager {
skillsDATS.put(SuperAbilityType.BLAST_MINING, result.getInt(OFFSET_DATS + 12));
uniqueData.put(UniqueDataType.CHIMAERA_WING_DATS, result.getInt(OFFSET_DATS + 13));
try {
mobHealthbarType = MobHealthbarType.valueOf(result.getString(OFFSET_OTHER + 1));
}
catch (Exception e) {
mobHealthbarType = Config.getInstance().getMobHealthbarDefault();
}
try {
scoreboardTipsShown = result.getInt(OFFSET_OTHER + 2);
}
@ -1157,7 +1192,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
uuid = null;
}
return new PlayerProfile(playerName, uuid, skills, skillsXp, skillsDATS, mobHealthbarType, scoreboardTipsShown, uniqueData);
return new PlayerProfile(playerName, uuid, skills, skillsXp, skillsDATS, scoreboardTipsShown, uniqueData, null);
}
private void printErrors(SQLException ex) {
@ -1191,6 +1226,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
statement.execute("ALTER TABLE `" + tablePrefix + "users` "
+ "DROP INDEX `user`,"
+ "ADD INDEX `user` (`user`(20) ASC)");
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.DROP_NAME_UNIQUENESS);
} catch (SQLException ex) {
ex.printStackTrace();
} finally {
@ -1201,6 +1237,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
private void checkUpgradeAddAlchemy(final Statement statement) throws SQLException {
try {
statement.executeQuery("SELECT `alchemy` FROM `" + tablePrefix + "skills` LIMIT 1");
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_ALCHEMY);
}
catch (SQLException ex) {
mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for Alchemy...");
@ -1212,6 +1249,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
private void checkUpgradeAddBlastMiningCooldown(final Statement statement) throws SQLException {
try {
statement.executeQuery("SELECT `blast_mining` FROM `" + tablePrefix + "cooldowns` LIMIT 1");
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_BLAST_MINING_COOLDOWN);
}
catch (SQLException ex) {
mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for Blast Mining...");
@ -1222,6 +1260,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
private void checkUpgradeAddUniqueChimaeraWing(final Statement statement) throws SQLException {
try {
statement.executeQuery("SELECT `chimaera_wing` FROM `" + tablePrefix + "cooldowns` LIMIT 1");
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_UNIQUE_PLAYER_DATA);
}
catch (SQLException ex) {
mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for Chimaera Wing...");
@ -1232,6 +1271,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
private void checkUpgradeAddFishing(final Statement statement) throws SQLException {
try {
statement.executeQuery("SELECT `fishing` FROM `" + tablePrefix + "skills` LIMIT 1");
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_FISHING);
}
catch (SQLException ex) {
mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for Fishing...");
@ -1243,16 +1283,18 @@ public final class SQLDatabaseManager implements DatabaseManager {
private void checkUpgradeAddMobHealthbars(final Statement statement) throws SQLException {
try {
statement.executeQuery("SELECT `mobhealthbar` FROM `" + tablePrefix + "huds` LIMIT 1");
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_MOB_HEALTHBARS);
}
catch (SQLException ex) {
mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for mob healthbars...");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "huds` ADD `mobhealthbar` varchar(50) NOT NULL DEFAULT '" + Config.getInstance().getMobHealthbarDefault() + "'");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "huds` ADD `mobhealthbar` varchar(50) NOT NULL DEFAULT '" + mcMMO.p.getGeneralConfig().getMobHealthbarDefault() + "'");
}
}
private void checkUpgradeAddScoreboardTips(final Statement statement) throws SQLException {
try {
statement.executeQuery("SELECT `scoreboardtips` FROM `" + tablePrefix + "huds` LIMIT 1");
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_SCOREBOARD_TIPS);
}
catch (SQLException ex) {
mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for scoreboard tips...");
@ -1267,10 +1309,10 @@ public final class SQLDatabaseManager implements DatabaseManager {
resultSet = statement.executeQuery("SHOW INDEX FROM `" + tablePrefix + "skills` WHERE `Key_name` LIKE 'idx\\_%'");
resultSet.last();
if (resultSet.getRow() != PrimarySkillType.NON_CHILD_SKILLS.size()) {
if (resultSet.getRow() != SkillTools.NON_CHILD_SKILLS.size()) {
mcMMO.p.getLogger().info("Indexing tables, this may take a while on larger databases");
for (PrimarySkillType skill : PrimarySkillType.NON_CHILD_SKILLS) {
for (PrimarySkillType skill : SkillTools.NON_CHILD_SKILLS) {
String skill_name = skill.name().toLowerCase(Locale.ENGLISH);
try {
@ -1281,6 +1323,8 @@ public final class SQLDatabaseManager implements DatabaseManager {
}
}
}
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_SQL_INDEXES);
}
catch (SQLException ex) {
printErrors(ex);
@ -1310,7 +1354,11 @@ public final class SQLDatabaseManager implements DatabaseManager {
mcMMO.p.getLogger().info("Adding UUIDs to mcMMO MySQL user table...");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "users` ADD `uuid` varchar(36) NULL DEFAULT NULL");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "users` ADD UNIQUE INDEX `uuid` (`uuid`) USING BTREE");
new GetUUIDUpdatesRequired().runTaskLaterAsynchronously(mcMMO.p, 100); // wait until after first purge
}
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_UUIDS);
}
catch (SQLException ex) {
printErrors(ex);
@ -1318,8 +1366,6 @@ public final class SQLDatabaseManager implements DatabaseManager {
finally {
tryClose(resultSet);
}
new GetUUIDUpdatesRequired().runTaskLaterAsynchronously(mcMMO.p, 100); // wait until after first purge
}
private class GetUUIDUpdatesRequired extends BukkitRunnable {
@ -1377,6 +1423,8 @@ public final class SQLDatabaseManager implements DatabaseManager {
mcMMO.p.getLogger().info("Removing party name from users table...");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "users` DROP COLUMN `party`");
}
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.DROP_SQL_PARTY_NAMES);
}
catch (SQLException ex) {
printErrors(ex);
@ -1412,6 +1460,8 @@ public final class SQLDatabaseManager implements DatabaseManager {
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "skills` ADD INDEX `idx_total` (`total`) USING BTREE");
connection.commit();
}
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_SKILL_TOTAL);
}
catch (SQLException ex) {
printErrors(ex);
@ -1443,6 +1493,8 @@ public final class SQLDatabaseManager implements DatabaseManager {
mcMMO.p.getLogger().info("Removing Spout HUD type from huds table...");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "huds` DROP COLUMN `hudtype`");
}
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.DROP_SPOUT);
}
catch (SQLException ex) {
printErrors(ex);
@ -1544,7 +1596,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
try {
connection = getConnection(PoolIdentifier.MISC);
statement = connection.prepareStatement("UPDATE " + tablePrefix + "huds SET mobhealthbar = ?");
statement.setString(1, Config.getInstance().getMobHealthbarDefault().toString());
statement.setString(1, mcMMO.p.getGeneralConfig().getMobHealthbarDefault().toString());
statement.executeUpdate();
}
catch (SQLException ex) {
@ -1555,4 +1607,67 @@ public final class SQLDatabaseManager implements DatabaseManager {
tryClose(connection);
}
}
private void updateCharacterSet(@NotNull Statement statement) {
//TODO: Could check the tables for being latin1 before executing queries but it seems moot because it is likely the same computational effort
/*
The following columns were set to use latin1 historically (now utf8mb4)
column user in <tablePrefix>users
column uuid in <tablePrefix>users
column mobhealthbar in <tablePrefix>huds
*/
//Alter users table
mcMMO.p.getLogger().info("SQL Converting tables from latin1 to utf8mb4");
//Update "user" column
try {
mcMMO.p.getLogger().info("Updating user column to new encoding");
statement.executeUpdate(getUpdateUserInUsersTableSQLQuery());
//Update "uuid" column
mcMMO.p.getLogger().info("Updating user column to new encoding");
statement.executeUpdate(getUpdateUUIDInUsersTableSQLQuery());
//Update "mobhealthbar" column
mcMMO.p.getLogger().info("Updating mobhealthbar column to new encoding");
statement.executeUpdate(getUpdateMobHealthBarInHudsTableSQLQuery());
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.SQL_CHARSET_UTF8MB4);
} catch (SQLException e) {
e.printStackTrace();
}
}
@NotNull
private String getUpdateUserInUsersTableSQLQuery() {
return "ALTER TABLE\n" +
" " + tablePrefix + "users\n" +
" CHANGE user user\n" +
" " + USER_VARCHAR + "\n" +
" CHARACTER SET utf8mb4\n" +
" COLLATE utf8mb4_unicode_ci;";
}
@NotNull
private String getUpdateUUIDInUsersTableSQLQuery() {
return "ALTER TABLE\n" +
" " + tablePrefix + "users\n" +
" CHANGE uuid uuid\n" +
" " + UUID_VARCHAR + "\n" +
" CHARACTER SET utf8mb4\n" +
" COLLATE utf8mb4_unicode_ci;";
}
@NotNull
private String getUpdateMobHealthBarInHudsTableSQLQuery() {
return "ALTER TABLE\n" +
" " + tablePrefix + "huds\n" +
" CHANGE mobhealthbar mobhealthbar\n" +
" " + MOBHEALTHBAR_VARCHAR + "\n" +
" CHARACTER SET utf8mb4\n" +
" COLLATE utf8mb4_unicode_ci;";
}
}

View File

@ -0,0 +1,7 @@
package com.gmail.nossr50.database;
import org.jetbrains.annotations.NotNull;
public interface UserQuery {
@NotNull UserQueryType getType();
}

View File

@ -0,0 +1,31 @@
package com.gmail.nossr50.database;
import org.jetbrains.annotations.NotNull;
import java.util.UUID;
public class UserQueryFull implements UserQueryUUID, UserQueryName {
private final @NotNull String name;
private final @NotNull UUID uuid;
public UserQueryFull(@NotNull String name, @NotNull UUID uuid) {
this.name = name;
this.uuid = uuid;
}
@Override
public @NotNull UserQueryType getType() {
return UserQueryType.UUID_AND_NAME;
}
@Override
public @NotNull String getName() {
return name;
}
@Override
public @NotNull UUID getUUID() {
return uuid;
}
}

View File

@ -0,0 +1,7 @@
package com.gmail.nossr50.database;
import org.jetbrains.annotations.NotNull;
public interface UserQueryName extends UserQuery {
@NotNull String getName();
}

View File

@ -0,0 +1,20 @@
package com.gmail.nossr50.database;
import org.jetbrains.annotations.NotNull;
public class UserQueryNameImpl implements UserQueryName {
private final @NotNull String name;
public UserQueryNameImpl(@NotNull String name) {
this.name = name;
}
@Override
public @NotNull UserQueryType getType() {
return UserQueryType.NAME;
}
public @NotNull String getName() {
return name;
}
}

View File

@ -0,0 +1,7 @@
package com.gmail.nossr50.database;
public enum UserQueryType {
UUID_AND_NAME,
UUID,
NAME
}

View File

@ -0,0 +1,11 @@
package com.gmail.nossr50.database;
import org.jetbrains.annotations.NotNull;
import java.util.UUID;
public interface UserQueryUUID extends UserQuery {
@NotNull UUID getUUID();
}

View File

@ -0,0 +1,23 @@
package com.gmail.nossr50.database;
import org.jetbrains.annotations.NotNull;
import java.util.UUID;
public class UserQueryUUIDImpl implements UserQueryUUID {
private final @NotNull UUID uuid;
public UserQueryUUIDImpl(@NotNull UUID uuid) {
this.uuid = uuid;
}
@Override
public @NotNull UserQueryType getType() {
return UserQueryType.UUID;
}
@Override
public @NotNull UUID getUUID() {
return uuid;
}
}

View File

@ -0,0 +1,42 @@
package com.gmail.nossr50.database.flatfile;
import com.gmail.nossr50.database.FlatFileDataFlag;
import com.google.common.base.Objects;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.HashSet;
public class BadCategorizedFlatFileData extends CategorizedFlatFileData {
private final boolean[] badDataIndexes;
protected BadCategorizedFlatFileData(int uniqueProcessingId, @NotNull HashSet<FlatFileDataFlag> dataFlags, @NotNull String[] splitData, boolean[] badDataIndexes) {
super(uniqueProcessingId, dataFlags, splitData);
this.badDataIndexes = badDataIndexes;
}
public boolean[] getBadDataIndexes() {
return badDataIndexes;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
BadCategorizedFlatFileData that = (BadCategorizedFlatFileData) o;
return Objects.equal(badDataIndexes, that.badDataIndexes);
}
@Override
public int hashCode() {
return Objects.hashCode(super.hashCode(), badDataIndexes);
}
@Override
public String toString() {
return "BadCategorizedFlatFileData{" +
"badDataIndexes=" + Arrays.toString(badDataIndexes) +
'}';
}
}

View File

@ -0,0 +1,58 @@
package com.gmail.nossr50.database.flatfile;
import com.gmail.nossr50.database.FlatFileDataFlag;
import com.google.common.base.Objects;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
public class CategorizedFlatFileData implements FlatFileDataContainer {
private final @NotNull Set<FlatFileDataFlag> dataFlags;
private final @NotNull String[] splitData;
private final int uniqueProcessingId;
public CategorizedFlatFileData(int uniqueProcessingId, @NotNull HashSet<FlatFileDataFlag> dataFlags, @NotNull String[] splitData) {
this.uniqueProcessingId = uniqueProcessingId;
this.dataFlags = dataFlags;
this.splitData = splitData;
}
public @NotNull Set<FlatFileDataFlag> getDataFlags() {
return dataFlags;
}
public @NotNull String[] getSplitData() {
return splitData;
}
public int getUniqueProcessingId() {
return uniqueProcessingId;
}
public boolean isHealthyData() {
return dataFlags.size() == 0;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CategorizedFlatFileData that = (CategorizedFlatFileData) o;
return uniqueProcessingId == that.uniqueProcessingId && Objects.equal(dataFlags, that.dataFlags) && Objects.equal(splitData, that.splitData);
}
@Override
public int hashCode() {
return Objects.hashCode(dataFlags, splitData, uniqueProcessingId);
}
@Override
public String toString() {
return "CategorizedFlatFileData{" +
"dataFlags=" + dataFlags +
", stringDataRepresentation='" + splitData + '\'' +
", uniqueProcessingId=" + uniqueProcessingId +
'}';
}
}

View File

@ -0,0 +1,42 @@
package com.gmail.nossr50.database.flatfile;
import com.gmail.nossr50.database.FlatFileDataFlag;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
public class FlatFileDataBuilder {
private final @NotNull HashSet<FlatFileDataFlag> dataFlags;
private @NotNull String[] splitStringData;
private final int uniqueProcessingId;
private boolean[] badDataValues;
public FlatFileDataBuilder(@NotNull String[] splitStringData, int uniqueProcessingId) {
this.uniqueProcessingId = uniqueProcessingId;
this.splitStringData = splitStringData;
dataFlags = new HashSet<>();
}
public @NotNull FlatFileDataBuilder appendFlag(@NotNull FlatFileDataFlag dataFlag) {
dataFlags.add(dataFlag);
return this;
}
public @NotNull FlatFileDataBuilder appendBadDataValues(boolean[] badDataValues) {
this.badDataValues = badDataValues;
return this;
}
public @NotNull FlatFileDataContainer build() {
if(dataFlags.contains(FlatFileDataFlag.BAD_VALUES)) {
return new BadCategorizedFlatFileData(uniqueProcessingId, dataFlags, splitStringData, badDataValues);
}
return new CategorizedFlatFileData(uniqueProcessingId, dataFlags, splitStringData);
}
public @NotNull FlatFileDataBuilder setSplitStringData(@NotNull String[] splitStringData) {
this.splitStringData = splitStringData;
return this;
}
}

View File

@ -0,0 +1,21 @@
package com.gmail.nossr50.database.flatfile;
import com.gmail.nossr50.database.FlatFileDataFlag;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Set;
public interface FlatFileDataContainer {
default @Nullable Set<FlatFileDataFlag> getDataFlags() {
return null;
}
@NotNull String[] getSplitData();
int getUniqueProcessingId();
default boolean isHealthyData() {
return getDataFlags() == null || getDataFlags().size() == 0;
}
}

View File

@ -0,0 +1,115 @@
package com.gmail.nossr50.database.flatfile;
import com.gmail.nossr50.database.FlatFileDataFlag;
import com.gmail.nossr50.database.FlatFileDatabaseManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import static com.gmail.nossr50.database.FlatFileDatabaseManager.*;
public class FlatFileDataUtil {
public static @Nullable String[] getPreparedSaveDataLine(@NotNull FlatFileDataContainer dataContainer) {
if(dataContainer.getDataFlags() == null) {
return dataContainer.getSplitData();
}
//Data of this type is not salvageable
//TODO: Test that we ignore the things we are supposed to ignore
//TODO: Should we even keep track of the bad data or just not even build data containers for it? Making containers for it is only really useful for debugging.. well I suppose operations are typically async so it shouldn't matter
if(dataContainer.getDataFlags().contains(FlatFileDataFlag.CORRUPTED_OR_UNRECOGNIZABLE)
|| dataContainer.getDataFlags().contains(FlatFileDataFlag.DUPLICATE_UUID) //For now we will not try to fix any issues with UUIDs
|| dataContainer.getDataFlags().contains(FlatFileDataFlag.BAD_UUID_DATA) //For now we will not try to fix any issues with UUIDs
|| dataContainer.getDataFlags().contains(FlatFileDataFlag.TOO_INCOMPLETE)) {
return null;
}
String[] splitData;
/*
* First fix the bad data values if they exist
*/
if(dataContainer instanceof BadCategorizedFlatFileData badData) {
splitData = repairBadData(dataContainer.getSplitData(), badData.getBadDataIndexes());
} else {
splitData = dataContainer.getSplitData();
}
//Make sure we have as many values as we are supposed to
assert splitData.length == FlatFileDatabaseManager.DATA_ENTRY_COUNT;
return splitData;
}
public static @NotNull String[] repairBadData(@NotNull String[] splitData, boolean[] badDataValues) {
for(int i = 0; i < FlatFileDatabaseManager.DATA_ENTRY_COUNT; i++) {
if(badDataValues[i]) {
//This data value was marked as bad so we zero initialize it
splitData[i] = getZeroInitialisedData(i, 0);
}
}
return splitData;
}
/**
* @param index "zero" Initialization will depend on what the index is for
* @return the "zero" initialized data corresponding to the index
*/
public static @NotNull String getZeroInitialisedData(int index, int startingLevel) throws IndexOutOfBoundsException {
switch(index) {
case USERNAME_INDEX:
return LEGACY_INVALID_OLD_USERNAME; //We'll keep using this value for legacy compatibility reasons (not sure if needed but don't care)
case 2: //Assumption: Used to be for something, no longer used
case 3: //Assumption: Used to be for something, no longer used
case 23: //Assumption: Used to be used for something, no longer used
case 33: //Assumption: Used to be used for something, no longer used
case LEGACY_LAST_LOGIN:
case HEALTHBAR:
return "IGNORED";
case SKILLS_MINING:
case SKILLS_REPAIR:
case SKILLS_UNARMED:
case SKILLS_HERBALISM:
case SKILLS_EXCAVATION:
case SKILLS_ARCHERY:
case SKILLS_SWORDS:
case SKILLS_AXES:
case SKILLS_WOODCUTTING:
case SKILLS_ACROBATICS:
case SKILLS_TAMING:
case SKILLS_FISHING:
case SKILLS_ALCHEMY:
return String.valueOf(startingLevel);
case OVERHAUL_LAST_LOGIN:
return String.valueOf(-1L);
case COOLDOWN_BERSERK:
case COOLDOWN_GIGA_DRILL_BREAKER:
case COOLDOWN_TREE_FELLER:
case COOLDOWN_GREEN_TERRA:
case COOLDOWN_SERRATED_STRIKES:
case COOLDOWN_SKULL_SPLITTER:
case COOLDOWN_SUPER_BREAKER:
case COOLDOWN_BLAST_MINING:
case SCOREBOARD_TIPS:
case COOLDOWN_CHIMAERA_WING:
case EXP_MINING:
case EXP_WOODCUTTING:
case EXP_REPAIR:
case EXP_UNARMED:
case EXP_HERBALISM:
case EXP_EXCAVATION:
case EXP_ARCHERY:
case EXP_SWORDS:
case EXP_AXES:
case EXP_ACROBATICS:
case EXP_TAMING:
case EXP_FISHING:
case EXP_ALCHEMY:
return "0";
case UUID_INDEX:
throw new IndexOutOfBoundsException(); //TODO: Add UUID recovery? Might not even be worth it.
}
throw new IndexOutOfBoundsException();
}
}

View File

@ -0,0 +1,7 @@
package com.gmail.nossr50.database.flatfile;
public enum LeaderboardStatus {
TOO_SOON_TO_UPDATE,
UPDATED,
FAILED
}

View File

@ -1,6 +1,5 @@
package com.gmail.nossr50.datatypes;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.mcMMO;
@ -38,11 +37,10 @@ public class LevelUpBroadcastPredicate<T extends CommandSender> implements Predi
return false;
}
if(t instanceof Player) {
Player listeningPlayer = (Player) t;
if(t instanceof Player listeningPlayer) {
//Party Member Check
if(Config.getInstance().isLevelUpBroadcastsPartyMembersOnly()) {
if(mcMMO.p.getGeneralConfig().isLevelUpBroadcastsPartyMembersOnly()) {
McMMOPlayer mmoListeningPlayer = UserManager.getPlayer(listeningPlayer);
if(mmoListeningPlayer == null) {
@ -68,27 +66,27 @@ public class LevelUpBroadcastPredicate<T extends CommandSender> implements Predi
}
//Distance checks
if(Config.getInstance().shouldLevelUpBroadcastsRestrictDistance()) {
if(!Misc.isNear(mmoBroadcastingPlayer.getPlayer().getLocation(), listeningPlayer.getLocation(), Config.getInstance().getLevelUpBroadcastRadius())) {
if(mcMMO.p.getGeneralConfig().shouldLevelUpBroadcastsRestrictDistance()) {
if(!Misc.isNear(mmoBroadcastingPlayer.getPlayer().getLocation(), listeningPlayer.getLocation(), mcMMO.p.getGeneralConfig().getLevelUpBroadcastRadius())) {
return false;
}
}
}
//Visibility checks
if(!listeningPlayer.canSee(mmoBroadcastingPlayer.getPlayer())) {
if(!listeningPlayer.canSee(mmoBroadcastingPlayer.getPlayer()) && listeningPlayer != mmoBroadcastingPlayer.getPlayer()) {
return false; //Player who leveled should be invisible to this player so don't send the message
}
return true;
} else {
//Send out to console
return Config.getInstance().shouldLevelUpBroadcastToConsole();
return mcMMO.p.getGeneralConfig().shouldLevelUpBroadcastToConsole();
}
}
private static boolean isLevelUpBroadcastsSameWorldOnly() {
return Config.getInstance().isLevelUpBroadcastsSameWorldOnly();
return mcMMO.p.getGeneralConfig().isLevelUpBroadcastsSameWorldOnly();
}
@Override

View File

@ -1,6 +1,5 @@
package com.gmail.nossr50.datatypes;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.mcMMO;
@ -38,11 +37,10 @@ public class PowerLevelUpBroadcastPredicate<T extends CommandSender> implements
return false;
}
if(t instanceof Player) {
Player listeningPlayer = (Player) t;
if(t instanceof Player listeningPlayer) {
//Party Member Check
if(Config.getInstance().isPowerLevelUpBroadcastsPartyMembersOnly()) {
if(mcMMO.p.getGeneralConfig().isPowerLevelUpBroadcastsPartyMembersOnly()) {
McMMOPlayer mmoListeningPlayer = UserManager.getPlayer(listeningPlayer);
if(mmoListeningPlayer == null) {
@ -68,27 +66,27 @@ public class PowerLevelUpBroadcastPredicate<T extends CommandSender> implements
}
//Distance checks
if(Config.getInstance().shouldPowerLevelUpBroadcastsRestrictDistance()) {
if(!Misc.isNear(mmoBroadcastingPlayer.getPlayer().getLocation(), listeningPlayer.getLocation(), Config.getInstance().getPowerLevelUpBroadcastRadius())) {
if(mcMMO.p.getGeneralConfig().shouldPowerLevelUpBroadcastsRestrictDistance()) {
if(!Misc.isNear(mmoBroadcastingPlayer.getPlayer().getLocation(), listeningPlayer.getLocation(), mcMMO.p.getGeneralConfig().getPowerLevelUpBroadcastRadius())) {
return false;
}
}
}
//Visibility checks
if(!listeningPlayer.canSee(mmoBroadcastingPlayer.getPlayer())) {
if(!listeningPlayer.canSee(mmoBroadcastingPlayer.getPlayer()) && listeningPlayer != mmoBroadcastingPlayer.getPlayer()) {
return false; //Player who leveled should be invisible to this player so don't send the message
}
return true;
} else {
//Send out to console
return Config.getInstance().shouldPowerLevelUpBroadcastToConsole();
return mcMMO.p.getGeneralConfig().shouldPowerLevelUpBroadcastToConsole();
}
}
private static boolean isPowerLevelUpBroadcastsSameWorldOnly() {
return Config.getInstance().isPowerLevelUpBroadcastsSameWorldOnly();
return mcMMO.p.getGeneralConfig().isPowerLevelUpBroadcastsSameWorldOnly();
}
@Override

View File

@ -16,5 +16,6 @@ public enum UpgradeType {
ADD_UNIQUE_PLAYER_DATA,
FIX_SPELLING_NETHERITE_SALVAGE,
FIX_SPELLING_NETHERITE_REPAIR,
FIX_NETHERITE_SALVAGE_QUANTITIES
FIX_NETHERITE_SALVAGE_QUANTITIES,
SQL_CHARSET_UTF8MB4
}

View File

@ -1,5 +1,7 @@
package com.gmail.nossr50.datatypes.interactions;
import org.jetbrains.annotations.NotNull;
/**
* This class helps define the types of information interactions we will have with players
*/
@ -23,14 +25,14 @@ public enum NotificationType {
CHAT_ONLY("ChatOnly"),
PARTY_MESSAGE("PartyMessage");
final String niceName;
private final String niceName;
NotificationType(String niceName)
{
NotificationType(@NotNull String niceName) {
this.niceName = niceName;
}
@Override
public String toString() {
public @NotNull String toString() {
return niceName;
}}
}
}

View File

@ -5,7 +5,7 @@ public class McMMOUrl {
public static final String urlDiscord = "https://discord.gg/bJ7pFS9";
public static final String urlPatreon = "https://www.patreon.com/nossr50";
public static final String urlWiki = "https://www.mcmmo.org/wiki/";
public static final String urlSpigot = "http://spigot.mcmmo.org";
public static final String urlSpigot = "https://spigot.mcmmo.org";
public static final String urlTranslate = "https://translate.mcmmo.org/";
public static String getUrl(McMMOWebLinks webLinks)

View File

@ -0,0 +1,25 @@
package com.gmail.nossr50.datatypes.meta;
import com.gmail.nossr50.runnables.skills.RuptureTask;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
public class RuptureTaskMeta extends FixedMetadataValue {
private final @NotNull RuptureTask ruptureTask;
/**
* Initializes a FixedMetadataValue with an Object
*
* @param owningPlugin the {@link Plugin} that created this metadata value
* @param ruptureTask the value assigned to this metadata value
*/
public RuptureTaskMeta(@NotNull Plugin owningPlugin, @NotNull RuptureTask ruptureTask) {
super(owningPlugin, ruptureTask);
this.ruptureTask = ruptureTask;
}
public @NotNull RuptureTask getRuptureTimerTask() {
return ruptureTask;
}
}

View File

@ -1,7 +1,6 @@
package com.gmail.nossr50.datatypes.party;
import com.gmail.nossr50.chat.SamePartyPredicate;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.datatypes.experience.FormulaType;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
@ -204,7 +203,7 @@ public class Party {
public int getXpToLevel() {
FormulaType formulaType = ExperienceConfig.getInstance().getFormulaType();
return (mcMMO.getFormulaManager().getXPtoNextLevel(level, formulaType)) * (getOnlineMembers().size() + Config.getInstance().getPartyXpCurveMultiplier());
return (mcMMO.getFormulaManager().getXPtoNextLevel(level, formulaType)) * (getOnlineMembers().size() + mcMMO.p.getGeneralConfig().getPartyXpCurveMultiplier());
}
public String getXpToLevelPercentage() {
@ -243,24 +242,24 @@ public class Party {
return;
}
if (!Config.getInstance().getPartyInformAllMembers()) {
if (!mcMMO.p.getGeneralConfig().getPartyInformAllMembers()) {
Player leader = mcMMO.p.getServer().getPlayer(this.leader.getUniqueId());
if (leader != null) {
leader.sendMessage(LocaleLoader.getString("Party.LevelUp", levelsGained, getLevel()));
if (Config.getInstance().getLevelUpSoundsEnabled()) {
if (mcMMO.p.getGeneralConfig().getLevelUpSoundsEnabled()) {
SoundManager.sendSound(leader, leader.getLocation(), SoundType.LEVEL_UP);
}
}
return;
} else {
PartyManager.informPartyMembersLevelUp(this, levelsGained, getLevel());
}
PartyManager.informPartyMembersLevelUp(this, levelsGained, getLevel());
}
public boolean hasReachedLevelCap() {
return Config.getInstance().getPartyLevelCap() < getLevel() + 1;
return mcMMO.p.getGeneralConfig().getPartyLevelCap() < getLevel() + 1;
}
public void setXpShareMode(ShareMode xpShareMode) {
@ -328,7 +327,7 @@ public class Party {
}
public boolean hasMember(String memberName) {
return this.getMembers().containsValue(memberName);
return this.getMembers().values().stream().anyMatch(memberName::equalsIgnoreCase);
}
public boolean hasMember(UUID uuid) {
@ -386,7 +385,7 @@ public class Party {
if (party != null) {
Player player = mcMMOPlayer.getPlayer();
double range = Config.getInstance().getPartyShareRange();
double range = mcMMO.p.getGeneralConfig().getPartyShareRange();
for (Player member : party.getOnlineMembers()) {
if (!player.equals(member) && member.isValid() && Misc.isNear(player.getLocation(), member.getLocation(), range)) {
@ -404,12 +403,10 @@ public class Party {
return false;
}
if (!(obj instanceof Party)) {
if (!(obj instanceof Party other)) {
return false;
}
Party other = (Party) obj;
if ((this.getName() == null) || (other.getName() == null)) {
return false;
}

Some files were not shown because too many files have changed in this diff Show More