1
0
mirror of https://github.com/mcMMO-Dev/mcMMO.git synced 2026-02-18 17:53:00 +01:00

Compare commits

...

363 Commits

Author SHA1 Message Date
nossr50
3e7c889f8f mcMMO 2.2.000-RC1 candidate for release 2024-03-30 06:03:25 -07:00
nossr50
e8a46d6ac8 Merge branch 'master' of https://github.com/mcMMO-Dev/mcMMO into endgame 2024-03-30 05:59:37 -07:00
nossr50
39503b7038 Fix missing verdant bounty stat in herbalism command 2024-03-30 05:44:02 -07:00
nossr50
6d0fbfd02e updating changelog 2024-03-30 05:39:25 -07:00
nossr50
84cb6e3f7b add metadata cleanup for trick shot 2024-03-30 05:35:02 -07:00
gecko10000
bead5feb14 Make PAPI expansion persist (#4986) 2024-03-30 05:31:47 -07:00
nossr50
e9407246d7 update note about WIP status on tridents/xbows 2024-03-30 05:22:28 -07:00
nossr50
221175d2d3 locale changes 2024-03-30 05:08:55 -07:00
nossr50
bf901a0a34 remove unimplemented features, fix tests again, and optimize imports 2024-03-30 05:05:28 -07:00
nossr50
ef3887a720 fix unit tests 2024-03-30 04:44:10 -07:00
nossr50
fba6e8a961 merge master 2024-03-19 16:17:41 -07:00
Lorenzo Cardinali
04ed2a47d4 Fixed import errors related to Alchemy data in AdvancedConfig (#4983) 2024-03-10 18:59:15 -07:00
nossr50
7da8c8c83a 2.1.231 2024-03-09 21:16:59 -08:00
Mangchi__
4d060b192b Update locale_ko.properties (#4977)
* Update locale_ko.properties

* Update locale_ko.properties fixed-1
2024-03-09 20:17:14 -08:00
Momshroom
2117c67084 Fixed NPE when party creation doesn't use password. Solves bug reported here: https://discord.com/channels/526933440214597677/526938425161416727/1213131451235827753 (#4981)
Signed-off-by: Momshroom <Momshroom@gmail.com>
2024-03-09 20:16:14 -08:00
nossr50
4d85f24d98 2.1.230 2024-02-22 18:04:57 -08:00
nossr50
416c5383c9 Merge branch 'master' of https://github.com/mcMMO-Dev/mcMMO 2024-02-22 17:57:17 -08:00
IAISI
7f9ed94d23 Fix exceptions on EntityCombustByEntityEvent, EntityDamageByEntityEvent, PartyAutoKickTask if parties are disabled (#4976)
* Only run EntityListener#checkParties on EntityCombustByEntityEvent if Parties are enabled

* Only run PartyAutoKickTask Task if Parties are enabled

* Only run EntityListener#checkParties on EntityDamageByEntityEvent if Parties are enabled

* Check if Parties are enabled before running inSameParty in CombatUtils#processCombatXP

---------

Co-authored-by: Dieu <info@l4b.org>
2024-02-22 17:57:05 -08:00
nossr50
b0d0030d60 2.1.230 2024-02-22 17:54:42 -08:00
IAISI
cdc187b211 Fix PartySaving related NPEs (only save parties if they're enabled) (#4973)
Co-authored-by: Dieu <info@l4b.org>
2024-02-20 09:20:08 -08:00
nossr50
3361d28887 Party system can now be disabled via config
Closes #4873
2024-02-19 17:55:57 -08:00
nossr50
c358c8ce0b Add missing getHandlerList() to McMMOEntityDamageByRuptureEvent fixes #4972 2024-02-19 16:12:39 -08:00
nossr50
aa65be0e1b dev mode 2024-02-17 16:30:47 -08:00
nossr50
70383b7250 merge master 2024-02-17 16:00:51 -08:00
nossr50
85f27fdbdb 2.1.228 2024-02-14 13:17:46 -08:00
nossr50
5bfca3c218 Fix spigot api break for entity damage events 2024-02-13 18:04:00 -08:00
nossr50
2271bd5236 wip super shotgun 2024-02-03 16:05:53 -08:00
nossr50
b0c42f8e44 enable super shotgun permission 2024-02-03 14:55:42 -08:00
nossr50
66a4886ee4 Crossbow multi-shot arrows that bounce are no longer pickup-able 2024-01-28 15:00:53 -08:00
nossr50
b3b8a12b6d Crossbow Fixes 2024-01-22 13:55:55 -08:00
nossr50
f051edd03d Tree Feller non-wood drop rate reduced by 90% 2024-01-22 13:51:15 -08:00
nossr50
377bf1be4d Tree Feller non-wood drop rate reduced by 90% 2024-01-16 12:49:42 -08:00
nossr50
dda5b45bb1 improve SQL exceptions to be more easily debuggable 2024-01-15 10:21:30 -08:00
nossr50
009d809d76 Fix bug with Excavation drop rate and misc mysql changes 2024-01-15 10:19:03 -08:00
nossr50
33cad7c2f1 typos 2024-01-14 09:45:40 -08:00
nossr50
efabaf1466 more work on end game update 2024-01-14 09:43:30 -08:00
nossr50
9cbe10827f Buff end game skills 2024-01-14 09:27:04 -08:00
nossr50
fdc308762c Hack to disable supers that aren't ready yet 2024-01-14 08:51:23 -08:00
nossr50
826d16d916 More work on Crossbows & Tridents 2024-01-04 12:39:26 -08:00
nossr50
4ba0f76eb9 Bouncing 2024-01-03 01:51:59 -08:00
nossr50
04c9db88ab more h2 compatibility stuff 2024-01-03 01:29:37 -08:00
nossr50
3fbb4827ca Update SQL schema when missing columns 2024-01-03 00:19:57 -08:00
nossr50
94754b150c Dev mode 2024-01-02 23:31:48 -08:00
nossr50
8cc4798752 Merge master 2024-01-02 23:00:23 -08:00
nossr50
415e3df226 2.1.227 2024-01-02 22:45:38 -08:00
nossr50
a941a1cc7f kill child.yml and more work on sql unit tests 2023-12-27 22:52:51 -08:00
nossr50
b0efd46584 starting work on sql unit tests 2023-12-27 21:14:14 -08:00
nossr50
dadc295431 Trickshot boiler plate stuff 2023-12-27 19:20:41 -08:00
nossr50
76d4b50554 Refactor ricochet code, don't reflect shallow angles 2023-12-27 19:20:32 -08:00
nossr50
afff3b4c50 Move projectile stuff to util 2023-12-23 17:04:19 -08:00
nossr50
1799d455b7 Deflect arrows off surfaces 2023-12-23 16:28:18 -08:00
Robert Alan Chapton
b5608ccb01 Update README.md 2023-12-23 15:53:30 -08:00
Robert Alan Chapton
d57e225576 Update README.md 2023-12-23 15:53:08 -08:00
Robert Alan Chapton
2f166507ca Update README.md 2023-12-23 15:50:49 -08:00
nossr50
9360e147ac Fun with arrows 2023-12-22 13:07:34 -08:00
nossr50
967ffd6442 update Changelog.txt 2023-12-22 11:39:13 -08:00
nossr50
5f63faf65d Unit test refactor 2023-12-22 11:37:17 -08:00
nossr50
7973ccc848 Update FlatFile for new skill cds 2023-12-22 11:05:26 -08:00
MithicSpirit
347e6112fb Make mcMMO anvil sounds categorized (#4954)
Default anvil sound is way too loud, and being in the master category
makes it hard to manage player-side without making the entire game too
soft.
2023-12-21 17:54:29 -08:00
Min Sa-Hun
65dfcb492d Renewed and completed the Korean locale (#4956)
Co-authored-by: Pindang2 <workspace@pindang2.com>
2023-12-21 17:53:38 -08:00
YuanYuanOwO
23a549a6d3 Update locale_zh_CN.properties (#4953)
Update language file to fix a typo error
2023-12-21 17:52:51 -08:00
nossr50
7e3826a4d6 WIP starting work on supers for archery/crossbow 2023-12-20 19:26:22 -08:00
nossr50
3e11b7da2c Add Explosive Shot definition 2023-12-20 19:11:08 -08:00
nossr50
23b8e0a28c Add BowType metadata 2023-12-20 16:53:20 -08:00
nossr50
25952154e3 Add in trident command 2023-12-19 11:17:22 -08:00
nossr50
c8dedfc980 Merge branch 'master' of github.com:mcMMO-Dev/mcMMO into endgame 2023-12-17 16:07:52 -08:00
nossr50
a522ab7b2f updata todo note 2023-12-16 17:59:40 -08:00
nossr50
a0923ad786 Merge branch 'master' of https://github.com/mcMMO-Dev/mcMMO 2023-12-16 17:46:37 -08:00
nossr50
dd04ee48b9 2.1.226 2023-12-16 17:45:17 -08:00
PikaMug
89b895af81 Update pom.xml with WorldEdit (#4951) 2023-10-27 11:19:38 -07:00
nossr50
9e1f5b44a6 dev mode 2023-10-15 12:29:27 -07:00
nossr50
a54590576f 2.1.225 2023-10-15 12:18:12 -07:00
Spongecade
06160c6d04 Update Minecraft wiki link to new domain (#4944) 2023-10-15 10:47:21 -07:00
nossr50
12e5a7f054 Bamboo is now treated like a cactus/sugar cane 2023-10-08 16:51:59 -07:00
nossr50
1f20e6344b 2.1.224 2023-10-02 18:16:02 -07:00
nossr50
13ba51cdf1 Fixed some mistakes in shake config 2023-09-30 15:46:20 -07:00
nossr50
4f22391465 Spelling/Grammar 2023-09-30 15:44:56 -07:00
nossr50
5f1a545437 Merge branch 'master' of https://github.com/mcMMO-Dev/mcMMO 2023-09-30 15:43:30 -07:00
nossr50
bad7023129 Shake has 8 ranks again 2023-09-30 15:43:19 -07:00
Huynh Tien
785f18c13a update FoliaLib (#4935)
- fix an issue with 0 ticks setting
- disable scheduler warning
2023-09-03 16:41:35 -07:00
nossr50
357995ecb0 2.1.223 Folia Support Added 2023-08-26 16:21:09 -07:00
nossr50
3e26eca48e Merge branch 'master' of https://github.com/mcMMO-Dev/mcMMO 2023-08-26 16:17:39 -07:00
nossr50
dd339c20ea Updated API 2023-08-26 16:17:31 -07:00
Yomamaeatstoes
c34230a82e mcMMO-Folia-PR (#4925)
Folia Support

---------

Co-authored-by: Rockyers <ethan@yocom.org>
Co-authored-by: TechnicallyCoded <technicallycoded@gmail.com>
Co-authored-by: HSGamer <huynhqtienvtag@gmail.com>
2023-08-26 16:16:18 -07:00
Greymagic27
192626f4da Fix packaging error on windows #4911 (#4919) 2023-08-19 14:23:05 -07:00
nossr50
24a57fab3d 2.1.222 2023-07-09 14:43:38 -07:00
nossr50
78596dc00e Glow Lichen nerf 2023-06-25 13:51:00 -07:00
nossr50
0b1b753d4c Merge branch 'master' of https://github.com/mcMMO-Dev/mcMMO 2023-06-25 13:47:25 -07:00
nossr50
3cbdcddcc1 Crossbows do not count as unarmed item with unarmed items setting 2023-06-25 13:47:04 -07:00
dependabot[bot]
25ecb6e1de Bump guava from 31.1-jre to 32.0.0-jre (#4903)
Bumps [guava](https://github.com/google/guava) from 31.1-jre to 32.0.0-jre.
- [Release notes](https://github.com/google/guava/releases)
- [Commits](https://github.com/google/guava/commits)

---
updated-dependencies:
- dependency-name: com.google.guava:guava
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-19 18:46:30 -07:00
nossr50
019d22d92a Make mcMMO quieter by moving most log messages to debug only 2023-06-19 16:26:30 -07:00
nossr50
e39022cc64 2.1.221 2023-06-19 14:11:53 -07:00
nossr50
a41106ee30 Update changelog 2023-06-17 20:34:18 -07:00
nossr50
b2110d4e1c PAPI Support pt 2 2023-06-17 20:32:51 -07:00
nossr50
f22043ebb5 PAPI Support WIP 2023-06-17 20:22:49 -07:00
nossr50
cc1b511c02 Don't look up offline players by name 2023-06-17 15:56:36 -07:00
nossr50
cbcddbf528 Merge master 2023-05-29 14:41:43 -07:00
nossr50
e9a020565f Added fail safes against bonus drop meta not being cleaned up 2023-05-29 14:34:47 -07:00
nossr50
44ab8d93ab Dev mode 2023-05-29 14:15:04 -07:00
Warrior
78922ea337 Fix blast mining bonus drops option not working (#4895) 2023-05-29 13:58:24 -07:00
nossr50
75ace0cfa0 Merge master 2023-05-13 15:02:04 -07:00
nossr50
db01b61371 2.1.220 2023-05-13 14:42:14 -07:00
nossr50
d30b2f7bf6 Fixed divide by zero bug impacting tridents XP when missing from config 2023-04-23 13:23:18 -07:00
Warrior
133a60c4bf Fix child skills counting towards power level in /inspect (#4889) 2023-04-23 11:08:06 -07:00
nossr50
72957c3d31 Add XP test for Woodcutting 2023-04-19 14:13:17 -07:00
nossr50
4f79f7881c Merge branch 'master' of https://github.com/mcMMO-Dev/mcMMO into endgame 2023-04-17 12:17:45 -07:00
nossr50
684e96ff6b Fix RankConfig 2023-04-17 12:17:28 -07:00
nossr50
f88dfe479e Pull master 2023-04-17 12:16:06 -07:00
nossr50
f40f68bdf0 Fix RankConfig not using the new updating config system 2023-04-17 12:07:59 -07:00
nossr50
640f4b0a9b Fix mcMMO attempting to copy out custom repair/salvage configs 2023-04-17 12:07:41 -07:00
nossr50
978ee4a9a3 Optimize the imports 2023-04-11 15:49:37 -07:00
nossr50
0ab93586fd Config files will update automatically again 2023-04-11 15:48:14 -07:00
nossr50
7af0bc468a Config files will update automatically again 2023-04-11 15:39:01 -07:00
nossr50
dc1d2540db Fixed UnarmedManager being used for Tridents 2023-04-11 04:24:48 -07:00
nossr50
aaa47d3b67 Add some combat processing logic for Tridents/Xbows 2023-04-11 04:17:29 -07:00
nossr50
63e7c09ed4 Added missing locale strings for Xbows/Tridents 2023-04-11 03:43:16 -07:00
nossr50
5b9ab65c78 Add Xbows/Tridents to combat skills list 2023-04-11 03:34:02 -07:00
nossr50
fc9287622d Add missing skill command definitions to plugin.yml 2023-04-11 03:28:15 -07:00
nossr50
534b22233d More work on Xbows/Tridents 2023-04-11 03:16:24 -07:00
nossr50
0db1d846bc Add missing parent definitions for Xbows/Tridents 2023-04-08 16:36:59 -07:00
nossr50
2c49f8ffeb Fixed failing tests + improved support for Xbows/Tridents 2023-04-08 16:30:32 -07:00
nossr50
921a0228db Merge remote-tracking branch 'origin/master' 2023-04-07 17:00:13 -07:00
nossr50
ac68c4ebe6 2.1.219 2023-04-07 17:00:01 -07:00
nossr50
8bb50fb53c Add Tridents/Xbows (WIP) 2023-04-03 17:57:33 -07:00
Smudge
4553310bb9 Fixed fishing exploiting compatibility (#4859)
* Fixed fishing exploiting compatibility

* Moved same target to class variable
2023-04-03 17:52:00 -07:00
Warrior
9b0632d63c Make party loading more resilient (#4881) 2023-04-03 17:49:35 -07:00
Warrior
69ef484b86 Fix dots not being replaced when renaming party (#4882) 2023-04-03 17:48:53 -07:00
Warrior
606a92f1ef Fix /party teleport NPE (#4885) 2023-04-03 17:48:01 -07:00
nossr50
02c5aa4628 Remove unused config values 2023-04-03 16:53:57 -07:00
nossr50
576b3c476c Merge branch 'master' of https://github.com/mcMMO-Dev/mcMMO into endgame 2023-04-03 16:50:05 -07:00
nossr50
79730383ab Fixed wiki url being incorrect in various commands 2023-04-03 16:47:58 -07:00
nossr50
68d4a179f1 merge master 2023-04-03 12:12:17 -07:00
nossr50
7264e1a8d6 Small tweaks 2023-04-03 12:07:34 -07:00
nossr50
e011f545a7 Added smithing_table to tool readiness blacklist 2023-04-02 20:44:00 -07:00
nossr50
283fa14380 Add Camel, Sniffer, and Snifflet to taming XP 2023-04-02 20:42:06 -07:00
nossr50
5f388a9906 Add support for torchflower replanting to herbalism 2023-04-02 20:38:05 -07:00
nossr50
cd96bc79d8 Change isHerbalismDrop to use strings.. this method still needs more work 2023-04-02 20:24:04 -07:00
nossr50
ae961caeab Added Torchflower to herbalism experience and bonus drops 2023-04-02 20:11:10 -07:00
nossr50
0b4d87aebc Add Sniffer and Snifflet to combat experience in experience.yml 2023-04-02 20:07:50 -07:00
nossr50
6106f70c24 Added Pitcher_Plants to bonus drops and herbalism experience 2023-04-02 20:05:52 -07:00
nossr50
100a7f8a8f Added pink_petals, cherry_wood, and cherry_log to bonus drops in config.yml 2023-04-02 20:02:32 -07:00
nossr50
4c792c4f2c Added Pink_Petals to experience.yml 2023-04-02 20:00:58 -07:00
nossr50
db4b820f80 Add new hanging signs to tool readiness blacklist 2023-04-02 19:58:16 -07:00
nossr50
ca710b4302 Add chiseled_bookshelf to tool readiness blacklist 2023-04-02 19:55:30 -07:00
nossr50
668cc0e4a3 Add support for upcoming Cherry trees 2023-04-02 19:53:13 -07:00
nossr50
6845fb4c44 Fix some bugs with new Probability type and unit tests 2023-03-26 13:41:31 -07:00
nossr50
6d0542b524 Merge remote-tracking branch 'origin/master' 2023-03-26 13:22:41 -07:00
nossr50
d84a5b37b7 Update kyori dependencies 2023-03-26 13:22:31 -07:00
optimizing-ci-builds
c072ae4990 disable xml report (#4880) 2023-03-21 22:05:40 -07:00
nossr50
2d78eaa495 Fixed Beetroots double drop issue #4667 2023-03-19 21:21:54 -07:00
nossr50
36adde7b3d Added some unit tests for double drops, fixed bug with bonus drops 2023-03-19 20:18:17 -07:00
Warrior
6bdc51be76 Fix missing return in notify command (#4870) 2023-02-25 15:20:45 -08:00
nossr50
af15617196 Add config toggle for Blast Mining bonus drops to advanced.yml 2023-02-19 13:40:14 -08:00
nossr50
e4470fd061 More work on end game skills 2023-02-18 23:44:01 -08:00
CuteLittleSky
643dff7915 Update locale_zh_CN.properties (#4858) 2023-02-09 18:16:26 -08:00
Justin
01fbfccc0d feat: Make power level display for offline players (#4861)
Fixes #4599
2023-02-09 18:12:46 -08:00
Jok
2362fe994a Don't call EntityDamageByEntityEvent with null damager (#4863)
Co-authored-by: Elioby <elioby@users.noreply.github.com>
2023-02-09 18:11:30 -08:00
nopeless
08b08b1285 Fix: player is no longer immune to projectiles shot by themselves (#4856) 2023-01-28 11:57:31 -08:00
nossr50
12fb4a3679 Refactor probability tests a little bit 2022-12-18 17:08:36 -08:00
nossr50
4a5e3542ef Add static chance skills to probability unit tests 2022-12-18 16:49:30 -08:00
nossr50
59f711834b Refactor Probability API a bit 2022-12-18 16:02:43 -08:00
nossr50
7f66d27141 Rename test 2022-12-18 15:06:44 -08:00
nossr50
11cf882830 Probability factory should live within the interface 2022-12-18 15:04:59 -08:00
nossr50
05c86f1125 Add some unit tests for new RNG dice rolls 2022-12-11 15:38:04 -08:00
nossr50
b077d9e0fb Fix compilation errors 2022-12-04 17:50:43 -08:00
nossr50
bb44e56bdb Merge master into endgame branch to prepare merge for beta 2.2.000 update 2022-12-04 15:58:23 -08:00
nossr50
965540dfaf 2.1.218 2022-12-04 14:32:34 -08:00
destro174
75822472fc Add item in mainhand when spawning in lumber bonus blocks. (#4826) 2022-12-04 14:22:37 -08:00
Daniil Z
59aecb79a1 Update Russian locale (#4832)
Added/updated some lines
Fixed new-line characters
2022-12-04 14:21:44 -08:00
DarkKnights22
c865c2d2e3 Fix bug where players could know staff are invis (#4833)
* Fix bug where players could know staff are invis

* remove whitespace
2022-12-04 14:21:22 -08:00
MrPowerGamerBR
93c64a8770 Fix pt_BR ability on typo (#4837) 2022-12-04 14:19:48 -08:00
Greymagic27
30ac82181e Updated plugins to latest version (#4817) 2022-08-09 07:35:12 -07:00
nossr50
2b219f48ec Dev mode 2022-08-07 16:13:18 -07:00
nossr50
fed0483d40 2.1.217 2022-08-07 16:03:55 -07:00
nossr50
101c43a4bc Tree Feller now partially destroys trees if the whole tree is too big
Fixes #4811
2022-08-07 15:55:19 -07:00
nossr50
fb738d85f6 Mangrove trees are now properly marked natural from growth
Fixes #4810
2022-08-07 15:54:22 -07:00
nossr50
032a407c8a Update changelog and version 2022-08-07 14:27:42 -07:00
Greymagic27
33e615f0f1 Updated dependencies to fix hovering over subskills for 1.19.2 (#4814)
* Updated dependencies that should fix the issue

* Updated spigotmc version

* Updated rest of dependencies

* Updated dependencies that fix the issue. Investigating what dependency update breaks compiling.

* Found the dependency that caused the compile issue, so have not updated that one
2022-08-07 14:19:46 -07:00
dod0lp
8feba60e2c Update config.yml (#4809) 2022-08-03 07:43:03 -07:00
nossr50
8a4fe8ae5d 2.1.216 2022-07-24 10:09:48 -07:00
nossr50
45f96793a5 Revert "Players who used unarmed combat are still considered using unarmed while not holding weapons for a brief time period"
This reverts commit 993b418fbc.
2022-07-24 10:05:56 -07:00
nossr50
df0362bcba Allow mining benefits while using Hoe 2022-07-23 17:04:43 -07:00
nossr50
25d558a5fa Added Sculk blocks to Mining 2022-07-23 16:57:42 -07:00
nossr50
c0e4d7a43d 2.1.215 - Unarmed change + Bug Fixes 2022-07-23 16:22:02 -07:00
nossr50
993b418fbc Players who used unarmed combat are still considered using unarmed while not holding weapons for a brief time period 2022-07-23 16:13:49 -07:00
nossr50
9cf856221d update changelog 2022-07-23 14:47:32 -07:00
nossr50
4db6e03517 Hacky workaround for Spigot API bug not showing burntime to the client when burntime was too high 2022-07-23 14:43:24 -07:00
nossr50
eb1393c02c Fix burnTime debug prints on mmodebug players 2022-07-23 14:24:31 -07:00
nossr50
e1a54b72a9 update changelog 2022-07-23 13:34:38 -07:00
Greymagic27
b266c7ce5b Updated Dependencies (#4798)
* Updated Dependencies

* Fix spelling mistake in dependencies

* Fixed dependency error that would prevent the plugin from loading.

Turned out I put in the wrong acf-bukkit, preventing the plugin from working. Oops!
2022-07-17 14:59:19 -07:00
nossr50
38f937fa01 revert potential furnace animation bug fix 2022-07-17 14:56:44 -07:00
nossr50
6d7982c0cf Merge branch 'master' of github.com:mcMMO-Dev/mcMMO 2022-07-17 14:03:10 -07:00
nossr50
89fa26d0eb Potential fix for #3005 2022-07-17 14:00:03 -07:00
Greymagic27
edd85c2f19 Updated kyori adventure-platform dependencies (#4797) 2022-07-17 13:38:44 -07:00
Greymagic27
88b6517f88 Added Dripstone Block to experience.yml (#4796) 2022-07-15 15:07:19 -07:00
PikaMug
2c09a0fdb6 Switch to new sk89q repo (#4791) 2022-07-02 19:25:27 -07:00
nossr50
90721ee859 Add missing Mangrove_Log to experience.yml 2022-06-26 18:43:09 -07:00
destro174
aa4011a226 Use item in mainhand to get drops when using treefeller (#4781) 2022-06-11 16:41:27 -07:00
nossr50
fa82fe8e67 Level up broadcasts should be visible to the player of origin 2022-06-09 22:50:36 -07:00
nossr50
444e1532f2 2.1.214 2022-06-09 22:39:11 -07:00
Smudge
1a34d2f647 Added 25% xp boost permission (#4773) 2022-06-09 14:31:06 -07:00
abridgedcarp
d543843235 Fix Maven build failure (#4779) 2022-06-09 14:26:50 -07:00
nossr50
c40af913f4 mcMMO 2.1.213 2022-06-07 18:07:14 -07:00
nossr50
f6268fe291 Add in new 1.19 stuff and tweak treasures.yml 2022-06-07 18:00:32 -07:00
nossr50
27854720f0 Add some exploit prevention to fishing 2022-05-15 15:24:25 -07:00
nossr50
d19cf1e260 2.1.212 - Fixed herbalism exploit and added damage limit for XP
calculations used in combat
2022-04-28 18:31:10 -07:00
Warrior
4a8630262e Fix hanging plants searching up instead of down. (#4766) 2022-04-28 08:33:45 -07:00
Werner
c41d2d1f39 Bump shade-plugin to 3.3.1 (#4762)
fixes building
2022-04-10 13:09:03 -07:00
nossr50
8821fb0b2f 2.1.211 2022-03-18 15:07:02 -07:00
nossr50
5ab55c1653 mcMMO will no longer use the DamageModifier API (potentially fix immortal player bug) 2022-03-17 19:58:42 -07:00
nossr50
8066f7f7f2 Tweak damage debug info to show modifier values 2022-03-17 16:08:50 -07:00
nossr50
5ea18e8ba7 Add combat debug info for player versus player combat /mmodebug 2022-03-17 15:03:42 -07:00
nossr50
0bf3f98d95 2.1.210 2022-03-17 13:59:17 -07:00
nossr50
fa33fa3d32 Revert 3 commits (work will be continued in branch)
Revert "Disabling mcMMO when the config breaks is dumb"

This reverts commit 86e7bfbf89.

Revert "Config validation rewrite part 1"

This reverts commit 16e90da8fd.

Revert "Update changelog"

This reverts commit 0ccd89fad4.
2022-03-17 13:49:46 -07:00
Mads U. Jensen
8b6a4c1e5b Update doubledrops IDs (#4743) 2022-02-10 17:31:22 -08:00
nossr50
0ccd89fad4 Update changelog 2022-01-30 15:47:08 -08:00
nossr50
16e90da8fd Config validation rewrite part 1 2022-01-30 15:31:52 -08:00
nossr50
86e7bfbf89 Disabling mcMMO when the config breaks is dumb
Fixes #4732
2022-01-30 14:24:21 -08:00
nossr50
8f0fb76847 Silence API out of date warning on config load 2022-01-17 15:57:04 -08:00
nossr50
3be15d3f65 Rewrite how mob/item/block metadata is tracked/retrieved
Fixes #4720
2022-01-17 15:32:02 -08:00
nossr50
74ced18bd0 Dev mode 2022-01-15 11:51:44 -08:00
nossr50
2e0a371ed8 Update changelog 2022-01-14 16:50:19 -08:00
nossr50
68ffe31246 2.1.209 2022-01-14 16:41:33 -08:00
nossr50
405de477d3 (thanks chew) Fix older MC versions not loading config files
Fixes #4716
2022-01-11 19:28:18 -08:00
nossr50
db0ae36fa7 fixed bug where duplicate comments with leading whitespace were ignored 2022-01-11 19:22:28 -08:00
nossr50
5d2028b5dc Java 16 compile target 2022-01-10 22:36:37 -08:00
nossr50
3e645a022d 2.1.208 2022-01-10 22:34:21 -08:00
nossr50
c21a040ddb Huge changes to how config files are loaded/updated, fixes many issues
Fixes #4715
2022-01-10 22:29:22 -08:00
the456gamer
dd4a5a6b9a remove YAML parsing hacks in favor of native bukkit provided parsing (#4714)
* fix yaml config to use native comment handling.
fixes #4702
replaces #4713
2022-01-09 11:16:17 -08:00
nossr50
d5ce8fc6ff Dev mode 2022-01-09 11:14:11 -08:00
dexasz
829aaea5d4 add & translate missing strings & fix a typo that broke placeholders (#4707) 2022-01-09 11:07:18 -08:00
Olivia
c92ae16c7f Fix extra 0 in level for gunpowder in retro mode (#4701) 2021-12-30 14:21:46 -08:00
nossr50
40160498ca 2.1.207 2021-12-27 11:40:33 -08:00
nossr50
9d08d88f2a Add new repair setting to default file 2021-12-27 11:34:55 -08:00
JeBobs
2ca3544741 Added option to disallow using enchanted materials to repair items. (#4693) 2021-12-27 11:29:54 -08:00
nossr50
ef714f98c9 Fix parties at level cap gaining XP and thus spamming messages
Fixes #4686
2021-12-27 11:22:16 -08:00
nossr50
dd550feb65 Update BlockTracker to use Spigot API directly instead of compatibility
layer
Fixes #4692 Fixes #4698
2021-12-27 11:09:27 -08:00
nossr50
ddc9a69f4b Fix ScoreboardManager NPE and added locale messages relating to scoreboards 2021-12-27 10:46:56 -08:00
TheBusyBiscuit
61388f46f1 Fixed #4694 (#4695) 2021-12-27 09:27:13 -08:00
nossr50
341dc45202 Takeout this warning 2021-12-14 23:27:51 -08:00
nossr50
13f7482b39 Unicode support for locale files 2021-12-14 23:08:08 -08:00
nossr50
a78dcffde7 Temporarily roll back to Java 16 2021-12-14 22:26:40 -08:00
nossr50
3671d0b565 dev mode 2021-12-14 22:23:31 -08:00
lilac & gooseberries
1b11fd2369 lithuanian translation for mcmmo (#4676) 2021-12-14 22:22:58 -08:00
nossr50
c36ff85cbf 2.1.206 - Memory leaks fixed and other changes Fixes #4681 2021-12-11 22:27:54 -08:00
nossr50
77cefbdfab Merge branch 'master' of https://github.com/mcMMO-Dev/mcMMO 2021-12-11 22:22:37 -08:00
nossr50
fbe0cd1471 Fixing like 10 memory leaks Fixes #4670 2021-12-11 22:22:02 -08:00
Robert Alan Chapton
728ba512c3 Java 17 for GH actions 2021-12-11 21:21:22 -08:00
nossr50
10470dde13 Reduce default volume of level up sound 2021-12-11 21:19:30 -08:00
nossr50
11245e87ef squelch ChunkStoreTest log output 2021-12-11 20:57:25 -08:00
nossr50
b88d752f61 update dependencies 2021-12-11 20:56:10 -08:00
Enderaoe
09ce259288 fix issue #4667 (#4669) 2021-12-07 19:55:42 -08:00
PikaMug
519d469cb2 Add null check to XP gain handler, fixes #4663 (#4677)
* Add null check to XP gain handler, fixes #4663

Co-authored-by: Robert Alan Chapton <nossr50@gmail.com>
2021-12-07 19:54:48 -08:00
nossr50
cf67e3502a dev mode 2021-12-07 19:29:36 -08:00
nossr50
9ab4584dfe MOB_METADATA_KEYS should be immutable 2021-11-14 09:36:00 -08:00
nossr50
8d27e8fccf 2.1.205 2021-11-14 09:33:27 -08:00
NemuruYama
ba1f15b655 Fixed the alchemy properly (#4658) 2021-11-14 08:05:42 -08:00
nossr50
5b1a69b3f7 2.1.204 2021-11-10 14:55:54 -08:00
Enderaoe
d185c7538c Fix issue #4626 double smelting on raw copper (#4652) 2021-11-10 04:55:04 -08:00
gecko10000
2347fc294f Fix IndexOutOfBoundsException for fake brew event by adding to list instead of setting the index (which doesn't work) (#4655) 2021-11-10 04:54:31 -08:00
nossr50
7aaec5b707 2.1.203 2021-11-08 19:07:02 -08:00
nossr50
20a713e04d Update changelog 2021-11-08 19:02:37 -08:00
gecko10000
81faf93f31 Fix hex colors in broadcasts (#4651) 2021-11-08 19:01:14 -08:00
PikaMug
19c0f6757e Add deprecated constructor w/o startinglevel per d9e195f (#4647) 2021-11-08 19:00:00 -08:00
nossr50
ec0815043e Update changelog 2021-11-08 18:58:11 -08:00
Enderaoe
182717eacf Fix issue #4105 Fishing shake percentage seems off. (#4649) 2021-11-08 18:57:32 -08:00
Robert Alan Chapton
e287ad47d1 updating github actions
hope this works
2021-11-08 18:54:46 -08:00
nossr50
8eee39b88b mcMMO now requires the latest MC version (currently 1.17.1)
Fixed a few bugs from API breaks
2021-11-08 18:38:50 -08:00
nossr50
4bf2ad46ea Require Java 16 2021-11-08 18:15:33 -08:00
nossr50
def676d8d7 2.1.202 2021-10-05 12:41:25 -07:00
nossr50
f8433cdbcc Fixed Kelp not awarding XP
Fixed #4639 Fixed #4110
2021-10-05 12:39:56 -07:00
nossr50
a2e10dbd0c Azalea trees bone mealed into existence no longer get marked unnatural
Fixes #4640
2021-10-05 11:58:31 -07:00
nossr50
e55ce00d62 Update changelog 2021-10-05 10:13:07 -07:00
nossr50
73c465ee64 Fixed a bug where mcMMO didn't flag all blocks as natural appropriately
in some StructureGrowEvent(s)
2021-09-28 16:58:40 -07:00
nossr50
c30892a0a5 Add flowering azalea leaves to Tree Feller 2021-09-28 00:09:04 -07:00
nossr50
58e7323c3e Bring adventure-api and adventure-platform (and dependencies) up to date 2021-09-23 12:59:58 -07:00
tunagohan
7fc6577196 Propose: Add an option for Exploiting Fishing. (#4619)
* feat: Add exploiting option for fishing

* Update experience.yml

Let's change how this was named

* Update ExperienceConfig.java

Let's change how this was named

Co-authored-by: Robert Alan Chapton <nossr50@gmail.com>
2021-09-22 15:11:54 -07:00
PikaMug
162c605dac Trigger change event for party create/disband (#4620) 2021-09-22 15:05:41 -07:00
rosaage
280eb0ba51 Added support for allowPublicKeyRetrieval=true in the JDBC launch (#4635)
options for MySQL

Co-authored-by: BuildTools <unconfigured@null.spigotmc.org>
2021-09-22 15:03:03 -07:00
GhostDC
8e5251ba66 update locale_zh_CN.properties (#4628) 2021-09-22 15:00:03 -07:00
Warrior
1e43e34547 Make /party kick case insensitive (#4630) 2021-09-22 14:59:39 -07:00
nossr50
5575309b79 Add amethyst block to experience.yml for Mining 2021-08-15 21:59:38 -07:00
nossr50
88dae5d5dd dev mode ( 2.1.202 ) 2021-08-10 14:59:13 -07:00
nossr50
da3909c08f 2.1.201 2021-08-10 14:44:13 -07:00
nossr50
6cad4993ed Tweaked Rupture's visual/audio effect 2021-08-10 14:42:08 -07:00
nossr50
af6e6b9545 Update changelog 2021-08-10 14:21:16 -07:00
emanondev
cd937a812d Fix for impact armor damage formula (#4425)
* Update SkillUtils.java

Add handleArmorDurabilityChange() to handle armor damage reduction correctly

* Update AxesManager.java

Changed method to handle impact damage calculation

* Update SkillUtils.java
2021-08-10 14:19:18 -07:00
Griffin Kubesa
264c0e2c78 Add /<skill> keep (#4512)
* Add /<skill> keep

* Add keep to tab completion

* Case insensitive
2021-08-10 14:17:37 -07:00
David
b42278932e Update locale_pt_BR.properties (#4566) 2021-08-10 14:15:56 -07:00
蘭蘭露 Flandre_tw
7fc7125ed3 Reupload new Chinese Traditional translation (#4584)
Hello, I have completed the Chinese Traditional translation. :)
2021-08-10 14:14:45 -07:00
nossr50
d3f012de27 Update changelog 2021-08-10 14:14:07 -07:00
Griffin Kubesa
dfa16c70a7 Set TNT source in blast mining (#4580)
* Set TNT source in blast mining

* Compatibility with older versions

Co-authored-by: TheBusyBiscuit <TheBusyBiscuit@users.noreply.github.com>

Co-authored-by: TheBusyBiscuit <TheBusyBiscuit@users.noreply.github.com>
2021-08-10 14:13:25 -07:00
GhostDC
8805a25d85 update locale_zh_CN.properties (#4585)
Thank you
2021-08-10 14:09:32 -07:00
nossr50
f91a2217c8 Fixed plugin incompatibility and exploits regarding buffed tools remaining buffed
Fixes #4616
2021-08-10 14:04:59 -07:00
nossr50
64f1ae4af6 Merge branch 'master' of github.com:mcMMO-Dev/mcMMO 2021-08-10 13:47:55 -07:00
nossr50
6d9a9d165d Blast Mining shouldn't drop Budding Amethyst
Fixes #4589
2021-08-10 13:46:33 -07:00
nossr50
5edc0d065d Add aliases to inspect command (mcinspect, mmoinspect) 2021-08-06 21:54:28 -07:00
Diablolend
a346fc3338 Fixed in every line of "\ \ " characters (#4588)
Where did they come from? 🤔
2021-07-29 15:16:07 -07:00
nossr50
dc94fedee1 Added member getPlayer to McMMOItemSpawnEvent
Fixes #4572
2021-07-20 18:47:25 -07:00
nossr50
93a6a73b4e Revert Woodcutting translation forortuguese
Fixes #4568
2021-07-20 18:32:34 -07:00
TheBusyBiscuit
2c849d9cb4 Added a Unit Test for mc version detection (#4560)
* Added a Unit Test for mc version detection

* Merge upstream and update server software string
2021-07-05 16:02:46 -07:00
nossr50
b79d452a6d 2.1.200 2021-07-01 21:02:59 -07:00
nossr50
fb94374e3c Update changelog 2021-07-01 16:14:13 -07:00
TheBusyBiscuit
5255ae846d Fixed #4556 (#4559) 2021-07-01 16:11:22 -07:00
stepech
e816310da8 Fix mcmmo picking wrong version on builds withou patch number (#4555)
* Fix server versioning

* Switch to regex when getting server version

* add comment

* Poor beginner mistakes

Co-authored-by: TheBusyBiscuit <TheBusyBiscuit@users.noreply.github.com>

Co-authored-by: TheBusyBiscuit <TheBusyBiscuit@users.noreply.github.com>
2021-07-01 16:07:44 -07:00
nossr50
de6ba4fb6a Dodge no longer triggers while blocking
Fixes #4543
2021-06-22 14:59:40 -07:00
TheBusyBiscuit
e35bfe758c Update to Junit5 and allow for mcMMO to be compiled on Java 16 (#4552)
* Updated all unit tests to Junit5 and removed Powermock

* Some formatting

* I did not mean to commit this file

* Fixed file ending

* We don't need these extra dependencies

* Replaced delegate with Junit5 assertThrows

* Revert this change

* Re-add mockito-core

* A bit more refactoring

* Update surefire and remove failsafe

* Updated Mockito

* Add failsafe back

* Bump Mockito to 3.11.2

They literally just released that.
2021-06-21 09:21:55 -07:00
nossr50
fffbacd239 2.1.199 2021-06-15 14:30:16 -07:00
nossr50
f286af3fff update changelog 2021-06-15 14:25:02 -07:00
nossr50
7e28799f94 Fix SQL on 1.17 (hacky) and optimized CompatibilityManager 2021-06-15 14:19:30 -07:00
nossr50
78dc56d263 Update Deepslate Lapis Ore on MaterialMapStore 2021-06-11 14:47:11 -07:00
nossr50
e3dfdfc6ee Fixed Deesplate Lapis Ore not being recognized 2021-06-11 14:46:27 -07:00
nossr50
4819a45be9 2.1.198 2021-06-11 14:26:28 -07:00
nossr50
5e0f8a334d Update changelog 2021-06-11 14:23:24 -07:00
nossr50
5f0cc2b09a Fix Smelting not recognizing the new 1.17 smeltables (like raw ores) 2021-06-11 14:22:33 -07:00
nossr50
6ff37c8baa Update changelog 2021-06-11 09:10:43 -07:00
TheBusyBiscuit
f7dc72359b Bump adventure to 4.8.0 (#4546) 2021-06-11 09:09:47 -07:00
nossr50
1ab5b82b22 2.1.198 dev mode 2021-06-11 09:08:22 -07:00
nossr50
28c6c90f23 2.1.197 2021-06-06 21:00:27 -07:00
nossr50
9bb38e3193 Add more 1.17 blocks 2021-06-06 20:59:43 -07:00
nossr50
551fac84a5 Add Glow Berries to Farmer's Diet 2021-06-06 20:56:14 -07:00
nossr50
0bc25b263b Add support for Glow Berries / Cave Vines 2021-06-06 20:52:27 -07:00
nossr50
fa9a3ae766 Add support for Glow Lichen 2021-06-06 20:44:33 -07:00
nossr50
33df92ea3a Add tuff to super breaker 2021-06-06 20:42:07 -07:00
nossr50
c3d86ba6c5 Add support for Tuff 2021-06-06 20:41:59 -07:00
nossr50
b569b9456e Add support for Mossy Block and Azalea Leaves 2021-06-06 20:37:51 -07:00
nossr50
4e6e58d9ca Add more support for 1.17 (mining related) 2021-06-06 11:18:03 -07:00
nossr50
619eec7667 Add new 'raw' ores to experience values and bonus drops 2021-06-03 14:34:36 -07:00
nossr50
97cfb1cfc7 More 1.17 support 2021-06-03 14:23:19 -07:00
nossr50
c28c8d164a Adding more 1.17 support 2021-06-03 14:20:00 -07:00
nossr50
e74e1e6829 Add Amethyst related blocks to experience.yml and update Super Breaker 2021-06-03 14:04:08 -07:00
nossr50
6dbc7adf48 Add glow_squid, goat, and axolotl to experience.yml 2021-06-03 13:44:56 -07:00
nossr50
cbaef4a092 Update changelog 2021-05-31 09:09:45 -07:00
lexikiq
eb10bcbc96 Disable launching from Minecart Anti-AFK (#4508) 2021-05-31 09:08:06 -07:00
nossr50
2875545fa4 Update pt_BR locale 2021-05-31 08:55:10 -07:00
nossr50
be595f2568 Update changelog 2021-05-31 08:37:07 -07:00
snake
882f6197c6 Update locale_ja_JP.propaties (#4529)
* Update locale_ja_JP.propaties

* Escape non-ASCII characters
2021-05-31 08:34:18 -07:00
nossr50
0d2f370185 Update our dependencies to their latest versions (where possibly)
Also adds Guava as a dependency as version upgrading our dependencies resulted in the loss of the included Guava libraries
2021-04-23 15:08:57 -07:00
nossr50
da1fcfe30a 2.1.196 2021-04-23 11:26:35 -07:00
nossr50
f983f95961 Remove explosion from rupture, and rupture bug fixes and other tweaks 2021-04-23 11:13:59 -07:00
nossr50
d67c561fed Update changelog 2021-04-23 10:46:59 -07:00
nossr50
989f7fd51b Fix Serrated Strikes not processing Rupture for additional targets 2021-04-23 10:45:19 -07:00
nossr50
e4b8b74987 Optimize imports 2021-04-23 10:37:22 -07:00
nossr50
9e7bb12dc3 Also avoid issues in this test by mocking instead of implementing an ever changing interface 2021-04-23 10:34:00 -07:00
nossr50
95c291d630 Avoid the pitfalls of implementing an everchanging interface from a SNAPSHOT 2021-04-23 10:30:26 -07:00
nossr50
9b4070d971 Don't process null McMMOPlayer events
Fixes #4499
2021-04-23 10:20:20 -07:00
lexikiq
6d0fe4fb58 Add McMMOEntityDamageByRuptureEvent (#4498) 2021-04-20 14:51:57 -07:00
nossr50
3e937c183f Merge branch 'master' of https://github.com/mcMMO-Dev/mcMMO into endgame 2021-03-02 15:23:30 -08:00
nossr50
1a180c4cdf Merge branch 'master' of https://github.com/mcMMO-Dev/mcMMO into endgame 2021-02-26 16:22:11 -08:00
nossr50
f039b4cbfa Fix display values for RNG 2021-02-23 19:22:39 -08:00
nossr50
6a3671a190 RandomChanceUtil refactor part 4 2021-02-18 16:41:57 -08:00
nossr50
e30c7110eb RandomChanceUtil refactor part 3 2021-02-18 12:48:16 -08:00
nossr50
fe889cf1c5 RandomChanceUtil Refactor part 2 2021-02-17 16:32:40 -08:00
nossr50
f7640938df RandomChanceUtil refactor part 1 2021-02-17 15:28:27 -08:00
nossr50
1bde79cd6f add toggle for sending chat messages to console
Fixes #4415
2021-02-10 10:05:42 -08:00
nossr50
addf9b0431 Add Clean Cuts to Woodcutting 2021-02-08 14:54:16 -08:00
nossr50
32b41b3fd3 Update references to mastery in en_us for Mining to Mother Lode 2021-02-08 12:13:53 -08:00
nossr50
73e36b11b3 rename references to mining mastery -> mother lode 2021-02-08 12:02:27 -08:00
nossr50
1ff2c0dcfc Add Mother Lode mastery subskill to Mining 2021-02-08 11:57:43 -08:00
nossr50
39a6c31894 Add permission nodes for mastery subskills 2021-02-08 11:02:12 -08:00
nossr50
9303d441b1 Change condition on power level command 2021-02-05 16:35:12 -08:00
nossr50
ce09a8bcdc get mmopower working 2021-02-05 16:26:46 -08:00
nossr50
eda227006f endgame progression WIP 2021-02-04 14:56:06 -08:00
347 changed files with 22472 additions and 17596 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
@@ -48,4 +49,4 @@ jobs:
# 4. Build via Maven
- name: Build via Maven
run: mvn verify -B --file pom.xml
run: mvn verify -B --file pom.xml -DdisableXmlReport=true

1
.gitignore vendored
View File

@@ -55,3 +55,4 @@
# Atlassian Stuff
/atlassian-ide-plugin.xml
/nulllocale_override.properties

View File

@@ -1,8 +1,505 @@
Version 2.1.196
Crossbows can now be fished up with enchantments
Version 2.2.000
General
Added Crossbows Skill, this skill is a WIP and feedback on discord is appreciated
Added Tridents Skill, this skill is a WIP and feedback on discord is appreciated
Added the "endgame" triple drop subskill 'Mother Lode' to Mining
Added the "endgame" triple drop subskill 'Clean Cuts' to Woodcutting
Added the "endgame" triple drop subskill 'Verdant Bounty' to Herbalism
Added /mmopower command which simply shows your power level (aliases /mmopowerlevel /powerlevel)
Config
Added 'Send_To_Console' settings to chat.yml to toggle sending party or admin chat messages to console
Replaced 'Experience_Formula.Modifier' in experience.yml with 'Experience_Formula.Skill_Multiplier' which is easier to understand and less prone to divide by zero bugs
child.yml config is gone now, feel free to delete it
Tweaks
Tree Feller now drops 90% less non-wood block rewards (leaves/etc) on average from Knock on Wood.
Treasure drop rate from Shake, Fishing, Hylian, and Excavation now benefit from the Luck perk
Updated advanced.yml with entries for the new skills
Permission nodes
Added 'mcmmo.commands.mmopower' permission node for the new /mmopower command
Added 'mcmmo.commands.crossbows' permission node
Added 'mcmmo.ability.crossbows.crossbowslimitbreak' permission node
Added 'mcmmo.ability.crossbows.trickshot' permission node
Added 'mcmmo.ability.herbalism.verdantbounty' permission node
Added 'mcmmo.ability.mining.motherlode' permission node
Added 'mcmmo.ability.woodcutting.cleancuts' permission node
Locale
Added locale entries for motherlode, cleancuts, and verdant bounty
Codebase
Major rewrite for how random chance was handled in the code
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
A lot of new unit tests were added to help keep mcMMO stable as part of this update, of course, more could always be added.
NOTES:
One feature of this update is to provide a endgame benefits to some skills that you can grind for a long time, ideally for a long while. I will likely expand upon this idea in future updates.
A few skills have these endgame oriented subskills, these new subskills provide a small benefit at first that grows and scales up to level 10,000 (or 1,000 for Standard mode which no one uses) and does not have ranks (other than the initial rank to unlock it).
These endgame sub skills unlock at level 1000 for users with default mcMMO settings, or 100 for those using the optional Standard scaling.
You can tweak the benefits of these skills in advanced.yml, the default settings are meant to be a good starting point.
Crossbows and Tridents are WIP skills, I would like feedback on discord about them.
More info on the new Triple Drop skills (Mother Lode, Clean Cuts, Verdant Bounty):
Currently these start at about 5% chance and can reach a maximum 50% chance if a player acquired 10,000 skill, you can adjust this in advanced.yml
These skills respect double drop settings from config.yml just like the corresponding Double Drop skills do, if a double drop is disabled for an item, then its disabled for triple drops too.
I added a new Power Level Command, for now this just shows you your current power level. If I ever add features based on power level, this command will likely display output related to those features.
Regarding Maces, I will likely add that as a WIP skill when the next Minecraft update drops.
Version 2.1.231
Fixed a bug preventing parties from being made without passwords (Thanks Momshroom)
Updated korean locale (thanks mangchi57)
Added some unit tests for party creation
Version 2.1.230
Fixed an error that could happen when mcMMO was saving when parties were disabled by party.yml (thanks IAISI & L4BORG)
Fixed several exceptions when checking PVP damage when parties were disabled by party.yml (thanks IAISI & L4BORG)
Version 2.1.229
Added new party.yml config, which lets admins disable the party system entirely without having to use permissions
Fixed error caused by missing API in McMMOEntityDamageByRuptureEvent
(API) Major API changes to PartyManager
(API) PartyManager is no longer a static singleton class, use mcMMO.getPartyManager() to get the PartyManager
(API) Added com.gmail.nossr50.mcMMO.isPartySystemEnabled to check if the party system is enabled
(API) Added com.gmail.nossr50.api.PartyAPI.isPartySystemEnabled as an alternative, to check if the party system is enabled
(API) Added missing com.gmail.nossr50.events.skills.rupture.McMMOEntityDamageByRuptureEvent.getHandlerList
NOTES:
Admins can now enable/disable the whole party system with a setting in the new party.yml config
You'll have to start your server one time to generate the config, then change the setting and reboot your server.
Version 2.1.228
Fixed a stack trace due to Spigot API break on EntityDamageEvent and EntityDamageByEntity event
(API) - Removed FakeEntityDamageEvent and FakeEntityDamageByEntityEvent
(API) - Reworked McMMOEntityDamageByRuptureEvent, this no longer extends EntityDamageByEntityEvent, instead it extends EntityEvent
Notes:
Some care went into keeping mcMMO compatible with older versions despite a big API break from Spigot, this may introduce some new bugs, so please report them if you run into any.
Version 2.1.227
Fixed bug where some text would not be displayed to players (Adventure dependency update)
Repair sound effect from mcMMO can now be adjusted in Minecraft sound options (Thanks MithicSpirit)
Korean locale updated (Thanks Pindang2)
Simplified Chinese locale updated (Thanks YuanYuanOwO)
NOTES:
For those curious, mcMMO uses Adventure to do a lot of the message sending to players.
It typically needs updating when new versions of MC come out, sorry for the delay on my part.
Version 2.1.226
Added Short_Grass to experience.yml for Herbalism
Updated Hylian Treasures "Bushes" alias to use short_grass when playing on new Minecraft versions
Fixed dirt_path and grass_block not being correctly whitelisted for herbalism abilities
Version 2.1.225
Fixed text from mcMMO not being sent or displayed to the player
Updated Adventure dependencies
Added new API McMMOPlayerNotificationEvent.getPlayer
Version 2.1.224
Updated to a new build of ACF to fix NoSuchFieldException locale
Improved Folia Support (Thanks HSGamer)
Fishing Shake has 8 ranks again
NOTES:
At some point Shake got reduced to 1 rank, this didn't really make sense as it was meant to be a skill that ranked up and got better over time.
It now has 8 ranks again, you may need to update advanced.yml and skillranks.yml to get the new ranks.
Version 2.1.223
Folia Support added (Thanks to HSGamer, TechnicallyCoded, Rockyers, and Yomamaeatstoes)
NOTES: This update brings mcMMO to Folia, not all features are guaranteed to work but from limited testing it appears to be working well.
Version 2.1.222
Fixed dupe exploit
Glow Lichen default XP changed from 200 to 5
A lot of mcMMO logging was moved from INFO to DEBUG, this should reduce the amount of noise in your logs and console
NOTES: If you want to see all logging messages, modify config.yml and set General.Verbose_Logging to true
You will have to adjust experience.yml to get the balance changes, or delete it to generate a new one
Version 2.1.221
PAPI Support is now built into mcMMO and loads when mcMMO loads (as long as you have PAPI running)
Fixed blast mining bonus drops not working (Thanks warriiorrrr)
Added fail safes to prevent bonus drops metadata from lingering on blocks
NOTES: Placeholders were brought in from electroniccat's original work on a PAPI expansion for mcMMO, the placeholders are the same as a result
I will be adding a leaderboard placeholder in the next patch (most likely). Feel free to share details of what functionality you'd want from additional placeholders on discord.
Version 2.1.220
(API) Added TreeFellerBlockBreakEvent class which extends FakeBlockBreakEvent (see notes), this is sent out during Tree Feller processing to allow other plugins to differentiate between Tree Feller and other fake block break events
Config files update automatically again
Default configs are now copied to plugins/mcMMO/defaults for easy reference
Fixed child skills counting towards power level in /inspect (Thanks Wariorrrr)
NOTES: For a while configs were not updating automatically as a rewrite of how config files were loaded was partially done, this is now complete and configs will update automatically again.
Fake block break events have been sent out historically by mcMMO to check other plugins for a players permission to break or place a block, Tree Feller will now specify via inheritance its own event type for this so mcMMO plugins can handle Tree Feller fake block break events differently if they so choose.
You can now view the default configs more easily as they are now copied to plugins/mcMMO/defaults, these configs will be overwritten on start up to match the default values of the config in the JAR
Version 2.1.219
Fixed Fishing exploit protection being triggered inappropriately by other plugins (Thanks smudgge)
Fixed wiki url being incorrect in commands
Party loading is more resilient (Thanks Wariorrrr)
Fixed periods not being replaced whe nrenaming party (Thanks Wariorrrr)
Fixed Party Teleport NPE (Thanks Wariorrrr)
Added support for various new things from Minecraft 1.20
Fixed double drop issue with Beetroots
Added 'Camel' to taming experience in experience.yml
Added 'Sniffer' to taming experience in experience.yml
Added 'Snifflet' to taming experience in experience.yml
Added 'Pitcher_Plant' to bonus drops in config.yml
Added 'Torchflower' to bonus drops in config.yml
Added 'Pink_Petals' to bonus drops in config.yml
Added 'Cherry_Log' to bonus drops in config.yml
Added 'Cherry_Wood' to bonus drops in config.yml
Added 'Camel' to combat experience in experience.yml
Added 'Sniffer' to combat experience in experience.yml
Added 'Snifflet' to combat experience in experience.yml
Added 'Torchflower' to herbalism experience in experience.yml
Added 'Pitcher_Plant' to herbalism experience in experience.yml
Added 'Pink_Petals' to herbalism experience in experience.yml
Added 'Cherry_Log' to woodcutting experience in experience.yml
Added 'Cherry_Wood' to woodcutting experience in experience.yml
Added 'Stripped_Cherry_Log' to woodcutting experience in experience.yml
Added 'Stripped_Cherry_Wood' to woodcutting experience in experience.yml
Added 'Skills.Mining.BlastMining.Bonus_Drops.Enabled' to advanced.yml to enable/disable bonus drops from Blast Mining
NOTE: There are plans to add experience and potentially subskills for discovering items via the new brushing mechanic, but this will have to wait for new Spigot API to become available
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
@@ -885,7 +1382,7 @@ Version 2.1.128
Fixed a bug where certain types of ore did not receive bonuses from Blast Mining
Fixed a few locale errors with commands
(API) Added ExperienceAPI::addCombatXP for adding combat XP to players, signature may change so its deprecated for now
mcMMO now logs whether or not its using FlatFile or SQL database on load
mcMMO now logs whether its using FlatFile or SQL database on load
(1.16) Strider added to combat experience with a value of 1.2
NOTES: A more thorough look at Unarmed balance will happen in the future, the intention of this nerf is to make Unarmed less rewarding until it is leveled quite a bit.
@@ -905,7 +1402,7 @@ Version 2.1.127
Version 2.1.126
mcMMO now relies on NMS for some of its features, if NMS cannot properly be wired up when initializing mcMMO behaviours relying on NMS will either be partially supported or disabled
mcMMO now has a compatibility mode, any features that require specific versions of Minecraft for full functionality will be disabled if your server is not running a compatible version, mcMMO will still function in compatibility mode, but either the feature will be modified or disabled depending on the version of the server software
New command /mmocompat - Shows information about whether or not mcMMO is fully functional or if some features are disabled due to the server software not being fully supported. Can be used by players or console.
New command /mmocompat - Shows information about whether mcMMO is fully functional or if some features are disabled due to the server software not being fully supported. Can be used by players or console.
New command /mmoxpbar (alias /xpbarsettings) - Players can choose to always show XP bars or to never show XP bars on a per skill basis
XPBars now last for 3 seconds before hiding instead of 2 seconds
Fixed an exploit involving fishing rods
@@ -1541,7 +2038,7 @@ Version 2.1.68
Fixed a bug where consuming food in the off hand did not trigger the Diet abilities
Version 2.1.67
The XP bar now reflects whether or not the player is receiving the early game boost
The XP bar now reflects whether the player is receiving the early game boost
Players who are receiving an early game boost will be shown "Learning a skill..." as the title of the XP bar while gaining XP
New locale string 'XPBar.Template.EarlyGameBoost'
@@ -1590,7 +2087,7 @@ Version 2.1.63
Version 2.1.62
Added a new admin notification system, sensitive commands will print chat messages to "admins" (players with either Operator status or admin chat permission)
Added a setting to disable the new admin notifications to config.yml 'General.AdminNotifications' (this will be more configurable in 2.2)
OPs and players with the admin chat permission will now see details about XP rate event commands regardless of whether or not the XP rate event messages are enabled
OPs and players with the admin chat permission will now see details about XP rate event commands regardless of whether the XP rate event messages are enabled
Updated hu_HU locale (thanks andris155)
Added XP for mining Magma_Block (default 30 XP - Update your config, see notes)
Diamond tools & armor in the repair config now have a minimum level of 0 (Update your config, temporary hotfix, 2.2 addresses this issue, see notes)
@@ -1598,9 +2095,9 @@ Version 2.1.62
New locale string - 'Server.ConsoleName' the name of the server console, this will be used in place of player names when sending admin notifications out if the command was used from console
New locale string - 'Notifications.Admin.Format.Others' style formatting + prefix for admin notifications used in the other new strings below
New locale string - 'Notifications.Admin.Format.Self' style formatting + prefix for admin command confirmations sent to the user who executed the command
New locale string - 'Notifications.Admin.XPRate.Start.Self' sent to the user who modifies the XP rate regardless of whether or not messages for the event are enabled
New locale string - 'Notifications.Admin.XPRate.Start.Self' sent to the user who modifies the XP rate regardless of whether messages for the event are enabled
New locale string - 'Notifications.Admin.XPRate.Start.Others' details of who started an XP rate event are sent to players who have Operator status or admin chat permission when the command to start or modify XP of an event has been issued
New locale string - 'Notifications.Admin.XPRate.End.Self' sent to the user who ended the XP rate event regardless of whether or not messages for the event are enabled
New locale string - 'Notifications.Admin.XPRate.End.Self' sent to the user who ended the XP rate event regardless of whether messages for the event are enabled
New locale string - 'Notifications.Admin.XPRate.End.Others' details of who ended an XP rate event are sent to players who have Operator status or admin chat permission when the command to end the event has been issued
NOTES:
@@ -1871,7 +2368,7 @@ Version 2.1.26
Notes:
The new Limit Break subskills are intended to make Prot IV players less tanky and for you to feel more powerful for having high skill level.
Limit Break has 10 ranks, each rank gives 1 extra RAW damage, this is damage before reductions from armor and enchantments. The net result is you deal about 50% more damage with an end game skill compared to before.
Limit Break has 10 ranks, each rank gives 1 extra RAW damage, this is damage before reductions from armor and enchantments. The net result is you deal about 50% more damage with an endgame skill compared to before.
With these new changes, most skills can 2 shot normal diamond armor, and it takes about 5 hits to kill someone in Prot IV Diamond Armor.
I'm not sure everyone will like these changes, the net result is players are a lot easier to kill now, whereas before you could take quite a beating before getting killed.
I collected several sets of data before making these changes, including damage to player with and without prot 4 diamond armor, damage to those players with and without enchanted weapons, damage with and without leveling your skills, and combinations of the previously mentioned things.
@@ -3572,7 +4069,7 @@ Removed performance debugging
Removed some useless settings from the config file
Version 1.0.34
Fixed the PVP setting determining whether or not you would hurt yourself from AoE Abilities
Fixed the PVP setting determining whether you would hurt yourself from AoE Abilities
Added Dutch (nl) language support
Super Breaker now gives the correct XP as determined by config.yml
Sand Stone XP is now configurable and no longer shares the 'stone' node
@@ -3582,7 +4079,7 @@ Version 1.0.33
Fixed the toggle for the Excavation drop 'Cocoa Beans'
Fixed bug where Unarmed users could disarm without being bare handed
Cocoa Beans now have an XP modifier in config.yml
You can now toggle whether or not Mobspawners will give XP (in config.yml)
You can now toggle whether Mobspawners will give XP (in config.yml)
MySQL version now makes requests to the MySQL server less frequently (should help performance)
Fixed bug with Skull Splitter hitting the user

View File

@@ -11,7 +11,12 @@ Spigot Resource: https://spigot.mcmmo.org
I plan to post links to our new wiki (its still under development), downloads, and dev blogs there.
### Builds
Currently, you can obtain our builds via the Spigot resource page: http://spigot.mcmmo.org
Currently, you can obtain our builds via the Spigot or Polymart:
http://spigot.mcmmo.org
https://polymart.org/resource/mcmmo.727
### Brief Description
The goal of mcMMO is to take core Minecraft game mechanics and expand them into an extensive and quality RPG experience. Everything in mcMMO has been carefully thought out and is constantly being improved upon. Currently, mcMMO adds fourteen unique skills to train and level in. Each of these skills is highly customizable through our configuration files, allowing server admins to tweak mcMMO to best suit the needs of his or her server. Know that the mcMMO team is dedicated to providing an ever-evolving experience, and that we carefully read all feedback and bug reports in order to evaluate and balance the mechanics of mcMMO in every update.
@@ -21,20 +26,14 @@ In December 2018, the original author and creator of mcMMO (nossr50) returned an
#### Project Lead & Founder
[![nossr50](http://www.gravatar.com/avatar/f2ee41eedfd645fb4a3a2c8f6cb1b18c.png)](https://github.com/nossr50)
#### mcMMO Devs
#### Current mcMMO Devs
[![nossr50](http://www.gravatar.com/avatar/f2ee41eedfd645fb4a3a2c8f6cb1b18c.png)](https://github.com/nossr50)
[![kashike](https://secure.gravatar.com/avatar/b5e86d6d443b957fd5cdee55501f3799.png)](https://github.com/kashike)
[![electronicboy](https://secure.gravatar.com/avatar/44759c38d311ce09596de6a2d5b88036.png)](https://github.com/electronicboy)
#### Classic Maintainer
[![t00thpick1](http://www.gravatar.com/avatar/ee23c7794a0c40120c3474287c7bce06.png)](https://github.com/t00thpick1)
## Former Team Members
### Former Lead & Awesome guy
[![gmcferrin](http://www.gravatar.com/avatar/b64c52daf25d206b27650788b5813b7b.png)](https://github.com/gmcferrin)
### Former team members
[![gmcferrin](http://www.gravatar.com/avatar/b64c52daf25d206b27650788b5813b7b.png)](https://github.com/gmcferrin)
[![kashike](https://secure.gravatar.com/avatar/b5e86d6d443b957fd5cdee55501f3799.png)](https://github.com/kashike)
[![electronicboy](https://secure.gravatar.com/avatar/44759c38d311ce09596de6a2d5b88036.png)](https://github.com/electronicboy)
[![t00thpick1](http://www.gravatar.com/avatar/ee23c7794a0c40120c3474287c7bce06.png)](https://github.com/t00thpick1)
[![bm01](http://www.gravatar.com/avatar/ec8146f5358177f12e9a252271bbc391.png)](https://github.com/bm01)
[![Glitchfinder](http://www.gravatar.com/avatar/5aa4cce22f72ae9c002ecec30f061d00.png)](https://github.com/Glitchfinder)
[![NuclearW](http://www.gravatar.com/avatar/90926bdcf1c8a75918df5ea5fa801ce6.png)](https://github.com/NuclearW)
@@ -43,20 +42,23 @@ In December 2018, the original author and creator of mcMMO (nossr50) returned an
[![riking](https://1.gravatar.com/avatar/aca9f37e569ac3a63929920035a91ba4.png)](https://github.com/riking)
[![TheYeti](https://i.imgur.com/tzFrxdo.png)](https://github.com/TheYeti)
#### Folia Contributors
[<img src="https://github.com/HSGamer.png" width=80 alt="HSGamer">](https://github.com/HSGamer)
[<img src="https://github.com/TechnicallyCoded.png" width=80 alt="TechnicallyCoded">](https://github.com/TechnicallyCoded)
[<img src="https://github.com/Yomamaeatstoes.png" width=80 alt="Yomamaeatstoes">](https://github.com/Yomamaeatstoes)
[<img src="https://github.com/Rockyers.png" width=80 alt="Rockyers">](https://github.com/Rockyers)
## Compiling
mcMMO uses Maven 3 to manage dependencies, packaging, and shading of necessary classes; Maven 3 is required to compile mcMMO.
mcMMO uses Maven to manage dependencies, packaging, and shading of necessary classes; Maven is required to compile mcMMO. It is recommended to always use the latest version of maven.
The typical command used to build mcMMO is: `mvn clean package install`
Required Libraries:
* Spigot
* JUnit
* WorldGuard 7
* bStats Bukkit
The typical command used to build mcMMO is: `mvn clean install`
https://spigot.mcmmo.org for more up to date information.
Resource Page
Downloads:
https://www.spigotmc.org/resources/official-mcmmo-original-author-returns.64348/
https://www.spigotmc.org/resources/official-mcmmo-original-author-returns.64348/
https://polymart.org/resource/mcmmo.727

240
pom.xml Executable file → Normal file
View File

@@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.gmail.nossr50.mcMMO</groupId>
<artifactId>mcMMO</artifactId>
<version>2.1.196-SNAPSHOT</version>
<version>2.2.000-RC1</version>
<name>mcMMO</name>
<url>https://github.com/mcMMO-Dev/mcMMO</url>
<scm>
@@ -14,6 +14,9 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<java.version>17</java.version>
</properties>
<issueManagement>
@@ -72,28 +75,37 @@
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<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>2.22.2</version>
<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>
@@ -118,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>
@@ -131,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>
@@ -139,21 +150,21 @@
<include>net.kyori:examination-api</include>
<include>net.kyori:examination-string</include>
<include>net.kyori:adventure-text-serializer-legacy</include>
<include>net.kyori:adventure-text-serializer-gson</include>
<include>net.kyori:adventure-text-serializer-json</include>
<include>net.kyori:adventure-text-serializer-bungeecord</include>
<include>net.kyori:adventure-text-serializer-craftbukkit</include>
<include>net.kyori:adventure-text-serializer-gson-legacy-impl</include>
<include>net.kyori:adventure-text-serializer-json-legacy-impl</include>
<include>net.kyori:option</include>
<include>co.aikar:acf-bukkit</include>
<include>com.tcoded:FoliaLib</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>
</relocation>
<relocation>
<pattern>net.kyori.adventure</pattern>
<shadedPattern>com.gmail.nossr50.mcmmo.kyori.adventure</shadedPattern>
<pattern>net.kyori</pattern>
<shadedPattern>com.gmail.nossr50.mcmmo.kyori</shadedPattern>
</relocation>
<relocation>
<pattern>co.aikar.commands</pattern>
@@ -179,6 +190,10 @@
<pattern>org.bstats</pattern>
<shadedPattern>com.gmail.nossr50.mcmmo.metrics.bstats</shadedPattern>
</relocation>
<relocation>
<pattern>com.tcoded.folialib</pattern>
<shadedPattern>com.gmail.nossr50.mcmmo.folialib</shadedPattern>
</relocation>
</relocations>
</configuration>
<executions>
@@ -195,10 +210,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>
@@ -209,8 +231,8 @@
<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>
@@ -220,100 +242,132 @@
<id>aikar</id>
<url>https://repo.aikar.co/content/groups/aikar/</url>
</repository>
<repository>
<id>sonatype-oss-snapshots1</id>
<url>https://s01.oss.sonatype.org/content/repositories/snapshots/</url>
</repository>
<repository>
<id>placeholderapi</id>
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
</repository>
<repository>
<id>devmart-other</id>
<url>https://nexuslite.gcnt.net/repos/other/</url>
</repository>
<!-- ... -->
<!-- ... -->
</repositories>
<!-- <dependencyManagement>-->
<!-- <dependencies>-->
<!-- <dependency>-->
<!-- <groupId>org.junit</groupId>-->
<!-- <artifactId>junit-bom</artifactId>-->
<!-- <version>5.7.1</version>-->
<!-- <type>pom</type>-->
<!-- <scope>import</scope>-->
<!-- </dependency>-->
<!-- </dependencies>-->
<!-- </dependencyManagement>-->
<dependencies>
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
<dependency>
<groupId>com.github.seeseemelk</groupId>
<artifactId>MockBukkit-v1.16</artifactId>
<version>0.25.0</version>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.2.224</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId>
<version>2.11.3</version>
<scope>provided</scope>
</dependency>
<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>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-serializer-bungeecord</artifactId>
<version>4.3.2</version>
</dependency>
<!-- adventure-api, adventure-text-serializer-gson, adventure-platform-bukkit-->
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-serializer-gson</artifactId>
<version>4.7.0</version>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-api</artifactId>
<version>4.7.0</version>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-nbt</artifactId>
<version>4.7.0</version>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-key</artifactId>
<version>4.7.0</version>
<version>4.15.0</version>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-serializer-gson-legacy-impl</artifactId>
<version>4.7.0</version>
<version>4.15.0</version>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-platform-bukkit</artifactId>
<version>4.0.0-SNAPSHOT</version>
<artifactId>adventure-text-serializer-json</artifactId>
<version>4.15.0</version>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-serializer-json-legacy-impl</artifactId>
<version>4.15.0</version>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-api</artifactId>
<version>4.15.0</version>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-nbt</artifactId>
<version>4.15.0</version>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-key</artifactId>
<version>4.15.0</version>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-platform-api</artifactId>
<version>4.0.0-SNAPSHOT</version>
<version>4.3.2</version>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-platform-common</artifactId>
<version>4.0.0-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>net.kyori</groupId>
<artifactId>adventure-nbt</artifactId>
</exclusion>
</exclusions>
<artifactId>adventure-platform-bukkit</artifactId>
<version>4.3.2</version>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-platform-facet</artifactId>
<version>4.3.2</version>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-platform-viaversion</artifactId>
<version>4.3.2</version>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>option</artifactId>
<version>1.0.0</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.20.4-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sk89q.worldedit</groupId>
<artifactId>worldedit-bukkit</artifactId>
<version>7.2.0-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 -->
@@ -336,50 +390,44 @@
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.7.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.7.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>5.6.2</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>
<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>32.1.1-jre</version> <!-- At this time Spigot is including 29.0 Guava classes that we are using -->
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.tcoded</groupId>
<artifactId>FoliaLib</artifactId>
<version>0.3.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
</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.mcMMO;
import com.gmail.nossr50.util.MetadataConstants;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
@@ -84,7 +84,7 @@ public final class AbilityAPI {
public static boolean isBleeding(LivingEntity entity) {
if(entity.isValid()) {
if(entity.hasMetadata(mcMMO.RUPTURE_META_KEY)) {
if(entity.hasMetadata(MetadataConstants.METADATA_KEY_RUPTURE)) {
return true;
}
}

View File

@@ -9,7 +9,6 @@ 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.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;
@@ -20,7 +19,6 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Set;
import java.util.UUID;
public final class ExperienceAPI {
@@ -35,13 +33,13 @@ 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) {
public static boolean isValidSkillType(@NotNull String skillType) {
return mcMMO.p.getSkillTools().matchSkill(skillType) != null;
}
/**
* Start the task that gives combat XP.
* Processes combat XP like mcMMO normally would, so mcMMO will check whether or not the entity should reward XP when giving out the XP
* Processes combat XP like mcMMO normally would, so mcMMO will check whether the entity should reward XP when giving out the XP
*
* @param mcMMOPlayer The attacking player
* @param target The defending entity
@@ -56,7 +54,7 @@ public final class ExperienceAPI {
/**
* Start the task that gives combat XP.
* Processes combat XP like mcMMO normally would, so mcMMO will check whether or not the entity should reward XP when giving out the XP
* Processes combat XP like mcMMO normally would, so mcMMO will check whether the entity should reward XP when giving out the XP
*
* @param mcMMOPlayer The attacking player
* @param target The defending entity
@@ -706,7 +704,7 @@ public final class ExperienceAPI {
PrimarySkillType skill = getSkillType(skillType);
if (SkillTools.isChildSkill(skill)) {
Set<PrimarySkillType> parentSkills = FamilyTree.getParents(skill);
var parentSkills = mcMMO.p.getSkillTools().getChildSkillParents(skill);
for (PrimarySkillType parentSkill : parentSkills) {
profile.addLevels(parentSkill, (levels / parentSkills.size()));
@@ -737,7 +735,7 @@ public final class ExperienceAPI {
PrimarySkillType skill = getSkillType(skillType);
if (SkillTools.isChildSkill(skill)) {
Set<PrimarySkillType> parentSkills = FamilyTree.getParents(skill);
var parentSkills = mcMMO.p.getSkillTools().getChildSkillParents(skill);
for (PrimarySkillType parentSkill : parentSkills) {
profile.addLevels(parentSkill, (levels / parentSkills.size()));

View File

@@ -0,0 +1,6 @@
package com.gmail.nossr50.api;
public enum FakeBlockBreakEventType {
FAKE,
TREE_FELLER
}

View File

@@ -3,12 +3,13 @@ package com.gmail.nossr50.api;
import com.gmail.nossr50.datatypes.interactions.NotificationType;
import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.datatypes.party.PartyLeader;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.party.PartyManager;
import com.gmail.nossr50.util.player.NotificationManager;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;
import java.util.*;
@@ -24,13 +25,22 @@ public final class PartyAPI {
* @return the name of the player's party, or null if not in a party
*/
public static String getPartyName(Player player) {
if (!inParty(player)) {
if (!mcMMO.p.getPartyConfig().isPartyEnabled() || !inParty(player)) {
return null;
}
return UserManager.getPlayer(player).getParty().getName();
}
/**
* Check if the party system is enabled.
*
* @return true if the party system is enabled, false otherwise
*/
public static boolean isPartySystemEnabled() {
return mcMMO.p.getPartyConfig().isPartyEnabled();
}
/**
* Checks if a player is in a party.
* </br>
@@ -40,7 +50,7 @@ public final class PartyAPI {
* @return true if the player is in a party, false otherwise
*/
public static boolean inParty(Player player) {
if(UserManager.getPlayer(player) == null)
if(!mcMMO.p.getPartyConfig().isPartyEnabled() || UserManager.getPlayer(player) == null)
return false;
return UserManager.getPlayer(player).inParty();
@@ -51,12 +61,15 @@ public final class PartyAPI {
* </br>
* This function is designed for API usage.
*
* @param playera The first player to check
* @param playerb The second player to check
* @param playerA The first player to check
* @param playerB The second player to check
* @return true if the two players are in the same party, false otherwise
*/
public static boolean inSameParty(Player playera, Player playerb) {
return PartyManager.inSameParty(playera, playerb);
public static boolean inSameParty(Player playerA, Player playerB) {
if (!mcMMO.p.getPartyConfig().isPartyEnabled())
return false;
return mcMMO.p.getPartyManager().inSameParty(playerA, playerB);
}
/**
@@ -67,7 +80,7 @@ public final class PartyAPI {
* @return the list of parties.
*/
public static List<Party> getParties() {
return PartyManager.getParties();
return mcMMO.p.getPartyManager().getParties();
}
/**
@@ -81,23 +94,29 @@ public final class PartyAPI {
*/
@Deprecated
public static void addToParty(Player player, String partyName) {
if(!mcMMO.p.getPartyConfig().isPartyEnabled()) {
return;
}
//Check if player profile is loaded
if(UserManager.getPlayer(player) == null)
final McMMOPlayer mmoPlayer = UserManager.getPlayer(player);
if(mmoPlayer == null)
return;
Party party = PartyManager.getParty(partyName);
Party party = mcMMO.p.getPartyManager().getParty(partyName);
if (party == null) {
party = new Party(new PartyLeader(player.getUniqueId(), player.getName()), partyName);
} else {
if(PartyManager.isPartyFull(player, party))
if(mcMMO.p.getPartyManager().isPartyFull(player, party))
{
NotificationManager.sendPlayerInformation(player, NotificationType.PARTY_MESSAGE, "Commands.Party.PartyFull", party.toString());
return;
}
}
PartyManager.addToParty(UserManager.getPlayer(player), party);
mcMMO.p.getPartyManager().addToParty(mmoPlayer, party);
}
/**
@@ -119,19 +138,18 @@ public final class PartyAPI {
* @param partyName The party to add the player to
* @param bypassLimit if true bypasses party size limits
*/
//TODO: bypasslimit not used?
public static void addToParty(Player player, String partyName, boolean bypassLimit) {
//Check if player profile is loaded
if(UserManager.getPlayer(player) == null)
if(!mcMMO.p.getPartyConfig().isPartyEnabled() || UserManager.getPlayer(player) == null)
return;
Party party = PartyManager.getParty(partyName);
Party party = mcMMO.p.getPartyManager().getParty(partyName);
if (party == null) {
party = new Party(new PartyLeader(player.getUniqueId(), player.getName()), partyName);
}
PartyManager.addToParty(UserManager.getPlayer(player), party);
mcMMO.p.getPartyManager().addToParty(UserManager.getPlayer(player), party);
}
/**
@@ -143,10 +161,10 @@ public final class PartyAPI {
*/
public static void removeFromParty(Player player) {
//Check if player profile is loaded
if(UserManager.getPlayer(player) == null)
if(!mcMMO.p.getPartyConfig().isPartyEnabled() || UserManager.getPlayer(player) == null)
return;
PartyManager.removeFromParty(UserManager.getPlayer(player));
mcMMO.p.getPartyManager().removeFromParty(UserManager.getPlayer(player));
}
/**
@@ -157,8 +175,11 @@ public final class PartyAPI {
* @param partyName The party name
* @return the leader of the party
*/
public static String getPartyLeader(String partyName) {
return PartyManager.getPartyLeaderName(partyName);
public static @Nullable String getPartyLeader(String partyName) {
if(!mcMMO.p.getPartyConfig().isPartyEnabled())
return null;
return mcMMO.p.getPartyManager().getPartyLeaderName(partyName);
}
/**
@@ -171,7 +192,10 @@ public final class PartyAPI {
*/
@Deprecated
public static void setPartyLeader(String partyName, String playerName) {
PartyManager.setPartyLeader(mcMMO.p.getServer().getOfflinePlayer(playerName).getUniqueId(), PartyManager.getParty(partyName));
if(!mcMMO.p.getPartyConfig().isPartyEnabled())
return;
mcMMO.p.getPartyManager().setPartyLeader(mcMMO.p.getServer().getOfflinePlayer(playerName).getUniqueId(), mcMMO.p.getPartyManager().getParty(partyName));
}
/**
@@ -184,9 +208,12 @@ public final class PartyAPI {
*/
@Deprecated
public static List<OfflinePlayer> getOnlineAndOfflineMembers(Player player) {
List<OfflinePlayer> members = new ArrayList<>();
if(!mcMMO.p.getPartyConfig().isPartyEnabled()) {
return null;
}
for (UUID memberUniqueId : PartyManager.getAllMembers(player).keySet()) {
List<OfflinePlayer> members = new ArrayList<>();
for (UUID memberUniqueId : mcMMO.p.getPartyManager().getAllMembers(player).keySet()) {
OfflinePlayer member = mcMMO.p.getServer().getOfflinePlayer(memberUniqueId);
members.add(member);
}
@@ -203,7 +230,10 @@ public final class PartyAPI {
*/
@Deprecated
public static LinkedHashSet<String> getMembers(Player player) {
return (LinkedHashSet<String>) PartyManager.getAllMembers(player).values();
if(!mcMMO.p.getPartyConfig().isPartyEnabled())
return null;
return (LinkedHashSet<String>) mcMMO.p.getPartyManager().getAllMembers(player).values();
}
/**
@@ -215,7 +245,10 @@ public final class PartyAPI {
* @return all the player names and uuids in the player's party
*/
public static LinkedHashMap<UUID, String> getMembersMap(Player player) {
return PartyManager.getAllMembers(player);
if(!mcMMO.p.getPartyConfig().isPartyEnabled())
return null;
return mcMMO.p.getPartyManager().getAllMembers(player);
}
/**
@@ -227,7 +260,10 @@ public final class PartyAPI {
* @return all online players in this party
*/
public static List<Player> getOnlineMembers(String partyName) {
return PartyManager.getOnlineMembers(partyName);
if(!mcMMO.p.getPartyConfig().isPartyEnabled())
return null;
return mcMMO.p.getPartyManager().getOnlineMembers(partyName);
}
/**
@@ -239,7 +275,7 @@ public final class PartyAPI {
* @return all online players in the player's party
*/
public static List<Player> getOnlineMembers(Player player) {
return PartyManager.getOnlineMembers(player);
return mcMMO.p.getPartyManager().getOnlineMembers(player);
}
public static boolean hasAlly(String partyName) {
@@ -247,7 +283,7 @@ public final class PartyAPI {
}
public static String getAllyName(String partyName) {
Party ally = PartyManager.getParty(partyName).getAlly();
Party ally = mcMMO.p.getPartyManager().getParty(partyName).getAlly();
if (ally != null) {
return ally.getName();
}

View File

@@ -0,0 +1,12 @@
package com.gmail.nossr50.api;
import com.gmail.nossr50.events.fake.FakeBlockBreakEvent;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class TreeFellerBlockBreakEvent extends FakeBlockBreakEvent {
public TreeFellerBlockBreakEvent(@NotNull Block theBlock, @NotNull Player player) {
super(theBlock, player);
}
}

View File

@@ -0,0 +1,9 @@
package com.gmail.nossr50.api.exceptions;
import org.jetbrains.annotations.NotNull;
public class ValueOutOfBoundsException extends RuntimeException {
public ValueOutOfBoundsException(@NotNull String message) {
super(message);
}
}

View File

@@ -43,7 +43,7 @@ public class ChatManager {
*
* @param mmoPlayer target player
* @param rawMessage the raw message from the player as it was typed
* @param isAsync whether or not this is getting processed via async
* @param isAsync whether this is getting processed via async
*/
public void processPlayerMessage(@NotNull McMMOPlayer mmoPlayer, @NotNull String rawMessage, boolean isAsync) {
processPlayerMessage(mmoPlayer, mmoPlayer.getChatChannel(), rawMessage, isAsync);
@@ -69,7 +69,7 @@ public class ChatManager {
* @param mmoPlayer target player
* @param chatChannel target chat channel
* @param rawMessage raw chat message as it was typed
* @param isAsync whether or not this is getting processed via async
* @param isAsync whether this is getting processed via async
*/
private void processPlayerMessage(@NotNull McMMOPlayer mmoPlayer, @NotNull ChatChannel chatChannel, @NotNull String rawMessage, boolean isAsync) {
switch (chatChannel) {
@@ -155,7 +155,7 @@ public class ChatManager {
}
/**
* Whether or not the player is allowed to send a message to the chat channel they are targeting
* Whether the player is allowed to send a message to the chat channel they are targeting
* @param mmoPlayer target player
* @return true if the player can send messages to that chat channel
*/
@@ -197,7 +197,7 @@ public class ChatManager {
}
/**
* Whether or not a specific chat channel is enabled
* Whether a specific chat channel is enabled
* ChatChannels are enabled/disabled via user config
*
* If chat is disabled, this always returns false

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

@@ -73,7 +73,7 @@ public abstract class AbstractPlayerAuthor implements Author {
* Sanitized names are associated with a {@link ChatChannel} as different chat channels have different chat name settings
*
* @param chatChannel target chat channel
* @param useDisplayName whether or not to use this authors display name
* @param useDisplayName whether to use this authors display name
*/
private void updateSanitizedNameCache(@NotNull ChatChannel chatChannel, boolean useDisplayName) {
if(useDisplayName) {

View File

@@ -17,14 +17,14 @@ public interface Author extends Identity {
@NotNull String getAuthoredName(@NotNull ChatChannel chatChannel);
/**
* Whether or not this author is a {@link org.bukkit.command.ConsoleCommandSender}
* Whether this author is a {@link org.bukkit.command.ConsoleCommandSender}
*
* @return true if this author is the console
*/
boolean isConsole();
/**
* Whether or not this author is a {@link org.bukkit.entity.Player}
* Whether this author is a {@link org.bukkit.entity.Player}
* @return true if this author is a player
*/
boolean isPlayer();

View File

@@ -3,6 +3,7 @@ package com.gmail.nossr50.chat.mailer;
import com.gmail.nossr50.chat.author.Author;
import com.gmail.nossr50.chat.message.AdminChatMessage;
import com.gmail.nossr50.chat.message.ChatMessage;
import com.gmail.nossr50.config.ChatConfig;
import com.gmail.nossr50.datatypes.chat.ChatChannel;
import com.gmail.nossr50.events.chat.McMMOAdminChatEvent;
import com.gmail.nossr50.events.chat.McMMOChatEvent;
@@ -44,7 +45,7 @@ public class AdminChatMailer extends AbstractChatMailer {
public @NotNull Predicate<CommandSender> predicate() {
return (commandSender) -> commandSender.isOp()
|| commandSender.hasPermission(MCMMO_CHAT_ADMINCHAT_PERMISSION)
|| commandSender instanceof ConsoleCommandSender;
|| (ChatConfig.getInstance().isConsoleIncludedInAudience(ChatChannel.ADMIN) && commandSender instanceof ConsoleCommandSender);
}
/**
@@ -73,8 +74,8 @@ public class AdminChatMailer extends AbstractChatMailer {
*
* @param author the author
* @param rawString the raw message as the author typed it before any styling
* @param isAsync whether or not this is being processed asynchronously
* @param canColor whether or not the author can use colors in chat
* @param isAsync whether this is being processed asynchronously
* @param canColor whether the author can use colors in chat
*/
public void processChatMessage(@NotNull Author author, @NotNull String rawString, boolean isAsync, boolean canColor) {
AdminChatMessage chatMessage = new AdminChatMessage(pluginRef, author, constructAudience(), rawString, addStyle(author, rawString, canColor));

View File

@@ -27,8 +27,8 @@ public class PartyChatMailer extends AbstractChatMailer {
*
* @param author the author
* @param rawString the raw message as the author typed it before any styling
* @param isAsync whether or not this is being processed asynchronously
* @param canColor whether or not the author can use colors in chat
* @param isAsync whether this is being processed asynchronously
* @param canColor whether the author can use colors in chat
*/
public void processChatMessage(@NotNull Author author, @NotNull String rawString, @NotNull Party party, boolean isAsync, boolean canColor, boolean isLeader) {
PartyChatMessage chatMessage = new PartyChatMessage(pluginRef, author, constructPartyAudience(party), rawString, addStyle(author, rawString, canColor, isLeader), party);

View File

@@ -1,6 +1,7 @@
package com.gmail.nossr50.chat.message;
import com.gmail.nossr50.chat.author.Author;
import com.gmail.nossr50.config.ChatConfig;
import com.gmail.nossr50.datatypes.chat.ChatChannel;
import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
@@ -51,7 +52,8 @@ public class PartyChatMessage extends AbstractChatMessage {
messagePartyChatSpies(spyMessage);
//Console message
mcMMO.p.getChatManager().sendConsoleMessage(author, spyMessage);
if(ChatConfig.getInstance().isConsoleIncludedInAudience(ChatChannel.PARTY))
mcMMO.p.getChatManager().sendConsoleMessage(author, spyMessage);
}
/**

View File

@@ -5,6 +5,7 @@ import co.aikar.commands.BukkitCommandManager;
import co.aikar.commands.ConditionFailedException;
import com.gmail.nossr50.commands.chat.AdminChatCommand;
import com.gmail.nossr50.commands.chat.PartyChatCommand;
import com.gmail.nossr50.commands.skills.PowerLevelCommand;
import com.gmail.nossr50.config.ChatConfig;
import com.gmail.nossr50.datatypes.chat.ChatChannel;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
@@ -20,9 +21,14 @@ import org.jetbrains.annotations.NotNull;
* For now this class will only handle ACF converted commands, all other commands will be handled elsewhere
*/
public class CommandManager {
public static final @NotNull String MMO_DATA_LOADED = "mmoDataLoaded";
//CHAT
public static final @NotNull String ADMIN_CONDITION = "adminCondition";
public static final @NotNull String PARTY_CONDITION = "partyCondition";
public static final @NotNull String MMO_DATA_LOADED = "mmoDataLoaded";
//SKILLS
public static final @NotNull String POWER_LEVEL_CONDITION = "powerLevelCondition";
private final @NotNull mcMMO pluginRef;
private final @NotNull BukkitCommandManager bukkitCommandManager;
@@ -36,9 +42,16 @@ public class CommandManager {
}
private void registerCommands() {
registerSkillCommands(); //TODO: Implement other skills not just power level
registerChatCommands();
}
private void registerSkillCommands() {
if(mcMMO.p.getGeneralConfig().isMasterySystemEnabled()) {
bukkitCommandManager.registerCommand(new PowerLevelCommand(pluginRef));
}
}
/**
* Registers chat commands if the chat system is enabled
*/
@@ -47,13 +60,30 @@ public class CommandManager {
if(ChatConfig.getInstance().isChatChannelEnabled(ChatChannel.ADMIN)) {
bukkitCommandManager.registerCommand(new AdminChatCommand(pluginRef));
}
if(ChatConfig.getInstance().isChatChannelEnabled(ChatChannel.PARTY)) {
if(pluginRef.getPartyConfig().isPartyEnabled() && ChatConfig.getInstance().isChatChannelEnabled(ChatChannel.PARTY)) {
bukkitCommandManager.registerCommand(new PartyChatCommand(pluginRef));
}
}
}
public void registerConditions() {
registerChatCommandConditions(); //Chat Commands
registerSkillConditions();
}
private void registerSkillConditions() {
bukkitCommandManager.getCommandConditions().addCondition(POWER_LEVEL_CONDITION, (context) -> {
BukkitCommandIssuer issuer = context.getIssuer();
if(issuer.getIssuer() instanceof Player) {
validateLoadedData(issuer.getPlayer());
} else {
throw new ConditionFailedException(LocaleLoader.getString("Commands.NoConsole"));
}
});
}
private void registerChatCommandConditions() {
// Method or Class based - Can only be used on methods
bukkitCommandManager.getCommandConditions().addCondition(ADMIN_CONDITION, (context) -> {
BukkitCommandIssuer issuer = context.getIssuer();
@@ -78,6 +108,7 @@ public class CommandManager {
if(bukkitCommandIssuer.getIssuer() instanceof Player) {
validateLoadedData(bukkitCommandIssuer.getPlayer());
validatePlayerParty(bukkitCommandIssuer.getPlayer());
//TODO: Is there even a point in validating permission? look into this later
validatePermission("mcmmo.chat.partychat", bukkitCommandIssuer.getPlayer());
}
});
@@ -105,7 +136,7 @@ public class CommandManager {
public void validatePlayerParty(@NotNull Player player) {
McMMOPlayer mmoPlayer = UserManager.getPlayer(player);
if(mmoPlayer.getParty() == null) {
if(!pluginRef.getPartyConfig().isPartyEnabled() || mmoPlayer.getParty() == null) {
throw new ConditionFailedException(LocaleLoader.getString("Commands.Party.None"));
}
}

View File

@@ -204,7 +204,7 @@ public class McImportCommand implements CommandExecutor {
else if (materialName.contains("LOG") || materialName.contains("LEAVES")) {
skillName = "Woodcutting";
}
else if (materialName.contains("GRASS") || materialName.contains("FLOWER") || materialName.contains("CROP")) {
else if (materialName.contains("GRASS") || materialName.contains("SHORT_GRASS") || materialName.contains("FLOWER") || materialName.contains("CROP")) {
skillName = "Herbalism";
}
else if (materialName.contains("DIRT") || materialName.contains("SAND")) {

View File

@@ -24,8 +24,10 @@ public class McnotifyCommand implements TabExecutor {
McMMOPlayer mcMMOPlayer = UserManager.getPlayer((Player) sender);
//Not Loaded yet
if (mcMMOPlayer == null)
if (mcMMOPlayer == null) {
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
return true;
}
sender.sendMessage(LocaleLoader.getString("Commands.Notifications." + (mcMMOPlayer.useChatNotifications() ? "Off" : "On")));
mcMMOPlayer.toggleChatNotifications();

View File

@@ -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")) {

View File

@@ -11,7 +11,6 @@ import com.gmail.nossr50.datatypes.chat.ChatChannel;
import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.party.PartyManager;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.text.StringUtils;
import org.bukkit.entity.Player;
@@ -78,7 +77,7 @@ public class PartyChatCommand extends BaseCommand {
mcMMO.p.getLogger().severe("You need to specify a party name and then write a message afterwards.");
} else {
//Grab party
Party targetParty = PartyManager.getParty(args[0]);
Party targetParty = mcMMO.p.getPartyManager().getParty(args[0]);
if(targetParty != null) {
pluginRef.getChatManager().processConsoleMessage(StringUtils.buildStringAfterNthElement(args, 1), targetParty);

View File

@@ -64,10 +64,10 @@ public class ConvertDatabaseCommand implements CommandExecutor {
mcMMO.getDatabaseManager().saveUser(profile);
}
new PlayerProfileLoadingTask(player).runTaskLaterAsynchronously(mcMMO.p, 1); // 1 Tick delay to ensure the player is marked as online before we begin loading
mcMMO.p.getFoliaLib().getImpl().runLaterAsync(new PlayerProfileLoadingTask(player), 1); // 1 Tick delay to ensure the player is marked as online before we begin loading
}
new DatabaseConversionTask(oldDatabase, sender, previousType.toString(), newType.toString()).runTaskAsynchronously(mcMMO.p);
mcMMO.p.getFoliaLib().getImpl().runAsync(new DatabaseConversionTask(oldDatabase, sender, previousType.toString(), newType.toString()));
return true;
}
return false;

View File

@@ -36,10 +36,10 @@ public class ConvertExperienceCommand implements CommandExecutor {
UserManager.saveAll();
UserManager.clearAll();
new FormulaConversionTask(sender, newType).runTaskLater(mcMMO.p, 1);
mcMMO.p.getFoliaLib().getImpl().runLater(new FormulaConversionTask(sender, newType), 1);
for (Player player : mcMMO.p.getServer().getOnlinePlayers()) {
new PlayerProfileLoadingTask(player).runTaskLaterAsynchronously(mcMMO.p, 1); // 1 Tick delay to ensure the player is marked as online before we begin loading
mcMMO.p.getFoliaLib().getImpl().runLaterAsync(new PlayerProfileLoadingTask(player), 1); // 1 Tick delay to ensure the player is marked as online before we begin loading
}
return true;

View File

@@ -2,7 +2,7 @@ package com.gmail.nossr50.commands.party;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.party.PartyManager;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
@@ -31,11 +31,11 @@ public class PartyAcceptCommand implements CommandExecutor {
}
// Changing parties
if (!PartyManager.changeOrJoinParty(mcMMOPlayer, mcMMOPlayer.getPartyInvite().getName())) {
if (!mcMMO.p.getPartyManager().changeOrJoinParty(mcMMOPlayer, mcMMOPlayer.getPartyInvite().getName())) {
return true;
}
PartyManager.joinInvitedParty(mcMMOPlayer);
mcMMO.p.getPartyManager().joinInvitedParty(mcMMOPlayer);
return true;
}
sender.sendMessage(LocaleLoader.getString("Commands.Usage.1", "party", "accept"));

View File

@@ -3,7 +3,6 @@ package com.gmail.nossr50.commands.party;
import com.gmail.nossr50.datatypes.party.Party;
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;
import org.bukkit.OfflinePlayer;
@@ -31,7 +30,7 @@ public class PartyChangeOwnerCommand implements CommandExecutor {
return true;
}
PartyManager.setPartyLeader(target.getUniqueId(), playerParty);
mcMMO.p.getPartyManager().setPartyLeader(target.getUniqueId(), playerParty);
return true;
}
sender.sendMessage(LocaleLoader.getString("Commands.Usage.2", "party", "owner", "<" + LocaleLoader.getString("Commands.Usage.Player") + ">"));

View File

@@ -23,11 +23,45 @@ import java.util.Collections;
import java.util.List;
public class PartyCommand implements TabExecutor {
private static final List<String> PARTY_SUBCOMMANDS;
private static final List<String> XPSHARE_COMPLETIONS = ImmutableList.of("none", "equal");
private static final List<String> ITEMSHARE_COMPLETIONS = ImmutableList.of("none", "equal", "random", "loot", "mining", "herbalism", "woodcutting", "misc");
private final List<String> PARTY_SUBCOMMANDS;
private final List<String> XPSHARE_COMPLETIONS = ImmutableList.of("none", "equal");
private final List<String> ITEMSHARE_COMPLETIONS = ImmutableList.of("none", "equal", "random", "loot", "mining", "herbalism", "woodcutting", "misc");
private final CommandExecutor partyJoinCommand;
private final CommandExecutor partyAcceptCommand;
private final CommandExecutor partyCreateCommand;
private final CommandExecutor partyQuitCommand;
private final CommandExecutor partyXpShareCommand;
private final CommandExecutor partyItemShareCommand;
private final CommandExecutor partyInviteCommand;
private final CommandExecutor partyKickCommand;
private final CommandExecutor partyDisbandCommand;
private final CommandExecutor partyChangeOwnerCommand;
private final CommandExecutor partyLockCommand;
private final CommandExecutor partyChangePasswordCommand;
private final CommandExecutor partyRenameCommand;
private final CommandExecutor partyInfoCommand;
private final CommandExecutor partyHelpCommand;
private final CommandExecutor partyTeleportCommand;
private final CommandExecutor partyAllianceCommand;
public PartyCommand() {
partyJoinCommand = new PartyJoinCommand();
partyAcceptCommand = new PartyAcceptCommand();
partyCreateCommand = new PartyCreateCommand();
partyQuitCommand = new PartyQuitCommand();
partyXpShareCommand = new PartyXpShareCommand();
partyItemShareCommand = new PartyItemShareCommand();
partyInviteCommand = new PartyInviteCommand();
partyKickCommand = new PartyKickCommand();
partyDisbandCommand = new PartyDisbandCommand();
partyChangeOwnerCommand = new PartyChangeOwnerCommand();
partyLockCommand = new PartyLockCommand();
partyChangePasswordCommand = new PartyChangePasswordCommand();
partyRenameCommand = new PartyRenameCommand();
partyInfoCommand = new PartyInfoCommand();
partyHelpCommand = new PartyHelpCommand();
partyTeleportCommand = new PtpCommand();
partyAllianceCommand = new PartyAllianceCommand();
static {
ArrayList<String> subcommands = new ArrayList<>();
for (PartySubcommandType subcommand : PartySubcommandType.values()) {
@@ -38,24 +72,6 @@ public class PartyCommand implements TabExecutor {
PARTY_SUBCOMMANDS = ImmutableList.copyOf(subcommands);
}
private final CommandExecutor partyJoinCommand = new PartyJoinCommand();
private final CommandExecutor partyAcceptCommand = new PartyAcceptCommand();
private final CommandExecutor partyCreateCommand = new PartyCreateCommand();
private final CommandExecutor partyQuitCommand = new PartyQuitCommand();
private final CommandExecutor partyXpShareCommand = new PartyXpShareCommand();
private final CommandExecutor partyItemShareCommand = new PartyItemShareCommand();
private final CommandExecutor partyInviteCommand = new PartyInviteCommand();
private final CommandExecutor partyKickCommand = new PartyKickCommand();
private final CommandExecutor partyDisbandCommand = new PartyDisbandCommand();
private final CommandExecutor partyChangeOwnerCommand = new PartyChangeOwnerCommand();
private final CommandExecutor partyLockCommand = new PartyLockCommand();
private final CommandExecutor partyChangePasswordCommand = new PartyChangePasswordCommand();
private final CommandExecutor partyRenameCommand = new PartyRenameCommand();
private final CommandExecutor partyInfoCommand = new PartyInfoCommand();
private final CommandExecutor partyHelpCommand = new PartyHelpCommand();
private final CommandExecutor partyTeleportCommand = new PtpCommand();
private final CommandExecutor partyAllianceCommand = new PartyAllianceCommand();
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
if (CommandUtils.noConsoleUsage(sender)) {
@@ -73,13 +89,13 @@ public class PartyCommand implements TabExecutor {
return true;
}
if(UserManager.getPlayer(player) == null)
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
if(mcMMOPlayer == null)
{
player.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
return true;
}
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
if (args.length < 1) {
if (!mcMMOPlayer.inParty()) {
@@ -140,31 +156,18 @@ public class PartyCommand implements TabExecutor {
return true;
}
switch (subcommand) {
case XPSHARE:
return partyXpShareCommand.onCommand(sender, command, label, args);
case ITEMSHARE:
return partyItemShareCommand.onCommand(sender, command, label, args);
case KICK:
return partyKickCommand.onCommand(sender, command, label, args);
case DISBAND:
return partyDisbandCommand.onCommand(sender, command, label, args);
case OWNER:
return partyChangeOwnerCommand.onCommand(sender, command, label, args);
case LOCK:
case UNLOCK:
return partyLockCommand.onCommand(sender, command, label, args);
case PASSWORD:
return partyChangePasswordCommand.onCommand(sender, command, label, args);
case RENAME:
return partyRenameCommand.onCommand(sender, command, label, args);
case ALLIANCE:
return partyAllianceCommand.onCommand(sender, command, label, args);
default:
break;
}
return true;
return switch (subcommand) {
case XPSHARE -> partyXpShareCommand.onCommand(sender, command, label, args);
case ITEMSHARE -> partyItemShareCommand.onCommand(sender, command, label, args);
case KICK -> partyKickCommand.onCommand(sender, command, label, args);
case DISBAND -> partyDisbandCommand.onCommand(sender, command, label, args);
case OWNER -> partyChangeOwnerCommand.onCommand(sender, command, label, args);
case LOCK, UNLOCK -> partyLockCommand.onCommand(sender, command, label, args);
case PASSWORD -> partyChangePasswordCommand.onCommand(sender, command, label, args);
case RENAME -> partyRenameCommand.onCommand(sender, command, label, args);
case ALLIANCE -> partyAllianceCommand.onCommand(sender, command, label, args);
default -> true;
};
}
@Override
@@ -179,12 +182,13 @@ public class PartyCommand implements TabExecutor {
return ImmutableList.of();
}
List<String> playerNames = CommandUtils.getOnlinePlayerNames(sender);
switch (subcommand) {
case JOIN:
case INVITE:
case KICK:
case OWNER:
List<String> playerNames = CommandUtils.getOnlinePlayerNames(sender);
return StringUtil.copyPartialMatches(args[1], playerNames, new ArrayList<>(playerNames.size()));
case XPSHARE:
return StringUtil.copyPartialMatches(args[1], XPSHARE_COMPLETIONS, new ArrayList<>(XPSHARE_COMPLETIONS.size()));
@@ -198,17 +202,21 @@ public class PartyCommand implements TabExecutor {
case TELEPORT:
List<String> matches = StringUtil.copyPartialMatches(args[1], PtpCommand.TELEPORT_SUBCOMMANDS, new ArrayList<>(PtpCommand.TELEPORT_SUBCOMMANDS.size()));
if (matches.size() == 0) {
if (matches.isEmpty()) {
Player player = (Player) sender;
final McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
//Not Loaded
if(UserManager.getPlayer(player) == null)
if(mcMMOPlayer == null)
{
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
return ImmutableList.of();
}
Party party = UserManager.getPlayer(player).getParty();
if (mcMMOPlayer.getParty() == null)
return ImmutableList.of();
final Party party = mcMMOPlayer.getParty();
playerNames = party.getOnlinePlayerNames(player);
return StringUtil.copyPartialMatches(args[1], playerNames, new ArrayList<>(playerNames.size()));

View File

@@ -2,7 +2,7 @@ package com.gmail.nossr50.commands.party;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.party.PartyManager;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
@@ -26,16 +26,16 @@ public class PartyCreateCommand implements CommandExecutor {
}
// Check to see if the party exists, and if it does cancel creating a new party
if (PartyManager.checkPartyExistence(player, args[1])) {
if (mcMMO.p.getPartyManager().checkPartyExistence(player, args[1])) {
return true;
}
// Changing parties
if (!PartyManager.changeOrJoinParty(mcMMOPlayer, args[1])) {
if (!mcMMO.p.getPartyManager().changeOrJoinParty(mcMMOPlayer, args[1])) {
return true;
}
PartyManager.createParty(mcMMOPlayer, args[1], getPassword(args));
mcMMO.p.getPartyManager().createParty(mcMMOPlayer, args[1], getPassword(args));
return true;
default:

View File

@@ -1,9 +1,10 @@
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;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
@@ -15,23 +16,24 @@ 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)) {
if (!mcMMO.p.getPartyManager().handlePartyChangeEvent(member, partyName, null, EventReason.KICKED_FROM_PARTY)) {
return true;
}
member.sendMessage(LocaleLoader.getString("Party.Disband"));
}
PartyManager.disbandParty(playerParty);
mcMMO.p.getPartyManager().disbandParty(mcMMOPlayer, playerParty);
return true;
}
sender.sendMessage(LocaleLoader.getString("Commands.Usage.1", "party", "disband"));

View File

@@ -6,7 +6,6 @@ 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;
import org.bukkit.command.Command;
@@ -125,7 +124,7 @@ public class PartyInfoCommand implements CommandExecutor {
* Only show members of the party that this member can see
*/
List<Player> nearMembers = PartyManager.getNearVisibleMembers(mcMMOPlayer);
List<Player> nearMembers = mcMMO.p.getPartyManager().getNearVisibleMembers(mcMMOPlayer);
int membersOnline = party.getVisibleMembers(player).size();
player.sendMessage(LocaleLoader.getString("Commands.Party.Members.Header"));

View File

@@ -4,7 +4,6 @@ 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;
import org.bukkit.command.Command;
@@ -40,19 +39,19 @@ public class PartyInviteCommand implements CommandExecutor {
return true;
}
if (PartyManager.inSameParty(player, target)) {
if (mcMMO.p.getPartyManager().inSameParty(player, target)) {
sender.sendMessage(LocaleLoader.getString("Party.Player.InSameParty", targetName));
return true;
}
if (!PartyManager.canInvite(mcMMOPlayer)) {
if (!mcMMO.p.getPartyManager().canInvite(mcMMOPlayer)) {
player.sendMessage(LocaleLoader.getString("Party.Locked"));
return true;
}
Party playerParty = mcMMOPlayer.getParty();
if (PartyManager.isPartyFull(target, playerParty)) {
if (mcMMO.p.getPartyManager().isPartyFull(target, playerParty)) {
player.sendMessage(LocaleLoader.getString("Commands.Party.PartyFull.Invite", target.getName(), playerParty.toString(), mcMMO.p.getGeneralConfig().getPartyMaxSize()));
return true;
}

View File

@@ -3,7 +3,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.locale.LocaleLoader;
import com.gmail.nossr50.party.PartyManager;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.command.Command;
@@ -51,25 +51,25 @@ public class PartyJoinCommand implements CommandExecutor {
String password = getPassword(args);
// Make sure party passwords match
if (!PartyManager.checkPartyPassword(player, targetParty, password)) {
if (!mcMMO.p.getPartyManager().checkPartyPassword(player, targetParty, password)) {
return true;
}
String partyName = targetParty.getName();
// Changing parties
if (!PartyManager.changeOrJoinParty(mcMMOPlayer, partyName)) {
if (!mcMMO.p.getPartyManager().changeOrJoinParty(mcMMOPlayer, partyName)) {
return true;
}
if(PartyManager.isPartyFull(player, targetParty))
if(mcMMO.p.getPartyManager().isPartyFull(player, targetParty))
{
player.sendMessage(LocaleLoader.getString("Commands.Party.PartyFull", targetParty.toString()));
return true;
}
player.sendMessage(LocaleLoader.getString("Commands.Party.Join", partyName));
PartyManager.addToParty(mcMMOPlayer, targetParty);
mcMMO.p.getPartyManager().addToParty(mcMMOPlayer, targetParty);
return true;
default:

View File

@@ -4,7 +4,6 @@ import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.events.party.McMMOPartyChangeEvent.EventReason;
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;
import org.bukkit.OfflinePlayer;
@@ -37,15 +36,15 @@ public class PartyKickCommand implements CommandExecutor {
Player onlineTarget = target.getPlayer();
String partyName = playerParty.getName();
if (!PartyManager.handlePartyChangeEvent(onlineTarget, partyName, null, EventReason.KICKED_FROM_PARTY)) {
if (!mcMMO.p.getPartyManager().handlePartyChangeEvent(onlineTarget, partyName, null, EventReason.KICKED_FROM_PARTY)) {
return true;
}
PartyManager.processPartyLeaving(UserManager.getPlayer(onlineTarget));
mcMMO.p.getPartyManager().processPartyLeaving(UserManager.getPlayer(onlineTarget));
onlineTarget.sendMessage(LocaleLoader.getString("Commands.Party.Kick", partyName));
}
PartyManager.removeFromParty(target, playerParty);
mcMMO.p.getPartyManager().removeFromParty(target, playerParty);
return true;
}
sender.sendMessage(LocaleLoader.getString("Commands.Usage.2", "party", "kick", "<" + LocaleLoader.getString("Commands.Usage.Player") + ">"));

View File

@@ -4,7 +4,7 @@ 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;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
@@ -26,11 +26,11 @@ public class PartyQuitCommand implements CommandExecutor {
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
Party playerParty = mcMMOPlayer.getParty();
if (!PartyManager.handlePartyChangeEvent(player, playerParty.getName(), null, EventReason.LEFT_PARTY)) {
if (!mcMMO.p.getPartyManager().handlePartyChangeEvent(player, playerParty.getName(), null, EventReason.LEFT_PARTY)) {
return true;
}
PartyManager.removeFromParty(mcMMOPlayer);
mcMMO.p.getPartyManager().removeFromParty(mcMMOPlayer);
sender.sendMessage(LocaleLoader.getString("Commands.Party.Leave"));
return true;
}

View File

@@ -4,7 +4,7 @@ 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;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
@@ -25,7 +25,7 @@ public class PartyRenameCommand implements CommandExecutor {
Party playerParty = mcMMOPlayer.getParty();
String oldPartyName = playerParty.getName();
String newPartyName = args[1];
String newPartyName = args[1].replace(".", "");
// This is to prevent party leaders from spamming other players with the rename message
if (oldPartyName.equalsIgnoreCase(newPartyName)) {
@@ -36,14 +36,14 @@ public class PartyRenameCommand implements CommandExecutor {
Player player = mcMMOPlayer.getPlayer();
// Check to see if the party exists, and if it does cancel renaming the party
if (PartyManager.checkPartyExistence(player, newPartyName)) {
if (mcMMO.p.getPartyManager().checkPartyExistence(player, newPartyName)) {
return true;
}
String leaderName = playerParty.getLeader().getPlayerName();
for (Player member : playerParty.getOnlineMembers()) {
if (!PartyManager.handlePartyChangeEvent(member, oldPartyName, newPartyName, EventReason.CHANGED_PARTIES)) {
if (!mcMMO.p.getPartyManager().handlePartyChangeEvent(member, oldPartyName, newPartyName, EventReason.CHANGED_PARTIES)) {
return true;
}

View File

@@ -2,7 +2,7 @@ package com.gmail.nossr50.commands.party.alliance;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.party.PartyManager;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
@@ -31,7 +31,7 @@ public class PartyAllianceAcceptCommand implements CommandExecutor {
return true;
}
PartyManager.acceptAllianceInvite(mcMMOPlayer);
mcMMO.p.getPartyManager().acceptAllianceInvite(mcMMOPlayer);
return true;
}
sender.sendMessage(LocaleLoader.getString("Commands.Usage.2", "party", "alliance", "accept"));

View File

@@ -5,7 +5,6 @@ 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;
import com.google.common.collect.ImmutableList;
@@ -129,7 +128,7 @@ public class PartyAllianceCommand implements TabExecutor {
}
private void displayMemberInfo(McMMOPlayer mcMMOPlayer) {
List<Player> nearMembers = PartyManager.getNearMembers(mcMMOPlayer);
List<Player> nearMembers = mcMMO.p.getPartyManager().getNearMembers(mcMMOPlayer);
player.sendMessage(LocaleLoader.getString("Commands.Party.Alliance.Members.Header"));
player.sendMessage(playerParty.createMembersList(player));
player.sendMessage(ChatColor.DARK_GRAY + "----------------------------");

View File

@@ -3,7 +3,7 @@ package com.gmail.nossr50.commands.party.alliance;
import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.party.PartyManager;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
@@ -28,7 +28,7 @@ public class PartyAllianceDisbandCommand implements CommandExecutor {
return true;
}
PartyManager.disbandAlliance(player, party, party.getAlly());
mcMMO.p.getPartyManager().disbandAlliance(player, party, party.getAlly());
return true;
}
sender.sendMessage(LocaleLoader.getString("Commands.Usage.2", "party", "alliance", "disband"));

View File

@@ -3,7 +3,7 @@ package com.gmail.nossr50.commands.party.alliance;
import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.party.PartyManager;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.commands.CommandUtils;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.command.Command;
@@ -44,7 +44,7 @@ public class PartyAllianceInviteCommand implements CommandExecutor {
return true;
}
if (PartyManager.inSameParty(player, target)) {
if (mcMMO.p.getPartyManager().inSameParty(player, target)) {
sender.sendMessage(LocaleLoader.getString("Party.Player.InSameParty", targetName));
return true;
}

View File

@@ -7,7 +7,6 @@ import com.gmail.nossr50.datatypes.party.PartyTeleportRecord;
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.runnables.items.TeleportationWarmup;
import com.gmail.nossr50.util.EventUtils;
import com.gmail.nossr50.util.Misc;
@@ -210,7 +209,7 @@ public class PtpCommand implements TabExecutor {
return false;
}
if (!PartyManager.inSameParty(player, target)) {
if (!mcMMO.p.getPartyManager().inSameParty(player, target)) {
player.sendMessage(LocaleLoader.getString("Party.NotInYourParty", targetName));
return false;
}
@@ -250,7 +249,7 @@ public class PtpCommand implements TabExecutor {
if (warmup > 0) {
teleportingPlayer.sendMessage(LocaleLoader.getString("Teleport.Commencing", warmup));
new TeleportationWarmup(mcMMOPlayer, mcMMOTarget).runTaskLater(mcMMO.p, 20 * warmup);
mcMMO.p.getFoliaLib().getImpl().runAtEntityLater(teleportingPlayer, new TeleportationWarmup(mcMMOPlayer, mcMMOTarget), 20 * warmup);
}
else {
EventUtils.handlePartyTeleportEvent(teleportingPlayer, targetPlayer);

View File

@@ -9,6 +9,7 @@ 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.scoreboards.ScoreboardManager;
import com.gmail.nossr50.util.skills.SkillTools;
import com.google.common.collect.ImmutableList;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@@ -62,6 +63,12 @@ public class InspectCommand implements TabExecutor {
sender.sendMessage(CommandUtils.displaySkill(profile, skill));
}
// Sum power level
int powerLevel = 0;
for (PrimarySkillType skill : SkillTools.NON_CHILD_SKILLS)
powerLevel += profile.getSkillLevel(skill);
sender.sendMessage(LocaleLoader.getString("Commands.PowerLevel", powerLevel));
} else {
Player target = mcMMOPlayer.getPlayer();
boolean isVanished = false;
@@ -85,10 +92,16 @@ public class InspectCommand implements TabExecutor {
}
}
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()));
}

View File

@@ -4,6 +4,7 @@ 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;
@@ -97,11 +98,11 @@ public class McrankCommand 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();
@@ -110,7 +111,7 @@ public class McrankCommand implements TabExecutor {
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);
mcMMO.p.getFoliaLib().getImpl().runAsync(new McrankCommandAsyncTask(playerName, sender, useBoard, useChat));
}
private long getCDSeconds(McMMOPlayer mcMMOPlayer, long cooldownMillis) {

View File

@@ -5,6 +5,7 @@ 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;
@@ -97,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();
@@ -114,7 +115,7 @@ public class MctopCommand implements TabExecutor {
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);
mcMMO.p.getFoliaLib().getImpl().runAsync(new MctopCommandAsyncTask(page, skill, sender, useBoard, useChat));
}
private PrimarySkillType extractSkill(CommandSender sender, String skillName) {

View File

@@ -5,9 +5,8 @@ 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.util.random.RandomChanceSkill;
import com.gmail.nossr50.util.random.RandomChanceUtil;
import com.gmail.nossr50.util.skills.SkillActivationType;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.random.ProbabilityUtil;
import com.gmail.nossr50.util.text.TextComponentFactory;
import net.kyori.adventure.text.Component;
import org.bukkit.entity.Player;
@@ -30,7 +29,7 @@ public class AcrobaticsCommand extends SkillCommand {
protected void dataCalculations(Player player, float skillValue) {
// ACROBATICS_DODGE
if (canDodge) {
String[] dodgeStrings = getAbilityDisplayValues(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, player, SubSkillType.ACROBATICS_DODGE);
String[] dodgeStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.ACROBATICS_DODGE);
dodgeChance = dodgeStrings[0];
dodgeChanceLucky = dodgeStrings[1];
}
@@ -38,8 +37,8 @@ public class AcrobaticsCommand extends SkillCommand {
@Override
protected void permissionsCheck(Player player) {
canDodge = canUseSubskill(player, SubSkillType.ACROBATICS_DODGE);
canRoll = canUseSubskill(player, SubSkillType.ACROBATICS_ROLL);
canDodge = Permissions.canUseSubSkill(player, SubSkillType.ACROBATICS_DODGE);
canRoll = Permissions.canUseSubSkill(player, SubSkillType.ACROBATICS_ROLL);
}
@Override
@@ -57,25 +56,7 @@ public class AcrobaticsCommand extends SkillCommand {
if(abstractSubSkill != null)
{
double rollChance, graceChance;
//Chance to roll at half
RandomChanceSkill roll_rcs = new RandomChanceSkill(player, SubSkillType.ACROBATICS_ROLL);
//Chance to graceful roll
RandomChanceSkill grace_rcs = new RandomChanceSkill(player, SubSkillType.ACROBATICS_ROLL);
grace_rcs.setSkillLevel(grace_rcs.getSkillLevel() * 2); //Double Odds
//Chance Stat Calculations
rollChance = RandomChanceUtil.getRandomChanceExecutionChance(roll_rcs);
graceChance = RandomChanceUtil.getRandomChanceExecutionChance(grace_rcs);
//damageThreshold = mcMMO.p.getAdvancedConfig().getRollDamageThreshold();
String[] rollStrings = getAbilityDisplayValues(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, player, SubSkillType.ACROBATICS_ROLL);
//Format
double rollChanceLucky = rollChance * 1.333D;
double graceChanceLucky = graceChance * 1.333D;
String[] rollStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.ACROBATICS_ROLL);
messages.add(getStatMessage(SubSkillType.ACROBATICS_ROLL, rollStrings[0])
+ (isLucky ? LocaleLoader.getString("Perks.Lucky.Bonus", rollStrings[1]) : ""));

View File

@@ -68,8 +68,8 @@ public class AlchemyCommand extends SkillCommand {
@Override
protected void permissionsCheck(Player player) {
canCatalysis = canUseSubskill(player, SubSkillType.ALCHEMY_CATALYSIS);
canConcoctions = canUseSubskill(player, SubSkillType.ALCHEMY_CONCOCTIONS);
canCatalysis = Permissions.canUseSubSkill(player, SubSkillType.ALCHEMY_CATALYSIS);
canConcoctions = Permissions.canUseSubSkill(player, SubSkillType.ALCHEMY_CONCOCTIONS);
}
@Override

View File

@@ -4,8 +4,9 @@ import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.skills.archery.Archery;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.random.ProbabilityUtil;
import com.gmail.nossr50.util.skills.CombatUtils;
import com.gmail.nossr50.util.skills.SkillActivationType;
import com.gmail.nossr50.util.text.TextComponentFactory;
import net.kyori.adventure.text.Component;
import org.bukkit.entity.Player;
@@ -32,14 +33,14 @@ public class ArcheryCommand extends SkillCommand {
protected void dataCalculations(Player player, float skillValue) {
// ARCHERY_ARROW_RETRIEVAL
if (canRetrieve) {
String[] retrieveStrings = getAbilityDisplayValues(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, player, SubSkillType.ARCHERY_ARROW_RETRIEVAL);
String[] retrieveStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.ARCHERY_ARROW_RETRIEVAL);
retrieveChance = retrieveStrings[0];
retrieveChanceLucky = retrieveStrings[1];
}
// ARCHERY_DAZE
if (canDaze) {
String[] dazeStrings = getAbilityDisplayValues(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, player, SubSkillType.ARCHERY_DAZE);
String[] dazeStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.ARCHERY_DAZE);
dazeChance = dazeStrings[0];
dazeChanceLucky = dazeStrings[1];
}
@@ -52,9 +53,9 @@ public class ArcheryCommand extends SkillCommand {
@Override
protected void permissionsCheck(Player player) {
canSkillShot = canUseSubskill(player, SubSkillType.ARCHERY_SKILL_SHOT);
canDaze = canUseSubskill(player, SubSkillType.ARCHERY_DAZE);
canRetrieve = canUseSubskill(player, SubSkillType.ARCHERY_ARROW_RETRIEVAL);
canSkillShot = Permissions.canUseSubSkill(player, SubSkillType.ARCHERY_SKILL_SHOT);
canDaze = Permissions.canUseSubSkill(player, SubSkillType.ARCHERY_DAZE);
canRetrieve = Permissions.canUseSubSkill(player, SubSkillType.ARCHERY_ARROW_RETRIEVAL);
}
@Override
@@ -75,7 +76,7 @@ public class ArcheryCommand extends SkillCommand {
messages.add(getStatMessage(SubSkillType.ARCHERY_SKILL_SHOT, skillShotBonus));
}
if(canUseSubskill(player, SubSkillType.ARCHERY_ARCHERY_LIMIT_BREAK)) {
if(Permissions.canUseSubSkill(player, SubSkillType.ARCHERY_ARCHERY_LIMIT_BREAK)) {
messages.add(getStatMessage(SubSkillType.ARCHERY_ARCHERY_LIMIT_BREAK,
String.valueOf(CombatUtils.getLimitBreakDamageAgainstQuality(player, SubSkillType.ARCHERY_ARCHERY_LIMIT_BREAK, 1000))));
}

View File

@@ -6,9 +6,9 @@ import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.skills.axes.Axes;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.random.ProbabilityUtil;
import com.gmail.nossr50.util.skills.CombatUtils;
import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.skills.SkillActivationType;
import com.gmail.nossr50.util.text.TextComponentFactory;
import net.kyori.adventure.text.Component;
import org.bukkit.entity.Player;
@@ -48,7 +48,7 @@ public class AxesCommand extends SkillCommand {
// CRITICAL HIT
if (canCritical) {
String[] criticalHitStrings = getAbilityDisplayValues(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, player, SubSkillType.AXES_CRITICAL_STRIKES);
String[] criticalHitStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.AXES_CRITICAL_STRIKES);
critChance = criticalHitStrings[0];
critChanceLucky = criticalHitStrings[1];
}
@@ -64,10 +64,10 @@ public class AxesCommand extends SkillCommand {
@Override
protected void permissionsCheck(Player player) {
canSkullSplitter = Permissions.skullSplitter(player) && RankUtils.hasUnlockedSubskill(player, SubSkillType.AXES_SKULL_SPLITTER);
canCritical = canUseSubskill(player, SubSkillType.AXES_CRITICAL_STRIKES);
canAxeMastery = canUseSubskill(player, SubSkillType.AXES_AXE_MASTERY);
canImpact = canUseSubskill(player, SubSkillType.AXES_ARMOR_IMPACT);
canGreaterImpact = canUseSubskill(player, SubSkillType.AXES_GREATER_IMPACT);
canCritical = Permissions.canUseSubSkill(player, SubSkillType.AXES_CRITICAL_STRIKES);
canAxeMastery = Permissions.canUseSubSkill(player, SubSkillType.AXES_AXE_MASTERY);
canImpact = Permissions.canUseSubSkill(player, SubSkillType.AXES_ARMOR_IMPACT);
canGreaterImpact = Permissions.canUseSubSkill(player, SubSkillType.AXES_GREATER_IMPACT);
}
@Override
@@ -96,7 +96,7 @@ public class AxesCommand extends SkillCommand {
+ (hasEndurance ? LocaleLoader.getString("Perks.ActivationTime.Bonus", skullSplitterLengthEndurance) : ""));
}
if(canUseSubskill(player, SubSkillType.AXES_AXES_LIMIT_BREAK)) {
if(Permissions.canUseSubSkill(player, SubSkillType.AXES_AXES_LIMIT_BREAK)) {
messages.add(getStatMessage(SubSkillType.AXES_AXES_LIMIT_BREAK,
String.valueOf(CombatUtils.getLimitBreakDamageAgainstQuality(player, SubSkillType.AXES_AXES_LIMIT_BREAK, 1000))));
}

View File

@@ -0,0 +1,77 @@
package com.gmail.nossr50.commands.skills;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
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.text.TextComponentFactory;
import net.kyori.adventure.text.Component;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import static com.gmail.nossr50.datatypes.skills.SubSkillType.*;
public class CrossbowsCommand extends SkillCommand {
private boolean canTrickShot;
private boolean canPoweredShot;
public CrossbowsCommand() {
super(PrimarySkillType.CROSSBOWS);
}
@Override
protected void dataCalculations(Player player, float skillValue) {
// TODO: Implement data calculations
}
@Override
protected void permissionsCheck(Player player) {
canTrickShot = RankUtils.hasUnlockedSubskill(player, CROSSBOWS_TRICK_SHOT)
&& Permissions.trickShot(player);
canPoweredShot = RankUtils.hasUnlockedSubskill(player, CROSSBOWS_POWERED_SHOT)
&& Permissions.poweredShot(player);
}
@Override
protected List<String> statsDisplay(Player player, float skillValue, boolean hasEndurance, boolean isLucky) {
List<String> messages = new ArrayList<>();
McMMOPlayer mmoPlayer = UserManager.getPlayer(player);
if (mmoPlayer == null) {
return messages;
}
if (canPoweredShot) {
messages.add(getStatMessage(ARCHERY_SKILL_SHOT, percent.format(mmoPlayer.getCrossbowsManager().getDamageBonusPercent(player))));
}
if (canTrickShot) {
messages.add(getStatMessage(CROSSBOWS_TRICK_SHOT,
String.valueOf(mmoPlayer.getCrossbowsManager().getTrickShotMaxBounceCount())));
}
if(Permissions.canUseSubSkill(player, CROSSBOWS_CROSSBOWS_LIMIT_BREAK)) {
messages.add(getStatMessage(CROSSBOWS_CROSSBOWS_LIMIT_BREAK,
String.valueOf(CombatUtils.getLimitBreakDamageAgainstQuality(player, CROSSBOWS_CROSSBOWS_LIMIT_BREAK, 1000))));
}
messages.add(ChatColor.GRAY + "The Crossbows skill is a work in progress and is still being developed, feedback would be appreciated in the mcMMO discord server.");
return messages;
}
@Override
protected List<Component> getTextComponents(Player player) {
List<Component> textComponents = new ArrayList<>();
TextComponentFactory.getSubSkillTextComponents(player, textComponents, PrimarySkillType.CROSSBOWS);
return textComponents;
}
}

View File

@@ -38,7 +38,7 @@ public class ExcavationCommand extends SkillCommand {
@Override
protected void permissionsCheck(Player player) {
canGigaDrill = Permissions.gigaDrillBreaker(player) && RankUtils.hasUnlockedSubskill(player, SubSkillType.EXCAVATION_GIGA_DRILL_BREAKER);
canTreasureHunt = canUseSubskill(player, SubSkillType.EXCAVATION_ARCHAEOLOGY);
canTreasureHunt = Permissions.canUseSubSkill(player, SubSkillType.EXCAVATION_ARCHAEOLOGY);
}
@Override
@@ -54,7 +54,7 @@ public class ExcavationCommand extends SkillCommand {
//messages.add(LocaleLoader.getString("Excavation.Effect.Length", gigaDrillBreakerLength) + (hasEndurance ? LocaleLoader.getString("Perks.ActivationTime.Bonus", gigaDrillBreakerLengthEndurance) : ""));
}
if(canUseSubskill(player, SubSkillType.EXCAVATION_ARCHAEOLOGY)) {
if(Permissions.canUseSubSkill(player, SubSkillType.EXCAVATION_ARCHAEOLOGY)) {
messages.add(getStatMessage(false, false, SubSkillType.EXCAVATION_ARCHAEOLOGY,
percent.format(excavationManager.getArchaelogyExperienceOrbChance() / 100.0D)));
messages.add(getStatMessage(true, false, SubSkillType.EXCAVATION_ARCHAEOLOGY,

View File

@@ -7,8 +7,10 @@ import com.gmail.nossr50.datatypes.treasure.Rarity;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.fishing.FishingManager;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.random.RandomChanceUtil;
import com.gmail.nossr50.util.random.Probability;
import com.gmail.nossr50.util.random.ProbabilityUtil;
import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.text.StringUtils;
import com.gmail.nossr50.util.text.TextComponentFactory;
@@ -79,7 +81,8 @@ public class FishingCommand extends SkillCommand {
// FISHING_SHAKE
if (canShake) {
String[] shakeStrings = RandomChanceUtil.calculateAbilityDisplayValuesStatic(player, PrimarySkillType.FISHING, fishingManager.getShakeChance());
Probability shakeProbability = Probability.ofPercent(fishingManager.getShakeChance());
String[] shakeStrings = ProbabilityUtil.getRNGDisplayValues(shakeProbability);
shakeChance = shakeStrings[0];
shakeChanceLucky = shakeStrings[1];
}
@@ -98,12 +101,12 @@ public class FishingCommand extends SkillCommand {
@Override
protected void permissionsCheck(Player player) {
canTreasureHunt = canUseSubskill(player, SubSkillType.FISHING_TREASURE_HUNTER);
canMagicHunt = canUseSubskill(player, SubSkillType.FISHING_MAGIC_HUNTER) && canUseSubskill(player, SubSkillType.FISHING_TREASURE_HUNTER);
canShake = canUseSubskill(player, SubSkillType.FISHING_SHAKE);
canFishermansDiet = canUseSubskill(player, SubSkillType.FISHING_FISHERMANS_DIET);
canMasterAngler = mcMMO.getCompatibilityManager().getMasterAnglerCompatibilityLayer() != null && canUseSubskill(player, SubSkillType.FISHING_MASTER_ANGLER);
canIceFish = canUseSubskill(player, SubSkillType.FISHING_ICE_FISHING);
canTreasureHunt = Permissions.canUseSubSkill(player, SubSkillType.FISHING_TREASURE_HUNTER);
canMagicHunt = Permissions.canUseSubSkill(player, SubSkillType.FISHING_MAGIC_HUNTER) && Permissions.canUseSubSkill(player, SubSkillType.FISHING_TREASURE_HUNTER);
canShake = Permissions.canUseSubSkill(player, SubSkillType.FISHING_SHAKE);
canFishermansDiet = Permissions.canUseSubSkill(player, SubSkillType.FISHING_FISHERMANS_DIET);
canMasterAngler = mcMMO.getCompatibilityManager().getMasterAnglerCompatibilityLayer() != null && Permissions.canUseSubSkill(player, SubSkillType.FISHING_MASTER_ANGLER);
canIceFish = Permissions.canUseSubSkill(player, SubSkillType.FISHING_ICE_FISHING);
}
@Override

View File

@@ -5,8 +5,8 @@ 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.random.ProbabilityUtil;
import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.skills.SkillActivationType;
import com.gmail.nossr50.util.text.TextComponentFactory;
import net.kyori.adventure.text.Component;
import org.bukkit.Material;
@@ -24,6 +24,8 @@ public class HerbalismCommand extends SkillCommand {
private int farmersDietRank;
private String doubleDropChance;
private String doubleDropChanceLucky;
private String tripleDropChance;
private String tripleDropChanceLucky;
private String hylianLuckChance;
private String hylianLuckChanceLucky;
private String shroomThumbChance;
@@ -35,6 +37,7 @@ public class HerbalismCommand extends SkillCommand {
private boolean canGreenThumbBlocks;
private boolean canFarmersDiet;
private boolean canDoubleDrop;
private boolean canTripleDrop;
private boolean canShroomThumb;
public HerbalismCommand() {
@@ -46,10 +49,16 @@ public class HerbalismCommand extends SkillCommand {
// DOUBLE DROPS
if (canDoubleDrop) {
String[] doubleDropStrings = getAbilityDisplayValues(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, player, SubSkillType.HERBALISM_DOUBLE_DROPS);
String[] doubleDropStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.HERBALISM_DOUBLE_DROPS);
doubleDropChance = doubleDropStrings[0];
doubleDropChanceLucky = doubleDropStrings[1];
}
if (canTripleDrop) {
String[] tripleDropStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.HERBALISM_VERDANT_BOUNTY);
tripleDropChance = tripleDropStrings[0];
tripleDropChanceLucky = tripleDropStrings[1];
}
// FARMERS DIET
if (canFarmersDiet) {
@@ -67,21 +76,21 @@ public class HerbalismCommand extends SkillCommand {
if (canGreenThumbBlocks || canGreenThumbPlants) {
greenThumbStage = RankUtils.getRank(player, SubSkillType.HERBALISM_GREEN_THUMB);
String[] greenThumbStrings = getAbilityDisplayValues(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, player, SubSkillType.HERBALISM_GREEN_THUMB);
String[] greenThumbStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.HERBALISM_GREEN_THUMB);
greenThumbChance = greenThumbStrings[0];
greenThumbChanceLucky = greenThumbStrings[1];
}
// HYLIAN LUCK
if (hasHylianLuck) {
String[] hylianLuckStrings = getAbilityDisplayValues(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, player, SubSkillType.HERBALISM_HYLIAN_LUCK);
String[] hylianLuckStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.HERBALISM_HYLIAN_LUCK);
hylianLuckChance = hylianLuckStrings[0];
hylianLuckChanceLucky = hylianLuckStrings[1];
}
// SHROOM THUMB
if (canShroomThumb) {
String[] shroomThumbStrings = getAbilityDisplayValues(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, player, SubSkillType.HERBALISM_SHROOM_THUMB);
String[] shroomThumbStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.HERBALISM_SHROOM_THUMB);
shroomThumbChance = shroomThumbStrings[0];
shroomThumbChanceLucky = shroomThumbStrings[1];
}
@@ -89,13 +98,14 @@ public class HerbalismCommand extends SkillCommand {
@Override
protected void permissionsCheck(Player player) {
hasHylianLuck = canUseSubskill(player, SubSkillType.HERBALISM_HYLIAN_LUCK);
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 = canUseSubskill(player, SubSkillType.HERBALISM_FARMERS_DIET);
canDoubleDrop = canUseSubskill(player, SubSkillType.HERBALISM_DOUBLE_DROPS) && !mcMMO.p.getGeneralConfig().getDoubleDropsDisabled(skill);
canShroomThumb = canUseSubskill(player, SubSkillType.HERBALISM_SHROOM_THUMB);
canFarmersDiet = Permissions.canUseSubSkill(player, SubSkillType.HERBALISM_FARMERS_DIET);
canDoubleDrop = Permissions.canUseSubSkill(player, SubSkillType.HERBALISM_DOUBLE_DROPS) && !mcMMO.p.getGeneralConfig().getDoubleDropsDisabled(skill);
canTripleDrop = Permissions.canUseSubSkill(player, SubSkillType.HERBALISM_VERDANT_BOUNTY) && !mcMMO.p.getGeneralConfig().getDoubleDropsDisabled(skill);
canShroomThumb = Permissions.canUseSubSkill(player, SubSkillType.HERBALISM_SHROOM_THUMB);
}
@Override
@@ -106,11 +116,16 @@ public class HerbalismCommand extends SkillCommand {
messages.add(getStatMessage(SubSkillType.HERBALISM_DOUBLE_DROPS, doubleDropChance)
+ (isLucky ? LocaleLoader.getString("Perks.Lucky.Bonus", doubleDropChanceLucky) : ""));
}
if (canTripleDrop) {
messages.add(getStatMessage(SubSkillType.HERBALISM_VERDANT_BOUNTY, tripleDropChance)
+ (isLucky ? LocaleLoader.getString("Perks.Lucky.Bonus", tripleDropChanceLucky) : ""));
}
if (canFarmersDiet) {
messages.add(getStatMessage(false, true, SubSkillType.HERBALISM_FARMERS_DIET, String.valueOf(farmersDietRank)));
}
if (canGreenTerra) {
messages.add(getStatMessage(SubSkillType.HERBALISM_GREEN_TERRA, greenTerraLength)
+ (hasEndurance ? LocaleLoader.getString("Perks.ActivationTime.Bonus", greenTerraLengthEndurance) : ""));

View File

@@ -6,8 +6,8 @@ import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.skills.mining.MiningManager;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.random.ProbabilityUtil;
import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.skills.SkillActivationType;
import com.gmail.nossr50.util.text.TextComponentFactory;
import net.kyori.adventure.text.Component;
import org.bukkit.entity.Player;
@@ -18,6 +18,8 @@ import java.util.List;
public class MiningCommand extends SkillCommand {
private String doubleDropChance;
private String doubleDropChanceLucky;
private String tripleDropChance;
private String tripleDropChanceLucky;
private String superBreakerLength;
private String superBreakerLengthEndurance;
@@ -30,6 +32,7 @@ public class MiningCommand extends SkillCommand {
private boolean canSuperBreaker;
private boolean canDoubleDrop;
private boolean canTripleDrop;
private boolean canBlast;
private boolean canBiggerBombs;
private boolean canDemoExpert;
@@ -51,10 +54,17 @@ public class MiningCommand extends SkillCommand {
blastDamageDecrease = percent.format(miningManager.getBlastDamageModifier() / 100.0D);
blastRadiusIncrease = miningManager.getBlastRadiusModifier();
}
// Mastery TRIPLE DROPS
if (canTripleDrop) {
String[] masteryTripleDropStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.MINING_MOTHER_LODE);
tripleDropChance = masteryTripleDropStrings[0];
tripleDropChanceLucky = masteryTripleDropStrings[1];
}
// DOUBLE DROPS
if (canDoubleDrop) {
String[] doubleDropStrings = getAbilityDisplayValues(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, player, SubSkillType.MINING_DOUBLE_DROPS);
String[] doubleDropStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.MINING_DOUBLE_DROPS);
doubleDropChance = doubleDropStrings[0];
doubleDropChanceLucky = doubleDropStrings[1];
}
@@ -72,7 +82,8 @@ public class MiningCommand extends SkillCommand {
canBiggerBombs = RankUtils.hasUnlockedSubskill(player, SubSkillType.MINING_BIGGER_BOMBS) && Permissions.biggerBombs(player);
canBlast = RankUtils.hasUnlockedSubskill(player, SubSkillType.MINING_BLAST_MINING) && Permissions.remoteDetonation(player);
canDemoExpert = RankUtils.hasUnlockedSubskill(player, SubSkillType.MINING_DEMOLITIONS_EXPERTISE) && Permissions.demolitionsExpertise(player);
canDoubleDrop = canUseSubskill(player, SubSkillType.MINING_DOUBLE_DROPS);
canDoubleDrop = Permissions.canUseSubSkill(player, SubSkillType.MINING_DOUBLE_DROPS);
canTripleDrop = Permissions.canUseSubSkill(player, SubSkillType.MINING_MOTHER_LODE);
canSuperBreaker = RankUtils.hasUnlockedSubskill(player, SubSkillType.MINING_SUPER_BREAKER) && Permissions.superBreaker(player);
}
@@ -94,13 +105,18 @@ public class MiningCommand extends SkillCommand {
messages.add(getStatMessage(SubSkillType.MINING_DEMOLITIONS_EXPERTISE, blastDamageDecrease));
//messages.add(LocaleLoader.getString("Mining.Effect.Decrease", blastDamageDecrease));
}
if (canDoubleDrop) {
messages.add(getStatMessage(SubSkillType.MINING_DOUBLE_DROPS, doubleDropChance)
+ (isLucky ? LocaleLoader.getString("Perks.Lucky.Bonus", doubleDropChanceLucky) : ""));
//messages.add(LocaleLoader.getString("Mining.Effect.DropChance", doubleDropChance) + (isLucky ? LocaleLoader.getString("Perks.Lucky.Bonus", doubleDropChanceLucky) : ""));
}
if(canTripleDrop) {
messages.add(getStatMessage(SubSkillType.MINING_MOTHER_LODE, tripleDropChance)
+ (isLucky ? LocaleLoader.getString("Perks.Lucky.Bonus", tripleDropChanceLucky) : ""));
}
if (canSuperBreaker) {
messages.add(getStatMessage(SubSkillType.MINING_SUPER_BREAKER, superBreakerLength)
+ (hasEndurance ? LocaleLoader.getString("Perks.ActivationTime.Bonus", superBreakerLengthEndurance) : ""));

View File

@@ -27,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)

View File

@@ -0,0 +1,40 @@
package com.gmail.nossr50.commands.skills;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.BukkitCommandIssuer;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Conditions;
import co.aikar.commands.annotation.Default;
import com.gmail.nossr50.commands.CommandManager;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
@CommandPermission("mcmmo.commands.mmopower")
@CommandAlias("mmopower|mmopowerlevel|powerlevel")
public class PowerLevelCommand extends BaseCommand {
private final @NotNull mcMMO pluginRef;
public PowerLevelCommand(@NotNull mcMMO pluginRef) {
this.pluginRef = pluginRef;
}
@Default
@Conditions(CommandManager.POWER_LEVEL_CONDITION)
public void processCommand(String[] args) {
BukkitCommandIssuer bukkitCommandIssuer = (BukkitCommandIssuer) getCurrentCommandIssuer();
Player player = bukkitCommandIssuer.getPlayer();
McMMOPlayer mmoPlayer = UserManager.getPlayer(player); //Should never be null at this point because its caught in an ACF validation
if (mmoPlayer == null) {
return;
}
int powerLevel = mmoPlayer.getPowerLevel();
mmoPlayer.getPlayer().sendMessage(ChatColor.DARK_AQUA + "Your " + ChatColor.GOLD + "[mcMMO]" + ChatColor.DARK_AQUA + " power level is: " + ChatColor.GREEN + powerLevel);
}
}

View File

@@ -11,8 +11,8 @@ import com.gmail.nossr50.skills.repair.RepairManager;
import com.gmail.nossr50.skills.repair.repairables.Repairable;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.random.ProbabilityUtil;
import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.skills.SkillActivationType;
import com.gmail.nossr50.util.text.TextComponentFactory;
import net.kyori.adventure.text.Component;
import org.bukkit.Material;
@@ -68,7 +68,7 @@ public class RepairCommand extends SkillCommand {
// SUPER REPAIR
if (canSuperRepair) {
String[] superRepairStrings = getAbilityDisplayValues(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, player, SubSkillType.REPAIR_SUPER_REPAIR);
String[] superRepairStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.REPAIR_SUPER_REPAIR);
superRepairChance = superRepairStrings[0];
superRepairChanceLucky = superRepairStrings[1];
}
@@ -76,9 +76,9 @@ public class RepairCommand extends SkillCommand {
@Override
protected void permissionsCheck(Player player) {
canSuperRepair = canUseSubskill(player, SubSkillType.REPAIR_SUPER_REPAIR);
canMasterRepair = canUseSubskill(player, SubSkillType.REPAIR_REPAIR_MASTERY);
canArcaneForge = canUseSubskill(player, SubSkillType.REPAIR_ARCANE_FORGING);
canSuperRepair = Permissions.canUseSubSkill(player, SubSkillType.REPAIR_SUPER_REPAIR);
canMasterRepair = Permissions.canUseSubSkill(player, SubSkillType.REPAIR_REPAIR_MASTERY);
canArcaneForge = Permissions.canUseSubSkill(player, SubSkillType.REPAIR_ARCANE_FORGING);
canRepairDiamond = Permissions.repairMaterialType(player, MaterialType.DIAMOND);
canRepairGold = Permissions.repairMaterialType(player, MaterialType.GOLD);
canRepairIron = Permissions.repairMaterialType(player, MaterialType.IRON);

View File

@@ -5,6 +5,7 @@ import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.skills.salvage.Salvage;
import com.gmail.nossr50.skills.salvage.SalvageManager;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.text.TextComponentFactory;
@@ -30,8 +31,8 @@ public class SalvageCommand extends SkillCommand {
@Override
protected void permissionsCheck(Player player) {
canScrapCollector = canUseSubskill(player, SubSkillType.SALVAGE_SCRAP_COLLECTOR);
canArcaneSalvage = canUseSubskill(player, SubSkillType.SALVAGE_ARCANE_SALVAGE);
canScrapCollector = Permissions.canUseSubSkill(player, SubSkillType.SALVAGE_SCRAP_COLLECTOR);
canArcaneSalvage = Permissions.canUseSubSkill(player, SubSkillType.SALVAGE_ARCANE_SALVAGE);
}
@Override

View File

@@ -5,16 +5,12 @@ 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;
@@ -32,7 +28,6 @@ import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Set;
public abstract class SkillCommand implements TabExecutor {
protected PrimarySkillType skill;
@@ -59,18 +54,17 @@ 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
@@ -116,8 +110,21 @@ public abstract class SkillCommand implements TabExecutor {
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);
}
@@ -161,7 +168,7 @@ public abstract class SkillCommand implements TabExecutor {
*/
Set<PrimarySkillType> parents = FamilyTree.getParents(skill);
var parents = mcMMO.p.getSkillTools().getChildSkillParents(skill);
//TODO: Add JSON here
/*player.sendMessage(parent.getName() + " - " + LocaleLoader.getString("Effects.Level.Overhaul", mcMMOPlayer.getSkillLevel(parent), mcMMOPlayer.getSkillXpLevel(parent), mcMMOPlayer.getXpToLevel(parent)))*/
@@ -211,7 +218,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();
}
@@ -220,9 +227,9 @@ 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[] getAbilityDisplayValues(SkillActivationType skillActivationType, Player player, SubSkillType subSkill) {
// return RandomChanceUtil.calculateAbilityDisplayValues(skillActivationType, player, subSkill);
// }
protected String[] calculateLengthDisplayValues(Player player, float skillValue) {
int maxLength = mcMMO.p.getSkillTools().getSuperAbilityMaxLength(mcMMO.p.getSkillTools().getSuperAbility(skill));
@@ -285,14 +292,4 @@ 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

@@ -5,8 +5,8 @@ import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.random.ProbabilityUtil;
import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.skills.SkillActivationType;
import com.gmail.nossr50.util.text.TextComponentFactory;
import net.kyori.adventure.text.Component;
import org.bukkit.entity.Player;
@@ -39,14 +39,14 @@ public class SmeltingCommand extends SkillCommand {
// FLUX MINING
/*if (canFluxMine) {
String[] fluxMiningStrings = getAbilityDisplayValues(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, player, SubSkillType.SMELTING_FLUX_MINING);
String[] fluxMiningStrings = getRNGDisplayValues(player, SubSkillType.SMELTING_FLUX_MINING);
str_fluxMiningChance = fluxMiningStrings[0];
str_fluxMiningChanceLucky = fluxMiningStrings[1];
}*/
// SECOND SMELT
if (canSecondSmelt) {
String[] secondSmeltStrings = getAbilityDisplayValues(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, player, SubSkillType.SMELTING_SECOND_SMELT);
String[] secondSmeltStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.SMELTING_SECOND_SMELT);
str_secondSmeltChance = secondSmeltStrings[0];
str_secondSmeltChanceLucky = secondSmeltStrings[1];
}
@@ -54,8 +54,8 @@ public class SmeltingCommand extends SkillCommand {
@Override
protected void permissionsCheck(Player player) {
canFuelEfficiency = canUseSubskill(player, SubSkillType.SMELTING_FUEL_EFFICIENCY);
canSecondSmelt = canUseSubskill(player, SubSkillType.SMELTING_SECOND_SMELT);
canFuelEfficiency = Permissions.canUseSubSkill(player, SubSkillType.SMELTING_FUEL_EFFICIENCY);
canSecondSmelt = Permissions.canUseSubSkill(player, SubSkillType.SMELTING_SECOND_SMELT);
//canFluxMine = canUseSubskill(player, SubSkillType.SMELTING_FLUX_MINING);
canUnderstandTheArt = Permissions.vanillaXpBoost(player, skill) && RankUtils.hasUnlockedSubskill(player, SubSkillType.SMELTING_UNDERSTANDING_THE_ART);
}

View File

@@ -6,9 +6,10 @@ 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.random.ProbabilityUtil;
import com.gmail.nossr50.util.skills.CombatUtils;
import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.skills.SkillActivationType;
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;
@@ -38,7 +39,7 @@ public class SwordsCommand extends SkillCommand {
protected void dataCalculations(Player player, float skillValue) {
// SWORDS_COUNTER_ATTACK
if (canCounter) {
String[] counterStrings = getAbilityDisplayValues(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, player, SubSkillType.SWORDS_COUNTER_ATTACK);
String[] counterStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.SWORDS_COUNTER_ATTACK);
counterChance = counterStrings[0];
counterChanceLucky = counterStrings[1];
}
@@ -69,8 +70,8 @@ public class SwordsCommand extends SkillCommand {
@Override
protected void permissionsCheck(Player player) {
canRupture = canUseSubskill(player, SubSkillType.SWORDS_RUPTURE);
canCounter = canUseSubskill(player, SubSkillType.SWORDS_COUNTER_ATTACK);
canRupture = SkillUtils.canUseSubskill(player, SubSkillType.SWORDS_RUPTURE);
canCounter = SkillUtils.canUseSubskill(player, SubSkillType.SWORDS_COUNTER_ATTACK);
canSerratedStrike = RankUtils.hasUnlockedSubskill(player, SubSkillType.SWORDS_SERRATED_STRIKES) && Permissions.serratedStrikes(player);
}
@@ -91,9 +92,9 @@ public class SwordsCommand extends SkillCommand {
ruptureLengthSecondsAgainstMobs));
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.SubSkill.Rupture.Stat.ExplosionDamage", ruptureExplosionDamageAgainstPlayers, ruptureExplosionDamageAgainstMobs));
messages.add(LocaleLoader.getString("Swords.Combat.Rupture.Note"));
messages.add(LocaleLoader.getString("Swords.Combat.Rupture.Note.Update.One"));
}
if (canSerratedStrike) {
@@ -101,13 +102,13 @@ public class SwordsCommand extends SkillCommand {
+ (hasEndurance ? LocaleLoader.getString("Perks.ActivationTime.Bonus", serratedStrikesLengthEndurance) : ""));
}
if(canUseSubskill(player, SubSkillType.SWORDS_STAB))
if(SkillUtils.canUseSubskill(player, SubSkillType.SWORDS_STAB))
{
messages.add(getStatMessage(SubSkillType.SWORDS_STAB,
String.valueOf(UserManager.getPlayer(player).getSwordsManager().getStabDamage())));
}
if(canUseSubskill(player, SubSkillType.SWORDS_SWORDS_LIMIT_BREAK)) {
if(SkillUtils.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

@@ -5,7 +5,7 @@ import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.skills.taming.Taming;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.skills.SkillActivationType;
import com.gmail.nossr50.util.random.ProbabilityUtil;
import com.gmail.nossr50.util.text.TextComponentFactory;
import net.kyori.adventure.text.Component;
import org.bukkit.entity.EntityType;
@@ -35,7 +35,7 @@ public class TamingCommand extends SkillCommand {
@Override
protected void dataCalculations(Player player, float skillValue) {
if (canGore) {
String[] goreStrings = getAbilityDisplayValues(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, player, SubSkillType.TAMING_GORE);
String[] goreStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.TAMING_GORE);
goreChance = goreStrings[0];
goreChanceLucky = goreStrings[1];
}
@@ -43,15 +43,15 @@ public class TamingCommand extends SkillCommand {
@Override
protected void permissionsCheck(Player player) {
canBeastLore = canUseSubskill(player, SubSkillType.TAMING_BEAST_LORE);
canBeastLore = Permissions.canUseSubSkill(player, SubSkillType.TAMING_BEAST_LORE);
canCallWild = Permissions.callOfTheWild(player, EntityType.HORSE) || Permissions.callOfTheWild(player, EntityType.WOLF) || Permissions.callOfTheWild(player, EntityType.OCELOT);
canEnvironmentallyAware = canUseSubskill(player, SubSkillType.TAMING_ENVIRONMENTALLY_AWARE);
canFastFood = canUseSubskill(player, SubSkillType.TAMING_FAST_FOOD_SERVICE);
canGore = canUseSubskill(player, SubSkillType.TAMING_GORE);
canSharpenedClaws = canUseSubskill(player, SubSkillType.TAMING_SHARPENED_CLAWS);
canShockProof = canUseSubskill(player, SubSkillType.TAMING_SHOCK_PROOF);
canThickFur = canUseSubskill(player, SubSkillType.TAMING_THICK_FUR);
canHolyHound = canUseSubskill(player, SubSkillType.TAMING_HOLY_HOUND);
canEnvironmentallyAware = Permissions.canUseSubSkill(player, SubSkillType.TAMING_ENVIRONMENTALLY_AWARE);
canFastFood = Permissions.canUseSubSkill(player, SubSkillType.TAMING_FAST_FOOD_SERVICE);
canGore = Permissions.canUseSubSkill(player, SubSkillType.TAMING_GORE);
canSharpenedClaws = Permissions.canUseSubSkill(player, SubSkillType.TAMING_SHARPENED_CLAWS);
canShockProof = Permissions.canUseSubSkill(player, SubSkillType.TAMING_SHOCK_PROOF);
canThickFur = Permissions.canUseSubSkill(player, SubSkillType.TAMING_THICK_FUR);
canHolyHound = Permissions.canUseSubSkill(player, SubSkillType.TAMING_HOLY_HOUND);
}
@Override

View File

@@ -0,0 +1,62 @@
package com.gmail.nossr50.commands.skills;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.skills.CombatUtils;
import com.gmail.nossr50.util.skills.SkillUtils;
import com.gmail.nossr50.util.text.TextComponentFactory;
import net.kyori.adventure.text.Component;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import static com.gmail.nossr50.datatypes.skills.SubSkillType.TRIDENTS_IMPALE;
import static com.gmail.nossr50.datatypes.skills.SubSkillType.TRIDENTS_TRIDENTS_LIMIT_BREAK;
public class TridentsCommand extends SkillCommand {
public TridentsCommand() {
super(PrimarySkillType.TRIDENTS);
}
@Override
protected void dataCalculations(Player player, float skillValue) {}
@Override
protected void permissionsCheck(Player player) {}
@Override
protected List<String> statsDisplay(Player player, float skillValue, boolean hasEndurance, boolean isLucky) {
List<String> messages = new ArrayList<>();
McMMOPlayer mmoPlayer = UserManager.getPlayer(player);
if (mmoPlayer == null) {
return messages;
}
if(SkillUtils.canUseSubskill(player, TRIDENTS_TRIDENTS_LIMIT_BREAK)) {
messages.add(getStatMessage(TRIDENTS_TRIDENTS_LIMIT_BREAK,
String.valueOf(CombatUtils.getLimitBreakDamageAgainstQuality(player, TRIDENTS_TRIDENTS_LIMIT_BREAK, 1000))));
}
if(SkillUtils.canUseSubskill(player, TRIDENTS_IMPALE)) {
messages.add(getStatMessage(TRIDENTS_IMPALE,
String.valueOf(mmoPlayer.getTridentsManager().impaleDamageBonus())));
}
messages.add(ChatColor.GRAY + "The Tridents skill is a work in progress and is still being developed, feedback would be appreciated in the mcMMO discord server.");
return messages;
}
@Override
protected List<Component> getTextComponents(Player player) {
List<Component> textComponents = new ArrayList<>();
TextComponentFactory.getSubSkillTextComponents(player, textComponents, PrimarySkillType.TRIDENTS);
return textComponents;
}
}

View File

@@ -5,9 +5,9 @@ import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.random.ProbabilityUtil;
import com.gmail.nossr50.util.skills.CombatUtils;
import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.skills.SkillActivationType;
import com.gmail.nossr50.util.text.TextComponentFactory;
import net.kyori.adventure.text.Component;
import org.bukkit.entity.Player;
@@ -40,7 +40,7 @@ public class UnarmedCommand extends SkillCommand {
protected void dataCalculations(Player player, float skillValue) {
// UNARMED_ARROW_DEFLECT
if (canDeflect) {
String[] deflectStrings = getAbilityDisplayValues(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, player, SubSkillType.UNARMED_ARROW_DEFLECT);
String[] deflectStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.UNARMED_ARROW_DEFLECT);
deflectChance = deflectStrings[0];
deflectChanceLucky = deflectStrings[1];
}
@@ -54,7 +54,7 @@ public class UnarmedCommand extends SkillCommand {
// UNARMED_DISARM
if (canDisarm) {
String[] disarmStrings = getAbilityDisplayValues(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, player, SubSkillType.UNARMED_DISARM);
String[] disarmStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.UNARMED_DISARM);
disarmChance = disarmStrings[0];
disarmChanceLucky = disarmStrings[1];
}
@@ -66,7 +66,7 @@ public class UnarmedCommand extends SkillCommand {
// IRON GRIP
if (canIronGrip) {
String[] ironGripStrings = getAbilityDisplayValues(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, player, SubSkillType.UNARMED_IRON_GRIP);
String[] ironGripStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.UNARMED_IRON_GRIP);
ironGripChance = ironGripStrings[0];
ironGripChanceLucky = ironGripStrings[1];
}
@@ -75,10 +75,10 @@ public class UnarmedCommand extends SkillCommand {
@Override
protected void permissionsCheck(Player player) {
canBerserk = RankUtils.hasUnlockedSubskill(player, SubSkillType.UNARMED_BERSERK) && Permissions.berserk(player);
canIronArm = canUseSubskill(player, SubSkillType.UNARMED_STEEL_ARM_STYLE);
canDeflect = canUseSubskill(player, SubSkillType.UNARMED_ARROW_DEFLECT);
canDisarm = canUseSubskill(player, SubSkillType.UNARMED_DISARM);
canIronGrip = canUseSubskill(player, SubSkillType.UNARMED_IRON_GRIP);
canIronArm = Permissions.canUseSubSkill(player, SubSkillType.UNARMED_STEEL_ARM_STYLE);
canDeflect = Permissions.canUseSubSkill(player, SubSkillType.UNARMED_ARROW_DEFLECT);
canDisarm = Permissions.canUseSubSkill(player, SubSkillType.UNARMED_DISARM);
canIronGrip = Permissions.canUseSubSkill(player, SubSkillType.UNARMED_IRON_GRIP);
// TODO: Apparently we forgot about block cracker?
}
@@ -114,7 +114,7 @@ public class UnarmedCommand extends SkillCommand {
//messages.add(LocaleLoader.getString("Unarmed.Ability.Chance.IronGrip", ironGripChance) + (isLucky ? LocaleLoader.getString("Perks.Lucky.Bonus", ironGripChanceLucky) : ""));
}
if(canUseSubskill(player, SubSkillType.UNARMED_UNARMED_LIMIT_BREAK)) {
if(Permissions.canUseSubSkill(player, SubSkillType.UNARMED_UNARMED_LIMIT_BREAK)) {
messages.add(getStatMessage(SubSkillType.UNARMED_UNARMED_LIMIT_BREAK,
String.valueOf(CombatUtils.getLimitBreakDamageAgainstQuality(player, SubSkillType.UNARMED_UNARMED_LIMIT_BREAK, 1000))));
}

View File

@@ -5,8 +5,8 @@ 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.random.ProbabilityUtil;
import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.skills.SkillActivationType;
import com.gmail.nossr50.util.text.TextComponentFactory;
import net.kyori.adventure.text.Component;
import org.bukkit.entity.Player;
@@ -18,15 +18,15 @@ public class WoodcuttingCommand extends SkillCommand {
private String treeFellerLength;
private String treeFellerLengthEndurance;
private String doubleDropChance;
private String tripleDropChance;
private String doubleDropChanceLucky;
private String tripleDropChanceLucky;
private boolean canTreeFell;
private boolean canLeafBlow;
private boolean canDoubleDrop;
private boolean canTripleDrop;
private boolean canKnockOnWood;
private boolean canSplinter;
private boolean canBarkSurgeon;
private boolean canNaturesBounty;
public WoodcuttingCommand() {
super(PrimarySkillType.WOODCUTTING);
@@ -38,7 +38,14 @@ public class WoodcuttingCommand extends SkillCommand {
if (canDoubleDrop) {
setDoubleDropClassicChanceStrings(player);
}
//Clean Cuts
if(canTripleDrop) {
String[] tripleDropStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.WOODCUTTING_CLEAN_CUTS);
tripleDropChance = tripleDropStrings[0];
tripleDropChanceLucky = tripleDropStrings[1];
}
// TREE FELLER
if (canTreeFell) {
String[] treeFellerStrings = calculateLengthDisplayValues(player, skillValue);
@@ -48,7 +55,7 @@ public class WoodcuttingCommand extends SkillCommand {
}
private void setDoubleDropClassicChanceStrings(Player player) {
String[] doubleDropStrings = getAbilityDisplayValues(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, player, SubSkillType.WOODCUTTING_HARVEST_LUMBER);
String[] doubleDropStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.WOODCUTTING_HARVEST_LUMBER);
doubleDropChance = doubleDropStrings[0];
doubleDropChanceLucky = doubleDropStrings[1];
}
@@ -56,14 +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 = canUseSubskill(player, SubSkillType.WOODCUTTING_HARVEST_LUMBER)
&& !mcMMO.p.getGeneralConfig().getDoubleDropsDisabled(skill)
canDoubleDrop = !mcMMO.p.getGeneralConfig().getDoubleDropsDisabled(skill)
&& Permissions.canUseSubSkill(player, SubSkillType.WOODCUTTING_HARVEST_LUMBER)
&& RankUtils.getRank(player, SubSkillType.WOODCUTTING_HARVEST_LUMBER) >= 1;
canLeafBlow = canUseSubskill(player, SubSkillType.WOODCUTTING_LEAF_BLOWER);
canKnockOnWood = canTreeFell && 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);*/
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);
}
@Override
@@ -75,6 +80,12 @@ public class WoodcuttingCommand extends SkillCommand {
+ (isLucky ? LocaleLoader.getString("Perks.Lucky.Bonus", doubleDropChanceLucky) : ""));
}
if(canTripleDrop) {
messages.add(getStatMessage(SubSkillType.WOODCUTTING_CLEAN_CUTS, tripleDropChance)
+ (isLucky ? LocaleLoader.getString("Perks.Lucky.Bonus", tripleDropChanceLucky) : ""));
}
if (canKnockOnWood) {
String lootNote;

View File

@@ -10,7 +10,7 @@ import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class AdvancedConfig extends AutoUpdateConfigLoader {
public class AdvancedConfig extends BukkitConfig {
public AdvancedConfig(File dataFolder) {
super("advanced.yml", dataFolder);
@@ -99,8 +99,7 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
}
/* AXES */
if(getAxeMasteryRankDamageMultiplier() < 0)
{
if (getAxeMasteryRankDamageMultiplier() < 0) {
reason.add("Skills.Axes.AxeMastery.RankDamageMultiplier should be at least 0!");
}
@@ -404,12 +403,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);
@@ -417,11 +422,12 @@ 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
* It returns a different value depending on whether 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);
@@ -429,28 +435,33 @@ 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
* It returns a different value depending on whether 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) {
@@ -462,35 +473,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);
}
@@ -509,6 +514,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()
@@ -557,7 +563,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);
@@ -598,110 +603,260 @@ 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 getCatalysisMaxBonusLevel() { return config.getInt("Skills.Alchemy.Catalysis.MaxBonusLevel", 1000); }
public int getCatalysisMaxBonusLevel() {
if (mcMMO.isRetroModeEnabled()) {
return config.getInt("Skills.Alchemy.Catalysis.MaxBonusLevel.RetroMode", 1000);
} else {
return config.getInt("Skills.Alchemy.Catalysis.MaxBonusLevel.Standard", 100);
}
}
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);
}
/* 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);
}
/* CROSSBOWS */
public double getPoweredShotRankDamageMultiplier() {
return config.getDouble("Skills.Crossbows.PoweredShot.RankDamageMultiplier", 10.0D);
}
public double getPoweredShotDamageMax() {
return config.getDouble("Skills.Archery.SkillShot.MaxDamage", 9.0D);
}
/* EXCAVATION */
//Nothing to configure, everything is already configurable in config.yml
/* FISHING */
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 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 double getMasterAnglerBoatModifier() {return config.getDouble("Skills.Fishing.MasterAngler.BoatModifier", 2.0); }
public double getMasterAnglerBiomeModifier() {return config.getDouble("Skills.Fishing.MasterAngler.BiomeModifier", 2.0); }
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 boolean isBlastMiningBonusDropsEnabled() {
return config.getBoolean("Skills.Mining.BlastMining.Bonus_Drops.Enabled", true);
}
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);
}
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 int getRepairMasteryMaxLevel() {
return config.getInt("Skills.Repair.RepairMastery.MaxBonusLevel", 100);
}
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 getAllowEnchantedRepairMaterials() {
return config.getBoolean("Skills.Repair.Use_Enchanted_Materials", false);
}
public boolean getArcaneSalvageEnchantDowngradeEnabled() { return config.getBoolean("Skills.Salvage.ArcaneSalvage.EnchantDowngradeEnabled", true); }
public boolean getArcaneSalvageEnchantLossEnabled() { return config.getBoolean("Skills.Salvage.ArcaneSalvage.EnchantLossEnabled", true); }
public boolean getArcaneForgingEnchantLossEnabled() {
return config.getBoolean("Skills.Repair.ArcaneForging.May_Lose_Enchants", 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); }
public double getArcaneForgingKeepEnchantsChance(int rank) {
return config.getDouble("Skills.Repair.ArcaneForging.Keep_Enchants_Chance.Rank_" + rank);
}
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 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 double getFluxMiningChance() { return config.getDouble("Skills.Smelting.FluxMining.Chance", 33.0D); }
public double getFluxMiningChance() {
return config.getDouble("Skills.Smelting.FluxMining.Chance", 33.0D);
}
/* SWORDS */
public double getRuptureTickDamage(boolean isTargetPlayer, int rank) {
@@ -731,35 +886,68 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
return config.getDouble(root + rank, 33);
}
public double getCounterModifier() { return config.getDouble("Skills.Swords.CounterAttack.DamageModifier", 2.0D); }
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); }
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 double getGoreModifier() { return config.getDouble("Skills.Taming.Gore.Modifier", 2.0D); }
public double getGoreModifier() {
return config.getDouble("Skills.Taming.Gore.Modifier", 2.0D);
}
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 double getThickFurModifier() { return config.getDouble("Skills.Taming.ThickFur.Modifier", 2.0D); }
public double getPummelChance() {
return config.getDouble("Skills.Taming.Pummel.Chance", 10.0D);
}
public double getShockProofModifier() { return config.getDouble("Skills.Taming.ShockProof.Modifier", 6.0D); }
public double getThickFurModifier() {
return config.getDouble("Skills.Taming.ThickFur.Modifier", 2.0D);
}
public double getSharpenedClawsBonus() { return config.getDouble("Skills.Taming.SharpenedClaws.Bonus", 2.0D); }
public double getShockProofModifier() {
return config.getDouble("Skills.Taming.ShockProof.Modifier", 6.0D);
}
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 getSharpenedClawsBonus() {
return config.getDouble("Skills.Taming.SharpenedClaws.Bonus", 2.0D);
}
public double getMinHorseJumpStrength() {
return config.getDouble("Skills.Taming.CallOfTheWild.MinHorseJumpStrength", 0.7D);
}
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,167 +0,0 @@
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.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 {
mcMMO.p.getLogger().info("Saving changes to config file - "+fileName);
config.save(configFile);
} catch (IOException e) {
e.printStackTrace();
}
}
protected @NotNull FileConfiguration getInternalConfig() {
return YamlConfiguration.loadConfiguration(mcMMO.p.getResourceAsReader(fileName));
}
@Override
protected void loadFile() {
super.loadFile();
FileConfiguration internalConfig = YamlConfiguration.loadConfiguration(mcMMO.p.getResourceAsReader(fileName));
Set<String> configKeys = config.getKeys(true);
Set<String> internalConfigKeys = internalConfig.getKeys(true);
boolean needSave = false;
Set<String> oldKeys = new HashSet<>(configKeys);
oldKeys.removeAll(internalConfigKeys);
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()) {
needSave = true;
}
//
// for (String key : oldKeys) {
// mcMMO.p.debug("Detected potentially unused key: " + key);
// //config.set(key, null);
// }
for (String key : newKeys) {
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(mcMMO.p.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 (!mcMMO.p.getConfig().getBoolean("General.Config_Update_Overwrite", true)) {
saveName += ".new";
}
File newSaveFile = new File(dataFolder, saveName);
FileWriter fileWriter = new FileWriter(newSaveFile.getAbsolutePath());
BufferedWriter writer = new BufferedWriter(fileWriter);
writer.write(output);
writer.flush();
writer.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}

View File

@@ -0,0 +1,106 @@
package com.gmail.nossr50.config;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.LogUtils;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
public abstract class AutoUpdateLegacyConfigLoader extends LegacyConfigLoader {
public AutoUpdateLegacyConfigLoader(String relativePath, String fileName, File dataFolder) {
super(relativePath, fileName, dataFolder);
}
public AutoUpdateLegacyConfigLoader(String fileName, File dataFolder) {
super(fileName, dataFolder);
}
@Deprecated
public AutoUpdateLegacyConfigLoader(String relativePath, String fileName) {
super(relativePath, fileName);
}
@Deprecated
public AutoUpdateLegacyConfigLoader(String fileName) {
super(fileName);
}
protected void saveConfig() {
try {
LogUtils.debug(mcMMO.p.getLogger(), "Saving changes to config file - " + fileName);
config.options().indent(2);
config.save(configFile);
} catch (IOException e) {
e.printStackTrace();
}
}
protected @NotNull FileConfiguration getInternalConfig() {
return YamlConfiguration.loadConfiguration(mcMMO.p.getResourceAsReader(fileName));
}
@Override
protected void loadFile() {
super.loadFile();
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()) {
LogUtils.debug(mcMMO.p.getLogger(), "old key(s) in \"" + fileName + "\"");
for (String key : oldKeys) {
LogUtils.debug(mcMMO.p.getLogger(), " old-key:" + key);
}
}
// keys present in template that are not in current file
Set<String> newKeys = new HashSet<>(internalConfigKeys);
newKeys.removeAll(configKeys);
if (!newKeys.isEmpty()) {
needSave = true;
}
for (String key : newKeys) {
LogUtils.debug(mcMMO.p.getLogger(), "Adding new key: " + key + " = " + internalConfig.get(key));
config.set(key, internalConfig.get(key));
}
if (needSave) {
// 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 (!mcMMO.p.getConfig().getBoolean("General.Config_Update_Overwrite", true)) {
saveName += ".new";
}
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,181 @@
package com.gmail.nossr50.config;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.LogUtils;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
public abstract class BukkitConfig {
boolean copyDefaults = true;
protected final String fileName;
protected final File configFile;
protected YamlConfiguration defaultYamlConfig;
protected YamlConfiguration config;
protected @NotNull final File dataFolder;
private boolean savedDefaults = false;
public BukkitConfig(@NotNull String fileName, @NotNull File dataFolder, boolean copyDefaults) {
LogUtils.debug(mcMMO.p.getLogger(), "Initializing config: " + fileName);
this.copyDefaults = copyDefaults;
this.fileName = fileName;
this.dataFolder = dataFolder;
configFile = new File(dataFolder, fileName);
this.defaultYamlConfig = saveDefaultConfigToDisk();
this.config = initConfig();
updateFile();
LogUtils.debug(mcMMO.p.getLogger(), "Config initialized: " + fileName);
}
public BukkitConfig(@NotNull String fileName, @NotNull File dataFolder) {
this(fileName, dataFolder, true);
}
public BukkitConfig(@NotNull String fileName) {
this(fileName, mcMMO.p.getDataFolder());
}
public BukkitConfig(@NotNull String fileName, boolean copyDefaults) {
this(fileName, mcMMO.p.getDataFolder(), copyDefaults);
}
/**
* Update the file on the disk by copying out any new and missing defaults
*/
public void updateFile() {
try {
config.save(configFile);
if(copyDefaults && !savedDefaults) {
copyMissingDefaultsFromResource();
savedDefaults = true;
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Copies missing keys and values from the internal resource config within the JAR
*/
private void copyMissingDefaultsFromResource() {
boolean updated = false;
for (String key : defaultYamlConfig.getKeys(true)) {
if (!config.contains(key)) {
config.set(key, defaultYamlConfig.get(key));
updated = true;
}
}
if (updated) {
updateFile();
}
}
/**
* Copies the config from the JAR to defaults/<fileName>
*/
YamlConfiguration saveDefaultConfigToDisk() {
LogUtils.debug(mcMMO.p.getLogger(), "Copying default config to disk: " + fileName + " to defaults/" + fileName);
try(InputStream inputStream = mcMMO.p.getResource(fileName)) {
if(inputStream == null) {
mcMMO.p.getLogger().severe("Unable to copy default config: " + fileName);
return null;
}
//Save default file into defaults/<fileName>
File defaultsFolder = new File(dataFolder, "defaults");
if (!defaultsFolder.exists()) {
defaultsFolder.mkdir();
}
File defaultFile = new File(defaultsFolder, fileName);
Path path = defaultFile.toPath();
Files.copy(inputStream, path, java.nio.file.StandardCopyOption.REPLACE_EXISTING);
// Load file into YAML config
YamlConfiguration defaultYamlConfig = new YamlConfiguration();
defaultYamlConfig.load(defaultFile);
return defaultYamlConfig;
} catch (IOException | InvalidConfigurationException e) {
e.printStackTrace();
}
return null;
}
YamlConfiguration initConfig() {
if (!configFile.exists()) {
LogUtils.debug(mcMMO.p.getLogger(), "User config file not found, copying a default config to disk: " + fileName);
mcMMO.p.saveResource(fileName, false);
}
LogUtils.debug(mcMMO.p.getLogger(), "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()) {
LogUtils.debug(mcMMO.p.getLogger(), "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() {
LogUtils.debug(mcMMO.p.getLogger(), "You are using an old version of the " + fileName + " file.");
LogUtils.debug(mcMMO.p.getLogger(), "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;
}
}

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() {
@@ -40,8 +40,10 @@ public class ChatConfig extends AutoUpdateConfigLoader {
}
/**
* Whether or not to use display names for players in target {@link ChatChannel}
* Whether 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) {
@@ -49,6 +51,12 @@ public class ChatConfig extends AutoUpdateConfigLoader {
return config.getBoolean(key, true);
}
public boolean isConsoleIncludedInAudience(@NotNull ChatChannel chatChannel) {
String key = "Chat.Channels." + StringUtils.getCapitalized(chatChannel.toString()) + ".Send_To_Console";
return config.getBoolean(key, true);
}
public boolean isSpyingAutomatic() {
return config.getBoolean("Chat.Channels.Party.Spies.Automatically_Enable_Spying", false);
}

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() {
@@ -37,23 +35,25 @@ public class CoreSkillsConfig extends AutoUpdateConfigLoader {
*/
/**
* Whether or not a skill is enabled
* Whether 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
* Whether 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

@@ -1,27 +1,28 @@
package com.gmail.nossr50.config;
import com.gmail.nossr50.mcMMO;
import org.bukkit.configuration.file.FileConfiguration;
import com.gmail.nossr50.util.LogUtils;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.List;
public abstract class ConfigLoader {
protected String fileName;
@Deprecated
public abstract class LegacyConfigLoader {
protected final File configFile;
protected FileConfiguration config;
protected @NotNull final File dataFolder;
protected final @NotNull File dataFolder;
protected String fileName;
protected YamlConfiguration config;
public ConfigLoader(String relativePath, String fileName, @NotNull File dataFolder) {
public LegacyConfigLoader(String relativePath, String fileName, @NotNull File dataFolder) {
this.fileName = fileName;
this.dataFolder = dataFolder;
configFile = new File(dataFolder, relativePath + File.separator + fileName);
loadFile();
}
public ConfigLoader(String fileName, @NotNull File dataFolder) {
public LegacyConfigLoader(String fileName, @NotNull File dataFolder) {
this.fileName = fileName;
this.dataFolder = dataFolder;
configFile = new File(dataFolder, fileName);
@@ -29,7 +30,7 @@ public abstract class ConfigLoader {
}
@Deprecated
public ConfigLoader(String relativePath, String fileName) {
public LegacyConfigLoader(String relativePath, String fileName) {
this.fileName = fileName;
configFile = new File(mcMMO.p.getDataFolder(), relativePath + File.separator + fileName);
this.dataFolder = mcMMO.p.getDataFolder();
@@ -37,7 +38,7 @@ public abstract class ConfigLoader {
}
@Deprecated
public ConfigLoader(String fileName) {
public LegacyConfigLoader(String fileName) {
this.fileName = fileName;
configFile = new File(mcMMO.p.getDataFolder(), fileName);
this.dataFolder = mcMMO.p.getDataFolder();
@@ -46,17 +47,15 @@ public abstract class ConfigLoader {
protected void loadFile() {
if (!configFile.exists()) {
mcMMO.p.debug("Creating mcMMO " + fileName + " File...");
LogUtils.debug(mcMMO.p.getLogger(), "Creating mcMMO " + fileName + " File...");
try {
mcMMO.p.saveResource(fileName, false); // Normal files
}
catch (IllegalArgumentException ex) {
} catch (IllegalArgumentException ex) {
mcMMO.p.saveResource(configFile.getParentFile().getName() + File.separator + fileName, false); // Mod files
}
}
else {
mcMMO.p.debug("Loading mcMMO " + fileName + " File...");
} else {
LogUtils.debug(mcMMO.p.getLogger(), "Loading mcMMO " + fileName + " File...");
}
config = YamlConfiguration.loadConfiguration(configFile);
@@ -78,9 +77,8 @@ public abstract class ConfigLoader {
protected void validate() {
if (validateKeys()) {
mcMMO.p.debug("No errors found in " + fileName + "!");
}
else {
LogUtils.debug(mcMMO.p.getLogger(), "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;

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() {

View File

@@ -3,35 +3,34 @@ 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 com.gmail.nossr50.util.LogUtils;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
public class RankConfig extends AutoUpdateConfigLoader {
public class RankConfig extends BukkitConfig {
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<>();
@@ -46,12 +45,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);
@@ -59,33 +59,37 @@ 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));
return config.getInt(key, defaultYamlConfig.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) {
@@ -125,62 +129,57 @@ public class RankConfig extends AutoUpdateConfigLoader {
private void resetRankValue(@NotNull SubSkillType subSkillType, int rank, boolean retroMode) {
String key = getRankAddressKey(subSkillType, rank, retroMode);
int defaultValue = getInternalConfig().getInt(key);
int defaultValue = defaultYamlConfig.getInt(key);
config.set(key, defaultValue);
mcMMO.p.getLogger().info(key +" SET -> " + defaultValue);
LogUtils.debug(mcMMO.p.getLogger(), 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;
mcMMO.p.getLogger().info("(FIXING CONFIG) mcMMO is correcting a few mistakes found in your skill rank config setup");
LogUtils.debug(mcMMO.p.getLogger(), "(FIXING CONFIG) mcMMO is correcting a few mistakes found in your skill rank config setup");
for(SubSkillType subSkillType : badSkillSetup) {
mcMMO.p.getLogger().info("(FIXING CONFIG) Resetting rank config settings for skill named - "+subSkillType.toString());
for (SubSkillType subSkillType : badSkillSetup) {
LogUtils.debug(mcMMO.p.getLogger(), "(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
mcMMO.p.getLogger().info("(CONFIG ISSUE) You have the ranks for the subskill "+ subSkillType.toString()+" set up poorly, sequential ranks should have ascending requirements");
LogUtils.debug(mcMMO.p.getLogger(), "(CONFIG ISSUE) You have the ranks for the subskill " + subSkillType + " set up poorly, sequential ranks should have ascending requirements");
badSkillSetup.add(subSkillType);
}
}
@@ -188,9 +187,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);
@@ -198,6 +196,6 @@ public class RankConfig extends AutoUpdateConfigLoader {
resetRankValue(subSkillType, index, false);
}
saveConfig();
updateFile();
}
}

View File

@@ -1,47 +1,42 @@
package com.gmail.nossr50.config;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.LogUtils;
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)
{
mcMMO.p.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) {
LogUtils.debug(mcMMO.p.getLogger(), "[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)
{
mcMMO.p.getLogger().info("[mcMMO] Sound pitch cannot be below 0 for "+soundType.toString());
if (!soundType.usesCustomPitch()) {
if (config.getDouble("Sounds." + soundType + ".Pitch") < 0) {
LogUtils.debug(mcMMO.p.getLogger(), "[mcMMO] Sound pitch cannot be below 0 for " + soundType);
return false;
}
}
@@ -49,23 +44,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,12 @@ public class WorldBlacklist {
closeRead(fileReader);
}
plugin.getLogger().info(blacklist.size()+" entries in mcMMO World Blacklist");
if(blacklist.size() > 0)
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 +86,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() {
@@ -34,7 +34,8 @@ public class ExperienceConfig extends AutoUpdateConfigLoader {
}
@Override
protected void loadKeys() {}
protected void loadKeys() {
}
@Override
protected boolean validateKeys() {
@@ -139,204 +140,291 @@ 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()), 1);
}
/* 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(String entity) {
return config.getDouble("Experience_Values.Combat.Multiplier." + entity);
}
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)
{
//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"))
public int getXp(PrimarySkillType skill, Material material) {
return getXpHelper(skill, StringUtils.getExplicitConfigMaterialString(material),
StringUtils.getFriendlyConfigMaterialString(material),
StringUtils.getWildcardConfigMaterialString(material));
}
public int getXp(PrimarySkillType skill, BlockState blockState) {
Material material = blockState.getType();
return getXp(skill, material);
}
public int getXp(PrimarySkillType skill, Block block) {
Material material = block.getType();
return getXp(skill, material);
}
public int getXp(PrimarySkillType skill, BlockData data) {
return getXpHelper(skill, StringUtils.getExplicitConfigBlockDataString(data),
StringUtils.getFriendlyConfigBlockDataString(data),
StringUtils.getWildcardConfigBlockDataString(data));
}
private int getXpHelper(PrimarySkillType skill, String explicitString, String friendlyString, String wildcardString) {
if (explicitString.equalsIgnoreCase("LILY_PAD")) {
return 0;
}
String baseString = "Experience_Values." + StringUtils.getCapitalized(skill.toString()) + ".";
String explicitString = baseString + StringUtils.getExplicitConfigMaterialString(material);
if (config.contains(explicitString))
return config.getInt(explicitString);
String friendlyString = baseString + StringUtils.getFriendlyConfigMaterialString(material);
if (config.contains(friendlyString))
return config.getInt(friendlyString);
String wildcardString = baseString + StringUtils.getWildcardConfigMaterialString(material);
if (config.contains(wildcardString))
return config.getInt(wildcardString);
String[] configStrings = {explicitString, friendlyString, wildcardString};
for (String configString : configStrings) {
String fullPath = baseString + configString;
if (config.contains(fullPath)) {
return config.getInt(fullPath);
}
}
return 0;
}
/* Materials */
public int getXp(PrimarySkillType skill, BlockState blockState)
{
Material data = blockState.getType();
String baseString = "Experience_Values." + StringUtils.getCapitalized(skill.toString()) + ".";
String explicitString = baseString + StringUtils.getExplicitConfigMaterialString(data);
if (config.contains(explicitString))
return config.getInt(explicitString);
String friendlyString = baseString + StringUtils.getFriendlyConfigMaterialString(data);
if (config.contains(friendlyString))
return config.getInt(friendlyString);
String wildcardString = baseString + StringUtils.getWildcardConfigMaterialString(data);
if (config.contains(wildcardString))
return config.getInt(wildcardString);
return 0;
public boolean doesBlockGiveSkillXP(PrimarySkillType skill, Material material) {
return doesBlockGiveSkillXPHelper(skill, StringUtils.getExplicitConfigMaterialString(material),
StringUtils.getFriendlyConfigMaterialString(material),
StringUtils.getWildcardConfigMaterialString(material));
}
/* Materials */
public int getXp(PrimarySkillType skill, Block block)
{
Material data = block.getType();
String baseString = "Experience_Values." + StringUtils.getCapitalized(skill.toString()) + ".";
String explicitString = baseString + StringUtils.getExplicitConfigMaterialString(data);
if (config.contains(explicitString))
return config.getInt(explicitString);
String friendlyString = baseString + StringUtils.getFriendlyConfigMaterialString(data);
if (config.contains(friendlyString))
return config.getInt(friendlyString);
String wildcardString = baseString + StringUtils.getWildcardConfigMaterialString(data);
if (config.contains(wildcardString))
return config.getInt(wildcardString);
return 0;
public boolean doesBlockGiveSkillXP(PrimarySkillType skill, BlockData data) {
return doesBlockGiveSkillXPHelper(skill, StringUtils.getExplicitConfigBlockDataString(data),
StringUtils.getFriendlyConfigBlockDataString(data),
StringUtils.getWildcardConfigBlockDataString(data));
}
/* Materials */
public int getXp(PrimarySkillType skill, BlockData data)
{
private boolean doesBlockGiveSkillXPHelper(PrimarySkillType skill, String explicitString, String friendlyString, String wildcardString) {
String baseString = "Experience_Values." + StringUtils.getCapitalized(skill.toString()) + ".";
String explicitString = baseString + StringUtils.getExplicitConfigBlockDataString(data);
if (config.contains(explicitString))
return config.getInt(explicitString);
String friendlyString = baseString + StringUtils.getFriendlyConfigBlockDataString(data);
if (config.contains(friendlyString))
return config.getInt(friendlyString);
String wildcardString = baseString + StringUtils.getWildcardConfigBlockDataString(data);
if (config.contains(wildcardString))
return config.getInt(wildcardString);
return 0;
String[] configStrings = {explicitString, friendlyString, wildcardString};
for (String configString : configStrings) {
String fullPath = baseString + configString;
if (config.contains(fullPath)) {
return true;
}
}
return false;
}
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))
return true;
String friendlyString = baseString + StringUtils.getFriendlyConfigMaterialString(data);
if (config.contains(friendlyString))
return true;
String wildcardString = baseString + StringUtils.getWildcardConfigMaterialString(data);
return config.contains(wildcardString);
}
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))
return true;
String friendlyString = baseString + StringUtils.getFriendlyConfigBlockDataString(data);
if (config.contains(friendlyString))
return true;
String wildcardString = baseString + StringUtils.getWildcardConfigBlockDataString(data);
return config.contains(wildcardString);
}
/*
* 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 +432,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 +445,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

@@ -29,7 +29,7 @@ public class ArmorConfigManager {
continue;
}
modManager.registerCustomArmor(new CustomArmorConfig(fileName));
modManager.registerCustomArmor(new CustomArmorLegacyConfig(fileName));
}
}
}

View File

@@ -29,7 +29,7 @@ public class BlockConfigManager {
continue;
}
modManager.registerCustomBlocks(new CustomBlockConfig(fileName));
modManager.registerCustomBlocks(new CustomBlockLegacyConfig(fileName));
}
}
}

View File

@@ -1,6 +1,6 @@
package com.gmail.nossr50.config.mods;
import com.gmail.nossr50.config.ConfigLoader;
import com.gmail.nossr50.config.LegacyConfigLoader;
import com.gmail.nossr50.datatypes.skills.ItemType;
import com.gmail.nossr50.datatypes.skills.MaterialType;
import com.gmail.nossr50.mcMMO;
@@ -13,17 +13,15 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class CustomArmorConfig extends ConfigLoader {
public class CustomArmorLegacyConfig extends LegacyConfigLoader {
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<Repairable> repairables = new ArrayList<>();
private boolean needsUpdate = false;
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<Repairable> repairables = new ArrayList<>();
protected CustomArmorConfig(String fileName) {
protected CustomArmorLegacyConfig(String fileName) {
super("mods", fileName);
loadKeys();
}

View File

@@ -1,6 +1,6 @@
package com.gmail.nossr50.config.mods;
import com.gmail.nossr50.config.ConfigLoader;
import com.gmail.nossr50.config.LegacyConfigLoader;
import com.gmail.nossr50.datatypes.mods.CustomBlock;
import com.gmail.nossr50.mcMMO;
import org.bukkit.Material;
@@ -11,20 +11,18 @@ import java.util.HashMap;
import java.util.List;
import java.util.Set;
public class CustomBlockConfig extends ConfigLoader {
public class CustomBlockLegacyConfig extends LegacyConfigLoader {
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;
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<>();
protected CustomBlockConfig(String fileName) {
protected CustomBlockLegacyConfig(String fileName) {
super("mods", fileName);
loadKeys();
}
@@ -85,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

@@ -1,6 +1,6 @@
package com.gmail.nossr50.config.mods;
import com.gmail.nossr50.config.ConfigLoader;
import com.gmail.nossr50.config.LegacyConfigLoader;
import com.gmail.nossr50.datatypes.mods.CustomEntity;
import com.gmail.nossr50.mcMMO;
import org.apache.commons.lang.ClassUtils;
@@ -9,11 +9,11 @@ import org.bukkit.inventory.ItemStack;
import java.util.HashMap;
public class CustomEntityConfig extends ConfigLoader {
public class CustomEntityLegacyConfig extends LegacyConfigLoader {
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) {
protected CustomEntityLegacyConfig(String fileName) {
super("mods", fileName);
loadKeys();
}
@@ -31,8 +31,7 @@ public class CustomEntityConfig extends ConfigLoader {
try {
clazz = ClassUtils.getClass(className);
}
catch (ClassNotFoundException e) {
} catch (ClassNotFoundException e) {
mcMMO.p.getLogger().warning("Invalid class (" + className + ") detected for " + entityName + ".");
mcMMO.p.getLogger().warning("This custom entity may not function properly.");
}

View File

@@ -1,6 +1,6 @@
package com.gmail.nossr50.config.mods;
import com.gmail.nossr50.config.ConfigLoader;
import com.gmail.nossr50.config.LegacyConfigLoader;
import com.gmail.nossr50.datatypes.mods.CustomTool;
import com.gmail.nossr50.datatypes.skills.ItemType;
import com.gmail.nossr50.datatypes.skills.MaterialType;
@@ -15,21 +15,18 @@ import java.util.HashMap;
import java.util.List;
import java.util.Set;
public class CustomToolConfig extends ConfigLoader {
public class CustomToolLegacyConfig extends LegacyConfigLoader {
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 HashMap<Material, CustomTool> customToolMap = new HashMap<>();
public List<Repairable> repairables = new ArrayList<>();
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> customPickaxes = 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<>();
protected CustomToolConfig(String fileName) {
protected CustomToolLegacyConfig(String fileName) {
super("mods", fileName);
loadKeys();
}

View File

@@ -29,7 +29,7 @@ public class EntityConfigManager {
continue;
}
modManager.registerCustomEntities(new CustomEntityConfig(fileName));
modManager.registerCustomEntities(new CustomEntityLegacyConfig(fileName));
}
}
}

View File

@@ -29,7 +29,7 @@ public class ToolConfigManager {
continue;
}
modManager.registerCustomTools(new CustomToolConfig(fileName));
modManager.registerCustomTools(new CustomToolLegacyConfig(fileName));
}
}
}

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

@@ -0,0 +1,21 @@
package com.gmail.nossr50.config.party;
import com.gmail.nossr50.config.BukkitConfig;
import java.io.File;
public class PartyConfig extends BukkitConfig {
public PartyConfig(File dataFolder) {
super("party.yml", dataFolder);
validate();
}
@Override
protected void loadKeys() {
}
public boolean isPartyEnabled() {
return config.getBoolean("Party.Enabled", true);
}
}

View File

@@ -1,8 +1,9 @@
package com.gmail.nossr50.config.skills.alchemy;
import com.gmail.nossr50.config.ConfigLoader;
import com.gmail.nossr50.config.LegacyConfigLoader;
import com.gmail.nossr50.datatypes.skills.alchemy.AlchemyPotion;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.LogUtils;
import org.bukkit.ChatColor;
import org.bukkit.Color;
import org.bukkit.Material;
@@ -15,7 +16,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class PotionConfig extends ConfigLoader {
public class PotionConfig extends LegacyConfigLoader {
private static PotionConfig instance;
private final List<ItemStack> concoctionsIngredientsTierOne = new ArrayList<>();
@@ -95,13 +96,12 @@ public class PotionConfig extends ConfigLoader {
if (potion != null) {
potionMap.put(potionName, potion);
pass++;
}
else {
} else {
fail++;
}
}
mcMMO.p.debug("Loaded " + pass + " Alchemy potions, skipped " + fail + ".");
LogUtils.debug(mcMMO.p.getLogger(), "Loaded " + pass + " Alchemy potions, skipped " + fail + ".");
}
/**
@@ -114,13 +114,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 +130,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 +155,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 +174,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 +239,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 +248,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 +266,7 @@ public class PotionConfig extends ConfigLoader {
}
return null;
}
public Color calculateAverageColor(List<Color> colors) {
int red = 0;
int green = 0;
@@ -280,7 +276,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,24 +1,25 @@
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;
import com.gmail.nossr50.skills.repair.repairables.Repairable;
import com.gmail.nossr50.skills.repair.repairables.RepairableFactory;
import com.gmail.nossr50.util.ItemUtils;
import com.gmail.nossr50.util.LogUtils;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
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);
public RepairConfig(String fileName, boolean copyDefaults) {
super(fileName, copyDefaults);
notSupported = new HashSet<>();
loadKeys();
}
@@ -48,7 +49,7 @@ public class RepairConfig extends ConfigLoader {
Material itemMaterial = Material.matchMaterial(key);
if (itemMaterial == null) {
//mcMMO.p.getLogger().info("No support for repair item "+key+ " in this version of Minecraft, skipping.");
//LogUtils.debug(mcMMO.p.getLogger(), "No support for repair item "+key+ " in this version of Minecraft, skipping.");
notSupported.add(key); //Collect names of unsupported items
continue;
}
@@ -62,33 +63,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 +115,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 +136,7 @@ public class RepairConfig extends ConfigLoader {
// Minimum Quantity
int minimumQuantity = config.getInt("Repairables." + key + ".MinimumQuantity");
if(minimumQuantity == 0) {
if (minimumQuantity == 0) {
minimumQuantity = -1;
}
@@ -158,21 +148,21 @@ 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(", ");
}
}
mcMMO.p.getLogger().info(stringBuilder.toString());
mcMMO.p.getLogger().info("Items using materials that are not supported will simply be skipped.");
LogUtils.debug(mcMMO.p.getLogger(), stringBuilder.toString());
LogUtils.debug(mcMMO.p.getLogger(), "Items using materials that are not supported will simply be skipped.");
}
}

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, true);
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);
RepairConfig rConfig = new RepairConfig(fileName, false);
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;
@@ -8,6 +8,7 @@ import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.salvage.salvageables.Salvageable;
import com.gmail.nossr50.skills.salvage.salvageables.SalvageableFactory;
import com.gmail.nossr50.util.ItemUtils;
import com.gmail.nossr50.util.LogUtils;
import com.gmail.nossr50.util.skills.SkillUtils;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
@@ -15,20 +16,21 @@ import org.bukkit.inventory.ItemStack;
import java.io.IOException;
import java.util.*;
import java.util.logging.Level;
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);
public SalvageConfig(String fileName, boolean copyDefaults) {
super(fileName, copyDefaults);
notSupported = new HashSet<>();
loadKeys();
}
@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,18 +42,18 @@ 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)) {
mcMMO.p.getLogger().info("Fixing incorrect Salvage quantities on Netherite gear, this will only run once...");
for(String namespacedkey : mcMMO.getMaterialMapStore().getNetheriteArmor()) {
if (mcMMO.getUpgradeManager().shouldUpgrade(UpgradeType.FIX_NETHERITE_SALVAGE_QUANTITIES)) {
mcMMO.p.getLogger().log(Level.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); //TODO: Doesn't make sense to default to 4 for everything
}
try {
config.save(getFile());
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.FIX_NETHERITE_SALVAGE_QUANTITIES);
mcMMO.p.getLogger().info("Fixed incorrect Salvage quantities for Netherite gear!");
LogUtils.debug(mcMMO.p.getLogger(), "Fixed incorrect Salvage quantities for Netherite gear!");
} catch (IOException e) {
mcMMO.p.getLogger().info("Unable to fix Salvage config, please delete the salvage yml file to generate a new one.");
LogUtils.debug(mcMMO.p.getLogger(), "Unable to fix Salvage config, please delete the salvage yml file to generate a new one.");
e.printStackTrace();
}
}
@@ -78,33 +80,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 +124,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,26 +167,26 @@ 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(", ");
}
}
mcMMO.p.getLogger().info(stringBuilder.toString());
mcMMO.p.getLogger().info("Items using materials that are not supported will simply be skipped.");
LogUtils.debug(mcMMO.p.getLogger(), stringBuilder.toString());
LogUtils.debug(mcMMO.p.getLogger(), "Items using materials that are not supported will simply be skipped.");
}
}
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) {

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, true);
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);
SalvageConfig salvageConfig = new SalvageConfig(fileName, false);
salvageables.addAll(salvageConfig.getLoadedSalvageables());
}
}
public List<Salvageable> getLoadedSalvageables() {
return salvageables;
return new ArrayList<>(salvageables);
}
}

View File

@@ -1,9 +1,10 @@
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;
import com.gmail.nossr50.util.LogUtils;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
@@ -18,17 +19,17 @@ 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);
super(FILENAME, false);
loadKeys();
validate();
}
@@ -45,33 +46,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 +96,7 @@ public class FishingTreasureConfig extends ConfigLoader {
for (EntityType entity : EntityType.values()) {
if (entity.isAlive()) {
loadTreasures("Shake." + entity.toString());
loadTreasures("Shake." + entity);
}
}
}
@@ -175,7 +182,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 +199,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 +211,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 +239,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 +283,6 @@ public class FishingTreasureConfig extends ConfigLoader {
}
if (noErrorsInConfig(reason)) {
if (isFishing) {
addFishingTreasure(rarity, new FishingTreasure(item, xp));
@@ -307,26 +313,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) {
LogUtils.debug(mcMMO.p.getLogger(), "[Fishing Treasure Init] Could not find any enchantments which matched the user defined enchantment named: " + str);
}
}
}
@@ -344,7 +351,7 @@ 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) {
@@ -374,10 +381,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,9 +1,11 @@
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.BlockUtils;
import com.gmail.nossr50.util.LogUtils;
import com.gmail.nossr50.util.text.StringUtils;
import org.bukkit.ChatColor;
import org.bukkit.Material;
@@ -20,7 +22,7 @@ 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";
@@ -32,10 +34,10 @@ public class TreasureConfig extends ConfigLoader {
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);
super(FILENAME, false);
loadKeys();
validate();
}
@@ -115,32 +117,32 @@ public class TreasureConfig extends ConfigLoader {
DropLevelKeyConversionType conversionType;
//Check for legacy drop level values and convert
if(getWrongKeyValue(type, treasureName, DropLevelKeyConversionType.LEGACY) != -1) {
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) {
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) {
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()) {
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) {
if (dropLevel == -1) {
mcMMO.p.getLogger().severe("Could not find a Level_Requirement entry for treasure " + treasureName);
mcMMO.p.getLogger().severe("Skipping treasure");
continue;
@@ -227,7 +229,7 @@ public class TreasureConfig extends ConfigLoader {
for (String dropper : dropList) {
if (dropper.equals("Bushes")) {
AddHylianTreasure(StringUtils.getFriendlyConfigMaterialString(Material.FERN), hylianTreasure);
AddHylianTreasure(StringUtils.getFriendlyConfigMaterialString(Material.TALL_GRASS), hylianTreasure);
AddHylianTreasure(StringUtils.getFriendlyConfigMaterialString(BlockUtils.getShortGrass()), hylianTreasure);
for (Material species : Tag.SAPLINGS.getValues())
AddHylianTreasure(StringUtils.getFriendlyConfigMaterialString(species), hylianTreasure);
@@ -258,7 +260,7 @@ public class TreasureConfig extends ConfigLoader {
}
//Apply our fix
if(shouldWeUpdateFile) {
if (shouldWeUpdateFile) {
try {
config.save(getFile());
} catch (IOException e) {
@@ -272,18 +274,18 @@ public class TreasureConfig extends ConfigLoader {
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");
LogUtils.debug(mcMMO.p.getLogger(), "(" + 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");
LogUtils.debug(mcMMO.p.getLogger(), "(" + 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) {
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
}
@@ -291,11 +293,11 @@ public class TreasureConfig extends ConfigLoader {
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");
LogUtils.debug(mcMMO.p.getLogger(), "(" + 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) {
if (wrongKeyValueRetro != -1) {
config.set(type + "." + treasureName + LEVEL_REQUIREMENT_RETRO_MODE, wrongKeyValueRetro);
}
@@ -306,22 +308,12 @@ public class TreasureConfig extends ConfigLoader {
}
private int getWrongKeyValue(String type, String treasureName, DropLevelKeyConversionType dropLevelKeyConversionType) {
switch (dropLevelKeyConversionType) {
case LEGACY:
return config.getInt(type + "." + treasureName + LEGACY_DROP_LEVEL, -1);
case WRONG_KEY_STANDARD:
return config.getInt(type + "." + treasureName + WRONG_KEY_VALUE_STANDARD, -1);
case WRONG_KEY_RETRO:
return config.getInt(type + "." + treasureName + WRONG_KEY_VALUE_RETRO, -1);
}
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);
};
return -1;
}
private enum DropLevelKeyConversionType {
LEGACY,
WRONG_KEY_STANDARD,
WRONG_KEY_RETRO
}
private void AddHylianTreasure(String dropper, HylianTreasure treasure) {
@@ -329,4 +321,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

@@ -2,6 +2,7 @@ package com.gmail.nossr50.database;
import com.gmail.nossr50.datatypes.database.DatabaseType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.LogUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -9,6 +10,7 @@ import java.util.logging.Logger;
public class DatabaseManagerFactory {
private static Class<? extends DatabaseManager> customManager = null;
public static final String MYSQL_DRIVER = "com.mysql.cj.jdbc.Driver";
public static DatabaseManager getDatabaseManager(@NotNull String userFilePath, @NotNull Logger logger, long purgeTime, int startingLevel) {
if (customManager != null) {
@@ -16,17 +18,17 @@ public class DatabaseManagerFactory {
return createDefaultCustomDatabaseManager();
}
catch (Exception e) {
mcMMO.p.debug("Could not create custom database manager");
LogUtils.debug(mcMMO.p.getLogger(), "Could not create custom database manager");
e.printStackTrace();
}
catch (Throwable e) {
mcMMO.p.debug("Failed to create custom database manager");
LogUtils.debug(mcMMO.p.getLogger(), "Failed to create custom database manager");
e.printStackTrace();
}
mcMMO.p.debug("Falling back on " + (mcMMO.p.getGeneralConfig().getUseMySQL() ? "SQL" : "Flatfile") + " database");
LogUtils.debug(mcMMO.p.getLogger(), "Falling back on " + (mcMMO.p.getGeneralConfig().getUseMySQL() ? "SQL" : "Flatfile") + " database");
}
return mcMMO.p.getGeneralConfig().getUseMySQL() ? new SQLDatabaseManager() : new FlatFileDatabaseManager(userFilePath, logger, purgeTime, startingLevel);
return mcMMO.p.getGeneralConfig().getUseMySQL() ? new SQLDatabaseManager(logger, MYSQL_DRIVER) : new FlatFileDatabaseManager(userFilePath, logger, purgeTime, startingLevel);
}
/**
@@ -62,16 +64,16 @@ public class DatabaseManagerFactory {
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");
LogUtils.debug(mcMMO.p.getLogger(), "Using FlatFile Database");
return new FlatFileDatabaseManager(userFilePath, logger, purgeTime, startingLevel);
case SQL:
mcMMO.p.getLogger().info("Using SQL Database");
return new SQLDatabaseManager();
LogUtils.debug(mcMMO.p.getLogger(), "Using SQL Database");
return new SQLDatabaseManager(logger, "com.mysql.cj.jdbc.Driver");
case CUSTOM:
try {
mcMMO.p.getLogger().info("Attempting to use Custom Database");
LogUtils.debug(mcMMO.p.getLogger(), "Attempting to use Custom Database");
return createDefaultCustomDatabaseManager();
}
catch (Throwable e) {

View File

@@ -276,6 +276,8 @@ public class FlatFileDataProcessor {
case SKILLS_TAMING:
case SKILLS_FISHING:
case SKILLS_ALCHEMY:
case SKILLS_CROSSBOWS:
case SKILLS_TRIDENTS:
case COOLDOWN_BERSERK:
case COOLDOWN_GIGA_DRILL_BREAKER:
case COOLDOWN_TREE_FELLER:
@@ -286,6 +288,9 @@ public class FlatFileDataProcessor {
case COOLDOWN_BLAST_MINING:
case SCOREBOARD_TIPS:
case COOLDOWN_CHIMAERA_WING:
case COOLDOWN_SUPER_SHOTGUN:
case COOLDOWN_TRIDENTS:
case COOLDOWN_ARCHERY:
return ExpectedType.INTEGER;
case EXP_MINING:
case EXP_WOODCUTTING:
@@ -300,6 +305,8 @@ public class FlatFileDataProcessor {
case EXP_TAMING:
case EXP_FISHING:
case EXP_ALCHEMY:
case EXP_CROSSBOWS:
case EXP_TRIDENTS:
return ExpectedType.FLOAT;
case UUID_INDEX:
return ExpectedType.UUID;

View File

@@ -9,6 +9,7 @@ import com.gmail.nossr50.datatypes.player.UniqueDataType;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.LogUtils;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.skills.SkillTools;
import org.bukkit.OfflinePlayer;
@@ -25,7 +26,7 @@ import java.util.logging.Logger;
public final class FlatFileDatabaseManager implements DatabaseManager {
public static final String IGNORED = "IGNORED";
public static final String LEGACY_INVALID_OLD_USERNAME = "_INVALID_OLD_USERNAME_'";
private final @NotNull EnumMap<PrimarySkillType, List<PlayerStat>> playerStatHash = new EnumMap<PrimarySkillType, List<PlayerStat>>(PrimarySkillType.class);
private final @NotNull EnumMap<PrimarySkillType, List<PlayerStat>> playerStatHash = new EnumMap<>(PrimarySkillType.class);
private final @NotNull List<PlayerStat> powerLevels = new ArrayList<>();
private long lastUpdate = 0;
private final @NotNull String usersFilePath;
@@ -79,10 +80,17 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
public static final int SCOREBOARD_TIPS = 42;
public static final int COOLDOWN_CHIMAERA_WING = 43;
public static final int OVERHAUL_LAST_LOGIN = 44;
public static final int EXP_CROSSBOWS = 45;
public static final int SKILLS_CROSSBOWS = 46;
public static final int EXP_TRIDENTS = 47;
public static final int SKILLS_TRIDENTS = 48;
public static final int COOLDOWN_SUPER_SHOTGUN = 49;
public static final int COOLDOWN_TRIDENTS = 50;
public static final int COOLDOWN_ARCHERY = 51;
//Update this everytime new data is added
public static final int DATA_ENTRY_COUNT = COOLDOWN_ARCHERY + 1;
public static final int DATA_ENTRY_COUNT = OVERHAUL_LAST_LOGIN + 1; //Update this everytime new data is added
protected FlatFileDatabaseManager(@NotNull File usersFile, @NotNull Logger logger, long purgeTime, int startingLevel, boolean testing) {
FlatFileDatabaseManager(@NotNull File usersFile, @NotNull Logger logger, long purgeTime, int startingLevel, boolean testing) {
this.usersFile = usersFile;
this.usersFilePath = usersFile.getPath();
this.logger = logger;
@@ -98,7 +106,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
List<FlatFileDataFlag> flatFileDataFlags = checkFileHealthAndStructure();
if(flatFileDataFlags != null) {
if(flatFileDataFlags.size() > 0) {
if(!flatFileDataFlags.isEmpty()) {
logger.info("Detected "+flatFileDataFlags.size() + " data entries which need correction.");
}
}
@@ -107,7 +115,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
}
}
protected FlatFileDatabaseManager(@NotNull String usersFilePath, @NotNull Logger logger, long purgeTime, int startingLevel) {
FlatFileDatabaseManager(@NotNull String usersFilePath, @NotNull Logger logger, long purgeTime, int startingLevel) {
this(new File(usersFilePath), logger, purgeTime, startingLevel, false);
}
@@ -115,12 +123,11 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
public int purgePowerlessUsers() {
int purgedUsers = 0;
logger.info("Purging powerless users...");
LogUtils.debug(logger, "Purging powerless users...");
BufferedReader in = null;
FileWriter out = null;
// This code is O(n) instead of O(n²)
synchronized (fileWritingLock) {
try {
in = new BufferedReader(new FileReader(usersFilePath));
@@ -184,7 +191,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
int removedPlayers = 0;
long currentTime = System.currentTimeMillis();
logger.info("Purging old users...");
LogUtils.debug(logger, "Purging old users...");
BufferedReader in = null;
FileWriter out = null;
@@ -198,7 +205,8 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
while ((line = in.readLine()) != null) {
String[] character = line.split(":");
String name = character[USERNAME_INDEX];
String uuidString = character[UUID_INDEX];
UUID uuid = UUID.fromString(uuidString);
long lastPlayed = 0;
boolean rewrite = false;
@@ -209,7 +217,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
}
if (lastPlayed == -1) {
OfflinePlayer player = mcMMO.p.getServer().getOfflinePlayer(name);
OfflinePlayer player = mcMMO.p.getServer().getOfflinePlayer(uuid);
if(player.getLastPlayed() != 0) {
lastPlayed = player.getLastPlayed();
@@ -217,7 +225,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
}
}
if (lastPlayed != -1 && lastPlayed != 0 && currentTime - lastPlayed > purgeTime) {
if (lastPlayed < 1 && (currentTime - lastPlayed > purgeTime)) {
removedPlayers++;
} else {
if (rewrite) {
@@ -236,7 +244,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
out.write(writer.toString());
if(testing) {
System.out.println(writer.toString());
System.out.println(writer);
}
}
catch (IOException e) {
@@ -466,6 +474,10 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
appendable.append(String.valueOf(profile.getScoreboardTipsShown())).append(":");
appendable.append(String.valueOf(profile.getUniqueData(UniqueDataType.CHIMAERA_WING_DATS))).append(":");
appendable.append(String.valueOf(profile.getLastLogin())).append(":"); //overhaul last login
appendable.append(String.valueOf(profile.getSkillXpLevel(PrimarySkillType.CROSSBOWS))).append(":");
appendable.append(String.valueOf(profile.getSkillLevel(PrimarySkillType.CROSSBOWS))).append(":");
appendable.append(String.valueOf(profile.getSkillXpLevel(PrimarySkillType.TRIDENTS))).append(":");
appendable.append(String.valueOf(profile.getSkillLevel(PrimarySkillType.TRIDENTS))).append(":");
appendable.append("\r\n");
}
@@ -564,16 +576,11 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
* @return a profile with the targets data or an unloaded profile if no data was found
*/
private @NotNull PlayerProfile processUserQuery(@NotNull UserQuery userQuery) throws RuntimeException {
switch(userQuery.getType()) {
case UUID_AND_NAME:
return queryByUUIDAndName((UserQueryFull) userQuery);
case UUID:
return queryByUUID((UserQueryUUID) userQuery);
case NAME:
return queryByName((UserQueryNameImpl) userQuery);
default:
throw new RuntimeException("No case for this UserQueryType!");
}
return switch (userQuery.getType()) {
case UUID_AND_NAME -> queryByUUIDAndName((UserQueryFull) userQuery);
case UUID -> queryByUUID((UserQueryUUID) userQuery);
case NAME -> queryByName((UserQueryNameImpl) userQuery);
};
}
private @NotNull PlayerProfile queryByName(@NotNull UserQueryName userQuery) {
@@ -602,8 +609,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
continue;
}
//If we couldn't find anyone
// we found the player
if(playerName.equalsIgnoreCase(rawSplitData[USERNAME_INDEX])) {
return loadFromLine(rawSplitData);
}
@@ -680,7 +686,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
* No match was found in the file
*/
return grabUnloadedProfile(uuid, "Player-Not-Found="+uuid.toString());
return grabUnloadedProfile(uuid, "Player-Not-Found="+ uuid);
}
private @NotNull PlayerProfile queryByUUIDAndName(@NotNull UserQueryFull userQuery) {
@@ -715,7 +721,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
boolean matchingName = dbPlayerName.equalsIgnoreCase(playerName);
if (!matchingName) {
logger.info("When loading user: "+playerName +" with UUID of (" + uuid.toString()
logger.warning("When loading user: "+playerName +" with UUID of (" + uuid
+") we found a mismatched name, the name in the DB will be replaced (DB name: "+dbPlayerName+")");
//logger.info("Name updated for player: " + rawSplitData[USERNAME_INDEX] + " => " + playerName);
rawSplitData[USERNAME_INDEX] = playerName;
@@ -840,7 +846,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
logger.severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e);
}
finally {
logger.info(i + " entries written while saving UUID for " + userName);
LogUtils.debug(logger, i + " entries written while saving UUID for " + userName);
if (in != null) {
try {
in.close();
@@ -898,7 +904,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
logger.severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e);
}
finally {
logger.info(i + " entries written while saving UUID batch");
LogUtils.debug(logger, i + " entries written while saving UUID batch");
if (in != null) {
try {
in.close();
@@ -979,6 +985,8 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
List<PlayerStat> taming = new ArrayList<>();
List<PlayerStat> fishing = new ArrayList<>();
List<PlayerStat> alchemy = new ArrayList<>();
List<PlayerStat> crossbows = new ArrayList<>();
List<PlayerStat> tridents = new ArrayList<>();
BufferedReader in = null;
String playerName = null;
@@ -1012,6 +1020,8 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
powerLevel += putStat(taming, playerName, skills.get(PrimarySkillType.TAMING));
powerLevel += putStat(unarmed, playerName, skills.get(PrimarySkillType.UNARMED));
powerLevel += putStat(woodcutting, playerName, skills.get(PrimarySkillType.WOODCUTTING));
powerLevel += putStat(crossbows, playerName, skills.get(PrimarySkillType.CROSSBOWS));
powerLevel += putStat(tridents, playerName, skills.get(PrimarySkillType.TRIDENTS));
putStat(powerLevels, playerName, powerLevel);
}
@@ -1047,6 +1057,8 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
taming.sort(c);
fishing.sort(c);
alchemy.sort(c);
crossbows.sort(c);
tridents.sort(c);
powerLevels.sort(c);
playerStatHash.put(PrimarySkillType.MINING, mining);
@@ -1062,6 +1074,8 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
playerStatHash.put(PrimarySkillType.TAMING, taming);
playerStatHash.put(PrimarySkillType.FISHING, fishing);
playerStatHash.put(PrimarySkillType.ALCHEMY, alchemy);
playerStatHash.put(PrimarySkillType.CROSSBOWS, crossbows);
playerStatHash.put(PrimarySkillType.TRIDENTS, tridents);
return LeaderboardStatus.UPDATED;
}
@@ -1092,8 +1106,8 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
public @Nullable List<FlatFileDataFlag> checkFileHealthAndStructure() {
ArrayList<FlatFileDataFlag> flagsFound = null;
logger.info("(" + usersFile.getPath() + ") Validating database file..");
FlatFileDataProcessor dataProcessor = null;
LogUtils.debug(logger, "(" + usersFile.getPath() + ") Validating database file..");
FlatFileDataProcessor dataProcessor;
if (usersFile.exists()) {
BufferedReader bufferedReader = null;
@@ -1125,9 +1139,9 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
}
//Only update the file if needed
if(dataProcessor.getFlatFileDataFlags().size() > 0) {
if(!dataProcessor.getFlatFileDataFlags().isEmpty()) {
flagsFound = new ArrayList<>(dataProcessor.getFlatFileDataFlags());
logger.info("Saving the updated and or repaired FlatFile Database...");
logger.info("Updating FlatFile Database...");
fileWriter = new FileWriter(usersFilePath);
//Write data to file
if(dbCommentDate != null)
@@ -1143,7 +1157,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
}
}
if(flagsFound == null || flagsFound.size() == 0) {
if(flagsFound == null || flagsFound.isEmpty()) {
return null;
} else {
return flagsFound;
@@ -1223,6 +1237,8 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
tryLoadSkillFloatValuesFromRawData(skillsXp, character, PrimarySkillType.ACROBATICS, EXP_ACROBATICS, username);
tryLoadSkillFloatValuesFromRawData(skillsXp, character, PrimarySkillType.FISHING, EXP_FISHING, username);
tryLoadSkillFloatValuesFromRawData(skillsXp, character, PrimarySkillType.ALCHEMY, EXP_ALCHEMY, username);
tryLoadSkillFloatValuesFromRawData(skillsXp, character, PrimarySkillType.CROSSBOWS, EXP_CROSSBOWS, username);
tryLoadSkillFloatValuesFromRawData(skillsXp, character, PrimarySkillType.TRIDENTS, EXP_TRIDENTS, username);
// Taming - Unused
tryLoadSkillCooldownFromRawData(skillsDATS, character, SuperAbilityType.SUPER_BREAKER, COOLDOWN_SUPER_BREAKER, username);
@@ -1231,11 +1247,13 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
tryLoadSkillCooldownFromRawData(skillsDATS, character, SuperAbilityType.BERSERK, COOLDOWN_BERSERK, username);
tryLoadSkillCooldownFromRawData(skillsDATS, character, SuperAbilityType.GREEN_TERRA, COOLDOWN_GREEN_TERRA, username);
tryLoadSkillCooldownFromRawData(skillsDATS, character, SuperAbilityType.GIGA_DRILL_BREAKER, COOLDOWN_GIGA_DRILL_BREAKER, username);
// Archery - Unused
tryLoadSkillCooldownFromRawData(skillsDATS, character, SuperAbilityType.EXPLOSIVE_SHOT, COOLDOWN_ARCHERY, username);
tryLoadSkillCooldownFromRawData(skillsDATS, character, SuperAbilityType.SERRATED_STRIKES, COOLDOWN_SERRATED_STRIKES, username);
tryLoadSkillCooldownFromRawData(skillsDATS, character, SuperAbilityType.SKULL_SPLITTER, COOLDOWN_SKULL_SPLITTER, username);
// Acrobatics - Unused
tryLoadSkillCooldownFromRawData(skillsDATS, character, SuperAbilityType.BLAST_MINING, COOLDOWN_BLAST_MINING, username);
tryLoadSkillCooldownFromRawData(skillsDATS, character, SuperAbilityType.SUPER_SHOTGUN, COOLDOWN_SUPER_SHOTGUN, username);
tryLoadSkillCooldownFromRawData(skillsDATS, character, SuperAbilityType.TRIDENTS_SUPER_ABILITY, COOLDOWN_TRIDENTS, username);
UUID uuid;
try {
@@ -1268,12 +1286,15 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
return new PlayerProfile(username, uuid, skills, skillsXp, skillsDATS, scoreboardTipsShown, uniquePlayerDataMap, lastLogin);
}
private void tryLoadSkillCooldownFromRawData(@NotNull Map<SuperAbilityType, Integer> cooldownMap, @NotNull String[] character, @NotNull SuperAbilityType superAbilityType, int cooldownSuperBreaker, @NotNull String userName) {
private void tryLoadSkillCooldownFromRawData(@NotNull Map<SuperAbilityType, Integer> cooldownMap, @NotNull String[] splitData, @NotNull SuperAbilityType superAbilityType, int index, @NotNull String userName) {
try {
cooldownMap.put(superAbilityType, Integer.valueOf(character[cooldownSuperBreaker]));
cooldownMap.put(superAbilityType, Integer.valueOf(splitData[index]));
} catch (IndexOutOfBoundsException e) {
// TODO: Add debug message
// set to 0 when data not found
cooldownMap.put(superAbilityType, 0);
} catch (NumberFormatException e) {
logger.severe("Data corruption when trying to load the value for skill "+superAbilityType+" for player named " + userName+ " setting value to zero");
e.printStackTrace();
throw new NumberFormatException("Data corruption when trying to load the cooldown for skill "+superAbilityType+" for player named " + userName);
}
}
@@ -1292,6 +1313,10 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
try {
int valueFromString = Integer.parseInt(character[index]);
skillMap.put(primarySkillType, valueFromString);
} catch (ArrayIndexOutOfBoundsException e ) {
// TODO: Add debug message
// set to 0 when data not found
skillMap.put(primarySkillType, 0);
} catch (NumberFormatException e) {
skillMap.put(primarySkillType, 0);
logger.severe("Data corruption when trying to load the value for skill "+primarySkillType+" for player named " + userName+ " setting value to zero");
@@ -1316,6 +1341,8 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
tryLoadSkillIntValuesFromRawData(skills, character, PrimarySkillType.AXES, SKILLS_AXES, username);
tryLoadSkillIntValuesFromRawData(skills, character, PrimarySkillType.FISHING, SKILLS_FISHING, username);
tryLoadSkillIntValuesFromRawData(skills, character, PrimarySkillType.ALCHEMY, SKILLS_ALCHEMY, username);
tryLoadSkillIntValuesFromRawData(skills, character, PrimarySkillType.CROSSBOWS, SKILLS_CROSSBOWS, username);
tryLoadSkillIntValuesFromRawData(skills, character, PrimarySkillType.TRIDENTS, SKILLS_TRIDENTS, username);
return skills;
}

View File

@@ -11,19 +11,20 @@ import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.runnables.database.UUIDUpdateAsyncTask;
import com.gmail.nossr50.util.LogUtils;
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;
import java.sql.*;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Logger;
public final class SQLDatabaseManager implements DatabaseManager {
private static final String ALL_QUERY_VERSION = "total";
@@ -32,6 +33,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
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";
public static final int MAGIC_NUMBER = 44;
private final String tablePrefix = mcMMO.p.getGeneralConfig().getMySQLTablePrefix();
private final Map<UUID, Integer> cachedUserIDs = new HashMap<>();
@@ -45,20 +47,22 @@ public final class SQLDatabaseManager implements DatabaseManager {
private final ReentrantLock massUpdateLock = new ReentrantLock();
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
private final Logger logger;
private final boolean h2;
protected SQLDatabaseManager() {
String connectionString = "jdbc:mysql://" + mcMMO.p.getGeneralConfig().getMySQLServerName()
+ ":" + mcMMO.p.getGeneralConfig().getMySQLServerPort() + "/" + mcMMO.p.getGeneralConfig().getMySQLDatabaseName();
SQLDatabaseManager(Logger logger, String driverPath) {
this(logger, driverPath, false);
}
if(mcMMO.p.getGeneralConfig().getMySQLSSL())
connectionString +=
"?verifyServerCertificate=false"+
"&useSSL=true"+
"&requireSSL=true";
else
SQLDatabaseManager(Logger logger, String driverPath, boolean h2) {
this.logger = logger;
this.h2 = h2;
String connectionString = getConnectionString(h2);
if(!h2 && mcMMO.p.getGeneralConfig().getMySQLPublicKeyRetrieval()) {
connectionString+=
"?useSSL=false";
"&allowPublicKeyRetrieval=true";
}
try {
// Force driver to load if not yet loaded
@@ -70,7 +74,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
} catch (ClassNotFoundException ex) {
e.printStackTrace();
ex.printStackTrace();
mcMMO.p.getLogger().severe("Neither driver found");
logger.severe("Neither driver found");
return;
}
//throw e; // aborts onEnable() Riking if you want to do this, fully implement it.
@@ -127,9 +131,31 @@ public final class SQLDatabaseManager implements DatabaseManager {
checkStructure();
}
@NotNull
private static String getConnectionString(boolean h2) {
if (h2) {
return "jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;MODE=MySQL";
}
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"+
"&requireSSL=true";
else
connectionString+=
"?useSSL=false";
return connectionString;
}
// TODO: unit tests
public int purgePowerlessUsers() {
massUpdateLock.lock();
mcMMO.p.getLogger().info("Purging powerless users...");
logger.info("Purging powerless users...");
Connection connection = null;
Statement statement = null;
@@ -143,7 +169,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
+ "taming = 0 AND mining = 0 AND woodcutting = 0 AND repair = 0 "
+ "AND unarmed = 0 AND herbalism = 0 AND excavation = 0 AND "
+ "archery = 0 AND swords = 0 AND axes = 0 AND acrobatics = 0 "
+ "AND fishing = 0 AND alchemy = 0;");
+ "AND fishing = 0 AND alchemy = 0 AND crossbows = 0 AND tridents = 0;");
statement.executeUpdate("DELETE FROM `" + tablePrefix + "experience` WHERE NOT EXISTS (SELECT * FROM `" + tablePrefix + "skills` `s` WHERE `" + tablePrefix + "experience`.`user_id` = `s`.`user_id`)");
statement.executeUpdate("DELETE FROM `" + tablePrefix + "huds` WHERE NOT EXISTS (SELECT * FROM `" + tablePrefix + "skills` `s` WHERE `" + tablePrefix + "huds`.`user_id` = `s`.`user_id`)");
@@ -159,13 +185,13 @@ public final class SQLDatabaseManager implements DatabaseManager {
massUpdateLock.unlock();
}
mcMMO.p.getLogger().info("Purged " + purged + " users from the database.");
logger.info("Purged " + purged + " users from the database.");
return purged;
}
public void purgeOldUsers() {
massUpdateLock.lock();
mcMMO.p.getLogger().info("Purging inactive users older than " + (mcMMO.p.getPurgeTime() / 2630000000L) + " months...");
logger.info("Purging inactive users older than " + (mcMMO.p.getPurgeTime() / 2630000000L) + " months...");
Connection connection = null;
Statement statement = null;
@@ -190,7 +216,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
massUpdateLock.unlock();
}
mcMMO.p.getLogger().info("Purged " + purged + " users from the database.");
logger.info("Purged " + purged + " users from the database.");
}
public boolean removeUser(String playerName, UUID uuid) {
@@ -206,7 +232,7 @@ 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 u.user = ?");
"WHERE u.`user` = ?");
statement.setString(1, playerName);
@@ -247,7 +273,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
if (id == -1) {
id = newUser(connection, profile.getPlayerName(), profile.getUniqueId());
if (id == -1) {
mcMMO.p.getLogger().severe("Failed to create new account for " + profile.getPlayerName());
logger.severe("Failed to create new account for " + profile.getPlayerName());
return false;
}
}
@@ -257,7 +283,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
success &= (statement.executeUpdate() != 0);
statement.close();
if (!success) {
mcMMO.p.getLogger().severe("Failed to update last login for " + profile.getPlayerName());
logger.severe("Failed to update last login for " + profile.getPlayerName());
return false;
}
@@ -265,7 +291,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
+ " taming = ?, mining = ?, repair = ?, woodcutting = ?"
+ ", unarmed = ?, herbalism = ?, excavation = ?"
+ ", archery = ?, swords = ?, axes = ?, acrobatics = ?"
+ ", fishing = ?, alchemy = ?, total = ? WHERE user_id = ?");
+ ", fishing = ?, alchemy = ?, crossbows = ?, tridents = ?, total = ? WHERE user_id = ?");
statement.setInt(1, profile.getSkillLevel(PrimarySkillType.TAMING));
statement.setInt(2, profile.getSkillLevel(PrimarySkillType.MINING));
statement.setInt(3, profile.getSkillLevel(PrimarySkillType.REPAIR));
@@ -279,15 +305,17 @@ public final class SQLDatabaseManager implements DatabaseManager {
statement.setInt(11, profile.getSkillLevel(PrimarySkillType.ACROBATICS));
statement.setInt(12, profile.getSkillLevel(PrimarySkillType.FISHING));
statement.setInt(13, profile.getSkillLevel(PrimarySkillType.ALCHEMY));
statement.setInt(14, profile.getSkillLevel(PrimarySkillType.CROSSBOWS));
statement.setInt(15, profile.getSkillLevel(PrimarySkillType.TRIDENTS));
int total = 0;
for (PrimarySkillType primarySkillType : SkillTools.NON_CHILD_SKILLS)
total += profile.getSkillLevel(primarySkillType);
statement.setInt(14, total);
statement.setInt(15, id);
statement.setInt(16, total);
statement.setInt(17, id);
success &= (statement.executeUpdate() != 0);
statement.close();
if (!success) {
mcMMO.p.getLogger().severe("Failed to update skills for " + profile.getPlayerName());
logger.severe("Failed to update skills for " + profile.getPlayerName());
return false;
}
@@ -295,7 +323,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
+ " taming = ?, mining = ?, repair = ?, woodcutting = ?"
+ ", unarmed = ?, herbalism = ?, excavation = ?"
+ ", archery = ?, swords = ?, axes = ?, acrobatics = ?"
+ ", fishing = ?, alchemy = ? WHERE user_id = ?");
+ ", fishing = ?, alchemy = ?, crossbows = ?, tridents = ? WHERE user_id = ?");
statement.setInt(1, profile.getSkillXpLevel(PrimarySkillType.TAMING));
statement.setInt(2, profile.getSkillXpLevel(PrimarySkillType.MINING));
statement.setInt(3, profile.getSkillXpLevel(PrimarySkillType.REPAIR));
@@ -309,18 +337,20 @@ public final class SQLDatabaseManager implements DatabaseManager {
statement.setInt(11, profile.getSkillXpLevel(PrimarySkillType.ACROBATICS));
statement.setInt(12, profile.getSkillXpLevel(PrimarySkillType.FISHING));
statement.setInt(13, profile.getSkillXpLevel(PrimarySkillType.ALCHEMY));
statement.setInt(14, id);
statement.setInt(14, profile.getSkillXpLevel(PrimarySkillType.CROSSBOWS));
statement.setInt(15, profile.getSkillXpLevel(PrimarySkillType.TRIDENTS));
statement.setInt(16, id);
success &= (statement.executeUpdate() != 0);
statement.close();
if (!success) {
mcMMO.p.getLogger().severe("Failed to update experience for " + profile.getPlayerName());
logger.severe("Failed to update experience for " + profile.getPlayerName());
return false;
}
statement = connection.prepareStatement("UPDATE " + tablePrefix + "cooldowns SET "
+ " mining = ?, woodcutting = ?, unarmed = ?"
+ ", herbalism = ?, excavation = ?, swords = ?"
+ ", axes = ?, blast_mining = ?, chimaera_wing = ? WHERE user_id = ?");
+ ", axes = ?, blast_mining = ?, chimaera_wing = ?, crossbows = ?, tridents = ? WHERE user_id = ?");
statement.setLong(1, profile.getAbilityDATS(SuperAbilityType.SUPER_BREAKER));
statement.setLong(2, profile.getAbilityDATS(SuperAbilityType.TREE_FELLER));
statement.setLong(3, profile.getAbilityDATS(SuperAbilityType.BERSERK));
@@ -330,11 +360,13 @@ public final class SQLDatabaseManager implements DatabaseManager {
statement.setLong(7, profile.getAbilityDATS(SuperAbilityType.SKULL_SPLITTER));
statement.setLong(8, profile.getAbilityDATS(SuperAbilityType.BLAST_MINING));
statement.setLong(9, profile.getUniqueData(UniqueDataType.CHIMAERA_WING_DATS));
statement.setInt(10, id);
statement.setLong(10, profile.getAbilityDATS(SuperAbilityType.SUPER_SHOTGUN));
statement.setLong(11, profile.getAbilityDATS(SuperAbilityType.TRIDENTS_SUPER_ABILITY));
statement.setInt(12, id);
success = (statement.executeUpdate() != 0);
statement.close();
if (!success) {
mcMMO.p.getLogger().severe("Failed to update cooldowns for " + profile.getPlayerName());
logger.severe("Failed to update cooldowns for " + profile.getPlayerName());
return false;
}
@@ -345,7 +377,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
success = (statement.executeUpdate() != 0);
statement.close();
if (!success) {
mcMMO.p.getLogger().severe("Failed to update hud settings for " + profile.getPlayerName());
logger.severe("Failed to update hud settings for " + profile.getPlayerName());
return false;
}
}
@@ -365,11 +397,10 @@ public final class SQLDatabaseManager implements DatabaseManager {
//Fix for a plugin that people are using that is throwing SQL errors
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!");
logger.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!");
}
String query = skill == null ? ALL_QUERY_VERSION : skill.name().toLowerCase(Locale.ENGLISH);
ResultSet resultSet = null;
PreparedStatement statement = null;
@@ -377,7 +408,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
try {
connection = getConnection(PoolIdentifier.MISC);
statement = connection.prepareStatement("SELECT " + query + ", user FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON (user_id = id) WHERE " + query + " > 0 AND NOT user = '\\_INVALID\\_OLD\\_USERNAME\\_' ORDER BY " + query + " DESC, user LIMIT ?, ?");
statement = connection.prepareStatement("SELECT " + query + ", `user` FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON (user_id = id) WHERE " + query + " > 0 AND NOT `user` = '\\_INVALID\\_OLD\\_USERNAME\\_' ORDER BY " + query + " DESC, `user` LIMIT ?, ?");
statement.setInt(1, (pageNumber * statsPerPage) - statsPerPage);
statement.setInt(2, statsPerPage);
resultSet = statement.executeQuery();
@@ -418,7 +449,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
// 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 " +
"AND " + skillName + " > (SELECT " + skillName + " FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id " +
"WHERE user = ?)";
"WHERE `user` = ?)";
statement = connection.prepareStatement(sql);
statement.setString(1, playerName);
@@ -431,7 +462,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
// Ties are settled by alphabetical order
sql = "SELECT user, " + skillName + " FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE " + skillName + " > 0 " +
"AND " + skillName + " = (SELECT " + skillName + " FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id " +
"WHERE user = '" + playerName + "') ORDER BY user";
"WHERE `user` = '" + playerName + "') ORDER BY user";
resultSet.close();
statement.close();
@@ -454,7 +485,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
"WHERE " + ALL_QUERY_VERSION + " > 0 " +
"AND " + ALL_QUERY_VERSION + " > " +
"(SELECT " + ALL_QUERY_VERSION + " " +
"FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE user = ?)";
"FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE `user` = ?)";
statement = connection.prepareStatement(sql);
statement.setString(1, playerName);
@@ -472,7 +503,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
"WHERE " + ALL_QUERY_VERSION + " > 0 " +
"AND " + ALL_QUERY_VERSION + " = " +
"(SELECT " + ALL_QUERY_VERSION + " " +
"FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE user = ?) ORDER BY user";
"FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE `user` = ?) ORDER BY user";
statement = connection.prepareStatement(sql);
statement.setString(1, playerName);
@@ -540,21 +571,26 @@ public final class SQLDatabaseManager implements DatabaseManager {
try {
statement = connection.prepareStatement(
"UPDATE `" + tablePrefix + "users` "
+ "SET user = ? "
+ "WHERE user = ?");
+ "SET `user` = ? "
+ "WHERE `user` = ?");
statement.setString(1, "_INVALID_OLD_USERNAME_");
statement.setString(2, playerName);
statement.executeUpdate();
statement.close();
statement = connection.prepareStatement("INSERT INTO " + tablePrefix + "users (user, uuid, lastlogin) VALUES (?, ?, UNIX_TIMESTAMP())", Statement.RETURN_GENERATED_KEYS);
long currentTimeMillis = System.currentTimeMillis();
String sql = "INSERT INTO " + tablePrefix + "users (`user`, uuid, lastlogin) VALUES (?, ?, ?)";
statement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
statement.setString(1, playerName);
statement.setString(2, uuid != null ? uuid.toString() : null);
statement.setLong(3, currentTimeMillis);
statement.executeUpdate();
resultSet = statement.getGeneratedKeys();
if (!resultSet.next()) {
mcMMO.p.getLogger().severe("Unable to create new user account in DB");
logger.severe("Unable to create new user account in DB");
return -1;
}
@@ -594,7 +630,6 @@ public final class SQLDatabaseManager implements DatabaseManager {
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.");
@@ -616,17 +651,18 @@ public final class SQLDatabaseManager implements DatabaseManager {
writeMissingRows(connection, id);
statement = connection.prepareStatement(
"SELECT "
+ "s.taming, s.mining, s.repair, s.woodcutting, s.unarmed, s.herbalism, s.excavation, s.archery, s.swords, s.axes, s.acrobatics, s.fishing, s.alchemy, "
+ "e.taming, e.mining, e.repair, e.woodcutting, e.unarmed, e.herbalism, e.excavation, e.archery, e.swords, e.axes, e.acrobatics, e.fishing, e.alchemy, "
+ "c.taming, c.mining, c.repair, c.woodcutting, c.unarmed, c.herbalism, c.excavation, c.archery, c.swords, c.axes, c.acrobatics, c.blast_mining, c.chimaera_wing, "
+ "h.mobhealthbar, h.scoreboardtips, u.uuid, u.user "
"SELECT " +
"s.taming, s.mining, s.repair, s.woodcutting, s.unarmed, s.herbalism, s.excavation, s.archery, s.swords, s.axes, s.acrobatics, s.fishing, s.alchemy, s.crossbows, s.tridents, " +
"e.taming, e.mining, e.repair, e.woodcutting, e.unarmed, e.herbalism, e.excavation, e.archery, e.swords, e.axes, e.acrobatics, e.fishing, e.alchemy, e.crossbows, e.tridents, " +
"c.taming, c.mining, c.repair, c.woodcutting, c.unarmed, c.herbalism, c.excavation, c.archery, c.swords, c.axes, c.acrobatics, c.blast_mining, c.chimaera_wing, c.crossbows, c.tridents, " +
"h.mobhealthbar, h.scoreboardtips, u.uuid, u.`user` "
+ "FROM " + tablePrefix + "users u "
+ "JOIN " + tablePrefix + "skills s ON (u.id = s.user_id) "
+ "JOIN " + tablePrefix + "experience e ON (u.id = e.user_id) "
+ "JOIN " + tablePrefix + "cooldowns c ON (u.id = c.user_id) "
+ "JOIN " + tablePrefix + "huds h ON (u.id = h.user_id) "
+ "WHERE u.id = ?");
+ "WHERE u.id = ?"
);
statement.setInt(1, id);
resultSet = statement.executeQuery();
@@ -634,7 +670,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
if (resultSet.next()) {
try {
PlayerProfile profile = loadFromResult(playerName, resultSet);
String name = resultSet.getString(42); // TODO: Magic Number, make sure it stays updated
String name = resultSet.getString(MAGIC_NUMBER); // TODO: Magic Number, make sure it stays updated
resultSet.close();
statement.close();
@@ -644,15 +680,15 @@ public final class SQLDatabaseManager implements DatabaseManager {
&& uuid != null) {
statement = connection.prepareStatement(
"UPDATE `" + tablePrefix + "users` "
+ "SET user = ? "
+ "WHERE user = ?");
+ "SET `user` = ? "
+ "WHERE `user` = ?");
statement.setString(1, "_INVALID_OLD_USERNAME_");
statement.setString(2, name);
statement.executeUpdate();
statement.close();
statement = connection.prepareStatement(
"UPDATE `" + tablePrefix + "users` "
+ "SET user = ?, uuid = ? "
+ "SET `user` = ?, uuid = ? "
+ "WHERE id = ?");
statement.setString(1, playerName);
statement.setString(2, uuid.toString());
@@ -700,7 +736,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
+ "JOIN " + tablePrefix + "experience e ON (u.id = e.user_id) "
+ "JOIN " + tablePrefix + "cooldowns c ON (u.id = c.user_id) "
+ "JOIN " + tablePrefix + "huds h ON (u.id = h.user_id) "
+ "WHERE u.user = ?");
+ "WHERE u.`user` = ?");
List<String> usernames = getStoredUsers();
int convertedUsers = 0;
long startMillis = System.currentTimeMillis();
@@ -739,7 +775,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
connection = getConnection(PoolIdentifier.MISC);
statement = connection.prepareStatement(
"UPDATE `" + tablePrefix + "users` SET "
+ " uuid = ? WHERE user = ?");
+ " uuid = ? WHERE `user` = ?");
statement.setString(1, uuid.toString());
statement.setString(2, userName);
statement.execute();
@@ -763,7 +799,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
try {
connection = getConnection(PoolIdentifier.MISC);
statement = connection.prepareStatement("UPDATE " + tablePrefix + "users SET uuid = ? WHERE user = ?");
statement = connection.prepareStatement("UPDATE " + tablePrefix + "users SET uuid = ? WHERE `user` = ?");
for (Map.Entry<String, UUID> entry : fetchedUUIDs.entrySet()) {
statement.setString(1, entry.getValue().toString());
@@ -805,7 +841,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
try {
connection = getConnection(PoolIdentifier.MISC);
statement = connection.createStatement();
resultSet = statement.executeQuery("SELECT user FROM " + tablePrefix + "users");
resultSet = statement.executeQuery("SELECT `user` FROM " + tablePrefix + "users");
while (resultSet.next()) {
users.add(resultSet.getString("user"));
}
@@ -826,7 +862,6 @@ public final class SQLDatabaseManager implements DatabaseManager {
* Checks that the database structure is present and correct
*/
private void checkStructure() {
PreparedStatement statement = null;
Statement createStatement = null;
ResultSet resultSet = null;
@@ -834,27 +869,30 @@ public final class SQLDatabaseManager implements DatabaseManager {
try {
connection = getConnection(PoolIdentifier.MISC);
statement = connection.prepareStatement("SELECT table_name FROM INFORMATION_SCHEMA.TABLES"
+ " WHERE table_schema = ?"
+ " AND table_name = ?");
statement.setString(1, mcMMO.p.getGeneralConfig().getMySQLDatabaseName());
statement.setString(2, tablePrefix + "users");
String schemaQuery = this.h2 ? "SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_name = ?"
: "SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = ? AND table_name = ?";
statement = connection.prepareStatement(schemaQuery);
setStatementQuery(statement, "users");
resultSet = statement.executeQuery();
if (!resultSet.next()) {
createStatement = connection.createStatement();
createStatement.executeUpdate("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "users` ("
+ "`id` int(10) unsigned NOT NULL AUTO_INCREMENT,"
+ "`user` varchar(40) NOT NULL,"
+ "`uuid` varchar(36) NULL DEFAULT NULL,"
+ "`lastlogin` int(32) unsigned NOT NULL,"
+ "PRIMARY KEY (`id`),"
+ "INDEX(`user`(20) ASC),"
+ "UNIQUE KEY `uuid` (`uuid`)) DEFAULT CHARSET=" + CHARSET_SQL + " AUTO_INCREMENT=1;");
String sql = "CREATE TABLE IF NOT EXISTS `" + tablePrefix + "users` (" +
"`id` int AUTO_INCREMENT," +
"`user` varchar(40) NOT NULL," +
"`uuid` varchar(36)," +
"`lastlogin` bigint NOT NULL," +
"PRIMARY KEY (`id`)," +
"INDEX `user_index`(`user`)," +
"UNIQUE(`uuid`))";
createStatement.executeUpdate(sql);
tryClose(createStatement);
}
tryClose(resultSet);
statement.setString(1, mcMMO.p.getGeneralConfig().getMySQLDatabaseName());
statement.setString(2, tablePrefix + "huds");
setStatementQuery(statement, "huds");
resultSet = statement.executeQuery();
if (!resultSet.next()) {
createStatement = connection.createStatement();
@@ -867,8 +905,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
tryClose(createStatement);
}
tryClose(resultSet);
statement.setString(1, mcMMO.p.getGeneralConfig().getMySQLDatabaseName());
statement.setString(2, tablePrefix + "cooldowns");
setStatementQuery(statement, "cooldowns");
resultSet = statement.executeQuery();
if (!resultSet.next()) {
createStatement = connection.createStatement();
@@ -887,13 +924,14 @@ public final class SQLDatabaseManager implements DatabaseManager {
+ "`acrobatics` int(32) unsigned NOT NULL DEFAULT '0',"
+ "`blast_mining` int(32) unsigned NOT NULL DEFAULT '0',"
+ "`chimaera_wing` int(32) unsigned NOT NULL DEFAULT '0',"
+ "`crossbows` int(32) unsigned NOT NULL DEFAULT '0',"
+ "`tridents` int(32) unsigned NOT NULL DEFAULT '0',"
+ "PRIMARY KEY (`user_id`)) "
+ "DEFAULT CHARSET=" + CHARSET_SQL + ";");
tryClose(createStatement);
}
tryClose(resultSet);
statement.setString(1, mcMMO.p.getGeneralConfig().getMySQLDatabaseName());
statement.setString(2, tablePrefix + "skills");
setStatementQuery(statement, "skills");
resultSet = statement.executeQuery();
if (!resultSet.next()) {
String startingLevel = "'" + mcMMO.p.getAdvancedConfig().getStartingLevel() + "'";
@@ -914,14 +952,15 @@ public final class SQLDatabaseManager implements DatabaseManager {
+ "`acrobatics` int(10) unsigned NOT NULL DEFAULT "+startingLevel+","
+ "`fishing` int(10) unsigned NOT NULL DEFAULT "+startingLevel+","
+ "`alchemy` int(10) unsigned NOT NULL DEFAULT "+startingLevel+","
+ "`crossbows` int(10) unsigned NOT NULL DEFAULT "+startingLevel+","
+ "`tridents` int(10) unsigned NOT NULL DEFAULT "+startingLevel+","
+ "`total` int(10) unsigned NOT NULL DEFAULT "+totalLevel+","
+ "PRIMARY KEY (`user_id`)) "
+ "DEFAULT CHARSET=" + CHARSET_SQL + ";");
tryClose(createStatement);
}
tryClose(resultSet);
statement.setString(1, mcMMO.p.getGeneralConfig().getMySQLDatabaseName());
statement.setString(2, tablePrefix + "experience");
setStatementQuery(statement, "experience");
resultSet = statement.executeQuery();
if (!resultSet.next()) {
createStatement = connection.createStatement();
@@ -940,6 +979,8 @@ public final class SQLDatabaseManager implements DatabaseManager {
+ "`acrobatics` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`fishing` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`alchemy` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`crossbows` int(10) unsigned NOT NULL DEFAULT '0',"
+ "`tridents` int(10) unsigned NOT NULL DEFAULT '0',"
+ "PRIMARY KEY (`user_id`)) "
+ "DEFAULT CHARSET=" + CHARSET_SQL + ";");
tryClose(createStatement);
@@ -962,7 +1003,8 @@ public final class SQLDatabaseManager implements DatabaseManager {
}
}
mcMMO.p.getLogger().info("Killing orphans");
// TODO: refactor
LogUtils.debug(logger, "Killing orphans");
createStatement = connection.createStatement();
createStatement.executeUpdate("DELETE FROM `" + tablePrefix + "experience` WHERE NOT EXISTS (SELECT * FROM `" + tablePrefix + "users` `u` WHERE `" + tablePrefix + "experience`.`user_id` = `u`.`id`)");
createStatement.executeUpdate("DELETE FROM `" + tablePrefix + "huds` WHERE NOT EXISTS (SELECT * FROM `" + tablePrefix + "users` `u` WHERE `" + tablePrefix + "huds`.`user_id` = `u`.`id`)");
@@ -979,21 +1021,53 @@ public final class SQLDatabaseManager implements DatabaseManager {
tryClose(connection);
}
String skills = "skills";
String crossbows = "crossbows";
String tridents = "tridents";
String experience = "experience";
String cooldowns = "cooldowns";
updateStructure(skills, crossbows, String.valueOf(32));
updateStructure(skills, tridents, String.valueOf(32));
updateStructure(experience, crossbows, String.valueOf(10));
updateStructure(experience, tridents, String.valueOf(10));
updateStructure(cooldowns, crossbows, String.valueOf(10));
updateStructure(cooldowns, tridents, String.valueOf(10));
}
private Connection getConnection(PoolIdentifier identifier) throws SQLException {
Connection connection = null;
switch (identifier) {
case LOAD:
connection = loadPool.getConnection();
break;
case MISC:
connection = miscPool.getConnection();
break;
case SAVE:
connection = savePool.getConnection();
break;
private void updateStructure(String tableName, String columnName, String columnSize) {
try (Connection connection = getConnection(PoolIdentifier.MISC);
Statement createStatement = connection.createStatement()) {
String startingLevel = "'" + mcMMO.p.getAdvancedConfig().getStartingLevel() + "'";
createStatement.executeUpdate("ALTER TABLE `" + tablePrefix + tableName + "` "
+ "ADD COLUMN IF NOT EXISTS `" + columnName + "` int(" + columnSize + ") unsigned NOT NULL DEFAULT " + startingLevel);
} catch (SQLException e) {
e.printStackTrace(); // Consider more robust logging
throw new RuntimeException(e);
}
}
private void setStatementQuery(PreparedStatement statement, String tableName) throws SQLException {
if (!this.h2) {
// Set schema name for MySQL
statement.setString(1, mcMMO.p.getGeneralConfig().getMySQLDatabaseName());
statement.setString(2, tablePrefix + tableName);
} else {
// For H2, the schema parameter is not needed
statement.setString(1, tablePrefix + tableName);
}
}
Connection getConnection(PoolIdentifier identifier) throws SQLException {
Connection connection = switch (identifier) {
case LOAD -> loadPool.getConnection();
case MISC -> miscPool.getConnection();
case SAVE -> savePool.getConnection();
};
if (connection == null) {
throw new RuntimeException("getConnection() for " + identifier.name().toLowerCase(Locale.ENGLISH) + " pool timed out. Increase max connections settings.");
}
@@ -1006,8 +1080,9 @@ public final class SQLDatabaseManager implements DatabaseManager {
* @param upgrade Upgrade to attempt to apply
*/
private void checkDatabaseStructure(Connection connection, UpgradeType upgrade) {
// TODO: Rewrite / Refactor
if (!mcMMO.getUpgradeManager().shouldUpgrade(upgrade)) {
mcMMO.p.debug("Skipping " + upgrade.name() + " upgrade (unneeded)");
LogUtils.debug(logger, "Skipping " + upgrade.name() + " upgrade (unneeded)");
return;
}
@@ -1116,8 +1191,8 @@ public final class SQLDatabaseManager implements DatabaseManager {
}
private PlayerProfile loadFromResult(String playerName, ResultSet result) throws SQLException {
Map<PrimarySkillType, Integer> skills = new EnumMap<PrimarySkillType, Integer>(PrimarySkillType.class); // Skill & Level
Map<PrimarySkillType, Float> skillsXp = new EnumMap<PrimarySkillType, Float>(PrimarySkillType.class); // Skill & XP
Map<PrimarySkillType, Integer> skills = new EnumMap<>(PrimarySkillType.class); // Skill & Level
Map<PrimarySkillType, Float> skillsXp = new EnumMap<>(PrimarySkillType.class); // Skill & XP
Map<SuperAbilityType, Integer> skillsDATS = new EnumMap<>(SuperAbilityType.class); // Ability & Cooldown
Map<UniqueDataType, Integer> uniqueData = new EnumMap<>(UniqueDataType.class); //Chimaera wing cooldown and other misc info
MobHealthbarType mobHealthbarType;
@@ -1126,9 +1201,9 @@ public final class SQLDatabaseManager implements DatabaseManager {
final int OFFSET_SKILLS = 0; // TODO update these numbers when the query
// changes (a new skill is added)
final int OFFSET_XP = 13;
final int OFFSET_DATS = 26;
final int OFFSET_OTHER = 39;
final int OFFSET_XP = 15;
final int OFFSET_DATS = 28;
final int OFFSET_OTHER = 41;
skills.put(PrimarySkillType.TAMING, result.getInt(OFFSET_SKILLS + 1));
skills.put(PrimarySkillType.MINING, result.getInt(OFFSET_SKILLS + 2));
@@ -1143,6 +1218,8 @@ public final class SQLDatabaseManager implements DatabaseManager {
skills.put(PrimarySkillType.ACROBATICS, result.getInt(OFFSET_SKILLS + 11));
skills.put(PrimarySkillType.FISHING, result.getInt(OFFSET_SKILLS + 12));
skills.put(PrimarySkillType.ALCHEMY, result.getInt(OFFSET_SKILLS + 13));
skills.put(PrimarySkillType.CROSSBOWS, result.getInt(OFFSET_SKILLS + 14));
skills.put(PrimarySkillType.TRIDENTS, result.getInt(OFFSET_SKILLS + 15));
skillsXp.put(PrimarySkillType.TAMING, result.getFloat(OFFSET_XP + 1));
skillsXp.put(PrimarySkillType.MINING, result.getFloat(OFFSET_XP + 2));
@@ -1157,6 +1234,8 @@ public final class SQLDatabaseManager implements DatabaseManager {
skillsXp.put(PrimarySkillType.ACROBATICS, result.getFloat(OFFSET_XP + 11));
skillsXp.put(PrimarySkillType.FISHING, result.getFloat(OFFSET_XP + 12));
skillsXp.put(PrimarySkillType.ALCHEMY, result.getFloat(OFFSET_XP + 13));
skillsXp.put(PrimarySkillType.CROSSBOWS, result.getFloat(OFFSET_XP + 14));
skillsXp.put(PrimarySkillType.TRIDENTS, result.getFloat(OFFSET_XP + 15));
// Taming - Unused - result.getInt(OFFSET_DATS + 1)
skillsDATS.put(SuperAbilityType.SUPER_BREAKER, result.getInt(OFFSET_DATS + 2));
@@ -1171,6 +1250,8 @@ public final class SQLDatabaseManager implements DatabaseManager {
// Acrobatics - Unused - result.getInt(OFFSET_DATS + 11)
skillsDATS.put(SuperAbilityType.BLAST_MINING, result.getInt(OFFSET_DATS + 12));
uniqueData.put(UniqueDataType.CHIMAERA_WING_DATS, result.getInt(OFFSET_DATS + 13));
skillsDATS.put(SuperAbilityType.SUPER_SHOTGUN, result.getInt(OFFSET_DATS + 14));
skillsDATS.put(SuperAbilityType.TRIDENTS_SUPER_ABILITY, result.getInt(OFFSET_DATS + 15));
try {
scoreboardTipsShown = result.getInt(OFFSET_OTHER + 2);
@@ -1190,17 +1271,21 @@ public final class SQLDatabaseManager implements DatabaseManager {
}
private void printErrors(SQLException ex) {
if (debug) {
ex.printStackTrace();
}
ex.printStackTrace();
StackTraceElement element = ex.getStackTrace()[0];
mcMMO.p.getLogger().severe("Location: " + element.getClassName() + " " + element.getMethodName() + " " + element.getLineNumber());
mcMMO.p.getLogger().severe("SQLException: " + ex.getMessage());
mcMMO.p.getLogger().severe("SQLState: " + ex.getSQLState());
mcMMO.p.getLogger().severe("VendorError: " + ex.getErrorCode());
// logger.severe("SQLException: " + ex.getMessage());
logger.severe("SQLState: " + ex.getSQLState());
logger.severe("VendorError: " + ex.getErrorCode());
// Handling SQLException chain
SQLException nextException = ex.getNextException();
while (nextException != null) {
logger.severe("Caused by: " + nextException.getMessage());
nextException = nextException.getNextException();
}
}
public DatabaseType getDatabaseType() {
return DatabaseType.SQL;
}
@@ -1216,7 +1301,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
return;
}
resultSet.close();
mcMMO.p.getLogger().info("Updating mcMMO MySQL tables to drop name uniqueness...");
logger.info("Updating mcMMO MySQL tables to drop name uniqueness...");
statement.execute("ALTER TABLE `" + tablePrefix + "users` "
+ "DROP INDEX `user`,"
+ "ADD INDEX `user` (`user`(20) ASC)");
@@ -1234,7 +1319,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_ALCHEMY);
}
catch (SQLException ex) {
mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for Alchemy...");
logger.info("Updating mcMMO MySQL tables for Alchemy...");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "skills` ADD `alchemy` int(10) NOT NULL DEFAULT '0'");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "experience` ADD `alchemy` int(10) NOT NULL DEFAULT '0'");
}
@@ -1246,7 +1331,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_BLAST_MINING_COOLDOWN);
}
catch (SQLException ex) {
mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for Blast Mining...");
logger.info("Updating mcMMO MySQL tables for Blast Mining...");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "cooldowns` ADD `blast_mining` int(32) NOT NULL DEFAULT '0'");
}
}
@@ -1257,7 +1342,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_UNIQUE_PLAYER_DATA);
}
catch (SQLException ex) {
mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for Chimaera Wing...");
logger.info("Updating mcMMO MySQL tables for Chimaera Wing...");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "cooldowns` ADD `chimaera_wing` int(32) NOT NULL DEFAULT '0'");
}
}
@@ -1268,7 +1353,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_FISHING);
}
catch (SQLException ex) {
mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for Fishing...");
logger.info("Updating mcMMO MySQL tables for Fishing...");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "skills` ADD `fishing` int(10) NOT NULL DEFAULT '0'");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "experience` ADD `fishing` int(10) NOT NULL DEFAULT '0'");
}
@@ -1280,7 +1365,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_MOB_HEALTHBARS);
}
catch (SQLException ex) {
mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for mob healthbars...");
logger.info("Updating mcMMO MySQL tables for mob healthbars...");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "huds` ADD `mobhealthbar` varchar(50) NOT NULL DEFAULT '" + mcMMO.p.getGeneralConfig().getMobHealthbarDefault() + "'");
}
}
@@ -1291,7 +1376,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_SCOREBOARD_TIPS);
}
catch (SQLException ex) {
mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for scoreboard tips...");
logger.info("Updating mcMMO MySQL tables for scoreboard tips...");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "huds` ADD `scoreboardtips` int(10) NOT NULL DEFAULT '0' ;");
}
}
@@ -1304,7 +1389,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
resultSet.last();
if (resultSet.getRow() != SkillTools.NON_CHILD_SKILLS.size()) {
mcMMO.p.getLogger().info("Indexing tables, this may take a while on larger databases");
logger.info("Indexing tables, this may take a while on larger databases");
for (PrimarySkillType skill : SkillTools.NON_CHILD_SKILLS) {
String skill_name = skill.name().toLowerCase(Locale.ENGLISH);
@@ -1345,11 +1430,11 @@ public final class SQLDatabaseManager implements DatabaseManager {
}
if (!column_exists) {
mcMMO.p.getLogger().info("Adding UUIDs to mcMMO MySQL user table...");
logger.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.p.getFoliaLib().getImpl().runLaterAsync(new GetUUIDUpdatesRequired(), 100); // wait until after first purge
}
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_UUIDS);
@@ -1362,7 +1447,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
}
}
private class GetUUIDUpdatesRequired extends BukkitRunnable {
private class GetUUIDUpdatesRequired implements Runnable {
public void run() {
massUpdateLock.lock();
List<String> names = new ArrayList<>();
@@ -1414,7 +1499,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
}
if (column_exists) {
mcMMO.p.getLogger().info("Removing party name from users table...");
logger.info("Removing party name from users table...");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "users` DROP COLUMN `party`");
}
@@ -1448,7 +1533,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
}
if (!column_exists) {
mcMMO.p.getLogger().info("Adding skill total column to skills table...");
logger.info("Adding skill total column to skills table...");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "skills` ADD COLUMN `total` int NOT NULL DEFAULT '0'");
statement.executeUpdate("UPDATE `" + tablePrefix + "skills` SET `total` = (taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing+alchemy)");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "skills` ADD INDEX `idx_total` (`total`) USING BTREE");
@@ -1484,7 +1569,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
}
if (column_exists) {
mcMMO.p.getLogger().info("Removing Spout HUD type from huds table...");
logger.info("Removing Spout HUD type from huds table...");
statement.executeUpdate("ALTER TABLE `" + tablePrefix + "huds` DROP COLUMN `hudtype`");
}
@@ -1509,7 +1594,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
PreparedStatement statement = null;
try {
statement = connection.prepareStatement("SELECT id, user FROM " + tablePrefix + "users WHERE uuid = ? OR (uuid IS NULL AND user = ?)");
statement = connection.prepareStatement("SELECT id, `user` FROM " + tablePrefix + "users WHERE uuid = ? OR (uuid IS NULL AND `user` = ?)");
statement.setString(1, uuid.toString());
statement.setString(2, playerName);
resultSet = statement.executeQuery();
@@ -1538,7 +1623,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
PreparedStatement statement = null;
try {
statement = connection.prepareStatement("SELECT id, user FROM " + tablePrefix + "users WHERE user = ?");
statement = connection.prepareStatement("SELECT id, `user` FROM " + tablePrefix + "users WHERE `user` = ?");
statement.setString(1, playerName);
resultSet = statement.executeQuery();
@@ -1571,7 +1656,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
@Override
public void onDisable() {
mcMMO.p.debug("Releasing connection pool resource...");
LogUtils.debug(logger, "Releasing connection pool resource...");
miscPool.close();
loadPool.close();
savePool.close();
@@ -1613,19 +1698,19 @@ public final class SQLDatabaseManager implements DatabaseManager {
*/
//Alter users table
mcMMO.p.getLogger().info("SQL Converting tables from latin1 to utf8mb4");
logger.info("SQL Converting tables from latin1 to utf8mb4");
//Update "user" column
try {
mcMMO.p.getLogger().info("Updating user column to new encoding");
logger.info("Updating user column to new encoding");
statement.executeUpdate(getUpdateUserInUsersTableSQLQuery());
//Update "uuid" column
mcMMO.p.getLogger().info("Updating user column to new encoding");
logger.info("Updating user column to new encoding");
statement.executeUpdate(getUpdateUUIDInUsersTableSQLQuery());
//Update "mobhealthbar" column
mcMMO.p.getLogger().info("Updating mobhealthbar column to new encoding");
logger.info("Updating mobhealthbar column to new encoding");
statement.executeUpdate(getUpdateMobHealthBarInHudsTableSQLQuery());
mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.SQL_CHARSET_UTF8MB4);
@@ -1639,7 +1724,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
private String getUpdateUserInUsersTableSQLQuery() {
return "ALTER TABLE\n" +
" " + tablePrefix + "users\n" +
" CHANGE user user\n" +
" CHANGE `user` user\n" +
" " + USER_VARCHAR + "\n" +
" CHARACTER SET utf8mb4\n" +
" COLLATE utf8mb4_unicode_ci;";
@@ -1664,4 +1749,28 @@ public final class SQLDatabaseManager implements DatabaseManager {
" CHARACTER SET utf8mb4\n" +
" COLLATE utf8mb4_unicode_ci;";
}
public void printAllTablesWithColumns(Connection connection) {
try {
DatabaseMetaData metaData = connection.getMetaData();
String[] types = {"TABLE"};
ResultSet tables = metaData.getTables(null, null, "%", types);
while (tables.next()) {
String tableName = tables.getString("TABLE_NAME");
System.out.println("Table: " + tableName);
ResultSet columns = metaData.getColumns(null, null, tableName, "%");
while (columns.next()) {
String columnName = columns.getString("COLUMN_NAME");
String columnType = columns.getString("TYPE_NAME");
System.out.println(" Column: " + columnName + " Type: " + columnType);
}
columns.close();
}
tables.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

View File

@@ -29,8 +29,7 @@ public class FlatFileDataUtil {
/*
* First fix the bad data values if they exist
*/
if(dataContainer instanceof BadCategorizedFlatFileData) {
BadCategorizedFlatFileData badData = (BadCategorizedFlatFileData) dataContainer;
if(dataContainer instanceof BadCategorizedFlatFileData badData) {
splitData = repairBadData(dataContainer.getSplitData(), badData.getBadDataIndexes());
} else {
splitData = dataContainer.getSplitData();
@@ -80,6 +79,8 @@ public class FlatFileDataUtil {
case SKILLS_TAMING:
case SKILLS_FISHING:
case SKILLS_ALCHEMY:
case SKILLS_CROSSBOWS:
case SKILLS_TRIDENTS:
return String.valueOf(startingLevel);
case OVERHAUL_LAST_LOGIN:
return String.valueOf(-1L);
@@ -91,6 +92,9 @@ public class FlatFileDataUtil {
case COOLDOWN_SKULL_SPLITTER:
case COOLDOWN_SUPER_BREAKER:
case COOLDOWN_BLAST_MINING:
case COOLDOWN_SUPER_SHOTGUN:
case COOLDOWN_TRIDENTS:
case COOLDOWN_ARCHERY:
case SCOREBOARD_TIPS:
case COOLDOWN_CHIMAERA_WING:
case EXP_MINING:
@@ -106,6 +110,8 @@ public class FlatFileDataUtil {
case EXP_TAMING:
case EXP_FISHING:
case EXP_ALCHEMY:
case EXP_CROSSBOWS:
case EXP_TRIDENTS:
return "0";
case UUID_INDEX:
throw new IndexOutOfBoundsException(); //TODO: Add UUID recovery? Might not even be worth it.

View File

@@ -37,8 +37,7 @@ 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(mcMMO.p.getGeneralConfig().isLevelUpBroadcastsPartyMembersOnly()) {
@@ -75,7 +74,7 @@ public class LevelUpBroadcastPredicate<T extends CommandSender> implements Predi
}
//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
}

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