Compare commits

..

265 Commits

Author SHA1 Message Date
Auxilor
87f90d8b26 Updated to 6.62.0 2023-05-24 14:45:37 +01:00
Auxilor
899d5cc054 Added caching to literal pattern compilation 2023-05-24 14:41:15 +01:00
Auxilor
c1ed771eb3 Updated to 6.61.1 2023-05-22 13:22:03 +01:00
Auxilor
08a4d9d6b1 Changed playerflow to use local server ID 2023-05-22 01:35:23 +01:00
Auxilor
7ef8dcfd64 Merge branch 'develop' 2023-05-21 19:07:56 +01:00
Auxilor
5bedf88b4c Updated lang.yml 2023-05-21 19:03:47 +01:00
Auxilor
1d241651b5 Added config option for playerflow 2023-05-21 17:01:13 +01:00
Auxilor
3ff2bfa412 Updated playerflow URL 2023-05-21 16:58:21 +01:00
Auxilor
3a508c693b Updated to 6.61.0 2023-05-21 16:38:35 +01:00
Auxilor
a4c5ff921e Added playerflow 2023-05-21 16:38:17 +01:00
Auxilor
137e9dc7d6 Added global price display names 2023-05-20 18:01:45 +01:00
Auxilor
710cec4bc1 Merge branch 'develop' 2023-05-19 13:17:05 +01:00
Auxilor
fa0ec7d6b0 Updated to 6.60.4 2023-05-19 13:16:20 +01:00
Auxilor
5093799775 Merge remote-tracking branch 'origin/develop' into develop 2023-05-19 13:15:34 +01:00
Will FP
8535f23ede Merge pull request #274
Fix PvPManager integration
2023-05-19 13:15:24 +01:00
Will FP
8e09ae7f4c Merge pull request #275
Add RoyaleEconomy to prices system
2023-05-19 13:14:54 +01:00
Sen2000
bbc2513b40 Fix RoyaleEconomy integration 2023-05-19 16:54:05 +07:00
Sen2000
c7f8063a3a Add RoyaleEconomy to prices system 2023-05-19 09:11:17 +07:00
ChanceSD
14b0f1be0c Fix PvPManager integration 2023-05-18 22:42:49 +01:00
Auxilor
af20bb315b Updated to 6.60.3 2023-05-18 15:35:54 +01:00
Auxilor
6645e216d5 Fixed stupid profile saver bug 2023-05-18 15:35:47 +01:00
Auxilor
eddf240f0c Updated to 6.60.2 2023-05-18 14:33:21 +01:00
Auxilor
4f406353ba Fixed data bug 2023-05-18 14:33:14 +01:00
Auxilor
095494dd2e Fixed PersistentDataKeyType.BIG_DECIMAL and javadoc 2023-05-17 18:39:48 +01:00
Auxilor
fd92645500 Updated to 6.60.1 2023-05-17 17:27:00 +01:00
Auxilor
1a6ac29083 Fixed PersistentDataKeyType.BIG_DECIMAL 2023-05-17 17:26:48 +01:00
Auxilor
7edc00d459 Added createTasks 2023-05-16 14:50:02 +01:00
Auxilor
a51bad058f Updated to 6.60.0 2023-05-16 14:47:06 +01:00
Auxilor
89ebb8ba59 Updated to 6.59.1 2023-05-15 17:43:03 +01:00
Auxilor
f0ae8f4f84 Fixed DelegatedBukkitCommand (again) 2023-05-15 17:42:49 +01:00
Auxilor
7d6cf78442 Cleanup 2023-05-15 16:38:33 +01:00
Auxilor
780d8f3b86 Fixed DefaultMap 2023-05-15 16:33:58 +01:00
Auxilor
146a0130f9 Fixed DefaultMap 2023-05-15 16:33:32 +01:00
Auxilor
df8c3411cb Updated to 6.59.0 2023-05-15 12:06:56 +01:00
Auxilor
4fc3c22a7d Added PersistentDataKeyType#BIG_DECIMAL 2023-05-15 12:05:37 +01:00
Auxilor
cfc4808bb8 Updated to 6.58.1 2023-05-14 16:36:05 +01:00
Auxilor
4ac6325a41 Fixed T?.toSingletonList() 2023-05-14 16:35:56 +01:00
Auxilor
4aed33751d EcoPlugin#afterLoad now runs 2 ticks after, with a preliminary reload 1 tick after startup to fix load order bugs 2023-05-13 17:43:31 +01:00
Auxilor
3fe1c2c69f Added EcoPlugin#cancelsTasksOnReload 2023-05-13 12:10:08 +01:00
Auxilor
5feaa84b2c Revert "Probably janky solution to command aliases"
This reverts commit 862b588c8d.
2023-05-12 16:57:12 +01:00
Auxilor
d8793bc2bb Fixed command aliases 2023-05-12 16:54:03 +01:00
Auxilor
15c512f3ca Cleanup 2023-05-12 15:40:28 +01:00
Auxilor
15ff2fb1d6 Fixed registry locks 2023-05-12 15:39:51 +01:00
Auxilor
862b588c8d Probably janky solution to command aliases 2023-05-12 15:37:29 +01:00
Auxilor
3c2a99b5f4 Added MenuBuilder#defaultPage 2023-05-12 14:53:44 +01:00
Auxilor
2d23c05c47 Added kotlin extensions to NumberUtils methods 2023-05-12 14:26:00 +01:00
Auxilor
8fc55d3393 Merge remote-tracking branch 'origin/develop' into develop 2023-05-12 13:53:45 +01:00
Auxilor
5900a756e4 Added margin options to line wrapping 2023-05-12 13:53:38 +01:00
Auxilor
c18b85f223 AAAAAAA 2023-05-12 13:53:16 +01:00
Auxilor
85116108c2 Oops 2023-05-12 13:47:47 +01:00
Auxilor
044f141bd0 Added margin options to line wrapping 2023-05-12 13:45:21 +01:00
Auxilor
9ca7f99fdb Added StringUtils#lineWrap kotlin extensions 2023-05-12 13:28:21 +01:00
Auxilor
7aa7770a3e Added StringUtils#lineWrap for lists 2023-05-12 13:27:13 +01:00
Auxilor
10202917fa Added StringUtils#lineWrap to wrap strings while preserving formatting 2023-05-11 17:24:05 +01:00
Auxilor
43df79e3b1 Fixed captive slots not forcing a re-render on shift click 2023-05-10 16:03:29 +01:00
Auxilor
5ef244f0bc Added option to store plugin data locally, even if eco is set to use a database 2023-05-10 15:19:15 +01:00
Auxilor
861f076c11 Updated to 6.58.0 2023-05-10 14:52:52 +01:00
Auxilor
7bed43059f Added Slot#shouldRenderOnClick 2023-05-08 18:39:27 +01:00
Auxilor
37e271c96c More optimisations to EcoConfig 2023-05-04 14:32:52 +01:00
Auxilor
3dad48e24d Updated to 6.57.2 2023-05-03 23:45:01 +01:00
Auxilor
ae77e4810b Digsusting hacks to optimise eval pipeline 2023-05-03 23:44:53 +01:00
Auxilor
3d50e37c37 Merge branch 'master' into develop 2023-05-03 23:01:41 +01:00
Auxilor
421fd3bd04 Finally removed LegacyMySQLDataHandler 2023-05-03 16:03:36 +01:00
Auxilor
5ecae0a366 Updated to 6.57.1 2023-05-03 14:19:01 +01:00
Auxilor
5de4914fd7 Fixed expression loading, improved hash codes down evaluation pipeline 2023-05-03 14:18:50 +01:00
Auxilor
0f9bf094ae Ignore case 2023-05-02 18:47:54 +01:00
Auxilor
e67680f397 Improved PlaceholderAPI 2023-05-02 17:39:15 +01:00
Auxilor
73c0a5d655 Fixed more stupidity 2023-05-02 17:17:41 +01:00
Auxilor
220ed26f4a Fixed stupidity 2023-05-02 17:14:03 +01:00
Auxilor
edf2ea41c7 Cleaned up RECIPE ERROR message to be nicer 2023-05-02 16:13:33 +01:00
Auxilor
16859b8ce5 Revert "Temporarily disabled Wolfyscript"
This reverts commit f973281dd9.
2023-05-02 15:01:01 +01:00
Auxilor
10fe7d190a Clean 2023-05-02 14:58:25 +01:00
Auxilor
60a1f2429c Added plugin-version and plugin to extension.yml 2023-05-02 14:26:53 +01:00
Auxilor
cc6dc1e67c Improved PAPI expansion 2023-05-02 13:57:23 +01:00
Auxilor
f4f5941691 Fixed duplicate config placeholder bug 2023-05-02 13:56:10 +01:00
Auxilor
f973281dd9 Temporarily disabled Wolfyscript 2023-05-02 13:55:50 +01:00
Auxilor
8acd76f363 Updated to 6.57.0 2023-05-01 19:53:45 +01:00
Auxilor
4a165a86dc Added PluginLike#getFile 2023-05-01 19:53:37 +01:00
Auxilor
43b7c393b9 Cleaned up data desync PR 2023-04-29 15:52:13 +01:00
Auxilor
714952bc45 PR Cleanup 2023-04-29 15:47:42 +01:00
Will FP
322e179b81 Merge pull request #269
Add PlayerPoints to prices system
2023-04-29 15:43:54 +01:00
Auxilor
469be73ada Added option to translate placeholders without a context 2023-04-29 15:03:02 +01:00
Auxilor
7eac60146f Added placeholderContext#copy 2023-04-29 13:44:03 +01:00
Auxilor
ad0223e1bb Cleaned up PlaceholderContext 2023-04-29 13:22:18 +01:00
BuildTools
430117f342 Add PlayerPoints to prices system 2023-04-29 10:20:53 +07:00
Auxilor
fa87cae81e Clarified PlaceholderParser 2023-04-28 19:59:13 +01:00
Auxilor
5695750fc5 Optimised additional player placeholder parsing 2023-04-28 17:05:40 +01:00
Auxilor
45e8a57880 Fixed DynamicInjectablePlaceholder 2023-04-28 16:24:34 +01:00
Auxilor
17fcd2c1b5 Added DynamicPlaceholder and DynamicInjectablePlaceholder 2023-04-28 16:24:18 +01:00
Auxilor
0c1e17c351 Massively optimised placeholder parsing with ListViewOfCollection 2023-04-28 16:11:21 +01:00
Auxilor
9415515849 Simplified enable logs 2023-04-28 14:34:30 +01:00
Auxilor
d0e957ea37 Cleaned up imports 2023-04-28 14:23:44 +01:00
Will FP
69514e2f85 Merge pull request #268
Denizen Integration
2023-04-28 14:22:29 +01:00
FireML
259e35c978 Script Name Alternative 2023-04-28 00:47:01 +01:00
FireML
40aec26f15 Initial Denizen Support 2023-04-27 23:03:34 +01:00
Auxilor
67b2fdd594 Merge branch 'master' into develop
# Conflicts:
#	gradle.properties
2023-04-27 19:27:57 +01:00
Auxilor
83f86983f6 Updated to 6.55.4 2023-04-27 19:22:30 +01:00
Auxilor
3ba98a9a5e Fixed UltraEconomy 2023-04-27 19:22:20 +01:00
Auxilor
f19e565fbe Moved to native fastToDoubleOrNull function 2023-04-27 19:08:10 +01:00
Auxilor
ee3ecb643b Cleanup 2023-04-27 18:55:03 +01:00
Auxilor
3aefb0e481 Switched back to ConcurrentHashMap in EcoConfig 2023-04-27 18:04:02 +01:00
Auxilor
d9eb1e1c26 Merge branch 'fix-data-desync' into develop 2023-04-27 18:02:09 +01:00
Auxilor
70631e67c5 Config injections no longer use a ConcurrentHashMap 2023-04-27 15:51:16 +01:00
Auxilor
82797e7342 Rewrote placeholder parsing 2023-04-27 15:42:46 +01:00
Auxilor
d2917341b1 Removed use-lower-protocollib-priority 2023-04-26 20:31:53 +01:00
Auxilor
760f42be0c Refactor, made math cache TTL configurable 2023-04-26 20:31:44 +01:00
Auxilor
bb01af2ab2 Optimised StringUtils#replaceQuickly 2023-04-26 18:22:56 +01:00
Auxilor
517d890c05 More optimisations to evaluation pipeline 2023-04-26 17:37:31 +01:00
Auxilor
f02fc56778 Added alternate crunch evaluation option 2023-04-26 16:55:40 +01:00
Auxilor
4417b09c14 Various optimisations along the evaluation pipeline 2023-04-26 16:10:04 +01:00
Auxilor
6b37fafa90 Further simplified Config 2023-04-26 15:25:50 +01:00
Auxilor
f8c5c9f06d Revert "Added KPlaceholderContext"
This reverts commit 0fd6cbaa08.
2023-04-26 15:02:05 +01:00
Auxilor
0fd6cbaa08 Added KPlaceholderContext 2023-04-26 14:58:48 +01:00
Auxilor
81afa32eb0 Added placeholderContext kotlin builder 2023-04-26 14:47:40 +01:00
Auxilor
7387fe2332 Improved default config methods 2023-04-26 14:44:13 +01:00
Auxilor
80fa05da98 Added PlaceholderContext#copyWithItem 2023-04-26 14:07:22 +01:00
Auxilor
77754249ad Added SimplePlaceholder and SimpleInjectablePlaceholder 2023-04-26 13:23:29 +01:00
Auxilor
1843cf0f8a PlaceholderManager#translatePlaceholders now includes injections 2023-04-26 13:13:59 +01:00
Auxilor
05eb5ee993 Rewrote more placeholder backend, deprecated MathContext 2023-04-26 13:07:18 +01:00
Auxilor
7bc11ee716 Added new format options 2023-04-25 19:19:43 +01:00
Auxilor
f566aec00e PlaceholderContext now extends MathContext 2023-04-25 19:11:15 +01:00
Auxilor
36d47c55a1 Updated to 6.56.0 2023-04-25 18:57:22 +01:00
Auxilor
40463213ac Added PlaceholderContext as a unified way to parse placeholders 2023-04-25 18:57:06 +01:00
Auxilor
6ec80d30ad Updated to 6.55.3 2023-04-25 10:28:38 +01:00
Auxilor
7ccee60a0c Fixed IntegrationRegistry#executeSafely 2023-04-25 10:28:23 +01:00
Auxilor
0805b48763 Updated to 6.55.2 2023-04-24 22:12:47 +01:00
Auxilor
d737322aaa Merge remote-tracking branch 'origin/master'
# Conflicts:
#	gradle.properties
2023-04-24 22:12:19 +01:00
Auxilor
4ddc150e1c Updated to 6.54.1 2023-04-24 22:11:55 +01:00
Auxilor
0da119d89d Finally reimplemented BlockUtils#getVein 2023-04-24 22:10:42 +01:00
Auxilor
fc0a07d1c5 Config injections now use a ConcurrentHashMap 2023-04-24 22:05:37 +01:00
Cyramek
4ce2850138 fix data desync 2023-04-23 14:35:17 +02:00
Auxilor
58316c2a06 Fixed locale bug with Registry 2023-04-20 20:32:07 +01:00
Auxilor
d96ad10960 Added locker to registry 2023-04-20 19:27:52 +01:00
Auxilor
21283b0928 Added ExternalDataStoreObjectAdapter 2023-04-20 19:19:00 +01:00
Auxilor
2797687f01 Cleanup 2023-04-20 17:54:23 +01:00
Auxilor
9c68d1fbc3 Merge branch 'master' into develop
# Conflicts:
#	eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/integrations/customitems/CustomItemsOraxen.kt
2023-04-20 17:45:06 +01:00
Auxilor
9371d9b88d Upstream 2023-04-20 17:44:58 +01:00
Auxilor
14e2ead488 Fixed javadoc, updated Kingdoms 2023-04-20 17:42:46 +01:00
Auxilor
5473bb8ef8 Cleaned up IntegrationRegistry 2023-04-20 17:34:18 +01:00
Auxilor
90c55849ae Isolated integration registration 2023-04-20 17:24:56 +01:00
Auxilor
9809140cf9 Isolated remaining integrations 2023-04-20 17:23:24 +01:00
Auxilor
49a82dc005 Isolated ShopManager 2023-04-20 17:15:18 +01:00
Auxilor
92dec03b9a Added IntegrationRegistry 2023-04-20 17:09:46 +01:00
Auxilor
7453c70b87 Fixed imports 2023-04-20 16:52:49 +01:00
Auxilor
3038ea43d0 Updated to 6.55.0 2023-04-20 16:51:11 +01:00
Auxilor
3c6ddd8255 Added OutdatedEcoVersionError 2023-04-20 16:50:35 +01:00
Auxilor
925ee04cc1 Added Version as a cross-version compatible version of DefaultArtifactVersion 2023-04-20 16:48:20 +01:00
Auxilor
6f7de8716b Added KRegistrable 2023-04-20 16:41:35 +01:00
Auxilor
a17b951a8b Made registry lockable and iterable 2023-04-20 16:40:06 +01:00
Auxilor
f003ed06a8 Fixed imports 2023-04-19 18:00:19 +01:00
Auxilor
f864953da2 Updated to 6.54.1 2023-04-19 17:38:22 +01:00
Auxilor
6ef31444ac Removed Checkstyle CI, cleaned up Oraxen PR 2023-04-19 17:38:09 +01:00
Will FP
99258116de Merge pull request #264 from MCCasper/master
fix oraxen and SNBT
2023-04-19 12:33:14 -04:00
casper
a59c68102e fix SNBT matching the same tag for diff materials 2023-04-19 11:09:26 -05:00
casper
2482525fe2 load oraxen later 2023-04-18 22:23:49 -05:00
Auxilor
acb326c0c8 Updated to 6.54.0 2023-04-13 12:13:32 -04:00
Auxilor
11d947e24b Updated to 6.53.2 2023-04-13 12:09:14 -04:00
Auxilor
3cced3012c Added Prerequisite#HAS_1_19_4 2023-04-13 11:59:04 -04:00
Auxilor
520523e903 Isolated integration loading 2023-04-13 11:57:49 -04:00
Auxilor
ee36cc74f8 Improved lifecycle error logging 2023-04-13 11:50:32 -04:00
Auxilor
55344e0550 Improved lifecycle error handling, isolated tasks 2023-04-13 11:49:43 -04:00
Auxilor
75f6f05c7d Merge branch 'master' into develop 2023-03-30 14:05:09 +01:00
Auxilor
17fa519501 Revert "Fixed ContinuallyAppliedPersistentDataContainer"
This reverts commit 1852ff86ec.
2023-03-30 14:04:43 +01:00
Auxilor
1a72cf3ca9 Revert "Updated to 6.53.2"
This reverts commit d11f355c44.
2023-03-30 14:04:43 +01:00
Auxilor
d11f355c44 Updated to 6.53.2 2023-03-30 12:08:37 +01:00
Auxilor
1852ff86ec Fixed ContinuallyAppliedPersistentDataContainer 2023-03-30 12:08:26 +01:00
Auxilor
ffe9219f45 Changed README to show repo.auxilor.io 2023-03-29 13:33:24 +01:00
Auxilor
f67a5d3b3d Added repo.auxilor.io 2023-03-29 13:30:15 +01:00
Auxilor
bbd541abe0 Added repo.auxilor.io 2023-03-29 13:21:40 +01:00
Auxilor
3de8d0fed9 Updated to 6.53.1 2023-03-28 17:13:04 +01:00
Auxilor
df4abe39eb Fixed tab completion for dynamically registered commands 2023-03-28 17:12:54 +01:00
Auxilor
f5e289966f Fixed tab completion for dynamically registered commands 2023-03-28 17:12:35 +01:00
Auxilor
bcfa4bd82e Added json() extension 2023-03-25 17:48:27 +00:00
Auxilor
229c9e58c3 Merge branch 'develop'
# Conflicts:
#	eco-api/src/main/java/com/willfp/eco/core/config/TransientConfig.java
#	eco-core/core-nms/nms-common/src/main/kotlin/com/willfp/eco/internal/spigot/proxy/common/packet/PacketInjectorListener.kt
#	gradle.properties
2023-03-25 15:34:47 +00:00
Auxilor
4f30a6e04e Removed all forRemoval classes / methods deprecated since before 6.43.0 2023-03-20 12:52:41 +00:00
Auxilor
9ea45ee0d0 Updated EcoPlugin#getID 2023-03-19 22:24:02 +00:00
Auxilor
192316214d Added Items.matchesAny 2023-03-19 22:08:47 +00:00
Auxilor
feb8898a87 Added default values to ExternalDataStore.get 2023-03-19 22:03:21 +00:00
Auxilor
1e64815e47 Added Registry.tryFitPattern 2023-03-19 22:00:42 +00:00
Auxilor
dc10648c25 Fixed DefaultMap and ListMap, adding tasks to lifecycle events, and packet injection 2023-03-19 17:39:20 +00:00
Auxilor
70131a6cae Added logging for invalid registry IDs 2023-03-18 15:22:20 +00:00
Auxilor
6d23cc7141 Fixed Registry#clear 2023-03-18 15:17:41 +00:00
Auxilor
473202527a Fixed EntityDeathByEntityEvent for WildStacker users 2023-03-17 21:23:54 +00:00
Auxilor
bc24aaeb3c Fixed 1.19.4 support
(cherry picked from commit ad47b7898e)
2023-03-15 21:10:33 +00:00
Auxilor
52072bd935 Added 1.19.4 support
(cherry picked from commit cb3ccbb39a)
2023-03-15 21:10:33 +00:00
Auxilor
ad47b7898e Fixed 1.19.4 support 2023-03-15 21:06:02 +00:00
Auxilor
19d6533db6 Updated to 6.52.3 2023-03-15 21:05:15 +00:00
Auxilor
3a37d40271 Fixed missing channel bug 2023-03-15 21:02:05 +00:00
Auxilor
cb3ccbb39a Added 1.19.4 support 2023-03-15 21:02:01 +00:00
Auxilor
5c3bb678b3 Updated backend paper version 2023-03-15 18:20:46 +00:00
Auxilor
4f4ee82e6b Converted remaining groovy buildscripts to kotlin 2023-03-14 19:46:12 +00:00
Auxilor
32d88f55f8 Fixed environment variables 2023-03-14 17:18:05 +00:00
Auxilor
bc8d615079 Added environment variables, moved eco.yml components around, added option to disable reflective reload, moved eco to be a paper plugin 2023-03-14 16:35:30 +00:00
Auxilor
55b7c3c16f Added ExternalDataStore 2023-03-14 12:45:35 +00:00
Auxilor
9535986f59 Fixed EcoPlugin#getID 2023-03-14 12:25:29 +00:00
Auxilor
fb17fc1383 Fixed annotation mismatch 2023-03-13 15:24:51 +00:00
Auxilor
4221368388 Made EcoPlugin registrable 2023-03-13 15:18:21 +00:00
Auxilor
d4432d0cb8 Updated to 6.53.0 2023-03-13 14:31:19 +00:00
Auxilor
f9093c2ed6 Added LifecyclePosition 2023-03-13 14:23:28 +00:00
Auxilor
15f4d5c098 Fixed missing channel bug 2023-03-13 13:35:51 +00:00
Auxilor
dc47bc7995 Updated Placeholder API, added ability to parse placeholders without PAPI installed 2023-03-11 17:08:50 +00:00
Auxilor
29ce0deb1b Merge remote-tracking branch 'origin/develop' into develop 2023-02-27 19:19:21 +00:00
Auxilor
fd78402bf5 Updated to 6.52.2 2023-02-27 19:19:18 +00:00
Will FP
5f65e3f520 Merge pull request #248
Yet another economyshopgui fix
2023-02-27 19:19:06 +00:00
0ft3n
ceaf4d34a5 Yet another economyshopgui fix 2023-02-27 22:13:02 +03:00
Auxilor
2d2e5f8150 Updated to 6.52.1 2023-02-27 17:00:24 +00:00
Auxilor
323a4aefef Fixed ListMap overload resolution ambiguity for kotlin 2023-02-27 17:00:15 +00:00
Auxilor
af486580c1 Updated to 6.52.0 2023-02-27 16:31:19 +00:00
Auxilor
7955a94f14 Added missing annotations 2023-02-25 19:03:18 +00:00
Auxilor
c99a1bd50a loadListeners is no longer abstract 2023-02-25 19:02:14 +00:00
Auxilor
93364247de Merge branch 'master' into develop 2023-02-25 14:49:15 +00:00
Auxilor
49612eddcb Updated to 6.51.4 2023-02-24 14:02:16 +00:00
Auxilor
834c29f843 Fixed placeholder bug with additional players, prevented NaN being evaluated by crunch 2023-02-24 14:02:04 +00:00
Auxilor
a806ac039d Added regex validation for Ids 2023-02-23 21:15:12 +00:00
Auxilor
0ca2651af0 Added ListMap#append 2023-02-23 21:07:04 +00:00
Auxilor
6157fdcfa1 Improved DefaultMap 2023-02-23 21:04:01 +00:00
Auxilor
36cfcd24c2 Added DefaultMap 2023-02-23 20:51:21 +00:00
Auxilor
d4558db40c Added registry 2023-02-23 18:33:28 +00:00
Auxilor
3f8448fee1 Updated to 6.51.3 2023-02-18 12:26:39 +00:00
Auxilor
8b6e15457c Fixed clearing entity goals on 1.19+ 2023-02-18 12:26:32 +00:00
Auxilor
b99e822db3 Updated to 6.51.2 2023-02-16 16:16:08 +00:00
Auxilor
02f8d33a81 Hot'fix' 2023-02-16 16:16:01 +00:00
Auxilor
76042bea68 Updated to 6.51.1 2023-02-15 15:28:52 +00:00
Auxilor
51ad09c536 Fixed bug with polymart 2023-02-15 15:28:42 +00:00
Auxilor
264c591020 Fixed readme again 2023-02-15 13:49:01 +00:00
Auxilor
6bd3ca0f5c Updated README 2023-02-15 13:48:07 +00:00
Auxilor
98df14a23a Fixed javadoc 2023-02-15 13:43:46 +00:00
Auxilor
ccb6e38064 Cleaned up entity / target goal code 2023-02-15 13:07:16 +00:00
Auxilor
50f1ba6a19 Fix 2023-02-15 12:55:16 +00:00
Auxilor
501e7b05a6 Fucksake, reverted my bugfixes 2023-02-14 20:21:12 +00:00
Auxilor
ebf8abf764 Oops 2023-02-14 20:09:56 +00:00
Auxilor
aff8fa8e88 Javadoc 2023-02-14 20:07:12 +00:00
Auxilor
1accad88fe Added GUI Detection system with DeluxeMenus support 2023-02-14 20:00:39 +00:00
Auxilor
a3a5e4df38 Fixed packet injector 2023-02-14 17:42:52 +00:00
Auxilor
6e8dc1d729 Packet refactor 2023-02-14 17:26:01 +00:00
Auxilor
a8556008f9 Fixed EcoPlugin compiler warnings 2023-02-14 16:53:45 +00:00
Auxilor
ab18a8bd29 Updated to 6.51.0 2023-02-14 16:49:16 +00:00
Auxilor
a053f512f8 Moved away from ProtocolLib 2023-02-14 16:49:04 +00:00
Auxilor
add5390787 Removed ProtocolLib dependency 2023-02-14 12:29:55 +00:00
Auxilor
49687f9a91 Updated to 6.50.3 2023-02-05 16:32:56 +00:00
Auxilor
5480c70f8c Fixed dynamic commands 2023-02-05 16:32:48 +00:00
Auxilor
ef922f6d3f Fixed dynamic commands 2023-01-31 18:58:05 +00:00
Auxilor
026bc55ffb Updated to 6.50.2 2023-01-31 18:35:17 +00:00
Will FP
270fdbb18c Merge pull request #238
Update oraxen dependency
2023-01-31 18:35:02 +00:00
casper
fbf5967d17 Update oraxen dependency 2023-01-31 12:21:41 -06:00
Auxilor
4102be1201 Updated to 6.50.1 2023-01-27 17:47:21 +00:00
Will FP
f6bdb9cc65 Merge pull request #236 from 0ft3n/develop
Fixed fix
2023-01-27 17:46:19 +00:00
Will FP
c8282d1acf Merge branch 'develop' into develop 2023-01-27 17:46:13 +00:00
_OfTeN_
b056b537ef Fixed fix x2 2023-01-27 20:31:00 +03:00
_OfTeN_
f69b458731 Fixed fix 2023-01-27 19:48:28 +03:00
Auxilor
b035fa8940 Changed deprecations 2023-01-27 12:52:55 +00:00
Auxilor
25c087592d Cached placeholder lookups 2023-01-27 12:45:57 +00:00
Auxilor
083cb39771 Cleanups, fixes 2023-01-27 12:20:51 +00:00
Auxilor
eb3e0f5c09 Updated to 6.50.0 2023-01-27 12:18:01 +00:00
Auxilor
08f43ddafd Added dynamic placeholders 2023-01-27 12:17:51 +00:00
Auxilor
9d3efb5e83 Imports, often. Imports 2023-01-27 11:50:50 +00:00
Auxilor
8a5d1a604a Updated to 6.49.2 2023-01-27 11:46:15 +00:00
Auxilor
ef67c6d6ae Merge branch 'develop' 2023-01-27 11:45:42 +00:00
Auxilor
5b2654db15 Merge remote-tracking branch 'origin/master' 2023-01-27 11:45:18 +00:00
Will FP
eccd793317 Merge pull request #235 from Baterka/master
Fix Prices evaluation if they include player placeholders
2023-01-27 11:43:56 +00:00
Will FP
1bc44755a0 Merge pull request #234 from 0ft3n/develop
EconomyShopGUI integration fixes
2023-01-27 11:35:39 +00:00
Baterka
ec606d9ebe Fix Prices evaluation if they include player placeholders 2023-01-27 03:04:48 +01:00
_OfTeN_
c5556f15ab Attempted to fix Lands integration 2023-01-27 04:54:09 +03:00
_OfTeN_
399cce21f5 EconomyShopGUI integration fixes 2023-01-27 04:48:18 +03:00
Auxilor
b25feffdfa Codestyle 2023-01-24 13:54:59 +00:00
317 changed files with 7418 additions and 3653 deletions

View File

@@ -1,15 +0,0 @@
name: Check PR Codestyle
on: [ pull_request ]
jobs:
checkstyle:
name: Checkstyle
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: dbelyaev/action-checkstyle@v0.5.1
with:
github_token: ${{ secrets.github_token }}
reporter: github-pr-review
level: warning
checkstyle_config: ../../config/checkstyle/checkstyle.xml

View File

@@ -28,6 +28,8 @@ jobs:
- name: Publish artifact - name: Publish artifact
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}
# The GITHUB_REF tag comes in the format 'refs/tags/xxx'. # The GITHUB_REF tag comes in the format 'refs/tags/xxx'.
# So if we split on '/' and take the 3rd value, we can get the release name. # So if we split on '/' and take the 3rd value, we can get the release name.

View File

@@ -31,6 +31,7 @@ eco comes packed with all the tools you need in your plugins:
- Yaml/JSON/TOML config system - Yaml/JSON/TOML config system
- Persistent data storage API with Yaml/MySQL/MongoDB support - Persistent data storage API with Yaml/MySQL/MongoDB support
- Packet item display system - Packet item display system
- Lightweight event loop based packet API
- Entity AI API with near-1:1 NMS mappings - Entity AI API with near-1:1 NMS mappings
- More events - More events
- Extension API, essentially plugins for plugins - Extension API, essentially plugins for plugins
@@ -52,7 +53,6 @@ eco comes packed with all the tools you need in your plugins:
- And much more - And much more
# For server owners # For server owners
- Requires ProtocolLib to be installed: get the latest version [here](https://www.spigotmc.org/resources/protocollib.1997/)
- Supports 1.17+ - Supports 1.17+
## Downloads ## Downloads
@@ -63,7 +63,7 @@ eco comes packed with all the tools you need in your plugins:
# For developers # For developers
## Javadoc ## Javadoc
The 6.49.0 Javadoc can be found [here](https://javadoc.jitpack.io/com/willfp/eco/6.49.0/javadoc/) The 6.53.0 Javadoc can be found [here](https://javadoc.jitpack.io/com/willfp/eco/6.53.0/javadoc/)
## Plugin Information ## Plugin Information
@@ -75,31 +75,31 @@ depend:
- eco - eco
``` ```
## Get from JitPack: ## Dependency Information:
Gradle: Gradle:
```groovy ```kts
repositories { repositories {
maven { url 'https://jitpack.io' } maven("https://repo.auxilor.io/repository/maven-public/")
} }
``` ```
```groovy ```groovy
dependencies { dependencies {
compileOnly 'com.willfp:eco:Tag' compileOnly("com.willfp:eco:Tag")
} }
``` ```
Replace `Tag` with a release tag for eco, eg `6.49.0`. Replace `Tag` with a release tag for eco, eg `6.53.0`.
Maven: Maven:
```xml ```xml
<repository> <repository>
<id>jitpack.io</id> <id>auxilor</id>
<url>https://jitpack.io</url> <url>https://repo.auxilor.io/repository/maven-public/</url>
</repository> </repository>
``` ```
@@ -112,7 +112,7 @@ Maven:
</dependency> </dependency>
``` ```
Replace `Tag` with a release tag for eco, eg `6.49.0`. Replace `Tag` with a release tag for eco, eg `6.53.0`.
## Build locally: ## Build locally:

View File

@@ -26,6 +26,7 @@ dependencies {
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")) implementation(project(path = ":eco-core:core-nms:v1_19_R1", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_19_R2", configuration = "reobf")) implementation(project(path = ":eco-core:core-nms:v1_19_R2", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_19_R3", configuration = "reobf"))
} }
allprojects { allprojects {
@@ -56,7 +57,7 @@ allprojects {
maven("https://repo.extendedclip.com/content/repositories/placeholderapi/") maven("https://repo.extendedclip.com/content/repositories/placeholderapi/")
// ProtocolLib // ProtocolLib
maven("https://repo.dmulloy2.net/nexus/repository/public/") //maven("https://repo.dmulloy2.net/nexus/repository/public/")
// WorldGuard // WorldGuard
maven("https://maven.enginehub.org/repo/") maven("https://maven.enginehub.org/repo/")
@@ -79,7 +80,14 @@ allprojects {
// LibsDisguises // LibsDisguises
maven("https://repo.md-5.net/content/groups/public/") maven("https://repo.md-5.net/content/groups/public/")
// UltraEconomy
maven("https://repo.techscode.com/repository/maven-releases/") maven("https://repo.techscode.com/repository/maven-releases/")
// PlayerPoints
maven("https://repo.rosewooddev.io/repository/public/")
// Denizen
maven("https://maven.citizensnpcs.co/repo")
} }
dependencies { dependencies {

View File

@@ -1,38 +0,0 @@
dependencies {
// Adventure
compileOnly 'net.kyori:adventure-platform-bukkit:4.1.0'
// Other
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
compileOnly 'com.comphenix.protocol:ProtocolLib:4.6.1-SNAPSHOT'
compileOnly 'com.google.code.gson:gson:2.8.8'
}
group 'com.willfp'
version rootProject.version
java {
withJavadocJar()
}
build.dependsOn publishToMavenLocal
publishing {
publications {
shadow(MavenPublication) {
from components.java
artifactId 'eco'
}
}
repositories {
maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/Auxilor/eco")
credentials {
username = System.getenv("GITHUB_ACTOR")
password = System.getenv("GITHUB_TOKEN")
}
}
}
}

55
eco-api/build.gradle.kts Normal file
View File

@@ -0,0 +1,55 @@
dependencies {
// Adventure
compileOnly("net.kyori:adventure-platform-bukkit:4.1.0")
// Other
compileOnly("org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT")
compileOnly("com.comphenix.protocol:ProtocolLib:4.6.1-SNAPSHOT")
compileOnly("com.google.code.gson:gson:2.8.8")
}
group = "com.willfp"
version = rootProject.version
java {
withJavadocJar()
}
tasks {
build {
dependsOn(publishToMavenLocal)
}
}
publishing {
publications {
create<MavenPublication>("shadow") {
from(components["java"])
artifactId = "eco"
}
}
repositories {
maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/Auxilor/eco")
credentials {
username = System.getenv("GITHUB_ACTOR")
password = System.getenv("GITHUB_TOKEN")
}
}
}
publishing {
repositories {
maven {
name = "Auxilor"
url = uri("https://repo.auxilor.io/repository/maven-releases/")
credentials {
username = System.getenv("MAVEN_USERNAME")
password = System.getenv("MAVEN_PASSWORD")
}
}
}
}
}

View File

@@ -13,27 +13,30 @@ import java.util.Collections;
/** /**
* Wrapper class for ProtocolLib packets. * Wrapper class for ProtocolLib packets.
*
* @deprecated ProtocolLib is no longer used by eco. Use {@link com.willfp.eco.core.packet.PacketListener} instead.
*/ */
@Deprecated(since = "6.51.0")
public abstract class AbstractPacketAdapter extends PacketAdapter { public abstract class AbstractPacketAdapter extends PacketAdapter {
/** /**
* The packet type to listen for. * The handle type to listen for.
*/ */
private final PacketType type; private final PacketType type;
/** /**
* Whether the packet adapter should be registered after the server has loaded. * Whether the handle adapter should be registered after the server has loaded.
* <p> * <p>
* Useful for monitor priority adapters that <b>must</b> be ran last. * Useful for monitor priority adapters that <b>must</b> be ran last.
*/ */
private final boolean postLoad; private final boolean postLoad;
/** /**
* Create a new packet adapter for a specified plugin and type. * Create a new handle adapter for a specified plugin and type.
* *
* @param plugin The plugin that ProtocolLib should mark as the owner. * @param plugin The plugin that ProtocolLib should mark as the owner.
* @param type The {@link PacketType} to listen for. * @param type The {@link PacketType} to listen for.
* @param priority The priority at which the adapter should be ran on packet send/receive. * @param priority The priority at which the adapter should be ran on handle send/receive.
* @param postLoad If the packet adapter should be registered after the server has loaded. * @param postLoad If the handle adapter should be registered after the server has loaded.
*/ */
protected AbstractPacketAdapter(@NotNull final EcoPlugin plugin, protected AbstractPacketAdapter(@NotNull final EcoPlugin plugin,
@NotNull final PacketType type, @NotNull final PacketType type,
@@ -45,11 +48,11 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
} }
/** /**
* Create a new packet adapter for a specified plugin and type. * Create a new handle adapter for a specified plugin and type.
* *
* @param plugin The plugin that ProtocolLib should mark as the owner. * @param plugin The plugin that ProtocolLib should mark as the owner.
* @param type The {@link PacketType} to listen for. * @param type The {@link PacketType} to listen for.
* @param postLoad If the packet adapter should be registered after the server has loaded. * @param postLoad If the handle adapter should be registered after the server has loaded.
*/ */
protected AbstractPacketAdapter(@NotNull final EcoPlugin plugin, protected AbstractPacketAdapter(@NotNull final EcoPlugin plugin,
@NotNull final PacketType type, @NotNull final PacketType type,
@@ -58,9 +61,9 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
} }
/** /**
* The code that should be executed once the packet has been received. * The code that should be executed once the handle has been received.
* *
* @param packet The packet. * @param packet The handle.
* @param player The player. * @param player The player.
* @param event The event. * @param event The event.
*/ */
@@ -71,9 +74,9 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
} }
/** /**
* THe code that should be executed once the packet has been sent. * THe code that should be executed once the handle has been sent.
* *
* @param packet The packet. * @param packet The handle.
* @param player The player. * @param player The player.
* @param event The event. * @param event The event.
*/ */
@@ -84,7 +87,7 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
} }
/** /**
* Boilerplate to assert that the packet is of the specified type. * Boilerplate to assert that the handle is of the specified type.
* *
* @param event The ProtocolLib event. * @param event The ProtocolLib event.
*/ */
@@ -102,7 +105,7 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
} }
/** /**
* Boilerplate to assert that the packet is of the specified type. * Boilerplate to assert that the handle is of the specified type.
* *
* @param event The ProtocolLib event. * @param event The ProtocolLib event.
*/ */
@@ -125,7 +128,7 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
} }
/** /**
* Register the packet adapter with ProtocolLib. * Register the handle adapter with ProtocolLib.
*/ */
public final void register() { public final void register() {
if (!ProtocolLibrary.getProtocolManager().getPacketListeners().contains(this)) { if (!ProtocolLibrary.getProtocolManager().getPacketListeners().contains(this)) {
@@ -134,7 +137,7 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
} }
/** /**
* Get if the packet adapter should be loaded last. * Get if the handle adapter should be loaded last.
* *
* @return If post load. * @return If post load.
*/ */

View File

@@ -25,14 +25,14 @@ import com.willfp.eco.core.gui.menu.MenuType;
import com.willfp.eco.core.gui.slot.SlotBuilder; import com.willfp.eco.core.gui.slot.SlotBuilder;
import com.willfp.eco.core.gui.slot.functional.SlotProvider; import com.willfp.eco.core.gui.slot.functional.SlotProvider;
import com.willfp.eco.core.items.TestableItem; import com.willfp.eco.core.items.TestableItem;
import com.willfp.eco.core.math.MathContext; import com.willfp.eco.core.packet.Packet;
import com.willfp.eco.core.placeholder.context.PlaceholderContext;
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;
import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.command.CommandMap;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Mob; import org.bukkit.entity.Mob;
@@ -135,6 +135,14 @@ public interface Eco {
@NotNull @NotNull
Logger createLogger(@NotNull EcoPlugin plugin); Logger createLogger(@NotNull EcoPlugin plugin);
/**
* Get NOOP logger.
*
* @return The logger.
*/
@NotNull
Logger getNOOPLogger();
/** /**
* Create a PAPI integration. * Create a PAPI integration.
* *
@@ -170,7 +178,7 @@ public interface Eco {
* @return The PluginCommandBase implementation * @return The PluginCommandBase implementation
*/ */
@NotNull @NotNull
PluginCommandBase createPluginCommand(@NotNull CommandBase parentDelegate, PluginCommandBase createPluginCommand(@NotNull PluginCommandBase parentDelegate,
@NotNull EcoPlugin plugin, @NotNull EcoPlugin plugin,
@NotNull String name, @NotNull String name,
@NotNull String permission, @NotNull String permission,
@@ -393,15 +401,6 @@ public interface Eco {
@NotNull @NotNull
ServerProfile getServerProfile(); ServerProfile getServerProfile();
/**
* Unload a player profile from memory.
* <p>
* This will not save the profile first.
*
* @param uuid The uuid.
*/
void unloadPlayerProfile(@NotNull UUID uuid);
/** /**
* Create dummy entity - never spawned, exists purely in code. * Create dummy entity - never spawned, exists purely in code.
* *
@@ -531,7 +530,7 @@ public interface Eco {
* @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,
@NotNull MathContext context); @NotNull PlaceholderContext context);
/** /**
* Get the menu a player currently has open. * Get the menu a player currently has open.
@@ -547,19 +546,45 @@ public interface Eco {
*/ */
void syncCommands(); void syncCommands();
/**
* Get the command map.
*
* @return The command map.
*/
@NotNull CommandMap getCommandMap();
/** /**
* Unregister a command. * Unregister a command.
* *
* @param command The command. * @param command The command.
*/ */
void unregisterCommand(@NotNull final PluginCommand command); void unregisterCommand(@NotNull PluginCommandBase command);
/**
* Send a packet.
*
* @param player The player.
* @param packet The packet.
*/
void sendPacket(@NotNull Player player,
@NotNull Packet packet);
/**
* Translate placeholders in a string.
*
* @param text The text.
* @param context The context.
* @return The translated text.
*/
@NotNull
String translatePlaceholders(@NotNull String text,
@NotNull PlaceholderContext context);
/**
* Get the value of a placeholder.
*
* @param plugin The plugin that owns the placeholder.
* @param args The placeholder arguments.
* @param context The context.
* @return The value, or null if invalid.
*/
@Nullable
String getPlaceholderValue(@Nullable EcoPlugin plugin,
@NotNull String args,
@NotNull PlaceholderContext context);
/** /**
* Get the instance of eco; the bridge between the api frontend and the implementation backend. * Get the instance of eco; the bridge between the api frontend and the implementation backend.

View File

@@ -13,11 +13,16 @@ import com.willfp.eco.core.factory.MetadataValueFactory;
import com.willfp.eco.core.factory.NamespacedKeyFactory; import com.willfp.eco.core.factory.NamespacedKeyFactory;
import com.willfp.eco.core.factory.RunnableFactory; import com.willfp.eco.core.factory.RunnableFactory;
import com.willfp.eco.core.integrations.IntegrationLoader; import com.willfp.eco.core.integrations.IntegrationLoader;
import com.willfp.eco.core.map.ListMap;
import com.willfp.eco.core.packet.PacketListener;
import com.willfp.eco.core.proxy.ProxyFactory; import com.willfp.eco.core.proxy.ProxyFactory;
import com.willfp.eco.core.registry.Registrable;
import com.willfp.eco.core.registry.Registry;
import com.willfp.eco.core.scheduling.Scheduler; import com.willfp.eco.core.scheduling.Scheduler;
import com.willfp.eco.core.version.OutdatedEcoVersionError;
import com.willfp.eco.core.version.Version;
import com.willfp.eco.core.web.UpdateChecker; import com.willfp.eco.core.web.UpdateChecker;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
@@ -28,12 +33,14 @@ import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -52,27 +59,12 @@ import java.util.stream.Collectors;
* <b>IMPORTANT: When reloading a plugin, all runnables / tasks will * <b>IMPORTANT: When reloading a plugin, all runnables / tasks will
* be cancelled.</b> * be cancelled.</b>
*/ */
@SuppressWarnings("unused") @SuppressWarnings({"unused", "DeprecatedIsStillUsed", "deprecation", "RedundantSuppression", "MismatchedQueryAndUpdateOfCollection"})
public abstract class EcoPlugin extends JavaPlugin implements PluginLike { public abstract class EcoPlugin extends JavaPlugin implements PluginLike, Registrable {
/** /**
* The polymart resource ID of the plugin. * The properties (eco.yml).
*/ */
private final int resourceId; private final PluginProps props;
/**
* The bStats resource ID of the plugin.
*/
private final int bStatsId;
/**
* The package where proxy implementations are.
*/
private final String proxyPackage;
/**
* The color of the plugin, used in messages.
*/
private final String color;
/** /**
* Loaded integrations. * Loaded integrations.
@@ -134,18 +126,13 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
/** /**
* The logger for the plugin. * The logger for the plugin.
*/ */
private final Logger logger; private Logger logger;
/** /**
* If the server is running an outdated version of the plugin. * If the server is running an outdated version of the plugin.
*/ */
private boolean outdated = false; private boolean outdated = false;
/**
* If the plugin supports extensions.
*/
private final boolean supportingExtensions;
/** /**
* The proxy factory. * The proxy factory.
*/ */
@@ -155,27 +142,32 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
/** /**
* The tasks to run on enable. * The tasks to run on enable.
*/ */
private final List<Runnable> onEnable = new ArrayList<>(); private final ListMap<LifecyclePosition, Runnable> onEnable = new ListMap<>();
/** /**
* The tasks to run on disable. * The tasks to run on disable.
*/ */
private final List<Runnable> onDisable = new ArrayList<>(); private final ListMap<LifecyclePosition, Runnable> onDisable = new ListMap<>();
/** /**
* The tasks to run on reload. * The tasks to run on reload.
*/ */
private final List<Runnable> onReload = new ArrayList<>(); private final ListMap<LifecyclePosition, Runnable> onReload = new ListMap<>();
/** /**
* The tasks to run on load. * The tasks to run on load.
*/ */
private final List<Runnable> onLoad = new ArrayList<>(); private final ListMap<LifecyclePosition, Runnable> onLoad = new ListMap<>();
/** /**
* The tasks to run after load. * The tasks to run after load.
*/ */
private final List<Runnable> afterLoad = new ArrayList<>(); private final ListMap<LifecyclePosition, Runnable> afterLoad = new ListMap<>();
/**
* The tasks to run on task creation.
*/
private final ListMap<LifecyclePosition, Runnable> createTasks = new ListMap<>();
/** /**
* Create a new plugin. * Create a new plugin.
@@ -192,7 +184,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* Create a new plugin without proxy support, polymart, or bStats. * Create a new plugin without proxy support, polymart, or bStats.
* *
* @param color The color. * @param color The color.
* @deprecated Use eco.yml instead.
*/ */
@Deprecated(since = "6.53.0", forRemoval = true)
protected EcoPlugin(@NotNull final String color) { protected EcoPlugin(@NotNull final String color) {
this("", color); this("", color);
} }
@@ -203,7 +197,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* *
* @param proxyPackage The package where proxy implementations are stored. * @param proxyPackage The package where proxy implementations are stored.
* @param color The color of the plugin (used in messages, using standard formatting) * @param color The color of the plugin (used in messages, using standard formatting)
* @deprecated Use eco.yml instead.
*/ */
@Deprecated(since = "6.53.0", forRemoval = true)
protected EcoPlugin(@NotNull final String proxyPackage, protected EcoPlugin(@NotNull final String proxyPackage,
@NotNull final String color) { @NotNull final String color) {
this(0, 0, proxyPackage, color); this(0, 0, proxyPackage, color);
@@ -215,7 +211,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param resourceId The polymart resource ID for the plugin. * @param resourceId The polymart resource ID for the plugin.
* @param bStatsId The bStats resource ID for the plugin. * @param bStatsId The bStats resource ID for the plugin.
* @param color The color of the plugin (used in messages, using standard formatting) * @param color The color of the plugin (used in messages, using standard formatting)
* @deprecated Use eco.yml instead.
*/ */
@Deprecated(since = "6.53.0", forRemoval = true)
protected EcoPlugin(final int resourceId, protected EcoPlugin(final int resourceId,
final int bStatsId, final int bStatsId,
@NotNull final String color) { @NotNull final String color) {
@@ -229,7 +227,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param bStatsId The bStats resource ID for the plugin. * @param bStatsId The bStats resource ID for the plugin.
* @param color The color of the plugin (used in messages, using standard formatting) * @param color The color of the plugin (used in messages, using standard formatting)
* @param supportingExtensions If the plugin supports extensions. * @param supportingExtensions If the plugin supports extensions.
* @deprecated Use eco.yml instead.
*/ */
@Deprecated(since = "6.53.0", forRemoval = true)
protected EcoPlugin(final int resourceId, protected EcoPlugin(final int resourceId,
final int bStatsId, final int bStatsId,
@NotNull final String color, @NotNull final String color,
@@ -244,7 +244,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param bStatsId The bStats resource ID for the plugin. * @param bStatsId The bStats resource ID for the plugin.
* @param proxyPackage The package where proxy implementations are stored. * @param proxyPackage The package where proxy implementations are stored.
* @param color The color of the plugin (used in messages, using standard formatting) * @param color The color of the plugin (used in messages, using standard formatting)
* @deprecated Use eco.yml instead.
*/ */
@Deprecated(since = "6.53.0", forRemoval = true)
protected EcoPlugin(final int resourceId, protected EcoPlugin(final int resourceId,
final int bStatsId, final int bStatsId,
@NotNull final String proxyPackage, @NotNull final String proxyPackage,
@@ -260,21 +262,15 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param proxyPackage The package where proxy implementations are stored. * @param proxyPackage The package where proxy implementations are stored.
* @param color The color of the plugin (used in messages, using standard formatting) * @param color The color of the plugin (used in messages, using standard formatting)
* @param supportingExtensions If the plugin supports extensions. * @param supportingExtensions If the plugin supports extensions.
* @deprecated Use eco.yml instead.
*/ */
@Deprecated(since = "6.53.0", forRemoval = true)
protected EcoPlugin(final int resourceId, protected EcoPlugin(final int resourceId,
final int bStatsId, final int bStatsId,
@NotNull final String proxyPackage, @NotNull final String proxyPackage,
@NotNull final String color, @NotNull final String color,
final boolean supportingExtensions) { final boolean supportingExtensions) {
this( this(PluginProps.createSimple(resourceId, bStatsId, proxyPackage, color, supportingExtensions));
PluginProps.createSimple(
resourceId,
bStatsId,
proxyPackage,
color,
supportingExtensions
)
);
} }
/** /**
@@ -324,13 +320,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
PluginProps props = this.mutateProps(generatedProps); PluginProps props = this.mutateProps(generatedProps);
props.validate(); props.validate();
this.resourceId = props.getResourceId(); this.props = props;
this.bStatsId = props.getBStatsId();
this.proxyPackage = props.getProxyPackage();
this.color = props.getColor();
this.supportingExtensions = props.isSupportingExtensions();
this.proxyFactory = this.proxyPackage.equalsIgnoreCase("") ? null : Eco.get().createProxyFactory(this); this.proxyFactory = this.props.getProxyPackage().equalsIgnoreCase("") ? null : Eco.get().createProxyFactory(this);
this.logger = Eco.get().createLogger(this); this.logger = Eco.get().createLogger(this);
this.getLogger().info("Initializing " + this.getColor() + this.getName()); this.getLogger().info("Initializing " + this.getColor() + this.getName());
@@ -362,14 +354,14 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
they have an outdated version of eco installed. they have an outdated version of eco installed.
*/ */
DefaultArtifactVersion runningVersion = new DefaultArtifactVersion(Eco.get().getEcoPlugin().getDescription().getVersion()); Version runningVersion = new Version(Eco.get().getEcoPlugin().getDescription().getVersion());
DefaultArtifactVersion requiredVersion = new DefaultArtifactVersion(this.getMinimumEcoVersion()); Version requiredVersion = new Version(this.getMinimumEcoVersion());
if (!(runningVersion.compareTo(requiredVersion) > 0 || runningVersion.equals(requiredVersion))) { if (!(runningVersion.compareTo(requiredVersion) > 0 || runningVersion.equals(requiredVersion))) {
this.getLogger().severe("You are running an outdated version of eco!"); this.getLogger().severe("You are running an outdated version of eco!");
this.getLogger().severe("You must be on at least" + this.getMinimumEcoVersion()); this.getLogger().severe("You must be on at least" + this.getMinimumEcoVersion());
this.getLogger().severe("Download the newest version here:"); this.getLogger().severe("Download the newest version here:");
this.getLogger().severe("https://polymart.org/download/773/recent/JSpprMspkuyecf5y1wQ2Jn8OoLQSQ_IW"); this.getLogger().severe("https://polymart.org/download/773/recent/JSpprMspkuyecf5y1wQ2Jn8OoLQSQ_IW");
Bukkit.getPluginManager().disablePlugin(this); throw new OutdatedEcoVersionError("This plugin requires at least eco version " + this.getMinimumEcoVersion() + " to run.");
} }
} }
@@ -380,13 +372,12 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
public final void onEnable() { public final void onEnable() {
super.onEnable(); super.onEnable();
this.getLogger().info("");
this.getLogger().info("Loading " + this.getColor() + this.getName()); this.getLogger().info("Loading " + this.getColor() + this.getName());
if (this.getResourceId() != 0 && !Eco.get().getEcoPlugin().getConfigYml().getBool("no-update-checker")) { if (this.getResourceId() != 0 && !Eco.get().getEcoPlugin().getConfigYml().getBool("no-update-checker")) {
new UpdateChecker(this).getVersion(version -> { new UpdateChecker(this).getVersion(version -> {
DefaultArtifactVersion currentVersion = new DefaultArtifactVersion(this.getDescription().getVersion()); Version currentVersion = new Version(this.getDescription().getVersion());
DefaultArtifactVersion mostRecentVersion = new DefaultArtifactVersion(version); Version mostRecentVersion = new Version(version);
if (!(currentVersion.compareTo(mostRecentVersion) > 0 || currentVersion.equals(mostRecentVersion))) { if (!(currentVersion.compareTo(mostRecentVersion) > 0 || currentVersion.equals(mostRecentVersion))) {
this.outdated = true; this.outdated = true;
this.getLogger().warning(this.getName() + " is out of date! (Version " + this.getDescription().getVersion() + ")"); this.getLogger().warning(this.getName() + " is out of date! (Version " + this.getDescription().getVersion() + ")");
@@ -400,10 +391,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
Eco.get().registerBStats(this); Eco.get().registerBStats(this);
} }
Set<String> enabledPlugins = Arrays.stream(Bukkit.getPluginManager().getPlugins()) Set<String> enabledPlugins = Arrays.stream(Bukkit.getPluginManager().getPlugins()).map(Plugin::getName).map(String::toLowerCase).collect(Collectors.toSet());
.map(Plugin::getName)
.map(String::toLowerCase)
.collect(Collectors.toSet());
if (enabledPlugins.contains("PlaceholderAPI".toLowerCase())) { if (enabledPlugins.contains("PlaceholderAPI".toLowerCase())) {
Eco.get().createPAPIIntegration(this); Eco.get().createPAPIIntegration(this);
@@ -411,44 +399,66 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
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()); try {
integrationLoader.load(); integrationLoader.load();
this.loadedIntegrations.add(integrationLoader.getPluginName());
} catch (Exception e) {
this.getLogger().warning("Failed to load integration for " + integrationLoader.getPluginName());
e.printStackTrace();
}
} }
}); });
this.loadedIntegrations.removeIf(pl -> pl.equalsIgnoreCase(this.getName())); this.loadedIntegrations.removeIf(pl -> pl.equalsIgnoreCase(this.getName()));
this.getLogger().info("Loaded integrations: " + String.join(", ", this.getLoadedIntegrations())); if (!this.getLoadedIntegrations().isEmpty()) {
this.getLogger().info("Loaded integrations: " + String.join(", ", this.getLoadedIntegrations()));
}
Prerequisite.update(); Prerequisite.update();
this.loadPacketAdapters().forEach(abstractPacketAdapter -> { if (Prerequisite.HAS_PROTOCOLLIB.isMet()) {
if (!abstractPacketAdapter.isPostLoad()) { this.loadPacketAdapters().forEach(abstractPacketAdapter -> {
abstractPacketAdapter.register(); if (!abstractPacketAdapter.isPostLoad()) {
} abstractPacketAdapter.register();
}); }
});
}
this.loadListeners().forEach(listener -> this.getEventManager().registerListener(listener)); this.loadListeners().forEach(listener -> this.getEventManager().registerListener(listener));
this.loadPacketListeners().forEach(listener -> this.getEventManager().registerPacketListener(listener));
this.loadPluginCommands().forEach(PluginCommand::register); this.loadPluginCommands().forEach(PluginCommand::register);
this.getScheduler().runLater(this::afterLoad, 1); // Run preliminary reload to resolve load order issues
this.getScheduler().runLater(() -> {
Logger before = this.getLogger();
// Temporary silence logger.
this.logger = Eco.get().getNOOPLogger();
this.reload(false);
this.logger = before;
}, 1);
this.getScheduler().runLater(this::afterLoad, 2);
if (this.isSupportingExtensions()) { if (this.isSupportingExtensions()) {
this.getExtensionLoader().loadExtensions(); this.getExtensionLoader().loadExtensions();
if (this.getExtensionLoader().getLoadedExtensions().isEmpty()) { if (!this.getExtensionLoader().getLoadedExtensions().isEmpty()) {
this.getLogger().info("&cNo extensions found"); List<String> loadedExtensions = this.getExtensionLoader().getLoadedExtensions().stream().map(
} else { extension -> extension.getName() + " v" + extension.getVersion()
this.getLogger().info("Extensions Loaded:"); ).toList();
this.getExtensionLoader().getLoadedExtensions().forEach(extension -> this.getLogger().info("- " + extension.getName() + " v" + extension.getVersion()));
this.getLogger().info(
"Loaded extensions: " +
String.join(", ", loadedExtensions)
);
} }
} }
this.handleEnable(); this.handleLifecycle(this.onEnable, this::handleEnable);
this.onEnable.forEach(Runnable::run);
this.getLogger().info("");
} }
/** /**
@@ -457,7 +467,18 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param task The task. * @param task The task.
*/ */
public final void onEnable(@NotNull final Runnable task) { public final void onEnable(@NotNull final Runnable task) {
this.onEnable.add(task); this.onEnable(LifecyclePosition.END, task);
}
/**
* Add new task to run on enable.
*
* @param position The position to run the task.
* @param task The task.
*/
public final void onEnable(@NotNull final LifecyclePosition position,
@NotNull final Runnable task) {
this.onEnable.append(position, task);
} }
/** /**
@@ -470,8 +491,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
this.getEventManager().unregisterAllListeners(); this.getEventManager().unregisterAllListeners();
this.getScheduler().cancelAll(); this.getScheduler().cancelAll();
this.handleDisable(); this.handleLifecycle(this.onDisable, this::handleDisable);
this.onDisable.forEach(Runnable::run);
if (this.isSupportingExtensions()) { if (this.isSupportingExtensions()) {
this.getExtensionLoader().unloadExtensions(); this.getExtensionLoader().unloadExtensions();
@@ -487,7 +507,18 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param task The task. * @param task The task.
*/ */
public final void onDisable(@NotNull final Runnable task) { public final void onDisable(@NotNull final Runnable task) {
this.onDisable.add(task); this.onDisable(LifecyclePosition.END, task);
}
/**
* Add new task to run on disable.
*
* @param position The position to run the task.
* @param task The task.
*/
public final void onDisable(@NotNull final LifecyclePosition position,
@NotNull final Runnable task) {
this.onDisable.append(position, task);
} }
/** /**
@@ -497,8 +528,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
public final void onLoad() { public final void onLoad() {
super.onLoad(); super.onLoad();
this.handleLoad(); this.handleLifecycle(this.onLoad, this::handleLoad);
this.onLoad.forEach(Runnable::run);
} }
/** /**
@@ -507,7 +537,18 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param task The task. * @param task The task.
*/ */
public final void onLoad(@NotNull final Runnable task) { public final void onLoad(@NotNull final Runnable task) {
this.onLoad.add(task); this.onLoad(LifecyclePosition.END, task);
}
/**
* Add new task to run on load.
*
* @param position The position to run the task.
* @param task The task.
*/
public final void onLoad(@NotNull final LifecyclePosition position,
@NotNull final Runnable task) {
this.onLoad.append(position, task);
} }
/** /**
@@ -520,11 +561,13 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
Display.registerDisplayModule(this.getDisplayModule()); Display.registerDisplayModule(this.getDisplayModule());
} }
this.loadPacketAdapters().forEach(abstractPacketAdapter -> { if (Prerequisite.HAS_PROTOCOLLIB.isMet()) {
if (abstractPacketAdapter.isPostLoad()) { this.loadPacketAdapters().forEach(abstractPacketAdapter -> {
abstractPacketAdapter.register(); if (abstractPacketAdapter.isPostLoad()) {
} abstractPacketAdapter.register();
}); }
});
}
if (!Prerequisite.HAS_PAPER.isMet()) { if (!Prerequisite.HAS_PAPER.isMet()) {
this.getLogger().severe(""); this.getLogger().severe("");
@@ -539,8 +582,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
this.getLogger().severe(""); this.getLogger().severe("");
} }
this.handleAfterLoad(); this.handleLifecycle(this.afterLoad, this::handleAfterLoad);
this.afterLoad.forEach(Runnable::run);
this.reload(); this.reload();
@@ -548,7 +590,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
extension.handleAfterLoad(); extension.handleAfterLoad();
} }
this.getLogger().info("Loaded " + this.color + this.getName()); this.getLogger().info("Loaded " + this.props.getColor() + this.getName());
} }
/** /**
@@ -557,21 +599,47 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param task The task. * @param task The task.
*/ */
public final void afterLoad(@NotNull final Runnable task) { public final void afterLoad(@NotNull final Runnable task) {
this.afterLoad.add(task); this.afterLoad(LifecyclePosition.END, task);
}
/**
* Add new task to run after load.
*
* @param position The position to run the task.
* @param task The task.
*/
public final void afterLoad(@NotNull final LifecyclePosition position,
@NotNull final Runnable task) {
this.afterLoad.append(position, task);
} }
/** /**
* Reload the plugin. * Reload the plugin.
*/ */
public final void reload() { public final void reload() {
this.reload(true);
}
/**
* Reload the plugin.
*
* @param cancelTasks If tasks should be cancelled.
*/
public final void reload(final boolean cancelTasks) {
this.getConfigHandler().updateConfigs(); this.getConfigHandler().updateConfigs();
this.getScheduler().cancelAll(); if (cancelTasks) {
this.getScheduler().cancelAll();
}
this.getConfigHandler().callUpdate(); this.getConfigHandler().callUpdate();
this.getConfigHandler().callUpdate(); // Call twice to fix issues this.getConfigHandler().callUpdate(); // Call twice to fix issues
this.handleReload(); this.handleLifecycle(this.onReload, this::handleReload);
this.onReload.forEach(Runnable::run);
if (cancelTasks) {
this.handleLifecycle(this.createTasks, this::createTasks);
}
for (Extension extension : this.extensionLoader.getLoadedExtensions()) { for (Extension extension : this.extensionLoader.getLoadedExtensions()) {
extension.handleReload(); extension.handleReload();
@@ -579,12 +647,23 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
} }
/** /**
* Add new task to run on enable. * Add new task to run on reload.
* *
* @param task The task. * @param task The task.
*/ */
public final void onReload(@NotNull final Runnable task) { public final void onReload(@NotNull final Runnable task) {
this.onReload.add(task); this.onReload(LifecyclePosition.END, task);
}
/**
* Add new task to run on reload.
*
* @param position The position to run the task.
* @param task The task.
*/
public final void onReload(@NotNull final LifecyclePosition position,
@NotNull final Runnable task) {
this.onReload.append(position, task);
} }
/** /**
@@ -600,6 +679,43 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
return System.currentTimeMillis() - startTime; return System.currentTimeMillis() - startTime;
} }
/**
* Handle lifecycle.
*
* @param tasks The tasks.
* @param handler The handler.
*/
private void handleLifecycle(@NotNull final ListMap<LifecyclePosition, Runnable> tasks,
@NotNull final Runnable handler) {
for (Runnable task : tasks.get(LifecyclePosition.START)) {
try {
task.run();
} catch (final Exception e) {
this.getLogger().log(Level.SEVERE, "Error while running lifecycle task!");
this.getLogger().log(Level.SEVERE, "The plugin may not function properly");
e.printStackTrace();
}
}
try {
handler.run();
} catch (final Exception e) {
this.getLogger().log(Level.SEVERE, "Error while running lifecycle task!");
this.getLogger().log(Level.SEVERE, "The plugin may not function properly");
e.printStackTrace();
}
for (Runnable task : tasks.get(LifecyclePosition.END)) {
try {
task.run();
} catch (final Exception e) {
this.getLogger().log(Level.SEVERE, "Error while running lifecycle task!");
this.getLogger().log(Level.SEVERE, "The plugin may not function properly");
e.printStackTrace();
}
}
}
/** /**
* The plugin-specific code to be executed on enable. * The plugin-specific code to be executed on enable.
* <p> * <p>
@@ -638,6 +754,15 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
} }
/**
* The plugin-specific code to create tasks.
* <p>
* Override when needed.
*/
protected void createTasks() {
}
/** /**
* The plugin-specific code to be executed after the server is up. * The plugin-specific code to be executed after the server is up.
* <p> * <p>
@@ -681,22 +806,35 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
} }
/** /**
* ProtocolLib packet adapters to be registered. * ProtocolLib handle adapters to be registered.
* <p> * <p>
* If the plugin does not require ProtocolLib this can be left empty. * If the plugin does not require ProtocolLib this can be left empty.
* *
* @return A list of packet adapters. * @return A list of handle adapters.
* @deprecated Use {@link #loadPacketListeners()} instead.
*/ */
@Deprecated(since = "6.51.0")
protected List<AbstractPacketAdapter> loadPacketAdapters() { protected List<AbstractPacketAdapter> loadPacketAdapters() {
return new ArrayList<>(); return new ArrayList<>();
} }
/**
* Packet Listeners to be registered.
*
* @return A list of handle listeners.
*/
protected List<PacketListener> loadPacketListeners() {
return new ArrayList<>();
}
/** /**
* All listeners to be registered. * All listeners to be registered.
* *
* @return A list of all listeners. * @return A list of all listeners.
*/ */
protected abstract List<Listener> loadListeners(); protected List<Listener> loadListeners() {
return new ArrayList<>();
}
/** /**
* Useful for custom LangYml implementations. * Useful for custom LangYml implementations.
@@ -743,10 +881,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
*/ */
@Nullable @Nullable
protected DisplayModule createDisplayModule() { protected DisplayModule createDisplayModule() {
Validate.isTrue( Validate.isTrue(this.getDisplayModule() == null, "Display module exists!");
this.getDisplayModule() == null,
"Display module exists!"
);
return null; return null;
} }
@@ -845,6 +980,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param pluginName The name. * @param pluginName The name.
* @return The plugin. * @return The plugin.
*/ */
@Nullable
public static EcoPlugin getPlugin(@NotNull final String pluginName) { public static EcoPlugin getPlugin(@NotNull final String pluginName) {
return Eco.get().getPluginByName(pluginName); return Eco.get().getPluginByName(pluginName);
} }
@@ -854,17 +990,28 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* *
* @return The set of names. * @return The set of names.
*/ */
@NotNull
public static Set<String> getPluginNames() { public static Set<String> getPluginNames() {
return new HashSet<>(Eco.get().getLoadedPlugins()); return new HashSet<>(Eco.get().getLoadedPlugins());
} }
/**
* Get the plugin props. (eco.yml).
*
* @return The props.
*/
@NotNull
public PluginProps getProps() {
return this.props;
}
/** /**
* Get the polymart resource ID. * Get the polymart resource ID.
* *
* @return The resource ID. * @return The resource ID.
*/ */
public int getResourceId() { public int getResourceId() {
return this.resourceId; return this.getProps().getResourceId();
} }
/** /**
@@ -873,7 +1020,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @return The ID. * @return The ID.
*/ */
public int getBStatsId() { public int getBStatsId() {
return this.bStatsId; return this.getProps().getBStatsId();
} }
/** /**
@@ -882,7 +1029,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @return The package where proxies are contained. * @return The package where proxies are contained.
*/ */
public String getProxyPackage() { public String getProxyPackage() {
return this.proxyPackage; return this.getProps().getProxyPackage();
} }
/** /**
@@ -891,7 +1038,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @return The color. * @return The color.
*/ */
public String getColor() { public String getColor() {
return this.color; return this.getProps().getColor();
} }
/** /**
@@ -980,7 +1127,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* *
* @return The config handler. * @return The config handler.
*/ */
public ConfigHandler getConfigHandler() { public @NotNull ConfigHandler getConfigHandler() {
return this.configHandler; return this.configHandler;
} }
@@ -1009,7 +1156,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @return If extensions are supported. * @return If extensions are supported.
*/ */
public boolean isSupportingExtensions() { public boolean isSupportingExtensions() {
return this.supportingExtensions; return this.getProps().isSupportingExtensions();
} }
/** /**
@@ -1043,4 +1190,25 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
public FixedMetadataValue createMetadataValue(@NotNull final Object value) { public FixedMetadataValue createMetadataValue(@NotNull final Object value) {
return this.getMetadataValueFactory().create(value); return this.getMetadataValueFactory().create(value);
} }
/**
* Get if all {@link com.willfp.eco.core.data.keys.PersistentDataKey}'s for this
* plugin should be saved locally (via data.yml.) even if eco is using a database.
*
* @return If using local storage.
*/
public boolean isUsingLocalStorage() {
return this.configYml.isUsingLocalStorage();
}
@Override
@NotNull
public final String getID() {
return Registry.tryFitPattern(this.getName());
}
@Override
public @NotNull File getFile() {
return super.getFile();
}
} }

View File

@@ -0,0 +1,16 @@
package com.willfp.eco.core;
/**
* Marks a position in a lifecycle (e.g. enable, reload, etc).
*/
public enum LifecyclePosition {
/**
* Run at the start of the lifecycle.
*/
START,
/**
* Run at the end of the lifecycle.
*/
END
}

View File

@@ -1,44 +0,0 @@
package com.willfp.eco.core;
import org.jetbrains.annotations.NotNull;
/**
* Quick DI class to manage passing eco plugins.
* <p>
* Basically just a quick bit of laziness if you can't be bothered to add a private field
* and a protected getter, don't use this in kotlin as you can just specify
* {@code
* private val plugin: EcoPlugin
* }
* in the constructor.
*
* @param <T> The eco plugin type.
* @deprecated Leaky inheritance, shouldn't exist.
*/
@Deprecated(since = "6.43.0", forRemoval = true)
public abstract class PluginDependent<T extends EcoPlugin> {
/**
* The {@link EcoPlugin} that is stored.
*/
@NotNull
private final T plugin;
/**
* Pass an {@link EcoPlugin} in order to interface with it.
*
* @param plugin The plugin to manage.
*/
protected PluginDependent(@NotNull final T plugin) {
this.plugin = plugin;
}
/**
* Get the plugin.
*
* @return The plugin.
*/
@NotNull
protected T getPlugin() {
return this.plugin;
}
}

View File

@@ -1,6 +1,8 @@
package com.willfp.eco.core; package com.willfp.eco.core;
import com.willfp.eco.core.config.updating.ConfigHandler; import com.willfp.eco.core.config.updating.ConfigHandler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File; import java.io.File;
import java.util.logging.Logger; import java.util.logging.Logger;
@@ -13,12 +15,13 @@ import java.util.logging.Logger;
*/ */
public interface PluginLike { public interface PluginLike {
/** /**
* Get the data folder of the object. * Get the data folder.
* <p> * <p>
* Returns the plugin data folder for a plugin, or the extension's parent plugin's folder * Returns the plugin data folder for a plugin, or the extension's parent plugin's folder
* *
* @return The data folder. * @return The data folder.
*/ */
@NotNull
File getDataFolder(); File getDataFolder();
/** /**
@@ -26,6 +29,7 @@ public interface PluginLike {
* *
* @return The config handler. * @return The config handler.
*/ */
@NotNull
ConfigHandler getConfigHandler(); ConfigHandler getConfigHandler();
/** /**
@@ -33,5 +37,16 @@ public interface PluginLike {
* *
* @return The logger. * @return The logger.
*/ */
@NotNull
Logger getLogger(); Logger getLogger();
/**
* Get the actual file.
*
* @return The file, i.e. the jar file.
*/
@Nullable
default File getFile() {
return null;
}
} }

View File

@@ -49,6 +49,16 @@ public final class PluginProps {
@Nullable @Nullable
private Boolean supportingExtensions; private Boolean supportingExtensions;
/**
* The environment variables.
*/
private final Map<String, String> environment = new HashMap<>();
/**
* If the plugin uses reflective reload (via {@link com.willfp.eco.core.config.updating.ConfigUpdater}).
*/
private boolean usesReflectiveReload = true;
/** /**
* Create new blank props. * Create new blank props.
*/ */
@@ -153,6 +163,46 @@ public final class PluginProps {
this.supportingExtensions = supportingExtensions; this.supportingExtensions = supportingExtensions;
} }
/**
* Get an environment variable.
*
* @param name The name.
* @return The value of the variable.
*/
@Nullable
public String getEnvironmentVariable(@NotNull final String name) {
return environment.get(name);
}
/**
* Set an environment variable.
*
* @param name The name.
* @param value The value.
*/
public void setEnvironmentVariable(@NotNull final String name,
@NotNull final String value) {
environment.put(name, value);
}
/**
* Set if the plugin uses reflective reload.
*
* @return If the plugin uses reflective reload.
*/
public boolean isUsingReflectiveReload() {
return usesReflectiveReload;
}
/**
* Set if the plugin uses reflective reload.
*
* @param usesReflectiveReload If the plugin uses reflective reload.
*/
public void setUsesReflectiveReload(final boolean usesReflectiveReload) {
this.usesReflectiveReload = usesReflectiveReload;
}
/** /**
* Ensure that all required props have been set. * Ensure that all required props have been set.
*/ */
@@ -232,7 +282,9 @@ public final class PluginProps {
* @param color The primary color of the plugin. * @param color The primary color of the plugin.
* @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.
* @deprecated Moving to force the usage of eco.yml.
*/ */
@Deprecated(since = "6.53.0")
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

@@ -1,6 +1,5 @@
package com.willfp.eco.core; package com.willfp.eco.core;
import com.willfp.eco.core.integrations.economy.EconomyManager;
import com.willfp.eco.core.proxy.ProxyConstants; import com.willfp.eco.core.proxy.ProxyConstants;
import com.willfp.eco.util.ClassUtils; import com.willfp.eco.util.ClassUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -31,14 +30,19 @@ public class Prerequisite {
); );
/** /**
* Requires the server to have vault installed. * Requires the server to be running an implementation of paper.
*
* @deprecated Use {@link EconomyManager#hasRegistrations()} instead.
*/ */
@Deprecated(forRemoval = true) public static final Prerequisite HAS_PROTOCOLLIB = new Prerequisite(
public static final Prerequisite HAS_VAULT = new Prerequisite( () -> ClassUtils.exists("com.comphenix.protocol.events.PacketAdapter"),
() -> ClassUtils.exists("net.milkbowl.vault.economy.Economy"), "Requires server to have ProtocolLib"
"Requires server to have vault" );
/**
* Requires the server to be running 1.19.4.
*/
public static final Prerequisite HAS_1_19_4 = new Prerequisite(
() -> ProxyConstants.NMS_VERSION.contains("19_R3"),
"Requires server to be running 1.19.4+"
); );
/** /**
@@ -57,17 +61,6 @@ public class Prerequisite {
"Requires server to be running 1.18+" "Requires server to be running 1.18+"
); );
/**
* Requires the server to be running 1.17.
*
* @deprecated eco no longer supports versions before 1.17.
*/
@Deprecated(since = "6.25.2", forRemoval = true)
public static final Prerequisite HAS_1_17 = new Prerequisite(
() -> ProxyConstants.NMS_VERSION.contains("17") || HAS_1_18.isMet(),
"Requires server to be running 1.17+"
);
/** /**
* Requires the server to be running an implementation of BungeeCord. * Requires the server to be running an implementation of BungeeCord.
* *

View File

@@ -1,5 +1,7 @@
package com.willfp.eco.core.command; package com.willfp.eco.core.command;
import org.jetbrains.annotations.NotNull;
/** /**
* A notification exception is thrown when {@link org.bukkit.command.CommandSender}s don't * A notification exception is thrown when {@link org.bukkit.command.CommandSender}s don't
* specify valid arguments in commands. * specify valid arguments in commands.
@@ -18,7 +20,7 @@ public class NotificationException extends Exception {
* *
* @param key The lang key of the notification. * @param key The lang key of the notification.
*/ */
public NotificationException(String key) { public NotificationException(@NotNull final String key) {
super(key); super(key);
this.key = key; this.key = key;
} }

View File

@@ -14,7 +14,7 @@ import java.util.List;
* *
* @deprecated Internal command implementations have been removed from the API. * @deprecated Internal command implementations have been removed from the API.
*/ */
@Deprecated(forRemoval = true, since = "6.49.0") @Deprecated(since = "6.49.0", forRemoval = true)
public final class DelegatedBukkitCommand extends Command implements TabCompleter, PluginIdentifiableCommand { public final class DelegatedBukkitCommand extends Command implements TabCompleter, PluginIdentifiableCommand {
/** /**
* The delegate command. * The delegate command.

View File

@@ -16,6 +16,8 @@ import org.jetbrains.annotations.NotNull;
*/ */
public abstract class ExtendableConfig extends LoadableConfigWrapper { public abstract class ExtendableConfig extends LoadableConfigWrapper {
/** /**
* Create a new extendable config.
*
* @param configName The name of the config * @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update. * @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin. * @param plugin The plugin.

View File

@@ -26,6 +26,8 @@ import java.util.Map;
@Deprecated(since = "6.44.0", forRemoval = true) @Deprecated(since = "6.44.0", forRemoval = true)
public class TransientConfig extends ConfigWrapper<Config> { public class TransientConfig extends ConfigWrapper<Config> {
/** /**
* Create new transient config from bukkit config.
*
* @param config The ConfigurationSection handle. * @param config The ConfigurationSection handle.
*/ */
public TransientConfig(@NotNull final ConfigurationSection config) { public TransientConfig(@NotNull final ConfigurationSection config) {
@@ -42,6 +44,8 @@ public class TransientConfig extends ConfigWrapper<Config> {
} }
/** /**
* Create a transient config from an input stream.
*
* @param stream The InputStream. * @param stream The InputStream.
*/ */
public TransientConfig(@Nullable final InputStream stream) { public TransientConfig(@Nullable final InputStream stream) {
@@ -51,15 +55,8 @@ public class TransientConfig extends ConfigWrapper<Config> {
} }
/** /**
* @param file The File. * Load a file to a config.
* @deprecated Specify the config type to prevent bugs. *
*/
@Deprecated(since = "6.30.0", forRemoval = true)
public TransientConfig(@Nullable final File file) {
this(file, ConfigType.YAML);
}
/**
* @param file The file. * @param file The file.
* @param type The config type to try read from. * @param type The config type to try read from.
*/ */
@@ -97,6 +94,8 @@ public class TransientConfig extends ConfigWrapper<Config> {
} }
/** /**
* Load a config from a string.
*
* @param contents The contents of the config. * @param contents The contents of the config.
* @param type The config type. * @param type The config type.
*/ */

View File

@@ -9,6 +9,11 @@ import org.jetbrains.annotations.NotNull;
* Default plugin config.yml. * Default plugin config.yml.
*/ */
public class ConfigYml extends BaseConfig { public class ConfigYml extends BaseConfig {
/**
* The use local storage key.
*/
public static final String KEY_USES_LOCAL_STORAGE = "use-local-storage";
/** /**
* Config.yml. * Config.yml.
* *
@@ -52,4 +57,13 @@ public class ConfigYml extends BaseConfig {
final boolean removeUnused) { final boolean removeUnused) {
super(name, plugin, removeUnused, ConfigType.YAML); super(name, plugin, removeUnused, ConfigType.YAML);
} }
/**
* Get if the plugin is using local storage.
*
* @return The prefix.
*/
public boolean isUsingLocalStorage() {
return this.getBool(KEY_USES_LOCAL_STORAGE);
}
} }

View File

@@ -6,6 +6,7 @@ import com.willfp.eco.core.config.Configs;
import com.willfp.eco.core.placeholder.AdditionalPlayer; import com.willfp.eco.core.placeholder.AdditionalPlayer;
import com.willfp.eco.core.placeholder.InjectablePlaceholder; 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.context.PlaceholderContext;
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;
@@ -30,16 +31,6 @@ import java.util.Set;
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
public interface Config extends Cloneable, PlaceholderInjectable { public interface Config extends Cloneable, PlaceholderInjectable {
/**
* Clears cache.
* <p>
* Configs no longer have caches as they have in previous versions.
*/
@Deprecated(since = "6.31.1", forRemoval = true)
default void clearCache() {
// Do nothing.
}
/** /**
* Convert the config into readable text. * Convert the config into readable text.
* *
@@ -144,7 +135,7 @@ public interface Config extends Cloneable, PlaceholderInjectable {
* @return The computed value, or 0 if not found or invalid. * @return The computed value, or 0 if not found or invalid.
*/ */
default int getIntFromExpression(@NotNull String path) { default int getIntFromExpression(@NotNull String path) {
return getIntFromExpression(path, null); return getIntFromExpression(path, PlaceholderContext.of(this));
} }
/** /**
@@ -173,6 +164,18 @@ public interface Config extends Cloneable, PlaceholderInjectable {
return Double.valueOf(getDoubleFromExpression(path, player, additionalPlayers)).intValue(); return Double.valueOf(getDoubleFromExpression(path, player, additionalPlayers)).intValue();
} }
/**
* Get a decimal value via a mathematical expression.
*
* @param path The key to fetch the value from.
* @param context The placeholder context.
* @return The computed value, or 0 if not found or invalid.
*/
default int getIntFromExpression(@NotNull String path,
@NotNull PlaceholderContext context) {
return Double.valueOf(getDoubleFromExpression(path, context)).intValue();
}
/** /**
* Get an integer from config. * Get an integer from config.
@@ -266,6 +269,22 @@ public interface Config extends Cloneable, PlaceholderInjectable {
return getString(path, true, option); return getString(path, true, option);
} }
/**
* Get a formatted string from config.
*
* @param path The key to fetch the value from.
* @param context The placeholder context.
* @return The found value, or an empty string if not found.
*/
@NotNull
default String getFormattedString(@NotNull String path,
@NotNull PlaceholderContext context) {
return Objects.requireNonNullElse(
getFormattedStringOrNull(path, context),
""
);
}
/** /**
* Get a string from config. * Get a string from config.
* <p> * <p>
@@ -298,7 +317,7 @@ public interface Config extends Cloneable, PlaceholderInjectable {
* Get a formatted string from config. * Get a formatted string from config.
* *
* @param path The key to fetch the value from. * @param path The key to fetch the value from.
* @return The found value, or an empty string if not found. * @return The found value, or null if not found.
*/ */
@Nullable @Nullable
default String getFormattedStringOrNull(@NotNull String path) { default String getFormattedStringOrNull(@NotNull String path) {
@@ -310,7 +329,7 @@ public interface Config extends Cloneable, PlaceholderInjectable {
* *
* @param path The key to fetch the value from. * @param path The key to fetch the value from.
* @param option The format option. * @param option The format option.
* @return The found value, or an empty string if not found. * @return The found value, or null if not found.
*/ */
@Nullable @Nullable
default String getFormattedStringOrNull(@NotNull String path, default String getFormattedStringOrNull(@NotNull String path,
@@ -318,6 +337,25 @@ public interface Config extends Cloneable, PlaceholderInjectable {
return getStringOrNull(path, true, option); return getStringOrNull(path, true, option);
} }
/**
* Get a formatted string from config.
*
* @param path The key to fetch the value from.
* @param context The placeholder context.
* @return The found value, or null if not found.
*/
@Nullable
default String getFormattedStringOrNull(@NotNull String path,
@NotNull PlaceholderContext context) {
String nullable = getStringOrNull(path);
if (nullable == null) {
return null;
}
return StringUtils.format(nullable, context.withInjectableContext(this));
}
/** /**
* Get a string from config. * Get a string from config.
* <p> * <p>
@@ -372,6 +410,24 @@ public interface Config extends Cloneable, PlaceholderInjectable {
return getStrings(path, true, option); return getStrings(path, true, option);
} }
/**
* Get a list of strings from config.
* <p>
* Formatted.
*
* @param path The key to fetch the value from.
* @param context The placeholder context.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@NotNull
default List<String> getFormattedStrings(@NotNull String path,
@NotNull PlaceholderContext context) {
return Objects.requireNonNullElse(
getFormattedStringsOrNull(path, context),
new ArrayList<>()
);
}
/** /**
* Get a list of strings from config. * Get a list of strings from config.
* <p> * <p>
@@ -428,6 +484,30 @@ public interface Config extends Cloneable, PlaceholderInjectable {
return getStringsOrNull(path, true, option); return getStringsOrNull(path, true, option);
} }
/**
* Get a list of strings from config.
* <p>
* Formatted.
*
* @param path The key to fetch the value from.
* @param context The placeholder context.
* @return The found value, or null if not found.
*/
@Nullable
default List<String> getFormattedStringsOrNull(@NotNull String path,
@NotNull PlaceholderContext context) {
List<String> nullable = getStringsOrNull(path);
if (nullable == null) {
return null;
}
return StringUtils.formatList(
nullable,
context.withInjectableContext(this)
);
}
/** /**
* Get a list of strings from config. * Get a list of strings from config.
* <p> * <p>
@@ -473,7 +553,7 @@ public interface Config extends Cloneable, PlaceholderInjectable {
* @return The computed value, or 0 if not found or invalid. * @return The computed value, or 0 if not found or invalid.
*/ */
default double getDoubleFromExpression(@NotNull String path) { default double getDoubleFromExpression(@NotNull String path) {
return getDoubleFromExpression(path, null); return getDoubleFromExpression(path, PlaceholderContext.of(this));
} }
/** /**
@@ -485,21 +565,38 @@ 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); return getDoubleFromExpression(path, player, Collections.emptyList());
} }
/** /**
* Get a decimal value via a mathematical expression. * Get a decimal value via a mathematical expression.
* *
* @param path The key to fetch the value from. * @param path The key to fetch the value from.
* @param player The player to evaluate placeholders with respect to. * @param player The player to evaluate placeholders with respect to.
* @param additionalPlayers The additional players 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. * @return The computed value, or 0 if not found or invalid.
*/ */
default double getDoubleFromExpression(@NotNull String path, default double getDoubleFromExpression(@NotNull String path,
@Nullable Player player, @Nullable Player player,
@NotNull Collection<AdditionalPlayer> additionalPlayers) { @NotNull Collection<AdditionalPlayer> additionalPlayers) {
return NumberUtils.evaluateExpression(this.getString(path), player, this, additionalPlayers); return getDoubleFromExpression(path, new PlaceholderContext(
player,
null,
this,
additionalPlayers
));
}
/**
* Get a decimal value via a mathematical expression.
*
* @param path The key to fetch the value from.
* @param context The placeholder context.
* @return The computed value, or 0 if not found or invalid.
*/
default double getDoubleFromExpression(@NotNull String path,
@NotNull PlaceholderContext context) {
return NumberUtils.evaluateExpression(this.getString(path), context.withInjectableContext(this));
} }
/** /**

View File

@@ -2,7 +2,6 @@ package com.willfp.eco.core.config.interfaces;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@@ -44,21 +43,6 @@ public interface LoadableConfig extends Config {
*/ */
String getName(); String getName();
/**
* Get bukkit {@link YamlConfiguration}.
* <p>
* This used to represent the underlying config, but since 6.30.0 configs use
* their own implementations internally, without relying on bukkit.
*
* @return The config, or null if config is not yaml-based.
* @deprecated Use toBukkit() instead.
*/
@Nullable
@Deprecated(since = "6.30.0", forRemoval = true)
default YamlConfiguration getBukkitHandle() {
return this.toBukkit();
}
/** /**
* Convert the config to a bukkit {@link YamlConfiguration}. * Convert the config to a bukkit {@link YamlConfiguration}.
*/ */

View File

@@ -38,6 +38,9 @@ import java.lang.annotation.Target;
* <p> * <p>
* By having a plugin as a parameter, you shouldn't really need getInstance() * By having a plugin as a parameter, you shouldn't really need getInstance()
* calls in your code. * calls in your code.
*
* While flexible, this can lead to long initialization times, so this feature
* can be disabled in eco.yml with the uses-reflective-reload option.
*/ */
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) @Target(ElementType.METHOD)

View File

@@ -19,7 +19,7 @@ import java.util.Set;
* *
* @param <T> The type of the handle. * @param <T> The type of the handle.
*/ */
@SuppressWarnings({"MethodDoesntCallSuperMethod", "removal"}) @SuppressWarnings("MethodDoesntCallSuperMethod")
public abstract class ConfigWrapper<T extends Config> implements Config { public abstract class ConfigWrapper<T extends Config> implements Config {
/** /**
* Configs from eco have an internal implementation, * Configs from eco have an internal implementation,
@@ -42,12 +42,6 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
this.handle = handle; this.handle = handle;
} }
@Override
@Deprecated(since = "6.31.1", forRemoval = true)
public void clearCache() {
handle.clearCache();
}
@Override @Override
public String toPlaintext() { public String toPlaintext() {
return handle.toPlaintext(); return handle.toPlaintext();

View File

@@ -0,0 +1,148 @@
package com.willfp.eco.core.data;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
/**
* A simple store key-value store for data to be stored outside of plugins.
*/
@SuppressWarnings("unchecked")
public final class ExternalDataStore {
/**
* The store.
*/
private static final Map<String, Object> DATA = new HashMap<>();
/**
* The store adapters.
*/
private static final List<ExternalDataStoreObjectAdapter<?, ?>> STORE_ADAPTERS = new ArrayList<>();
/**
* Put data into the store.
*
* @param key The key.
* @param value The value.
*/
public static void put(@NotNull final String key,
@NotNull final Object value) {
doPut(key, value);
}
/**
* Put data into the store.
*
* @param key The key.
* @param value The value.
* @param <A> The stored type.
*/
private static <A> void doPut(@NotNull final String key,
@NotNull final A value) {
Object storedValue = value;
for (ExternalDataStoreObjectAdapter<?, ?> unknownAdapter : STORE_ADAPTERS) {
if (unknownAdapter.getAccessedClass().isInstance(value)) {
ExternalDataStoreObjectAdapter<A, ?> adapter = (ExternalDataStoreObjectAdapter<A, ?>) unknownAdapter;
storedValue = adapter.toStoredObject(value);
break;
}
}
DATA.put(key, storedValue);
}
/**
* Get data from the store.
*
* @param key The key.
* @param clazz The class.
* @param <T> The type.
* @return The value.
*/
@Nullable
public static <T> T get(@NotNull final String key,
@NotNull final Class<T> clazz) {
return doGet(key, clazz);
}
/**
* Get data from the store.
*
* @param key The key.
* @param clazz The class.
* @param <A> The accessed type.
* @param <S> The stored type.
* @return The value.
*/
@Nullable
private static <A, S> A doGet(@NotNull final String key,
@NotNull final Class<A> clazz) {
Object value = DATA.get(key);
for (ExternalDataStoreObjectAdapter<?, ?> unknownAdapter : STORE_ADAPTERS) {
if (unknownAdapter.getStoredClass().isInstance(value) && unknownAdapter.getAccessedClass().equals(clazz)) {
ExternalDataStoreObjectAdapter<A, S> adapter = (ExternalDataStoreObjectAdapter<A, S>) unknownAdapter;
value = adapter.toAccessedObject((S) value);
break;
}
}
if (clazz.isInstance(value)) {
return clazz.cast(value);
} else {
return null;
}
}
/**
* Get data from the store.
*
* @param key The key.
* @param clazz The class.
* @param defaultValue The default value.
* @param <T> The type.
* @return The value.
*/
@NotNull
public static <T> T get(@NotNull final String key,
@NotNull final Class<T> clazz,
@NotNull final T defaultValue) {
T value = get(key, clazz);
return value == null ? defaultValue : value;
}
/**
* Get data from the store.
*
* @param key The key.
* @param clazz The class.
* @param defaultValue The default value.
* @param <T> The type.
* @return The value.
*/
@NotNull
public static <T> T get(@NotNull final String key,
@NotNull final Class<T> clazz,
@NotNull final Supplier<T> defaultValue) {
return get(key, clazz, defaultValue.get());
}
/**
* Register a new adapter.
*
* @param adapter The adapter.
*/
public static void registerAdapter(@NotNull final ExternalDataStoreObjectAdapter<?, ?> adapter) {
STORE_ADAPTERS.add(adapter);
}
private ExternalDataStore() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
}

View File

@@ -0,0 +1,69 @@
package com.willfp.eco.core.data;
import org.jetbrains.annotations.NotNull;
/**
* An adapter for objects stored in {@link ExternalDataStore}.
*
* @param <A> The accessed class.
* @param <S> The stored class.
*/
public abstract class ExternalDataStoreObjectAdapter<A, S> {
/**
* The class that is accessed (read / written).
*/
private final Class<? extends A> accessedClass;
/**
* The class that is stored internally.
*/
private final Class<? extends S> storedClass;
/**
* Create a new adapter.
*
* @param accessedClass The class that is accessed (read / written).
* @param storedClass The class that is stored internally.
*/
protected ExternalDataStoreObjectAdapter(@NotNull final Class<? extends A> accessedClass,
@NotNull final Class<? extends S> storedClass) {
this.accessedClass = accessedClass;
this.storedClass = storedClass;
}
/**
* Convert an object to the stored object.
*
* @param obj The object.
* @return The stored object.
*/
@NotNull
public abstract S toStoredObject(@NotNull final A obj);
/**
* Convert an object to the accessed object.
*
* @param obj The object.
* @return The accessed object.
*/
@NotNull
public abstract A toAccessedObject(@NotNull final S obj);
/**
* Get the class that is accessed (read / written).
*
* @return The class.
*/
public Class<? extends A> getAccessedClass() {
return accessedClass;
}
/**
* Get the class that is stored internally.
*
* @return The class.
*/
public Class<? extends S> getStoredClass() {
return storedClass;
}
}

View File

@@ -9,6 +9,22 @@ import org.jetbrains.annotations.NotNull;
* Profiles save automatically, so there is no need to save after changes. * Profiles save automatically, so there is no need to save after changes.
*/ */
public interface ServerProfile extends Profile { public interface ServerProfile extends Profile {
/**
* Get the server ID.
*
* @return The server ID.
*/
@NotNull
String getServerID();
/**
* Get the local server ID.
*
* @return The local server ID.
*/
@NotNull
String getLocalServerID();
/** /**
* Load the server profile. * Load the server profile.
* *

View File

@@ -82,44 +82,6 @@ public final class PersistentDataKey<T> {
return this.type; return this.type;
} }
/**
* 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
* database immediately rather than waiting for auto-categorization.
* <p>
* This will improve performance.
*
* @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() {
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
* database immediately rather than waiting for auto-categorization.
* <p>
* This will improve performance.
*
* @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() {
return this;
}
/** /**
* Get all persistent data keys. * Get all persistent data keys.
* *

View File

@@ -4,6 +4,7 @@ import com.willfp.eco.core.config.interfaces.Config;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@@ -22,55 +23,43 @@ public final class PersistentDataKeyType<T> {
/** /**
* String. * String.
*/ */
public static final PersistentDataKeyType<String> STRING = new PersistentDataKeyType<>(String.class, "STRING"); public static final PersistentDataKeyType<String> STRING = new PersistentDataKeyType<>("STRING");
/** /**
* Boolean. * Boolean.
*/ */
public static final PersistentDataKeyType<Boolean> BOOLEAN = new PersistentDataKeyType<>(Boolean.class, "BOOLEAN"); public static final PersistentDataKeyType<Boolean> BOOLEAN = new PersistentDataKeyType<>("BOOLEAN");
/** /**
* Int. * Int.
*/ */
public static final PersistentDataKeyType<Integer> INT = new PersistentDataKeyType<>(Integer.class, "INT"); public static final PersistentDataKeyType<Integer> INT = new PersistentDataKeyType<>("INT");
/** /**
* Double. * Double.
*/ */
public static final PersistentDataKeyType<Double> DOUBLE = new PersistentDataKeyType<>(Double.class, "DOUBLE"); public static final PersistentDataKeyType<Double> DOUBLE = new PersistentDataKeyType<>("DOUBLE");
/** /**
* String List. * String List.
*/ */
public static final PersistentDataKeyType<List<String>> STRING_LIST = new PersistentDataKeyType<>(null, "STRING_LIST"); public static final PersistentDataKeyType<List<String>> STRING_LIST = new PersistentDataKeyType<>("STRING_LIST");
/** /**
* Config. * Config.
*/ */
public static final PersistentDataKeyType<Config> CONFIG = new PersistentDataKeyType<>(Config.class, "CONFIG"); public static final PersistentDataKeyType<Config> CONFIG = new PersistentDataKeyType<>("CONFIG");
/** /**
* The class of the type. * Big Decimal.
*/ */
private final Class<T> typeClass; public static final PersistentDataKeyType<BigDecimal> BIG_DECIMAL = new PersistentDataKeyType<>("BIG_DECIMAL");
/** /**
* The name of the key type. * The name of the key type.
*/ */
private final String name; private final String name;
/**
* Get the class of the type.
*
* @return The class.
* @deprecated String list type will return null.
*/
@Deprecated(since = "6.36.0", forRemoval = true)
@Nullable
public Class<T> getTypeClass() {
return typeClass;
}
/** /**
* Get the name of the key type. * Get the name of the key type.
* *
@@ -83,14 +72,11 @@ public final class PersistentDataKeyType<T> {
/** /**
* Create new PersistentDataKeyType. * Create new PersistentDataKeyType.
* *
* @param typeClass The type class.
* @param name The name. * @param name The name.
*/ */
private PersistentDataKeyType(@Nullable final Class<T> typeClass, private PersistentDataKeyType(@NotNull final String name) {
@NotNull final String name) {
VALUES.add(this); VALUES.add(this);
this.typeClass = typeClass;
this.name = name; this.name = name;
} }

View File

@@ -1,6 +1,7 @@
package com.willfp.eco.core.display; package com.willfp.eco.core.display;
import com.willfp.eco.core.fast.FastItemStack; import com.willfp.eco.core.fast.FastItemStack;
import com.willfp.eco.core.integrations.guidetection.GUIDetectionManager;
import com.willfp.eco.util.NamespacedKeyUtils; import com.willfp.eco.util.NamespacedKeyUtils;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@@ -18,6 +19,9 @@ import java.util.TreeMap;
/** /**
* Utility class to manage client-side item display. * Utility class to manage client-side item display.
* <p>
* Packet display is not done on the main thread, so make sure
* all your modules are thread-safe.
*/ */
public final class Display { public final class Display {
/** /**
@@ -71,7 +75,7 @@ public final class Display {
ItemStack original = itemStack.clone(); ItemStack original = itemStack.clone();
Inventory inventory = player == null ? null : player.getOpenInventory().getTopInventory(); Inventory inventory = player == null ? null : player.getOpenInventory().getTopInventory();
boolean inInventory = inventory != null && inventory.contains(original); boolean inInventory = inventory != null && inventory.contains(original);
boolean inGui = inventory != null && inventory.getHolder() == null; boolean inGui = player != null && GUIDetectionManager.hasGUIOpen(player);
DisplayProperties properties = new DisplayProperties( DisplayProperties properties = new DisplayProperties(
inInventory, inInventory,

View File

@@ -8,6 +8,8 @@ import org.jetbrains.annotations.Nullable;
/** /**
* Class for all plugin-specific client-side item display modules. * Class for all plugin-specific client-side item display modules.
* <p>
* Display modules are called in the netty thread, so make sure they are thread-safe.
*/ */
public abstract class DisplayModule { public abstract class DisplayModule {
/** /**
@@ -110,23 +112,6 @@ public abstract class DisplayModule {
return this.getPlugin().getName(); return this.getPlugin().getName();
} }
/**
* Get the display priority.
*
* @return The priority.
* @deprecated Use getWeight instead.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
public DisplayPriority getPriority() {
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. * Get the display weight.
* *

View File

@@ -6,7 +6,10 @@ package com.willfp.eco.core.display;
public enum DisplayPriority { public enum DisplayPriority {
/** /**
* Custom weight. * Custom weight.
*
* @deprecated Will never be used.
*/ */
@Deprecated(since = "6.53.0", forRemoval = true)
CUSTOM(250), CUSTOM(250),
/** /**

View File

@@ -20,6 +20,13 @@ public abstract class CustomGoal<T extends Mob> implements EntityGoal<T>, Target
*/ */
private final Set<GoalFlag> flags = EnumSet.noneOf(GoalFlag.class); private final Set<GoalFlag> flags = EnumSet.noneOf(GoalFlag.class);
/**
* Create a new custom goal.
*/
protected CustomGoal() {
}
/** /**
* Initialize the goal with a mob. * Initialize the goal with a mob.
* <p> * <p>

View File

@@ -13,10 +13,10 @@ import org.jetbrains.annotations.Nullable;
/** /**
* Avoid entities. * Avoid entities.
* *
* @param entity The entity type to avoid. * @param entity The entity type to avoid.
* @param distance The distance to flee to. * @param distance The distance to flee to.
* @param slowSpeed The slow movement speed. * @param slowSpeed The slow movement speed.
* @param fastSpeed The fast movement speed. * @param fastSpeed The fast movement speed.
*/ */
public record EntityGoalAvoidEntity( public record EntityGoalAvoidEntity(
@NotNull TestableEntity entity, @NotNull TestableEntity entity,
@@ -45,23 +45,14 @@ public record EntityGoalAvoidEntity(
return null; return null;
} }
try { TestableEntity entity = Entities.lookup(config.getString("entity"));
TestableEntity entity = Entities.lookup(config.getString("entity"));
return new EntityGoalAvoidEntity( return new EntityGoalAvoidEntity(
entity, entity,
config.getDouble("distance"), config.getDouble("distance"),
config.getDouble("slowSpeed"), config.getDouble("slowSpeed"),
config.getDouble("fastSpeed") config.getDouble("fastSpeed")
); );
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
} }
@NotNull @NotNull

View File

@@ -34,18 +34,9 @@ public record EntityGoalBreakDoors(
return null; return null;
} }
try { return new EntityGoalBreakDoors(
return new EntityGoalBreakDoors( config.getInt("ticks")
config.getInt("ticks") );
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
} }
@NotNull @NotNull

View File

@@ -34,18 +34,9 @@ public record EntityGoalBreed(
return null; return null;
} }
try { return new EntityGoalBreed(
return new EntityGoalBreed( config.getDouble("speed")
config.getDouble("speed") );
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
} }
@NotNull @NotNull

View File

@@ -37,19 +37,10 @@ public record EntityGoalCatLieOnBed(
return null; return null;
} }
try { return new EntityGoalCatLieOnBed(
return new EntityGoalCatLieOnBed( config.getDouble("speed"),
config.getDouble("speed"), config.getInt("range")
config.getInt("range") );
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
} }
@NotNull @NotNull

View File

@@ -34,18 +34,9 @@ public record EntityGoalCatSitOnBed(
return null; return null;
} }
try { return new EntityGoalCatSitOnBed(
return new EntityGoalCatSitOnBed( config.getDouble("speed")
config.getDouble("speed") );
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
} }
@NotNull @NotNull

View File

@@ -34,18 +34,9 @@ public record EntityGoalFleeSun(
return null; return null;
} }
try { return new EntityGoalFleeSun(
return new EntityGoalFleeSun( config.getDouble("speed")
config.getDouble("speed") );
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
} }
@NotNull @NotNull

View File

@@ -40,20 +40,11 @@ public record EntityGoalFollowMobs(
return null; return null;
} }
try { return new EntityGoalFollowMobs(
return new EntityGoalFollowMobs( config.getDouble("speed"),
config.getDouble("speed"), config.getDouble("minDistance"),
config.getDouble("minDistance"), config.getDouble("maxDistance")
config.getDouble("maxDistance") );
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
} }
@NotNull @NotNull

View File

@@ -42,20 +42,11 @@ public record EntityGoalInteract(
return null; return null;
} }
try { return new EntityGoalInteract(
return new EntityGoalInteract( Entities.lookup(config.getString("target")),
Entities.lookup(config.getString("target")), config.getDouble("range"),
config.getDouble("range"), config.getDouble("chance")
config.getDouble("chance") );
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
} }
@NotNull @NotNull

View File

@@ -34,18 +34,9 @@ public record EntityGoalLeapAtTarget(
return null; return null;
} }
try { return new EntityGoalLeapAtTarget(
return new EntityGoalLeapAtTarget( config.getDouble("velocity")
config.getDouble("velocity") );
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
} }
@NotNull @NotNull

View File

@@ -37,19 +37,10 @@ public record EntityGoalLookAtPlayer(
return null; return null;
} }
try { return new EntityGoalLookAtPlayer(
return new EntityGoalLookAtPlayer( config.getDouble("range"),
config.getDouble("range"), config.getDouble("chance")
config.getDouble("chance") );
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
} }
@NotNull @NotNull

View File

@@ -37,19 +37,10 @@ public record EntityGoalMeleeAttack(
return null; return null;
} }
try { return new EntityGoalMeleeAttack(
return new EntityGoalMeleeAttack( config.getDouble("speed"),
config.getDouble("speed"), config.getBool("pauseWhenMobIdle")
config.getBool("pauseWhenMobIdle") );
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
} }
@NotNull @NotNull

View File

@@ -37,19 +37,10 @@ public record EntityGoalMoveBackToVillage(
return null; return null;
} }
try { return new EntityGoalMoveBackToVillage(
return new EntityGoalMoveBackToVillage( config.getDouble("speed"),
config.getDouble("speed"), config.getBool("canDespawn")
config.getBool("canDespawn") );
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
} }
@NotNull @NotNull

View File

@@ -43,21 +43,12 @@ public record EntityGoalMoveThroughVillage(
return null; return null;
} }
try { return new EntityGoalMoveThroughVillage(
return new EntityGoalMoveThroughVillage( config.getDouble("speed"),
config.getDouble("speed"), config.getBool("onlyAtNight"),
config.getBool("onlyAtNight"), config.getInt("distance"),
config.getInt("distance"), config.getBool("canPassThroughDoors")
config.getBool("canPassThroughDoors") );
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
} }
@NotNull @NotNull

View File

@@ -34,18 +34,9 @@ public record EntityGoalMoveTowardsRestriction(
return null; return null;
} }
try { return new EntityGoalMoveTowardsRestriction(
return new EntityGoalMoveTowardsRestriction( config.getDouble("speed")
config.getDouble("speed") );
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
} }
@NotNull @NotNull

View File

@@ -37,19 +37,10 @@ public record EntityGoalMoveTowardsTarget(
return null; return null;
} }
try { return new EntityGoalMoveTowardsTarget(
return new EntityGoalMoveTowardsTarget( config.getDouble("speed"),
config.getDouble("speed"), config.getDouble("maxDistance")
config.getDouble("maxDistance") );
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
} }
@NotNull @NotNull

View File

@@ -34,18 +34,9 @@ public record EntityGoalOpenDoors(
return null; return null;
} }
try { return new EntityGoalOpenDoors(
return new EntityGoalOpenDoors( config.getBool("delayClosing")
config.getBool("delayClosing") );
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
} }
@NotNull @NotNull

View File

@@ -34,18 +34,9 @@ public record EntityGoalPanic(
return null; return null;
} }
try { return new EntityGoalPanic(
return new EntityGoalPanic( config.getDouble("speed")
config.getDouble("speed") );
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
} }
@NotNull @NotNull

View File

@@ -40,20 +40,11 @@ public record EntityGoalRandomStroll(
return null; return null;
} }
try { return new EntityGoalRandomStroll(
return new EntityGoalRandomStroll( config.getDouble("speed"),
config.getDouble("speed"), config.getInt("interval"),
config.getInt("interval"), config.getBool("canDespawn")
config.getBool("canDespawn") );
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
} }
@NotNull @NotNull

View File

@@ -37,19 +37,10 @@ public record EntityGoalRandomSwimming(
return null; return null;
} }
try { return new EntityGoalRandomSwimming(
return new EntityGoalRandomSwimming( config.getDouble("speed"),
config.getDouble("speed"), config.getInt("interval")
config.getInt("interval") );
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
} }
@NotNull @NotNull

View File

@@ -45,21 +45,12 @@ public record EntityGoalRangedAttack(
return null; return null;
} }
try { return new EntityGoalRangedAttack(
return new EntityGoalRangedAttack( config.getDouble("speed"),
config.getDouble("speed"), config.getInt("minInterval"),
config.getInt("minInterval"), config.getInt("maxInterval"),
config.getInt("maxInterval"), config.getDouble("range")
config.getDouble("range") );
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
} }
@NotNull @NotNull

View File

@@ -13,9 +13,9 @@ import org.jetbrains.annotations.Nullable;
* <p> * <p>
* Only supports monsters that have bow attacks. * Only supports monsters that have bow attacks.
* *
* @param speed The speed. * @param speed The speed.
* @param interval The interval between attacks (in ticks). * @param interval The interval between attacks (in ticks).
* @param range The max range at which to attack. * @param range The max range at which to attack.
*/ */
public record EntityGoalRangedBowAttack( public record EntityGoalRangedBowAttack(
double speed, double speed,
@@ -42,20 +42,11 @@ public record EntityGoalRangedBowAttack(
return null; return null;
} }
try { return new EntityGoalRangedBowAttack(
return new EntityGoalRangedBowAttack( config.getDouble("speed"),
config.getDouble("speed"), config.getInt("interval"),
config.getInt("interval"), config.getDouble("range")
config.getDouble("range") );
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
} }
@NotNull @NotNull

View File

@@ -39,19 +39,10 @@ public record EntityGoalRangedCrossbowAttack(
return null; return null;
} }
try { return new EntityGoalRangedCrossbowAttack(
return new EntityGoalRangedCrossbowAttack( config.getDouble("speed"),
config.getDouble("speed"), config.getDouble("range")
config.getDouble("range") );
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
} }
@NotNull @NotNull

View File

@@ -34,18 +34,9 @@ public record EntityGoalStrollThroughVillage(
return null; return null;
} }
try { return new EntityGoalStrollThroughVillage(
return new EntityGoalStrollThroughVillage( config.getInt("searchRange")
config.getInt("searchRange") );
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
} }
@NotNull @NotNull

View File

@@ -28,6 +28,8 @@ public record EntityGoalTempt(
boolean canBeScared boolean canBeScared
) implements EntityGoal<Mob> { ) implements EntityGoal<Mob> {
/** /**
* Create a new entity goal.
*
* @param speed The speed at which the entity follows the item. * @param speed The speed at which the entity follows the item.
* @param item The item that the entity will be attracted by. * @param item The item that the entity will be attracted by.
* @param canBeScared If the entity can be scared and lose track of the item. * @param canBeScared If the entity can be scared and lose track of the item.
@@ -58,25 +60,16 @@ public record EntityGoalTempt(
return null; return null;
} }
try { Collection<TestableItem> items = config.getStrings("items").stream()
Collection<TestableItem> items = config.getStrings("items").stream() .map(Items::lookup)
.map(Items::lookup) .filter(it -> !(it instanceof EmptyTestableItem))
.filter(it -> !(it instanceof EmptyTestableItem)) .collect(Collectors.toList());
.collect(Collectors.toList());
return new EntityGoalTempt( return new EntityGoalTempt(
config.getDouble("speed"), config.getDouble("speed"),
items, items,
config.getBool("canBeScared") config.getBool("canBeScared")
); );
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
} }
@NotNull @NotNull

View File

@@ -48,22 +48,13 @@ public record EntityGoalUseItem(
return null; return null;
} }
try { TestableEntity filter = Entities.lookup(config.getString("condition"));
TestableEntity filter = Entities.lookup(config.getString("condition"));
return new EntityGoalUseItem( return new EntityGoalUseItem(
Items.lookup(config.getString("item")).getItem(), Items.lookup(config.getString("item")).getItem(),
Sound.valueOf(config.getString("sound").toUpperCase()), Sound.valueOf(config.getString("sound").toUpperCase()),
filter::matches filter::matches
); );
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
} }
@NotNull @NotNull

View File

@@ -34,18 +34,9 @@ public record EntityGoalWaterAvoidingRandomFlying(
return null; return null;
} }
try { return new EntityGoalWaterAvoidingRandomFlying(
return new EntityGoalWaterAvoidingRandomFlying( config.getDouble("speed")
config.getDouble("speed") );
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
} }
@NotNull @NotNull

View File

@@ -37,19 +37,10 @@ public record EntityGoalWaterAvoidingRandomStroll(
return null; return null;
} }
try { return new EntityGoalWaterAvoidingRandomStroll(
return new EntityGoalWaterAvoidingRandomStroll( config.getDouble("speed"),
config.getDouble("speed"), config.getDouble("chance")
config.getDouble("chance") );
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
} }
@NotNull @NotNull

View File

@@ -34,18 +34,9 @@ public record EntityGoalWolfBeg(
return null; return null;
} }
try { return new EntityGoalWolfBeg(
return new EntityGoalWolfBeg( config.getDouble("distance")
config.getDouble("distance") );
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
} }
@NotNull @NotNull

View File

@@ -37,18 +37,9 @@ public record TargetGoalHurtBy(
return null; return null;
} }
try { return new TargetGoalHurtBy(
return new TargetGoalHurtBy( Entities.lookup(config.getString("blacklist"))
Entities.lookup(config.getString("blacklist")) );
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
} }
@NotNull @NotNull

View File

@@ -30,6 +30,8 @@ public record TargetGoalNearestAttackable(
@NotNull Predicate<LivingEntity> targetFilter @NotNull Predicate<LivingEntity> targetFilter
) implements TargetGoal<Raider> { ) implements TargetGoal<Raider> {
/** /**
* Create a new target goal.
*
* @param target The type of entities to attack. * @param target The type of entities to attack.
* @param checkVisibility If visibility should be checked. * @param checkVisibility If visibility should be checked.
* @param checkCanNavigate If navigation should be checked. * @param checkCanNavigate If navigation should be checked.
@@ -63,32 +65,23 @@ public record TargetGoalNearestAttackable(
return null; return null;
} }
try { if (config.has("targetFilter")) {
if (config.has("targetFilter")) { TestableEntity filter = Entities.lookup(config.getString("targetFilter"));
TestableEntity filter = Entities.lookup(config.getString("targetFilter"));
return new TargetGoalNearestAttackable( return new TargetGoalNearestAttackable(
Entities.lookup(config.getString("target")), Entities.lookup(config.getString("target")),
config.getBool("checkVisibility"), config.getBool("checkVisibility"),
config.getBool("checkCanNavigate"), config.getBool("checkCanNavigate"),
config.getInt("reciprocalChance"), config.getInt("reciprocalChance"),
filter::matches filter::matches
); );
} else { } else {
return new TargetGoalNearestAttackable( return new TargetGoalNearestAttackable(
Entities.lookup(config.getString("target")), Entities.lookup(config.getString("target")),
config.getBool("checkVisibility"), config.getBool("checkVisibility"),
config.getBool("checkCanNavigate"), config.getBool("checkCanNavigate"),
config.getInt("reciprocalChance") config.getInt("reciprocalChance")
); );
}
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
} }
} }

View File

@@ -30,6 +30,8 @@ public record TargetGoalNearestAttackableWitch(
@NotNull Predicate<LivingEntity> targetFilter @NotNull Predicate<LivingEntity> targetFilter
) implements TargetGoal<Raider> { ) implements TargetGoal<Raider> {
/** /**
* Create a new target goal.
*
* @param target The type of entities to attack. * @param target The type of entities to attack.
* @param checkVisibility If visibility should be checked. * @param checkVisibility If visibility should be checked.
* @param checkCanNavigate If navigation should be checked. * @param checkCanNavigate If navigation should be checked.
@@ -63,32 +65,23 @@ public record TargetGoalNearestAttackableWitch(
return null; return null;
} }
try { if (config.has("targetFilter")) {
if (config.has("targetFilter")) { TestableEntity filter = Entities.lookup(config.getString("targetFilter"));
TestableEntity filter = Entities.lookup(config.getString("targetFilter"));
return new TargetGoalNearestAttackableWitch( return new TargetGoalNearestAttackableWitch(
Entities.lookup(config.getString("target")), Entities.lookup(config.getString("target")),
config.getBool("checkVisibility"), config.getBool("checkVisibility"),
config.getBool("checkCanNavigate"), config.getBool("checkCanNavigate"),
config.getInt("reciprocalChance"), config.getInt("reciprocalChance"),
filter::matches filter::matches
); );
} else { } else {
return new TargetGoalNearestAttackableWitch( return new TargetGoalNearestAttackableWitch(
Entities.lookup(config.getString("target")), Entities.lookup(config.getString("target")),
config.getBool("checkVisibility"), config.getBool("checkVisibility"),
config.getBool("checkCanNavigate"), config.getBool("checkCanNavigate"),
config.getInt("reciprocalChance") config.getInt("reciprocalChance")
); );
}
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
} }
} }

View File

@@ -26,6 +26,8 @@ public record TargetGoalNearestHealableRaider(
@NotNull Predicate<LivingEntity> targetFilter @NotNull Predicate<LivingEntity> targetFilter
) implements TargetGoal<Raider> { ) implements TargetGoal<Raider> {
/** /**
* Create a new target goal.
*
* @param target The target. * @param target The target.
* @param checkVisibility If visibility should be checked. * @param checkVisibility If visibility should be checked.
*/ */
@@ -53,28 +55,19 @@ public record TargetGoalNearestHealableRaider(
return null; return null;
} }
try { if (config.has("targetFilter")) {
if (config.has("targetFilter")) { TestableEntity filter = Entities.lookup(config.getString("targetFilter"));
TestableEntity filter = Entities.lookup(config.getString("targetFilter"));
return new TargetGoalNearestHealableRaider( return new TargetGoalNearestHealableRaider(
Entities.lookup(config.getString("target")), Entities.lookup(config.getString("target")),
config.getBool("checkVisibility"), config.getBool("checkVisibility"),
filter::matches filter::matches
); );
} else { } else {
return new TargetGoalNearestHealableRaider( return new TargetGoalNearestHealableRaider(
Entities.lookup(config.getString("target")), Entities.lookup(config.getString("target")),
config.getBool("checkVisibility") config.getBool("checkVisibility")
); );
}
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
} }
} }

View File

@@ -26,6 +26,8 @@ public record TargetGoalNonTameRandom(
@NotNull Predicate<LivingEntity> targetFilter @NotNull Predicate<LivingEntity> targetFilter
) implements TargetGoal<Tameable> { ) implements TargetGoal<Tameable> {
/** /**
* Create a new target goal.
*
* @param target The types of entities to heal. * @param target The types of entities to heal.
* @param checkVisibility If visibility should be checked. * @param checkVisibility If visibility should be checked.
*/ */
@@ -53,28 +55,19 @@ public record TargetGoalNonTameRandom(
return null; return null;
} }
try { if (config.has("targetFilter")) {
if (config.has("targetFilter")) { TestableEntity filter = Entities.lookup(config.getString("targetFilter"));
TestableEntity filter = Entities.lookup(config.getString("targetFilter"));
return new TargetGoalNonTameRandom( return new TargetGoalNonTameRandom(
Entities.lookup(config.getString("target")), Entities.lookup(config.getString("target")),
config.getBool("checkVisibility"), config.getBool("checkVisibility"),
filter::matches filter::matches
); );
} else { } else {
return new TargetGoalNonTameRandom( return new TargetGoalNonTameRandom(
Entities.lookup(config.getString("target")), Entities.lookup(config.getString("target")),
config.getBool("checkVisibility") config.getBool("checkVisibility")
); );
}
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
} }
} }

View File

@@ -36,18 +36,9 @@ public record TargetGoalResetUniversalAnger(
return null; return null;
} }
try { return new TargetGoalResetUniversalAnger(
return new TargetGoalResetUniversalAnger( config.getBool("triggerOthers")
config.getBool("triggerOthers") );
);
} catch (Exception e) {
/*
Exceptions could be caused by configs having values of a wrong type,
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
so we encapsulate them as null.
*/
return null;
}
} }
@NotNull @NotNull

View File

@@ -7,6 +7,8 @@ import java.util.function.Consumer;
import java.util.function.Predicate; import java.util.function.Predicate;
/** /**
* The result of an arg parses.
*
* @param test The test for the entity. * @param test The test for the entity.
* @param modifier The modifier to apply to the entity. * @param modifier The modifier to apply to the entity.
* @see EntityArgParser * @see EntityArgParser

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core.events; package com.willfp.eco.core.events;
import com.willfp.eco.core.packet.PacketListener;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -25,4 +26,11 @@ public interface EventManager {
* Unregister all listeners associated with the plugin. * Unregister all listeners associated with the plugin.
*/ */
void unregisterAllListeners(); void unregisterAllListeners();
/**
* Register a packet listener.
*
* @param listener The listener.
*/
void registerPacketListener(@NotNull PacketListener listener);
} }

View File

@@ -135,20 +135,26 @@ public abstract class Extension implements PluginLike {
} }
@Override @Override
public File getDataFolder() { public @NotNull File getDataFolder() {
return this.plugin.getDataFolder(); return this.plugin.getDataFolder();
} }
@Override @Override
public ConfigHandler getConfigHandler() { public @NotNull ConfigHandler getConfigHandler() {
return this.plugin.getConfigHandler(); return this.plugin.getConfigHandler();
} }
@Override @Override
public Logger getLogger() { public @NotNull Logger getLogger() {
return this.plugin.getLogger(); return this.plugin.getLogger();
} }
@Override
public @NotNull File getFile() {
Validate.notNull(metadata, "Metadata cannot be null!");
return this.metadata.file();
}
/** /**
* Get the plugin for the extension. * Get the plugin for the extension.
* *

View File

@@ -0,0 +1,17 @@
package com.willfp.eco.core.extensions;
import org.jetbrains.annotations.NotNull;
/**
* Generic exception in extension loading.
*/
public class ExtensionLoadException extends RuntimeException {
/**
* Create a new ExtensionLoadException.
*
* @param errorMessage The error message to show.
*/
public ExtensionLoadException(@NotNull final String errorMessage) {
super(errorMessage);
}
}

View File

@@ -1,7 +1,10 @@
package com.willfp.eco.core.extensions; package com.willfp.eco.core.extensions;
import com.willfp.eco.core.version.Version;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.io.File;
/** /**
* The extension's metadata. * The extension's metadata.
* <p> * <p>
@@ -13,6 +16,23 @@ import org.jetbrains.annotations.NotNull;
*/ */
public record ExtensionMetadata(@NotNull String version, public record ExtensionMetadata(@NotNull String version,
@NotNull String name, @NotNull String name,
@NotNull String author) { @NotNull String author,
@NotNull File file,
@NotNull Version minimumPluginVersion) {
/**
* Legacy constructor.
*
* @param version The extension version.
* @param name The extension name.
* @param author The extension's author.
* @deprecated Use {@link ExtensionMetadata#ExtensionMetadata(String, String, String, File, Version)} instead.
*/
@SuppressWarnings("ConstantConditions")
@Deprecated(since = "6.57.0", forRemoval = true)
public ExtensionMetadata(@NotNull String version,
@NotNull String name,
@NotNull String author) {
this(version, name, author, null, null);
throw new UnsupportedOperationException("Legacy constructor is not supported.");
}
} }

View File

@@ -7,7 +7,7 @@ import org.jetbrains.annotations.NotNull;
* Missing or invalid extension.yml. * Missing or invalid extension.yml.
* Invalid filetype. * Invalid filetype.
*/ */
public class MalformedExtensionException extends RuntimeException { public class MalformedExtensionException extends ExtensionLoadException {
/** /**
* Create a new MalformedExtensionException. * Create a new MalformedExtensionException.
* *

View File

@@ -20,18 +20,6 @@ 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 extends PersistentDataHolder { public interface FastItemStack extends PersistentDataHolder {
/**
* Get all enchantments on an item.
*
* @param checkStored If stored NBT should also be checked.
* @return A map of all enchantments.
* @deprecated Poorly named method. Use getEnchants instead.
*/
@Deprecated(since = "6.24.0", forRemoval = true)
default Map<Enchantment, Integer> getEnchantmentsOnItem(boolean checkStored) {
return getEnchants(checkStored);
}
/** /**
* Get all enchantments on an item. * Get all enchantments on an item.
* Does not account for stored enchants. * Does not account for stored enchants.
@@ -51,33 +39,6 @@ public interface FastItemStack extends PersistentDataHolder {
@NotNull @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.
*
* @param enchantment The enchantment.
* @param checkStored If the stored NBT should also be checked.
* @return The enchantment level, or 0 if not found.
* @deprecated Poorly named method. Use getEnchantmentLevel instead.
*/
@Deprecated(since = "6.34.0", forRemoval = true)
@SuppressWarnings("DeprecatedIsStillUsed")
default int getLevelOnItem(@NotNull Enchantment enchantment,
boolean checkStored) {
return getEnchantmentLevel(enchantment, checkStored);
}
/** /**
* Get the level of an enchantment. * Get the level of an enchantment.
* *
@@ -85,7 +46,7 @@ public interface FastItemStack extends PersistentDataHolder {
* @return The enchantment level, or 0 if not found. * @return The enchantment level, or 0 if not found.
*/ */
default int getEnchantmentLevel(@NotNull Enchantment enchantment) { default int getEnchantmentLevel(@NotNull Enchantment enchantment) {
return getLevelOnItem(enchantment, false); return getEnchantmentLevel(enchantment, false);
} }
/** /**

View File

@@ -3,20 +3,15 @@ package com.willfp.eco.core.gui.menu;
import com.willfp.eco.core.Eco; import com.willfp.eco.core.Eco;
import com.willfp.eco.core.gui.page.Page; import com.willfp.eco.core.gui.page.Page;
import com.willfp.eco.core.gui.slot.Slot; import com.willfp.eco.core.gui.slot.Slot;
import com.willfp.eco.util.NamespacedKeyUtils;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
/** /**
* GUI version of {@link Inventory}. * GUI version of {@link Inventory}.
@@ -240,58 +235,6 @@ public interface Menu {
return Objects.requireNonNullElse(pageState, Integer.MAX_VALUE); return Objects.requireNonNullElse(pageState, Integer.MAX_VALUE);
} }
/**
* Write data.
*
* @param player The player.
* @param key The key.
* @param type The type.
* @param value The value.
* @param <T> The type.
* @param <Z> The type.
* @deprecated Use addState instead.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
default <T, Z> void writeData(@NotNull final Player player,
@NotNull final NamespacedKey key,
@NotNull final PersistentDataType<T, Z> type,
@NotNull final Z value) {
this.setState(player, key.toString(), value);
}
/**
* Read data.
*
* @param player The player.
* @param key The key.
* @param type The type.
* @param <T> The type.
* @param <Z> The type.
* @return The data.
* @deprecated Use getState instead.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
default @Nullable <T, Z> T readData(@NotNull final Player player,
@NotNull final NamespacedKey key,
@NotNull final PersistentDataType<T, Z> type) {
return this.getState(player, key.toString());
}
/**
* Get all data keys for a player.
*
* @param player The player.
* @return The keys.
* @deprecated Use getState instead.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
default Set<NamespacedKey> getKeys(@NotNull final Player player) {
return this.getState(player).keySet().stream()
.map(NamespacedKeyUtils::fromStringOrNull)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
}
/** /**
* Create a builder with a given amount of rows. * Create a builder with a given amount of rows.
* *

View File

@@ -142,6 +142,26 @@ public interface MenuBuilder extends PageBuilder {
return this.onRender((player, menu) -> menu.setState(player, Page.MAX_PAGE_KEY, pages.apply(player))); return this.onRender((player, menu) -> menu.setState(player, Page.MAX_PAGE_KEY, pages.apply(player)));
} }
/**
* Set the default page.
*
* @param page The page.
* @return The builder.
*/
default MenuBuilder defaultPage(final int page) {
return this.maxPages(player -> page);
}
/**
* Set the default page dynamically for a player.
*
* @param page The default page.
* @return The builder.
*/
default MenuBuilder defaultPage(@NotNull final Function<Player, Integer> page) {
return this.onOpen((player, menu) -> menu.setState(player, Page.PAGE_KEY, page.apply(player)));
}
/** /**
* Add a menu close handler. * Add a menu close handler.
* *

View File

@@ -76,6 +76,15 @@ public abstract class CustomSlot implements Slot {
return delegate; return delegate;
} }
@Override
public boolean shouldRenderOnClick() {
if (delegate == null) {
throw new IllegalStateException("Custom Slot was not initialized!");
}
return delegate.shouldRenderOnClick();
}
@Override @Override
public final int getRows() { public final int getRows() {
return Slot.super.getRows(); return Slot.super.getRows();
@@ -90,17 +99,4 @@ public abstract class CustomSlot implements Slot {
public final Slot getSlotAt(int row, int column) { public final Slot getSlotAt(int row, int column) {
return Slot.super.getSlotAt(row, column); return Slot.super.getSlotAt(row, column);
} }
/**
* Get the delegate slot.
* <p>
* This is not required to add the slot to a menu, but is instead used internally.
*
* @return The slot.
* @deprecated Replaced with {@link Slot#getActionableSlot(Player, Menu)}
*/
@Deprecated(since = "6.43.0", forRemoval = true)
public Slot getDelegate() {
return this.delegate;
}
} }

View File

@@ -92,6 +92,15 @@ public interface Slot extends GUIComponent {
return false; return false;
} }
/**
* If the slot should re-render the menu if clicked.
*
* @return If the slot should re-render.
*/
default boolean shouldRenderOnClick() {
return true;
}
@Override @Override
default int getRows() { default int getRows() {
return 1; return 1;
@@ -158,27 +167,4 @@ public interface Slot extends GUIComponent {
static SlotBuilder builder(@NotNull final SlotProvider provider) { static SlotBuilder builder(@NotNull final SlotProvider provider) {
return Eco.get().createSlotBuilder(provider); return Eco.get().createSlotBuilder(provider);
} }
/**
* If the slot is not captive for a player.
*
* @param player The player.
* @return If not captive for the player.
* @deprecated Captivity is now reactive, this method can produce incorrect results.
*/
@Deprecated(since = "6.43.0", forRemoval = true)
default boolean isNotCaptiveFor(@NotNull Player player) {
return false;
}
/**
* If the slot is captive. (Can items be placed in it).
*
* @return If captive.
* @deprecated Captivity is now reactive, this method can produce incorrect results.
*/
@Deprecated(since = "6.43.0", forRemoval = true)
default boolean isCaptive() {
return false;
}
} }

View File

@@ -1,13 +1,22 @@
package com.willfp.eco.core.integrations; package com.willfp.eco.core.integrations;
import com.willfp.eco.core.registry.Registrable;
import com.willfp.eco.core.registry.Registry;
import org.jetbrains.annotations.NotNull;
/** /**
* Abstract class for integrations. * Abstract class for integrations.
*/ */
public interface Integration { public interface Integration extends Registrable {
/** /**
* Get the name of integration. * Get the name of integration.
* *
* @return The name. * @return The name.
*/ */
String getPluginName(); String getPluginName();
@Override
default @NotNull String getID() {
return Registry.tryFitPattern(this.getPluginName());
}
} }

View File

@@ -0,0 +1,138 @@
package com.willfp.eco.core.integrations;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.registry.Registry;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashSet;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
* Registry for integrations.
*
* @param <T> The type of integration.
*/
public class IntegrationRegistry<T extends Integration> extends Registry<T> {
/**
* Create a new integration registry.
*/
public IntegrationRegistry() {
super();
}
@Override
public @NotNull T register(@NotNull final T element) {
return executeSafely(() -> super.register(element), element);
}
/**
* Iterate over all integrations, safely.
*
* @param action The action to perform.
*/
public void forEachSafely(@NotNull final Consumer<T> action) {
for (T integration : new HashSet<>(this.values())) {
executeSafely(() -> action.accept(integration), integration);
}
}
/**
* If any integrations return true, safely.
*
* @param predicate The predicate to test.
* @return If any integrations return true.
*/
public boolean anySafely(@NotNull final Predicate<T> predicate) {
for (T integration : new HashSet<>(this.values())) {
Boolean result = executeSafely(() -> predicate.test(integration), integration);
if (result != null && result) {
return true;
}
}
return false;
}
/**
* Get the first integration that returns a value, safely.
*
* @param function The function to apply.
* @param defaultValue The default value.
* @param <R> The type of value.
* @return The first value that returns a value.
*/
@NotNull
public <R> R firstSafely(@NotNull final Function<T, R> function,
@NotNull final R defaultValue) {
if (this.isEmpty()) {
return defaultValue;
}
T integration = this.iterator().next();
return executeSafely(() -> function.apply(integration), integration, defaultValue);
}
/**
* Executes a given action safely, catching any exceptions and logging the issue.
*
* @param action The action to execute.
* @param integration The integration to apply the action on.
*/
private void executeSafely(@NotNull final Runnable action,
@NotNull final T integration) {
executeSafely(() -> {
action.run();
return null;
}, integration);
}
/**
* Executes a given action safely, catching any exceptions and logging the issue.
*
* @param action The action to execute.
* @param integration The integration to apply the action on.
* @param <R> The return type of the action.
* @return The result of the action, or null if an exception was thrown.
*/
private <R> R executeSafely(@NotNull final Supplier<R> action,
@NotNull final T integration) {
return executeSafely(action, integration, null);
}
/**
* Executes a given action safely, catching any exceptions and logging the issue.
*
* @param action The action to execute.
* @param integration The integration to apply the action on.
* @param defaultValue The default value to return if an exception is thrown.
* @param <R> The return type of the action.
* @return The result of the action, or the default value if an exception was thrown.
*/
private <R> R executeSafely(@NotNull final Supplier<R> action,
@NotNull final T integration,
@Nullable final R defaultValue) {
try {
return action.get();
} catch (final Exception e) {
Eco.get().getEcoPlugin().getLogger().warning("Integration for " + integration.getPluginName() + " threw an exception!");
Eco.get().getEcoPlugin().getLogger().warning("The integration will be disabled.");
e.printStackTrace();
this.remove(integration);
return defaultValue;
}
}
/**
* If all integrations return true, safely.
*
* @param predicate The predicate to test.
* @return If all integrations return true.
*/
public boolean allSafely(@NotNull final Predicate<T> predicate) {
return !this.anySafely(predicate.negate());
}
}

View File

@@ -1,11 +1,9 @@
package com.willfp.eco.core.integrations.afk; package com.willfp.eco.core.integrations.afk;
import com.willfp.eco.core.integrations.IntegrationRegistry;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
/** /**
* Class to handle afk integrations. * Class to handle afk integrations.
*/ */
@@ -13,7 +11,7 @@ public final class AFKManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private static final Set<AFKIntegration> REGISTERED = new HashSet<>(); private static final IntegrationRegistry<AFKIntegration> REGISTRY = new IntegrationRegistry<>();
/** /**
* Register a new integration. * Register a new integration.
@@ -21,8 +19,7 @@ public final class AFKManager {
* @param integration The integration to register. * @param integration The integration to register.
*/ */
public static void register(@NotNull final AFKIntegration integration) { public static void register(@NotNull final AFKIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName())); REGISTRY.register(integration);
REGISTERED.add(integration);
} }
/** /**
@@ -32,13 +29,7 @@ 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 (AFKIntegration integration : REGISTERED) { return REGISTRY.anySafely(integration -> integration.isAfk(player));
if (integration.isAfk(player)) {
return true;
}
}
return false;
} }
private AFKManager() { private AFKManager() {

View File

@@ -1,11 +0,0 @@
package com.willfp.eco.core.integrations.afk;
/**
* Wrapper class for afk integrations.
*
* @deprecated Use AFKIntegration instead.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
public interface AFKWrapper extends AFKIntegration {
}

View File

@@ -1,14 +1,11 @@
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.Eco;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.integrations.IntegrationRegistry;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
/** /**
* Class to handle anticheat integrations. * Class to handle anticheat integrations.
*/ */
@@ -16,20 +13,7 @@ public final class AnticheatManager {
/** /**
* A set of all registered anticheats. * A set of all registered anticheats.
*/ */
private static final Set<AnticheatIntegration> ANTICHEATS = new HashSet<>(); private static final IntegrationRegistry<AnticheatIntegration> REGISTRY = new IntegrationRegistry<>();
/**
* Register a new anticheat.
*
* @param plugin The plugin.
* @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,
@NotNull final AnticheatIntegration anticheat) {
register(anticheat);
}
/** /**
* Register a new anticheat. * Register a new anticheat.
@@ -40,8 +24,7 @@ public final class AnticheatManager {
if (anticheat instanceof Listener) { if (anticheat instanceof Listener) {
Eco.get().getEcoPlugin().getEventManager().registerListener((Listener) anticheat); Eco.get().getEcoPlugin().getEventManager().registerListener((Listener) anticheat);
} }
ANTICHEATS.removeIf(it -> it.getPluginName().equalsIgnoreCase(anticheat.getPluginName())); REGISTRY.register(anticheat);
ANTICHEATS.add(anticheat);
} }
/** /**
@@ -50,17 +33,16 @@ public final class AnticheatManager {
* @param player The player to exempt. * @param player The player to exempt.
*/ */
public static void exemptPlayer(@NotNull final Player player) { public static void exemptPlayer(@NotNull final Player player) {
ANTICHEATS.forEach(anticheat -> anticheat.exempt(player)); REGISTRY.forEachSafely(anticheat -> anticheat.exempt(player));
} }
/** /**
* Unexempt a player from triggering anticheats. * Unexempt a player from triggering anticheats.
* This is ran a tick after it is called to ensure that there are no event timing conflicts.
* *
* @param player The player to remove the exemption. * @param player The player to remove the exemption.
*/ */
public static void unexemptPlayer(@NotNull final Player player) { public static void unexemptPlayer(@NotNull final Player player) {
ANTICHEATS.forEach(anticheat -> anticheat.unexempt(player)); REGISTRY.forEachSafely(anticheat -> anticheat.unexempt(player));
} }
private AnticheatManager() { private AnticheatManager() {

View File

@@ -1,11 +0,0 @@
package com.willfp.eco.core.integrations.anticheat;
/**
* Wrapper class for anticheat integrations.
*
* @deprecated Use AnticheatIntegration instead.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
public interface AnticheatWrapper extends AnticheatIntegration {
}

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core.integrations.antigrief; package com.willfp.eco.core.integrations.antigrief;
import com.willfp.eco.core.integrations.IntegrationRegistry;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
@@ -16,7 +17,7 @@ public final class AntigriefManager {
/** /**
* Registered antigriefs. * Registered antigriefs.
*/ */
private static final Set<AntigriefIntegration> REGISTERED = new HashSet<>(); private static final IntegrationRegistry<AntigriefIntegration> REGISTRY = new IntegrationRegistry<>();
/** /**
* Register a new AntiGrief/Land Management integration. * Register a new AntiGrief/Land Management integration.
@@ -24,8 +25,7 @@ public final class AntigriefManager {
* @param antigrief The integration to register. * @param antigrief The integration to register.
*/ */
public static void register(@NotNull final AntigriefIntegration antigrief) { public static void register(@NotNull final AntigriefIntegration antigrief) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(antigrief.getPluginName())); REGISTRY.register(antigrief);
REGISTERED.add(antigrief);
} }
/** /**
@@ -34,8 +34,7 @@ public final class AntigriefManager {
* @param antigrief The integration to unregister. * @param antigrief The integration to unregister.
*/ */
public static void unregister(@NotNull final AntigriefIntegration antigrief) { public static void unregister(@NotNull final AntigriefIntegration antigrief) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(antigrief.getPluginName())); REGISTRY.remove(antigrief);
REGISTERED.remove(antigrief);
} }
/** /**
@@ -47,7 +46,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(antigriefIntegration -> antigriefIntegration.canPickupItem(player, location)); return REGISTRY.allSafely(integration -> integration.canPickupItem(player, location));
} }
/** /**
@@ -59,7 +58,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(antigriefIntegration -> antigriefIntegration.canBreakBlock(player, block)); return REGISTRY.allSafely(integration -> integration.canBreakBlock(player, block));
} }
/** /**
@@ -71,7 +70,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(antigriefIntegration -> antigriefIntegration.canCreateExplosion(player, location)); return REGISTRY.allSafely(integration -> integration.canCreateExplosion(player, location));
} }
/** /**
@@ -83,7 +82,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(antigriefIntegration -> antigriefIntegration.canPlaceBlock(player, block)); return REGISTRY.allSafely(integration -> integration.canPlaceBlock(player, block));
} }
/** /**
@@ -95,7 +94,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(antigriefIntegration -> antigriefIntegration.canInjure(player, victim)); return REGISTRY.allSafely(integration -> integration.canInjure(player, victim));
} }
private AntigriefManager() { private AntigriefManager() {

View File

@@ -1,11 +0,0 @@
package com.willfp.eco.core.integrations.antigrief;
/**
* Wrapper class for antigrief integrations.
*
* @deprecated Use AntigriefIntegration instead.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
public interface AntigriefWrapper extends AntigriefIntegration {
}

View File

@@ -1,10 +1,8 @@
package com.willfp.eco.core.integrations.customentities; package com.willfp.eco.core.integrations.customentities;
import com.willfp.eco.core.integrations.IntegrationRegistry;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
/** /**
* Class to handle custom entity integrations. * Class to handle custom entity integrations.
*/ */
@@ -12,7 +10,7 @@ public final class CustomEntitiesManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private static final Set<CustomEntitiesIntegration> REGISTERED = new HashSet<>(); private static final IntegrationRegistry<CustomEntitiesIntegration> REGISTRY = new IntegrationRegistry<>();
/** /**
* Register a new integration. * Register a new integration.
@@ -20,8 +18,7 @@ public final class CustomEntitiesManager {
* @param integration The integration to register. * @param integration The integration to register.
*/ */
public static void register(@NotNull final CustomEntitiesIntegration integration) { public static void register(@NotNull final CustomEntitiesIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName())); REGISTRY.register(integration);
REGISTERED.add(integration);
} }
/** /**
@@ -30,9 +27,7 @@ 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 (CustomEntitiesIntegration integration : REGISTERED) { REGISTRY.forEachSafely(CustomEntitiesIntegration::registerAllEntities);
integration.registerAllEntities();
}
} }
private CustomEntitiesManager() { private CustomEntitiesManager() {

View File

@@ -1,11 +0,0 @@
package com.willfp.eco.core.integrations.customentities;
/**
* Wrapper class for custom item integrations.
*
* @deprecated Use CustomEntitiesIntegration instead.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
public interface CustomEntitiesWrapper extends CustomEntitiesIntegration {
}

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core.integrations.customitems; package com.willfp.eco.core.integrations.customitems;
import com.willfp.eco.core.integrations.IntegrationRegistry;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.HashSet; import java.util.HashSet;
@@ -12,7 +13,7 @@ public final class CustomItemsManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private static final Set<CustomItemsIntegration> REGISTERED = new HashSet<>(); private static final IntegrationRegistry<CustomItemsIntegration> REGISTRY = new IntegrationRegistry<>();
/** /**
* Register a new integration. * Register a new integration.
@@ -20,8 +21,7 @@ public final class CustomItemsManager {
* @param integration The integration to register. * @param integration The integration to register.
*/ */
public static void register(@NotNull final CustomItemsIntegration integration) { public static void register(@NotNull final CustomItemsIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName())); REGISTRY.register(integration);
REGISTERED.add(integration);
} }
/** /**
@@ -30,9 +30,7 @@ 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 (CustomItemsIntegration customItemsIntegration : REGISTERED) { REGISTRY.forEachSafely(CustomItemsIntegration::registerAllItems);
customItemsIntegration.registerAllItems();
}
} }
/** /**
@@ -41,9 +39,7 @@ 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 (CustomItemsIntegration customItemsIntegration : REGISTERED) { REGISTRY.forEachSafely(CustomItemsIntegration::registerProvider);
customItemsIntegration.registerProvider();
}
} }
private CustomItemsManager() { private CustomItemsManager() {

View File

@@ -1,11 +0,0 @@
package com.willfp.eco.core.integrations.customitems;
/**
* Wrapper class for custom item integrations.
*
* @deprecated Use CustomItemsIntegration instead.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
public interface CustomItemsWrapper extends CustomItemsIntegration {
}

View File

@@ -1,11 +1,10 @@
package com.willfp.eco.core.integrations.economy; package com.willfp.eco.core.integrations.economy;
import com.willfp.eco.core.integrations.IntegrationRegistry;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.HashSet;
import java.util.Set;
/** /**
* Class to handle economy. * Class to handle economy.
@@ -14,7 +13,7 @@ public final class EconomyManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private static final Set<EconomyIntegration> REGISTERED = new HashSet<>(); private static final IntegrationRegistry<EconomyIntegration> REGISTRY = new IntegrationRegistry<>();
/** /**
* Register a new integration. * Register a new integration.
@@ -22,8 +21,7 @@ public final class EconomyManager {
* @param integration The integration to register. * @param integration The integration to register.
*/ */
public static void register(@NotNull final EconomyIntegration integration) { public static void register(@NotNull final EconomyIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName())); REGISTRY.register(integration);
REGISTERED.add(integration);
} }
/** /**
@@ -32,7 +30,7 @@ public final class EconomyManager {
* @return If any economy. * @return If any economy.
*/ */
public static boolean hasRegistrations() { public static boolean hasRegistrations() {
return !REGISTERED.isEmpty(); return REGISTRY.isNotEmpty();
} }
/** /**
@@ -56,11 +54,10 @@ public final class EconomyManager {
*/ */
public static boolean hasAmount(@NotNull final OfflinePlayer player, public static boolean hasAmount(@NotNull final OfflinePlayer player,
final BigDecimal amount) { final BigDecimal amount) {
for (EconomyIntegration integration : REGISTERED) { return REGISTRY.firstSafely(
return integration.hasAmount(player, amount); integration -> integration.hasAmount(player, amount),
} false
);
return false;
} }
/** /**
@@ -84,11 +81,10 @@ public final class EconomyManager {
*/ */
public static boolean giveMoney(@NotNull final OfflinePlayer player, public static boolean giveMoney(@NotNull final OfflinePlayer player,
@NotNull final BigDecimal amount) { @NotNull final BigDecimal amount) {
for (EconomyIntegration integration : REGISTERED) { return REGISTRY.firstSafely(
return integration.giveMoney(player, amount); integration -> integration.giveMoney(player, amount),
} false
);
return false;
} }
/** /**
@@ -112,11 +108,10 @@ public final class EconomyManager {
*/ */
public static boolean removeMoney(@NotNull final OfflinePlayer player, public static boolean removeMoney(@NotNull final OfflinePlayer player,
@NotNull final BigDecimal amount) { @NotNull final BigDecimal amount) {
for (EconomyIntegration integration : REGISTERED) { return REGISTRY.firstSafely(
return integration.removeMoney(player, amount); integration -> integration.removeMoney(player, amount),
} false
);
return false;
} }
/** /**
@@ -136,11 +131,10 @@ public final class EconomyManager {
* @return The balance. * @return The balance.
*/ */
public static BigDecimal getExactBalance(@NotNull final OfflinePlayer player) { public static BigDecimal getExactBalance(@NotNull final OfflinePlayer player) {
for (EconomyIntegration integration : REGISTERED) { return REGISTRY.firstSafely(
return integration.getExactBalance(player); integration -> integration.getExactBalance(player),
} BigDecimal.ZERO
);
return BigDecimal.ZERO;
} }
private EconomyManager() { private EconomyManager() {

View File

@@ -1,11 +0,0 @@
package com.willfp.eco.core.integrations.economy;
/**
* Wrapper class for economy integrations.
*
* @deprecated Use EconomyIntegration instead.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
public interface EconomyWrapper extends EconomyIntegration {
}

View File

@@ -0,0 +1,18 @@
package com.willfp.eco.core.integrations.guidetection;
import com.willfp.eco.core.integrations.Integration;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
/**
* Wrapper class for GUI integrations.
*/
public interface GUIDetectionIntegration extends Integration {
/**
* Determine if a player is in a GUI.
*
* @param player The player.
* @return If the player is in a GUI.
*/
boolean hasGUIOpen(@NotNull final Player player);
}

View File

@@ -0,0 +1,43 @@
package com.willfp.eco.core.integrations.guidetection;
import com.willfp.eco.core.integrations.IntegrationRegistry;
import com.willfp.eco.util.MenuUtils;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
/**
* Class to handle GUI detection.
*/
public final class GUIDetectionManager {
/**
* A set of all registered integrations.
*/
private static final IntegrationRegistry<GUIDetectionIntegration> REGISTRY = new IntegrationRegistry<>();
/**
* Register a new integration.
*
* @param integration The integration to register.
*/
public static void register(@NotNull final GUIDetectionIntegration integration) {
REGISTRY.register(integration);
}
/**
* Get if a player is in a GUI.
*
* @param player The player.
* @return If the player has a GUI open.
*/
public static boolean hasGUIOpen(@NotNull final Player player) {
if (MenuUtils.getOpenMenu(player) != null) {
return true;
}
return REGISTRY.anySafely(integration -> integration.hasGUIOpen(player));
}
private GUIDetectionManager() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
}

View File

@@ -1,11 +1,10 @@
package com.willfp.eco.core.integrations.hologram; package com.willfp.eco.core.integrations.hologram;
import com.willfp.eco.core.integrations.IntegrationRegistry;
import org.bukkit.Location; import org.bukkit.Location;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
/** /**
* Class to handle hologram integrations. * Class to handle hologram integrations.
@@ -14,7 +13,7 @@ public final class HologramManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private static final Set<HologramIntegration> REGISTERED = new HashSet<>(); private static final IntegrationRegistry<HologramIntegration> REGISTRY = new IntegrationRegistry<>();
/** /**
* Register a new integration. * Register a new integration.
@@ -22,8 +21,7 @@ public final class HologramManager {
* @param integration The integration to register. * @param integration The integration to register.
*/ */
public static void register(@NotNull final HologramIntegration integration) { public static void register(@NotNull final HologramIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName())); REGISTRY.register(integration);
REGISTERED.add(integration);
} }
/** /**
@@ -35,11 +33,10 @@ 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 (HologramIntegration integration : REGISTERED) { return REGISTRY.firstSafely(
return integration.createHologram(location, contents); integration -> integration.createHologram(location, contents),
} new DummyHologram()
);
return new DummyHologram();
} }
private HologramManager() { private HologramManager() {

View File

@@ -1,11 +0,0 @@
package com.willfp.eco.core.integrations.hologram;
/**
* Wrapper class for hologram integrations.
*
* @deprecated Use HologramIntegration instead.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
public interface HologramWrapper extends HologramIntegration {
}

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core.integrations.mcmmo; package com.willfp.eco.core.integrations.mcmmo;
import com.willfp.eco.core.integrations.IntegrationRegistry;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.event.Event; import org.bukkit.event.Event;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -14,7 +15,7 @@ public final class McmmoManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private static final Set<McmmoIntegration> REGISTERED = new HashSet<>(); private static final IntegrationRegistry<McmmoIntegration> REGISTERED = new IntegrationRegistry<>();
/** /**
* Register a new integration. * Register a new integration.
@@ -22,8 +23,7 @@ public final class McmmoManager {
* @param integration The integration to register. * @param integration The integration to register.
*/ */
public static void register(@NotNull final McmmoIntegration integration) { public static void register(@NotNull final McmmoIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName())); REGISTERED.register(integration);
REGISTERED.add(integration);
} }
/** /**
@@ -34,13 +34,11 @@ public final class McmmoManager {
*/ */
public static int getBonusDropCount(@NotNull final Block block) { public static int getBonusDropCount(@NotNull final Block block) {
int finalValue = 0; int finalValue = 0;
for (McmmoIntegration mcmmoIntegration : REGISTERED) { for (McmmoIntegration mcmmoIntegration : REGISTERED) {
finalValue += mcmmoIntegration.getBonusDropCount(block); finalValue += mcmmoIntegration.getBonusDropCount(block);
} }
return finalValue; return finalValue;
} }
@@ -51,13 +49,7 @@ 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 (McmmoIntegration mcmmoIntegration : REGISTERED) { return REGISTERED.anySafely(integration -> integration.isFake(event));
if (mcmmoIntegration.isFake(event)) {
return true;
}
}
return false;
} }
private McmmoManager() { private McmmoManager() {

View File

@@ -1,11 +0,0 @@
package com.willfp.eco.core.integrations.mcmmo;
/**
* Wrapper class for mcmmo integrations.
*
* @deprecated Use McmmoIntegration instead.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
public interface McmmoWrapper extends McmmoIntegration {
}

View File

@@ -1,190 +0,0 @@
package com.willfp.eco.core.integrations.placeholder;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.placeholder.Placeholder;
import com.willfp.eco.core.placeholder.PlayerPlaceholder;
import com.willfp.eco.core.placeholder.PlayerlessPlaceholder;
import org.apache.commons.lang.Validate;
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 entry is a placeholder in and of itself.
* <p>
* It should be fairly straightforward.
*
* @deprecated Confusing functionality with inconsistent nullability and poor naming.
*/
@Deprecated(since = "6.28.0", forRemoval = true)
public class PlaceholderEntry {
/**
* The name of the placeholder, used in lookups.
*/
private final String identifier;
/**
* The lambda to retrieve the output of the placeholder given a player.
*/
private final Function<Player, String> function;
/**
* If the placeholder requires a player to lookup.
*/
private final boolean requiresPlayer;
/**
* The plugin for the placeholder.
*/
@Nullable
private final EcoPlugin plugin;
/**
* Create a placeholder entry that doesn't require a player.
*
* @param identifier The identifier of the placeholder.
* @param function A lambda to get the result of the placeholder given a player.
* @deprecated Specify a plugin.
*/
@Deprecated
public PlaceholderEntry(@NotNull final String identifier,
@NotNull final Function<Player, String> function) {
this(identifier, function, false);
}
/**
* Create a placeholder entry that may require a player.
*
* @param identifier The identifier of the placeholder.
* @param function A lambda to get the result of the placeholder.
* @param requiresPlayer If the placeholder requires a player.
* @deprecated Specify a plugin.
*/
@Deprecated
public PlaceholderEntry(@NotNull final String identifier,
@NotNull final Function<Player, String> function,
final boolean requiresPlayer) {
this(null, identifier, function, requiresPlayer);
}
/**
* Create a placeholder entry that doesn't require a player.
*
* @param plugin The plugin for the placeholder.
* @param identifier The identifier of the placeholder.
* @param function A lambda to get the result of the placeholder given a player.
*/
public PlaceholderEntry(@Nullable final EcoPlugin plugin,
@NotNull final String identifier,
@NotNull final Function<Player, String> function) {
this(plugin, identifier, function, false);
}
/**
* Create a placeholder entry that may require a player.
*
* @param plugin The plugin for the placeholder.
* @param identifier The identifier of the placeholder.
* @param function A lambda to get the result of the placeholder.
* @param requiresPlayer If the placeholder requires a player.
*/
public PlaceholderEntry(@Nullable final EcoPlugin plugin,
@NotNull final String identifier,
@NotNull final Function<Player, String> function,
final boolean requiresPlayer) {
this.plugin = plugin;
this.identifier = identifier;
this.function = function;
this.requiresPlayer = requiresPlayer;
}
/**
* Get the result of the placeholder with respect to a player.
*
* @param player The player to translate with respect to.
* @return The result of the placeholder.
*/
public String getResult(@Nullable final Player player) {
if (player == null) {
Validate.isTrue(!requiresPlayer, "null player passed to requiresPlayer placeholder.");
}
return this.function.apply(player);
}
/**
* Get if the placeholder requires a player to get a result.
*
* @return If the placeholder requires a player.
*/
public boolean requiresPlayer() {
return requiresPlayer;
}
/**
* Get the identifier.
*
* @return The identifier.
*/
public String getIdentifier() {
return identifier;
}
/**
* Get the plugin.
*
* @return The plugin.
*/
@Nullable
public EcoPlugin getPlugin() {
return plugin;
}
/**
* Register the placeholder.
*/
public void register() {
PlaceholderManager.registerPlaceholder(this.toModernPlaceholder());
}
/**
* Convert the placeholder to a modern placeholder.
*
* @return The placeholder.
*/
Placeholder toModernPlaceholder() {
if (this.requiresPlayer) {
return new PlayerPlaceholder(
Objects.requireNonNullElse(plugin, Eco.get().getEcoPlugin()),
identifier,
function
);
} else {
return new PlayerlessPlaceholder(
Objects.requireNonNullElse(plugin, Eco.get().getEcoPlugin()),
identifier,
() -> function.apply(null)
);
}
}
@Override
public boolean equals(@Nullable final Object o) {
if (this == o) {
return true;
}
if (!(o instanceof PlaceholderEntry entry)) {
return false;
}
return Objects.equals(this.getIdentifier(), entry.getIdentifier())
&& Objects.equals(this.getPlugin(), entry.getPlugin());
}
@Override
public int hashCode() {
return Objects.hash(this.getIdentifier(), this.getPlugin());
}
}

View File

@@ -9,7 +9,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
* Wrapper class for placeholder integrations. * Wrapper class for arguments integrations.
*/ */
public interface PlaceholderIntegration extends Integration { public interface PlaceholderIntegration extends Integration {
/** /**

View File

@@ -1,18 +1,15 @@
package com.willfp.eco.core.integrations.placeholder; package com.willfp.eco.core.integrations.placeholder;
import com.github.benmanes.caffeine.cache.Caffeine; import com.google.common.collect.ImmutableSet;
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.map.DefaultMap;
import com.willfp.eco.core.placeholder.AdditionalPlayer; import com.willfp.eco.core.placeholder.AdditionalPlayer;
import com.willfp.eco.core.placeholder.InjectablePlaceholder; 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.PlaceholderInjectable;
import com.willfp.eco.core.placeholder.PlayerPlaceholder; import com.willfp.eco.core.placeholder.RegistrablePlaceholder;
import com.willfp.eco.core.placeholder.PlayerStaticPlaceholder; import com.willfp.eco.core.placeholder.context.PlaceholderContext;
import com.willfp.eco.core.placeholder.PlayerlessPlaceholder;
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;
@@ -20,46 +17,41 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/** /**
* Class to handle placeholder integrations. * Class to handle arguments integrations.
*/ */
@SuppressWarnings("removal")
public final class PlaceholderManager { public final class PlaceholderManager {
/** /**
* All registered placeholders. * All registered placeholders.
*/ */
private static final Map<EcoPlugin, Map<String, Placeholder>> REGISTERED_PLACEHOLDERS = new HashMap<>(); private static final DefaultMap<EcoPlugin, Set<Placeholder>> REGISTERED_PLACEHOLDERS = new DefaultMap<>(HashSet::new);
/** /**
* All registered placeholder integrations. * All registered arguments integrations.
*/ */
private static final Set<PlaceholderIntegration> REGISTERED_INTEGRATIONS = new HashSet<>(); private static final Set<PlaceholderIntegration> REGISTERED_INTEGRATIONS = new HashSet<>();
/**
* Placeholder Cache.
*/
private static final LoadingCache<EntryWithPlayer, String> PLACEHOLDER_CACHE = Caffeine.newBuilder()
.expireAfterWrite(50, TimeUnit.MILLISECONDS)
.build(key -> key.entry.getValue(key.player));
/** /**
* The default PlaceholderAPI pattern; brought in for compatibility. * The default PlaceholderAPI pattern; brought in for compatibility.
*/ */
private static final Pattern PATTERN = Pattern.compile("[%]([^% ]+)[%]"); private static final Pattern PATTERN = Pattern.compile("%([^% ]+)%");
/** /**
* Empty injectable object. * Empty injectableContext object.
*/ */
public static final PlaceholderInjectable EMPTY_INJECTABLE = new PlaceholderInjectable() { public static final PlaceholderInjectable EMPTY_INJECTABLE = new PlaceholderInjectable() {
@Override
public void addInjectablePlaceholder(@NotNull Iterable<InjectablePlaceholder> placeholders) {
// Do nothing.
}
@Override @Override
public void clearInjectedPlaceholders() { public void clearInjectedPlaceholders() {
// Do nothing. // Do nothing.
@@ -83,85 +75,68 @@ public final class PlaceholderManager {
} }
/** /**
* Register a placeholder. * Register a arguments.
* *
* @param placeholder The placeholder to register. * @param placeholder The arguments to register.
* @deprecated Use {@link #registerPlaceholder(RegistrablePlaceholder)} instead.
*/ */
@Deprecated(since = "6.56.0", forRemoval = true)
public static void registerPlaceholder(@NotNull final Placeholder placeholder) { public static void registerPlaceholder(@NotNull final Placeholder placeholder) {
if (placeholder instanceof StaticPlaceholder) { if (!(placeholder instanceof RegistrablePlaceholder)) {
throw new IllegalArgumentException("Static placeholders cannot be registered!"); throw new IllegalArgumentException("Placeholder must be RegistrablePlaceholder!");
} }
EcoPlugin plugin = placeholder.getPlugin() == null ? Eco.get().getEcoPlugin() : placeholder.getPlugin(); registerPlaceholder((RegistrablePlaceholder) placeholder);
Map<String, Placeholder> pluginPlaceholders = REGISTERED_PLACEHOLDERS
.getOrDefault(plugin, new HashMap<>());
pluginPlaceholders.put(placeholder.getIdentifier(), placeholder);
REGISTERED_PLACEHOLDERS.put(plugin, pluginPlaceholders);
} }
/** /**
* Register a placeholder. * Register a arguments.
* *
* @param placeholder The placeholder to register. * @param placeholder The arguments to register.
* @deprecated Uses old placeholder system.
*/ */
@Deprecated(since = "6.28.0", forRemoval = true) public static void registerPlaceholder(@NotNull final RegistrablePlaceholder placeholder) {
public static void registerPlaceholder(@NotNull final PlaceholderEntry placeholder) { // Storing as immutable set leads to slower times to register placeholders, but much
registerPlaceholder(placeholder.toModernPlaceholder()); // faster times to access registrations.
Set<Placeholder> pluginPlaceholders = new HashSet<>(REGISTERED_PLACEHOLDERS.get(placeholder.getPlugin()));
pluginPlaceholders.add(placeholder);
REGISTERED_PLACEHOLDERS.put(placeholder.getPlugin(), ImmutableSet.copyOf(pluginPlaceholders));
} }
/** /**
* Get the result of a placeholder with respect to a player. * Get the result of a placeholder with respect to a player.
* *
* @param player The player to get the result from. * @param player The player to get the result from.
* @param identifier The placeholder identifier. * @param identifier The placeholder args.
* @return The value of the placeholder. * @param plugin The plugin for the arguments.
* @deprecated Specify a plugin to get the result from. * @return The value of the arguments.
*/
@Deprecated
public static String getResult(@Nullable final Player player,
@NotNull final String identifier) {
return getResult(player, identifier, null);
}
/**
* Get the result of a placeholder with respect to a player.
*
* @param player The player to get the result from.
* @param identifier The placeholder identifier.
* @param plugin The plugin for the placeholder.
* @return The value of the placeholder.
*/ */
@NotNull @NotNull
public static String getResult(@Nullable final Player player, public static String getResult(@Nullable final Player player,
@NotNull final String identifier, @NotNull final String identifier,
@Nullable final EcoPlugin plugin) { @Nullable final EcoPlugin plugin) {
EcoPlugin owner = plugin == null ? Eco.get().getEcoPlugin() : plugin; return Objects.requireNonNullElse(
Placeholder placeholder = REGISTERED_PLACEHOLDERS.getOrDefault(owner, new HashMap<>()).get(identifier.toLowerCase()); getResult(
plugin,
identifier,
new PlaceholderContext(player)
),
""
);
}
if (placeholder == null && plugin != null) { /**
Placeholder alternate = REGISTERED_PLACEHOLDERS.getOrDefault(Eco.get().getEcoPlugin(), new HashMap<>()) * Get the result of a placeholder given a plugin and arguments.
.get(identifier.toLowerCase()); *
if (alternate != null) { * @param plugin The plugin for the placeholder.
placeholder = alternate; * @param args The arguments.
} * @param context The context.
} * @return The value of the arguments.
*/
if (placeholder == null) { @Nullable
return ""; public static String getResult(@Nullable final EcoPlugin plugin,
} @NotNull final String args,
@NotNull final PlaceholderContext context) {
if (placeholder instanceof PlayerPlaceholder playerPlaceholder) { return Eco.get().getPlaceholderValue(plugin, args, context);
if (player == null) {
return "";
} else {
return PLACEHOLDER_CACHE.get(new EntryWithPlayer(playerPlaceholder, player));
}
} else if (placeholder instanceof PlayerlessPlaceholder playerlessPlaceholder) {
return playerlessPlaceholder.getValue();
} else {
return "";
}
} }
/** /**
@@ -170,7 +145,10 @@ public final class PlaceholderManager {
* @param text The text that may contain placeholders to translate. * @param text The text that may contain placeholders to translate.
* @param player The player to translate the placeholders with respect to. * @param player The player to translate the placeholders with respect to.
* @return The text, translated. * @return The text, translated.
* @deprecated Use {@link #translatePlaceholders(String, PlaceholderContext)} instead.
*/ */
@Deprecated(since = "6.56.0", forRemoval = true)
@NotNull
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, EMPTY_INJECTABLE); return translatePlaceholders(text, player, EMPTY_INJECTABLE);
@@ -181,25 +159,12 @@ public final class PlaceholderManager {
* *
* @param text The text that may contain placeholders to translate. * @param text The text that may contain placeholders to translate.
* @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 context The injectableContext parseContext.
* @return The text, translated.
* @deprecated Use new static system.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
public static String translatePlaceholders(@NotNull final String text,
@Nullable final Player player,
@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. * @return The text, translated.
* @deprecated Use {@link #translatePlaceholders(String, PlaceholderContext)} instead.
*/ */
@Deprecated(since = "6.56.0", forRemoval = true)
@NotNull
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 PlaceholderInjectable context) { @NotNull final PlaceholderInjectable context) {
@@ -211,49 +176,50 @@ public final class PlaceholderManager {
* *
* @param text The text that may contain placeholders to translate. * @param text The text that may contain placeholders to translate.
* @param player The player to translate the placeholders with respect to. * @param player The player to translate the placeholders with respect to.
* @param context The injectable context. * @param context The injectableContext parseContext.
* @param additionalPlayers Additional players to translate placeholders for. * @param additionalPlayers Additional players to translate placeholders for.
* @return The text, translated. * @return The text, translated.
* @deprecated Use {@link #translatePlaceholders(String, PlaceholderContext)} instead.
*/ */
@Deprecated(since = "6.56.0", forRemoval = true)
@NotNull
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 PlaceholderInjectable context, @NotNull final PlaceholderInjectable context,
@NotNull final Collection<AdditionalPlayer> additionalPlayers) { @NotNull final Collection<AdditionalPlayer> additionalPlayers) {
String processed = text; return translatePlaceholders(
text,
new PlaceholderContext(
player,
null,
context,
additionalPlayers
)
);
}
// Prevent running 2 scans if there are no additional players. /**
if (!additionalPlayers.isEmpty()) { * Translate all placeholders without a placeholder context.
List<String> found = findPlaceholdersIn(text); *
* @param text The text that may contain placeholders to translate.
* @return The text, translated.
*/
@NotNull
public static String translatePlaceholders(@NotNull final String text) {
return Eco.get().translatePlaceholders(text, PlaceholderContext.EMPTY);
}
for (AdditionalPlayer additionalPlayer : additionalPlayers) { /**
for (String placeholder : found) { * Translate all placeholders in a translation context.
String prefix = "%" + additionalPlayer.getIdentifier() + "_"; *
* @param text The text that may contain placeholders to translate.
if (placeholder.startsWith(prefix)) { * @param context The translation context.
processed = processed.replace( * @return The text, translated.
placeholder, */
translatePlaceholders( @NotNull
"%" + StringUtils.removePrefix(prefix, placeholder), public static String translatePlaceholders(@NotNull final String text,
additionalPlayer.getPlayer() @NotNull final PlaceholderContext context) {
) return Eco.get().translatePlaceholders(text, context);
);
}
}
}
}
for (PlaceholderIntegration integration : REGISTERED_INTEGRATIONS) {
processed = integration.translate(processed, player);
}
for (InjectablePlaceholder injection : context.getPlaceholderInjections()) {
// Do I know this is a bad way of doing this? Yes.
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;
} }
/** /**
@@ -265,12 +231,9 @@ public final class PlaceholderManager {
public static List<String> findPlaceholdersIn(@NotNull final String text) { public static List<String> findPlaceholdersIn(@NotNull final String text) {
Set<String> found = new HashSet<>(); Set<String> found = new HashSet<>();
// Mock PAPI for those without it installed Matcher matcher = PATTERN.matcher(text);
if (REGISTERED_INTEGRATIONS.isEmpty()) { while (matcher.find()) {
Matcher matcher = PATTERN.matcher(text); found.add(matcher.group());
while (matcher.find()) {
found.add(matcher.group());
}
} }
for (PlaceholderIntegration integration : REGISTERED_INTEGRATIONS) { for (PlaceholderIntegration integration : REGISTERED_INTEGRATIONS) {
@@ -280,9 +243,23 @@ public final class PlaceholderManager {
return new ArrayList<>(found); return new ArrayList<>(found);
} }
private record EntryWithPlayer(@NotNull PlayerPlaceholder entry, /**
@NotNull Player player) { * Get all registered placeholder integrations.
*
* @return The integrations.
*/
public static Set<PlaceholderIntegration> getRegisteredIntegrations() {
return Set.copyOf(REGISTERED_INTEGRATIONS);
}
/**
* Get all registered placeholders for a plugin.
*
* @param plugin The plugin.
* @return The placeholders.
*/
public static Set<Placeholder> getRegisteredPlaceholders(@NotNull final EcoPlugin plugin) {
return REGISTERED_PLACEHOLDERS.get(plugin);
} }
private PlaceholderManager() { private PlaceholderManager() {

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