Compare commits

..

513 Commits

Author SHA1 Message Date
Auxilor
69a5fa81b4 Updated MythicMobs 2022-03-16 20:48:42 +00:00
Auxilor
0316e627e1 Updated to 6.29.0 2022-03-16 13:22:17 +00:00
Auxilor
5bc5b47bf8 Added Menu#refresh 2022-03-16 13:22:05 +00:00
Auxilor
a9c906843d Updated to 6.28.3 2022-03-13 16:59:14 +00:00
Auxilor
85861971d3 Added wildcard material testable items 2022-03-13 16:59:02 +00:00
Auxilor
bdb24e5a14 Updated to 6.28.2 2022-03-12 21:03:59 +00:00
Auxilor
cb481d4532 Fixed 1.17.1 and 1.18.1 errors 2022-03-12 21:03:45 +00:00
Auxilor
97fba3e243 Updated to 6.28.1 2022-03-11 16:29:15 +00:00
Auxilor
e47c6387a2 Injecting placeholders now clears config cache 2022-03-11 16:29:05 +00:00
Auxilor
00df39097c Fixed statics in expressions 2022-03-11 16:28:21 +00:00
Auxilor
efcb406e9a Revert "Updated to 6.28.1"
This reverts commit 9e92ea6062.
2022-03-11 10:52:36 +00:00
Auxilor
9e92ea6062 Updated to 6.28.1 2022-03-11 10:41:43 +00:00
Auxilor
9dbc25df6f Added PlaceholderInjectable#clearInjectedPlaceholders 2022-03-11 09:01:57 +00:00
Auxilor
bc85c5232e Fixed more placeholder injection stuff 2022-03-11 09:00:24 +00:00
Auxilor
2f4783f13e Fixed placeholder equality 2022-03-11 08:58:58 +00:00
Auxilor
614241a058 Fixed placeholder injection on config wrappers 2022-03-11 08:47:50 +00:00
Auxilor
c541adb557 Improved PlaceholderInjectable 2022-03-10 20:42:06 +00:00
Auxilor
a484eecc8f Reworked placeholder system 2022-03-10 20:38:09 +00:00
Auxilor
3933e38891 Updated to 6.28.0 2022-03-10 19:54:58 +00:00
Auxilor
1d5345b367 Merge remote-tracking branch 'origin/master' into develop
# Conflicts:
#	gradle.properties
2022-03-10 19:54:25 +00:00
Auxilor
f8513ff1e9 Updated to 6.27.4 2022-03-09 11:21:14 +00:00
Auxilor
ca9c940b2b Updated/fixed crunch 2022-03-09 11:20:54 +00:00
Auxilor
af198d30f7 Updated to 6.27.3 2022-03-08 08:25:45 +00:00
Auxilor
637b239c66 Fixed MiniMessage on 1.18.2 2022-03-08 08:25:25 +00:00
Auxilor
124c059294 Fixed MiniMessage on 1.18.2 2022-03-07 12:32:52 +00:00
Auxilor
f1d0bd901d Updated to 6.28.0 2022-03-07 12:29:02 +00:00
Auxilor
20f4bf4e78 Improved shapeless recipe support 2022-03-07 12:27:21 +00:00
Auxilor
595bc76294 Added shapeless recipe support 2022-03-07 11:32:18 +00:00
Auxilor
9a66e78dcd Merge remote-tracking branch 'origin/master' 2022-03-07 10:29:15 +00:00
Auxilor
0fcf229bfb Fixed missing javadoc jar 2022-03-07 10:28:59 +00:00
Will FP
d2ffc43b17 Update README.md 2022-03-07 10:25:50 +00:00
Auxilor
c50f69b372 Fixed javadoc 2022-03-07 10:16:52 +00:00
Will FP
f5eafafc4c Update README.md 2022-03-06 15:50:39 +00:00
Auxilor
39372c9b1a Updated to 6.27.2 2022-03-06 13:59:51 +00:00
Auxilor
4c64f03aa1 Fixed isCustomItem 2022-03-06 13:59:42 +00:00
Auxilor
6bb4e301bc Merge remote-tracking branch 'origin/master' 2022-03-05 12:59:51 +00:00
Auxilor
827e9fd98a Cleanup 2022-03-05 12:56:32 +00:00
Auxilor
c3e9bbbc50 Updated to 6.27.1 2022-03-05 12:53:43 +00:00
Auxilor
7328881977 Cleaned up MythicMobs drop support PR 2022-03-05 12:53:11 +00:00
Auxilor
00531d0a04 Merge branch '0ft3n_master' into develop 2022-03-05 12:39:44 +00:00
Auxilor
5d4a2b4633 Updated guava 2022-03-05 12:37:33 +00:00
Auxilor
28c86460fc Merge remote-tracking branch 'origin/master' into develop 2022-03-05 12:37:27 +00:00
Will FP
4a1d714b71 Merge pull request #101
Bump guava from 31.0.1-jre to 31.1-jre
2022-03-05 12:37:02 +00:00
Will FP
4ef16530d3 Merge pull request #106
Bump io.papermc.paperweight.userdev from 1.3.4 to 1.3.5
2022-03-05 12:36:47 +00:00
Auxilor
a22ad1b22d Optimized custom item cache 2022-03-05 12:34:39 +00:00
dependabot[bot]
623c3589a3 Bump io.papermc.paperweight.userdev from 1.3.4 to 1.3.5
Bumps [io.papermc.paperweight.userdev](https://github.com/PaperMC/paperweight) from 1.3.4 to 1.3.5.
- [Release notes](https://github.com/PaperMC/paperweight/releases)
- [Commits](https://github.com/PaperMC/paperweight/compare/v1.3.4...v1.3.5)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-04 21:21:12 +00:00
Auxilor
44924cdf83 MiniMessage safety checks 2022-03-04 11:00:36 +00:00
Auxilor
75363181e4 MiniMessage is an endless source of suffering 2022-03-04 10:56:27 +00:00
Auxilor
1fc9d66457 Even more minimessage pain 2022-03-04 10:50:02 +00:00
Auxilor
2fdbe0da28 More minimessage pain 2022-03-04 10:40:56 +00:00
Auxilor
a1922cb195 MiniMessage pain 2022-03-04 10:36:35 +00:00
Auxilor
725e950092 Updated MiniMessage and adventure-platform 2022-03-04 09:21:44 +00:00
Auxilor
bf123d3105 Fixed init order bug 2022-03-04 09:16:30 +00:00
dependabot[bot]
83b6721484 Bump guava from 31.0.1-jre to 31.1-jre
Bumps [guava](https://github.com/google/guava) from 31.0.1-jre to 31.1-jre.
- [Release notes](https://github.com/google/guava/releases)
- [Commits](https://github.com/google/guava/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-04 09:13:02 +00:00
Auxilor
dca952c10a Fixed deprecated adventure api usage 2022-03-04 09:11:10 +00:00
Auxilor
b2e5896885 Updated MiniMessage 2022-03-04 09:08:48 +00:00
Auxilor
38542dad5e Added utility methods to EntityGoals and TargetGoals 2022-03-04 09:07:21 +00:00
Auxilor
852a9c5fb1 Updated v1_18_R2 module, updated adventure 2022-03-04 09:02:12 +00:00
Auxilor
12aa0e349e Updated paper to 1.18.2 2022-03-04 08:53:09 +00:00
Auxilor
351f5d8c16 Updated KingdomsX 2022-03-03 17:29:43 +00:00
Auxilor
7e4b3075ed Added maxmimum size to recipes cache 2022-03-03 14:52:29 +00:00
Auxilor
cf0d725189 Improved removing entity goals 2022-03-03 14:50:26 +00:00
Auxilor
a9f33fb846 Refactoring delegated spellcasters 2022-03-03 14:19:18 +00:00
Auxilor
4a9ab7a0eb Added EntityGoalIllusionerBlindnessSpell and EntityGoalIllusionerMirrorSpell 2022-03-03 14:16:25 +00:00
Auxilor
3982ab99a6 Added some entity goals 2022-03-03 13:32:26 +00:00
Auxilor
1fb39e55d2 Removed redundant suppression 2022-03-03 11:58:25 +00:00
Auxilor
56d32b532d Move improvements to CustomGoal 2022-03-03 10:12:02 +00:00
Auxilor
0d0800dfb5 Improved CustomGoal 2022-03-03 10:07:40 +00:00
Auxilor
f32110687f Added missing nullability parameter 2022-03-03 09:47:36 +00:00
Auxilor
dbf39f3621 Added more helpful utility methods 2022-03-03 09:46:14 +00:00
Auxilor
9a2f0e3df8 Switched from com.willfp.libs.shaded to com.willfp.eco.libs 2022-03-03 08:31:47 +00:00
Auxilor
56fb9b40b9 Added Goal<T>, which EntityGoal<T> and TargetGoal<T> extend from, giving them a shared parent class 2022-03-02 20:17:06 +00:00
Auxilor
fbc7bb6f07 Tempt now uses TestableItem 2022-03-02 19:12:59 +00:00
Auxilor
2294c3758d Fixed ItemStack.mergeIfNeeded 2022-03-02 18:52:12 +00:00
Auxilor
c573da6e31 Suppressed warning 2022-03-02 18:51:07 +00:00
Auxilor
6362931e6b Stopped using percentages in goals 2022-03-02 18:48:44 +00:00
Auxilor
0be1f45edc Fixed refactoring bugs 2022-03-02 18:45:34 +00:00
Auxilor
9700aa7eac Added secondary constructors without predicates 2022-03-02 18:39:32 +00:00
Auxilor
75eaf58aa2 NMS Refactoring 2022-03-02 18:29:11 +00:00
Auxilor
63352989b1 Switched interact and hurt_by to use TestableEntity 2022-03-02 18:05:03 +00:00
Auxilor
dd5e0e3847 Switched class-based entity restrictions to TestableEntity where possible 2022-03-02 17:52:00 +00:00
Auxilor
4f009c6d57 EntityGoalAvoidEntity now functions using TestableEntity 2022-03-02 17:45:40 +00:00
Auxilor
09d4db816e Renaming goals, second pass 2022-03-02 16:22:18 +00:00
Auxilor
fb7799e931 Renaming goals, first pass 2022-03-02 16:01:16 +00:00
Auxilor
13a1965f03 Added EntityController#clearAllGoals 2022-03-02 15:06:53 +00:00
Auxilor
3abefb73f9 Added deserializers for all entity goals 2022-03-02 14:38:46 +00:00
Auxilor
a35f5bb405 Added deserializers for all target goals 2022-03-02 14:13:49 +00:00
Auxilor
88a7fb53a3 Added ConfigSerializer, ConfigDeserializer, made Testable extend Predicate 2022-03-02 13:48:05 +00:00
Auxilor
866ba8440d Refactored EntityController.of to EntityController.getFor 2022-03-02 13:10:39 +00:00
Auxilor
61896bbddd Commons refactoring 2022-03-02 12:53:21 +00:00
Auxilor
7a4891d4e3 Fixed refactoring bugs 2022-03-02 12:48:13 +00:00
Auxilor
dbd5cd341e Moved FastItemStack into commons 2022-03-02 12:42:41 +00:00
Auxilor
7df707a59d Updated goal javadoc 2022-03-02 12:33:35 +00:00
Auxilor
92dfa32d07 CustomGoal inheritance fixes 2022-03-02 12:22:37 +00:00
Auxilor
5cad1d31e3 Added v1_18_R2 Module (to be updated when papermc updates) 2022-03-02 12:18:41 +00:00
Auxilor
e4c0418fd4 Removed requirement system 2022-03-02 12:14:21 +00:00
Auxilor
54c74d0138 Added more goals, added shorthand goal syntax, added kotlin extension for entity controllers 2022-03-02 12:14:03 +00:00
Auxilor
6e21bdeb5b Updated/Added some goals 2022-03-02 12:03:28 +00:00
Auxilor
00439a1b04 Began refactoring NMS 2022-03-02 11:52:49 +00:00
Auxilor
87684abbbb Fixed NMS buildscripts some more 2022-03-02 11:28:16 +00:00
Auxilor
0cbf78733e Changed NMS Commons relocation 2022-03-02 11:24:37 +00:00
Auxilor
ecf0e7c356 NMS Buildscript changes 2022-03-02 11:22:49 +00:00
Auxilor
f20d9884b5 NMS Commons changes 2022-03-02 11:18:55 +00:00
Auxilor
61d713ad4d Moved NMS AI implementations into craftbukkit-less commons 2022-03-02 11:15:44 +00:00
Auxilor
ca5cce3f40 Fixed shadow relocations 2022-03-01 22:28:33 +00:00
Auxilor
1c8edac807 Finally fixed intersection generics 2022-03-01 22:26:47 +00:00
Auxilor
98b465f8f3 Take 3 at fixing generic issues 2022-03-01 22:20:12 +00:00
Auxilor
3c3e34eda3 Take 2 at fixing generic issues 2022-03-01 22:16:09 +00:00
Auxilor
02ad6f7810 Fixed issues with generics 2022-03-01 22:14:25 +00:00
Auxilor
5369ee7d42 Improved CustomGoal 2022-03-01 22:06:39 +00:00
Auxilor
c441e0761f Updated to 6.27.0 2022-03-01 21:10:42 +00:00
Auxilor
a02dd06c20 Added entity goals in for 1_18_R1, minor refactoring 2022-03-01 21:10:02 +00:00
Auxilor
957af5c5bf Continued work on entity controllers 2022-03-01 21:01:00 +00:00
Auxilor
2c51a6900f Added remaining entity goals 2022-03-01 20:40:45 +00:00
Auxilor
e09e9b4e8d Added more entity goals 2022-03-01 20:20:02 +00:00
Auxilor
02497d485b Added more entity goals 2022-03-01 20:04:04 +00:00
Auxilor
bd32f3bc8d Continued implementing entity goals 2022-03-01 19:58:05 +00:00
Auxilor
7176342e15 Continued goal implementation 2022-03-01 19:44:27 +00:00
Auxilor
32ef8d8c5c Began entity controller system 2022-03-01 18:04:27 +00:00
Auxilor
92f8787eb9 Updated to 6.26.3 2022-03-01 13:03:56 +00:00
Auxilor
5403f7a9ed Fixed multiple option display 2022-03-01 11:29:51 +00:00
Auxilor
2924d6f560 All options are now shown to players in crafting 2022-03-01 11:22:31 +00:00
Auxilor
36c0708c17 (Narrator voice) It wasn't 2022-03-01 10:56:54 +00:00
Auxilor
b9fe54e883 This isn't going to be the last commit, is it 2022-03-01 10:49:09 +00:00
Auxilor
5cc2f23547 Removed debug messages 2022-03-01 10:40:07 +00:00
Auxilor
30514ba780 Suffering 2022-03-01 10:39:24 +00:00
Auxilor
02e6c5e8f3 More working around how broken spigot is 2022-03-01 10:35:49 +00:00
Auxilor
fac97329aa Working around how broken spigot is 2022-03-01 10:31:19 +00:00
Auxilor
cdf5cc3abe Suppressed warnings 2022-03-01 10:25:43 +00:00
Auxilor
4cb630d201 Fixed crafting, deprecated now-unneeded API 2022-03-01 10:24:38 +00:00
Auxilor
79d6277d94 Updated to 6.26.2 2022-03-01 08:33:24 +00:00
Auxilor
1a90fa6707 Fixed ComplexInEco 2022-03-01 08:33:14 +00:00
Auxilor
6ecbb2d901 Updated to 6.26.1 2022-02-28 20:54:01 +00:00
Auxilor
3373901b95 Fixed recipe groups not working 2022-02-28 20:53:50 +00:00
Auxilor
7eb1b917dc Moved supported versions into ProxyConstants 2022-02-28 20:15:40 +00:00
Auxilor
fdba12082c Refactoring 2022-02-28 20:12:15 +00:00
Auxilor
516ecc1c3d Lookup cleanup 2022-02-28 20:10:53 +00:00
Auxilor
cfd545c735 Added ScheduledForRemoval inVersion 2022-02-28 20:04:02 +00:00
Auxilor
0ded1fe68b DummyEntity changes 2022-02-28 20:02:58 +00:00
Auxilor
4fce11b149 Fixed name and equipment arg parsers 2022-02-28 19:29:53 +00:00
Auxilor
2374e8fe03 Merge remote-tracking branch 'origin/develop' into develop 2022-02-28 18:52:18 +00:00
Auxilor
36ccf346d7 Codestyle 2022-02-28 18:51:49 +00:00
Auxilor
cb480bd88d Removed requirements from the backend, added warnings in static intializers. 2022-02-28 18:51:07 +00:00
Auxilor
8cc96cb30e Added StringUtils#toNiceString 2022-02-28 16:04:02 +00:00
Auxilor
736ba0f8b0 Janky CombatLogX fix 2022-02-28 15:55:21 +00:00
Auxilor
5b5fefee8e Fixed StringUtils#splitAround 2022-02-28 15:34:56 +00:00
Auxilor
8941e3179b Minor changes 2022-02-28 15:26:40 +00:00
Auxilor
19ce4c56a9 Fixed tests 2022-02-28 14:24:10 +00:00
Auxilor
337c5d2b84 Fixed missing lib jar 2022-02-28 14:17:24 +00:00
Auxilor
631c17aedc Build changes 2022-02-28 14:16:39 +00:00
Auxilor
0ff4ac92be Fixed SCore dependency 2022-02-28 14:15:01 +00:00
Auxilor
aa94094078 Moved SCore to jitpac 2022-02-28 14:11:45 +00:00
Auxilor
135ddcf331 Fixed ExecutableItems dependencies 2022-02-28 14:07:45 +00:00
Auxilor
e5d31e0b49 Updated to 6.26.0 2022-02-28 13:56:16 +00:00
Auxilor
448b2e4b3f Switched entity lookup off to new system 2022-02-28 13:53:44 +00:00
Auxilor
ebb30e3a70 Began rewriting lookups to reusable system 2022-02-28 13:18:58 +00:00
Auxilor
fb89415636 Dummy entities are now instances of the DummyEntityDelegate class 2022-02-28 12:17:33 +00:00
0ft3n
d0d64b3e58 Merge branch 'Auxilor:master' into master 2022-02-23 11:43:39 +03:00
often
49273abbfc Added Items lookup system support to mythicmobs drops 2022-02-23 11:32:46 +03:00
Auxilor
36c77d81eb Fixed included modules 2022-02-19 18:33:16 +00:00
Auxilor
b6cd56ad15 Fixed supported versions 2022-02-19 18:33:04 +00:00
Auxilor
1a524aea94 Updated to 6.25.2 2022-02-19 18:32:29 +00:00
Auxilor
2ebab99a06 Removed support for 1.16.5 2022-02-19 18:31:36 +00:00
Auxilor
46663f7edb Merge branch 'master' into develop 2022-02-19 18:29:18 +00:00
Will FP
4fad66cd90 Update README.md 2022-02-19 18:26:37 +00:00
Auxilor
a9fafeec00 Lightened cache on MySQL 2022-02-19 11:51:05 +00:00
Auxilor
0d8308d6cd Updated dependencies 2022-02-19 11:48:38 +00:00
Auxilor
13772002e8 Updated to 6.25.1 2022-02-17 17:03:16 +00:00
Auxilor
c9b84889e7 Fixed recursive caching bug 2022-02-17 17:03:10 +00:00
Auxilor
1513578266 Fixed recursive caching bug 2022-02-17 17:01:42 +00:00
Auxilor
89d6f2f867 Fixed initialization order 2022-02-17 12:53:54 +00:00
Auxilor
8e6d98c997 More MySQL Changes 2022-02-17 12:51:43 +00:00
Auxilor
5bc2cb31a4 Switched expiry from write to access (MySQL) 2022-02-17 12:47:59 +00:00
Auxilor
041575a103 Cached rows and columns with Caffeine 2022-02-17 12:47:32 +00:00
Auxilor
c88dac56b7 Added ability to manually categorize keys to improve performance 2022-02-17 12:21:26 +00:00
Auxilor
00da717f6d Changed key serialization 2022-02-17 11:49:26 +00:00
Auxilor
cc557378cc Preloaded known data keys 2022-02-16 18:16:09 +00:00
Auxilor
b5c49c79b8 Improvements to key saving 2022-02-16 18:13:04 +00:00
Auxilor
28018430e7 Categorized keys are now saved completely serialized 2022-02-16 18:01:41 +00:00
Auxilor
7b6c8d68a8 Key registration changes 2022-02-16 17:38:07 +00:00
Auxilor
ad3cb3a620 Fixed postInit 2022-02-16 16:48:40 +00:00
Auxilor
511a7e4830 Added optimisations to lazy column creation 2022-02-16 16:42:47 +00:00
Auxilor
5aeeafc041 MySQL Data Changes: Keys are now registered on first read/write 2022-02-16 16:32:38 +00:00
Auxilor
9a51fb8358 Updated to 6.25.0 2022-02-16 16:11:31 +00:00
Auxilor
eeefb9f40e Server persistence changes 2022-02-16 16:01:55 +00:00
Auxilor
aa1ce34cbc Updated to 6.24.4 2022-02-16 14:21:49 +00:00
Auxilor
47772c3ff7 Reverted Shaped Recipe changes 2022-02-16 14:21:03 +00:00
Auxilor
dfcac5d527 PR Changes 2022-02-14 13:28:37 +00:00
Auxilor
40f88f0b59 Revert "refactor(nms): Change checking if value is initialized to a lazy val"
This reverts commit 6361c0e8e9.
2022-02-14 13:28:25 +00:00
Auxilor
105355d967 Updated to 6.24.3 2022-02-14 13:15:55 +00:00
Will FP
3cddff22b8 Merge pull request #73
Bump com.github.johnrengelman.shadow from 7.1.0 to 7.1.2
2022-02-14 13:15:39 +00:00
Will FP
f8e930d29e Merge pull request #91
Update ShapedRecipeListener.kt
2022-02-14 13:15:28 +00:00
Will FP
9dbe088e66 Merge pull request #92
refactor(nms): Change checking if value is initialized to a lazy val
2022-02-14 13:15:17 +00:00
Racci
6361c0e8e9 refactor(nms): Change checking if value is initialized to a lazy val 2022-02-14 17:32:12 +11:00
casper
1135672241 Update ShapedRecipeListener.kt
| ShapedRecipeListener.kt Modified to change matrix at the end of the crafting to prevent duplication of items
2022-02-13 12:55:05 -05:00
Auxilor
80891e4a81 Fixed profile saveAll not working 2022-02-11 10:14:33 +00:00
Auxilor
3e0be3a629 Updated to 6.24.2 2022-02-09 15:20:30 +00:00
Auxilor
17819de2ea Fixed adult/baby parsers 2022-02-09 15:20:21 +00:00
Auxilor
209cdd6b0d Updated to 6.24.1 2022-02-05 17:05:29 +00:00
Auxilor
fbf6b2edd9 Added equipment arg parser 2022-02-05 17:05:18 +00:00
dependabot[bot]
8b9e8589a0 Bump com.github.johnrengelman.shadow from 7.1.0 to 7.1.2
Bumps com.github.johnrengelman.shadow from 7.1.0 to 7.1.2.

---
updated-dependencies:
- dependency-name: com.github.johnrengelman.shadow
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-03 18:54:34 +00:00
Auxilor
525cc019ea Updated kotlin gradle plugin 2022-02-03 18:53:19 +00:00
Auxilor
04f2d15783 Fixed missing compileKotlin options 2022-02-03 18:46:36 +00:00
Auxilor
f988b591a4 Updated kotlin 2022-02-03 18:42:53 +00:00
Auxilor
9ebfb124c8 Refactored build logic 2022-02-03 18:42:01 +00:00
Auxilor
b9ab263f67 Updated CONTRIBUTING.md 2022-02-03 17:54:44 +00:00
Auxilor
bb5f68283b Updated empty (default) EcoPlugin constructor 2022-02-03 17:51:54 +00:00
Auxilor
9bbf1cfe36 Added EcoPlugin#mutateProps 2022-02-03 17:49:26 +00:00
Auxilor
19bb5f608c Updated more javadoc 2022-02-03 17:46:31 +00:00
Auxilor
a1c70d2081 Corrected PluginProps javadoc 2022-02-03 17:43:40 +00:00
Auxilor
979ddf0ff0 Safety checks to FastItemStack 2022-02-03 17:41:45 +00:00
Auxilor
232a63c00d Cleaned up FillerMask 2022-02-03 17:22:46 +00:00
Auxilor
e65cf9be2c Added extra methods to Items 2022-02-03 17:17:01 +00:00
Auxilor
fbf56037d4 Deprecated MaskMaterials in favour of MaskItems 2022-02-03 16:54:52 +00:00
Auxilor
aa0c4ee7fa Refactored props name 2022-02-03 16:08:18 +00:00
Auxilor
5f3375bf87 Added props validation 2022-02-03 15:11:15 +00:00
Auxilor
11dc6d0e67 Allowed custom props parameter 2022-02-03 15:06:35 +00:00
Auxilor
9cccbd10ba Removed need to reflectively instantiate props 2022-02-03 15:02:45 +00:00
Auxilor
1f0ad48480 Updated props javadoc 2022-02-03 14:58:12 +00:00
Auxilor
93322dcfa5 Updated props javadoc 2022-02-03 14:56:29 +00:00
Auxilor
e3b630fcb7 Improved props system 2022-02-03 14:54:43 +00:00
Auxilor
8690b75f4c Added namespacedKeyOf 2022-02-03 14:19:59 +00:00
Auxilor
6de792f308 Added more durability utils 2022-02-03 14:17:41 +00:00
Auxilor
e59037635e Removed debug from eco.yml 2022-02-03 13:52:48 +00:00
Auxilor
b9d50e261d Fixed missing javadoc 2022-02-03 13:44:15 +00:00
Auxilor
15173c8369 Finally added eco.yml 2022-02-03 13:38:14 +00:00
Auxilor
4ee0645a4e Codestyle 2022-02-03 12:57:29 +00:00
Auxilor
96bd53c089 Codestyle 2022-02-03 12:36:49 +00:00
Auxilor
e658bf3fa8 Removed redundant suppression 2022-02-03 12:36:14 +00:00
Auxilor
988836b5b9 Deprecated UnsupportedVersionException in favour of UnsupportedVersionError 2022-02-03 12:32:46 +00:00
Auxilor
5688f41b8b Fixed deprecation 2022-02-03 12:27:47 +00:00
Auxilor
4eaa6ab75c Fixed build issue 2022-02-03 12:25:39 +00:00
Auxilor
b29363cdf6 Fixed javadoc 2022-02-03 12:22:05 +00:00
Auxilor
c8648a92f5 Resolved PlayerUtils ambiguity in kotlin 2022-02-03 12:10:29 +00:00
Auxilor
0a59b6a208 ProxyFactory error changes 2022-02-03 12:06:00 +00:00
Auxilor
4e18a0ab78 Updated proxy errors 2022-02-03 12:05:22 +00:00
Auxilor
d49405f839 Updated create2DList method signature 2022-02-03 11:47:26 +00:00
Auxilor
e10566da66 Deprecated TeamUtils#getMaterialColorTeam 2022-02-03 11:45:56 +00:00
Auxilor
0c64cd98e0 Updated to 6.24.0 2022-02-03 11:43:47 +00:00
Auxilor
231af30c61 Deprecated + Marked requirement system for removal 2022-02-03 11:41:58 +00:00
Auxilor
9b5cc1fd9c Added more kotlin utilities 2022-02-03 11:23:07 +00:00
Auxilor
7628c0bbfd Renamed FastItemStack methods 2022-02-03 11:17:29 +00:00
Auxilor
0beedc6b07 Updated kotlin to use kotlin API 2022-02-03 11:09:36 +00:00
Auxilor
f3c69f1c15 Added NumberUtils extensions 2022-02-03 11:08:20 +00:00
Auxilor
a148f667e5 Added kotlin builder for commands and PlayerUtils#runExempted 2022-02-03 11:07:04 +00:00
Auxilor
b2370b4b6e Player only commands now can have non-player only subcommands 2022-02-03 10:41:24 +00:00
Auxilor
525bd5264a Removed checkstyle suppressions 2022-02-03 10:34:43 +00:00
Auxilor
54c27a0379 More CI changes 2022-02-03 10:30:22 +00:00
Auxilor
989dda0a4f Updated CI workflows 2022-02-03 10:25:38 +00:00
Auxilor
1f2bb3341e Suppression 2022-02-02 16:54:09 +00:00
Auxilor
65221bdddf Deprecated SlotModifier, replaced with SlotUpdater 2022-02-02 16:52:52 +00:00
Auxilor
b386f2df1b Updated CONTRIBUTING.md 2022-02-02 16:38:05 +00:00
Auxilor
969329486d Reverted publication changes 2022-02-02 16:00:01 +00:00
Auxilor
aab2e8237c Gave up trying to have separate java and kotlin modules 2022-02-02 15:57:45 +00:00
Auxilor
30457c29a1 Gave up trying to have separate java and kotlin modules 2022-02-02 15:57:37 +00:00
Auxilor
9ad480ecf0 Shadow publication attempt 1 2022-02-02 15:50:43 +00:00
Auxilor
b0d3256d1b Fixed conflicting jvm names 2022-02-02 14:23:51 +00:00
Auxilor
4ff9d82cc1 Added kotlin builders for GUIs 2022-02-02 13:21:28 +00:00
Auxilor
f9178e248b Updated paperweight userdev 2022-02-02 12:47:56 +00:00
Auxilor
cc8a799438 Added log-full-extension-errors 2022-02-02 12:46:49 +00:00
Auxilor
90b81f56df Codestyle 2022-02-02 12:43:55 +00:00
Auxilor
1240c14c14 Added kotlin extensions 2022-02-02 12:42:38 +00:00
Auxilor
ed46900f2f Re-added NMS Modules after build checks 2022-02-02 12:20:33 +00:00
Auxilor
dade3d7fbb Fixed build.gradle in eco-api 2022-02-02 12:16:39 +00:00
Auxilor
df141875d3 Updated CI workflows 2022-02-02 12:15:34 +00:00
Auxilor
50b07de5d1 Updated CI workflows 2022-02-02 12:13:58 +00:00
Auxilor
e2a033c24f Dev changes 2022-02-02 12:13:36 +00:00
Auxilor
3fa574105f Hopefully resolved circular dependencies 2022-02-02 11:40:39 +00:00
Auxilor
a64386f980 Hopefully resolved circular dependencies 2022-02-02 11:40:03 +00:00
Auxilor
4c5a0f9887 Even more buildscript changes 2022-02-02 11:31:21 +00:00
Auxilor
cbd43f5757 More buildscript changes 2022-02-02 11:24:33 +00:00
Auxilor
01f1425557 buildscript changes 2022-02-02 11:24:12 +00:00
Auxilor
25e8cc0837 Refactored API, added kotlin extensions 2022-02-02 11:22:19 +00:00
Auxilor
7ff3eeef06 Updated to 6.22.3 2022-02-01 19:09:24 +00:00
Auxilor
58faf6de23 Fixed more server profile issues 2022-02-01 19:09:10 +00:00
Auxilor
7f42cbe32e Updated to 6.22.2 2022-02-01 18:55:18 +00:00
Auxilor
ae12ab17fe Fixed server profile 2022-02-01 18:55:07 +00:00
Auxilor
9949ed4f5f Updated to 6.22.1 2022-02-01 18:16:47 +00:00
Auxilor
e3f81a51e8 Revert "Fixed WorldGuard antigrief integration"
This reverts commit feebbd8ec7.
2022-02-01 18:16:27 +00:00
Auxilor
a06d782dea Cleaned up StringUtils 2022-02-01 14:12:03 +00:00
Auxilor
7e60ee63ea Merge branch '0ft3n_master' into develop 2022-02-01 14:04:50 +00:00
Auxilor
e349f47e66 Swapped out guava cache for caffeine 2022-02-01 14:04:00 +00:00
Auxilor
f710a69455 Changed cache expiry times 2022-02-01 13:49:35 +00:00
Auxilor
20b06be1f2 Changed item cache off to guava 2022-02-01 13:24:36 +00:00
Auxilor
9992820580 Items changes 2022-02-01 13:17:52 +00:00
0ft3n
feebbd8ec7 Fixed WorldGuard antigrief integration 2022-02-01 15:26:40 +03:00
Auxilor
5302aa07a5 Un-did thing? 2022-02-01 11:19:23 +00:00
Auxilor
d124c5b274 Fixed build issues 2022-02-01 11:08:08 +00:00
Auxilor
f188919197 Fixed wrong suppression 2022-02-01 11:04:24 +00:00
Auxilor
388268e906 Minor changes 2022-02-01 11:03:02 +00:00
Auxilor
6367867d2b Suppressed warnings 2022-02-01 11:01:36 +00:00
Auxilor
291357e235 Updated to 6.22.0 2022-02-01 10:55:13 +00:00
Auxilor
07178b0645 Added cache to string formats 2022-02-01 10:54:13 +00:00
Auxilor
70ef99e875 Added guava caches to performance-sensitive components 2022-02-01 10:44:19 +00:00
Auxilor
885a7835ea Fixed CrashClaim integration not being registered 2022-02-01 10:09:41 +00:00
Auxilor
94e9b47f02 Renaming 2022-02-01 10:08:21 +00:00
Auxilor
e8f4bdd4aa Added toString methods on profile impl 2022-02-01 10:07:25 +00:00
Auxilor
c01e409904 Added ServerProfile, internal annotations 2022-02-01 10:06:39 +00:00
Auxilor
f1cf82160e Rewrote custom recipe listener in kotlin 2022-02-01 09:46:59 +00:00
0ft3n
d1c15f8699 Merge branch 'Auxilor:master' into master 2022-01-29 20:41:22 +03:00
_OfTeN_
be6e7b1f46 Added RPGHorses Antigrief integration
Fixed CustoMCrafting compatibility

Updated CustomCrafting Items lookup integration

Added a warning for empty recipes
2022-01-29 00:25:13 +03:00
Auxilor
b78fc2fb66 Suppressed warning 2022-01-28 09:30:57 +00:00
Auxilor
23a297b8e3 Updated to 6.21.1 2022-01-28 09:15:39 +00:00
Auxilor
4e99ca51f0 PR Codestyle 2022-01-28 09:15:16 +00:00
NicoNekoDev
47c93a6dbe Fix strange imports 2022-01-28 01:16:28 +02:00
NicoNekoDev
da7f47d1ba Fix getCustomItem lookup system for better performance 2022-01-28 01:14:55 +02:00
_OfTeN_
144ea0dd10 Added silent arg parser for entities 2022-01-27 16:51:39 +03:00
Auxilor
732aaa3bf1 Fixed NamespacedKeyUtils.fromString 2022-01-27 13:23:25 +00:00
Auxilor
a38387be33 Fixed more stupidity 2022-01-27 13:16:42 +00:00
Auxilor
582f9b08f3 Fixed stupidity 2022-01-27 13:15:19 +00:00
Auxilor
638367cbb2 Switched objenesis instantiator 2022-01-27 13:08:59 +00:00
Auxilor
ec35e7d779 Fixed lateinit issues 2022-01-27 13:04:33 +00:00
Auxilor
1cc2a585d6 NamespacedKey changes 2022-01-27 12:51:22 +00:00
Auxilor
aa553b96d6 Updated to 6.21.0 2022-01-27 12:41:53 +00:00
Auxilor
feb7ecee48 Added fast NamespacedKey creation 2022-01-27 12:41:18 +00:00
Auxilor
c0be6a12ff Changed behaviour to not be the same as enum behaviour 2022-01-26 12:42:05 +00:00
Auxilor
1dc6b651a0 Switched PersistentDataKeyType to not be an enum 2022-01-26 12:40:15 +00:00
Auxilor
3c26c02642 Added issue template 2022-01-26 11:19:02 +00:00
Auxilor
343508f099 Updated to 6.20.4 2022-01-20 09:44:08 +00:00
Auxilor
76dc4948bc Fixed playerless placeholders 2022-01-20 09:43:53 +00:00
Auxilor
8fa209a981 Switched from shallow to deep packet cloning for async 2022-01-18 09:19:14 +00:00
Auxilor
b3a0634ad0 Updated to 6.20.3 2022-01-18 09:18:36 +00:00
Auxilor
97d7acc0a9 Tweaked async display 2022-01-18 09:18:25 +00:00
Auxilor
ebac75b0ee Updated to 6.20.2 2022-01-18 08:41:04 +00:00
Auxilor
02d0fa85b5 Updated plugin.yml 2022-01-18 08:40:53 +00:00
Auxilor
168915868c Added support for CustomCrafting and ExecutableItems 2022-01-18 08:40:38 +00:00
Auxilor
d62d598fd6 Merge branch '0ft3n_master' into develop
# Conflicts:
#	eco-core/core-plugin/src/main/kotlin/com/willfp/eco/internal/spigot/EcoSpigotPlugin.kt
2022-01-18 08:38:53 +00:00
0ft3n
06561c5387 Removed unneeded event call 2022-01-18 02:00:10 +03:00
Auxilor
c9805e91b4 Updated to 6.20.1 2022-01-17 17:09:06 +00:00
Auxilor
e3be95ca4d Added soft faliures to config updating 2022-01-17 17:08:57 +00:00
Auxilor
2e6463aed9 Fixed global placeholders 2022-01-17 11:15:18 +00:00
Auxilor
2501574eeb Updated to 6.20.0 2022-01-17 11:12:58 +00:00
Auxilor
3c237fd856 Codestyle 2022-01-17 11:12:45 +00:00
Auxilor
7b3fd1d0c2 Moved placeholders to be registered per-plugin 2022-01-17 11:11:46 +00:00
Auxilor
e599add6de Removed arg parsers that were marked for removal several versions ago 2022-01-12 16:27:43 +00:00
Auxilor
1bda970f6b Improved Items performance 2022-01-12 16:17:49 +00:00
Auxilor
eb1f694905 Added item-cache-ttl 2022-01-12 16:14:24 +00:00
Auxilor
efd3403eda Updated to 6.19.1 2022-01-12 16:02:14 +00:00
Auxilor
08b563d528 Improved Items#getCustomItem and Items#isCustomItem performance 2022-01-12 15:59:25 +00:00
Auxilor
c3f88bf7b0 Fixed updatechecker formatting 2022-01-12 11:23:01 +00:00
Auxilor
eb6d76e0c6 Updated to 6.19.0 2022-01-12 11:17:32 +00:00
Auxilor
f2d0e8c368 Merge branch 'master' into develop 2022-01-12 11:17:23 +00:00
Auxilor
5e7b9573a1 Switched try/catch blocks to runCatching in kotlin and improved async packet encoding 2022-01-12 11:17:03 +00:00
Auxilor
7d457ea496 Added more safety checks to compiled expressions 2022-01-12 08:31:45 +00:00
Auxilor
806bf9a43f Added getDouble/IntFromExpression to Config 2022-01-11 17:05:22 +00:00
Auxilor
316f134b71 NumberUtils changes 2022-01-11 16:54:32 +00:00
Auxilor
0d363b9fb6 Added error safety to CrunchHandler 2022-01-11 16:51:38 +00:00
Auxilor
2890083eaa Excluded lang3 2022-01-11 16:47:57 +00:00
Auxilor
694646431b Fixed commons lang issue 2022-01-11 16:45:30 +00:00
Auxilor
86d5e9d09e Added support for evaluating mathematical expressions via Crunch 2022-01-11 16:43:36 +00:00
Auxilor
8635e5f7a5 Updated to 6.18.5 2022-01-11 10:01:49 +00:00
Auxilor
aa718649eb Fixed v1_18_R1 remapping bugs 2022-01-11 10:01:40 +00:00
Auxilor
1dc0fa449b Updated to 6.18.4 2022-01-11 09:20:52 +00:00
Auxilor
19e3061a13 Fixed MythicMobs NPE 2022-01-11 09:20:43 +00:00
Auxilor
ecafbd76de Updated to 6.18.3 2022-01-10 11:11:44 +00:00
Auxilor
3728f2fc7a Fixed apache commons lang not existing on classpath 2022-01-10 11:11:31 +00:00
Auxilor
56c124dbd2 Updated to 6.18.2 2022-01-09 18:19:29 +00:00
Auxilor
6730697fc5 Merge branch 'develop' 2022-01-09 18:19:15 +00:00
Auxilor
c8e1c83061 Merge remote-tracking branch 'origin/master' 2022-01-09 18:19:07 +00:00
Auxilor
a9fd5a9418 Merge remote-tracking branch 'origin/develop'
# Conflicts:
#	gradle.properties
2022-01-09 18:19:00 +00:00
Auxilor
7b1179f402 Fixed string getter for multiple-in-craft 2022-01-09 18:18:44 +00:00
Auxilor
f4907329d9 Updated to 6.18.2 2022-01-07 10:38:41 +00:00
Auxilor
1e23cbaa5e Fixed SuperiorSkyblockAPI build isseus 2022-01-07 10:38:09 +00:00
Auxilor
863818d2eb Fixed NoAI arg parser 2022-01-07 10:05:00 +00:00
Auxilor
d35285d0dc More config simplification 2022-01-07 09:26:06 +00:00
Auxilor
bc92f8a444 Added destructurability to EntityArgParseResult 2022-01-07 09:24:02 +00:00
Auxilor
2fafef17d7 Simplified internal config implementations 2022-01-07 09:22:32 +00:00
Auxilor
24078a2838 Merge remote-tracking branch 'origin/develop' into develop 2022-01-07 09:01:19 +00:00
Auxilor
73d13277be Made update checker less annoyign 2022-01-06 18:34:44 +00:00
Auxilor
0e4c23d70c Fixed potential remapping bugs 2022-01-06 18:21:51 +00:00
Auxilor
ddf5094c5a Added MythicMobs softdepend 2022-01-06 16:13:36 +00:00
Auxilor
925fc56cab MythicMobs integration uses apiHelper where possible 2022-01-06 16:13:17 +00:00
Auxilor
3208d0328f Added EmptyTestableEntity (dummy entities) for failed TestableEntity lookups 2022-01-06 16:05:10 +00:00
Auxilor
317824ae78 Removed broken test 2022-01-06 15:17:06 +00:00
Auxilor
41a4b4fc1a Scheduled old java arg parsers for removal in the next release 2022-01-06 15:01:36 +00:00
Auxilor
c528e4cd42 Referencing for-removal arg parsers at all will now log an error 2022-01-06 15:00:31 +00:00
Auxilor
2724f21d4e Referencing for-removal arg parsers at all will now log an error 2022-01-06 14:59:39 +00:00
Auxilor
5cb14e31b7 Finally updated Config string getters to not be formatted by default 2022-01-06 14:51:55 +00:00
Auxilor
6b9942f412 Updated to 6.18.0 2022-01-06 14:32:46 +00:00
Auxilor
fbe88ab0fd Added MythicMobs integration 2022-01-06 14:31:02 +00:00
Auxilor
d042211dbe Added Charged and Explosion radius arg parsers, fixed size arg parser 2022-01-06 14:10:20 +00:00
Auxilor
5781df011e Added adult arg parser 2022-01-06 14:03:59 +00:00
Auxilor
c191ff0767 Added baby arg parser 2022-01-06 14:03:06 +00:00
Auxilor
b9cbcbe7a0 Added Entity lookup system, TestableEntity, CustomEntity 2022-01-06 13:55:03 +00:00
Auxilor
6009122c48 Removed underscores from name arg parsers 2022-01-06 12:11:27 +00:00
Auxilor
7536794100 Added quote support to lookup strings (for names) 2022-01-06 12:05:38 +00:00
Auxilor
e80aa5f910 Added substrings (escaped with "") to arg parsers for cleaner syntax 2022-01-06 10:46:35 +00:00
Auxilor
b4aeeac570 Added tree growth to PlayerBlockListener.kt 2022-01-05 16:22:52 +00:00
Auxilor
33515aa5f7 Updated to 6.17.7 2022-01-05 13:44:47 +00:00
Auxilor
047b535a40 Merge remote-tracking branch 'origin/master' into develop 2022-01-05 13:44:22 +00:00
Auxilor
ef8093ec7f Updated to 6.17.6 2022-01-05 13:42:24 +00:00
Auxilor
9d0f95617d Fixed CrashClaim integration 2022-01-05 13:42:14 +00:00
Auxilor
b4f3988fc7 Updated to 6.17.7 2022-01-02 17:37:34 +00:00
Auxilor
e7e1751acc Disabled CrashClaim 2022-01-02 17:37:24 +00:00
Auxilor
e68d482aa5 Disabled CrashClaim 2022-01-02 17:37:19 +00:00
often
c0547a7c34 Readded and fixed CustomItems support, added ExecutableItems support 2022-01-02 13:19:35 +03:00
Auxilor
183b18c0ec Updated to 6.17.6 2021-12-29 18:47:44 +00:00
Auxilor
e026a767d9 Fixed v1_18_R1 bugs 2021-12-29 18:47:33 +00:00
Auxilor
d2966aa428 Updated to 6.17.5 2021-12-26 17:21:21 +00:00
Auxilor
9168e68b5a StringUtils#jsonToLegacy will now fail silently 2021-12-26 17:21:01 +00:00
Auxilor
51a61b65c6 Updated to 6.17.4 2021-12-26 16:57:54 +00:00
Auxilor
76be236dac Error catching to StringUtils#jsonToLegacy 2021-12-26 16:56:53 +00:00
Auxilor
f1bbac2dd0 Codestyle 2021-12-26 16:48:03 +00:00
Auxilor
6e88aef572 FastItemStack#getLore changes 2021-12-26 16:40:09 +00:00
Auxilor
804f187964 legacy <-> json changes 2021-12-26 16:34:52 +00:00
Auxilor
623b8a18f4 Codestyle 2021-12-26 16:20:38 +00:00
Auxilor
0d4e424582 Codestyle 2021-12-26 16:19:59 +00:00
Auxilor
452e499467 Added NumberUtils#logBase 2021-12-26 16:10:33 +00:00
Auxilor
b2950ab035 Added ListUtils#containsIgnoreCase 2021-12-26 12:53:57 +00:00
Auxilor
e47d05ccb2 NMS changes 2021-12-26 12:23:13 +00:00
Auxilor
b9e61b8c0d Merged v1_18_R1 thanks to paperweight update 2021-12-26 12:17:02 +00:00
Auxilor
0f35d5d16e Updated to 6.17.3 2021-12-21 12:20:33 +00:00
Stealth2800
3a7315d728 Make defensive copy of CustomItem's returned item 2021-12-20 20:24:21 -08:00
Auxilor
6f193f70b0 Staggered player profile loading to load when needed 2021-12-15 12:26:20 +00:00
Auxilor
bab3f078f6 Added @JvmStatic mention to @ConfigUpdater 2021-12-15 11:28:07 +00:00
Auxilor
5b4b17b97f Updated to 6.17.2 2021-12-15 10:31:16 +00:00
Auxilor
f0e02ca25e Added HikariCP to plugin.yml 2021-12-15 10:31:05 +00:00
Auxilor
7426e9adba Updated to use hikari 2021-12-15 10:30:49 +00:00
Auxilor
00905aa9d5 Updated to 6.17.1 2021-12-14 19:09:50 +00:00
Auxilor
f7b57880cb Switched essentials dependency 2021-12-14 19:09:38 +00:00
Auxilor
c1b673e30c Fixed config.yml bug 2021-12-14 08:51:33 +00:00
Auxilor
4cf45795d6 Clarified forRemoval 2021-12-14 08:40:58 +00:00
Auxilor
59d31584e6 Generalized ConfigYml into LoadableConfig for custom implementations 2021-12-14 08:38:51 +00:00
Auxilor
68e1f4afac Added piston moving / retracting support to BlockUtils#isPlayerPlaced 2021-12-14 08:30:34 +00:00
Auxilor
507fad186a Improved PlayerJumpEvent on paper 2021-12-13 13:00:05 +00:00
Auxilor
ca6b3185a3 Fixed legacy configs not having 100% parity 2021-12-13 12:56:22 +00:00
Auxilor
8e96329fdc Fixed ConfigWrapper constructor access 2021-12-13 12:24:12 +00:00
Auxilor
440605f636 Re-made ConfigWrapper abstract 2021-12-13 12:24:01 +00:00
Auxilor
bb686dca17 Config refactor 2021-12-13 12:23:41 +00:00
Auxilor
e595ea2247 Marked AbstractProxy for removal 2021-12-13 12:09:58 +00:00
Auxilor
a776b60f86 Deprecated AbstractProxy 2021-12-13 12:05:49 +00:00
Auxilor
db7ac55eb2 Minor codestyle changes 2021-12-13 11:49:46 +00:00
Auxilor
52d77d7861 Added TestableItem support to ItemStackBuilder 2021-12-13 11:43:36 +00:00
Auxilor
f8ece2d6c7 @NotNull to Handler#getPlayerProfileHandler 2021-12-13 11:35:46 +00:00
Auxilor
b353b5ec04 More javadoc 2021-12-13 10:45:33 +00:00
Auxilor
bbc412e589 Added ListUtils#getOrNull 2021-12-13 10:08:46 +00:00
Auxilor
b4a474c703 Integration / Scheduling changes 2021-12-13 09:59:33 +00:00
Auxilor
75e6a3da79 Documentation and visibility changes 2021-12-13 09:54:39 +00:00
Auxilor
a1afffdbbb Added since to deprecation 2021-12-13 09:35:55 +00:00
Auxilor
f6942192de Added since to deprecation 2021-12-12 15:52:39 +00:00
Auxilor
dab26cbe95 Deprecation changes and warnings 2021-12-12 15:47:46 +00:00
Auxilor
b945a3f948 Improved deprecation javadoc 2021-12-12 15:43:25 +00:00
Auxilor
b2c1d650de Removed DeprecatedIsStillUsed suppressions 2021-12-12 14:21:23 +00:00
Auxilor
4b994d5f4c Fixed javadoc 2021-12-12 14:04:53 +00:00
Auxilor
ed2dffb52c Fixed internal use of YamlBaseConfig 2021-12-12 14:04:21 +00:00
Auxilor
20c870da06 Fixed internal use of deprecated config class 2021-12-12 14:01:28 +00:00
Auxilor
7684e431f5 Even more config parity fixes 2021-12-12 13:58:53 +00:00
Auxilor
abcc13685f Fixed config parity bugs 2021-12-12 13:55:15 +00:00
Auxilor
ac902eaa08 Overhauled config system 2021-12-12 13:44:58 +00:00
Auxilor
4e52913504 Javadoc 2021-12-12 12:47:37 +00:00
Auxilor
7505f7732f Merge remote-tracking branch 'origin/dependabot/gradle/com.github.johnrengelman.shadow-7.1.0' into develop 2021-12-12 12:43:40 +00:00
Auxilor
15fae21fd5 Merge remote-tracking branch 'origin/dependabot/gradle/com.massivecraft-Factions-1.6.9.5-2.7.0-STABLE' into develop 2021-12-12 12:43:36 +00:00
Auxilor
e9d98816ce Merge remote-tracking branch 'origin/dependabot/gradle/org.junit.jupiter-junit-jupiter-api-5.8.2' into develop
# Conflicts:
#	build.gradle.kts
2021-12-12 12:43:32 +00:00
Auxilor
675fc07ebf Merge remote-tracking branch 'origin/dependabot/gradle/org.junit.jupiter-junit-jupiter-engine-5.8.2' into develop 2021-12-12 12:43:11 +00:00
Auxilor
b8b8fd70b5 Javadoc 2021-12-12 12:42:16 +00:00
Auxilor
1d9fca1fb8 Added permissions to recipes 2021-12-12 12:38:04 +00:00
Auxilor
9b83f6eab4 Added ListUtils#toSingletonList 2021-12-12 12:17:45 +00:00
Auxilor
8190660b8f Removed redundant suppression 2021-12-12 12:14:50 +00:00
Auxilor
cbf4d111fb More dev niceties 2021-12-12 12:14:24 +00:00
Auxilor
6a139bef67 Kotlin-friendliness 2021-12-12 12:09:12 +00:00
Auxilor
9e3fecfd13 Updated to 6.17.0 2021-12-12 12:00:20 +00:00
Auxilor
3b260e2e5d Improved command system 2021-12-12 12:00:09 +00:00
Auxilor
0c0370e256 Updated to 6.16.2 2021-12-08 20:47:22 +00:00
Auxilor
227b748f85 Fixed bStats issues 2021-12-08 20:46:26 +00:00
Auxilor
c8382bd8cf Updated to 6.16.1 2021-12-08 20:40:59 +00:00
Auxilor
df22768367 Fixed bugs 2021-12-08 20:40:39 +00:00
Auxilor
00ea3506ca config.yml changes 2021-12-08 20:32:55 +00:00
Auxilor
521659cfec bStats changes 2021-12-08 20:32:31 +00:00
Auxilor
bbe5f1eba4 Merge remote-tracking branch 'origin/develop' into develop
# Conflicts:
#	eco-core/core-plugin/build.gradle
2021-12-08 20:24:07 +00:00
dependabot[bot]
3d4c33860a Bump junit-jupiter-engine from 5.8.1 to 5.8.2
Bumps [junit-jupiter-engine](https://github.com/junit-team/junit5) from 5.8.1 to 5.8.2.
- [Release notes](https://github.com/junit-team/junit5/releases)
- [Commits](https://github.com/junit-team/junit5/compare/r5.8.1...r5.8.2)

---
updated-dependencies:
- dependency-name: org.junit.jupiter:junit-jupiter-engine
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-08 20:18:37 +00:00
Auxilor
eae5d29f8d Downgraded bStats 2021-12-08 20:16:59 +00:00
Auxilor
c878d6fd12 Implemented stipped-down bStats directly (recoded in kotlin) 2021-12-08 16:08:03 +00:00
Auxilor
2b97c0072f Downgraded bStats 2021-12-08 14:18:24 +00:00
Auxilor
63079df745 Removed explicit buffer size 2021-12-08 12:41:24 +00:00
Auxilor
079b41e877 Switched to old config behavior 2021-12-08 12:40:13 +00:00
Auxilor
1aaab459d8 Updated bStats to 2.2.1 2021-12-08 12:34:38 +00:00
Auxilor
db78c2eb4c Fixed javadoc + codestyle 2021-12-08 12:22:51 +00:00
Auxilor
02fd07b3c8 Fixed shadowed name 2021-12-08 12:17:22 +00:00
Auxilor
3de2e53031 Fixed default captive items bug 2021-12-08 11:27:33 +00:00
Auxilor
cb088bb70b Allowed specifiying default captive items 2021-12-08 11:23:23 +00:00
Auxilor
36fca7016f Fixed ArgParserEnchantment never returning null 2021-12-08 11:11:59 +00:00
Auxilor
7e1137da06 Cleaned up SS2 integration 2021-12-08 10:53:16 +00:00
Auxilor
0da104d614 Added color:#fffff support x 2021-12-08 10:51:25 +00:00
Auxilor
9095de7d19 Updated to 6.16.0 2021-12-08 10:50:36 +00:00
Auxilor
7a8abac1a2 Pull Request Fixes / Changes, config changes 2021-12-08 10:50:12 +00:00
0ft3n
1ddcb6e964 Merge branch 'master' into master 2021-12-07 14:11:40 +03:00
_OfTeN_
4d0858ad84 Added AntigriefManager#canPickupItem and created and implemented DropQueuePushEvent event 2021-12-07 14:08:04 +03:00
_OfTeN_
3d05695a36 Added Items#getItem 2021-12-07 13:30:36 +03:00
Auxilor
d676be15ce Grammar 2021-12-06 13:46:27 +00:00
Auxilor
16848caec1 Fixed grammar errors 2021-12-06 13:08:45 +00:00
Auxilor
ef26fe4629 Removed legacy arg parser method bodies 2021-12-06 13:06:22 +00:00
Auxilor
29fbd785d7 Added ArgParserName 2021-12-06 12:54:28 +00:00
Auxilor
8c73676ee0 Added ArgParserUnbreakable 2021-12-06 12:50:26 +00:00
Auxilor
ebf27d28d9 Updated to 6.15.2 2021-12-06 12:49:10 +00:00
Auxilor
317bc13f65 Moved arg parsers to internals and added ArgParserFlag 2021-12-06 12:49:00 +00:00
Auxilor
b8ec0ee6fc Updated to 6.15.1 2021-12-06 10:14:14 +00:00
Auxilor
307e57c902 Display frame changes with PacketHeldWindowItems 2021-12-06 10:13:29 +00:00
Auxilor
db0d55659f Empty transient config 2021-12-06 10:10:35 +00:00
Auxilor
548529feb3 Javadoc formatting 2021-12-06 10:09:52 +00:00
Auxilor
fb56baf452 Fixed class-cast error 2021-12-06 10:02:24 +00:00
Auxilor
5d18b424d7 Added ColorArgParser 2021-12-04 15:37:29 +00:00
Auxilor
7be9a1bd10 Fixed EcoYamlConfigWrapper cast issues 2021-12-03 20:59:07 +00:00
Auxilor
97c39b56dd Updated to 6.15.0 2021-12-03 20:23:25 +00:00
_OfTeN_
3a9f5bc139 Added support for DecentHolograms 2021-12-03 21:10:40 +03:00
Auxilor
1e5955f249 Codestyle fixes 2021-12-03 16:21:47 +00:00
Auxilor
bad076bbe9 Added kotlin.code.style = official 2021-12-03 16:18:53 +00:00
Auxilor
e219b2f33c Config additions 2021-12-03 16:13:37 +00:00
Auxilor
2f7603409e Generic variance 2021-12-03 15:58:41 +00:00
Auxilor
28cdb65176 Added Config#getSubsections 2021-12-03 15:49:00 +00:00
_OfTeN_
03ae9e89b3 Added color:#FFFFFF, color:FFFFFF or color:red,green,blue parser for leather armor color 2021-12-02 23:26:38 +03:00
dependabot[bot]
651426ed76 Bump junit-jupiter-api from 5.8.1 to 5.8.2
Bumps [junit-jupiter-api](https://github.com/junit-team/junit5) from 5.8.1 to 5.8.2.
- [Release notes](https://github.com/junit-team/junit5/releases)
- [Commits](https://github.com/junit-team/junit5/compare/r5.8.1...r5.8.2)

---
updated-dependencies:
- dependency-name: org.junit.jupiter:junit-jupiter-api
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-30 19:41:43 +00:00
dependabot[bot]
1a49165656 Bump com.github.johnrengelman.shadow from 7.0.0 to 7.1.0
Bumps com.github.johnrengelman.shadow from 7.0.0 to 7.1.0.

---
updated-dependencies:
- dependency-name: com.github.johnrengelman.shadow
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-26 19:13:10 +00:00
dependabot[bot]
a48c3c2fed Bump Factions from 1.6.9.5-U0.5.10 to 1.6.9.5-2.7.0-STABLE
Bumps Factions from 1.6.9.5-U0.5.10 to 1.6.9.5-2.7.0-STABLE.

---
updated-dependencies:
- dependency-name: com.massivecraft:Factions
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-15 21:04:02 +00:00
453 changed files with 15079 additions and 2633 deletions

8
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: Auxilor Community Discord
url: https://discord.gg/ZcwpSsE/
about: Join the Auxilor discord to get help from support staff and the general community!
- name: The most common issues people have
url: https://github.com/Auxilor/eco/issues/78
about: Check the list of known common issues to see if your issue has already been solved

31
.github/ISSUE_TEMPLATE/report-a-bug.md vendored Normal file
View File

@@ -0,0 +1,31 @@
---
name: Report a Bug
about: Report an issue with the plugin
title: ''
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Server Information (please complete the following information):**
- Version: (output of `/ver` command)
- Version of plugin and eco (`/ver eco`, `/ver <plugin>`)
**Additional context**
Add any other context about the problem here.

View File

@@ -0,0 +1,20 @@
---
name: Request a Feature
about: Suggest an idea for this plugin
title: ''
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

15
.github/workflows/checkstyle.yml vendored Normal file
View File

@@ -0,0 +1,15 @@
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

@@ -1,6 +1,6 @@
name: Java CI name: Java CI
on: [push] on: [ push, pull_request ]
jobs: jobs:
build: build:

42
.github/workflows/test-publish.yml vendored Normal file
View File

@@ -0,0 +1,42 @@
name: Publish API (Dev)
on: [ push, pull_request ]
jobs:
publish-release:
runs-on: ubuntu-latest
steps:
- name: Checkout latest code
uses: actions/checkout@v2
- name: Set outputs
id: vars
run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
- name: Set up JDK 17
uses: actions/setup-java@v2
with:
distribution: 'temurin'
java-version: 17
- name: Setup build cache
uses: actions/cache@v2.1.6
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle.kts') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Publish artifact
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# 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.
run: |
NEW_VERSION=$(echo "${GITHUB_REF}" | cut -d "/" -f3)
echo "New version: ${{ steps.vars.outputs.sha_short }}"
echo "Github username: ${GITHUB_ACTOR}"
./gradlew -Pversion=dev-${{ steps.vars.outputs.sha_short }} publish

View File

@@ -1,24 +1,38 @@
# How to contribute to eco # How to contribute to eco
## Codestyle ## Codestyle
1. The eco checkstyle is in /config/checkstyle.xml 1. The eco checkstyle is in /config/checkstyle.xml
- The pull request must not have any checkstyle issues. - The pull request must not have any checkstyle issues.
- Every method and field must have a javadoc attached. - Every method and field must have a javadoc attached.
2. Use JetBrains annotations 2. Use JetBrains annotations
- Every parameter should be annotated with @NotNull or @Nullable - Every parameter should be annotated with @NotNull or @Nullable
- Use @NotNull over lombok @NonNull
3. Imports 3. Imports
- No group (*) imports. - No group (*) imports.
- No static 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 ## Dependency Injection
- eco uses Dependency Injection - eco uses Dependency Injection
- Any calls to Eco#getHandler#getEcoPlugin are code smells and should never be used unless **absolutely necessary**. - 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. - 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. - 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 ## Other
- All drops **must** be sent through a DropQueue - calls to World#dropItem will get your PR rejected. - All drops **must** be sent through a DropQueue - calls to World#dropItem will get your PR rejected.
- eco is built with java 17. - eco is built with java 17.

View File

@@ -29,7 +29,7 @@ and many more.
# For server owners # For server owners
- Requires ProtocolLib to be installed: get the latest version [here](https://www.spigotmc.org/resources/protocollib.1997/) - Requires ProtocolLib to be installed: get the latest version [here](https://www.spigotmc.org/resources/protocollib.1997/)
- Supports 1.16.5+ - Supports 1.17+
## Downloads ## Downloads
@@ -39,7 +39,7 @@ and many more.
# For developers # For developers
## Javadoc ## Javadoc
The 6.13.0 Javadoc can be found [here](https://javadoc.jitpack.io/com/willfp/eco/6.13.0/javadoc/) The 6.27.2 Javadoc can be found [here](https://javadoc.jitpack.io/com/willfp/eco/6.27.2/javadoc/)
## Plugin Information ## Plugin Information
@@ -68,7 +68,7 @@ dependencies {
} }
``` ```
Replace `Tag` with a release tag for eco, eg `6.13.0`. Replace `Tag` with a release tag for eco, eg `6.27.2`.
Maven: Maven:
@@ -88,7 +88,7 @@ Maven:
</dependency> </dependency>
``` ```
Replace `Tag` with a release tag for eco, eg `6.13.0`. Replace `Tag` with a release tag for eco, eg `6.27.2`.
## Build locally: ## Build locally:

View File

@@ -1,8 +1,19 @@
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10")
}
}
plugins { plugins {
id("java-library") id("java-library")
id("com.github.johnrengelman.shadow") version "7.0.0" id("com.github.johnrengelman.shadow") version "7.1.2"
id("maven-publish") id("maven-publish")
id("java") id("java")
kotlin("jvm") version "1.6.10"
} }
dependencies { dependencies {
@@ -10,9 +21,9 @@ dependencies {
implementation(project(":eco-core:core-plugin")) implementation(project(":eco-core:core-plugin"))
implementation(project(":eco-core:core-proxy")) implementation(project(":eco-core:core-proxy"))
implementation(project(":eco-core:core-backend")) implementation(project(":eco-core:core-backend"))
implementation(project(":eco-core:core-nms:v1_16_R3"))
implementation(project(path = ":eco-core:core-nms:v1_17_R1", configuration = "reobf")) implementation(project(path = ":eco-core:core-nms:v1_17_R1", configuration = "reobf"))
implementation(project(":eco-core:core-nms:v1_18_R1")) implementation(project(path = ":eco-core:core-nms:v1_18_R1", configuration = "reobf"))
implementation(project(path = ":eco-core:core-nms:v1_18_R2", configuration = "reobf"))
} }
allprojects { allprojects {
@@ -20,6 +31,7 @@ allprojects {
apply(plugin = "java-library") apply(plugin = "java-library")
apply(plugin = "maven-publish") apply(plugin = "maven-publish")
apply(plugin = "com.github.johnrengelman.shadow") apply(plugin = "com.github.johnrengelman.shadow")
apply(plugin = "kotlin")
repositories { repositories {
mavenCentral() mavenCentral()
@@ -35,7 +47,7 @@ allprojects {
// NMS (for jitpack compilation) // NMS (for jitpack compilation)
maven("https://repo.codemc.org/repository/nms/") maven("https://repo.codemc.org/repository/nms/")
// bStats, mcMMO, BentoBox // mcMMO, BentoBox
maven("https://repo.codemc.org/repository/maven-public/") maven("https://repo.codemc.org/repository/maven-public/")
// Spigot API, Bungee API // Spigot API, Bungee API
@@ -61,19 +73,33 @@ allprojects {
// IridiumSkyblock // IridiumSkyblock
maven("https://nexus.iridiumdevelopment.net/repository/maven-releases/") maven("https://nexus.iridiumdevelopment.net/repository/maven-releases/")
// MythicMobs
maven("https://mvn.lumine.io/repository/maven-public/")
// Crunch
maven("https://redempt.dev")
// LibsDisguises
maven("https://repo.md-5.net/content/groups/public/")
} }
dependencies { dependencies {
compileOnly(kotlin("stdlib", version = "1.6.10"))
compileOnly("org.jetbrains:annotations:23.0.0") compileOnly("org.jetbrains:annotations:23.0.0")
// Test // Test
testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.1") testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.2")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.2")
// Adventure // Adventure
compileOnly("net.kyori:adventure-api:4.9.3") compileOnly("net.kyori:adventure-api:4.10.0")
compileOnly("net.kyori:adventure-text-serializer-gson:4.9.3") compileOnly("net.kyori:adventure-text-serializer-gson:4.10.0")
compileOnly("net.kyori:adventure-text-serializer-legacy:4.9.3") compileOnly("net.kyori:adventure-text-serializer-legacy:4.10.0")
// Other
compileOnly("com.google.guava:guava:31.1-jre")
compileOnly("com.github.ben-manes.caffeine:caffeine:3.0.5")
} }
tasks.withType<JavaCompile> { tasks.withType<JavaCompile> {
@@ -88,12 +114,25 @@ allprojects {
exclude(group = "org.spongepowered", module = "configurate-hocon") exclude(group = "org.spongepowered", module = "configurate-hocon")
exclude(group = "com.darkblade12", module = "particleeffect") exclude(group = "com.darkblade12", module = "particleeffect")
exclude(group = "com.github.cryptomorin", module = "XSeries") exclude(group = "com.github.cryptomorin", module = "XSeries")
exclude(group = "net.wesjd", module = "anvilgui")
}
configurations.testImplementation {
setExtendsFrom(listOf(configurations.compileOnly.get()))
} }
tasks { tasks {
compileKotlin {
kotlinOptions {
jvmTarget = "17"
}
targetCompatibility = "17"
sourceCompatibility = "17"
}
shadowJar { shadowJar {
relocate("org.bstats", "com.willfp.eco.shaded.bstats") relocate("org.bstats", "com.willfp.eco.libs.bstats")
relocate("net.kyori.adventure.text.minimessage", "com.willfp.eco.shaded.minimessage") relocate("redempt.crunch", "com.willfp.eco.libs.crunch")
} }
compileJava { compileJava {

View File

@@ -32,10 +32,6 @@
--> -->
<module name="Checker"> <module name="Checker">
<module name="SuppressionFilter">
<property name="file" value="config/checkstyle/suppression.xml"/>
</module>
<!-- <!--
If you set the basedir property below, then all reported file If you set the basedir property below, then all reported file
names will be relative to the specified directory. See names will be relative to the specified directory. See

View File

@@ -1,24 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE suppressions PUBLIC
"-//Puppy Crawl//DTD Suppressions 1.1//EN"
"http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
<suppressions>
<!-- Internals don't need javadoc. -->
<suppress files="[\\/]internal[\\/]" checks="MissingJavadocMethod"/>
<suppress files="[\\/]internal[\\/]" checks="JavadocVariable"/>
<suppress files="[\\/]eco[\\/]spigot[\\/]" checks="MissingJavadocMethod"/>
<suppress files="[\\/]eco[\\/]spigot[\\/]" checks="JavadocVariable"/>
<suppress files="[\\/]eco[\\/]proxy[\\/]" checks="MissingJavadocMethod"/>
<suppress files="[\\/]eco[\\/]proxy[\\/]" checks="JavadocVariable"/>
<!-- Modified version of library -->
<suppress files="ArmorEquipEvent.java" checks="JavadocVariable"/>
<suppress files="ArmorEquipEvent.java" checks="MissingJavadocMethod"/>
<suppress files="ArmorEquipEvent.java" checks="JavadocStyle"/>
<suppress files="ArmorListener.java" checks="JavadocVariable"/>
<suppress files="ArmorListener.java" checks="MissingJavadocMethod"/>
<suppress files="ArmorType.java" checks="JavadocVariable"/>
<suppress files="ArmorType.java" checks="MissingJavadocMethod"/>
</suppressions>

View File

@@ -1,14 +1,6 @@
plugins {
id 'com.github.johnrengelman.shadow'
}
group 'com.willfp'
version rootProject.version
dependencies { dependencies {
// Adventure // Adventure
compileOnly 'net.kyori:adventure-platform-bukkit:4.0.0' compileOnly 'net.kyori:adventure-platform-bukkit:4.1.0'
compileOnly 'net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT'
// Other // Other
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT' compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
@@ -17,11 +9,13 @@ dependencies {
compileOnly 'com.google.code.gson:gson:2.8.8' compileOnly 'com.google.code.gson:gson:2.8.8'
} }
group 'com.willfp'
version rootProject.version
java { java {
withJavadocJar() withJavadocJar()
} }
build.dependsOn publishToMavenLocal build.dependsOn publishToMavenLocal
publishing { publishing {

View File

@@ -4,11 +4,20 @@ import org.apache.commons.lang.Validate;
import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
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;
/** /**
* Base class to hold the handler. * Holds the instance of the eco handler for bridging between the frontend
* and backend.
* *
* @see Eco#getHandler()
* @see Handler * @see Handler
*/ */
@ApiStatus.Internal
public final class Eco { public final class Eco {
/** /**
* Instance of eco handler. * Instance of eco handler.
@@ -18,6 +27,7 @@ public final class Eco {
/** /**
* Set the handler. * Set the handler.
*
* @param handler The handler. * @param handler The handler.
*/ */
@ApiStatus.Internal @ApiStatus.Internal
@@ -28,18 +38,18 @@ public final class Eco {
} }
/** /**
* Get the instance of the eco handler. * Get the instance of the eco handler; the bridge between the api frontend
* and the implementation backend.
* <p> * <p>
* The handler is, in essence, a way to interface between the eco-api * <strong>Do not use the handler in your plugins!</strong> It can and will contain
* frontend module, and the eco-backend implementations. * 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> * <p>
* There shouldn't really be any reason to ever use the handler * Prior to version 6.12.0, the handler was considered as an API component, but it has
* in your own plugins, and you are likely to break things. All parts of * since been moved into an internal component, and in 6.17.0, the first breaking change
* the handler are abstracted into logically named parts of the API. * was introduced to {@link com.willfp.eco.core.config.wrapper.ConfigFactory}. This means
* <p> * that any usages of the handler can now cause problems in your plugins.
* In versions of eco before 6.12.0, the handler was considered part of
* the eco API, however it has since been moved into an internal component
* that shouldn't be used in your plugins.
* *
* @return The handler. * @return The handler.
*/ */
@@ -48,6 +58,24 @@ public final class Eco {
return handler; return handler;
} }
/**
* 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.
*/
@Documented
@Retention(RetentionPolicy.CLASS)
@Target({ElementType.TYPE})
public @interface HandlerComponent {
}
private Eco() { private Eco() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
} }

View File

@@ -14,7 +14,6 @@ import com.willfp.eco.core.factory.NamespacedKeyFactory;
import com.willfp.eco.core.factory.RunnableFactory; import com.willfp.eco.core.factory.RunnableFactory;
import com.willfp.eco.core.integrations.IntegrationLoader; import com.willfp.eco.core.integrations.IntegrationLoader;
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager; import com.willfp.eco.core.integrations.placeholder.PlaceholderManager;
import com.willfp.eco.core.proxy.AbstractProxy;
import com.willfp.eco.core.proxy.ProxyFactory; import com.willfp.eco.core.proxy.ProxyFactory;
import com.willfp.eco.core.scheduling.Scheduler; import com.willfp.eco.core.scheduling.Scheduler;
import com.willfp.eco.core.web.UpdateChecker; import com.willfp.eco.core.web.UpdateChecker;
@@ -32,6 +31,7 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -152,10 +152,14 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
private final ProxyFactory proxyFactory; private final ProxyFactory proxyFactory;
/** /**
* Create a new plugin without a specified color, proxy support, polymart, or bStats. * Create a new plugin.
* <p>
* Will read from eco.yml (like plugin.yml) to fetch values that would otherwise be passed
* into the constructor. If no eco.yml is present, the plugin will load without extension
* support, without proxy support, with no update-checker or bStats, and with the color white.
*/ */
protected EcoPlugin() { protected EcoPlugin() {
this("&f"); this((PluginProps) null);
} }
/** /**
@@ -236,6 +240,23 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
@NotNull final String proxyPackage, @NotNull final String proxyPackage,
@NotNull final String color, @NotNull final String color,
final boolean supportingExtensions) { final boolean supportingExtensions) {
this(
PluginProps.createSimple(
resourceId,
bStatsId,
proxyPackage,
color,
supportingExtensions
)
);
}
/**
* Create a new plugin.
*
* @param pluginProps The props. If left null, it will read from eco.yml.
*/
protected EcoPlugin(@Nullable final PluginProps pluginProps) {
/* /*
The handler must be initialized before any plugin's constructors The handler must be initialized before any plugin's constructors
are called, as the constructors call Eco#getHandler(). are called, as the constructors call Eco#getHandler().
@@ -253,15 +274,15 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
a standalone handler class, but then there would be an interface a standalone handler class, but then there would be an interface
left in the API that doesn't really help anything. left in the API that doesn't really help anything.
The other alternative would be do use reflection to get a 'createHandler' The other alternative would be to use reflection to get a 'createHandler'
method that only exists in EcoSpigotPlugin - but that feels really dirty method that only exists in EcoSpigotPlugin - but that feels filthy,
and I'd rather only use reflection where necessary. and I'd rather only use reflection where necessary.
*/ */
if (Eco.getHandler() == null && this instanceof Handler) { if (Eco.getHandler() == null && this instanceof Handler) {
/* /*
This code is only ever called by EcoSpigotPlugin (EcoHandler) This code is only ever called by EcoSpigotPlugin (EcoHandler)
as it's the first plugin to load and it is a handler. as it's the first plugin to load, and it is a handler.
Any other plugins will never call this code as the handler Any other plugins will never call this code as the handler
will have already been initialized. will have already been initialized.
@@ -272,11 +293,16 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
assert Eco.getHandler() != null; assert Eco.getHandler() != null;
this.resourceId = resourceId; PluginProps generatedProps = Eco.getHandler().getProps(pluginProps, this.getClass());
this.bStatsId = bStatsId; generatedProps.validate();
this.proxyPackage = proxyPackage; PluginProps props = this.mutateProps(generatedProps);
this.color = color; props.validate();
this.supportingExtensions = supportingExtensions;
this.resourceId = props.getResourceId();
this.bStatsId = props.getBStatsId();
this.proxyPackage = props.getProxyPackage();
this.color = props.getColor();
this.supportingExtensions = props.isSupportingExtensions();
this.scheduler = Eco.getHandler().createScheduler(this); this.scheduler = Eco.getHandler().createScheduler(this);
this.eventManager = Eco.getHandler().createEventManager(this); this.eventManager = Eco.getHandler().createEventManager(this);
@@ -296,8 +322,8 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
/* /*
The minimum eco version check was moved here because it's very common The minimum eco version check was moved here because it's very common
to add a lot of code in the constructor of plugins; meaning that the plugin to add a lot of code in the constructor of plugins; meaning that the plugin
can throw errors without it being obvious to the user that the reason is can throw errors without it being obvious to the user that the reason is that
because they have an outdated version of eco installed. they have an outdated version of eco installed.
*/ */
DefaultArtifactVersion runningVersion = new DefaultArtifactVersion(Eco.getHandler().getEcoPlugin().getDescription().getVersion()); DefaultArtifactVersion runningVersion = new DefaultArtifactVersion(Eco.getHandler().getEcoPlugin().getDescription().getVersion());
@@ -327,11 +353,9 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
DefaultArtifactVersion mostRecentVersion = new DefaultArtifactVersion(version); DefaultArtifactVersion mostRecentVersion = new DefaultArtifactVersion(version);
if (!(currentVersion.compareTo(mostRecentVersion) > 0 || currentVersion.equals(mostRecentVersion))) { if (!(currentVersion.compareTo(mostRecentVersion) > 0 || currentVersion.equals(mostRecentVersion))) {
this.outdated = true; this.outdated = true;
this.getScheduler().runTimer(() -> { this.getLogger().warning("&c" + this.getName() + " is out of date! (Version " + this.getDescription().getVersion() + ")");
this.getLogger().info("&c " + this.getName() + " is out of date! (Version " + this.getDescription().getVersion() + ")"); this.getLogger().warning("&cThe newest version is &f" + version);
this.getLogger().info("&cThe newest version is &f" + version); this.getLogger().warning("&cDownload the new version!");
this.getLogger().info("&cDownload the new version!");
}, 0, 864000);
} }
}); });
} }
@@ -536,6 +560,21 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
} }
/**
* Mutate the plugin props.
* <p>
* Useful for eco-based plugin libraries to enforce certain properties, such as
* forcing extensions to be enabled.
* <p>
* Props are validated both before and after calling this method.
*
* @param props The props.
* @return The mutated props.
*/
protected PluginProps mutateProps(@NotNull final PluginProps props) {
return props;
}
/** /**
* The plugin-specific integrations to be tested and loaded. * The plugin-specific integrations to be tested and loaded.
* *
@@ -636,8 +675,8 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @param <T> The proxy type. * @param <T> The proxy type.
* @return The proxy. * @return The proxy.
*/ */
public final <T extends AbstractProxy> T getProxy(@NotNull final Class<T> proxyClass) { public final <T> T getProxy(@NotNull final Class<T> proxyClass) {
Validate.notNull(proxyFactory, "Plugin does not support proxy!"); Validate.notNull(proxyFactory, "Plugin does not support proxies!");
return proxyFactory.getProxy(proxyClass); return proxyFactory.getProxy(proxyClass);
} }
@@ -655,7 +694,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
public final FileConfiguration getConfig() { public final FileConfiguration getConfig() {
this.getLogger().warning("Call to default config method in eco plugin!"); this.getLogger().warning("Call to default config method in eco plugin!");
return this.getConfigYml().getBukkitHandle(); return Objects.requireNonNull(this.getConfigYml().getBukkitHandle());
} }
/** /**

View File

@@ -2,9 +2,10 @@ package com.willfp.eco.core;
import com.willfp.eco.core.config.updating.ConfigHandler; import com.willfp.eco.core.config.updating.ConfigHandler;
import com.willfp.eco.core.config.wrapper.ConfigFactory; import com.willfp.eco.core.config.wrapper.ConfigFactory;
import com.willfp.eco.core.data.PlayerProfileHandler; import com.willfp.eco.core.data.ProfileHandler;
import com.willfp.eco.core.data.keys.KeyRegistry; import com.willfp.eco.core.data.keys.KeyRegistry;
import com.willfp.eco.core.drops.DropQueueFactory; import com.willfp.eco.core.drops.DropQueueFactory;
import com.willfp.eco.core.entities.ai.EntityController;
import com.willfp.eco.core.events.EventManager; import com.willfp.eco.core.events.EventManager;
import com.willfp.eco.core.extensions.ExtensionLoader; import com.willfp.eco.core.extensions.ExtensionLoader;
import com.willfp.eco.core.factory.MetadataValueFactory; import com.willfp.eco.core.factory.MetadataValueFactory;
@@ -15,9 +16,12 @@ import com.willfp.eco.core.gui.GUIFactory;
import com.willfp.eco.core.integrations.placeholder.PlaceholderIntegration; import com.willfp.eco.core.integrations.placeholder.PlaceholderIntegration;
import com.willfp.eco.core.proxy.Cleaner; import com.willfp.eco.core.proxy.Cleaner;
import com.willfp.eco.core.proxy.ProxyFactory; import com.willfp.eco.core.proxy.ProxyFactory;
import com.willfp.eco.core.requirement.RequirementFactory;
import com.willfp.eco.core.scheduling.Scheduler; import com.willfp.eco.core.scheduling.Scheduler;
import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.bukkit.Location;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Mob;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -201,14 +205,6 @@ public interface Handler {
*/ */
void registerBStats(@NotNull EcoPlugin plugin); void registerBStats(@NotNull EcoPlugin plugin);
/**
* Get the requirement factory.
*
* @return The factory.
*/
@NotNull
RequirementFactory getRequirementFactory();
/** /**
* Get Adventure audiences. * Get Adventure audiences.
* *
@@ -230,5 +226,60 @@ public interface Handler {
* *
* @return The handler. * @return The handler.
*/ */
PlayerProfileHandler getPlayerProfileHandler(); @NotNull
ProfileHandler getProfileHandler();
/**
* Create dummy entity - never spawned, exists purely in code.
*
* @param location The location.
* @return The entity.
*/
@NotNull
Entity createDummyEntity(@NotNull Location location);
/**
* Create a {@link NamespacedKey} quickly
* <p>
* Bypasses the constructor, allowing for the creation of invalid keys,
* therefore this is considered unsafe and should only be called after
* the key has been confirmed to be valid.
*
* @param namespace The namespace.
* @param key The key.
* @return The key.
*/
@NotNull
NamespacedKey createNamespacedKey(@NotNull String namespace,
@NotNull String key);
/**
* Return or get props for a plugin.
*
* @param existing The existing constructor props.
* @param plugin The plugin.
* @return The props.
*/
@NotNull
PluginProps getProps(@Nullable PluginProps existing,
@NotNull Class<? extends EcoPlugin> plugin);
/**
* Format a string with MiniMessage.
*
* @param message The message.
* @return The formatted string.
*/
@NotNull
String formatMiniMessage(@NotNull String message);
/**
* Create controlled entity from a mob.
*
* @param mob The mob.
* @param <T> The mob type.
* @return The controlled entity.
*/
@NotNull
<T extends Mob> EntityController<T> createEntityController(@NotNull T mob);
} }

View File

@@ -4,6 +4,13 @@ import org.jetbrains.annotations.NotNull;
/** /**
* Quick DI class to manage passing eco plugins. * 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. * @param <T> The eco plugin type.
*/ */

View File

@@ -3,6 +3,7 @@ package com.willfp.eco.core;
import com.willfp.eco.core.config.updating.ConfigHandler; import com.willfp.eco.core.config.updating.ConfigHandler;
import java.io.File; import java.io.File;
import java.util.logging.Logger;
/** /**
* Represents any class that acts like a plugin, for example {@link EcoPlugin} * Represents any class that acts like a plugin, for example {@link EcoPlugin}
@@ -26,4 +27,11 @@ public interface PluginLike {
* @return The config handler. * @return The config handler.
*/ */
ConfigHandler getConfigHandler(); ConfigHandler getConfigHandler();
/**
* Get the logger.
*
* @return The logger.
*/
Logger getLogger();
} }

View File

@@ -0,0 +1,275 @@
package com.willfp.eco.core;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
/**
* Plugin props are the arguments related to the plugin that are required on start-up.
* <p>
* This class is complex in how it works intentionally. This is done so that fields can be
* added to the props without breaking API backwards compatibility. Thus, there is no public
* constructor and no way to instantiate props without creating a parser.
*/
public final class PluginProps {
/**
* All registered parsers.
*/
private static final Map<Class<?>, PropsParser<?>> REGISTERED_PARSERS = new HashMap<>();
/**
* The polymart resource ID.
*/
@Nullable
private Integer resourceId;
/**
* The bStats ID.
*/
@Nullable
private Integer bStatsId;
/**
* The proxy package.
*/
@Nullable
private String proxyPackage;
/**
* The color.
*/
@Nullable
private String color;
/**
* If extensions are supported.
*/
@Nullable
private Boolean supportingExtensions;
/**
* Create new blank props.
*/
private PluginProps() {
}
/**
* Get resource ID.
*
* @return The resource ID.
*/
public int getResourceId() {
assert resourceId != null;
return resourceId;
}
/**
* Set resource ID.
*
* @param resourceId The resource ID.
*/
public void setResourceId(final int resourceId) {
this.resourceId = resourceId;
}
/**
* Get bStats ID.
*
* @return The bStats ID.
*/
public int getBStatsId() {
assert bStatsId != null;
return bStatsId;
}
/**
* Set bStats ID.
*
* @param bStatsId The bStats ID.
*/
public void setBStatsId(final int bStatsId) {
this.bStatsId = bStatsId;
}
/**
* Get the proxy package.
*
* @return The package.
*/
@NotNull
public String getProxyPackage() {
assert proxyPackage != null;
return proxyPackage;
}
/**
* Set the proxy package.
*
* @param proxyPackage The proxy package.
*/
public void setProxyPackage(@NotNull final String proxyPackage) {
this.proxyPackage = proxyPackage;
}
/**
* Get color.
*
* @return The color.
*/
@NotNull
public String getColor() {
assert color != null;
return color;
}
/**
* Set the color.
*
* @param color The color.
*/
public void setColor(@NotNull final String color) {
this.color = color;
}
/**
* Get if extensions are supported.
*
* @return If supported.
*/
public boolean isSupportingExtensions() {
assert supportingExtensions != null;
return supportingExtensions;
}
/**
* Set if extensions are supported.
*
* @param supportingExtensions If supported.
*/
public void setSupportingExtensions(final boolean supportingExtensions) {
this.supportingExtensions = supportingExtensions;
}
/**
* Ensure that all required props have been set.
*/
public void validate() {
if (
supportingExtensions == null
|| proxyPackage == null
|| color == null
|| bStatsId == null
|| resourceId == null
) {
throw new IllegalStateException("Missing required props!");
}
}
/**
* Parse props from source.
*
* @param source The source.
* @param sourceClass The source class.
* @param <T> The source type.
* @return The props.
*/
public static <T> PluginProps parse(@NotNull final T source,
@NotNull final Class<? extends T> sourceClass) {
for (Map.Entry<Class<?>, PropsParser<?>> entry : REGISTERED_PARSERS.entrySet()) {
Class<?> clazz = entry.getKey();
if (clazz.equals(sourceClass)) {
@SuppressWarnings("unchecked")
PropsParser<T> parser = (PropsParser<T>) entry.getValue();
return parser.parseFrom(source);
}
}
throw new IllegalArgumentException("No parser exists for class " + sourceClass);
}
/**
* Register a parser for a type.
*
* @param clazz The class.
* @param parser The parser.
* @param <T> The source type.
*/
public static <T> void registerParser(@NotNull final Class<T> clazz,
@NotNull final PropsParser<T> parser) {
REGISTERED_PARSERS.put(clazz, parser);
}
/**
* Get if there is a registered parser for a class.
*
* @param clazz The class.
* @return If there is a parser registered.
*/
public static boolean hasParserFor(@NotNull final Class<?> clazz) {
for (Class<?> test : REGISTERED_PARSERS.keySet()) {
if (test.equals(clazz)) {
return true;
}
}
return false;
}
/**
* Create new props from known values.
*
* 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.
*
* @param resourceId The ID of the plugin on polymart.
* @param bStatsId The ID of the plugin on bStats.
* @param proxyPackage The package where proxies can be found.
* @param color The primary color of the plugin.
* @param supportsExtensions If the plugin should attempt to look for extensions.
* @return The props.
*/
@ApiStatus.Internal
static PluginProps createSimple(final int resourceId,
final int bStatsId,
@NotNull final String proxyPackage,
@NotNull final String color,
final boolean supportsExtensions) {
PluginProps props = new PluginProps();
props.setResourceId(resourceId);
props.setBStatsId(bStatsId);
props.setProxyPackage(proxyPackage);
props.setColor(color);
props.setSupportingExtensions(supportsExtensions);
return props;
}
/**
* Parse arguments into props for a plugin.
*
* @param <T> The type of source.
*/
public interface PropsParser<T> {
/**
* Parse props from a given source.
*
* @param source The source.
* @return The props.
*/
PluginProps parseFrom(@NotNull T source);
/**
* Get a new, blank props instance.
*
* @return Blank props.
*/
default PluginProps getBlankProps() {
return new PluginProps();
}
}
}

View File

@@ -51,7 +51,10 @@ public class Prerequisite {
/** /**
* Requires the server to be running 1.17. * Requires the server to be running 1.17.
*
* @deprecated eco no longer supports versions before 1.17.
*/ */
@Deprecated(since = "6.25.2")
public static final Prerequisite HAS_1_17 = new Prerequisite( public static final Prerequisite HAS_1_17 = new Prerequisite(
() -> ProxyConstants.NMS_VERSION.contains("17") || HAS_1_18.isMet(), () -> ProxyConstants.NMS_VERSION.contains("17") || HAS_1_18.isMet(),
"Requires server to be running 1.17+" "Requires server to be running 1.17+"

View File

@@ -1,7 +1,12 @@
package com.willfp.eco.core.command; package com.willfp.eco.core.command;
import com.willfp.eco.core.EcoPlugin;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
/** /**
* Interface for all command implementations. * Interface for all command implementations.
*/ */
@@ -35,31 +40,77 @@ public interface CommandBase {
*/ */
CommandBase addSubcommand(@NotNull CommandBase command); CommandBase addSubcommand(@NotNull CommandBase command);
/**
* Handle command execution.
* <p>
* Marked as default void with no implementation for backwards compatibility.
*
* @param sender The sender.
* @param args The args.
*/
default void onExecute(@NotNull CommandSender sender,
@NotNull List<String> args) {
// Do nothing.
}
/**
* Handle tab completion.
* <p>
* Marked as default void with no implementation for backwards compatibility.
*
* @param sender The sender.
* @param args The args.
* @return The results.
*/
default List<String> tabComplete(@NotNull CommandSender sender,
@NotNull List<String> args) {
return new ArrayList<>();
}
/**
* Get the plugin.
*
* @return The plugin.
*/
EcoPlugin getPlugin();
/** /**
* Get the handler. * Get the handler.
* *
* @return The handler. * @return The handler.
* @see CommandHandler
* @deprecated Use {@link CommandBase#onExecute(CommandSender, List)} instead.
*/ */
@Deprecated
CommandHandler getHandler(); CommandHandler getHandler();
/** /**
* Set the handler. * Set the handler.
* *
* @param handler The handler. * @param handler The handler.
* @see CommandHandler
* @deprecated Handlers have been deprecated.
*/ */
@Deprecated
void setHandler(@NotNull CommandHandler handler); void setHandler(@NotNull CommandHandler handler);
/** /**
* Get the tab completer. * Get the tab completer.
* *
* @return The tab completer. * @return The tab completer.
* @see TabCompleteHandler
* @deprecated Use {@link CommandBase#tabComplete(CommandSender, List)} instead.
*/ */
@Deprecated
TabCompleteHandler getTabCompleter(); TabCompleteHandler getTabCompleter();
/** /**
* Set the tab completer. * Set the tab completer.
* *
* @param handler The handler. * @param handler The handler.
* @see TabCompleteHandler
* @deprecated Handlers have been deprecated.
*/ */
@Deprecated
void setTabCompleter(@NotNull TabCompleteHandler handler); void setTabCompleter(@NotNull TabCompleteHandler handler);
} }

View File

@@ -10,9 +10,13 @@ import java.util.List;
* A command handler handles the actual code for a command. * A command handler handles the actual code for a command.
* <p> * <p>
* The replacement for {@link org.bukkit.command.CommandExecutor#onCommand(CommandSender, Command, String, String[])} * The replacement for {@link org.bukkit.command.CommandExecutor#onCommand(CommandSender, Command, String, String[])}
*
* @see CommandBase * @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 @FunctionalInterface
@Deprecated(since = "6.17.0")
public interface CommandHandler { public interface CommandHandler {
/** /**
* The code to be called on execution. * The code to be called on execution.

View File

@@ -10,9 +10,13 @@ import java.util.List;
* A Tab Complete handler handles the actual tab-completion code. * A Tab Complete handler handles the actual tab-completion code.
* <p> * <p>
* The replacement for {@link org.bukkit.command.TabCompleter#onTabComplete(CommandSender, Command, String, String[])} * The replacement for {@link org.bukkit.command.TabCompleter#onTabComplete(CommandSender, Command, String, String[])}
*
* @see CommandBase * @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 @FunctionalInterface
@Deprecated(since = "6.17.0")
public interface TabCompleteHandler { public interface TabCompleteHandler {
/** /**
* Handle Tab Completion. * Handle Tab Completion.

View File

@@ -1,7 +1,6 @@
package com.willfp.eco.core.command.impl; package com.willfp.eco.core.command.impl;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginDependent;
import com.willfp.eco.core.command.CommandBase; import com.willfp.eco.core.command.CommandBase;
import com.willfp.eco.core.command.CommandHandler; import com.willfp.eco.core.command.CommandHandler;
import com.willfp.eco.core.command.TabCompleteHandler; import com.willfp.eco.core.command.TabCompleteHandler;
@@ -9,6 +8,7 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil; import org.bukkit.util.StringUtil;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@@ -23,7 +23,13 @@ import java.util.stream.Collectors;
* in order to execute the command-specific code. It's essentially an internal * in order to execute the command-specific code. It's essentially an internal
* layer, hence why it's a package-private class. * layer, hence why it's a package-private class.
*/ */
abstract class HandledCommand extends PluginDependent<EcoPlugin> implements CommandBase { @SuppressWarnings({"DeprecatedIsStillUsed"})
abstract class HandledCommand implements CommandBase {
/**
* The plugin.
*/
private final EcoPlugin plugin;
/** /**
* The name of the command. * The name of the command.
*/ */
@@ -46,14 +52,16 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
/** /**
* The actual code to be executed in the command. * The actual code to be executed in the command.
*/ */
private CommandHandler handler = (sender, args) -> { @Deprecated
// Do nothing by default @Nullable
}; private CommandHandler handler = null;
/** /**
* The tab completion code to be executed in the command. * The tab completion code to be executed in the command.
*/ */
private TabCompleteHandler tabCompleter = (sender, args) -> new ArrayList<>(); @Deprecated
@Nullable
private TabCompleteHandler tabCompleter = null;
/** /**
* All subcommands for the command. * All subcommands for the command.
@@ -74,7 +82,7 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
@NotNull final String name, @NotNull final String name,
@NotNull final String permission, @NotNull final String permission,
final boolean playersOnly) { final boolean playersOnly) {
super(plugin); this.plugin = plugin;
this.name = name; this.name = name;
this.permission = permission; this.permission = permission;
this.playersOnly = playersOnly; this.playersOnly = playersOnly;
@@ -94,6 +102,16 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
return this; return this;
} }
/**
* Get the plugin.
*
* @return The plugin.
*/
@Override
public EcoPlugin getPlugin() {
return this.plugin;
}
/** /**
* Handle the command. * Handle the command.
* *
@@ -120,7 +138,16 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
} }
} }
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)); this.getHandler().onExecute(sender, Arrays.asList(args));
} else {
this.onExecute(sender, Arrays.asList(args));
}
} }
/** /**
@@ -167,7 +194,11 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
} }
} }
if (this.getTabCompleter() != null) {
return this.getTabCompleter().tabComplete(sender, Arrays.asList(args)); return this.getTabCompleter().tabComplete(sender, Arrays.asList(args));
} else {
return this.tabComplete(sender, Arrays.asList(args));
}
} }
/** /**
@@ -181,11 +212,6 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
public static boolean canExecute(@NotNull final CommandSender sender, public static boolean canExecute(@NotNull final CommandSender sender,
@NotNull final CommandBase command, @NotNull final CommandBase command,
@NotNull final EcoPlugin plugin) { @NotNull final EcoPlugin plugin) {
if (command.isPlayersOnly() && !(sender instanceof Player)) {
sender.sendMessage(plugin.getLangYml().getMessage("not-player"));
return false;
}
if (!sender.hasPermission(command.getPermission()) && sender instanceof Player) { if (!sender.hasPermission(command.getPermission()) && sender instanceof Player) {
sender.sendMessage(plugin.getLangYml().getNoPermission()); sender.sendMessage(plugin.getLangYml().getNoPermission());
return false; return false;
@@ -221,24 +247,6 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
return this.playersOnly; return this.playersOnly;
} }
/**
* Get the actual code to be executed in the command.
*
* @return The code.
*/
public CommandHandler getHandler() {
return this.handler;
}
/**
* Get the tab completion code to be executed in the command.
*
* @return The code.
*/
public TabCompleteHandler getTabCompleter() {
return this.tabCompleter;
}
/** /**
* Get the subcommands of the command. * Get the subcommands of the command.
* *
@@ -248,21 +256,27 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
return this.subcommands; return this.subcommands;
} }
/** @Deprecated
* Set the command handler. @Override
* public @Nullable CommandHandler getHandler() {
* @param handler The handler. return this.handler;
*/ }
public void setHandler(@NotNull final CommandHandler handler) {
@Deprecated
@Override
public @Nullable TabCompleteHandler getTabCompleter() {
return this.tabCompleter;
}
@Deprecated
@Override
public void setHandler(@Nullable final CommandHandler handler) {
this.handler = handler; this.handler = handler;
} }
/** @Deprecated
* Set the tab completer. @Override
* public void setTabCompleter(@Nullable final TabCompleteHandler tabCompleter) {
* @param tabCompleter The tab completer.
*/
public void setTabCompleter(@NotNull final TabCompleteHandler tabCompleter) {
this.tabCompleter = tabCompleter; this.tabCompleter = tabCompleter;
} }
} }

View File

@@ -12,7 +12,9 @@ import org.jetbrains.annotations.Nullable;
import java.util.List; import java.util.List;
/** /**
* PluginCommands are the class to be used instead of CommandExecutor. * 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> * <p>
* The command will not be registered until register() is called. * The command will not be registered until register() is called.
* <p> * <p>

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.core.config;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.wrapper.LoadableConfigWrapper;
import org.jetbrains.annotations.NotNull;
/**
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
* <p>
* Automatically updates.
*/
public abstract class BaseConfig extends LoadableConfigWrapper {
/**
* Create new Base Config.
*
* @param plugin The plugin or extension.
* @param configName The config name (excluding extension).
* @param removeUnused If unused sections should be removed.
* @param type The config type.
*/
protected BaseConfig(@NotNull final String configName,
@NotNull final PluginLike plugin,
final boolean removeUnused,
@NotNull final ConfigType type) {
super(Eco.getHandler().getConfigFactory().createUpdatableConfig(
configName,
plugin,
"",
plugin.getClass(),
removeUnused,
type
));
}
}

View File

@@ -0,0 +1,16 @@
package com.willfp.eco.core.config;
/**
* Config types, classified by file extension.
*/
public enum ConfigType {
/**
* .json config.
*/
JSON,
/**
* .yml config.
*/
YAML
}

View File

@@ -0,0 +1,44 @@
package com.willfp.eco.core.config;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.wrapper.LoadableConfigWrapper;
import org.jetbrains.annotations.NotNull;
/**
* Config implementation for configs present in one of two places:
* <ul>
* <li>Plugin base directory (eg config.yml, lang.json)</li>
* <li>Other extension's configs</li>
* </ul>
* <p>
* Automatically updates.
*/
public abstract class ExtendableConfig extends LoadableConfigWrapper {
/**
* @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param plugin The plugin.
* @param updateBlacklist Substring of keys to not add/remove keys for.
* @param subDirectoryPath The subdirectory path.
* @param type The config type.
* @param source The class that owns the resource.
*/
protected ExtendableConfig(@NotNull final String configName,
final boolean removeUnused,
@NotNull final PluginLike plugin,
@NotNull final Class<?> source,
@NotNull final String subDirectoryPath,
@NotNull final ConfigType type,
@NotNull final String... updateBlacklist) {
super(Eco.getHandler().getConfigFactory().createUpdatableConfig(
configName,
plugin,
subDirectoryPath,
source,
removeUnused,
type,
updateBlacklist
));
}
}

View File

@@ -0,0 +1,32 @@
package com.willfp.eco.core.config;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.wrapper.LoadableConfigWrapper;
import org.jetbrains.annotations.NotNull;
/**
* Non-updatable yaml config that exists within a plugin jar.
*/
public abstract class StaticBaseConfig extends LoadableConfigWrapper {
/**
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
* <p>
* Does not automatically update.
*
* @param configName The name of the config
* @param plugin The plugin.
* @param type The config type.
*/
protected StaticBaseConfig(@NotNull final String configName,
@NotNull final PluginLike plugin,
@NotNull final ConfigType type) {
super(Eco.getHandler().getConfigFactory().createLoadableConfig(
configName,
plugin,
"",
plugin.getClass(),
type
));
}
}

View File

@@ -0,0 +1,60 @@
package com.willfp.eco.core.config;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.config.wrapper.ConfigWrapper;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.InputStream;
import java.io.InputStreamReader;
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.
*/
public class TransientConfig extends ConfigWrapper<Config> {
/**
* @param config The YamlConfiguration handle.
*/
public TransientConfig(@NotNull final YamlConfiguration config) {
super(Eco.getHandler().getConfigFactory().createConfig(config));
}
/**
* @param stream The InputStream.
*/
public TransientConfig(@Nullable final InputStream stream) {
super(stream != null ? Eco.getHandler().getConfigFactory().createConfig(YamlConfiguration.loadConfiguration(
new InputStreamReader(stream)
)) : new TransientConfig());
}
/**
* Create a new empty transient config.
*
* @param values The values.
*/
public TransientConfig(@NotNull final Map<String, Object> values) {
super(Eco.getHandler().getConfigFactory().createConfig(values));
}
/**
* Create a new empty transient config.
*/
public TransientConfig() {
super(Eco.getHandler().getConfigFactory().createConfig("", ConfigType.YAML));
}
/**
* @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));
}
}

View File

@@ -1,20 +1,21 @@
package com.willfp.eco.core.config.base; package com.willfp.eco.core.config.base;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.config.yaml.YamlBaseConfig; import com.willfp.eco.core.config.BaseConfig;
import com.willfp.eco.core.config.ConfigType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/** /**
* Default plugin config.yml. * Default plugin config.yml.
*/ */
public class ConfigYml extends YamlBaseConfig { public class ConfigYml extends BaseConfig {
/** /**
* Config.yml. * Config.yml.
* *
* @param plugin The plugin. * @param plugin The plugin.
*/ */
public ConfigYml(@NotNull final EcoPlugin plugin) { public ConfigYml(@NotNull final EcoPlugin plugin) {
super("config", true, plugin); super("config", plugin, true, ConfigType.YAML);
} }
/** /**
@@ -25,7 +26,7 @@ public class ConfigYml extends YamlBaseConfig {
*/ */
public ConfigYml(@NotNull final EcoPlugin plugin, public ConfigYml(@NotNull final EcoPlugin plugin,
final boolean removeUnused) { final boolean removeUnused) {
super("config", removeUnused, plugin); super("config", plugin, removeUnused, ConfigType.YAML);
} }
/** /**
@@ -36,7 +37,7 @@ public class ConfigYml extends YamlBaseConfig {
*/ */
public ConfigYml(@NotNull final EcoPlugin plugin, public ConfigYml(@NotNull final EcoPlugin plugin,
@NotNull final String name) { @NotNull final String name) {
super(name, true, plugin); super(name, plugin, true, ConfigType.YAML);
} }
/** /**
@@ -49,7 +50,6 @@ public class ConfigYml extends YamlBaseConfig {
public ConfigYml(@NotNull final EcoPlugin plugin, public ConfigYml(@NotNull final EcoPlugin plugin,
@NotNull final String name, @NotNull final String name,
final boolean removeUnused) { final boolean removeUnused) {
super(name, removeUnused, plugin); super(name, plugin, removeUnused, ConfigType.YAML);
} }
} }

View File

@@ -1,21 +1,22 @@
package com.willfp.eco.core.config.base; package com.willfp.eco.core.config.base;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.config.yaml.YamlBaseConfig; import com.willfp.eco.core.config.BaseConfig;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.util.StringUtils; import com.willfp.eco.util.StringUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/** /**
* Default plugin lang.yml. * Default plugin lang.yml.
*/ */
public class LangYml extends YamlBaseConfig { public class LangYml extends BaseConfig {
/** /**
* Lang.yml. * Lang.yml.
* *
* @param plugin The plugin. * @param plugin The plugin.
*/ */
public LangYml(@NotNull final EcoPlugin plugin) { public LangYml(@NotNull final EcoPlugin plugin) {
super("lang", false, plugin); super("lang", plugin, false, ConfigType.YAML);
} }
/** /**

View File

@@ -1,18 +1,27 @@
package com.willfp.eco.core.config.interfaces; package com.willfp.eco.core.config.interfaces;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.TransientConfig;
import com.willfp.eco.core.placeholder.PlaceholderInjectable;
import com.willfp.eco.core.placeholder.StaticPlaceholder;
import com.willfp.eco.util.NumberUtils;
import com.willfp.eco.util.StringUtils; import com.willfp.eco.util.StringUtils;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Objects;
/** /**
* All canfigs implement this interface. * All configs implement this interface.
* <p> * <p>
* Contains all methods that must exist in yaml and json configurations. * Contains all methods that must exist in yaml and json configurations.
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
public interface Config extends Cloneable { public interface Config extends Cloneable, PlaceholderInjectable {
/** /**
* Clears cache. * Clears cache.
*/ */
@@ -66,10 +75,12 @@ public interface Config extends Cloneable {
* Get subsection from config. * Get subsection from config.
* *
* @param path The key to check. * @param path The key to check.
* @return The subsection. Throws NPE if not found. * @return The subsection. Returns an empty section if not found.
*/ */
@NotNull @NotNull
Config getSubsection(@NotNull String path); default Config getSubsection(@NotNull String path) {
return Objects.requireNonNullElse(getSubsectionOrNull(path), new TransientConfig());
}
/** /**
* Get subsection from config. * Get subsection from config.
@@ -86,7 +97,44 @@ public interface Config extends Cloneable {
* @param path The key to fetch the value from. * @param path The key to fetch the value from.
* @return The found value, or 0 if not found. * @return The found value, or 0 if not found.
*/ */
int getInt(@NotNull String path); default int getInt(@NotNull String path) {
return Objects.requireNonNullElse(getIntOrNull(path), 0);
}
/**
* Get an integer from config with a specified default (not found) value.
*
* @param path The key to fetch the value from.
* @param def The value to default to if not found.
* @return The found value, or the default.
*/
default int getInt(@NotNull String path,
int def) {
return Objects.requireNonNullElse(getIntOrNull(path), def);
}
/**
* Get a decimal value via a mathematical expression.
*
* @param path The key to fetch the value from.
* @return The computed value, or 0 if not found or invalid.
*/
default int getIntFromExpression(@NotNull String path) {
return getIntFromExpression(path, null);
}
/**
* Get a decimal value via a mathematical expression.
*
* @param path The key to fetch the value from.
* @param player The player to evaluate placeholders with respect to.
* @return The computed value, or 0 if not found or invalid.
*/
default int getIntFromExpression(@NotNull String path,
@Nullable Player player) {
return Double.valueOf(getDoubleFromExpression(path, player)).intValue();
}
/** /**
* Get an integer from config. * Get an integer from config.
@@ -97,16 +145,6 @@ public interface Config extends Cloneable {
@Nullable @Nullable
Integer getIntOrNull(@NotNull String path); Integer getIntOrNull(@NotNull String path);
/**
* Get an integer from config with a specified default (not found) value.
*
* @param path The key to fetch the value from.
* @param def The value to default to if not found.
* @return The found value, or the default.
*/
int getInt(@NotNull String path,
int def);
/** /**
* Get a list of integers from config. * Get a list of integers from config.
* *
@@ -114,7 +152,9 @@ public interface Config extends Cloneable {
* @return The found value, or a blank {@link java.util.ArrayList} if not found. * @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/ */
@NotNull @NotNull
List<Integer> getInts(@NotNull String path); default List<Integer> getInts(@NotNull String path) {
return Objects.requireNonNullElse(getIntsOrNull(path), new ArrayList<>());
}
/** /**
* Get a list of integers from config. * Get a list of integers from config.
@@ -131,7 +171,9 @@ public interface Config extends Cloneable {
* @param path The key to fetch the value from. * @param path The key to fetch the value from.
* @return The found value, or false if not found. * @return The found value, or false if not found.
*/ */
boolean getBool(@NotNull String path); default boolean getBool(@NotNull String path) {
return Objects.requireNonNullElse(getBoolOrNull(path), false);
}
/** /**
* Get a boolean from config. * Get a boolean from config.
@@ -149,7 +191,9 @@ public interface Config extends Cloneable {
* @return The found value, or a blank {@link java.util.ArrayList} if not found. * @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/ */
@NotNull @NotNull
List<Boolean> getBools(@NotNull String path); default List<Boolean> getBools(@NotNull String path) {
return Objects.requireNonNullElse(getBoolsOrNull(path), new ArrayList<>());
}
/** /**
* Get a list of booleans from config. * Get a list of booleans from config.
@@ -168,7 +212,7 @@ public interface Config extends Cloneable {
*/ */
@NotNull @NotNull
default String getFormattedString(@NotNull String path) { default String getFormattedString(@NotNull String path) {
return getString(path, true); return getString(path, true, StringUtils.FormatOption.WITH_PLACEHOLDERS);
} }
/** /**
@@ -187,25 +231,25 @@ public interface Config extends Cloneable {
/** /**
* Get a string from config. * Get a string from config.
* <p> * <p>
* Formatted by default. * Not formatted.
* *
* @param path The key to fetch the value from. * @param path The key to fetch the value from.
* @return The found value, or an empty string if not found. * @return The found value, or an empty string if not found.
*/ */
@NotNull @NotNull
default String getString(@NotNull String path) { default String getString(@NotNull String path) {
return getString(path, true); return getString(path, false, StringUtils.FormatOption.WITHOUT_PLACEHOLDERS);
} }
/** /**
* Get a string from config. * Get a string from config.
* <p>
* This will be deprecated when {@link Config#getString(String)} no longer formats by default.
* *
* @param path The key to fetch the value from. * @param path The key to fetch the value from.
* @param format If the string should be formatted. * @param format If the string should be formatted.
* @return The found value, or an empty string if not found. * @return The found value, or an empty string if not found.
* @deprecated Since 6.18.0, {@link Config#getString(String)} is not formatted by default.
*/ */
@Deprecated(since = "6.18.0")
default String getString(@NotNull String path, default String getString(@NotNull String path,
boolean format) { boolean format) {
return this.getString(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS); return this.getString(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
@@ -235,9 +279,11 @@ public interface Config extends Cloneable {
* @return The found value, or an empty string if not found. * @return The found value, or an empty string if not found.
*/ */
@NotNull @NotNull
String getString(@NotNull String path, default String getString(@NotNull String path,
boolean format, boolean format,
@NotNull StringUtils.FormatOption option); @NotNull StringUtils.FormatOption option) {
return Objects.requireNonNullElse(getStringOrNull(path, format, option), "");
}
/** /**
* Get a formatted string from config. * Get a formatted string from config.
@@ -247,7 +293,7 @@ public interface Config extends Cloneable {
*/ */
@Nullable @Nullable
default String getFormattedStringOrNull(@NotNull String path) { default String getFormattedStringOrNull(@NotNull String path) {
return getStringOrNull(path, true); return getStringOrNull(path, true, StringUtils.FormatOption.WITH_PLACEHOLDERS);
} }
/** /**
@@ -273,19 +319,19 @@ public interface Config extends Cloneable {
*/ */
@Nullable @Nullable
default String getStringOrNull(@NotNull String path) { default String getStringOrNull(@NotNull String path) {
return getStringOrNull(path, true); return getStringOrNull(path, false, StringUtils.FormatOption.WITH_PLACEHOLDERS);
} }
/** /**
* Get a string from config. * Get a string from config.
* <p>
* This will be deprecated when {@link Config#getStringOrNull(String)} no longer formats by default.
* *
* @param path The key to fetch the value from. * @param path The key to fetch the value from.
* @param format If the string should be formatted. * @param format If the string should be formatted.
* @return The found value, or null if not found. * @return The found value, or null if not found.
* @deprecated Since 6.18.0, {@link Config#getString(String)} is not formatted by default.
*/ */
@Nullable @Nullable
@Deprecated(since = "6.18.0")
default String getStringOrNull(@NotNull String path, default String getStringOrNull(@NotNull String path,
boolean format) { boolean format) {
return this.getStringOrNull(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS); return this.getStringOrNull(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
@@ -350,28 +396,26 @@ public interface Config extends Cloneable {
/** /**
* Get a list of strings from config. * Get a list of strings from config.
* <p> * <p>
* Formatted by default. * Not formatted.
* <p>
* This will be changed in newer versions to <b>not</b> format by default.
* *
* @param path The key to fetch the value from. * @param path The key to fetch the value from.
* @return The found value, or a blank {@link java.util.ArrayList} if not found. * @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/ */
@NotNull @NotNull
default List<String> getStrings(@NotNull String path) { default List<String> getStrings(@NotNull String path) {
return getStrings(path, true); return getStrings(path, false, StringUtils.FormatOption.WITH_PLACEHOLDERS);
} }
/** /**
* Get a list of strings from config. * Get a list of strings from config.
* <p>
* This will be deprecated when {@link Config#getStrings(String)} no longer formats by default.
* *
* @param path The key to fetch the value from. * @param path The key to fetch the value from.
* @param format If the strings should be formatted. * @param format If the strings should be formatted.
* @return The found value, or a blank {@link java.util.ArrayList} if not found. * @return The found value, or a blank {@link java.util.ArrayList} if not found.
* @deprecated Since 6.18.0, {@link Config#getString(String)} is not formatted by default.
*/ */
@NotNull @NotNull
@Deprecated(since = "6.18.0")
default List<String> getStrings(@NotNull String path, default List<String> getStrings(@NotNull String path,
boolean format) { boolean format) {
return this.getStrings(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS); return this.getStrings(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
@@ -389,7 +433,7 @@ public interface Config extends Cloneable {
@Deprecated @Deprecated
default List<String> getStrings(@NotNull String path, default List<String> getStrings(@NotNull String path,
@NotNull StringUtils.FormatOption option) { @NotNull StringUtils.FormatOption option) {
return getStrings(path, true, option); return getStrings(path, false, option);
} }
/** /**
@@ -401,14 +445,16 @@ public interface Config extends Cloneable {
* @return The found value, or a blank {@link java.util.ArrayList} if not found. * @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/ */
@NotNull @NotNull
List<String> getStrings(@NotNull String path, default List<String> getStrings(@NotNull String path,
boolean format, boolean format,
@NotNull StringUtils.FormatOption option); @NotNull StringUtils.FormatOption option) {
return Objects.requireNonNullElse(getStringsOrNull(path, format, option), new ArrayList<>());
}
/** /**
* Get a list of strings from config. * Get a list of strings from config.
* <p> * <p>
* Formatted by default. * Formatted.
* *
* @param path The key to fetch the value from. * @param path The key to fetch the value from.
* @return The found value, or null if not found. * @return The found value, or null if not found.
@@ -421,7 +467,7 @@ public interface Config extends Cloneable {
/** /**
* Get a list of strings from config. * Get a list of strings from config.
* <p> * <p>
* Formatted by default. * Formatted.
* *
* @param path The key to fetch the value from. * @param path The key to fetch the value from.
* @param option The format option. * @param option The format option.
@@ -436,7 +482,7 @@ public interface Config extends Cloneable {
/** /**
* Get a list of strings from config. * Get a list of strings from config.
* <p> * <p>
* Formatted by default. * Not formatted.
* <p> * <p>
* This will be changed in newer versions to <b>not</b> format by default. * This will be changed in newer versions to <b>not</b> format by default.
* *
@@ -445,7 +491,7 @@ public interface Config extends Cloneable {
*/ */
@Nullable @Nullable
default List<String> getStringsOrNull(@NotNull String path) { default List<String> getStringsOrNull(@NotNull String path) {
return getStringsOrNull(path, true); return getStringsOrNull(path, false, StringUtils.FormatOption.WITH_PLACEHOLDERS);
} }
/** /**
@@ -454,8 +500,10 @@ public interface Config extends Cloneable {
* @param path The key to fetch the value from. * @param path The key to fetch the value from.
* @param format If the strings should be formatted. * @param format If the strings should be formatted.
* @return The found value, or null if not found. * @return The found value, or null if not found.
* @deprecated Since 6.18.0, {@link Config#getString(String)} is not formatted by default.
*/ */
@Nullable @Nullable
@Deprecated(since = "6.18.0")
default List<String> getStringsOrNull(@NotNull String path, default List<String> getStringsOrNull(@NotNull String path,
boolean format) { boolean format) {
return getStringsOrNull(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS); return getStringsOrNull(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
@@ -473,7 +521,7 @@ public interface Config extends Cloneable {
@Deprecated @Deprecated
default List<String> getStringsOrNull(@NotNull String path, default List<String> getStringsOrNull(@NotNull String path,
@NotNull StringUtils.FormatOption option) { @NotNull StringUtils.FormatOption option) {
return getStringsOrNull(path, true, option); return getStringsOrNull(path, false, option);
} }
/** /**
@@ -495,7 +543,31 @@ public interface Config extends Cloneable {
* @param path The key to fetch the value from. * @param path The key to fetch the value from.
* @return The found value, or 0 if not found. * @return The found value, or 0 if not found.
*/ */
double getDouble(@NotNull String path); default double getDouble(@NotNull String path) {
return Objects.requireNonNullElse(getDoubleOrNull(path), 0.0);
}
/**
* Get a decimal value via a mathematical expression.
*
* @param path The key to fetch the value from.
* @return The computed value, or 0 if not found or invalid.
*/
default double getDoubleFromExpression(@NotNull String path) {
return getDoubleFromExpression(path, null);
}
/**
* Get a decimal value via a mathematical expression.
*
* @param path The key to fetch the value from.
* @param player The player to evaluate placeholders with respect to.
* @return The computed value, or 0 if not found or invalid.
*/
default double getDoubleFromExpression(@NotNull String path,
@Nullable Player player) {
return NumberUtils.evaluateExpression(this.getString(path), player, this.getInjectedPlaceholders());
}
/** /**
* Get a decimal from config. * Get a decimal from config.
@@ -513,7 +585,9 @@ public interface Config extends Cloneable {
* @return The found value, or a blank {@link java.util.ArrayList} if not found. * @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/ */
@NotNull @NotNull
List<Double> getDoubles(@NotNull String path); default List<Double> getDoubles(@NotNull String path) {
return Objects.requireNonNullElse(getDoublesOrNull(path), new ArrayList<>());
}
/** /**
* Get a list of decimals from config. * Get a list of decimals from config.
@@ -524,10 +598,53 @@ public interface Config extends Cloneable {
@Nullable @Nullable
List<Double> getDoublesOrNull(@NotNull String path); List<Double> getDoublesOrNull(@NotNull String path);
/**
* Get a list of subsections from config.
*
* @param path The key to fetch the value from.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@NotNull
default List<? extends Config> getSubsections(@NotNull String path) {
return Objects.requireNonNullElse(getSubsectionsOrNull(path), new ArrayList<>());
}
/**
* Get a list of subsections from config.
*
* @param path The key to fetch the value from.
* @return The found value, or null if not found.
*/
@Nullable
List<? extends Config> getSubsectionsOrNull(@NotNull String path);
/**
* Get config type.
*
* @return The type.
*/
@NotNull
ConfigType getType();
/** /**
* Clone the config. * Clone the config.
* *
* @return The clone. * @return The clone.
*/ */
Config clone(); Config clone();
@Override
default void injectPlaceholders(@NotNull Iterable<StaticPlaceholder> placeholders) {
// Do nothing.
}
@Override
default List<StaticPlaceholder> getInjectedPlaceholders() {
return Collections.emptyList();
}
@Override
default void clearInjectedPlaceholders() {
// Do nothing.
}
} }

View File

@@ -3,13 +3,19 @@ package com.willfp.eco.core.config.interfaces;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
/** /**
* JSON configs have extra methods compared to yaml configs. * JSON config.
* <p> *
* If you need to use them, then use JSONConfig instead. * @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/ */
@Deprecated(since = "6.17.0")
@SuppressWarnings("DeprecatedIsStillUsed")
public interface JSONConfig extends Config { public interface JSONConfig extends Config {
/** /**
* Get a list of subsections from config. * Get a list of subsections from config.
@@ -18,7 +24,9 @@ public interface JSONConfig extends Config {
* @return The found value, or a blank {@link java.util.ArrayList} if not found. * @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/ */
@NotNull @NotNull
List<JSONConfig> getSubsections(@NotNull String path); default List<JSONConfig> getSubsections(@NotNull String path) {
return Objects.requireNonNullElse(getSubsectionsOrNull(path), new ArrayList<>());
}
/** /**
* Get a list of subsections from config. * Get a list of subsections from config.

View File

@@ -1,12 +1,16 @@
package com.willfp.eco.core.config.interfaces; package com.willfp.eco.core.config.interfaces;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.Nullable;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
/** /**
* Interface for configs that physically exist as files in plugins. * Interface for configs that physically exist as files in plugins.
*/ */
public interface LoadableConfig { public interface LoadableConfig extends Config {
/** /**
* Create the file. * Create the file.
*/ */
@@ -39,4 +43,18 @@ public interface LoadableConfig {
* @return The name. * @return The name.
*/ */
String getName(); String getName();
/**
* Get bukkit {@link YamlConfiguration}.
* <p>
* This method is not recommended unless absolutely required as it
* only returns true if the type of config is {@link com.willfp.eco.core.config.ConfigType#YAML},
* and if the handle is an {@link YamlConfiguration} specifically. This depends on the internals
* and the implementation, and so may cause problems - it exists mostly for parity with
* {@link JavaPlugin#getConfig()}.
*
* @return The config, or null if config is not yaml-based.
*/
@Nullable
YamlConfiguration getBukkitHandle();
} }

View File

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

View File

@@ -3,6 +3,8 @@ package com.willfp.eco.core.config.json;
import com.willfp.eco.core.Eco; import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike; import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper; import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -10,7 +12,12 @@ import org.jetbrains.annotations.NotNull;
* Config implementation for configs present in the plugin's base directory (eg config.json). * Config implementation for configs present in the plugin's base directory (eg config.json).
* <p> * <p>
* Automatically updates. * Automatically updates.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/ */
@Deprecated(since = "6.17.0")
public abstract class JSONBaseConfig extends LoadableJSONConfigWrapper { public abstract class JSONBaseConfig extends LoadableJSONConfigWrapper {
/** /**
* @param configName The name of the config * @param configName The name of the config
@@ -23,12 +30,15 @@ public abstract class JSONBaseConfig extends LoadableJSONConfigWrapper {
@NotNull final PluginLike plugin, @NotNull final PluginLike plugin,
@NotNull final String... updateBlacklist) { @NotNull final String... updateBlacklist) {
super( super(
Eco.getHandler().getConfigFactory().createUpdatableJSONConfig( (JSONConfig)
Eco.getHandler().getConfigFactory().createUpdatableConfig(
configName, configName,
plugin, plugin,
"", "",
plugin.getClass(), plugin.getClass(),
removeUnused, updateBlacklist removeUnused,
ConfigType.JSON,
updateBlacklist
) )
); );
} }
@@ -42,12 +52,14 @@ public abstract class JSONBaseConfig extends LoadableJSONConfigWrapper {
final boolean removeUnused, final boolean removeUnused,
@NotNull final PluginLike plugin) { @NotNull final PluginLike plugin) {
super( super(
Eco.getHandler().getConfigFactory().createUpdatableJSONConfig( (JSONConfig)
Eco.getHandler().getConfigFactory().createUpdatableConfig(
configName, configName,
plugin, plugin,
"", "",
plugin.getClass(), plugin.getClass(),
removeUnused removeUnused,
ConfigType.JSON
) )
); );
} }

View File

@@ -3,6 +3,8 @@ package com.willfp.eco.core.config.json;
import com.willfp.eco.core.Eco; import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike; import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper; import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -14,7 +16,12 @@ import org.jetbrains.annotations.NotNull;
* </ul> * </ul>
* <p> * <p>
* Automatically updates. * Automatically updates.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/ */
@Deprecated(since = "6.17.0")
public abstract class JSONExtendableConfig extends LoadableJSONConfigWrapper { public abstract class JSONExtendableConfig extends LoadableJSONConfigWrapper {
/** /**
* @param configName The name of the config * @param configName The name of the config
@@ -31,16 +38,19 @@ public abstract class JSONExtendableConfig extends LoadableJSONConfigWrapper {
@NotNull final String subDirectoryPath, @NotNull final String subDirectoryPath,
@NotNull final String... updateBlacklist) { @NotNull final String... updateBlacklist) {
super( super(
Eco.getHandler().getConfigFactory().createUpdatableJSONConfig( (JSONConfig)
Eco.getHandler().getConfigFactory().createUpdatableConfig(
configName, configName,
plugin, plugin,
subDirectoryPath, subDirectoryPath,
source, source,
removeUnused, removeUnused,
ConfigType.JSON,
updateBlacklist updateBlacklist
) )
); );
} }
/** /**
* @param configName The name of the config * @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update. * @param removeUnused Whether keys not present in the default config should be removed on update.

View File

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

View File

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

View File

@@ -9,7 +9,12 @@ import java.util.List;
/** /**
* Wrapper to handle the backend JSON config implementations. * Wrapper to handle the backend JSON config implementations.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/ */
@Deprecated(since = "6.17.0")
public abstract class JSONConfigWrapper extends ConfigWrapper<JSONConfig> implements JSONConfig { public abstract class JSONConfigWrapper extends ConfigWrapper<JSONConfig> implements JSONConfig {
/** /**
* Create a config wrapper. * Create a config wrapper.

View File

@@ -3,14 +3,21 @@ package com.willfp.eco.core.config.json.wrapper;
import com.willfp.eco.core.config.interfaces.JSONConfig; import com.willfp.eco.core.config.interfaces.JSONConfig;
import com.willfp.eco.core.config.interfaces.LoadableConfig; import com.willfp.eco.core.config.interfaces.LoadableConfig;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
/** /**
* Wrapper to handle the backend loadable JSON config implementations. * Wrapper to handle the backend loadable JSON config implementations.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/ */
@Deprecated(since = "6.17.0")
public abstract class LoadableJSONConfigWrapper extends JSONConfigWrapper implements LoadableConfig { public abstract class LoadableJSONConfigWrapper extends JSONConfigWrapper implements LoadableConfig {
/** /**
* Create a config wrapper. * Create a config wrapper.
@@ -48,4 +55,9 @@ public abstract class LoadableJSONConfigWrapper extends JSONConfigWrapper implem
public String getName() { public String getName() {
return ((LoadableConfig) this.getHandle()).getName(); return ((LoadableConfig) this.getHandle()).getName();
} }
@Override
public @Nullable YamlConfiguration getBukkitHandle() {
return null;
}
} }

View File

@@ -23,10 +23,14 @@ import java.lang.annotation.Target;
* <p> * <p>
* The second: * The second:
* <pre>{@code * <pre>{@code
* public static void update(EcoPlugin plugin) {} * public static void update(EcoPlugin plugin) {
* // Update code * // Update code
* }
* }</pre> * }</pre>
* <p> * <p>
* If using kotlin, you have to annotate the method with {@code @JvmStatic}
* in order to prevent null pointer exceptions.
* <p>
* Config update methods in all classes in a plugin jar will be called * Config update methods in all classes in a plugin jar will be called
* on reload. * on reload.
* <p> * <p>

View File

@@ -1,9 +1,12 @@
package com.willfp.eco.core.config.wrapper; package com.willfp.eco.core.config.wrapper;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.PluginLike; 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.Config;
import com.willfp.eco.core.config.interfaces.JSONConfig; import com.willfp.eco.core.config.interfaces.LoadableConfig;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Map; import java.util.Map;
@@ -11,6 +14,8 @@ import java.util.Map;
/** /**
* Internal component to create backend config implementations. * Internal component to create backend config implementations.
*/ */
@ApiStatus.Internal
@Eco.HandlerComponent
public interface ConfigFactory { public interface ConfigFactory {
/** /**
* Updatable config. * Updatable config.
@@ -20,75 +25,57 @@ public interface ConfigFactory {
* @param subDirectoryPath The subdirectory path. * @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource. * @param source The class that owns the resource.
* @param removeUnused Whether keys not present in the default config should be removed on update. * @param removeUnused Whether keys not present in the default config should be removed on update.
* @param type The config type.
* @param updateBlacklist Substring of keys to not add/remove keys for. * @param updateBlacklist Substring of keys to not add/remove keys for.
* @return The config implementation. * @return The config implementation.
*/ */
Config createUpdatableYamlConfig(@NotNull String configName, LoadableConfig createUpdatableConfig(@NotNull String configName,
@NotNull PluginLike plugin, @NotNull PluginLike plugin,
@NotNull String subDirectoryPath, @NotNull String subDirectoryPath,
@NotNull Class<?> source, @NotNull Class<?> source,
boolean removeUnused, boolean removeUnused,
@NotNull ConfigType type,
@NotNull String... updateBlacklist); @NotNull String... updateBlacklist);
/** /**
* Updatable config. * Loadable config.
* *
* @param configName The name of the config * @param configName The name of the config
* @param plugin The plugin. * @param plugin The plugin.
* @param subDirectoryPath The subdirectory path. * @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource. * @param source The class that owns the resource.
* @param removeUnused Whether keys not present in the default config should be removed on update. * @param type The config type.
* @param updateBlacklist Substring of keys to not add/remove keys for.
* @return The config implementation. * @return The config implementation.
*/ */
JSONConfig createUpdatableJSONConfig(@NotNull String configName, LoadableConfig createLoadableConfig(@NotNull String configName,
@NotNull PluginLike plugin, @NotNull PluginLike plugin,
@NotNull String subDirectoryPath, @NotNull String subDirectoryPath,
@NotNull Class<?> source, @NotNull Class<?> source,
boolean removeUnused, @NotNull ConfigType type);
@NotNull String... updateBlacklist);
/** /**
* JSON loadable config. * Create 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.
* @return The config implementation.
*/
JSONConfig createLoadableJSONConfig(@NotNull String configName,
@NotNull PluginLike plugin,
@NotNull String subDirectoryPath,
@NotNull Class<?> source);
/**
* Yaml 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.
* @return The config implementation.
*/
Config createLoadableYamlConfig(@NotNull String configName,
@NotNull PluginLike plugin,
@NotNull String subDirectoryPath,
@NotNull Class<?> source);
/**
* Yaml config.
* *
* @param config The handle. * @param config The handle.
* @return The config implementation. * @return The config implementation.
*/ */
Config createYamlConfig(@NotNull YamlConfiguration config); Config createConfig(@NotNull YamlConfiguration config);
/** /**
* JSON config. * Create config.
* *
* @param values The values. * @param values The values.
* @return The config implementation. * @return The config implementation.
*/ */
JSONConfig createJSONConfig(@NotNull Map<String, Object> values); Config createConfig(@NotNull Map<String, Object> values);
/**
* Create config.
*
* @param contents The file contents.
* @param type The type.
* @return The config implementation.
*/
Config createConfig(@NotNull String contents,
@NotNull ConfigType type);
} }

View File

@@ -1,6 +1,8 @@
package com.willfp.eco.core.config.wrapper; package com.willfp.eco.core.config.wrapper;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.interfaces.Config; import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.placeholder.StaticPlaceholder;
import com.willfp.eco.util.StringUtils; import com.willfp.eco.util.StringUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -15,6 +17,7 @@ import java.util.List;
* *
* @param <T> The type of the handle. * @param <T> The type of the handle.
*/ */
@SuppressWarnings("MethodDoesntCallSuperMethod")
public abstract class ConfigWrapper<T extends Config> implements Config { public abstract class ConfigWrapper<T extends Config> implements Config {
/** /**
* Configs from eco have an internal implementation, * Configs from eco have an internal implementation,
@@ -68,70 +71,31 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
handle.set(path, object); handle.set(path, object);
} }
@Override
public @NotNull Config getSubsection(@NotNull final String path) {
return handle.getSubsection(path);
}
@Override @Override
public @Nullable Config getSubsectionOrNull(@NotNull final String path) { public @Nullable Config getSubsectionOrNull(@NotNull final String path) {
return handle.getSubsectionOrNull(path); return handle.getSubsectionOrNull(path);
} }
@Override
public int getInt(@NotNull final String path) {
return handle.getInt(path);
}
@Override @Override
public @Nullable Integer getIntOrNull(@NotNull final String path) { public @Nullable Integer getIntOrNull(@NotNull final String path) {
return handle.getIntOrNull(path); return handle.getIntOrNull(path);
} }
@Override
public int getInt(@NotNull final String path,
final int def) {
return handle.getInt(path, def);
}
@Override
public @NotNull List<Integer> getInts(@NotNull final String path) {
return handle.getInts(path);
}
@Override @Override
public @Nullable List<Integer> getIntsOrNull(@NotNull final String path) { public @Nullable List<Integer> getIntsOrNull(@NotNull final String path) {
return handle.getIntsOrNull(path); return handle.getIntsOrNull(path);
} }
@Override
public boolean getBool(@NotNull final String path) {
return handle.getBool(path);
}
@Override @Override
public @Nullable Boolean getBoolOrNull(@NotNull final String path) { public @Nullable Boolean getBoolOrNull(@NotNull final String path) {
return handle.getBoolOrNull(path); return handle.getBoolOrNull(path);
} }
@Override
public @NotNull List<Boolean> getBools(@NotNull final String path) {
return handle.getBools(path);
}
@Override @Override
public @Nullable List<Boolean> getBoolsOrNull(@NotNull final String path) { public @Nullable List<Boolean> getBoolsOrNull(@NotNull final String path) {
return handle.getBoolsOrNull(path); return handle.getBoolsOrNull(path);
} }
@Override
public @NotNull String getString(@NotNull final String path,
final boolean format,
@NotNull final StringUtils.FormatOption option) {
return handle.getString(path, format, option);
}
@Override @Override
public @Nullable String getStringOrNull(@NotNull final String path, public @Nullable String getStringOrNull(@NotNull final String path,
final boolean format, final boolean format,
@@ -139,13 +103,6 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
return handle.getStringOrNull(path, format, option); return handle.getStringOrNull(path, format, option);
} }
@Override
public @NotNull List<String> getStrings(@NotNull final String path,
final boolean format,
@NotNull final StringUtils.FormatOption option) {
return handle.getStrings(path, format, option);
}
@Override @Override
public @Nullable List<String> getStringsOrNull(@NotNull final String path, public @Nullable List<String> getStringsOrNull(@NotNull final String path,
final boolean format, final boolean format,
@@ -153,31 +110,51 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
return handle.getStringsOrNull(path, format, option); return handle.getStringsOrNull(path, format, option);
} }
@Override
public double getDouble(@NotNull final String path) {
return handle.getDouble(path);
}
@Override @Override
public @Nullable Double getDoubleOrNull(@NotNull final String path) { public @Nullable Double getDoubleOrNull(@NotNull final String path) {
return handle.getDoubleOrNull(path); return handle.getDoubleOrNull(path);
} }
@Override
public @NotNull List<Double> getDoubles(@NotNull final String path) {
return handle.getDoubles(path);
}
@Override @Override
public @Nullable List<Double> getDoublesOrNull(@NotNull final String path) { public @Nullable List<Double> getDoublesOrNull(@NotNull final String path) {
return handle.getDoublesOrNull(path); return handle.getDoublesOrNull(path);
} }
@Override
public @Nullable List<? extends Config> getSubsectionsOrNull(@NotNull final String path) {
return handle.getSubsectionsOrNull(path);
}
@Override @Override
public Config clone() { public Config clone() {
return handle.clone(); return handle.clone();
} }
@Override
public @NotNull ConfigType getType() {
return handle.getType();
}
@Override
public void injectPlaceholders(@NotNull final StaticPlaceholder... placeholders) {
handle.injectPlaceholders(placeholders);
}
@Override
public void injectPlaceholders(@NotNull final Iterable<StaticPlaceholder> placeholders) {
handle.injectPlaceholders(placeholders);
}
@Override
public List<StaticPlaceholder> getInjectedPlaceholders() {
return handle.getInjectedPlaceholders();
}
@Override
public void clearInjectedPlaceholders() {
handle.clearInjectedPlaceholders();
}
/** /**
* Get the handle. * Get the handle.
* *

View File

@@ -0,0 +1,53 @@
package com.willfp.eco.core.config.wrapper;
import com.willfp.eco.core.config.interfaces.LoadableConfig;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
/**
* Wrapper to handle the backend loadable yaml config implementations.
*/
public abstract class LoadableConfigWrapper extends ConfigWrapper<LoadableConfig> implements LoadableConfig {
/**
* Create a config wrapper.
*
* @param handle The handle.
*/
protected LoadableConfigWrapper(@NotNull final LoadableConfig handle) {
super(handle);
}
@Override
public void createFile() {
this.getHandle().createFile();
}
@Override
public String getResourcePath() {
return this.getHandle().getResourcePath();
}
@Override
public void save() throws IOException {
this.getHandle().save();
}
@Override
public File getConfigFile() {
return this.getHandle().getConfigFile();
}
@Override
public String getName() {
return this.getHandle().getName();
}
@Override
public @Nullable YamlConfiguration getBukkitHandle() {
return this.getHandle().getBukkitHandle();
}
}

View File

@@ -3,6 +3,7 @@ package com.willfp.eco.core.config.yaml;
import com.willfp.eco.core.Eco; import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike; import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper; import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -10,7 +11,12 @@ import org.jetbrains.annotations.NotNull;
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml). * Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
* <p> * <p>
* Automatically updates. * Automatically updates.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/ */
@Deprecated(since = "6.17.0")
public abstract class YamlBaseConfig extends LoadableYamlConfigWrapper { public abstract class YamlBaseConfig extends LoadableYamlConfigWrapper {
/** /**
* @param configName The name of the config * @param configName The name of the config
@@ -23,12 +29,14 @@ public abstract class YamlBaseConfig extends LoadableYamlConfigWrapper {
@NotNull final PluginLike plugin, @NotNull final PluginLike plugin,
@NotNull final String... updateBlacklist) { @NotNull final String... updateBlacklist) {
super( super(
Eco.getHandler().getConfigFactory().createUpdatableYamlConfig( Eco.getHandler().getConfigFactory().createUpdatableConfig(
configName, configName,
plugin, plugin,
"", "",
plugin.getClass(), plugin.getClass(),
removeUnused, updateBlacklist removeUnused,
ConfigType.YAML,
updateBlacklist
) )
); );
} }
@@ -42,12 +50,13 @@ public abstract class YamlBaseConfig extends LoadableYamlConfigWrapper {
final boolean removeUnused, final boolean removeUnused,
@NotNull final PluginLike plugin) { @NotNull final PluginLike plugin) {
super( super(
Eco.getHandler().getConfigFactory().createUpdatableYamlConfig( Eco.getHandler().getConfigFactory().createUpdatableConfig(
configName, configName,
plugin, plugin,
"", "",
plugin.getClass(), plugin.getClass(),
removeUnused removeUnused,
ConfigType.YAML
) )
); );
} }

View File

@@ -3,6 +3,7 @@ package com.willfp.eco.core.config.yaml;
import com.willfp.eco.core.Eco; import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginLike; import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper; import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -14,7 +15,12 @@ import org.jetbrains.annotations.NotNull;
* </ul> * </ul>
* <p> * <p>
* Automatically updates. * Automatically updates.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/ */
@Deprecated(since = "6.17.0")
public abstract class YamlExtendableConfig extends LoadableYamlConfigWrapper { public abstract class YamlExtendableConfig extends LoadableYamlConfigWrapper {
/** /**
* @param configName The name of the config * @param configName The name of the config
@@ -31,16 +37,18 @@ public abstract class YamlExtendableConfig extends LoadableYamlConfigWrapper {
@NotNull final String subDirectoryPath, @NotNull final String subDirectoryPath,
@NotNull final String... updateBlacklist) { @NotNull final String... updateBlacklist) {
super( super(
Eco.getHandler().getConfigFactory().createUpdatableYamlConfig( Eco.getHandler().getConfigFactory().createUpdatableConfig(
configName, configName,
plugin, plugin,
subDirectoryPath, subDirectoryPath,
source, source,
removeUnused, removeUnused,
ConfigType.YAML,
updateBlacklist updateBlacklist
) )
); );
} }
/** /**
* @param configName The name of the config * @param configName The name of the config
* @param removeUnused Whether keys not present in the default config should be removed on update. * @param removeUnused Whether keys not present in the default config should be removed on update.

View File

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

View File

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

View File

@@ -3,14 +3,21 @@ package com.willfp.eco.core.config.yaml.wrapper;
import com.willfp.eco.core.config.interfaces.Config; import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.config.interfaces.LoadableConfig; import com.willfp.eco.core.config.interfaces.LoadableConfig;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
/** /**
* Wrapper to handle the backend loadable yaml config implementations. * Wrapper to handle the backend loadable yaml config implementations.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/ */
@Deprecated(since = "6.17.0")
public abstract class LoadableYamlConfigWrapper extends YamlConfigWrapper implements LoadableConfig { public abstract class LoadableYamlConfigWrapper extends YamlConfigWrapper implements LoadableConfig {
/** /**
* Create a config wrapper. * Create a config wrapper.
@@ -48,4 +55,9 @@ public abstract class LoadableYamlConfigWrapper extends YamlConfigWrapper implem
public String getName() { public String getName() {
return ((LoadableConfig) this.getHandle()).getName(); return ((LoadableConfig) this.getHandle()).getName();
} }
@Override
public @Nullable YamlConfiguration getBukkitHandle() {
return ((LoadableConfig) this.getHandle()).getBukkitHandle();
}
} }

View File

@@ -8,7 +8,12 @@ import org.jetbrains.annotations.NotNull;
/** /**
* Wrapper to handle the backend yaml config implementations. * Wrapper to handle the backend yaml config implementations.
*
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
* These configs will be removed eventually.
*/ */
@Deprecated(since = "6.17.0")
public abstract class YamlConfigWrapper extends ConfigWrapper<Config> implements WrappedYamlConfiguration { public abstract class YamlConfigWrapper extends ConfigWrapper<Config> implements WrappedYamlConfiguration {
/** /**
* Create a config wrapper. * Create a config wrapper.

View File

@@ -1,7 +1,6 @@
package com.willfp.eco.core.data; package com.willfp.eco.core.data;
import com.willfp.eco.core.Eco; import com.willfp.eco.core.Eco;
import com.willfp.eco.core.data.keys.PersistentDataKey;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -12,26 +11,7 @@ import java.util.UUID;
* <p> * <p>
* Profiles save automatically, so there is no need to save after changes. * Profiles save automatically, so there is no need to save after changes.
*/ */
public interface PlayerProfile { public interface PlayerProfile extends Profile {
/**
* Write a key to a player's persistent data.
*
* @param key The key.
* @param value The value.
* @param <T> The type of the key.
*/
<T> void write(@NotNull PersistentDataKey<T> key,
@NotNull T value);
/**
* Read a key from a player's persistent data.
*
* @param key The key.
* @param <T> The type of the key.
* @return The value, or the default value if not found.
*/
<T> @NotNull T read(@NotNull PersistentDataKey<T> key);
/** /**
* Load a player profile. * Load a player profile.
* *
@@ -51,6 +31,6 @@ public interface PlayerProfile {
*/ */
@NotNull @NotNull
static PlayerProfile load(@NotNull final UUID uuid) { static PlayerProfile load(@NotNull final UUID uuid) {
return Eco.getHandler().getPlayerProfileHandler().load(uuid); return Eco.getHandler().getProfileHandler().load(uuid);
} }
} }

View File

@@ -0,0 +1,30 @@
package com.willfp.eco.core.data;
import com.willfp.eco.core.data.keys.PersistentDataKey;
import org.jetbrains.annotations.NotNull;
/**
* Persistent data storage interface.
* <p>
* Profiles save automatically, so there is no need to save after changes.
*/
public interface Profile {
/**
* Write a key to persistent data.
*
* @param key The key.
* @param value The value.
* @param <T> The type of the key.
*/
<T> void write(@NotNull PersistentDataKey<T> key,
@NotNull T value);
/**
* Read a key from persistent data.
*
* @param key The key.
* @param <T> The type of the key.
* @return The value, or the default value if not found.
*/
<T> @NotNull T read(@NotNull PersistentDataKey<T> key);
}

View File

@@ -1,15 +1,19 @@
package com.willfp.eco.core.data; package com.willfp.eco.core.data;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.data.keys.PersistentDataKey; import com.willfp.eco.core.data.keys.PersistentDataKey;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
/** /**
* API to handle player profiles. * API to handle profiles.
*/ */
public interface PlayerProfileHandler { @ApiStatus.Internal
@Eco.HandlerComponent
public interface ProfileHandler {
/** /**
* Load a player profile. * Load a player profile.
* *
@@ -18,6 +22,13 @@ public interface PlayerProfileHandler {
*/ */
PlayerProfile load(@NotNull UUID uuid); PlayerProfile load(@NotNull UUID uuid);
/**
* Load the server profile.
*
* @return The profile.
*/
ServerProfile loadServerProfile();
/** /**
* Unload a player profile from memory. * Unload a player profile from memory.
* <p> * <p>
@@ -37,7 +48,7 @@ public interface PlayerProfileHandler {
*/ */
@Deprecated @Deprecated
default void savePlayer(@NotNull UUID uuid) { default void savePlayer(@NotNull UUID uuid) {
this.saveKeysForPlayer(uuid, PersistentDataKey.values()); this.saveKeysFor(uuid, PersistentDataKey.values());
} }
/** /**
@@ -48,7 +59,7 @@ public interface PlayerProfileHandler {
* @param uuid The uuid. * @param uuid The uuid.
* @param keys The keys. * @param keys The keys.
*/ */
void saveKeysForPlayer(@NotNull UUID uuid, void saveKeysFor(@NotNull UUID uuid,
@NotNull Set<PersistentDataKey<?>> keys); @NotNull Set<PersistentDataKey<?>> keys);
/** /**

View File

@@ -0,0 +1,21 @@
package com.willfp.eco.core.data;
import com.willfp.eco.core.Eco;
import org.jetbrains.annotations.NotNull;
/**
* Persistent data storage interface for servers.
* <p>
* Profiles save automatically, so there is no need to save after changes.
*/
public interface ServerProfile extends Profile {
/**
* Load the server profile.
*
* @return The profile.
*/
@NotNull
static ServerProfile load() {
return Eco.getHandler().getProfileHandler().loadServerProfile();
}
}

View File

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

View File

@@ -3,7 +3,9 @@ package com.willfp.eco.core.data.keys;
import com.willfp.eco.core.Eco; import com.willfp.eco.core.Eco;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
import java.util.Set; import java.util.Set;
/** /**
@@ -11,7 +13,7 @@ import java.util.Set;
* *
* @param <T> The type of the data. * @param <T> The type of the data.
*/ */
public class PersistentDataKey<T> { public final class PersistentDataKey<T> {
/** /**
* The key of the persistent data value. * The key of the persistent data value.
*/ */
@@ -25,7 +27,7 @@ public class PersistentDataKey<T> {
/** /**
* The persistent data key type. * The persistent data key type.
*/ */
private final PersistentDataKeyType type; private final PersistentDataKeyType<T> type;
/** /**
* Create a new Persistent Data Key. * Create a new Persistent Data Key.
@@ -35,7 +37,7 @@ public class PersistentDataKey<T> {
* @param defaultValue The default value. * @param defaultValue The default value.
*/ */
public PersistentDataKey(@NotNull final NamespacedKey key, public PersistentDataKey(@NotNull final NamespacedKey key,
@NotNull final PersistentDataKeyType type, @NotNull final PersistentDataKeyType<T> type,
@NotNull final T defaultValue) { @NotNull final T defaultValue) {
this.key = key; this.key = key;
this.defaultValue = defaultValue; this.defaultValue = defaultValue;
@@ -53,15 +55,6 @@ public class PersistentDataKey<T> {
+ '}'; + '}';
} }
/**
* Get all persistent data keys.
*
* @return The keys.
*/
public static Set<PersistentDataKey<?>> values() {
return Eco.getHandler().getKeyRegistry().getRegisteredKeys();
}
/** /**
* Get the key. * Get the key.
* *
@@ -85,7 +78,58 @@ public class PersistentDataKey<T> {
* *
* @return The key type. * @return The key type.
*/ */
public PersistentDataKeyType getType() { public PersistentDataKeyType<T> getType() {
return this.type; return this.type;
} }
/**
* 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.
*/
public PersistentDataKey<T> server() {
Eco.getHandler().getKeyRegistry().markKeyAs(this, KeyRegistry.KeyCategory.SERVER);
return this;
}
/**
* 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.
*/
public PersistentDataKey<T> player() {
Eco.getHandler().getKeyRegistry().markKeyAs(this, KeyRegistry.KeyCategory.PLAYER);
return this;
}
/**
* Get all persistent data keys.
*
* @return The keys.
*/
public static Set<PersistentDataKey<?>> values() {
return Eco.getHandler().getKeyRegistry().getRegisteredKeys();
}
@Override
public boolean equals(@Nullable final Object o) {
if (this == o) {
return true;
}
if (!(o instanceof PersistentDataKey that)) {
return false;
}
return Objects.equals(this.getKey(), that.getKey());
}
@Override
public int hashCode() {
return Objects.hash(this.getKey());
}
} }

View File

@@ -1,26 +1,108 @@
package com.willfp.eco.core.data.keys; package com.willfp.eco.core.data.keys;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
/** /**
* All storable data key types. * All storable data key types.
*
* @param <T> The type.
*/ */
public enum PersistentDataKeyType { public final class PersistentDataKeyType<T> {
/**
* The registered key types.
*/
private static final List<PersistentDataKeyType<?>> VALUES = new ArrayList<>();
/** /**
* String. * String.
*/ */
STRING, public static final PersistentDataKeyType<String> STRING = new PersistentDataKeyType<>(String.class, "STRING");
/** /**
* Boolean. * Boolean.
*/ */
BOOLEAN, public static final PersistentDataKeyType<Boolean> BOOLEAN = new PersistentDataKeyType<>(Boolean.class, "BOOLEAN");
/** /**
* Integer. * Int.
*/ */
INT, public static final PersistentDataKeyType<Integer> INT = new PersistentDataKeyType<>(Integer.class, "INT");
/** /**
* Double. * Double.
*/ */
DOUBLE public static final PersistentDataKeyType<Double> DOUBLE = new PersistentDataKeyType<>(Double.class, "DOUBLE");
/**
* The class of the type.
*/
private final Class<T> typeClass;
/**
* The name of the key type.
*/
private final String name;
/**
* Get the class of the type.
*
* @return The class.
*/
public Class<T> getTypeClass() {
return typeClass;
}
/**
* Get the name of the key type.
*
* @return The name.
*/
public String name() {
return name;
}
/**
* Create new PersistentDataKeyType.
*
* @param typeClass The type class.
* @param name The name.
*/
private PersistentDataKeyType(@NotNull final Class<T> typeClass,
@NotNull final String name) {
VALUES.add(this);
this.typeClass = typeClass;
this.name = name;
}
/**
* Get all registered {@link PersistentDataKeyType}s.
*
* @return The registered types.
*/
@NotNull
public static PersistentDataKeyType<?>[] values() {
return VALUES.toArray(new PersistentDataKeyType[0]);
}
/**
* Get a key type from a name.
*
* @param name The name.
* @return The type, or null if not found.
*/
@Nullable
public static PersistentDataKeyType<?> valueOf(@NotNull final String name) {
for (PersistentDataKeyType<?> type : VALUES) {
if (type.name.equalsIgnoreCase(name)) {
return type;
}
}
return null;
}
} }

View File

@@ -1,13 +1,17 @@
package com.willfp.eco.core.display; package com.willfp.eco.core.display;
import com.willfp.eco.core.Eco;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
/** /**
* Interface for display implementations. * Interface for display implementations.
*/ */
@ApiStatus.Internal
@Eco.HandlerComponent
public interface DisplayHandler { public interface DisplayHandler {
/** /**
* Register display module. * Register display module.

View File

@@ -1,11 +1,15 @@
package com.willfp.eco.core.drops; package com.willfp.eco.core.drops;
import com.willfp.eco.core.Eco;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/** /**
* Internal component to create backend DropQueue implementations. * Internal component to create backend DropQueue implementations.
*/ */
@ApiStatus.Internal
@Eco.HandlerComponent
public interface DropQueueFactory { public interface DropQueueFactory {
/** /**
* Create a DropQueue. * Create a DropQueue.

View File

@@ -1,7 +1,9 @@
package com.willfp.eco.core.drops; package com.willfp.eco.core.drops;
import com.willfp.eco.core.Eco;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Collection; import java.util.Collection;
@@ -9,6 +11,8 @@ import java.util.Collection;
/** /**
* Internal interface for backend DropQueue implementations. * Internal interface for backend DropQueue implementations.
*/ */
@ApiStatus.Internal
@Eco.HandlerComponent
public interface InternalDropQueue { public interface InternalDropQueue {
/** /**
* Add item to queue. * Add item to queue.

View File

@@ -0,0 +1,84 @@
package com.willfp.eco.core.entities;
import org.apache.commons.lang.Validate;
import org.bukkit.Location;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Entity;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Function;
import java.util.function.Predicate;
/**
* A custom entity has 3 components.
*
* <ul>
* <li>The key to identify it</li>
* <li>The test to check if any entity is this custom entity</li>
* <li>The supplier to spawn the custom {@link org.bukkit.entity.Entity}</li>
* </ul>
*/
public class CustomEntity implements TestableEntity {
/**
* The key.
*/
private final NamespacedKey key;
/**
* The test for Entities to pass.
*/
private final Predicate<@NotNull Entity> test;
/**
* The provider to spawn the entity.
*/
private final Function<Location, Entity> provider;
/**
* Create a new custom entity.
*
* @param key The entity key.
* @param test The test.
* @param provider The provider to spawn the entity.
*/
public CustomEntity(@NotNull final NamespacedKey key,
@NotNull final Predicate<@NotNull Entity> test,
@NotNull final Function<Location, Entity> provider) {
this.key = key;
this.test = test;
this.provider = provider;
}
@Override
public boolean matches(@Nullable final Entity entity) {
if (entity == null) {
return false;
}
return test.test(entity);
}
@Override
public Entity spawn(@NotNull final Location location) {
Validate.notNull(location.getWorld());
return provider.apply(location);
}
/**
* Register the entity.
*/
public void register() {
Entities.registerCustomEntity(this.getKey(), this);
}
/**
* Get the key.
*
* @return The key.
*/
public NamespacedKey getKey() {
return this.key;
}
}

View File

@@ -0,0 +1,10 @@
package com.willfp.eco.core.entities;
import org.bukkit.entity.Entity;
/**
* Interface for Dummy Entities in order to filter them using instanceof.
*/
public interface DummyEntity extends Entity {
}

View File

@@ -0,0 +1,232 @@
package com.willfp.eco.core.entities;
import com.willfp.eco.core.entities.args.EntityArgParseResult;
import com.willfp.eco.core.entities.args.EntityArgParser;
import com.willfp.eco.core.entities.impl.EmptyTestableEntity;
import com.willfp.eco.core.entities.impl.ModifiedTestableEntity;
import com.willfp.eco.core.entities.impl.SimpleTestableEntity;
import com.willfp.eco.util.NamespacedKeyUtils;
import org.bukkit.Location;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
/**
* Class to manage all custom and vanilla entities.
*/
public final class Entities {
/**
* All entities.
*/
private static final Map<NamespacedKey, TestableEntity> REGISTRY = new ConcurrentHashMap<>();
/**
* All entity parsers.
*/
private static final List<EntityArgParser> ARG_PARSERS = new ArrayList<>();
/**
* The lookup handler.
*/
private static final EntitiesLookupHandler ENTITIES_LOOKUP_HANDLER = new EntitiesLookupHandler(Entities::doParse);
/**
* Register a new custom item.
*
* @param key The key of the item.
* @param item The item.
*/
public static void registerCustomEntity(@NotNull final NamespacedKey key,
@NotNull final TestableEntity item) {
REGISTRY.put(key, item);
}
/**
* Register a new arg parser.
*
* @param parser The parser.
*/
public static void registerArgParser(@NotNull final EntityArgParser parser) {
ARG_PARSERS.add(parser);
}
/**
* Remove an entity.
*
* @param key The key of the entity.
*/
public static void removeCustomEntity(@NotNull final NamespacedKey key) {
REGISTRY.remove(key);
}
/**
* This is the backbone of the entire eco entity system.
* <p>
* You can look up a TestableEntity for any type or custom entity,
* and it will return it with any modifiers passed as parameters.
* <p>
* If you want to get an Entity instance from this, then just call
* {@link TestableEntity#spawn(Location)}.
* <p>
* The advantages of the testable entity system are that there is the inbuilt
* {@link TestableEntity#matches(Entity)} - this allows to check if any entity
* is that testable entity; which may sound negligible, but actually it allows for
* much more power and flexibility. For example, you can have an entity with an
* extra metadata tag, extra lore lines, different display name - and it
* will still work as long as the test passes.
*
* @param key The lookup string.
* @return The testable entity, or an empty testable entity if not found.
*/
@NotNull
public static TestableEntity lookup(@NotNull final String key) {
return ENTITIES_LOOKUP_HANDLER.parseKey(key);
}
@NotNull
private static TestableEntity doParse(@NotNull final String[] args) {
if (args.length == 0) {
return new EmptyTestableEntity();
}
TestableEntity entity;
String[] split = args[0].toLowerCase().split(":");
if (split.length == 1) {
EntityType type;
try {
type = EntityType.valueOf(args[0].toUpperCase());
} catch (IllegalArgumentException e) {
return new EmptyTestableEntity();
}
entity = new SimpleTestableEntity(type);
} else {
String namespace = split[0];
String keyID = split[1];
NamespacedKey namespacedKey = NamespacedKeyUtils.create(namespace, keyID);
TestableEntity part = REGISTRY.get(namespacedKey);
if (part == null) {
return new EmptyTestableEntity();
}
entity = part;
}
String[] modifierArgs = Arrays.copyOfRange(args, 1, args.length);
List<EntityArgParseResult> parseResults = new ArrayList<>();
for (EntityArgParser argParser : ARG_PARSERS) {
EntityArgParseResult result = argParser.parseArguments(modifierArgs);
if (result != null) {
parseResults.add(result);
}
}
Function<Location, Entity> spawner = entity::spawn;
if (!parseResults.isEmpty()) {
entity = new ModifiedTestableEntity(
entity,
test -> {
for (EntityArgParseResult parseResult : parseResults) {
if (!parseResult.test().test(test)) {
return false;
}
}
return true;
},
location -> {
Entity spawned = spawner.apply(location);
for (EntityArgParseResult parseResult : parseResults) {
parseResult.modifier().accept(spawned);
}
return spawned;
}
);
}
return entity;
}
/**
* Get a Testable Entity from an ItemStack.
* <p>
* Will search for registered entity first. If there are no matches in the registry,
* then it will return a {@link com.willfp.eco.core.entities.impl.SimpleTestableEntity} matching the entity type.
* <p>
* If the entity is not custom and has unknown type, this will return null.
*
* @param entity The Entity.
* @return The found Testable Entity.
*/
@Nullable
public static TestableEntity getEntity(@Nullable final Entity entity) {
if (entity == null) {
return null;
}
TestableEntity customEntity = getEntity(entity);
if (customEntity != null) {
return customEntity;
}
for (TestableEntity known : REGISTRY.values()) {
if (known.matches(entity)) {
return known;
}
}
if (entity.getType() == EntityType.UNKNOWN) {
return null;
}
return new SimpleTestableEntity(entity.getType());
}
/**
* Get if entity is a custom entity.
*
* @param entity The entity to check.
* @return If is custom.
*/
public static boolean isCustomEntity(@NotNull final Entity entity) {
for (TestableEntity testable : REGISTRY.values()) {
if (testable.matches(entity)) {
return true;
}
}
return false;
}
/**
* Get all registered custom items.
*
* @return A set of all items.
*/
public static Set<TestableEntity> getCustomEntities() {
return new HashSet<>(REGISTRY.values());
}
private Entities() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
}

View File

@@ -0,0 +1,48 @@
package com.willfp.eco.core.entities;
import com.willfp.eco.core.entities.impl.EmptyTestableEntity;
import com.willfp.eco.core.entities.impl.GroupedTestableEntities;
import com.willfp.eco.core.lookup.LookupHandler;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.function.Function;
/**
* Handle item lookup strings.
*/
public class EntitiesLookupHandler implements LookupHandler<TestableEntity> {
/**
* The parser.
*/
private final Function<String[], @NotNull TestableEntity> parser;
/**
* Create new lookup handler.
*
* @param parser The parser.
*/
public EntitiesLookupHandler(@NotNull final Function<String[], @NotNull TestableEntity> parser) {
this.parser = parser;
}
@Override
public @NotNull TestableEntity parse(@NotNull final String[] args) {
return parser.apply(args);
}
@Override
public boolean validate(@NotNull final TestableEntity object) {
return !(object instanceof EmptyTestableEntity);
}
@Override
public @NotNull TestableEntity getFailsafe() {
return new EmptyTestableEntity();
}
@Override
public @NotNull TestableEntity join(@NotNull final Collection<TestableEntity> options) {
return new GroupedTestableEntities(options);
}
}

View File

@@ -0,0 +1,29 @@
package com.willfp.eco.core.entities;
import com.willfp.eco.core.lookup.Testable;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* An item with a test to see if any item is that item.
*/
public interface TestableEntity extends Testable<Entity> {
/**
* If an Entity matches the test.
*
* @param entity The entity to test.
* @return If the entity matches.
*/
@Override
boolean matches(@Nullable Entity entity);
/**
* Spawn the entity.
*
* @param location The location.
* @return The entity.
*/
Entity spawn(@NotNull Location location);
}

View File

@@ -0,0 +1,122 @@
package com.willfp.eco.core.entities.ai;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
/**
* Base interface for all custom goals.
* <p>
* Can be used both for entity goals and target goals.
*
* @param <T> The type of mob that this goal can be applied to.
*/
public abstract class CustomGoal<T extends Mob> implements EntityGoal<T>, TargetGoal<T> {
/**
* The flags for the goal.
*/
private final Set<GoalFlag> flags = EnumSet.noneOf(GoalFlag.class);
/**
* Initialize the goal with a mob.
* <p>
* This will be run before any implementation code, treat this as the constructor.
*
* @param mob The mob.
*/
public abstract void initialize(@NotNull T mob);
/**
* Get if the goal can be used.
* Will start the goal if this returns true.
*
* @return If the goal can be used.
*/
public abstract boolean canUse();
/**
* Tick the goal.
* <p>
* Runs ever tick as long as canUse returns true.
* <p>
* Runs after start().
*/
public void tick() {
// Override when needed.
}
/**
* Start the goal.
* <p>
* Runs once canUse() returns true.
*/
public void start() {
// Override when needed.
}
/**
* Stop the goal.
* <p>
* Runs once canUse() returns false.
*/
public void stop() {
// Override when needed.
}
/**
* Get if the goal can continue to be used.
*
* @return If the goal can continue to be used.
*/
public boolean canContinueToUse() {
return this.canUse();
}
/**
* Get if the goal is interruptable.
*
* @return If interruptable.
*/
public boolean isInterruptable() {
return true;
}
/**
* Get the goal flags.
*
* @return The flags.
*/
public EnumSet<GoalFlag> getFlags() {
return EnumSet.copyOf(this.flags);
}
/**
* Set the flags for the goal.
*
* @param flags The flags.
*/
public final void setFlags(@NotNull final GoalFlag... flags) {
this.setFlags(EnumSet.copyOf(List.of(flags)));
}
/**
* Set the flags for the goal.
*
* @param flags The flags.
*/
public void setFlags(@NotNull final EnumSet<GoalFlag> flags) {
this.flags.clear();
this.flags.addAll(flags);
}
@Override
public T addToEntity(@NotNull final T entity,
final int priority) {
throw new UnsupportedOperationException(
"Shorthand syntax is not supported for custom goals by default as they can be both entity and target goals."
);
}
}

View File

@@ -0,0 +1,106 @@
package com.willfp.eco.core.entities.ai;
import com.willfp.eco.core.Eco;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
/**
* An entity controller allows for adding targets and goals to entities.
*
* @param <T> The wrapped mob.
*/
public interface EntityController<T extends Mob> {
/**
* Add a target goal to the entity.
* <p>
* Mutates the instance.
*
* @param priority The priority.
* @param goal The goal.
* @return The entity controller.
*/
EntityController<T> addTargetGoal(int priority,
@NotNull TargetGoal<? super T> goal);
/**
* Remove all target goals from the entity.
* <p>
* Mutates the instance.
*
* @return The entity controller.
*/
EntityController<T> clearTargetGoals();
/**
* Remove a target goal from the entity.
* <p>
* Mutates the instance.
*
* @param goal The goal.
* @return The entity controller.
*/
EntityController<T> removeTargetGoal(@NotNull TargetGoal<? super T> goal);
/**
* Add an entity goal to the entity.
* <p>
* Mutates the instance.
*
* @param priority The priority.
* @param goal The goal.
* @return The entity controller.
*/
EntityController<T> addEntityGoal(int priority,
@NotNull EntityGoal<? super T> goal);
/**
* Remove an entity goal from the entity.
* <p>
* Mutates the instance.
*
* @param goal The goal.
* @return The entity controller.
*/
EntityController<T> removeEntityGoal(@NotNull EntityGoal<? super T> goal);
/**
* Remove all entity goals from the entity.
* <p>
* Mutates the instance.
*
* @return The entity controller.
*/
EntityController<T> clearEntityGoals();
/**
* Remove all goals from the entity.
* <p>
* Mutates the instance.
*
* @return The entity controller.
*/
default EntityController<T> clearAllGoals() {
this.clearTargetGoals();
return this.clearEntityGoals();
}
/**
* Get the mob back from the controlled entity.
* <p>
* Not required to apply changes, as the mob instance will be altered.
*
* @return The mob.
*/
T getEntity();
/**
* Create an entity controller for an entity in order to modify targets and goals.
*
* @param entity The entity.
* @param <T> The mob type.
* @return The entity controller.
*/
static <T extends Mob> EntityController<T> getFor(@NotNull final T entity) {
return Eco.getHandler().createEntityController(entity);
}
}

View File

@@ -0,0 +1,18 @@
package com.willfp.eco.core.entities.ai;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
/**
* A goal for entity AI.
*
* @param <T> The type of mob that the goal can be applied to.
*/
public interface EntityGoal<T extends Mob> extends Goal<T> {
@Override
default T addToEntity(@NotNull T entity, int priority) {
return EntityController.getFor(entity)
.addEntityGoal(priority, this)
.getEntity();
}
}

View File

@@ -0,0 +1,175 @@
package com.willfp.eco.core.entities.ai;
import com.google.common.collect.HashBiMap;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.entity.EntityGoalAvoidEntity;
import com.willfp.eco.core.entities.ai.entity.EntityGoalBreakDoors;
import com.willfp.eco.core.entities.ai.entity.EntityGoalBreatheAir;
import com.willfp.eco.core.entities.ai.entity.EntityGoalBreed;
import com.willfp.eco.core.entities.ai.entity.EntityGoalCatLieOnBed;
import com.willfp.eco.core.entities.ai.entity.EntityGoalCatSitOnBed;
import com.willfp.eco.core.entities.ai.entity.EntityGoalEatGrass;
import com.willfp.eco.core.entities.ai.entity.EntityGoalFleeSun;
import com.willfp.eco.core.entities.ai.entity.EntityGoalFloat;
import com.willfp.eco.core.entities.ai.entity.EntityGoalFollowBoats;
import com.willfp.eco.core.entities.ai.entity.EntityGoalFollowMobs;
import com.willfp.eco.core.entities.ai.entity.EntityGoalIllusionerBlindnessSpell;
import com.willfp.eco.core.entities.ai.entity.EntityGoalIllusionerMirrorSpell;
import com.willfp.eco.core.entities.ai.entity.EntityGoalInteract;
import com.willfp.eco.core.entities.ai.entity.EntityGoalLeapAtTarget;
import com.willfp.eco.core.entities.ai.entity.EntityGoalLookAtPlayer;
import com.willfp.eco.core.entities.ai.entity.EntityGoalMeleeAttack;
import com.willfp.eco.core.entities.ai.entity.EntityGoalMoveBackToVillage;
import com.willfp.eco.core.entities.ai.entity.EntityGoalMoveThroughVillage;
import com.willfp.eco.core.entities.ai.entity.EntityGoalMoveTowardsRestriction;
import com.willfp.eco.core.entities.ai.entity.EntityGoalMoveTowardsTarget;
import com.willfp.eco.core.entities.ai.entity.EntityGoalOcelotAttack;
import com.willfp.eco.core.entities.ai.entity.EntityGoalOpenDoors;
import com.willfp.eco.core.entities.ai.entity.EntityGoalPanic;
import com.willfp.eco.core.entities.ai.entity.EntityGoalRandomLookAround;
import com.willfp.eco.core.entities.ai.entity.EntityGoalRandomStroll;
import com.willfp.eco.core.entities.ai.entity.EntityGoalRandomSwimming;
import com.willfp.eco.core.entities.ai.entity.EntityGoalRangedAttack;
import com.willfp.eco.core.entities.ai.entity.EntityGoalRangedBowAttack;
import com.willfp.eco.core.entities.ai.entity.EntityGoalRangedCrossbowAttack;
import com.willfp.eco.core.entities.ai.entity.EntityGoalRestrictSun;
import com.willfp.eco.core.entities.ai.entity.EntityGoalStrollThroughVillage;
import com.willfp.eco.core.entities.ai.entity.EntityGoalTempt;
import com.willfp.eco.core.entities.ai.entity.EntityGoalTryFindWater;
import com.willfp.eco.core.entities.ai.entity.EntityGoalUseItem;
import com.willfp.eco.core.entities.ai.entity.EntityGoalWaterAvoidingRandomFlying;
import com.willfp.eco.core.entities.ai.entity.EntityGoalWaterAvoidingRandomStroll;
import com.willfp.eco.core.entities.ai.entity.EntityGoalWolfBeg;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
/**
* Class to manage entity goals.
*/
public final class EntityGoals {
/**
* All registered deserializers.
*/
private static final Map<NamespacedKey, KeyedDeserializer<? extends EntityGoal<?>>> BY_KEY = HashBiMap.create();
static {
register(EntityGoalAvoidEntity.DESERIALIZER);
register(EntityGoalBreakDoors.DESERIALIZER);
register(EntityGoalBreatheAir.DESERIALIZER);
register(EntityGoalEatGrass.DESERIALIZER);
register(EntityGoalFleeSun.DESERIALIZER);
register(EntityGoalFloat.DESERIALIZER);
register(EntityGoalFollowBoats.DESERIALIZER);
register(EntityGoalFollowMobs.DESERIALIZER);
register(EntityGoalInteract.DESERIALIZER);
register(EntityGoalLeapAtTarget.DESERIALIZER);
register(EntityGoalLookAtPlayer.DESERIALIZER);
register(EntityGoalMeleeAttack.DESERIALIZER);
register(EntityGoalMoveBackToVillage.DESERIALIZER);
register(EntityGoalMoveThroughVillage.DESERIALIZER);
register(EntityGoalMoveTowardsRestriction.DESERIALIZER);
register(EntityGoalMoveTowardsTarget.DESERIALIZER);
register(EntityGoalOcelotAttack.DESERIALIZER);
register(EntityGoalOpenDoors.DESERIALIZER);
register(EntityGoalPanic.DESERIALIZER);
register(EntityGoalRandomLookAround.DESERIALIZER);
register(EntityGoalRandomStroll.DESERIALIZER);
register(EntityGoalRandomSwimming.DESERIALIZER);
register(EntityGoalRangedAttack.DESERIALIZER);
register(EntityGoalRangedBowAttack.DESERIALIZER);
register(EntityGoalRangedCrossbowAttack.DESERIALIZER);
register(EntityGoalRestrictSun.DESERIALIZER);
register(EntityGoalStrollThroughVillage.DESERIALIZER);
register(EntityGoalTempt.DESERIALIZER);
register(EntityGoalTryFindWater.DESERIALIZER);
register(EntityGoalUseItem.DESERIALIZER);
register(EntityGoalWaterAvoidingRandomFlying.DESERIALIZER);
register(EntityGoalWaterAvoidingRandomStroll.DESERIALIZER);
register(EntityGoalWolfBeg.DESERIALIZER);
register(EntityGoalBreed.DESERIALIZER);
register(EntityGoalCatSitOnBed.DESERIALIZER);
register(EntityGoalCatLieOnBed.DESERIALIZER);
register(EntityGoalIllusionerBlindnessSpell.DESERIALIZER);
register(EntityGoalIllusionerMirrorSpell.DESERIALIZER);
}
/**
* Get deserializer by key.
*
* @param key The key.
* @return The deserializer, or null if not found.
*/
@Nullable
public static KeyedDeserializer<? extends EntityGoal<? extends Mob>> getByKey(@NotNull final NamespacedKey key) {
return BY_KEY.get(key);
}
/**
* Get deserializer by key, with a defined type (to prevent cluttering code with unsafe casts).
*
* @param key The key.
* @param clazz The type of target goal.
* @param <T> The type of mob the goal can be applied to.
* @return The deserializer, or null if not found.
*/
@Nullable
@SuppressWarnings({"unchecked", "unused"})
public static <T extends Mob> KeyedDeserializer<EntityGoal<T>> getByKeyOfType(@NotNull final NamespacedKey key,
@NotNull final Class<T> clazz) {
return (KeyedDeserializer<EntityGoal<T>>) BY_KEY.get(key);
}
/**
* Apply goal to entity given key and config.
* <p>
* If the key or config are invalid, the goal will not be applied.
*
* @param entity The entity.
* @param key The key.
* @param config The config.
* @param priority The priority.
* @param <T> The entity type.
* @return The entity.
*/
@NotNull
@SuppressWarnings("unchecked")
public static <T extends Mob> T applyToEntity(@NotNull final T entity,
@NotNull final NamespacedKey key,
@NotNull final Config config,
final int priority) {
KeyedDeserializer<EntityGoal<T>> deserializer = getByKeyOfType(key, (Class<T>) entity.getClass());
if (deserializer == null) {
return entity;
}
EntityGoal<T> goal = deserializer.deserialize(config);
if (goal == null) {
return entity;
}
return goal.addToEntity(entity, priority);
}
/**
* Register a deserializer for an entity goal.
*
* @param toRegister The entity goal to register.
* @param <T> The type of deserializer.
* @return The deserializer.
*/
@NotNull
public static <T extends KeyedDeserializer<? extends EntityGoal<?>>> T register(@NotNull final T toRegister) {
BY_KEY.put(toRegister.getKey(), toRegister);
return toRegister;
}
private EntityGoals() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
}

View File

@@ -0,0 +1,24 @@
package com.willfp.eco.core.entities.ai;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
/**
* A generic goal for entity AI.
*
* @param <T> The type of mob that the goal can be applied to.
*/
public interface Goal<T extends Mob> {
/**
* Add the entity goal to an entity.
* <p>
* The lower the priority, the higher up the execution order; so
* priority 0 will execute first. Lower priority (higher number) goals
* will only execute if all higher priority goals are stopped.
*
* @param entity The entity.
* @param priority The priority.
* @return The entity, modified.
*/
T addToEntity(@NotNull T entity, int priority);
}

View File

@@ -0,0 +1,26 @@
package com.willfp.eco.core.entities.ai;
/**
* Flags for ai goals.
*/
public enum GoalFlag {
/**
* Move.
*/
MOVE,
/**
* Look around.
*/
LOOK,
/**
* Jump.
*/
JUMP,
/**
* Target.
*/
TARGET
}

View File

@@ -0,0 +1,18 @@
package com.willfp.eco.core.entities.ai;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
/**
* A goal for entity target AI.
*
* @param <T> The type of mob that the goal can be applied to.
*/
public interface TargetGoal<T extends Mob> extends Goal<T> {
@Override
default T addToEntity(@NotNull T entity, int priority) {
return EntityController.getFor(entity)
.addTargetGoal(priority, this)
.getEntity();
}
}

View File

@@ -0,0 +1,117 @@
package com.willfp.eco.core.entities.ai;
import com.google.common.collect.HashBiMap;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.target.TargetGoalDefendVillage;
import com.willfp.eco.core.entities.ai.target.TargetGoalHurtBy;
import com.willfp.eco.core.entities.ai.target.TargetGoalNearestAttackable;
import com.willfp.eco.core.entities.ai.target.TargetGoalNearestAttackableWitch;
import com.willfp.eco.core.entities.ai.target.TargetGoalNearestHealableRaider;
import com.willfp.eco.core.entities.ai.target.TargetGoalNonTameRandom;
import com.willfp.eco.core.entities.ai.target.TargetGoalOwnerHurtBy;
import com.willfp.eco.core.entities.ai.target.TargetGoalOwnerTarget;
import com.willfp.eco.core.entities.ai.target.TargetGoalResetUniversalAnger;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
/**
* Class to manage target goals.
*/
public final class TargetGoals {
/**
* All registered deserializers.
*/
private static final Map<NamespacedKey, KeyedDeserializer<? extends TargetGoal<?>>> BY_KEY = HashBiMap.create();
static {
register(TargetGoalDefendVillage.DESERIALIZER);
register(TargetGoalHurtBy.DESERIALIZER);
register(TargetGoalNearestAttackable.DESERIALIZER);
register(TargetGoalNearestAttackableWitch.DESERIALIZER);
register(TargetGoalNearestHealableRaider.DESERIALIZER);
register(TargetGoalNonTameRandom.DESERIALIZER);
register(TargetGoalOwnerTarget.DESERIALIZER);
register(TargetGoalOwnerHurtBy.DESERIALIZER);
register(TargetGoalResetUniversalAnger.DESERIALIZER);
}
/**
* Get deserializer by key.
*
* @param key The key.
* @return The deserializer, or null if not found.
*/
@Nullable
public static KeyedDeserializer<? extends TargetGoal<? extends Mob>> getByKey(@NotNull final NamespacedKey key) {
return BY_KEY.get(key);
}
/**
* Get deserializer by key, with a defined type (to prevent cluttering code with unsafe casts).
*
* @param key The key.
* @param clazz The type of target goal.
* @param <T> The type of mob the goal can be applied to.
* @return The deserializer, or null if not found.
*/
@Nullable
@SuppressWarnings({"unchecked", "unused"})
public static <T extends Mob> KeyedDeserializer<TargetGoal<T>> getByKeyOfType(@NotNull final NamespacedKey key,
@NotNull final Class<T> clazz) {
return (KeyedDeserializer<TargetGoal<T>>) BY_KEY.get(key);
}
/**
* Apply goal to entity given key and config.
* <p>
* If the key or config are invalid, the goal will not be applied.
*
* @param entity The entity.
* @param key The key.
* @param config The config.
* @param priority The priority.
* @param <T> The entity type.
* @return The entity.
*/
@NotNull
@SuppressWarnings("unchecked")
public static <T extends Mob> T applyToEntity(@NotNull final T entity,
@NotNull final NamespacedKey key,
@NotNull final Config config,
final int priority) {
KeyedDeserializer<TargetGoal<T>> deserializer = getByKeyOfType(key, (Class<T>) entity.getClass());
if (deserializer == null) {
return entity;
}
TargetGoal<T> goal = deserializer.deserialize(config);
if (goal == null) {
return entity;
}
return goal.addToEntity(entity, priority);
}
/**
* Register a deserializer for a target goal.
*
* @param toRegister The target goal to register.
* @param <T> The type of deserializer.
* @return The deserializer.
*/
@NotNull
public static <T extends KeyedDeserializer<? extends TargetGoal<?>>> T register(@NotNull final T toRegister) {
BY_KEY.put(toRegister.getKey(), toRegister);
return toRegister;
}
private TargetGoals() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
}

View File

@@ -0,0 +1,73 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.Entities;
import com.willfp.eco.core.entities.TestableEntity;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Avoid entities.
*
* @param entity The entity type to avoid.
* @param distance The distance to flee to.
* @param slowSpeed The slow movement speed.
* @param fastSpeed The fast movement speed.
*/
public record EntityGoalAvoidEntity(
@NotNull TestableEntity entity,
double distance,
double slowSpeed,
double fastSpeed
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalAvoidEntity> DESERIALIZER = new Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalAvoidEntity> {
@Override
@Nullable
public EntityGoalAvoidEntity deserialize(@NotNull final Config config) {
if (!(
config.has("entity")
&& config.has("distance")
&& config.has("slowSpeed")
&& config.has("fastSpeed")
)) {
return null;
}
try {
TestableEntity entity = Entities.lookup(config.getString("entity"));
return new EntityGoalAvoidEntity(
entity,
config.getDouble("distance"),
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
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("avoid_entity");
}
}
}

View File

@@ -0,0 +1,57 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows an entity to break down doors.
*
* @param ticks The time taken to break the door. Minimum value is 240, as set by the game.
*/
public record EntityGoalBreakDoors(
int ticks
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalBreakDoors> DESERIALIZER = new EntityGoalBreakDoors.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalBreakDoors> {
@Override
@Nullable
public EntityGoalBreakDoors deserialize(@NotNull final Config config) {
if (!(
config.has("ticks")
)) {
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
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("break_doors");
}
}
}

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
/**
* Breathe air.
*/
public record EntityGoalBreatheAir(
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalBreatheAir> DESERIALIZER = new EntityGoalBreatheAir.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalBreatheAir> {
@Override
public EntityGoalBreatheAir deserialize(@NotNull final Config config) {
return new EntityGoalBreatheAir();
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("breathe_air");
}
}
}

View File

@@ -0,0 +1,57 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Animals;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows animals to breed.
*
* @param speed The speed at which to move to a partner.
*/
public record EntityGoalBreed(
double speed
) implements EntityGoal<Animals> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalBreed> DESERIALIZER = new EntityGoalBreed.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalBreed> {
@Override
@Nullable
public EntityGoalBreed deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
)) {
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
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("breed");
}
}
}

View File

@@ -0,0 +1,61 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Cat;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows a cat to lie on a bed.
*
* @param speed The speed at which to move to the bed.
* @param range The range at which to search for beds.
*/
public record EntityGoalCatLieOnBed(
double speed,
int range
) implements EntityGoal<Cat> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalCatLieOnBed> DESERIALIZER = new EntityGoalCatLieOnBed.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalCatLieOnBed> {
@Override
@Nullable
public EntityGoalCatLieOnBed deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
&& config.has("range")
)) {
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
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("cat_lie_on_bed");
}
}
}

View File

@@ -0,0 +1,57 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Cat;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows a cat to sit on a bed.
*
* @param speed The speed at which to move to the bed.
*/
public record EntityGoalCatSitOnBed(
double speed
) implements EntityGoal<Cat> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalCatSitOnBed> DESERIALIZER = new EntityGoalCatSitOnBed.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalCatSitOnBed> {
@Override
@Nullable
public EntityGoalCatSitOnBed deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
)) {
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
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("cat_sit_on_bed");
}
}
}

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
/**
* Allows an entity to eat the ground.
*/
public record EntityGoalEatGrass(
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalEatGrass> DESERIALIZER = new EntityGoalEatGrass.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalEatGrass> {
@Override
public EntityGoalEatGrass deserialize(@NotNull final Config config) {
return new EntityGoalEatGrass();
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("eat_grass");
}
}
}

View File

@@ -0,0 +1,57 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Will make the entity actively avoid the sunlight.
*
* @param speed The speed at which to flee.
*/
public record EntityGoalFleeSun(
double speed
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalFleeSun> DESERIALIZER = new EntityGoalFleeSun.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalFleeSun> {
@Override
@Nullable
public EntityGoalFleeSun deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
)) {
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
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("flee_sun");
}
}
}

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
/**
* Allows an entity to float on water.
*/
public record EntityGoalFloat(
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalFloat> DESERIALIZER = new EntityGoalFloat.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalFloat> {
@Override
public EntityGoalFloat deserialize(@NotNull final Config config) {
return new EntityGoalFloat();
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("float");
}
}
}

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
/**
* Follow boats.
*/
public record EntityGoalFollowBoats(
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalFollowBoats> DESERIALIZER = new EntityGoalFollowBoats.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalFollowBoats> {
@Override
public EntityGoalFollowBoats deserialize(@NotNull final Config config) {
return new EntityGoalFollowBoats();
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("follow_boats");
}
}
}

View File

@@ -0,0 +1,65 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows an entity to follow and gather around all types of mobs, both hostile and neutral mobs.
*
* @param speed The speed at which to follow.
* @param minDistance The minimum follow distance.
* @param maxDistance The maximum follow distance.
*/
public record EntityGoalFollowMobs(
double speed,
double minDistance,
double maxDistance
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalFollowMobs> DESERIALIZER = new EntityGoalFollowMobs.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalFollowMobs> {
@Override
@Nullable
public EntityGoalFollowMobs deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
&& config.has("minDistance")
&& config.has("maxDistance")
)) {
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
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("follow_mobs");
}
}
}

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Illusioner;
import org.jetbrains.annotations.NotNull;
/**
* Allows an illusioner to perform the blindness spell.
*/
public record EntityGoalIllusionerBlindnessSpell(
) implements EntityGoal<Illusioner> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalIllusionerBlindnessSpell> DESERIALIZER = new EntityGoalIllusionerBlindnessSpell.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalIllusionerBlindnessSpell> {
@Override
public EntityGoalIllusionerBlindnessSpell deserialize(@NotNull final Config config) {
return new EntityGoalIllusionerBlindnessSpell();
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("illusioner_blindness_spell");
}
}
}

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Illusioner;
import org.jetbrains.annotations.NotNull;
/**
* Allows an illusioner to perform the mirror spell.
*/
public record EntityGoalIllusionerMirrorSpell(
) implements EntityGoal<Illusioner> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalIllusionerMirrorSpell> DESERIALIZER = new EntityGoalIllusionerMirrorSpell.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalIllusionerMirrorSpell> {
@Override
public EntityGoalIllusionerMirrorSpell deserialize(@NotNull final Config config) {
return new EntityGoalIllusionerMirrorSpell();
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("illusioner_mirror_spell");
}
}
}

View File

@@ -0,0 +1,67 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.Entities;
import com.willfp.eco.core.entities.TestableEntity;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Interact with other mobs.
*
* @param target The type of entity to interact with.
* @param range The range at which to interact.
* @param chance The chance for interaction, between 0 and 1.
*/
public record EntityGoalInteract(
@NotNull TestableEntity target,
double range,
double chance
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalInteract> DESERIALIZER = new EntityGoalInteract.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalInteract> {
@Override
@Nullable
public EntityGoalInteract deserialize(@NotNull final Config config) {
if (!(
config.has("target")
&& config.has("range")
&& config.has("chance")
)) {
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
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("interact");
}
}
}

View File

@@ -0,0 +1,57 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows an entity to jump towards a target.
*
* @param velocity The leap velocity.
*/
public record EntityGoalLeapAtTarget(
double velocity
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalLeapAtTarget> DESERIALIZER = new EntityGoalLeapAtTarget.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalLeapAtTarget> {
@Override
@Nullable
public EntityGoalLeapAtTarget deserialize(@NotNull final Config config) {
if (!(
config.has("velocity")
)) {
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
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("leap_at_target");
}
}
}

View File

@@ -0,0 +1,61 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows an entity to look at the player by rotating the head bone pose within a set limit.
*
* @param range The range at which to look at the player.
* @param chance The chance to look at the player, between 0 and 1.
*/
public record EntityGoalLookAtPlayer(
double range,
double chance
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalLookAtPlayer> DESERIALIZER = new EntityGoalLookAtPlayer.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalLookAtPlayer> {
@Override
@Nullable
public EntityGoalLookAtPlayer deserialize(@NotNull final Config config) {
if (!(
config.has("range")
&& config.has("chance")
)) {
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
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("look_at_player");
}
}
}

View File

@@ -0,0 +1,61 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows entities to make close combat melee attacks.
*
* @param speed The speed at which to attack the target.
* @param pauseWhenMobIdle If the entity should pause attacking when the target is idle.
*/
public record EntityGoalMeleeAttack(
double speed,
boolean pauseWhenMobIdle
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalMeleeAttack> DESERIALIZER = new EntityGoalMeleeAttack.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalMeleeAttack> {
@Override
@Nullable
public EntityGoalMeleeAttack deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
&& config.has("pauseWhenMobIdle")
)) {
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
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("melee_attack");
}
}
}

View File

@@ -0,0 +1,61 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows an entity to navigate and search for a nearby village.
*
* @param speed The speed at which to move back to the village.
* @param canDespawn If the entity can despawn.
*/
public record EntityGoalMoveBackToVillage(
double speed,
boolean canDespawn
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalMoveBackToVillage> DESERIALIZER = new EntityGoalMoveBackToVillage.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalMoveBackToVillage> {
@Override
@Nullable
public EntityGoalMoveBackToVillage deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
&& config.has("canDespawn")
)) {
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
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("move_back_to_village");
}
}
}

View File

@@ -0,0 +1,69 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows the entity to create paths around the village.
*
* @param speed The speed at which to move through the village.
* @param onlyAtNight If the entity can only move through village at night.
* @param distance The distance to move through the village.
* @param canPassThroughDoors If the entity can pass through doors.
*/
public record EntityGoalMoveThroughVillage(
double speed,
boolean onlyAtNight,
int distance,
boolean canPassThroughDoors
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalMoveThroughVillage> DESERIALIZER = new EntityGoalMoveThroughVillage.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalMoveThroughVillage> {
@Override
@Nullable
public EntityGoalMoveThroughVillage deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
&& config.has("onlyAtNight")
&& config.has("distance")
&& config.has("canPassThroughDoors")
)) {
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
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("move_through_village");
}
}
}

View File

@@ -0,0 +1,57 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Move towards restriction.
*
* @param speed The speed at which to move towards the restriction.
*/
public record EntityGoalMoveTowardsRestriction(
double speed
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalMoveTowardsRestriction> DESERIALIZER = new EntityGoalMoveTowardsRestriction.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalMoveTowardsRestriction> {
@Override
@Nullable
public EntityGoalMoveTowardsRestriction deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
)) {
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
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("move_towards_restriction");
}
}
}

View File

@@ -0,0 +1,61 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows an entity to move towards a target.
*
* @param speed The speed at which to move towards the target.
* @param maxDistance The maximum distance the target can be where the entity will still move towards it.
*/
public record EntityGoalMoveTowardsTarget(
double speed,
double maxDistance
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalMoveTowardsTarget> DESERIALIZER = new EntityGoalMoveTowardsTarget.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalMoveTowardsTarget> {
@Override
@Nullable
public EntityGoalMoveTowardsTarget deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
&& config.has("maxDistance")
)) {
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
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("move_towards_target");
}
}
}

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
/**
* Attack like an ocelot.
*/
public record EntityGoalOcelotAttack(
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalOcelotAttack> DESERIALIZER = new EntityGoalOcelotAttack.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalOcelotAttack> {
@Override
public EntityGoalOcelotAttack deserialize(@NotNull final Config config) {
return new EntityGoalOcelotAttack();
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("ocelot_attack");
}
}
}

View File

@@ -0,0 +1,57 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows an entity to interact and open a door.
*
* @param delayClosing If closing the door should be delayed.
*/
public record EntityGoalOpenDoors(
boolean delayClosing
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalOpenDoors> DESERIALIZER = new EntityGoalOpenDoors.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalOpenDoors> {
@Override
@Nullable
public EntityGoalOpenDoors deserialize(@NotNull final Config config) {
if (!(
config.has("delayClosing")
)) {
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
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("open_doors");
}
}
}

View File

@@ -0,0 +1,57 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows an entity to react when it receives damage.
*
* @param speed The speed at which to panic.
*/
public record EntityGoalPanic(
double speed
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalPanic> DESERIALIZER = new EntityGoalPanic.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalPanic> {
@Override
@Nullable
public EntityGoalPanic deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
)) {
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
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("panic");
}
}
}

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
/**
* Allows an entity to choose a random direction to look in for a random duration within a range.
*/
public record EntityGoalRandomLookAround(
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalRandomLookAround> DESERIALIZER = new EntityGoalRandomLookAround.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalRandomLookAround> {
@Override
public EntityGoalRandomLookAround deserialize(@NotNull final Config config) {
return new EntityGoalRandomLookAround();
}
@NotNull
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("random_look_around");
}
}
}

View File

@@ -0,0 +1,65 @@
package com.willfp.eco.core.entities.ai.entity;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.entities.ai.EntityGoal;
import com.willfp.eco.core.serialization.KeyedDeserializer;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Allows an entity to choose a random direction to walk towards.
*
* @param speed The speed at which to move around.
* @param interval The amount of ticks to wait (on average) between strolling around.
* @param canDespawn If the entity can despawn.
*/
public record EntityGoalRandomStroll(
double speed,
int interval,
boolean canDespawn
) implements EntityGoal<Mob> {
/**
* The deserializer for the goal.
*/
public static final KeyedDeserializer<EntityGoalRandomStroll> DESERIALIZER = new EntityGoalRandomStroll.Deserializer();
/**
* Deserialize configs into the goal.
*/
private static final class Deserializer implements KeyedDeserializer<EntityGoalRandomStroll> {
@Override
@Nullable
public EntityGoalRandomStroll deserialize(@NotNull final Config config) {
if (!(
config.has("speed")
&& config.has("interval")
&& config.has("canDespawn")
)) {
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
@Override
public NamespacedKey getKey() {
return NamespacedKey.minecraft("random_stroll");
}
}
}

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