Compare commits

..

532 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
Auxilor
1a96fdf465 Updated to 6.49.1 2023-01-24 11:47:18 +00:00
Auxilor
cee1ac4cc2 Fixed eco setting off it's own warnings 2023-01-23 12:10:12 +00:00
Auxilor
ac10fa46dc Fixed javadoc 2023-01-23 11:27:44 +00:00
Auxilor
7c616e64ae Fixed XP / XPL 2023-01-18 20:03:28 +00:00
Auxilor
708f9130c6 Removed old docs URL 2023-01-18 12:53:13 +00:00
Auxilor
9118d49c67 Updated README.md 2023-01-18 12:52:29 +00:00
Auxilor
a1ce72476f Fixed README.md 2023-01-18 12:38:39 +00:00
Auxilor
2cfab99644 Fixed a plethora of codestyle issues 2023-01-17 17:57:40 +00:00
Auxilor
cc9b3f7710 Small blips 2023-01-17 17:50:07 +00:00
Auxilor
5bfe48c8d9 Updated CONTRIBUTING.md 2023-01-17 17:48:45 +00:00
Auxilor
22ff157ffc Merge branch 'MisterFrans_master' into develop 2023-01-17 17:44:35 +00:00
Auxilor
720dbe789c Merge branch 'patch-1' into develop 2023-01-17 17:42:49 +00:00
Auxilor
b51dd51941 Deprecated Prerequisite#HAS_BUNGEECORD and Prerequisite#HAS_VELOCITY 2023-01-17 16:05:06 +00:00
Auxilor
f3ffaa4cf6 Javadoc improvements 2023-01-17 16:02:07 +00:00
Auxilor
085032e315 Further command cleanup, added lang.yml validation and removed magic strings 2023-01-17 15:59:15 +00:00
Auxilor
3d920ee2b4 Updated to 6.49.0 2023-01-17 12:20:51 +00:00
Auxilor
06a04e4375 Fixed spelling inconsistency 2023-01-17 12:19:59 +00:00
Auxilor
7349f15784 Cleaned up command rework 2023-01-17 12:18:10 +00:00
Auxilor
a4c77857d5 Merge branch 'master' into Samkist_master 2023-01-17 12:00:10 +00:00
Auxilor
999fafc8df Javadoc cleanjp 2023-01-17 12:00:04 +00:00
Auxilor
0d533850f6 Updated to 6.48.3 2023-01-13 17:53:44 +00:00
Auxilor
569f9cfcb4 Merge remote-tracking branch 'origin/master' 2023-01-13 17:52:53 +00:00
Auxilor
f0619f2374 Updated to 6.48.2 2023-01-13 17:52:48 +00:00
Auxilor
7e8d97e11d Updated MythicMobs and ExecutableItems 2023-01-13 17:52:20 +00:00
Auxilor
d3414f25ad Cleanup 2023-01-13 17:39:29 +00:00
MCCasper
f0cf118448 Update McmmoManager.java
Change to not quit after first iteration of loop
2022-12-29 10:07:05 -05:00
François
297bb10b85 Removal of an unnecessary semicolon 2022-12-27 13:06:22 +01:00
François
751624bc8d Update of Lands api to the latest version (6.26.7). 2022-12-26 15:34:11 +01:00
Auxilor
8b1b15a3e4 Updated to 6.48.2 2022-12-20 15:05:30 +00:00
Auxilor
7fe330bafb Fixed 1.19.3 support 2022-12-20 15:05:21 +00:00
Auxilor
20584b2a9b Updated to 6.48.1 2022-12-12 12:13:32 +00:00
Auxilor
bd7594a117 Fixed 1.19.3 build 2022-12-12 12:13:22 +00:00
Samuel Pizette
f1bfa21270 restructured some methods 2022-12-11 20:32:23 -05:00
Samuel Pizette
01aa1e708a more missing documentations 2022-12-11 14:17:16 -05:00
Samuel Pizette
8424baa285 wrote missing documentations 2022-12-11 14:14:37 -05:00
Auxilor
d9a8d26990 Fixed 1.19.3 build 2022-12-11 17:07:33 +00:00
Auxilor
4d3eeaaefc Added 1.19.3 support 2022-12-11 16:58:58 +00:00
Samuel Pizette
d54a2b9516 fixed method signature of extensions 2022-12-10 17:18:06 -05:00
Samuel Pizette
f7f12b6255 finished working refactor 2022-12-10 16:50:52 -05:00
Samuel Pizette
42eb1344a6 removed unneeded debug statement 2022-12-10 16:08:33 -05:00
Samuel Pizette
4c2a8585cc got command functionality working 2022-12-10 16:08:01 -05:00
Samuel Pizette
8cccc67b0d wrote documentation for Eco Plugin and Eco Sub Command 2022-12-09 14:42:12 -05:00
Samuel Pizette
396d74497c wrote EcoHandledCommand.kt documentation 2022-12-09 14:38:13 -05:00
Samuel Pizette
49602dce04 rewrote notify documentation 2022-12-09 14:24:13 -05:00
Samuel Pizette
5da811ba74 added notifyPermissionRequired and updated some comments 2022-12-09 13:52:03 -05:00
Samuel Pizette
a4d57e21fe cleaned up eco handled command 2022-12-09 13:29:33 -05:00
Samuel Pizette
4b8efdc79f whoops 2022-12-09 12:10:39 -05:00
Auxilor
610110efde Improved CombinedDisplayPrice 2022-12-07 16:38:32 +00:00
Samuel Pizette
a87f675269 updated method signature annotations to accurately reflect behavior 2022-12-06 03:42:34 -05:00
Samuel Pizette
a371d314b8 shortened logic of notifyNull extension 2022-12-06 03:38:28 -05:00
Samuel Pizette
9a9097adc5 updated some annotations 2022-12-05 20:27:31 -05:00
Samuel Pizette
0669a57e4b updated some annotations 2022-12-05 20:08:35 -05:00
Samuel Pizette
692eaf6836 changed onTabComplete return signature in EcoDelegatedBukkitCommand.kt from nullable to not null 2022-12-05 19:22:09 -05:00
Auxilor
7f9052c64d Updated to 6.48.0 2022-12-05 12:34:53 +00:00
Auxilor
55a841b3f5 Added CombinedDisplayPrice 2022-12-05 12:34:45 +00:00
Samuel Pizette
85f02c5ca2 wrote notification kotlin extensions 2022-12-04 19:35:54 -05:00
Samuel Pizette
74c428b90d rearranged notify methods 2022-12-04 19:17:36 -05:00
Samuel Pizette
fd8c67fa66 wrote handle tab complete for ecohandled command 2022-12-04 19:13:23 -05:00
Samuel Pizette
a396754e2e commands rework progress
- Wrote EcoDelegatedBukkitCommand.kt
- Wrote EcoHandledCommand.kt
- Wrote Eco#createSubCommand
- Renamed RegistrableCommandBase.java to PluginCommandBase
- Moved most of EcoPluginCommand.kt to EcoHandledCommand.kt
- Changed Delegate type in PluginCommand from CommandBase to PluginCommandBase
2022-12-04 18:52:19 -05:00
Samuel Pizette
6f97f47712 removed getAliases and getDescription from commandbase 2022-12-04 18:50:03 -05:00
Samuel Pizette
d1109e485a more fixing auto reformat 2022-12-04 17:56:07 -05:00
Samuel Pizette
476e5c7cae fuck auto reformat 2022-12-04 17:54:50 -05:00
Samuel Pizette
dc2b7a6fda returned instance get to original location 2022-12-04 17:53:49 -05:00
Samuel Pizette
00f18519b0 progress commit 2022-12-04 17:52:05 -05:00
Samuel Pizette
f7ea5fd182 fix eco format 2022-11-30 16:50:02 -05:00
Samuel Pizette
70d29c872a removed HandledCommand 2022-11-29 16:29:23 -05:00
Samuel Pizette
f79f4a84c3 deprecated DelegatedBukkitCommand 2022-11-29 16:29:16 -05:00
Samuel Pizette
9af63907ef Merge branch 'master' into master 2022-11-29 16:28:37 -05:00
Samuel Pizette
c9aa92895b work in progress commit 2022-11-29 16:13:01 -05:00
Auxilor
c57c824027 Cleaned up UltraEconomy integration 2022-11-29 15:56:30 +00:00
Auxilor
7cb905e65a Merge remote-tracking branch 'origin/develop' into develop
# Conflicts:
#	eco-api/src/main/java/com/willfp/eco/core/gui/slot/ConfigSlot.java
2022-11-29 15:47:52 +00:00
Auxilor
31a2c7e338 Added lore to ConfigSlot 2022-11-29 15:47:41 +00:00
Auxilor
1759b52f82 Added lore to ConfigSlot 2022-11-29 15:37:36 +00:00
Auxilor
ccf93e3a4d Fixed 2x2 crafting bug 2022-11-28 23:55:45 +00:00
Auxilor
abd07389ab Fixed dynamic command registration 2022-11-28 17:28:29 +00:00
Auxilor
80ad738bb2 Removed AbstractItemStackBuilder correctifying things 2022-11-28 15:10:28 +00:00
Auxilor
b01105819a Updated EconomyShopGUI and ShopGUI+ integrations 2022-11-28 14:46:38 +00:00
Auxilor
a7c08b0731 Updated shop API (again) 2022-11-28 14:40:42 +00:00
Auxilor
7e4c071698 Fixed javadoc 2022-11-28 14:28:38 +00:00
Auxilor
f94f7ead08 Reworked price/shop API to have call-site multipliers 2022-11-28 14:26:46 +00:00
Auxilor
b21c5bf3a9 Fixed captive filter and GUI drag bug 2022-11-28 13:57:41 +00:00
Auxilor
7a9e8c5c10 Fixed bug with multiple stacked paginated menus 2022-11-25 16:51:17 +00:00
Auxilor
a6ddbc46ab Fixes 2022-11-25 16:28:24 +00:00
Auxilor
ffaee137d8 Overhauled ShopSellEvent API 2022-11-24 23:19:03 +00:00
Auxilor
18d882dac6 Reworked Shop API 2022-11-24 23:12:25 +00:00
Auxilor
52841f7f04 Fixed bug with price copying 2022-11-23 22:31:37 +00:00
Auxilor
47b72e9243 Javadoc fix 2022-11-23 22:03:44 +00:00
Auxilor
854a10e8fd Added Price#withMultiplier 2022-11-23 22:00:07 +00:00
Auxilor
823ef6477b Refactoring for naming, updated to 6.47.0 2022-11-23 21:56:07 +00:00
Auxilor
eccb146852 Reworked slot changes into canCaptivateItem 2022-11-18 18:08:21 +00:00
Auxilor
d877b707d6 Improved lang.yml/config.yml warning messages 2022-11-17 15:12:28 +00:00
Auxilor
bcb7401c74 Fixed captive slot changes PR 2022-11-17 15:10:05 +00:00
Auxilor
f05c5f3cd6 Fixed UltraEconomy integration 2022-11-17 15:02:40 +00:00
_OfTeN_
3bd8bccb81 Added UltraEconomy support to Price Lookup 2022-11-17 02:58:53 +03:00
_OfTeN_
6f55787c84 Added ability to filter items for captive slots 2022-11-13 02:50:23 +03:00
_OfTeN_
eb4dc168fc Added proper error displaying when missing config or lang ymls 2022-11-11 02:08:19 +03:00
Auxilor
c5085de5d1 Updated to 6.46.1 2022-11-09 12:59:44 +00:00
Auxilor
019cdbf9c8 Fixed tab completion bug 2022-11-09 12:59:37 +00:00
Auxilor
d5ddcaea4b Cleaned up Menu API 2022-11-08 18:11:27 +00:00
Auxilor
d3a7ef72e8 Thread naming 2022-11-08 16:39:28 +00:00
Auxilor
a311ce1227 Added save-interval option 2022-11-08 16:01:46 +00:00
Auxilor
5c0d4540a8 Merge branch 'pvpmanager-support' into develop 2022-11-08 15:55:03 +00:00
Auxilor
7e66ee8071 Merge branch 'fix/exposed' into develop 2022-11-08 15:54:06 +00:00
Auxilor
fd233df736 Added relevant kt extension for onBuild 2022-11-07 16:43:32 +00:00
Auxilor
6baf636e6a Added MenuBuilder#onBuild 2022-11-07 16:42:40 +00:00
Auxilor
9ee579f2c4 Updated to 6.46.0 2022-11-07 16:40:14 +00:00
Auxilor
3b5ea87353 Fixes to ReactiveSlot 2022-11-07 15:42:46 +00:00
Auxilor
00d32ed218 Added CaptiveItemChangeEvent 2022-11-07 15:32:01 +00:00
Auxilor
5ce9a1c04e Added ItemStack#modify and TestableItem#modify 2022-11-07 15:13:19 +00:00
Auxilor
966549065d Added PlayableSound 2022-11-07 15:08:26 +00:00
Auxilor
ee2911b57c Revert "Added "undyable" arg parser"
This reverts commit a9c32000d8.
2022-11-07 15:00:47 +00:00
_OfTeN_
f15ec5eec0 Merge remote-tracking branch 'origin/master'
# Conflicts:
#	eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/integrations/customitems/CustomItemsScyther.kt
2022-11-07 15:54:25 +03:00
_OfTeN_
a9c32000d8 Added "undyable" arg parser 2022-11-07 15:54:02 +03:00
_OfTeN_
b68459951f Fixed scyther integration 2022-11-07 14:51:03 +03:00
Will FP
b520c76169 Update README.md 2022-11-06 20:03:25 +00:00
Auxilor
d081afbd8e Improved command sync 2022-11-06 19:23:11 +00:00
Auxilor
46fd0439a5 Fixed dynamic command reg 2022-11-06 19:17:21 +00:00
Auxilor
ad58ce4a74 GUI Fixes + Improvements 2022-11-06 14:21:49 +00:00
Auxilor
b5cd8f42e0 Fixed illusioner goals 2022-11-05 21:25:52 +00:00
Auxilor
d0baf50709 Fixed illusioner goals 2022-11-04 15:07:34 +00:00
Auxilor
2496f318fa Removed health-fixer 2022-11-04 13:57:16 +00:00
Auxilor
048c200c95 Changed ConfiguredPrice to be a delegate 2022-11-01 22:05:25 +00:00
Auxilor
17446acb2e Fixed javadoc 2022-11-01 21:55:56 +00:00
Auxilor
7929113c91 Improved PriceItem 2022-11-01 21:53:27 +00:00
Auxilor
6acc5864bd Reworked Price API (again) 2022-11-01 21:36:09 +00:00
Kees Monshouwer
fa64950d28 add support for PvPManager 2022-10-31 09:39:17 +01:00
Auxilor
730c20dbc0 Added Testable Extensions 2022-10-30 16:53:29 +00:00
Auxilor
0c5ae54c3a Codestyle 2022-10-30 16:34:08 +00:00
Auxilor
b48e80837d Fixed javadoc 2022-10-30 16:32:30 +00:00
Auxilor
17eb4cf5f8 Added alias and description support to PluginCommand 2022-10-30 16:02:44 +00:00
Auxilor
890f85fa56 Added Player versions of onExecute and tabComplete 2022-10-30 15:58:14 +00:00
Auxilor
86b427c95e Improved commands 2022-10-30 15:21:21 +00:00
Auxilor
8c1fde57b0 Improved DelegatedBukkitCommand 2022-10-30 15:03:17 +00:00
Auxilor
2efc040a8e Added dynamic command registration 2022-10-29 19:06:15 +01:00
Auxilor
54b2b42512 Added price multipliers 2022-10-29 16:53:24 +01:00
Auxilor
e67d9d634c Fixed javadoc 2022-10-29 16:34:18 +01:00
Auxilor
39fb676b9a Updated to 6.45.0 2022-10-29 16:28:57 +01:00
Auxilor
ec8936b765 Updated price API 2022-10-29 16:28:48 +01:00
Auxilor
cf347de4b8 Updated to 6.44.1 2022-10-27 16:20:51 +01:00
Auxilor
2b7122c5c2 Fixed particles 2022-10-27 16:20:42 +01:00
Auxilor
062b5c9b92 Fixed ProtocolLib bug with TemporaryPlayer 2022-10-27 15:13:20 +01:00
DaRacci
052cd74756 fix: explicit database for transactions 2022-10-28 01:06:35 +11:00
Auxilor
082b39a2e4 Fixed config bug with list getters 2022-10-25 16:27:35 +01:00
Auxilor
616fa032d9 Removed Prices#lookup due to poor usage 2022-10-24 15:59:41 +01:00
Auxilor
ea997239fc Fix 2022-10-24 15:59:06 +01:00
Auxilor
ad04abab73 Reworked prices 2022-10-24 15:29:03 +01:00
Auxilor
f440ef922b Updated prices, removed display text 2022-10-24 14:57:27 +01:00
Auxilor
933271fb4a Imrpoved Economy Price 2022-10-24 13:41:41 +01:00
Auxilor
9679d3100f Imrpoved Economy Price 2022-10-24 13:38:39 +01:00
Auxilor
6e20763522 Refactor 2022-10-24 13:20:30 +01:00
Auxilor
18dea2c20c Fixed javadoc 2022-10-24 13:19:38 +01:00
Auxilor
62b666559c Added MathContext, added value to price 2022-10-24 13:17:09 +01:00
Auxilor
465563523b Fixed javadco 2022-10-24 12:40:14 +01:00
Auxilor
f0f014ed89 Added particle lookup system 2022-10-24 12:23:41 +01:00
Auxilor
58811c5d77 Updated PriceFree 2022-10-24 11:53:01 +01:00
Auxilor
81d495e76e Added display text to prices 2022-10-23 21:43:43 +01:00
Auxilor
c78e397959 Renamed addState to setState 2022-10-23 17:32:28 +01:00
Auxilor
95740f155e Imports 2022-10-23 17:08:46 +01:00
Auxilor
5638d5e152 Added GenericConfig to cover last remaining use of TransientConfig 2022-10-23 16:56:10 +01:00
Auxilor
4d3712057c Added plurals to vanilla item names 2022-10-23 16:48:06 +01:00
Auxilor
458fcd78b3 Updated to 6.44.0 2022-10-23 16:41:49 +01:00
Auxilor
ee13de31f4 Added price system 2022-10-23 16:40:52 +01:00
Auxilor
9588d49788 Added functional pattern to plugin lifecycle hooks 2022-10-23 15:55:23 +01:00
Auxilor
8e7ce298b0 Improved Config API, minor cleanup 2022-10-23 15:48:50 +01:00
Auxilor
32a11ce5b8 Added friendly material names 2022-10-23 15:08:33 +01:00
Auxilor
960f62cc8b Updated to 6.43.7 2022-10-16 21:48:14 +01:00
Auxilor
28ceb83eb5 Fixed ExtendedPersistentDataContainerFactory.kt 2022-10-16 21:47:46 +01:00
Auxilor
6f748b6b8a Updated to 6.43.6 2022-10-07 17:28:39 +01:00
Auxilor
190ea5d49f Refactor + Fix 2022-10-07 17:28:28 +01:00
Auxilor
c0ed083a5c Fixed PAPI 2022-10-04 11:58:15 +01:00
Auxilor
04f04bb7a6 Fixed custom model data parser 2022-10-04 11:48:06 +01:00
Auxilor
b8a3806ff9 Updated to 6.43.5 2022-10-04 11:44:17 +01:00
Auxilor
ae49d41542 Fixes to placeholders and integrations 2022-10-04 11:43:10 +01:00
Auxilor
5f2255a3bc Fixed initial render 2022-10-03 23:33:39 +01:00
Auxilor
065ccfbe67 Updated to 6.43.4 2022-10-03 22:30:27 +01:00
Auxilor
17727c9015 Optimized second render for captive changes 2022-10-03 22:30:20 +01:00
Auxilor
ea64e69b4d Fixed GUI bug 2022-10-03 22:25:03 +01:00
Auxilor
07ca6c2359 Fixed 2 more GUI bugs 2022-10-03 21:58:53 +01:00
Auxilor
162558b1c2 Updated to 6.43.3 2022-10-03 13:44:28 +01:00
Auxilor
10f9e8dce0 Fixed Skull 2022-10-03 13:44:17 +01:00
Will FP
b02943d7ff Merge pull request #204
Fix: Skull texture out of bounds error
2022-10-03 13:42:39 +01:00
Auxilor
40ad970ffa Updated to 6.43.2 2022-10-03 13:00:02 +01:00
Auxilor
aefdfa786d Fixed menu rendering bugs 2022-10-03 12:59:54 +01:00
MillionthOdin16
1cf08955a0 Additional check for bounds error
explanation in comment
2022-10-02 19:33:37 -04:00
Auxilor
4077a4c28b Updated to 6.43.1 2022-10-02 20:01:30 +01:00
Auxilor
6c375ef297 Fixed changing held item edge case 2022-10-02 20:01:23 +01:00
Auxilor
f77fc5d182 Fixed compile bug 2022-10-02 14:24:30 +01:00
Auxilor
6d1cc4c05d Fixed buildscript comments 2022-10-02 14:19:16 +01:00
Auxilor
0775f0992f Internal refactoring, added Model Engine support as an arg parser 2022-10-02 14:12:57 +01:00
Auxilor
debb39105d Moved #getPage #getMaxPage to Menu 2022-10-02 12:20:57 +01:00
Auxilor
3b4aa59bfb Fixed startup bug 2022-10-02 12:03:29 +01:00
Auxilor
4e902c3964 Added warning to legacy MySQL 2022-10-02 02:20:58 +01:00
Auxilor
3e325697e7 Added PersistentDataKeyType#CONFIG 2022-10-02 02:17:42 +01:00
Auxilor
13b3e1e440 Cleaning up after Handler 2022-10-02 02:08:22 +01:00
Auxilor
2b2406a4d0 Deprecated PluginDependent 2022-10-02 01:57:13 +01:00
Auxilor
048982c74a Deprecated PluginDependent 2022-10-02 01:56:45 +01:00
Auxilor
29b63a2ebb Removed Handler, HandlerComponent, and all internal-only API components except Eco; huge backend rework 2022-10-02 01:52:35 +01:00
Auxilor
2a9cbdacfd Cleanup 2022-10-02 00:33:36 +01:00
Auxilor
35cfcdf4a9 Improved ConfigSlot 2022-10-02 00:30:30 +01:00
Auxilor
06c1dc9afb Fixed excludes 2022-10-01 22:34:06 +01:00
Auxilor
18b58d584f Fixes to GUI 2022-10-01 22:31:37 +01:00
Auxilor
a774791e65 Updated excludes 2022-10-01 22:26:43 +01:00
Auxilor
bc22adae84 Fixed changing item bugs with Menu, added Menu#allowsChangingHeldItem 2022-10-01 22:24:24 +01:00
Auxilor
0eba82b221 Added .toml support to config 2022-10-01 21:59:16 +01:00
Auxilor
4822ec3955 Prevented changing the held item with a menu open 2022-10-01 20:55:56 +01:00
Auxilor
b845001467 Many improvements to captive items and menus 2022-10-01 14:36:53 +01:00
Auxilor
25b6a15c9c Fixed getStringsOrNull 2022-10-01 13:11:42 +01:00
Auxilor
1a3d035f78 Revert "Fixed null lore bug with AbstractItemStackBuilder"
This reverts commit a69f9f6e11.
2022-10-01 13:02:21 +01:00
Auxilor
a69f9f6e11 Fixed null lore bug with AbstractItemStackBuilder 2022-10-01 12:55:28 +01:00
Auxilor
6efd9e4fcd Fixed MySQLDataHandler 2022-10-01 12:47:41 +01:00
Auxilor
3e948beb7a Hotfix for SnakeYaml 2022-09-30 20:05:16 +01:00
Auxilor
a8a491a0b7 Brushing over some deprecated behaviour 2022-09-30 19:59:34 +01:00
Auxilor
2c0330898c Javadoc 2022-09-30 19:57:23 +01:00
Auxilor
e9794cfbf4 Fixed OfflinePlayer#exactBalance 2022-09-30 19:54:10 +01:00
Auxilor
1694d858bc Fixed EconomyIntegration javadoc 2022-09-30 19:51:23 +01:00
Auxilor
b79955ae9e Switched EconomyIntegration to be based around BigDecimal 2022-09-30 19:49:20 +01:00
Auxilor
803a8c5d17 Fixed yaml size limit 2022-09-30 19:39:47 +01:00
Auxilor
c5cd15ad92 Merge remote-tracking branch 'origin/master' into develop 2022-09-30 15:24:43 +01:00
Auxilor
489b170888 Added lambda parameter names to GUI DSL 2022-09-30 15:17:39 +01:00
Auxilor
9f57a322e8 Added ItemStack#toSNBT extension function 2022-09-30 15:15:34 +01:00
Auxilor
86e113214d Internal refactoring 2022-09-30 15:10:10 +01:00
Auxilor
e791bb8893 Renamed signals to menu events 2022-09-30 15:04:44 +01:00
Auxilor
f1220bd186 Added dispenserMenu() to GUI DSL 2022-09-30 14:07:54 +01:00
Auxilor
21d933cb11 Added support for 3x3 menus, improved Java Page API. 2022-09-30 14:06:39 +01:00
Auxilor
e1c063d5f4 Added dynamic-size components 2022-09-30 13:29:50 +01:00
Auxilor
27d2b5c8a4 Added menu signals 2022-09-30 12:44:06 +01:00
Auxilor
3b34d6ef27 Made captivity reactive 2022-09-30 12:20:46 +01:00
Auxilor
bc1c8b8f46 Re-added MythicMobs (repo back up) 2022-09-30 12:09:20 +01:00
Auxilor
2fa926ec02 Fix 2022-09-30 12:05:09 +01:00
Auxilor
d7891e1218 Improved Page API 2022-09-29 20:17:57 +01:00
Auxilor
11685cd352 Fixed PageChanger 2022-09-29 20:04:43 +01:00
Auxilor
785127fe16 Optimized AbstractItemStackBuilder via FIS 2022-09-29 19:56:44 +01:00
Auxilor
4a13bc5fea Cleanup 2022-09-29 19:52:43 +01:00
Auxilor
c7ad122050 Minor fix 2022-09-29 19:52:25 +01:00
Auxilor
28d63fc2e3 Improved performance of menu renders 2022-09-29 19:51:33 +01:00
Auxilor
bb62cc0bcd Fixed default layer 2022-09-29 19:12:29 +01:00
Auxilor
740c79f087 Added layers to menus and fixed several bugs (and temporarily removed MythicCraft repos) 2022-09-29 19:10:02 +01:00
Auxilor
33ab8e04a0 Fixed javadoc 2022-09-29 17:35:53 +01:00
Auxilor
fcd3aac363 Updated to 6.43.0 2022-09-29 17:33:56 +01:00
Auxilor
753d148d1b Refactor 2022-09-29 17:33:45 +01:00
Auxilor
1bb47a9f13 Improved MergedStateMenu 2022-09-29 17:21:31 +01:00
Auxilor
40b4c26e0f Added menu pagination 2022-09-29 17:17:13 +01:00
Auxilor
97adae7b32 More GUI improvements, improving Slot API 2022-09-29 16:15:19 +01:00
Auxilor
3d35a91314 Major improvements to menus 2022-09-29 15:51:26 +01:00
Auxilor
0caa328b1e Overhauled GUI component-based backend to support reactive and static slots 2022-09-29 15:08:34 +01:00
Auxilor
ab8c946914 Reworked GUI backend to be component-based 2022-09-29 14:10:41 +01:00
Auxilor
e667537404 Fixed CustomSlot 2022-09-29 13:41:29 +01:00
Auxilor
6bd2f2b823 Codestyle 2022-09-29 12:54:54 +01:00
Auxilor
8d8a8045c0 Moved frontend -> backend communication to be purely via the handler 2022-09-29 09:51:43 +01:00
Auxilor
d5c669c72c Added shorthand NamespacedKey and FixedMetadataValue creation 2022-09-29 08:49:17 +01:00
Auxilor
28b268e175 Added %player% to configslot 2022-09-28 12:38:38 +01:00
Auxilor
33937d1ce7 Switched Crunch to fork 2022-09-28 11:04:59 +01:00
Auxilor
e971778cc3 Updated to 6.42.0 2022-09-28 10:47:51 +01:00
Auxilor
f99612ded3 Added CustomSlot, improved various GUI elements, added GUI components. 2022-09-28 10:47:42 +01:00
Auxilor
50272bbbcf Improved skull texture API backend 2022-09-28 08:44:16 +01:00
Auxilor
9a703f6190 One more held item slot fix 2022-09-26 14:02:20 +01:00
Auxilor
f8fec7eec4 Updated to 6.41.3 2022-09-26 13:57:50 +01:00
Auxilor
f6aadda4ed Fixed PacketHeldItemSlot 2022-09-26 13:57:39 +01:00
Auxilor
d8fca0f348 Switched KingdomsX to local jar 2022-09-26 12:52:46 +01:00
Auxilor
65ff4c4a31 PR Codestyle 2022-09-26 12:36:34 +01:00
Auxilor
90702bc7aa Merge remote-tracking branch 'origin/develop' into develop 2022-09-26 12:34:53 +01:00
Will FP
e81b788a1b Merge pull request #199 from mani1232/master
Update KingdomsX dependence
2022-09-26 12:34:46 +01:00
Auxilor
ebc0ee7940 Updated to 6.41.2 2022-09-26 12:33:25 +01:00
Auxilor
82d269daf1 Improved PacketWindowItems and DisplayFrame 2022-09-26 12:32:07 +01:00
Auxilor
9d5300d6ae Began display system fixes 2022-09-26 12:10:22 +01:00
mani1232
8870e4d6fb Update KingdomsX dependence 2022-09-25 21:26:21 +02:00
_OfTeN_
7767e48e51 Fixed scyther integration 2022-09-14 23:03:20 +03:00
491 changed files with 15140 additions and 6406 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
env:
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'.
# So if we split on '/' and take the 3rd value, we can get the release name.

View File

@@ -1,38 +1,7 @@
# How to contribute to eco
## Codestyle
Please open any Pull Requests into the `develop` branch or ideally into a new branch for your changes. PRs that go into `master` won't be ignored, but I have to checkout and merge manually, which makes your PR show as being closed.
1. The eco checkstyle is in /config/checkstyle.xml
Do not write any Kotlin-only APIs; all API components should be written in Java, Kotlin extensions should not have functionality that isn't available in java. The same applies the other way round, do not write any backend code in Java, it should be Kotlin-exclusive.
- The pull request must not have any checkstyle issues.
- Every method and field must have a javadoc attached.
2. Use JetBrains annotations
- Every parameter should be annotated with @NotNull or @Nullable
3. Imports
- No group (*) imports.
- No static imports.
4. Kotlin
- Kotlin should be the only language used in the backend, java should be the only language used in the frontend.
- Kotlin API extensions should only be for creating extension functions and extra niceties that aren't possible in java.
Do not write API components in kotlin.
- Kotlin code should never be called directly from the frontend Java API. Kotlin API extensions should always rely on
java, not the other way round.
## Dependency Injection
- eco uses Dependency Injection
- Any calls to Eco#getHandler#getEcoPlugin are code smells and should never be used unless **absolutely necessary**.
- NamespacedKeys, FixedMetadataValues, Runnables, and Schedules should be managed using AbstractEcoPlugin through DI.
- Any DI class should extend PluginDependent where possible. If the class extends another, then you **must** store the
plugin instance in a private final variable called **plugin** with a private or protected getter.
## Other
- All drops **must** be sent through a DropQueue - calls to World#dropItem will get your PR rejected.
- eco is built with java 17.
If you have any questions about contributing, feel free to ask in the [Discord](https://discord.gg/ZcwpSsE)!

View File

@@ -1,5 +1,5 @@
# eco
eco is a powerful Spigot development library that simplifies the process of plugin creation and supercharges
eco is a powerful Spigot plugin framework that simplifies the process of plugin creation and supercharges
your plugins.
It's the engine behind [EcoEnchants](https://polymart.org/resource/490), [Reforges](https://polymart.org/resource/1330),
[EcoItems](https://polymart.org/resource/1247), [EcoSkills](https://polymart.org/resource/1351),
@@ -16,30 +16,54 @@ and many more.
<a href="https://bstats.org/plugin/bukkit/EcoEnchants" alt="bstats players">
<img src="https://img.shields.io/bstats/players/7666?color=informational"/>
</a>
<a href="https://plugins.auxilor.io/" alt="Docs (gitbook)">
<img src="https://img.shields.io/badge/docs-gitbook-informational"/>
</a>
<a href="https://discord.gg/ZcwpSsE/" alt="Discord">
<img src="https://img.shields.io/discord/452518336627081236?label=discord&color=informational"/>
</a>
<a href="https://github.com/Auxilor/eco/actions/workflows/java-ci.yml" alt="Latest Dev Build">
<img src="https://img.shields.io/github/workflow/status/Auxilor/eco/Java%20CI/develop?color=informational"/>
<img src="https://img.shields.io/github/actions/workflow/status/Auxilor/eco/java-ci.yml?branch=develop&color=informational"/>
</a>
</p>
eco comes packed with all the tools you need in your plugins:
- Modern command API
- Native color parsing with full hex/RGB/MiniMessage support
- Yaml/JSON/TOML config system
- Persistent data storage API with Yaml/MySQL/MongoDB support
- Packet item display system
- Lightweight event loop based packet API
- Entity AI API with near-1:1 NMS mappings
- More events
- Extension API, essentially plugins for plugins
- Fluent dependency injection for NamespacedKey, Metadata values, etc.
- Ultra-fast ItemStack reimplementation bypassing ItemMeta
- Complete GUI API with pre-made components available from [ecomponent](https://github.com/Auxilor/ecomponent)
- Over 30 native integrations for other plugins
- First-class custom item support with lookup strings
- Math expression parsing via [Crunch](https://github.com/Redempt/Crunch)
- Particle lookups
- Complete Placeholder API
- Price system, supporting economy plugins, XP, Items, etc.
- NMS/Version-specific tooling
- Custom crafting recipe API with support for stacks and custom items
- Native plugin update checking
- Native bStats support
- Full Kotlin support and native extensions
- Tooling to make meta-frameworks, like [libreforge](https://github.com/Auxilor/libreforge)
- And much more
# For server owners
- Requires ProtocolLib to be installed: get the latest version [here](https://www.spigotmc.org/resources/protocollib.1997/)
- Supports 1.17+
## Downloads
- Stable (Recommended): [GitHub](https://github.com/Auxilor/eco/releases), [Polymart](https://polymart.org/resource/eco.773)
- Dev (Not Recommended): [GitHub](https://github.com/Auxilor/eco/actions/workflows/java-ci.yml) (Open latest run and download)
- Stable: [GitHub](https://github.com/Auxilor/eco/releases), [Polymart](https://polymart.org/resource/eco.773)
- Dev: [GitHub](https://github.com/Auxilor/eco/actions/workflows/java-ci.yml) (Open latest run and download)
# For developers
## Javadoc
The 6.38.2 Javadoc can be found [here](https://javadoc.jitpack.io/com/willfp/eco/6.38.2/javadoc/)
The 6.53.0 Javadoc can be found [here](https://javadoc.jitpack.io/com/willfp/eco/6.53.0/javadoc/)
## Plugin Information
@@ -51,31 +75,31 @@ depend:
- eco
```
## Get from JitPack:
## Dependency Information:
Gradle:
```groovy
```kts
repositories {
maven { url 'https://jitpack.io' }
maven("https://repo.auxilor.io/repository/maven-public/")
}
```
```groovy
dependencies {
compileOnly 'com.willfp:eco:Tag'
compileOnly("com.willfp:eco:Tag")
}
```
Replace `Tag` with a release tag for eco, eg `6.27.2`.
Replace `Tag` with a release tag for eco, eg `6.53.0`.
Maven:
```xml
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
<id>auxilor</id>
<url>https://repo.auxilor.io/repository/maven-public/</url>
</repository>
```
@@ -88,7 +112,7 @@ Maven:
</dependency>
```
Replace `Tag` with a release tag for eco, eg `6.27.2`.
Replace `Tag` with a release tag for eco, eg `6.53.0`.
## Build locally:
@@ -103,7 +127,7 @@ cd eco
## License
*Click here to read [the entire license](https://github.com/Auxilor/eco/blob/master/LICENSE.md).*
eco is licensed under GNU GPL3. *Click here to read [the entire license](https://github.com/Auxilor/eco/blob/master/LICENSE.md).*
<h1 align="center">
Check out our partners!

View File

@@ -25,6 +25,8 @@ dependencies {
implementation(project(path = ":eco-core:core-nms:v1_18_R1", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_18_R2", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_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_R3", configuration = "reobf"))
}
allprojects {
@@ -55,7 +57,7 @@ allprojects {
maven("https://repo.extendedclip.com/content/repositories/placeholderapi/")
// ProtocolLib
maven("https://repo.dmulloy2.net/nexus/repository/public/")
//maven("https://repo.dmulloy2.net/nexus/repository/public/")
// WorldGuard
maven("https://maven.enginehub.org/repo/")
@@ -77,6 +79,15 @@ allprojects {
// LibsDisguises
maven("https://repo.md-5.net/content/groups/public/")
// UltraEconomy
maven("https://repo.techscode.com/repository/maven-releases/")
// PlayerPoints
maven("https://repo.rosewooddev.io/repository/public/")
// Denizen
maven("https://maven.citizensnpcs.co/repo")
}
dependencies {
@@ -158,6 +169,7 @@ allprojects {
relocate("org.litote", "com.willfp.eco.libs.litote")
relocate("org.reactivestreams", "com.willfp.eco.libs.reactivestreams")
relocate("reactor.", "com.willfp.eco.libs.reactor.") // Dot in name to be safe
relocate("com.moandjiezana.toml", "com.willfp.eco.libs.toml")
/*
Kotlin and caffeine are not shaded so that they can be accessed directly by eco plugins.

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.
*
* @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 {
/**
* The packet type to listen for.
* The handle type to listen for.
*/
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>
* Useful for monitor priority adapters that <b>must</b> be ran last.
*/
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 type The {@link PacketType} to listen for.
* @param priority The priority at which the adapter should be ran on packet send/receive.
* @param postLoad If the packet adapter should be registered after the server has loaded.
* @param priority The priority at which the adapter should be ran on handle send/receive.
* @param postLoad If the handle adapter should be registered after the server has loaded.
*/
protected AbstractPacketAdapter(@NotNull final EcoPlugin plugin,
@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 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,
@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 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 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.
*/
@@ -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.
*/
@@ -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() {
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.
*/

View File

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

View File

@@ -13,26 +13,34 @@ import com.willfp.eco.core.factory.MetadataValueFactory;
import com.willfp.eco.core.factory.NamespacedKeyFactory;
import com.willfp.eco.core.factory.RunnableFactory;
import com.willfp.eco.core.integrations.IntegrationLoader;
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager;
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.registry.Registrable;
import com.willfp.eco.core.registry.Registry;
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 org.apache.commons.lang.Validate;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.event.Listener;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
@@ -51,27 +59,12 @@ import java.util.stream.Collectors;
* <b>IMPORTANT: When reloading a plugin, all runnables / tasks will
* be cancelled.</b>
*/
@SuppressWarnings("unused")
public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
@SuppressWarnings({"unused", "DeprecatedIsStillUsed", "deprecation", "RedundantSuppression", "MismatchedQueryAndUpdateOfCollection"})
public abstract class EcoPlugin extends JavaPlugin implements PluginLike, Registrable {
/**
* The polymart resource ID of the plugin.
* The properties (eco.yml).
*/
private final int resourceId;
/**
* 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;
private final PluginProps props;
/**
* Loaded integrations.
@@ -79,12 +72,12 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
private final Set<String> loadedIntegrations = new HashSet<>();
/**
* The internal plugin scheduler.
* The plugin scheduler.
*/
private final Scheduler scheduler;
/**
* The internal plugin Event Manager.
* The plugin Event Manager.
*/
private final EventManager eventManager;
@@ -99,17 +92,17 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
private final LangYml langYml;
/**
* The internal factory to produce {@link org.bukkit.NamespacedKey}s.
* The factory to produce {@link org.bukkit.NamespacedKey}s.
*/
private final NamespacedKeyFactory namespacedKeyFactory;
/**
* The internal factory to produce {@link org.bukkit.metadata.FixedMetadataValue}s.
* The factory to produce {@link org.bukkit.metadata.FixedMetadataValue}s.
*/
private final MetadataValueFactory metadataValueFactory;
/**
* The internal factory to produce {@link com.willfp.eco.core.scheduling.RunnableTask}s.
* The factory to produce {@link com.willfp.eco.core.scheduling.RunnableTask}s.
*/
private final RunnableFactory runnableFactory;
@@ -133,24 +126,49 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
/**
* The logger for the plugin.
*/
private final Logger logger;
private Logger logger;
/**
* If the server is running an outdated version of the plugin.
*/
private boolean outdated = false;
/**
* If the plugin supports extensions.
*/
private final boolean supportingExtensions;
/**
* The proxy factory.
*/
@Nullable
private final ProxyFactory proxyFactory;
/**
* The tasks to run on enable.
*/
private final ListMap<LifecyclePosition, Runnable> onEnable = new ListMap<>();
/**
* The tasks to run on disable.
*/
private final ListMap<LifecyclePosition, Runnable> onDisable = new ListMap<>();
/**
* The tasks to run on reload.
*/
private final ListMap<LifecyclePosition, Runnable> onReload = new ListMap<>();
/**
* The tasks to run on load.
*/
private final ListMap<LifecyclePosition, Runnable> onLoad = new ListMap<>();
/**
* The tasks to run after load.
*/
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.
* <p>
@@ -166,7 +184,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* Create a new plugin without proxy support, polymart, or bStats.
*
* @param color The color.
* @deprecated Use eco.yml instead.
*/
@Deprecated(since = "6.53.0", forRemoval = true)
protected EcoPlugin(@NotNull final String color) {
this("", color);
}
@@ -177,7 +197,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
*
* @param proxyPackage The package where proxy implementations are stored.
* @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,
@NotNull final String color) {
this(0, 0, proxyPackage, color);
@@ -189,7 +211,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param resourceId The polymart 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)
* @deprecated Use eco.yml instead.
*/
@Deprecated(since = "6.53.0", forRemoval = true)
protected EcoPlugin(final int resourceId,
final int bStatsId,
@NotNull final String color) {
@@ -203,7 +227,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param bStatsId The bStats resource ID for the plugin.
* @param color The color of the plugin (used in messages, using standard formatting)
* @param supportingExtensions If the plugin supports extensions.
* @deprecated Use eco.yml instead.
*/
@Deprecated(since = "6.53.0", forRemoval = true)
protected EcoPlugin(final int resourceId,
final int bStatsId,
@NotNull final String color,
@@ -218,7 +244,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param bStatsId The bStats resource ID for the plugin.
* @param proxyPackage The package where proxy implementations are stored.
* @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,
final int bStatsId,
@NotNull final String proxyPackage,
@@ -234,21 +262,15 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param proxyPackage The package where proxy implementations are stored.
* @param color The color of the plugin (used in messages, using standard formatting)
* @param supportingExtensions If the plugin supports extensions.
* @deprecated Use eco.yml instead.
*/
@Deprecated(since = "6.53.0", forRemoval = true)
protected EcoPlugin(final int resourceId,
final int bStatsId,
@NotNull final String proxyPackage,
@NotNull final String color,
final boolean supportingExtensions) {
this(
PluginProps.createSimple(
resourceId,
bStatsId,
proxyPackage,
color,
supportingExtensions
)
);
this(PluginProps.createSimple(resourceId, bStatsId, proxyPackage, color, supportingExtensions));
}
/**
@@ -258,69 +280,72 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
*/
protected EcoPlugin(@Nullable final PluginProps pluginProps) {
/*
The handler must be initialized before any plugin's constructors
are called, as the constructors call Eco#getHandler().
Eco must be initialized before any plugin's constructors
are called, as the constructors call Eco#get().
To fix this, EcoSpigotPlugin an abstract class and the 'actual'
plugin class is EcoHandler - that way I can create the handler
plugin class is EcoImpl - that way I can initialize eco
before any plugins are loaded while still having a separation between
the plugin class and the handler class (for code clarity).
the plugin class and the implementation class (for code clarity).
I don't really like the fact that the handler class *is* the
I don't really like the fact that the implementation class *is* the
spigot plugin, but it is what it is.
There is probably a better way of doing it - maybe with
some sort of HandlerCreator interface in order to still have
a standalone handler class, but then there would be an interface
some sort of EcoCrater interface in order to still have
a standalone eco class, but then there would be an interface
left in the API that doesn't really help anything.
The other alternative would be to use reflection to get a 'createHandler'
The other alternative would be to use reflection to get a 'createEco'
method that only exists in EcoSpigotPlugin - but that feels filthy,
and I'd rather only use reflection where necessary.
*/
if (Eco.getHandler() == null && this instanceof Handler) {
if (Eco.get() == null && this instanceof Eco) {
/*
This code is only ever called by EcoSpigotPlugin (EcoHandler)
as it's the first plugin to load, and it is a handler.
This code is only ever called by EcoSpigotPlugin (EcoImpl)
as it's the first plugin to load, and it's an instance of eco.
Any other plugins will never call this code as the handler
will have already been initialized.
Any other plugins will never call this code as eco will have already
been initialized.
*/
Eco.setHandler((Handler) this);
Eco.Instance.set((Eco) this);
}
assert Eco.getHandler() != null;
assert Eco.get() != null;
PluginProps generatedProps = Eco.getHandler().getProps(pluginProps, this.getClass());
PluginProps generatedProps = Eco.get().getProps(pluginProps, this.getClass());
generatedProps.validate();
PluginProps props = this.mutateProps(generatedProps);
props.validate();
this.resourceId = props.getResourceId();
this.bStatsId = props.getBStatsId();
this.proxyPackage = props.getProxyPackage();
this.color = props.getColor();
this.supportingExtensions = props.isSupportingExtensions();
this.props = props;
this.proxyFactory = this.proxyPackage.equalsIgnoreCase("") ? null : Eco.getHandler().createProxyFactory(this);
this.logger = Eco.getHandler().createLogger(this);
this.proxyFactory = this.props.getProxyPackage().equalsIgnoreCase("") ? null : Eco.get().createProxyFactory(this);
this.logger = Eco.get().createLogger(this);
this.getLogger().info("Initializing " + this.getColor() + this.getName());
this.scheduler = Eco.getHandler().createScheduler(this);
this.eventManager = Eco.getHandler().createEventManager(this);
this.namespacedKeyFactory = Eco.getHandler().createNamespacedKeyFactory(this);
this.metadataValueFactory = Eco.getHandler().createMetadataValueFactory(this);
this.runnableFactory = Eco.getHandler().createRunnableFactory(this);
this.extensionLoader = Eco.getHandler().createExtensionLoader(this);
this.configHandler = Eco.getHandler().createConfigHandler(this);
this.scheduler = Eco.get().createScheduler(this);
this.eventManager = Eco.get().createEventManager(this);
this.namespacedKeyFactory = Eco.get().createNamespacedKeyFactory(this);
this.metadataValueFactory = Eco.get().createMetadataValueFactory(this);
this.runnableFactory = Eco.get().createRunnableFactory(this);
this.extensionLoader = Eco.get().createExtensionLoader(this);
this.configHandler = Eco.get().createConfigHandler(this);
this.langYml = this.createLangYml();
if (!this.langYml.isValid() && !(this instanceof Eco)) {
this.getLogger().warning("Notify plugin authors " + String.join(", ", this.getDescription().getAuthors()) + " that");
this.getLogger().warning("they are missing crucial lang.yml keys! They can be found");
this.getLogger().warning("in the LangYml class.");
}
this.configYml = this.createConfigYml();
Eco.getHandler().addNewPlugin(this);
Eco.get().addNewPlugin(this);
/*
The minimum eco version check was moved here because it's very common
@@ -329,14 +354,14 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
they have an outdated version of eco installed.
*/
DefaultArtifactVersion runningVersion = new DefaultArtifactVersion(Eco.getHandler().getEcoPlugin().getDescription().getVersion());
DefaultArtifactVersion requiredVersion = new DefaultArtifactVersion(this.getMinimumEcoVersion());
Version runningVersion = new Version(Eco.get().getEcoPlugin().getDescription().getVersion());
Version requiredVersion = new Version(this.getMinimumEcoVersion());
if (!(runningVersion.compareTo(requiredVersion) > 0 || runningVersion.equals(requiredVersion))) {
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("Download the newest version here:");
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.");
}
}
@@ -347,13 +372,12 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
public final void onEnable() {
super.onEnable();
this.getLogger().info("");
this.getLogger().info("Loading " + this.getColor() + this.getName());
if (this.getResourceId() != 0 && !Eco.getHandler().getEcoPlugin().getConfigYml().getBool("no-update-checker")) {
if (this.getResourceId() != 0 && !Eco.get().getEcoPlugin().getConfigYml().getBool("no-update-checker")) {
new UpdateChecker(this).getVersion(version -> {
DefaultArtifactVersion currentVersion = new DefaultArtifactVersion(this.getDescription().getVersion());
DefaultArtifactVersion mostRecentVersion = new DefaultArtifactVersion(version);
Version currentVersion = new Version(this.getDescription().getVersion());
Version mostRecentVersion = new Version(version);
if (!(currentVersion.compareTo(mostRecentVersion) > 0 || currentVersion.equals(mostRecentVersion))) {
this.outdated = true;
this.getLogger().warning(this.getName() + " is out of date! (Version " + this.getDescription().getVersion() + ")");
@@ -364,56 +388,97 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
}
if (this.getBStatsId() != 0) {
Eco.getHandler().registerBStats(this);
Eco.get().registerBStats(this);
}
Set<String> enabledPlugins = Arrays.stream(Bukkit.getPluginManager().getPlugins())
.map(Plugin::getName)
.map(String::toLowerCase)
.collect(Collectors.toSet());
Set<String> enabledPlugins = Arrays.stream(Bukkit.getPluginManager().getPlugins()).map(Plugin::getName).map(String::toLowerCase).collect(Collectors.toSet());
if (enabledPlugins.contains("PlaceholderAPI".toLowerCase())) {
this.loadedIntegrations.add("PlaceholderAPI");
PlaceholderManager.addIntegration(Eco.getHandler().createPAPIIntegration(this));
Eco.get().createPAPIIntegration(this);
}
this.loadIntegrationLoaders().forEach(integrationLoader -> {
if (enabledPlugins.contains(integrationLoader.getPluginName().toLowerCase())) {
this.loadedIntegrations.add(integrationLoader.getPluginName());
try {
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()));
if (!this.getLoadedIntegrations().isEmpty()) {
this.getLogger().info("Loaded integrations: " + String.join(", ", this.getLoadedIntegrations()));
}
Prerequisite.update();
if (Prerequisite.HAS_PROTOCOLLIB.isMet()) {
this.loadPacketAdapters().forEach(abstractPacketAdapter -> {
if (!abstractPacketAdapter.isPostLoad()) {
abstractPacketAdapter.register();
}
});
}
this.loadListeners().forEach(listener -> this.getEventManager().registerListener(listener));
this.loadPacketListeners().forEach(listener -> this.getEventManager().registerPacketListener(listener));
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()) {
this.getExtensionLoader().loadExtensions();
if (this.getExtensionLoader().getLoadedExtensions().isEmpty()) {
this.getLogger().info("&cNo extensions found");
} else {
this.getLogger().info("Extensions Loaded:");
this.getExtensionLoader().getLoadedExtensions().forEach(extension -> this.getLogger().info("- " + extension.getName() + " v" + extension.getVersion()));
if (!this.getExtensionLoader().getLoadedExtensions().isEmpty()) {
List<String> loadedExtensions = this.getExtensionLoader().getLoadedExtensions().stream().map(
extension -> extension.getName() + " v" + extension.getVersion()
).toList();
this.getLogger().info(
"Loaded extensions: " +
String.join(", ", loadedExtensions)
);
}
}
this.handleEnable();
this.handleLifecycle(this.onEnable, this::handleEnable);
}
this.getLogger().info("");
/**
* Add new task to run on enable.
*
* @param task The task.
*/
public final void onEnable(@NotNull final Runnable 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);
}
/**
@@ -426,14 +491,34 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
this.getEventManager().unregisterAllListeners();
this.getScheduler().cancelAll();
this.handleDisable();
this.handleLifecycle(this.onDisable, this::handleDisable);
if (this.isSupportingExtensions()) {
this.getExtensionLoader().unloadExtensions();
}
this.getLogger().info("Cleaning up...");
Eco.getHandler().getCleaner().clean(this);
Eco.get().clean(this);
}
/**
* Add new task to run on disable.
*
* @param task The task.
*/
public final void onDisable(@NotNull final Runnable 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);
}
/**
@@ -443,7 +528,27 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
public final void onLoad() {
super.onLoad();
this.handleLoad();
this.handleLifecycle(this.onLoad, this::handleLoad);
}
/**
* Add new task to run on load.
*
* @param task The task.
*/
public final void onLoad(@NotNull final Runnable 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);
}
/**
@@ -456,11 +561,13 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
Display.registerDisplayModule(this.getDisplayModule());
}
if (Prerequisite.HAS_PROTOCOLLIB.isMet()) {
this.loadPacketAdapters().forEach(abstractPacketAdapter -> {
if (abstractPacketAdapter.isPostLoad()) {
abstractPacketAdapter.register();
}
});
}
if (!Prerequisite.HAS_PAPER.isMet()) {
this.getLogger().severe("");
@@ -475,7 +582,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
this.getLogger().severe("");
}
this.handleAfterLoad();
this.handleLifecycle(this.afterLoad, this::handleAfterLoad);
this.reload();
@@ -483,26 +590,82 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
extension.handleAfterLoad();
}
this.getLogger().info("Loaded " + this.color + this.getName());
this.getLogger().info("Loaded " + this.props.getColor() + this.getName());
}
/**
* Add new task to run after load.
*
* @param task The task.
*/
public final void afterLoad(@NotNull final Runnable 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.
*/
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();
if (cancelTasks) {
this.getScheduler().cancelAll();
}
this.getConfigHandler().callUpdate();
this.getConfigHandler().callUpdate(); // Call twice to fix issues
this.handleReload();
this.handleLifecycle(this.onReload, this::handleReload);
if (cancelTasks) {
this.handleLifecycle(this.createTasks, this::createTasks);
}
for (Extension extension : this.extensionLoader.getLoadedExtensions()) {
extension.handleReload();
}
}
/**
* Add new task to run on reload.
*
* @param task The task.
*/
public final void onReload(@NotNull final Runnable 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);
}
/**
* Reload the plugin and return the time taken to reload.
*
@@ -516,6 +679,43 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
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.
* <p>
@@ -554,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.
* <p>
@@ -597,22 +806,35 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
}
/**
* ProtocolLib packet adapters to be registered.
* ProtocolLib handle adapters to be registered.
* <p>
* 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() {
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.
*
* @return A list of all listeners.
*/
protected abstract List<Listener> loadListeners();
protected List<Listener> loadListeners() {
return new ArrayList<>();
}
/**
* Useful for custom LangYml implementations.
@@ -622,7 +844,15 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @return lang.yml.
*/
protected LangYml createLangYml() {
try {
return new LangYml(this);
} catch (NullPointerException e) {
this.getLogger().severe("Failed to load lang.yml!");
this.getLogger().severe("For the developer of this plugin: make sure you have a lang.yml");
e.printStackTrace();
Bukkit.getPluginManager().disablePlugin(this);
return null;
}
}
/**
@@ -633,7 +863,15 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @return config.yml.
*/
protected ConfigYml createConfigYml() {
try {
return new ConfigYml(this);
} catch (NullPointerException e) {
this.getLogger().severe("Failed to load config.yml!");
this.getLogger().severe("For the developer of this plugin: make sure you have a config.yml");
e.printStackTrace();
Bukkit.getPluginManager().disablePlugin(this);
return null;
}
}
/**
@@ -643,10 +881,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
*/
@Nullable
protected DisplayModule createDisplayModule() {
Validate.isTrue(
this.getDisplayModule() == null,
"Display module exists!"
);
Validate.isTrue(this.getDisplayModule() == null, "Display module exists!");
return null;
}
@@ -745,8 +980,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param pluginName The name.
* @return The plugin.
*/
@Nullable
public static EcoPlugin getPlugin(@NotNull final String pluginName) {
return Eco.getHandler().getPluginByName(pluginName);
return Eco.get().getPluginByName(pluginName);
}
/**
@@ -754,8 +990,19 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
*
* @return The set of names.
*/
@NotNull
public static Set<String> getPluginNames() {
return new HashSet<>(Eco.getHandler().getLoadedPlugins());
return new HashSet<>(Eco.get().getLoadedPlugins());
}
/**
* Get the plugin props. (eco.yml).
*
* @return The props.
*/
@NotNull
public PluginProps getProps() {
return this.props;
}
/**
@@ -764,7 +1011,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @return The resource ID.
*/
public int getResourceId() {
return this.resourceId;
return this.getProps().getResourceId();
}
/**
@@ -773,7 +1020,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @return The ID.
*/
public int getBStatsId() {
return this.bStatsId;
return this.getProps().getBStatsId();
}
/**
@@ -782,7 +1029,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @return The package where proxies are contained.
*/
public String getProxyPackage() {
return this.proxyPackage;
return this.getProps().getProxyPackage();
}
/**
@@ -791,7 +1038,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @return The color.
*/
public String getColor() {
return this.color;
return this.getProps().getColor();
}
/**
@@ -880,7 +1127,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
*
* @return The config handler.
*/
public ConfigHandler getConfigHandler() {
public @NotNull ConfigHandler getConfigHandler() {
return this.configHandler;
}
@@ -909,7 +1156,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @return If extensions are supported.
*/
public boolean isSupportingExtensions() {
return this.supportingExtensions;
return this.getProps().isSupportingExtensions();
}
/**
@@ -921,4 +1168,47 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
public ProxyFactory getProxyFactory() {
return this.proxyFactory;
}
/**
* Create a NamespacedKey.
*
* @param key The key.
* @return The namespaced key.
*/
@NotNull
public NamespacedKey createNamespacedKey(@NotNull final String key) {
return this.getNamespacedKeyFactory().create(key);
}
/**
* Create a metadata value.
*
* @param value The value.
* @return The metadata value.
*/
@NotNull
public FixedMetadataValue createMetadataValue(@NotNull final Object value) {
return this.getMetadataValueFactory().create(value);
}
/**
* 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

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

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,42 +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.
*/
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;
import com.willfp.eco.core.config.updating.ConfigHandler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.logging.Logger;
@@ -13,12 +15,13 @@ import java.util.logging.Logger;
*/
public interface PluginLike {
/**
* Get the data folder of the object.
* Get the data folder.
* <p>
* Returns the plugin data folder for a plugin, or the extension's parent plugin's folder
*
* @return The data folder.
*/
@NotNull
File getDataFolder();
/**
@@ -26,6 +29,7 @@ public interface PluginLike {
*
* @return The config handler.
*/
@NotNull
ConfigHandler getConfigHandler();
/**
@@ -33,5 +37,16 @@ public interface PluginLike {
*
* @return The logger.
*/
@NotNull
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
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.
*/
@@ -153,6 +163,46 @@ public final class PluginProps {
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.
*/
@@ -221,7 +271,7 @@ public final class PluginProps {
/**
* Create new props from known values.
*
* <p>
* Marked as internal as this method will break whenever the properties themselves
* are updated (e.g. if a new property is added) - so to prevent any potential
* backwards-compatibility bugs, this method cannot be invoked outside eco itself.
@@ -232,7 +282,9 @@ public final class PluginProps {
* @param color The primary color of the plugin.
* @param supportsExtensions If the plugin should attempt to look for extensions.
* @return The props.
* @deprecated Moving to force the usage of eco.yml.
*/
@Deprecated(since = "6.53.0")
static PluginProps createSimple(final int resourceId,
final int bStatsId,
@NotNull final String proxyPackage,

View File

@@ -1,6 +1,5 @@
package com.willfp.eco.core;
import com.willfp.eco.core.integrations.economy.EconomyManager;
import com.willfp.eco.core.proxy.ProxyConstants;
import com.willfp.eco.util.ClassUtils;
import org.jetbrains.annotations.NotNull;
@@ -31,14 +30,19 @@ public class Prerequisite {
);
/**
* Requires the server to have vault installed.
*
* @deprecated Use {@link EconomyManager#hasRegistrations()} instead.
* Requires the server to be running an implementation of paper.
*/
@Deprecated(forRemoval = true)
public static final Prerequisite HAS_VAULT = new Prerequisite(
() -> ClassUtils.exists("net.milkbowl.vault.economy.Economy"),
"Requires server to have vault"
public static final Prerequisite HAS_PROTOCOLLIB = new Prerequisite(
() -> ClassUtils.exists("com.comphenix.protocol.events.PacketAdapter"),
"Requires server to have ProtocolLib"
);
/**
* 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,20 +61,12 @@ public class Prerequisite {
"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.
*
* @deprecated This will never return true.
*/
@Deprecated(since = "6.49.0", forRemoval = true)
public static final Prerequisite HAS_BUNGEECORD = new Prerequisite(
() -> ClassUtils.exists("net.md_5.bungee.api.event.ServerConnectedEvent"),
"Requires server to be running BungeeCord (or a fork)"
@@ -78,7 +74,10 @@ public class Prerequisite {
/**
* Requires the server to be running an implementation of Velocity.
*
* @deprecated This will never return true.
*/
@Deprecated(since = "6.49.0", forRemoval = true)
public static final Prerequisite HAS_VELOCITY = new Prerequisite(
() -> ClassUtils.exists("com.velocitypowered.api.event.player.ServerConnectedEvent"),
"Requires server to be running Velocity (or a fork)"

View File

@@ -1,30 +1,37 @@
package com.willfp.eco.core.command;
import com.willfp.eco.core.EcoPlugin;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;
/**
* Interface for all command implementations.
* Generic interface for commands.
*/
@SuppressWarnings("removal")
@SuppressWarnings("null")
public interface CommandBase {
/**
* Get command name.
*
* @return The name.
*/
String getName();
@NotNull String getName();
/**
* Get command permission.
*
* @return The permission.
*/
String getPermission();
@NotNull String getPermission();
/**
* If only players can execute the command.
@@ -39,79 +46,237 @@ public interface CommandBase {
* @param command The subcommand.
* @return The parent command.
*/
CommandBase addSubcommand(@NotNull CommandBase command);
@NotNull CommandBase addSubcommand(@NotNull CommandBase command);
/**
* Get the subcommands of the command.
*
* @return The subcommands.
*/
@NotNull List<CommandBase> getSubcommands();
/**
* Intended for returning the enclosing CommandBase,
* when this instance is serving as the delegate command base.
*
* @return the wrapping object of this delegate.
*/
default @NotNull CommandBase getWrapped() {
return this;
}
/**
* Handle command execution.
* <p>
* Marked as default void with no implementation for backwards compatibility.
* This will always be called on command execution.
*
* @param sender The sender.
* @param args The args.
* @throws NotificationException naturally, this is handled as a part of the command system.
*/
default void onExecute(@NotNull CommandSender sender,
@NotNull List<String> args) {
default void onExecute(@NotNull final CommandSender sender, @NotNull final List<String> args) throws NotificationException {
// Do nothing.
}
/**
* Handle command execution from players.
* <p>
* This will only be called if the sender is a player.
*
* @param sender The sender.
* @param args The args.
* @throws NotificationException naturally, this is handled as a part of the command system.
*/
default void onExecute(@NotNull final Player sender, @NotNull final List<String> args) throws NotificationException {
// Do nothing.
}
/**
* Handle tab completion.
* <p>
* Marked as default void with no implementation for backwards compatibility.
* This will always be called on tab completion.
*
* @param sender The sender.
* @param args The args.
* @return The results.
*/
default List<String> tabComplete(@NotNull CommandSender sender,
@NotNull List<String> args) {
@NotNull
default List<String> tabComplete(@NotNull final CommandSender sender, @NotNull final List<String> args) {
return new ArrayList<>();
}
/**
* Handle tab completion.
* <p>
* This will only be called if the sender is a player.
*
* @param sender The sender.
* @param args The args.
* @return The results.
*/
@NotNull
default List<String> tabComplete(@NotNull final Player sender, @NotNull final List<String> args) {
return new ArrayList<>();
}
/**
* Throws an {@link NotificationException} relating to a specific lang.yml key.
* <p>
* This is automatically handled with eco, and should not be surrounded by a
* try/catch block.
*
* @param key The lang.yml key for the message to be sent.
* @throws NotificationException always.
*/
default void notify(@NotNull final String key) throws NotificationException {
throw new NotificationException(key);
}
/**
* Throws an {@link NotificationException} relating to a specific lang.yml key
* if the passed object is null.
* <p>
* This is automatically handled with eco, and should not be surrounded by a
* try/catch block.
*
* @param obj The object to test.
* @param key The lang.yml key for the message to be sent.
* @param <T> The object type.
* @return Returns the object, definitely not-null.
* @throws NotificationException If the object is null.
*/
@NotNull
default <T> T notifyNull(@Nullable final T obj,
@NotNull final String key) throws NotificationException {
if (Objects.isNull(obj)) {
notify(key);
}
return Objects.requireNonNull(obj);
}
/**
* Throws an {@link NotificationException} relating to a specific lang.yml key
* if the passed object doesn't match the predicate.
* <p>
* This is automatically handled with eco, and should not be surrounded by a
* try/catch block.
*
* @param obj The object to test.
* @param key The lang.yml key for the message to be sent.
* @param predicate The predicate to test the object against.
* @param <T> The type of the object.
* @return Returns the object, definitely not-null.
* @throws NotificationException If the object doesn't satisfy the predicate.
*/
@NotNull
default <T> T notifyFalse(@NotNull final T obj,
@NotNull final String key,
@NotNull final Predicate<T> predicate) throws NotificationException {
notifyFalse(predicate.test(obj), key);
return obj;
}
/**
* Throws an {@link NotificationException} relating to a specific lang.yml key
* if a condition is false.
* <p>
* This is automatically handled with eco, and should not be surrounded by a
* try/catch block.
*
* @param condition The condition to test.
* @param key The lang.yml key for the message to be sent.
* @return True.
* @throws NotificationException If the condition is false.
*/
default boolean notifyFalse(final boolean condition,
@NotNull final String key) throws NotificationException {
if (!condition) {
notify(key);
}
return true;
}
/**
* Throws an {@link NotificationException} relating to a specific lang.yml key
* if the passed string doesn't relate to a currently online player.
* <p>
* This is automatically handled with eco, and should not be surrounded by a
* try/catch block.
*
* @param playerName The player name.
* @param key The lang.yml key for the message to be sent.
* @return Returns the player, definitely not-null.
* @throws NotificationException If the player name is invalid.
*/
@NotNull
default Player notifyPlayerRequired(@Nullable final String playerName, @NotNull final String key) throws NotificationException {
if (playerName == null) {
notify(key);
}
assert playerName != null;
final Player player = Bukkit.getPlayer(playerName);
notifyNull(player, key);
return Objects.requireNonNull(player);
}
/**
* Throws an {@link NotificationException} relating to a specific lang.yml key
* if the passed string doesn't relate to a player on the server.
* <p>
* This is automatically handled with eco, and should not be surrounded by a
* try/catch block.
*
* @param playerName The player name.
* @param key The lang.yml key for the message to be sent.
* @return Returns the offline player, definitely not-null.
* @throws NotificationException If the player name is invalid.
*/
@NotNull
default OfflinePlayer notifyOfflinePlayerRequired(@Nullable final String playerName,
@NotNull final String key) throws NotificationException {
if (playerName == null) {
notify(key);
}
assert playerName != null;
@SuppressWarnings("deprecation") final OfflinePlayer player = Bukkit.getOfflinePlayer(playerName);
boolean hasPlayedBefore = player.hasPlayedBefore() || player.isOnline();
notifyFalse(!hasPlayedBefore, key);
return player;
}
/**
* Throws an exception containing a langYml key if player doesn't have permission.
*
* @param player The player.
* @param permission The permission.
* @param key The lang.yml key for the message to be sent.
* @return The player.
* @throws NotificationException If the player doesn't have the required permission.
*/
@NotNull
default Player notifyPermissionRequired(@NotNull final Player player,
@NotNull final String permission,
@NotNull final String key) throws NotificationException {
return notifyFalse(player, key, p -> p.hasPermission(permission));
}
/**
* Get the plugin.
*
* @return The plugin.
*/
EcoPlugin getPlugin();
/**
* Get the handler.
*
* @return The handler.
* @see CommandHandler
* @deprecated Use {@link CommandBase#onExecute(CommandSender, List)} instead.
*/
@Deprecated(forRemoval = true)
CommandHandler getHandler();
/**
* Set the handler.
*
* @param handler The handler.
* @see CommandHandler
* @deprecated Handlers have been deprecated.
*/
@Deprecated(forRemoval = true)
void setHandler(@NotNull CommandHandler handler);
/**
* Get the tab completer.
*
* @return The tab completer.
* @see TabCompleteHandler
* @deprecated Use {@link CommandBase#tabComplete(CommandSender, List)} instead.
*/
@Deprecated(forRemoval = true)
TabCompleteHandler getTabCompleter();
/**
* Set the tab completer.
*
* @param handler The handler.
* @see TabCompleteHandler
* @deprecated Handlers have been deprecated.
*/
@Deprecated(forRemoval = true)
void setTabCompleter(@NotNull TabCompleteHandler handler);
}

View File

@@ -1,29 +0,0 @@
package com.willfp.eco.core.command;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* A command handler handles the actual code for a command.
* <p>
* The replacement for {@link org.bukkit.command.CommandExecutor#onCommand(CommandSender, Command, String, String[])}
*
* @see CommandBase
* @deprecated Handlers have been deprecated. This legacy system will eventually be removed,
* update to use the new system: {@link CommandBase#onExecute(CommandSender, List)}.
*/
@FunctionalInterface
@Deprecated(since = "6.17.0", forRemoval = true)
public interface CommandHandler {
/**
* The code to be called on execution.
*
* @param sender The sender.
* @param args The arguments.
*/
void onExecute(@NotNull CommandSender sender,
@NotNull List<String> args);
}

View File

@@ -0,0 +1,36 @@
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
* specify valid arguments in commands.
* <p>
* Methods in eco that throw this will contain automatic handling and thus
* should not be surrounded by try / catch blocks.
*/
public class NotificationException extends Exception {
/**
* The key for the lang.yml message to be sent.
*/
private final String key;
/**
* Creates a notification exception.
*
* @param key The lang key of the notification.
*/
public NotificationException(@NotNull final String key) {
super(key);
this.key = key;
}
/**
* Get the lang key.
*
* @return The lang key.
*/
public String getKey() {
return key;
}
}

View File

@@ -0,0 +1,44 @@
package com.willfp.eco.core.command;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
/**
* Plugin command bases can be registered directly with the server,
* this essentially functions as the interface that is implemented generically
* via {@link com.willfp.eco.core.command.impl.PluginCommand}.
*/
public interface PluginCommandBase extends CommandBase {
/**
* Register the PluginCommandBase to the bukkit commandMap.
*/
void register();
/**
* Unregister the PluginCommandBase from the bukkit commandMap.
*/
void unregister();
/**
* Get aliases. Leave null if this command is from plugin.yml.
*
* @return The aliases.
*/
@NotNull
default List<String> getAliases() {
return new ArrayList<>();
}
/**
* Get description.
*
* @return The description.
*/
@Nullable
default String getDescription() {
return null;
}
}

View File

@@ -1,30 +0,0 @@
package com.willfp.eco.core.command;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* A Tab Complete handler handles the actual tab-completion code.
* <p>
* The replacement for {@link org.bukkit.command.TabCompleter#onTabComplete(CommandSender, Command, String, String[])}
*
* @see CommandBase
* @deprecated Handlers have been deprecated. This legacy system will eventually be removed,
* update to use the new system: {@link CommandBase#tabComplete(CommandSender, List)}
*/
@FunctionalInterface
@Deprecated(since = "6.17.0", forRemoval = true)
public interface TabCompleteHandler {
/**
* Handle Tab Completion.
*
* @param sender The sender.
* @param args The arguments.
* @return The tab completion results.
*/
List<String> tabComplete(@NotNull CommandSender sender,
@NotNull List<String> args);
}

View File

@@ -0,0 +1,72 @@
package com.willfp.eco.core.command.impl;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.PluginIdentifiableCommand;
import org.bukkit.command.TabCompleter;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* Delegates a bukkit command to an eco command (for registrations).
*
* @deprecated Internal command implementations have been removed from the API.
*/
@Deprecated(since = "6.49.0", forRemoval = true)
public final class DelegatedBukkitCommand extends Command implements TabCompleter, PluginIdentifiableCommand {
/**
* The delegate command.
*/
private final PluginCommand delegate;
/**
* Create a new delegated command.
*
* @param delegate The delegate.
*/
public DelegatedBukkitCommand(@NotNull final PluginCommand delegate) {
super(delegate.getName());
this.delegate = delegate;
}
@Override
public boolean execute(@NotNull final CommandSender commandSender,
@NotNull final String label,
@NotNull final String[] args) {
return false;
}
@Override
public List<String> onTabComplete(@NotNull final CommandSender commandSender,
@NotNull final Command command,
@NotNull final String label,
@NotNull final String[] args) {
return List.of();
}
@NotNull
@Override
public Plugin getPlugin() {
return this.delegate.getPlugin();
}
@Override
public @NotNull String getPermission() {
return this.delegate.getPermission();
}
@NotNull
@Override
public String getDescription() {
return this.delegate.getDescription() == null ? "" : this.delegate.getDescription();
}
@NotNull
@Override
public List<String> getAliases() {
return this.delegate.getAliases();
}
}

View File

@@ -1,287 +0,0 @@
package com.willfp.eco.core.command.impl;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.command.CommandBase;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
* Abstract class for commands that can be handled.
* <p>
* Handled commands have a method to pass in raw input from bukkit commands
* in order to execute the command-specific code. It's essentially an internal
* layer, hence why it's a package-private class.
*/
@SuppressWarnings({"DeprecatedIsStillUsed", "removal"})
abstract class HandledCommand implements CommandBase {
/**
* The plugin.
*/
private final EcoPlugin plugin;
/**
* The name of the command.
*/
private final String name;
/**
* The permission required to execute the command.
* <p>
* Written out as a string for flexibility with subclasses.
*/
private final String permission;
/**
* Should the command only be allowed to be executed by players?
* <p>
* In other worlds, only allowed to be executed by console.
*/
private final boolean playersOnly;
/**
* The actual code to be executed in the command.
*/
@Deprecated
@Nullable
private com.willfp.eco.core.command.CommandHandler handler = null;
/**
* The tab completion code to be executed in the command.
*/
@Deprecated
@Nullable
private com.willfp.eco.core.command.TabCompleteHandler tabCompleter = null;
/**
* All subcommands for the command.
*/
private final List<CommandBase> subcommands;
/**
* Create a new command.
* <p>
* The name cannot be the same as an existing command as this will conflict.
*
* @param plugin Instance of a plugin.
* @param name The name used in execution.
* @param permission The permission required to execute the command.
* @param playersOnly If only players should be able to execute this command.
*/
HandledCommand(@NotNull final EcoPlugin plugin,
@NotNull final String name,
@NotNull final String permission,
final boolean playersOnly) {
this.plugin = plugin;
this.name = name;
this.permission = permission;
this.playersOnly = playersOnly;
this.subcommands = new ArrayList<>();
}
/**
* Add a subcommand to the command.
*
* @param subcommand The subcommand.
* @return The parent command.
*/
@Override
public final CommandBase addSubcommand(@NotNull final CommandBase subcommand) {
subcommands.add(subcommand);
return this;
}
/**
* Get the plugin.
*
* @return The plugin.
*/
@Override
public EcoPlugin getPlugin() {
return this.plugin;
}
/**
* Handle the command.
*
* @param sender The sender.
* @param args The arguments.
*/
protected final void handle(@NotNull final CommandSender sender,
@NotNull final String[] args) {
if (!canExecute(sender, this, this.getPlugin())) {
return;
}
if (args.length > 0) {
for (CommandBase subcommand : this.getSubcommands()) {
if (subcommand.getName().equalsIgnoreCase(args[0])) {
if (!canExecute(sender, subcommand, this.getPlugin())) {
return;
}
((HandledCommand) subcommand).handle(sender, Arrays.copyOfRange(args, 1, args.length));
return;
}
}
}
if (this.isPlayersOnly() && !(sender instanceof Player)) {
sender.sendMessage(this.getPlugin().getLangYml().getMessage("not-player"));
return;
}
if (this.getHandler() != null) {
this.getHandler().onExecute(sender, Arrays.asList(args));
} else {
this.onExecute(sender, Arrays.asList(args));
}
}
/**
* Handle the tab completion.
*
* @param sender The sender.
* @param args The arguments.
* @return The tab completion results.
*/
protected final List<String> handleTabCompletion(@NotNull final CommandSender sender,
@NotNull final String[] args) {
if (!sender.hasPermission(this.getPermission())) {
return null;
}
if (args.length == 1) {
List<String> completions = new ArrayList<>();
StringUtil.copyPartialMatches(
args[0],
this.getSubcommands().stream()
.filter(subCommand -> sender.hasPermission(subCommand.getPermission()))
.map(CommandBase::getName)
.collect(Collectors.toList()),
completions
);
Collections.sort(completions);
if (!completions.isEmpty()) {
return completions;
}
}
if (args.length >= 2) {
HandledCommand command = null;
for (CommandBase subcommand : this.getSubcommands()) {
if (!sender.hasPermission(subcommand.getPermission())) {
continue;
}
if (args[0].equalsIgnoreCase(subcommand.getName())) {
command = (HandledCommand) subcommand;
}
}
if (command != null) {
return command.handleTabCompletion(sender, Arrays.copyOfRange(args, 1, args.length));
}
}
if (this.getTabCompleter() != null) {
return this.getTabCompleter().tabComplete(sender, Arrays.asList(args));
} else {
return this.tabComplete(sender, Arrays.asList(args));
}
}
/**
* If a sender can execute the command.
*
* @param sender The sender.
* @param command The command.
* @param plugin The plugin.
* @return If the sender can execute.
*/
public static boolean canExecute(@NotNull final CommandSender sender,
@NotNull final CommandBase command,
@NotNull final EcoPlugin plugin) {
if (!sender.hasPermission(command.getPermission()) && sender instanceof Player) {
sender.sendMessage(plugin.getLangYml().getNoPermission());
return false;
}
return true;
}
/**
* Get the command name.
*
* @return The name.
*/
public String getName() {
return this.name;
}
/**
* Get the permission required to execute the command.
*
* @return The permission.
*/
public String getPermission() {
return this.permission;
}
/**
* Get if the command can only be executed by players.
*
* @return If players only.
*/
public boolean isPlayersOnly() {
return this.playersOnly;
}
/**
* Get the subcommands of the command.
*
* @return The subcommands.
*/
public List<CommandBase> getSubcommands() {
return this.subcommands;
}
@Deprecated(forRemoval = true)
@Override
public @Nullable com.willfp.eco.core.command.CommandHandler getHandler() {
return this.handler;
}
@Deprecated(forRemoval = true)
@Override
public @Nullable com.willfp.eco.core.command.TabCompleteHandler getTabCompleter() {
return this.tabCompleter;
}
@Deprecated(forRemoval = true)
@Override
public void setHandler(@Nullable final com.willfp.eco.core.command.CommandHandler handler) {
this.handler = handler;
}
@Deprecated(forRemoval = true)
@Override
public void setTabCompleter(@Nullable final com.willfp.eco.core.command.TabCompleteHandler tabCompleter) {
this.tabCompleter = tabCompleter;
}
}

View File

@@ -1,26 +1,28 @@
package com.willfp.eco.core.command.impl;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import com.willfp.eco.core.command.CommandBase;
import com.willfp.eco.core.command.PluginCommandBase;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* PluginCommands are the class to be used instead of CommandExecutor,
* they function as the base command, e.g. {@code /ecoenchants} would be a base command, with each
* subsequent argument functioning as subcommands.
* PluginCommands are the class to be used instead of CommandExecutor, they function as the base
* command, e.g. {@code /ecoenchants} would be a base command, with each subsequent argument
* functioning as subcommands.
* <p>
* The command will not be registered until register() is called.
* <p>
* The name cannot be the same as an existing command as this will conflict.
*/
public abstract class PluginCommand extends HandledCommand implements CommandExecutor, TabCompleter {
public abstract class PluginCommand implements PluginCommandBase {
/**
* The delegate command.
*/
private final PluginCommandBase delegate;
/**
* Create a new command.
*
@@ -33,64 +35,51 @@ public abstract class PluginCommand extends HandledCommand implements CommandExe
@NotNull final String name,
@NotNull final String permission,
final boolean playersOnly) {
super(plugin, name, permission, playersOnly);
this.delegate = Eco.get().createPluginCommand(this, plugin, name, permission, playersOnly);
}
/**
* Registers the command with the server,
* <p>
* Requires the command name to exist, defined in plugin.yml.
*/
public final void register() {
org.bukkit.command.PluginCommand command = Bukkit.getPluginCommand(this.getName());
assert command != null;
command.setExecutor(this);
command.setTabCompleter(this);
}
/**
* Internal implementation used to clean up boilerplate.
* Used for parity with {@link CommandExecutor#onCommand(CommandSender, Command, String, String[])}.
*
* @param sender The executor of the command.
* @param command The bukkit command.
* @param label The name of the executed command.
* @param args The arguments of the command (anything after the physical command name)
* @return If the command was processed by the linked {@link EcoPlugin}
*/
@Override
public final boolean onCommand(@NotNull final CommandSender sender,
@NotNull final Command command,
@NotNull final String label,
@NotNull final String[] args) {
if (!command.getName().equalsIgnoreCase(this.getName())) {
return false;
public @NotNull String getName() {
return delegate.getName();
}
this.handle(sender, args);
return true;
}
/**
* Internal implementation used to clean up boilerplate.
* Used for parity with {@link TabCompleter#onTabComplete(CommandSender, Command, String, String[])}.
*
* @param sender The executor of the command.
* @param command The bukkit command.
* @param label The name of the executed command.
* @param args The arguments of the command (anything after the physical command name).
* @return The list of tab-completions.
*/
@Override
public @Nullable List<String> onTabComplete(@NotNull final CommandSender sender,
@NotNull final Command command,
@NotNull final String label,
@NotNull final String[] args) {
if (!command.getName().equalsIgnoreCase(this.getName())) {
return null;
public @NotNull String getPermission() {
return delegate.getPermission();
}
return this.handleTabCompletion(sender, args);
@Override
public boolean isPlayersOnly() {
return delegate.isPlayersOnly();
}
@Override
public @NotNull CommandBase addSubcommand(@NotNull CommandBase command) {
return delegate.addSubcommand(command);
}
@Override
public @NotNull List<CommandBase> getSubcommands() {
return delegate.getSubcommands();
}
@Override
public @NotNull CommandBase getWrapped() {
return this;
}
@Override
public void register() {
delegate.register();
}
@Override
public void unregister() {
delegate.unregister();
}
@Override
public EcoPlugin getPlugin() {
return delegate.getPlugin();
}
}

View File

@@ -1,13 +1,21 @@
package com.willfp.eco.core.command.impl;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.command.CommandBase;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* Subcommands can be added to PluginCommands or to other Subcommands.
* A command implementation that must exist as a subcommand (i.e. cannot be registered directly).
*/
public abstract class Subcommand extends HandledCommand {
public abstract class Subcommand implements CommandBase {
/**
* The delegate command.
*/
private final CommandBase delegate;
/**
* Create subcommand.
*
@@ -20,7 +28,7 @@ public abstract class Subcommand extends HandledCommand {
@NotNull final String name,
@NotNull final String permission,
final boolean playersOnly) {
super(plugin, name, permission, playersOnly);
this.delegate = Eco.get().createSubcommand(this, plugin, name, permission, playersOnly);
}
/**
@@ -33,6 +41,41 @@ public abstract class Subcommand extends HandledCommand {
protected Subcommand(@NotNull final EcoPlugin plugin,
@NotNull final String name,
@NotNull final CommandBase parent) {
super(plugin, name, parent.getPermission(), parent.isPlayersOnly());
this(plugin, name, parent.getPermission(), parent.isPlayersOnly());
}
@Override
public @NotNull String getName() {
return delegate.getName();
}
@Override
public @NotNull String getPermission() {
return delegate.getPermission();
}
@Override
public boolean isPlayersOnly() {
return delegate.isPlayersOnly();
}
@Override
public @NotNull CommandBase addSubcommand(@NotNull CommandBase command) {
return delegate.addSubcommand(command);
}
@Override
public @NotNull List<CommandBase> getSubcommands() {
return delegate.getSubcommands();
}
@Override
public @NotNull CommandBase getWrapped() {
return this;
}
@Override
public EcoPlugin getPlugin() {
return delegate.getPlugin();
}
}

View File

@@ -40,7 +40,7 @@ public abstract class BaseConfig extends LoadableConfigWrapper {
final boolean removeUnused,
@NotNull final ConfigType type,
final boolean requiresChangeToSave) {
super(Eco.getHandler().getConfigFactory().createUpdatableConfig(
super(Eco.get().createUpdatableConfig(
configName,
plugin,
"",

View File

@@ -6,12 +6,12 @@ import org.jetbrains.annotations.Nullable;
/**
* Builder for configs to create them programmatically.
*/
public class BuildableConfig extends TransientConfig {
public class BuildableConfig extends GenericConfig {
/**
* Create a new empty config builder.
*/
public BuildableConfig() {
super();
}
/**

View File

@@ -14,7 +14,12 @@ public enum ConfigType {
/**
* .yml config.
*/
YAML("yml");
YAML("yml"),
/**
* .toml config.
*/
TOML("toml");
/**
* The file extension.

View File

@@ -0,0 +1,157 @@
package com.willfp.eco.core.config;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.config.interfaces.Config;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;
/**
* Utilities / API methods for configs.
*/
public final class Configs {
/**
* Load a Config from a bukkit {@link ConfigurationSection}.
*
* @param config The ConfigurationSection.
* @return The config.
*/
@NotNull
public static Config fromBukkit(@Nullable final ConfigurationSection config) {
return config == null ? empty() : Eco.get().wrapConfigurationSection(config);
}
/**
* Load a config from an {@link InputStream}.
* <p>
* Only for yaml configs.
*
* @param stream The InputStream.
* @return The config.
*/
@NotNull
public static Config fromStream(@Nullable final InputStream stream) {
return stream != null ? fromBukkit(YamlConfiguration.loadConfiguration(
new InputStreamReader(stream)
)) : empty();
}
/**
* Load a config from a file.
*
* @param file The file.
* @return The config.
*/
@NotNull
public static Config fromFile(@Nullable final File file) {
if (file == null) {
return empty();
}
int lastIndex = file.getName().lastIndexOf(".");
if (lastIndex < 0) {
return empty();
}
for (ConfigType type : ConfigType.values()) {
if (file.getName().substring(lastIndex + 1).equalsIgnoreCase(type.getExtension())) {
return fromFile(file, type);
}
}
return empty();
}
/**
* Load a config from a file.
*
* @param file The file.
* @param type The type.
* @return The config.
*/
@NotNull
public static Config fromFile(@Nullable final File file,
@NotNull final ConfigType type) {
if (file == null) {
return empty();
}
try {
return Eco.get().createConfig(Files.readString(file.toPath()), type);
} catch (IOException e) {
return empty();
}
}
/**
* Load config from map (uses {@link ConfigType#JSON}).
*
* @param values The values.
* @return The config.
*/
@NotNull
public static Config fromMap(@NotNull final Map<String, Object> values) {
return fromMap(values, ConfigType.JSON);
}
/**
* Load config from map.
*
* @param values The values.
* @param type The type.
* @return The config.
*/
@NotNull
public static Config fromMap(@NotNull final Map<String, Object> values,
@NotNull final ConfigType type) {
return Eco.get().createConfig(values, type);
}
/**
* Create empty config (uses {@link ConfigType#JSON}).
*
* @return An empty config.
*/
@NotNull
public static Config empty() {
return fromMap(new HashMap<>(), ConfigType.JSON);
}
/**
* Create empty config.
*
* @param type The type.
* @return An empty config.
*/
@NotNull
public static Config empty(@NotNull final ConfigType type) {
return fromMap(new HashMap<>(), type);
}
/**
* Load config from string.
*
* @param contents The contents of the config.
* @param type The config type.
* @return The config.
*/
@NotNull
public static Config fromString(@NotNull final String contents,
@NotNull final ConfigType type) {
return Eco.get().createConfig(contents, type);
}
private Configs() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
}

View File

@@ -16,6 +16,8 @@ import org.jetbrains.annotations.NotNull;
*/
public abstract class ExtendableConfig extends LoadableConfigWrapper {
/**
* Create a new extendable config.
*
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
@@ -31,7 +33,7 @@ public abstract class ExtendableConfig extends LoadableConfigWrapper {
@NotNull final String subDirectoryPath,
@NotNull final ConfigType type,
@NotNull final String... updateBlacklist) {
super(Eco.getHandler().getConfigFactory().createUpdatableConfig(
super(Eco.get().createUpdatableConfig(
configName,
plugin,
subDirectoryPath,

View File

@@ -0,0 +1,27 @@
package com.willfp.eco.core.config;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.config.wrapper.ConfigWrapper;
import org.jetbrains.annotations.NotNull;
/**
* Generic config to simplify creating custom configs without having
* to meddle with delegation.
*/
public abstract class GenericConfig extends ConfigWrapper<Config> {
/**
* Create a new generic config.
*/
protected GenericConfig() {
super(Configs.empty());
}
/**
* Create a new generic config.
*
* @param type The config type.
*/
protected GenericConfig(@NotNull final ConfigType type) {
super(Configs.empty(type));
}
}

View File

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

View File

@@ -20,13 +20,18 @@ import java.util.Map;
* Config that exists purely in the code, not linked to any file.
* <p>
* Use for inline configs to move data around or to add subsections to other configs.
*
* @deprecated Poorly named class, makes the config system seem needlessly complicated.
*/
@Deprecated(since = "6.44.0", forRemoval = true)
public class TransientConfig extends ConfigWrapper<Config> {
/**
* Create new transient config from bukkit config.
*
* @param config The ConfigurationSection handle.
*/
public TransientConfig(@NotNull final ConfigurationSection config) {
super(Eco.getHandler().getConfigFactory().createConfig(config));
super(Eco.get().wrapConfigurationSection(config));
}
/**
@@ -39,30 +44,25 @@ public class TransientConfig extends ConfigWrapper<Config> {
}
/**
* Create a transient config from an input stream.
*
* @param stream The InputStream.
*/
public TransientConfig(@Nullable final InputStream stream) {
super(stream != null ? Eco.getHandler().getConfigFactory().createConfig(YamlConfiguration.loadConfiguration(
super(stream != null ? Eco.get().wrapConfigurationSection(YamlConfiguration.loadConfiguration(
new InputStreamReader(stream)
)) : new TransientConfig());
}
/**
* @param file The File.
* @deprecated Specify the config type to prevent bugs.
*/
@Deprecated(since = "6.30.0", forRemoval = true)
public TransientConfig(@Nullable final File file) {
this(file, ConfigType.YAML);
}
/**
* Load a file to a config.
*
* @param file The file.
* @param type The config type to try read from.
*/
public TransientConfig(@Nullable final File file,
@NotNull final ConfigType type) {
super(file != null ? Eco.getHandler().getConfigFactory().createConfig(readFile(file), type)
super(file != null ? Eco.get().createConfig(readFile(file), type)
: new TransientConfig());
}
@@ -72,7 +72,7 @@ public class TransientConfig extends ConfigWrapper<Config> {
* @param values The values.
*/
public TransientConfig(@NotNull final Map<String, Object> values) {
super(Eco.getHandler().getConfigFactory().createConfig(values, ConfigType.YAML));
super(Eco.get().createConfig(values, ConfigType.YAML));
}
/**
@@ -83,7 +83,7 @@ public class TransientConfig extends ConfigWrapper<Config> {
*/
public TransientConfig(@NotNull final Map<String, Object> values,
@NotNull final ConfigType type) {
super(Eco.getHandler().getConfigFactory().createConfig(values, type));
super(Eco.get().createConfig(values, type));
}
/**
@@ -94,12 +94,14 @@ public class TransientConfig extends ConfigWrapper<Config> {
}
/**
* Load a config from a string.
*
* @param contents The contents of the config.
* @param type The config type.
*/
public TransientConfig(@NotNull final String contents,
@NotNull final ConfigType type) {
super(Eco.getHandler().getConfigFactory().createConfig(contents, type));
super(Eco.get().createConfig(contents, type));
}
/**

View File

@@ -9,6 +9,11 @@ import org.jetbrains.annotations.NotNull;
* Default plugin config.yml.
*/
public class ConfigYml extends BaseConfig {
/**
* The use local storage key.
*/
public static final String KEY_USES_LOCAL_STORAGE = "use-local-storage";
/**
* Config.yml.
*
@@ -52,4 +57,13 @@ public class ConfigYml extends BaseConfig {
final boolean removeUnused) {
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,10 +6,32 @@ import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.util.StringUtils;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* Default plugin lang.yml.
*/
public class LangYml extends BaseConfig {
/**
* The messages key.
*/
public static final String KEY_MESSAGES = "messages";
/**
* The prefix key.
*/
public static final String KEY_PREFIX = "messages.prefix";
/**
* The no permission key.
*/
public static final String KEY_NO_PERMISSION = "messages.no-permission";
/**
* The not player key.
*/
public static final String KEY_NOT_PLAYER = "messages.not-player";
/**
* Lang.yml.
*
@@ -19,13 +41,31 @@ public class LangYml extends BaseConfig {
super("lang", plugin, false, ConfigType.YAML);
}
/**
* lang.yml requires certain keys to be present.
* <p>
* If the lang.yml does not contain these keys, it is considered to be
* invalid and thus will show a warning in console.
*
* @return If valid.
*/
public boolean isValid() {
for (String key : List.of(KEY_MESSAGES, KEY_PREFIX, KEY_NO_PERMISSION, KEY_NOT_PLAYER)) {
if (!this.has(key)) {
return false;
}
}
return true;
}
/**
* Get the prefix for messages in chat.
*
* @return The prefix.
*/
public String getPrefix() {
return this.getFormattedString("messages.prefix");
return this.getFormattedString(KEY_PREFIX);
}
/**
@@ -34,7 +74,7 @@ public class LangYml extends BaseConfig {
* @return The message.
*/
public String getNoPermission() {
return getPrefix() + this.getFormattedString("messages.no-permission");
return getPrefix() + this.getFormattedString(KEY_NO_PERMISSION);
}
/**
@@ -56,6 +96,6 @@ public class LangYml extends BaseConfig {
*/
public String getMessage(@NotNull final String message,
@NotNull final StringUtils.FormatOption option) {
return getPrefix() + this.getFormattedString("messages." + message, option);
return getPrefix() + this.getFormattedString(KEY_MESSAGES + "." + message, option);
}
}

View File

@@ -2,10 +2,11 @@ package com.willfp.eco.core.config.interfaces;
import com.willfp.eco.core.config.BuildableConfig;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.TransientConfig;
import com.willfp.eco.core.config.Configs;
import com.willfp.eco.core.placeholder.AdditionalPlayer;
import com.willfp.eco.core.placeholder.InjectablePlaceholder;
import com.willfp.eco.core.placeholder.PlaceholderInjectable;
import com.willfp.eco.core.placeholder.context.PlaceholderContext;
import com.willfp.eco.util.NumberUtils;
import com.willfp.eco.util.StringUtils;
import org.bukkit.configuration.ConfigurationSection;
@@ -30,16 +31,6 @@ import java.util.Set;
*/
@SuppressWarnings("unused")
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.
*
@@ -103,7 +94,7 @@ public interface Config extends Cloneable, PlaceholderInjectable {
*/
@NotNull
default Config getSubsection(@NotNull String path) {
return Objects.requireNonNullElse(getSubsectionOrNull(path), new TransientConfig());
return Objects.requireNonNullElse(getSubsectionOrNull(path), Configs.empty());
}
/**
@@ -144,7 +135,7 @@ public interface Config extends Cloneable, PlaceholderInjectable {
* @return The computed value, or 0 if not found or invalid.
*/
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();
}
/**
* 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.
@@ -266,6 +269,22 @@ public interface Config extends Cloneable, PlaceholderInjectable {
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.
* <p>
@@ -298,7 +317,7 @@ public interface Config extends Cloneable, PlaceholderInjectable {
* Get a formatted string from config.
*
* @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
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 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
default String getFormattedStringOrNull(@NotNull String path,
@@ -318,6 +337,25 @@ public interface Config extends Cloneable, PlaceholderInjectable {
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.
* <p>
@@ -372,6 +410,24 @@ public interface Config extends Cloneable, PlaceholderInjectable {
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.
* <p>
@@ -428,6 +484,30 @@ public interface Config extends Cloneable, PlaceholderInjectable {
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.
* <p>
@@ -473,7 +553,7 @@ public interface Config extends Cloneable, PlaceholderInjectable {
* @return The computed value, or 0 if not found or invalid.
*/
default double getDoubleFromExpression(@NotNull String path) {
return getDoubleFromExpression(path, null);
return getDoubleFromExpression(path, PlaceholderContext.of(this));
}
/**
@@ -485,7 +565,7 @@ public interface Config extends Cloneable, PlaceholderInjectable {
*/
default double getDoubleFromExpression(@NotNull String path,
@Nullable Player player) {
return NumberUtils.evaluateExpression(this.getString(path), player, this);
return getDoubleFromExpression(path, player, Collections.emptyList());
}
/**
@@ -499,7 +579,24 @@ public interface Config extends Cloneable, PlaceholderInjectable {
default double getDoubleFromExpression(@NotNull String path,
@Nullable Player player,
@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.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
@@ -44,21 +43,6 @@ public interface LoadableConfig extends Config {
*/
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}.
*/

View File

@@ -38,6 +38,9 @@ import java.lang.annotation.Target;
* <p>
* By having a plugin as a parameter, you shouldn't really need getInstance()
* 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)
@Target(ElementType.METHOD)

View File

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

View File

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

View File

@@ -87,7 +87,7 @@ public interface ExtendedPersistentDataContainer {
* @return The extended container.
*/
static ExtendedPersistentDataContainer extend(@NotNull PersistentDataContainer base) {
return Eco.getHandler().adaptPdc(base);
return Eco.get().adaptPdc(base);
}
/**
@@ -96,6 +96,6 @@ public interface ExtendedPersistentDataContainer {
* @return The extended container.
*/
static ExtendedPersistentDataContainer create() {
return extend(Eco.getHandler().newPdc());
return extend(Eco.get().newPdc());
}
}

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

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

View File

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

View File

@@ -9,6 +9,22 @@ import org.jetbrains.annotations.NotNull;
* Profiles save automatically, so there is no need to save after changes.
*/
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.
*
@@ -16,6 +32,6 @@ public interface ServerProfile extends Profile {
*/
@NotNull
static ServerProfile load() {
return Eco.getHandler().getProfileHandler().loadServerProfile();
return Eco.get().getServerProfile();
}
}

View File

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

View File

@@ -43,7 +43,7 @@ public final class PersistentDataKey<T> {
this.defaultValue = defaultValue;
this.type = type;
Eco.getHandler().getKeyRegistry().registerKey(this);
Eco.get().registerPersistentKey(this);
}
@Override
@@ -82,51 +82,13 @@ public final class PersistentDataKey<T> {
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.
*
* @return The keys.
*/
public static Set<PersistentDataKey<?>> values() {
return Eco.getHandler().getKeyRegistry().getRegisteredKeys();
return Eco.get().getRegisteredPersistentDataKeys();
}
@Override
@@ -134,7 +96,7 @@ public final class PersistentDataKey<T> {
if (this == o) {
return true;
}
if (!(o instanceof PersistentDataKey that)) {
if (!(o instanceof PersistentDataKey<?> that)) {
return false;
}
return Objects.equals(this.getKey(), that.getKey());

View File

@@ -1,8 +1,10 @@
package com.willfp.eco.core.data.keys;
import com.willfp.eco.core.config.interfaces.Config;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@@ -21,50 +23,43 @@ public final class PersistentDataKeyType<T> {
/**
* String.
*/
public static final PersistentDataKeyType<String> STRING = new PersistentDataKeyType<>(String.class, "STRING");
public static final PersistentDataKeyType<String> STRING = new PersistentDataKeyType<>("STRING");
/**
* Boolean.
*/
public static final PersistentDataKeyType<Boolean> BOOLEAN = new PersistentDataKeyType<>(Boolean.class, "BOOLEAN");
public static final PersistentDataKeyType<Boolean> BOOLEAN = new PersistentDataKeyType<>("BOOLEAN");
/**
* Int.
*/
public static final PersistentDataKeyType<Integer> INT = new PersistentDataKeyType<>(Integer.class, "INT");
public static final PersistentDataKeyType<Integer> INT = new PersistentDataKeyType<>("INT");
/**
* Double.
*/
public static final PersistentDataKeyType<Double> DOUBLE = new PersistentDataKeyType<>(Double.class, "DOUBLE");
public static final PersistentDataKeyType<Double> DOUBLE = new PersistentDataKeyType<>("DOUBLE");
/**
* 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");
/**
* The class of the type.
* Config.
*/
private final Class<T> typeClass;
public static final PersistentDataKeyType<Config> CONFIG = new PersistentDataKeyType<>("CONFIG");
/**
* Big Decimal.
*/
public static final PersistentDataKeyType<BigDecimal> BIG_DECIMAL = new PersistentDataKeyType<>("BIG_DECIMAL");
/**
* The name of the key type.
*/
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.
*
@@ -77,14 +72,11 @@ public final class PersistentDataKeyType<T> {
/**
* Create new PersistentDataKeyType.
*
* @param typeClass The type class.
* @param name The name.
*/
private PersistentDataKeyType(@Nullable final Class<T> typeClass,
@NotNull final String name) {
private PersistentDataKeyType(@NotNull final String name) {
VALUES.add(this);
this.typeClass = typeClass;
this.name = name;
}
@@ -93,7 +85,7 @@ public final class PersistentDataKeyType<T> {
if (this == that) {
return true;
}
if (!(that instanceof PersistentDataKeyType type)) {
if (!(that instanceof PersistentDataKeyType<?> type)) {
return false;
}
return Objects.equals(this.name, type.name);

View File

@@ -1,13 +1,27 @@
package com.willfp.eco.core.display;
import com.willfp.eco.core.fast.FastItemStack;
import com.willfp.eco.core.integrations.guidetection.GUIDetectionManager;
import com.willfp.eco.util.NamespacedKeyUtils;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.bukkit.persistence.PersistentDataType;
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.TreeMap;
/**
* 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 {
/**
@@ -16,9 +30,14 @@ public final class Display {
public static final String PREFIX = "§z";
/**
* The display handler.
* All registered modules.
*/
private static DisplayHandler handler = null;
private static final Map<Integer, List<DisplayModule>> REGISTERED_MODULES = new TreeMap<>();
/**
* The finalize key.
*/
private static final NamespacedKey FINALIZE_KEY = NamespacedKeyUtils.createEcoKey("finalized");
/**
* Display on ItemStacks.
@@ -39,7 +58,49 @@ public final class Display {
*/
public static ItemStack display(@NotNull final ItemStack itemStack,
@Nullable final Player player) {
return handler.display(itemStack, player);
Map<String, Object[]> pluginVarArgs = new HashMap<>();
for (List<DisplayModule> modules : REGISTERED_MODULES.values()) {
for (DisplayModule module : modules) {
pluginVarArgs.put(module.getPluginName(), module.generateVarArgs(itemStack));
}
}
Display.revert(itemStack);
if (!itemStack.hasItemMeta()) {
return itemStack;
}
ItemStack original = itemStack.clone();
Inventory inventory = player == null ? null : player.getOpenInventory().getTopInventory();
boolean inInventory = inventory != null && inventory.contains(original);
boolean inGui = player != null && GUIDetectionManager.hasGUIOpen(player);
DisplayProperties properties = new DisplayProperties(
inInventory,
inGui,
original
);
for (List<DisplayModule> modules : REGISTERED_MODULES.values()) {
for (DisplayModule module : modules) {
Object[] varargs = pluginVarArgs.get(module.getPluginName());
if (varargs == null) {
continue;
}
module.display(itemStack, varargs);
if (player != null) {
module.display(itemStack, player, varargs);
module.display(itemStack, player, properties, varargs);
}
}
}
return itemStack;
}
/**
@@ -71,7 +132,25 @@ public final class Display {
* @return The ItemStack.
*/
public static ItemStack revert(@NotNull final ItemStack itemStack) {
return handler.revert(itemStack);
if (Display.isFinalized(itemStack)) {
Display.unfinalize(itemStack);
}
FastItemStack fast = FastItemStack.wrap(itemStack);
List<String> lore = fast.getLore();
if (!lore.isEmpty() && lore.removeIf(line -> line.startsWith(Display.PREFIX))) {
fast.setLore(lore);
}
for (List<DisplayModule> modules : REGISTERED_MODULES.values()) {
for (DisplayModule module : modules) {
module.revert(itemStack);
}
}
return itemStack;
}
/**
@@ -81,7 +160,15 @@ public final class Display {
* @return The ItemStack.
*/
public static ItemStack finalize(@NotNull final ItemStack itemStack) {
return handler.finalize(itemStack);
if (itemStack.getType().getMaxStackSize() > 1) {
return itemStack;
}
FastItemStack.wrap(itemStack)
.getPersistentDataContainer()
.set(FINALIZE_KEY, PersistentDataType.INTEGER, 1);
return itemStack;
}
/**
@@ -91,7 +178,11 @@ public final class Display {
* @return The ItemStack.
*/
public static ItemStack unfinalize(@NotNull final ItemStack itemStack) {
return handler.unfinalize(itemStack);
FastItemStack.wrap(itemStack)
.getPersistentDataContainer()
.remove(FINALIZE_KEY);
return itemStack;
}
/**
@@ -101,7 +192,9 @@ public final class Display {
* @return If finalized.
*/
public static boolean isFinalized(@NotNull final ItemStack itemStack) {
return handler.isFinalized(itemStack);
return FastItemStack.wrap(itemStack)
.getPersistentDataContainer()
.has(FINALIZE_KEY, PersistentDataType.INTEGER);
}
/**
@@ -110,23 +203,15 @@ public final class Display {
* @param module The module.
*/
public static void registerDisplayModule(@NotNull final DisplayModule module) {
handler.registerDisplayModule(module);
}
List<DisplayModule> modules = REGISTERED_MODULES.getOrDefault(
module.getWeight(),
new ArrayList<>()
);
/**
* Set the display handler.
* <p>
* Internal API component, you will cause bugs if you create your own handler.
*
* @param handler The handler.
*/
@ApiStatus.Internal
public static void setHandler(@NotNull final DisplayHandler handler) {
if (Display.handler != null) {
throw new IllegalStateException("Display already initialized!");
}
modules.removeIf(it -> it.getPluginName().equalsIgnoreCase(module.getPluginName()));
modules.add(module);
Display.handler = handler;
REGISTERED_MODULES.put(module.getWeight(), modules);
}
private Display() {

View File

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

View File

@@ -1,7 +1,6 @@
package com.willfp.eco.core.display;
import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginDependent;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
@@ -9,13 +8,20 @@ import org.jetbrains.annotations.Nullable;
/**
* 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 extends PluginDependent<EcoPlugin> {
public abstract class DisplayModule {
/**
* The priority of the module.
*/
private final int weight;
/**
* The plugin.
*/
private final EcoPlugin plugin;
/**
* Create a new display module.
*
@@ -24,8 +30,7 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
*/
protected DisplayModule(@NotNull final EcoPlugin plugin,
@NotNull final DisplayPriority priority) {
super(plugin);
this.weight = priority.getWeight();
this(plugin, priority.getWeight());
}
/**
@@ -36,7 +41,7 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
*/
protected DisplayModule(@NotNull final EcoPlugin plugin,
final int weight) {
super(plugin);
this.plugin = plugin;
this.weight = weight;
}
@@ -104,24 +109,7 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
* @return The plugin name.
*/
public final String getPluginName() {
return super.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;
};
return this.getPlugin().getName();
}
/**
@@ -132,4 +120,13 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
public int getWeight() {
return this.weight;
}
/**
* Get the plugin.
*
* @return The plugin.
*/
public EcoPlugin getPlugin() {
return plugin;
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -45,7 +45,6 @@ public record EntityGoalAvoidEntity(
return null;
}
try {
TestableEntity entity = Entities.lookup(config.getString("entity"));
return new EntityGoalAvoidEntity(
@@ -54,14 +53,6 @@ public record EntityGoalAvoidEntity(
config.getDouble("slowSpeed"),
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

View File

@@ -34,18 +34,9 @@ public record EntityGoalBreakDoors(
return null;
}
try {
return new EntityGoalBreakDoors(
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

View File

@@ -34,18 +34,9 @@ public record EntityGoalBreed(
return null;
}
try {
return new EntityGoalBreed(
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

View File

@@ -37,19 +37,10 @@ public record EntityGoalCatLieOnBed(
return null;
}
try {
return new EntityGoalCatLieOnBed(
config.getDouble("speed"),
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

View File

@@ -34,18 +34,9 @@ public record EntityGoalCatSitOnBed(
return null;
}
try {
return new EntityGoalCatSitOnBed(
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

View File

@@ -34,18 +34,9 @@ public record EntityGoalFleeSun(
return null;
}
try {
return new EntityGoalFleeSun(
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

View File

@@ -40,20 +40,11 @@ public record EntityGoalFollowMobs(
return null;
}
try {
return new EntityGoalFollowMobs(
config.getDouble("speed"),
config.getDouble("minDistance"),
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

View File

@@ -42,20 +42,11 @@ public record EntityGoalInteract(
return null;
}
try {
return new EntityGoalInteract(
Entities.lookup(config.getString("target")),
config.getDouble("range"),
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

View File

@@ -34,18 +34,9 @@ public record EntityGoalLeapAtTarget(
return null;
}
try {
return new EntityGoalLeapAtTarget(
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

View File

@@ -37,19 +37,10 @@ public record EntityGoalLookAtPlayer(
return null;
}
try {
return new EntityGoalLookAtPlayer(
config.getDouble("range"),
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

View File

@@ -37,19 +37,10 @@ public record EntityGoalMeleeAttack(
return null;
}
try {
return new EntityGoalMeleeAttack(
config.getDouble("speed"),
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

View File

@@ -37,19 +37,10 @@ public record EntityGoalMoveBackToVillage(
return null;
}
try {
return new EntityGoalMoveBackToVillage(
config.getDouble("speed"),
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

View File

@@ -43,21 +43,12 @@ public record EntityGoalMoveThroughVillage(
return null;
}
try {
return new EntityGoalMoveThroughVillage(
config.getDouble("speed"),
config.getBool("onlyAtNight"),
config.getInt("distance"),
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

View File

@@ -34,18 +34,9 @@ public record EntityGoalMoveTowardsRestriction(
return null;
}
try {
return new EntityGoalMoveTowardsRestriction(
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

View File

@@ -37,19 +37,10 @@ public record EntityGoalMoveTowardsTarget(
return null;
}
try {
return new EntityGoalMoveTowardsTarget(
config.getDouble("speed"),
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

View File

@@ -34,18 +34,9 @@ public record EntityGoalOpenDoors(
return null;
}
try {
return new EntityGoalOpenDoors(
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

View File

@@ -34,18 +34,9 @@ public record EntityGoalPanic(
return null;
}
try {
return new EntityGoalPanic(
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

View File

@@ -40,20 +40,11 @@ public record EntityGoalRandomStroll(
return null;
}
try {
return new EntityGoalRandomStroll(
config.getDouble("speed"),
config.getInt("interval"),
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

View File

@@ -37,19 +37,10 @@ public record EntityGoalRandomSwimming(
return null;
}
try {
return new EntityGoalRandomSwimming(
config.getDouble("speed"),
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

View File

@@ -45,21 +45,12 @@ public record EntityGoalRangedAttack(
return null;
}
try {
return new EntityGoalRangedAttack(
config.getDouble("speed"),
config.getInt("minInterval"),
config.getInt("maxInterval"),
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

View File

@@ -42,20 +42,11 @@ public record EntityGoalRangedBowAttack(
return null;
}
try {
return new EntityGoalRangedBowAttack(
config.getDouble("speed"),
config.getInt("interval"),
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

View File

@@ -39,19 +39,10 @@ public record EntityGoalRangedCrossbowAttack(
return null;
}
try {
return new EntityGoalRangedCrossbowAttack(
config.getDouble("speed"),
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

View File

@@ -34,18 +34,9 @@ public record EntityGoalStrollThroughVillage(
return null;
}
try {
return new EntityGoalStrollThroughVillage(
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

View File

@@ -28,6 +28,8 @@ public record EntityGoalTempt(
boolean canBeScared
) implements EntityGoal<Mob> {
/**
* Create a new entity goal.
*
* @param speed The speed at which the entity follows the item.
* @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.
@@ -58,7 +60,6 @@ public record EntityGoalTempt(
return null;
}
try {
Collection<TestableItem> items = config.getStrings("items").stream()
.map(Items::lookup)
.filter(it -> !(it instanceof EmptyTestableItem))
@@ -69,14 +70,6 @@ public record EntityGoalTempt(
items,
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

View File

@@ -48,7 +48,6 @@ public record EntityGoalUseItem(
return null;
}
try {
TestableEntity filter = Entities.lookup(config.getString("condition"));
return new EntityGoalUseItem(
@@ -56,14 +55,6 @@ public record EntityGoalUseItem(
Sound.valueOf(config.getString("sound").toUpperCase()),
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

View File

@@ -34,18 +34,9 @@ public record EntityGoalWaterAvoidingRandomFlying(
return null;
}
try {
return new EntityGoalWaterAvoidingRandomFlying(
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

View File

@@ -37,19 +37,10 @@ public record EntityGoalWaterAvoidingRandomStroll(
return null;
}
try {
return new EntityGoalWaterAvoidingRandomStroll(
config.getDouble("speed"),
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

View File

@@ -34,18 +34,9 @@ public record EntityGoalWolfBeg(
return null;
}
try {
return new EntityGoalWolfBeg(
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

View File

@@ -37,18 +37,9 @@ public record TargetGoalHurtBy(
return null;
}
try {
return new TargetGoalHurtBy(
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

View File

@@ -30,6 +30,8 @@ public record TargetGoalNearestAttackable(
@NotNull Predicate<LivingEntity> targetFilter
) implements TargetGoal<Raider> {
/**
* Create a new target goal.
*
* @param target The type of entities to attack.
* @param checkVisibility If visibility should be checked.
* @param checkCanNavigate If navigation should be checked.
@@ -63,7 +65,6 @@ public record TargetGoalNearestAttackable(
return null;
}
try {
if (config.has("targetFilter")) {
TestableEntity filter = Entities.lookup(config.getString("targetFilter"));
@@ -82,14 +83,6 @@ public record TargetGoalNearestAttackable(
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;
}
}
@NotNull

View File

@@ -30,6 +30,8 @@ public record TargetGoalNearestAttackableWitch(
@NotNull Predicate<LivingEntity> targetFilter
) implements TargetGoal<Raider> {
/**
* Create a new target goal.
*
* @param target The type of entities to attack.
* @param checkVisibility If visibility should be checked.
* @param checkCanNavigate If navigation should be checked.
@@ -63,7 +65,6 @@ public record TargetGoalNearestAttackableWitch(
return null;
}
try {
if (config.has("targetFilter")) {
TestableEntity filter = Entities.lookup(config.getString("targetFilter"));
@@ -82,14 +83,6 @@ public record TargetGoalNearestAttackableWitch(
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;
}
}
@NotNull

View File

@@ -26,6 +26,8 @@ public record TargetGoalNearestHealableRaider(
@NotNull Predicate<LivingEntity> targetFilter
) implements TargetGoal<Raider> {
/**
* Create a new target goal.
*
* @param target The target.
* @param checkVisibility If visibility should be checked.
*/
@@ -53,7 +55,6 @@ public record TargetGoalNearestHealableRaider(
return null;
}
try {
if (config.has("targetFilter")) {
TestableEntity filter = Entities.lookup(config.getString("targetFilter"));
@@ -68,14 +69,6 @@ public record TargetGoalNearestHealableRaider(
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;
}
}
@NotNull

View File

@@ -26,6 +26,8 @@ public record TargetGoalNonTameRandom(
@NotNull Predicate<LivingEntity> targetFilter
) implements TargetGoal<Tameable> {
/**
* Create a new target goal.
*
* @param target The types of entities to heal.
* @param checkVisibility If visibility should be checked.
*/
@@ -53,7 +55,6 @@ public record TargetGoalNonTameRandom(
return null;
}
try {
if (config.has("targetFilter")) {
TestableEntity filter = Entities.lookup(config.getString("targetFilter"));
@@ -68,14 +69,6 @@ public record TargetGoalNonTameRandom(
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;
}
}
@NotNull

View File

@@ -36,18 +36,9 @@ public record TargetGoalResetUniversalAnger(
return null;
}
try {
return new TargetGoalResetUniversalAnger(
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

View File

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

View File

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

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core.events;
import com.willfp.eco.core.packet.PacketListener;
import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull;
@@ -25,4 +26,11 @@ public interface EventManager {
* Unregister all listeners associated with the plugin.
*/
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
public File getDataFolder() {
public @NotNull File getDataFolder() {
return this.plugin.getDataFolder();
}
@Override
public ConfigHandler getConfigHandler() {
public @NotNull ConfigHandler getConfigHandler() {
return this.plugin.getConfigHandler();
}
@Override
public Logger getLogger() {
public @NotNull Logger 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.
*

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

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

View File

@@ -1,7 +1,10 @@
package com.willfp.eco.core.extensions;
import com.willfp.eco.core.version.Version;
import org.jetbrains.annotations.NotNull;
import java.io.File;
/**
* The extension's metadata.
* <p>
@@ -12,7 +15,24 @@ import org.jetbrains.annotations.NotNull;
* @param author The extension's author.
*/
public record ExtensionMetadata(@NotNull String version,
@NotNull String name,
@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.
* Invalid filetype.
*/
public class MalformedExtensionException extends RuntimeException {
public class MalformedExtensionException extends ExtensionLoadException {
/**
* Create a new MalformedExtensionException.
*

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