Compare commits
584 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac10fa46dc | ||
|
|
7c616e64ae | ||
|
|
708f9130c6 | ||
|
|
9118d49c67 | ||
|
|
a1ce72476f | ||
|
|
2cfab99644 | ||
|
|
cc9b3f7710 | ||
|
|
5bfe48c8d9 | ||
|
|
22ff157ffc | ||
|
|
720dbe789c | ||
|
|
b51dd51941 | ||
|
|
f3ffaa4cf6 | ||
|
|
085032e315 | ||
|
|
3d920ee2b4 | ||
|
|
06a04e4375 | ||
|
|
7349f15784 | ||
|
|
a4c77857d5 | ||
|
|
999fafc8df | ||
|
|
0d533850f6 | ||
|
|
569f9cfcb4 | ||
|
|
f0619f2374 | ||
|
|
7e8d97e11d | ||
|
|
d3414f25ad | ||
|
|
f0cf118448 | ||
|
|
297bb10b85 | ||
|
|
751624bc8d | ||
|
|
8b1b15a3e4 | ||
|
|
7fe330bafb | ||
|
|
20584b2a9b | ||
|
|
bd7594a117 | ||
|
|
f1bfa21270 | ||
|
|
01aa1e708a | ||
|
|
8424baa285 | ||
|
|
d9a8d26990 | ||
|
|
4d3eeaaefc | ||
|
|
d54a2b9516 | ||
|
|
f7f12b6255 | ||
|
|
42eb1344a6 | ||
|
|
4c2a8585cc | ||
|
|
8cccc67b0d | ||
|
|
396d74497c | ||
|
|
49602dce04 | ||
|
|
5da811ba74 | ||
|
|
a4d57e21fe | ||
|
|
4b8efdc79f | ||
|
|
610110efde | ||
|
|
a87f675269 | ||
|
|
a371d314b8 | ||
|
|
9a9097adc5 | ||
|
|
0669a57e4b | ||
|
|
692eaf6836 | ||
|
|
7f9052c64d | ||
|
|
55a841b3f5 | ||
|
|
85f02c5ca2 | ||
|
|
74c428b90d | ||
|
|
fd8c67fa66 | ||
|
|
a396754e2e | ||
|
|
6f97f47712 | ||
|
|
d1109e485a | ||
|
|
476e5c7cae | ||
|
|
dc2b7a6fda | ||
|
|
00f18519b0 | ||
|
|
f7ea5fd182 | ||
|
|
70d29c872a | ||
|
|
f79f4a84c3 | ||
|
|
9af63907ef | ||
|
|
c9aa92895b | ||
|
|
c57c824027 | ||
|
|
7cb905e65a | ||
|
|
31a2c7e338 | ||
|
|
1759b52f82 | ||
|
|
ccf93e3a4d | ||
|
|
abd07389ab | ||
|
|
80ad738bb2 | ||
|
|
b01105819a | ||
|
|
a7c08b0731 | ||
|
|
7e4c071698 | ||
|
|
f94f7ead08 | ||
|
|
b21c5bf3a9 | ||
|
|
7a9e8c5c10 | ||
|
|
a6ddbc46ab | ||
|
|
ffaee137d8 | ||
|
|
18d882dac6 | ||
|
|
52841f7f04 | ||
|
|
47b72e9243 | ||
|
|
854a10e8fd | ||
|
|
823ef6477b | ||
|
|
eccb146852 | ||
|
|
d877b707d6 | ||
|
|
bcb7401c74 | ||
|
|
f05c5f3cd6 | ||
|
|
3bd8bccb81 | ||
|
|
6f55787c84 | ||
|
|
eb4dc168fc | ||
|
|
c5085de5d1 | ||
|
|
019cdbf9c8 | ||
|
|
d5ddcaea4b | ||
|
|
d3a7ef72e8 | ||
|
|
a311ce1227 | ||
|
|
5c0d4540a8 | ||
|
|
7e66ee8071 | ||
|
|
fd233df736 | ||
|
|
6baf636e6a | ||
|
|
9ee579f2c4 | ||
|
|
3b5ea87353 | ||
|
|
00d32ed218 | ||
|
|
5ce9a1c04e | ||
|
|
966549065d | ||
|
|
ee2911b57c | ||
|
|
f15ec5eec0 | ||
|
|
a9c32000d8 | ||
|
|
b68459951f | ||
|
|
b520c76169 | ||
|
|
d081afbd8e | ||
|
|
46fd0439a5 | ||
|
|
ad58ce4a74 | ||
|
|
b5cd8f42e0 | ||
|
|
d0baf50709 | ||
|
|
2496f318fa | ||
|
|
048c200c95 | ||
|
|
17446acb2e | ||
|
|
7929113c91 | ||
|
|
6acc5864bd | ||
|
|
fa64950d28 | ||
|
|
730c20dbc0 | ||
|
|
0c5ae54c3a | ||
|
|
b48e80837d | ||
|
|
17eb4cf5f8 | ||
|
|
890f85fa56 | ||
|
|
86b427c95e | ||
|
|
8c1fde57b0 | ||
|
|
2efc040a8e | ||
|
|
54b2b42512 | ||
|
|
e67d9d634c | ||
|
|
39fb676b9a | ||
|
|
ec8936b765 | ||
|
|
cf347de4b8 | ||
|
|
2b7122c5c2 | ||
|
|
062b5c9b92 | ||
|
|
052cd74756 | ||
|
|
082b39a2e4 | ||
|
|
616fa032d9 | ||
|
|
ea997239fc | ||
|
|
ad04abab73 | ||
|
|
f440ef922b | ||
|
|
933271fb4a | ||
|
|
9679d3100f | ||
|
|
6e20763522 | ||
|
|
18dea2c20c | ||
|
|
62b666559c | ||
|
|
465563523b | ||
|
|
f0f014ed89 | ||
|
|
58811c5d77 | ||
|
|
81d495e76e | ||
|
|
c78e397959 | ||
|
|
95740f155e | ||
|
|
5638d5e152 | ||
|
|
4d3712057c | ||
|
|
458fcd78b3 | ||
|
|
ee13de31f4 | ||
|
|
9588d49788 | ||
|
|
8e7ce298b0 | ||
|
|
32a11ce5b8 | ||
|
|
960f62cc8b | ||
|
|
28ceb83eb5 | ||
|
|
6f748b6b8a | ||
|
|
190ea5d49f | ||
|
|
c0ed083a5c | ||
|
|
04f04bb7a6 | ||
|
|
b8a3806ff9 | ||
|
|
ae49d41542 | ||
|
|
5f2255a3bc | ||
|
|
065ccfbe67 | ||
|
|
17727c9015 | ||
|
|
ea64e69b4d | ||
|
|
07ca6c2359 | ||
|
|
162558b1c2 | ||
|
|
10f9e8dce0 | ||
|
|
b02943d7ff | ||
|
|
40ad970ffa | ||
|
|
aefdfa786d | ||
|
|
1cf08955a0 | ||
|
|
4077a4c28b | ||
|
|
6c375ef297 | ||
|
|
f77fc5d182 | ||
|
|
6d1cc4c05d | ||
|
|
0775f0992f | ||
|
|
debb39105d | ||
|
|
3b4aa59bfb | ||
|
|
4e902c3964 | ||
|
|
3e325697e7 | ||
|
|
13b3e1e440 | ||
|
|
2b2406a4d0 | ||
|
|
048982c74a | ||
|
|
29b63a2ebb | ||
|
|
2a9cbdacfd | ||
|
|
35cfcdf4a9 | ||
|
|
06c1dc9afb | ||
|
|
18b58d584f | ||
|
|
a774791e65 | ||
|
|
bc22adae84 | ||
|
|
0eba82b221 | ||
|
|
4822ec3955 | ||
|
|
b845001467 | ||
|
|
25b6a15c9c | ||
|
|
1a3d035f78 | ||
|
|
a69f9f6e11 | ||
|
|
6efd9e4fcd | ||
|
|
3e948beb7a | ||
|
|
a8a491a0b7 | ||
|
|
2c0330898c | ||
|
|
e9794cfbf4 | ||
|
|
1694d858bc | ||
|
|
b79955ae9e | ||
|
|
803a8c5d17 | ||
|
|
c5cd15ad92 | ||
|
|
489b170888 | ||
|
|
9f57a322e8 | ||
|
|
86e113214d | ||
|
|
e791bb8893 | ||
|
|
f1220bd186 | ||
|
|
21d933cb11 | ||
|
|
e1c063d5f4 | ||
|
|
27d2b5c8a4 | ||
|
|
3b34d6ef27 | ||
|
|
bc1c8b8f46 | ||
|
|
2fa926ec02 | ||
|
|
d7891e1218 | ||
|
|
11685cd352 | ||
|
|
785127fe16 | ||
|
|
4a13bc5fea | ||
|
|
c7ad122050 | ||
|
|
28d63fc2e3 | ||
|
|
bb62cc0bcd | ||
|
|
740c79f087 | ||
|
|
33ab8e04a0 | ||
|
|
fcd3aac363 | ||
|
|
753d148d1b | ||
|
|
1bb47a9f13 | ||
|
|
40b4c26e0f | ||
|
|
97adae7b32 | ||
|
|
3d35a91314 | ||
|
|
0caa328b1e | ||
|
|
ab8c946914 | ||
|
|
e667537404 | ||
|
|
6bd2f2b823 | ||
|
|
8d8a8045c0 | ||
|
|
d5c669c72c | ||
|
|
28b268e175 | ||
|
|
33937d1ce7 | ||
|
|
e971778cc3 | ||
|
|
f99612ded3 | ||
|
|
50272bbbcf | ||
|
|
9a703f6190 | ||
|
|
f8fec7eec4 | ||
|
|
f6aadda4ed | ||
|
|
d8fca0f348 | ||
|
|
65ff4c4a31 | ||
|
|
90702bc7aa | ||
|
|
e81b788a1b | ||
|
|
ebc0ee7940 | ||
|
|
82d269daf1 | ||
|
|
9d5300d6ae | ||
|
|
8870e4d6fb | ||
|
|
d826a9f71f | ||
|
|
7ec3355237 | ||
|
|
e59a8cc2e6 | ||
|
|
88f974fd10 | ||
|
|
7767e48e51 | ||
|
|
dfe2f1361b | ||
|
|
3826f9f713 | ||
|
|
c2d2303c91 | ||
|
|
b1158ceb3d | ||
|
|
af4048afbe | ||
|
|
fce12020d5 | ||
|
|
7e37332b64 | ||
|
|
52dbf9ff52 | ||
|
|
78b6292367 | ||
|
|
09705e787b | ||
|
|
9c86069a85 | ||
|
|
0a7acceb83 | ||
|
|
40aa8b17dd | ||
|
|
71eb386a19 | ||
|
|
c857df2360 | ||
|
|
f4fc611f3b | ||
|
|
0d91324d47 | ||
|
|
e9dbc3ec73 | ||
|
|
493d1b1b6d | ||
|
|
68221d5912 | ||
|
|
7f2ef4e038 | ||
|
|
be0a19175b | ||
|
|
5afdcd75f7 | ||
|
|
a1c0b8c857 | ||
|
|
0442ccf58f | ||
|
|
1c1a796610 | ||
|
|
eacb243493 | ||
|
|
7bbed31d4e | ||
|
|
58bccf3cd7 | ||
|
|
4502e1e311 | ||
|
|
054a8d5a5e | ||
|
|
dbdd4785ba | ||
|
|
35f800b62a | ||
|
|
591800dba8 | ||
|
|
46673e8d24 | ||
|
|
bb7c300074 | ||
|
|
b003ec96f7 | ||
|
|
a526f51780 | ||
|
|
dd14fc666a | ||
|
|
ae0150f012 | ||
|
|
04418fa038 | ||
|
|
bcb9523315 | ||
|
|
43e7972ca3 | ||
|
|
7ea61eb393 | ||
|
|
5245a9b1d8 | ||
|
|
195932463c | ||
|
|
3cf60a7e2c | ||
|
|
0f9f57fca2 | ||
|
|
fe21616dd5 | ||
|
|
396144abaa | ||
|
|
50b4fa59ab | ||
|
|
a6754379e8 | ||
|
|
bbd0182c2a | ||
|
|
0370e9f454 | ||
|
|
8d585b58cb | ||
|
|
0bfbd4c036 | ||
|
|
881839955e | ||
|
|
8ffc5f9c0f | ||
|
|
709de3bb5f | ||
|
|
f2aa2ffd9b | ||
|
|
5ce70399f0 | ||
|
|
3f8759b08a | ||
|
|
abecaa6e9f | ||
|
|
4744bfc78b | ||
|
|
487e68221a | ||
|
|
1c68992a8e | ||
|
|
c5b7d0b644 | ||
|
|
0f91aec3b7 | ||
|
|
d2bf38c5c9 | ||
|
|
2c96b79aba | ||
|
|
d539b9e59e | ||
|
|
b0b06ef402 | ||
|
|
7a84c3de3b | ||
|
|
9431321e1c | ||
|
|
4816284fba | ||
|
|
a9874c9386 | ||
|
|
fe68760184 | ||
|
|
5ae8e72a98 | ||
|
|
15fc6053c8 | ||
|
|
1f7cf78491 | ||
|
|
fc3c80f633 | ||
|
|
2bcbf181a9 | ||
|
|
7adcdd572d | ||
|
|
f6eba21006 | ||
|
|
cc02f26807 | ||
|
|
60f552ce65 | ||
|
|
9fe8d4ad15 | ||
|
|
b835988eec | ||
|
|
22366835de | ||
|
|
cdd1baec6c | ||
|
|
1ea0da365a | ||
|
|
852d40372d | ||
|
|
999c831dd7 | ||
|
|
80fa5d346a | ||
|
|
336cdc3716 | ||
|
|
a49a9e92b4 | ||
|
|
1c6e64832e | ||
|
|
44a141cddc | ||
|
|
ea4956870e | ||
|
|
9207d1782b | ||
|
|
9debcb7089 | ||
|
|
ef53ee2ed3 | ||
|
|
4c90360038 | ||
|
|
d4b5102913 | ||
|
|
f4553c544a | ||
|
|
5ad1db72fc | ||
|
|
c761df9ee6 | ||
|
|
b6d79da4e1 | ||
|
|
42f41618ca | ||
|
|
de878fd423 | ||
|
|
7782657d57 | ||
|
|
7778425936 | ||
|
|
6446cef255 | ||
|
|
8dacecbcba | ||
|
|
5f8ec4f94a | ||
|
|
d7847e9efc | ||
|
|
930ecd4896 | ||
|
|
af8d6a4167 | ||
|
|
361f0a0103 | ||
|
|
eb545a7d9e | ||
|
|
d3c64deef4 | ||
|
|
31db9dcb95 | ||
|
|
4938ad84bc | ||
|
|
06b2301da1 | ||
|
|
c307878c09 | ||
|
|
3b10ff01ec | ||
|
|
e042754f5d | ||
|
|
c2b8a80560 | ||
|
|
07c0e72564 | ||
|
|
de9b961d83 | ||
|
|
83958c719c | ||
|
|
9c3dfaeb01 | ||
|
|
7e61340285 | ||
|
|
78b76cb453 | ||
|
|
bb1da29704 | ||
|
|
cf152215d3 | ||
|
|
e6a59fbc91 | ||
|
|
b787f8b76a | ||
|
|
ccc83da5b0 | ||
|
|
f11068f2f1 | ||
|
|
a5cc1a5d32 | ||
|
|
7440749ba5 | ||
|
|
75010d25fa | ||
|
|
bb95376b93 | ||
|
|
ab6d4c7aa2 | ||
|
|
9ab8827e55 | ||
|
|
991290095b | ||
|
|
8735478fc3 | ||
|
|
6e44f09621 | ||
|
|
060106881e | ||
|
|
96cc9706b3 | ||
|
|
3d87b1eb73 | ||
|
|
4c4247b4ec | ||
|
|
b94dc4ac3a | ||
|
|
06bcb10958 | ||
|
|
295095e9ce | ||
|
|
ba9c5865e3 | ||
|
|
d24be4121f | ||
|
|
bcc5e4ef08 | ||
|
|
bf8609666a | ||
|
|
1a02335825 | ||
|
|
f5ef98ec5c | ||
|
|
45135e2b55 | ||
|
|
758b42ff8e | ||
|
|
4a134402da | ||
|
|
e6ad4c9268 | ||
|
|
809dcbae85 | ||
|
|
d7fce6834c | ||
|
|
ac807a991b | ||
|
|
ba315ced3c | ||
|
|
f2e65174f9 | ||
|
|
bd5555ff01 | ||
|
|
d5584e863b | ||
|
|
d9c0e8e763 | ||
|
|
b223f8457d | ||
|
|
694d57edf4 | ||
|
|
02afe7d788 | ||
|
|
0593e631ea | ||
|
|
2f22e02ff1 | ||
|
|
fb240bfd0a | ||
|
|
11c49a543f | ||
|
|
c565f5248d | ||
|
|
fac4f40430 | ||
|
|
a20cb63755 | ||
|
|
f17f67227f | ||
|
|
106c9b37fc | ||
|
|
f7cfcd5cbb | ||
|
|
44d9581222 | ||
|
|
0fa30a5f62 | ||
|
|
84f439976c | ||
|
|
01bcb62b31 | ||
|
|
47c8ea3341 | ||
|
|
e28c4288a3 | ||
|
|
386792d7ca | ||
|
|
8c6d98a666 | ||
|
|
6f42224593 | ||
|
|
36c857086b | ||
|
|
014bcddc0a | ||
|
|
96c56b0291 | ||
|
|
c1fe633e72 | ||
|
|
c9a9d86160 | ||
|
|
e79c7e9881 | ||
|
|
be617241e7 | ||
|
|
cb9b59ae01 | ||
|
|
a993acae72 | ||
|
|
e6cdc7d2ba | ||
|
|
94534b2f61 | ||
|
|
fe6b7805c7 | ||
|
|
be25f2f4fc | ||
|
|
a19cc7df1e | ||
|
|
13dbd08dcc | ||
|
|
5f80b6052d | ||
|
|
a48885b79a | ||
|
|
350c2d8775 | ||
|
|
5988dfb1fd | ||
|
|
57687859e4 | ||
|
|
ef42e689ae | ||
|
|
9a3aac9a66 | ||
|
|
7be5fbfbc4 | ||
|
|
4b344ccd18 | ||
|
|
3f50ae0a44 | ||
|
|
afb498b4bf | ||
|
|
6b18b06763 | ||
|
|
033e334877 | ||
|
|
eb9112e480 | ||
|
|
b75e4d59e4 | ||
|
|
c69bb6904f | ||
|
|
9f193b7206 | ||
|
|
6fce2c13fe | ||
|
|
02342c11a6 | ||
|
|
2fde56df0d | ||
|
|
cb64dedd74 | ||
|
|
a7c489413e | ||
|
|
f9ed174e31 | ||
|
|
496d878a14 | ||
|
|
00853d4a92 | ||
|
|
5eb0d2380a | ||
|
|
d19cff9a42 | ||
|
|
234b5fdd8e | ||
|
|
2dbe6c7fe4 | ||
|
|
9d4d1ace08 | ||
|
|
364550d228 | ||
|
|
d5e8cbaf33 | ||
|
|
c4d532fda9 | ||
|
|
aa097cf7e2 | ||
|
|
6f4ca40a94 | ||
|
|
2ef9b4033c | ||
|
|
9aa22ffc86 | ||
|
|
d81c1e6fcb | ||
|
|
ac72e0770a | ||
|
|
5e3e09c4bc | ||
|
|
ee945d5901 | ||
|
|
7f747f3afc | ||
|
|
2d47593f51 | ||
|
|
df529ba239 | ||
|
|
2fea736631 | ||
|
|
9df4fae2dc | ||
|
|
ca964a1a40 | ||
|
|
ada2832839 | ||
|
|
4d92cbb7ff | ||
|
|
d6ab36929b | ||
|
|
e06623d3fe | ||
|
|
8b70a37459 | ||
|
|
daab3829bc | ||
|
|
d09021707b | ||
|
|
bea8cb5757 | ||
|
|
bde546efcb | ||
|
|
e1ffc851a3 | ||
|
|
828229b3e5 | ||
|
|
f36e2f5349 | ||
|
|
cdbe5b141a | ||
|
|
08c3fc0cfa | ||
|
|
8f758fb100 | ||
|
|
ec339b0ecd | ||
|
|
9dedfb86a5 | ||
|
|
0146cff8d3 | ||
|
|
2454d99d84 | ||
|
|
7d9b1bc266 | ||
|
|
77c56c46a8 | ||
|
|
85303098a7 | ||
|
|
821dc62d56 | ||
|
|
f9af4a9e66 | ||
|
|
41b9d6b01d | ||
|
|
7a521acccf | ||
|
|
49233aef88 | ||
|
|
c5b47ed073 | ||
|
|
ddcef7cf0c | ||
|
|
0f86e1c1c1 | ||
|
|
f0f7e229ea | ||
|
|
ea674a3757 | ||
|
|
b7c51eba5e | ||
|
|
1127bf1700 | ||
|
|
376e3284fb | ||
|
|
12f355b205 | ||
|
|
f4b02591e8 | ||
|
|
f843725cf5 | ||
|
|
ed0536c188 | ||
|
|
849e005095 | ||
|
|
927d61dd6b | ||
|
|
9285cffc56 | ||
|
|
1b6c90e87d | ||
|
|
c79de6fbc1 | ||
|
|
fc83ebbb34 | ||
|
|
f330cc954c | ||
|
|
df4f98251c | ||
|
|
74861e9c01 | ||
|
|
7dad9d7875 | ||
|
|
338b9b2d4e | ||
|
|
f6d83867f3 | ||
|
|
bb632ac849 | ||
|
|
793f946b44 | ||
|
|
519a59cc88 | ||
|
|
79b1bff547 | ||
|
|
17ee1ac2ff | ||
|
|
a6fa446d95 |
@@ -1,38 +1,7 @@
|
||||
# How to contribute to eco
|
||||
|
||||
## Codestyle
|
||||
Please open any Pull Requests into the `develop` branch or ideally into a new branch for your changes. PRs that go into `master` won't be ignored, but I have to checkout and merge manually, which makes your PR show as being closed.
|
||||
|
||||
1. The eco checkstyle is in /config/checkstyle.xml
|
||||
Do not write any Kotlin-only APIs; all API components should be written in Java, Kotlin extensions should not have functionality that isn't available in java. The same applies the other way round, do not write any backend code in Java, it should be Kotlin-exclusive.
|
||||
|
||||
- The pull request must not have any checkstyle issues.
|
||||
- Every method and field must have a javadoc attached.
|
||||
|
||||
2. Use JetBrains annotations
|
||||
|
||||
- Every parameter should be annotated with @NotNull or @Nullable
|
||||
|
||||
3. Imports
|
||||
|
||||
- No group (*) imports.
|
||||
- No static imports.
|
||||
|
||||
4. Kotlin
|
||||
|
||||
- Kotlin should be the only language used in the backend, java should be the only language used in the frontend.
|
||||
- Kotlin API extensions should only be for creating extension functions and extra niceties that aren't possible in java.
|
||||
Do not write API components in kotlin.
|
||||
- Kotlin code should never be called directly from the frontend Java API. Kotlin API extensions should always rely on
|
||||
java, not the other way round.
|
||||
|
||||
## Dependency Injection
|
||||
|
||||
- eco uses Dependency Injection
|
||||
- Any calls to Eco#getHandler#getEcoPlugin are code smells and should never be used unless **absolutely necessary**.
|
||||
- NamespacedKeys, FixedMetadataValues, Runnables, and Schedules should be managed using AbstractEcoPlugin through DI.
|
||||
- Any DI class should extend PluginDependent where possible. If the class extends another, then you **must** store the
|
||||
plugin instance in a private final variable called **plugin** with a private or protected getter.
|
||||
|
||||
## Other
|
||||
|
||||
- All drops **must** be sent through a DropQueue - calls to World#dropItem will get your PR rejected.
|
||||
- eco is built with java 17.
|
||||
If you have any questions about contributing, feel free to ask in the [Discord](https://discord.gg/ZcwpSsE)!
|
||||
46
README.md
46
README.md
@@ -1,5 +1,5 @@
|
||||
# eco
|
||||
eco is a powerful Spigot development library that simplifies the process of plugin creation and supercharges
|
||||
eco is a powerful Spigot plugin framework that simplifies the process of plugin creation and supercharges
|
||||
your plugins.
|
||||
It's the engine behind [EcoEnchants](https://polymart.org/resource/490), [Reforges](https://polymart.org/resource/1330),
|
||||
[EcoItems](https://polymart.org/resource/1247), [EcoSkills](https://polymart.org/resource/1351),
|
||||
@@ -16,30 +16,54 @@ and many more.
|
||||
<a href="https://bstats.org/plugin/bukkit/EcoEnchants" alt="bstats players">
|
||||
<img src="https://img.shields.io/bstats/players/7666?color=informational"/>
|
||||
</a>
|
||||
<a href="https://plugins.auxilor.io/" alt="Docs (gitbook)">
|
||||
<img src="https://img.shields.io/badge/docs-gitbook-informational"/>
|
||||
</a>
|
||||
<a href="https://discord.gg/ZcwpSsE/" alt="Discord">
|
||||
<img src="https://img.shields.io/discord/452518336627081236?label=discord&color=informational"/>
|
||||
</a>
|
||||
<a href="https://github.com/Auxilor/eco/actions/workflows/java-ci.yml" alt="Latest Dev Build">
|
||||
<img src="https://img.shields.io/github/workflow/status/Auxilor/eco/Java%20CI/develop?color=informational"/>
|
||||
<img src="https://img.shields.io/github/actions/workflow/status/Auxilor/eco/java-ci.yml?branch=develop&color=informational"/>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
eco comes packed with all the tools you need in your plugins:
|
||||
|
||||
- Modern command API
|
||||
- Native color parsing with full hex/RGB/MiniMessage support
|
||||
- Yaml/JSON/TOML config system
|
||||
- Persistent data storage API with Yaml/MySQL/MongoDB support
|
||||
- Packet item display system
|
||||
- Entity AI API with near-1:1 NMS mappings
|
||||
- More events
|
||||
- Extension API, essentially plugins for plugins
|
||||
- Fluent dependency injection for NamespacedKey, Metadata values, etc.
|
||||
- Ultra-fast ItemStack reimplementation bypassing ItemMeta
|
||||
- Complete GUI API with pre-made components available from [ecomponent](https://github.com/Auxilor/ecomponent)
|
||||
- Over 30 native integrations for other plugins
|
||||
- First-class custom item support with lookup strings
|
||||
- Math expression parsing via [Crunch](https://github.com/Redempt/Crunch)
|
||||
- Particle lookups
|
||||
- Complete Placeholder API
|
||||
- Price system, supporting economy plugins, XP, Items, etc.
|
||||
- NMS/Version-specific tooling
|
||||
- Custom crafting recipe API with support for stacks and custom items
|
||||
- Native plugin update checking
|
||||
- Native bStats support
|
||||
- Full Kotlin support and native extensions
|
||||
- Tooling to make meta-frameworks, like [libreforge](https://github.com/Auxilor/libreforge)
|
||||
- And much more
|
||||
|
||||
# For server owners
|
||||
- Requires ProtocolLib to be installed: get the latest version [here](https://www.spigotmc.org/resources/protocollib.1997/)
|
||||
- Supports 1.17+
|
||||
|
||||
## Downloads
|
||||
|
||||
- Stable (Recommended): [GitHub](https://github.com/Auxilor/eco/releases), [Polymart](https://polymart.org/resource/eco.773)
|
||||
- Dev (Not Recommended): [GitHub](https://github.com/Auxilor/eco/actions/workflows/java-ci.yml) (Open latest run and download)
|
||||
- Stable: [GitHub](https://github.com/Auxilor/eco/releases), [Polymart](https://polymart.org/resource/eco.773)
|
||||
- Dev: [GitHub](https://github.com/Auxilor/eco/actions/workflows/java-ci.yml) (Open latest run and download)
|
||||
|
||||
# For developers
|
||||
|
||||
## Javadoc
|
||||
The 6.27.2 Javadoc can be found [here](https://javadoc.jitpack.io/com/willfp/eco/6.27.2/javadoc/)
|
||||
The 6.49.0 Javadoc can be found [here](https://javadoc.jitpack.io/com/willfp/eco/6.49.0/javadoc/)
|
||||
|
||||
## Plugin Information
|
||||
|
||||
@@ -68,7 +92,7 @@ dependencies {
|
||||
}
|
||||
```
|
||||
|
||||
Replace `Tag` with a release tag for eco, eg `6.27.2`.
|
||||
Replace `Tag` with a release tag for eco, eg `6.49.0`.
|
||||
|
||||
Maven:
|
||||
|
||||
@@ -88,7 +112,7 @@ Maven:
|
||||
</dependency>
|
||||
```
|
||||
|
||||
Replace `Tag` with a release tag for eco, eg `6.27.2`.
|
||||
Replace `Tag` with a release tag for eco, eg `6.49.0`.
|
||||
|
||||
## Build locally:
|
||||
|
||||
@@ -103,7 +127,7 @@ cd eco
|
||||
|
||||
## License
|
||||
|
||||
*Click here to read [the entire license](https://github.com/Auxilor/eco/blob/master/LICENSE.md).*
|
||||
eco is licensed under GNU GPL3. *Click here to read [the entire license](https://github.com/Auxilor/eco/blob/master/LICENSE.md).*
|
||||
|
||||
<h1 align="center">
|
||||
Check out our partners!
|
||||
|
||||
@@ -4,7 +4,7 @@ buildscript {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10")
|
||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,17 +13,19 @@ plugins {
|
||||
id("com.github.johnrengelman.shadow") version "7.1.2"
|
||||
id("maven-publish")
|
||||
id("java")
|
||||
kotlin("jvm") version "1.6.10"
|
||||
kotlin("jvm") version "1.7.10"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":eco-api"))
|
||||
implementation(project(":eco-core:core-plugin"))
|
||||
implementation(project(path = ":eco-core:core-plugin", configuration = "shadow"))
|
||||
implementation(project(":eco-core:core-proxy"))
|
||||
implementation(project(":eco-core:core-backend"))
|
||||
implementation(project(path = ":eco-core:core-nms:v1_17_R1", configuration = "reobf"))
|
||||
implementation(project(path = ":eco-core:core-nms:v1_18_R1", configuration = "reobf"))
|
||||
implementation(project(path = ":eco-core:core-nms:v1_18_R2", configuration = "reobf"))
|
||||
implementation(project(path = ":eco-core:core-nms:v1_19_R1", configuration = "reobf"))
|
||||
implementation(project(path = ":eco-core:core-nms:v1_19_R2", configuration = "reobf"))
|
||||
}
|
||||
|
||||
allprojects {
|
||||
@@ -44,11 +46,8 @@ allprojects {
|
||||
// SuperiorSkyblock2
|
||||
maven("https://repo.bg-software.com/repository/api/")
|
||||
|
||||
// NMS (for jitpack compilation)
|
||||
maven("https://repo.codemc.org/repository/nms/")
|
||||
|
||||
// mcMMO, BentoBox
|
||||
maven("https://repo.codemc.org/repository/maven-public/")
|
||||
maven("https://repo.codemc.io/repository/maven-public/")
|
||||
|
||||
// Spigot API, Bungee API
|
||||
maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/")
|
||||
@@ -63,7 +62,7 @@ allprojects {
|
||||
maven("https://maven.enginehub.org/repo/")
|
||||
|
||||
// FactionsUUID
|
||||
maven("https://ci.ender.zone/plugin/repository/everything/")
|
||||
//maven("https://ci.ender.zone/plugin/repository/everything/")
|
||||
|
||||
// NoCheatPlus
|
||||
maven("https://repo.md-5.net/content/repositories/snapshots/")
|
||||
@@ -71,9 +70,6 @@ allprojects {
|
||||
// CombatLogX
|
||||
maven("https://nexus.sirblobman.xyz/repository/public/")
|
||||
|
||||
// IridiumSkyblock
|
||||
maven("https://nexus.iridiumdevelopment.net/repository/maven-releases/")
|
||||
|
||||
// MythicMobs
|
||||
maven("https://mvn.lumine.io/repository/maven-public/")
|
||||
|
||||
@@ -82,24 +78,33 @@ allprojects {
|
||||
|
||||
// LibsDisguises
|
||||
maven("https://repo.md-5.net/content/groups/public/")
|
||||
|
||||
maven("https://repo.techscode.com/repository/maven-releases/")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly(kotlin("stdlib", version = "1.6.10"))
|
||||
// Kotlin
|
||||
implementation(kotlin("stdlib", version = "1.7.10"))
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.2")
|
||||
|
||||
// Included in spigot jar, no need to move to implementation
|
||||
compileOnly("org.jetbrains:annotations:23.0.0")
|
||||
compileOnly("com.google.guava:guava:31.1-jre")
|
||||
|
||||
// Test
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.2")
|
||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.2")
|
||||
|
||||
|
||||
// Adventure
|
||||
compileOnly("net.kyori:adventure-api:4.10.0")
|
||||
compileOnly("net.kyori:adventure-text-serializer-gson:4.10.0")
|
||||
compileOnly("net.kyori:adventure-text-serializer-legacy:4.10.0")
|
||||
implementation("net.kyori:adventure-api:4.10.1")
|
||||
implementation("net.kyori:adventure-text-serializer-gson:4.10.1") {
|
||||
exclude("com.google.code.gson", "gson") // Prevent shading into the jar
|
||||
}
|
||||
implementation("net.kyori:adventure-text-serializer-legacy:4.10.1")
|
||||
|
||||
// Other
|
||||
compileOnly("com.google.guava:guava:31.1-jre")
|
||||
compileOnly("com.github.ben-manes.caffeine:caffeine:3.0.5")
|
||||
implementation("com.github.ben-manes.caffeine:caffeine:3.1.0")
|
||||
implementation("org.apache.maven:maven-artifact:3.8.5")
|
||||
}
|
||||
|
||||
tasks.withType<JavaCompile> {
|
||||
@@ -115,10 +120,11 @@ allprojects {
|
||||
exclude(group = "com.darkblade12", module = "particleeffect")
|
||||
exclude(group = "com.github.cryptomorin", module = "XSeries")
|
||||
exclude(group = "net.wesjd", module = "anvilgui")
|
||||
exclude(group = "org.slf4j", module = "slf4j-api")
|
||||
}
|
||||
|
||||
configurations.testImplementation {
|
||||
setExtendsFrom(listOf(configurations.compileOnly.get()))
|
||||
setExtendsFrom(listOf(configurations.compileOnly.get(), configurations.implementation.get()))
|
||||
}
|
||||
|
||||
tasks {
|
||||
@@ -126,13 +132,41 @@ allprojects {
|
||||
kotlinOptions {
|
||||
jvmTarget = "17"
|
||||
}
|
||||
targetCompatibility = "17"
|
||||
sourceCompatibility = "17"
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
relocate("org.bstats", "com.willfp.eco.libs.bstats")
|
||||
relocate("redempt.crunch", "com.willfp.eco.libs.crunch")
|
||||
relocate("org.apache.commons.lang3", "com.willfp.eco.libs.lang3")
|
||||
relocate("org.apache.maven", "com.willfp.eco.libs.maven")
|
||||
relocate("org.checkerframework", "com.willfp.eco.libs.checkerframework")
|
||||
relocate("org.intellij", "com.willfp.eco.libs.intellij")
|
||||
relocate("org.jetbrains.annotations", "com.willfp.eco.libs.jetbrains.annotations")
|
||||
//relocate("org.jetbrains.exposed", "com.willfp.eco.libs.exposed")
|
||||
relocate("org.objenesis", "com.willfp.eco.libs.objenesis")
|
||||
relocate("org.reflections", "com.willfp.eco.libs.reflections")
|
||||
relocate("javassist", "com.willfp.eco.libs.javassist")
|
||||
relocate("javax.annotation", "com.willfp.eco.libs.annotation")
|
||||
relocate("com.google.errorprone", "com.willfp.eco.libs.errorprone")
|
||||
relocate("com.google.j2objc", "com.willfp.eco.libs.j2objc")
|
||||
relocate("com.google.thirdparty", "com.willfp.eco.libs.google.thirdparty")
|
||||
relocate("com.google.protobuf", "com.willfp.eco.libs.google.protobuf") // No I don't know either
|
||||
relocate("google.protobuf", "com.willfp.eco.libs.protobuf") // Still don't know
|
||||
relocate("com.zaxxer.hikari", "com.willfp.eco.libs.hikari")
|
||||
//relocate("com.mysql", "com.willfp.eco.libs.mysql")
|
||||
relocate("de.undercouch.bson4jackson", "com.willfp.eco.libs.bson4jackson")
|
||||
relocate("com.fasterxml.jackson", "com.willfp.eco.libs.jackson")
|
||||
relocate("com.mongodb", "com.willfp.eco.libs.mongodb")
|
||||
relocate("org.bson", "com.willfp.eco.libs.bson")
|
||||
relocate("org.litote", "com.willfp.eco.libs.litote")
|
||||
relocate("org.reactivestreams", "com.willfp.eco.libs.reactivestreams")
|
||||
relocate("reactor.", "com.willfp.eco.libs.reactor.") // Dot in name to be safe
|
||||
relocate("com.moandjiezana.toml", "com.willfp.eco.libs.toml")
|
||||
|
||||
/*
|
||||
Kotlin and caffeine are not shaded so that they can be accessed directly by eco plugins.
|
||||
Also, not relocating adventure, because it's a pain in the ass, and it doesn't *seem* to be causing loader constraint violations.
|
||||
*/
|
||||
}
|
||||
|
||||
compileJava {
|
||||
|
||||
@@ -4,7 +4,6 @@ dependencies {
|
||||
|
||||
// Other
|
||||
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
|
||||
compileOnly 'org.apache.maven:maven-artifact:3.8.1'
|
||||
compileOnly 'com.comphenix.protocol:ProtocolLib:4.6.1-SNAPSHOT'
|
||||
compileOnly 'com.google.code.gson:gson:2.8.8'
|
||||
}
|
||||
|
||||
@@ -1,82 +1,611 @@
|
||||
package com.willfp.eco.core;
|
||||
|
||||
import com.willfp.eco.core.command.CommandBase;
|
||||
import com.willfp.eco.core.command.PluginCommandBase;
|
||||
import com.willfp.eco.core.command.impl.PluginCommand;
|
||||
import com.willfp.eco.core.config.ConfigType;
|
||||
import com.willfp.eco.core.config.interfaces.Config;
|
||||
import com.willfp.eco.core.config.interfaces.LoadableConfig;
|
||||
import com.willfp.eco.core.config.updating.ConfigHandler;
|
||||
import com.willfp.eco.core.data.ExtendedPersistentDataContainer;
|
||||
import com.willfp.eco.core.data.PlayerProfile;
|
||||
import com.willfp.eco.core.data.ServerProfile;
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKey;
|
||||
import com.willfp.eco.core.drops.DropQueue;
|
||||
import com.willfp.eco.core.entities.ai.EntityController;
|
||||
import com.willfp.eco.core.events.EventManager;
|
||||
import com.willfp.eco.core.extensions.ExtensionLoader;
|
||||
import com.willfp.eco.core.factory.MetadataValueFactory;
|
||||
import com.willfp.eco.core.factory.NamespacedKeyFactory;
|
||||
import com.willfp.eco.core.factory.RunnableFactory;
|
||||
import com.willfp.eco.core.fast.FastItemStack;
|
||||
import com.willfp.eco.core.gui.menu.Menu;
|
||||
import com.willfp.eco.core.gui.menu.MenuBuilder;
|
||||
import com.willfp.eco.core.gui.menu.MenuType;
|
||||
import com.willfp.eco.core.gui.slot.SlotBuilder;
|
||||
import com.willfp.eco.core.gui.slot.functional.SlotProvider;
|
||||
import com.willfp.eco.core.items.TestableItem;
|
||||
import com.willfp.eco.core.math.MathContext;
|
||||
import com.willfp.eco.core.proxy.ProxyFactory;
|
||||
import com.willfp.eco.core.scheduling.Scheduler;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.command.CommandMap;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Mob;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Holds the instance of the eco handler for bridging between the frontend
|
||||
* and backend.
|
||||
* Holds the instance of eco for bridging between the frontend and backend.
|
||||
* <p>
|
||||
* <strong>Do not use this in your plugins!</strong> It can and will contain
|
||||
* breaking changes between minor versions and even patches, and you will create compatibility
|
||||
* issues by. All parts of this have been abstracted into logically named API components that you
|
||||
* can use.
|
||||
*
|
||||
* @see Eco#getHandler()
|
||||
* @see Handler
|
||||
* @see Eco#get()
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public final class Eco {
|
||||
/**
|
||||
* Instance of eco handler.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
private static Handler handler;
|
||||
public interface Eco {
|
||||
|
||||
/**
|
||||
* Set the handler.
|
||||
* Create a scheduler.
|
||||
*
|
||||
* @param handler The handler.
|
||||
* @param plugin The plugin.
|
||||
* @return The scheduler.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public static void setHandler(@NotNull final Handler handler) {
|
||||
Validate.isTrue(Eco.handler == null, "Already initialized!");
|
||||
|
||||
Eco.handler = handler;
|
||||
}
|
||||
@NotNull
|
||||
Scheduler createScheduler(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
* Get the instance of the eco handler; the bridge between the api frontend
|
||||
* and the implementation backend.
|
||||
* <p>
|
||||
* <strong>Do not use the handler in your plugins!</strong> It can and will contain
|
||||
* breaking changes between minor versions and even patches, and you will create
|
||||
* compatibility issues by using the handler. All parts of the handler have been abstracted
|
||||
* into logically named API components that you can use.
|
||||
* <p>
|
||||
* Prior to version 6.12.0, the handler was considered as an API component, but it has
|
||||
* since been moved into an internal component, and in 6.17.0, the first breaking change
|
||||
* was introduced to {@link com.willfp.eco.core.config.wrapper.ConfigFactory}. This means
|
||||
* that any usages of the handler can now cause problems in your plugins.
|
||||
* Create an event manager.
|
||||
*
|
||||
* @param plugin The plugin.F
|
||||
* @return The event manager.
|
||||
*/
|
||||
@NotNull
|
||||
EventManager createEventManager(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
* Create a NamespacedKey factory.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
* @return The factory.
|
||||
*/
|
||||
@NotNull
|
||||
NamespacedKeyFactory createNamespacedKeyFactory(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
* Create a MetadataValue factory.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
* @return The factory.
|
||||
*/
|
||||
@NotNull
|
||||
MetadataValueFactory createMetadataValueFactory(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
* Create a Runnable factory.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
* @return The factory.
|
||||
*/
|
||||
@NotNull
|
||||
RunnableFactory createRunnableFactory(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
* Create an ExtensionLoader.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
* @return The factory.
|
||||
*/
|
||||
@NotNull
|
||||
ExtensionLoader createExtensionLoader(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
* Create a config handler.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
* @return The handler.
|
||||
*/
|
||||
@NotNull
|
||||
ConfigHandler createConfigHandler(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
* Create a logger.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
* @return The logger.
|
||||
*/
|
||||
@NotNull
|
||||
Logger createLogger(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
* Create a PAPI integration.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
*/
|
||||
void createPAPIIntegration(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
* Create a proxy factory.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
* @return The factory.
|
||||
*/
|
||||
@NotNull
|
||||
ProxyFactory createProxyFactory(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
* Get eco Spigot plugin.
|
||||
*
|
||||
* @return The plugin.
|
||||
*/
|
||||
@NotNull
|
||||
EcoPlugin getEcoPlugin();
|
||||
|
||||
/**
|
||||
* Create PluginCommandBase implementation of {@link PluginCommand}.
|
||||
*
|
||||
* @param parentDelegate the enclosing class of this implementation.
|
||||
* @param plugin the plugin.
|
||||
* @param name the name of the command.
|
||||
* @param permission the permission of the command.
|
||||
* @param playersOnly if the command is players only.
|
||||
* @return The PluginCommandBase implementation
|
||||
*/
|
||||
@NotNull
|
||||
PluginCommandBase createPluginCommand(@NotNull CommandBase parentDelegate,
|
||||
@NotNull EcoPlugin plugin,
|
||||
@NotNull String name,
|
||||
@NotNull String permission,
|
||||
boolean playersOnly);
|
||||
|
||||
/**
|
||||
* Create CommandBase implementation of {@link com.willfp.eco.core.command.impl.Subcommand Subcommand}.
|
||||
*
|
||||
* @param parentDelegate the enclosing class of this implementation.
|
||||
* @param plugin the plugin.
|
||||
* @param name the name of the command.
|
||||
* @param permission the permission of the command.
|
||||
* @param playersOnly if the command is players only.
|
||||
* @return The CommandBase implementation
|
||||
*/
|
||||
@NotNull
|
||||
CommandBase createSubcommand(@NotNull CommandBase parentDelegate,
|
||||
@NotNull EcoPlugin plugin,
|
||||
@NotNull String name,
|
||||
@NotNull String permission,
|
||||
boolean playersOnly);
|
||||
|
||||
/**
|
||||
* Updatable config.
|
||||
*
|
||||
* @param configName The name of the config
|
||||
* @param plugin The plugin.
|
||||
* @param subDirectoryPath The subdirectory path.
|
||||
* @param source The class that owns the resource.
|
||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||
* @param type The config type.
|
||||
* @param updateBlacklist Substring of keys to not add/remove keys for.
|
||||
* @param requiresChangesToSave If the config must be changed in order to save the config.
|
||||
* @return The config implementation.
|
||||
*/
|
||||
@NotNull
|
||||
LoadableConfig createUpdatableConfig(@NotNull String configName,
|
||||
@NotNull PluginLike plugin,
|
||||
@NotNull String subDirectoryPath,
|
||||
@NotNull Class<?> source,
|
||||
boolean removeUnused,
|
||||
@NotNull ConfigType type,
|
||||
boolean requiresChangesToSave,
|
||||
@NotNull String... updateBlacklist);
|
||||
|
||||
/**
|
||||
* Loadable config.
|
||||
*
|
||||
* @param configName The name of the config
|
||||
* @param plugin The plugin.
|
||||
* @param subDirectoryPath The subdirectory path.
|
||||
* @param source The class that owns the resource.
|
||||
* @param type The config type.
|
||||
* @param requiresChangesToSave If the config must be changed in order to save the config.
|
||||
* @return The config implementation.
|
||||
*/
|
||||
@NotNull
|
||||
LoadableConfig createLoadableConfig(@NotNull String configName,
|
||||
@NotNull PluginLike plugin,
|
||||
@NotNull String subDirectoryPath,
|
||||
@NotNull Class<?> source,
|
||||
@NotNull ConfigType type,
|
||||
boolean requiresChangesToSave);
|
||||
|
||||
/**
|
||||
* Create config.
|
||||
*
|
||||
* @param config The handle.
|
||||
* @return The config implementation.
|
||||
*/
|
||||
@NotNull
|
||||
Config wrapConfigurationSection(@NotNull ConfigurationSection config);
|
||||
|
||||
/**
|
||||
* Create config.
|
||||
*
|
||||
* @param values The values.
|
||||
* @param type The config type.
|
||||
* @return The config implementation.
|
||||
*/
|
||||
@NotNull
|
||||
Config createConfig(@NotNull Map<String, Object> values,
|
||||
@NotNull ConfigType type);
|
||||
|
||||
/**
|
||||
* Create config.
|
||||
*
|
||||
* @param contents The file contents.
|
||||
* @param type The type.
|
||||
* @return The config implementation.
|
||||
*/
|
||||
@NotNull
|
||||
Config createConfig(@NotNull String contents,
|
||||
@NotNull ConfigType type);
|
||||
|
||||
/**
|
||||
* Create a Drop Queue.
|
||||
*
|
||||
* @param player The player.
|
||||
* @return The drop queue.
|
||||
*/
|
||||
@NotNull
|
||||
DropQueue createDropQueue(@NotNull Player player);
|
||||
|
||||
/**
|
||||
* Create slot builder.
|
||||
*
|
||||
* @param provider The provider.
|
||||
* @return The builder.
|
||||
*/
|
||||
@NotNull
|
||||
SlotBuilder createSlotBuilder(@NotNull SlotProvider provider);
|
||||
|
||||
/**
|
||||
* Create menu builder.
|
||||
*
|
||||
* @param rows The amount of rows.
|
||||
* @param type The type.
|
||||
* @return The builder.
|
||||
*/
|
||||
@NotNull
|
||||
MenuBuilder createMenuBuilder(int rows,
|
||||
@NotNull MenuType type);
|
||||
|
||||
/**
|
||||
* Combine the state of two menus together.
|
||||
*
|
||||
* @param base The base menu.
|
||||
* @param additional The additional state.
|
||||
* @return The menu.
|
||||
*/
|
||||
@NotNull
|
||||
Menu blendMenuState(@NotNull Menu base,
|
||||
@NotNull Menu additional);
|
||||
|
||||
/**
|
||||
* Clean up ClassLoader (etc.) to allow PlugMan support.
|
||||
*
|
||||
* @param plugin The plugin to clean up.
|
||||
*/
|
||||
void clean(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
* Add new plugin.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
*/
|
||||
void addNewPlugin(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
* Get plugin by name.
|
||||
*
|
||||
* @param name The name.
|
||||
* @return The plugin.
|
||||
*/
|
||||
@Nullable
|
||||
EcoPlugin getPluginByName(@NotNull String name);
|
||||
|
||||
/**
|
||||
* Get all loaded eco plugins.
|
||||
*
|
||||
* @return A list of plugin names in lowercase.
|
||||
*/
|
||||
@NotNull
|
||||
List<String> getLoadedPlugins();
|
||||
|
||||
/**
|
||||
* Create a FastItemStack.
|
||||
*
|
||||
* @param itemStack The base ItemStack.
|
||||
* @return The FastItemStack.
|
||||
*/
|
||||
@NotNull
|
||||
FastItemStack createFastItemStack(@NotNull ItemStack itemStack);
|
||||
|
||||
/**
|
||||
* Register bStats metrics.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
*/
|
||||
void registerBStats(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
* Get Adventure audiences.
|
||||
*
|
||||
* @return The audiences.
|
||||
*/
|
||||
@Nullable
|
||||
BukkitAudiences getAdventure();
|
||||
|
||||
/**
|
||||
* Register a persistent data key to be stored.
|
||||
*
|
||||
* @param key The key.
|
||||
*/
|
||||
void registerPersistentKey(@NotNull PersistentDataKey<?> key);
|
||||
|
||||
/**
|
||||
* Get all registered keys.
|
||||
*
|
||||
* @return The keys.
|
||||
*/
|
||||
@NotNull
|
||||
Set<PersistentDataKey<?>> getRegisteredPersistentDataKeys();
|
||||
|
||||
/**
|
||||
* Load a player profile.
|
||||
*
|
||||
* @param uuid The UUID.
|
||||
* @return The profile.
|
||||
*/
|
||||
@NotNull
|
||||
PlayerProfile loadPlayerProfile(@NotNull UUID uuid);
|
||||
|
||||
/**
|
||||
* Load the server profile.
|
||||
*
|
||||
* @return The profile.
|
||||
*/
|
||||
@NotNull
|
||||
ServerProfile getServerProfile();
|
||||
|
||||
/**
|
||||
* Unload a player profile from memory.
|
||||
* <p>
|
||||
* This will not save the profile first.
|
||||
*
|
||||
* @param uuid The uuid.
|
||||
*/
|
||||
void unloadPlayerProfile(@NotNull UUID uuid);
|
||||
|
||||
/**
|
||||
* Create dummy entity - never spawned, exists purely in code.
|
||||
*
|
||||
* @param location The location.
|
||||
* @return The entity.
|
||||
*/
|
||||
@NotNull
|
||||
Entity createDummyEntity(@NotNull Location location);
|
||||
|
||||
/**
|
||||
* Create a {@link NamespacedKey} quickly
|
||||
* <p>
|
||||
* Bypasses the constructor, allowing for the creation of invalid keys, therefore this is
|
||||
* considered unsafe and should only be called after the key has been confirmed to be valid.
|
||||
*
|
||||
* @param namespace The namespace.
|
||||
* @param key The key.
|
||||
* @return The key.
|
||||
*/
|
||||
@NotNull
|
||||
NamespacedKey createNamespacedKey(@NotNull String namespace,
|
||||
@NotNull String key);
|
||||
|
||||
/**
|
||||
* Return or get props for a plugin.
|
||||
*
|
||||
* @param existing The existing constructor props.
|
||||
* @param plugin The plugin.
|
||||
* @return The props.
|
||||
*/
|
||||
@NotNull
|
||||
PluginProps getProps(@Nullable PluginProps existing,
|
||||
@NotNull Class<? extends EcoPlugin> plugin);
|
||||
|
||||
/**
|
||||
* Format a string with MiniMessage.
|
||||
*
|
||||
* @param message The message.
|
||||
* @return The formatted string.
|
||||
*/
|
||||
@NotNull
|
||||
String formatMiniMessage(@NotNull String message);
|
||||
|
||||
/**
|
||||
* Create controlled entity from a mob.
|
||||
*
|
||||
* @param mob The mob.
|
||||
* @param <T> The mob type.
|
||||
* @return The controlled entity.
|
||||
*/
|
||||
@NotNull <T extends Mob> EntityController<T> createEntityController(@NotNull T mob);
|
||||
|
||||
/**
|
||||
* Adapt base PDC to extended PDC.
|
||||
*
|
||||
* @param container The container.
|
||||
* @return The extended container.
|
||||
*/
|
||||
@NotNull
|
||||
ExtendedPersistentDataContainer adaptPdc(@NotNull PersistentDataContainer container);
|
||||
|
||||
/**
|
||||
* Create new PDC.
|
||||
*
|
||||
* @return The container.
|
||||
*/
|
||||
@NotNull
|
||||
PersistentDataContainer newPdc();
|
||||
|
||||
/**
|
||||
* Get item from SNBT.
|
||||
*
|
||||
* @param snbt The NBT string.
|
||||
* @return The ItemStack, or null if invalid.
|
||||
*/
|
||||
@Nullable
|
||||
ItemStack fromSNBT(@NotNull String snbt);
|
||||
|
||||
/**
|
||||
* Convert item to SNBT.
|
||||
*
|
||||
* @param itemStack The item.
|
||||
* @return The NBT string.
|
||||
*/
|
||||
@NotNull
|
||||
String toSNBT(@NotNull ItemStack itemStack);
|
||||
|
||||
/**
|
||||
* Make TestableItem from SNBT.
|
||||
*
|
||||
* @param snbt The NBT string.
|
||||
* @return The TestableItem.
|
||||
*/
|
||||
@NotNull
|
||||
TestableItem testableItemFromSNBT(@NotNull String snbt);
|
||||
|
||||
/**
|
||||
* Get the texture of a skull.
|
||||
*
|
||||
* @param meta The skull meta.
|
||||
* @return The texture, or null if not found.
|
||||
*/
|
||||
@Nullable
|
||||
String getSkullTexture(@NotNull SkullMeta meta);
|
||||
|
||||
/**
|
||||
* Set the texture of a skull.
|
||||
*
|
||||
* @param meta The skull meta.
|
||||
* @param base64 The texture.
|
||||
*/
|
||||
void setSkullTexture(@NotNull SkullMeta meta,
|
||||
@NotNull String base64);
|
||||
|
||||
/**
|
||||
* Get the current server TPS.
|
||||
*
|
||||
* @return The TPS.
|
||||
*/
|
||||
double getTPS();
|
||||
|
||||
/**
|
||||
* Evaluate an expression.
|
||||
*
|
||||
* @param expression The expression.
|
||||
* @param context The context.
|
||||
* @return The value of the expression, or zero if invalid.
|
||||
*/
|
||||
double evaluate(@NotNull String expression,
|
||||
@NotNull MathContext context);
|
||||
|
||||
/**
|
||||
* Get the menu a player currently has open.
|
||||
*
|
||||
* @param player The player.
|
||||
* @return The menu, or null if no menu open.
|
||||
*/
|
||||
@Nullable
|
||||
Menu getOpenMenu(@NotNull Player player);
|
||||
|
||||
/**
|
||||
* Sync commands.
|
||||
*/
|
||||
void syncCommands();
|
||||
|
||||
/**
|
||||
* Get the command map.
|
||||
*
|
||||
* @return The command map.
|
||||
*/
|
||||
@NotNull CommandMap getCommandMap();
|
||||
|
||||
/**
|
||||
* Unregister a command.
|
||||
*
|
||||
* @param command The command.
|
||||
*/
|
||||
void unregisterCommand(@NotNull final PluginCommand command);
|
||||
|
||||
/**
|
||||
* Get the instance of eco; the bridge between the api frontend and the implementation backend.
|
||||
*
|
||||
* @return The instance of eco.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public static Handler getHandler() {
|
||||
return handler;
|
||||
static Eco get() {
|
||||
return Instance.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Eco Handler components are internals, so if a class is marked as a handler component,
|
||||
* then it should be treated the same as if it was marked with {@link ApiStatus.Internal}.
|
||||
* <p>
|
||||
* If a class is marked with {@link HandlerComponent}, <strong>Do not reference it in
|
||||
* your code!</strong> It can and will contain breaking changes between minor versions and
|
||||
* even patches, and you will create compatibility issues by using them.
|
||||
* <p>
|
||||
* Handler components should also be marked with {@link ApiStatus.Internal} in order to
|
||||
* cause compiler / IDE warnings.
|
||||
* Manages the internal frontend -> backend communication.
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
@Target({ElementType.TYPE})
|
||||
public @interface HandlerComponent {
|
||||
@ApiStatus.Internal
|
||||
final class Instance {
|
||||
|
||||
}
|
||||
/**
|
||||
* Instance of eco.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
private static Eco eco;
|
||||
|
||||
private Eco() {
|
||||
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||
/**
|
||||
* Initialize eco.
|
||||
*
|
||||
* @param eco The instance of eco.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
static void set(@NotNull final Eco eco) {
|
||||
Validate.isTrue(Instance.eco == null, "Already initialized!");
|
||||
|
||||
Instance.eco = eco;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get eco.
|
||||
*
|
||||
* @return eco.
|
||||
*/
|
||||
static Eco get() {
|
||||
return eco;
|
||||
}
|
||||
|
||||
private Instance() {
|
||||
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,15 +13,16 @@ import com.willfp.eco.core.factory.MetadataValueFactory;
|
||||
import com.willfp.eco.core.factory.NamespacedKeyFactory;
|
||||
import com.willfp.eco.core.factory.RunnableFactory;
|
||||
import com.willfp.eco.core.integrations.IntegrationLoader;
|
||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager;
|
||||
import com.willfp.eco.core.proxy.ProxyFactory;
|
||||
import com.willfp.eco.core.scheduling.Scheduler;
|
||||
import com.willfp.eco.core.web.UpdateChecker;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -79,12 +80,12 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
private final Set<String> loadedIntegrations = new HashSet<>();
|
||||
|
||||
/**
|
||||
* The internal plugin scheduler.
|
||||
* The plugin scheduler.
|
||||
*/
|
||||
private final Scheduler scheduler;
|
||||
|
||||
/**
|
||||
* The internal plugin Event Manager.
|
||||
* The plugin Event Manager.
|
||||
*/
|
||||
private final EventManager eventManager;
|
||||
|
||||
@@ -99,17 +100,17 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
private final LangYml langYml;
|
||||
|
||||
/**
|
||||
* The internal factory to produce {@link org.bukkit.NamespacedKey}s.
|
||||
* The factory to produce {@link org.bukkit.NamespacedKey}s.
|
||||
*/
|
||||
private final NamespacedKeyFactory namespacedKeyFactory;
|
||||
|
||||
/**
|
||||
* The internal factory to produce {@link org.bukkit.metadata.FixedMetadataValue}s.
|
||||
* The factory to produce {@link org.bukkit.metadata.FixedMetadataValue}s.
|
||||
*/
|
||||
private final MetadataValueFactory metadataValueFactory;
|
||||
|
||||
/**
|
||||
* The internal factory to produce {@link com.willfp.eco.core.scheduling.RunnableTask}s.
|
||||
* The factory to produce {@link com.willfp.eco.core.scheduling.RunnableTask}s.
|
||||
*/
|
||||
private final RunnableFactory runnableFactory;
|
||||
|
||||
@@ -151,6 +152,31 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
@Nullable
|
||||
private final ProxyFactory proxyFactory;
|
||||
|
||||
/**
|
||||
* The tasks to run on enable.
|
||||
*/
|
||||
private final List<Runnable> onEnable = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* The tasks to run on disable.
|
||||
*/
|
||||
private final List<Runnable> onDisable = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* The tasks to run on reload.
|
||||
*/
|
||||
private final List<Runnable> onReload = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* The tasks to run on load.
|
||||
*/
|
||||
private final List<Runnable> onLoad = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* The tasks to run after load.
|
||||
*/
|
||||
private final List<Runnable> afterLoad = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Create a new plugin.
|
||||
* <p>
|
||||
@@ -258,42 +284,42 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
*/
|
||||
protected EcoPlugin(@Nullable final PluginProps pluginProps) {
|
||||
/*
|
||||
The handler must be initialized before any plugin's constructors
|
||||
are called, as the constructors call Eco#getHandler().
|
||||
Eco must be initialized before any plugin's constructors
|
||||
are called, as the constructors call Eco#get().
|
||||
|
||||
To fix this, EcoSpigotPlugin an abstract class and the 'actual'
|
||||
plugin class is EcoHandler - that way I can create the handler
|
||||
plugin class is EcoImpl - that way I can initialize eco
|
||||
before any plugins are loaded while still having a separation between
|
||||
the plugin class and the handler class (for code clarity).
|
||||
the plugin class and the implementation class (for code clarity).
|
||||
|
||||
I don't really like the fact that the handler class *is* the
|
||||
I don't really like the fact that the implementation class *is* the
|
||||
spigot plugin, but it is what it is.
|
||||
|
||||
There is probably a better way of doing it - maybe with
|
||||
some sort of HandlerCreator interface in order to still have
|
||||
a standalone handler class, but then there would be an interface
|
||||
some sort of EcoCrater interface in order to still have
|
||||
a standalone eco class, but then there would be an interface
|
||||
left in the API that doesn't really help anything.
|
||||
|
||||
The other alternative would be to use reflection to get a 'createHandler'
|
||||
The other alternative would be to use reflection to get a 'createEco'
|
||||
method that only exists in EcoSpigotPlugin - but that feels filthy,
|
||||
and I'd rather only use reflection where necessary.
|
||||
*/
|
||||
|
||||
if (Eco.getHandler() == null && this instanceof Handler) {
|
||||
if (Eco.get() == null && this instanceof Eco) {
|
||||
/*
|
||||
This code is only ever called by EcoSpigotPlugin (EcoHandler)
|
||||
as it's the first plugin to load, and it is a handler.
|
||||
This code is only ever called by EcoSpigotPlugin (EcoImpl)
|
||||
as it's the first plugin to load, and it's an instance of eco.
|
||||
|
||||
Any other plugins will never call this code as the handler
|
||||
will have already been initialized.
|
||||
Any other plugins will never call this code as eco will have already
|
||||
been initialized.
|
||||
*/
|
||||
|
||||
Eco.setHandler((Handler) this);
|
||||
Eco.Instance.set((Eco) this);
|
||||
}
|
||||
|
||||
assert Eco.getHandler() != null;
|
||||
assert Eco.get() != null;
|
||||
|
||||
PluginProps generatedProps = Eco.getHandler().getProps(pluginProps, this.getClass());
|
||||
PluginProps generatedProps = Eco.get().getProps(pluginProps, this.getClass());
|
||||
generatedProps.validate();
|
||||
PluginProps props = this.mutateProps(generatedProps);
|
||||
props.validate();
|
||||
@@ -304,20 +330,30 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
this.color = props.getColor();
|
||||
this.supportingExtensions = props.isSupportingExtensions();
|
||||
|
||||
this.scheduler = Eco.getHandler().createScheduler(this);
|
||||
this.eventManager = Eco.getHandler().createEventManager(this);
|
||||
this.namespacedKeyFactory = Eco.getHandler().createNamespacedKeyFactory(this);
|
||||
this.metadataValueFactory = Eco.getHandler().createMetadataValueFactory(this);
|
||||
this.runnableFactory = Eco.getHandler().createRunnableFactory(this);
|
||||
this.extensionLoader = Eco.getHandler().createExtensionLoader(this);
|
||||
this.configHandler = Eco.getHandler().createConfigHandler(this);
|
||||
this.logger = Eco.getHandler().createLogger(this);
|
||||
this.proxyFactory = this.proxyPackage.equalsIgnoreCase("") ? null : Eco.getHandler().createProxyFactory(this);
|
||||
this.proxyFactory = this.proxyPackage.equalsIgnoreCase("") ? null : Eco.get().createProxyFactory(this);
|
||||
this.logger = Eco.get().createLogger(this);
|
||||
|
||||
this.getLogger().info("Initializing " + this.getColor() + this.getName());
|
||||
|
||||
this.scheduler = Eco.get().createScheduler(this);
|
||||
this.eventManager = Eco.get().createEventManager(this);
|
||||
this.namespacedKeyFactory = Eco.get().createNamespacedKeyFactory(this);
|
||||
this.metadataValueFactory = Eco.get().createMetadataValueFactory(this);
|
||||
this.runnableFactory = Eco.get().createRunnableFactory(this);
|
||||
this.extensionLoader = Eco.get().createExtensionLoader(this);
|
||||
this.configHandler = Eco.get().createConfigHandler(this);
|
||||
|
||||
this.langYml = this.createLangYml();
|
||||
|
||||
if (!this.langYml.isValid()) {
|
||||
this.getLogger().warning("Notify plugin authors " + String.join(", ", this.getDescription().getAuthors()) + " that");
|
||||
this.getLogger().warning("they are missing crucial lang.yml keys! They can be found");
|
||||
this.getLogger().warning("in the LangYml class.");
|
||||
}
|
||||
|
||||
this.configYml = this.createConfigYml();
|
||||
|
||||
Eco.getHandler().addNewPlugin(this);
|
||||
Eco.get().addNewPlugin(this);
|
||||
|
||||
/*
|
||||
The minimum eco version check was moved here because it's very common
|
||||
@@ -326,7 +362,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
they have an outdated version of eco installed.
|
||||
*/
|
||||
|
||||
DefaultArtifactVersion runningVersion = new DefaultArtifactVersion(Eco.getHandler().getEcoPlugin().getDescription().getVersion());
|
||||
DefaultArtifactVersion runningVersion = new DefaultArtifactVersion(Eco.get().getEcoPlugin().getDescription().getVersion());
|
||||
DefaultArtifactVersion requiredVersion = new DefaultArtifactVersion(this.getMinimumEcoVersion());
|
||||
if (!(runningVersion.compareTo(requiredVersion) > 0 || runningVersion.equals(requiredVersion))) {
|
||||
this.getLogger().severe("You are running an outdated version of eco!");
|
||||
@@ -347,21 +383,21 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
this.getLogger().info("");
|
||||
this.getLogger().info("Loading " + this.getColor() + this.getName());
|
||||
|
||||
if (this.getResourceId() != 0) {
|
||||
if (this.getResourceId() != 0 && !Eco.get().getEcoPlugin().getConfigYml().getBool("no-update-checker")) {
|
||||
new UpdateChecker(this).getVersion(version -> {
|
||||
DefaultArtifactVersion currentVersion = new DefaultArtifactVersion(this.getDescription().getVersion());
|
||||
DefaultArtifactVersion mostRecentVersion = new DefaultArtifactVersion(version);
|
||||
if (!(currentVersion.compareTo(mostRecentVersion) > 0 || currentVersion.equals(mostRecentVersion))) {
|
||||
this.outdated = true;
|
||||
this.getLogger().warning("&c" + this.getName() + " is out of date! (Version " + this.getDescription().getVersion() + ")");
|
||||
this.getLogger().warning("&cThe newest version is &f" + version);
|
||||
this.getLogger().warning("&cDownload the new version!");
|
||||
this.getLogger().warning(this.getName() + " is out of date! (Version " + this.getDescription().getVersion() + ")");
|
||||
this.getLogger().warning("The newest version is " + version);
|
||||
this.getLogger().warning("Download the new version!");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (this.getBStatsId() != 0) {
|
||||
Eco.getHandler().registerBStats(this);
|
||||
Eco.get().registerBStats(this);
|
||||
}
|
||||
|
||||
Set<String> enabledPlugins = Arrays.stream(Bukkit.getPluginManager().getPlugins())
|
||||
@@ -370,16 +406,17 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
if (enabledPlugins.contains("PlaceholderAPI".toLowerCase())) {
|
||||
this.loadedIntegrations.add("PlaceholderAPI");
|
||||
PlaceholderManager.addIntegration(Eco.getHandler().createPAPIIntegration(this));
|
||||
Eco.get().createPAPIIntegration(this);
|
||||
}
|
||||
|
||||
this.loadIntegrationLoaders().forEach((integrationLoader -> {
|
||||
this.loadIntegrationLoaders().forEach(integrationLoader -> {
|
||||
if (enabledPlugins.contains(integrationLoader.getPluginName().toLowerCase())) {
|
||||
this.loadedIntegrations.add(integrationLoader.getPluginName());
|
||||
integrationLoader.load();
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
this.loadedIntegrations.removeIf(pl -> pl.equalsIgnoreCase(this.getName()));
|
||||
|
||||
this.getLogger().info("Loaded integrations: " + String.join(", ", this.getLoadedIntegrations()));
|
||||
|
||||
@@ -409,10 +446,20 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
}
|
||||
|
||||
this.handleEnable();
|
||||
this.onEnable.forEach(Runnable::run);
|
||||
|
||||
this.getLogger().info("");
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new task to run on enable.
|
||||
*
|
||||
* @param task The task.
|
||||
*/
|
||||
public final void onEnable(@NotNull final Runnable task) {
|
||||
this.onEnable.add(task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default code to be executed on plugin disable.
|
||||
*/
|
||||
@@ -424,13 +471,23 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
this.getScheduler().cancelAll();
|
||||
|
||||
this.handleDisable();
|
||||
this.onDisable.forEach(Runnable::run);
|
||||
|
||||
if (this.isSupportingExtensions()) {
|
||||
this.getExtensionLoader().unloadExtensions();
|
||||
}
|
||||
|
||||
this.getLogger().info("Cleaning up...");
|
||||
Eco.getHandler().getCleaner().clean(this);
|
||||
Eco.get().clean(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new task to run on disable.
|
||||
*
|
||||
* @param task The task.
|
||||
*/
|
||||
public final void onDisable(@NotNull final Runnable task) {
|
||||
this.onDisable.add(task);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -441,6 +498,16 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
super.onLoad();
|
||||
|
||||
this.handleLoad();
|
||||
this.onLoad.forEach(Runnable::run);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new task to run on load.
|
||||
*
|
||||
* @param task The task.
|
||||
*/
|
||||
public final void onLoad(@NotNull final Runnable task) {
|
||||
this.onLoad.add(task);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -473,6 +540,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
}
|
||||
|
||||
this.handleAfterLoad();
|
||||
this.afterLoad.forEach(Runnable::run);
|
||||
|
||||
this.reload();
|
||||
|
||||
@@ -483,23 +551,42 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
this.getLogger().info("Loaded " + this.color + this.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new task to run after load.
|
||||
*
|
||||
* @param task The task.
|
||||
*/
|
||||
public final void afterLoad(@NotNull final Runnable task) {
|
||||
this.afterLoad.add(task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload the plugin.
|
||||
*/
|
||||
public final void reload() {
|
||||
this.getConfigHandler().updateConfigs();
|
||||
|
||||
this.getScheduler().cancelAll();
|
||||
this.getConfigHandler().callUpdate();
|
||||
this.getConfigHandler().callUpdate(); // Call twice to fix issues
|
||||
this.getScheduler().cancelAll();
|
||||
|
||||
this.handleReload();
|
||||
this.onReload.forEach(Runnable::run);
|
||||
|
||||
for (Extension extension : this.extensionLoader.getLoadedExtensions()) {
|
||||
extension.handleReload();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new task to run on enable.
|
||||
*
|
||||
* @param task The task.
|
||||
*/
|
||||
public final void onReload(@NotNull final Runnable task) {
|
||||
this.onReload.add(task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload the plugin and return the time taken to reload.
|
||||
*
|
||||
@@ -619,7 +706,15 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
* @return lang.yml.
|
||||
*/
|
||||
protected LangYml createLangYml() {
|
||||
return new LangYml(this);
|
||||
try {
|
||||
return new LangYml(this);
|
||||
} catch (NullPointerException e) {
|
||||
this.getLogger().severe("Failed to load lang.yml!");
|
||||
this.getLogger().severe("For the developer of this plugin: make sure you have a lang.yml");
|
||||
e.printStackTrace();
|
||||
Bukkit.getPluginManager().disablePlugin(this);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -630,7 +725,15 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
* @return config.yml.
|
||||
*/
|
||||
protected ConfigYml createConfigYml() {
|
||||
return new ConfigYml(this);
|
||||
try {
|
||||
return new ConfigYml(this);
|
||||
} catch (NullPointerException e) {
|
||||
this.getLogger().severe("Failed to load config.yml!");
|
||||
this.getLogger().severe("For the developer of this plugin: make sure you have a config.yml");
|
||||
e.printStackTrace();
|
||||
Bukkit.getPluginManager().disablePlugin(this);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -694,7 +797,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
public final FileConfiguration getConfig() {
|
||||
this.getLogger().warning("Call to default config method in eco plugin!");
|
||||
|
||||
return Objects.requireNonNull(this.getConfigYml().getBukkitHandle());
|
||||
return Objects.requireNonNull(this.getConfigYml().toBukkit());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -743,7 +846,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
* @return The plugin.
|
||||
*/
|
||||
public static EcoPlugin getPlugin(@NotNull final String pluginName) {
|
||||
return Eco.getHandler().getPluginByName(pluginName);
|
||||
return Eco.get().getPluginByName(pluginName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -752,7 +855,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
* @return The set of names.
|
||||
*/
|
||||
public static Set<String> getPluginNames() {
|
||||
return new HashSet<>(Eco.getHandler().getLoadedPlugins());
|
||||
return new HashSet<>(Eco.get().getLoadedPlugins());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -918,4 +1021,26 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
public ProxyFactory getProxyFactory() {
|
||||
return this.proxyFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a NamespacedKey.
|
||||
*
|
||||
* @param key The key.
|
||||
* @return The namespaced key.
|
||||
*/
|
||||
@NotNull
|
||||
public NamespacedKey createNamespacedKey(@NotNull final String key) {
|
||||
return this.getNamespacedKeyFactory().create(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a metadata value.
|
||||
*
|
||||
* @param value The value.
|
||||
* @return The metadata value.
|
||||
*/
|
||||
@NotNull
|
||||
public FixedMetadataValue createMetadataValue(@NotNull final Object value) {
|
||||
return this.getMetadataValueFactory().create(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,285 +0,0 @@
|
||||
package com.willfp.eco.core;
|
||||
|
||||
import com.willfp.eco.core.config.updating.ConfigHandler;
|
||||
import com.willfp.eco.core.config.wrapper.ConfigFactory;
|
||||
import com.willfp.eco.core.data.ProfileHandler;
|
||||
import com.willfp.eco.core.data.keys.KeyRegistry;
|
||||
import com.willfp.eco.core.drops.DropQueueFactory;
|
||||
import com.willfp.eco.core.entities.ai.EntityController;
|
||||
import com.willfp.eco.core.events.EventManager;
|
||||
import com.willfp.eco.core.extensions.ExtensionLoader;
|
||||
import com.willfp.eco.core.factory.MetadataValueFactory;
|
||||
import com.willfp.eco.core.factory.NamespacedKeyFactory;
|
||||
import com.willfp.eco.core.factory.RunnableFactory;
|
||||
import com.willfp.eco.core.fast.FastItemStack;
|
||||
import com.willfp.eco.core.gui.GUIFactory;
|
||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderIntegration;
|
||||
import com.willfp.eco.core.proxy.Cleaner;
|
||||
import com.willfp.eco.core.proxy.ProxyFactory;
|
||||
import com.willfp.eco.core.scheduling.Scheduler;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Mob;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* @see Eco#getHandler()
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public interface Handler {
|
||||
/**
|
||||
* Create a scheduler.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
* @return The scheduler.
|
||||
*/
|
||||
@NotNull
|
||||
Scheduler createScheduler(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
* Create an event manager.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
* @return The event manager.
|
||||
*/
|
||||
@NotNull
|
||||
EventManager createEventManager(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
* Create a NamespacedKey factory.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
* @return The factory.
|
||||
*/
|
||||
@NotNull
|
||||
NamespacedKeyFactory createNamespacedKeyFactory(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
* Create a MetadataValue factory.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
* @return The factory.
|
||||
*/
|
||||
@NotNull
|
||||
MetadataValueFactory createMetadataValueFactory(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
* Create a Runnable factory.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
* @return The factory.
|
||||
*/
|
||||
@NotNull
|
||||
RunnableFactory createRunnableFactory(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
* Create an ExtensionLoader.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
* @return The factory.
|
||||
*/
|
||||
@NotNull
|
||||
ExtensionLoader createExtensionLoader(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
* Create a config handler.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
* @return The handler.
|
||||
*/
|
||||
@NotNull
|
||||
ConfigHandler createConfigHandler(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
* Create a logger.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
* @return The logger.
|
||||
*/
|
||||
@NotNull
|
||||
Logger createLogger(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
* Create a PAPI integration.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
* @return The integration.
|
||||
*/
|
||||
@NotNull
|
||||
PlaceholderIntegration createPAPIIntegration(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
* Create a proxy factory.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
* @return The factory.
|
||||
*/
|
||||
@NotNull
|
||||
ProxyFactory createProxyFactory(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
* Get eco Spigot plugin.
|
||||
*
|
||||
* @return The plugin.
|
||||
*/
|
||||
@NotNull
|
||||
EcoPlugin getEcoPlugin();
|
||||
|
||||
/**
|
||||
* Get config factory.
|
||||
*
|
||||
* @return The factory.
|
||||
*/
|
||||
@NotNull
|
||||
ConfigFactory getConfigFactory();
|
||||
|
||||
/**
|
||||
* Get drop queue factory.
|
||||
*
|
||||
* @return The factory.
|
||||
*/
|
||||
@NotNull
|
||||
DropQueueFactory getDropQueueFactory();
|
||||
|
||||
/**
|
||||
* Get GUI factory.
|
||||
*
|
||||
* @return The factory.
|
||||
*/
|
||||
@NotNull
|
||||
GUIFactory getGUIFactory();
|
||||
|
||||
/**
|
||||
* Get cleaner.
|
||||
*
|
||||
* @return The cleaner.
|
||||
*/
|
||||
@NotNull
|
||||
Cleaner getCleaner();
|
||||
|
||||
/**
|
||||
* Add new plugin.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
*/
|
||||
void addNewPlugin(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
* Get plugin by name.
|
||||
*
|
||||
* @param name The name.
|
||||
* @return The plugin.
|
||||
*/
|
||||
@Nullable
|
||||
EcoPlugin getPluginByName(@NotNull String name);
|
||||
|
||||
/**
|
||||
* Get all loaded eco plugins.
|
||||
*
|
||||
* @return A list of plugin names in lowercase.
|
||||
*/
|
||||
@NotNull
|
||||
List<String> getLoadedPlugins();
|
||||
|
||||
/**
|
||||
* Create a FastItemStack.
|
||||
*
|
||||
* @param itemStack The base ItemStack.
|
||||
* @return The FastItemStack.
|
||||
*/
|
||||
@NotNull
|
||||
FastItemStack createFastItemStack(@NotNull ItemStack itemStack);
|
||||
|
||||
/**
|
||||
* Register bStats metrics.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
*/
|
||||
void registerBStats(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
* Get Adventure audiences.
|
||||
*
|
||||
* @return The audiences.
|
||||
*/
|
||||
@Nullable
|
||||
BukkitAudiences getAdventure();
|
||||
|
||||
/**
|
||||
* Get the key registry.
|
||||
*
|
||||
* @return The registry.
|
||||
*/
|
||||
@NotNull
|
||||
KeyRegistry getKeyRegistry();
|
||||
|
||||
/**
|
||||
* Get the PlayerProfile handler.
|
||||
*
|
||||
* @return The handler.
|
||||
*/
|
||||
@NotNull
|
||||
ProfileHandler getProfileHandler();
|
||||
|
||||
/**
|
||||
* Create dummy entity - never spawned, exists purely in code.
|
||||
*
|
||||
* @param location The location.
|
||||
* @return The entity.
|
||||
*/
|
||||
@NotNull
|
||||
Entity createDummyEntity(@NotNull Location location);
|
||||
|
||||
/**
|
||||
* Create a {@link NamespacedKey} quickly
|
||||
* <p>
|
||||
* Bypasses the constructor, allowing for the creation of invalid keys,
|
||||
* therefore this is considered unsafe and should only be called after
|
||||
* the key has been confirmed to be valid.
|
||||
*
|
||||
* @param namespace The namespace.
|
||||
* @param key The key.
|
||||
* @return The key.
|
||||
*/
|
||||
@NotNull
|
||||
NamespacedKey createNamespacedKey(@NotNull String namespace,
|
||||
@NotNull String key);
|
||||
|
||||
/**
|
||||
* Return or get props for a plugin.
|
||||
*
|
||||
* @param existing The existing constructor props.
|
||||
* @param plugin The plugin.
|
||||
* @return The props.
|
||||
*/
|
||||
@NotNull
|
||||
PluginProps getProps(@Nullable PluginProps existing,
|
||||
@NotNull Class<? extends EcoPlugin> plugin);
|
||||
|
||||
/**
|
||||
* Format a string with MiniMessage.
|
||||
*
|
||||
* @param message The message.
|
||||
* @return The formatted string.
|
||||
*/
|
||||
@NotNull
|
||||
String formatMiniMessage(@NotNull String message);
|
||||
|
||||
/**
|
||||
* Create controlled entity from a mob.
|
||||
*
|
||||
* @param mob The mob.
|
||||
* @param <T> The mob type.
|
||||
* @return The controlled entity.
|
||||
*/
|
||||
@NotNull
|
||||
<T extends Mob> EntityController<T> createEntityController(@NotNull T mob);
|
||||
}
|
||||
@@ -13,7 +13,9 @@ import org.jetbrains.annotations.NotNull;
|
||||
* in the constructor.
|
||||
*
|
||||
* @param <T> The eco plugin type.
|
||||
* @deprecated Leaky inheritance, shouldn't exist.
|
||||
*/
|
||||
@Deprecated(since = "6.43.0", forRemoval = true)
|
||||
public abstract class PluginDependent<T extends EcoPlugin> {
|
||||
/**
|
||||
* The {@link EcoPlugin} that is stored.
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.willfp.eco.core;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -222,7 +221,7 @@ public final class PluginProps {
|
||||
|
||||
/**
|
||||
* Create new props from known values.
|
||||
*
|
||||
* <p>
|
||||
* Marked as internal as this method will break whenever the properties themselves
|
||||
* are updated (e.g. if a new property is added) - so to prevent any potential
|
||||
* backwards-compatibility bugs, this method cannot be invoked outside eco itself.
|
||||
@@ -234,7 +233,6 @@ public final class PluginProps {
|
||||
* @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,
|
||||
|
||||
@@ -26,7 +26,7 @@ public class Prerequisite {
|
||||
* Requires the server to be running an implementation of paper.
|
||||
*/
|
||||
public static final Prerequisite HAS_PAPER = new Prerequisite(
|
||||
() -> ClassUtils.exists("com.destroystokyo.paper.event.player.PlayerElytraBoostEvent"),
|
||||
() -> ClassUtils.exists("com.destroystokyo.paper.event.block.BeaconEffectEvent"),
|
||||
"Requires server to be running paper (or a fork)"
|
||||
);
|
||||
|
||||
@@ -35,17 +35,25 @@ public class Prerequisite {
|
||||
*
|
||||
* @deprecated Use {@link EconomyManager#hasRegistrations()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@Deprecated(forRemoval = true)
|
||||
public static final Prerequisite HAS_VAULT = new Prerequisite(
|
||||
() -> ClassUtils.exists("net.milkbowl.vault.economy.Economy"),
|
||||
"Requires server to have vault"
|
||||
);
|
||||
|
||||
/**
|
||||
* Requires the server to be running 1.19.
|
||||
*/
|
||||
public static final Prerequisite HAS_1_19 = new Prerequisite(
|
||||
() -> ProxyConstants.NMS_VERSION.contains("19"),
|
||||
"Requires server to be running 1.19+"
|
||||
);
|
||||
|
||||
/**
|
||||
* Requires the server to be running 1.18.
|
||||
*/
|
||||
public static final Prerequisite HAS_1_18 = new Prerequisite(
|
||||
() -> ProxyConstants.NMS_VERSION.contains("18"),
|
||||
() -> ProxyConstants.NMS_VERSION.contains("18") || HAS_1_19.isMet(),
|
||||
"Requires server to be running 1.18+"
|
||||
);
|
||||
|
||||
@@ -54,7 +62,7 @@ public class Prerequisite {
|
||||
*
|
||||
* @deprecated eco no longer supports versions before 1.17.
|
||||
*/
|
||||
@Deprecated(since = "6.25.2")
|
||||
@Deprecated(since = "6.25.2", forRemoval = true)
|
||||
public static final Prerequisite HAS_1_17 = new Prerequisite(
|
||||
() -> ProxyConstants.NMS_VERSION.contains("17") || HAS_1_18.isMet(),
|
||||
"Requires server to be running 1.17+"
|
||||
@@ -62,7 +70,10 @@ public class Prerequisite {
|
||||
|
||||
/**
|
||||
* Requires the server to be running an implementation of BungeeCord.
|
||||
*
|
||||
* @deprecated This will never return true.
|
||||
*/
|
||||
@Deprecated(since = "6.49.0", forRemoval = true)
|
||||
public static final Prerequisite HAS_BUNGEECORD = new Prerequisite(
|
||||
() -> ClassUtils.exists("net.md_5.bungee.api.event.ServerConnectedEvent"),
|
||||
"Requires server to be running BungeeCord (or a fork)"
|
||||
@@ -70,7 +81,10 @@ public class Prerequisite {
|
||||
|
||||
/**
|
||||
* Requires the server to be running an implementation of Velocity.
|
||||
*
|
||||
* @deprecated This will never return true.
|
||||
*/
|
||||
@Deprecated(since = "6.49.0", forRemoval = true)
|
||||
public static final Prerequisite HAS_VELOCITY = new Prerequisite(
|
||||
() -> ClassUtils.exists("com.velocitypowered.api.event.player.ServerConnectedEvent"),
|
||||
"Requires server to be running Velocity (or a fork)"
|
||||
|
||||
@@ -1,29 +1,37 @@
|
||||
package com.willfp.eco.core.command;
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Interface for all command implementations.
|
||||
* Generic interface for commands.
|
||||
*/
|
||||
@SuppressWarnings("null")
|
||||
public interface CommandBase {
|
||||
|
||||
/**
|
||||
* Get command name.
|
||||
*
|
||||
* @return The name.
|
||||
*/
|
||||
String getName();
|
||||
@NotNull String getName();
|
||||
|
||||
/**
|
||||
* Get command permission.
|
||||
*
|
||||
* @return The permission.
|
||||
*/
|
||||
String getPermission();
|
||||
@NotNull String getPermission();
|
||||
|
||||
/**
|
||||
* If only players can execute the command.
|
||||
@@ -38,79 +46,237 @@ public interface CommandBase {
|
||||
* @param command The subcommand.
|
||||
* @return The parent command.
|
||||
*/
|
||||
CommandBase addSubcommand(@NotNull CommandBase command);
|
||||
@NotNull CommandBase addSubcommand(@NotNull CommandBase command);
|
||||
|
||||
/**
|
||||
* Get the subcommands of the command.
|
||||
*
|
||||
* @return The subcommands.
|
||||
*/
|
||||
@NotNull List<CommandBase> getSubcommands();
|
||||
|
||||
/**
|
||||
* Intended for returning the enclosing CommandBase,
|
||||
* when this instance is serving as the delegate command base.
|
||||
*
|
||||
* @return the wrapping object of this delegate.
|
||||
*/
|
||||
default @NotNull CommandBase getWrapped() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle command execution.
|
||||
* <p>
|
||||
* Marked as default void with no implementation for backwards compatibility.
|
||||
* This will always be called on command execution.
|
||||
*
|
||||
* @param sender The sender.
|
||||
* @param args The args.
|
||||
* @throws NotificationException naturally, this is handled as a part of the command system.
|
||||
*/
|
||||
default void onExecute(@NotNull CommandSender sender,
|
||||
@NotNull List<String> args) {
|
||||
default void onExecute(@NotNull final CommandSender sender, @NotNull final List<String> args) throws NotificationException {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle command execution from players.
|
||||
* <p>
|
||||
* This will only be called if the sender is a player.
|
||||
*
|
||||
* @param sender The sender.
|
||||
* @param args The args.
|
||||
* @throws NotificationException naturally, this is handled as a part of the command system.
|
||||
*/
|
||||
default void onExecute(@NotNull final Player sender, @NotNull final List<String> args) throws NotificationException {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle tab completion.
|
||||
* <p>
|
||||
* Marked as default void with no implementation for backwards compatibility.
|
||||
* This will always be called on tab completion.
|
||||
*
|
||||
* @param sender The sender.
|
||||
* @param args The args.
|
||||
* @return The results.
|
||||
*/
|
||||
default List<String> tabComplete(@NotNull CommandSender sender,
|
||||
@NotNull List<String> args) {
|
||||
@NotNull
|
||||
default List<String> tabComplete(@NotNull final CommandSender sender, @NotNull final List<String> args) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle tab completion.
|
||||
* <p>
|
||||
* This will only be called if the sender is a player.
|
||||
*
|
||||
* @param sender The sender.
|
||||
* @param args The args.
|
||||
* @return The results.
|
||||
*/
|
||||
@NotNull
|
||||
default List<String> tabComplete(@NotNull final Player sender, @NotNull final List<String> args) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an {@link NotificationException} relating to a specific lang.yml key.
|
||||
* <p>
|
||||
* This is automatically handled with eco, and should not be surrounded by a
|
||||
* try/catch block.
|
||||
*
|
||||
* @param key The lang.yml key for the message to be sent.
|
||||
* @throws NotificationException always.
|
||||
*/
|
||||
default void notify(@NotNull final String key) throws NotificationException {
|
||||
throw new NotificationException(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an {@link NotificationException} relating to a specific lang.yml key
|
||||
* if the passed object is null.
|
||||
* <p>
|
||||
* This is automatically handled with eco, and should not be surrounded by a
|
||||
* try/catch block.
|
||||
*
|
||||
* @param obj The object to test.
|
||||
* @param key The lang.yml key for the message to be sent.
|
||||
* @param <T> The object type.
|
||||
* @return Returns the object, definitely not-null.
|
||||
* @throws NotificationException If the object is null.
|
||||
*/
|
||||
@NotNull
|
||||
default <T> T notifyNull(@Nullable final T obj,
|
||||
@NotNull final String key) throws NotificationException {
|
||||
if (Objects.isNull(obj)) {
|
||||
notify(key);
|
||||
}
|
||||
|
||||
return Objects.requireNonNull(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an {@link NotificationException} relating to a specific lang.yml key
|
||||
* if the passed object doesn't match the predicate.
|
||||
* <p>
|
||||
* This is automatically handled with eco, and should not be surrounded by a
|
||||
* try/catch block.
|
||||
*
|
||||
* @param obj The object to test.
|
||||
* @param key The lang.yml key for the message to be sent.
|
||||
* @param predicate The predicate to test the object against.
|
||||
* @param <T> The type of the object.
|
||||
* @return Returns the object, definitely not-null.
|
||||
* @throws NotificationException If the object doesn't satisfy the predicate.
|
||||
*/
|
||||
@NotNull
|
||||
default <T> T notifyFalse(@NotNull final T obj,
|
||||
@NotNull final String key,
|
||||
@NotNull final Predicate<T> predicate) throws NotificationException {
|
||||
notifyFalse(predicate.test(obj), key);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Throws an {@link NotificationException} relating to a specific lang.yml key
|
||||
* if a condition is false.
|
||||
* <p>
|
||||
* This is automatically handled with eco, and should not be surrounded by a
|
||||
* try/catch block.
|
||||
*
|
||||
* @param condition The condition to test.
|
||||
* @param key The lang.yml key for the message to be sent.
|
||||
* @return True.
|
||||
* @throws NotificationException If the condition is false.
|
||||
*/
|
||||
default boolean notifyFalse(final boolean condition,
|
||||
@NotNull final String key) throws NotificationException {
|
||||
if (!condition) {
|
||||
notify(key);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an {@link NotificationException} relating to a specific lang.yml key
|
||||
* if the passed string doesn't relate to a currently online player.
|
||||
* <p>
|
||||
* This is automatically handled with eco, and should not be surrounded by a
|
||||
* try/catch block.
|
||||
*
|
||||
* @param playerName The player name.
|
||||
* @param key The lang.yml key for the message to be sent.
|
||||
* @return Returns the player, definitely not-null.
|
||||
* @throws NotificationException If the player name is invalid.
|
||||
*/
|
||||
@NotNull
|
||||
default Player notifyPlayerRequired(@Nullable final String playerName, @NotNull final String key) throws NotificationException {
|
||||
if (playerName == null) {
|
||||
notify(key);
|
||||
}
|
||||
|
||||
assert playerName != null;
|
||||
|
||||
final Player player = Bukkit.getPlayer(playerName);
|
||||
|
||||
notifyNull(player, key);
|
||||
|
||||
return Objects.requireNonNull(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an {@link NotificationException} relating to a specific lang.yml key
|
||||
* if the passed string doesn't relate to a player on the server.
|
||||
* <p>
|
||||
* This is automatically handled with eco, and should not be surrounded by a
|
||||
* try/catch block.
|
||||
*
|
||||
* @param playerName The player name.
|
||||
* @param key The lang.yml key for the message to be sent.
|
||||
* @return Returns the offline player, definitely not-null.
|
||||
* @throws NotificationException If the player name is invalid.
|
||||
*/
|
||||
@NotNull
|
||||
default OfflinePlayer notifyOfflinePlayerRequired(@Nullable final String playerName,
|
||||
@NotNull final String key) throws NotificationException {
|
||||
if (playerName == null) {
|
||||
notify(key);
|
||||
}
|
||||
|
||||
assert playerName != null;
|
||||
|
||||
@SuppressWarnings("deprecation") final OfflinePlayer player = Bukkit.getOfflinePlayer(playerName);
|
||||
|
||||
boolean hasPlayedBefore = player.hasPlayedBefore() || player.isOnline();
|
||||
|
||||
notifyFalse(!hasPlayedBefore, key);
|
||||
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an exception containing a langYml key if player doesn't have permission.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param permission The permission.
|
||||
* @param key The lang.yml key for the message to be sent.
|
||||
* @return The player.
|
||||
* @throws NotificationException If the player doesn't have the required permission.
|
||||
*/
|
||||
@NotNull
|
||||
default Player notifyPermissionRequired(@NotNull final Player player,
|
||||
@NotNull final String permission,
|
||||
@NotNull final String key) throws NotificationException {
|
||||
return notifyFalse(player, key, p -> p.hasPermission(permission));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plugin.
|
||||
*
|
||||
* @return The plugin.
|
||||
*/
|
||||
EcoPlugin getPlugin();
|
||||
|
||||
/**
|
||||
* Get the handler.
|
||||
*
|
||||
* @return The handler.
|
||||
* @see CommandHandler
|
||||
* @deprecated Use {@link CommandBase#onExecute(CommandSender, List)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
CommandHandler getHandler();
|
||||
|
||||
/**
|
||||
* Set the handler.
|
||||
*
|
||||
* @param handler The handler.
|
||||
* @see CommandHandler
|
||||
* @deprecated Handlers have been deprecated.
|
||||
*/
|
||||
@Deprecated
|
||||
void setHandler(@NotNull CommandHandler handler);
|
||||
|
||||
/**
|
||||
* Get the tab completer.
|
||||
*
|
||||
* @return The tab completer.
|
||||
* @see TabCompleteHandler
|
||||
* @deprecated Use {@link CommandBase#tabComplete(CommandSender, List)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
TabCompleteHandler getTabCompleter();
|
||||
|
||||
/**
|
||||
* Set the tab completer.
|
||||
*
|
||||
* @param handler The handler.
|
||||
* @see TabCompleteHandler
|
||||
* @deprecated Handlers have been deprecated.
|
||||
*/
|
||||
@Deprecated
|
||||
void setTabCompleter(@NotNull TabCompleteHandler handler);
|
||||
}
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
package com.willfp.eco.core.command;
|
||||
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A command handler handles the actual code for a command.
|
||||
* <p>
|
||||
* The replacement for {@link org.bukkit.command.CommandExecutor#onCommand(CommandSender, Command, String, String[])}
|
||||
*
|
||||
* @see CommandBase
|
||||
* @deprecated Handlers have been deprecated. This legacy system will eventually be removed,
|
||||
* update to use the new system: {@link CommandBase#onExecute(CommandSender, List)}.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
@Deprecated(since = "6.17.0")
|
||||
public interface CommandHandler {
|
||||
/**
|
||||
* The code to be called on execution.
|
||||
*
|
||||
* @param sender The sender.
|
||||
* @param args The arguments.
|
||||
*/
|
||||
void onExecute(@NotNull CommandSender sender,
|
||||
@NotNull List<String> args);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.willfp.eco.core.command;
|
||||
|
||||
/**
|
||||
* A notification exception is thrown when {@link org.bukkit.command.CommandSender}s don't
|
||||
* specify valid arguments in commands.
|
||||
* <p>
|
||||
* Methods in eco that throw this will contain automatic handling and thus
|
||||
* should not be surrounded by try / catch blocks.
|
||||
*/
|
||||
public class NotificationException extends Exception {
|
||||
/**
|
||||
* The key for the lang.yml message to be sent.
|
||||
*/
|
||||
private final String key;
|
||||
|
||||
/**
|
||||
* Creates a notification exception.
|
||||
*
|
||||
* @param key The lang key of the notification.
|
||||
*/
|
||||
public NotificationException(String key) {
|
||||
super(key);
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the lang key.
|
||||
*
|
||||
* @return The lang key.
|
||||
*/
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.willfp.eco.core.command;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Plugin command bases can be registered directly with the server,
|
||||
* this essentially functions as the interface that is implemented generically
|
||||
* via {@link com.willfp.eco.core.command.impl.PluginCommand}.
|
||||
*/
|
||||
public interface PluginCommandBase extends CommandBase {
|
||||
/**
|
||||
* Register the PluginCommandBase to the bukkit commandMap.
|
||||
*/
|
||||
void register();
|
||||
|
||||
/**
|
||||
* Unregister the PluginCommandBase from the bukkit commandMap.
|
||||
*/
|
||||
void unregister();
|
||||
|
||||
/**
|
||||
* Get aliases. Leave null if this command is from plugin.yml.
|
||||
*
|
||||
* @return The aliases.
|
||||
*/
|
||||
@NotNull
|
||||
default List<String> getAliases() {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get description.
|
||||
*
|
||||
* @return The description.
|
||||
*/
|
||||
@Nullable
|
||||
default String getDescription() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package com.willfp.eco.core.command;
|
||||
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A Tab Complete handler handles the actual tab-completion code.
|
||||
* <p>
|
||||
* The replacement for {@link org.bukkit.command.TabCompleter#onTabComplete(CommandSender, Command, String, String[])}
|
||||
*
|
||||
* @see CommandBase
|
||||
* @deprecated Handlers have been deprecated. This legacy system will eventually be removed,
|
||||
* update to use the new system: {@link CommandBase#tabComplete(CommandSender, List)}
|
||||
*/
|
||||
@FunctionalInterface
|
||||
@Deprecated(since = "6.17.0")
|
||||
public interface TabCompleteHandler {
|
||||
/**
|
||||
* Handle Tab Completion.
|
||||
*
|
||||
* @param sender The sender.
|
||||
* @param args The arguments.
|
||||
* @return The tab completion results.
|
||||
*/
|
||||
List<String> tabComplete(@NotNull CommandSender sender,
|
||||
@NotNull List<String> args);
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.willfp.eco.core.command.impl;
|
||||
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.PluginIdentifiableCommand;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Delegates a bukkit command to an eco command (for registrations).
|
||||
*
|
||||
* @deprecated Internal command implementations have been removed from the API.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "6.49.0")
|
||||
public final class DelegatedBukkitCommand extends Command implements TabCompleter, PluginIdentifiableCommand {
|
||||
/**
|
||||
* The delegate command.
|
||||
*/
|
||||
private final PluginCommand delegate;
|
||||
|
||||
/**
|
||||
* Create a new delegated command.
|
||||
*
|
||||
* @param delegate The delegate.
|
||||
*/
|
||||
public DelegatedBukkitCommand(@NotNull final PluginCommand delegate) {
|
||||
super(delegate.getName());
|
||||
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(@NotNull final CommandSender commandSender,
|
||||
@NotNull final String label,
|
||||
@NotNull final String[] args) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull final CommandSender commandSender,
|
||||
@NotNull final Command command,
|
||||
@NotNull final String label,
|
||||
@NotNull final String[] args) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Plugin getPlugin() {
|
||||
return this.delegate.getPlugin();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getPermission() {
|
||||
return this.delegate.getPermission();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return this.delegate.getDescription() == null ? "" : this.delegate.getDescription();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<String> getAliases() {
|
||||
return this.delegate.getAliases();
|
||||
}
|
||||
}
|
||||
@@ -1,282 +0,0 @@
|
||||
package com.willfp.eco.core.command.impl;
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.command.CommandBase;
|
||||
import com.willfp.eco.core.command.CommandHandler;
|
||||
import com.willfp.eco.core.command.TabCompleteHandler;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.StringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Abstract class for commands that can be handled.
|
||||
* <p>
|
||||
* Handled commands have a method to pass in raw input from bukkit commands
|
||||
* in order to execute the command-specific code. It's essentially an internal
|
||||
* layer, hence why it's a package-private class.
|
||||
*/
|
||||
@SuppressWarnings({"DeprecatedIsStillUsed"})
|
||||
abstract class HandledCommand implements CommandBase {
|
||||
/**
|
||||
* The plugin.
|
||||
*/
|
||||
private final EcoPlugin plugin;
|
||||
|
||||
/**
|
||||
* The name of the command.
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* The permission required to execute the command.
|
||||
* <p>
|
||||
* Written out as a string for flexibility with subclasses.
|
||||
*/
|
||||
private final String permission;
|
||||
|
||||
/**
|
||||
* Should the command only be allowed to be executed by players?
|
||||
* <p>
|
||||
* In other worlds, only allowed to be executed by console.
|
||||
*/
|
||||
private final boolean playersOnly;
|
||||
|
||||
/**
|
||||
* The actual code to be executed in the command.
|
||||
*/
|
||||
@Deprecated
|
||||
@Nullable
|
||||
private CommandHandler handler = null;
|
||||
|
||||
/**
|
||||
* The tab completion code to be executed in the command.
|
||||
*/
|
||||
@Deprecated
|
||||
@Nullable
|
||||
private TabCompleteHandler tabCompleter = null;
|
||||
|
||||
/**
|
||||
* All subcommands for the command.
|
||||
*/
|
||||
private final List<CommandBase> subcommands;
|
||||
|
||||
/**
|
||||
* Create a new command.
|
||||
* <p>
|
||||
* The name cannot be the same as an existing command as this will conflict.
|
||||
*
|
||||
* @param plugin Instance of a plugin.
|
||||
* @param name The name used in execution.
|
||||
* @param permission The permission required to execute the command.
|
||||
* @param playersOnly If only players should be able to execute this command.
|
||||
*/
|
||||
HandledCommand(@NotNull final EcoPlugin plugin,
|
||||
@NotNull final String name,
|
||||
@NotNull final String permission,
|
||||
final boolean playersOnly) {
|
||||
this.plugin = plugin;
|
||||
this.name = name;
|
||||
this.permission = permission;
|
||||
this.playersOnly = playersOnly;
|
||||
this.subcommands = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a subcommand to the command.
|
||||
*
|
||||
* @param subcommand The subcommand.
|
||||
* @return The parent command.
|
||||
*/
|
||||
@Override
|
||||
public final CommandBase addSubcommand(@NotNull final CommandBase subcommand) {
|
||||
subcommands.add(subcommand);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plugin.
|
||||
*
|
||||
* @return The plugin.
|
||||
*/
|
||||
@Override
|
||||
public EcoPlugin getPlugin() {
|
||||
return this.plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the command.
|
||||
*
|
||||
* @param sender The sender.
|
||||
* @param args The arguments.
|
||||
*/
|
||||
protected final void handle(@NotNull final CommandSender sender,
|
||||
@NotNull final String[] args) {
|
||||
if (!canExecute(sender, this, this.getPlugin())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.length > 0) {
|
||||
for (CommandBase subcommand : this.getSubcommands()) {
|
||||
if (subcommand.getName().equalsIgnoreCase(args[0])) {
|
||||
if (!canExecute(sender, subcommand, this.getPlugin())) {
|
||||
return;
|
||||
}
|
||||
|
||||
((HandledCommand) subcommand).handle(sender, Arrays.copyOfRange(args, 1, args.length));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.isPlayersOnly() && !(sender instanceof Player)) {
|
||||
sender.sendMessage(this.getPlugin().getLangYml().getMessage("not-player"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.getHandler() != null) {
|
||||
this.getHandler().onExecute(sender, Arrays.asList(args));
|
||||
} else {
|
||||
this.onExecute(sender, Arrays.asList(args));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the tab completion.
|
||||
*
|
||||
* @param sender The sender.
|
||||
* @param args The arguments.
|
||||
* @return The tab completion results.
|
||||
*/
|
||||
protected final List<String> handleTabCompletion(@NotNull final CommandSender sender,
|
||||
@NotNull final String[] args) {
|
||||
|
||||
if (!sender.hasPermission(this.getPermission())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (args.length == 1) {
|
||||
List<String> completions = new ArrayList<>();
|
||||
|
||||
StringUtil.copyPartialMatches(
|
||||
args[0],
|
||||
this.getSubcommands().stream().map(CommandBase::getName).collect(Collectors.toList()),
|
||||
completions
|
||||
);
|
||||
|
||||
Collections.sort(completions);
|
||||
|
||||
if (!completions.isEmpty()) {
|
||||
return completions;
|
||||
}
|
||||
}
|
||||
|
||||
if (args.length >= 2) {
|
||||
HandledCommand command = null;
|
||||
|
||||
for (CommandBase subcommand : this.getSubcommands()) {
|
||||
if (args[0].equalsIgnoreCase(subcommand.getName())) {
|
||||
command = (HandledCommand) subcommand;
|
||||
}
|
||||
}
|
||||
|
||||
if (command != null) {
|
||||
return command.handleTabCompletion(sender, Arrays.copyOfRange(args, 1, args.length));
|
||||
}
|
||||
}
|
||||
|
||||
if (this.getTabCompleter() != null) {
|
||||
return this.getTabCompleter().tabComplete(sender, Arrays.asList(args));
|
||||
} else {
|
||||
return this.tabComplete(sender, Arrays.asList(args));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If a sender can execute the command.
|
||||
*
|
||||
* @param sender The sender.
|
||||
* @param command The command.
|
||||
* @param plugin The plugin.
|
||||
* @return If the sender can execute.
|
||||
*/
|
||||
public static boolean canExecute(@NotNull final CommandSender sender,
|
||||
@NotNull final CommandBase command,
|
||||
@NotNull final EcoPlugin plugin) {
|
||||
if (!sender.hasPermission(command.getPermission()) && sender instanceof Player) {
|
||||
sender.sendMessage(plugin.getLangYml().getNoPermission());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the command name.
|
||||
*
|
||||
* @return The name.
|
||||
*/
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the permission required to execute the command.
|
||||
*
|
||||
* @return The permission.
|
||||
*/
|
||||
public String getPermission() {
|
||||
return this.permission;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if the command can only be executed by players.
|
||||
*
|
||||
* @return If players only.
|
||||
*/
|
||||
public boolean isPlayersOnly() {
|
||||
return this.playersOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the subcommands of the command.
|
||||
*
|
||||
* @return The subcommands.
|
||||
*/
|
||||
public List<CommandBase> getSubcommands() {
|
||||
return this.subcommands;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public @Nullable CommandHandler getHandler() {
|
||||
return this.handler;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public @Nullable TabCompleteHandler getTabCompleter() {
|
||||
return this.tabCompleter;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public void setHandler(@Nullable final CommandHandler handler) {
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public void setTabCompleter(@Nullable final TabCompleteHandler tabCompleter) {
|
||||
this.tabCompleter = tabCompleter;
|
||||
}
|
||||
}
|
||||
@@ -1,26 +1,28 @@
|
||||
package com.willfp.eco.core.command.impl;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
import com.willfp.eco.core.command.CommandBase;
|
||||
import com.willfp.eco.core.command.PluginCommandBase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* PluginCommands are the class to be used instead of CommandExecutor,
|
||||
* they function as the base command, e.g. {@code /ecoenchants} would be a base command, with each
|
||||
* subsequent argument functioning as subcommands.
|
||||
* PluginCommands are the class to be used instead of CommandExecutor, they function as the base
|
||||
* command, e.g. {@code /ecoenchants} would be a base command, with each subsequent argument
|
||||
* functioning as subcommands.
|
||||
* <p>
|
||||
* The command will not be registered until register() is called.
|
||||
* <p>
|
||||
* The name cannot be the same as an existing command as this will conflict.
|
||||
*/
|
||||
public abstract class PluginCommand extends HandledCommand implements CommandExecutor, TabCompleter {
|
||||
public abstract class PluginCommand implements PluginCommandBase {
|
||||
/**
|
||||
* The delegate command.
|
||||
*/
|
||||
private final PluginCommandBase delegate;
|
||||
|
||||
/**
|
||||
* Create a new command.
|
||||
*
|
||||
@@ -33,64 +35,51 @@ public abstract class PluginCommand extends HandledCommand implements CommandExe
|
||||
@NotNull final String name,
|
||||
@NotNull final String permission,
|
||||
final boolean playersOnly) {
|
||||
super(plugin, name, permission, playersOnly);
|
||||
this.delegate = Eco.get().createPluginCommand(this, plugin, name, permission, playersOnly);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the command with the server,
|
||||
* <p>
|
||||
* Requires the command name to exist, defined in plugin.yml.
|
||||
*/
|
||||
public final void register() {
|
||||
org.bukkit.command.PluginCommand command = Bukkit.getPluginCommand(this.getName());
|
||||
assert command != null;
|
||||
command.setExecutor(this);
|
||||
command.setTabCompleter(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal implementation used to clean up boilerplate.
|
||||
* Used for parity with {@link CommandExecutor#onCommand(CommandSender, Command, String, String[])}.
|
||||
*
|
||||
* @param sender The executor of the command.
|
||||
* @param command The bukkit command.
|
||||
* @param label The name of the executed command.
|
||||
* @param args The arguments of the command (anything after the physical command name)
|
||||
* @return If the command was processed by the linked {@link EcoPlugin}
|
||||
*/
|
||||
@Override
|
||||
public final boolean onCommand(@NotNull final CommandSender sender,
|
||||
@NotNull final Command command,
|
||||
@NotNull final String label,
|
||||
@NotNull final String[] args) {
|
||||
if (!command.getName().equalsIgnoreCase(this.getName())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.handle(sender, args);
|
||||
|
||||
return true;
|
||||
public @NotNull String getName() {
|
||||
return delegate.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal implementation used to clean up boilerplate.
|
||||
* Used for parity with {@link TabCompleter#onTabComplete(CommandSender, Command, String, String[])}.
|
||||
*
|
||||
* @param sender The executor of the command.
|
||||
* @param command The bukkit command.
|
||||
* @param label The name of the executed command.
|
||||
* @param args The arguments of the command (anything after the physical command name).
|
||||
* @return The list of tab-completions.
|
||||
*/
|
||||
@Override
|
||||
public @Nullable List<String> onTabComplete(@NotNull final CommandSender sender,
|
||||
@NotNull final Command command,
|
||||
@NotNull final String label,
|
||||
@NotNull final String[] args) {
|
||||
if (!command.getName().equalsIgnoreCase(this.getName())) {
|
||||
return null;
|
||||
}
|
||||
public @NotNull String getPermission() {
|
||||
return delegate.getPermission();
|
||||
}
|
||||
|
||||
return this.handleTabCompletion(sender, args);
|
||||
@Override
|
||||
public boolean isPlayersOnly() {
|
||||
return delegate.isPlayersOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull CommandBase addSubcommand(@NotNull CommandBase command) {
|
||||
return delegate.addSubcommand(command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<CommandBase> getSubcommands() {
|
||||
return delegate.getSubcommands();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull CommandBase getWrapped() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register() {
|
||||
delegate.register();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregister() {
|
||||
delegate.unregister();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EcoPlugin getPlugin() {
|
||||
return delegate.getPlugin();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,21 @@
|
||||
package com.willfp.eco.core.command.impl;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.command.CommandBase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Subcommands can be added to PluginCommands or to other Subcommands.
|
||||
* A command implementation that must exist as a subcommand (i.e. cannot be registered directly).
|
||||
*/
|
||||
public abstract class Subcommand extends HandledCommand {
|
||||
public abstract class Subcommand implements CommandBase {
|
||||
/**
|
||||
* The delegate command.
|
||||
*/
|
||||
private final CommandBase delegate;
|
||||
|
||||
/**
|
||||
* Create subcommand.
|
||||
*
|
||||
@@ -20,7 +28,7 @@ public abstract class Subcommand extends HandledCommand {
|
||||
@NotNull final String name,
|
||||
@NotNull final String permission,
|
||||
final boolean playersOnly) {
|
||||
super(plugin, name, permission, playersOnly);
|
||||
this.delegate = Eco.get().createSubcommand(this, plugin, name, permission, playersOnly);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -33,6 +41,41 @@ public abstract class Subcommand extends HandledCommand {
|
||||
protected Subcommand(@NotNull final EcoPlugin plugin,
|
||||
@NotNull final String name,
|
||||
@NotNull final CommandBase parent) {
|
||||
super(plugin, name, parent.getPermission(), parent.isPlayersOnly());
|
||||
this(plugin, name, parent.getPermission(), parent.isPlayersOnly());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getName() {
|
||||
return delegate.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getPermission() {
|
||||
return delegate.getPermission();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPlayersOnly() {
|
||||
return delegate.isPlayersOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull CommandBase addSubcommand(@NotNull CommandBase command) {
|
||||
return delegate.addSubcommand(command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<CommandBase> getSubcommands() {
|
||||
return delegate.getSubcommands();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull CommandBase getWrapped() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EcoPlugin getPlugin() {
|
||||
return delegate.getPlugin();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,13 +23,31 @@ public abstract class BaseConfig extends LoadableConfigWrapper {
|
||||
@NotNull final PluginLike plugin,
|
||||
final boolean removeUnused,
|
||||
@NotNull final ConfigType type) {
|
||||
super(Eco.getHandler().getConfigFactory().createUpdatableConfig(
|
||||
this(configName, plugin, removeUnused, type, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new Base Config.
|
||||
*
|
||||
* @param plugin The plugin or extension.
|
||||
* @param configName The config name (excluding extension).
|
||||
* @param removeUnused If unused sections should be removed.
|
||||
* @param type The config type.
|
||||
* @param requiresChangeToSave If changes must be applied to save the config.
|
||||
*/
|
||||
protected BaseConfig(@NotNull final String configName,
|
||||
@NotNull final PluginLike plugin,
|
||||
final boolean removeUnused,
|
||||
@NotNull final ConfigType type,
|
||||
final boolean requiresChangeToSave) {
|
||||
super(Eco.get().createUpdatableConfig(
|
||||
configName,
|
||||
plugin,
|
||||
"",
|
||||
plugin.getClass(),
|
||||
removeUnused,
|
||||
type
|
||||
type,
|
||||
requiresChangeToSave
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.willfp.eco.core.config;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Builder for configs to create them programmatically.
|
||||
*/
|
||||
public class BuildableConfig extends GenericConfig {
|
||||
/**
|
||||
* Create a new empty config builder.
|
||||
*/
|
||||
public BuildableConfig() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add to the config builder.
|
||||
*
|
||||
* @param path The path.
|
||||
* @param object The object.
|
||||
* @return The builder.
|
||||
*/
|
||||
public BuildableConfig add(@NotNull final String path,
|
||||
@Nullable final Object object) {
|
||||
set(path, object);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.willfp.eco.core.config;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Config types, classified by file extension.
|
||||
*/
|
||||
@@ -7,10 +9,33 @@ public enum ConfigType {
|
||||
/**
|
||||
* .json config.
|
||||
*/
|
||||
JSON,
|
||||
JSON("json"),
|
||||
|
||||
/**
|
||||
* .yml config.
|
||||
*/
|
||||
YAML
|
||||
YAML("yml"),
|
||||
|
||||
/**
|
||||
* .toml config.
|
||||
*/
|
||||
TOML("toml");
|
||||
|
||||
/**
|
||||
* The file extension.
|
||||
*/
|
||||
private final String extension;
|
||||
|
||||
ConfigType(@NotNull final String extension) {
|
||||
this.extension = extension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file extension.
|
||||
*
|
||||
* @return The extension.
|
||||
*/
|
||||
public String getExtension() {
|
||||
return extension;
|
||||
}
|
||||
}
|
||||
|
||||
157
eco-api/src/main/java/com/willfp/eco/core/config/Configs.java
Normal file
157
eco-api/src/main/java/com/willfp/eco/core/config/Configs.java
Normal file
@@ -0,0 +1,157 @@
|
||||
package com.willfp.eco.core.config;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.config.interfaces.Config;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.file.Files;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Utilities / API methods for configs.
|
||||
*/
|
||||
public final class Configs {
|
||||
/**
|
||||
* Load a Config from a bukkit {@link ConfigurationSection}.
|
||||
*
|
||||
* @param config The ConfigurationSection.
|
||||
* @return The config.
|
||||
*/
|
||||
@NotNull
|
||||
public static Config fromBukkit(@Nullable final ConfigurationSection config) {
|
||||
return config == null ? empty() : Eco.get().wrapConfigurationSection(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a config from an {@link InputStream}.
|
||||
* <p>
|
||||
* Only for yaml configs.
|
||||
*
|
||||
* @param stream The InputStream.
|
||||
* @return The config.
|
||||
*/
|
||||
@NotNull
|
||||
public static Config fromStream(@Nullable final InputStream stream) {
|
||||
return stream != null ? fromBukkit(YamlConfiguration.loadConfiguration(
|
||||
new InputStreamReader(stream)
|
||||
)) : empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a config from a file.
|
||||
*
|
||||
* @param file The file.
|
||||
* @return The config.
|
||||
*/
|
||||
@NotNull
|
||||
public static Config fromFile(@Nullable final File file) {
|
||||
if (file == null) {
|
||||
return empty();
|
||||
}
|
||||
|
||||
int lastIndex = file.getName().lastIndexOf(".");
|
||||
|
||||
if (lastIndex < 0) {
|
||||
return empty();
|
||||
}
|
||||
|
||||
for (ConfigType type : ConfigType.values()) {
|
||||
if (file.getName().substring(lastIndex + 1).equalsIgnoreCase(type.getExtension())) {
|
||||
return fromFile(file, type);
|
||||
}
|
||||
}
|
||||
|
||||
return empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a config from a file.
|
||||
*
|
||||
* @param file The file.
|
||||
* @param type The type.
|
||||
* @return The config.
|
||||
*/
|
||||
@NotNull
|
||||
public static Config fromFile(@Nullable final File file,
|
||||
@NotNull final ConfigType type) {
|
||||
if (file == null) {
|
||||
return empty();
|
||||
}
|
||||
|
||||
try {
|
||||
return Eco.get().createConfig(Files.readString(file.toPath()), type);
|
||||
} catch (IOException e) {
|
||||
return empty();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load config from map (uses {@link ConfigType#JSON}).
|
||||
*
|
||||
* @param values The values.
|
||||
* @return The config.
|
||||
*/
|
||||
@NotNull
|
||||
public static Config fromMap(@NotNull final Map<String, Object> values) {
|
||||
return fromMap(values, ConfigType.JSON);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load config from map.
|
||||
*
|
||||
* @param values The values.
|
||||
* @param type The type.
|
||||
* @return The config.
|
||||
*/
|
||||
@NotNull
|
||||
public static Config fromMap(@NotNull final Map<String, Object> values,
|
||||
@NotNull final ConfigType type) {
|
||||
return Eco.get().createConfig(values, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create empty config (uses {@link ConfigType#JSON}).
|
||||
*
|
||||
* @return An empty config.
|
||||
*/
|
||||
@NotNull
|
||||
public static Config empty() {
|
||||
return fromMap(new HashMap<>(), ConfigType.JSON);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create empty config.
|
||||
*
|
||||
* @param type The type.
|
||||
* @return An empty config.
|
||||
*/
|
||||
@NotNull
|
||||
public static Config empty(@NotNull final ConfigType type) {
|
||||
return fromMap(new HashMap<>(), type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load config from string.
|
||||
*
|
||||
* @param contents The contents of the config.
|
||||
* @param type The config type.
|
||||
* @return The config.
|
||||
*/
|
||||
@NotNull
|
||||
public static Config fromString(@NotNull final String contents,
|
||||
@NotNull final ConfigType type) {
|
||||
return Eco.get().createConfig(contents, type);
|
||||
}
|
||||
|
||||
private Configs() {
|
||||
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||
}
|
||||
}
|
||||
@@ -31,13 +31,14 @@ public abstract class ExtendableConfig extends LoadableConfigWrapper {
|
||||
@NotNull final String subDirectoryPath,
|
||||
@NotNull final ConfigType type,
|
||||
@NotNull final String... updateBlacklist) {
|
||||
super(Eco.getHandler().getConfigFactory().createUpdatableConfig(
|
||||
super(Eco.get().createUpdatableConfig(
|
||||
configName,
|
||||
plugin,
|
||||
subDirectoryPath,
|
||||
source,
|
||||
removeUnused,
|
||||
type,
|
||||
true,
|
||||
updateBlacklist
|
||||
));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.willfp.eco.core.config;
|
||||
|
||||
import com.willfp.eco.core.config.interfaces.Config;
|
||||
import com.willfp.eco.core.config.wrapper.ConfigWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Generic config to simplify creating custom configs without having
|
||||
* to meddle with delegation.
|
||||
*/
|
||||
public abstract class GenericConfig extends ConfigWrapper<Config> {
|
||||
/**
|
||||
* Create a new generic config.
|
||||
*/
|
||||
protected GenericConfig() {
|
||||
super(Configs.empty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new generic config.
|
||||
*
|
||||
* @param type The config type.
|
||||
*/
|
||||
protected GenericConfig(@NotNull final ConfigType type) {
|
||||
super(Configs.empty(type));
|
||||
}
|
||||
}
|
||||
@@ -21,12 +21,13 @@ public abstract class StaticBaseConfig extends LoadableConfigWrapper {
|
||||
protected StaticBaseConfig(@NotNull final String configName,
|
||||
@NotNull final PluginLike plugin,
|
||||
@NotNull final ConfigType type) {
|
||||
super(Eco.getHandler().getConfigFactory().createLoadableConfig(
|
||||
super(Eco.get().createLoadableConfig(
|
||||
configName,
|
||||
plugin,
|
||||
"",
|
||||
plugin.getClass(),
|
||||
type
|
||||
type,
|
||||
true
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,50 +3,97 @@ 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.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.file.Files;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Config that exists purely in the code, not linked to any file.
|
||||
* <p>
|
||||
* Use for inline configs to move data around or to add subsections to other configs.
|
||||
*
|
||||
* @deprecated Poorly named class, makes the config system seem needlessly complicated.
|
||||
*/
|
||||
@Deprecated(since = "6.44.0", forRemoval = true)
|
||||
public class TransientConfig extends ConfigWrapper<Config> {
|
||||
/**
|
||||
* @param config The ConfigurationSection handle.
|
||||
*/
|
||||
public TransientConfig(@NotNull final ConfigurationSection config) {
|
||||
super(Eco.get().wrapConfigurationSection(config));
|
||||
}
|
||||
|
||||
/**
|
||||
* Exists for backwards compatibility, YamlConfigurations are ConfigurationSections.
|
||||
*
|
||||
* @param config The YamlConfiguration handle.
|
||||
*/
|
||||
public TransientConfig(@NotNull final YamlConfiguration config) {
|
||||
super(Eco.getHandler().getConfigFactory().createConfig(config));
|
||||
this((ConfigurationSection) config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param stream The InputStream.
|
||||
*/
|
||||
public TransientConfig(@Nullable final InputStream stream) {
|
||||
super(stream != null ? Eco.getHandler().getConfigFactory().createConfig(YamlConfiguration.loadConfiguration(
|
||||
super(stream != null ? Eco.get().wrapConfigurationSection(YamlConfiguration.loadConfiguration(
|
||||
new InputStreamReader(stream)
|
||||
)) : new TransientConfig());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param file The File.
|
||||
* @deprecated Specify the config type to prevent bugs.
|
||||
*/
|
||||
@Deprecated(since = "6.30.0", forRemoval = true)
|
||||
public TransientConfig(@Nullable final File file) {
|
||||
this(file, ConfigType.YAML);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param file The file.
|
||||
* @param type The config type to try read from.
|
||||
*/
|
||||
public TransientConfig(@Nullable final File file,
|
||||
@NotNull final ConfigType type) {
|
||||
super(file != null ? Eco.get().createConfig(readFile(file), type)
|
||||
: new TransientConfig());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new empty transient config.
|
||||
*
|
||||
* @param values The values.
|
||||
*/
|
||||
public TransientConfig(@NotNull final Map<String, Object> values) {
|
||||
super(Eco.getHandler().getConfigFactory().createConfig(values));
|
||||
super(Eco.get().createConfig(values, ConfigType.YAML));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new empty transient config.
|
||||
*
|
||||
* @param values The values.
|
||||
* @param type The type.
|
||||
*/
|
||||
public TransientConfig(@NotNull final Map<String, Object> values,
|
||||
@NotNull final ConfigType type) {
|
||||
super(Eco.get().createConfig(values, type));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new empty transient config.
|
||||
*/
|
||||
public TransientConfig() {
|
||||
super(Eco.getHandler().getConfigFactory().createConfig("", ConfigType.YAML));
|
||||
this(new HashMap<>(), ConfigType.JSON);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,6 +102,24 @@ public class TransientConfig extends ConfigWrapper<Config> {
|
||||
*/
|
||||
public TransientConfig(@NotNull final String contents,
|
||||
@NotNull final ConfigType type) {
|
||||
super(Eco.getHandler().getConfigFactory().createConfig(contents, type));
|
||||
super(Eco.get().createConfig(contents, type));
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a file to a string.
|
||||
*
|
||||
* @param file The file.
|
||||
* @return The string.
|
||||
*/
|
||||
private static String readFile(@Nullable final File file) {
|
||||
if (file == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
try {
|
||||
return Files.readString(file.toPath());
|
||||
} catch (IOException e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,32 @@ import com.willfp.eco.core.config.ConfigType;
|
||||
import com.willfp.eco.util.StringUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Default plugin lang.yml.
|
||||
*/
|
||||
public class LangYml extends BaseConfig {
|
||||
/**
|
||||
* The messages key.
|
||||
*/
|
||||
public static final String KEY_MESSAGES = "messages";
|
||||
|
||||
/**
|
||||
* The prefix key.
|
||||
*/
|
||||
public static final String KEY_PREFIX = "messages.prefix";
|
||||
|
||||
/**
|
||||
* The no permission key.
|
||||
*/
|
||||
public static final String KEY_NO_PERMISSION = "messages.no-permission";
|
||||
|
||||
/**
|
||||
* The not player key.
|
||||
*/
|
||||
public static final String KEY_NOT_PLAYER = "messages.not-player";
|
||||
|
||||
/**
|
||||
* Lang.yml.
|
||||
*
|
||||
@@ -19,13 +41,31 @@ public class LangYml extends BaseConfig {
|
||||
super("lang", plugin, false, ConfigType.YAML);
|
||||
}
|
||||
|
||||
/**
|
||||
* lang.yml requires certain keys to be present.
|
||||
* <p>
|
||||
* If the lang.yml does not contain these keys, it is considered to be
|
||||
* invalid and thus will show a warning in console.
|
||||
*
|
||||
* @return If valid.
|
||||
*/
|
||||
public boolean isValid() {
|
||||
for (String key : List.of(KEY_MESSAGES, KEY_PREFIX, KEY_NO_PERMISSION, KEY_NOT_PLAYER)) {
|
||||
if (!this.has(key)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the prefix for messages in chat.
|
||||
*
|
||||
* @return The prefix.
|
||||
*/
|
||||
public String getPrefix() {
|
||||
return this.getFormattedString("messages.prefix");
|
||||
return this.getFormattedString(KEY_PREFIX);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -34,7 +74,7 @@ public class LangYml extends BaseConfig {
|
||||
* @return The message.
|
||||
*/
|
||||
public String getNoPermission() {
|
||||
return getPrefix() + this.getFormattedString("messages.no-permission");
|
||||
return getPrefix() + this.getFormattedString(KEY_NO_PERMISSION);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,6 +96,6 @@ public class LangYml extends BaseConfig {
|
||||
*/
|
||||
public String getMessage(@NotNull final String message,
|
||||
@NotNull final StringUtils.FormatOption option) {
|
||||
return getPrefix() + this.getFormattedString("messages." + message, option);
|
||||
return getPrefix() + this.getFormattedString(KEY_MESSAGES + "." + message, option);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,27 @@
|
||||
package com.willfp.eco.core.config.interfaces;
|
||||
|
||||
import com.willfp.eco.core.config.BuildableConfig;
|
||||
import com.willfp.eco.core.config.ConfigType;
|
||||
import com.willfp.eco.core.config.TransientConfig;
|
||||
import com.willfp.eco.core.config.Configs;
|
||||
import com.willfp.eco.core.placeholder.AdditionalPlayer;
|
||||
import com.willfp.eco.core.placeholder.InjectablePlaceholder;
|
||||
import com.willfp.eco.core.placeholder.PlaceholderInjectable;
|
||||
import com.willfp.eco.core.placeholder.StaticPlaceholder;
|
||||
import com.willfp.eco.util.NumberUtils;
|
||||
import com.willfp.eco.util.StringUtils;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* All configs implement this interface.
|
||||
@@ -24,8 +32,13 @@ import java.util.Objects;
|
||||
public interface Config extends Cloneable, PlaceholderInjectable {
|
||||
/**
|
||||
* Clears cache.
|
||||
* <p>
|
||||
* Configs no longer have caches as they have in previous versions.
|
||||
*/
|
||||
void clearCache();
|
||||
@Deprecated(since = "6.31.1", forRemoval = true)
|
||||
default void clearCache() {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the config into readable text.
|
||||
@@ -51,9 +64,21 @@ public interface Config extends Cloneable, PlaceholderInjectable {
|
||||
@NotNull
|
||||
List<String> getKeys(boolean deep);
|
||||
|
||||
/**
|
||||
* Recurse config keys.
|
||||
*
|
||||
* @param found The found keys.
|
||||
* @param root The root.
|
||||
* @return The keys.
|
||||
*/
|
||||
@NotNull
|
||||
default List<String> recurseKeys(@NotNull Set<String> found,
|
||||
@NotNull String root) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an object from config.
|
||||
* Default implementations call {@link org.bukkit.configuration.file.YamlConfiguration#get(String)}.
|
||||
*
|
||||
* @param path The path.
|
||||
* @return The object.
|
||||
@@ -63,7 +88,6 @@ public interface Config extends Cloneable, PlaceholderInjectable {
|
||||
|
||||
/**
|
||||
* Set an object in config.
|
||||
* Default implementations call {@link org.bukkit.configuration.file.YamlConfiguration#set(String, Object)}
|
||||
*
|
||||
* @param path The path.
|
||||
* @param object The object.
|
||||
@@ -79,7 +103,7 @@ public interface Config extends Cloneable, PlaceholderInjectable {
|
||||
*/
|
||||
@NotNull
|
||||
default Config getSubsection(@NotNull String path) {
|
||||
return Objects.requireNonNullElse(getSubsectionOrNull(path), new TransientConfig());
|
||||
return Objects.requireNonNullElse(getSubsectionOrNull(path), Configs.empty());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -135,6 +159,20 @@ public interface Config extends Cloneable, PlaceholderInjectable {
|
||||
return Double.valueOf(getDoubleFromExpression(path, player)).intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a decimal value via a mathematical expression.
|
||||
*
|
||||
* @param path The key to fetch the value from.
|
||||
* @param player The player to evaluate placeholders with respect to.
|
||||
* @param additionalPlayers The additional players to evaluate placeholders with respect to.
|
||||
* @return The computed value, or 0 if not found or invalid.
|
||||
*/
|
||||
default int getIntFromExpression(@NotNull String path,
|
||||
@Nullable Player player,
|
||||
@NotNull Collection<AdditionalPlayer> additionalPlayers) {
|
||||
return Double.valueOf(getDoubleFromExpression(path, player, additionalPlayers)).intValue();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get an integer from config.
|
||||
@@ -241,35 +279,6 @@ public interface Config extends Cloneable, PlaceholderInjectable {
|
||||
return getString(path, false, StringUtils.FormatOption.WITHOUT_PLACEHOLDERS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a string from config.
|
||||
*
|
||||
* @param path The key to fetch the value from.
|
||||
* @param format If the string should be formatted.
|
||||
* @return The found value, or an empty string if not found.
|
||||
* @deprecated Since 6.18.0, {@link Config#getString(String)} is not formatted by default.
|
||||
*/
|
||||
@Deprecated(since = "6.18.0")
|
||||
default String getString(@NotNull String path,
|
||||
boolean format) {
|
||||
return this.getString(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a string from config.
|
||||
*
|
||||
* @param path The key to fetch the value from.
|
||||
* @param option The format option.
|
||||
* @return The found value, or an empty string if not found.
|
||||
* @deprecated Use {@link Config#getFormattedString(String, StringUtils.FormatOption)} instead.
|
||||
*/
|
||||
@NotNull
|
||||
@Deprecated
|
||||
default String getString(@NotNull String path,
|
||||
@NotNull final StringUtils.FormatOption option) {
|
||||
return this.getString(path, true, option);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a string from config.
|
||||
*
|
||||
@@ -322,36 +331,6 @@ public interface Config extends Cloneable, PlaceholderInjectable {
|
||||
return getStringOrNull(path, false, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a string from config.
|
||||
*
|
||||
* @param path The key to fetch the value from.
|
||||
* @param format If the string should be formatted.
|
||||
* @return The found value, or null if not found.
|
||||
* @deprecated Since 6.18.0, {@link Config#getString(String)} is not formatted by default.
|
||||
*/
|
||||
@Nullable
|
||||
@Deprecated(since = "6.18.0")
|
||||
default String getStringOrNull(@NotNull String path,
|
||||
boolean format) {
|
||||
return this.getStringOrNull(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a string from config.
|
||||
*
|
||||
* @param path The key to fetch the value from.
|
||||
* @param option The format option.
|
||||
* @return The found value, or null if not found.
|
||||
* @deprecated Use {@link Config#getFormattedString(String, StringUtils.FormatOption)} instead.
|
||||
*/
|
||||
@Nullable
|
||||
@Deprecated
|
||||
default String getStringOrNull(@NotNull String path,
|
||||
@NotNull StringUtils.FormatOption option) {
|
||||
return this.getStringOrNull(path, true, option);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a string from config.
|
||||
*
|
||||
@@ -406,36 +385,6 @@ public interface Config extends Cloneable, PlaceholderInjectable {
|
||||
return getStrings(path, false, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of strings from config.
|
||||
*
|
||||
* @param path The key to fetch the value from.
|
||||
* @param format If the strings should be formatted.
|
||||
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||
* @deprecated Since 6.18.0, {@link Config#getString(String)} is not formatted by default.
|
||||
*/
|
||||
@NotNull
|
||||
@Deprecated(since = "6.18.0")
|
||||
default List<String> getStrings(@NotNull String path,
|
||||
boolean format) {
|
||||
return this.getStrings(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of strings from config.
|
||||
*
|
||||
* @param path The key to fetch the value from.
|
||||
* @param option The format option.
|
||||
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||
* @deprecated Use {@link Config#getFormattedStrings(String, StringUtils.FormatOption)} instead.
|
||||
*/
|
||||
@NotNull
|
||||
@Deprecated
|
||||
default List<String> getStrings(@NotNull String path,
|
||||
@NotNull StringUtils.FormatOption option) {
|
||||
return getStrings(path, false, option);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of strings from config.
|
||||
*
|
||||
@@ -494,36 +443,6 @@ public interface Config extends Cloneable, PlaceholderInjectable {
|
||||
return getStringsOrNull(path, false, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of strings from config.
|
||||
*
|
||||
* @param path The key to fetch the value from.
|
||||
* @param format If the strings should be formatted.
|
||||
* @return The found value, or null if not found.
|
||||
* @deprecated Since 6.18.0, {@link Config#getString(String)} is not formatted by default.
|
||||
*/
|
||||
@Nullable
|
||||
@Deprecated(since = "6.18.0")
|
||||
default List<String> getStringsOrNull(@NotNull String path,
|
||||
boolean format) {
|
||||
return getStringsOrNull(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of strings from config.
|
||||
*
|
||||
* @param path The key to fetch the value from.
|
||||
* @param option The format option.
|
||||
* @return The found value, or null if not found.
|
||||
* @deprecated Use {@link Config#getFormattedStringsOrNull(String, StringUtils.FormatOption)} instead.
|
||||
*/
|
||||
@Nullable
|
||||
@Deprecated
|
||||
default List<String> getStringsOrNull(@NotNull String path,
|
||||
@NotNull StringUtils.FormatOption option) {
|
||||
return getStringsOrNull(path, false, option);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of strings from config.
|
||||
*
|
||||
@@ -566,7 +485,21 @@ public interface Config extends Cloneable, PlaceholderInjectable {
|
||||
*/
|
||||
default double getDoubleFromExpression(@NotNull String path,
|
||||
@Nullable Player player) {
|
||||
return NumberUtils.evaluateExpression(this.getString(path), player, this.getInjectedPlaceholders());
|
||||
return NumberUtils.evaluateExpression(this.getString(path), player, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a decimal value via a mathematical expression.
|
||||
*
|
||||
* @param path The key to fetch the value from.
|
||||
* @param player The player to evaluate placeholders with respect to.
|
||||
* @param additionalPlayers The additional players to evaluate placeholders with respect to.
|
||||
* @return The computed value, or 0 if not found or invalid.
|
||||
*/
|
||||
default double getDoubleFromExpression(@NotNull String path,
|
||||
@Nullable Player player,
|
||||
@NotNull Collection<AdditionalPlayer> additionalPlayers) {
|
||||
return NumberUtils.evaluateExpression(this.getString(path), player, this, additionalPlayers);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -634,12 +567,12 @@ public interface Config extends Cloneable, PlaceholderInjectable {
|
||||
Config clone();
|
||||
|
||||
@Override
|
||||
default void injectPlaceholders(@NotNull Iterable<StaticPlaceholder> placeholders) {
|
||||
default void addInjectablePlaceholder(@NotNull Iterable<InjectablePlaceholder> placeholders) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
default List<StaticPlaceholder> getInjectedPlaceholders() {
|
||||
default @NotNull List<InjectablePlaceholder> getPlaceholderInjections() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@@ -647,4 +580,33 @@ public interface Config extends Cloneable, PlaceholderInjectable {
|
||||
default void clearInjectedPlaceholders() {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the config to a map of values.
|
||||
*
|
||||
* @return The values.
|
||||
*/
|
||||
default Map<String, Object> toMap() {
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the config to a map of values.
|
||||
*
|
||||
* @return The values.
|
||||
*/
|
||||
default ConfigurationSection toBukkit() {
|
||||
YamlConfiguration empty = new YamlConfiguration();
|
||||
empty.createSection("temp", this.toMap());
|
||||
return empty.getConfigurationSection("temp");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new config builder.
|
||||
*
|
||||
* @return The builder.
|
||||
*/
|
||||
static BuildableConfig builder() {
|
||||
return new BuildableConfig();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
package com.willfp.eco.core.config.interfaces;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* JSON config.
|
||||
*
|
||||
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
|
||||
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
|
||||
* These configs will be removed eventually.
|
||||
*/
|
||||
@Deprecated(since = "6.17.0")
|
||||
@SuppressWarnings("DeprecatedIsStillUsed")
|
||||
public interface JSONConfig extends Config {
|
||||
/**
|
||||
* Get a list of subsections from config.
|
||||
*
|
||||
* @param path The key to fetch the value from.
|
||||
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||
*/
|
||||
@NotNull
|
||||
default List<JSONConfig> getSubsections(@NotNull String path) {
|
||||
return Objects.requireNonNullElse(getSubsectionsOrNull(path), new ArrayList<>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of subsections from config.
|
||||
*
|
||||
* @param path The key to fetch the value from.
|
||||
* @return The found value, or null if not found.
|
||||
*/
|
||||
@Nullable
|
||||
List<JSONConfig> getSubsectionsOrNull(@NotNull String path);
|
||||
|
||||
|
||||
/**
|
||||
* Get subsection from config.
|
||||
*
|
||||
* @param path The key to check.
|
||||
* @return The subsection. Throws NPE if not found.
|
||||
*/
|
||||
@Override
|
||||
@NotNull
|
||||
JSONConfig getSubsection(@NotNull String path);
|
||||
|
||||
/**
|
||||
* Get subsection from config.
|
||||
*
|
||||
* @param path The key to check.
|
||||
* @return The subsection, or null if not found.
|
||||
*/
|
||||
@Override
|
||||
@Nullable
|
||||
JSONConfig getSubsectionOrNull(@NotNull String path);
|
||||
|
||||
@Override
|
||||
JSONConfig clone();
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.willfp.eco.core.config.interfaces;
|
||||
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
@@ -47,14 +47,21 @@ public interface LoadableConfig extends Config {
|
||||
/**
|
||||
* 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()}.
|
||||
* This used to represent the underlying config, but since 6.30.0 configs use
|
||||
* their own implementations internally, without relying on bukkit.
|
||||
*
|
||||
* @return The config, or null if config is not yaml-based.
|
||||
* @deprecated Use toBukkit() instead.
|
||||
*/
|
||||
@Nullable
|
||||
YamlConfiguration getBukkitHandle();
|
||||
@Deprecated(since = "6.30.0", forRemoval = true)
|
||||
default YamlConfiguration getBukkitHandle() {
|
||||
return this.toBukkit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the config to a bukkit {@link YamlConfiguration}.
|
||||
*/
|
||||
@NotNull
|
||||
YamlConfiguration toBukkit();
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
package com.willfp.eco.core.config.interfaces;
|
||||
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
/**
|
||||
* Interface for configs that wrap an {@link YamlConfiguration}.
|
||||
*
|
||||
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
|
||||
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
|
||||
* These configs will be removed eventually.
|
||||
*/
|
||||
@Deprecated(since = "6.17.0")
|
||||
@SuppressWarnings("DeprecatedIsStillUsed")
|
||||
public interface WrappedYamlConfiguration {
|
||||
/**
|
||||
* Get the ConfigurationSection handle.
|
||||
*
|
||||
* @return The handle.
|
||||
*/
|
||||
YamlConfiguration getBukkitHandle();
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
package com.willfp.eco.core.config.json;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.PluginLike;
|
||||
import com.willfp.eco.core.config.ConfigType;
|
||||
import com.willfp.eco.core.config.interfaces.JSONConfig;
|
||||
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Config implementation for configs present in the plugin's base directory (eg config.json).
|
||||
* <p>
|
||||
* Automatically updates.
|
||||
*
|
||||
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
|
||||
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
|
||||
* These configs will be removed eventually.
|
||||
*/
|
||||
@Deprecated(since = "6.17.0")
|
||||
public abstract class JSONBaseConfig extends LoadableJSONConfigWrapper {
|
||||
/**
|
||||
* @param configName The name of the config
|
||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||
* @param plugin The plugin.
|
||||
* @param updateBlacklist Substring of keys to not add/remove keys for.
|
||||
*/
|
||||
protected JSONBaseConfig(@NotNull final String configName,
|
||||
final boolean removeUnused,
|
||||
@NotNull final PluginLike plugin,
|
||||
@NotNull final String... updateBlacklist) {
|
||||
super(
|
||||
(JSONConfig)
|
||||
Eco.getHandler().getConfigFactory().createUpdatableConfig(
|
||||
configName,
|
||||
plugin,
|
||||
"",
|
||||
plugin.getClass(),
|
||||
removeUnused,
|
||||
ConfigType.JSON,
|
||||
updateBlacklist
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param configName The name of the config
|
||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||
* @param plugin The plugin.
|
||||
*/
|
||||
protected JSONBaseConfig(@NotNull final String configName,
|
||||
final boolean removeUnused,
|
||||
@NotNull final PluginLike plugin) {
|
||||
super(
|
||||
(JSONConfig)
|
||||
Eco.getHandler().getConfigFactory().createUpdatableConfig(
|
||||
configName,
|
||||
plugin,
|
||||
"",
|
||||
plugin.getClass(),
|
||||
removeUnused,
|
||||
ConfigType.JSON
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param configName The name of the config
|
||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||
* @param plugin The plugin.
|
||||
* @param updateBlacklist Substring of keys to not add/remove keys for.
|
||||
*/
|
||||
protected JSONBaseConfig(@NotNull final String configName,
|
||||
final boolean removeUnused,
|
||||
@NotNull final EcoPlugin plugin,
|
||||
@NotNull final String... updateBlacklist) {
|
||||
this(configName, removeUnused, (PluginLike) plugin, updateBlacklist);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param configName The name of the config
|
||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||
* @param plugin The plugin.
|
||||
*/
|
||||
protected JSONBaseConfig(@NotNull final String configName,
|
||||
final boolean removeUnused,
|
||||
@NotNull final EcoPlugin plugin) {
|
||||
this(configName, removeUnused, (PluginLike) plugin);
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
package com.willfp.eco.core.config.json;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.PluginLike;
|
||||
import com.willfp.eco.core.config.ConfigType;
|
||||
import com.willfp.eco.core.config.interfaces.JSONConfig;
|
||||
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Config implementation for configs present in one of two places:
|
||||
* <ul>
|
||||
* <li>Plugin base directory (eg config.yml, lang.yml)</li>
|
||||
* <li>Other extension's configs</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* Automatically updates.
|
||||
*
|
||||
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
|
||||
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
|
||||
* These configs will be removed eventually.
|
||||
*/
|
||||
@Deprecated(since = "6.17.0")
|
||||
public abstract class JSONExtendableConfig extends LoadableJSONConfigWrapper {
|
||||
/**
|
||||
* @param configName The name of the config
|
||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||
* @param plugin The plugin.
|
||||
* @param updateBlacklist Substring of keys to not add/remove keys for.
|
||||
* @param subDirectoryPath The subdirectory path.
|
||||
* @param source The class that owns the resource.
|
||||
*/
|
||||
protected JSONExtendableConfig(@NotNull final String configName,
|
||||
final boolean removeUnused,
|
||||
@NotNull final PluginLike plugin,
|
||||
@NotNull final Class<?> source,
|
||||
@NotNull final String subDirectoryPath,
|
||||
@NotNull final String... updateBlacklist) {
|
||||
super(
|
||||
(JSONConfig)
|
||||
Eco.getHandler().getConfigFactory().createUpdatableConfig(
|
||||
configName,
|
||||
plugin,
|
||||
subDirectoryPath,
|
||||
source,
|
||||
removeUnused,
|
||||
ConfigType.JSON,
|
||||
updateBlacklist
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param configName The name of the config
|
||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||
* @param plugin The plugin.
|
||||
* @param updateBlacklist Substring of keys to not add/remove keys for.
|
||||
* @param subDirectoryPath The subdirectory path.
|
||||
* @param source The class that owns the resource.
|
||||
*/
|
||||
protected JSONExtendableConfig(@NotNull final String configName,
|
||||
final boolean removeUnused,
|
||||
@NotNull final EcoPlugin plugin,
|
||||
@NotNull final Class<?> source,
|
||||
@NotNull final String subDirectoryPath,
|
||||
@NotNull final String... updateBlacklist) {
|
||||
this(configName, removeUnused, (PluginLike) plugin, source, subDirectoryPath, updateBlacklist);
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package com.willfp.eco.core.config.json;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.PluginLike;
|
||||
import com.willfp.eco.core.config.ConfigType;
|
||||
import com.willfp.eco.core.config.interfaces.JSONConfig;
|
||||
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Non-updatable JSON config that exists within a plugin jar.
|
||||
*
|
||||
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
|
||||
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
|
||||
* These configs will be removed eventually.
|
||||
*/
|
||||
@Deprecated(since = "6.17.0")
|
||||
public abstract class JSONStaticBaseConfig extends LoadableJSONConfigWrapper {
|
||||
/**
|
||||
* Config implementation for configs present in the plugin's base directory (eg config.json, lang.json).
|
||||
* <p>
|
||||
* Does not automatically update.
|
||||
*
|
||||
* @param configName The name of the config
|
||||
* @param plugin The plugin.
|
||||
*/
|
||||
protected JSONStaticBaseConfig(@NotNull final String configName,
|
||||
@NotNull final PluginLike plugin) {
|
||||
super((JSONConfig) Eco.getHandler().getConfigFactory().createLoadableConfig(configName, plugin, "", plugin.getClass(), ConfigType.JSON));
|
||||
}
|
||||
|
||||
/**
|
||||
* Config implementation for configs present in the plugin's base directory (eg config.json, lang.json).
|
||||
* <p>
|
||||
* Does not automatically update.
|
||||
*
|
||||
* @param configName The name of the config
|
||||
* @param plugin The plugin.
|
||||
*/
|
||||
protected JSONStaticBaseConfig(@NotNull final String configName,
|
||||
@NotNull final EcoPlugin plugin) {
|
||||
this(configName, (PluginLike) plugin);
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
package com.willfp.eco.core.config.json;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.config.interfaces.JSONConfig;
|
||||
import com.willfp.eco.core.config.json.wrapper.JSONConfigWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Raw JSON config with a map of values at its core.
|
||||
*
|
||||
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
|
||||
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
|
||||
* These configs will be removed eventually.
|
||||
*/
|
||||
@Deprecated(since = "6.17.0")
|
||||
public class JSONTransientConfig extends JSONConfigWrapper {
|
||||
/**
|
||||
* Config implementation for passing maps.
|
||||
* <p>
|
||||
* Does not automatically update.
|
||||
*
|
||||
* @param values The map of values.
|
||||
*/
|
||||
public JSONTransientConfig(@NotNull final Map<String, Object> values) {
|
||||
super((JSONConfig) Eco.getHandler().getConfigFactory().createConfig(values));
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty JSON config.
|
||||
*/
|
||||
public JSONTransientConfig() {
|
||||
super((JSONConfig) Eco.getHandler().getConfigFactory().createConfig(new HashMap<>()));
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
package com.willfp.eco.core.config.json.wrapper;
|
||||
|
||||
import com.willfp.eco.core.config.interfaces.JSONConfig;
|
||||
import com.willfp.eco.core.config.wrapper.ConfigWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Wrapper to handle the backend JSON config implementations.
|
||||
*
|
||||
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
|
||||
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
|
||||
* These configs will be removed eventually.
|
||||
*/
|
||||
@Deprecated(since = "6.17.0")
|
||||
public abstract class JSONConfigWrapper extends ConfigWrapper<JSONConfig> implements JSONConfig {
|
||||
/**
|
||||
* Create a config wrapper.
|
||||
*
|
||||
* @param handle The handle.
|
||||
*/
|
||||
protected JSONConfigWrapper(@NotNull final JSONConfig handle) {
|
||||
super(handle);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull List<JSONConfig> getSubsections(@NotNull final String path) {
|
||||
return this.getHandle().getSubsections(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable List<JSONConfig> getSubsectionsOrNull(@NotNull final String path) {
|
||||
return this.getHandle().getSubsectionsOrNull(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull JSONConfig getSubsection(@NotNull final String path) {
|
||||
return this.getHandle().getSubsection(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable JSONConfig getSubsectionOrNull(@NotNull final String path) {
|
||||
return this.getHandle().getSubsectionOrNull(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONConfig clone() {
|
||||
return this.getHandle().clone();
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
package com.willfp.eco.core.config.json.wrapper;
|
||||
|
||||
import com.willfp.eco.core.config.interfaces.JSONConfig;
|
||||
import com.willfp.eco.core.config.interfaces.LoadableConfig;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Wrapper to handle the backend loadable JSON config implementations.
|
||||
*
|
||||
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
|
||||
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
|
||||
* These configs will be removed eventually.
|
||||
*/
|
||||
@Deprecated(since = "6.17.0")
|
||||
public abstract class LoadableJSONConfigWrapper extends JSONConfigWrapper implements LoadableConfig {
|
||||
/**
|
||||
* Create a config wrapper.
|
||||
*
|
||||
* @param handle The handle.
|
||||
*/
|
||||
protected LoadableJSONConfigWrapper(@NotNull final JSONConfig handle) {
|
||||
super(handle);
|
||||
|
||||
Validate.isTrue(handle instanceof LoadableConfig, "Wrapped config must be loadable!");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void createFile() {
|
||||
((LoadableConfig) this.getHandle()).createFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResourcePath() {
|
||||
return ((LoadableConfig) this.getHandle()).getResourcePath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() throws IOException {
|
||||
((LoadableConfig) this.getHandle()).save();
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getConfigFile() {
|
||||
return ((LoadableConfig) this.getHandle()).getConfigFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return ((LoadableConfig) this.getHandle()).getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable YamlConfiguration getBukkitHandle() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.willfp.eco.core.config.updating;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@@ -29,7 +30,8 @@ import java.lang.annotation.Target;
|
||||
* }</pre>
|
||||
* <p>
|
||||
* If using kotlin, you have to annotate the method with {@code @JvmStatic}
|
||||
* in order to prevent null pointer exceptions.
|
||||
* in order to prevent null pointer exceptions - this also means that you cannot
|
||||
* have config updater methods in companion objects.
|
||||
* <p>
|
||||
* Config update methods in all classes in a plugin jar will be called
|
||||
* on reload.
|
||||
@@ -39,5 +41,6 @@ import java.lang.annotation.Target;
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
@Documented
|
||||
public @interface ConfigUpdater {
|
||||
}
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
package com.willfp.eco.core.config.wrapper;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.PluginLike;
|
||||
import com.willfp.eco.core.config.ConfigType;
|
||||
import com.willfp.eco.core.config.interfaces.Config;
|
||||
import com.willfp.eco.core.config.interfaces.LoadableConfig;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Internal component to create backend config implementations.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
@Eco.HandlerComponent
|
||||
public interface ConfigFactory {
|
||||
/**
|
||||
* Updatable config.
|
||||
*
|
||||
* @param configName The name of the config
|
||||
* @param plugin The plugin.
|
||||
* @param subDirectoryPath The subdirectory path.
|
||||
* @param source The class that owns the resource.
|
||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||
* @param type The config type.
|
||||
* @param updateBlacklist Substring of keys to not add/remove keys for.
|
||||
* @return The config implementation.
|
||||
*/
|
||||
LoadableConfig createUpdatableConfig(@NotNull String configName,
|
||||
@NotNull PluginLike plugin,
|
||||
@NotNull String subDirectoryPath,
|
||||
@NotNull Class<?> source,
|
||||
boolean removeUnused,
|
||||
@NotNull ConfigType type,
|
||||
@NotNull String... updateBlacklist);
|
||||
|
||||
/**
|
||||
* Loadable config.
|
||||
*
|
||||
* @param configName The name of the config
|
||||
* @param plugin The plugin.
|
||||
* @param subDirectoryPath The subdirectory path.
|
||||
* @param source The class that owns the resource.
|
||||
* @param type The config type.
|
||||
* @return The config implementation.
|
||||
*/
|
||||
LoadableConfig createLoadableConfig(@NotNull String configName,
|
||||
@NotNull PluginLike plugin,
|
||||
@NotNull String subDirectoryPath,
|
||||
@NotNull Class<?> source,
|
||||
@NotNull ConfigType type);
|
||||
|
||||
/**
|
||||
* Create config.
|
||||
*
|
||||
* @param config The handle.
|
||||
* @return The config implementation.
|
||||
*/
|
||||
Config createConfig(@NotNull YamlConfiguration config);
|
||||
|
||||
/**
|
||||
* Create config.
|
||||
*
|
||||
* @param values The values.
|
||||
* @return The config implementation.
|
||||
*/
|
||||
Config createConfig(@NotNull Map<String, Object> values);
|
||||
|
||||
/**
|
||||
* Create config.
|
||||
*
|
||||
* @param contents The file contents.
|
||||
* @param type The type.
|
||||
* @return The config implementation.
|
||||
*/
|
||||
Config createConfig(@NotNull String contents,
|
||||
@NotNull ConfigType type);
|
||||
}
|
||||
@@ -2,12 +2,14 @@ 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.placeholder.StaticPlaceholder;
|
||||
import com.willfp.eco.core.placeholder.InjectablePlaceholder;
|
||||
import com.willfp.eco.util.StringUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Configs from eco have an internal implementation,
|
||||
@@ -17,7 +19,7 @@ import java.util.List;
|
||||
*
|
||||
* @param <T> The type of the handle.
|
||||
*/
|
||||
@SuppressWarnings("MethodDoesntCallSuperMethod")
|
||||
@SuppressWarnings({"MethodDoesntCallSuperMethod", "removal"})
|
||||
public abstract class ConfigWrapper<T extends Config> implements Config {
|
||||
/**
|
||||
* Configs from eco have an internal implementation,
|
||||
@@ -41,6 +43,7 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated(since = "6.31.1", forRemoval = true)
|
||||
public void clearCache() {
|
||||
handle.clearCache();
|
||||
}
|
||||
@@ -60,6 +63,12 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
|
||||
return handle.getKeys(deep);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<String> recurseKeys(@NotNull final Set<String> found,
|
||||
@NotNull final String root) {
|
||||
return handle.recurseKeys(found, root);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Object get(@NotNull final String path) {
|
||||
return handle.get(path);
|
||||
@@ -136,18 +145,13 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectPlaceholders(@NotNull final StaticPlaceholder... placeholders) {
|
||||
handle.injectPlaceholders(placeholders);
|
||||
public void addInjectablePlaceholder(@NotNull final Iterable<InjectablePlaceholder> placeholders) {
|
||||
handle.addInjectablePlaceholder(placeholders);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectPlaceholders(@NotNull final Iterable<StaticPlaceholder> placeholders) {
|
||||
handle.injectPlaceholders(placeholders);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StaticPlaceholder> getInjectedPlaceholders() {
|
||||
return handle.getInjectedPlaceholders();
|
||||
public @NotNull List<InjectablePlaceholder> getPlaceholderInjections() {
|
||||
return handle.getPlaceholderInjections();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -155,6 +159,11 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
|
||||
handle.clearInjectedPlaceholders();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> toMap() {
|
||||
return this.handle.toMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the handle.
|
||||
*
|
||||
|
||||
@@ -3,7 +3,6 @@ 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;
|
||||
@@ -47,7 +46,7 @@ public abstract class LoadableConfigWrapper extends ConfigWrapper<LoadableConfig
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable YamlConfiguration getBukkitHandle() {
|
||||
return this.getHandle().getBukkitHandle();
|
||||
public @NotNull YamlConfiguration toBukkit() {
|
||||
return this.getHandle().toBukkit();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
package com.willfp.eco.core.config.yaml;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.PluginLike;
|
||||
import com.willfp.eco.core.config.ConfigType;
|
||||
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
|
||||
* <p>
|
||||
* Automatically updates.
|
||||
*
|
||||
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
|
||||
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
|
||||
* These configs will be removed eventually.
|
||||
*/
|
||||
@Deprecated(since = "6.17.0")
|
||||
public abstract class YamlBaseConfig extends LoadableYamlConfigWrapper {
|
||||
/**
|
||||
* @param configName The name of the config
|
||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||
* @param plugin The plugin.
|
||||
* @param updateBlacklist Substring of keys to not add/remove keys for.
|
||||
*/
|
||||
protected YamlBaseConfig(@NotNull final String configName,
|
||||
final boolean removeUnused,
|
||||
@NotNull final PluginLike plugin,
|
||||
@NotNull final String... updateBlacklist) {
|
||||
super(
|
||||
Eco.getHandler().getConfigFactory().createUpdatableConfig(
|
||||
configName,
|
||||
plugin,
|
||||
"",
|
||||
plugin.getClass(),
|
||||
removeUnused,
|
||||
ConfigType.YAML,
|
||||
updateBlacklist
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param configName The name of the config
|
||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||
* @param plugin The plugin.
|
||||
*/
|
||||
protected YamlBaseConfig(@NotNull final String configName,
|
||||
final boolean removeUnused,
|
||||
@NotNull final PluginLike plugin) {
|
||||
super(
|
||||
Eco.getHandler().getConfigFactory().createUpdatableConfig(
|
||||
configName,
|
||||
plugin,
|
||||
"",
|
||||
plugin.getClass(),
|
||||
removeUnused,
|
||||
ConfigType.YAML
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param configName The name of the config
|
||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||
* @param plugin The plugin.
|
||||
* @param updateBlacklist Substring of keys to not add/remove keys for.
|
||||
*/
|
||||
protected YamlBaseConfig(@NotNull final String configName,
|
||||
final boolean removeUnused,
|
||||
@NotNull final EcoPlugin plugin,
|
||||
@NotNull final String... updateBlacklist) {
|
||||
this(configName, removeUnused, (PluginLike) plugin, updateBlacklist);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param configName The name of the config
|
||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||
* @param plugin The plugin.
|
||||
*/
|
||||
protected YamlBaseConfig(@NotNull final String configName,
|
||||
final boolean removeUnused,
|
||||
@NotNull final EcoPlugin plugin) {
|
||||
this(configName, removeUnused, (PluginLike) plugin);
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
package com.willfp.eco.core.config.yaml;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.PluginLike;
|
||||
import com.willfp.eco.core.config.ConfigType;
|
||||
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Config implementation for configs present in one of two places:
|
||||
* <ul>
|
||||
* <li>Plugin base directory (eg config.yml, lang.yml)</li>
|
||||
* <li>Other extension's configs</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* Automatically updates.
|
||||
*
|
||||
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
|
||||
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
|
||||
* These configs will be removed eventually.
|
||||
*/
|
||||
@Deprecated(since = "6.17.0")
|
||||
public abstract class YamlExtendableConfig extends LoadableYamlConfigWrapper {
|
||||
/**
|
||||
* @param configName The name of the config
|
||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||
* @param plugin The plugin.
|
||||
* @param updateBlacklist Substring of keys to not add/remove keys for.
|
||||
* @param subDirectoryPath The subdirectory path.
|
||||
* @param source The class that owns the resource.
|
||||
*/
|
||||
protected YamlExtendableConfig(@NotNull final String configName,
|
||||
final boolean removeUnused,
|
||||
@NotNull final PluginLike plugin,
|
||||
@NotNull final Class<?> source,
|
||||
@NotNull final String subDirectoryPath,
|
||||
@NotNull final String... updateBlacklist) {
|
||||
super(
|
||||
Eco.getHandler().getConfigFactory().createUpdatableConfig(
|
||||
configName,
|
||||
plugin,
|
||||
subDirectoryPath,
|
||||
source,
|
||||
removeUnused,
|
||||
ConfigType.YAML,
|
||||
updateBlacklist
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param configName The name of the config
|
||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||
* @param plugin The plugin.
|
||||
* @param updateBlacklist Substring of keys to not add/remove keys for.
|
||||
* @param subDirectoryPath The subdirectory path.
|
||||
* @param source The class that owns the resource.
|
||||
*/
|
||||
protected YamlExtendableConfig(@NotNull final String configName,
|
||||
final boolean removeUnused,
|
||||
@NotNull final EcoPlugin plugin,
|
||||
@NotNull final Class<?> source,
|
||||
@NotNull final String subDirectoryPath,
|
||||
@NotNull final String... updateBlacklist) {
|
||||
this(configName, removeUnused, (PluginLike) plugin, source, subDirectoryPath, updateBlacklist);
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package com.willfp.eco.core.config.yaml;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.PluginLike;
|
||||
import com.willfp.eco.core.config.ConfigType;
|
||||
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Non-updatable yaml config that exists within a plugin jar.
|
||||
*
|
||||
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
|
||||
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
|
||||
* These configs will be removed eventually.
|
||||
*/
|
||||
@Deprecated(since = "6.17.0")
|
||||
public abstract class YamlStaticBaseConfig extends LoadableYamlConfigWrapper {
|
||||
/**
|
||||
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
|
||||
* <p>
|
||||
* Does not automatically update.
|
||||
*
|
||||
* @param configName The name of the config
|
||||
* @param plugin The plugin.
|
||||
*/
|
||||
protected YamlStaticBaseConfig(@NotNull final String configName,
|
||||
@NotNull final PluginLike plugin) {
|
||||
super(Eco.getHandler().getConfigFactory().createLoadableConfig(configName, plugin, "", plugin.getClass(), ConfigType.YAML));
|
||||
}
|
||||
|
||||
/**
|
||||
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
|
||||
* <p>
|
||||
* Does not automatically update.
|
||||
*
|
||||
* @param configName The name of the config
|
||||
* @param plugin The plugin.
|
||||
*/
|
||||
protected YamlStaticBaseConfig(@NotNull final String configName,
|
||||
@NotNull final EcoPlugin plugin) {
|
||||
this(configName, (PluginLike) plugin);
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
package com.willfp.eco.core.config.yaml;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.config.ConfigType;
|
||||
import com.willfp.eco.core.config.yaml.wrapper.YamlConfigWrapper;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.StringReader;
|
||||
|
||||
/**
|
||||
* Config implementation for passing YamlConfigurations.
|
||||
* <p>
|
||||
* Does not automatically update.
|
||||
*
|
||||
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
|
||||
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
|
||||
* These configs will be removed eventually.
|
||||
*/
|
||||
@Deprecated(since = "6.17.0")
|
||||
public class YamlTransientConfig extends YamlConfigWrapper {
|
||||
/**
|
||||
* @param config The YamlConfiguration handle.
|
||||
*/
|
||||
public YamlTransientConfig(@NotNull final YamlConfiguration config) {
|
||||
super(Eco.getHandler().getConfigFactory().createConfig(config));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param contents The contents of the config.
|
||||
*/
|
||||
public YamlTransientConfig(@NotNull final String contents) {
|
||||
super(Eco.getHandler().getConfigFactory().createConfig(contents, ConfigType.YAML));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new empty transient config.
|
||||
*/
|
||||
public YamlTransientConfig() {
|
||||
super(Eco.getHandler().getConfigFactory().createConfig(YamlConfiguration.loadConfiguration(new StringReader(""))));
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
package com.willfp.eco.core.config.yaml.wrapper;
|
||||
|
||||
import com.willfp.eco.core.config.interfaces.Config;
|
||||
import com.willfp.eco.core.config.interfaces.LoadableConfig;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Wrapper to handle the backend loadable yaml config implementations.
|
||||
*
|
||||
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
|
||||
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
|
||||
* These configs will be removed eventually.
|
||||
*/
|
||||
@Deprecated(since = "6.17.0")
|
||||
public abstract class LoadableYamlConfigWrapper extends YamlConfigWrapper implements LoadableConfig {
|
||||
/**
|
||||
* Create a config wrapper.
|
||||
*
|
||||
* @param handle The handle.
|
||||
*/
|
||||
protected LoadableYamlConfigWrapper(@NotNull final Config handle) {
|
||||
super(handle);
|
||||
|
||||
Validate.isTrue(handle instanceof LoadableConfig, "Wrapped config must be loadable!");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void createFile() {
|
||||
((LoadableConfig) this.getHandle()).createFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResourcePath() {
|
||||
return ((LoadableConfig) this.getHandle()).getResourcePath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() throws IOException {
|
||||
((LoadableConfig) this.getHandle()).save();
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getConfigFile() {
|
||||
return ((LoadableConfig) this.getHandle()).getConfigFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return ((LoadableConfig) this.getHandle()).getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable YamlConfiguration getBukkitHandle() {
|
||||
return ((LoadableConfig) this.getHandle()).getBukkitHandle();
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package com.willfp.eco.core.config.yaml.wrapper;
|
||||
|
||||
import com.willfp.eco.core.config.interfaces.Config;
|
||||
import com.willfp.eco.core.config.interfaces.WrappedYamlConfiguration;
|
||||
import com.willfp.eco.core.config.wrapper.ConfigWrapper;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Wrapper to handle the backend yaml config implementations.
|
||||
*
|
||||
* @deprecated JSON and yml have full parity, use configs without a prefix instead,
|
||||
* eg {@link com.willfp.eco.core.config.TransientConfig}, {@link com.willfp.eco.core.config.BaseConfig}.
|
||||
* These configs will be removed eventually.
|
||||
*/
|
||||
@Deprecated(since = "6.17.0")
|
||||
public abstract class YamlConfigWrapper extends ConfigWrapper<Config> implements WrappedYamlConfiguration {
|
||||
/**
|
||||
* Create a config wrapper.
|
||||
*
|
||||
* @param handle The handle.
|
||||
*/
|
||||
protected YamlConfigWrapper(@NotNull final Config handle) {
|
||||
super(handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public YamlConfiguration getBukkitHandle() {
|
||||
return ((WrappedYamlConfiguration) this.getHandle()).getBukkitHandle();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package com.willfp.eco.core.data;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Persistent data container wrapper that allows for full string (non-namespaced) keys.
|
||||
*/
|
||||
public interface ExtendedPersistentDataContainer {
|
||||
/**
|
||||
* Set a key.
|
||||
*
|
||||
* @param key The key.
|
||||
* @param dataType The data type.
|
||||
* @param value The value.
|
||||
* @param <T> The type.
|
||||
* @param <Z> The type.
|
||||
*/
|
||||
<T, Z> void set(@NotNull String key, @NotNull PersistentDataType<T, Z> dataType, @NotNull Z value);
|
||||
|
||||
/**
|
||||
* Get if there is a key.
|
||||
*
|
||||
* @param key The key.
|
||||
* @param dataType The data type.
|
||||
* @param <T> The type.
|
||||
* @param <Z> The type.
|
||||
* @return If the key is present.
|
||||
*/
|
||||
<T, Z> boolean has(@NotNull String key, @NotNull PersistentDataType<T, Z> dataType);
|
||||
|
||||
/**
|
||||
* Get a value.
|
||||
*
|
||||
* @param key The key.
|
||||
* @param dataType The data type.
|
||||
* @param <T> The type.
|
||||
* @param <Z> The type.
|
||||
* @return The value, or null if not found.
|
||||
*/
|
||||
@Nullable <T, Z> Z get(@NotNull String key, @NotNull PersistentDataType<T, Z> dataType);
|
||||
|
||||
/**
|
||||
* Get a value or default if not present.
|
||||
*
|
||||
* @param key The key.
|
||||
* @param dataType The data type.
|
||||
* @param defaultValue The default value.
|
||||
* @param <T> The type.
|
||||
* @param <Z> The type.
|
||||
* @return The value, or the default if not found.
|
||||
*/
|
||||
@NotNull <T, Z> Z getOrDefault(@NotNull String key, @NotNull PersistentDataType<T, Z> dataType, @NotNull Z defaultValue);
|
||||
|
||||
/**
|
||||
* Get all keys, including namespaced keys.
|
||||
*
|
||||
* @return The keys.
|
||||
*/
|
||||
@NotNull
|
||||
Set<String> getAllKeys();
|
||||
|
||||
/**
|
||||
* Remove a key.
|
||||
*
|
||||
* @param key The key.
|
||||
*/
|
||||
void remove(@NotNull String key);
|
||||
|
||||
/**
|
||||
* Get the base PDC.
|
||||
*
|
||||
* @return The base.
|
||||
*/
|
||||
@NotNull
|
||||
PersistentDataContainer getBase();
|
||||
|
||||
/**
|
||||
* Get extension for PersistentDataContainers to add non-namespaced keys.
|
||||
*
|
||||
* @param base The base container.
|
||||
* @return The extended container.
|
||||
*/
|
||||
static ExtendedPersistentDataContainer extend(@NotNull PersistentDataContainer base) {
|
||||
return Eco.get().adaptPdc(base);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new extended container.
|
||||
*
|
||||
* @return The extended container.
|
||||
*/
|
||||
static ExtendedPersistentDataContainer create() {
|
||||
return extend(Eco.get().newPdc());
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,6 @@ public interface PlayerProfile extends Profile {
|
||||
*/
|
||||
@NotNull
|
||||
static PlayerProfile load(@NotNull final UUID uuid) {
|
||||
return Eco.getHandler().getProfileHandler().load(uuid);
|
||||
return Eco.get().loadPlayerProfile(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
package com.willfp.eco.core.data;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKey;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* API to handle profiles.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
@Eco.HandlerComponent
|
||||
public interface ProfileHandler {
|
||||
/**
|
||||
* Load a player profile.
|
||||
*
|
||||
* @param uuid The UUID.
|
||||
* @return The profile.
|
||||
*/
|
||||
PlayerProfile load(@NotNull UUID uuid);
|
||||
|
||||
/**
|
||||
* Load the server profile.
|
||||
*
|
||||
* @return The profile.
|
||||
*/
|
||||
ServerProfile loadServerProfile();
|
||||
|
||||
/**
|
||||
* Unload a player profile from memory.
|
||||
* <p>
|
||||
* This will not save the profile first.
|
||||
*
|
||||
* @param uuid The uuid.
|
||||
*/
|
||||
void unloadPlayer(@NotNull UUID uuid);
|
||||
|
||||
/**
|
||||
* Save a player profile.
|
||||
* <p>
|
||||
* Can run async if using MySQL.
|
||||
*
|
||||
* @param uuid The uuid.
|
||||
* @deprecated Saving changes is faster and should be used. Saving a player manually is not recommended.
|
||||
*/
|
||||
@Deprecated
|
||||
default void savePlayer(@NotNull UUID uuid) {
|
||||
this.saveKeysFor(uuid, PersistentDataKey.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Save keys for a player.
|
||||
* <p>
|
||||
* Can run async if using MySQL.
|
||||
*
|
||||
* @param uuid The uuid.
|
||||
* @param keys The keys.
|
||||
*/
|
||||
void saveKeysFor(@NotNull UUID uuid,
|
||||
@NotNull Set<PersistentDataKey<?>> keys);
|
||||
|
||||
/**
|
||||
* Save all player data.
|
||||
*
|
||||
* @param async If the saving should be done asynchronously.
|
||||
* @deprecated async is now handled automatically depending on implementation.
|
||||
*/
|
||||
@Deprecated
|
||||
default void saveAll(boolean async) {
|
||||
saveAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save all player data.
|
||||
* <p>
|
||||
* Can run async if using MySQL.
|
||||
*/
|
||||
void saveAll();
|
||||
|
||||
/**
|
||||
* Commit all changes to the file.
|
||||
* <p>
|
||||
* Does nothing if using MySQL.
|
||||
*/
|
||||
void save();
|
||||
}
|
||||
@@ -16,6 +16,6 @@ public interface ServerProfile extends Profile {
|
||||
*/
|
||||
@NotNull
|
||||
static ServerProfile load() {
|
||||
return Eco.getHandler().getProfileHandler().loadServerProfile();
|
||||
return Eco.get().getServerProfile();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
package com.willfp.eco.core.data.keys;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* API to register persistent data keys.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
@Eco.HandlerComponent
|
||||
public interface KeyRegistry {
|
||||
/**
|
||||
* Register a persistent data key to be stored.
|
||||
*
|
||||
* @param key The key.
|
||||
*/
|
||||
void registerKey(@NotNull PersistentDataKey<?> key);
|
||||
|
||||
/**
|
||||
* Get all registered keys.
|
||||
*
|
||||
* @return The keys.
|
||||
*/
|
||||
Set<PersistentDataKey<?>> getRegisteredKeys();
|
||||
|
||||
/**
|
||||
* Mark key as category.
|
||||
*
|
||||
* @param key The key.
|
||||
* @param category The category.
|
||||
*/
|
||||
void markKeyAs(@NotNull PersistentDataKey<?> key,
|
||||
@NotNull KeyRegistry.KeyCategory category);
|
||||
|
||||
/**
|
||||
* Get persistent data key from namespaced key.
|
||||
*
|
||||
* @param namespacedKey The key.
|
||||
* @return The key, or null if not found.
|
||||
*/
|
||||
@Nullable
|
||||
PersistentDataKey<?> getKeyFrom(@NotNull NamespacedKey namespacedKey);
|
||||
|
||||
/**
|
||||
* Locations for key categorization.
|
||||
*/
|
||||
enum KeyCategory {
|
||||
/**
|
||||
* Player keys.
|
||||
*/
|
||||
PLAYER,
|
||||
|
||||
/**
|
||||
* Server keys.
|
||||
*/
|
||||
SERVER
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,7 @@ public final class PersistentDataKey<T> {
|
||||
this.defaultValue = defaultValue;
|
||||
this.type = type;
|
||||
|
||||
Eco.getHandler().getKeyRegistry().registerKey(this);
|
||||
Eco.get().registerPersistentKey(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -83,28 +83,40 @@ public final class PersistentDataKey<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* In older eco versions, keys would have to be categorized in order
|
||||
* to register the columns in the MySQL database. This is no longer needed.
|
||||
* <p>
|
||||
* Old description is below:
|
||||
* <p>
|
||||
* Categorize key as a server key, will register new column to MySQL
|
||||
* database immediately rather than waiting for auto-categorization.
|
||||
* <p>
|
||||
* This will improve performance.
|
||||
*
|
||||
* @return The key.
|
||||
* @deprecated Not required since the new MySQL data handler was introduced.
|
||||
*/
|
||||
@Deprecated(since = "6.40.0", forRemoval = true)
|
||||
public PersistentDataKey<T> server() {
|
||||
Eco.getHandler().getKeyRegistry().markKeyAs(this, KeyRegistry.KeyCategory.SERVER);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* In older eco versions, keys would have to be categorized in order
|
||||
* to register the columns in the MySQL database. This is no longer needed.
|
||||
* <p>
|
||||
* Old description is below:
|
||||
* <p>
|
||||
* Categorize key as a player key, will register new column to MySQL
|
||||
* database immediately rather than waiting for auto-categorization.
|
||||
* <p>
|
||||
* This will improve performance.
|
||||
*
|
||||
* @return The key.
|
||||
* @deprecated Not required since the new MySQL data handler was introduced.
|
||||
*/
|
||||
@Deprecated(since = "6.40.0", forRemoval = true)
|
||||
public PersistentDataKey<T> player() {
|
||||
Eco.getHandler().getKeyRegistry().markKeyAs(this, KeyRegistry.KeyCategory.PLAYER);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -114,7 +126,7 @@ public final class PersistentDataKey<T> {
|
||||
* @return The keys.
|
||||
*/
|
||||
public static Set<PersistentDataKey<?>> values() {
|
||||
return Eco.getHandler().getKeyRegistry().getRegisteredKeys();
|
||||
return Eco.get().getRegisteredPersistentDataKeys();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -122,7 +134,7 @@ public final class PersistentDataKey<T> {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof PersistentDataKey that)) {
|
||||
if (!(o instanceof PersistentDataKey<?> that)) {
|
||||
return false;
|
||||
}
|
||||
return Objects.equals(this.getKey(), that.getKey());
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package com.willfp.eco.core.data.keys;
|
||||
|
||||
import com.willfp.eco.core.config.interfaces.Config;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* All storable data key types.
|
||||
@@ -37,6 +39,16 @@ public final class PersistentDataKeyType<T> {
|
||||
*/
|
||||
public static final PersistentDataKeyType<Double> DOUBLE = new PersistentDataKeyType<>(Double.class, "DOUBLE");
|
||||
|
||||
/**
|
||||
* String List.
|
||||
*/
|
||||
public static final PersistentDataKeyType<List<String>> STRING_LIST = new PersistentDataKeyType<>(null, "STRING_LIST");
|
||||
|
||||
/**
|
||||
* Config.
|
||||
*/
|
||||
public static final PersistentDataKeyType<Config> CONFIG = new PersistentDataKeyType<>(Config.class, "CONFIG");
|
||||
|
||||
/**
|
||||
* The class of the type.
|
||||
*/
|
||||
@@ -51,7 +63,10 @@ public final class PersistentDataKeyType<T> {
|
||||
* Get the class of the type.
|
||||
*
|
||||
* @return The class.
|
||||
* @deprecated String list type will return null.
|
||||
*/
|
||||
@Deprecated(since = "6.36.0", forRemoval = true)
|
||||
@Nullable
|
||||
public Class<T> getTypeClass() {
|
||||
return typeClass;
|
||||
}
|
||||
@@ -71,7 +86,7 @@ public final class PersistentDataKeyType<T> {
|
||||
* @param typeClass The type class.
|
||||
* @param name The name.
|
||||
*/
|
||||
private PersistentDataKeyType(@NotNull final Class<T> typeClass,
|
||||
private PersistentDataKeyType(@Nullable final Class<T> typeClass,
|
||||
@NotNull final String name) {
|
||||
VALUES.add(this);
|
||||
|
||||
@@ -79,6 +94,22 @@ public final class PersistentDataKeyType<T> {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable final Object that) {
|
||||
if (this == that) {
|
||||
return true;
|
||||
}
|
||||
if (!(that instanceof PersistentDataKeyType<?> type)) {
|
||||
return false;
|
||||
}
|
||||
return Objects.equals(this.name, type.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all registered {@link PersistentDataKeyType}s.
|
||||
*
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
package com.willfp.eco.core.display;
|
||||
|
||||
import com.willfp.eco.core.fast.FastItemStack;
|
||||
import com.willfp.eco.util.NamespacedKeyUtils;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* Utility class to manage client-side item display.
|
||||
*/
|
||||
@@ -16,9 +26,14 @@ public final class Display {
|
||||
public static final String PREFIX = "§z";
|
||||
|
||||
/**
|
||||
* The display handler.
|
||||
* All registered modules.
|
||||
*/
|
||||
private static DisplayHandler handler = null;
|
||||
private static final Map<Integer, List<DisplayModule>> REGISTERED_MODULES = new TreeMap<>();
|
||||
|
||||
/**
|
||||
* The finalize key.
|
||||
*/
|
||||
private static final NamespacedKey FINALIZE_KEY = NamespacedKeyUtils.createEcoKey("finalized");
|
||||
|
||||
/**
|
||||
* Display on ItemStacks.
|
||||
@@ -39,7 +54,49 @@ public final class Display {
|
||||
*/
|
||||
public static ItemStack display(@NotNull final ItemStack itemStack,
|
||||
@Nullable final Player player) {
|
||||
return handler.display(itemStack, player);
|
||||
Map<String, Object[]> pluginVarArgs = new HashMap<>();
|
||||
|
||||
for (List<DisplayModule> modules : REGISTERED_MODULES.values()) {
|
||||
for (DisplayModule module : modules) {
|
||||
pluginVarArgs.put(module.getPluginName(), module.generateVarArgs(itemStack));
|
||||
}
|
||||
}
|
||||
|
||||
Display.revert(itemStack);
|
||||
|
||||
if (!itemStack.hasItemMeta()) {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
ItemStack original = itemStack.clone();
|
||||
Inventory inventory = player == null ? null : player.getOpenInventory().getTopInventory();
|
||||
boolean inInventory = inventory != null && inventory.contains(original);
|
||||
boolean inGui = inventory != null && inventory.getHolder() == null;
|
||||
|
||||
DisplayProperties properties = new DisplayProperties(
|
||||
inInventory,
|
||||
inGui,
|
||||
original
|
||||
);
|
||||
|
||||
for (List<DisplayModule> modules : REGISTERED_MODULES.values()) {
|
||||
for (DisplayModule module : modules) {
|
||||
Object[] varargs = pluginVarArgs.get(module.getPluginName());
|
||||
|
||||
if (varargs == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
module.display(itemStack, varargs);
|
||||
|
||||
if (player != null) {
|
||||
module.display(itemStack, player, varargs);
|
||||
module.display(itemStack, player, properties, varargs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,7 +128,25 @@ public final class Display {
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
public static ItemStack revert(@NotNull final ItemStack itemStack) {
|
||||
return handler.revert(itemStack);
|
||||
if (Display.isFinalized(itemStack)) {
|
||||
Display.unfinalize(itemStack);
|
||||
}
|
||||
|
||||
FastItemStack fast = FastItemStack.wrap(itemStack);
|
||||
|
||||
List<String> lore = fast.getLore();
|
||||
|
||||
if (!lore.isEmpty() && lore.removeIf(line -> line.startsWith(Display.PREFIX))) {
|
||||
fast.setLore(lore);
|
||||
}
|
||||
|
||||
for (List<DisplayModule> modules : REGISTERED_MODULES.values()) {
|
||||
for (DisplayModule module : modules) {
|
||||
module.revert(itemStack);
|
||||
}
|
||||
}
|
||||
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,7 +156,15 @@ public final class Display {
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
public static ItemStack finalize(@NotNull final ItemStack itemStack) {
|
||||
return handler.finalize(itemStack);
|
||||
if (itemStack.getType().getMaxStackSize() > 1) {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
FastItemStack.wrap(itemStack)
|
||||
.getPersistentDataContainer()
|
||||
.set(FINALIZE_KEY, PersistentDataType.INTEGER, 1);
|
||||
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -91,7 +174,11 @@ public final class Display {
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
public static ItemStack unfinalize(@NotNull final ItemStack itemStack) {
|
||||
return handler.unfinalize(itemStack);
|
||||
FastItemStack.wrap(itemStack)
|
||||
.getPersistentDataContainer()
|
||||
.remove(FINALIZE_KEY);
|
||||
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -101,7 +188,9 @@ public final class Display {
|
||||
* @return If finalized.
|
||||
*/
|
||||
public static boolean isFinalized(@NotNull final ItemStack itemStack) {
|
||||
return handler.isFinalized(itemStack);
|
||||
return FastItemStack.wrap(itemStack)
|
||||
.getPersistentDataContainer()
|
||||
.has(FINALIZE_KEY, PersistentDataType.INTEGER);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,69 +199,15 @@ public final class Display {
|
||||
* @param module The module.
|
||||
*/
|
||||
public static void registerDisplayModule(@NotNull final DisplayModule module) {
|
||||
handler.registerDisplayModule(module);
|
||||
}
|
||||
List<DisplayModule> modules = REGISTERED_MODULES.getOrDefault(
|
||||
module.getWeight(),
|
||||
new ArrayList<>()
|
||||
);
|
||||
|
||||
/**
|
||||
* Initialize the display system.
|
||||
*
|
||||
* @param handler The handler.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public static void init(@NotNull final DisplayHandler handler) {
|
||||
if (Display.handler != null) {
|
||||
throw new IllegalArgumentException("Already Initialized!");
|
||||
}
|
||||
Display.handler = handler;
|
||||
}
|
||||
modules.removeIf(it -> it.getPluginName().equalsIgnoreCase(module.getPluginName()));
|
||||
modules.add(module);
|
||||
|
||||
/**
|
||||
* Extremely janky method - also internal, so don't use it. <b>This method is
|
||||
* NOT part of the API and may be removed at any time!</b>
|
||||
* <p>
|
||||
* This calls a display module with the specified parameters, now
|
||||
* you might ask why I need a static java method when the DisplayHandler
|
||||
* implementation could just call it itself? Well, kotlin doesn't really
|
||||
* like dealing with vararg ambiguity, and so while kotlin can't figure out
|
||||
* what is and isn't a vararg when I call display with a player, java can.
|
||||
* <p>
|
||||
* Because of this, I need to have this part of the code in java.
|
||||
*
|
||||
* <b>Don't call this method as part of your plugins!</b>
|
||||
* <p>
|
||||
* No, seriously - don't. This skips a bunch of checks and you'll almost
|
||||
* definitely break something.
|
||||
*
|
||||
* @param module The display module.
|
||||
* @param itemStack The ItemStack.
|
||||
* @param player The player.
|
||||
* @param args The args.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public static void callDisplayModule(@NotNull final DisplayModule module,
|
||||
@NotNull final ItemStack itemStack,
|
||||
@Nullable final Player player,
|
||||
@NotNull final Object... args) {
|
||||
module.display(itemStack, args);
|
||||
if (player != null) {
|
||||
module.display(itemStack, player, args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the display handler.
|
||||
* <p>
|
||||
* Internal API component, you will cause bugs if you create your own handler.
|
||||
*
|
||||
* @param handler The handler.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public static void setHandler(@NotNull final DisplayHandler handler) {
|
||||
if (Display.handler != null) {
|
||||
throw new IllegalStateException("Display already initialized!");
|
||||
}
|
||||
|
||||
Display.handler = handler;
|
||||
REGISTERED_MODULES.put(module.getWeight(), modules);
|
||||
}
|
||||
|
||||
private Display() {
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
package com.willfp.eco.core.display;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Interface for display implementations.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
@Eco.HandlerComponent
|
||||
public interface DisplayHandler {
|
||||
/**
|
||||
* Register display module.
|
||||
*
|
||||
* @param module The module.
|
||||
*/
|
||||
void registerDisplayModule(@NotNull DisplayModule module);
|
||||
|
||||
/**
|
||||
* Display on ItemStacks.
|
||||
*
|
||||
* @param itemStack The item.
|
||||
* @param player The player.
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
ItemStack display(@NotNull ItemStack itemStack,
|
||||
@Nullable Player player);
|
||||
|
||||
/**
|
||||
* Revert on ItemStacks.
|
||||
*
|
||||
* @param itemStack The item.
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
ItemStack revert(@NotNull ItemStack itemStack);
|
||||
|
||||
/**
|
||||
* Finalize an ItemStacks.
|
||||
*
|
||||
* @param itemStack The item.
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
ItemStack finalize(@NotNull ItemStack itemStack);
|
||||
|
||||
/**
|
||||
* Unfinalize an ItemStacks.
|
||||
*
|
||||
* @param itemStack The item.
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
ItemStack unfinalize(@NotNull ItemStack itemStack);
|
||||
|
||||
/**
|
||||
* If an item is finalized.
|
||||
*
|
||||
* @param itemStack The item.
|
||||
* @return If finalized.
|
||||
*/
|
||||
boolean isFinalized(@NotNull ItemStack itemStack);
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.willfp.eco.core.display;
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.PluginDependent;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -10,11 +9,16 @@ import org.jetbrains.annotations.Nullable;
|
||||
/**
|
||||
* Class for all plugin-specific client-side item display modules.
|
||||
*/
|
||||
public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
|
||||
public abstract class DisplayModule {
|
||||
/**
|
||||
* The priority of the module.
|
||||
*/
|
||||
private final DisplayPriority priority;
|
||||
private final int weight;
|
||||
|
||||
/**
|
||||
* The plugin.
|
||||
*/
|
||||
private final EcoPlugin plugin;
|
||||
|
||||
/**
|
||||
* Create a new display module.
|
||||
@@ -24,8 +28,19 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
|
||||
*/
|
||||
protected DisplayModule(@NotNull final EcoPlugin plugin,
|
||||
@NotNull final DisplayPriority priority) {
|
||||
super(plugin);
|
||||
this.priority = priority;
|
||||
this(plugin, priority.getWeight());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new display module.
|
||||
*
|
||||
* @param plugin The plugin that the display is for.
|
||||
* @param weight The weight/priority of the module.
|
||||
*/
|
||||
protected DisplayModule(@NotNull final EcoPlugin plugin,
|
||||
final int weight) {
|
||||
this.plugin = plugin;
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,6 +67,21 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
|
||||
// Technically optional.
|
||||
}
|
||||
|
||||
/**
|
||||
* Display an item.
|
||||
*
|
||||
* @param itemStack The item.
|
||||
* @param player The player.
|
||||
* @param properties The properties.
|
||||
* @param args Optional args for display.
|
||||
*/
|
||||
public void display(@NotNull final ItemStack itemStack,
|
||||
@Nullable final Player player,
|
||||
@NotNull final DisplayProperties properties,
|
||||
@NotNull final Object... args) {
|
||||
// Technically optional.
|
||||
}
|
||||
|
||||
/**
|
||||
* Revert an item.
|
||||
*
|
||||
@@ -77,15 +107,41 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
|
||||
* @return The plugin name.
|
||||
*/
|
||||
public final String getPluginName() {
|
||||
return super.getPlugin().getName();
|
||||
return this.getPlugin().getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the display priority.
|
||||
*
|
||||
* @return The priority.
|
||||
* @deprecated Use getWeight instead.
|
||||
*/
|
||||
@Deprecated(since = "6.35.0", forRemoval = true)
|
||||
public DisplayPriority getPriority() {
|
||||
return this.priority;
|
||||
return switch (this.weight) {
|
||||
case 100 -> DisplayPriority.LOWEST;
|
||||
case 200 -> DisplayPriority.LOW;
|
||||
case 300 -> DisplayPriority.HIGH;
|
||||
case 400 -> DisplayPriority.HIGHEST;
|
||||
default -> DisplayPriority.CUSTOM;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the display weight.
|
||||
*
|
||||
* @return The weight.
|
||||
*/
|
||||
public int getWeight() {
|
||||
return this.weight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plugin.
|
||||
*
|
||||
* @return The plugin.
|
||||
*/
|
||||
public EcoPlugin getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,23 +4,51 @@ package com.willfp.eco.core.display;
|
||||
* The priority (order) of display modules.
|
||||
*/
|
||||
public enum DisplayPriority {
|
||||
/**
|
||||
* Custom weight.
|
||||
*/
|
||||
CUSTOM(250),
|
||||
|
||||
/**
|
||||
* Ran first.
|
||||
*/
|
||||
LOWEST,
|
||||
LOWEST(100),
|
||||
|
||||
/**
|
||||
* Ran second.
|
||||
*/
|
||||
LOW,
|
||||
LOW(200),
|
||||
|
||||
/**
|
||||
* Ran third.
|
||||
*/
|
||||
HIGH,
|
||||
HIGH(300),
|
||||
|
||||
/**
|
||||
* Ran last.
|
||||
*/
|
||||
HIGHEST
|
||||
HIGHEST(400);
|
||||
|
||||
/**
|
||||
* The display priority weight.
|
||||
*/
|
||||
private final int weight;
|
||||
|
||||
/**
|
||||
* Create new display priority.
|
||||
*
|
||||
* @param weight The weight.
|
||||
*/
|
||||
DisplayPriority(final int weight) {
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the weight.
|
||||
*
|
||||
* @return The weight.
|
||||
*/
|
||||
public int getWeight() {
|
||||
return weight;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.willfp.eco.core.display;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Extra properties passed into {@link DisplayModule}.
|
||||
*
|
||||
* @param inInventory If the item was in an inventory.
|
||||
* @param inGui If the item is assumed to be in a gui. (Not perfectly accurate).
|
||||
* @param originalItem The original item, not to be modified.
|
||||
*/
|
||||
public record DisplayProperties(
|
||||
boolean inInventory,
|
||||
boolean inGui,
|
||||
@NotNull ItemStack originalItem
|
||||
) {
|
||||
}
|
||||
@@ -21,13 +21,25 @@ public class DropQueue {
|
||||
/**
|
||||
* The internally used {@link DropQueue}.
|
||||
*/
|
||||
private final InternalDropQueue handle;
|
||||
private final DropQueue delegate;
|
||||
|
||||
/**
|
||||
* Create a new DropQueue.
|
||||
*
|
||||
* @param player The player.
|
||||
*/
|
||||
public DropQueue(@NotNull final Player player) {
|
||||
handle = Eco.getHandler().getDropQueueFactory().create(player);
|
||||
this.delegate = Eco.get().createDropQueue(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new DropQueue with no delegate.
|
||||
* <p>
|
||||
* Call this constructor if you're creating custom DropQueue
|
||||
* implementations.
|
||||
*/
|
||||
protected DropQueue() {
|
||||
this.delegate = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,7 +49,11 @@ public class DropQueue {
|
||||
* @return The DropQueue.
|
||||
*/
|
||||
public DropQueue addItem(@NotNull final ItemStack item) {
|
||||
handle.addItem(item);
|
||||
if (delegate == null) {
|
||||
return this;
|
||||
}
|
||||
|
||||
delegate.addItem(item);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -48,7 +64,11 @@ public class DropQueue {
|
||||
* @return The DropQueue.
|
||||
*/
|
||||
public DropQueue addItems(@NotNull final Collection<ItemStack> itemStacks) {
|
||||
handle.addItems(itemStacks);
|
||||
if (delegate == null) {
|
||||
return this;
|
||||
}
|
||||
|
||||
delegate.addItems(itemStacks);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -59,7 +79,11 @@ public class DropQueue {
|
||||
* @return The DropQueue.
|
||||
*/
|
||||
public DropQueue addXP(final int amount) {
|
||||
handle.addXP(amount);
|
||||
if (delegate == null) {
|
||||
return this;
|
||||
}
|
||||
|
||||
delegate.addXP(amount);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -70,7 +94,11 @@ public class DropQueue {
|
||||
* @return The DropQueue.
|
||||
*/
|
||||
public DropQueue setLocation(@NotNull final Location location) {
|
||||
handle.setLocation(location);
|
||||
if (delegate == null) {
|
||||
return this;
|
||||
}
|
||||
|
||||
delegate.setLocation(location);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -80,7 +108,11 @@ public class DropQueue {
|
||||
* @return The DropQueue.
|
||||
*/
|
||||
public DropQueue forceTelekinesis() {
|
||||
handle.forceTelekinesis();
|
||||
if (delegate == null) {
|
||||
return this;
|
||||
}
|
||||
|
||||
delegate.forceTelekinesis();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -88,6 +120,10 @@ public class DropQueue {
|
||||
* Push the queue.
|
||||
*/
|
||||
public void push() {
|
||||
handle.push();
|
||||
if (delegate == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
delegate.push();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
package com.willfp.eco.core.drops;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Internal component to create backend DropQueue implementations.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
@Eco.HandlerComponent
|
||||
public interface DropQueueFactory {
|
||||
/**
|
||||
* Create a DropQueue.
|
||||
*
|
||||
* @param player The player.
|
||||
* @return The Queue.
|
||||
*/
|
||||
InternalDropQueue create(@NotNull Player player);
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
package com.willfp.eco.core.drops;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Internal interface for backend DropQueue implementations.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
@Eco.HandlerComponent
|
||||
public interface InternalDropQueue {
|
||||
/**
|
||||
* Add item to queue.
|
||||
*
|
||||
* @param item The item to add.
|
||||
* @return The DropQueue.
|
||||
*/
|
||||
InternalDropQueue addItem(@NotNull ItemStack item);
|
||||
|
||||
/**
|
||||
* Add multiple items to queue.
|
||||
*
|
||||
* @param itemStacks The items to add.
|
||||
* @return The DropQueue.
|
||||
*/
|
||||
InternalDropQueue addItems(@NotNull Collection<ItemStack> itemStacks);
|
||||
|
||||
/**
|
||||
* Add xp to queue.
|
||||
*
|
||||
* @param amount The amount to add.
|
||||
* @return The DropQueue.
|
||||
*/
|
||||
InternalDropQueue addXP(int amount);
|
||||
|
||||
/**
|
||||
* Set location of the origin of the drops.
|
||||
*
|
||||
* @param location The location.
|
||||
* @return The DropQueue.
|
||||
*/
|
||||
InternalDropQueue setLocation(@NotNull Location location);
|
||||
|
||||
/**
|
||||
* Force the queue to act as if player is telekinetic.
|
||||
*
|
||||
* @return The DropQueue.
|
||||
*/
|
||||
InternalDropQueue forceTelekinesis();
|
||||
|
||||
/**
|
||||
* Push the queue.
|
||||
*/
|
||||
void push();
|
||||
}
|
||||
@@ -101,6 +101,6 @@ public interface EntityController<T extends Mob> {
|
||||
* @return The entity controller.
|
||||
*/
|
||||
static <T extends Mob> EntityController<T> getFor(@NotNull final T entity) {
|
||||
return Eco.getHandler().createEntityController(entity);
|
||||
return Eco.get().createEntityController(entity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,6 @@ public class EmptyTestableEntity implements TestableEntity {
|
||||
public Entity spawn(@NotNull final Location location) {
|
||||
Validate.notNull(location.getWorld());
|
||||
|
||||
return Eco.getHandler().createDummyEntity(location);
|
||||
return Eco.get().createDummyEntity(location);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.willfp.eco.core.extensions;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Internal component to manage loading and unloading extensions.
|
||||
* Manages the loading and unloading of extensions for a particular plugin.
|
||||
*/
|
||||
public interface ExtensionLoader {
|
||||
/**
|
||||
|
||||
@@ -13,5 +13,6 @@ public interface NamespacedKeyFactory {
|
||||
* @param key The key in the {@link NamespacedKey}.
|
||||
* @return The created {@link NamespacedKey}.
|
||||
*/
|
||||
@NotNull
|
||||
NamespacedKey create(@NotNull String key);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package com.willfp.eco.core.fast;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import org.bukkit.persistence.PersistentDataHolder;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -16,7 +19,7 @@ import java.util.Set;
|
||||
/**
|
||||
* FastItemStack contains methods to modify and read items faster than in default bukkit.
|
||||
*/
|
||||
public interface FastItemStack {
|
||||
public interface FastItemStack extends PersistentDataHolder {
|
||||
/**
|
||||
* Get all enchantments on an item.
|
||||
*
|
||||
@@ -24,7 +27,7 @@ public interface FastItemStack {
|
||||
* @return A map of all enchantments.
|
||||
* @deprecated Poorly named method. Use getEnchants instead.
|
||||
*/
|
||||
@Deprecated(since = "6.24.0")
|
||||
@Deprecated(since = "6.24.0", forRemoval = true)
|
||||
default Map<Enchantment, Integer> getEnchantmentsOnItem(boolean checkStored) {
|
||||
return getEnchants(checkStored);
|
||||
}
|
||||
@@ -45,17 +48,55 @@ public interface FastItemStack {
|
||||
* @param checkStored If stored enchantments should be accounted for.
|
||||
* @return A map of all enchantments.
|
||||
*/
|
||||
@NotNull
|
||||
Map<Enchantment, Integer> getEnchants(boolean checkStored);
|
||||
|
||||
/**
|
||||
* Get the level of an enchantment on an item.
|
||||
*
|
||||
* @param enchantment The enchantment.
|
||||
* @return The enchantment level, or 0 if not found.
|
||||
* @deprecated Poorly named method. Use getEnchantmentLevel instead.
|
||||
*/
|
||||
@Deprecated(since = "6.34.0", forRemoval = true)
|
||||
default int getLevelOnItem(@NotNull Enchantment enchantment) {
|
||||
return getEnchantmentLevel(enchantment, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the level of an enchantment on an item.
|
||||
*
|
||||
* @param enchantment The enchantment.
|
||||
* @param checkStored If the stored NBT should also be checked.
|
||||
* @return The enchantment level, or 0 if not found.
|
||||
* @deprecated Poorly named method. Use getEnchantmentLevel instead.
|
||||
*/
|
||||
int getLevelOnItem(@NotNull Enchantment enchantment,
|
||||
boolean checkStored);
|
||||
@Deprecated(since = "6.34.0", forRemoval = true)
|
||||
@SuppressWarnings("DeprecatedIsStillUsed")
|
||||
default int getLevelOnItem(@NotNull Enchantment enchantment,
|
||||
boolean checkStored) {
|
||||
return getEnchantmentLevel(enchantment, checkStored);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the level of an enchantment.
|
||||
*
|
||||
* @param enchantment The enchantment.
|
||||
* @return The enchantment level, or 0 if not found.
|
||||
*/
|
||||
default int getEnchantmentLevel(@NotNull Enchantment enchantment) {
|
||||
return getLevelOnItem(enchantment, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the level of an enchantment.
|
||||
*
|
||||
* @param enchantment The enchantment.
|
||||
* @param checkStored If the stored NBT should also be checked.
|
||||
* @return The enchantment level, or 0 if not found.
|
||||
*/
|
||||
int getEnchantmentLevel(@NotNull Enchantment enchantment,
|
||||
boolean checkStored);
|
||||
|
||||
/**
|
||||
* Set the item lore.
|
||||
@@ -64,6 +105,13 @@ public interface FastItemStack {
|
||||
*/
|
||||
void setLore(@Nullable List<String> lore);
|
||||
|
||||
/**
|
||||
* Set the item lore.
|
||||
*
|
||||
* @param lore The lore.
|
||||
*/
|
||||
void setLoreComponents(@Nullable List<Component> lore);
|
||||
|
||||
/**
|
||||
* Get the item lore.
|
||||
*
|
||||
@@ -71,6 +119,40 @@ public interface FastItemStack {
|
||||
*/
|
||||
List<String> getLore();
|
||||
|
||||
/**
|
||||
* Get the item lore.
|
||||
*
|
||||
* @return The lore.
|
||||
*/
|
||||
List<Component> getLoreComponents();
|
||||
|
||||
/**
|
||||
* Set the item name.
|
||||
*
|
||||
* @param name The name.
|
||||
*/
|
||||
void setDisplayName(@Nullable Component name);
|
||||
|
||||
/**
|
||||
* Set the item name.
|
||||
*
|
||||
* @param name The name.
|
||||
*/
|
||||
void setDisplayName(@Nullable String name);
|
||||
|
||||
/**
|
||||
* Get the item display name.
|
||||
*
|
||||
* @return The display name.
|
||||
*/
|
||||
Component getDisplayNameComponent();
|
||||
|
||||
/**
|
||||
* Get the item display name.
|
||||
*
|
||||
* @return The display name.
|
||||
*/
|
||||
String getDisplayName();
|
||||
|
||||
/**
|
||||
* Set the rework penalty.
|
||||
@@ -81,7 +163,6 @@ public interface FastItemStack {
|
||||
|
||||
/**
|
||||
* Get the rework penalty.
|
||||
* .
|
||||
*
|
||||
* @return The rework penalty found on the item.
|
||||
*/
|
||||
@@ -116,11 +197,72 @@ public interface FastItemStack {
|
||||
*/
|
||||
boolean hasItemFlag(@NotNull ItemFlag flag);
|
||||
|
||||
/**
|
||||
* Get the base NBT tag (Not PublicBukkitValues, the base) as a PersistentDataContainer.
|
||||
* <p>
|
||||
* The returned PersistentDataContainer will not modify the item until the tag is set.
|
||||
*
|
||||
* @return The base NBT tag.
|
||||
*/
|
||||
PersistentDataContainer getBaseTag();
|
||||
|
||||
/**
|
||||
* Set the base NBT tag (Not PublicBukkitValues, the base) from a PersistentDataContainer.
|
||||
*
|
||||
* @param container The PersistentDataContainer.
|
||||
*/
|
||||
void setBaseTag(@Nullable PersistentDataContainer container);
|
||||
|
||||
/**
|
||||
* Get the type of the item.
|
||||
*
|
||||
* @return The type.
|
||||
*/
|
||||
@NotNull
|
||||
Material getType();
|
||||
|
||||
/**
|
||||
* Set the type of the item.
|
||||
*
|
||||
* @param material The type.
|
||||
*/
|
||||
void setType(@NotNull Material material);
|
||||
|
||||
/**
|
||||
* Get the amount of the item.
|
||||
*
|
||||
* @return The amount.
|
||||
*/
|
||||
int getAmount();
|
||||
|
||||
/**
|
||||
* Set the amount of the item.
|
||||
*
|
||||
* @param amount The amount.
|
||||
*/
|
||||
void setAmount(int amount);
|
||||
|
||||
/**
|
||||
* Get the custom model data.
|
||||
*
|
||||
* @return The data, or null if none.
|
||||
*/
|
||||
@Nullable
|
||||
Integer getCustomModelData();
|
||||
|
||||
/**
|
||||
* Set the custom model data.
|
||||
*
|
||||
* @param data The data, null to remove.
|
||||
*/
|
||||
void setCustomModelData(@Nullable Integer data);
|
||||
|
||||
/**
|
||||
* Get the Bukkit ItemStack again.
|
||||
*
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
@NotNull
|
||||
ItemStack unwrap();
|
||||
|
||||
/**
|
||||
@@ -130,6 +272,6 @@ public interface FastItemStack {
|
||||
* @return The FastItemStack.
|
||||
*/
|
||||
static FastItemStack wrap(@Nullable final ItemStack itemStack) {
|
||||
return Eco.getHandler().createFastItemStack(Objects.requireNonNullElseGet(itemStack, () -> new ItemStack(Material.AIR)));
|
||||
return Eco.get().createFastItemStack(Objects.requireNonNullElseGet(itemStack, () -> new ItemStack(Material.AIR)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.willfp.eco.core.gui;
|
||||
|
||||
import com.willfp.eco.core.gui.menu.Menu;
|
||||
import com.willfp.eco.core.gui.slot.Slot;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* A GUI Component is a 2-dimensional set of slots that can be
|
||||
* placed in a menu.
|
||||
*/
|
||||
public interface GUIComponent {
|
||||
/**
|
||||
* Get the amount of rows in the component.
|
||||
*
|
||||
* @return The rows.
|
||||
*/
|
||||
int getRows();
|
||||
|
||||
/**
|
||||
* Get the amount of columns in the component.
|
||||
*
|
||||
* @return The columns.
|
||||
*/
|
||||
int getColumns();
|
||||
|
||||
/**
|
||||
* Initialize the component.
|
||||
* <p>
|
||||
* This is called before getRows / getColumns is queried,
|
||||
* and allows for dynamically sized components.
|
||||
* <p>
|
||||
* getRows and getColumns can return values bigger than this,
|
||||
* it will simply prevent the component from being added at
|
||||
* this position (for minimum-sized components).
|
||||
*
|
||||
* @param maxRows The maximum number of rows.
|
||||
* @param maxColumns The maximum number of columns.
|
||||
*/
|
||||
default void init(final int maxRows,
|
||||
final int maxColumns) {
|
||||
// Most components will not require initialization.
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the slot at a certain position in the component.
|
||||
* <p>
|
||||
* It's safe to assume to the row and column will always be in bounds.
|
||||
*
|
||||
* @param row The row (1-indexed).
|
||||
* @param column The column (1-indexed).
|
||||
* @return The slot, or null if no slot at the location.
|
||||
*/
|
||||
@Nullable
|
||||
default Slot getSlotAt(final int row,
|
||||
final int column) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the slot at a certain position in the component.
|
||||
* <p>
|
||||
* If your component doesn't use context data (player, menu),
|
||||
* then it will default to the raw slot.
|
||||
* <p>
|
||||
* It's safe to assume to the row and column will always be in bounds.
|
||||
*
|
||||
* @param row The row (1-indexed).
|
||||
* @param column The column (1-indexed).
|
||||
* @param player The player.
|
||||
* @param menu The menu.
|
||||
* @return The slot, or null if no slot at the location.
|
||||
*/
|
||||
@Nullable
|
||||
default Slot getSlotAt(final int row,
|
||||
final int column,
|
||||
@NotNull final Player player,
|
||||
@NotNull final Menu menu) {
|
||||
return getSlotAt(row, column);
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package com.willfp.eco.core.gui;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.gui.menu.MenuBuilder;
|
||||
import com.willfp.eco.core.gui.slot.SlotBuilder;
|
||||
import com.willfp.eco.core.gui.slot.functional.SlotProvider;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Internal component used by {@link com.willfp.eco.core.gui.menu.Menu#builder(int)}
|
||||
* and {@link com.willfp.eco.core.gui.slot.Slot#builder(ItemStack)}.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
@Eco.HandlerComponent
|
||||
public interface GUIFactory {
|
||||
/**
|
||||
* Create slot builder.
|
||||
*
|
||||
* @param provider The provider.
|
||||
* @return The builder.
|
||||
*/
|
||||
SlotBuilder createSlotBuilder(@NotNull SlotProvider provider);
|
||||
|
||||
/**
|
||||
* Create menu builder.
|
||||
*
|
||||
* @param rows The amount of rows.
|
||||
* @return The builder.
|
||||
*/
|
||||
MenuBuilder createMenuBuilder(int rows);
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.willfp.eco.core.gui.menu;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.gui.page.Page;
|
||||
import com.willfp.eco.core.gui.slot.Slot;
|
||||
import com.willfp.eco.util.NamespacedKeyUtils;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
@@ -11,7 +13,10 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* GUI version of {@link Inventory}.
|
||||
@@ -27,7 +32,19 @@ public interface Menu {
|
||||
int getRows();
|
||||
|
||||
/**
|
||||
* Get slot at given row and column.
|
||||
* Get the amount of columns.
|
||||
*
|
||||
* @return The amount of columns.
|
||||
*/
|
||||
default int getColumns() {
|
||||
return 9;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a static slot at a given row and column.
|
||||
* <p>
|
||||
* If the slot at the location is reactive, this will return
|
||||
* an empty slot.
|
||||
*
|
||||
* @param row The row.
|
||||
* @param column The column.
|
||||
@@ -36,6 +53,42 @@ public interface Menu {
|
||||
Slot getSlot(int row,
|
||||
int column);
|
||||
|
||||
/**
|
||||
* Get a slot at a given row and column.
|
||||
* <p>
|
||||
* Defaults to static slot if no reactive slot exists.
|
||||
*
|
||||
* @param row The row.
|
||||
* @param column The column.
|
||||
* @param player The player
|
||||
* @param menu The menu.
|
||||
* @return The slot.
|
||||
* @deprecated Menu shouldn't be a parameter.
|
||||
*/
|
||||
@Deprecated(since = "6.46.0", forRemoval = true)
|
||||
default Slot getSlot(final int row,
|
||||
final int column,
|
||||
@NotNull final Player player,
|
||||
@NotNull final Menu menu) {
|
||||
return this.getSlot(row, column, player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a slot at a given row and column.
|
||||
* <p>
|
||||
* Defaults to static slot if no reactive slot exists.
|
||||
*
|
||||
* @param row The row.
|
||||
* @param column The column.
|
||||
* @param player The player
|
||||
* @return The slot.
|
||||
*/
|
||||
default Slot getSlot(final int row,
|
||||
final int column,
|
||||
@NotNull final Player player) {
|
||||
return this.getSlot(row, column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the menu title.
|
||||
*
|
||||
@@ -59,6 +112,134 @@ public interface Menu {
|
||||
*/
|
||||
List<ItemStack> getCaptiveItems(@NotNull Player player);
|
||||
|
||||
/**
|
||||
* Get a captive item at a specific position.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param row The row.
|
||||
* @param column The column.
|
||||
* @return The captive item.
|
||||
*/
|
||||
@Nullable
|
||||
default ItemStack getCaptiveItem(@NotNull final Player player,
|
||||
final int row,
|
||||
final int column) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set state for a player.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param key The key.
|
||||
* @param value The state.
|
||||
*/
|
||||
default void setState(@NotNull Player player,
|
||||
@NotNull String key,
|
||||
@Nullable Object value) {
|
||||
// Blank method for backwards compatibility.
|
||||
}
|
||||
|
||||
/**
|
||||
* Add state for a player.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param key The key.
|
||||
* @param value The state.
|
||||
* @deprecated Poorly named, use setState instead.
|
||||
*/
|
||||
@Deprecated(since = "6.44.0", forRemoval = true)
|
||||
default void addState(@NotNull Player player,
|
||||
@NotNull String key,
|
||||
@Nullable Object value) {
|
||||
this.setState(player, key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove state for a player.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param key The key.
|
||||
*/
|
||||
void removeState(@NotNull Player player,
|
||||
@NotNull String key);
|
||||
|
||||
/**
|
||||
* Clear state for a player.
|
||||
*
|
||||
* @param player The player.
|
||||
*/
|
||||
void clearState(@NotNull Player player);
|
||||
|
||||
|
||||
/**
|
||||
* Get state for a player.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param key The key.
|
||||
* @param <T> The type of state.
|
||||
* @return The value.
|
||||
*/
|
||||
@Nullable <T> T getState(@NotNull Player player,
|
||||
@NotNull String key);
|
||||
|
||||
/**
|
||||
* Get state for a player.
|
||||
*
|
||||
* @param player The player.
|
||||
* @return The state.
|
||||
*/
|
||||
Map<String, Object> getState(@NotNull Player player);
|
||||
|
||||
/**
|
||||
* Re-render the menu for a player.
|
||||
*
|
||||
* @param player The player.
|
||||
*/
|
||||
void refresh(@NotNull Player player);
|
||||
|
||||
/**
|
||||
* If the menu allows changing the held item.
|
||||
*
|
||||
* @return If allowed.
|
||||
*/
|
||||
default boolean allowsChangingHeldItem() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call a menu event.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param menuEvent The event.
|
||||
*/
|
||||
default void callEvent(@NotNull final Player player,
|
||||
@NotNull final MenuEvent menuEvent) {
|
||||
// Override when needed.
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current page a player is on.
|
||||
*
|
||||
* @param player The player.
|
||||
* @return The page.
|
||||
*/
|
||||
default int getPage(@NotNull final Player player) {
|
||||
Integer pageState = this.getState(player, Page.PAGE_KEY);
|
||||
return Objects.requireNonNullElse(pageState, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the max page for a player.
|
||||
*
|
||||
* @param player The player.
|
||||
* @return The page.
|
||||
*/
|
||||
default int getMaxPage(@NotNull final Player player) {
|
||||
Integer pageState = this.getState(player, Page.MAX_PAGE_KEY);
|
||||
return Objects.requireNonNullElse(pageState, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write data.
|
||||
*
|
||||
@@ -68,11 +249,15 @@ public interface Menu {
|
||||
* @param value The value.
|
||||
* @param <T> The type.
|
||||
* @param <Z> The type.
|
||||
* @deprecated Use addState instead.
|
||||
*/
|
||||
<T, Z> void writeData(@NotNull Player player,
|
||||
@NotNull NamespacedKey key,
|
||||
@NotNull PersistentDataType<T, Z> type,
|
||||
@NotNull Z value);
|
||||
@Deprecated(since = "6.35.0", forRemoval = true)
|
||||
default <T, Z> void writeData(@NotNull final Player player,
|
||||
@NotNull final NamespacedKey key,
|
||||
@NotNull final PersistentDataType<T, Z> type,
|
||||
@NotNull final Z value) {
|
||||
this.setState(player, key.toString(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read data.
|
||||
@@ -83,25 +268,29 @@ public interface Menu {
|
||||
* @param <T> The type.
|
||||
* @param <Z> The type.
|
||||
* @return The data.
|
||||
* @deprecated Use getState instead.
|
||||
*/
|
||||
@Nullable <T, Z> T readData(@NotNull Player player,
|
||||
@NotNull NamespacedKey key,
|
||||
@NotNull PersistentDataType<T, Z> type);
|
||||
@Deprecated(since = "6.35.0", forRemoval = true)
|
||||
default @Nullable <T, Z> T readData(@NotNull final Player player,
|
||||
@NotNull final NamespacedKey key,
|
||||
@NotNull final PersistentDataType<T, Z> type) {
|
||||
return this.getState(player, key.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all data keys for a player.
|
||||
*
|
||||
* @param player The player.
|
||||
* @return The keys.
|
||||
* @deprecated Use getState instead.
|
||||
*/
|
||||
Set<NamespacedKey> getKeys(@NotNull Player player);
|
||||
|
||||
/**
|
||||
* Re-render the menu for a player.
|
||||
*
|
||||
* @param player The player.
|
||||
*/
|
||||
void refresh(@NotNull Player player);
|
||||
@Deprecated(since = "6.35.0", forRemoval = true)
|
||||
default Set<NamespacedKey> getKeys(@NotNull final Player player) {
|
||||
return this.getState(player).keySet().stream()
|
||||
.map(NamespacedKeyUtils::fromStringOrNull)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a builder with a given amount of rows.
|
||||
@@ -110,6 +299,19 @@ public interface Menu {
|
||||
* @return The builder.
|
||||
*/
|
||||
static MenuBuilder builder(final int rows) {
|
||||
return Eco.getHandler().getGUIFactory().createMenuBuilder(rows);
|
||||
return Eco.get().createMenuBuilder(
|
||||
rows,
|
||||
MenuType.NORMAL
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a builder with a given type.
|
||||
*
|
||||
* @param type The menu type.
|
||||
* @return The builder.
|
||||
*/
|
||||
static MenuBuilder builder(@NotNull final MenuType type) {
|
||||
return Eco.get().createMenuBuilder(type.getDefaultRows(), type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,22 @@
|
||||
package com.willfp.eco.core.gui.menu;
|
||||
|
||||
import com.willfp.eco.core.gui.GUIComponent;
|
||||
import com.willfp.eco.core.gui.page.Page;
|
||||
import com.willfp.eco.core.gui.page.PageBuilder;
|
||||
import com.willfp.eco.core.gui.slot.FillerMask;
|
||||
import com.willfp.eco.core.gui.slot.Slot;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Builder to create menus.
|
||||
*/
|
||||
public interface MenuBuilder {
|
||||
public interface MenuBuilder extends PageBuilder {
|
||||
/**
|
||||
* Set the menu title.
|
||||
*
|
||||
@@ -19,6 +25,15 @@ public interface MenuBuilder {
|
||||
*/
|
||||
MenuBuilder setTitle(@NotNull String title);
|
||||
|
||||
/**
|
||||
* Get the menu title.
|
||||
*
|
||||
* @return The builder.
|
||||
*/
|
||||
default String getTitle() {
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a slot.
|
||||
*
|
||||
@@ -27,9 +42,44 @@ public interface MenuBuilder {
|
||||
* @param slot The slot.
|
||||
* @return The builder.
|
||||
*/
|
||||
MenuBuilder setSlot(int row,
|
||||
int column,
|
||||
@NotNull Slot slot);
|
||||
@Override
|
||||
default MenuBuilder setSlot(final int row,
|
||||
final int column,
|
||||
@NotNull final Slot slot) {
|
||||
return this.addComponent(row, column, slot);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a component.
|
||||
*
|
||||
* @param layer The layer.
|
||||
* @param row The row of the top left corner.
|
||||
* @param column The column of the top left corner.
|
||||
* @param component The component.
|
||||
* @return The builder.
|
||||
*/
|
||||
@Override
|
||||
MenuBuilder addComponent(@NotNull MenuLayer layer,
|
||||
int row,
|
||||
int column,
|
||||
@NotNull GUIComponent component);
|
||||
|
||||
|
||||
/**
|
||||
* Add a component.
|
||||
*
|
||||
* @param row The row of the top left corner.
|
||||
* @param column The column of the top left corner.
|
||||
* @param component The component.
|
||||
* @return The builder.
|
||||
*/
|
||||
@Override
|
||||
default MenuBuilder addComponent(final int row,
|
||||
final int column,
|
||||
@NotNull final GUIComponent component) {
|
||||
return this.addComponent(MenuLayer.MIDDLE, row, column, component);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run function to modify the builder.
|
||||
@@ -45,27 +95,116 @@ public interface MenuBuilder {
|
||||
* @param mask The mask.
|
||||
* @return The builder.
|
||||
*/
|
||||
MenuBuilder setMask(@NotNull FillerMask mask);
|
||||
@Override
|
||||
default MenuBuilder setMask(@NotNull final FillerMask mask) {
|
||||
return this.addComponent(MenuLayer.BACKGROUND, 1, 1, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the menu close handler.
|
||||
* Add a page.
|
||||
*
|
||||
* @param page The page.
|
||||
* @return The builder.
|
||||
*/
|
||||
default MenuBuilder addPage(@NotNull final Page page) {
|
||||
return this.addComponent(MenuLayer.UPPER, 1, 1, page);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a page.
|
||||
*
|
||||
* @param pageNumber The page number.
|
||||
* @param builder The page builder.
|
||||
* @return The builder.
|
||||
*/
|
||||
default MenuBuilder addPage(final int pageNumber,
|
||||
@NotNull final PageBuilder builder) {
|
||||
return this.addPage(new Page(pageNumber, ((MenuBuilder) builder).build()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the max pages.
|
||||
*
|
||||
* @param pages The max pages.
|
||||
* @return The builder.
|
||||
*/
|
||||
default MenuBuilder maxPages(final int pages) {
|
||||
return this.maxPages(player -> pages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the max pages dynamically for a player.
|
||||
*
|
||||
* @param pages The max pages.
|
||||
* @return The builder.
|
||||
*/
|
||||
default MenuBuilder maxPages(@NotNull final Function<Player, Integer> pages) {
|
||||
return this.onRender((player, menu) -> menu.setState(player, Page.MAX_PAGE_KEY, pages.apply(player)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a menu close handler.
|
||||
*
|
||||
* @param action The handler.
|
||||
* @return The builder.
|
||||
*/
|
||||
default MenuBuilder onClose(@NotNull Consumer<InventoryCloseEvent> action) {
|
||||
onClose((event, menu) -> action.accept(event));
|
||||
return this;
|
||||
default MenuBuilder onClose(@NotNull final Consumer<InventoryCloseEvent> action) {
|
||||
return this.onClose((event, menu) -> action.accept(event));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the menu close handler.
|
||||
* Add a menu close handler.
|
||||
*
|
||||
* @param action The handler.
|
||||
* @return The builder.
|
||||
*/
|
||||
MenuBuilder onClose(@NotNull CloseHandler action);
|
||||
|
||||
/**
|
||||
* Add a menu open handler.
|
||||
*
|
||||
* @param action The handler.
|
||||
* @return The builder.
|
||||
*/
|
||||
MenuBuilder onOpen(@NotNull OpenHandler action);
|
||||
|
||||
/**
|
||||
* Add an action to run on render.
|
||||
*
|
||||
* @param action The action.
|
||||
* @return The builder.
|
||||
*/
|
||||
MenuBuilder onRender(@NotNull BiConsumer<Player, Menu> action);
|
||||
|
||||
/**
|
||||
* Add an action to run on an event.
|
||||
*
|
||||
* @param action The action.
|
||||
* @return The builder.
|
||||
*/
|
||||
default MenuBuilder onEvent(@NotNull final MenuEventHandler<?> action) {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow the player to change their held item.
|
||||
*
|
||||
* @return The builder.
|
||||
*/
|
||||
default MenuBuilder allowChangingHeldItem() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an action to run on build.
|
||||
*
|
||||
* @param action The action.
|
||||
* @return The builder.
|
||||
*/
|
||||
default MenuBuilder onBuild(@NotNull Consumer<Menu> action) {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the menu.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.willfp.eco.core.gui.menu;
|
||||
|
||||
/**
|
||||
* Represents an event sent to a menu.
|
||||
*/
|
||||
public interface MenuEvent {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.willfp.eco.core.gui.menu;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Handles menu events.
|
||||
*/
|
||||
public abstract class MenuEventHandler<T extends MenuEvent> {
|
||||
/**
|
||||
* The class of the event.
|
||||
*/
|
||||
private final Class<T> eventClass;
|
||||
|
||||
/**
|
||||
* Create a new menu event handler.
|
||||
*
|
||||
* @param eventClass The class of event to handle.
|
||||
*/
|
||||
protected MenuEventHandler(@NotNull final Class<T> eventClass) {
|
||||
this.eventClass = eventClass;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs this operation on the given arguments.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param menu The menu.
|
||||
* @param event The event.
|
||||
*/
|
||||
public abstract void handle(@NotNull Player player,
|
||||
@NotNull Menu menu,
|
||||
@NotNull T event);
|
||||
|
||||
/**
|
||||
* Get if this handler can handle a certain event.
|
||||
*
|
||||
* @param menuEvent The event
|
||||
* @return If the event can be handled.
|
||||
*/
|
||||
public boolean canHandleEvent(@NotNull final MenuEvent menuEvent) {
|
||||
return eventClass.isAssignableFrom(menuEvent.getClass());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.willfp.eco.core.gui.menu;
|
||||
|
||||
/**
|
||||
* Different layers of the menu.
|
||||
*/
|
||||
public enum MenuLayer {
|
||||
/**
|
||||
* Right at the back.
|
||||
*/
|
||||
BACKGROUND,
|
||||
|
||||
/**
|
||||
* Second from the back.
|
||||
*/
|
||||
LOWER,
|
||||
|
||||
/**
|
||||
* In the middle (default).
|
||||
*/
|
||||
MIDDLE,
|
||||
|
||||
/**
|
||||
* Near the top.
|
||||
*/
|
||||
UPPER,
|
||||
|
||||
/**
|
||||
* At the absolute top.
|
||||
*/
|
||||
TOP
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.willfp.eco.core.gui.menu;
|
||||
|
||||
/**
|
||||
* The type of menu.
|
||||
*/
|
||||
public enum MenuType {
|
||||
/**
|
||||
* Normal menu (1x9, 2x9, 3x9, etc).
|
||||
*/
|
||||
NORMAL(9, 6),
|
||||
|
||||
/**
|
||||
* Dispenser menu (3x3).
|
||||
*/
|
||||
DISPENSER(3, 3);
|
||||
|
||||
/**
|
||||
* The amount of columns.
|
||||
*/
|
||||
private final int columns;
|
||||
|
||||
/**
|
||||
* The default amount of rows.
|
||||
*/
|
||||
private final int defaultRows;
|
||||
|
||||
/**
|
||||
* Create a new menu type.
|
||||
*
|
||||
* @param columns The number of columns.
|
||||
* @param defaultRows The default number of rows.
|
||||
*/
|
||||
MenuType(final int columns,
|
||||
final int defaultRows) {
|
||||
this.columns = columns;
|
||||
this.defaultRows = defaultRows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the amount of columns.
|
||||
*
|
||||
* @return The columns.
|
||||
*/
|
||||
public int getColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default amount of rows.
|
||||
*
|
||||
* @return The default amount of rows.
|
||||
*/
|
||||
public int getDefaultRows() {
|
||||
return defaultRows;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.willfp.eco.core.gui.menu;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Interface to run on menu open.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface OpenHandler {
|
||||
/**
|
||||
* Performs this operation on the given arguments.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param menu The menu.
|
||||
*/
|
||||
void handle(@NotNull Player player,
|
||||
@NotNull Menu menu);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.willfp.eco.core.gui.menu.events;
|
||||
|
||||
import com.willfp.eco.core.gui.menu.MenuEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Represents a captive item change.
|
||||
*
|
||||
* @param row The row.
|
||||
* @param column The column.
|
||||
* @param before The previous item in the slot.
|
||||
* @param after The new item in the slot.
|
||||
*/
|
||||
public record CaptiveItemChangeEvent(
|
||||
int row,
|
||||
int column,
|
||||
@Nullable ItemStack before,
|
||||
@Nullable ItemStack after
|
||||
) implements MenuEvent {
|
||||
|
||||
}
|
||||
115
eco-api/src/main/java/com/willfp/eco/core/gui/page/Page.java
Normal file
115
eco-api/src/main/java/com/willfp/eco/core/gui/page/Page.java
Normal file
@@ -0,0 +1,115 @@
|
||||
package com.willfp.eco.core.gui.page;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.gui.GUIComponent;
|
||||
import com.willfp.eco.core.gui.menu.Menu;
|
||||
import com.willfp.eco.core.gui.menu.MenuBuilder;
|
||||
import com.willfp.eco.core.gui.slot.Slot;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* A page is a component representing another menu.
|
||||
* This allows full component support in pagination.
|
||||
*/
|
||||
public final class Page implements GUIComponent {
|
||||
/**
|
||||
* The Menu state key for the current page.
|
||||
*/
|
||||
public static final String PAGE_KEY = "page";
|
||||
|
||||
/**
|
||||
* The Menu state key for the amount of pages.
|
||||
*/
|
||||
public static final String MAX_PAGE_KEY = "max_page";
|
||||
|
||||
/**
|
||||
* The page number.
|
||||
*/
|
||||
private final int pageNumber;
|
||||
|
||||
/**
|
||||
* The base menu.
|
||||
*/
|
||||
private final Menu page;
|
||||
|
||||
/**
|
||||
* The delegate menu.
|
||||
*/
|
||||
private Menu delegate = null;
|
||||
|
||||
/**
|
||||
* The rows for the page to have.
|
||||
*/
|
||||
private int rows = 6;
|
||||
|
||||
/**
|
||||
* The columns for the page to have.
|
||||
*/
|
||||
private int columns = 9;
|
||||
|
||||
/**
|
||||
* Create a new page.
|
||||
*
|
||||
* @param pageNumber The page number.
|
||||
* @param page The base menu.
|
||||
*/
|
||||
public Page(final int pageNumber,
|
||||
@NotNull final Menu page) {
|
||||
this.pageNumber = pageNumber;
|
||||
this.page = page;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current page number.
|
||||
*
|
||||
* @return The page number.
|
||||
*/
|
||||
public int getPageNumber() {
|
||||
return this.pageNumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Slot getSlotAt(final int row,
|
||||
final int column,
|
||||
@NotNull final Player player,
|
||||
@NotNull final Menu menu) {
|
||||
if (menu.getPage(player) != pageNumber) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (delegate == null) {
|
||||
delegate = Eco.get().blendMenuState(page, menu);
|
||||
}
|
||||
|
||||
return page.getSlot(row, column, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(final int maxRows,
|
||||
final int maxColumns) {
|
||||
this.rows = maxRows;
|
||||
this.columns = maxColumns;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRows() {
|
||||
return rows;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new page builder.
|
||||
*
|
||||
* @param context The context to create the page for.
|
||||
* @return The page builder.
|
||||
*/
|
||||
public static PageBuilder builder(@NotNull final MenuBuilder context) {
|
||||
return Menu.builder(context.getRows());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package com.willfp.eco.core.gui.page;
|
||||
|
||||
import com.willfp.eco.core.gui.GUIComponent;
|
||||
import com.willfp.eco.core.gui.menu.Menu;
|
||||
import com.willfp.eco.core.gui.menu.MenuLayer;
|
||||
import com.willfp.eco.core.gui.slot.FillerMask;
|
||||
import com.willfp.eco.core.gui.slot.Slot;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
/**
|
||||
* Builder to create pages.
|
||||
*/
|
||||
public interface PageBuilder {
|
||||
/**
|
||||
* Get the amount of rows.
|
||||
*
|
||||
* @return The amount of rows.
|
||||
*/
|
||||
int getRows();
|
||||
|
||||
/**
|
||||
* Get the amount of columns.
|
||||
*
|
||||
* @return The amount of columns.
|
||||
*/
|
||||
int getColumns();
|
||||
|
||||
/**
|
||||
* Set a slot.
|
||||
*
|
||||
* @param row The row.
|
||||
* @param column The column.
|
||||
* @param slot The slot.
|
||||
* @return The builder.
|
||||
*/
|
||||
default PageBuilder setSlot(final int row,
|
||||
final int column,
|
||||
@NotNull final Slot slot) {
|
||||
return this.addComponent(row, column, slot);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a component.
|
||||
*
|
||||
* @param layer The layer.
|
||||
* @param row The row of the top left corner.
|
||||
* @param column The column of the top left corner.
|
||||
* @param component The component.
|
||||
* @return The builder.
|
||||
*/
|
||||
PageBuilder addComponent(@NotNull MenuLayer layer,
|
||||
int row,
|
||||
int column,
|
||||
@NotNull GUIComponent component);
|
||||
|
||||
|
||||
/**
|
||||
* Add a component.
|
||||
*
|
||||
* @param row The row of the top left corner.
|
||||
* @param column The column of the top left corner.
|
||||
* @param component The component.
|
||||
* @return The builder.
|
||||
*/
|
||||
default PageBuilder addComponent(final int row,
|
||||
final int column,
|
||||
@NotNull final GUIComponent component) {
|
||||
return this.addComponent(MenuLayer.MIDDLE, row, column, component);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the menu mask.
|
||||
*
|
||||
* @param mask The mask.
|
||||
* @return The builder.
|
||||
*/
|
||||
default PageBuilder setMask(@NotNull final FillerMask mask) {
|
||||
return this.addComponent(MenuLayer.BACKGROUND, 1, 1, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the action to run on render.
|
||||
*
|
||||
* @param action The action.
|
||||
* @return The builder.
|
||||
*/
|
||||
PageBuilder onRender(@NotNull BiConsumer<Player, Menu> action);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.willfp.eco.core.gui.page;
|
||||
|
||||
import com.willfp.eco.core.gui.menu.MenuEvent;
|
||||
|
||||
/**
|
||||
* Represents a page change.
|
||||
*
|
||||
* @param newPage The new page.
|
||||
* @param oldPage The old page.
|
||||
*/
|
||||
public record PageChangeEvent(
|
||||
int newPage,
|
||||
int oldPage
|
||||
) implements MenuEvent {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package com.willfp.eco.core.gui.page;
|
||||
|
||||
import com.willfp.eco.core.gui.GUIComponent;
|
||||
import com.willfp.eco.core.gui.menu.Menu;
|
||||
import com.willfp.eco.core.gui.slot.Slot;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* A slot loaded in from config.
|
||||
*/
|
||||
public final class PageChanger implements GUIComponent {
|
||||
/**
|
||||
* The slot to be shown.
|
||||
*/
|
||||
private final Slot slot;
|
||||
|
||||
/**
|
||||
* The direction to turn the page.
|
||||
*/
|
||||
private final Direction direction;
|
||||
|
||||
/**
|
||||
* Create a new page change slot.
|
||||
*
|
||||
* @param itemStack The ItemStack.
|
||||
* @param direction The direction.
|
||||
*/
|
||||
public PageChanger(@NotNull final ItemStack itemStack,
|
||||
@NotNull final Direction direction) {
|
||||
this.direction = direction;
|
||||
|
||||
slot = Slot.builder(itemStack)
|
||||
.onLeftClick((event, slot, menu) -> {
|
||||
Player player = (Player) event.getWhoClicked();
|
||||
int page = menu.getPage(player);
|
||||
int newPage = Math.max(
|
||||
1,
|
||||
Math.min(
|
||||
page + direction.getChange(),
|
||||
menu.getMaxPage(player)
|
||||
)
|
||||
);
|
||||
|
||||
if (newPage == page) {
|
||||
return;
|
||||
}
|
||||
|
||||
menu.setState(player, Page.PAGE_KEY, newPage);
|
||||
menu.callEvent(player, new PageChangeEvent(
|
||||
newPage,
|
||||
page
|
||||
));
|
||||
})
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRows() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumns() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Slot getSlotAt(final int row,
|
||||
final int column,
|
||||
@NotNull final Player player,
|
||||
@NotNull final Menu menu) {
|
||||
int page = menu.getPage(player);
|
||||
int maxPage = menu.getMaxPage(player);
|
||||
|
||||
if (page <= 1 && this.direction == Direction.BACKWARDS) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (page >= maxPage && this.direction == Direction.FORWARDS) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* The direction to change the page.
|
||||
*/
|
||||
public enum Direction {
|
||||
/**
|
||||
* Increment the page by 1.
|
||||
*/
|
||||
FORWARDS(1),
|
||||
|
||||
/**
|
||||
* Decrement the page by 1.
|
||||
*/
|
||||
BACKWARDS(-1);
|
||||
|
||||
/**
|
||||
* The amount of pages to change by.
|
||||
*/
|
||||
private final int change;
|
||||
|
||||
/**
|
||||
* Create a new direction.
|
||||
*
|
||||
* @param change The amount of pages to change by.
|
||||
*/
|
||||
Direction(final int change) {
|
||||
this.change = change;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the amount of pages to change by.
|
||||
*
|
||||
* @return The change.
|
||||
*/
|
||||
public int getChange() {
|
||||
return change;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
package com.willfp.eco.core.gui.slot;
|
||||
|
||||
import com.willfp.eco.core.config.interfaces.Config;
|
||||
import com.willfp.eco.core.fast.FastItemStack;
|
||||
import com.willfp.eco.core.gui.slot.functional.SlotHandler;
|
||||
import com.willfp.eco.core.items.Items;
|
||||
import com.willfp.eco.util.StringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A slot loaded in from config.
|
||||
*/
|
||||
public class ConfigSlot extends CustomSlot {
|
||||
/**
|
||||
* The config of the slot.
|
||||
*/
|
||||
private final Config config;
|
||||
|
||||
/**
|
||||
* Cached handlers, for performance.
|
||||
*/
|
||||
private final Map<String, List<CommandToDispatch>> handlers = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Create a new config slot.
|
||||
*
|
||||
* @param config The config.
|
||||
*/
|
||||
public ConfigSlot(@NotNull final Config config) {
|
||||
this.config = config;
|
||||
|
||||
ItemStack item = Items.lookup(config.getString("item")).getItem();
|
||||
|
||||
SlotBuilder builder = Slot.builder((player, menu) -> {
|
||||
if (!config.has("lore")) {
|
||||
return item;
|
||||
} else {
|
||||
FastItemStack fast = FastItemStack.wrap(item.clone());
|
||||
List<String> newLore = new ArrayList<>(fast.getLore());
|
||||
newLore.addAll(
|
||||
StringUtils.formatList(
|
||||
config.getStrings("lore"),
|
||||
player,
|
||||
StringUtils.FormatOption.WITH_PLACEHOLDERS
|
||||
)
|
||||
);
|
||||
fast.setLore(newLore);
|
||||
return fast.unwrap();
|
||||
}
|
||||
});
|
||||
|
||||
for (ClickType clickType : ClickType.values()) {
|
||||
builder.onClick(
|
||||
clickType,
|
||||
dispatchCommandHandler(
|
||||
clickType.name().toLowerCase(Locale.ROOT)
|
||||
.replace("_", "-")
|
||||
+ "-click"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
init(builder.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a slot handler for dispatching commands.
|
||||
*
|
||||
* @param configKey The config key.
|
||||
* @return The handler.
|
||||
*/
|
||||
private SlotHandler dispatchCommandHandler(@NotNull final String configKey) {
|
||||
if (!handlers.containsKey(configKey)) {
|
||||
List<CommandToDispatch> commands = new ArrayList<>();
|
||||
|
||||
for (String command : config.getStrings(configKey)) {
|
||||
if (command.startsWith("console:")) {
|
||||
commands.add(new CommandToDispatch(
|
||||
StringUtils.removePrefix("console:", command),
|
||||
true
|
||||
));
|
||||
} else {
|
||||
commands.add(new CommandToDispatch(
|
||||
command,
|
||||
false
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
handlers.put(configKey, commands);
|
||||
}
|
||||
|
||||
List<CommandToDispatch> toDispatch = handlers.get(configKey);
|
||||
|
||||
return (event, slot, menu) -> {
|
||||
Player player = (Player) event.getWhoClicked();
|
||||
|
||||
for (CommandToDispatch dispatch : toDispatch) {
|
||||
dispatch.dispatch(player);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Signifies a command to dispatch.
|
||||
*
|
||||
* @param command The command.
|
||||
* @param console If the command should be run as console.
|
||||
*/
|
||||
private record CommandToDispatch(
|
||||
@NotNull String command,
|
||||
boolean console
|
||||
) {
|
||||
/**
|
||||
* Dispatch command.
|
||||
*
|
||||
* @param player The player.
|
||||
*/
|
||||
void dispatch(@NotNull final Player player) {
|
||||
if (console()) {
|
||||
Bukkit.dispatchCommand(
|
||||
Bukkit.getConsoleSender(),
|
||||
command().replace("%player%", player.getName())
|
||||
);
|
||||
} else {
|
||||
Bukkit.dispatchCommand(
|
||||
player,
|
||||
command().replace("%player%", player.getName())
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package com.willfp.eco.core.gui.slot;
|
||||
|
||||
import com.willfp.eco.core.gui.menu.Menu;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Base class for custom slot implementations.
|
||||
*/
|
||||
public abstract class CustomSlot implements Slot {
|
||||
/**
|
||||
* The internal slot to delegate to.
|
||||
*/
|
||||
private Slot delegate = null;
|
||||
|
||||
/**
|
||||
* Create a new custom slot.
|
||||
*/
|
||||
protected CustomSlot() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the slot with the delegate.
|
||||
*
|
||||
* @param slot The slot to delegate to.
|
||||
*/
|
||||
protected void init(@NotNull final Slot slot) {
|
||||
this.delegate = slot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final @NotNull ItemStack getItemStack(@NotNull final Player player) {
|
||||
if (delegate == null) {
|
||||
throw new IllegalStateException("Custom Slot was not initialized!");
|
||||
}
|
||||
|
||||
return delegate.getItemStack(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isCaptive(@NotNull final Player player,
|
||||
@NotNull final Menu menu) {
|
||||
if (delegate == null) {
|
||||
throw new IllegalStateException("Custom Slot was not initialized!");
|
||||
}
|
||||
|
||||
return delegate.isCaptive(player, menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isAllowedCaptive(@NotNull final Player player,
|
||||
@NotNull final Menu menu,
|
||||
@Nullable final ItemStack itemStack) {
|
||||
if (delegate == null) {
|
||||
throw new IllegalStateException("Custom Slot was not initialized!");
|
||||
}
|
||||
|
||||
return delegate.isAllowedCaptive(player, menu, itemStack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isCaptiveFromEmpty() {
|
||||
if (delegate == null) {
|
||||
throw new IllegalStateException("Custom Slot was not initialized!");
|
||||
}
|
||||
|
||||
return delegate.isCaptiveFromEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final @NotNull Slot getActionableSlot(@NotNull final Player player,
|
||||
@NotNull final Menu menu) {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getRows() {
|
||||
return Slot.super.getRows();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getColumns() {
|
||||
return Slot.super.getColumns();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Slot getSlotAt(int row, int column) {
|
||||
return Slot.super.getSlotAt(row, column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the delegate slot.
|
||||
* <p>
|
||||
* This is not required to add the slot to a menu, but is instead used internally.
|
||||
*
|
||||
* @return The slot.
|
||||
* @deprecated Replaced with {@link Slot#getActionableSlot(Player, Menu)}
|
||||
*/
|
||||
@Deprecated(since = "6.43.0", forRemoval = true)
|
||||
public Slot getDelegate() {
|
||||
return this.delegate;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.willfp.eco.core.gui.slot;
|
||||
|
||||
import com.willfp.eco.core.gui.GUIComponent;
|
||||
import com.willfp.eco.core.items.builder.ItemStackBuilder;
|
||||
import com.willfp.eco.core.recipe.parts.EmptyTestableItem;
|
||||
import com.willfp.eco.core.recipe.parts.MaterialTestableItem;
|
||||
@@ -7,6 +8,7 @@ import com.willfp.eco.util.ListUtils;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -26,12 +28,17 @@ import java.util.List;
|
||||
* "11111111"
|
||||
* );
|
||||
*/
|
||||
public class FillerMask {
|
||||
public class FillerMask implements GUIComponent {
|
||||
/**
|
||||
* Mask.
|
||||
*/
|
||||
private final List<List<Slot>> mask;
|
||||
|
||||
/**
|
||||
* Rows.
|
||||
*/
|
||||
private final int rows;
|
||||
|
||||
/**
|
||||
* Create a new filler mask.
|
||||
*
|
||||
@@ -71,7 +78,8 @@ public class FillerMask {
|
||||
throw new IllegalArgumentException("Items cannot be empty!");
|
||||
}
|
||||
|
||||
mask = ListUtils.create2DList(6, 9);
|
||||
rows = pattern.length;
|
||||
mask = ListUtils.create2DList(rows, 9);
|
||||
|
||||
for (int i = 0; i < items.items().length; i++) {
|
||||
ItemStack itemStack = new ItemStackBuilder(items.items()[i])
|
||||
@@ -82,9 +90,6 @@ public class FillerMask {
|
||||
|
||||
for (String patternRow : pattern) {
|
||||
int column = 0;
|
||||
if (patternRow.length() != 9) {
|
||||
throw new IllegalArgumentException("Invalid amount of columns in pattern!");
|
||||
}
|
||||
for (char c : patternRow.toCharArray()) {
|
||||
if (c == '0') {
|
||||
mask.get(row).set(column, null);
|
||||
@@ -107,4 +112,20 @@ public class FillerMask {
|
||||
public List<List<Slot>> getMask() {
|
||||
return this.mask;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRows() {
|
||||
return rows;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumns() {
|
||||
return 9;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Slot getSlotAt(final int row,
|
||||
final int column) {
|
||||
return mask.get(row - 1).get(column - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.willfp.eco.core.gui.slot;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -9,37 +8,16 @@ import org.jetbrains.annotations.NotNull;
|
||||
* <p>
|
||||
* Useful for backgrounds.
|
||||
*/
|
||||
public class FillerSlot implements Slot {
|
||||
/**
|
||||
* The ItemStack.
|
||||
*/
|
||||
private final ItemStack itemStack;
|
||||
|
||||
public class FillerSlot extends CustomSlot {
|
||||
/**
|
||||
* Create new filler slot.
|
||||
*
|
||||
* @param itemStack The ItemStack.
|
||||
*/
|
||||
public FillerSlot(@NotNull final ItemStack itemStack) {
|
||||
this.itemStack = itemStack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItemStack(@NotNull final Player player) {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCaptive() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ItemStack.
|
||||
*
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
public ItemStack getItemStack() {
|
||||
return this.itemStack;
|
||||
init(
|
||||
Slot.builder(itemStack)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import org.bukkit.Material;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -17,6 +18,15 @@ import java.util.List;
|
||||
* @param items The items.
|
||||
*/
|
||||
public record MaskItems(@NotNull TestableItem... items) {
|
||||
/**
|
||||
* Create mask items from materials.
|
||||
*
|
||||
* @param materials The materials.
|
||||
*/
|
||||
public MaskItems(@NotNull final Material... materials) {
|
||||
this(Arrays.stream(materials).map(MaterialTestableItem::new).toList().toArray(new TestableItem[0]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create MaskItems from a list of item names.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.willfp.eco.core.gui.slot;
|
||||
|
||||
import com.willfp.eco.core.gui.menu.Menu;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Base class for custom slot implementations.
|
||||
*/
|
||||
public abstract class ReactiveSlot implements Slot {
|
||||
/**
|
||||
* Create a new reactive slot.
|
||||
*/
|
||||
protected ReactiveSlot() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the actual slot to be shown.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param menu The menu.
|
||||
* @return The slot.
|
||||
*/
|
||||
@NotNull
|
||||
public abstract Slot getSlot(@NotNull final Player player,
|
||||
@NotNull final Menu menu);
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack getItemStack(@NotNull final Player player) {
|
||||
return new ItemStack(Material.AIR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isCaptive(@NotNull final Player player,
|
||||
@NotNull final Menu menu) {
|
||||
return getSlot(player, menu).isCaptive(player, menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isAllowedCaptive(@NotNull final Player player,
|
||||
@NotNull final Menu menu,
|
||||
@Nullable final ItemStack itemStack) {
|
||||
return getSlot(player, menu).isAllowedCaptive(player, menu, itemStack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final @NotNull Slot getActionableSlot(@NotNull final Player player,
|
||||
@NotNull final Menu menu) {
|
||||
return getSlot(player, menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getRows() {
|
||||
return Slot.super.getRows();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getColumns() {
|
||||
return Slot.super.getColumns();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Slot getSlotAt(int row, int column) {
|
||||
return Slot.super.getSlotAt(row, column);
|
||||
}
|
||||
}
|
||||
@@ -1,32 +1,112 @@
|
||||
package com.willfp.eco.core.gui.slot;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.gui.GUIComponent;
|
||||
import com.willfp.eco.core.gui.menu.Menu;
|
||||
import com.willfp.eco.core.gui.slot.functional.SlotProvider;
|
||||
import com.willfp.eco.core.items.TestableItem;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* A slot is an item in a GUI that can handle clicks.
|
||||
* <p>
|
||||
* While you can create custom Slot implementations directly from this class,
|
||||
* it's heavily encouraged to extend {@link CustomSlot}, which will abstract
|
||||
* internal functionality away.
|
||||
* <p>
|
||||
* A lot of methods here are marked as default as in 6.43.0 the GUI system
|
||||
* was overhauled, but to preserve backwards compatibility, the new methods
|
||||
* had to be marked default, and many old methods became deprecated.
|
||||
*/
|
||||
public interface Slot {
|
||||
public interface Slot extends GUIComponent {
|
||||
/**
|
||||
* Get the ItemStack that would be shown to a player.
|
||||
*
|
||||
* @param player The player.
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
@NotNull
|
||||
ItemStack getItemStack(@NotNull Player player);
|
||||
|
||||
/**
|
||||
* If the slot is captive. (Can items be placed in it).
|
||||
*
|
||||
* @param player The player.
|
||||
* @param menu The menu.
|
||||
* @return If captive.
|
||||
*/
|
||||
boolean isCaptive();
|
||||
default boolean isCaptive(@NotNull final Player player,
|
||||
@NotNull final Menu menu) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the slot allows a certain item to be placed in it.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param menu The menu.
|
||||
* @param itemStack The item; use null if the item is unknown.
|
||||
* @return If captive.
|
||||
*/
|
||||
default boolean isAllowedCaptive(@NotNull final Player player,
|
||||
@NotNull final Menu menu,
|
||||
@Nullable final ItemStack itemStack) {
|
||||
return this.isCaptive(player, menu);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the actionable slot to be shown.
|
||||
* <p>
|
||||
* This is mostly internal, if you want to implement custom slots you should
|
||||
* turn to {@link CustomSlot} or {@link ReactiveSlot}, which abstract this
|
||||
* behaviour away.
|
||||
* <p>
|
||||
* **Never** return {@code this} from this method. Always make sure that your
|
||||
* slots eventually delegate to a slot created by {@link Slot#builder()}.
|
||||
* <p>
|
||||
* {@code this} is returned by default for backwards-compatibility.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param menu The menu.
|
||||
* @return The slot.
|
||||
*/
|
||||
@NotNull
|
||||
default Slot getActionableSlot(@NotNull final Player player,
|
||||
@NotNull final Menu menu) {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the slot is captive from empty.
|
||||
* If true, a captive item will be returned even if the item is the same as the rendered item.
|
||||
*
|
||||
* @return If captive from empty.
|
||||
*/
|
||||
default boolean isCaptiveFromEmpty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
default int getRows() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
default int getColumns() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
default Slot getSlotAt(final int row,
|
||||
final int column) {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a builder for an ItemStack.
|
||||
@@ -34,7 +114,7 @@ public interface Slot {
|
||||
* @return The builder.
|
||||
*/
|
||||
static SlotBuilder builder() {
|
||||
return Eco.getHandler().getGUIFactory().createSlotBuilder((player, menu) -> new ItemStack(Material.AIR));
|
||||
return Eco.get().createSlotBuilder((player, menu) -> new ItemStack(Material.AIR));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,7 +124,17 @@ public interface Slot {
|
||||
* @return The builder.
|
||||
*/
|
||||
static SlotBuilder builder(@NotNull final ItemStack itemStack) {
|
||||
return Eco.getHandler().getGUIFactory().createSlotBuilder((player, menu) -> itemStack);
|
||||
return Eco.get().createSlotBuilder((player, menu) -> itemStack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a builder for a TestableItem.
|
||||
*
|
||||
* @param item The item.
|
||||
* @return The builder.
|
||||
*/
|
||||
static SlotBuilder builder(@NotNull final TestableItem item) {
|
||||
return Eco.get().createSlotBuilder((player, menu) -> item.getItem());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,9 +142,11 @@ public interface Slot {
|
||||
*
|
||||
* @param provider The provider.
|
||||
* @return The builder.
|
||||
* @deprecated This method was written incorrectly, should have been a Player + Menu function.
|
||||
*/
|
||||
@Deprecated(since = "6.45.0", forRemoval = true)
|
||||
static SlotBuilder builder(@NotNull final Function<Player, ItemStack> provider) {
|
||||
return Eco.getHandler().getGUIFactory().createSlotBuilder((player, menu) -> provider.apply(player));
|
||||
return Eco.get().createSlotBuilder((player, menu) -> provider.apply(player));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,6 +156,29 @@ public interface Slot {
|
||||
* @return The builder.
|
||||
*/
|
||||
static SlotBuilder builder(@NotNull final SlotProvider provider) {
|
||||
return Eco.getHandler().getGUIFactory().createSlotBuilder(provider);
|
||||
return Eco.get().createSlotBuilder(provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the slot is not captive for a player.
|
||||
*
|
||||
* @param player The player.
|
||||
* @return If not captive for the player.
|
||||
* @deprecated Captivity is now reactive, this method can produce incorrect results.
|
||||
*/
|
||||
@Deprecated(since = "6.43.0", forRemoval = true)
|
||||
default boolean isNotCaptiveFor(@NotNull Player player) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the slot is captive. (Can items be placed in it).
|
||||
*
|
||||
* @return If captive.
|
||||
* @deprecated Captivity is now reactive, this method can produce incorrect results.
|
||||
*/
|
||||
@Deprecated(since = "6.43.0", forRemoval = true)
|
||||
default boolean isCaptive() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,43 @@
|
||||
package com.willfp.eco.core.gui.slot;
|
||||
|
||||
import com.willfp.eco.core.gui.slot.functional.CaptiveFilter;
|
||||
import com.willfp.eco.core.gui.slot.functional.SlotHandler;
|
||||
import com.willfp.eco.core.gui.slot.functional.SlotModifier;
|
||||
import com.willfp.eco.core.gui.slot.functional.SlotUpdater;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Builder to create slots.
|
||||
*/
|
||||
public interface SlotBuilder {
|
||||
/**
|
||||
* Set click handler.
|
||||
*
|
||||
* @param type The click type.
|
||||
* @param handler The handler.
|
||||
* @return The builder.
|
||||
*/
|
||||
SlotBuilder onClick(@NotNull ClickType type,
|
||||
@NotNull SlotHandler handler);
|
||||
|
||||
/**
|
||||
* Set click handler.
|
||||
*
|
||||
* @param type The click type.
|
||||
* @param action The handler.
|
||||
* @return The builder.
|
||||
*/
|
||||
default SlotBuilder onClick(@NotNull final ClickType type,
|
||||
@NotNull final BiConsumer<InventoryClickEvent, Slot> action) {
|
||||
return onClick(type, (event, slot, menu) -> action.accept(event, slot));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set click handler.
|
||||
*
|
||||
@@ -28,7 +54,9 @@ public interface SlotBuilder {
|
||||
* @param handler The handler.
|
||||
* @return The builder.
|
||||
*/
|
||||
SlotBuilder onLeftClick(@NotNull SlotHandler handler);
|
||||
default SlotBuilder onLeftClick(@NotNull final SlotHandler handler) {
|
||||
return onClick(ClickType.LEFT, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set click handler.
|
||||
@@ -46,7 +74,9 @@ public interface SlotBuilder {
|
||||
* @param handler The handler.
|
||||
* @return The builder.
|
||||
*/
|
||||
SlotBuilder onRightClick(@NotNull SlotHandler handler);
|
||||
default SlotBuilder onRightClick(@NotNull final SlotHandler handler) {
|
||||
return onClick(ClickType.RIGHT, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set click handler.
|
||||
@@ -64,7 +94,9 @@ public interface SlotBuilder {
|
||||
* @param handler The handler.
|
||||
* @return The builder.
|
||||
*/
|
||||
SlotBuilder onShiftLeftClick(@NotNull SlotHandler handler);
|
||||
default SlotBuilder onShiftLeftClick(@NotNull final SlotHandler handler) {
|
||||
return onClick(ClickType.SHIFT_LEFT, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set click handler.
|
||||
@@ -82,7 +114,9 @@ public interface SlotBuilder {
|
||||
* @param handler The handler.
|
||||
* @return The builder.
|
||||
*/
|
||||
SlotBuilder onShiftRightClick(@NotNull SlotHandler handler);
|
||||
default SlotBuilder onShiftRightClick(@NotNull final SlotHandler handler) {
|
||||
return onClick(ClickType.SHIFT_RIGHT, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set click handler.
|
||||
@@ -100,21 +134,26 @@ public interface SlotBuilder {
|
||||
* @param handler The handler.
|
||||
* @return The builder.
|
||||
*/
|
||||
SlotBuilder onMiddleClick(@NotNull SlotHandler handler);
|
||||
default SlotBuilder onMiddleClick(@NotNull final SlotHandler handler) {
|
||||
return onClick(ClickType.MIDDLE, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify the ItemStack.
|
||||
* Prevent captive for players that match a predicate.
|
||||
*
|
||||
* @param modifier The modifier.
|
||||
* @param predicate The predicate. Returns true when the slot should not be captive.
|
||||
* @return The builder.
|
||||
* @deprecated Use {@link SlotBuilder#setUpdater(SlotUpdater)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default SlotBuilder setModifier(@NotNull SlotModifier modifier) {
|
||||
return setUpdater((player, menu, previous) -> {
|
||||
modifier.modify(player, menu, previous);
|
||||
return previous;
|
||||
});
|
||||
SlotBuilder notCaptiveFor(@NotNull final Predicate<Player> predicate);
|
||||
|
||||
/**
|
||||
* Set a whitelist for allowed captive items.
|
||||
*
|
||||
* @param filter The filter.
|
||||
* @return The builder.
|
||||
*/
|
||||
default SlotBuilder setCaptiveFilter(@NotNull final CaptiveFilter filter) {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,7 +169,17 @@ public interface SlotBuilder {
|
||||
*
|
||||
* @return The builder.
|
||||
*/
|
||||
SlotBuilder setCaptive();
|
||||
default SlotBuilder setCaptive() {
|
||||
return setCaptive(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set slot to be a captive slot.
|
||||
*
|
||||
* @param fromEmpty If an item with the same output as the rendered item counts as captive.
|
||||
* @return The builder.
|
||||
*/
|
||||
SlotBuilder setCaptive(boolean fromEmpty);
|
||||
|
||||
/**
|
||||
* Build the slot.
|
||||
@@ -138,4 +187,19 @@ public interface SlotBuilder {
|
||||
* @return The slot.
|
||||
*/
|
||||
Slot build();
|
||||
|
||||
/**
|
||||
* Modify the ItemStack.
|
||||
*
|
||||
* @param modifier The modifier.
|
||||
* @return The builder.
|
||||
* @deprecated Use {@link SlotBuilder#setUpdater(SlotUpdater)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default SlotBuilder setModifier(@NotNull SlotModifier modifier) {
|
||||
return setUpdater((player, menu, previous) -> {
|
||||
modifier.modify(player, menu, previous);
|
||||
return previous;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.willfp.eco.core.gui.slot.functional;
|
||||
|
||||
import com.willfp.eco.core.gui.menu.Menu;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Interface to test if a captive slot is allowed to contain an item given a player and a menu.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface CaptiveFilter {
|
||||
/**
|
||||
* Get if allowed.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param menu The menu.
|
||||
* @param itemStack The item.
|
||||
* @return If captive.
|
||||
*/
|
||||
boolean isAllowed(@NotNull Player player,
|
||||
@NotNull Menu menu,
|
||||
@Nullable ItemStack itemStack);
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import com.willfp.eco.core.gui.menu.Menu;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Interface to run on slot display.
|
||||
@@ -17,6 +18,7 @@ public interface SlotProvider {
|
||||
* @param menu The menu.
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
@Nullable
|
||||
ItemStack provide(@NotNull Player player,
|
||||
@NotNull Menu menu);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.willfp.eco.core.gui.menu.Menu;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Interface to run on slot update.
|
||||
@@ -18,6 +19,7 @@ public interface SlotUpdater {
|
||||
* @param previous The previous ItemStack.
|
||||
* @return The new ItemStack.
|
||||
*/
|
||||
@Nullable
|
||||
ItemStack update(@NotNull Player player,
|
||||
@NotNull Menu menu,
|
||||
@NotNull ItemStack previous);
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.willfp.eco.core.integrations.afk;
|
||||
|
||||
import com.willfp.eco.core.integrations.Integration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* AFK Integration.
|
||||
*/
|
||||
public interface AFKIntegration extends Integration {
|
||||
/**
|
||||
* Get if a player is afk.
|
||||
*
|
||||
* @param player The player.
|
||||
* @return If afk.
|
||||
*/
|
||||
boolean isAfk(@NotNull Player player);
|
||||
}
|
||||
@@ -13,14 +13,15 @@ public final class AFKManager {
|
||||
/**
|
||||
* A set of all registered integrations.
|
||||
*/
|
||||
private static final Set<AFKWrapper> REGISTERED = new HashSet<>();
|
||||
private static final Set<AFKIntegration> REGISTERED = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Register a new integration.
|
||||
*
|
||||
* @param integration The integration to register.
|
||||
*/
|
||||
public static void register(@NotNull final AFKWrapper integration) {
|
||||
public static void register(@NotNull final AFKIntegration integration) {
|
||||
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName()));
|
||||
REGISTERED.add(integration);
|
||||
}
|
||||
|
||||
@@ -31,8 +32,8 @@ public final class AFKManager {
|
||||
* @return If afk.
|
||||
*/
|
||||
public static boolean isAfk(@NotNull final Player player) {
|
||||
for (AFKWrapper afkWrapper : REGISTERED) {
|
||||
if (afkWrapper.isAfk(player)) {
|
||||
for (AFKIntegration integration : REGISTERED) {
|
||||
if (integration.isAfk(player)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,11 @@
|
||||
package com.willfp.eco.core.integrations.afk;
|
||||
|
||||
import com.willfp.eco.core.integrations.Integration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Wrapper class for afk integrations.
|
||||
*
|
||||
* @deprecated Use AFKIntegration instead.
|
||||
*/
|
||||
public interface AFKWrapper extends Integration {
|
||||
/**
|
||||
* Get if a player is afk.
|
||||
*
|
||||
* @param player The player.
|
||||
* @return If afk.
|
||||
*/
|
||||
boolean isAfk(@NotNull Player player);
|
||||
@Deprecated(since = "6.35.0", forRemoval = true)
|
||||
public interface AFKWrapper extends AFKIntegration {
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.willfp.eco.core.integrations.anticheat;
|
||||
|
||||
import com.willfp.eco.core.integrations.Integration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Wrapper class for anticheat integrations.
|
||||
*/
|
||||
public interface AnticheatIntegration extends Integration {
|
||||
/**
|
||||
* Exempt a player from checks.
|
||||
*
|
||||
* @param player The player to exempt.
|
||||
*/
|
||||
void exempt(@NotNull Player player);
|
||||
|
||||
/**
|
||||
* Unexempt a player from checks.
|
||||
*
|
||||
* @param player The player to unexempt.
|
||||
*/
|
||||
void unexempt(@NotNull Player player);
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.willfp.eco.core.integrations.anticheat;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Listener;
|
||||
@@ -15,19 +16,31 @@ public final class AnticheatManager {
|
||||
/**
|
||||
* A set of all registered anticheats.
|
||||
*/
|
||||
private static final Set<AnticheatWrapper> ANTICHEATS = new HashSet<>();
|
||||
private static final Set<AnticheatIntegration> ANTICHEATS = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Register a new anticheat.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
* @param anticheat The anticheat to register.
|
||||
* @deprecated Don't pass instance of eco.
|
||||
*/
|
||||
@Deprecated(since = "6.35.0", forRemoval = true)
|
||||
public static void register(@NotNull final EcoPlugin plugin,
|
||||
@NotNull final AnticheatWrapper anticheat) {
|
||||
@NotNull final AnticheatIntegration anticheat) {
|
||||
register(anticheat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new anticheat.
|
||||
*
|
||||
* @param anticheat The anticheat to register.
|
||||
*/
|
||||
public static void register(@NotNull final AnticheatIntegration anticheat) {
|
||||
if (anticheat instanceof Listener) {
|
||||
plugin.getEventManager().registerListener((Listener) anticheat);
|
||||
Eco.get().getEcoPlugin().getEventManager().registerListener((Listener) anticheat);
|
||||
}
|
||||
ANTICHEATS.removeIf(it -> it.getPluginName().equalsIgnoreCase(anticheat.getPluginName()));
|
||||
ANTICHEATS.add(anticheat);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,24 +1,11 @@
|
||||
package com.willfp.eco.core.integrations.anticheat;
|
||||
|
||||
import com.willfp.eco.core.integrations.Integration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Wrapper class for anticheat integrations.
|
||||
*
|
||||
* @deprecated Use AnticheatIntegration instead.
|
||||
*/
|
||||
public interface AnticheatWrapper extends Integration {
|
||||
/**
|
||||
* Exempt a player from checks.
|
||||
*
|
||||
* @param player The player to exempt.
|
||||
*/
|
||||
void exempt(@NotNull Player player);
|
||||
@Deprecated(since = "6.35.0", forRemoval = true)
|
||||
public interface AnticheatWrapper extends AnticheatIntegration {
|
||||
|
||||
/**
|
||||
* Unexempt a player from checks.
|
||||
*
|
||||
* @param player The player to unexempt.
|
||||
*/
|
||||
void unexempt(@NotNull Player player);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.willfp.eco.core.integrations.antigrief;
|
||||
|
||||
import com.willfp.eco.core.integrations.Integration;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Wrapper class for antigrief integrations.
|
||||
*/
|
||||
public interface AntigriefIntegration extends Integration {
|
||||
/**
|
||||
* Can player break block.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param block The block.
|
||||
* @return If player can break block.
|
||||
*/
|
||||
boolean canBreakBlock(@NotNull Player player, @NotNull Block block);
|
||||
|
||||
/**
|
||||
* Can player create explosion at location.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param location The location.
|
||||
* @return If player can create explosion.
|
||||
*/
|
||||
boolean canCreateExplosion(@NotNull Player player, @NotNull Location location);
|
||||
|
||||
/**
|
||||
* Can player place block.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param block The block.
|
||||
* @return If player can place block.
|
||||
*/
|
||||
boolean canPlaceBlock(@NotNull Player player, @NotNull Block block);
|
||||
|
||||
/**
|
||||
* Can player injure living entity.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param victim The victim.
|
||||
* @return If player can injure.
|
||||
*/
|
||||
boolean canInjure(@NotNull Player player, @NotNull LivingEntity victim);
|
||||
|
||||
/**
|
||||
* Can player pick up item.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param location The location.
|
||||
* @return If player can pick up item.
|
||||
*/
|
||||
default boolean canPickupItem(@NotNull Player player, @NotNull Location location) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user