Compare commits

..

397 Commits

Author SHA1 Message Date
Auxilor
f77fc5d182 Fixed compile bug 2022-10-02 14:24:30 +01:00
Auxilor
6d1cc4c05d Fixed buildscript comments 2022-10-02 14:19:16 +01:00
Auxilor
0775f0992f Internal refactoring, added Model Engine support as an arg parser 2022-10-02 14:12:57 +01:00
Auxilor
debb39105d Moved #getPage #getMaxPage to Menu 2022-10-02 12:20:57 +01:00
Auxilor
3b4aa59bfb Fixed startup bug 2022-10-02 12:03:29 +01:00
Auxilor
4e902c3964 Added warning to legacy MySQL 2022-10-02 02:20:58 +01:00
Auxilor
3e325697e7 Added PersistentDataKeyType#CONFIG 2022-10-02 02:17:42 +01:00
Auxilor
13b3e1e440 Cleaning up after Handler 2022-10-02 02:08:22 +01:00
Auxilor
2b2406a4d0 Deprecated PluginDependent 2022-10-02 01:57:13 +01:00
Auxilor
048982c74a Deprecated PluginDependent 2022-10-02 01:56:45 +01:00
Auxilor
29b63a2ebb Removed Handler, HandlerComponent, and all internal-only API components except Eco; huge backend rework 2022-10-02 01:52:35 +01:00
Auxilor
2a9cbdacfd Cleanup 2022-10-02 00:33:36 +01:00
Auxilor
35cfcdf4a9 Improved ConfigSlot 2022-10-02 00:30:30 +01:00
Auxilor
06c1dc9afb Fixed excludes 2022-10-01 22:34:06 +01:00
Auxilor
18b58d584f Fixes to GUI 2022-10-01 22:31:37 +01:00
Auxilor
a774791e65 Updated excludes 2022-10-01 22:26:43 +01:00
Auxilor
bc22adae84 Fixed changing item bugs with Menu, added Menu#allowsChangingHeldItem 2022-10-01 22:24:24 +01:00
Auxilor
0eba82b221 Added .toml support to config 2022-10-01 21:59:16 +01:00
Auxilor
4822ec3955 Prevented changing the held item with a menu open 2022-10-01 20:55:56 +01:00
Auxilor
b845001467 Many improvements to captive items and menus 2022-10-01 14:36:53 +01:00
Auxilor
25b6a15c9c Fixed getStringsOrNull 2022-10-01 13:11:42 +01:00
Auxilor
1a3d035f78 Revert "Fixed null lore bug with AbstractItemStackBuilder"
This reverts commit a69f9f6e11.
2022-10-01 13:02:21 +01:00
Auxilor
a69f9f6e11 Fixed null lore bug with AbstractItemStackBuilder 2022-10-01 12:55:28 +01:00
Auxilor
6efd9e4fcd Fixed MySQLDataHandler 2022-10-01 12:47:41 +01:00
Auxilor
3e948beb7a Hotfix for SnakeYaml 2022-09-30 20:05:16 +01:00
Auxilor
a8a491a0b7 Brushing over some deprecated behaviour 2022-09-30 19:59:34 +01:00
Auxilor
2c0330898c Javadoc 2022-09-30 19:57:23 +01:00
Auxilor
e9794cfbf4 Fixed OfflinePlayer#exactBalance 2022-09-30 19:54:10 +01:00
Auxilor
1694d858bc Fixed EconomyIntegration javadoc 2022-09-30 19:51:23 +01:00
Auxilor
b79955ae9e Switched EconomyIntegration to be based around BigDecimal 2022-09-30 19:49:20 +01:00
Auxilor
803a8c5d17 Fixed yaml size limit 2022-09-30 19:39:47 +01:00
Auxilor
c5cd15ad92 Merge remote-tracking branch 'origin/master' into develop 2022-09-30 15:24:43 +01:00
Auxilor
489b170888 Added lambda parameter names to GUI DSL 2022-09-30 15:17:39 +01:00
Auxilor
9f57a322e8 Added ItemStack#toSNBT extension function 2022-09-30 15:15:34 +01:00
Auxilor
86e113214d Internal refactoring 2022-09-30 15:10:10 +01:00
Auxilor
e791bb8893 Renamed signals to menu events 2022-09-30 15:04:44 +01:00
Auxilor
f1220bd186 Added dispenserMenu() to GUI DSL 2022-09-30 14:07:54 +01:00
Auxilor
21d933cb11 Added support for 3x3 menus, improved Java Page API. 2022-09-30 14:06:39 +01:00
Auxilor
e1c063d5f4 Added dynamic-size components 2022-09-30 13:29:50 +01:00
Auxilor
27d2b5c8a4 Added menu signals 2022-09-30 12:44:06 +01:00
Auxilor
3b34d6ef27 Made captivity reactive 2022-09-30 12:20:46 +01:00
Auxilor
bc1c8b8f46 Re-added MythicMobs (repo back up) 2022-09-30 12:09:20 +01:00
Auxilor
2fa926ec02 Fix 2022-09-30 12:05:09 +01:00
Auxilor
d7891e1218 Improved Page API 2022-09-29 20:17:57 +01:00
Auxilor
11685cd352 Fixed PageChanger 2022-09-29 20:04:43 +01:00
Auxilor
785127fe16 Optimized AbstractItemStackBuilder via FIS 2022-09-29 19:56:44 +01:00
Auxilor
4a13bc5fea Cleanup 2022-09-29 19:52:43 +01:00
Auxilor
c7ad122050 Minor fix 2022-09-29 19:52:25 +01:00
Auxilor
28d63fc2e3 Improved performance of menu renders 2022-09-29 19:51:33 +01:00
Auxilor
bb62cc0bcd Fixed default layer 2022-09-29 19:12:29 +01:00
Auxilor
740c79f087 Added layers to menus and fixed several bugs (and temporarily removed MythicCraft repos) 2022-09-29 19:10:02 +01:00
Auxilor
33ab8e04a0 Fixed javadoc 2022-09-29 17:35:53 +01:00
Auxilor
fcd3aac363 Updated to 6.43.0 2022-09-29 17:33:56 +01:00
Auxilor
753d148d1b Refactor 2022-09-29 17:33:45 +01:00
Auxilor
1bb47a9f13 Improved MergedStateMenu 2022-09-29 17:21:31 +01:00
Auxilor
40b4c26e0f Added menu pagination 2022-09-29 17:17:13 +01:00
Auxilor
97adae7b32 More GUI improvements, improving Slot API 2022-09-29 16:15:19 +01:00
Auxilor
3d35a91314 Major improvements to menus 2022-09-29 15:51:26 +01:00
Auxilor
0caa328b1e Overhauled GUI component-based backend to support reactive and static slots 2022-09-29 15:08:34 +01:00
Auxilor
ab8c946914 Reworked GUI backend to be component-based 2022-09-29 14:10:41 +01:00
Auxilor
e667537404 Fixed CustomSlot 2022-09-29 13:41:29 +01:00
Auxilor
6bd2f2b823 Codestyle 2022-09-29 12:54:54 +01:00
Auxilor
8d8a8045c0 Moved frontend -> backend communication to be purely via the handler 2022-09-29 09:51:43 +01:00
Auxilor
d5c669c72c Added shorthand NamespacedKey and FixedMetadataValue creation 2022-09-29 08:49:17 +01:00
Auxilor
28b268e175 Added %player% to configslot 2022-09-28 12:38:38 +01:00
Auxilor
33937d1ce7 Switched Crunch to fork 2022-09-28 11:04:59 +01:00
Auxilor
e971778cc3 Updated to 6.42.0 2022-09-28 10:47:51 +01:00
Auxilor
f99612ded3 Added CustomSlot, improved various GUI elements, added GUI components. 2022-09-28 10:47:42 +01:00
Auxilor
50272bbbcf Improved skull texture API backend 2022-09-28 08:44:16 +01:00
Auxilor
9a703f6190 One more held item slot fix 2022-09-26 14:02:20 +01:00
Auxilor
f8fec7eec4 Updated to 6.41.3 2022-09-26 13:57:50 +01:00
Auxilor
f6aadda4ed Fixed PacketHeldItemSlot 2022-09-26 13:57:39 +01:00
Auxilor
d8fca0f348 Switched KingdomsX to local jar 2022-09-26 12:52:46 +01:00
Auxilor
65ff4c4a31 PR Codestyle 2022-09-26 12:36:34 +01:00
Auxilor
90702bc7aa Merge remote-tracking branch 'origin/develop' into develop 2022-09-26 12:34:53 +01:00
Will FP
e81b788a1b Merge pull request #199 from mani1232/master
Update KingdomsX dependence
2022-09-26 12:34:46 +01:00
Auxilor
ebc0ee7940 Updated to 6.41.2 2022-09-26 12:33:25 +01:00
Auxilor
82d269daf1 Improved PacketWindowItems and DisplayFrame 2022-09-26 12:32:07 +01:00
Auxilor
9d5300d6ae Began display system fixes 2022-09-26 12:10:22 +01:00
mani1232
8870e4d6fb Update KingdomsX dependence 2022-09-25 21:26:21 +02:00
Auxilor
d826a9f71f Switched FabledSkyblock to local jar 2022-09-14 21:18:55 +01:00
Auxilor
7ec3355237 Updated to 6.41.1 2022-09-14 21:18:28 +01:00
Auxilor
e59a8cc2e6 Oops 2022-09-14 21:13:33 +01:00
Auxilor
88f974fd10 Fixed long standing bug with ItemProvider (and scyther integration) 2022-09-14 21:08:14 +01:00
Auxilor
dfe2f1361b Updated to 6.41.0 2022-09-14 13:58:10 +01:00
Auxilor
3826f9f713 Added item price API 2022-09-14 13:57:01 +01:00
Auxilor
c2d2303c91 Added scyther integration and BigDecimal economy support 2022-09-14 13:45:32 +01:00
Auxilor
b1158ceb3d Added configurable host to Paste 2022-09-12 14:39:15 +01:00
Auxilor
af4048afbe Updated to 6.40.2 2022-09-12 13:53:51 +01:00
Auxilor
fce12020d5 Fixed bug with old MySQL versions 2022-09-12 13:53:35 +01:00
Auxilor
7e37332b64 Updated to 6.40.1 2022-09-11 10:47:23 +01:00
Auxilor
52dbf9ff52 Codestyle 2022-09-11 10:47:00 +01:00
Auxilor
78b6292367 Merge remote-tracking branch 'origin/master' 2022-09-11 10:46:43 +01:00
Will FP
09705e787b Merge pull request #193
Fix DeluxeCombat and FabledSkyBlock integration
2022-09-11 10:46:44 +01:00
Auxilor
9c86069a85 Added option to disable the update checker 2022-09-11 10:45:40 +01:00
Auxilor
0a7acceb83 Updated to 6.40.0 2022-09-10 19:59:07 +01:00
Auxilor
40aa8b17dd Fixed MySQL changes 2022-09-10 19:58:57 +01:00
Auxilor
71eb386a19 Reworked MySQL data handler and data migration 2022-09-10 19:22:29 +01:00
Kapitowa
c857df2360 fix FabledSkyBlock integration for proper check 2022-09-09 14:45:33 +03:00
Kapitowa
f4fc611f3b Fix when damager with DeluxeCombat protection can cause damage 2022-09-09 05:31:54 +03:00
Auxilor
0d91324d47 Updated crunch 2022-09-06 15:26:46 +01:00
Auxilor
e9dbc3ec73 Updated crunch 2022-09-06 15:11:42 +01:00
Auxilor
493d1b1b6d Updated crunch 2022-09-06 15:11:14 +01:00
Auxilor
68221d5912 Updated crunch 2022-09-06 15:07:29 +01:00
Auxilor
7f2ef4e038 Updated to 6.39.1 2022-09-06 15:06:11 +01:00
Auxilor
be0a19175b Added additional players to config expression getters 2022-09-06 15:05:52 +01:00
Auxilor
5afdcd75f7 Added min and max functions to crunch 2022-09-06 14:49:40 +01:00
Auxilor
a1c0b8c857 Fixed FUUID 2022-09-06 13:25:17 +01:00
Auxilor
0442ccf58f Fixed FactionsUUID jar 2022-09-06 13:23:59 +01:00
Auxilor
1c1a796610 FactionsUUID to local jar 2022-09-06 13:19:49 +01:00
Auxilor
eacb243493 Fixed FactionsUUID 2022-09-06 13:17:55 +01:00
Auxilor
7bbed31d4e Fixed FactionsUUID 2022-09-06 13:17:43 +01:00
Auxilor
58bccf3cd7 Added songoda repo for FabledSkyblock 2022-09-06 13:15:36 +01:00
Auxilor
4502e1e311 Removed ender.zone, using JitPack build instead 2022-09-06 13:14:27 +01:00
Auxilor
054a8d5a5e Updated to 6.39.0 2022-09-06 13:04:55 +01:00
Auxilor
dbdd4785ba Added AdditionalPlayer support to placeholders 2022-09-06 13:04:00 +01:00
Will FP
35f800b62a Merge pull request #178
Added FabledSkyBlock integration in AntigriefManager
2022-09-06 12:50:56 +01:00
Auxilor
591800dba8 Updated to 6.38.3 2022-08-22 14:16:20 +02:00
Auxilor
46673e8d24 Fixed SNBT 2022-08-22 14:16:07 +02:00
Kapitowa
bb7c300074 fix space and fill softdepend 2022-08-02 18:46:09 +03:00
Kapitowa
b003ec96f7 Added FabledSkyBlock integration in AntigriefManager 2022-08-02 18:33:18 +03:00
Will FP
a526f51780 Update README.md 2022-07-28 16:07:08 +01:00
Auxilor
dd14fc666a Updated to 6.38.2 2022-07-27 19:42:19 +01:00
Auxilor
ae0150f012 Bumped ShopGUI+ 2022-07-27 19:42:06 +01:00
Auxilor
04418fa038 Updated ProtocolLib for compatibility 2022-07-27 19:40:08 +01:00
Auxilor
bcb9523315 Updated to 6.38.1 2022-07-25 16:51:55 +01:00
Auxilor
43e7972ca3 Improved menu re-renders 2022-07-25 16:51:38 +01:00
Auxilor
7ea61eb393 Removed source/target compatibility no longer required by kotlin 1.7.x 2022-07-22 14:08:33 +01:00
Auxilor
5245a9b1d8 Updated to 6.38.0 2022-07-22 14:05:53 +01:00
Auxilor
195932463c Added DisplayProperties to DisplayModule 2022-07-22 14:04:42 +01:00
Auxilor
3cf60a7e2c Added MenuUtils#getOpenMenu 2022-07-22 13:54:45 +01:00
Auxilor
0f9f57fca2 Merge remote-tracking branch 'origin/master' 2022-07-22 13:47:03 +01:00
Will FP
fe21616dd5 Merge pull request #161 from Syrent/master
Add MythicMobs 5.X support.
2022-07-22 13:46:53 +01:00
Auxilor
396144abaa Added Vector#isSafeVelocity 2022-07-22 13:46:08 +01:00
Auxilor
50b4fa59ab Added onOpen to menu 2022-07-22 13:42:48 +01:00
Auxilor
a6754379e8 Updated to 6.37.3 2022-07-07 22:55:03 +01:00
Auxilor
bbd0182c2a Fixed weird bug 2022-07-07 22:54:54 +01:00
Auxilor
0370e9f454 Fixed startup order 2022-07-03 16:49:26 +01:00
Auxilor
8d585b58cb Fixed initializing text 2022-07-03 16:45:44 +01:00
Auxilor
0bfbd4c036 Updated to 6.37.2 2022-07-03 16:38:32 +01:00
Auxilor
881839955e Added player health fixer 2022-07-03 16:38:21 +01:00
Syrent
8ffc5f9c0f Add MythicMobs 5.X support. 2022-06-28 08:07:05 +04:30
Auxilor
709de3bb5f Updated to 6.37.1 2022-06-14 12:43:11 +01:00
Auxilor
f2aa2ffd9b Removed ExactTestableItem 2022-06-14 12:43:04 +01:00
Auxilor
5ce70399f0 Improved SNBT lookups 2022-06-14 12:42:49 +01:00
Auxilor
3f8759b08a Updated to 6.37.0 2022-06-14 12:14:33 +01:00
Auxilor
abecaa6e9f Added SNBT parsing 2022-06-14 12:13:48 +01:00
Auxilor
4744bfc78b Updated to 6.36.5 2022-06-09 19:24:49 +01:00
Auxilor
487e68221a Added 1.19 support 2022-06-09 19:24:37 +01:00
Auxilor
1c68992a8e Updated to 6.36.4 2022-05-29 17:46:52 +01:00
Auxilor
c5b7d0b644 Fixed conflict finder breaking the polymart autoupdater 2022-05-29 17:46:24 +01:00
Auxilor
0f91aec3b7 Slots can now be not captive for some players 2022-05-29 11:34:32 +01:00
Auxilor
d2bf38c5c9 Updated to 6.36.3 2022-05-29 11:11:33 +01:00
Auxilor
2c96b79aba Improved slots 2022-05-29 11:11:16 +01:00
Auxilor
d539b9e59e Improvements to captive items 2022-05-28 17:33:06 +01:00
Auxilor
b0b06ef402 Updated to 6.36.2 2022-05-28 17:20:35 +01:00
Auxilor
7a84c3de3b Captive from empty, take 2 2022-05-28 17:20:23 +01:00
Auxilor
9431321e1c Revert "Added captive defaults"
This reverts commit 7adcdd572d.
2022-05-28 17:08:36 +01:00
Auxilor
4816284fba Revert "Added captive default kotlin extension"
This reverts commit 2bcbf181a9.
2022-05-28 17:08:01 +01:00
Auxilor
a9874c9386 Revert "Updated to 6.37.0"
This reverts commit fc3c80f633.
2022-05-28 17:08:01 +01:00
Auxilor
fe68760184 Revert "Fixed backwards compatibility"
This reverts commit 1f7cf78491.
2022-05-28 17:08:01 +01:00
Auxilor
5ae8e72a98 Revert "Fixed captive default"
This reverts commit 15fc6053c8.
2022-05-28 17:08:01 +01:00
Auxilor
15fc6053c8 Fixed captive default 2022-05-28 16:54:58 +01:00
Auxilor
1f7cf78491 Fixed backwards compatibility 2022-05-28 16:43:35 +01:00
Auxilor
fc3c80f633 Updated to 6.37.0 2022-05-28 16:41:30 +01:00
Auxilor
2bcbf181a9 Added captive default kotlin extension 2022-05-28 16:41:20 +01:00
Auxilor
7adcdd572d Added captive defaults 2022-05-28 16:40:14 +01:00
Auxilor
f6eba21006 Updated to 6.36.1 2022-05-28 16:10:40 +01:00
Auxilor
cc02f26807 Fixed key registry 2022-05-28 16:10:30 +01:00
Auxilor
60f552ce65 KDoc Formatting 2022-05-28 14:38:59 +01:00
Auxilor
9fe8d4ad15 Added more slot builders 2022-05-28 14:36:48 +01:00
Auxilor
b835988eec Added toSingletonList 2022-05-28 14:32:35 +01:00
Auxilor
22366835de Added additional MaskItems constructor 2022-05-28 14:31:20 +01:00
Auxilor
cdd1baec6c Fixed codemc 2022-05-28 14:28:24 +01:00
Auxilor
1ea0da365a Removed villager-display-fix 2022-05-28 13:59:38 +01:00
Auxilor
852d40372d Added option to toggle displayed recipes 2022-05-28 13:59:03 +01:00
Auxilor
999c831dd7 Removed non-functional packet splitting 2022-05-28 13:47:44 +01:00
Auxilor
80fa5d346a Fixed recipe packet fixer 2022-05-28 12:37:47 +01:00
Auxilor
336cdc3716 Added recipe packet splitting 2022-05-28 12:31:55 +01:00
Auxilor
a49a9e92b4 Updated villager trade 2022-05-28 12:23:47 +01:00
Auxilor
1c6e64832e Minor changes 2022-05-28 12:12:35 +01:00
Auxilor
44a141cddc Improved economy helpers 2022-05-27 19:03:53 +01:00
Auxilor
ea4956870e Added more GUI kotlin utils 2022-05-27 19:02:47 +01:00
Auxilor
9207d1782b Various changes 2022-05-27 17:09:00 +01:00
Auxilor
9debcb7089 Server will no longer restart after data migration 2022-05-27 16:25:11 +01:00
Auxilor
ef53ee2ed3 Fixed constrained types 2022-05-27 16:17:31 +01:00
Auxilor
4c90360038 More MySQL fixes 2022-05-27 16:07:24 +01:00
Auxilor
d4b5102913 Fixed MySQL 2022-05-27 16:01:44 +01:00
Auxilor
f4553c544a Fixed MySQL 2022-05-27 15:57:15 +01:00
Auxilor
5ad1db72fc Fixed minimize 2022-05-27 15:52:36 +01:00
Auxilor
c761df9ee6 Data Handler changes 2022-05-27 15:48:13 +01:00
Auxilor
b6d79da4e1 Improved config.yml header 2022-05-27 15:43:02 +01:00
Auxilor
42f41618ca Added warning for MySQL users 2022-05-27 15:38:28 +01:00
Auxilor
de878fd423 Codestyle 2022-05-27 15:29:39 +01:00
Auxilor
7782657d57 Improved DataHandlers again 2022-05-27 15:29:03 +01:00
Auxilor
7778425936 Improved DataHandler 2022-05-27 15:12:05 +01:00
Auxilor
6446cef255 OOps 2022-05-27 15:06:18 +01:00
Auxilor
8dacecbcba Added big ominous comment to the MySQL Data Handler 2022-05-27 15:06:00 +01:00
Auxilor
5f8ec4f94a Added PersistentDataKeyType#STRING_LIST 2022-05-27 14:56:53 +01:00
Auxilor
d7847e9efc Optimized writes mongo 2022-05-27 14:17:17 +01:00
Auxilor
930ecd4896 Improved conflict finder 2022-05-27 14:03:54 +01:00
Auxilor
af8d6a4167 Added OfflinePlayer#balance kotlin extensions 2022-05-27 14:02:52 +01:00
Auxilor
361f0a0103 Added unused suppression 2022-05-27 13:58:45 +01:00
Auxilor
eb545a7d9e Fixed relocations 2022-05-27 13:53:28 +01:00
Auxilor
d3c64deef4 Fixed minimize / exclude 2022-05-27 13:51:20 +01:00
Auxilor
31db9dcb95 Minimzed plugin module 2022-05-27 13:24:35 +01:00
Auxilor
4938ad84bc Added clarifying comment 2022-05-27 13:02:51 +01:00
Auxilor
06b2301da1 Janky fix for mongo logging 2022-05-27 13:00:59 +01:00
Auxilor
c307878c09 More migration improvements 2022-05-26 20:40:57 +01:00
Auxilor
3b10ff01ec Updated to 6.36.0 2022-05-26 20:17:47 +01:00
Auxilor
e042754f5d Mongo improvements / Added data migration 2022-05-26 20:17:31 +01:00
Auxilor
c2b8a80560 Improved MongoDB 2022-05-25 20:21:50 +01:00
Auxilor
07c0e72564 Added MongoDB data handler 2022-05-25 20:08:24 +01:00
Auxilor
de9b961d83 Revert "Added LONG_STRING column type"
This reverts commit 83958c719c.
2022-05-25 19:20:47 +01:00
Auxilor
83958c719c Added LONG_STRING column type 2022-05-21 19:35:05 +01:00
Auxilor
9c3dfaeb01 Updated to 6.35.12 2022-05-19 17:13:00 +01:00
Auxilor
7e61340285 Fixed static placeholder string formatting 2022-05-19 17:12:51 +01:00
Auxilor
78b76cb453 Updated to 6.35.11 2022-05-18 16:02:56 +01:00
Auxilor
bb1da29704 Added placeholder injections to strings 2022-05-18 16:02:36 +01:00
Auxilor
cf152215d3 Cleaned up internal 2022-05-18 15:00:23 +01:00
Auxilor
e6a59fbc91 Updated to 6.35.10 2022-05-18 10:53:06 +01:00
Will FP
b787f8b76a Merge pull request #133
Bump io.papermc.paperweight.userdev from 1.3.5 to 1.3.6
2022-05-18 10:52:43 +01:00
Will FP
ccc83da5b0 Merge pull request #135
Bump caffeine from 3.0.6 to 3.1.0
2022-05-18 10:52:30 +01:00
Will FP
f11068f2f1 Merge pull request #145
add CMI gradient format
2022-05-18 10:52:18 +01:00
Will FP
a5cc1a5d32 Merge pull request #146
Add an exception for armorstand in interact flag of WG
2022-05-18 10:52:10 +01:00
Kapitowa
7440749ba5 Add an exception for armorstand in interact flag of WG 2022-05-18 01:28:10 +03:00
Kapitowa
75010d25fa add CMI gradient format 2022-05-18 01:01:07 +03:00
Auxilor
bb95376b93 Removed async-display 2022-05-17 19:55:13 +01:00
Auxilor
ab6d4c7aa2 Updated to 6.35.9 2022-05-17 16:53:57 +01:00
Auxilor
9ab8827e55 Fixed non-applied FIS Flags 2022-05-17 16:45:37 +01:00
Auxilor
991290095b Updated to 6.35.8 2022-05-17 10:19:48 +01:00
Auxilor
8735478fc3 More bit manip 2022-05-17 10:19:36 +01:00
Auxilor
6e44f09621 Fixed ItemFlags in FastItemStack 2022-05-17 10:11:04 +01:00
Auxilor
060106881e Updated to 6.35.7 2022-05-13 12:07:26 +01:00
Auxilor
96cc9706b3 Placeholder injection fixes 2022-05-13 12:07:15 +01:00
Auxilor
3d87b1eb73 Revert "Fixed placeholder injection bugs"
This reverts commit 06bcb10958.
2022-05-13 11:46:57 +01:00
Auxilor
4c4247b4ec Revert "Updated to 6.35.7"
This reverts commit b94dc4ac3a.
2022-05-13 11:46:57 +01:00
Auxilor
b94dc4ac3a Updated to 6.35.7 2022-05-13 11:34:58 +01:00
Auxilor
06bcb10958 Fixed placeholder injection bugs 2022-05-13 11:34:42 +01:00
Auxilor
295095e9ce Fixed spelling 2022-05-09 12:34:14 +01:00
Auxilor
ba9c5865e3 Updated to 6.35.6 2022-05-09 12:30:22 +01:00
Auxilor
d24be4121f Added conflict finder 2022-05-09 12:30:14 +01:00
Auxilor
bcc5e4ef08 Skull improvements 2022-05-09 10:23:35 +01:00
Auxilor
bf8609666a Codestyle 2022-05-09 10:20:05 +01:00
Auxilor
1a02335825 Fixed dumbest error of all time 2022-05-09 10:14:18 +01:00
Auxilor
f5ef98ec5c Improved custom item lookup 2022-05-09 10:11:06 +01:00
Auxilor
45135e2b55 Updated to 6.35.5 2022-05-08 17:27:14 +01:00
Auxilor
758b42ff8e Fixed ItemsAdder integration 2022-05-08 17:26:50 +01:00
Auxilor
4a134402da Fixed Prerequisite#HAS_PAPER 2022-05-06 09:09:54 +01:00
Auxilor
e6ad4c9268 Updated to 6.35.4 2022-05-06 09:08:38 +01:00
Auxilor
809dcbae85 Improved NaturalExpGainListeners for paper 2022-05-06 09:07:57 +01:00
Auxilor
d7fce6834c Updated to 6.35.3 2022-05-03 13:05:41 +01:00
Auxilor
ac807a991b Players can no longer tab-complete commands they don't have permission for 2022-05-03 13:05:32 +01:00
Auxilor
ba315ced3c Updated to 6.35.2 2022-04-29 22:45:42 +01:00
Auxilor
f2e65174f9 Reverted to old block vein code 2022-04-29 22:45:02 +01:00
dependabot[bot]
bd5555ff01 Bump caffeine from 3.0.6 to 3.1.0
Bumps [caffeine](https://github.com/ben-manes/caffeine) from 3.0.6 to 3.1.0.
- [Release notes](https://github.com/ben-manes/caffeine/releases)
- [Commits](https://github.com/ben-manes/caffeine/compare/v3.0.6...v3.1.0)

---
updated-dependencies:
- dependency-name: com.github.ben-manes.caffeine:caffeine
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-28 21:41:30 +00:00
Auxilor
d5584e863b Updated to 6.35.1 2022-04-27 18:52:39 +01:00
Auxilor
d9c0e8e763 Fixed overload resolution ambiguity 2022-04-27 18:52:27 +01:00
Auxilor
b223f8457d Removed unused param 2022-04-27 18:23:36 +01:00
Auxilor
694d57edf4 Changing state will no longer re-render 2022-04-27 18:20:36 +01:00
Auxilor
02afe7d788 Fixed state-render infinite loops 2022-04-27 16:20:48 +01:00
Auxilor
0593e631ea Improved reactive state 2022-04-27 16:16:00 +01:00
Auxilor
2f22e02ff1 Added MenuBuilder#onRender to add reactive state 2022-04-27 16:14:28 +01:00
Auxilor
fb240bfd0a Replaced Menu data with Menu state 2022-04-27 16:07:38 +01:00
Auxilor
11c49a543f Improved config DSL 2022-04-27 14:17:13 +01:00
Auxilor
c565f5248d Fixed ShopWrapper deprecation comment 2022-04-27 13:44:51 +01:00
Auxilor
fac4f40430 Fixed codestyle 2022-04-27 13:28:04 +01:00
Auxilor
a20cb63755 Improved integration API 2022-04-27 13:18:57 +01:00
Auxilor
f17f67227f Commented CustomItem 2022-04-27 13:16:53 +01:00
Auxilor
106c9b37fc Removed unneeded test 2022-04-27 13:11:25 +01:00
Auxilor
f7cfcd5cbb Fixed redundant method 2022-04-27 13:06:35 +01:00
Auxilor
44d9581222 Cleanup 2022-04-27 13:04:57 +01:00
Auxilor
0fa30a5f62 Finally removed Display#callDisplayModule 2022-04-27 13:04:24 +01:00
Auxilor
84f439976c Fixed refactoring bugs 2022-04-27 12:51:45 +01:00
Auxilor
01bcb62b31 Refactored -Wrapper suffix to -Integration 2022-04-27 12:42:20 +01:00
Auxilor
47c8ea3341 Switched from DisplayPriority to weight 2022-04-27 12:31:27 +01:00
Auxilor
e28c4288a3 Removed ItemMeta usage in EcoDisplayHandler 2022-04-27 12:22:58 +01:00
Auxilor
386792d7ca Reworked PersistentDataContainer 2022-04-27 12:15:37 +01:00
Auxilor
8c6d98a666 Added string progress bars 2022-04-26 11:17:24 +01:00
Auxilor
6f42224593 Various codestyle improvements 2022-04-25 20:24:52 +01:00
Auxilor
36c857086b Fixed KDoc 2022-04-25 20:17:46 +01:00
Auxilor
014bcddc0a Fixed problem with extension functinos 2022-04-25 20:16:36 +01:00
Auxilor
96c56b0291 Codestyle 2022-04-25 20:03:09 +01:00
Auxilor
c1fe633e72 Improved config DSL 2022-04-25 20:02:28 +01:00
Auxilor
c9a9d86160 Added ConfigHelpers.kt 2022-04-25 19:44:01 +01:00
Auxilor
e79c7e9881 Codestyle 2022-04-25 13:40:26 +01:00
Auxilor
be617241e7 Removed ScriptUtils 2022-04-25 13:39:18 +01:00
Auxilor
cb9b59ae01 Added ScriptUtils 2022-04-25 11:32:47 +01:00
Auxilor
a993acae72 Fixed deprecated method use 2022-04-25 10:20:49 +01:00
Auxilor
e6cdc7d2ba Added PlayerUtils#tryAsPlayer 2022-04-25 10:14:24 +01:00
Auxilor
94534b2f61 Refactoring 2022-04-25 10:09:09 +01:00
Auxilor
fe6b7805c7 Added ShopSellEvent as well as integrations for zShop, EconomyShopGUI, and DeluxeSellwands 2022-04-25 10:03:23 +01:00
Auxilor
be25f2f4fc Added startup message in constructor 2022-04-25 09:42:03 +01:00
Auxilor
a19cc7df1e Added ExtendedPersistentDataContainer.create 2022-04-23 15:54:40 +01:00
Auxilor
13dbd08dcc Removed debug and now-unused API 2022-04-23 14:14:43 +01:00
dependabot[bot]
5f80b6052d Bump io.papermc.paperweight.userdev from 1.3.5 to 1.3.6
Bumps [io.papermc.paperweight.userdev](https://github.com/PaperMC/paperweight) from 1.3.5 to 1.3.6.
- [Release notes](https://github.com/PaperMC/paperweight/releases)
- [Commits](https://github.com/PaperMC/paperweight/compare/v1.3.5...v1.3.6)

---
updated-dependencies:
- dependency-name: io.papermc.paperweight.userdev
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-22 21:29:44 +00:00
Auxilor
a48885b79a Added kotlin extensions to ExtendedPersistentDataContainer 2022-04-22 21:18:14 +01:00
Auxilor
350c2d8775 Added ExtendedPersistentDataContainer#getBase 2022-04-22 20:53:26 +01:00
Auxilor
5988dfb1fd Fixed ExtendedPersistentDataContainer 2022-04-22 20:47:21 +01:00
Auxilor
57687859e4 Updated to 6.35.0 2022-04-22 20:45:16 +01:00
Auxilor
ef42e689ae Added ExtendedPersistentDataContainer 2022-04-22 20:44:59 +01:00
Auxilor
9a3aac9a66 Stripped out current mining speed check 2022-04-22 20:15:02 +01:00
Auxilor
7be5fbfbc4 Debug changes 2022-04-22 16:35:15 +01:00
Auxilor
4b344ccd18 More changes 2022-04-22 16:31:44 +01:00
Auxilor
3f50ae0a44 Began javassisting 2022-04-22 11:36:44 +01:00
Auxilor
afb498b4bf Added more mappings to FastItemStack 2022-04-22 10:48:33 +01:00
Auxilor
6b18b06763 Fixed placeholder equality 2022-04-22 09:55:55 +01:00
Auxilor
033e334877 Codestyle and reduced memory garbage 2022-04-22 09:53:40 +01:00
Auxilor
eb9112e480 Updated placeholder injection 2022-04-22 09:48:11 +01:00
Auxilor
b75e4d59e4 Changed getNearbyBlocks 2022-04-21 10:04:16 +01:00
Auxilor
c69bb6904f Minor fixes 2022-04-20 11:31:37 +01:00
Auxilor
9f193b7206 Fixed val using annotations 2022-04-20 11:28:55 +01:00
Auxilor
6fce2c13fe Updated to 6.34.0 2022-04-20 11:25:19 +01:00
Auxilor
02342c11a6 Added utility methods for base NBT 2022-04-20 11:25:00 +01:00
Auxilor
2fde56df0d Added ability to modify full item NBT via PersistentDataContainers and FastItemStack 2022-04-20 11:19:24 +01:00
Auxilor
cb64dedd74 Updated to kotlin 1.6.21 2022-04-20 10:57:27 +01:00
Auxilor
a7c489413e Moved IridiumSkyblock to use jar 2022-04-20 10:56:47 +01:00
Auxilor
f9ed174e31 Added PersistentDataHolder to FastItemStack 2022-04-13 13:21:37 +01:00
Auxilor
496d878a14 Added missing FIS method 2022-04-13 12:55:48 +01:00
Auxilor
00853d4a92 Fixed getSkullTexture 2022-04-13 12:39:32 +01:00
Auxilor
5eb0d2380a Updated to 6.33.0 2022-04-13 12:37:19 +01:00
Auxilor
d19cff9a42 Added component methods to FastItemStack 2022-04-13 12:36:49 +01:00
Auxilor
234b5fdd8e Fixed newbiehelper and bentobox 2022-04-11 15:02:29 +01:00
Auxilor
2dbe6c7fe4 Updated to 6.32.2 2022-04-11 14:55:48 +01:00
Auxilor
9d4d1ace08 Fixed use_spell and tempt 2022-04-11 14:55:35 +01:00
Auxilor
364550d228 Pain 2022-04-06 13:47:01 +01:00
Auxilor
d5e8cbaf33 Updated to 6.32.1 2022-04-06 13:35:34 +01:00
Auxilor
c4d532fda9 Removed MySQL relocation 2022-04-06 13:34:33 +01:00
Auxilor
aa097cf7e2 Fixed wrong MySQL driver class 2022-04-06 13:08:29 +01:00
Auxilor
6f4ca40a94 Changed load order for custom items 2022-04-05 16:29:13 +01:00
Auxilor
2ef9b4033c Updated to 6.32.0 2022-04-05 15:38:44 +01:00
Auxilor
9aa22ffc86 Added Items#mergeFrom 2022-04-05 15:38:34 +01:00
Auxilor
d81c1e6fcb Added comment 2022-04-05 13:22:13 +01:00
Auxilor
ac72e0770a Undid last commit 2022-04-05 13:17:29 +01:00
Auxilor
5e3e09c4bc Moved adventure api to api configuration 2022-04-05 13:17:07 +01:00
Auxilor
ee945d5901 Updated to 6.31.4 2022-04-05 13:14:48 +01:00
Auxilor
7f747f3afc Fixed & color code 2022-04-05 13:12:49 +01:00
Auxilor
2d47593f51 More build changes 2022-04-05 13:12:29 +01:00
Auxilor
df529ba239 Minimized use of the lib-loader 2022-04-05 13:01:05 +01:00
Auxilor
2fea736631 Updated to 6.31.3 2022-04-02 14:36:23 +01:00
Auxilor
9df4fae2dc Fixed colors in console on new versions of paper 2022-04-02 14:36:14 +01:00
Auxilor
ca964a1a40 Updated to 6.31.2 and fixed default key values 2022-03-29 16:17:59 +01:00
Auxilor
ada2832839 Fixed data.yml 2022-03-28 21:24:34 +01:00
Auxilor
4d92cbb7ff Fixed PersistentDataKeyType equality 2022-03-28 14:33:28 +01:00
Auxilor
d6ab36929b Changed data reading 2022-03-28 14:29:56 +01:00
Auxilor
e06623d3fe Fixed some config constructors 2022-03-28 14:23:27 +01:00
Auxilor
8b70a37459 Updated to 6.31.1 2022-03-28 14:21:19 +01:00
Auxilor
daab3829bc Config changes 2022-03-28 14:21:09 +01:00
Auxilor
d09021707b Fixed name arg parser 2022-03-27 13:20:53 +01:00
Auxilor
bea8cb5757 Updated to 6.31.0 2022-03-27 13:20:21 +01:00
Auxilor
bde546efcb Added Items#toLookupString 2022-03-27 13:19:48 +01:00
Auxilor
e1ffc851a3 Updated to 6.30.2 2022-03-26 16:02:09 +00:00
Auxilor
828229b3e5 Updated to 6.30.1 2022-03-26 15:43:34 +00:00
Auxilor
f36e2f5349 Fixed config header duplication bug 2022-03-26 15:43:24 +00:00
Auxilor
cdbe5b141a Fixed yaml printing 2022-03-24 18:13:11 +00:00
Auxilor
08c3fc0cfa Fixed config removing 2022-03-24 15:53:12 +00:00
Auxilor
8f758fb100 Changed bukkit -> eco config mapping 2022-03-24 12:21:15 +00:00
Auxilor
ec339b0ecd Removed debug println 2022-03-24 12:13:49 +00:00
Auxilor
9dedfb86a5 Fixed more config things 2022-03-24 12:13:02 +00:00
Auxilor
0146cff8d3 More config work 2022-03-24 11:26:41 +00:00
Auxilor
2454d99d84 Reworked getKeys 2022-03-24 10:50:35 +00:00
Auxilor
7d9b1bc266 Removed debug toggle 2022-03-24 10:46:52 +00:00
Auxilor
77c56c46a8 Keep the reworks coming 2022-03-24 10:41:09 +00:00
Auxilor
85303098a7 Reworked configs (again) 2022-03-24 09:46:27 +00:00
Auxilor
821dc62d56 More anti-anchor prevention 2022-03-23 19:44:23 +00:00
Auxilor
f9af4a9e66 Removed debug 2022-03-23 16:26:51 +00:00
Auxilor
41b9d6b01d Config cleanup 2022-03-23 16:24:17 +00:00
Auxilor
7a521acccf More config improvements (and codestyle) 2022-03-23 15:50:25 +00:00
Auxilor
49233aef88 Comment headers are now preserved 2022-03-23 15:32:43 +00:00
Auxilor
c5b47ed073 And they dont stop coming 2022-03-23 14:21:25 +00:00
Auxilor
ddcef7cf0c The config rewrites never stop 2022-03-23 13:53:56 +00:00
Auxilor
0f86e1c1c1 More config rewrites 2022-03-23 12:59:53 +00:00
Auxilor
f0f7e229ea Began complete config rewrite 2022-03-23 12:28:34 +00:00
Auxilor
ea674a3757 Merge remote-tracking branch 'origin/develop' into develop 2022-03-23 10:51:50 +00:00
Auxilor
b7c51eba5e Fixed more config bugs 2022-03-22 19:55:19 +00:00
Auxilor
1127bf1700 Renamed ConfigBuilder to BuildableConfig 2022-03-22 16:59:20 +00:00
Auxilor
376e3284fb Fixed config bugs 2022-03-22 16:53:16 +00:00
Auxilor
12f355b205 Fixed GUI and rendering bugs 2022-03-22 16:46:32 +00:00
Auxilor
f4b02591e8 Clarified javadoc 2022-03-22 16:25:18 +00:00
Auxilor
f843725cf5 Fixed missing method 2022-03-22 16:16:58 +00:00
Auxilor
ed0536c188 Fixed stupidity 2022-03-22 14:14:45 +00:00
Auxilor
849e005095 More oraxen tweaks 2022-03-22 14:12:39 +00:00
Auxilor
927d61dd6b Marked ConfigUpdater as @Documented 2022-03-22 14:09:36 +00:00
Auxilor
9285cffc56 Updated ConfigUpdater javadoc 2022-03-22 14:08:25 +00:00
Auxilor
1b6c90e87d Updated to 6.30.0 2022-03-22 14:07:14 +00:00
Auxilor
c79de6fbc1 Marked more deprecated things as for removal 2022-03-22 14:06:59 +00:00
Auxilor
fc83ebbb34 Removed all long-deprecated config methods 2022-03-22 14:03:02 +00:00
Auxilor
f330cc954c Added ConfigBuilder and more TransientConfig constructors 2022-03-22 14:01:18 +00:00
Auxilor
df4f98251c Improved setting with JSON configs 2022-03-22 12:58:20 +00:00
Auxilor
74861e9c01 Improved config setters 2022-03-22 11:36:16 +00:00
Auxilor
7dad9d7875 Fixed config setters 2022-03-22 11:24:27 +00:00
Auxilor
338b9b2d4e Fixed configs 2022-03-22 11:02:01 +00:00
Auxilor
f6d83867f3 Updated to 6.29.3 2022-03-22 10:41:52 +00:00
Auxilor
bb632ac849 Codestyle 2022-03-22 10:40:02 +00:00
Auxilor
793f946b44 Removed long-deprecated, for-removal configs 2022-03-22 10:39:20 +00:00
Auxilor
519a59cc88 Reworked configs, marked all deprecated configs for removal 2022-03-22 10:35:44 +00:00
Auxilor
79b1bff547 Recoded GUI internals 2022-03-22 09:55:10 +00:00
373 changed files with 9935 additions and 5584 deletions

View File

@@ -39,7 +39,7 @@ and many more.
# For developers # For developers
## Javadoc ## Javadoc
The 6.27.2 Javadoc can be found [here](https://javadoc.jitpack.io/com/willfp/eco/6.27.2/javadoc/) The 6.38.2 Javadoc can be found [here](https://javadoc.jitpack.io/com/willfp/eco/6.38.2/javadoc/)
## Plugin Information ## Plugin Information

View File

@@ -4,7 +4,7 @@ buildscript {
} }
dependencies { dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10")
} }
} }
@@ -13,17 +13,18 @@ plugins {
id("com.github.johnrengelman.shadow") version "7.1.2" id("com.github.johnrengelman.shadow") version "7.1.2"
id("maven-publish") id("maven-publish")
id("java") id("java")
kotlin("jvm") version "1.6.10" kotlin("jvm") version "1.7.10"
} }
dependencies { dependencies {
implementation(project(":eco-api")) implementation(project(":eco-api"))
implementation(project(":eco-core:core-plugin")) implementation(project(path = ":eco-core:core-plugin", configuration = "shadow"))
implementation(project(":eco-core:core-proxy")) implementation(project(":eco-core:core-proxy"))
implementation(project(":eco-core:core-backend")) implementation(project(":eco-core:core-backend"))
implementation(project(path = ":eco-core:core-nms:v1_17_R1", configuration = "reobf")) implementation(project(path = ":eco-core:core-nms:v1_17_R1", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_18_R1", configuration = "reobf")) implementation(project(path = ":eco-core:core-nms:v1_18_R1", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_18_R2", configuration = "reobf")) implementation(project(path = ":eco-core:core-nms:v1_18_R2", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_19_R1", configuration = "reobf"))
} }
allprojects { allprojects {
@@ -44,11 +45,8 @@ allprojects {
// SuperiorSkyblock2 // SuperiorSkyblock2
maven("https://repo.bg-software.com/repository/api/") maven("https://repo.bg-software.com/repository/api/")
// NMS (for jitpack compilation)
maven("https://repo.codemc.org/repository/nms/")
// mcMMO, BentoBox // mcMMO, BentoBox
maven("https://repo.codemc.org/repository/maven-public/") maven("https://repo.codemc.io/repository/maven-public/")
// Spigot API, Bungee API // Spigot API, Bungee API
maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/") maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/")
@@ -63,7 +61,7 @@ allprojects {
maven("https://maven.enginehub.org/repo/") maven("https://maven.enginehub.org/repo/")
// FactionsUUID // FactionsUUID
maven("https://ci.ender.zone/plugin/repository/everything/") //maven("https://ci.ender.zone/plugin/repository/everything/")
// NoCheatPlus // NoCheatPlus
maven("https://repo.md-5.net/content/repositories/snapshots/") maven("https://repo.md-5.net/content/repositories/snapshots/")
@@ -71,9 +69,6 @@ allprojects {
// CombatLogX // CombatLogX
maven("https://nexus.sirblobman.xyz/repository/public/") maven("https://nexus.sirblobman.xyz/repository/public/")
// IridiumSkyblock
maven("https://nexus.iridiumdevelopment.net/repository/maven-releases/")
// MythicMobs // MythicMobs
maven("https://mvn.lumine.io/repository/maven-public/") maven("https://mvn.lumine.io/repository/maven-public/")
@@ -85,21 +80,28 @@ allprojects {
} }
dependencies { dependencies {
compileOnly(kotlin("stdlib", version = "1.6.10")) // Kotlin
implementation(kotlin("stdlib", version = "1.7.10"))
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.2")
// Included in spigot jar, no need to move to implementation
compileOnly("org.jetbrains:annotations:23.0.0") compileOnly("org.jetbrains:annotations:23.0.0")
compileOnly("com.google.guava:guava:31.1-jre")
// Test // Test
testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.2") testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.2")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.2") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.2")
// Adventure // Adventure
compileOnly("net.kyori:adventure-api:4.10.0") implementation("net.kyori:adventure-api:4.10.1")
compileOnly("net.kyori:adventure-text-serializer-gson:4.10.0") implementation("net.kyori:adventure-text-serializer-gson:4.10.1") {
compileOnly("net.kyori:adventure-text-serializer-legacy:4.10.0") exclude("com.google.code.gson", "gson") // Prevent shading into the jar
}
implementation("net.kyori:adventure-text-serializer-legacy:4.10.1")
// Other // Other
compileOnly("com.google.guava:guava:31.1-jre") implementation("com.github.ben-manes.caffeine:caffeine:3.1.0")
compileOnly("com.github.ben-manes.caffeine:caffeine:3.0.5") implementation("org.apache.maven:maven-artifact:3.8.5")
} }
tasks.withType<JavaCompile> { tasks.withType<JavaCompile> {
@@ -115,10 +117,11 @@ allprojects {
exclude(group = "com.darkblade12", module = "particleeffect") exclude(group = "com.darkblade12", module = "particleeffect")
exclude(group = "com.github.cryptomorin", module = "XSeries") exclude(group = "com.github.cryptomorin", module = "XSeries")
exclude(group = "net.wesjd", module = "anvilgui") exclude(group = "net.wesjd", module = "anvilgui")
exclude(group = "org.slf4j", module = "slf4j-api")
} }
configurations.testImplementation { configurations.testImplementation {
setExtendsFrom(listOf(configurations.compileOnly.get())) setExtendsFrom(listOf(configurations.compileOnly.get(), configurations.implementation.get()))
} }
tasks { tasks {
@@ -126,13 +129,41 @@ allprojects {
kotlinOptions { kotlinOptions {
jvmTarget = "17" jvmTarget = "17"
} }
targetCompatibility = "17"
sourceCompatibility = "17"
} }
shadowJar { shadowJar {
relocate("org.bstats", "com.willfp.eco.libs.bstats") relocate("org.bstats", "com.willfp.eco.libs.bstats")
relocate("redempt.crunch", "com.willfp.eco.libs.crunch") relocate("redempt.crunch", "com.willfp.eco.libs.crunch")
relocate("org.apache.commons.lang3", "com.willfp.eco.libs.lang3")
relocate("org.apache.maven", "com.willfp.eco.libs.maven")
relocate("org.checkerframework", "com.willfp.eco.libs.checkerframework")
relocate("org.intellij", "com.willfp.eco.libs.intellij")
relocate("org.jetbrains.annotations", "com.willfp.eco.libs.jetbrains.annotations")
//relocate("org.jetbrains.exposed", "com.willfp.eco.libs.exposed")
relocate("org.objenesis", "com.willfp.eco.libs.objenesis")
relocate("org.reflections", "com.willfp.eco.libs.reflections")
relocate("javassist", "com.willfp.eco.libs.javassist")
relocate("javax.annotation", "com.willfp.eco.libs.annotation")
relocate("com.google.errorprone", "com.willfp.eco.libs.errorprone")
relocate("com.google.j2objc", "com.willfp.eco.libs.j2objc")
relocate("com.google.thirdparty", "com.willfp.eco.libs.google.thirdparty")
relocate("com.google.protobuf", "com.willfp.eco.libs.google.protobuf") // No I don't know either
relocate("google.protobuf", "com.willfp.eco.libs.protobuf") // Still don't know
relocate("com.zaxxer.hikari", "com.willfp.eco.libs.hikari")
//relocate("com.mysql", "com.willfp.eco.libs.mysql")
relocate("de.undercouch.bson4jackson", "com.willfp.eco.libs.bson4jackson")
relocate("com.fasterxml.jackson", "com.willfp.eco.libs.jackson")
relocate("com.mongodb", "com.willfp.eco.libs.mongodb")
relocate("org.bson", "com.willfp.eco.libs.bson")
relocate("org.litote", "com.willfp.eco.libs.litote")
relocate("org.reactivestreams", "com.willfp.eco.libs.reactivestreams")
relocate("reactor.", "com.willfp.eco.libs.reactor.") // Dot in name to be safe
relocate("com.moandjiezana.toml", "com.willfp.eco.libs.toml")
/*
Kotlin and caffeine are not shaded so that they can be accessed directly by eco plugins.
Also, not relocating adventure, because it's a pain in the ass, and it doesn't *seem* to be causing loader constraint violations.
*/
} }
compileJava { compileJava {

View File

@@ -4,7 +4,6 @@ dependencies {
// Other // Other
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT' compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
compileOnly 'org.apache.maven:maven-artifact:3.8.1'
compileOnly 'com.comphenix.protocol:ProtocolLib:4.6.1-SNAPSHOT' compileOnly 'com.comphenix.protocol:ProtocolLib:4.6.1-SNAPSHOT'
compileOnly 'com.google.code.gson:gson:2.8.8' compileOnly 'com.google.code.gson:gson:2.8.8'
} }

View File

@@ -1,82 +1,583 @@
package com.willfp.eco.core; package com.willfp.eco.core;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.config.interfaces.LoadableConfig;
import com.willfp.eco.core.config.updating.ConfigHandler;
import com.willfp.eco.core.data.ExtendedPersistentDataContainer;
import com.willfp.eco.core.data.PlayerProfile;
import com.willfp.eco.core.data.ServerProfile;
import com.willfp.eco.core.data.keys.PersistentDataKey;
import com.willfp.eco.core.drops.DropQueue;
import com.willfp.eco.core.entities.ai.EntityController;
import com.willfp.eco.core.events.EventManager;
import com.willfp.eco.core.extensions.ExtensionLoader;
import com.willfp.eco.core.factory.MetadataValueFactory;
import com.willfp.eco.core.factory.NamespacedKeyFactory;
import com.willfp.eco.core.factory.RunnableFactory;
import com.willfp.eco.core.fast.FastItemStack;
import com.willfp.eco.core.gui.menu.Menu;
import com.willfp.eco.core.gui.menu.MenuBuilder;
import com.willfp.eco.core.gui.menu.MenuType;
import com.willfp.eco.core.gui.slot.SlotBuilder;
import com.willfp.eco.core.gui.slot.functional.SlotProvider;
import com.willfp.eco.core.integrations.placeholder.PlaceholderIntegration;
import com.willfp.eco.core.items.TestableItem;
import com.willfp.eco.core.placeholder.AdditionalPlayer;
import com.willfp.eco.core.placeholder.PlaceholderInjectable;
import com.willfp.eco.core.proxy.ProxyFactory;
import com.willfp.eco.core.scheduling.Scheduler;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.Location;
import org.bukkit.NamespacedKey;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Mob;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.annotation.Documented; import java.util.Collection;
import java.lang.annotation.ElementType; import java.util.List;
import java.lang.annotation.Retention; import java.util.Map;
import java.lang.annotation.RetentionPolicy; import java.util.Set;
import java.lang.annotation.Target; import java.util.UUID;
import java.util.logging.Logger;
/** /**
* Holds the instance of the eco handler for bridging between the frontend * Holds the instance of eco for bridging between the frontend
* and backend. * and backend.
* <p>
* <strong>Do not use this in your plugins!</strong> It can and will contain
* breaking changes between minor versions and even patches, and you will create
* compatibility issues by. All parts of this have been abstracted
* into logically named API components that you can use.
* *
* @see Eco#getHandler() * @see Eco#get()
* @see Handler
*/ */
@ApiStatus.Internal @ApiStatus.Internal
public final class Eco { public interface Eco {
/** /**
* Instance of eco handler. * Create a scheduler.
*/
@ApiStatus.Internal
private static Handler handler;
/**
* Set the handler.
* *
* @param handler The handler. * @param plugin The plugin.
* @return The scheduler.
*/ */
@ApiStatus.Internal @NotNull
public static void setHandler(@NotNull final Handler handler) { Scheduler createScheduler(@NotNull EcoPlugin plugin);
Validate.isTrue(Eco.handler == null, "Already initialized!");
Eco.handler = handler;
}
/** /**
* Get the instance of the eco handler; the bridge between the api frontend * Create an event manager.
* and the implementation backend.
* <p>
* <strong>Do not use the handler in your plugins!</strong> It can and will contain
* breaking changes between minor versions and even patches, and you will create
* compatibility issues by using the handler. All parts of the handler have been abstracted
* into logically named API components that you can use.
* <p>
* Prior to version 6.12.0, the handler was considered as an API component, but it has
* since been moved into an internal component, and in 6.17.0, the first breaking change
* was introduced to {@link com.willfp.eco.core.config.wrapper.ConfigFactory}. This means
* that any usages of the handler can now cause problems in your plugins.
* *
* @param plugin The plugin.
* @return The event manager.
*/
@NotNull
EventManager createEventManager(@NotNull EcoPlugin plugin);
/**
* Create a NamespacedKey factory.
*
* @param plugin The plugin.
* @return The factory.
*/
@NotNull
NamespacedKeyFactory createNamespacedKeyFactory(@NotNull EcoPlugin plugin);
/**
* Create a MetadataValue factory.
*
* @param plugin The plugin.
* @return The factory.
*/
@NotNull
MetadataValueFactory createMetadataValueFactory(@NotNull EcoPlugin plugin);
/**
* Create a Runnable factory.
*
* @param plugin The plugin.
* @return The factory.
*/
@NotNull
RunnableFactory createRunnableFactory(@NotNull EcoPlugin plugin);
/**
* Create an ExtensionLoader.
*
* @param plugin The plugin.
* @return The factory.
*/
@NotNull
ExtensionLoader createExtensionLoader(@NotNull EcoPlugin plugin);
/**
* Create a config handler.
*
* @param plugin The plugin.
* @return The handler. * @return The handler.
*/ */
@NotNull
ConfigHandler createConfigHandler(@NotNull EcoPlugin plugin);
/**
* Create a logger.
*
* @param plugin The plugin.
* @return The logger.
*/
@NotNull
Logger createLogger(@NotNull EcoPlugin plugin);
/**
* Create a PAPI integration.
*
* @param plugin The plugin.
* @return The integration.
*/
@NotNull
PlaceholderIntegration createPAPIIntegration(@NotNull EcoPlugin plugin);
/**
* Create a proxy factory.
*
* @param plugin The plugin.
* @return The factory.
*/
@NotNull
ProxyFactory createProxyFactory(@NotNull EcoPlugin plugin);
/**
* Get eco Spigot plugin.
*
* @return The plugin.
*/
@NotNull
EcoPlugin getEcoPlugin();
/**
* Updatable config.
*
* @param configName The name of the config
* @param plugin The plugin.
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param type The config type.
* @param updateBlacklist Substring of keys to not add/remove keys for.
* @param requiresChangesToSave If the config must be changed in order to save the config.
* @return The config implementation.
*/
LoadableConfig createUpdatableConfig(@NotNull String configName,
@NotNull PluginLike plugin,
@NotNull String subDirectoryPath,
@NotNull Class<?> source,
boolean removeUnused,
@NotNull ConfigType type,
boolean requiresChangesToSave,
@NotNull String... updateBlacklist);
/**
* Loadable config.
*
* @param configName The name of the config
* @param plugin The plugin.
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
* @param type The config type.
* @param requiresChangesToSave If the config must be changed in order to save the config.
* @return The config implementation.
*/
LoadableConfig createLoadableConfig(@NotNull String configName,
@NotNull PluginLike plugin,
@NotNull String subDirectoryPath,
@NotNull Class<?> source,
@NotNull ConfigType type,
boolean requiresChangesToSave);
/**
* Create config.
*
* @param config The handle.
* @return The config implementation.
*/
Config wrapConfigurationSection(@NotNull ConfigurationSection config);
/**
* Create config.
*
* @param values The values.
* @param type The config type.
* @return The config implementation.
*/
Config createConfig(@NotNull Map<String, Object> values,
@NotNull ConfigType type);
/**
* Create config.
*
* @param contents The file contents.
* @param type The type.
* @return The config implementation.
*/
Config createConfig(@NotNull String contents,
@NotNull ConfigType type);
/**
* Create a Drop Queue.
*
* @param player The player.
* @return The drop queue.
*/
@NotNull
DropQueue createDropQueue(@NotNull Player player);
/**
* Create slot builder.
*
* @param provider The provider.
* @return The builder.
*/
@NotNull
SlotBuilder createSlotBuilder(@NotNull SlotProvider provider);
/**
* Create menu builder.
*
* @param rows The amount of rows.
* @param type The type.
* @return The builder.
*/
@NotNull
MenuBuilder createMenuBuilder(int rows,
@NotNull MenuType type);
/**
* Combine the state of two menus together.
*
* @param base The base menu.
* @param additional The additional state.
* @return The menu.
*/
@NotNull
Menu blendMenuState(@NotNull Menu base,
@NotNull Menu additional);
/**
* Clean up ClassLoader (etc.) to allow PlugMan support.
*
* @param plugin The plugin to clean up.
*/
void clean(@NotNull EcoPlugin plugin);
/**
* Add new plugin.
*
* @param plugin The plugin.
*/
void addNewPlugin(@NotNull EcoPlugin plugin);
/**
* Get plugin by name.
*
* @param name The name.
* @return The plugin.
*/
@Nullable
EcoPlugin getPluginByName(@NotNull String name);
/**
* Get all loaded eco plugins.
*
* @return A list of plugin names in lowercase.
*/
@NotNull
List<String> getLoadedPlugins();
/**
* Create a FastItemStack.
*
* @param itemStack The base ItemStack.
* @return The FastItemStack.
*/
@NotNull
FastItemStack createFastItemStack(@NotNull ItemStack itemStack);
/**
* Register bStats metrics.
*
* @param plugin The plugin.
*/
void registerBStats(@NotNull EcoPlugin plugin);
/**
* Get Adventure audiences.
*
* @return The audiences.
*/
@Nullable
BukkitAudiences getAdventure();
/**
* Register a persistent data key to be stored.
*
* @param key The key.
*/
void registerPersistentKey(@NotNull PersistentDataKey<?> key);
/**
* Get all registered keys.
*
* @return The keys.
*/
Set<PersistentDataKey<?>> getRegisteredPersistentDataKeys();
/**
* Get persistent data key from namespaced key.
*
* @param namespacedKey The key.
* @return The key, or null if not found.
*/
@Nullable
PersistentDataKey<?> getPersistentDataKeyFrom(@NotNull NamespacedKey namespacedKey);
/**
* Load a player profile.
*
* @param uuid The UUID.
* @return The profile.
*/
PlayerProfile loadPlayerProfile(@NotNull UUID uuid);
/**
* Load the server profile.
*
* @return The profile.
*/
ServerProfile getServerProfile();
/**
* Unload a player profile from memory.
* <p>
* This will not save the profile first.
*
* @param uuid The uuid.
*/
void unloadPlayerProfile(@NotNull UUID uuid);
/**
* Save keys for a player.
* <p>
* Can run async if using MySQL.
*
* @param uuid The uuid.
* @param keys The keys.
*/
void savePersistentDataKeysFor(@NotNull UUID uuid,
@NotNull Set<PersistentDataKey<?>> keys);
/**
* Commit all changes to the file.
* <p>
* Does nothing if using MySQL.
*/
void saveAllProfiles();
/**
* Create dummy entity - never spawned, exists purely in code.
*
* @param location The location.
* @return The entity.
*/
@NotNull
Entity createDummyEntity(@NotNull Location location);
/**
* Create a {@link NamespacedKey} quickly
* <p>
* Bypasses the constructor, allowing for the creation of invalid keys,
* therefore this is considered unsafe and should only be called after
* the key has been confirmed to be valid.
*
* @param namespace The namespace.
* @param key The key.
* @return The key.
*/
@NotNull
NamespacedKey createNamespacedKey(@NotNull String namespace,
@NotNull String key);
/**
* Return or get props for a plugin.
*
* @param existing The existing constructor props.
* @param plugin The plugin.
* @return The props.
*/
@NotNull
PluginProps getProps(@Nullable PluginProps existing,
@NotNull Class<? extends EcoPlugin> plugin);
/**
* Format a string with MiniMessage.
*
* @param message The message.
* @return The formatted string.
*/
@NotNull
String formatMiniMessage(@NotNull String message);
/**
* Create controlled entity from a mob.
*
* @param mob The mob.
* @param <T> The mob type.
* @return The controlled entity.
*/
@NotNull <T extends Mob> EntityController<T> createEntityController(@NotNull T mob);
/**
* Adapt base PDC to extended PDC.
*
* @param container The container.
* @return The extended container.
*/
@NotNull
ExtendedPersistentDataContainer adaptPdc(@NotNull PersistentDataContainer container);
/**
* Create new PDC.
*
* @return The container.
*/
@NotNull
PersistentDataContainer newPdc();
/**
* Get item from SNBT.
*
* @param snbt The NBT string.
* @return The ItemStack, or null if invalid.
*/
@Nullable
ItemStack fromSNBT(@NotNull String snbt);
/**
* Convert item to SNBT.
*
* @param itemStack The item.
* @return The NBT string.
*/
@NotNull
String toSNBT(@NotNull ItemStack itemStack);
/**
* Make TestableItem from SNBT.
*
* @param snbt The NBT string.
* @return The TestableItem.
*/
@NotNull
TestableItem testableItemFromSNBT(@NotNull String snbt);
/**
* Get the texture of a skull.
*
* @param meta The skull meta.
* @return The texture, or null if not found.
*/
@Nullable
String getSkullTexture(@NotNull SkullMeta meta);
/**
* Set the texture of a skull.
*
* @param meta The skull meta.
* @param base64 The texture.
*/
void setSkullTexture(@NotNull SkullMeta meta,
@NotNull String base64);
/**
* Get the current server TPS.
*
* @return The TPS.
*/
double getTPS();
/**
* Evaluate an expression.
*
* @param expression The expression.
* @param player The player.
* @param injectable The injectable placeholders.
* @param additionalPlayers The additional players.
* @return The value of the expression, or zero if invalid.
*/
double evaluate(@NotNull String expression,
@Nullable Player player,
@NotNull PlaceholderInjectable injectable,
@NotNull Collection<AdditionalPlayer> additionalPlayers);
/**
* Get the menu a player currently has open.
*
* @param player The player.
* @return The menu, or null if no menu open.
*/
@Nullable
Menu getOpenMenu(@NotNull Player player);
/**
* Get the instance of eco; the bridge between the api frontend
* and the implementation backend.
*
* @return The instance of eco.
*/
@ApiStatus.Internal @ApiStatus.Internal
public static Handler getHandler() { static Eco get() {
return handler; return Instance.get();
} }
/** /**
* Eco Handler components are internals, so if a class is marked as a handler component, * Manages the internal frontend -> backend communication.
* then it should be treated the same as if it was marked with {@link ApiStatus.Internal}.
* <p>
* If a class is marked with {@link HandlerComponent}, <strong>Do not reference it in
* your code!</strong> It can and will contain breaking changes between minor versions and
* even patches, and you will create compatibility issues by using them.
* <p>
* Handler components should also be marked with {@link ApiStatus.Internal} in order to
* cause compiler / IDE warnings.
*/ */
@Documented @ApiStatus.Internal
@Retention(RetentionPolicy.CLASS) final class Instance {
@Target({ElementType.TYPE}) /**
public @interface HandlerComponent { * Instance of eco.
*/
@ApiStatus.Internal
private static Eco eco;
} /**
* Initialize eco.
*
* @param eco The instance of eco.
*/
@ApiStatus.Internal
static void set(@NotNull final Eco eco) {
Validate.isTrue(Instance.eco == null, "Already initialized!");
private Eco() { Instance.eco = eco;
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); }
/**
* Get eco.
*
* @return eco.
*/
static Eco get() {
return eco;
}
private Instance() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
} }
} }

View File

@@ -20,8 +20,10 @@ import com.willfp.eco.core.web.UpdateChecker;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion; import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -79,12 +81,12 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
private final Set<String> loadedIntegrations = new HashSet<>(); private final Set<String> loadedIntegrations = new HashSet<>();
/** /**
* The internal plugin scheduler. * The plugin scheduler.
*/ */
private final Scheduler scheduler; private final Scheduler scheduler;
/** /**
* The internal plugin Event Manager. * The plugin Event Manager.
*/ */
private final EventManager eventManager; private final EventManager eventManager;
@@ -99,17 +101,17 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
private final LangYml langYml; private final LangYml langYml;
/** /**
* The internal factory to produce {@link org.bukkit.NamespacedKey}s. * The factory to produce {@link org.bukkit.NamespacedKey}s.
*/ */
private final NamespacedKeyFactory namespacedKeyFactory; private final NamespacedKeyFactory namespacedKeyFactory;
/** /**
* The internal factory to produce {@link org.bukkit.metadata.FixedMetadataValue}s. * The factory to produce {@link org.bukkit.metadata.FixedMetadataValue}s.
*/ */
private final MetadataValueFactory metadataValueFactory; private final MetadataValueFactory metadataValueFactory;
/** /**
* The internal factory to produce {@link com.willfp.eco.core.scheduling.RunnableTask}s. * The factory to produce {@link com.willfp.eco.core.scheduling.RunnableTask}s.
*/ */
private final RunnableFactory runnableFactory; private final RunnableFactory runnableFactory;
@@ -258,42 +260,42 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
*/ */
protected EcoPlugin(@Nullable final PluginProps pluginProps) { protected EcoPlugin(@Nullable final PluginProps pluginProps) {
/* /*
The handler must be initialized before any plugin's constructors Eco must be initialized before any plugin's constructors
are called, as the constructors call Eco#getHandler(). are called, as the constructors call Eco#get().
To fix this, EcoSpigotPlugin an abstract class and the 'actual' To fix this, EcoSpigotPlugin an abstract class and the 'actual'
plugin class is EcoHandler - that way I can create the handler plugin class is EcoImpl - that way I can initialize eco
before any plugins are loaded while still having a separation between before any plugins are loaded while still having a separation between
the plugin class and the handler class (for code clarity). the plugin class and the implementation class (for code clarity).
I don't really like the fact that the handler class *is* the I don't really like the fact that the implementation class *is* the
spigot plugin, but it is what it is. spigot plugin, but it is what it is.
There is probably a better way of doing it - maybe with There is probably a better way of doing it - maybe with
some sort of HandlerCreator interface in order to still have some sort of EcoCrater interface in order to still have
a standalone handler class, but then there would be an interface a standalone eco class, but then there would be an interface
left in the API that doesn't really help anything. left in the API that doesn't really help anything.
The other alternative would be to use reflection to get a 'createHandler' The other alternative would be to use reflection to get a 'createEco'
method that only exists in EcoSpigotPlugin - but that feels filthy, method that only exists in EcoSpigotPlugin - but that feels filthy,
and I'd rather only use reflection where necessary. and I'd rather only use reflection where necessary.
*/ */
if (Eco.getHandler() == null && this instanceof Handler) { if (Eco.get() == null && this instanceof Eco) {
/* /*
This code is only ever called by EcoSpigotPlugin (EcoHandler) This code is only ever called by EcoSpigotPlugin (EcoImpl)
as it's the first plugin to load, and it is a handler. as it's the first plugin to load, and it's an instance of eco.
Any other plugins will never call this code as the handler Any other plugins will never call this code as eco will have already
will have already been initialized. been initialized.
*/ */
Eco.setHandler((Handler) this); Eco.Instance.set((Eco) this);
} }
assert Eco.getHandler() != null; assert Eco.get() != null;
PluginProps generatedProps = Eco.getHandler().getProps(pluginProps, this.getClass()); PluginProps generatedProps = Eco.get().getProps(pluginProps, this.getClass());
generatedProps.validate(); generatedProps.validate();
PluginProps props = this.mutateProps(generatedProps); PluginProps props = this.mutateProps(generatedProps);
props.validate(); props.validate();
@@ -304,20 +306,23 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
this.color = props.getColor(); this.color = props.getColor();
this.supportingExtensions = props.isSupportingExtensions(); this.supportingExtensions = props.isSupportingExtensions();
this.scheduler = Eco.getHandler().createScheduler(this); this.proxyFactory = this.proxyPackage.equalsIgnoreCase("") ? null : Eco.get().createProxyFactory(this);
this.eventManager = Eco.getHandler().createEventManager(this); this.logger = Eco.get().createLogger(this);
this.namespacedKeyFactory = Eco.getHandler().createNamespacedKeyFactory(this);
this.metadataValueFactory = Eco.getHandler().createMetadataValueFactory(this); this.getLogger().info("Initializing " + this.getColor() + this.getName());
this.runnableFactory = Eco.getHandler().createRunnableFactory(this);
this.extensionLoader = Eco.getHandler().createExtensionLoader(this); this.scheduler = Eco.get().createScheduler(this);
this.configHandler = Eco.getHandler().createConfigHandler(this); this.eventManager = Eco.get().createEventManager(this);
this.logger = Eco.getHandler().createLogger(this); this.namespacedKeyFactory = Eco.get().createNamespacedKeyFactory(this);
this.proxyFactory = this.proxyPackage.equalsIgnoreCase("") ? null : Eco.getHandler().createProxyFactory(this); this.metadataValueFactory = Eco.get().createMetadataValueFactory(this);
this.runnableFactory = Eco.get().createRunnableFactory(this);
this.extensionLoader = Eco.get().createExtensionLoader(this);
this.configHandler = Eco.get().createConfigHandler(this);
this.langYml = this.createLangYml(); this.langYml = this.createLangYml();
this.configYml = this.createConfigYml(); this.configYml = this.createConfigYml();
Eco.getHandler().addNewPlugin(this); Eco.get().addNewPlugin(this);
/* /*
The minimum eco version check was moved here because it's very common The minimum eco version check was moved here because it's very common
@@ -326,7 +331,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
they have an outdated version of eco installed. they have an outdated version of eco installed.
*/ */
DefaultArtifactVersion runningVersion = new DefaultArtifactVersion(Eco.getHandler().getEcoPlugin().getDescription().getVersion()); DefaultArtifactVersion runningVersion = new DefaultArtifactVersion(Eco.get().getEcoPlugin().getDescription().getVersion());
DefaultArtifactVersion requiredVersion = new DefaultArtifactVersion(this.getMinimumEcoVersion()); DefaultArtifactVersion requiredVersion = new DefaultArtifactVersion(this.getMinimumEcoVersion());
if (!(runningVersion.compareTo(requiredVersion) > 0 || runningVersion.equals(requiredVersion))) { if (!(runningVersion.compareTo(requiredVersion) > 0 || runningVersion.equals(requiredVersion))) {
this.getLogger().severe("You are running an outdated version of eco!"); this.getLogger().severe("You are running an outdated version of eco!");
@@ -347,21 +352,21 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
this.getLogger().info(""); this.getLogger().info("");
this.getLogger().info("Loading " + this.getColor() + this.getName()); this.getLogger().info("Loading " + this.getColor() + this.getName());
if (this.getResourceId() != 0) { if (this.getResourceId() != 0 && !Eco.get().getEcoPlugin().getConfigYml().getBool("no-update-checker")) {
new UpdateChecker(this).getVersion(version -> { new UpdateChecker(this).getVersion(version -> {
DefaultArtifactVersion currentVersion = new DefaultArtifactVersion(this.getDescription().getVersion()); DefaultArtifactVersion currentVersion = new DefaultArtifactVersion(this.getDescription().getVersion());
DefaultArtifactVersion mostRecentVersion = new DefaultArtifactVersion(version); DefaultArtifactVersion mostRecentVersion = new DefaultArtifactVersion(version);
if (!(currentVersion.compareTo(mostRecentVersion) > 0 || currentVersion.equals(mostRecentVersion))) { if (!(currentVersion.compareTo(mostRecentVersion) > 0 || currentVersion.equals(mostRecentVersion))) {
this.outdated = true; this.outdated = true;
this.getLogger().warning("&c" + this.getName() + " is out of date! (Version " + this.getDescription().getVersion() + ")"); this.getLogger().warning(this.getName() + " is out of date! (Version " + this.getDescription().getVersion() + ")");
this.getLogger().warning("&cThe newest version is &f" + version); this.getLogger().warning("The newest version is " + version);
this.getLogger().warning("&cDownload the new version!"); this.getLogger().warning("Download the new version!");
} }
}); });
} }
if (this.getBStatsId() != 0) { if (this.getBStatsId() != 0) {
Eco.getHandler().registerBStats(this); Eco.get().registerBStats(this);
} }
Set<String> enabledPlugins = Arrays.stream(Bukkit.getPluginManager().getPlugins()) Set<String> enabledPlugins = Arrays.stream(Bukkit.getPluginManager().getPlugins())
@@ -371,15 +376,15 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
if (enabledPlugins.contains("PlaceholderAPI".toLowerCase())) { if (enabledPlugins.contains("PlaceholderAPI".toLowerCase())) {
this.loadedIntegrations.add("PlaceholderAPI"); this.loadedIntegrations.add("PlaceholderAPI");
PlaceholderManager.addIntegration(Eco.getHandler().createPAPIIntegration(this)); PlaceholderManager.addIntegration(Eco.get().createPAPIIntegration(this));
} }
this.loadIntegrationLoaders().forEach((integrationLoader -> { this.loadIntegrationLoaders().forEach(integrationLoader -> {
if (enabledPlugins.contains(integrationLoader.getPluginName().toLowerCase())) { if (enabledPlugins.contains(integrationLoader.getPluginName().toLowerCase())) {
this.loadedIntegrations.add(integrationLoader.getPluginName()); this.loadedIntegrations.add(integrationLoader.getPluginName());
integrationLoader.load(); integrationLoader.load();
} }
})); });
this.getLogger().info("Loaded integrations: " + String.join(", ", this.getLoadedIntegrations())); this.getLogger().info("Loaded integrations: " + String.join(", ", this.getLoadedIntegrations()));
@@ -430,7 +435,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
} }
this.getLogger().info("Cleaning up..."); this.getLogger().info("Cleaning up...");
Eco.getHandler().getCleaner().clean(this); Eco.get().clean(this);
} }
/** /**
@@ -489,9 +494,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
public final void reload() { public final void reload() {
this.getConfigHandler().updateConfigs(); this.getConfigHandler().updateConfigs();
this.getScheduler().cancelAll();
this.getConfigHandler().callUpdate(); this.getConfigHandler().callUpdate();
this.getConfigHandler().callUpdate(); // Call twice to fix issues this.getConfigHandler().callUpdate(); // Call twice to fix issues
this.getScheduler().cancelAll();
this.handleReload(); this.handleReload();
@@ -694,7 +699,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
public final FileConfiguration getConfig() { public final FileConfiguration getConfig() {
this.getLogger().warning("Call to default config method in eco plugin!"); this.getLogger().warning("Call to default config method in eco plugin!");
return Objects.requireNonNull(this.getConfigYml().getBukkitHandle()); return Objects.requireNonNull(this.getConfigYml().toBukkit());
} }
/** /**
@@ -743,7 +748,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @return The plugin. * @return The plugin.
*/ */
public static EcoPlugin getPlugin(@NotNull final String pluginName) { public static EcoPlugin getPlugin(@NotNull final String pluginName) {
return Eco.getHandler().getPluginByName(pluginName); return Eco.get().getPluginByName(pluginName);
} }
/** /**
@@ -752,7 +757,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @return The set of names. * @return The set of names.
*/ */
public static Set<String> getPluginNames() { public static Set<String> getPluginNames() {
return new HashSet<>(Eco.getHandler().getLoadedPlugins()); return new HashSet<>(Eco.get().getLoadedPlugins());
} }
/** /**
@@ -918,4 +923,26 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
public ProxyFactory getProxyFactory() { public ProxyFactory getProxyFactory() {
return this.proxyFactory; return this.proxyFactory;
} }
/**
* Create a NamespacedKey.
*
* @param key The key.
* @return The namespaced key.
*/
@NotNull
public NamespacedKey createNamespacedKey(@NotNull final String key) {
return this.getNamespacedKeyFactory().create(key);
}
/**
* Create a metadata value.
*
* @param value The value.
* @return The metadata value.
*/
@NotNull
public FixedMetadataValue createMetadataValue(@NotNull final Object value) {
return this.getMetadataValueFactory().create(value);
}
} }

View File

@@ -1,285 +0,0 @@
package com.willfp.eco.core;
import com.willfp.eco.core.config.updating.ConfigHandler;
import com.willfp.eco.core.config.wrapper.ConfigFactory;
import com.willfp.eco.core.data.ProfileHandler;
import com.willfp.eco.core.data.keys.KeyRegistry;
import com.willfp.eco.core.drops.DropQueueFactory;
import com.willfp.eco.core.entities.ai.EntityController;
import com.willfp.eco.core.events.EventManager;
import com.willfp.eco.core.extensions.ExtensionLoader;
import com.willfp.eco.core.factory.MetadataValueFactory;
import com.willfp.eco.core.factory.NamespacedKeyFactory;
import com.willfp.eco.core.factory.RunnableFactory;
import com.willfp.eco.core.fast.FastItemStack;
import com.willfp.eco.core.gui.GUIFactory;
import com.willfp.eco.core.integrations.placeholder.PlaceholderIntegration;
import com.willfp.eco.core.proxy.Cleaner;
import com.willfp.eco.core.proxy.ProxyFactory;
import com.willfp.eco.core.scheduling.Scheduler;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.bukkit.Location;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Mob;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.logging.Logger;
/**
* @see Eco#getHandler()
*/
@ApiStatus.Internal
public interface Handler {
/**
* Create a scheduler.
*
* @param plugin The plugin.
* @return The scheduler.
*/
@NotNull
Scheduler createScheduler(@NotNull EcoPlugin plugin);
/**
* Create an event manager.
*
* @param plugin The plugin.
* @return The event manager.
*/
@NotNull
EventManager createEventManager(@NotNull EcoPlugin plugin);
/**
* Create a NamespacedKey factory.
*
* @param plugin The plugin.
* @return The factory.
*/
@NotNull
NamespacedKeyFactory createNamespacedKeyFactory(@NotNull EcoPlugin plugin);
/**
* Create a MetadataValue factory.
*
* @param plugin The plugin.
* @return The factory.
*/
@NotNull
MetadataValueFactory createMetadataValueFactory(@NotNull EcoPlugin plugin);
/**
* Create a Runnable factory.
*
* @param plugin The plugin.
* @return The factory.
*/
@NotNull
RunnableFactory createRunnableFactory(@NotNull EcoPlugin plugin);
/**
* Create an ExtensionLoader.
*
* @param plugin The plugin.
* @return The factory.
*/
@NotNull
ExtensionLoader createExtensionLoader(@NotNull EcoPlugin plugin);
/**
* Create a config handler.
*
* @param plugin The plugin.
* @return The handler.
*/
@NotNull
ConfigHandler createConfigHandler(@NotNull EcoPlugin plugin);
/**
* Create a logger.
*
* @param plugin The plugin.
* @return The logger.
*/
@NotNull
Logger createLogger(@NotNull EcoPlugin plugin);
/**
* Create a PAPI integration.
*
* @param plugin The plugin.
* @return The integration.
*/
@NotNull
PlaceholderIntegration createPAPIIntegration(@NotNull EcoPlugin plugin);
/**
* Create a proxy factory.
*
* @param plugin The plugin.
* @return The factory.
*/
@NotNull
ProxyFactory createProxyFactory(@NotNull EcoPlugin plugin);
/**
* Get eco Spigot plugin.
*
* @return The plugin.
*/
@NotNull
EcoPlugin getEcoPlugin();
/**
* Get config factory.
*
* @return The factory.
*/
@NotNull
ConfigFactory getConfigFactory();
/**
* Get drop queue factory.
*
* @return The factory.
*/
@NotNull
DropQueueFactory getDropQueueFactory();
/**
* Get GUI factory.
*
* @return The factory.
*/
@NotNull
GUIFactory getGUIFactory();
/**
* Get cleaner.
*
* @return The cleaner.
*/
@NotNull
Cleaner getCleaner();
/**
* Add new plugin.
*
* @param plugin The plugin.
*/
void addNewPlugin(@NotNull EcoPlugin plugin);
/**
* Get plugin by name.
*
* @param name The name.
* @return The plugin.
*/
@Nullable
EcoPlugin getPluginByName(@NotNull String name);
/**
* Get all loaded eco plugins.
*
* @return A list of plugin names in lowercase.
*/
@NotNull
List<String> getLoadedPlugins();
/**
* Create a FastItemStack.
*
* @param itemStack The base ItemStack.
* @return The FastItemStack.
*/
@NotNull
FastItemStack createFastItemStack(@NotNull ItemStack itemStack);
/**
* Register bStats metrics.
*
* @param plugin The plugin.
*/
void registerBStats(@NotNull EcoPlugin plugin);
/**
* Get Adventure audiences.
*
* @return The audiences.
*/
@Nullable
BukkitAudiences getAdventure();
/**
* Get the key registry.
*
* @return The registry.
*/
@NotNull
KeyRegistry getKeyRegistry();
/**
* Get the PlayerProfile handler.
*
* @return The handler.
*/
@NotNull
ProfileHandler getProfileHandler();
/**
* Create dummy entity - never spawned, exists purely in code.
*
* @param location The location.
* @return The entity.
*/
@NotNull
Entity createDummyEntity(@NotNull Location location);
/**
* Create a {@link NamespacedKey} quickly
* <p>
* Bypasses the constructor, allowing for the creation of invalid keys,
* therefore this is considered unsafe and should only be called after
* the key has been confirmed to be valid.
*
* @param namespace The namespace.
* @param key The key.
* @return The key.
*/
@NotNull
NamespacedKey createNamespacedKey(@NotNull String namespace,
@NotNull String key);
/**
* Return or get props for a plugin.
*
* @param existing The existing constructor props.
* @param plugin The plugin.
* @return The props.
*/
@NotNull
PluginProps getProps(@Nullable PluginProps existing,
@NotNull Class<? extends EcoPlugin> plugin);
/**
* Format a string with MiniMessage.
*
* @param message The message.
* @return The formatted string.
*/
@NotNull
String formatMiniMessage(@NotNull String message);
/**
* Create controlled entity from a mob.
*
* @param mob The mob.
* @param <T> The mob type.
* @return The controlled entity.
*/
@NotNull
<T extends Mob> EntityController<T> createEntityController(@NotNull T mob);
}

View File

@@ -13,7 +13,9 @@ import org.jetbrains.annotations.NotNull;
* in the constructor. * in the constructor.
* *
* @param <T> The eco plugin type. * @param <T> The eco plugin type.
* @deprecated Leaky inheritance, shouldn't exist.
*/ */
@Deprecated(since = "6.43.0", forRemoval = true)
public abstract class PluginDependent<T extends EcoPlugin> { public abstract class PluginDependent<T extends EcoPlugin> {
/** /**
* The {@link EcoPlugin} that is stored. * The {@link EcoPlugin} that is stored.

View File

@@ -1,6 +1,5 @@
package com.willfp.eco.core; package com.willfp.eco.core;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -234,7 +233,6 @@ public final class PluginProps {
* @param supportsExtensions If the plugin should attempt to look for extensions. * @param supportsExtensions If the plugin should attempt to look for extensions.
* @return The props. * @return The props.
*/ */
@ApiStatus.Internal
static PluginProps createSimple(final int resourceId, static PluginProps createSimple(final int resourceId,
final int bStatsId, final int bStatsId,
@NotNull final String proxyPackage, @NotNull final String proxyPackage,

View File

@@ -26,7 +26,7 @@ public class Prerequisite {
* Requires the server to be running an implementation of paper. * Requires the server to be running an implementation of paper.
*/ */
public static final Prerequisite HAS_PAPER = new Prerequisite( public static final Prerequisite HAS_PAPER = new Prerequisite(
() -> ClassUtils.exists("com.destroystokyo.paper.event.player.PlayerElytraBoostEvent"), () -> ClassUtils.exists("com.destroystokyo.paper.event.block.BeaconEffectEvent"),
"Requires server to be running paper (or a fork)" "Requires server to be running paper (or a fork)"
); );
@@ -35,17 +35,25 @@ public class Prerequisite {
* *
* @deprecated Use {@link EconomyManager#hasRegistrations()} instead. * @deprecated Use {@link EconomyManager#hasRegistrations()} instead.
*/ */
@Deprecated @Deprecated(forRemoval = true)
public static final Prerequisite HAS_VAULT = new Prerequisite( public static final Prerequisite HAS_VAULT = new Prerequisite(
() -> ClassUtils.exists("net.milkbowl.vault.economy.Economy"), () -> ClassUtils.exists("net.milkbowl.vault.economy.Economy"),
"Requires server to have vault" "Requires server to have vault"
); );
/**
* Requires the server to be running 1.19.
*/
public static final Prerequisite HAS_1_19 = new Prerequisite(
() -> ProxyConstants.NMS_VERSION.contains("19"),
"Requires server to be running 1.19+"
);
/** /**
* Requires the server to be running 1.18. * Requires the server to be running 1.18.
*/ */
public static final Prerequisite HAS_1_18 = new Prerequisite( public static final Prerequisite HAS_1_18 = new Prerequisite(
() -> ProxyConstants.NMS_VERSION.contains("18"), () -> ProxyConstants.NMS_VERSION.contains("18") || HAS_1_19.isMet(),
"Requires server to be running 1.18+" "Requires server to be running 1.18+"
); );
@@ -54,7 +62,7 @@ public class Prerequisite {
* *
* @deprecated eco no longer supports versions before 1.17. * @deprecated eco no longer supports versions before 1.17.
*/ */
@Deprecated(since = "6.25.2") @Deprecated(since = "6.25.2", forRemoval = true)
public static final Prerequisite HAS_1_17 = new Prerequisite( public static final Prerequisite HAS_1_17 = new Prerequisite(
() -> ProxyConstants.NMS_VERSION.contains("17") || HAS_1_18.isMet(), () -> ProxyConstants.NMS_VERSION.contains("17") || HAS_1_18.isMet(),
"Requires server to be running 1.17+" "Requires server to be running 1.17+"

View File

@@ -10,6 +10,7 @@ import java.util.List;
/** /**
* Interface for all command implementations. * Interface for all command implementations.
*/ */
@SuppressWarnings("removal")
public interface CommandBase { public interface CommandBase {
/** /**
* Get command name. * Get command name.
@@ -81,7 +82,7 @@ public interface CommandBase {
* @see CommandHandler * @see CommandHandler
* @deprecated Use {@link CommandBase#onExecute(CommandSender, List)} instead. * @deprecated Use {@link CommandBase#onExecute(CommandSender, List)} instead.
*/ */
@Deprecated @Deprecated(forRemoval = true)
CommandHandler getHandler(); CommandHandler getHandler();
/** /**
@@ -91,7 +92,7 @@ public interface CommandBase {
* @see CommandHandler * @see CommandHandler
* @deprecated Handlers have been deprecated. * @deprecated Handlers have been deprecated.
*/ */
@Deprecated @Deprecated(forRemoval = true)
void setHandler(@NotNull CommandHandler handler); void setHandler(@NotNull CommandHandler handler);
/** /**
@@ -101,7 +102,7 @@ public interface CommandBase {
* @see TabCompleteHandler * @see TabCompleteHandler
* @deprecated Use {@link CommandBase#tabComplete(CommandSender, List)} instead. * @deprecated Use {@link CommandBase#tabComplete(CommandSender, List)} instead.
*/ */
@Deprecated @Deprecated(forRemoval = true)
TabCompleteHandler getTabCompleter(); TabCompleteHandler getTabCompleter();
/** /**
@@ -111,6 +112,6 @@ public interface CommandBase {
* @see TabCompleteHandler * @see TabCompleteHandler
* @deprecated Handlers have been deprecated. * @deprecated Handlers have been deprecated.
*/ */
@Deprecated @Deprecated(forRemoval = true)
void setTabCompleter(@NotNull TabCompleteHandler handler); void setTabCompleter(@NotNull TabCompleteHandler handler);
} }

View File

@@ -16,7 +16,7 @@ import java.util.List;
* update to use the new system: {@link CommandBase#onExecute(CommandSender, List)}. * update to use the new system: {@link CommandBase#onExecute(CommandSender, List)}.
*/ */
@FunctionalInterface @FunctionalInterface
@Deprecated(since = "6.17.0") @Deprecated(since = "6.17.0", forRemoval = true)
public interface CommandHandler { public interface CommandHandler {
/** /**
* The code to be called on execution. * The code to be called on execution.

View File

@@ -16,7 +16,7 @@ import java.util.List;
* update to use the new system: {@link CommandBase#tabComplete(CommandSender, List)} * update to use the new system: {@link CommandBase#tabComplete(CommandSender, List)}
*/ */
@FunctionalInterface @FunctionalInterface
@Deprecated(since = "6.17.0") @Deprecated(since = "6.17.0", forRemoval = true)
public interface TabCompleteHandler { public interface TabCompleteHandler {
/** /**
* Handle Tab Completion. * Handle Tab Completion.

View File

@@ -2,8 +2,6 @@ package com.willfp.eco.core.command.impl;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.command.CommandBase; import com.willfp.eco.core.command.CommandBase;
import com.willfp.eco.core.command.CommandHandler;
import com.willfp.eco.core.command.TabCompleteHandler;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil; import org.bukkit.util.StringUtil;
@@ -23,7 +21,7 @@ import java.util.stream.Collectors;
* in order to execute the command-specific code. It's essentially an internal * in order to execute the command-specific code. It's essentially an internal
* layer, hence why it's a package-private class. * layer, hence why it's a package-private class.
*/ */
@SuppressWarnings({"DeprecatedIsStillUsed"}) @SuppressWarnings({"DeprecatedIsStillUsed", "removal"})
abstract class HandledCommand implements CommandBase { abstract class HandledCommand implements CommandBase {
/** /**
* The plugin. * The plugin.
@@ -54,14 +52,14 @@ abstract class HandledCommand implements CommandBase {
*/ */
@Deprecated @Deprecated
@Nullable @Nullable
private CommandHandler handler = null; private com.willfp.eco.core.command.CommandHandler handler = null;
/** /**
* The tab completion code to be executed in the command. * The tab completion code to be executed in the command.
*/ */
@Deprecated @Deprecated
@Nullable @Nullable
private TabCompleteHandler tabCompleter = null; private com.willfp.eco.core.command.TabCompleteHandler tabCompleter = null;
/** /**
* All subcommands for the command. * All subcommands for the command.
@@ -169,7 +167,10 @@ abstract class HandledCommand implements CommandBase {
StringUtil.copyPartialMatches( StringUtil.copyPartialMatches(
args[0], args[0],
this.getSubcommands().stream().map(CommandBase::getName).collect(Collectors.toList()), this.getSubcommands().stream()
.filter(subCommand -> sender.hasPermission(subCommand.getPermission()))
.map(CommandBase::getName)
.collect(Collectors.toList()),
completions completions
); );
@@ -184,6 +185,10 @@ abstract class HandledCommand implements CommandBase {
HandledCommand command = null; HandledCommand command = null;
for (CommandBase subcommand : this.getSubcommands()) { for (CommandBase subcommand : this.getSubcommands()) {
if (!sender.hasPermission(subcommand.getPermission())) {
continue;
}
if (args[0].equalsIgnoreCase(subcommand.getName())) { if (args[0].equalsIgnoreCase(subcommand.getName())) {
command = (HandledCommand) subcommand; command = (HandledCommand) subcommand;
} }
@@ -256,27 +261,27 @@ abstract class HandledCommand implements CommandBase {
return this.subcommands; return this.subcommands;
} }
@Deprecated @Deprecated(forRemoval = true)
@Override @Override
public @Nullable CommandHandler getHandler() { public @Nullable com.willfp.eco.core.command.CommandHandler getHandler() {
return this.handler; return this.handler;
} }
@Deprecated @Deprecated(forRemoval = true)
@Override @Override
public @Nullable TabCompleteHandler getTabCompleter() { public @Nullable com.willfp.eco.core.command.TabCompleteHandler getTabCompleter() {
return this.tabCompleter; return this.tabCompleter;
} }
@Deprecated @Deprecated(forRemoval = true)
@Override @Override
public void setHandler(@Nullable final CommandHandler handler) { public void setHandler(@Nullable final com.willfp.eco.core.command.CommandHandler handler) {
this.handler = handler; this.handler = handler;
} }
@Deprecated @Deprecated(forRemoval = true)
@Override @Override
public void setTabCompleter(@Nullable final TabCompleteHandler tabCompleter) { public void setTabCompleter(@Nullable final com.willfp.eco.core.command.TabCompleteHandler tabCompleter) {
this.tabCompleter = tabCompleter; this.tabCompleter = tabCompleter;
} }
} }

View File

@@ -23,13 +23,31 @@ public abstract class BaseConfig extends LoadableConfigWrapper {
@NotNull final PluginLike plugin, @NotNull final PluginLike plugin,
final boolean removeUnused, final boolean removeUnused,
@NotNull final ConfigType type) { @NotNull final ConfigType type) {
super(Eco.getHandler().getConfigFactory().createUpdatableConfig( this(configName, plugin, removeUnused, type, true);
}
/**
* Create new Base Config.
*
* @param plugin The plugin or extension.
* @param configName The config name (excluding extension).
* @param removeUnused If unused sections should be removed.
* @param type The config type.
* @param requiresChangeToSave If changes must be applied to save the config.
*/
protected BaseConfig(@NotNull final String configName,
@NotNull final PluginLike plugin,
final boolean removeUnused,
@NotNull final ConfigType type,
final boolean requiresChangeToSave) {
super(Eco.get().createUpdatableConfig(
configName, configName,
plugin, plugin,
"", "",
plugin.getClass(), plugin.getClass(),
removeUnused, removeUnused,
type type,
requiresChangeToSave
)); ));
} }
} }

View File

@@ -0,0 +1,29 @@
package com.willfp.eco.core.config;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Builder for configs to create them programmatically.
*/
public class BuildableConfig extends TransientConfig {
/**
* Create a new empty config builder.
*/
public BuildableConfig() {
super();
}
/**
* Add to the config builder.
*
* @param path The path.
* @param object The object.
* @return The builder.
*/
public BuildableConfig add(@NotNull final String path,
@Nullable final Object object) {
set(path, object);
return this;
}
}

View File

@@ -1,5 +1,7 @@
package com.willfp.eco.core.config; package com.willfp.eco.core.config;
import org.jetbrains.annotations.NotNull;
/** /**
* Config types, classified by file extension. * Config types, classified by file extension.
*/ */
@@ -7,10 +9,33 @@ public enum ConfigType {
/** /**
* .json config. * .json config.
*/ */
JSON, JSON("json"),
/** /**
* .yml config. * .yml config.
*/ */
YAML YAML("yml"),
/**
* .toml config.
*/
TOML("toml");
/**
* The file extension.
*/
private final String extension;
ConfigType(@NotNull final String extension) {
this.extension = extension;
}
/**
* Get the file extension.
*
* @return The extension.
*/
public String getExtension() {
return extension;
}
} }

View File

@@ -31,13 +31,14 @@ public abstract class ExtendableConfig extends LoadableConfigWrapper {
@NotNull final String subDirectoryPath, @NotNull final String subDirectoryPath,
@NotNull final ConfigType type, @NotNull final ConfigType type,
@NotNull final String... updateBlacklist) { @NotNull final String... updateBlacklist) {
super(Eco.getHandler().getConfigFactory().createUpdatableConfig( super(Eco.get().createUpdatableConfig(
configName, configName,
plugin, plugin,
subDirectoryPath, subDirectoryPath,
source, source,
removeUnused, removeUnused,
type, type,
true,
updateBlacklist updateBlacklist
)); ));
} }

View File

@@ -21,12 +21,13 @@ public abstract class StaticBaseConfig extends LoadableConfigWrapper {
protected StaticBaseConfig(@NotNull final String configName, protected StaticBaseConfig(@NotNull final String configName,
@NotNull final PluginLike plugin, @NotNull final PluginLike plugin,
@NotNull final ConfigType type) { @NotNull final ConfigType type) {
super(Eco.getHandler().getConfigFactory().createLoadableConfig( super(Eco.get().createLoadableConfig(
configName, configName,
plugin, plugin,
"", "",
plugin.getClass(), plugin.getClass(),
type type,
true
)); ));
} }
} }

View File

@@ -3,12 +3,17 @@ package com.willfp.eco.core.config;
import com.willfp.eco.core.Eco; import com.willfp.eco.core.Eco;
import com.willfp.eco.core.config.interfaces.Config; import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.config.wrapper.ConfigWrapper; import com.willfp.eco.core.config.wrapper.ConfigWrapper;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
@@ -18,35 +23,74 @@ import java.util.Map;
*/ */
public class TransientConfig extends ConfigWrapper<Config> { public class TransientConfig extends ConfigWrapper<Config> {
/** /**
* @param config The ConfigurationSection handle.
*/
public TransientConfig(@NotNull final ConfigurationSection config) {
super(Eco.get().wrapConfigurationSection(config));
}
/**
* Exists for backwards compatibility, YamlConfigurations are ConfigurationSections.
*
* @param config The YamlConfiguration handle. * @param config The YamlConfiguration handle.
*/ */
public TransientConfig(@NotNull final YamlConfiguration config) { public TransientConfig(@NotNull final YamlConfiguration config) {
super(Eco.getHandler().getConfigFactory().createConfig(config)); this((ConfigurationSection) config);
} }
/** /**
* @param stream The InputStream. * @param stream The InputStream.
*/ */
public TransientConfig(@Nullable final InputStream stream) { public TransientConfig(@Nullable final InputStream stream) {
super(stream != null ? Eco.getHandler().getConfigFactory().createConfig(YamlConfiguration.loadConfiguration( super(stream != null ? Eco.get().wrapConfigurationSection(YamlConfiguration.loadConfiguration(
new InputStreamReader(stream) new InputStreamReader(stream)
)) : new TransientConfig()); )) : new TransientConfig());
} }
/**
* @param file The File.
* @deprecated Specify the config type to prevent bugs.
*/
@Deprecated(since = "6.30.0", forRemoval = true)
public TransientConfig(@Nullable final File file) {
this(file, ConfigType.YAML);
}
/**
* @param file The file.
* @param type The config type to try read from.
*/
public TransientConfig(@Nullable final File file,
@NotNull final ConfigType type) {
super(file != null ? Eco.get().createConfig(readFile(file), type)
: new TransientConfig());
}
/** /**
* Create a new empty transient config. * Create a new empty transient config.
* *
* @param values The values. * @param values The values.
*/ */
public TransientConfig(@NotNull final Map<String, Object> values) { public TransientConfig(@NotNull final Map<String, Object> values) {
super(Eco.getHandler().getConfigFactory().createConfig(values)); super(Eco.get().createConfig(values, ConfigType.YAML));
}
/**
* Create a new empty transient config.
*
* @param values The values.
* @param type The type.
*/
public TransientConfig(@NotNull final Map<String, Object> values,
@NotNull final ConfigType type) {
super(Eco.get().createConfig(values, type));
} }
/** /**
* Create a new empty transient config. * Create a new empty transient config.
*/ */
public TransientConfig() { public TransientConfig() {
super(Eco.getHandler().getConfigFactory().createConfig("", ConfigType.YAML)); this(new HashMap<>(), ConfigType.JSON);
} }
/** /**
@@ -55,6 +99,24 @@ public class TransientConfig extends ConfigWrapper<Config> {
*/ */
public TransientConfig(@NotNull final String contents, public TransientConfig(@NotNull final String contents,
@NotNull final ConfigType type) { @NotNull final ConfigType type) {
super(Eco.getHandler().getConfigFactory().createConfig(contents, type)); super(Eco.get().createConfig(contents, type));
}
/**
* Read a file to a string.
*
* @param file The file.
* @return The string.
*/
private static String readFile(@Nullable final File file) {
if (file == null) {
return "";
}
try {
return Files.readString(file.toPath());
} catch (IOException e) {
return "";
}
} }
} }

View File

@@ -1,19 +1,27 @@
package com.willfp.eco.core.config.interfaces; package com.willfp.eco.core.config.interfaces;
import com.willfp.eco.core.config.BuildableConfig;
import com.willfp.eco.core.config.ConfigType; import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.TransientConfig; import com.willfp.eco.core.config.TransientConfig;
import com.willfp.eco.core.placeholder.AdditionalPlayer;
import com.willfp.eco.core.placeholder.InjectablePlaceholder;
import com.willfp.eco.core.placeholder.PlaceholderInjectable; import com.willfp.eco.core.placeholder.PlaceholderInjectable;
import com.willfp.eco.core.placeholder.StaticPlaceholder;
import com.willfp.eco.util.NumberUtils; import com.willfp.eco.util.NumberUtils;
import com.willfp.eco.util.StringUtils; import com.willfp.eco.util.StringUtils;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
/** /**
* All configs implement this interface. * All configs implement this interface.
@@ -24,8 +32,13 @@ import java.util.Objects;
public interface Config extends Cloneable, PlaceholderInjectable { public interface Config extends Cloneable, PlaceholderInjectable {
/** /**
* Clears cache. * Clears cache.
* <p>
* Configs no longer have caches as they have in previous versions.
*/ */
void clearCache(); @Deprecated(since = "6.31.1", forRemoval = true)
default void clearCache() {
// Do nothing.
}
/** /**
* Convert the config into readable text. * Convert the config into readable text.
@@ -51,9 +64,21 @@ public interface Config extends Cloneable, PlaceholderInjectable {
@NotNull @NotNull
List<String> getKeys(boolean deep); List<String> getKeys(boolean deep);
/**
* Recurse config keys.
*
* @param found The found keys.
* @param root The root.
* @return The keys.
*/
@NotNull
default List<String> recurseKeys(@NotNull Set<String> found,
@NotNull String root) {
return new ArrayList<>();
}
/** /**
* Get an object from config. * Get an object from config.
* Default implementations call {@link org.bukkit.configuration.file.YamlConfiguration#get(String)}.
* *
* @param path The path. * @param path The path.
* @return The object. * @return The object.
@@ -63,7 +88,6 @@ public interface Config extends Cloneable, PlaceholderInjectable {
/** /**
* Set an object in config. * Set an object in config.
* Default implementations call {@link org.bukkit.configuration.file.YamlConfiguration#set(String, Object)}
* *
* @param path The path. * @param path The path.
* @param object The object. * @param object The object.
@@ -135,6 +159,20 @@ public interface Config extends Cloneable, PlaceholderInjectable {
return Double.valueOf(getDoubleFromExpression(path, player)).intValue(); return Double.valueOf(getDoubleFromExpression(path, player)).intValue();
} }
/**
* Get a decimal value via a mathematical expression.
*
* @param path The key to fetch the value from.
* @param player The player to evaluate placeholders with respect to.
* @param additionalPlayers The additional players to evaluate placeholders with respect to.
* @return The computed value, or 0 if not found or invalid.
*/
default int getIntFromExpression(@NotNull String path,
@Nullable Player player,
@NotNull Collection<AdditionalPlayer> additionalPlayers) {
return Double.valueOf(getDoubleFromExpression(path, player, additionalPlayers)).intValue();
}
/** /**
* Get an integer from config. * Get an integer from config.
@@ -241,35 +279,6 @@ public interface Config extends Cloneable, PlaceholderInjectable {
return getString(path, false, StringUtils.FormatOption.WITHOUT_PLACEHOLDERS); return getString(path, false, StringUtils.FormatOption.WITHOUT_PLACEHOLDERS);
} }
/**
* Get a string from config.
*
* @param path The key to fetch the value from.
* @param format If the string should be formatted.
* @return The found value, or an empty string if not found.
* @deprecated Since 6.18.0, {@link Config#getString(String)} is not formatted by default.
*/
@Deprecated(since = "6.18.0")
default String getString(@NotNull String path,
boolean format) {
return this.getString(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
}
/**
* Get a string from config.
*
* @param path The key to fetch the value from.
* @param option The format option.
* @return The found value, or an empty string if not found.
* @deprecated Use {@link Config#getFormattedString(String, StringUtils.FormatOption)} instead.
*/
@NotNull
@Deprecated
default String getString(@NotNull String path,
@NotNull final StringUtils.FormatOption option) {
return this.getString(path, true, option);
}
/** /**
* Get a string from config. * Get a string from config.
* *
@@ -322,36 +331,6 @@ public interface Config extends Cloneable, PlaceholderInjectable {
return getStringOrNull(path, false, StringUtils.FormatOption.WITH_PLACEHOLDERS); return getStringOrNull(path, false, StringUtils.FormatOption.WITH_PLACEHOLDERS);
} }
/**
* Get a string from config.
*
* @param path The key to fetch the value from.
* @param format If the string should be formatted.
* @return The found value, or null if not found.
* @deprecated Since 6.18.0, {@link Config#getString(String)} is not formatted by default.
*/
@Nullable
@Deprecated(since = "6.18.0")
default String getStringOrNull(@NotNull String path,
boolean format) {
return this.getStringOrNull(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
}
/**
* Get a string from config.
*
* @param path The key to fetch the value from.
* @param option The format option.
* @return The found value, or null if not found.
* @deprecated Use {@link Config#getFormattedString(String, StringUtils.FormatOption)} instead.
*/
@Nullable
@Deprecated
default String getStringOrNull(@NotNull String path,
@NotNull StringUtils.FormatOption option) {
return this.getStringOrNull(path, true, option);
}
/** /**
* Get a string from config. * Get a string from config.
* *
@@ -406,36 +385,6 @@ public interface Config extends Cloneable, PlaceholderInjectable {
return getStrings(path, false, StringUtils.FormatOption.WITH_PLACEHOLDERS); return getStrings(path, false, StringUtils.FormatOption.WITH_PLACEHOLDERS);
} }
/**
* Get a list of strings from config.
*
* @param path The key to fetch the value from.
* @param format If the strings should be formatted.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
* @deprecated Since 6.18.0, {@link Config#getString(String)} is not formatted by default.
*/
@NotNull
@Deprecated(since = "6.18.0")
default List<String> getStrings(@NotNull String path,
boolean format) {
return this.getStrings(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
}
/**
* Get a list of strings from config.
*
* @param path The key to fetch the value from.
* @param option The format option.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
* @deprecated Use {@link Config#getFormattedStrings(String, StringUtils.FormatOption)} instead.
*/
@NotNull
@Deprecated
default List<String> getStrings(@NotNull String path,
@NotNull StringUtils.FormatOption option) {
return getStrings(path, false, option);
}
/** /**
* Get a list of strings from config. * Get a list of strings from config.
* *
@@ -494,36 +443,6 @@ public interface Config extends Cloneable, PlaceholderInjectable {
return getStringsOrNull(path, false, StringUtils.FormatOption.WITH_PLACEHOLDERS); return getStringsOrNull(path, false, StringUtils.FormatOption.WITH_PLACEHOLDERS);
} }
/**
* Get a list of strings from config.
*
* @param path The key to fetch the value from.
* @param format If the strings should be formatted.
* @return The found value, or null if not found.
* @deprecated Since 6.18.0, {@link Config#getString(String)} is not formatted by default.
*/
@Nullable
@Deprecated(since = "6.18.0")
default List<String> getStringsOrNull(@NotNull String path,
boolean format) {
return getStringsOrNull(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
}
/**
* Get a list of strings from config.
*
* @param path The key to fetch the value from.
* @param option The format option.
* @return The found value, or null if not found.
* @deprecated Use {@link Config#getFormattedStringsOrNull(String, StringUtils.FormatOption)} instead.
*/
@Nullable
@Deprecated
default List<String> getStringsOrNull(@NotNull String path,
@NotNull StringUtils.FormatOption option) {
return getStringsOrNull(path, false, option);
}
/** /**
* Get a list of strings from config. * Get a list of strings from config.
* *
@@ -566,7 +485,21 @@ public interface Config extends Cloneable, PlaceholderInjectable {
*/ */
default double getDoubleFromExpression(@NotNull String path, default double getDoubleFromExpression(@NotNull String path,
@Nullable Player player) { @Nullable Player player) {
return NumberUtils.evaluateExpression(this.getString(path), player, this.getInjectedPlaceholders()); return NumberUtils.evaluateExpression(this.getString(path), player, this);
}
/**
* Get a decimal value via a mathematical expression.
*
* @param path The key to fetch the value from.
* @param player The player to evaluate placeholders with respect to.
* @param additionalPlayers The additional players to evaluate placeholders with respect to.
* @return The computed value, or 0 if not found or invalid.
*/
default double getDoubleFromExpression(@NotNull String path,
@Nullable Player player,
@NotNull Collection<AdditionalPlayer> additionalPlayers) {
return NumberUtils.evaluateExpression(this.getString(path), player, this, additionalPlayers);
} }
/** /**
@@ -634,12 +567,12 @@ public interface Config extends Cloneable, PlaceholderInjectable {
Config clone(); Config clone();
@Override @Override
default void injectPlaceholders(@NotNull Iterable<StaticPlaceholder> placeholders) { default void addInjectablePlaceholder(@NotNull Iterable<InjectablePlaceholder> placeholders) {
// Do nothing. // Do nothing.
} }
@Override @Override
default List<StaticPlaceholder> getInjectedPlaceholders() { default @NotNull List<InjectablePlaceholder> getPlaceholderInjections() {
return Collections.emptyList(); return Collections.emptyList();
} }
@@ -647,4 +580,33 @@ public interface Config extends Cloneable, PlaceholderInjectable {
default void clearInjectedPlaceholders() { default void clearInjectedPlaceholders() {
// Do nothing. // Do nothing.
} }
/**
* Convert the config to a map of values.
*
* @return The values.
*/
default Map<String, Object> toMap() {
return new HashMap<>();
}
/**
* Convert the config to a map of values.
*
* @return The values.
*/
default ConfigurationSection toBukkit() {
YamlConfiguration empty = new YamlConfiguration();
empty.createSection("temp", this.toMap());
return empty.getConfigurationSection("temp");
}
/**
* Create a new config builder.
*
* @return The builder.
*/
static BuildableConfig builder() {
return new BuildableConfig();
}
} }

View File

@@ -1,63 +0,0 @@
package com.willfp.eco.core.config.interfaces;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* JSON config.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
@SuppressWarnings("DeprecatedIsStillUsed")
public interface JSONConfig extends Config {
/**
* Get a list of subsections from config.
*
* @param path The key to fetch the value from.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@NotNull
default List<JSONConfig> getSubsections(@NotNull String path) {
return Objects.requireNonNullElse(getSubsectionsOrNull(path), new ArrayList<>());
}
/**
* Get a list of subsections from config.
*
* @param path The key to fetch the value from.
* @return The found value, or null if not found.
*/
@Nullable
List<JSONConfig> getSubsectionsOrNull(@NotNull String path);
/**
* Get subsection from config.
*
* @param path The key to check.
* @return The subsection. Throws NPE if not found.
*/
@Override
@NotNull
JSONConfig getSubsection(@NotNull String path);
/**
* Get subsection from config.
*
* @param path The key to check.
* @return The subsection, or null if not found.
*/
@Override
@Nullable
JSONConfig getSubsectionOrNull(@NotNull String path);
@Override
JSONConfig clone();
}

View File

@@ -1,7 +1,7 @@
package com.willfp.eco.core.config.interfaces; package com.willfp.eco.core.config.interfaces;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.io.File; import java.io.File;
@@ -47,14 +47,21 @@ public interface LoadableConfig extends Config {
/** /**
* Get bukkit {@link YamlConfiguration}. * Get bukkit {@link YamlConfiguration}.
* <p> * <p>
* This method is not recommended unless absolutely required as it * This used to represent the underlying config, but since 6.30.0 configs use
* only returns true if the type of config is {@link com.willfp.eco.core.config.ConfigType#YAML}, * their own implementations internally, without relying on bukkit.
* and if the handle is an {@link YamlConfiguration} specifically. This depends on the internals
* and the implementation, and so may cause problems - it exists mostly for parity with
* {@link JavaPlugin#getConfig()}.
* *
* @return The config, or null if config is not yaml-based. * @return The config, or null if config is not yaml-based.
* @deprecated Use toBukkit() instead.
*/ */
@Nullable @Nullable
YamlConfiguration getBukkitHandle(); @Deprecated(since = "6.30.0", forRemoval = true)
default YamlConfiguration getBukkitHandle() {
return this.toBukkit();
}
/**
* Convert the config to a bukkit {@link YamlConfiguration}.
*/
@NotNull
YamlConfiguration toBukkit();
} }

View File

@@ -1,21 +0,0 @@
package com.willfp.eco.core.config.interfaces;
import org.bukkit.configuration.file.YamlConfiguration;
/**
* Interface for configs that wrap an {@link YamlConfiguration}.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
@SuppressWarnings("DeprecatedIsStillUsed")
public interface WrappedYamlConfiguration {
/**
* Get the ConfigurationSection handle.
*
* @return The handle.
*/
YamlConfiguration getBukkitHandle();
}

View File

@@ -1,90 +0,0 @@
package com.willfp.eco.core.config.json;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
import org.jetbrains.annotations.NotNull;
/**
* Config implementation for configs present in the plugin's base directory (eg config.json).
* <p>
* Automatically updates.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public abstract class JSONBaseConfig extends LoadableJSONConfigWrapper {
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param updateBlacklist Substring of keys to not add/remove keys for.
*/
protected JSONBaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final PluginLike plugin,
@NotNull final String... updateBlacklist) {
super(
(JSONConfig)
Eco.getHandler().getConfigFactory().createUpdatableConfig(
configName,
plugin,
"",
plugin.getClass(),
removeUnused,
ConfigType.JSON,
updateBlacklist
)
);
}
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
*/
protected JSONBaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final PluginLike plugin) {
super(
(JSONConfig)
Eco.getHandler().getConfigFactory().createUpdatableConfig(
configName,
plugin,
"",
plugin.getClass(),
removeUnused,
ConfigType.JSON
)
);
}
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param updateBlacklist Substring of keys to not add/remove keys for.
*/
protected JSONBaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final EcoPlugin plugin,
@NotNull final String... updateBlacklist) {
this(configName, removeUnused, (PluginLike) plugin, updateBlacklist);
}
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
*/
protected JSONBaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final EcoPlugin plugin) {
this(configName, removeUnused, (PluginLike) plugin);
}
}

View File

@@ -1,70 +0,0 @@
package com.willfp.eco.core.config.json;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
import org.jetbrains.annotations.NotNull;
/**
* Config implementation for configs present in one of two places:
* <ul>
* <li>Plugin base directory (eg config.yml, lang.yml)</li>
* <li>Other extension's configs</li>
* </ul>
* <p>
* Automatically updates.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public abstract class JSONExtendableConfig extends LoadableJSONConfigWrapper {
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param updateBlacklist Substring of keys to not add/remove keys for.
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
*/
protected JSONExtendableConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final PluginLike plugin,
@NotNull final Class<?> source,
@NotNull final String subDirectoryPath,
@NotNull final String... updateBlacklist) {
super(
(JSONConfig)
Eco.getHandler().getConfigFactory().createUpdatableConfig(
configName,
plugin,
subDirectoryPath,
source,
removeUnused,
ConfigType.JSON,
updateBlacklist
)
);
}
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param updateBlacklist Substring of keys to not add/remove keys for.
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
*/
protected JSONExtendableConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final EcoPlugin plugin,
@NotNull final Class<?> source,
@NotNull final String subDirectoryPath,
@NotNull final String... updateBlacklist) {
this(configName, removeUnused, (PluginLike) plugin, source, subDirectoryPath, updateBlacklist);
}
}

View File

@@ -1,45 +0,0 @@
package com.willfp.eco.core.config.json;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
import org.jetbrains.annotations.NotNull;
/**
* Non-updatable JSON config that exists within a plugin jar.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public abstract class JSONStaticBaseConfig extends LoadableJSONConfigWrapper {
/**
* Config implementation for configs present in the plugin's base directory (eg config.json, lang.json).
* <p>
* Does not automatically update.
*
* @param configName The name of the config
* @param plugin The plugin.
*/
protected JSONStaticBaseConfig(@NotNull final String configName,
@NotNull final PluginLike plugin) {
super((JSONConfig) Eco.getHandler().getConfigFactory().createLoadableConfig(configName, plugin, "", plugin.getClass(), ConfigType.JSON));
}
/**
* Config implementation for configs present in the plugin's base directory (eg config.json, lang.json).
* <p>
* Does not automatically update.
*
* @param configName The name of the config
* @param plugin The plugin.
*/
protected JSONStaticBaseConfig(@NotNull final String configName,
@NotNull final EcoPlugin plugin) {
this(configName, (PluginLike) plugin);
}
}

View File

@@ -1,37 +0,0 @@
package com.willfp.eco.core.config.json;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.eco.core.config.json.wrapper.JSONConfigWrapper;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
/**
* Raw JSON config with a map of values at its core.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public class JSONTransientConfig extends JSONConfigWrapper {
/**
* Config implementation for passing maps.
* <p>
* Does not automatically update.
*
* @param values The map of values.
*/
public JSONTransientConfig(@NotNull final Map<String, Object> values) {
super((JSONConfig) Eco.getHandler().getConfigFactory().createConfig(values));
}
/**
* Empty JSON config.
*/
public JSONTransientConfig() {
super((JSONConfig) Eco.getHandler().getConfigFactory().createConfig(new HashMap<>()));
}
}

View File

@@ -1,53 +0,0 @@
package com.willfp.eco.core.config.json.wrapper;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.eco.core.config.wrapper.ConfigWrapper;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* Wrapper to handle the backend JSON config implementations.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public abstract class JSONConfigWrapper extends ConfigWrapper<JSONConfig> implements JSONConfig {
/**
* Create a config wrapper.
*
* @param handle The handle.
*/
protected JSONConfigWrapper(@NotNull final JSONConfig handle) {
super(handle);
}
@Override
public @NotNull List<JSONConfig> getSubsections(@NotNull final String path) {
return this.getHandle().getSubsections(path);
}
@Override
public @Nullable List<JSONConfig> getSubsectionsOrNull(@NotNull final String path) {
return this.getHandle().getSubsectionsOrNull(path);
}
@Override
public @NotNull JSONConfig getSubsection(@NotNull final String path) {
return this.getHandle().getSubsection(path);
}
@Override
public @Nullable JSONConfig getSubsectionOrNull(@NotNull final String path) {
return this.getHandle().getSubsectionOrNull(path);
}
@Override
public JSONConfig clone() {
return this.getHandle().clone();
}
}

View File

@@ -1,63 +0,0 @@
package com.willfp.eco.core.config.json.wrapper;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.eco.core.config.interfaces.LoadableConfig;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
/**
* Wrapper to handle the backend loadable JSON config implementations.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public abstract class LoadableJSONConfigWrapper extends JSONConfigWrapper implements LoadableConfig {
/**
* Create a config wrapper.
*
* @param handle The handle.
*/
protected LoadableJSONConfigWrapper(@NotNull final JSONConfig handle) {
super(handle);
Validate.isTrue(handle instanceof LoadableConfig, "Wrapped config must be loadable!");
}
@Override
public void createFile() {
((LoadableConfig) this.getHandle()).createFile();
}
@Override
public String getResourcePath() {
return ((LoadableConfig) this.getHandle()).getResourcePath();
}
@Override
public void save() throws IOException {
((LoadableConfig) this.getHandle()).save();
}
@Override
public File getConfigFile() {
return ((LoadableConfig) this.getHandle()).getConfigFile();
}
@Override
public String getName() {
return ((LoadableConfig) this.getHandle()).getName();
}
@Override
public @Nullable YamlConfiguration getBukkitHandle() {
return null;
}
}

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core.config.updating; package com.willfp.eco.core.config.updating;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
@@ -29,7 +30,8 @@ import java.lang.annotation.Target;
* }</pre> * }</pre>
* <p> * <p>
* If using kotlin, you have to annotate the method with {@code @JvmStatic} * If using kotlin, you have to annotate the method with {@code @JvmStatic}
* in order to prevent null pointer exceptions. * in order to prevent null pointer exceptions - this also means that you cannot
* have config updater methods in companion objects.
* <p> * <p>
* Config update methods in all classes in a plugin jar will be called * Config update methods in all classes in a plugin jar will be called
* on reload. * on reload.
@@ -39,5 +41,6 @@ import java.lang.annotation.Target;
*/ */
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) @Target(ElementType.METHOD)
@Documented
public @interface ConfigUpdater { public @interface ConfigUpdater {
} }

View File

@@ -1,81 +0,0 @@
package com.willfp.eco.core.config.wrapper;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.config.interfaces.LoadableConfig;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
/**
* Internal component to create backend config implementations.
*/
@ApiStatus.Internal
@Eco.HandlerComponent
public interface ConfigFactory {
/**
* Updatable config.
*
* @param configName The name of the config
* @param plugin The plugin.
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param type The config type.
* @param updateBlacklist Substring of keys to not add/remove keys for.
* @return The config implementation.
*/
LoadableConfig createUpdatableConfig(@NotNull String configName,
@NotNull PluginLike plugin,
@NotNull String subDirectoryPath,
@NotNull Class<?> source,
boolean removeUnused,
@NotNull ConfigType type,
@NotNull String... updateBlacklist);
/**
* Loadable config.
*
* @param configName The name of the config
* @param plugin The plugin.
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
* @param type The config type.
* @return The config implementation.
*/
LoadableConfig createLoadableConfig(@NotNull String configName,
@NotNull PluginLike plugin,
@NotNull String subDirectoryPath,
@NotNull Class<?> source,
@NotNull ConfigType type);
/**
* Create config.
*
* @param config The handle.
* @return The config implementation.
*/
Config createConfig(@NotNull YamlConfiguration config);
/**
* Create config.
*
* @param values The values.
* @return The config implementation.
*/
Config createConfig(@NotNull Map<String, Object> values);
/**
* Create config.
*
* @param contents The file contents.
* @param type The type.
* @return The config implementation.
*/
Config createConfig(@NotNull String contents,
@NotNull ConfigType type);
}

View File

@@ -2,12 +2,14 @@ package com.willfp.eco.core.config.wrapper;
import com.willfp.eco.core.config.ConfigType; import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.interfaces.Config; import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.placeholder.StaticPlaceholder; import com.willfp.eco.core.placeholder.InjectablePlaceholder;
import com.willfp.eco.util.StringUtils; import com.willfp.eco.util.StringUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set;
/** /**
* Configs from eco have an internal implementation, * Configs from eco have an internal implementation,
@@ -17,7 +19,7 @@ import java.util.List;
* *
* @param <T> The type of the handle. * @param <T> The type of the handle.
*/ */
@SuppressWarnings("MethodDoesntCallSuperMethod") @SuppressWarnings({"MethodDoesntCallSuperMethod", "removal"})
public abstract class ConfigWrapper<T extends Config> implements Config { public abstract class ConfigWrapper<T extends Config> implements Config {
/** /**
* Configs from eco have an internal implementation, * Configs from eco have an internal implementation,
@@ -41,6 +43,7 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
} }
@Override @Override
@Deprecated(since = "6.31.1", forRemoval = true)
public void clearCache() { public void clearCache() {
handle.clearCache(); handle.clearCache();
} }
@@ -60,6 +63,12 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
return handle.getKeys(deep); return handle.getKeys(deep);
} }
@Override
public @NotNull List<String> recurseKeys(@NotNull final Set<String> found,
@NotNull final String root) {
return handle.recurseKeys(found, root);
}
@Override @Override
public @Nullable Object get(@NotNull final String path) { public @Nullable Object get(@NotNull final String path) {
return handle.get(path); return handle.get(path);
@@ -136,18 +145,13 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
} }
@Override @Override
public void injectPlaceholders(@NotNull final StaticPlaceholder... placeholders) { public void addInjectablePlaceholder(@NotNull final Iterable<InjectablePlaceholder> placeholders) {
handle.injectPlaceholders(placeholders); handle.addInjectablePlaceholder(placeholders);
} }
@Override @Override
public void injectPlaceholders(@NotNull final Iterable<StaticPlaceholder> placeholders) { public @NotNull List<InjectablePlaceholder> getPlaceholderInjections() {
handle.injectPlaceholders(placeholders); return handle.getPlaceholderInjections();
}
@Override
public List<StaticPlaceholder> getInjectedPlaceholders() {
return handle.getInjectedPlaceholders();
} }
@Override @Override
@@ -155,6 +159,11 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
handle.clearInjectedPlaceholders(); handle.clearInjectedPlaceholders();
} }
@Override
public Map<String, Object> toMap() {
return this.handle.toMap();
}
/** /**
* Get the handle. * Get the handle.
* *

View File

@@ -3,7 +3,6 @@ package com.willfp.eco.core.config.wrapper;
import com.willfp.eco.core.config.interfaces.LoadableConfig; import com.willfp.eco.core.config.interfaces.LoadableConfig;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@@ -47,7 +46,7 @@ public abstract class LoadableConfigWrapper extends ConfigWrapper<LoadableConfig
} }
@Override @Override
public @Nullable YamlConfiguration getBukkitHandle() { public @NotNull YamlConfiguration toBukkit() {
return this.getHandle().getBukkitHandle(); return this.getHandle().toBukkit();
} }
} }

View File

@@ -1,87 +0,0 @@
package com.willfp.eco.core.config.yaml;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
import org.jetbrains.annotations.NotNull;
/**
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
* <p>
* Automatically updates.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public abstract class YamlBaseConfig extends LoadableYamlConfigWrapper {
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param updateBlacklist Substring of keys to not add/remove keys for.
*/
protected YamlBaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final PluginLike plugin,
@NotNull final String... updateBlacklist) {
super(
Eco.getHandler().getConfigFactory().createUpdatableConfig(
configName,
plugin,
"",
plugin.getClass(),
removeUnused,
ConfigType.YAML,
updateBlacklist
)
);
}
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
*/
protected YamlBaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final PluginLike plugin) {
super(
Eco.getHandler().getConfigFactory().createUpdatableConfig(
configName,
plugin,
"",
plugin.getClass(),
removeUnused,
ConfigType.YAML
)
);
}
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param updateBlacklist Substring of keys to not add/remove keys for.
*/
protected YamlBaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final EcoPlugin plugin,
@NotNull final String... updateBlacklist) {
this(configName, removeUnused, (PluginLike) plugin, updateBlacklist);
}
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
*/
protected YamlBaseConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final EcoPlugin plugin) {
this(configName, removeUnused, (PluginLike) plugin);
}
}

View File

@@ -1,68 +0,0 @@
package com.willfp.eco.core.config.yaml;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
import org.jetbrains.annotations.NotNull;
/**
* Config implementation for configs present in one of two places:
* <ul>
* <li>Plugin base directory (eg config.yml, lang.yml)</li>
* <li>Other extension's configs</li>
* </ul>
* <p>
* Automatically updates.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public abstract class YamlExtendableConfig extends LoadableYamlConfigWrapper {
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param updateBlacklist Substring of keys to not add/remove keys for.
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
*/
protected YamlExtendableConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final PluginLike plugin,
@NotNull final Class<?> source,
@NotNull final String subDirectoryPath,
@NotNull final String... updateBlacklist) {
super(
Eco.getHandler().getConfigFactory().createUpdatableConfig(
configName,
plugin,
subDirectoryPath,
source,
removeUnused,
ConfigType.YAML,
updateBlacklist
)
);
}
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param updateBlacklist Substring of keys to not add/remove keys for.
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
*/
protected YamlExtendableConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final EcoPlugin plugin,
@NotNull final Class<?> source,
@NotNull final String subDirectoryPath,
@NotNull final String... updateBlacklist) {
this(configName, removeUnused, (PluginLike) plugin, source, subDirectoryPath, updateBlacklist);
}
}

View File

@@ -1,44 +0,0 @@
package com.willfp.eco.core.config.yaml;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
import org.jetbrains.annotations.NotNull;
/**
* Non-updatable yaml config that exists within a plugin jar.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public abstract class YamlStaticBaseConfig extends LoadableYamlConfigWrapper {
/**
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
* <p>
* Does not automatically update.
*
* @param configName The name of the config
* @param plugin The plugin.
*/
protected YamlStaticBaseConfig(@NotNull final String configName,
@NotNull final PluginLike plugin) {
super(Eco.getHandler().getConfigFactory().createLoadableConfig(configName, plugin, "", plugin.getClass(), ConfigType.YAML));
}
/**
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
* <p>
* Does not automatically update.
*
* @param configName The name of the config
* @param plugin The plugin.
*/
protected YamlStaticBaseConfig(@NotNull final String configName,
@NotNull final EcoPlugin plugin) {
this(configName, (PluginLike) plugin);
}
}

View File

@@ -1,42 +0,0 @@
package com.willfp.eco.core.config.yaml;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.yaml.wrapper.YamlConfigWrapper;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import java.io.StringReader;
/**
* Config implementation for passing YamlConfigurations.
* <p>
* Does not automatically update.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public class YamlTransientConfig extends YamlConfigWrapper {
/**
* @param config The YamlConfiguration handle.
*/
public YamlTransientConfig(@NotNull final YamlConfiguration config) {
super(Eco.getHandler().getConfigFactory().createConfig(config));
}
/**
* @param contents The contents of the config.
*/
public YamlTransientConfig(@NotNull final String contents) {
super(Eco.getHandler().getConfigFactory().createConfig(contents, ConfigType.YAML));
}
/**
* Create a new empty transient config.
*/
public YamlTransientConfig() {
super(Eco.getHandler().getConfigFactory().createConfig(YamlConfiguration.loadConfiguration(new StringReader(""))));
}
}

View File

@@ -1,63 +0,0 @@
package com.willfp.eco.core.config.yaml.wrapper;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.config.interfaces.LoadableConfig;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
/**
* Wrapper to handle the backend loadable yaml config implementations.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public abstract class LoadableYamlConfigWrapper extends YamlConfigWrapper implements LoadableConfig {
/**
* Create a config wrapper.
*
* @param handle The handle.
*/
protected LoadableYamlConfigWrapper(@NotNull final Config handle) {
super(handle);
Validate.isTrue(handle instanceof LoadableConfig, "Wrapped config must be loadable!");
}
@Override
public void createFile() {
((LoadableConfig) this.getHandle()).createFile();
}
@Override
public String getResourcePath() {
return ((LoadableConfig) this.getHandle()).getResourcePath();
}
@Override
public void save() throws IOException {
((LoadableConfig) this.getHandle()).save();
}
@Override
public File getConfigFile() {
return ((LoadableConfig) this.getHandle()).getConfigFile();
}
@Override
public String getName() {
return ((LoadableConfig) this.getHandle()).getName();
}
@Override
public @Nullable YamlConfiguration getBukkitHandle() {
return ((LoadableConfig) this.getHandle()).getBukkitHandle();
}
}

View File

@@ -1,31 +0,0 @@
package com.willfp.eco.core.config.yaml.wrapper;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.config.interfaces.WrappedYamlConfiguration;
import com.willfp.eco.core.config.wrapper.ConfigWrapper;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
/**
* Wrapper to handle the backend yaml config implementations.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/
@Deprecated(since = "6.17.0")
public abstract class YamlConfigWrapper extends ConfigWrapper<Config> implements WrappedYamlConfiguration {
/**
* Create a config wrapper.
*
* @param handle The handle.
*/
protected YamlConfigWrapper(@NotNull final Config handle) {
super(handle);
}
@Override
public YamlConfiguration getBukkitHandle() {
return ((WrappedYamlConfiguration) this.getHandle()).getBukkitHandle();
}
}

View File

@@ -0,0 +1,101 @@
package com.willfp.eco.core.data;
import com.willfp.eco.core.Eco;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Set;
/**
* Persistent data container wrapper that allows for full string (non-namespaced) keys.
*/
public interface ExtendedPersistentDataContainer {
/**
* Set a key.
*
* @param key The key.
* @param dataType The data type.
* @param value The value.
* @param <T> The type.
* @param <Z> The type.
*/
<T, Z> void set(@NotNull String key, @NotNull PersistentDataType<T, Z> dataType, @NotNull Z value);
/**
* Get if there is a key.
*
* @param key The key.
* @param dataType The data type.
* @param <T> The type.
* @param <Z> The type.
* @return If the key is present.
*/
<T, Z> boolean has(@NotNull String key, @NotNull PersistentDataType<T, Z> dataType);
/**
* Get a value.
*
* @param key The key.
* @param dataType The data type.
* @param <T> The type.
* @param <Z> The type.
* @return The value, or null if not found.
*/
@Nullable <T, Z> Z get(@NotNull String key, @NotNull PersistentDataType<T, Z> dataType);
/**
* Get a value or default if not present.
*
* @param key The key.
* @param dataType The data type.
* @param defaultValue The default value.
* @param <T> The type.
* @param <Z> The type.
* @return The value, or the default if not found.
*/
@NotNull <T, Z> Z getOrDefault(@NotNull String key, @NotNull PersistentDataType<T, Z> dataType, @NotNull Z defaultValue);
/**
* Get all keys, including namespaced keys.
*
* @return The keys.
*/
@NotNull
Set<String> getAllKeys();
/**
* Remove a key.
*
* @param key The key.
*/
void remove(@NotNull String key);
/**
* Get the base PDC.
*
* @return The base.
*/
@NotNull
PersistentDataContainer getBase();
/**
* Get extension for PersistentDataContainers to add non-namespaced keys.
*
* @param base The base container.
* @return The extended container.
*/
static ExtendedPersistentDataContainer extend(@NotNull PersistentDataContainer base) {
return Eco.get().adaptPdc(base);
}
/**
* Create a new extended container.
*
* @return The extended container.
*/
static ExtendedPersistentDataContainer create() {
return extend(Eco.get().newPdc());
}
}

View File

@@ -31,6 +31,6 @@ public interface PlayerProfile extends Profile {
*/ */
@NotNull @NotNull
static PlayerProfile load(@NotNull final UUID uuid) { static PlayerProfile load(@NotNull final UUID uuid) {
return Eco.getHandler().getProfileHandler().load(uuid); return Eco.get().loadPlayerProfile(uuid);
} }
} }

View File

@@ -1,89 +0,0 @@
package com.willfp.eco.core.data;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.data.keys.PersistentDataKey;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
import java.util.UUID;
/**
* API to handle profiles.
*/
@ApiStatus.Internal
@Eco.HandlerComponent
public interface ProfileHandler {
/**
* Load a player profile.
*
* @param uuid The UUID.
* @return The profile.
*/
PlayerProfile load(@NotNull UUID uuid);
/**
* Load the server profile.
*
* @return The profile.
*/
ServerProfile loadServerProfile();
/**
* Unload a player profile from memory.
* <p>
* This will not save the profile first.
*
* @param uuid The uuid.
*/
void unloadPlayer(@NotNull UUID uuid);
/**
* Save a player profile.
* <p>
* Can run async if using MySQL.
*
* @param uuid The uuid.
* @deprecated Saving changes is faster and should be used. Saving a player manually is not recommended.
*/
@Deprecated
default void savePlayer(@NotNull UUID uuid) {
this.saveKeysFor(uuid, PersistentDataKey.values());
}
/**
* Save keys for a player.
* <p>
* Can run async if using MySQL.
*
* @param uuid The uuid.
* @param keys The keys.
*/
void saveKeysFor(@NotNull UUID uuid,
@NotNull Set<PersistentDataKey<?>> keys);
/**
* Save all player data.
*
* @param async If the saving should be done asynchronously.
* @deprecated async is now handled automatically depending on implementation.
*/
@Deprecated
default void saveAll(boolean async) {
saveAll();
}
/**
* Save all player data.
* <p>
* Can run async if using MySQL.
*/
void saveAll();
/**
* Commit all changes to the file.
* <p>
* Does nothing if using MySQL.
*/
void save();
}

View File

@@ -16,6 +16,6 @@ public interface ServerProfile extends Profile {
*/ */
@NotNull @NotNull
static ServerProfile load() { static ServerProfile load() {
return Eco.getHandler().getProfileHandler().loadServerProfile(); return Eco.get().getServerProfile();
} }
} }

View File

@@ -1,63 +0,0 @@
package com.willfp.eco.core.data.keys;
import com.willfp.eco.core.Eco;
import org.bukkit.NamespacedKey;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Set;
/**
* API to register persistent data keys.
*/
@ApiStatus.Internal
@Eco.HandlerComponent
public interface KeyRegistry {
/**
* Register a persistent data key to be stored.
*
* @param key The key.
*/
void registerKey(@NotNull PersistentDataKey<?> key);
/**
* Get all registered keys.
*
* @return The keys.
*/
Set<PersistentDataKey<?>> getRegisteredKeys();
/**
* Mark key as category.
*
* @param key The key.
* @param category The category.
*/
void markKeyAs(@NotNull PersistentDataKey<?> key,
@NotNull KeyRegistry.KeyCategory category);
/**
* Get persistent data key from namespaced key.
*
* @param namespacedKey The key.
* @return The key, or null if not found.
*/
@Nullable
PersistentDataKey<?> getKeyFrom(@NotNull NamespacedKey namespacedKey);
/**
* Locations for key categorization.
*/
enum KeyCategory {
/**
* Player keys.
*/
PLAYER,
/**
* Server keys.
*/
SERVER
}
}

View File

@@ -43,7 +43,7 @@ public final class PersistentDataKey<T> {
this.defaultValue = defaultValue; this.defaultValue = defaultValue;
this.type = type; this.type = type;
Eco.getHandler().getKeyRegistry().registerKey(this); Eco.get().registerPersistentKey(this);
} }
@Override @Override
@@ -83,28 +83,40 @@ public final class PersistentDataKey<T> {
} }
/** /**
* In older eco versions, keys would have to be categorized in order
* to register the columns in the MySQL database. This is no longer needed.
* <p>
* Old description is below:
* <p>
* Categorize key as a server key, will register new column to MySQL * Categorize key as a server key, will register new column to MySQL
* database immediately rather than waiting for auto-categorization. * database immediately rather than waiting for auto-categorization.
* <p> * <p>
* This will improve performance. * This will improve performance.
* *
* @return The key. * @return The key.
* @deprecated Not required since the new MySQL data handler was introduced.
*/ */
@Deprecated(since = "6.40.0", forRemoval = true)
public PersistentDataKey<T> server() { public PersistentDataKey<T> server() {
Eco.getHandler().getKeyRegistry().markKeyAs(this, KeyRegistry.KeyCategory.SERVER);
return this; return this;
} }
/** /**
* In older eco versions, keys would have to be categorized in order
* to register the columns in the MySQL database. This is no longer needed.
* <p>
* Old description is below:
* <p>
* Categorize key as a player key, will register new column to MySQL * Categorize key as a player key, will register new column to MySQL
* database immediately rather than waiting for auto-categorization. * database immediately rather than waiting for auto-categorization.
* <p> * <p>
* This will improve performance. * This will improve performance.
* *
* @return The key. * @return The key.
* @deprecated Not required since the new MySQL data handler was introduced.
*/ */
@Deprecated(since = "6.40.0", forRemoval = true)
public PersistentDataKey<T> player() { public PersistentDataKey<T> player() {
Eco.getHandler().getKeyRegistry().markKeyAs(this, KeyRegistry.KeyCategory.PLAYER);
return this; return this;
} }
@@ -114,7 +126,7 @@ public final class PersistentDataKey<T> {
* @return The keys. * @return The keys.
*/ */
public static Set<PersistentDataKey<?>> values() { public static Set<PersistentDataKey<?>> values() {
return Eco.getHandler().getKeyRegistry().getRegisteredKeys(); return Eco.get().getRegisteredPersistentDataKeys();
} }
@Override @Override

View File

@@ -1,10 +1,12 @@
package com.willfp.eco.core.data.keys; package com.willfp.eco.core.data.keys;
import com.willfp.eco.core.config.interfaces.Config;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
/** /**
* All storable data key types. * All storable data key types.
@@ -37,6 +39,16 @@ public final class PersistentDataKeyType<T> {
*/ */
public static final PersistentDataKeyType<Double> DOUBLE = new PersistentDataKeyType<>(Double.class, "DOUBLE"); public static final PersistentDataKeyType<Double> DOUBLE = new PersistentDataKeyType<>(Double.class, "DOUBLE");
/**
* String List.
*/
public static final PersistentDataKeyType<List<String>> STRING_LIST = new PersistentDataKeyType<>(null, "STRING_LIST");
/**
* Config.
*/
public static final PersistentDataKeyType<Config> CONFIG = new PersistentDataKeyType<>(Config.class, "CONFIG");
/** /**
* The class of the type. * The class of the type.
*/ */
@@ -51,7 +63,10 @@ public final class PersistentDataKeyType<T> {
* Get the class of the type. * Get the class of the type.
* *
* @return The class. * @return The class.
* @deprecated String list type will return null.
*/ */
@Deprecated(since = "6.36.0", forRemoval = true)
@Nullable
public Class<T> getTypeClass() { public Class<T> getTypeClass() {
return typeClass; return typeClass;
} }
@@ -71,7 +86,7 @@ public final class PersistentDataKeyType<T> {
* @param typeClass The type class. * @param typeClass The type class.
* @param name The name. * @param name The name.
*/ */
private PersistentDataKeyType(@NotNull final Class<T> typeClass, private PersistentDataKeyType(@Nullable final Class<T> typeClass,
@NotNull final String name) { @NotNull final String name) {
VALUES.add(this); VALUES.add(this);
@@ -79,6 +94,22 @@ public final class PersistentDataKeyType<T> {
this.name = name; this.name = name;
} }
@Override
public boolean equals(@Nullable final Object that) {
if (this == that) {
return true;
}
if (!(that instanceof PersistentDataKeyType type)) {
return false;
}
return Objects.equals(this.name, type.name);
}
@Override
public int hashCode() {
return Objects.hash(this.name);
}
/** /**
* Get all registered {@link PersistentDataKeyType}s. * Get all registered {@link PersistentDataKeyType}s.
* *

View File

@@ -1,11 +1,22 @@
package com.willfp.eco.core.display; package com.willfp.eco.core.display;
import com.willfp.eco.core.fast.FastItemStack;
import com.willfp.eco.util.NamespacedKeyUtils;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
/** /**
* Utility class to manage client-side item display. * Utility class to manage client-side item display.
*/ */
@@ -16,9 +27,14 @@ public final class Display {
public static final String PREFIX = "§z"; public static final String PREFIX = "§z";
/** /**
* The display handler. * All registered modules.
*/ */
private static DisplayHandler handler = null; private static final Map<Integer, List<DisplayModule>> REGISTERED_MODULES = new TreeMap<>();
/**
* The finalize key.
*/
private static final NamespacedKey FINALIZE_KEY = NamespacedKeyUtils.createEcoKey("finalized");
/** /**
* Display on ItemStacks. * Display on ItemStacks.
@@ -39,7 +55,49 @@ public final class Display {
*/ */
public static ItemStack display(@NotNull final ItemStack itemStack, public static ItemStack display(@NotNull final ItemStack itemStack,
@Nullable final Player player) { @Nullable final Player player) {
return handler.display(itemStack, player); Map<String, Object[]> pluginVarArgs = new HashMap<>();
for (List<DisplayModule> modules : REGISTERED_MODULES.values()) {
for (DisplayModule module : modules) {
pluginVarArgs.put(module.getPluginName(), module.generateVarArgs(itemStack));
}
}
Display.revert(itemStack);
if (!itemStack.hasItemMeta()) {
return itemStack;
}
ItemStack original = itemStack.clone();
Inventory inventory = player == null ? null : player.getOpenInventory().getTopInventory();
boolean inInventory = inventory != null && inventory.contains(original);
boolean inGui = inventory != null && inventory.getHolder() == null;
DisplayProperties properties = new DisplayProperties(
inInventory,
inGui,
original
);
for (List<DisplayModule> modules : REGISTERED_MODULES.values()) {
for (DisplayModule module : modules) {
Object[] varargs = pluginVarArgs.get(module.getPluginName());
if (varargs == null) {
continue;
}
module.display(itemStack, varargs);
if (player != null) {
module.display(itemStack, player, varargs);
module.display(itemStack, player, properties, varargs);
}
}
}
return itemStack;
} }
/** /**
@@ -71,7 +129,25 @@ public final class Display {
* @return The ItemStack. * @return The ItemStack.
*/ */
public static ItemStack revert(@NotNull final ItemStack itemStack) { public static ItemStack revert(@NotNull final ItemStack itemStack) {
return handler.revert(itemStack); if (Display.isFinalized(itemStack)) {
Display.unfinalize(itemStack);
}
FastItemStack fast = FastItemStack.wrap(itemStack);
List<String> lore = fast.getLore();
if (!lore.isEmpty() && lore.removeIf(line -> line.startsWith(Display.PREFIX))) {
fast.setLore(lore);
}
for (List<DisplayModule> modules : REGISTERED_MODULES.values()) {
for (DisplayModule module : modules) {
module.revert(itemStack);
}
}
return itemStack;
} }
/** /**
@@ -81,7 +157,15 @@ public final class Display {
* @return The ItemStack. * @return The ItemStack.
*/ */
public static ItemStack finalize(@NotNull final ItemStack itemStack) { public static ItemStack finalize(@NotNull final ItemStack itemStack) {
return handler.finalize(itemStack); if (itemStack.getType().getMaxStackSize() > 1) {
return itemStack;
}
FastItemStack.wrap(itemStack)
.getPersistentDataContainer()
.set(FINALIZE_KEY, PersistentDataType.INTEGER, 1);
return itemStack;
} }
/** /**
@@ -91,7 +175,11 @@ public final class Display {
* @return The ItemStack. * @return The ItemStack.
*/ */
public static ItemStack unfinalize(@NotNull final ItemStack itemStack) { public static ItemStack unfinalize(@NotNull final ItemStack itemStack) {
return handler.unfinalize(itemStack); FastItemStack.wrap(itemStack)
.getPersistentDataContainer()
.remove(FINALIZE_KEY);
return itemStack;
} }
/** /**
@@ -101,7 +189,9 @@ public final class Display {
* @return If finalized. * @return If finalized.
*/ */
public static boolean isFinalized(@NotNull final ItemStack itemStack) { public static boolean isFinalized(@NotNull final ItemStack itemStack) {
return handler.isFinalized(itemStack); return FastItemStack.wrap(itemStack)
.getPersistentDataContainer()
.has(FINALIZE_KEY, PersistentDataType.INTEGER);
} }
/** /**
@@ -110,69 +200,15 @@ public final class Display {
* @param module The module. * @param module The module.
*/ */
public static void registerDisplayModule(@NotNull final DisplayModule module) { public static void registerDisplayModule(@NotNull final DisplayModule module) {
handler.registerDisplayModule(module); List<DisplayModule> modules = REGISTERED_MODULES.getOrDefault(
} module.getWeight(),
new ArrayList<>()
);
/** modules.removeIf(it -> it.getPluginName().equalsIgnoreCase(module.getPluginName()));
* Initialize the display system. modules.add(module);
*
* @param handler The handler.
*/
@ApiStatus.Internal
public static void init(@NotNull final DisplayHandler handler) {
if (Display.handler != null) {
throw new IllegalArgumentException("Already Initialized!");
}
Display.handler = handler;
}
/** REGISTERED_MODULES.put(module.getWeight(), modules);
* Extremely janky method - also internal, so don't use it. <b>This method is
* NOT part of the API and may be removed at any time!</b>
* <p>
* This calls a display module with the specified parameters, now
* you might ask why I need a static java method when the DisplayHandler
* implementation could just call it itself? Well, kotlin doesn't really
* like dealing with vararg ambiguity, and so while kotlin can't figure out
* what is and isn't a vararg when I call display with a player, java can.
* <p>
* Because of this, I need to have this part of the code in java.
*
* <b>Don't call this method as part of your plugins!</b>
* <p>
* No, seriously - don't. This skips a bunch of checks and you'll almost
* definitely break something.
*
* @param module The display module.
* @param itemStack The ItemStack.
* @param player The player.
* @param args The args.
*/
@ApiStatus.Internal
public static void callDisplayModule(@NotNull final DisplayModule module,
@NotNull final ItemStack itemStack,
@Nullable final Player player,
@NotNull final Object... args) {
module.display(itemStack, args);
if (player != null) {
module.display(itemStack, player, args);
}
}
/**
* Set the display handler.
* <p>
* Internal API component, you will cause bugs if you create your own handler.
*
* @param handler The handler.
*/
@ApiStatus.Internal
public static void setHandler(@NotNull final DisplayHandler handler) {
if (Display.handler != null) {
throw new IllegalStateException("Display already initialized!");
}
Display.handler = handler;
} }
private Display() { private Display() {

View File

@@ -1,64 +0,0 @@
package com.willfp.eco.core.display;
import com.willfp.eco.core.Eco;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Interface for display implementations.
*/
@ApiStatus.Internal
@Eco.HandlerComponent
public interface DisplayHandler {
/**
* Register display module.
*
* @param module The module.
*/
void registerDisplayModule(@NotNull DisplayModule module);
/**
* Display on ItemStacks.
*
* @param itemStack The item.
* @param player The player.
* @return The ItemStack.
*/
ItemStack display(@NotNull ItemStack itemStack,
@Nullable Player player);
/**
* Revert on ItemStacks.
*
* @param itemStack The item.
* @return The ItemStack.
*/
ItemStack revert(@NotNull ItemStack itemStack);
/**
* Finalize an ItemStacks.
*
* @param itemStack The item.
* @return The ItemStack.
*/
ItemStack finalize(@NotNull ItemStack itemStack);
/**
* Unfinalize an ItemStacks.
*
* @param itemStack The item.
* @return The ItemStack.
*/
ItemStack unfinalize(@NotNull ItemStack itemStack);
/**
* If an item is finalized.
*
* @param itemStack The item.
* @return If finalized.
*/
boolean isFinalized(@NotNull ItemStack itemStack);
}

View File

@@ -1,7 +1,6 @@
package com.willfp.eco.core.display; package com.willfp.eco.core.display;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginDependent;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -10,11 +9,16 @@ import org.jetbrains.annotations.Nullable;
/** /**
* Class for all plugin-specific client-side item display modules. * Class for all plugin-specific client-side item display modules.
*/ */
public abstract class DisplayModule extends PluginDependent<EcoPlugin> { public abstract class DisplayModule {
/** /**
* The priority of the module. * The priority of the module.
*/ */
private final DisplayPriority priority; private final int weight;
/**
* The plugin.
*/
private final EcoPlugin plugin;
/** /**
* Create a new display module. * Create a new display module.
@@ -24,8 +28,19 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
*/ */
protected DisplayModule(@NotNull final EcoPlugin plugin, protected DisplayModule(@NotNull final EcoPlugin plugin,
@NotNull final DisplayPriority priority) { @NotNull final DisplayPriority priority) {
super(plugin); this(plugin, priority.getWeight());
this.priority = priority; }
/**
* Create a new display module.
*
* @param plugin The plugin that the display is for.
* @param weight The weight/priority of the module.
*/
protected DisplayModule(@NotNull final EcoPlugin plugin,
final int weight) {
this.plugin = plugin;
this.weight = weight;
} }
/** /**
@@ -52,6 +67,21 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
// Technically optional. // Technically optional.
} }
/**
* Display an item.
*
* @param itemStack The item.
* @param player The player.
* @param properties The properties.
* @param args Optional args for display.
*/
public void display(@NotNull final ItemStack itemStack,
@Nullable final Player player,
@NotNull final DisplayProperties properties,
@NotNull final Object... args) {
// Technically optional.
}
/** /**
* Revert an item. * Revert an item.
* *
@@ -77,15 +107,41 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
* @return The plugin name. * @return The plugin name.
*/ */
public final String getPluginName() { public final String getPluginName() {
return super.getPlugin().getName(); return this.getPlugin().getName();
} }
/** /**
* Get the display priority. * Get the display priority.
* *
* @return The priority. * @return The priority.
* @deprecated Use getWeight instead.
*/ */
@Deprecated(since = "6.35.0", forRemoval = true)
public DisplayPriority getPriority() { public DisplayPriority getPriority() {
return this.priority; return switch (this.weight) {
case 100 -> DisplayPriority.LOWEST;
case 200 -> DisplayPriority.LOW;
case 300 -> DisplayPriority.HIGH;
case 400 -> DisplayPriority.HIGHEST;
default -> DisplayPriority.CUSTOM;
};
}
/**
* Get the display weight.
*
* @return The weight.
*/
public int getWeight() {
return this.weight;
}
/**
* Get the plugin.
*
* @return The plugin.
*/
public EcoPlugin getPlugin() {
return plugin;
} }
} }

View File

@@ -4,23 +4,51 @@ package com.willfp.eco.core.display;
* The priority (order) of display modules. * The priority (order) of display modules.
*/ */
public enum DisplayPriority { public enum DisplayPriority {
/**
* Custom weight.
*/
CUSTOM(250),
/** /**
* Ran first. * Ran first.
*/ */
LOWEST, LOWEST(100),
/** /**
* Ran second. * Ran second.
*/ */
LOW, LOW(200),
/** /**
* Ran third. * Ran third.
*/ */
HIGH, HIGH(300),
/** /**
* Ran last. * Ran last.
*/ */
HIGHEST HIGHEST(400);
/**
* The display priority weight.
*/
private final int weight;
/**
* Create new display priority.
*
* @param weight The weight.
*/
DisplayPriority(final int weight) {
this.weight = weight;
}
/**
* Get the weight.
*
* @return The weight.
*/
public int getWeight() {
return weight;
}
} }

View File

@@ -0,0 +1,18 @@
package com.willfp.eco.core.display;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
* Extra properties passed into {@link DisplayModule}.
*
* @param inInventory If the item was in an inventory.
* @param inGui If the item is assumed to be in a gui. (Not perfectly accurate).
* @param originalItem The original item, not to be modified.
*/
public record DisplayProperties(
boolean inInventory,
boolean inGui,
@NotNull ItemStack originalItem
) {
}

View File

@@ -21,13 +21,25 @@ public class DropQueue {
/** /**
* The internally used {@link DropQueue}. * The internally used {@link DropQueue}.
*/ */
private final InternalDropQueue handle; private final DropQueue delegate;
/** /**
* Create a new DropQueue.
*
* @param player The player. * @param player The player.
*/ */
public DropQueue(@NotNull final Player player) { public DropQueue(@NotNull final Player player) {
handle = Eco.getHandler().getDropQueueFactory().create(player); this.delegate = Eco.get().createDropQueue(player);
}
/**
* Create a new DropQueue with no delegate.
* <p>
* Call this constructor if you're creating custom DropQueue
* implementations.
*/
protected DropQueue() {
this.delegate = null;
} }
/** /**
@@ -37,7 +49,11 @@ public class DropQueue {
* @return The DropQueue. * @return The DropQueue.
*/ */
public DropQueue addItem(@NotNull final ItemStack item) { public DropQueue addItem(@NotNull final ItemStack item) {
handle.addItem(item); if (delegate == null) {
return this;
}
delegate.addItem(item);
return this; return this;
} }
@@ -48,7 +64,11 @@ public class DropQueue {
* @return The DropQueue. * @return The DropQueue.
*/ */
public DropQueue addItems(@NotNull final Collection<ItemStack> itemStacks) { public DropQueue addItems(@NotNull final Collection<ItemStack> itemStacks) {
handle.addItems(itemStacks); if (delegate == null) {
return this;
}
delegate.addItems(itemStacks);
return this; return this;
} }
@@ -59,7 +79,11 @@ public class DropQueue {
* @return The DropQueue. * @return The DropQueue.
*/ */
public DropQueue addXP(final int amount) { public DropQueue addXP(final int amount) {
handle.addXP(amount); if (delegate == null) {
return this;
}
delegate.addXP(amount);
return this; return this;
} }
@@ -70,7 +94,11 @@ public class DropQueue {
* @return The DropQueue. * @return The DropQueue.
*/ */
public DropQueue setLocation(@NotNull final Location location) { public DropQueue setLocation(@NotNull final Location location) {
handle.setLocation(location); if (delegate == null) {
return this;
}
delegate.setLocation(location);
return this; return this;
} }
@@ -80,7 +108,11 @@ public class DropQueue {
* @return The DropQueue. * @return The DropQueue.
*/ */
public DropQueue forceTelekinesis() { public DropQueue forceTelekinesis() {
handle.forceTelekinesis(); if (delegate == null) {
return this;
}
delegate.forceTelekinesis();
return this; return this;
} }
@@ -88,6 +120,10 @@ public class DropQueue {
* Push the queue. * Push the queue.
*/ */
public void push() { public void push() {
handle.push(); if (delegate == null) {
return;
}
delegate.push();
} }
} }

View File

@@ -1,21 +0,0 @@
package com.willfp.eco.core.drops;
import com.willfp.eco.core.Eco;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
/**
* Internal component to create backend DropQueue implementations.
*/
@ApiStatus.Internal
@Eco.HandlerComponent
public interface DropQueueFactory {
/**
* Create a DropQueue.
*
* @param player The player.
* @return The Queue.
*/
InternalDropQueue create(@NotNull Player player);
}

View File

@@ -1,60 +0,0 @@
package com.willfp.eco.core.drops;
import com.willfp.eco.core.Eco;
import org.bukkit.Location;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
/**
* Internal interface for backend DropQueue implementations.
*/
@ApiStatus.Internal
@Eco.HandlerComponent
public interface InternalDropQueue {
/**
* Add item to queue.
*
* @param item The item to add.
* @return The DropQueue.
*/
InternalDropQueue addItem(@NotNull ItemStack item);
/**
* Add multiple items to queue.
*
* @param itemStacks The items to add.
* @return The DropQueue.
*/
InternalDropQueue addItems(@NotNull Collection<ItemStack> itemStacks);
/**
* Add xp to queue.
*
* @param amount The amount to add.
* @return The DropQueue.
*/
InternalDropQueue addXP(int amount);
/**
* Set location of the origin of the drops.
*
* @param location The location.
* @return The DropQueue.
*/
InternalDropQueue setLocation(@NotNull Location location);
/**
* Force the queue to act as if player is telekinetic.
*
* @return The DropQueue.
*/
InternalDropQueue forceTelekinesis();
/**
* Push the queue.
*/
void push();
}

View File

@@ -101,6 +101,6 @@ public interface EntityController<T extends Mob> {
* @return The entity controller. * @return The entity controller.
*/ */
static <T extends Mob> EntityController<T> getFor(@NotNull final T entity) { static <T extends Mob> EntityController<T> getFor(@NotNull final T entity) {
return Eco.getHandler().createEntityController(entity); return Eco.get().createEntityController(entity);
} }
} }

View File

@@ -28,6 +28,6 @@ public class EmptyTestableEntity implements TestableEntity {
public Entity spawn(@NotNull final Location location) { public Entity spawn(@NotNull final Location location) {
Validate.notNull(location.getWorld()); Validate.notNull(location.getWorld());
return Eco.getHandler().createDummyEntity(location); return Eco.get().createDummyEntity(location);
} }
} }

View File

@@ -3,7 +3,7 @@ package com.willfp.eco.core.extensions;
import java.util.Set; import java.util.Set;
/** /**
* Internal component to manage loading and unloading extensions. * Manages the loading and unloading of extensions for a particular plugin.
*/ */
public interface ExtensionLoader { public interface ExtensionLoader {
/** /**

View File

@@ -13,5 +13,6 @@ public interface NamespacedKeyFactory {
* @param key The key in the {@link NamespacedKey}. * @param key The key in the {@link NamespacedKey}.
* @return The created {@link NamespacedKey}. * @return The created {@link NamespacedKey}.
*/ */
@NotNull
NamespacedKey create(@NotNull String key); NamespacedKey create(@NotNull String key);
} }

View File

@@ -1,10 +1,13 @@
package com.willfp.eco.core.fast; package com.willfp.eco.core.fast;
import com.willfp.eco.core.Eco; import com.willfp.eco.core.Eco;
import net.kyori.adventure.text.Component;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataHolder;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -16,7 +19,7 @@ import java.util.Set;
/** /**
* FastItemStack contains methods to modify and read items faster than in default bukkit. * FastItemStack contains methods to modify and read items faster than in default bukkit.
*/ */
public interface FastItemStack { public interface FastItemStack extends PersistentDataHolder {
/** /**
* Get all enchantments on an item. * Get all enchantments on an item.
* *
@@ -24,7 +27,7 @@ public interface FastItemStack {
* @return A map of all enchantments. * @return A map of all enchantments.
* @deprecated Poorly named method. Use getEnchants instead. * @deprecated Poorly named method. Use getEnchants instead.
*/ */
@Deprecated(since = "6.24.0") @Deprecated(since = "6.24.0", forRemoval = true)
default Map<Enchantment, Integer> getEnchantmentsOnItem(boolean checkStored) { default Map<Enchantment, Integer> getEnchantmentsOnItem(boolean checkStored) {
return getEnchants(checkStored); return getEnchants(checkStored);
} }
@@ -45,17 +48,55 @@ public interface FastItemStack {
* @param checkStored If stored enchantments should be accounted for. * @param checkStored If stored enchantments should be accounted for.
* @return A map of all enchantments. * @return A map of all enchantments.
*/ */
@NotNull
Map<Enchantment, Integer> getEnchants(boolean checkStored); Map<Enchantment, Integer> getEnchants(boolean checkStored);
/**
* Get the level of an enchantment on an item.
*
* @param enchantment The enchantment.
* @return The enchantment level, or 0 if not found.
* @deprecated Poorly named method. Use getEnchantmentLevel instead.
*/
@Deprecated(since = "6.34.0", forRemoval = true)
default int getLevelOnItem(@NotNull Enchantment enchantment) {
return getEnchantmentLevel(enchantment, false);
}
/** /**
* Get the level of an enchantment on an item. * Get the level of an enchantment on an item.
* *
* @param enchantment The enchantment. * @param enchantment The enchantment.
* @param checkStored If the stored NBT should also be checked. * @param checkStored If the stored NBT should also be checked.
* @return The enchantment level, or 0 if not found. * @return The enchantment level, or 0 if not found.
* @deprecated Poorly named method. Use getEnchantmentLevel instead.
*/ */
int getLevelOnItem(@NotNull Enchantment enchantment, @Deprecated(since = "6.34.0", forRemoval = true)
boolean checkStored); @SuppressWarnings("DeprecatedIsStillUsed")
default int getLevelOnItem(@NotNull Enchantment enchantment,
boolean checkStored) {
return getEnchantmentLevel(enchantment, checkStored);
}
/**
* Get the level of an enchantment.
*
* @param enchantment The enchantment.
* @return The enchantment level, or 0 if not found.
*/
default int getEnchantmentLevel(@NotNull Enchantment enchantment) {
return getLevelOnItem(enchantment, false);
}
/**
* Get the level of an enchantment.
*
* @param enchantment The enchantment.
* @param checkStored If the stored NBT should also be checked.
* @return The enchantment level, or 0 if not found.
*/
int getEnchantmentLevel(@NotNull Enchantment enchantment,
boolean checkStored);
/** /**
* Set the item lore. * Set the item lore.
@@ -64,6 +105,13 @@ public interface FastItemStack {
*/ */
void setLore(@Nullable List<String> lore); void setLore(@Nullable List<String> lore);
/**
* Set the item lore.
*
* @param lore The lore.
*/
void setLoreComponents(@Nullable List<Component> lore);
/** /**
* Get the item lore. * Get the item lore.
* *
@@ -71,6 +119,40 @@ public interface FastItemStack {
*/ */
List<String> getLore(); List<String> getLore();
/**
* Get the item lore.
*
* @return The lore.
*/
List<Component> getLoreComponents();
/**
* Set the item name.
*
* @param name The name.
*/
void setDisplayName(@Nullable Component name);
/**
* Set the item name.
*
* @param name The name.
*/
void setDisplayName(@Nullable String name);
/**
* Get the item display name.
*
* @return The display name.
*/
Component getDisplayNameComponent();
/**
* Get the item display name.
*
* @return The display name.
*/
String getDisplayName();
/** /**
* Set the rework penalty. * Set the rework penalty.
@@ -81,7 +163,6 @@ public interface FastItemStack {
/** /**
* Get the rework penalty. * Get the rework penalty.
* .
* *
* @return The rework penalty found on the item. * @return The rework penalty found on the item.
*/ */
@@ -116,11 +197,72 @@ public interface FastItemStack {
*/ */
boolean hasItemFlag(@NotNull ItemFlag flag); boolean hasItemFlag(@NotNull ItemFlag flag);
/**
* Get the base NBT tag (Not PublicBukkitValues, the base) as a PersistentDataContainer.
* <p>
* The returned PersistentDataContainer will not modify the item until the tag is set.
*
* @return The base NBT tag.
*/
PersistentDataContainer getBaseTag();
/**
* Set the base NBT tag (Not PublicBukkitValues, the base) from a PersistentDataContainer.
*
* @param container The PersistentDataContainer.
*/
void setBaseTag(@Nullable PersistentDataContainer container);
/**
* Get the type of the item.
*
* @return The type.
*/
@NotNull
Material getType();
/**
* Set the type of the item.
*
* @param material The type.
*/
void setType(@NotNull Material material);
/**
* Get the amount of the item.
*
* @return The amount.
*/
int getAmount();
/**
* Set the amount of the item.
*
* @param amount The amount.
*/
void setAmount(int amount);
/**
* Get the custom model data.
*
* @return The data, or null if none.
*/
@Nullable
Integer getCustomModelData();
/**
* Set the custom model data.
*
* @param data The data, null to remove.
*/
void setCustomModelData(@Nullable Integer data);
/** /**
* Get the Bukkit ItemStack again. * Get the Bukkit ItemStack again.
* *
* @return The ItemStack. * @return The ItemStack.
*/ */
@NotNull
ItemStack unwrap(); ItemStack unwrap();
/** /**
@@ -130,6 +272,6 @@ public interface FastItemStack {
* @return The FastItemStack. * @return The FastItemStack.
*/ */
static FastItemStack wrap(@Nullable final ItemStack itemStack) { static FastItemStack wrap(@Nullable final ItemStack itemStack) {
return Eco.getHandler().createFastItemStack(Objects.requireNonNullElseGet(itemStack, () -> new ItemStack(Material.AIR))); return Eco.get().createFastItemStack(Objects.requireNonNullElseGet(itemStack, () -> new ItemStack(Material.AIR)));
} }
} }

View File

@@ -0,0 +1,82 @@
package com.willfp.eco.core.gui;
import com.willfp.eco.core.gui.menu.Menu;
import com.willfp.eco.core.gui.slot.Slot;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* A GUI Component is a 2-dimensional set of slots that can be
* placed in a menu.
*/
public interface GUIComponent {
/**
* Get the amount of rows in the component.
*
* @return The rows.
*/
int getRows();
/**
* Get the amount of columns in the component.
*
* @return The columns.
*/
int getColumns();
/**
* Initialize the component.
* <p>
* This is called before getRows / getColumns is queried,
* and allows for dynamically sized components.
* <p>
* getRows and getColumns can return values bigger than this,
* it will simply prevent the component from being added at
* this position (for minimum-sized components).
*
* @param maxRows The maximum number of rows.
* @param maxColumns The maximum number of columns.
*/
default void init(final int maxRows,
final int maxColumns) {
// Most components will not require initialization.
}
/**
* Get the slot at a certain position in the component.
* <p>
* It's safe to assume to the row and column will always be in bounds.
*
* @param row The row (1-indexed).
* @param column The column (1-indexed).
* @return The slot, or null if no slot at the location.
*/
@Nullable
default Slot getSlotAt(final int row,
final int column) {
return null;
}
/**
* Get the slot at a certain position in the component.
* <p>
* If your component doesn't use context data (player, menu),
* then it will default to the raw slot.
* <p>
* It's safe to assume to the row and column will always be in bounds.
*
* @param row The row (1-indexed).
* @param column The column (1-indexed).
* @param player The player.
* @param menu The menu.
* @return The slot, or null if no slot at the location.
*/
@Nullable
default Slot getSlotAt(final int row,
final int column,
@NotNull final Player player,
@NotNull final Menu menu) {
return getSlotAt(row, column);
}
}

View File

@@ -1,33 +0,0 @@
package com.willfp.eco.core.gui;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.gui.menu.MenuBuilder;
import com.willfp.eco.core.gui.slot.SlotBuilder;
import com.willfp.eco.core.gui.slot.functional.SlotProvider;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
/**
* Internal component used by {@link com.willfp.eco.core.gui.menu.Menu#builder(int)}
* and {@link com.willfp.eco.core.gui.slot.Slot#builder(ItemStack)}.
*/
@ApiStatus.Internal
@Eco.HandlerComponent
public interface GUIFactory {
/**
* Create slot builder.
*
* @param provider The provider.
* @return The builder.
*/
SlotBuilder createSlotBuilder(@NotNull SlotProvider provider);
/**
* Create menu builder.
*
* @param rows The amount of rows.
* @return The builder.
*/
MenuBuilder createMenuBuilder(int rows);
}

View File

@@ -1,7 +1,9 @@
package com.willfp.eco.core.gui.menu; package com.willfp.eco.core.gui.menu;
import com.willfp.eco.core.Eco; import com.willfp.eco.core.Eco;
import com.willfp.eco.core.gui.page.Page;
import com.willfp.eco.core.gui.slot.Slot; import com.willfp.eco.core.gui.slot.Slot;
import com.willfp.eco.util.NamespacedKeyUtils;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
@@ -11,7 +13,10 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
/** /**
* GUI version of {@link Inventory}. * GUI version of {@link Inventory}.
@@ -27,7 +32,19 @@ public interface Menu {
int getRows(); int getRows();
/** /**
* Get slot at given row and column. * Get the amount of columns.
*
* @return The amount of columns.
*/
default int getColumns() {
return 9;
}
/**
* Get a static slot at a given row and column.
* <p>
* If the slot at the location is reactive, this will return
* an empty slot.
* *
* @param row The row. * @param row The row.
* @param column The column. * @param column The column.
@@ -36,6 +53,24 @@ public interface Menu {
Slot getSlot(int row, Slot getSlot(int row,
int column); int column);
/**
* Get a slot at a given row and column.
* <p>
* Defaults to static slot if no reactive slot exists.
*
* @param row The row.
* @param column The column.
* @param player The player
* @param menu The menu.
* @return The slot.
*/
default Slot getSlot(int row,
int column,
@NotNull Player player,
@NotNull Menu menu) {
return this.getSlot(row, column);
}
/** /**
* Get the menu title. * Get the menu title.
* *
@@ -59,6 +94,117 @@ public interface Menu {
*/ */
List<ItemStack> getCaptiveItems(@NotNull Player player); List<ItemStack> getCaptiveItems(@NotNull Player player);
/**
* Get a captive item at a specific position.
*
* @param player The player.
* @param row The row.
* @param column The column.
* @return The captive item.
*/
@Nullable
default ItemStack getCaptiveItem(@NotNull final Player player,
final int row,
final int column) {
return null;
}
/**
* Add state for a player.
*
* @param player The player.
* @param key The key.
* @param value The state.
*/
void addState(@NotNull Player player,
@NotNull String key,
@Nullable Object value);
/**
* Remove state for a player.
*
* @param player The player.
* @param key The key.
*/
void removeState(@NotNull Player player,
@NotNull String key);
/**
* Clear state for a player.
*
* @param player The player.
*/
void clearState(@NotNull Player player);
/**
* Get state for a player.
*
* @param player The player.
* @param key The key.
* @param <T> The type of state.
* @return The value.
*/
@Nullable <T> T getState(@NotNull Player player,
@NotNull String key);
/**
* Get state for a player.
*
* @param player The player.
* @return The state.
*/
Map<String, Object> getState(@NotNull Player player);
/**
* Re-render the menu for a player.
*
* @param player The player.
*/
void refresh(@NotNull Player player);
/**
* If the menu allows changing the held item.
*
* @return If allowed.
*/
default boolean allowsChangingHeldItem() {
return false;
}
/**
* Call a menu event.
*
* @param player The player.
* @param menuEvent The event.
*/
default void callEvent(@NotNull final Player player,
@NotNull final MenuEvent menuEvent) {
// Override when needed.
}
/**
* Get the current page a player is on.
*
* @param player The player.
* @return The page.
*/
default int getPage(@NotNull final Player player) {
Integer pageState = this.getState(player, Page.PAGE_KEY);
return Objects.requireNonNullElse(pageState, 1);
}
/**
* Get the max page for a player.
*
* @param player The player.
* @return The page.
*/
default int getMaxPage(@NotNull final Player player) {
Integer pageState = this.getState(player, Page.MAX_PAGE_KEY);
return Objects.requireNonNullElse(pageState, Integer.MAX_VALUE);
}
/** /**
* Write data. * Write data.
* *
@@ -68,11 +214,15 @@ public interface Menu {
* @param value The value. * @param value The value.
* @param <T> The type. * @param <T> The type.
* @param <Z> The type. * @param <Z> The type.
* @deprecated Use addState instead.
*/ */
<T, Z> void writeData(@NotNull Player player, @Deprecated(since = "6.35.0", forRemoval = true)
@NotNull NamespacedKey key, default <T, Z> void writeData(@NotNull final Player player,
@NotNull PersistentDataType<T, Z> type, @NotNull final NamespacedKey key,
@NotNull Z value); @NotNull final PersistentDataType<T, Z> type,
@NotNull final Z value) {
this.addState(player, key.toString(), value);
}
/** /**
* Read data. * Read data.
@@ -83,25 +233,29 @@ public interface Menu {
* @param <T> The type. * @param <T> The type.
* @param <Z> The type. * @param <Z> The type.
* @return The data. * @return The data.
* @deprecated Use getState instead.
*/ */
@Nullable <T, Z> T readData(@NotNull Player player, @Deprecated(since = "6.35.0", forRemoval = true)
@NotNull NamespacedKey key, default @Nullable <T, Z> T readData(@NotNull final Player player,
@NotNull PersistentDataType<T, Z> type); @NotNull final NamespacedKey key,
@NotNull final PersistentDataType<T, Z> type) {
return this.getState(player, key.toString());
}
/** /**
* Get all data keys for a player. * Get all data keys for a player.
* *
* @param player The player. * @param player The player.
* @return The keys. * @return The keys.
* @deprecated Use getState instead.
*/ */
Set<NamespacedKey> getKeys(@NotNull Player player); @Deprecated(since = "6.35.0", forRemoval = true)
default Set<NamespacedKey> getKeys(@NotNull final Player player) {
/** return this.getState(player).keySet().stream()
* Re-render the menu for a player. .map(NamespacedKeyUtils::fromStringOrNull)
* .filter(Objects::nonNull)
* @param player The player. .collect(Collectors.toSet());
*/ }
void refresh(@NotNull Player player);
/** /**
* Create a builder with a given amount of rows. * Create a builder with a given amount of rows.
@@ -110,6 +264,19 @@ public interface Menu {
* @return The builder. * @return The builder.
*/ */
static MenuBuilder builder(final int rows) { static MenuBuilder builder(final int rows) {
return Eco.getHandler().getGUIFactory().createMenuBuilder(rows); return Eco.get().createMenuBuilder(
rows,
MenuType.NORMAL
);
}
/**
* Create a builder with a given type.
*
* @param type The menu type.
* @return The builder.
*/
static MenuBuilder builder(@NotNull final MenuType type) {
return Eco.get().createMenuBuilder(type.getDefaultRows(), type);
} }
} }

View File

@@ -1,16 +1,22 @@
package com.willfp.eco.core.gui.menu; package com.willfp.eco.core.gui.menu;
import com.willfp.eco.core.gui.GUIComponent;
import com.willfp.eco.core.gui.page.Page;
import com.willfp.eco.core.gui.page.PageBuilder;
import com.willfp.eco.core.gui.slot.FillerMask; import com.willfp.eco.core.gui.slot.FillerMask;
import com.willfp.eco.core.gui.slot.Slot; import com.willfp.eco.core.gui.slot.Slot;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryCloseEvent; import org.bukkit.event.inventory.InventoryCloseEvent;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.function.BiConsumer;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function;
/** /**
* Builder to create menus. * Builder to create menus.
*/ */
public interface MenuBuilder { public interface MenuBuilder extends PageBuilder {
/** /**
* Set the menu title. * Set the menu title.
* *
@@ -19,6 +25,15 @@ public interface MenuBuilder {
*/ */
MenuBuilder setTitle(@NotNull String title); MenuBuilder setTitle(@NotNull String title);
/**
* Get the menu title.
*
* @return The builder.
*/
default String getTitle() {
return "";
}
/** /**
* Set a slot. * Set a slot.
* *
@@ -27,9 +42,44 @@ public interface MenuBuilder {
* @param slot The slot. * @param slot The slot.
* @return The builder. * @return The builder.
*/ */
MenuBuilder setSlot(int row, @Override
int column, default MenuBuilder setSlot(final int row,
@NotNull Slot slot); final int column,
@NotNull final Slot slot) {
return this.addComponent(row, column, slot);
}
/**
* Add a component.
*
* @param layer The layer.
* @param row The row of the top left corner.
* @param column The column of the top left corner.
* @param component The component.
* @return The builder.
*/
@Override
MenuBuilder addComponent(@NotNull MenuLayer layer,
int row,
int column,
@NotNull GUIComponent component);
/**
* Add a component.
*
* @param row The row of the top left corner.
* @param column The column of the top left corner.
* @param component The component.
* @return The builder.
*/
@Override
default MenuBuilder addComponent(final int row,
final int column,
@NotNull final GUIComponent component) {
return this.addComponent(MenuLayer.MIDDLE, row, column, component);
}
/** /**
* Run function to modify the builder. * Run function to modify the builder.
@@ -45,27 +95,106 @@ public interface MenuBuilder {
* @param mask The mask. * @param mask The mask.
* @return The builder. * @return The builder.
*/ */
MenuBuilder setMask(@NotNull FillerMask mask); @Override
default MenuBuilder setMask(@NotNull final FillerMask mask) {
return this.addComponent(MenuLayer.BACKGROUND, 1, 1, mask);
}
/** /**
* Set the menu close handler. * Add a page.
*
* @param page The page.
* @return The builder.
*/
default MenuBuilder addPage(@NotNull final Page page) {
return this.addComponent(MenuLayer.TOP, 1, 1, page);
}
/**
* Add a page.
*
* @param pageNumber The page number.
* @param builder The page builder.
* @return The builder.
*/
default MenuBuilder addPage(final int pageNumber,
@NotNull final PageBuilder builder) {
return this.addPage(new Page(pageNumber, ((MenuBuilder) builder).build()));
}
/**
* Set the max pages.
*
* @param pages The max pages.
* @return The builder.
*/
default MenuBuilder maxPages(final int pages) {
return this.maxPages(player -> pages);
}
/**
* Set the max pages dynamically for a player.
*
* @param pages The max pages.
* @return The builder.
*/
default MenuBuilder maxPages(@NotNull final Function<Player, Integer> pages) {
return onOpen((player, menu) -> menu.addState(player, Page.MAX_PAGE_KEY, pages.apply(player)));
}
/**
* Add a menu close handler.
* *
* @param action The handler. * @param action The handler.
* @return The builder. * @return The builder.
*/ */
default MenuBuilder onClose(@NotNull Consumer<InventoryCloseEvent> action) { default MenuBuilder onClose(@NotNull final Consumer<InventoryCloseEvent> action) {
onClose((event, menu) -> action.accept(event)); return this.onClose((event, menu) -> action.accept(event));
return this;
} }
/** /**
* Set the menu close handler. * Add a menu close handler.
* *
* @param action The handler. * @param action The handler.
* @return The builder. * @return The builder.
*/ */
MenuBuilder onClose(@NotNull CloseHandler action); MenuBuilder onClose(@NotNull CloseHandler action);
/**
* Add a menu open handler.
*
* @param action The handler.
* @return The builder.
*/
MenuBuilder onOpen(@NotNull OpenHandler action);
/**
* Add an action to run on render.
*
* @param action The action.
* @return The builder.
*/
MenuBuilder onRender(@NotNull BiConsumer<Player, Menu> action);
/**
* Add an action to run on an event.
*
* @param action The action.
* @return The builder.
*/
default MenuBuilder onEvent(@NotNull final MenuEventHandler<?> action) {
return this;
}
/**
* Allow the player to change their held item.
*
* @return The builder.
*/
default MenuBuilder allowChangingHeldItem() {
return this;
}
/** /**
* Build the menu. * Build the menu.
* *

View File

@@ -0,0 +1,8 @@
package com.willfp.eco.core.gui.menu;
/**
* Represents an event sent to a menu.
*/
public interface MenuEvent {
}

View File

@@ -0,0 +1,45 @@
package com.willfp.eco.core.gui.menu;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
/**
* Handles menu events.
*/
public abstract class MenuEventHandler<T extends MenuEvent> {
/**
* The class of the event.
*/
private final Class<T> eventClass;
/**
* Create a new menu event handler.
*
* @param eventClass The class of event to handle.
*/
protected MenuEventHandler(@NotNull final Class<T> eventClass) {
this.eventClass = eventClass;
}
/**
* Performs this operation on the given arguments.
*
* @param player The player.
* @param menu The menu.
* @param event The event.
*/
public abstract void handle(@NotNull Player player,
@NotNull Menu menu,
@NotNull T event);
/**
* Get if this handler can handle a certain event.
*
* @param menuEvent The event
* @return If the event can be handled.
*/
public boolean canHandleEvent(@NotNull final MenuEvent menuEvent) {
return eventClass.isAssignableFrom(menuEvent.getClass());
}
}

View File

@@ -0,0 +1,31 @@
package com.willfp.eco.core.gui.menu;
/**
* Different layers of the menu.
*/
public enum MenuLayer {
/**
* Right at the back.
*/
BACKGROUND,
/**
* Second from the back.
*/
LOWER,
/**
* In the middle (default).
*/
MIDDLE,
/**
* Near the top.
*/
UPPER,
/**
* At the absolute top.
*/
TOP
}

View File

@@ -0,0 +1,56 @@
package com.willfp.eco.core.gui.menu;
/**
* The type of menu.
*/
public enum MenuType {
/**
* Normal menu (1x9, 2x9, 3x9, etc).
*/
NORMAL(9, 6),
/**
* Dispenser menu (3x3).
*/
DISPENSER(3, 3);
/**
* The amount of columns.
*/
private final int columns;
/**
* The default amount of rows.
*/
private final int defaultRows;
/**
* Create a new menu type.
*
* @param columns The number of columns.
* @param defaultRows The default number of rows.
*/
MenuType(final int columns,
final int defaultRows) {
this.columns = columns;
this.defaultRows = defaultRows;
}
/**
* Get the amount of columns.
*
* @return The columns.
*/
public int getColumns() {
return columns;
}
/**
* Get the default amount of rows.
*
* @return The default amount of rows.
*/
public int getDefaultRows() {
return defaultRows;
}
}

View File

@@ -0,0 +1,19 @@
package com.willfp.eco.core.gui.menu;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
/**
* Interface to run on menu open.
*/
@FunctionalInterface
public interface OpenHandler {
/**
* Performs this operation on the given arguments.
*
* @param player The player.
* @param menu The menu.
*/
void handle(@NotNull Player player,
@NotNull Menu menu);
}

View File

@@ -0,0 +1,117 @@
package com.willfp.eco.core.gui.page;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.gui.GUIComponent;
import com.willfp.eco.core.gui.menu.Menu;
import com.willfp.eco.core.gui.menu.MenuBuilder;
import com.willfp.eco.core.gui.slot.Slot;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
/**
* A page is a component representing another menu.
* This allows full component support in pagination.
*/
public final class Page implements GUIComponent {
/**
* The Menu state key for the current page.
*/
public static final String PAGE_KEY = "page";
/**
* The Menu state key for the amount of pages.
*/
public static final String MAX_PAGE_KEY = "max_page";
/**
* The page number.
*/
private final int pageNumber;
/**
* The base menu.
*/
private final Menu page;
/**
* The delegate menu.
*/
private Menu delegate = null;
/**
* The rows for the page to have.
*/
private int rows = 6;
/**
* The columns for the page to have.
*/
private int columns = 9;
/**
* Create a new page.
*
* @param pageNumber The page number.
* @param page The base menu.
*/
public Page(final int pageNumber,
@NotNull final Menu page) {
this.pageNumber = pageNumber;
this.page = page;
}
/**
* Get the current page number.
*
* @return The page number.
*/
public int getPageNumber() {
return this.pageNumber;
}
@Override
public @Nullable Slot getSlotAt(final int row,
final int column,
@NotNull final Player player,
@NotNull final Menu menu) {
if (menu.getPage(player) != pageNumber) {
return null;
}
if (delegate == null) {
delegate = Eco.get().blendMenuState(page, menu);
}
return page.getSlot(row, column, player, delegate);
}
@Override
public void init(final int maxRows,
final int maxColumns) {
this.rows = maxRows;
this.columns = maxColumns;
}
@Override
public int getRows() {
return rows;
}
@Override
public int getColumns() {
return columns;
}
/**
* Create a new page builder.
*
* @param context The context to create the page for.
* @return The page builder.
*/
public static PageBuilder builder(@NotNull final MenuBuilder context) {
return Menu.builder(context.getRows());
}
}

View File

@@ -0,0 +1,92 @@
package com.willfp.eco.core.gui.page;
import com.willfp.eco.core.gui.GUIComponent;
import com.willfp.eco.core.gui.menu.Menu;
import com.willfp.eco.core.gui.menu.MenuLayer;
import com.willfp.eco.core.gui.slot.FillerMask;
import com.willfp.eco.core.gui.slot.Slot;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.function.BiConsumer;
/**
* Builder to create pages.
*/
public interface PageBuilder {
/**
* Get the amount of rows.
*
* @return The amount of rows.
*/
int getRows();
/**
* Get the amount of columns.
*
* @return The amount of columns.
*/
int getColumns();
/**
* Set a slot.
*
* @param row The row.
* @param column The column.
* @param slot The slot.
* @return The builder.
*/
default PageBuilder setSlot(final int row,
final int column,
@NotNull final Slot slot) {
return this.addComponent(row, column, slot);
}
/**
* Add a component.
*
* @param layer The layer.
* @param row The row of the top left corner.
* @param column The column of the top left corner.
* @param component The component.
* @return The builder.
*/
PageBuilder addComponent(@NotNull MenuLayer layer,
int row,
int column,
@NotNull GUIComponent component);
/**
* Add a component.
*
* @param row The row of the top left corner.
* @param column The column of the top left corner.
* @param component The component.
* @return The builder.
*/
default PageBuilder addComponent(final int row,
final int column,
@NotNull final GUIComponent component) {
return this.addComponent(MenuLayer.MIDDLE, row, column, component);
}
/**
* Set the menu mask.
*
* @param mask The mask.
* @return The builder.
*/
default PageBuilder setMask(@NotNull final FillerMask mask) {
return this.addComponent(MenuLayer.BACKGROUND, 1, 1, mask);
}
/**
* Set the action to run on render.
*
* @param action The action.
* @return The builder.
*/
PageBuilder onRender(@NotNull BiConsumer<Player, Menu> action);
}

View File

@@ -0,0 +1,16 @@
package com.willfp.eco.core.gui.page;
import com.willfp.eco.core.gui.menu.MenuEvent;
/**
* Represents a page change.
*
* @param newPage The new page.
* @param oldPage The old page.
*/
public record PageChangeEvent(
int newPage,
int oldPage
) implements MenuEvent {
}

View File

@@ -0,0 +1,126 @@
package com.willfp.eco.core.gui.page;
import com.willfp.eco.core.gui.GUIComponent;
import com.willfp.eco.core.gui.menu.Menu;
import com.willfp.eco.core.gui.slot.Slot;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* A slot loaded in from config.
*/
public final class PageChanger implements GUIComponent {
/**
* The slot to be shown.
*/
private final Slot slot;
/**
* The direction to turn the page.
*/
private final Direction direction;
/**
* Create a new page change slot.
*
* @param itemStack The ItemStack.
* @param direction The direction.
*/
public PageChanger(@NotNull final ItemStack itemStack,
@NotNull final Direction direction) {
this.direction = direction;
slot = Slot.builder(itemStack)
.onLeftClick((event, slot, menu) -> {
Player player = (Player) event.getWhoClicked();
int page = menu.getPage(player);
int newPage = Math.max(
1,
Math.min(
page + direction.getChange(),
menu.getMaxPage(player)
)
);
if (newPage == page) {
return;
}
menu.addState(player, Page.PAGE_KEY, newPage);
menu.callEvent(player, new PageChangeEvent(
newPage,
page
));
})
.build();
}
@Override
public int getRows() {
return 1;
}
@Override
public int getColumns() {
return 1;
}
@Override
public @Nullable Slot getSlotAt(final int row,
final int column,
@NotNull final Player player,
@NotNull final Menu menu) {
int page = menu.getPage(player);
int maxPage = menu.getMaxPage(player);
if (page <= 1 && this.direction == Direction.BACKWARDS) {
return null;
}
if (page >= maxPage - 1 && this.direction == Direction.FORWARDS) {
return null;
}
return slot;
}
/**
* The direction to change the page.
*/
public enum Direction {
/**
* Increment the page by 1.
*/
FORWARDS(1),
/**
* Decrement the page by 1.
*/
BACKWARDS(-1);
/**
* The amount of pages to change by.
*/
private final int change;
/**
* Create a new direction.
*
* @param change The amount of pages to change by.
*/
Direction(final int change) {
this.change = change;
}
/**
* Get the amount of pages to change by.
*
* @return The change.
*/
public int getChange() {
return change;
}
}
}

View File

@@ -0,0 +1,123 @@
package com.willfp.eco.core.gui.slot;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.gui.slot.functional.SlotHandler;
import com.willfp.eco.core.items.Items;
import com.willfp.eco.util.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
/**
* A slot loaded in from config.
*/
public class ConfigSlot extends CustomSlot {
/**
* The config of the slot.
*/
private final Config config;
/**
* Cached handlers, for performance.
*/
private final Map<String, List<CommandToDispatch>> handlers = new HashMap<>();
/**
* Create a new config slot.
*
* @param config The config.
*/
public ConfigSlot(@NotNull final Config config) {
this.config = config;
SlotBuilder builder = Slot.builder(Items.lookup(config.getString("item")));
for (ClickType clickType : ClickType.values()) {
builder.onClick(
clickType,
dispatchCommandHandler(
clickType.name().toLowerCase(Locale.ROOT)
.replace("_", "-")
+ "-click"
)
);
}
init(builder.build());
}
/**
* Create a slot handler for dispatching commands.
*
* @param configKey The config key.
* @return The handler.
*/
private SlotHandler dispatchCommandHandler(@NotNull final String configKey) {
if (!handlers.containsKey(configKey)) {
List<CommandToDispatch> commands = new ArrayList<>();
for (String command : config.getStrings(configKey)) {
if (command.startsWith("console:")) {
commands.add(new CommandToDispatch(
StringUtils.removePrefix("console:", command),
true
));
} else {
commands.add(new CommandToDispatch(
command,
false
));
}
}
handlers.put(configKey, commands);
}
List<CommandToDispatch> toDispatch = handlers.get(configKey);
return (event, slot, menu) -> {
Player player = (Player) event.getWhoClicked();
for (CommandToDispatch dispatch : toDispatch) {
dispatch.dispatch(player);
}
};
}
/**
* Signifies a command to dispatch.
*
* @param command The command.
* @param console If the command should be run as console.
*/
private record CommandToDispatch(
@NotNull String command,
boolean console
) {
/**
* Dispatch command.
*
* @param player The player.
*/
void dispatch(@NotNull final Player player) {
if (console()) {
Bukkit.dispatchCommand(
Bukkit.getConsoleSender(),
command().replace("%player%", player.getName())
);
} else {
Bukkit.dispatchCommand(
player,
command().replace("%player%", player.getName())
);
}
}
}
}

View File

@@ -0,0 +1,94 @@
package com.willfp.eco.core.gui.slot;
import com.willfp.eco.core.gui.menu.Menu;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
* Base class for custom slot implementations.
*/
public abstract class CustomSlot implements Slot {
/**
* The internal slot to delegate to.
*/
private Slot delegate = null;
/**
* Create a new custom slot.
*/
protected CustomSlot() {
}
/**
* Initialize the slot with the delegate.
*
* @param slot The slot to delegate to.
*/
protected void init(@NotNull final Slot slot) {
this.delegate = slot;
}
@Override
public ItemStack getItemStack(@NotNull final Player player) {
if (delegate == null) {
throw new IllegalStateException("Custom Slot was not initialized!");
}
return delegate.getItemStack(player);
}
@Override
public boolean isCaptive(@NotNull final Player player,
@NotNull final Menu menu) {
if (delegate == null) {
throw new IllegalStateException("Custom Slot was not initialized!");
}
return delegate.isCaptive(player, menu);
}
@Override
public boolean isCaptiveFromEmpty() {
if (delegate == null) {
throw new IllegalStateException("Custom Slot was not initialized!");
}
return delegate.isCaptiveFromEmpty();
}
@Override
public final Slot getActionableSlot(@NotNull final Player player,
@NotNull final Menu menu) {
return delegate;
}
@Override
public final int getRows() {
return Slot.super.getRows();
}
@Override
public final int getColumns() {
return Slot.super.getColumns();
}
@Override
public final Slot getSlotAt(int row, int column) {
return Slot.super.getSlotAt(row, column);
}
/**
* Get the delegate slot.
* <p>
* This is not required to add the slot to a menu, but is instead used internally.
*
* @return The slot.
* @deprecated Replaced with {@link Slot#getActionableSlot(Player, Menu)}
*/
@Deprecated(since = "6.43.0", forRemoval = true)
public Slot getDelegate() {
return this.delegate;
}
}

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core.gui.slot; package com.willfp.eco.core.gui.slot;
import com.willfp.eco.core.gui.GUIComponent;
import com.willfp.eco.core.items.builder.ItemStackBuilder; import com.willfp.eco.core.items.builder.ItemStackBuilder;
import com.willfp.eco.core.recipe.parts.EmptyTestableItem; import com.willfp.eco.core.recipe.parts.EmptyTestableItem;
import com.willfp.eco.core.recipe.parts.MaterialTestableItem; import com.willfp.eco.core.recipe.parts.MaterialTestableItem;
@@ -7,6 +8,7 @@ import com.willfp.eco.util.ListUtils;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@@ -26,12 +28,17 @@ import java.util.List;
* "11111111" * "11111111"
* ); * );
*/ */
public class FillerMask { public class FillerMask implements GUIComponent {
/** /**
* Mask. * Mask.
*/ */
private final List<List<Slot>> mask; private final List<List<Slot>> mask;
/**
* Rows.
*/
private final int rows;
/** /**
* Create a new filler mask. * Create a new filler mask.
* *
@@ -71,7 +78,8 @@ public class FillerMask {
throw new IllegalArgumentException("Items cannot be empty!"); throw new IllegalArgumentException("Items cannot be empty!");
} }
mask = ListUtils.create2DList(6, 9); rows = pattern.length;
mask = ListUtils.create2DList(rows, 9);
for (int i = 0; i < items.items().length; i++) { for (int i = 0; i < items.items().length; i++) {
ItemStack itemStack = new ItemStackBuilder(items.items()[i]) ItemStack itemStack = new ItemStackBuilder(items.items()[i])
@@ -82,9 +90,6 @@ public class FillerMask {
for (String patternRow : pattern) { for (String patternRow : pattern) {
int column = 0; int column = 0;
if (patternRow.length() != 9) {
throw new IllegalArgumentException("Invalid amount of columns in pattern!");
}
for (char c : patternRow.toCharArray()) { for (char c : patternRow.toCharArray()) {
if (c == '0') { if (c == '0') {
mask.get(row).set(column, null); mask.get(row).set(column, null);
@@ -107,4 +112,20 @@ public class FillerMask {
public List<List<Slot>> getMask() { public List<List<Slot>> getMask() {
return this.mask; return this.mask;
} }
@Override
public int getRows() {
return rows;
}
@Override
public int getColumns() {
return 9;
}
@Override
public @Nullable Slot getSlotAt(final int row,
final int column) {
return mask.get(row - 1).get(column - 1);
}
} }

View File

@@ -1,6 +1,5 @@
package com.willfp.eco.core.gui.slot; package com.willfp.eco.core.gui.slot;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -9,37 +8,16 @@ import org.jetbrains.annotations.NotNull;
* <p> * <p>
* Useful for backgrounds. * Useful for backgrounds.
*/ */
public class FillerSlot implements Slot { public class FillerSlot extends CustomSlot {
/**
* The ItemStack.
*/
private final ItemStack itemStack;
/** /**
* Create new filler slot. * Create new filler slot.
* *
* @param itemStack The ItemStack. * @param itemStack The ItemStack.
*/ */
public FillerSlot(@NotNull final ItemStack itemStack) { public FillerSlot(@NotNull final ItemStack itemStack) {
this.itemStack = itemStack; init(
} Slot.builder(itemStack)
.build()
@Override );
public ItemStack getItemStack(@NotNull final Player player) {
return itemStack;
}
@Override
public boolean isCaptive() {
return false;
}
/**
* Get the ItemStack.
*
* @return The ItemStack.
*/
public ItemStack getItemStack() {
return this.itemStack;
} }
} }

View File

@@ -8,6 +8,7 @@ import org.bukkit.Material;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
/** /**
@@ -17,6 +18,15 @@ import java.util.List;
* @param items The items. * @param items The items.
*/ */
public record MaskItems(@NotNull TestableItem... items) { public record MaskItems(@NotNull TestableItem... items) {
/**
* Create mask items from materials.
*
* @param materials The materials.
*/
public MaskItems(@NotNull final Material... materials) {
this(Arrays.stream(materials).map(MaterialTestableItem::new).toList().toArray(new TestableItem[0]));
}
/** /**
* Create MaskItems from a list of item names. * Create MaskItems from a list of item names.
* *

View File

@@ -0,0 +1,62 @@
package com.willfp.eco.core.gui.slot;
import com.willfp.eco.core.gui.menu.Menu;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
* Base class for custom slot implementations.
*/
public abstract class ReactiveSlot implements Slot {
/**
* Create a new reactive slot.
*/
protected ReactiveSlot() {
}
/**
* Get the actual slot to be shown.
*
* @param player The player.
* @param menu The menu.
* @return The slot.
*/
@NotNull
public abstract Slot getSlot(@NotNull final Player player,
@NotNull final Menu menu);
@Override
public ItemStack getItemStack(@NotNull final Player player) {
return new ItemStack(Material.STONE);
}
@Override
public boolean isCaptive(@NotNull final Player player,
@NotNull final Menu menu) {
return getSlot(player, menu).isCaptive(player, menu);
}
@Override
public final Slot getActionableSlot(@NotNull final Player player,
@NotNull final Menu menu) {
return getSlot(player, menu);
}
@Override
public final int getRows() {
return Slot.super.getRows();
}
@Override
public final int getColumns() {
return Slot.super.getColumns();
}
@Override
public final Slot getSlotAt(int row, int column) {
return Slot.super.getSlotAt(row, column);
}
}

View File

@@ -1,7 +1,10 @@
package com.willfp.eco.core.gui.slot; package com.willfp.eco.core.gui.slot;
import com.willfp.eco.core.Eco; import com.willfp.eco.core.Eco;
import com.willfp.eco.core.gui.GUIComponent;
import com.willfp.eco.core.gui.menu.Menu;
import com.willfp.eco.core.gui.slot.functional.SlotProvider; import com.willfp.eco.core.gui.slot.functional.SlotProvider;
import com.willfp.eco.core.items.TestableItem;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@@ -11,8 +14,16 @@ import java.util.function.Function;
/** /**
* A slot is an item in a GUI that can handle clicks. * A slot is an item in a GUI that can handle clicks.
* <p>
* While you can create custom Slot implementations directly from this class,
* it's heavily encouraged to extend {@link CustomSlot}, which will abstract
* internal functionality away.
* <p>
* A lot of methods here are marked as default as in 6.43.0 the GUI system
* was overhauled, but to preserve backwards compatibility, the new methods
* had to be marked default, and many old methods became deprecated.
*/ */
public interface Slot { public interface Slot extends GUIComponent {
/** /**
* Get the ItemStack that would be shown to a player. * Get the ItemStack that would be shown to a player.
* *
@@ -24,9 +35,61 @@ public interface Slot {
/** /**
* If the slot is captive. (Can items be placed in it). * If the slot is captive. (Can items be placed in it).
* *
* @param player The player.
* @param menu The menu.
* @return If captive. * @return If captive.
*/ */
boolean isCaptive(); default boolean isCaptive(@NotNull final Player player,
@NotNull final Menu menu) {
return false;
}
/**
* Get the actionable slot to be shown.
* <p>
* This is mostly internal, if you want to implement custom slots you should
* turn to {@link CustomSlot} or {@link ReactiveSlot}, which abstract this
* behaviour away.
* <p>
* **Never** return {@code this} from this method. Always make sure that your
* slots eventually delegate to a slot created by {@link Slot#builder()}.
* <p>
* {@code this} is returned by default for backwards-compatibility.
*
* @param player The player.
* @param menu The menu.
* @return The slot.
*/
default Slot getActionableSlot(@NotNull final Player player,
@NotNull final Menu menu) {
return this;
}
/**
* If the slot is captive from empty.
* If true, a captive item will be returned even if the item is the same as the rendered item.
*
* @return If captive from empty.
*/
default boolean isCaptiveFromEmpty() {
return false;
}
@Override
default int getRows() {
return 1;
}
@Override
default int getColumns() {
return 1;
}
@Override
default Slot getSlotAt(final int row,
final int column) {
return this;
}
/** /**
* Create a builder for an ItemStack. * Create a builder for an ItemStack.
@@ -34,7 +97,7 @@ public interface Slot {
* @return The builder. * @return The builder.
*/ */
static SlotBuilder builder() { static SlotBuilder builder() {
return Eco.getHandler().getGUIFactory().createSlotBuilder((player, menu) -> new ItemStack(Material.AIR)); return Eco.get().createSlotBuilder((player, menu) -> new ItemStack(Material.AIR));
} }
/** /**
@@ -44,7 +107,17 @@ public interface Slot {
* @return The builder. * @return The builder.
*/ */
static SlotBuilder builder(@NotNull final ItemStack itemStack) { static SlotBuilder builder(@NotNull final ItemStack itemStack) {
return Eco.getHandler().getGUIFactory().createSlotBuilder((player, menu) -> itemStack); return Eco.get().createSlotBuilder((player, menu) -> itemStack);
}
/**
* Create a builder for a TestableItem.
*
* @param item The item.
* @return The builder.
*/
static SlotBuilder builder(@NotNull final TestableItem item) {
return Eco.get().createSlotBuilder((player, menu) -> item.getItem());
} }
/** /**
@@ -54,7 +127,7 @@ public interface Slot {
* @return The builder. * @return The builder.
*/ */
static SlotBuilder builder(@NotNull final Function<Player, ItemStack> provider) { static SlotBuilder builder(@NotNull final Function<Player, ItemStack> provider) {
return Eco.getHandler().getGUIFactory().createSlotBuilder((player, menu) -> provider.apply(player)); return Eco.get().createSlotBuilder((player, menu) -> provider.apply(player));
} }
/** /**
@@ -64,6 +137,29 @@ public interface Slot {
* @return The builder. * @return The builder.
*/ */
static SlotBuilder builder(@NotNull final SlotProvider provider) { static SlotBuilder builder(@NotNull final SlotProvider provider) {
return Eco.getHandler().getGUIFactory().createSlotBuilder(provider); return Eco.get().createSlotBuilder(provider);
}
/**
* If the slot is not captive for a player.
*
* @param player The player.
* @return If not captive for the player.
* @deprecated Captivity is now reactive, this method can produce incorrect results.
*/
@Deprecated(since = "6.43.0", forRemoval = true)
default boolean isNotCaptiveFor(@NotNull Player player) {
return false;
}
/**
* If the slot is captive. (Can items be placed in it).
*
* @return If captive.
* @deprecated Captivity is now reactive, this method can produce incorrect results.
*/
@Deprecated(since = "6.43.0", forRemoval = true)
default boolean isCaptive() {
return false;
} }
} }

View File

@@ -3,15 +3,40 @@ package com.willfp.eco.core.gui.slot;
import com.willfp.eco.core.gui.slot.functional.SlotHandler; import com.willfp.eco.core.gui.slot.functional.SlotHandler;
import com.willfp.eco.core.gui.slot.functional.SlotModifier; import com.willfp.eco.core.gui.slot.functional.SlotModifier;
import com.willfp.eco.core.gui.slot.functional.SlotUpdater; import com.willfp.eco.core.gui.slot.functional.SlotUpdater;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Predicate;
/** /**
* Builder to create slots. * Builder to create slots.
*/ */
public interface SlotBuilder { public interface SlotBuilder {
/**
* Set click handler.
*
* @param type The click type.
* @param handler The handler.
* @return The builder.
*/
SlotBuilder onClick(@NotNull ClickType type,
@NotNull SlotHandler handler);
/**
* Set click handler.
*
* @param type The click type.
* @param action The handler.
* @return The builder.
*/
default SlotBuilder onClick(@NotNull final ClickType type,
@NotNull final BiConsumer<InventoryClickEvent, Slot> action) {
return onClick(type, (event, slot, menu) -> action.accept(event, slot));
}
/** /**
* Set click handler. * Set click handler.
* *
@@ -28,7 +53,9 @@ public interface SlotBuilder {
* @param handler The handler. * @param handler The handler.
* @return The builder. * @return The builder.
*/ */
SlotBuilder onLeftClick(@NotNull SlotHandler handler); default SlotBuilder onLeftClick(@NotNull final SlotHandler handler) {
return onClick(ClickType.LEFT, handler);
}
/** /**
* Set click handler. * Set click handler.
@@ -46,7 +73,9 @@ public interface SlotBuilder {
* @param handler The handler. * @param handler The handler.
* @return The builder. * @return The builder.
*/ */
SlotBuilder onRightClick(@NotNull SlotHandler handler); default SlotBuilder onRightClick(@NotNull final SlotHandler handler) {
return onClick(ClickType.RIGHT, handler);
}
/** /**
* Set click handler. * Set click handler.
@@ -64,7 +93,9 @@ public interface SlotBuilder {
* @param handler The handler. * @param handler The handler.
* @return The builder. * @return The builder.
*/ */
SlotBuilder onShiftLeftClick(@NotNull SlotHandler handler); default SlotBuilder onShiftLeftClick(@NotNull final SlotHandler handler) {
return onClick(ClickType.SHIFT_LEFT, handler);
}
/** /**
* Set click handler. * Set click handler.
@@ -82,7 +113,9 @@ public interface SlotBuilder {
* @param handler The handler. * @param handler The handler.
* @return The builder. * @return The builder.
*/ */
SlotBuilder onShiftRightClick(@NotNull SlotHandler handler); default SlotBuilder onShiftRightClick(@NotNull final SlotHandler handler) {
return onClick(ClickType.SHIFT_RIGHT, handler);
}
/** /**
* Set click handler. * Set click handler.
@@ -100,7 +133,49 @@ public interface SlotBuilder {
* @param handler The handler. * @param handler The handler.
* @return The builder. * @return The builder.
*/ */
SlotBuilder onMiddleClick(@NotNull SlotHandler handler); default SlotBuilder onMiddleClick(@NotNull final SlotHandler handler) {
return onClick(ClickType.MIDDLE, handler);
}
/**
* Prevent captive for players that match a predicate.
*
* @param predicate The predicate. Returns true when the slot should not be captive.
* @return The builder.
*/
SlotBuilder notCaptiveFor(@NotNull Predicate<Player> predicate);
/**
* Set the ItemStack updater.
*
* @param updater The updater.
* @return The builder.
*/
SlotBuilder setUpdater(@NotNull SlotUpdater updater);
/**
* Set slot to be a captive slot.
*
* @return The builder.
*/
default SlotBuilder setCaptive() {
return setCaptive(false);
}
/**
* Set slot to be a captive slot.
*
* @param fromEmpty If an item with the same output as the rendered item counts as captive.
* @return The builder.
*/
SlotBuilder setCaptive(boolean fromEmpty);
/**
* Build the slot.
*
* @return The slot.
*/
Slot build();
/** /**
* Modify the ItemStack. * Modify the ItemStack.
@@ -116,26 +191,4 @@ public interface SlotBuilder {
return previous; return previous;
}); });
} }
/**
* Set the ItemStack updater.
*
* @param updater The updater.
* @return The builder.
*/
SlotBuilder setUpdater(@NotNull SlotUpdater updater);
/**
* Set slot to be a captive slot.
*
* @return The builder.
*/
SlotBuilder setCaptive();
/**
* Build the slot.
*
* @return The slot.
*/
Slot build();
} }

View File

@@ -4,6 +4,7 @@ import com.willfp.eco.core.gui.menu.Menu;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/** /**
* Interface to run on slot display. * Interface to run on slot display.
@@ -17,6 +18,7 @@ public interface SlotProvider {
* @param menu The menu. * @param menu The menu.
* @return The ItemStack. * @return The ItemStack.
*/ */
@Nullable
ItemStack provide(@NotNull Player player, ItemStack provide(@NotNull Player player,
@NotNull Menu menu); @NotNull Menu menu);
} }

View File

@@ -4,6 +4,7 @@ import com.willfp.eco.core.gui.menu.Menu;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/** /**
* Interface to run on slot update. * Interface to run on slot update.
@@ -18,6 +19,7 @@ public interface SlotUpdater {
* @param previous The previous ItemStack. * @param previous The previous ItemStack.
* @return The new ItemStack. * @return The new ItemStack.
*/ */
@Nullable
ItemStack update(@NotNull Player player, ItemStack update(@NotNull Player player,
@NotNull Menu menu, @NotNull Menu menu,
@NotNull ItemStack previous); @NotNull ItemStack previous);

View File

@@ -0,0 +1,18 @@
package com.willfp.eco.core.integrations.afk;
import com.willfp.eco.core.integrations.Integration;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
/**
* AFK Integration.
*/
public interface AFKIntegration extends Integration {
/**
* Get if a player is afk.
*
* @param player The player.
* @return If afk.
*/
boolean isAfk(@NotNull Player player);
}

View File

@@ -13,14 +13,15 @@ public final class AFKManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private static final Set<AFKWrapper> REGISTERED = new HashSet<>(); private static final Set<AFKIntegration> REGISTERED = new HashSet<>();
/** /**
* Register a new integration. * Register a new integration.
* *
* @param integration The integration to register. * @param integration The integration to register.
*/ */
public static void register(@NotNull final AFKWrapper integration) { public static void register(@NotNull final AFKIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName()));
REGISTERED.add(integration); REGISTERED.add(integration);
} }
@@ -31,8 +32,8 @@ public final class AFKManager {
* @return If afk. * @return If afk.
*/ */
public static boolean isAfk(@NotNull final Player player) { public static boolean isAfk(@NotNull final Player player) {
for (AFKWrapper afkWrapper : REGISTERED) { for (AFKIntegration integration : REGISTERED) {
if (afkWrapper.isAfk(player)) { if (integration.isAfk(player)) {
return true; return true;
} }
} }

View File

@@ -1,18 +1,11 @@
package com.willfp.eco.core.integrations.afk; package com.willfp.eco.core.integrations.afk;
import com.willfp.eco.core.integrations.Integration;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
/** /**
* Wrapper class for afk integrations. * Wrapper class for afk integrations.
*
* @deprecated Use AFKIntegration instead.
*/ */
public interface AFKWrapper extends Integration { @Deprecated(since = "6.35.0", forRemoval = true)
/** public interface AFKWrapper extends AFKIntegration {
* Get if a player is afk.
*
* @param player The player.
* @return If afk.
*/
boolean isAfk(@NotNull Player player);
} }

View File

@@ -0,0 +1,24 @@
package com.willfp.eco.core.integrations.anticheat;
import com.willfp.eco.core.integrations.Integration;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
/**
* Wrapper class for anticheat integrations.
*/
public interface AnticheatIntegration extends Integration {
/**
* Exempt a player from checks.
*
* @param player The player to exempt.
*/
void exempt(@NotNull Player player);
/**
* Unexempt a player from checks.
*
* @param player The player to unexempt.
*/
void unexempt(@NotNull Player player);
}

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core.integrations.anticheat; package com.willfp.eco.core.integrations.anticheat;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.EcoPlugin;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
@@ -15,19 +16,31 @@ public final class AnticheatManager {
/** /**
* A set of all registered anticheats. * A set of all registered anticheats.
*/ */
private static final Set<AnticheatWrapper> ANTICHEATS = new HashSet<>(); private static final Set<AnticheatIntegration> ANTICHEATS = new HashSet<>();
/** /**
* Register a new anticheat. * Register a new anticheat.
* *
* @param plugin The plugin. * @param plugin The plugin.
* @param anticheat The anticheat to register. * @param anticheat The anticheat to register.
* @deprecated Don't pass instance of eco.
*/ */
@Deprecated(since = "6.35.0", forRemoval = true)
public static void register(@NotNull final EcoPlugin plugin, public static void register(@NotNull final EcoPlugin plugin,
@NotNull final AnticheatWrapper anticheat) { @NotNull final AnticheatIntegration anticheat) {
register(anticheat);
}
/**
* Register a new anticheat.
*
* @param anticheat The anticheat to register.
*/
public static void register(@NotNull final AnticheatIntegration anticheat) {
if (anticheat instanceof Listener) { if (anticheat instanceof Listener) {
plugin.getEventManager().registerListener((Listener) anticheat); Eco.get().getEcoPlugin().getEventManager().registerListener((Listener) anticheat);
} }
ANTICHEATS.removeIf(it -> it.getPluginName().equalsIgnoreCase(anticheat.getPluginName()));
ANTICHEATS.add(anticheat); ANTICHEATS.add(anticheat);
} }

View File

@@ -1,24 +1,11 @@
package com.willfp.eco.core.integrations.anticheat; package com.willfp.eco.core.integrations.anticheat;
import com.willfp.eco.core.integrations.Integration;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
/** /**
* Wrapper class for anticheat integrations. * Wrapper class for anticheat integrations.
*
* @deprecated Use AnticheatIntegration instead.
*/ */
public interface AnticheatWrapper extends Integration { @Deprecated(since = "6.35.0", forRemoval = true)
/** public interface AnticheatWrapper extends AnticheatIntegration {
* Exempt a player from checks.
*
* @param player The player to exempt.
*/
void exempt(@NotNull Player player);
/**
* Unexempt a player from checks.
*
* @param player The player to unexempt.
*/
void unexempt(@NotNull Player player);
} }

View File

@@ -0,0 +1,60 @@
package com.willfp.eco.core.integrations.antigrief;
import com.willfp.eco.core.integrations.Integration;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
/**
* Wrapper class for antigrief integrations.
*/
public interface AntigriefIntegration extends Integration {
/**
* Can player break block.
*
* @param player The player.
* @param block The block.
* @return If player can break block.
*/
boolean canBreakBlock(@NotNull Player player, @NotNull Block block);
/**
* Can player create explosion at location.
*
* @param player The player.
* @param location The location.
* @return If player can create explosion.
*/
boolean canCreateExplosion(@NotNull Player player, @NotNull Location location);
/**
* Can player place block.
*
* @param player The player.
* @param block The block.
* @return If player can place block.
*/
boolean canPlaceBlock(@NotNull Player player, @NotNull Block block);
/**
* Can player injure living entity.
*
* @param player The player.
* @param victim The victim.
* @return If player can injure.
*/
boolean canInjure(@NotNull Player player, @NotNull LivingEntity victim);
/**
* Can player pick up item.
*
* @param player The player.
* @param location The location.
* @return If player can pick up item.
*/
default boolean canPickupItem(@NotNull Player player, @NotNull Location location) {
return true;
}
}

View File

@@ -16,14 +16,15 @@ public final class AntigriefManager {
/** /**
* Registered antigriefs. * Registered antigriefs.
*/ */
private static final Set<AntigriefWrapper> REGISTERED = new HashSet<>(); private static final Set<AntigriefIntegration> REGISTERED = new HashSet<>();
/** /**
* Register a new AntiGrief/Land Management integration. * Register a new AntiGrief/Land Management integration.
* *
* @param antigrief The integration to register. * @param antigrief The integration to register.
*/ */
public static void register(@NotNull final AntigriefWrapper antigrief) { public static void register(@NotNull final AntigriefIntegration antigrief) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(antigrief.getPluginName()));
REGISTERED.add(antigrief); REGISTERED.add(antigrief);
} }
@@ -32,7 +33,7 @@ public final class AntigriefManager {
* *
* @param antigrief The integration to unregister. * @param antigrief The integration to unregister.
*/ */
public static void unregister(@NotNull final AntigriefWrapper antigrief) { public static void unregister(@NotNull final AntigriefIntegration antigrief) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(antigrief.getPluginName())); REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(antigrief.getPluginName()));
REGISTERED.remove(antigrief); REGISTERED.remove(antigrief);
} }
@@ -46,7 +47,7 @@ public final class AntigriefManager {
*/ */
public static boolean canPickupItem(@NotNull final Player player, public static boolean canPickupItem(@NotNull final Player player,
@NotNull final Location location) { @NotNull final Location location) {
return REGISTERED.stream().allMatch(antigriefWrapper -> antigriefWrapper.canPickupItem(player, location)); return REGISTERED.stream().allMatch(antigriefIntegration -> antigriefIntegration.canPickupItem(player, location));
} }
/** /**
@@ -58,7 +59,7 @@ public final class AntigriefManager {
*/ */
public static boolean canBreakBlock(@NotNull final Player player, public static boolean canBreakBlock(@NotNull final Player player,
@NotNull final Block block) { @NotNull final Block block) {
return REGISTERED.stream().allMatch(antigriefWrapper -> antigriefWrapper.canBreakBlock(player, block)); return REGISTERED.stream().allMatch(antigriefIntegration -> antigriefIntegration.canBreakBlock(player, block));
} }
/** /**
@@ -70,7 +71,7 @@ public final class AntigriefManager {
*/ */
public static boolean canCreateExplosion(@NotNull final Player player, public static boolean canCreateExplosion(@NotNull final Player player,
@NotNull final Location location) { @NotNull final Location location) {
return REGISTERED.stream().allMatch(antigriefWrapper -> antigriefWrapper.canCreateExplosion(player, location)); return REGISTERED.stream().allMatch(antigriefIntegration -> antigriefIntegration.canCreateExplosion(player, location));
} }
/** /**
@@ -82,7 +83,7 @@ public final class AntigriefManager {
*/ */
public static boolean canPlaceBlock(@NotNull final Player player, public static boolean canPlaceBlock(@NotNull final Player player,
@NotNull final Block block) { @NotNull final Block block) {
return REGISTERED.stream().allMatch(antigriefWrapper -> antigriefWrapper.canPlaceBlock(player, block)); return REGISTERED.stream().allMatch(antigriefIntegration -> antigriefIntegration.canPlaceBlock(player, block));
} }
/** /**
@@ -94,7 +95,7 @@ public final class AntigriefManager {
*/ */
public static boolean canInjure(@NotNull final Player player, public static boolean canInjure(@NotNull final Player player,
@NotNull final LivingEntity victim) { @NotNull final LivingEntity victim) {
return REGISTERED.stream().allMatch(antigriefWrapper -> antigriefWrapper.canInjure(player, victim)); return REGISTERED.stream().allMatch(antigriefIntegration -> antigriefIntegration.canInjure(player, victim));
} }
private AntigriefManager() { private AntigriefManager() {

View File

@@ -1,60 +1,11 @@
package com.willfp.eco.core.integrations.antigrief; package com.willfp.eco.core.integrations.antigrief;
import com.willfp.eco.core.integrations.Integration;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
/** /**
* Wrapper class for antigrief integrations. * Wrapper class for antigrief integrations.
*
* @deprecated Use AntigriefIntegration instead.
*/ */
public interface AntigriefWrapper extends Integration { @Deprecated(since = "6.35.0", forRemoval = true)
/** public interface AntigriefWrapper extends AntigriefIntegration {
* Can player break block.
*
* @param player The player.
* @param block The block.
* @return If player can break block.
*/
boolean canBreakBlock(@NotNull Player player, @NotNull Block block);
/**
* Can player create explosion at location.
*
* @param player The player.
* @param location The location.
* @return If player can create explosion.
*/
boolean canCreateExplosion(@NotNull Player player, @NotNull Location location);
/**
* Can player place block.
*
* @param player The player.
* @param block The block.
* @return If player can place block.
*/
boolean canPlaceBlock(@NotNull Player player, @NotNull Block block);
/**
* Can player injure living entity.
*
* @param player The player.
* @param victim The victim.
* @return If player can injure.
*/
boolean canInjure(@NotNull Player player, @NotNull LivingEntity victim);
/**
* Can player pick up item.
*
* @param player The player.
* @param location The location.
* @return If player can pick up item.
*/
default boolean canPickupItem(@NotNull Player player, @NotNull Location location) {
return true;
}
} }

View File

@@ -0,0 +1,15 @@
package com.willfp.eco.core.integrations.customentities;
import com.willfp.eco.core.integrations.Integration;
/**
* Wrapper class for custom item integrations.
*/
public interface CustomEntitiesIntegration extends Integration {
/**
* Register all the custom entities for a specific plugin into eco.
*
* @see com.willfp.eco.core.entities.Entities
*/
void registerAllEntities();
}

View File

@@ -12,14 +12,15 @@ public final class CustomEntitiesManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private static final Set<CustomEntitiesWrapper> REGISTERED = new HashSet<>(); private static final Set<CustomEntitiesIntegration> REGISTERED = new HashSet<>();
/** /**
* Register a new integration. * Register a new integration.
* *
* @param integration The integration to register. * @param integration The integration to register.
*/ */
public static void register(@NotNull final CustomEntitiesWrapper integration) { public static void register(@NotNull final CustomEntitiesIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName()));
REGISTERED.add(integration); REGISTERED.add(integration);
} }
@@ -29,8 +30,8 @@ public final class CustomEntitiesManager {
* @see com.willfp.eco.core.entities.Entities * @see com.willfp.eco.core.entities.Entities
*/ */
public static void registerAllEntities() { public static void registerAllEntities() {
for (CustomEntitiesWrapper wrapper : REGISTERED) { for (CustomEntitiesIntegration integration : REGISTERED) {
wrapper.registerAllEntities(); integration.registerAllEntities();
} }
} }

View File

@@ -1,15 +1,11 @@
package com.willfp.eco.core.integrations.customentities; package com.willfp.eco.core.integrations.customentities;
import com.willfp.eco.core.integrations.Integration;
/** /**
* Wrapper class for custom item integrations. * Wrapper class for custom item integrations.
*
* @deprecated Use CustomEntitiesIntegration instead.
*/ */
public interface CustomEntitiesWrapper extends Integration { @Deprecated(since = "6.35.0", forRemoval = true)
/** public interface CustomEntitiesWrapper extends CustomEntitiesIntegration {
* Register all the custom entities for a specific plugin into eco.
*
* @see com.willfp.eco.core.entities.Entities
*/
void registerAllEntities();
} }

View File

@@ -0,0 +1,24 @@
package com.willfp.eco.core.integrations.customitems;
import com.willfp.eco.core.integrations.Integration;
/**
* Wrapper class for custom item integrations.
*/
public interface CustomItemsIntegration extends Integration {
/**
* Register all the custom items for a specific plugin into eco.
*
* @see com.willfp.eco.core.items.Items
*/
default void registerAllItems() {
// Override when needed.
}
/**
* Register {@link com.willfp.eco.core.items.provider.ItemProvider}s.
*/
default void registerProvider() {
// Override when needed.
}
}

View File

@@ -12,14 +12,15 @@ public final class CustomItemsManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private static final Set<CustomItemsWrapper> REGISTERED = new HashSet<>(); private static final Set<CustomItemsIntegration> REGISTERED = new HashSet<>();
/** /**
* Register a new integration. * Register a new integration.
* *
* @param integration The integration to register. * @param integration The integration to register.
*/ */
public static void register(@NotNull final CustomItemsWrapper integration) { public static void register(@NotNull final CustomItemsIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName()));
REGISTERED.add(integration); REGISTERED.add(integration);
} }
@@ -29,8 +30,19 @@ public final class CustomItemsManager {
* @see com.willfp.eco.core.items.Items * @see com.willfp.eco.core.items.Items
*/ */
public static void registerAllItems() { public static void registerAllItems() {
for (CustomItemsWrapper customItemsWrapper : REGISTERED) { for (CustomItemsIntegration customItemsIntegration : REGISTERED) {
customItemsWrapper.registerAllItems(); customItemsIntegration.registerAllItems();
}
}
/**
* Register all the custom items for a specific plugin into eco.
*
* @see com.willfp.eco.core.items.Items
*/
public static void registerProviders() {
for (CustomItemsIntegration customItemsIntegration : REGISTERED) {
customItemsIntegration.registerProvider();
} }
} }

View File

@@ -1,15 +1,11 @@
package com.willfp.eco.core.integrations.customitems; package com.willfp.eco.core.integrations.customitems;
import com.willfp.eco.core.integrations.Integration;
/** /**
* Wrapper class for custom item integrations. * Wrapper class for custom item integrations.
*
* @deprecated Use CustomItemsIntegration instead.
*/ */
public interface CustomItemsWrapper extends Integration { @Deprecated(since = "6.35.0", forRemoval = true)
/** public interface CustomItemsWrapper extends CustomItemsIntegration {
* Register all the custom items for a specific plugin into eco.
*
* @see com.willfp.eco.core.items.Items
*/
void registerAllItems();
} }

View File

@@ -0,0 +1,125 @@
package com.willfp.eco.core.integrations.economy;
import com.willfp.eco.core.integrations.Integration;
import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull;
import java.math.BigDecimal;
/**
* Wrapper class for economy integrations.
* <p>
* If you're adding your economy to be supported in eco,
* it's recommended to override the {@link BigDecimal} methods
* as opposed to the {@code double} methods.
* <p>
* <strong>You must override at least one of all methods</strong>,
* i.e. one {@code hasAmount}, one {@code giveMoney}, etc.,
* otherwise your integration will cause {@link StackOverflowError}.
* <p>
* All methods are marked as default to preserve compatibility with
* integrations made before 6.43.0.
*/
@SuppressWarnings("DeprecatedIsStillUsed")
public interface EconomyIntegration extends Integration {
/**
* Get if a player has a certain amount.
*
* @param player The player.
* @param amount The amount.
* @return If the player has the amount.
* @deprecated Use {@link BigDecimal} methods instead.
*/
@Deprecated(since = "6.43.0")
default boolean hasAmount(@NotNull OfflinePlayer player,
double amount) {
return hasAmount(player, BigDecimal.valueOf(amount));
}
/**
* Get if a player has a certain amount.
*
* @param player The player.
* @param amount The amount
* @return If the player has the amount.
*/
default boolean hasAmount(@NotNull OfflinePlayer player,
@NotNull BigDecimal amount) {
return hasAmount(player, amount.doubleValue());
}
/**
* Give money to a player.
*
* @param player The player.
* @param amount The amount to give.
* @return If the transaction was a success.
* @deprecated Use {@link BigDecimal} methods instead.
*/
@Deprecated(since = "6.43.0")
default boolean giveMoney(@NotNull OfflinePlayer player,
double amount) {
return giveMoney(player, BigDecimal.valueOf(amount));
}
/**
* Give money to a player.
*
* @param player The player.
* @param amount The amount to give.
* @return If the transaction was a success.
*/
default boolean giveMoney(@NotNull OfflinePlayer player,
@NotNull BigDecimal amount) {
return giveMoney(player, amount.doubleValue());
}
/**
* Remove money from a player.
*
* @param player The player.
* @param amount The amount to remove.
* @return If the transaction was a success.
* @deprecated Use {@link BigDecimal} methods instead.
*/
@Deprecated(since = "6.43.0")
default boolean removeMoney(@NotNull OfflinePlayer player,
double amount) {
return removeMoney(player, BigDecimal.valueOf(amount));
}
/**
* Remove money from a player.
*
* @param player The player.
* @param amount The amount to remove.
* @return If the transaction was a success.
*/
default boolean removeMoney(@NotNull OfflinePlayer player,
@NotNull BigDecimal amount) {
return removeMoney(player, amount.doubleValue());
}
/**
* Get the balance of a player.
*
* @param player The player.
* @return The balance.
* @deprecated Use {@link BigDecimal} methods instead.
*/
@Deprecated(since = "6.43.0")
default double getBalance(@NotNull OfflinePlayer player) {
return getExactBalance(player).doubleValue();
}
/**
* Get the balance of a player.
*
* @param player The player.
* @return The balance.
*/
default BigDecimal getExactBalance(@NotNull OfflinePlayer player) {
return BigDecimal.valueOf(getBalance(player));
}
}

View File

@@ -3,6 +3,7 @@ package com.willfp.eco.core.integrations.economy;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.math.BigDecimal;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@@ -13,14 +14,15 @@ public final class EconomyManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private static final Set<EconomyWrapper> REGISTERED = new HashSet<>(); private static final Set<EconomyIntegration> REGISTERED = new HashSet<>();
/** /**
* Register a new integration. * Register a new integration.
* *
* @param integration The integration to register. * @param integration The integration to register.
*/ */
public static void register(@NotNull final EconomyWrapper integration) { public static void register(@NotNull final EconomyIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName()));
REGISTERED.add(integration); REGISTERED.add(integration);
} }
@@ -42,8 +44,20 @@ public final class EconomyManager {
*/ */
public static boolean hasAmount(@NotNull final OfflinePlayer player, public static boolean hasAmount(@NotNull final OfflinePlayer player,
final double amount) { final double amount) {
for (EconomyWrapper wrapper : REGISTERED) { return hasAmount(player, BigDecimal.valueOf(amount));
return wrapper.hasAmount(player, amount); }
/**
* Get if a player has a certain amount.
*
* @param player The player.
* @param amount The amount.
* @return If the player has the amount.
*/
public static boolean hasAmount(@NotNull final OfflinePlayer player,
final BigDecimal amount) {
for (EconomyIntegration integration : REGISTERED) {
return integration.hasAmount(player, amount);
} }
return false; return false;
@@ -58,8 +72,20 @@ public final class EconomyManager {
*/ */
public static boolean giveMoney(@NotNull final OfflinePlayer player, public static boolean giveMoney(@NotNull final OfflinePlayer player,
final double amount) { final double amount) {
for (EconomyWrapper wrapper : REGISTERED) { return giveMoney(player, BigDecimal.valueOf(amount));
return wrapper.giveMoney(player, amount); }
/**
* Give money to a player.
*
* @param player The player.
* @param amount The amount to give.
* @return If the transaction was a success.
*/
public static boolean giveMoney(@NotNull final OfflinePlayer player,
@NotNull final BigDecimal amount) {
for (EconomyIntegration integration : REGISTERED) {
return integration.giveMoney(player, amount);
} }
return false; return false;
@@ -74,8 +100,20 @@ public final class EconomyManager {
*/ */
public static boolean removeMoney(@NotNull final OfflinePlayer player, public static boolean removeMoney(@NotNull final OfflinePlayer player,
final double amount) { final double amount) {
for (EconomyWrapper wrapper : REGISTERED) { return removeMoney(player, BigDecimal.valueOf(amount));
return wrapper.removeMoney(player, amount); }
/**
* Remove money from a player.
*
* @param player The player.
* @param amount The amount to remove.
* @return If the transaction was a success.
*/
public static boolean removeMoney(@NotNull final OfflinePlayer player,
@NotNull final BigDecimal amount) {
for (EconomyIntegration integration : REGISTERED) {
return integration.removeMoney(player, amount);
} }
return false; return false;
@@ -88,11 +126,21 @@ public final class EconomyManager {
* @return The balance. * @return The balance.
*/ */
public static double getBalance(@NotNull final OfflinePlayer player) { public static double getBalance(@NotNull final OfflinePlayer player) {
for (EconomyWrapper wrapper : REGISTERED) { return getExactBalance(player).doubleValue();
return wrapper.getBalance(player); }
/**
* Get the balance of a player.
*
* @param player The player.
* @return The balance.
*/
public static BigDecimal getExactBalance(@NotNull final OfflinePlayer player) {
for (EconomyIntegration integration : REGISTERED) {
return integration.getExactBalance(player);
} }
return 0; return BigDecimal.ZERO;
} }
private EconomyManager() { private EconomyManager() {

View File

@@ -1,48 +1,11 @@
package com.willfp.eco.core.integrations.economy; package com.willfp.eco.core.integrations.economy;
import com.willfp.eco.core.integrations.Integration;
import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull;
/** /**
* Wrapper class for economy integrations. * Wrapper class for economy integrations.
*
* @deprecated Use EconomyIntegration instead.
*/ */
public interface EconomyWrapper extends Integration { @Deprecated(since = "6.35.0", forRemoval = true)
/** public interface EconomyWrapper extends EconomyIntegration {
* Get if a player has a certain amount.
*
* @param player The player.
* @param amount The amount.
* @return If the player has the amount.
*/
boolean hasAmount(@NotNull OfflinePlayer player,
double amount);
/**
* Give money to a player.
*
* @param player The player.
* @param amount The amount to give.
* @return If the transaction was a success.
*/
boolean giveMoney(@NotNull OfflinePlayer player,
double amount);
/**
* Remove money from a player.
*
* @param player The player.
* @param amount The amount to remove.
* @return If the transaction was a success.
*/
boolean removeMoney(@NotNull OfflinePlayer player,
double amount);
/**
* Get the balance of a player.
*
* @param player The player.
* @return The balance.
*/
double getBalance(@NotNull OfflinePlayer player);
} }

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