Compare commits

..

238 Commits

Author SHA1 Message Date
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
237 changed files with 5771 additions and 1942 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/")
@@ -82,9 +77,16 @@ allprojects {
// LibsDisguises // LibsDisguises
maven("https://repo.md-5.net/content/groups/public/") maven("https://repo.md-5.net/content/groups/public/")
// FabledSkyblock
maven("https://repo.songoda.com/repository/public/")
} }
dependencies { dependencies {
// 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 // 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") compileOnly("com.google.guava:guava:31.1-jre")
@@ -101,9 +103,8 @@ allprojects {
implementation("net.kyori:adventure-text-serializer-legacy:4.10.1") implementation("net.kyori:adventure-text-serializer-legacy:4.10.1")
// Other // Other
implementation("com.github.ben-manes.caffeine:caffeine:3.0.6") implementation("com.github.ben-manes.caffeine:caffeine:3.1.0")
implementation("org.apache.maven:maven-artifact:3.8.4") implementation("org.apache.maven:maven-artifact:3.8.5")
implementation(kotlin("stdlib", version = "1.6.10"))
} }
tasks.withType<JavaCompile> { tasks.withType<JavaCompile> {
@@ -131,8 +132,6 @@ allprojects {
kotlinOptions { kotlinOptions {
jvmTarget = "17" jvmTarget = "17"
} }
targetCompatibility = "17"
sourceCompatibility = "17"
} }
shadowJar { shadowJar {
@@ -155,6 +154,13 @@ allprojects {
relocate("google.protobuf", "com.willfp.eco.libs.protobuf") // Still don't know relocate("google.protobuf", "com.willfp.eco.libs.protobuf") // Still don't know
relocate("com.zaxxer.hikari", "com.willfp.eco.libs.hikari") relocate("com.zaxxer.hikari", "com.willfp.eco.libs.hikari")
//relocate("com.mysql", "com.willfp.eco.libs.mysql") //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
/* /*
Kotlin and caffeine are not shaded so that they can be accessed directly by eco plugins. Kotlin and caffeine are not shaded so that they can be accessed directly by eco plugins.

View File

@@ -304,6 +304,11 @@ 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.proxyFactory = this.proxyPackage.equalsIgnoreCase("") ? null : Eco.getHandler().createProxyFactory(this);
this.logger = Eco.getHandler().createLogger(this);
this.getLogger().info("Initializing " + this.getColor() + this.getName());
this.scheduler = Eco.getHandler().createScheduler(this); this.scheduler = Eco.getHandler().createScheduler(this);
this.eventManager = Eco.getHandler().createEventManager(this); this.eventManager = Eco.getHandler().createEventManager(this);
this.namespacedKeyFactory = Eco.getHandler().createNamespacedKeyFactory(this); this.namespacedKeyFactory = Eco.getHandler().createNamespacedKeyFactory(this);
@@ -311,8 +316,6 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
this.runnableFactory = Eco.getHandler().createRunnableFactory(this); this.runnableFactory = Eco.getHandler().createRunnableFactory(this);
this.extensionLoader = Eco.getHandler().createExtensionLoader(this); this.extensionLoader = Eco.getHandler().createExtensionLoader(this);
this.configHandler = Eco.getHandler().createConfigHandler(this); this.configHandler = Eco.getHandler().createConfigHandler(this);
this.logger = Eco.getHandler().createLogger(this);
this.proxyFactory = this.proxyPackage.equalsIgnoreCase("") ? null : Eco.getHandler().createProxyFactory(this);
this.langYml = this.createLangYml(); this.langYml = this.createLangYml();
this.configYml = this.createConfigYml(); this.configYml = this.createConfigYml();
@@ -347,7 +350,7 @@ 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.getHandler().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);
@@ -374,12 +377,12 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
PlaceholderManager.addIntegration(Eco.getHandler().createPAPIIntegration(this)); PlaceholderManager.addIntegration(Eco.getHandler().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()));

View File

@@ -2,6 +2,7 @@ package com.willfp.eco.core;
import com.willfp.eco.core.config.updating.ConfigHandler; import com.willfp.eco.core.config.updating.ConfigHandler;
import com.willfp.eco.core.config.wrapper.ConfigFactory; import com.willfp.eco.core.config.wrapper.ConfigFactory;
import com.willfp.eco.core.data.ExtendedPersistentDataContainer;
import com.willfp.eco.core.data.ProfileHandler; import com.willfp.eco.core.data.ProfileHandler;
import com.willfp.eco.core.data.keys.KeyRegistry; import com.willfp.eco.core.data.keys.KeyRegistry;
import com.willfp.eco.core.drops.DropQueueFactory; import com.willfp.eco.core.drops.DropQueueFactory;
@@ -14,6 +15,7 @@ import com.willfp.eco.core.factory.RunnableFactory;
import com.willfp.eco.core.fast.FastItemStack; import com.willfp.eco.core.fast.FastItemStack;
import com.willfp.eco.core.gui.GUIFactory; import com.willfp.eco.core.gui.GUIFactory;
import com.willfp.eco.core.integrations.placeholder.PlaceholderIntegration; import com.willfp.eco.core.integrations.placeholder.PlaceholderIntegration;
import com.willfp.eco.core.items.SNBTHandler;
import com.willfp.eco.core.proxy.Cleaner; import com.willfp.eco.core.proxy.Cleaner;
import com.willfp.eco.core.proxy.ProxyFactory; import com.willfp.eco.core.proxy.ProxyFactory;
import com.willfp.eco.core.scheduling.Scheduler; import com.willfp.eco.core.scheduling.Scheduler;
@@ -23,6 +25,7 @@ import org.bukkit.NamespacedKey;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Mob; import org.bukkit.entity.Mob;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
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 org.jetbrains.annotations.Nullable;
@@ -280,6 +283,30 @@ public interface Handler {
* @param <T> The mob type. * @param <T> The mob type.
* @return The controlled entity. * @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 @NotNull
<T extends Mob> EntityController<T> createEntityController(@NotNull T mob); ExtendedPersistentDataContainer adaptPdc(@NotNull PersistentDataContainer container);
/**
* Create new PDC.
*
* @return The container.
*/
@NotNull
PersistentDataContainer newPdc();
/**
* Get SNBT handler.
*
* @return The SNBT handler.
*/
@NotNull
SNBTHandler getSNBTHandler();
} }

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)"
); );
@@ -41,11 +41,19 @@ public class Prerequisite {
"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+"
); );

View File

@@ -167,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
); );
@@ -182,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;
} }

View File

@@ -3,8 +3,9 @@ package com.willfp.eco.core.config.interfaces;
import com.willfp.eco.core.config.BuildableConfig; 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.ConfigurationSection;
@@ -14,6 +15,7 @@ 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.HashMap;
import java.util.List; import java.util.List;
@@ -77,7 +79,6 @@ public interface Config extends Cloneable, PlaceholderInjectable {
/** /**
* 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.
@@ -87,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.
@@ -159,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.
@@ -471,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);
} }
/** /**
@@ -539,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();
} }

View File

@@ -2,7 +2,7 @@ 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;
@@ -145,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

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.getHandler().adaptPdc(base);
}
/**
* Create a new extended container.
*
* @return The extended container.
*/
static ExtendedPersistentDataContainer create() {
return extend(Eco.getHandler().newPdc());
}
}

View File

@@ -68,7 +68,7 @@ public interface ProfileHandler {
* @param async If the saving should be done asynchronously. * @param async If the saving should be done asynchronously.
* @deprecated async is now handled automatically depending on implementation. * @deprecated async is now handled automatically depending on implementation.
*/ */
@Deprecated @Deprecated(forRemoval = true)
default void saveAll(boolean async) { default void saveAll(boolean async) {
saveAll(); saveAll();
} }
@@ -77,8 +77,13 @@ public interface ProfileHandler {
* Save all player data. * Save all player data.
* <p> * <p>
* Can run async if using MySQL. * Can run async if using MySQL.
*
* @deprecated Never used.
*/ */
void saveAll(); @Deprecated(since = "6.36.0", forRemoval = true)
default void saveAll() {
// Do nothing.
}
/** /**
* Commit all changes to the file. * Commit all changes to the file.

View File

@@ -28,15 +28,6 @@ public interface KeyRegistry {
*/ */
Set<PersistentDataKey<?>> getRegisteredKeys(); 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. * Get persistent data key from namespaced key.
* *
@@ -45,19 +36,4 @@ public interface KeyRegistry {
*/ */
@Nullable @Nullable
PersistentDataKey<?> getKeyFrom(@NotNull NamespacedKey namespacedKey); PersistentDataKey<?> getKeyFrom(@NotNull NamespacedKey namespacedKey);
/**
* Locations for key categorization.
*/
enum KeyCategory {
/**
* Player keys.
*/
PLAYER,
/**
* Server keys.
*/
SERVER
}
} }

View File

@@ -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;
} }

View File

@@ -38,6 +38,11 @@ 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");
/** /**
* The class of the type. * The class of the type.
*/ */
@@ -52,7 +57,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;
} }
@@ -72,7 +80,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);

View File

@@ -113,52 +113,6 @@ public final class Display {
handler.registerDisplayModule(module); handler.registerDisplayModule(module);
} }
/**
* Initialize the display system.
*
* @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;
}
/**
* 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. * Set the display handler.
* <p> * <p>

View File

@@ -14,7 +14,7 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
/** /**
* The priority of the module. * The priority of the module.
*/ */
private final DisplayPriority priority; private final int weight;
/** /**
* Create a new display module. * Create a new display module.
@@ -25,7 +25,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); super(plugin);
this.priority = priority; this.weight = priority.getWeight();
}
/**
* 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) {
super(plugin);
this.weight = weight;
} }
/** /**
@@ -52,6 +64,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.
* *
@@ -84,8 +111,25 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
* 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;
} }
} }

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

@@ -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.
* *
@@ -45,17 +48,54 @@ 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); 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 +104,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 +118,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 +162,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 +196,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();
/** /**

View File

@@ -11,6 +11,7 @@ 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; import java.util.Set;
/** /**
@@ -59,6 +60,53 @@ public interface Menu {
*/ */
List<ItemStack> getCaptiveItems(@NotNull Player player); List<ItemStack> getCaptiveItems(@NotNull Player player);
/**
* 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);
/** /**
* Write data. * Write data.
* *
@@ -68,7 +116,9 @@ 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.
*/ */
@Deprecated(since = "6.35.0", forRemoval = true)
<T, Z> void writeData(@NotNull Player player, <T, Z> void writeData(@NotNull Player player,
@NotNull NamespacedKey key, @NotNull NamespacedKey key,
@NotNull PersistentDataType<T, Z> type, @NotNull PersistentDataType<T, Z> type,
@@ -83,7 +133,9 @@ 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.
*/ */
@Deprecated(since = "6.35.0", forRemoval = true)
@Nullable <T, Z> T readData(@NotNull Player player, @Nullable <T, Z> T readData(@NotNull Player player,
@NotNull NamespacedKey key, @NotNull NamespacedKey key,
@NotNull PersistentDataType<T, Z> type); @NotNull PersistentDataType<T, Z> type);
@@ -93,7 +145,9 @@ public interface Menu {
* *
* @param player The player. * @param player The player.
* @return The keys. * @return The keys.
* @deprecated Use getState instead.
*/ */
@Deprecated(since = "6.35.0", forRemoval = true)
Set<NamespacedKey> getKeys(@NotNull Player player); Set<NamespacedKey> getKeys(@NotNull Player player);
/** /**

View File

@@ -2,9 +2,11 @@ package com.willfp.eco.core.gui.menu;
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;
/** /**
@@ -66,6 +68,22 @@ public interface MenuBuilder {
*/ */
MenuBuilder onClose(@NotNull CloseHandler action); MenuBuilder onClose(@NotNull CloseHandler action);
/**
* Set the menu open handler.
*
* @param action The handler.
* @return The builder.
*/
MenuBuilder onOpen(@NotNull OpenHandler action);
/**
* Set the action to run on render.
*
* @param action The action.
* @return The builder.
*/
MenuBuilder onRender(@NotNull BiConsumer<Player, Menu> action);
/** /**
* Build the menu. * Build the menu.
* *

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

@@ -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

@@ -28,6 +28,26 @@ public interface Slot {
*/ */
boolean isCaptive(); boolean isCaptive();
/**
* If the slot is not captive for a player.
*
* @param player The player.
* @return If not captive for the player.
*/
default boolean isNotCaptiveFor(@NotNull Player player) {
return false;
}
/**
* 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;
}
/** /**
* Create a builder for an ItemStack. * Create a builder for an ItemStack.
* *

View File

@@ -3,10 +3,12 @@ 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.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.
@@ -102,6 +104,14 @@ public interface SlotBuilder {
*/ */
SlotBuilder onMiddleClick(@NotNull SlotHandler handler); SlotBuilder onMiddleClick(@NotNull SlotHandler 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);
/** /**
* Modify the ItemStack. * Modify the ItemStack.
* *
@@ -130,7 +140,17 @@ public interface SlotBuilder {
* *
* @return The builder. * @return The builder.
*/ */
SlotBuilder setCaptive(); 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. * Build the slot.

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.getHandler().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,8 @@ 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();
} }
} }
@@ -40,8 +41,8 @@ public final class CustomItemsManager {
* @see com.willfp.eco.core.items.Items * @see com.willfp.eco.core.items.Items
*/ */
public static void registerProviders() { public static void registerProviders() {
for (CustomItemsWrapper customItemsWrapper : REGISTERED) { for (CustomItemsIntegration customItemsIntegration : REGISTERED) {
customItemsWrapper.registerProvider(); customItemsIntegration.registerProvider();
} }
} }

View File

@@ -1,24 +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
*/
default void registerAllItems() {
// Override when needed.
}
/**
* Register {@link com.willfp.eco.core.items.provider.ItemProvider}s.
*/
default void registerProvider() {
// Override when needed.
}
} }

View File

@@ -0,0 +1,60 @@
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.
*/
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.
*/
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);
/**
* 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,8 @@ 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) { for (EconomyIntegration integration : REGISTERED) {
return wrapper.hasAmount(player, amount); return integration.hasAmount(player, amount);
} }
return false; return false;
@@ -58,8 +60,8 @@ 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) { for (EconomyIntegration integration : REGISTERED) {
return wrapper.giveMoney(player, amount); return integration.giveMoney(player, amount);
} }
return false; return false;
@@ -74,8 +76,8 @@ 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) { for (EconomyIntegration integration : REGISTERED) {
return wrapper.removeMoney(player, amount); return integration.removeMoney(player, amount);
} }
return false; return false;
@@ -88,13 +90,27 @@ 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) { for (EconomyIntegration integration : REGISTERED) {
return wrapper.getBalance(player); return integration.getBalance(player);
} }
return 0; return 0;
} }
/**
* 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 BigDecimal.ZERO;
}
private EconomyManager() { private EconomyManager() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
} }

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);
} }

View File

@@ -0,0 +1,22 @@
package com.willfp.eco.core.integrations.hologram;
import com.willfp.eco.core.integrations.Integration;
import org.bukkit.Location;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* Wrapper class for hologram integrations.
*/
public interface HologramIntegration extends Integration {
/**
* Create hologram.
*
* @param location The location.
* @param contents The contents for the hologram.
* @return The hologram.
*/
Hologram createHologram(@NotNull Location location,
@NotNull List<String> contents);
}

View File

@@ -14,14 +14,15 @@ public final class HologramManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private static final Set<HologramWrapper> REGISTERED = new HashSet<>(); private static final Set<HologramIntegration> 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 HologramWrapper integration) { public static void register(@NotNull final HologramIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName()));
REGISTERED.add(integration); REGISTERED.add(integration);
} }
@@ -34,8 +35,8 @@ public final class HologramManager {
*/ */
public static Hologram createHologram(@NotNull final Location location, public static Hologram createHologram(@NotNull final Location location,
@NotNull final List<String> contents) { @NotNull final List<String> contents) {
for (HologramWrapper wrapper : REGISTERED) { for (HologramIntegration integration : REGISTERED) {
return wrapper.createHologram(location, contents); return integration.createHologram(location, contents);
} }
return new DummyHologram(); return new DummyHologram();

View File

@@ -1,22 +1,11 @@
package com.willfp.eco.core.integrations.hologram; package com.willfp.eco.core.integrations.hologram;
import com.willfp.eco.core.integrations.Integration;
import org.bukkit.Location;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/** /**
* Wrapper class for hologram integrations. * Wrapper class for hologram integrations.
*
* @deprecated Use HologramIntegration instead.
*/ */
public interface HologramWrapper extends Integration { @Deprecated(since = "6.35.0", forRemoval = true)
/** public interface HologramWrapper extends HologramIntegration {
* Create hologram.
*
* @param location The location.
* @param contents The contents for the hologram.
* @return The hologram.
*/
Hologram createHologram(@NotNull Location location,
@NotNull List<String> contents);
} }

View File

@@ -0,0 +1,27 @@
package com.willfp.eco.core.integrations.mcmmo;
import com.willfp.eco.core.integrations.Integration;
import org.bukkit.block.Block;
import org.bukkit.event.Event;
import org.jetbrains.annotations.NotNull;
/**
* Wrapper class for mcmmo integrations.
*/
public interface McmmoIntegration extends Integration {
/**
* Get bonus drop count of block.
*
* @param block The block.
* @return The drop multiplier.
*/
int getBonusDropCount(@NotNull Block block);
/**
* Get if event is fake.
*
* @param event The event.
* @return If is fake.
*/
boolean isFake(@NotNull Event event);
}

View File

@@ -14,14 +14,15 @@ public final class McmmoManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private static final Set<McmmoWrapper> REGISTERED = new HashSet<>(); private static final Set<McmmoIntegration> 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 McmmoWrapper integration) { public static void register(@NotNull final McmmoIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName()));
REGISTERED.add(integration); REGISTERED.add(integration);
} }
@@ -32,8 +33,8 @@ public final class McmmoManager {
* @return The bonus drop count. * @return The bonus drop count.
*/ */
public static int getBonusDropCount(@NotNull final Block block) { public static int getBonusDropCount(@NotNull final Block block) {
for (McmmoWrapper mcmmoWrapper : REGISTERED) { for (McmmoIntegration mcmmoIntegration : REGISTERED) {
return mcmmoWrapper.getBonusDropCount(block); return mcmmoIntegration.getBonusDropCount(block);
} }
return 0; return 0;
} }
@@ -45,8 +46,8 @@ public final class McmmoManager {
* @return If the event is fake. * @return If the event is fake.
*/ */
public static boolean isFake(@NotNull final Event event) { public static boolean isFake(@NotNull final Event event) {
for (McmmoWrapper mcmmoWrapper : REGISTERED) { for (McmmoIntegration mcmmoIntegration : REGISTERED) {
return mcmmoWrapper.isFake(event); return mcmmoIntegration.isFake(event);
} }
return false; return false;
} }

View File

@@ -1,27 +1,11 @@
package com.willfp.eco.core.integrations.mcmmo; package com.willfp.eco.core.integrations.mcmmo;
import com.willfp.eco.core.integrations.Integration;
import org.bukkit.block.Block;
import org.bukkit.event.Event;
import org.jetbrains.annotations.NotNull;
/** /**
* Wrapper class for mcmmo integrations. * Wrapper class for mcmmo integrations.
*
* @deprecated Use McmmoIntegration instead.
*/ */
public interface McmmoWrapper extends Integration { @Deprecated(since = "6.35.0", forRemoval = true)
/** public interface McmmoWrapper extends McmmoIntegration {
* Get bonus drop count of block.
*
* @param block The block.
* @return The drop multiplier.
*/
int getBonusDropCount(@NotNull Block block);
/**
* Get if event is fake.
*
* @param event The event.
* @return If is fake.
*/
boolean isFake(@NotNull Event event);
} }

View File

@@ -4,15 +4,21 @@ import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache; import com.github.benmanes.caffeine.cache.LoadingCache;
import com.willfp.eco.core.Eco; import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.placeholder.AdditionalPlayer;
import com.willfp.eco.core.placeholder.InjectablePlaceholder;
import com.willfp.eco.core.placeholder.Placeholder; import com.willfp.eco.core.placeholder.Placeholder;
import com.willfp.eco.core.placeholder.PlaceholderInjectable;
import com.willfp.eco.core.placeholder.PlayerPlaceholder; import com.willfp.eco.core.placeholder.PlayerPlaceholder;
import com.willfp.eco.core.placeholder.PlayerStaticPlaceholder;
import com.willfp.eco.core.placeholder.PlayerlessPlaceholder; import com.willfp.eco.core.placeholder.PlayerlessPlaceholder;
import com.willfp.eco.core.placeholder.StaticPlaceholder; import com.willfp.eco.core.placeholder.StaticPlaceholder;
import com.willfp.eco.util.StringUtils;
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.HashMap;
import java.util.HashSet; import java.util.HashSet;
@@ -20,6 +26,8 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/** /**
* Class to handle placeholder integrations. * Class to handle placeholder integrations.
@@ -43,6 +51,27 @@ public final class PlaceholderManager {
.expireAfterWrite(50, TimeUnit.MILLISECONDS) .expireAfterWrite(50, TimeUnit.MILLISECONDS)
.build(key -> key.entry.getValue(key.player)); .build(key -> key.entry.getValue(key.player));
/**
* Empty injectable object.
*/
private static final PlaceholderInjectable EMPTY_INJECTABLE = new PlaceholderInjectable() {
@Override
public void clearInjectedPlaceholders() {
// Do nothing.
}
@Override
public @NotNull
List<InjectablePlaceholder> getPlaceholderInjections() {
return Collections.emptyList();
}
};
/**
* The default PlaceholderAPI pattern; brought in for compatibility.
*/
private static final Pattern PATTERN = Pattern.compile("[%]([^%]+)[%]");
/** /**
* Register a new placeholder integration. * Register a new placeholder integration.
* *
@@ -144,7 +173,7 @@ public final class PlaceholderManager {
*/ */
public static String translatePlaceholders(@NotNull final String text, public static String translatePlaceholders(@NotNull final String text,
@Nullable final Player player) { @Nullable final Player player) {
return translatePlaceholders(text, player, Collections.emptyList()); return translatePlaceholders(text, player, EMPTY_INJECTABLE);
} }
/** /**
@@ -154,17 +183,75 @@ public final class PlaceholderManager {
* @param player The player to translate the placeholders with respect to. * @param player The player to translate the placeholders with respect to.
* @param statics Extra static placeholders. * @param statics Extra static placeholders.
* @return The text, translated. * @return The text, translated.
* @deprecated Use new static system.
*/ */
@Deprecated(since = "6.35.0", forRemoval = true)
public static String translatePlaceholders(@NotNull final String text, public static String translatePlaceholders(@NotNull final String text,
@Nullable final Player player, @Nullable final Player player,
@NotNull final List<StaticPlaceholder> statics) { @NotNull final List<StaticPlaceholder> statics) {
return translatePlaceholders(text, player, EMPTY_INJECTABLE);
}
/**
* Translate all placeholders with respect to a player.
*
* @param text The text that may contain placeholders to translate.
* @param player The player to translate the placeholders with respect to.
* @param context The injectable context.
* @return The text, translated.
*/
public static String translatePlaceholders(@NotNull final String text,
@Nullable final Player player,
@NotNull final PlaceholderInjectable context) {
return translatePlaceholders(text, player, context, new ArrayList<>());
}
/**
* Translate all placeholders with respect to a player.
*
* @param text The text that may contain placeholders to translate.
* @param player The player to translate the placeholders with respect to.
* @param context The injectable context.
* @param additionalPlayers Additional players to translate placeholders for.
* @return The text, translated.
*/
public static String translatePlaceholders(@NotNull final String text,
@Nullable final Player player,
@NotNull final PlaceholderInjectable context,
@NotNull final Collection<AdditionalPlayer> additionalPlayers) {
String processed = text; String processed = text;
// Prevent running 2 scans if there are no additional players.
if (!additionalPlayers.isEmpty()) {
List<String> found = findPlaceholdersIn(text);
for (AdditionalPlayer additionalPlayer : additionalPlayers) {
for (String placeholder : found) {
String prefix = "%" + additionalPlayer.getIdentifier() + "_";
if (placeholder.startsWith(prefix)) {
processed = processed.replace(
placeholder,
translatePlaceholders(
"%" + StringUtils.removePrefix(prefix, placeholder),
additionalPlayer.getPlayer()
)
);
}
}
}
}
for (PlaceholderIntegration integration : REGISTERED_INTEGRATIONS) { for (PlaceholderIntegration integration : REGISTERED_INTEGRATIONS) {
processed = integration.translate(processed, player); processed = integration.translate(processed, player);
} }
for (StaticPlaceholder placeholder : statics) { for (InjectablePlaceholder injection : context.getPlaceholderInjections()) {
// Do I know this is a bad way of doing this? Yes. // Do I know this is a bad way of doing this? Yes.
processed = processed.replace("%" + placeholder.getIdentifier() + "%", placeholder.getValue()); if (injection instanceof StaticPlaceholder placeholder) {
processed = processed.replace("%" + placeholder.getIdentifier() + "%", placeholder.getValue());
} else if (injection instanceof PlayerStaticPlaceholder placeholder && player != null) {
processed = processed.replace("%" + placeholder.getIdentifier() + "%", placeholder.getValue(player));
}
} }
return processed; return processed;
} }
@@ -176,12 +263,21 @@ public final class PlaceholderManager {
* @return The placeholders. * @return The placeholders.
*/ */
public static List<String> findPlaceholdersIn(@NotNull final String text) { public static List<String> findPlaceholdersIn(@NotNull final String text) {
List<String> found = new ArrayList<>(); Set<String> found = new HashSet<>();
// Mock PAPI for those without it installed
if (REGISTERED_INTEGRATIONS.isEmpty()) {
Matcher matcher = PATTERN.matcher(text);
while (matcher.find()) {
found.add(matcher.group());
}
}
for (PlaceholderIntegration integration : REGISTERED_INTEGRATIONS) { for (PlaceholderIntegration integration : REGISTERED_INTEGRATIONS) {
found.addAll(integration.findPlaceholdersIn(text)); found.addAll(integration.findPlaceholdersIn(text));
} }
return found; return new ArrayList<>(found);
} }
private record EntryWithPlayer(@NotNull PlayerPlaceholder entry, private record EntryWithPlayer(@NotNull PlayerPlaceholder entry,

View File

@@ -0,0 +1,54 @@
package com.willfp.eco.core.integrations.shop;
import com.willfp.eco.core.integrations.Integration;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Wrapper class for shop integrations.
*/
public interface ShopIntegration extends Integration {
/**
* Register eco item provider for shop plugins.
*/
default void registerEcoProvider() {
// Do nothing unless overridden.
}
/**
* Get the sell event adapter.
*
* @return The listener.
*/
@Nullable
default Listener getSellEventAdapter() {
// Do nothing unless overridden.
return null;
}
/**
* Get the price of an item.
*
* @param itemStack The item.
* @return The price.
*/
default double getPrice(@NotNull final ItemStack itemStack) {
// Do nothing unless overridden.
return 0.0;
}
/**
* Get the price of an item.
*
* @param itemStack The item.
* @param player The player.
* @return The price.
*/
default double getPrice(@NotNull final ItemStack itemStack,
@NotNull final Player player) {
return getPrice(itemStack);
}
}

View File

@@ -1,6 +1,12 @@
package com.willfp.eco.core.integrations.shop; package com.willfp.eco.core.integrations.shop;
import com.willfp.eco.core.EcoPlugin;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@@ -12,26 +18,77 @@ public final class ShopManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private static final Set<ShopWrapper> REGISTERED = new HashSet<>(); private static final Set<ShopIntegration> 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 ShopWrapper integration) { public static void register(@NotNull final ShopIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName()));
REGISTERED.add(integration); REGISTERED.add(integration);
} }
/**
* Register the events with eco.
*
* @param plugin Instance of eco.
*/
@ApiStatus.Internal
public static void registerEvents(@NotNull final EcoPlugin plugin) {
for (ShopIntegration integration : REGISTERED) {
Listener listener = integration.getSellEventAdapter();
if (listener != null) {
plugin.getEventManager().registerListener(listener);
}
}
}
/** /**
* Register eco item provider for shop plugins. * Register eco item provider for shop plugins.
*/ */
public static void registerEcoProvider() { public static void registerEcoProvider() {
for (ShopWrapper shopWrapper : REGISTERED) { for (ShopIntegration shopIntegration : REGISTERED) {
shopWrapper.registerEcoProvider(); shopIntegration.registerEcoProvider();
} }
} }
/**
* Get the price of an item.
*
* @param itemStack The item.
* @return The price.
*/
public static double getItemPrice(@Nullable final ItemStack itemStack) {
return getItemPrice(itemStack, null);
}
/**
* Get the price of an item.
*
* @param itemStack The item.
* @param player The player.
* @return The price.
*/
public static double getItemPrice(@Nullable final ItemStack itemStack,
@Nullable final Player player) {
if (itemStack == null) {
return 0.0;
}
for (ShopIntegration shopIntegration : REGISTERED) {
if (player == null) {
return shopIntegration.getPrice(itemStack);
} else {
return shopIntegration.getPrice(itemStack, player);
}
}
return 0.0;
}
private ShopManager() { private ShopManager() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
} }

View File

@@ -0,0 +1,104 @@
package com.willfp.eco.core.integrations.shop;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Unified event for shop plugins to fire in order to have sell multipliers.
*/
public class ShopSellEvent extends PlayerEvent {
/**
* The event handler list.
*/
private static final HandlerList HANDLER_LIST = new HandlerList();
/**
* The sell price.
*/
private double price;
/**
* The item to be sold.
*/
@Nullable
private final ItemStack item;
/**
* Create new shop sell event.
*
* @param who The player.
* @param price The price.
* @param item The item.
*/
public ShopSellEvent(@NotNull final Player who,
final double price,
@Nullable final ItemStack item) {
super(who);
this.price = price;
this.item = item;
}
/**
* Get the price.
*
* @return The price.
*/
public double getPrice() {
return this.price;
}
/**
* Set the price.
*
* @param price The price.
*/
public void setPrice(final double price) {
this.price = price;
}
/**
* Get the item to be sold.
*
* @return The item. Can be null for some plugins, so check hasKnownItem first!
*/
@Nullable
public ItemStack getItem() {
return item;
}
/**
* Get if the item is known. Some shop plugins are lacking this in their event,
* so always check this before getItem(), as getItem() may be null.
*
* @return If the item is known.
*/
public boolean hasKnownItem() {
return item != null;
}
/**
* Bukkit parity.
*
* @return The handlers.
*/
@NotNull
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
/**
* Bukkit parity.
*
* @return The handlers.
*/
@NotNull
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}

View File

@@ -1,13 +1,11 @@
package com.willfp.eco.core.integrations.shop; package com.willfp.eco.core.integrations.shop;
import com.willfp.eco.core.integrations.Integration;
/** /**
* Wrapper class for shop integrations. * Wrapper class for shop integrations.
*
* @deprecated Use ShopIntegration instead.
*/ */
public interface ShopWrapper extends Integration { @Deprecated(since = "6.35.0", forRemoval = true)
/** public interface ShopWrapper extends ShopIntegration {
* Register eco item provider for shop plugins.
*/
void registerEcoProvider();
} }

View File

@@ -48,6 +48,11 @@ public class CustomItem implements TestableItem {
this.test = test; this.test = test;
this.item = item; this.item = item;
/*
This runs the next tick, because it's very likely that the test can't return true
immediately after due to registration order; so eco waits until the item should be
working in order to check.
*/
Eco.getHandler().getEcoPlugin().getScheduler().runLater(() -> { Eco.getHandler().getEcoPlugin().getScheduler().runLater(() -> {
if (!matches(getItem())) { if (!matches(getItem())) {
Bukkit.getLogger().severe("Item with key " + key + " is invalid!"); Bukkit.getLogger().severe("Item with key " + key + " is invalid!");

View File

@@ -2,6 +2,8 @@ package com.willfp.eco.core.items;
import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache; import com.github.benmanes.caffeine.cache.LoadingCache;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.fast.FastItemStack;
import com.willfp.eco.core.items.args.LookupArgParser; import com.willfp.eco.core.items.args.LookupArgParser;
import com.willfp.eco.core.items.provider.ItemProvider; import com.willfp.eco.core.items.provider.ItemProvider;
import com.willfp.eco.core.recipe.parts.EmptyTestableItem; import com.willfp.eco.core.recipe.parts.EmptyTestableItem;
@@ -16,6 +18,7 @@ import org.bukkit.NamespacedKey;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -183,6 +186,10 @@ public final class Items {
*/ */
@NotNull @NotNull
public static TestableItem lookup(@NotNull final String key) { public static TestableItem lookup(@NotNull final String key) {
if (key.startsWith("{")) {
return Eco.getHandler().getSNBTHandler().createTestable(key);
}
return ITEMS_LOOKUP_HANDLER.parseKey(key); return ITEMS_LOOKUP_HANDLER.parseKey(key);
} }
@@ -220,7 +227,10 @@ public final class Items {
if (part == null && PROVIDERS.containsKey(namespace)) { if (part == null && PROVIDERS.containsKey(namespace)) {
ItemProvider provider = PROVIDERS.get(namespace); ItemProvider provider = PROVIDERS.get(namespace);
item = provider.provideForKey(keyID);
String reformattedKey = keyID.replace("__", ":");
item = provider.provideForKey(reformattedKey);
if (item instanceof EmptyTestableItem || item == null) { if (item instanceof EmptyTestableItem || item == null) {
return new EmptyTestableItem(); return new EmptyTestableItem();
} }
@@ -489,6 +499,54 @@ public final class Items {
return to; return to;
} }
/**
* Get the base NBT tag on an item.
*
* @param itemStack The ItemStack.
* @return The base NBT.
*/
@NotNull
public static PersistentDataContainer getBaseNBT(@NotNull final ItemStack itemStack) {
return FastItemStack.wrap(itemStack).getBaseTag();
}
/**
* Set the base NBT tag on an item.
*
* @param itemStack The ItemStack.
* @param container The base NBT tag.
* @return The ItemStack, modified. Not required to use, as this modifies the instance.¬
*/
@NotNull
public static ItemStack setBaseNBT(@NotNull final ItemStack itemStack,
@Nullable final PersistentDataContainer container) {
FastItemStack fis = FastItemStack.wrap(itemStack);
fis.setBaseTag(container);
return fis.unwrap();
}
/**
* Convert item to SNBT.
*
* @param itemStack The item.
* @return The NBT string.
*/
@NotNull
public static String toSNBT(@NotNull final ItemStack itemStack) {
return Eco.getHandler().getSNBTHandler().toSNBT(itemStack);
}
/**
* Get item from SNBT.
*
* @param snbt The NBT string.
* @return The ItemStack, or null if invalid.
*/
@Nullable
public static ItemStack fromSNBT(@NotNull final String snbt) {
return Eco.getHandler().getSNBTHandler().fromSNBT(snbt);
}
private Items() { private Items() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
} }

View File

@@ -0,0 +1,41 @@
package com.willfp.eco.core.items;
import com.willfp.eco.core.Eco;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* API to handle SNBT conversion.
*/
@ApiStatus.Internal
@Eco.HandlerComponent
public interface SNBTHandler {
/**
* 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 createTestable(@NotNull String snbt);
}

View File

@@ -0,0 +1,49 @@
package com.willfp.eco.core.placeholder;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
/**
* An additional player with an identifier to parse placeholders for the player.
*/
public class AdditionalPlayer {
/**
* The player.
*/
private final Player player;
/**
* The identifier.
*/
private final String identifier;
/**
* Create a new additional player.
*
* @param player The player.
* @param identifier The identifier.
*/
public AdditionalPlayer(@NotNull final Player player,
@NotNull final String identifier) {
this.player = player;
this.identifier = identifier;
}
/**
* Get the player.
*
* @return The player.
*/
public Player getPlayer() {
return player;
}
/**
* Get the identifier.
*
* @return The identifier.
*/
public String getIdentifier() {
return identifier;
}
}

View File

@@ -0,0 +1,14 @@
package com.willfp.eco.core.placeholder;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
/**
* Placeholders that can be injected into {@link PlaceholderInjectable} objects.
*/
public sealed interface InjectablePlaceholder extends Placeholder permits PlayerStaticPlaceholder, StaticPlaceholder {
@Override
default EcoPlugin getPlugin() {
return Eco.getHandler().getEcoPlugin();
}
}

View File

@@ -5,7 +5,7 @@ import com.willfp.eco.core.EcoPlugin;
/** /**
* A placeholder represents a string that can hold a value. * A placeholder represents a string that can hold a value.
*/ */
public sealed interface Placeholder permits PlayerPlaceholder, PlayerlessPlaceholder, StaticPlaceholder { public sealed interface Placeholder permits PlayerPlaceholder, PlayerlessPlaceholder, InjectablePlaceholder {
/** /**
* Get the plugin that holds the placeholder. * Get the plugin that holds the placeholder.
* *

View File

@@ -2,6 +2,7 @@ package com.willfp.eco.core.placeholder;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
@@ -22,7 +23,40 @@ public interface PlaceholderInjectable {
* *
* @param placeholders The placeholders. * @param placeholders The placeholders.
*/ */
void injectPlaceholders(@NotNull Iterable<StaticPlaceholder> placeholders); default void injectPlaceholders(@NotNull InjectablePlaceholder... placeholders) {
this.addInjectablePlaceholder(List.of(placeholders));
}
/**
* Inject placeholder.
*
* @param placeholders The placeholders.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
default void injectPlaceholders(@NotNull Iterable<StaticPlaceholder> placeholders) {
List<InjectablePlaceholder> toInject = new ArrayList<>();
for (StaticPlaceholder placeholder : placeholders) {
toInject.add(placeholder);
}
this.addInjectablePlaceholder(toInject);
}
/**
* Inject placeholders.
* <p>
* When implementing a PlaceholderInjectable object, override this method.
*
* @param placeholders The placeholders.
*/
default void addInjectablePlaceholder(@NotNull Iterable<InjectablePlaceholder> placeholders) {
List<StaticPlaceholder> toInject = new ArrayList<>();
for (InjectablePlaceholder placeholder : placeholders) {
if (placeholder instanceof StaticPlaceholder staticPlaceholder) {
toInject.add(staticPlaceholder);
}
}
this.injectPlaceholders(toInject);
}
/** /**
* Clear injected placeholders. * Clear injected placeholders.
@@ -33,6 +67,31 @@ public interface PlaceholderInjectable {
* Get injected placeholders. * Get injected placeholders.
* *
* @return Injected placeholders. * @return Injected placeholders.
* @deprecated Use getPlaceholderInjections.
*/ */
List<StaticPlaceholder> getInjectedPlaceholders(); @Deprecated(since = "6.35.0", forRemoval = true)
@NotNull
default List<StaticPlaceholder> getInjectedPlaceholders() {
List<StaticPlaceholder> found = new ArrayList<>();
for (InjectablePlaceholder placeholder : getPlaceholderInjections()) {
if (placeholder instanceof StaticPlaceholder staticPlaceholder) {
found.add(staticPlaceholder);
}
}
return found;
}
/**
* Get injected placeholders.
* <p>
* Override this method in implementations.
*
* @return Injected placeholders.
*/
@NotNull
default List<InjectablePlaceholder> getPlaceholderInjections() {
return new ArrayList<>(getInjectedPlaceholders());
}
} }

View File

@@ -78,7 +78,7 @@ public final class PlayerPlaceholder implements Placeholder {
if (this == o) { if (this == o) {
return true; return true;
} }
if (!(o instanceof StaticPlaceholder that)) { if (!(o instanceof PlayerPlaceholder that)) {
return false; return false;
} }
return Objects.equals(this.getIdentifier(), that.getIdentifier()) return Objects.equals(this.getIdentifier(), that.getIdentifier())

View File

@@ -0,0 +1,66 @@
package com.willfp.eco.core.placeholder;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
import java.util.function.Function;
/**
* A placeholder that cannot be registered, and exists purely in injection.
*/
public final class PlayerStaticPlaceholder implements InjectablePlaceholder {
/**
* The name of the placeholder.
*/
private final String identifier;
/**
* The function to retrieve the output of the placeholder.
*/
private final Function<Player, String> function;
/**
* Create a new player placeholder.
*
* @param identifier The identifier.
* @param function The function to retrieve the value.
*/
public PlayerStaticPlaceholder(@NotNull final String identifier,
@NotNull final Function<Player, String> function) {
this.identifier = identifier;
this.function = function;
}
/**
* Get the value of the placeholder.
*
* @param player The player.
* @return The value.
*/
public String getValue(@NotNull final Player player) {
return function.apply(player);
}
@Override
public String getIdentifier() {
return this.identifier;
}
@Override
public boolean equals(@Nullable final Object o) {
if (this == o) {
return true;
}
if (!(o instanceof PlayerStaticPlaceholder that)) {
return false;
}
return Objects.equals(this.getIdentifier(), that.getIdentifier());
}
@Override
public int hashCode() {
return Objects.hash(this.getIdentifier());
}
}

View File

@@ -76,7 +76,7 @@ public final class PlayerlessPlaceholder implements Placeholder {
if (this == o) { if (this == o) {
return true; return true;
} }
if (!(o instanceof StaticPlaceholder that)) { if (!(o instanceof PlayerlessPlaceholder that)) {
return false; return false;
} }
return Objects.equals(this.getIdentifier(), that.getIdentifier()) return Objects.equals(this.getIdentifier(), that.getIdentifier())

View File

@@ -1,7 +1,5 @@
package com.willfp.eco.core.placeholder; package com.willfp.eco.core.placeholder;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -11,7 +9,7 @@ import java.util.function.Supplier;
/** /**
* A placeholder that cannot be registered, and exists purely in injection. * A placeholder that cannot be registered, and exists purely in injection.
*/ */
public final class StaticPlaceholder implements Placeholder { public final class StaticPlaceholder implements InjectablePlaceholder {
/** /**
* The name of the placeholder. * The name of the placeholder.
*/ */
@@ -43,11 +41,6 @@ public final class StaticPlaceholder implements Placeholder {
return function.get(); return function.get();
} }
@Override
public EcoPlugin getPlugin() {
return Eco.getHandler().getEcoPlugin();
}
@Override @Override
public String getIdentifier() { public String getIdentifier() {
return this.identifier; return this.identifier;

View File

@@ -20,7 +20,8 @@ public final class ProxyConstants {
public static final List<String> SUPPORTED_VERSIONS = Arrays.asList( public static final List<String> SUPPORTED_VERSIONS = Arrays.asList(
"v1_17_R1", "v1_17_R1",
"v1_18_R1", "v1_18_R1",
"v1_18_R2" "v1_18_R2",
"v1_19_R1"
); );
private ProxyConstants() { private ProxyConstants() {

View File

@@ -96,50 +96,53 @@ public final class ShapedCraftingRecipe extends PluginDependent<EcoPlugin> imple
shapedRecipe.setIngredient(character, parts.get(i).getItem().getType()); shapedRecipe.setIngredient(character, parts.get(i).getItem().getType());
} }
ShapedRecipe displayedRecipe = new ShapedRecipe(this.getDisplayedKey(), this.getOutput()); if (Eco.getHandler().getEcoPlugin().getConfigYml().getBool("displayed-recipes")) {
displayedRecipe.shape("012", "345", "678"); ShapedRecipe displayedRecipe = new ShapedRecipe(this.getDisplayedKey(), this.getOutput());
for (int i = 0; i < 9; i++) { displayedRecipe.shape("012", "345", "678");
if (parts.get(i) instanceof EmptyTestableItem) { for (int i = 0; i < 9; i++) {
continue; if (parts.get(i) instanceof EmptyTestableItem) {
} continue;
char character = String.valueOf(i).toCharArray()[0];
List<TestableItem> items = new ArrayList<>();
if (parts.get(i) instanceof GroupedTestableItems group) {
items.addAll(group.getChildren());
} else {
items.add(parts.get(i));
}
List<ItemStack> displayedItems = new ArrayList<>();
for (TestableItem testableItem : items) {
if (testableItem instanceof TestableStack) {
ItemStack item = testableItem.getItem().clone();
ItemMeta meta = item.getItemMeta();
assert meta != null;
List<String> lore = meta.hasLore() ? meta.getLore() : new ArrayList<>();
assert lore != null;
lore.add("");
String add = Eco.getHandler().getEcoPlugin().getLangYml().getFormattedString("multiple-in-craft");
add = add.replace("%amount%", String.valueOf(item.getAmount()));
lore.add(add);
meta.setLore(lore);
item.setItemMeta(meta);
displayedItems.add(item);
} else {
displayedItems.add(testableItem.getItem());
} }
char character = String.valueOf(i).toCharArray()[0];
List<TestableItem> items = new ArrayList<>();
if (parts.get(i) instanceof GroupedTestableItems group) {
items.addAll(group.getChildren());
} else {
items.add(parts.get(i));
}
List<ItemStack> displayedItems = new ArrayList<>();
for (TestableItem testableItem : items) {
if (testableItem instanceof TestableStack) {
ItemStack item = testableItem.getItem().clone();
ItemMeta meta = item.getItemMeta();
assert meta != null;
List<String> lore = meta.hasLore() ? meta.getLore() : new ArrayList<>();
assert lore != null;
lore.add("");
String add = Eco.getHandler().getEcoPlugin().getLangYml().getFormattedString("multiple-in-craft");
add = add.replace("%amount%", String.valueOf(item.getAmount()));
lore.add(add);
meta.setLore(lore);
item.setItemMeta(meta);
displayedItems.add(item);
} else {
displayedItems.add(testableItem.getItem());
}
}
displayedRecipe.setIngredient(character, new RecipeChoice.ExactChoice(displayedItems));
} }
displayedRecipe.setIngredient(character, new RecipeChoice.ExactChoice(displayedItems)); Bukkit.getServer().addRecipe(displayedRecipe);
} }
Bukkit.getServer().addRecipe(shapedRecipe); Bukkit.getServer().addRecipe(shapedRecipe);
Bukkit.getServer().addRecipe(displayedRecipe);
} }
/** /**

View File

@@ -101,43 +101,46 @@ public final class ShapelessCraftingRecipe extends PluginDependent<EcoPlugin> im
shapelessRecipe.addIngredient(part.getItem().getType()); shapelessRecipe.addIngredient(part.getItem().getType());
} }
ShapelessRecipe displayedRecipe = new ShapelessRecipe(this.getDisplayedKey(), this.getOutput()); if (Eco.getHandler().getEcoPlugin().getConfigYml().getBool("displayed-recipes")) {
for (TestableItem part : parts) { ShapelessRecipe displayedRecipe = new ShapelessRecipe(this.getDisplayedKey(), this.getOutput());
List<TestableItem> items = new ArrayList<>(); for (TestableItem part : parts) {
if (part instanceof GroupedTestableItems group) { List<TestableItem> items = new ArrayList<>();
items.addAll(group.getChildren()); if (part instanceof GroupedTestableItems group) {
} else { items.addAll(group.getChildren());
items.add(part);
}
List<ItemStack> displayedItems = new ArrayList<>();
for (TestableItem testableItem : items) {
if (testableItem instanceof TestableStack) {
ItemStack item = testableItem.getItem().clone();
ItemMeta meta = item.getItemMeta();
assert meta != null;
List<String> lore = meta.hasLore() ? meta.getLore() : new ArrayList<>();
assert lore != null;
lore.add("");
String add = Eco.getHandler().getEcoPlugin().getLangYml().getFormattedString("multiple-in-craft");
add = add.replace("%amount%", String.valueOf(item.getAmount()));
lore.add(add);
meta.setLore(lore);
item.setItemMeta(meta);
displayedItems.add(item);
} else { } else {
displayedItems.add(testableItem.getItem()); items.add(part);
} }
List<ItemStack> displayedItems = new ArrayList<>();
for (TestableItem testableItem : items) {
if (testableItem instanceof TestableStack) {
ItemStack item = testableItem.getItem().clone();
ItemMeta meta = item.getItemMeta();
assert meta != null;
List<String> lore = meta.hasLore() ? meta.getLore() : new ArrayList<>();
assert lore != null;
lore.add("");
String add = Eco.getHandler().getEcoPlugin().getLangYml().getFormattedString("multiple-in-craft");
add = add.replace("%amount%", String.valueOf(item.getAmount()));
lore.add(add);
meta.setLore(lore);
item.setItemMeta(meta);
displayedItems.add(item);
} else {
displayedItems.add(testableItem.getItem());
}
}
displayedRecipe.addIngredient(new RecipeChoice.ExactChoice(displayedItems));
} }
displayedRecipe.addIngredient(new RecipeChoice.ExactChoice(displayedItems)); Bukkit.getServer().addRecipe(displayedRecipe);
} }
Bukkit.getServer().addRecipe(shapelessRecipe); Bukkit.getServer().addRecipe(shapelessRecipe);
Bukkit.getServer().addRecipe(displayedRecipe);
} }
/** /**

View File

@@ -25,13 +25,30 @@ public class Paste {
*/ */
private final String contents; private final String contents;
/**
* The host.
*/
private final String host;
/** /**
* Create a new paste. * Create a new paste.
* *
* @param contents The contents. * @param contents The contents.
*/ */
public Paste(@NotNull final String contents) { public Paste(@NotNull final String contents) {
this(contents, "https://paste.willfp.com");
}
/**
* Create a new paste.
*
* @param contents The contents.
* @param host The host.
*/
public Paste(@NotNull final String contents,
@NotNull final String host) {
this.contents = contents; this.contents = contents;
this.host = host;
} }
/** /**
@@ -47,7 +64,7 @@ public class Paste {
byte[] postData = URLEncoder.encode(contents, StandardCharsets.UTF_8).getBytes(StandardCharsets.UTF_8); byte[] postData = URLEncoder.encode(contents, StandardCharsets.UTF_8).getBytes(StandardCharsets.UTF_8);
int postDataLength = postData.length; int postDataLength = postData.length;
String requestURL = "https://paste.willfp.com/documents"; String requestURL = this.host + "/documents";
URL url = new URL(requestURL); URL url = new URL(requestURL);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setDoOutput(true); conn.setDoOutput(true);
@@ -85,14 +102,26 @@ public class Paste {
* @return The paste. * @return The paste.
*/ */
public static Paste getFromHastebin(@NotNull final String token) { public static Paste getFromHastebin(@NotNull final String token) {
return getFromHastebin(token, "https://paste.willfp.com");
}
/**
* Get paste from hastebin.
*
* @param token The token.
* @param host The host.
* @return The paste.
*/
public static Paste getFromHastebin(@NotNull final String token,
@NotNull final String host) {
try { try {
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();
URL url = new URL("https://paste.willfp.com/raw/" + token); URL url = new URL(host + "/raw/" + token);
HttpURLConnection conn = (HttpURLConnection) url.openConnection(); HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET"); conn.setRequestMethod("GET");
try (var reader = new BufferedReader( try (var reader = new BufferedReader(
new InputStreamReader(conn.getInputStream()))) { new InputStreamReader(conn.getInputStream()))) {
for (String line; (line = reader.readLine()) != null;) { for (String line; (line = reader.readLine()) != null; ) {
result.append(line); result.append(line);
} }
} }

View File

@@ -18,6 +18,11 @@ import java.util.Set;
* Utilities / API methods for blocks. * Utilities / API methods for blocks.
*/ */
public final class BlockUtils { public final class BlockUtils {
/**
* Max blocks to mine (yes, this is to prevent a stack overflow).
*/
private static final int MAX_BLOCKS = 2500;
private static Set<Block> getNearbyBlocks(@NotNull final Block start, private static Set<Block> getNearbyBlocks(@NotNull final Block start,
@NotNull final List<Material> allowedMaterials, @NotNull final List<Material> allowedMaterials,
@NotNull final Set<Block> blocks, @NotNull final Set<Block> blocks,
@@ -31,7 +36,7 @@ public final class BlockUtils {
if (allowedMaterials.contains(block.getType())) { if (allowedMaterials.contains(block.getType())) {
blocks.add(block); blocks.add(block);
if (blocks.size() > limit || blocks.size() > 2500) { if (blocks.size() > limit || blocks.size() > MAX_BLOCKS) {
return blocks; return blocks;
} }

View File

@@ -109,8 +109,8 @@ public final class DurabilityUtils {
return; return;
} }
// Suppression because when I fix it, it causes weird compile bugs.
Damageable meta = (Damageable) item.getItemMeta(); @SuppressWarnings("PatternVariableCanBeUsed") Damageable meta = (Damageable) item.getItemMeta();
meta.setDamage(meta.getDamage() + damage); meta.setDamage(meta.getDamage() + damage);
if (meta.getDamage() >= item.getType().getMaxDurability()) { if (meta.getDamage() >= item.getType().getMaxDurability()) {

View File

@@ -1,12 +1,24 @@
package com.willfp.eco.util; package com.willfp.eco.util;
import com.willfp.eco.core.gui.menu.Menu;
import com.willfp.eco.core.tuples.Pair; import com.willfp.eco.core.tuples.Pair;
import org.apache.commons.lang.Validate;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Function;
/** /**
* Utilities / API methods for menus. * Utilities / API methods for menus.
*/ */
public final class MenuUtils { public final class MenuUtils {
/**
* The menu supplier.
*/
private static Function<Player, Menu> menuGetter = null;
/** /**
* Convert 0-53 slot to row and column pair. * Convert 0-53 slot to row and column pair.
* *
@@ -20,6 +32,40 @@ public final class MenuUtils {
return new Pair<>(row + 1, column + 1); return new Pair<>(row + 1, column + 1);
} }
/**
* Convert row and column to 0-53 slot.
*
* @param row The row.
* @param column The column.
* @return The slot.
*/
public static int rowColumnToSlot(final int row, final int column) {
return (column - 1) + ((row - 1) * 9);
}
/**
* Get a player's open menu.
*
* @param player The player.
* @return The menu, or null if none open.
*/
@Nullable
public static Menu getOpenMenu(@NotNull final Player player) {
return menuGetter.apply(player);
}
/**
* Initialize the tps supplier function.
*
* @param function The function.
*/
@ApiStatus.Internal
public static void initialize(@NotNull final Function<Player, Menu> function) {
Validate.isTrue(menuGetter == null, "Already initialized!");
menuGetter = function;
}
private MenuUtils() { private MenuUtils() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
} }

View File

@@ -1,5 +1,8 @@
package com.willfp.eco.util; package com.willfp.eco.util;
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.StaticPlaceholder; import com.willfp.eco.core.placeholder.StaticPlaceholder;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@@ -8,7 +11,10 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
@@ -252,7 +258,18 @@ public final class NumberUtils {
*/ */
public static double evaluateExpression(@NotNull final String expression, public static double evaluateExpression(@NotNull final String expression,
@Nullable final Player player) { @Nullable final Player player) {
return evaluateExpression(expression, player, Collections.emptyList()); return evaluateExpression(expression, player, new PlaceholderInjectable() {
@Override
public void clearInjectedPlaceholders() {
// Nothing.
}
@Override
public @NotNull
List<InjectablePlaceholder> getPlaceholderInjections() {
return Collections.emptyList();
}
});
} }
/** /**
@@ -262,11 +279,57 @@ public final class NumberUtils {
* @param player The player. * @param player The player.
* @param statics The static placeholders. * @param statics The static placeholders.
* @return The value of the expression, or zero if invalid. * @return The value of the expression, or zero if invalid.
* @deprecated Use new statics system.
*/ */
@Deprecated(since = "6.35.0", forRemoval = true)
public static double evaluateExpression(@NotNull final String expression, public static double evaluateExpression(@NotNull final String expression,
@Nullable final Player player, @Nullable final Player player,
@NotNull final Iterable<StaticPlaceholder> statics) { @NotNull final Iterable<StaticPlaceholder> statics) {
return crunch.evaluate(expression, player, statics); return evaluateExpression(expression, player, new PlaceholderInjectable() {
@Override
public void clearInjectedPlaceholders() {
// Do nothing.
}
@Override
public @NotNull List<InjectablePlaceholder> getPlaceholderInjections() {
List<InjectablePlaceholder> injections = new ArrayList<>();
for (StaticPlaceholder placeholder : statics) {
injections.add(placeholder);
}
return injections;
}
});
}
/**
* Evaluate an expression with respect to a player (for placeholders).
*
* @param expression The expression.
* @param player The player.
* @param context The injectable placeholders.
* @return The value of the expression, or zero if invalid.
*/
public static double evaluateExpression(@NotNull final String expression,
@Nullable final Player player,
@NotNull final PlaceholderInjectable context) {
return evaluateExpression(expression, player, context, new ArrayList<>());
}
/**
* Evaluate an expression with respect to a player (for placeholders).
*
* @param expression The expression.
* @param player The player.
* @param context The injectable placeholders.
* @param additionalPlayers Additional players to parse placeholders for.
* @return The value of the expression, or zero if invalid.
*/
public static double evaluateExpression(@NotNull final String expression,
@Nullable final Player player,
@NotNull final PlaceholderInjectable context,
@NotNull final Collection<AdditionalPlayer> additionalPlayers) {
return crunch.evaluate(expression, player, context, additionalPlayers);
} }
/** /**
@@ -288,14 +351,16 @@ public final class NumberUtils {
/** /**
* Evaluate an expression. * Evaluate an expression.
* *
* @param expression The expression. * @param expression The expression.
* @param player The player. * @param player The player.
* @param statics The statics. * @param injectable The injectable placeholders.
* @param additionalPlayers The additional players.
* @return The value of the expression, or zero if invalid. * @return The value of the expression, or zero if invalid.
*/ */
double evaluate(@NotNull String expression, double evaluate(@NotNull String expression,
@Nullable Player player, @Nullable Player player,
@NotNull Iterable<StaticPlaceholder> statics); @NotNull PlaceholderInjectable injectable,
@NotNull Collection<AdditionalPlayer> additionalPlayers);
} }
private NumberUtils() { private NumberUtils() {

View File

@@ -10,8 +10,14 @@ import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.AnimalTamer;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.Tameable;
import org.bukkit.projectiles.ProjectileSource;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Consumer; import java.util.function.Consumer;
@@ -142,6 +148,39 @@ public final class PlayerUtils {
} }
} }
/**
* Try an entity as a player.
*
* @param entity The entity.
* @return The player, or null if no player could be found.
*/
@Nullable
public static Player tryAsPlayer(@Nullable final Entity entity) {
if (entity == null) {
return null;
}
if (entity instanceof Player player) {
return player;
}
if (entity instanceof Projectile projectile) {
ProjectileSource shooter = projectile.getShooter();
if (shooter instanceof Player player) {
return player;
}
}
if (entity instanceof Tameable tameable) {
AnimalTamer tamer = tameable.getOwner();
if (tamer instanceof Player player) {
return player;
}
}
return null;
}
private PlayerUtils() { private PlayerUtils() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
} }

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.util; package com.willfp.eco.util;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache; import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@@ -12,6 +13,7 @@ import net.kyori.adventure.text.format.TextDecoration;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
import org.apache.commons.lang.Validate;
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;
@@ -41,6 +43,7 @@ public final class StringUtils {
.add(Pattern.compile("<G#([0-9A-Fa-f]{6})>(.*?)</G#([0-9A-Fa-f]{6})>", Pattern.CASE_INSENSITIVE)) .add(Pattern.compile("<G#([0-9A-Fa-f]{6})>(.*?)</G#([0-9A-Fa-f]{6})>", Pattern.CASE_INSENSITIVE))
.add(Pattern.compile("<#:([0-9A-Fa-f]{6})>(.*?)</#:([0-9A-Fa-f]{6})>")) .add(Pattern.compile("<#:([0-9A-Fa-f]{6})>(.*?)</#:([0-9A-Fa-f]{6})>"))
.add(Pattern.compile("\\{#:([0-9A-Fa-f]{6})}(.*?)\\{/#:([0-9A-Fa-f]{6})}")) .add(Pattern.compile("\\{#:([0-9A-Fa-f]{6})}(.*?)\\{/#:([0-9A-Fa-f]{6})}"))
.add(Pattern.compile("\\{#([0-9A-Fa-f]{6})>}(.*?)\\{#([0-9A-Fa-f]{6})<}"))
.build(); .build();
/** /**
@@ -76,33 +79,37 @@ public final class StringUtils {
.build(StringUtils::processFormatting); .build(StringUtils::processFormatting);
/** /**
* Json -> Legacy Cache. * Json -> Component Cache.
*/ */
private static final LoadingCache<String, String> JSON_TO_LEGACY = Caffeine.newBuilder() private static final Cache<String, Component> JSON_TO_COMPONENT = Caffeine.newBuilder()
.expireAfterAccess(10, TimeUnit.SECONDS) .expireAfterAccess(10, TimeUnit.SECONDS)
.build( .build();
json -> {
try {
Component component = GSON_COMPONENT_SERIALIZER.deserialize(json);
return LEGACY_COMPONENT_SERIALIZER.serialize(component);
} catch (JsonSyntaxException e) {
return json;
}
}
);
/** /**
* Legacy -> Json Cache. * Component -> Json Cache.
*/ */
private static final LoadingCache<String, String> LEGACY_TO_JSON = Caffeine.newBuilder() private static final Cache<Component, String> COMPONENT_TO_JSON = Caffeine.newBuilder()
.expireAfterAccess(10, TimeUnit.SECONDS) .expireAfterAccess(10, TimeUnit.SECONDS)
.build( .build();
legacy -> GSON_COMPONENT_SERIALIZER.serialize(
Component.empty().decoration(TextDecoration.ITALIC, false).append( /**
LEGACY_COMPONENT_SERIALIZER.deserialize(legacy) * Legacy -> Component Cache.
) */
) private static final Cache<String, Component> LEGACY_TO_COMPONENT = Caffeine.newBuilder()
); .expireAfterAccess(10, TimeUnit.SECONDS)
.build();
/**
* Component -> Legacy Cache.
*/
private static final Cache<Component, String> COMPONENT_TO_LEGACY = Caffeine.newBuilder()
.expireAfterAccess(10, TimeUnit.SECONDS)
.build();
/**
* Empty JSON.
*/
private static final String EMPTY_JSON = GSON_COMPONENT_SERIALIZER.serialize(Component.empty());
/** /**
* Color map. * Color map.
@@ -483,12 +490,7 @@ public final class StringUtils {
*/ */
@NotNull @NotNull
public static String legacyToJson(@Nullable final String legacy) { public static String legacyToJson(@Nullable final String legacy) {
String processed = legacy; return componentToJson(toComponent(legacy));
if (legacy == null) {
processed = "";
}
return LEGACY_TO_JSON.get(processed);
} }
/** /**
@@ -499,11 +501,53 @@ public final class StringUtils {
*/ */
@NotNull @NotNull
public static String jsonToLegacy(@Nullable final String json) { public static String jsonToLegacy(@Nullable final String json) {
if (json == null || json.isEmpty()) { return toLegacy(jsonToComponent(json));
return ""; }
/**
* Convert Component to JSON String.
*
* @param component The Component.
* @return The JSON string.
*/
@NotNull
public static String componentToJson(@Nullable final Component component) {
if (component == null) {
return EMPTY_JSON;
} }
return JSON_TO_LEGACY.get(json); return COMPONENT_TO_JSON.get(component, it -> {
try {
return GSON_COMPONENT_SERIALIZER.serialize(
Component.empty().decoration(TextDecoration.ITALIC, false).append(
it
)
);
} catch (JsonSyntaxException e) {
return GSON_COMPONENT_SERIALIZER.serialize(Component.empty());
}
});
}
/**
* Convert JSON String to Component.
*
* @param json The JSON String.
* @return The component.
*/
@NotNull
public static Component jsonToComponent(@Nullable final String json) {
if (json == null || json.isEmpty()) {
return Component.empty();
}
return JSON_TO_COMPONENT.get(json, it -> {
try {
return GSON_COMPONENT_SERIALIZER.deserialize(it);
} catch (JsonSyntaxException e) {
return Component.empty();
}
});
} }
/** /**
@@ -514,12 +558,7 @@ public final class StringUtils {
*/ */
@NotNull @NotNull
public static Component toComponent(@Nullable final String legacy) { public static Component toComponent(@Nullable final String legacy) {
String processed = legacy; return LEGACY_TO_COMPONENT.get(legacy == null ? "" : legacy, LEGACY_COMPONENT_SERIALIZER::deserialize);
if (legacy == null) {
processed = "";
}
return LEGACY_COMPONENT_SERIALIZER.deserialize(processed);
} }
/** /**
@@ -530,7 +569,7 @@ public final class StringUtils {
*/ */
@NotNull @NotNull
public static String toLegacy(@NotNull final Component component) { public static String toLegacy(@NotNull final Component component) {
return LEGACY_COMPONENT_SERIALIZER.serialize(component); return COMPONENT_TO_LEGACY.get(component, LEGACY_COMPONENT_SERIALIZER::serialize);
} }
/** /**
@@ -596,6 +635,59 @@ public final class StringUtils {
return SPACE_AROUND_CHARACTER.get(separator).split(input); return SPACE_AROUND_CHARACTER.get(separator).split(input);
} }
/**
* Create progress bar.
*
* @param character The bar character.
* @param bars The number of bars.
* @param progress The bar progress, between 0 and 1.
* @param completeFormat The color of a complete bar section.
* @param inProgressFormat The color of an in-progress bar section.
* @param incompleteFormat The color of an incomplete bar section.
* @return The progress bar.
*/
@NotNull
public static String createProgressBar(final char character,
final int bars,
final double progress,
@NotNull final String completeFormat,
@NotNull final String inProgressFormat,
@NotNull final String incompleteFormat) {
Validate.isTrue(progress >= 0 && progress <= 1, "Progress must be between 0 and 1!");
Validate.isTrue(bars > 1, "Must have at least 2 bars!");
String completeColor = format(completeFormat);
String inProgressColor = format(inProgressFormat);
String incompleteColor = format(incompleteFormat);
StringBuilder builder = new StringBuilder();
// Full bar special case.
if (progress == 1) {
builder.append(completeColor);
builder.append(String.valueOf(character).repeat(bars));
return builder.toString();
}
int completeBars = (int) Math.floor(progress * bars);
int incompleteBars = bars - completeBars - 1;
if (completeBars > 0) {
builder.append(completeColor)
.append(String.valueOf(character).repeat(completeBars));
}
builder.append(inProgressColor)
.append(character);
if (incompleteBars > 0) {
builder.append(incompleteColor)
.append(String.valueOf(character).repeat(incompleteBars));
}
return builder.toString();
}
/** /**
* Options for formatting. * Options for formatting.
*/ */

View File

@@ -12,7 +12,6 @@ import org.jetbrains.annotations.NotNull;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.stream.Collectors;
/** /**
* Utilities / API methods for teams. * Utilities / API methods for teams.
@@ -49,7 +48,7 @@ public final class TeamUtils {
Team team; Team team;
if (!SCOREBOARD.getTeams().stream().map(Team::getName).collect(Collectors.toList()).contains("EC-" + color.name())) { if (!SCOREBOARD.getTeams().stream().map(Team::getName).toList().contains("EC-" + color.name())) {
team = SCOREBOARD.registerNewTeam("EC-" + color.name()); team = SCOREBOARD.registerNewTeam("EC-" + color.name());
} else { } else {
team = SCOREBOARD.getTeam("EC-" + color.name()); team = SCOREBOARD.getTeam("EC-" + color.name());

View File

@@ -152,6 +152,20 @@ public final class VectorUtils {
return vectors.toArray(new Vector[0]); return vectors.toArray(new Vector[0]);
} }
/**
* Get if a vector is a safe velocity.
*
* @param vec The vector to check.
* @return If safe.
*/
public static boolean isSafeVelocity(@NotNull final Vector vec) {
double x = Math.abs(vec.getX());
double y = Math.abs(vec.getY());
double z = Math.abs(vec.getZ());
return x < 4 && y < 4 && z < 4;
}
private VectorUtils() { private VectorUtils() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
} }

View File

@@ -121,8 +121,8 @@ fun CommandBase.addSubcommand(
} }
/** /**
* Kotlin builder for commands. * Kotlin builder for commands. Inherits plugin, permission, players
* Inherits plugin, permission, players only. * only.
* *
* @param name The command name. * @param name The command name.
* @param init The builder. * @param init The builder.

View File

@@ -0,0 +1,36 @@
@file:JvmName("ConfigExtensions")
package com.willfp.eco.core.config
import com.willfp.eco.core.config.interfaces.Config
/** Helper class to create configs with a kotlin DSL. */
class DSLConfig internal constructor(type: ConfigType) : TransientConfig(emptyMap(), type) {
/**
* Map a key to a value.
*
* @param value The value.
*/
infix fun String.to(value: Any?) =
set(this, value)
/**
* Helper function to create configs with a kotlin DSL.
*
* Inherits the config type of the sub-builder.
*
* @param builder The builder.
* @return The config.
*/
fun config(builder: DSLConfig.() -> Unit): Config =
DSLConfig(type).apply(builder)
}
/**
* Helper function to create configs with a kotlin DSL.
*
* @param builder The builder.
* @return The config.
*/
fun config(type: ConfigType = ConfigType.YAML, builder: DSLConfig.() -> Unit): Config =
DSLConfig(type).apply(builder)

View File

@@ -0,0 +1,37 @@
@file:JvmName("PersistentDataContainerExtensions")
package com.willfp.eco.core.data
import org.bukkit.persistence.PersistentDataContainer
import org.bukkit.persistence.PersistentDataType
/** @see ExtendedPersistentDataContainer.set */
fun <T : Any, Z : Any> PersistentDataContainer.set(key: String, dataType: PersistentDataType<T, Z>, value: Z) =
ExtendedPersistentDataContainer.extend(this).set(key, dataType, value)
/** @see ExtendedPersistentDataContainer.has */
fun <T : Any, Z : Any> PersistentDataContainer.has(key: String, dataType: PersistentDataType<T, Z>): Boolean =
ExtendedPersistentDataContainer.extend(this).has(key, dataType)
/** @see ExtendedPersistentDataContainer.get */
fun <T : Any, Z : Any> PersistentDataContainer.get(key: String, dataType: PersistentDataType<T, Z>): Z? =
ExtendedPersistentDataContainer.extend(this).get(key, dataType)
/** @see ExtendedPersistentDataContainer.getOrDefault */
fun <T : Any, Z : Any> PersistentDataContainer.getOrDefault(
key: String,
dataType: PersistentDataType<T, Z>,
defaultValue: Z
): Z = ExtendedPersistentDataContainer.extend(this).getOrDefault(key, dataType, defaultValue)
/** @see ExtendedPersistentDataContainer.getAllKeys */
fun PersistentDataContainer.getAllKeys(): Set<String> =
ExtendedPersistentDataContainer.extend(this).allKeys
/** @see ExtendedPersistentDataContainer.remove */
fun PersistentDataContainer.remove(key: String) =
ExtendedPersistentDataContainer.extend(this).remove(key)
/** Create a new PDC without the need for an adapter context. */
fun newPersistentDataContainer() =
ExtendedPersistentDataContainer.create().base

View File

@@ -5,14 +5,10 @@ package com.willfp.eco.core.data
import org.bukkit.OfflinePlayer import org.bukkit.OfflinePlayer
import org.bukkit.Server import org.bukkit.Server
/** /** @see PlayerProfile.load */
* @see PlayerProfile.load
*/
val OfflinePlayer.profile: PlayerProfile val OfflinePlayer.profile: PlayerProfile
get() = PlayerProfile.load(this) get() = PlayerProfile.load(this)
/** /** @see ServerProfile.load */
* @see ServerProfile.load
*/
val Server.profile: ServerProfile val Server.profile: ServerProfile
get() = ServerProfile.load() get() = ServerProfile.load()

View File

@@ -5,8 +5,6 @@ package com.willfp.eco.core.entities
import com.willfp.eco.core.entities.ai.EntityController import com.willfp.eco.core.entities.ai.EntityController
import org.bukkit.entity.Mob import org.bukkit.entity.Mob
/** /** @see EntityController.getFor */
* @see EntityController.getFor
*/
val <T : Mob> T.controller: EntityController<T> val <T : Mob> T.controller: EntityController<T>
get() = EntityController.getFor(this) get() = EntityController.getFor(this)

View File

@@ -4,8 +4,6 @@ package com.willfp.eco.core.fast
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
/** /** @see FastItemStack.wrap */
* @see FastItemStack.wrap
*/
fun ItemStack.fast(): FastItemStack = fun ItemStack.fast(): FastItemStack =
FastItemStack.wrap(this) FastItemStack.wrap(this)

View File

@@ -6,41 +6,36 @@ import com.willfp.eco.core.gui.menu.Menu
import com.willfp.eco.core.gui.menu.MenuBuilder import com.willfp.eco.core.gui.menu.MenuBuilder
import com.willfp.eco.core.gui.slot.Slot import com.willfp.eco.core.gui.slot.Slot
import com.willfp.eco.core.gui.slot.SlotBuilder import com.willfp.eco.core.gui.slot.SlotBuilder
import com.willfp.eco.core.items.TestableItem
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.event.inventory.InventoryClickEvent import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.inventory.InventoryCloseEvent import org.bukkit.event.inventory.InventoryCloseEvent
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
/** /** @see SlotBuilder.onLeftClick */
* @see SlotBuilder.onLeftClick
*/
fun SlotBuilder.onLeftClick(action: (InventoryClickEvent, Slot, Menu) -> Unit): SlotBuilder = fun SlotBuilder.onLeftClick(action: (InventoryClickEvent, Slot, Menu) -> Unit): SlotBuilder =
this.onLeftClick { a, b, c -> action(a, b, c) } this.onLeftClick { a, b, c -> action(a, b, c) }
/** /** @see SlotBuilder.onRightClick */
* @see SlotBuilder.onRightClick
*/
fun SlotBuilder.onRightClick(action: (InventoryClickEvent, Slot, Menu) -> Unit): SlotBuilder = fun SlotBuilder.onRightClick(action: (InventoryClickEvent, Slot, Menu) -> Unit): SlotBuilder =
this.onRightClick { a, b, c -> action(a, b, c) } this.onRightClick { a, b, c -> action(a, b, c) }
/** /** @see SlotBuilder.onShiftLeftClick */
* @see SlotBuilder.onShiftLeftClick
*/
fun SlotBuilder.onShiftLeftClick(action: (InventoryClickEvent, Slot, Menu) -> Unit): SlotBuilder = fun SlotBuilder.onShiftLeftClick(action: (InventoryClickEvent, Slot, Menu) -> Unit): SlotBuilder =
this.onShiftLeftClick { a, b, c -> action(a, b, c) } this.onShiftLeftClick { a, b, c -> action(a, b, c) }
/** /** @see SlotBuilder.onShiftRightClick */
* @see SlotBuilder.onShiftRightClick
*/
fun SlotBuilder.onShiftRightClick(action: (InventoryClickEvent, Slot, Menu) -> Unit): SlotBuilder = fun SlotBuilder.onShiftRightClick(action: (InventoryClickEvent, Slot, Menu) -> Unit): SlotBuilder =
this.onShiftRightClick { a, b, c -> action(a, b, c) } this.onShiftRightClick { a, b, c -> action(a, b, c) }
/** /** @see SlotBuilder.onShiftRightClick */
* @see SlotBuilder.onShiftRightClick
*/
fun SlotBuilder.onMiddleClick(action: (InventoryClickEvent, Slot, Menu) -> Unit): SlotBuilder = fun SlotBuilder.onMiddleClick(action: (InventoryClickEvent, Slot, Menu) -> Unit): SlotBuilder =
this.onMiddleClick { a, b, c -> action(a, b, c) } this.onMiddleClick { a, b, c -> action(a, b, c) }
/** @see SlotBuilder.notCaptiveFor */
fun SlotBuilder.notCaptiveFor(test: (Player) -> Boolean): SlotBuilder =
this.notCaptiveFor { test(it) }
/** /**
* @see SlotBuilder.setModifier * @see SlotBuilder.setModifier
* @deprecated Use SlotUpdater instead. * @deprecated Use SlotUpdater instead.
@@ -50,15 +45,32 @@ fun SlotBuilder.onMiddleClick(action: (InventoryClickEvent, Slot, Menu) -> Unit)
fun SlotBuilder.setModifier(action: (Player, Menu, ItemStack) -> Unit): SlotBuilder = fun SlotBuilder.setModifier(action: (Player, Menu, ItemStack) -> Unit): SlotBuilder =
this.setUpdater { a, b, c -> c.apply { action(a, b, c) } } this.setUpdater { a, b, c -> c.apply { action(a, b, c) } }
/** /** @see SlotBuilder.setUpdater */
* @see SlotBuilder.setUpdater
*/
fun SlotBuilder.setUpdater(action: (Player, Menu, ItemStack) -> ItemStack): SlotBuilder = fun SlotBuilder.setUpdater(action: (Player, Menu, ItemStack) -> ItemStack): SlotBuilder =
this.setUpdater { a, b, c -> action(a, b, c) } this.setUpdater { a, b, c -> action(a, b, c) }
/** /** Kotlin builder for slots. */
* Kotlin builder for slots. fun captiveSlot(): Slot = Slot.builder().setCaptive().build()
*/
/** Kotlin builder for slots. */
fun captiveSlot(
init: SlotBuilder.() -> Unit
): Slot {
val builder = Slot.builder().setCaptive()
init(builder)
return builder.build()
}
/** Kotlin builder for slots. */
fun slot(
init: SlotBuilder.() -> Unit
): Slot {
val builder = Slot.builder()
init(builder)
return builder.build()
}
/** Kotlin builder for slots. */
fun slot( fun slot(
item: ItemStack, item: ItemStack,
init: SlotBuilder.() -> Unit init: SlotBuilder.() -> Unit
@@ -68,9 +80,17 @@ fun slot(
return builder.build() return builder.build()
} }
/** /** Kotlin builder for slots. */
* Kotlin builder for slots. fun slot(
*/ item: ItemStack
): Slot = Slot.builder(item).build()
/** Kotlin builder for slots. */
fun slot(
item: TestableItem
): Slot = Slot.builder(item.item).build()
/** Kotlin builder for slots. */
fun slot( fun slot(
provider: (Player, Menu) -> ItemStack, provider: (Player, Menu) -> ItemStack,
init: SlotBuilder.() -> Unit init: SlotBuilder.() -> Unit
@@ -80,21 +100,28 @@ fun slot(
return builder.build() return builder.build()
} }
/** /** Kotlin builder for slots. */
* @see MenuBuilder.onClose fun slot(
*/ provider: (Player, Menu) -> ItemStack
): Slot = Slot.builder { a, b -> provider(a, b) }.build()
/** @see MenuBuilder.onClose */
fun MenuBuilder.onClose(action: (InventoryCloseEvent, Menu) -> Unit): MenuBuilder = fun MenuBuilder.onClose(action: (InventoryCloseEvent, Menu) -> Unit): MenuBuilder =
this.onClose { a, b -> action(a, b) } this.onClose { a, b -> action(a, b) }
/** /** @see MenuBuilder.onOpen */
* @see MenuBuilder.modify fun MenuBuilder.onOpen(action: (Player, Menu) -> Unit): MenuBuilder =
*/ this.onOpen { a, b -> action(a, b) }
/** @see MenuBuilder.modify */
fun MenuBuilder.modify(modifier: (MenuBuilder) -> Unit): MenuBuilder = fun MenuBuilder.modify(modifier: (MenuBuilder) -> Unit): MenuBuilder =
this.modfiy { modifier(it) } this.modfiy { modifier(it) }
/** /** @see MenuBuilder.onRender */
* Kotlin builder for menus. fun MenuBuilder.onRender(action: (Player, Menu) -> Unit): MenuBuilder =
*/ this.onRender { a, b -> action(a, b) }
/** Kotlin builder for menus. */
fun menu( fun menu(
rows: Int, rows: Int,
init: MenuBuilder.() -> Unit init: MenuBuilder.() -> Unit

View File

@@ -0,0 +1,42 @@
@file:JvmName("EconomyExtensions")
package com.willfp.eco.core.integrations.economy
import org.bukkit.OfflinePlayer
import java.math.BigDecimal
/** @see EconomyManager */
var OfflinePlayer.balance: Double
get() = EconomyManager.getBalance(this)
set(value) {
if (value <= 0) {
EconomyManager.removeMoney(this, this.balance)
return
}
val diff = this.balance - value
if (diff > 0) {
EconomyManager.removeMoney(this, diff)
} else if (diff < 0) {
EconomyManager.giveMoney(this, -diff)
}
}
/** @see EconomyManager */
var OfflinePlayer.exactBalance: BigDecimal
get() = EconomyManager.getBalance(this).toBigDecimal()
set(value) {
if (value <= BigDecimal.ZERO) {
EconomyManager.removeMoney(this, this.balance)
return
}
val diff = this.exactBalance - value
if (diff > BigDecimal.ZERO) {
EconomyManager.removeMoney(this, diff.toDouble())
} else if (diff < BigDecimal.ZERO) {
EconomyManager.giveMoney(this, -diff.toDouble())
}
}

View File

@@ -0,0 +1,14 @@
@file:JvmName("ShopExtensions")
package com.willfp.eco.core.integrations.shop
import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack
/** @see ShopManager.getItemPrice **/
val ItemStack.price: Double
get() = ShopManager.getItemPrice(this)
/** @see ShopManager.getItemPrice **/
fun ItemStack.getPrice(player: Player): Double =
ShopManager.getItemPrice(this, player)

View File

@@ -4,21 +4,30 @@ package com.willfp.eco.core.items
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.ItemMeta import org.bukkit.inventory.meta.ItemMeta
import org.bukkit.persistence.PersistentDataContainer
/** /** @see Items.toLookupString */
* @see Items.toLookupString
*/
fun ItemStack?.toLookupString(): String = fun ItemStack?.toLookupString(): String =
Items.toLookupString(this) Items.toLookupString(this)
/** /** @see Items.mergeFrom */
* @see Items.mergeFrom
*/
fun ItemStack.mergeFrom(other: ItemStack): ItemStack = fun ItemStack.mergeFrom(other: ItemStack): ItemStack =
Items.mergeFrom(other, this) Items.mergeFrom(other, this)
/** /** @see Items.mergeFrom */
* @see Items.mergeFrom
*/
fun ItemMeta.mergeFrom(other: ItemMeta): ItemMeta = fun ItemMeta.mergeFrom(other: ItemMeta): ItemMeta =
Items.mergeFrom(other, this) Items.mergeFrom(other, this)
/**
* @see Items.getBaseNBT
* @see Items.setBaseNBT
*/
var ItemStack.baseNBT: PersistentDataContainer
get() = Items.getBaseNBT(this)
set(value) {
Items.setBaseNBT(this, value)
}
/** @see Items.setBaseNBT */
fun ItemStack.clearNBT() =
Items.setBaseNBT(this, null)

View File

@@ -5,8 +5,6 @@ package com.willfp.eco.util
import org.bukkit.entity.Arrow import org.bukkit.entity.Arrow
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
/** /** @see ArrowUtils.getBow */
* @see ArrowUtils.getBow
*/
val Arrow.bow: ItemStack? val Arrow.bow: ItemStack?
get() = ArrowUtils.getBow(this) get() = ArrowUtils.getBow(this)

View File

@@ -4,8 +4,6 @@ package com.willfp.eco.util
import org.bukkit.block.Block import org.bukkit.block.Block
/** /** @see ArrowUtils.getBow */
* @see ArrowUtils.getBow
*/
val Block.isPlayerPlaced: Boolean val Block.isPlayerPlaced: Boolean
get() = BlockUtils.isPlayerPlaced(this) get() = BlockUtils.isPlayerPlaced(this)

View File

@@ -5,14 +5,10 @@ package com.willfp.eco.util
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
/** /** @see DurabilityUtils.damageItem */
* @see DurabilityUtils.damageItem
*/
fun ItemStack.damage(damage: Int) = fun ItemStack.damage(damage: Int) =
DurabilityUtils.damageItem(this, damage) DurabilityUtils.damageItem(this, damage)
/** /** @see DurabilityUtils.damageItem */
* @see DurabilityUtils.damageItem
*/
fun ItemStack.damage(damage: Int, player: Player) = fun ItemStack.damage(damage: Int, player: Player) =
DurabilityUtils.damageItem(player, this, damage) DurabilityUtils.damageItem(player, this, damage)

View File

@@ -2,20 +2,18 @@
package com.willfp.eco.util package com.willfp.eco.util
/** /** @see ListUtils.listToFrequencyMap */
* @see ListUtils.listToFrequencyMap
*/
fun <T> List<T>.toFrequencyMap(): Map<T, Int> = fun <T> List<T>.toFrequencyMap(): Map<T, Int> =
ListUtils.listToFrequencyMap(this) ListUtils.listToFrequencyMap(this)
/** /** @see ListUtils.containsIgnoreCase */
* @see ListUtils.containsIgnoreCase
*/
fun Iterable<String>.containsIgnoreCase(element: String): Boolean = fun Iterable<String>.containsIgnoreCase(element: String): Boolean =
ListUtils.containsIgnoreCase(this, element) ListUtils.containsIgnoreCase(this, element)
/** /** @see ListUtils.create2DList */
* @see ListUtils.create2DList
*/
fun <T> create2DList(rows: Int, columns: Int): MutableList<MutableList<T>> = fun <T> create2DList(rows: Int, columns: Int): MutableList<MutableList<T>> =
ListUtils.create2DList(rows, columns) ListUtils.create2DList(rows, columns)
/** @see ListUtils.toSingletonList */
fun <T> T.toSingletonList(): List<T> =
ListUtils.toSingletonList(this)

View File

@@ -0,0 +1,10 @@
@file:JvmName("MenuUtilsExtensions")
package com.willfp.eco.util
import com.willfp.eco.core.gui.menu.Menu
import org.bukkit.entity.Player
/** @see MenuUtils.getOpenMenu */
val Player.openMenu: Menu?
get() = MenuUtils.getOpenMenu(this)

View File

@@ -4,26 +4,18 @@ package com.willfp.eco.util
import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.EcoPlugin
/** /** @see NamespacedKeyUtils.fromString */
* @see NamespacedKeyUtils.fromString
*/
fun namespacedKeyOf(string: String) = fun namespacedKeyOf(string: String) =
NamespacedKeyUtils.fromString(string) NamespacedKeyUtils.fromString(string)
/** /** @see NamespacedKeyUtils.fromString */
* @see NamespacedKeyUtils.fromString
*/
fun safeNamespacedKeyOf(string: String) = fun safeNamespacedKeyOf(string: String) =
NamespacedKeyUtils.fromStringOrNull(string) NamespacedKeyUtils.fromStringOrNull(string)
/** /** @see NamespacedKeyUtils.create */
* @see NamespacedKeyUtils.create
*/
fun namespacedKeyOf(namespace: String, key: String) = fun namespacedKeyOf(namespace: String, key: String) =
NamespacedKeyUtils.create(namespace, key) NamespacedKeyUtils.create(namespace, key)
/** /** @see EcoPlugin.namespacedKeyFactory */
* @see EcoPlugin.namespacedKeyFactory
*/
fun namespacedKeyOf(plugin: EcoPlugin, key: String) = fun namespacedKeyOf(plugin: EcoPlugin, key: String) =
plugin.namespacedKeyFactory.create(key) plugin.namespacedKeyFactory.create(key)

View File

@@ -2,8 +2,6 @@
package com.willfp.eco.util package com.willfp.eco.util
/** /** @see NumberUtils.toNumeral */
* @see NumberUtils.toNumeral
*/
fun Number.toNumeral(): String = fun Number.toNumeral(): String =
NumberUtils.toNumeral(this.toInt()) NumberUtils.toNumeral(this.toInt())

View File

@@ -5,28 +5,25 @@ package com.willfp.eco.util
import net.kyori.adventure.audience.Audience import net.kyori.adventure.audience.Audience
import org.bukkit.OfflinePlayer import org.bukkit.OfflinePlayer
import org.bukkit.command.CommandSender import org.bukkit.command.CommandSender
import org.bukkit.entity.Entity
import org.bukkit.entity.Player import org.bukkit.entity.Player
/** /** @see PlayerUtils.getSavedDisplayName */
* @see PlayerUtils.getSavedDisplayName
*/
val OfflinePlayer.savedDisplayName: String val OfflinePlayer.savedDisplayName: String
get() = PlayerUtils.getSavedDisplayName(this) get() = PlayerUtils.getSavedDisplayName(this)
/** /** @see PlayerUtils.getAudience */
* @see PlayerUtils.getAudience
*/
fun Player.asAudience(): Audience = fun Player.asAudience(): Audience =
PlayerUtils.getAudience(this) PlayerUtils.getAudience(this)
/** /** @see PlayerUtils.getAudience */
* @see PlayerUtils.getAudience
*/
fun CommandSender.asAudience(): Audience = fun CommandSender.asAudience(): Audience =
PlayerUtils.getAudience(this) PlayerUtils.getAudience(this)
/** /** @see PlayerUtils.runExempted */
* @see PlayerUtils.runExempted
*/
fun Player.runExempted(action: () -> Unit) = fun Player.runExempted(action: () -> Unit) =
PlayerUtils.runExempted(this, action) PlayerUtils.runExempted(this, action)
/** @see PlayerUtils.tryAsPlayer */
fun Entity?.tryAsPlayer(): Player? =
PlayerUtils.tryAsPlayer(this)

View File

@@ -4,8 +4,6 @@ package com.willfp.eco.util
import org.bukkit.potion.PotionData import org.bukkit.potion.PotionData
/** /** @see PotionData.duration */
* @see PotionData.duration
*/
val PotionData.duration: Int val PotionData.duration: Int
get() = PotionUtils.getDuration(this) get() = PotionUtils.getDuration(this)

View File

@@ -4,8 +4,6 @@ package com.willfp.eco.util
import org.bukkit.Server import org.bukkit.Server
/** /** @see ServerUtils.getTps */
* @see ServerUtils.getTps
*/
val Server.tps: Double val Server.tps: Double
get() = ServerUtils.getTps() get() = ServerUtils.getTps()

View File

@@ -5,21 +5,23 @@ package com.willfp.eco.util
import net.kyori.adventure.text.Component import net.kyori.adventure.text.Component
import org.bukkit.entity.Player import org.bukkit.entity.Player
/** /** @see StringUtils.toComponent */
* @see StringUtils.toComponent
*/
fun String.toComponent(): Component = fun String.toComponent(): Component =
StringUtils.toComponent(this) StringUtils.toComponent(this)
/** /** @see StringUtils.jsonToComponent */
* @see StringUtils.toLegacy fun String.jsonToComponent(): Component =
*/ StringUtils.jsonToComponent(this)
/** @see StringUtils.toLegacy */
fun Component.toLegacy(): String = fun Component.toLegacy(): String =
StringUtils.toLegacy(this) StringUtils.toLegacy(this)
/** /** @see StringUtils.componentToJson */
* @see StringUtils.format fun Component.toJSON(): String =
*/ StringUtils.componentToJson(this)
/** @see StringUtils.format */
fun String.formatEco( fun String.formatEco(
player: Player? = null, player: Player? = null,
formatPlaceholders: Boolean = false formatPlaceholders: Boolean = false
@@ -29,9 +31,7 @@ fun String.formatEco(
if (formatPlaceholders) StringUtils.FormatOption.WITH_PLACEHOLDERS else StringUtils.FormatOption.WITHOUT_PLACEHOLDERS if (formatPlaceholders) StringUtils.FormatOption.WITH_PLACEHOLDERS else StringUtils.FormatOption.WITHOUT_PLACEHOLDERS
) )
/** /** @see StringUtils.formatList */
* @see StringUtils.formatList
*/
fun List<String>.formatEco( fun List<String>.formatEco(
player: Player? = null, player: Player? = null,
formatPlaceholders: Boolean = false formatPlaceholders: Boolean = false
@@ -41,14 +41,10 @@ fun List<String>.formatEco(
if (formatPlaceholders) StringUtils.FormatOption.WITH_PLACEHOLDERS else StringUtils.FormatOption.WITHOUT_PLACEHOLDERS if (formatPlaceholders) StringUtils.FormatOption.WITH_PLACEHOLDERS else StringUtils.FormatOption.WITHOUT_PLACEHOLDERS
) )
/** /** @see StringUtils.splitAround */
* @see StringUtils.splitAround
*/
fun String.splitAround(separator: String): Array<String> = fun String.splitAround(separator: String): Array<String> =
StringUtils.splitAround(this, separator) StringUtils.splitAround(this, separator)
/** /** @see StringUtils.toNiceString */
* @see StringUtils.toNiceString
*/
fun Any?.toNiceString(): String = fun Any?.toNiceString(): String =
StringUtils.toNiceString(this) StringUtils.toNiceString(this)

View File

@@ -4,14 +4,14 @@ package com.willfp.eco.util
import org.bukkit.util.Vector import org.bukkit.util.Vector
/** /** @see VectorUtils.isFinite */
* @see VectorUtils.isFinite
*/
val Vector.isFinite: Boolean val Vector.isFinite: Boolean
get() = VectorUtils.isFinite(this) get() = VectorUtils.isFinite(this)
/** /** @see VectorUtils.simplifyVector */
* @see VectorUtils.simplifyVector
*/
fun Vector.simplify(): Vector = fun Vector.simplify(): Vector =
VectorUtils.simplifyVector(this) VectorUtils.simplifyVector(this)
/** @see VectorUtils.isSafeVelocity */
val Vector.isSafeVelocity: Boolean
get() = VectorUtils.isSafeVelocity(this)

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