Compare commits
1545 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
2f98c0ace5 | ||
|
|
60d7abcda8 | ||
|
|
69a5fa81b4 | ||
|
|
0316e627e1 | ||
|
|
5bc5b47bf8 | ||
|
|
a9c906843d | ||
|
|
85861971d3 | ||
|
|
bdb24e5a14 | ||
|
|
cb481d4532 | ||
|
|
97fba3e243 | ||
|
|
e47c6387a2 | ||
|
|
00df39097c | ||
|
|
efcb406e9a | ||
|
|
9e92ea6062 | ||
|
|
9dbc25df6f | ||
|
|
bc85c5232e | ||
|
|
2f4783f13e | ||
|
|
614241a058 | ||
|
|
c541adb557 | ||
|
|
a484eecc8f | ||
|
|
3933e38891 | ||
|
|
1d5345b367 | ||
|
|
f8513ff1e9 | ||
|
|
ca9c940b2b | ||
|
|
af198d30f7 | ||
|
|
637b239c66 | ||
|
|
124c059294 | ||
|
|
f1d0bd901d | ||
|
|
20f4bf4e78 | ||
|
|
595bc76294 | ||
|
|
9a66e78dcd | ||
|
|
0fcf229bfb | ||
|
|
d2ffc43b17 | ||
|
|
c50f69b372 | ||
|
|
f5eafafc4c | ||
|
|
39372c9b1a | ||
|
|
4c64f03aa1 | ||
|
|
6bb4e301bc | ||
|
|
827e9fd98a | ||
|
|
c3e9bbbc50 | ||
|
|
7328881977 | ||
|
|
00531d0a04 | ||
|
|
5d4a2b4633 | ||
|
|
28c86460fc | ||
|
|
4a1d714b71 | ||
|
|
4ef16530d3 | ||
|
|
a22ad1b22d | ||
|
|
623c3589a3 | ||
|
|
44924cdf83 | ||
|
|
75363181e4 | ||
|
|
1fc9d66457 | ||
|
|
2fdbe0da28 | ||
|
|
a1922cb195 | ||
|
|
725e950092 | ||
|
|
bf123d3105 | ||
|
|
83b6721484 | ||
|
|
dca952c10a | ||
|
|
b2e5896885 | ||
|
|
38542dad5e | ||
|
|
852a9c5fb1 | ||
|
|
12aa0e349e | ||
|
|
351f5d8c16 | ||
|
|
7e4b3075ed | ||
|
|
cf0d725189 | ||
|
|
a9f33fb846 | ||
|
|
4a9ab7a0eb | ||
|
|
3982ab99a6 | ||
|
|
1fb39e55d2 | ||
|
|
56d32b532d | ||
|
|
0d0800dfb5 | ||
|
|
f32110687f | ||
|
|
dbf39f3621 | ||
|
|
9a2f0e3df8 | ||
|
|
56fb9b40b9 | ||
|
|
fbc7bb6f07 | ||
|
|
2294c3758d | ||
|
|
c573da6e31 | ||
|
|
6362931e6b | ||
|
|
0be1f45edc | ||
|
|
9700aa7eac | ||
|
|
75eaf58aa2 | ||
|
|
63352989b1 | ||
|
|
dd5e0e3847 | ||
|
|
4f009c6d57 | ||
|
|
09d4db816e | ||
|
|
fb7799e931 | ||
|
|
13a1965f03 | ||
|
|
3abefb73f9 | ||
|
|
a35f5bb405 | ||
|
|
88a7fb53a3 | ||
|
|
866ba8440d | ||
|
|
61896bbddd | ||
|
|
7a4891d4e3 | ||
|
|
dbd5cd341e | ||
|
|
7df707a59d | ||
|
|
92dfa32d07 | ||
|
|
5cad1d31e3 | ||
|
|
e4c0418fd4 | ||
|
|
54c74d0138 | ||
|
|
6e21bdeb5b | ||
|
|
00439a1b04 | ||
|
|
87684abbbb | ||
|
|
0cbf78733e | ||
|
|
ecf0e7c356 | ||
|
|
f20d9884b5 | ||
|
|
61d713ad4d | ||
|
|
ca5cce3f40 | ||
|
|
1c8edac807 | ||
|
|
98b465f8f3 | ||
|
|
3c3e34eda3 | ||
|
|
02ad6f7810 | ||
|
|
5369ee7d42 | ||
|
|
c441e0761f | ||
|
|
a02dd06c20 | ||
|
|
957af5c5bf | ||
|
|
2c51a6900f | ||
|
|
e09e9b4e8d | ||
|
|
02497d485b | ||
|
|
bd32f3bc8d | ||
|
|
7176342e15 | ||
|
|
32ef8d8c5c | ||
|
|
92f8787eb9 | ||
|
|
5403f7a9ed | ||
|
|
2924d6f560 | ||
|
|
36c0708c17 | ||
|
|
b9fe54e883 | ||
|
|
5cc2f23547 | ||
|
|
30514ba780 | ||
|
|
02e6c5e8f3 | ||
|
|
fac97329aa | ||
|
|
cdf5cc3abe | ||
|
|
4cb630d201 | ||
|
|
79d6277d94 | ||
|
|
1a90fa6707 | ||
|
|
6ecbb2d901 | ||
|
|
3373901b95 | ||
|
|
7eb1b917dc | ||
|
|
fdba12082c | ||
|
|
516ecc1c3d | ||
|
|
cfd545c735 | ||
|
|
0ded1fe68b | ||
|
|
4fce11b149 | ||
|
|
2374e8fe03 | ||
|
|
36ccf346d7 | ||
|
|
cb480bd88d | ||
|
|
8cc96cb30e | ||
|
|
736ba0f8b0 | ||
|
|
5b5fefee8e | ||
|
|
8941e3179b | ||
|
|
19ce4c56a9 | ||
|
|
337c5d2b84 | ||
|
|
631c17aedc | ||
|
|
0ff4ac92be | ||
|
|
aa94094078 | ||
|
|
135ddcf331 | ||
|
|
e5d31e0b49 | ||
|
|
448b2e4b3f | ||
|
|
ebb30e3a70 | ||
|
|
fb89415636 | ||
|
|
d0d64b3e58 | ||
|
|
49273abbfc | ||
|
|
36c77d81eb | ||
|
|
b6cd56ad15 | ||
|
|
1a524aea94 | ||
|
|
2ebab99a06 | ||
|
|
46663f7edb | ||
|
|
4fad66cd90 | ||
|
|
a9fafeec00 | ||
|
|
0d8308d6cd | ||
|
|
13772002e8 | ||
|
|
c9b84889e7 | ||
|
|
1513578266 | ||
|
|
89d6f2f867 | ||
|
|
8e6d98c997 | ||
|
|
5bc2cb31a4 | ||
|
|
041575a103 | ||
|
|
c88dac56b7 | ||
|
|
00da717f6d | ||
|
|
cc557378cc | ||
|
|
b5c49c79b8 | ||
|
|
28018430e7 | ||
|
|
7b6c8d68a8 | ||
|
|
ad3cb3a620 | ||
|
|
511a7e4830 | ||
|
|
5aeeafc041 | ||
|
|
9a51fb8358 | ||
|
|
eeefb9f40e | ||
|
|
aa1ce34cbc | ||
|
|
47772c3ff7 | ||
|
|
dfcac5d527 | ||
|
|
40f88f0b59 | ||
|
|
105355d967 | ||
|
|
3cddff22b8 | ||
|
|
f8e930d29e | ||
|
|
9dbe088e66 | ||
|
|
6361c0e8e9 | ||
|
|
1135672241 | ||
|
|
80891e4a81 | ||
|
|
3e0be3a629 | ||
|
|
17819de2ea | ||
|
|
209cdd6b0d | ||
|
|
fbf6b2edd9 | ||
|
|
8b9e8589a0 | ||
|
|
525cc019ea | ||
|
|
04f2d15783 | ||
|
|
f988b591a4 | ||
|
|
9ebfb124c8 | ||
|
|
b9ab263f67 | ||
|
|
bb5f68283b | ||
|
|
9bbf1cfe36 | ||
|
|
19bb5f608c | ||
|
|
a1c70d2081 | ||
|
|
979ddf0ff0 | ||
|
|
232a63c00d | ||
|
|
e65cf9be2c | ||
|
|
fbf56037d4 | ||
|
|
aa0c4ee7fa | ||
|
|
5f3375bf87 | ||
|
|
11dc6d0e67 | ||
|
|
9cccbd10ba | ||
|
|
1f0ad48480 | ||
|
|
93322dcfa5 | ||
|
|
e3b630fcb7 | ||
|
|
8690b75f4c | ||
|
|
6de792f308 | ||
|
|
e59037635e | ||
|
|
b9d50e261d | ||
|
|
15173c8369 | ||
|
|
4ee0645a4e | ||
|
|
96bd53c089 | ||
|
|
e658bf3fa8 | ||
|
|
988836b5b9 | ||
|
|
5688f41b8b | ||
|
|
4eaa6ab75c | ||
|
|
b29363cdf6 | ||
|
|
c8648a92f5 | ||
|
|
0a59b6a208 | ||
|
|
4e18a0ab78 | ||
|
|
d49405f839 | ||
|
|
e10566da66 | ||
|
|
0c64cd98e0 | ||
|
|
231af30c61 | ||
|
|
9b5cc1fd9c | ||
|
|
7628c0bbfd | ||
|
|
0beedc6b07 | ||
|
|
f3c69f1c15 | ||
|
|
a148f667e5 | ||
|
|
b2370b4b6e | ||
|
|
525bd5264a | ||
|
|
54c27a0379 | ||
|
|
989dda0a4f | ||
|
|
1f2bb3341e | ||
|
|
65221bdddf | ||
|
|
b386f2df1b | ||
|
|
969329486d | ||
|
|
aab2e8237c | ||
|
|
30457c29a1 | ||
|
|
9ad480ecf0 | ||
|
|
b0d3256d1b | ||
|
|
4ff9d82cc1 | ||
|
|
f9178e248b | ||
|
|
cc8a799438 | ||
|
|
90b81f56df | ||
|
|
1240c14c14 | ||
|
|
ed46900f2f | ||
|
|
dade3d7fbb | ||
|
|
df141875d3 | ||
|
|
50b07de5d1 | ||
|
|
e2a033c24f | ||
|
|
3fa574105f | ||
|
|
a64386f980 | ||
|
|
4c5a0f9887 | ||
|
|
cbd43f5757 | ||
|
|
01f1425557 | ||
|
|
25e8cc0837 | ||
|
|
7ff3eeef06 | ||
|
|
58faf6de23 | ||
|
|
7f42cbe32e | ||
|
|
ae12ab17fe | ||
|
|
9949ed4f5f | ||
|
|
e3f81a51e8 | ||
|
|
a06d782dea | ||
|
|
7e60ee63ea | ||
|
|
e349f47e66 | ||
|
|
f710a69455 | ||
|
|
20b06be1f2 | ||
|
|
9992820580 | ||
|
|
feebbd8ec7 | ||
|
|
5302aa07a5 | ||
|
|
d124c5b274 | ||
|
|
f188919197 | ||
|
|
388268e906 | ||
|
|
6367867d2b | ||
|
|
291357e235 | ||
|
|
07178b0645 | ||
|
|
70ef99e875 | ||
|
|
885a7835ea | ||
|
|
94e9b47f02 | ||
|
|
e8f4bdd4aa | ||
|
|
c01e409904 | ||
|
|
f1cf82160e | ||
|
|
d1c15f8699 | ||
|
|
be6e7b1f46 | ||
|
|
b78fc2fb66 | ||
|
|
23a297b8e3 | ||
|
|
4e99ca51f0 | ||
|
|
47c93a6dbe | ||
|
|
da7f47d1ba | ||
|
|
144ea0dd10 | ||
|
|
732aaa3bf1 | ||
|
|
a38387be33 | ||
|
|
582f9b08f3 | ||
|
|
638367cbb2 | ||
|
|
ec35e7d779 | ||
|
|
1cc2a585d6 | ||
|
|
aa553b96d6 | ||
|
|
feb7ecee48 | ||
|
|
c0be6a12ff | ||
|
|
1dc6b651a0 | ||
|
|
3c26c02642 | ||
|
|
343508f099 | ||
|
|
76dc4948bc | ||
|
|
8fa209a981 | ||
|
|
b3a0634ad0 | ||
|
|
97d7acc0a9 | ||
|
|
ebac75b0ee | ||
|
|
02d0fa85b5 | ||
|
|
168915868c | ||
|
|
d62d598fd6 | ||
|
|
06561c5387 | ||
|
|
c9805e91b4 | ||
|
|
e3be95ca4d | ||
|
|
2e6463aed9 | ||
|
|
2501574eeb | ||
|
|
3c237fd856 | ||
|
|
7b3fd1d0c2 | ||
|
|
e599add6de | ||
|
|
1bda970f6b | ||
|
|
eb1f694905 | ||
|
|
efd3403eda | ||
|
|
08b563d528 | ||
|
|
c3f88bf7b0 | ||
|
|
eb6d76e0c6 | ||
|
|
f2d0e8c368 | ||
|
|
5e7b9573a1 | ||
|
|
7d457ea496 | ||
|
|
806bf9a43f | ||
|
|
316f134b71 | ||
|
|
0d363b9fb6 | ||
|
|
2890083eaa | ||
|
|
694646431b | ||
|
|
86d5e9d09e | ||
|
|
8635e5f7a5 | ||
|
|
aa718649eb | ||
|
|
1dc0fa449b | ||
|
|
19e3061a13 | ||
|
|
ecafbd76de | ||
|
|
3728f2fc7a | ||
|
|
56c124dbd2 | ||
|
|
6730697fc5 | ||
|
|
c8e1c83061 | ||
|
|
a9fd5a9418 | ||
|
|
7b1179f402 | ||
|
|
f4907329d9 | ||
|
|
1e23cbaa5e | ||
|
|
863818d2eb | ||
|
|
d35285d0dc | ||
|
|
bc92f8a444 | ||
|
|
2fafef17d7 | ||
|
|
24078a2838 | ||
|
|
73d13277be | ||
|
|
0e4c23d70c | ||
|
|
ddf5094c5a | ||
|
|
925fc56cab | ||
|
|
3208d0328f | ||
|
|
317824ae78 | ||
|
|
41a4b4fc1a | ||
|
|
c528e4cd42 | ||
|
|
2724f21d4e | ||
|
|
5cb14e31b7 | ||
|
|
6b9942f412 | ||
|
|
fbe88ab0fd | ||
|
|
d042211dbe | ||
|
|
5781df011e | ||
|
|
c191ff0767 | ||
|
|
b9cbcbe7a0 | ||
|
|
6009122c48 | ||
|
|
7536794100 | ||
|
|
e80aa5f910 | ||
|
|
b4aeeac570 | ||
|
|
33515aa5f7 | ||
|
|
047b535a40 | ||
|
|
ef8093ec7f | ||
|
|
9d0f95617d | ||
|
|
b4f3988fc7 | ||
|
|
e7e1751acc | ||
|
|
e68d482aa5 | ||
|
|
c0547a7c34 | ||
|
|
183b18c0ec | ||
|
|
e026a767d9 | ||
|
|
d2966aa428 | ||
|
|
9168e68b5a | ||
|
|
51a61b65c6 | ||
|
|
76be236dac | ||
|
|
f1bbac2dd0 | ||
|
|
6e88aef572 | ||
|
|
804f187964 | ||
|
|
623b8a18f4 | ||
|
|
0d4e424582 | ||
|
|
452e499467 | ||
|
|
b2950ab035 | ||
|
|
e47d05ccb2 | ||
|
|
b9e61b8c0d | ||
|
|
0f35d5d16e | ||
|
|
3a7315d728 | ||
|
|
6f193f70b0 | ||
|
|
bab3f078f6 | ||
|
|
5b4b17b97f | ||
|
|
f0e02ca25e | ||
|
|
7426e9adba | ||
|
|
00905aa9d5 | ||
|
|
f7b57880cb | ||
|
|
c1b673e30c | ||
|
|
4cf45795d6 | ||
|
|
59d31584e6 | ||
|
|
68e1f4afac | ||
|
|
507fad186a | ||
|
|
ca6b3185a3 | ||
|
|
8e96329fdc | ||
|
|
440605f636 | ||
|
|
bb686dca17 | ||
|
|
e595ea2247 | ||
|
|
a776b60f86 | ||
|
|
db7ac55eb2 | ||
|
|
52d77d7861 | ||
|
|
f8ece2d6c7 | ||
|
|
b353b5ec04 | ||
|
|
bbc412e589 | ||
|
|
b4a474c703 | ||
|
|
75e6a3da79 | ||
|
|
a1afffdbbb | ||
|
|
f6942192de | ||
|
|
dab26cbe95 | ||
|
|
b945a3f948 | ||
|
|
b2c1d650de | ||
|
|
4b994d5f4c | ||
|
|
ed2dffb52c | ||
|
|
20c870da06 | ||
|
|
7684e431f5 | ||
|
|
abcc13685f | ||
|
|
ac902eaa08 | ||
|
|
4e52913504 | ||
|
|
7505f7732f | ||
|
|
15fae21fd5 | ||
|
|
e9d98816ce | ||
|
|
675fc07ebf | ||
|
|
b8b8fd70b5 | ||
|
|
1d9fca1fb8 | ||
|
|
9b83f6eab4 | ||
|
|
8190660b8f | ||
|
|
cbf4d111fb | ||
|
|
6a139bef67 | ||
|
|
9e3fecfd13 | ||
|
|
3b260e2e5d | ||
|
|
0c0370e256 | ||
|
|
227b748f85 | ||
|
|
c8382bd8cf | ||
|
|
df22768367 | ||
|
|
00ea3506ca | ||
|
|
521659cfec | ||
|
|
bbe5f1eba4 | ||
|
|
3d4c33860a | ||
|
|
eae5d29f8d | ||
|
|
c878d6fd12 | ||
|
|
2b97c0072f | ||
|
|
63079df745 | ||
|
|
079b41e877 | ||
|
|
1aaab459d8 | ||
|
|
db78c2eb4c | ||
|
|
02fd07b3c8 | ||
|
|
3de2e53031 | ||
|
|
cb088bb70b | ||
|
|
36fca7016f | ||
|
|
7e1137da06 | ||
|
|
0da104d614 | ||
|
|
9095de7d19 | ||
|
|
7a8abac1a2 | ||
|
|
1ddcb6e964 | ||
|
|
4d0858ad84 | ||
|
|
3d05695a36 | ||
|
|
d676be15ce | ||
|
|
16848caec1 | ||
|
|
ef26fe4629 | ||
|
|
29fbd785d7 | ||
|
|
8c73676ee0 | ||
|
|
ebf27d28d9 | ||
|
|
317bc13f65 | ||
|
|
b8ec0ee6fc | ||
|
|
307e57c902 | ||
|
|
db0d55659f | ||
|
|
548529feb3 | ||
|
|
fb56baf452 | ||
|
|
5d18b424d7 | ||
|
|
7be9a1bd10 | ||
|
|
97c39b56dd | ||
|
|
3a9f5bc139 | ||
|
|
1e5955f249 | ||
|
|
bad076bbe9 | ||
|
|
e219b2f33c | ||
|
|
2f7603409e | ||
|
|
28cdb65176 | ||
|
|
03ae9e89b3 | ||
|
|
2d074bc186 | ||
|
|
7e4422f6e2 | ||
|
|
5b29c90457 | ||
|
|
651426ed76 | ||
|
|
4ebc1a18a1 | ||
|
|
db20bed6e0 | ||
|
|
0826da6cfc | ||
|
|
6d8fce3462 | ||
|
|
eedb1404b6 | ||
|
|
299abe4568 | ||
|
|
98e1f19145 | ||
|
|
424e2ff43d | ||
|
|
3a899226a3 | ||
|
|
8336eee892 | ||
|
|
a48f756582 | ||
|
|
2aa463d083 | ||
|
|
ea833de9f7 | ||
|
|
3c0822310d | ||
|
|
d5cbc1d497 | ||
|
|
c912ad1c9c | ||
|
|
752f38ef25 | ||
|
|
a5525ab332 | ||
|
|
1b442f400d | ||
|
|
3c9c0bcef4 | ||
|
|
3a7a938e7f | ||
|
|
32c17aa3ae | ||
|
|
e451732876 | ||
|
|
53f81c0a03 | ||
|
|
f60d91c5f3 | ||
|
|
a9bdca56a5 | ||
|
|
3516d5881e | ||
|
|
95cecc2b2a | ||
|
|
1a49165656 | ||
|
|
66d0625d2e | ||
|
|
99a60f2b8b | ||
|
|
0bdfbe76fe | ||
|
|
e0240069fc | ||
|
|
11d2f7d711 | ||
|
|
5cf632e58b | ||
|
|
a90fe5d100 | ||
|
|
8dd145ed7d | ||
|
|
e4c65f1db5 | ||
|
|
2208f161c0 | ||
|
|
95833ea8f6 | ||
|
|
ba2da5c238 | ||
|
|
f276026972 | ||
|
|
d2c6cc0d2e | ||
|
|
60829a3e1d | ||
|
|
38c5bf97a0 | ||
|
|
d61f1bd23b | ||
|
|
275f08fcb6 | ||
|
|
68ae25b7db | ||
|
|
89c529fdb3 | ||
|
|
43157b154a | ||
|
|
8721f96a2f | ||
|
|
a48c3c2fed | ||
|
|
ad3f7e529d | ||
|
|
ec6ac88fea | ||
|
|
13b10c13b3 | ||
|
|
1e24cbf67b | ||
|
|
d9cfc8b91a | ||
|
|
b40001d79b | ||
|
|
b8128ef87e | ||
|
|
be885e9092 | ||
|
|
5658c92d3d | ||
|
|
e4b0a602f0 | ||
|
|
bf5c36d2c9 | ||
|
|
cc57d10a36 | ||
|
|
dcbdbb5230 | ||
|
|
de19d67275 | ||
|
|
43abfcb3fc | ||
|
|
34f201d62d | ||
|
|
d3c811614f | ||
|
|
44da61daaa | ||
|
|
3ea6d11026 | ||
|
|
9a03a2e47a | ||
|
|
af91c9d659 | ||
|
|
89eaaf3a5e | ||
|
|
ab174e2d41 | ||
|
|
cfa9badc1e | ||
|
|
3ec1183ec3 | ||
|
|
b3e37ea717 | ||
|
|
9d0707a4db | ||
|
|
41eee84966 | ||
|
|
0f215b48bf | ||
|
|
abad973051 | ||
|
|
b385ebff75 | ||
|
|
f924d23feb | ||
|
|
d603476201 | ||
|
|
b911bbce87 | ||
|
|
d2676c2af1 | ||
|
|
e725811c2f | ||
|
|
f861820572 | ||
|
|
6e310a48c1 | ||
|
|
505234ec13 | ||
|
|
587aeb21a1 | ||
|
|
cc344bf7ca | ||
|
|
c912b97438 | ||
|
|
4788f036ee | ||
|
|
f5ff484086 | ||
|
|
c031534b0d | ||
|
|
62ac49db4b | ||
|
|
32c416ef8e | ||
|
|
a1e22540d4 | ||
|
|
1b66843992 | ||
|
|
55d316cb9d | ||
|
|
ac7a47a0f7 | ||
|
|
70cd23d39a | ||
|
|
44d39c4f5f | ||
|
|
a3ba7cdcf2 | ||
|
|
779323e280 | ||
|
|
5c8a8ca3e4 | ||
|
|
4e4f792bcc | ||
|
|
48ae8ebe65 | ||
|
|
f8c65898d8 | ||
|
|
dbe514f97c | ||
|
|
b244be6dd6 | ||
|
|
4870f7f0d1 | ||
|
|
27888da33a | ||
|
|
33c132065d | ||
|
|
ec09dbddf4 | ||
|
|
3811b01e81 | ||
|
|
f883f8fe1d | ||
|
|
80f43238e0 | ||
|
|
18e7548c23 | ||
|
|
40020b0503 | ||
|
|
830f92bbdb | ||
|
|
c6e39e89fd | ||
|
|
7d38d7db15 | ||
|
|
a6f139c47e | ||
|
|
1bae159f94 | ||
|
|
43d2835087 | ||
|
|
cb2d4d6a34 | ||
|
|
9bb73d8e90 | ||
|
|
86c4867206 | ||
|
|
43e13248d6 | ||
|
|
f6ff45228a | ||
|
|
af1c20f5c5 | ||
|
|
9ac564c345 | ||
|
|
857d51a7a1 | ||
|
|
ab5f8cee5a | ||
|
|
bdd518b280 | ||
|
|
494c1a87b2 | ||
|
|
f78f92b5f6 | ||
|
|
048b56c58c | ||
|
|
75dec2bf49 | ||
|
|
7119da13b7 | ||
|
|
6a8637922b | ||
|
|
abce7b898c | ||
|
|
562d7f382c | ||
|
|
c72b15c3a6 | ||
|
|
54b7e99c82 | ||
|
|
4b6a0ee05d | ||
|
|
89e5d8898b | ||
|
|
08c14f4def | ||
|
|
0fa6f972c0 | ||
|
|
8837fecfa0 | ||
|
|
af1841770e | ||
|
|
1d85dbf08d | ||
|
|
ba9812534a | ||
|
|
1f95a33385 | ||
|
|
bc652a8154 | ||
|
|
0c2e1f0cae | ||
|
|
39d6eb7f9a | ||
|
|
61bae6de55 | ||
|
|
86f230c836 | ||
|
|
aa4ac4c6d1 | ||
|
|
7141b12e95 | ||
|
|
2382548629 | ||
|
|
0c4bd182f7 | ||
|
|
e90e053b45 | ||
|
|
742c1abb00 | ||
|
|
c0686ca386 | ||
|
|
db2ea7daa9 | ||
|
|
ed4f0b2ab6 | ||
|
|
6decc68d1b | ||
|
|
1e061313a4 | ||
|
|
4762004e94 | ||
|
|
0d9889ef43 | ||
|
|
b2a23e80a1 | ||
|
|
0e439db7b3 | ||
|
|
f615006b23 | ||
|
|
d952dbc61b | ||
|
|
d95a96f4c6 | ||
|
|
33940f5778 | ||
|
|
173d04595f | ||
|
|
c7c4ca3777 | ||
|
|
cbf7316db9 | ||
|
|
601cadd582 | ||
|
|
877647db03 | ||
|
|
81196bb132 | ||
|
|
ef701f1f86 | ||
|
|
58d8f72cf5 | ||
|
|
3abf916f18 | ||
|
|
b459a746e3 | ||
|
|
30c37078a2 | ||
|
|
36ccfb5fc6 | ||
|
|
c84f1a060a | ||
|
|
d8d5609f6b | ||
|
|
462abd46c6 | ||
|
|
e89008cf97 | ||
|
|
d34e43797d | ||
|
|
63ee83c795 | ||
|
|
2eec17698e | ||
|
|
ad52c2a086 | ||
|
|
6e482cccda | ||
|
|
899b4297f7 | ||
|
|
ceb95e20b5 | ||
|
|
bdfeb9a0ab | ||
|
|
e0707e2afa | ||
|
|
e8048f5a0a | ||
|
|
a36018e31a | ||
|
|
a34c63161d | ||
|
|
2eb350977c | ||
|
|
8a89a63c5f | ||
|
|
5c26e6e782 | ||
|
|
f88b914fa6 | ||
|
|
15ff6b3ea3 | ||
|
|
b14eed696c | ||
|
|
cffae33c87 | ||
|
|
adf6d1c800 | ||
|
|
2b7c8962e7 | ||
|
|
b60cbfce2c | ||
|
|
910ad18703 | ||
|
|
8a4a71ebc1 | ||
|
|
2e748b1723 | ||
|
|
cb28726bc3 | ||
|
|
c0c20d63bb | ||
|
|
3b11610c45 | ||
|
|
232048022e | ||
|
|
9abfe0ab01 | ||
|
|
e7ac05278c | ||
|
|
85ba40c279 | ||
|
|
1acf86492e | ||
|
|
4609d38389 | ||
|
|
2d6836cc93 | ||
|
|
8e21617345 | ||
|
|
2f99a17d02 | ||
|
|
34edf1d7b4 | ||
|
|
be85ba5706 | ||
|
|
b817b00ca4 | ||
|
|
ee02528abc | ||
|
|
794948c8f9 | ||
|
|
7c70dec2e7 | ||
|
|
d1f20b7111 | ||
|
|
595751a094 | ||
|
|
8231afdcbf | ||
|
|
4f55d66096 | ||
|
|
d350febbdc | ||
|
|
78755b0e9a | ||
|
|
63d7bdab6b | ||
|
|
344032b7e3 | ||
|
|
3ae5c8a72c | ||
|
|
e4f2bc2e39 | ||
|
|
90ba0a0391 | ||
|
|
801a3cd4f9 | ||
|
|
ce9cada75a | ||
|
|
ae551dd0f7 | ||
|
|
1b3dd53fb8 | ||
|
|
dda4224e6e | ||
|
|
6e14265655 | ||
|
|
77fd99d215 | ||
|
|
cf05efc2ff | ||
|
|
0e8c759a4c | ||
|
|
ba7bfb828b | ||
|
|
8dd1239b99 | ||
|
|
edada09966 | ||
|
|
19c300bbf3 | ||
|
|
4fc9c21034 | ||
|
|
2366dcd293 | ||
|
|
054e6a53c0 | ||
|
|
46f590fe3e | ||
|
|
b46aaf547f | ||
|
|
0f7125e1c8 | ||
|
|
6cb99819f3 | ||
|
|
a018a1fca5 | ||
|
|
8a7b8f2b03 | ||
|
|
abf3dc1e9e | ||
|
|
e92cc41be6 | ||
|
|
49570c841b | ||
|
|
9aa465844d | ||
|
|
a692fbee01 | ||
|
|
4223e8f17a | ||
|
|
5f26b23a53 | ||
|
|
c8c179981c | ||
|
|
4bb8bb62f9 | ||
|
|
c1b3bec67c | ||
|
|
f2535ce75c | ||
|
|
049d64821e | ||
|
|
bf5766e61c | ||
|
|
38da5fe6d1 | ||
|
|
e16649873b | ||
|
|
a3b0b4f847 | ||
|
|
d9f1ddd188 | ||
|
|
14a4d9291b | ||
|
|
6630044546 | ||
|
|
1043981fe4 | ||
|
|
fb0b7c52cf | ||
|
|
74e5464f7d | ||
|
|
2ad1ff4cdb | ||
|
|
2d47c18be6 | ||
|
|
69e67be436 | ||
|
|
c144723d5b | ||
|
|
108375f545 | ||
|
|
83d5b3e96e | ||
|
|
37e09a470e | ||
|
|
1f064110b7 | ||
|
|
94a0b4de5d | ||
|
|
8a68666f86 | ||
|
|
2c218d1088 | ||
|
|
3fa95d82a6 | ||
|
|
9648b42c4d | ||
|
|
66887f0a3a | ||
|
|
410cdfe7e3 | ||
|
|
bbffdc7e23 | ||
|
|
0d267e2bec | ||
|
|
578256f89b | ||
|
|
90ecbfce00 | ||
|
|
9945704338 | ||
|
|
5c7a7876d8 | ||
|
|
94df0e67a6 | ||
|
|
92c4e62709 | ||
|
|
e094a1e934 | ||
|
|
26c07a20e7 | ||
|
|
ad68e1efef | ||
|
|
d8c3a3befa | ||
|
|
aa52dcdf94 | ||
|
|
9d3ba7ea88 | ||
|
|
e2b417af74 | ||
|
|
77394d3038 | ||
|
|
fcc7f82b38 | ||
|
|
396f4dac44 | ||
|
|
3341093735 | ||
|
|
714d04e48f | ||
|
|
73b7ccea3a | ||
|
|
606bf8fcd2 | ||
|
|
fbbf893d64 | ||
|
|
36001373eb | ||
|
|
9ac34288eb | ||
|
|
6345d1fe92 | ||
|
|
a7fa0ecf26 | ||
|
|
a65f16cfac | ||
|
|
49965c091b | ||
|
|
f9bc2aba99 | ||
|
|
5627582bd5 | ||
|
|
ab8065d06e | ||
|
|
444764e481 | ||
|
|
c240e94a6b | ||
|
|
9da28a1dff | ||
|
|
cf3c1f8394 | ||
|
|
f98befbdce | ||
|
|
d0d8ea07e4 | ||
|
|
109347a601 | ||
|
|
43bef762bf | ||
|
|
69a2e0e247 | ||
|
|
874a9b4f32 | ||
|
|
5690221c27 | ||
|
|
f19b143804 | ||
|
|
10a313bef5 | ||
|
|
9ae40ae09e | ||
|
|
7b4e1d8d24 | ||
|
|
7035280731 | ||
|
|
a1e3d53cd2 | ||
|
|
d7885f05c3 | ||
|
|
415c425097 | ||
|
|
cb4d992e7d | ||
|
|
cb64d088d1 | ||
|
|
bbbf19c041 | ||
|
|
61ace5c8e5 | ||
|
|
94b73ef35c | ||
|
|
5cfc2068e7 | ||
|
|
0ce7d1dd6c | ||
|
|
19eefaf879 | ||
|
|
1ebf7fb875 | ||
|
|
e8afd15d80 | ||
|
|
d024c9238e | ||
|
|
1356bd1f26 | ||
|
|
407ccca5e0 | ||
|
|
82de602d47 | ||
|
|
b0873112af | ||
|
|
3a0b81b7de | ||
|
|
5142b9ce92 | ||
|
|
9403a1cbcb | ||
|
|
e4ebea354d | ||
|
|
d32b31f1e5 | ||
|
|
384657f1dc | ||
|
|
7c9d226bc3 | ||
|
|
031401bb8e | ||
|
|
1a5c429b67 | ||
|
|
d028cf5bf3 | ||
|
|
fdd1581ce3 | ||
|
|
3d07e10543 | ||
|
|
c851e35347 | ||
|
|
4cbb33b1fd | ||
|
|
2ff1458772 | ||
|
|
e71ad9f034 | ||
|
|
196a651ab3 | ||
|
|
253a8c24ad | ||
|
|
ac265d0260 | ||
|
|
ad861b10bb | ||
|
|
db5b7f89f6 | ||
|
|
2c33ce25c0 | ||
|
|
9c3ca429c9 | ||
|
|
70e294501a | ||
|
|
65a0a0ecc7 | ||
|
|
d4431e7569 | ||
|
|
a6191b0870 | ||
|
|
5eecef83ee | ||
|
|
82a02f3738 | ||
|
|
804142799b | ||
|
|
e1de9b9ab3 | ||
|
|
cc56343041 | ||
|
|
69d28e8bc2 | ||
|
|
6878a74724 | ||
|
|
ebc76bba76 | ||
|
|
378218b7da | ||
|
|
e053514b94 | ||
|
|
341a30e6da | ||
|
|
70eb6d4420 | ||
|
|
aa368909ae | ||
|
|
606a54bcf8 | ||
|
|
7f8fb3d87b | ||
|
|
e97d454ff6 | ||
|
|
109b9aa3f3 | ||
|
|
4a90385b27 | ||
|
|
0edd50832c | ||
|
|
46415268b7 | ||
|
|
b652dbad2d | ||
|
|
50550d077a | ||
|
|
60c3b58a33 | ||
|
|
7216d0b09f | ||
|
|
97eeea8d48 | ||
|
|
82061ee6a3 | ||
|
|
f274b9045e | ||
|
|
2241a5c90f | ||
|
|
bbc38ae801 | ||
|
|
e77346ed62 | ||
|
|
6117abca56 | ||
|
|
2e2a061ebe | ||
|
|
cdc89ac397 | ||
|
|
e758cebe77 | ||
|
|
a408e3436a | ||
|
|
3df977c1bc | ||
|
|
136f1841b4 | ||
|
|
1086a59a6a | ||
|
|
d9147f9918 | ||
|
|
d144df4048 | ||
|
|
061f77e911 | ||
|
|
5cebe2fce8 | ||
|
|
1e712dcae6 | ||
|
|
09d444da58 | ||
|
|
09f45c0ab5 | ||
|
|
f64d69f084 | ||
|
|
86a948738f | ||
|
|
8f9c5e7ed8 | ||
|
|
ae897b7493 | ||
|
|
f1a7c9d50e | ||
|
|
83ee8fe4cd | ||
|
|
465f885e22 | ||
|
|
d4141735a9 | ||
|
|
b9b4ce1937 | ||
|
|
56234e6c83 | ||
|
|
2dda34097e | ||
|
|
155a349569 | ||
|
|
ce231934a3 | ||
|
|
5cbb7bfe47 | ||
|
|
06e0ec0295 | ||
|
|
02ed583674 | ||
|
|
8e4cbdd1aa | ||
|
|
8828f8e45d | ||
|
|
d15524ee9e | ||
|
|
d45e66d71e | ||
|
|
6b1dde7540 | ||
|
|
abf2964c48 | ||
|
|
db51c4c761 | ||
|
|
cbb574acec | ||
|
|
93c044ef09 | ||
|
|
1cc39fe40a | ||
|
|
edfd561fcd | ||
|
|
bd7f22cb02 | ||
|
|
3233bad307 | ||
|
|
3cefcbe0bb | ||
|
|
49bce53724 | ||
|
|
2b86159b30 | ||
|
|
d028511a48 | ||
|
|
5ad1ef33b8 | ||
|
|
634d6194d6 | ||
|
|
7f7eb4f45a | ||
|
|
bd90ae996b | ||
|
|
1bc57dec08 | ||
|
|
ce44d40f0f | ||
|
|
68824fb4d0 | ||
|
|
fd96b0d2cf | ||
|
|
2669569e81 | ||
|
|
067f740bcc | ||
|
|
2ce96ab0b1 | ||
|
|
027f9be194 | ||
|
|
a09018d1f0 | ||
|
|
a1da83173d | ||
|
|
8ac30283f8 | ||
|
|
6099b5d64d | ||
|
|
19d2e0788b | ||
|
|
1b223b3736 | ||
|
|
d6d1f01704 | ||
|
|
51231939c0 | ||
|
|
72fb20ecd9 | ||
|
|
58a386922c | ||
|
|
12824c7f6c | ||
|
|
b5236b8db6 | ||
|
|
3ffbb861d1 | ||
|
|
f8fad15f0b | ||
|
|
a0e96fca35 | ||
|
|
6cf9a53a65 | ||
|
|
a4909453d7 | ||
|
|
a10666f792 | ||
|
|
a845cda9ed | ||
|
|
ed5f1ccb5e | ||
|
|
c6e59e1d62 | ||
|
|
ed24b6278e | ||
|
|
3aea7b4077 | ||
|
|
f53c29cd56 | ||
|
|
6845152a09 | ||
|
|
7eaf2dc8ed | ||
|
|
310485402f | ||
|
|
727dc25083 | ||
|
|
364f36d502 | ||
|
|
b6086bc4bd | ||
|
|
dd3beaa548 | ||
|
|
c36c0c247f | ||
|
|
6611a0f82c | ||
|
|
625b981b81 | ||
|
|
d8607917a1 | ||
|
|
30d5f54459 | ||
|
|
a59c05174f | ||
|
|
cf01abcf87 | ||
|
|
70a4a06d4f | ||
|
|
bbee18fd8a | ||
|
|
26ab9a327d | ||
|
|
0676f5fa33 | ||
|
|
051b95ad88 | ||
|
|
d786014cbc | ||
|
|
b62bb48bb6 | ||
|
|
b238a10209 | ||
|
|
251049f1f1 | ||
|
|
16d146dba0 |
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
blank_issues_enabled: false
|
||||||
|
contact_links:
|
||||||
|
- name: Auxilor Community Discord
|
||||||
|
url: https://discord.gg/ZcwpSsE/
|
||||||
|
about: Join the Auxilor discord to get help from support staff and the general community!
|
||||||
|
- name: The most common issues people have
|
||||||
|
url: https://github.com/Auxilor/eco/issues/78
|
||||||
|
about: Check the list of known common issues to see if your issue has already been solved
|
||||||
31
.github/ISSUE_TEMPLATE/report-a-bug.md
vendored
Normal file
31
.github/ISSUE_TEMPLATE/report-a-bug.md
vendored
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
---
|
||||||
|
name: Report a Bug
|
||||||
|
about: Report an issue with the plugin
|
||||||
|
title: ''
|
||||||
|
labels: bug
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behavior:
|
||||||
|
1. Go to '...'
|
||||||
|
2. Click on '....'
|
||||||
|
3. Scroll down to '....'
|
||||||
|
4. See error
|
||||||
|
|
||||||
|
**Expected behavior**
|
||||||
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
|
**Screenshots**
|
||||||
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
|
**Server Information (please complete the following information):**
|
||||||
|
- Version: (output of `/ver` command)
|
||||||
|
- Version of plugin and eco (`/ver eco`, `/ver <plugin>`)
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context about the problem here.
|
||||||
20
.github/ISSUE_TEMPLATE/request-a-feature.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/request-a-feature.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
name: Request a Feature
|
||||||
|
about: Suggest an idea for this plugin
|
||||||
|
title: ''
|
||||||
|
labels: enhancement
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Is your feature request related to a problem? Please describe.**
|
||||||
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
|
**Describe alternatives you've considered**
|
||||||
|
A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context or screenshots about the feature request here.
|
||||||
11
.github/dependabot.yml
vendored
Normal file
11
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# To get started with Dependabot version updates, you'll need to specify which
|
||||||
|
# package ecosystems to update and where the package manifests are located.
|
||||||
|
# Please see the documentation for all configuration options:
|
||||||
|
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||||
|
|
||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "gradle" # See documentation for possible values
|
||||||
|
directory: "/" # Location of package manifests
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
15
.github/workflows/checkstyle.yml
vendored
Normal file
15
.github/workflows/checkstyle.yml
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
name: Check PR Codestyle
|
||||||
|
on: [ pull_request ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
checkstyle:
|
||||||
|
name: Checkstyle
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: dbelyaev/action-checkstyle@v0.5.1
|
||||||
|
with:
|
||||||
|
github_token: ${{ secrets.github_token }}
|
||||||
|
reporter: github-pr-review
|
||||||
|
level: warning
|
||||||
|
checkstyle_config: ../../config/checkstyle/checkstyle.xml
|
||||||
36
.github/workflows/java-ci.yml
vendored
Normal file
36
.github/workflows/java-ci.yml
vendored
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
name: Java CI
|
||||||
|
|
||||||
|
on: [ push, pull_request ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout latest code
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Set outputs
|
||||||
|
id: vars
|
||||||
|
run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
|
||||||
|
|
||||||
|
- name: Set up JDK 17
|
||||||
|
uses: actions/setup-java@v2
|
||||||
|
with:
|
||||||
|
distribution: 'temurin'
|
||||||
|
java-version: 17
|
||||||
|
|
||||||
|
- name: Setup build cache
|
||||||
|
uses: actions/cache@v2.1.6
|
||||||
|
with:
|
||||||
|
path: ~/.gradle/caches
|
||||||
|
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle.kts') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-gradle-
|
||||||
|
|
||||||
|
- run: ./gradlew build --full-stacktrace
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: eco-dev-${{ steps.vars.outputs.sha_short }}
|
||||||
|
path: build/libs
|
||||||
6
.github/workflows/publish-release.yml
vendored
6
.github/workflows/publish-release.yml
vendored
@@ -12,11 +12,11 @@ jobs:
|
|||||||
- name: Checkout latest code
|
- name: Checkout latest code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Set up JDK 16
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@v2
|
uses: actions/setup-java@v2
|
||||||
with:
|
with:
|
||||||
distribution: 'adopt'
|
distribution: 'temurin'
|
||||||
java-version: 16
|
java-version: 17
|
||||||
|
|
||||||
- name: Setup build cache
|
- name: Setup build cache
|
||||||
uses: actions/cache@v2.1.6
|
uses: actions/cache@v2.1.6
|
||||||
|
|||||||
42
.github/workflows/test-publish.yml
vendored
Normal file
42
.github/workflows/test-publish.yml
vendored
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
name: Publish API (Dev)
|
||||||
|
|
||||||
|
on: [ push, pull_request ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish-release:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout latest code
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Set outputs
|
||||||
|
id: vars
|
||||||
|
run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
|
||||||
|
|
||||||
|
- name: Set up JDK 17
|
||||||
|
uses: actions/setup-java@v2
|
||||||
|
with:
|
||||||
|
distribution: 'temurin'
|
||||||
|
java-version: 17
|
||||||
|
|
||||||
|
- name: Setup build cache
|
||||||
|
uses: actions/cache@v2.1.6
|
||||||
|
with:
|
||||||
|
path: ~/.gradle/caches
|
||||||
|
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle.kts') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-gradle-
|
||||||
|
|
||||||
|
|
||||||
|
- name: Publish artifact
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
# The GITHUB_REF tag comes in the format 'refs/tags/xxx'.
|
||||||
|
# So if we split on '/' and take the 3rd value, we can get the release name.
|
||||||
|
run: |
|
||||||
|
NEW_VERSION=$(echo "${GITHUB_REF}" | cut -d "/" -f3)
|
||||||
|
echo "New version: ${{ steps.vars.outputs.sha_short }}"
|
||||||
|
echo "Github username: ${GITHUB_ACTOR}"
|
||||||
|
./gradlew -Pversion=dev-${{ steps.vars.outputs.sha_short }} publish
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -14,6 +14,7 @@ bin/
|
|||||||
# Gradle
|
# Gradle
|
||||||
.gradle
|
.gradle
|
||||||
**/build/
|
**/build/
|
||||||
|
**/out/
|
||||||
!eco-api/src/**/build/
|
!eco-api/src/**/build/
|
||||||
.gradletasknamecache
|
.gradletasknamecache
|
||||||
!gradle-wrapper.jar
|
!gradle-wrapper.jar
|
||||||
|
|||||||
@@ -1,27 +1,38 @@
|
|||||||
# How to contribute to eco
|
# How to contribute to eco
|
||||||
|
|
||||||
## Codestyle
|
## Codestyle
|
||||||
|
|
||||||
1. The eco checkstyle is in /config/checkstyle.xml
|
1. The eco checkstyle is in /config/checkstyle.xml
|
||||||
|
|
||||||
- The pull request must not have any checkstyle issues.
|
- The pull request must not have any checkstyle issues.
|
||||||
- Every method and field must have a javadoc attached.
|
- Every method and field must have a javadoc attached.
|
||||||
|
|
||||||
2. Use lombok wherever possible.
|
2. Use JetBrains annotations
|
||||||
- @Getter, @Setter, @UtilityClass only.
|
|
||||||
|
|
||||||
3. Use JetBrains annotations
|
|
||||||
- Every parameter should be annotated with @NotNull or @Nullable
|
- Every parameter should be annotated with @NotNull or @Nullable
|
||||||
- Use @NotNull over lombok @NonNull
|
|
||||||
|
|
||||||
4. Imports
|
3. Imports
|
||||||
|
|
||||||
- No group (*) imports.
|
- No group (*) imports.
|
||||||
- No static imports.
|
- No static imports.
|
||||||
|
|
||||||
|
4. Kotlin
|
||||||
|
|
||||||
|
- Kotlin should be the only language used in the backend, java should be the only language used in the frontend.
|
||||||
|
- Kotlin API extensions should only be for creating extension functions and extra niceties that aren't possible in java.
|
||||||
|
Do not write API components in kotlin.
|
||||||
|
- Kotlin code should never be called directly from the frontend Java API. Kotlin API extensions should always rely on
|
||||||
|
java, not the other way round.
|
||||||
|
|
||||||
## Dependency Injection
|
## Dependency Injection
|
||||||
|
|
||||||
- eco uses Dependency Injection
|
- eco uses Dependency Injection
|
||||||
- Any calls to AbstractEcoPlugin#getInstance are code smells and should never be used unless **absolutely necessary**.
|
- Any calls to Eco#getHandler#getEcoPlugin are code smells and should never be used unless **absolutely necessary**.
|
||||||
- NamespacedKeys, FixedMetadataValues, Runnables, and Schedules should be managed using AbstractEcoPlugin through DI.
|
- NamespacedKeys, FixedMetadataValues, Runnables, and Schedules should be managed using AbstractEcoPlugin through DI.
|
||||||
- Any DI class should extend PluginDependent where possible. If the class extends another, then you **must** store the plugin instance in a private final variable called **plugin** with a private or protected getter.
|
- Any DI class should extend PluginDependent where possible. If the class extends another, then you **must** store the
|
||||||
|
plugin instance in a private final variable called **plugin** with a private or protected getter.
|
||||||
|
|
||||||
## Other
|
## Other
|
||||||
|
|
||||||
- All drops **must** be sent through a DropQueue - calls to World#dropItem will get your PR rejected.
|
- All drops **must** be sent through a DropQueue - calls to World#dropItem will get your PR rejected.
|
||||||
- eco is built with java 16.
|
- eco is built with java 17.
|
||||||
134
README.md
134
README.md
@@ -1,22 +1,45 @@
|
|||||||
<h1 align="center">
|
# eco
|
||||||
<br>
|
eco is a powerful Spigot development library that simplifies the process of plugin creation and supercharges
|
||||||
<img src="https://i.imgur.com/p5uR2Qp.png" alt="eco logo" width="256">
|
your plugins.
|
||||||
<br>
|
It's the engine behind [EcoEnchants](https://polymart.org/resource/490), [Reforges](https://polymart.org/resource/1330),
|
||||||
</h1>
|
[EcoItems](https://polymart.org/resource/1247), [EcoSkills](https://polymart.org/resource/1351),
|
||||||
|
[EcoArmor](https://polymart.org/resource/687), [Talismans](https://polymart.org/resource/611),
|
||||||
|
and many more.
|
||||||
|
|
||||||
<h4 align="center">eco - Simplify spigot development.</h4>
|
<p>
|
||||||
|
<a href="https://github.com/Auxilor/eco/releases">
|
||||||
|
<img alt="spigot" src="https://img.shields.io/github/v/release/Auxilor/eco?color=informational"/>
|
||||||
|
</a>
|
||||||
|
<a href="https://bstats.org/plugin/bukkit/EcoEnchants" alt="bstats servers">
|
||||||
|
<img src="https://img.shields.io/bstats/servers/7666?color=informational"/>
|
||||||
|
</a>
|
||||||
|
<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"/>
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
### Plugin Information
|
# For server owners
|
||||||
- Requires ProtocolLib to be installed: get the latest version [here](https://www.spigotmc.org/resources/protocollib.1997/)
|
- Requires ProtocolLib to be installed: get the latest version [here](https://www.spigotmc.org/resources/protocollib.1997/)
|
||||||
- Supports 1.16.5+
|
- Supports 1.17+
|
||||||
|
|
||||||
### bStats
|
## Downloads
|
||||||
<img src="https://bstats.org/signatures/bukkit/eco.svg" width="512">
|
|
||||||
|
|
||||||
# Information for development
|
- 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)
|
||||||
|
|
||||||
|
# For developers
|
||||||
|
|
||||||
## Javadoc
|
## Javadoc
|
||||||
The 6.0.0 Javadoc can be found [here](https://javadoc.jitpack.io/com/willfp/eco/6.0.0/javadoc/)
|
The 6.45.0 Javadoc can be found [here](https://javadoc.jitpack.io/com/willfp/eco/6.45.0/javadoc/)
|
||||||
|
|
||||||
## Plugin Information
|
## Plugin Information
|
||||||
|
|
||||||
@@ -28,13 +51,6 @@ depend:
|
|||||||
- eco
|
- eco
|
||||||
```
|
```
|
||||||
|
|
||||||
eco is available from any of these places:
|
|
||||||
|
|
||||||
- [GitHub](https://github.com/Auxilor/eco/releases)
|
|
||||||
- [Spigot](https://www.spigotmc.org/resources/eco.87955/)
|
|
||||||
- [Polymart](https://polymart.org/resource/eco.773)
|
|
||||||
- [Build it locally](https://github.com/Auxilor/eco#build-locally).
|
|
||||||
|
|
||||||
## Get from JitPack:
|
## Get from JitPack:
|
||||||
|
|
||||||
Gradle:
|
Gradle:
|
||||||
@@ -52,7 +68,7 @@ dependencies {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Replace `Tag` with a release tag for eco, eg `6.0.0`.
|
Replace `Tag` with a release tag for eco, eg `6.45.0`.
|
||||||
|
|
||||||
Maven:
|
Maven:
|
||||||
|
|
||||||
@@ -72,7 +88,7 @@ Maven:
|
|||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
|
|
||||||
Replace `Tag` with a release tag for eco, eg `6.0.0`.
|
Replace `Tag` with a release tag for eco, eg `6.45.0`.
|
||||||
|
|
||||||
## Build locally:
|
## Build locally:
|
||||||
|
|
||||||
@@ -85,81 +101,21 @@ cd eco
|
|||||||
./gradlew build
|
./gradlew build
|
||||||
```
|
```
|
||||||
|
|
||||||
# Features
|
|
||||||
|
|
||||||
Here's a list of some (not all) of the features of eco:
|
|
||||||
|
|
||||||
- Command system with subcommands
|
|
||||||
- Reworked config system
|
|
||||||
- JSON Config Support
|
|
||||||
- Client-Side item display
|
|
||||||
- World drop system
|
|
||||||
- Event manager
|
|
||||||
- PlayerJumpEvent
|
|
||||||
- ArmorEquipEvent
|
|
||||||
- EntityDeathByEntityEvent
|
|
||||||
- NaturalExpGainEvent
|
|
||||||
- Plugin extensions (Plugins for plugins)
|
|
||||||
- GUI System
|
|
||||||
- Integration system for external plugins
|
|
||||||
- Anticheat support
|
|
||||||
- AAC
|
|
||||||
- Matrix
|
|
||||||
- NCP
|
|
||||||
- Spartan
|
|
||||||
- Vulcan
|
|
||||||
- Antigrief/Combat support
|
|
||||||
- CombatLogX (V10 + V11)
|
|
||||||
- FactionsUUID
|
|
||||||
- GriefPrevention
|
|
||||||
- Kingdoms
|
|
||||||
- Lands
|
|
||||||
- Towny
|
|
||||||
- WorldGuard
|
|
||||||
- mcMMO support
|
|
||||||
- Custom Items support
|
|
||||||
- Oraxen
|
|
||||||
- PlaceholderAPI support
|
|
||||||
- NMS Proxy / Wrapper system built in
|
|
||||||
- Custom Items system
|
|
||||||
- Crafting Recipe handler
|
|
||||||
- Tuples
|
|
||||||
- Support uploading to / downloading from hastebin
|
|
||||||
- Packet System (via ProtocolLib)
|
|
||||||
- Dependency Injection systems
|
|
||||||
- Prerequisite system
|
|
||||||
- API additions (via utility classes)
|
|
||||||
- Get bow from arrow
|
|
||||||
- Break a block as a player
|
|
||||||
- Get a vein of blocks
|
|
||||||
- Create 2D lists
|
|
||||||
- Create NamespacedKeys safely
|
|
||||||
- Random number, distribution, roman numerals
|
|
||||||
- Set skull texture
|
|
||||||
- Format all strings
|
|
||||||
- Hex Support
|
|
||||||
- Gradient Support
|
|
||||||
- Placeholder Support
|
|
||||||
- Get a scoreboard team from any color
|
|
||||||
- Telekinesis (Drops straight to inventory) system
|
|
||||||
- More vector options
|
|
||||||
- Update checker
|
|
||||||
- bStats integration
|
|
||||||
- Reworked systems for:
|
|
||||||
- NamespacedKey
|
|
||||||
- MetadataValue
|
|
||||||
- Runnables / Scheduling
|
|
||||||
|
|
||||||
... and a lot more!
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
*Click here to read [the entire license](https://github.com/Auxilor/eco/blob/master/LICENSE.md).*
|
*Click here to read [the entire license](https://github.com/Auxilor/eco/blob/master/LICENSE.md).*
|
||||||
|
|
||||||
<h1 align="center">
|
<h1 align="center">
|
||||||
|
Check out our partners!
|
||||||
<br>
|
<br>
|
||||||
|
<div style="width: 50%; margin: 0 auto;">
|
||||||
|
<br>
|
||||||
|
<a href="https://gamersupps.gg/discount/Auxilor?afmc=Auxilor" target="_blank">
|
||||||
|
<img src="https://i.imgur.com/7mFhlQO.png" alt="supps banner">
|
||||||
|
</a>
|
||||||
<a href="https://dedimc.promo/Auxilor" target="_blank">
|
<a href="https://dedimc.promo/Auxilor" target="_blank">
|
||||||
<img src="https://i.imgur.com/zdDLhFA.png" alt="dedimc banner">
|
<img src="https://i.imgur.com/x9aeH38.png" alt="dedimc banner">
|
||||||
</a>
|
</a>
|
||||||
<br>
|
<br>
|
||||||
|
</div>
|
||||||
</h1>
|
</h1>
|
||||||
|
|||||||
103
build.gradle
103
build.gradle
@@ -1,103 +0,0 @@
|
|||||||
plugins {
|
|
||||||
id 'java-library'
|
|
||||||
id 'com.github.johnrengelman.shadow' version '7.0.0'
|
|
||||||
id 'maven-publish'
|
|
||||||
id 'java'
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation project(":eco-api")
|
|
||||||
implementation project(":eco-core").getSubprojects()
|
|
||||||
}
|
|
||||||
|
|
||||||
allprojects {
|
|
||||||
apply plugin: 'java'
|
|
||||||
apply plugin: 'java-library'
|
|
||||||
apply plugin: 'maven-publish'
|
|
||||||
apply plugin: 'com.github.johnrengelman.shadow'
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
mavenCentral()
|
|
||||||
mavenLocal()
|
|
||||||
maven { url 'https://jitpack.io' }
|
|
||||||
|
|
||||||
// NMS (for jitpack compilation)
|
|
||||||
maven { url 'https://repo.codemc.org/repository/nms/' }
|
|
||||||
|
|
||||||
// bStats, mcMMO
|
|
||||||
maven { url 'https://repo.codemc.org/repository/maven-public' }
|
|
||||||
|
|
||||||
// Spigot API
|
|
||||||
maven { url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' }
|
|
||||||
|
|
||||||
// PlaceholderAPI
|
|
||||||
maven { url 'https://repo.extendedclip.com/content/repositories/placeholderapi/' }
|
|
||||||
|
|
||||||
// ProtocolLib
|
|
||||||
maven { url 'https://repo.dmulloy2.net/nexus/repository/public/' }
|
|
||||||
|
|
||||||
// WorldGuard
|
|
||||||
maven { url 'https://maven.enginehub.org/repo/' }
|
|
||||||
|
|
||||||
// FactionsUUID
|
|
||||||
maven { url 'https://ci.ender.zone/plugin/repository/everything/' }
|
|
||||||
|
|
||||||
// NoCheatPlus
|
|
||||||
maven { url 'https://repo.md-5.net/content/repositories/snapshots/' }
|
|
||||||
|
|
||||||
// CombatLogX
|
|
||||||
maven { url 'https://nexus.sirblobman.xyz/repository/public/' }
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
compileOnly 'org.jetbrains:annotations:19.0.0'
|
|
||||||
|
|
||||||
// Lombok
|
|
||||||
compileOnly 'org.projectlombok:lombok:1.18.20'
|
|
||||||
annotationProcessor 'org.projectlombok:lombok:1.18.20'
|
|
||||||
testCompileOnly 'org.projectlombok:lombok:1.18.20'
|
|
||||||
testAnnotationProcessor 'org.projectlombok:lombok:1.18.20'
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.withType(JavaCompile) {
|
|
||||||
options.deprecation = true
|
|
||||||
options.encoding = 'UTF-8'
|
|
||||||
}
|
|
||||||
|
|
||||||
configurations.all {
|
|
||||||
exclude group: "org.codehaus.plexus", module: "plexus-utils"
|
|
||||||
exclude group: "com.mojang", module: "brigadier"
|
|
||||||
exclude group: "org.kitteh", module: "paste-gg-api"
|
|
||||||
exclude group: "org.kitteh", module: "pastegg"
|
|
||||||
exclude group: "org.spongepowered", module: "configurate-hocon"
|
|
||||||
exclude group: "com.darkblade12", module: "particleeffect"
|
|
||||||
exclude group: "com.github.cryptomorin", module: "XSeries"
|
|
||||||
}
|
|
||||||
|
|
||||||
shadowJar {
|
|
||||||
relocate('org.bstats.bukkit', 'com.willfp.eco.shaded.bstats')
|
|
||||||
}
|
|
||||||
|
|
||||||
jar {
|
|
||||||
onlyIf { !sourceSets.main.allSource.files.isEmpty() }
|
|
||||||
}
|
|
||||||
|
|
||||||
compileJava {
|
|
||||||
onlyIf { !sourceSets.main.allSource.files.isEmpty() }
|
|
||||||
}
|
|
||||||
|
|
||||||
java {
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_16
|
|
||||||
targetCompatibility = JavaVersion.VERSION_16
|
|
||||||
withSourcesJar()
|
|
||||||
}
|
|
||||||
|
|
||||||
compileJava.options.encoding = 'UTF-8'
|
|
||||||
compileJava.dependsOn clean
|
|
||||||
|
|
||||||
build.dependsOn shadowJar
|
|
||||||
}
|
|
||||||
|
|
||||||
group = 'com.willfp'
|
|
||||||
archivesBaseName = project.name
|
|
||||||
version = findProperty("version")
|
|
||||||
196
build.gradle.kts
Normal file
196
build.gradle.kts
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id("java-library")
|
||||||
|
id("com.github.johnrengelman.shadow") version "7.1.2"
|
||||||
|
id("maven-publish")
|
||||||
|
id("java")
|
||||||
|
kotlin("jvm") version "1.7.10"
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation(project(":eco-api"))
|
||||||
|
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"))
|
||||||
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
apply(plugin = "java")
|
||||||
|
apply(plugin = "java-library")
|
||||||
|
apply(plugin = "maven-publish")
|
||||||
|
apply(plugin = "com.github.johnrengelman.shadow")
|
||||||
|
apply(plugin = "kotlin")
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
mavenLocal()
|
||||||
|
maven("https://jitpack.io")
|
||||||
|
|
||||||
|
// CustomCrafting
|
||||||
|
maven("https://maven.wolfyscript.com/repository/public/")
|
||||||
|
|
||||||
|
// SuperiorSkyblock2
|
||||||
|
maven("https://repo.bg-software.com/repository/api/")
|
||||||
|
|
||||||
|
// mcMMO, BentoBox
|
||||||
|
maven("https://repo.codemc.io/repository/maven-public/")
|
||||||
|
|
||||||
|
// Spigot API, Bungee API
|
||||||
|
maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/")
|
||||||
|
|
||||||
|
// PlaceholderAPI
|
||||||
|
maven("https://repo.extendedclip.com/content/repositories/placeholderapi/")
|
||||||
|
|
||||||
|
// ProtocolLib
|
||||||
|
maven("https://repo.dmulloy2.net/nexus/repository/public/")
|
||||||
|
|
||||||
|
// WorldGuard
|
||||||
|
maven("https://maven.enginehub.org/repo/")
|
||||||
|
|
||||||
|
// FactionsUUID
|
||||||
|
//maven("https://ci.ender.zone/plugin/repository/everything/")
|
||||||
|
|
||||||
|
// NoCheatPlus
|
||||||
|
maven("https://repo.md-5.net/content/repositories/snapshots/")
|
||||||
|
|
||||||
|
// CombatLogX
|
||||||
|
maven("https://nexus.sirblobman.xyz/repository/public/")
|
||||||
|
|
||||||
|
// MythicMobs
|
||||||
|
maven("https://mvn.lumine.io/repository/maven-public/")
|
||||||
|
|
||||||
|
// Crunch
|
||||||
|
maven("https://redempt.dev")
|
||||||
|
|
||||||
|
// LibsDisguises
|
||||||
|
maven("https://repo.md-5.net/content/groups/public/")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
// 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
|
||||||
|
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
|
||||||
|
implementation("com.github.ben-manes.caffeine:caffeine:3.1.0")
|
||||||
|
implementation("org.apache.maven:maven-artifact:3.8.5")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType<JavaCompile> {
|
||||||
|
options.encoding = "UTF-8"
|
||||||
|
}
|
||||||
|
|
||||||
|
configurations.all {
|
||||||
|
exclude(group = "org.codehaus.plexus", module = "plexus-utils")
|
||||||
|
exclude(group = "com.mojang", module = "brigadier")
|
||||||
|
exclude(group = "org.kitteh", module = "paste-gg-api")
|
||||||
|
exclude(group = "org.kitteh", module = "pastegg")
|
||||||
|
exclude(group = "org.spongepowered", module = "configurate-hocon")
|
||||||
|
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(), configurations.implementation.get()))
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
compileKotlin {
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = "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 {
|
||||||
|
dependsOn(clean)
|
||||||
|
options.encoding = "UTF-8"
|
||||||
|
}
|
||||||
|
|
||||||
|
java {
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_17
|
||||||
|
targetCompatibility = JavaVersion.VERSION_17
|
||||||
|
withSourcesJar()
|
||||||
|
}
|
||||||
|
|
||||||
|
test {
|
||||||
|
useJUnitPlatform()
|
||||||
|
|
||||||
|
// Show test results.
|
||||||
|
testLogging {
|
||||||
|
events("passed", "skipped", "failed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
build {
|
||||||
|
dependsOn(shadowJar)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
group = "com.willfp"
|
||||||
|
version = findProperty("version")!!
|
||||||
@@ -32,10 +32,6 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<module name="Checker">
|
<module name="Checker">
|
||||||
<module name="SuppressionFilter">
|
|
||||||
<property name="file" value="config/checkstyle/suppression.xml"/>
|
|
||||||
</module>
|
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
If you set the basedir property below, then all reported file
|
If you set the basedir property below, then all reported file
|
||||||
names will be relative to the specified directory. See
|
names will be relative to the specified directory. See
|
||||||
@@ -45,7 +41,7 @@
|
|||||||
-->
|
-->
|
||||||
<property name="severity" value="error"/>
|
<property name="severity" value="error"/>
|
||||||
|
|
||||||
<property name="fileExtensions" value="java, properties, xml"/>
|
<property name="fileExtensions" value="java, properties, xml, kt"/>
|
||||||
|
|
||||||
<!-- Excludes all 'module-info.java' files -->
|
<!-- Excludes all 'module-info.java' files -->
|
||||||
<!-- See https://checkstyle.org/config_filefilters.html -->
|
<!-- See https://checkstyle.org/config_filefilters.html -->
|
||||||
@@ -66,6 +62,7 @@
|
|||||||
<module name="FileLength"/>
|
<module name="FileLength"/>
|
||||||
<module name="LineLength">
|
<module name="LineLength">
|
||||||
<property name="fileExtensions" value="java"/>
|
<property name="fileExtensions" value="java"/>
|
||||||
|
<property name="fileExtensions" value="kt"/>
|
||||||
<property name="max" value="200"/>
|
<property name="max" value="200"/>
|
||||||
</module>
|
</module>
|
||||||
|
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
|
|
||||||
<!DOCTYPE suppressions PUBLIC
|
|
||||||
"-//Puppy Crawl//DTD Suppressions 1.1//EN"
|
|
||||||
"http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
|
|
||||||
|
|
||||||
<suppressions>
|
|
||||||
<!-- Internals don't need javadoc. -->
|
|
||||||
<suppress files="[\\/]internal[\\/]" checks="MissingJavadocMethod"/>
|
|
||||||
<suppress files="[\\/]internal[\\/]" checks="JavadocVariable"/>
|
|
||||||
<suppress files="[\\/]eco[\\/]spigot[\\/]" checks="MissingJavadocMethod"/>
|
|
||||||
<suppress files="[\\/]eco[\\/]spigot[\\/]" checks="JavadocVariable"/>
|
|
||||||
<suppress files="[\\/]eco[\\/]proxy[\\/]" checks="MissingJavadocMethod"/>
|
|
||||||
<suppress files="[\\/]eco[\\/]proxy[\\/]" checks="JavadocVariable"/>
|
|
||||||
|
|
||||||
<!-- Modified version of library -->
|
|
||||||
<suppress files="ArmorEquipEvent.java" checks="JavadocVariable"/>
|
|
||||||
<suppress files="ArmorEquipEvent.java" checks="MissingJavadocMethod"/>
|
|
||||||
<suppress files="ArmorEquipEvent.java" checks="JavadocStyle"/>
|
|
||||||
<suppress files="ArmorListener.java" checks="JavadocVariable"/>
|
|
||||||
<suppress files="ArmorListener.java" checks="MissingJavadocMethod"/>
|
|
||||||
<suppress files="ArmorType.java" checks="JavadocVariable"/>
|
|
||||||
<suppress files="ArmorType.java" checks="MissingJavadocMethod"/>
|
|
||||||
</suppressions>
|
|
||||||
@@ -1,25 +1,20 @@
|
|||||||
plugins {
|
dependencies {
|
||||||
id 'com.github.johnrengelman.shadow'
|
// Adventure
|
||||||
|
compileOnly 'net.kyori:adventure-platform-bukkit:4.1.0'
|
||||||
|
|
||||||
|
// Other
|
||||||
|
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
|
||||||
|
compileOnly 'com.comphenix.protocol:ProtocolLib:4.6.1-SNAPSHOT'
|
||||||
|
compileOnly 'com.google.code.gson:gson:2.8.8'
|
||||||
}
|
}
|
||||||
|
|
||||||
group 'com.willfp'
|
group 'com.willfp'
|
||||||
version rootProject.version
|
version rootProject.version
|
||||||
|
|
||||||
dependencies {
|
|
||||||
compileOnly 'org.spigotmc:spigot-api:1.17-R0.1-SNAPSHOT'
|
|
||||||
compileOnly 'org.apache.maven:maven-artifact:3.0.3'
|
|
||||||
compileOnly 'org.bstats:bstats-bukkit:1.7'
|
|
||||||
compileOnly 'com.comphenix.protocol:ProtocolLib:4.6.0-SNAPSHOT'
|
|
||||||
compileOnly 'com.google.code.gson:gson:2.8.7'
|
|
||||||
}
|
|
||||||
|
|
||||||
java {
|
java {
|
||||||
withJavadocJar()
|
withJavadocJar()
|
||||||
}
|
}
|
||||||
|
|
||||||
compileJava.options.encoding = 'UTF-8'
|
|
||||||
compileJava.dependsOn clean
|
|
||||||
|
|
||||||
build.dependsOn publishToMavenLocal
|
build.dependsOn publishToMavenLocal
|
||||||
|
|
||||||
publishing {
|
publishing {
|
||||||
@@ -40,4 +35,4 @@ publishing {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import com.comphenix.protocol.events.ListenerPriority;
|
|||||||
import com.comphenix.protocol.events.PacketAdapter;
|
import com.comphenix.protocol.events.PacketAdapter;
|
||||||
import com.comphenix.protocol.events.PacketContainer;
|
import com.comphenix.protocol.events.PacketContainer;
|
||||||
import com.comphenix.protocol.events.PacketEvent;
|
import com.comphenix.protocol.events.PacketEvent;
|
||||||
import lombok.Getter;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
@@ -26,7 +25,6 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
|
|||||||
* <p>
|
* <p>
|
||||||
* Useful for monitor priority adapters that <b>must</b> be ran last.
|
* Useful for monitor priority adapters that <b>must</b> be ran last.
|
||||||
*/
|
*/
|
||||||
@Getter
|
|
||||||
private final boolean postLoad;
|
private final boolean postLoad;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -134,4 +132,13 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
|
|||||||
ProtocolLibrary.getProtocolManager().addPacketListener(this);
|
ProtocolLibrary.getProtocolManager().addPacketListener(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get if the packet adapter should be loaded last.
|
||||||
|
*
|
||||||
|
* @return If post load.
|
||||||
|
*/
|
||||||
|
public boolean isPostLoad() {
|
||||||
|
return this.postLoad;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,40 +1,560 @@
|
|||||||
package com.willfp.eco.core;
|
package com.willfp.eco.core;
|
||||||
|
|
||||||
import lombok.Getter;
|
import com.willfp.eco.core.config.ConfigType;
|
||||||
import lombok.experimental.UtilityClass;
|
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.apache.commons.lang.Validate;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.Mob;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.SkullMeta;
|
||||||
|
import org.bukkit.persistence.PersistentDataContainer;
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class to hold the handler.
|
* 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 Handler
|
* @see Eco#get()
|
||||||
*/
|
*/
|
||||||
@UtilityClass
|
@ApiStatus.Internal
|
||||||
public class Eco {
|
public interface Eco {
|
||||||
/**
|
/**
|
||||||
* Instance of eco handler.
|
* Create a scheduler.
|
||||||
* <p>
|
*
|
||||||
* The handler is, in essence, a way to interface between the eco-api
|
* @param plugin The plugin.
|
||||||
* frontend module, and the eco-backend implementations.
|
* @return The scheduler.
|
||||||
* <p>
|
|
||||||
* There shouldn't really be any reason to ever use the handler
|
|
||||||
* in your own plugins, but if you want to then you can - it's
|
|
||||||
* just a part of the API like any other.
|
|
||||||
*/
|
*/
|
||||||
@Getter
|
@NotNull
|
||||||
private Handler handler;
|
Scheduler createScheduler(@NotNull EcoPlugin plugin);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the handler.
|
* Create an event manager.
|
||||||
*
|
*
|
||||||
* @param handler The handler.
|
* @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.
|
||||||
|
*/
|
||||||
|
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();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 instance of eco; the bridge between the api frontend
|
||||||
|
* and the implementation backend.
|
||||||
|
*
|
||||||
|
* @return The instance of eco.
|
||||||
*/
|
*/
|
||||||
@ApiStatus.Internal
|
@ApiStatus.Internal
|
||||||
public void setHandler(@NotNull final Handler handler) {
|
static Eco get() {
|
||||||
Validate.isTrue(Eco.handler == null, "Already initialized!");
|
return Instance.get();
|
||||||
|
}
|
||||||
|
|
||||||
Eco.handler = handler;
|
/**
|
||||||
|
* Manages the internal frontend -> backend communication.
|
||||||
|
*/
|
||||||
|
@ApiStatus.Internal
|
||||||
|
final class Instance {
|
||||||
|
/**
|
||||||
|
* Instance of eco.
|
||||||
|
*/
|
||||||
|
@ApiStatus.Internal
|
||||||
|
private static Eco eco;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize eco.
|
||||||
|
*
|
||||||
|
* @param eco The instance of eco.
|
||||||
|
*/
|
||||||
|
@ApiStatus.Internal
|
||||||
|
static void set(@NotNull final Eco eco) {
|
||||||
|
Validate.isTrue(Instance.eco == null, "Already initialized!");
|
||||||
|
|
||||||
|
Instance.eco = eco;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get eco.
|
||||||
|
*
|
||||||
|
* @return eco.
|
||||||
|
*/
|
||||||
|
static Eco get() {
|
||||||
|
return eco;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Instance() {
|
||||||
|
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,23 +7,22 @@ import com.willfp.eco.core.config.updating.ConfigHandler;
|
|||||||
import com.willfp.eco.core.display.Display;
|
import com.willfp.eco.core.display.Display;
|
||||||
import com.willfp.eco.core.display.DisplayModule;
|
import com.willfp.eco.core.display.DisplayModule;
|
||||||
import com.willfp.eco.core.events.EventManager;
|
import com.willfp.eco.core.events.EventManager;
|
||||||
|
import com.willfp.eco.core.extensions.Extension;
|
||||||
import com.willfp.eco.core.extensions.ExtensionLoader;
|
import com.willfp.eco.core.extensions.ExtensionLoader;
|
||||||
import com.willfp.eco.core.factory.MetadataValueFactory;
|
import com.willfp.eco.core.factory.MetadataValueFactory;
|
||||||
import com.willfp.eco.core.factory.NamespacedKeyFactory;
|
import com.willfp.eco.core.factory.NamespacedKeyFactory;
|
||||||
import com.willfp.eco.core.factory.RunnableFactory;
|
import com.willfp.eco.core.factory.RunnableFactory;
|
||||||
import com.willfp.eco.core.integrations.IntegrationLoader;
|
import com.willfp.eco.core.integrations.IntegrationLoader;
|
||||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager;
|
|
||||||
import com.willfp.eco.core.proxy.AbstractProxy;
|
|
||||||
import com.willfp.eco.core.proxy.ProxyFactory;
|
import com.willfp.eco.core.proxy.ProxyFactory;
|
||||||
import com.willfp.eco.core.scheduling.Scheduler;
|
import com.willfp.eco.core.scheduling.Scheduler;
|
||||||
import com.willfp.eco.core.web.UpdateChecker;
|
import com.willfp.eco.core.web.UpdateChecker;
|
||||||
import lombok.Getter;
|
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
|
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
|
||||||
import org.bstats.bukkit.Metrics;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.metadata.FixedMetadataValue;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -33,6 +32,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -52,77 +52,66 @@ import java.util.stream.Collectors;
|
|||||||
* <b>IMPORTANT: When reloading a plugin, all runnables / tasks will
|
* <b>IMPORTANT: When reloading a plugin, all runnables / tasks will
|
||||||
* be cancelled.</b>
|
* be cancelled.</b>
|
||||||
*/
|
*/
|
||||||
public abstract class EcoPlugin extends JavaPlugin {
|
@SuppressWarnings("unused")
|
||||||
|
public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||||
/**
|
/**
|
||||||
* The spigot resource ID of the plugin.
|
* The polymart resource ID of the plugin.
|
||||||
*/
|
*/
|
||||||
@Getter
|
|
||||||
private final int resourceId;
|
private final int resourceId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The bStats resource ID of the plugin.
|
* The bStats resource ID of the plugin.
|
||||||
*/
|
*/
|
||||||
@Getter
|
|
||||||
private final int bStatsId;
|
private final int bStatsId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The package where proxy implementations are.
|
* The package where proxy implementations are.
|
||||||
*/
|
*/
|
||||||
@Getter
|
|
||||||
private final String proxyPackage;
|
private final String proxyPackage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The color of the plugin, used in messages.
|
* The color of the plugin, used in messages.
|
||||||
*/
|
*/
|
||||||
@Getter
|
|
||||||
private final String color;
|
private final String color;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loaded integrations.
|
* Loaded integrations.
|
||||||
*/
|
*/
|
||||||
@Getter
|
|
||||||
private final Set<String> loadedIntegrations = new HashSet<>();
|
private final Set<String> loadedIntegrations = new HashSet<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The internal plugin scheduler.
|
* The plugin scheduler.
|
||||||
*/
|
*/
|
||||||
@Getter
|
|
||||||
private final Scheduler scheduler;
|
private final Scheduler scheduler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The internal plugin Event Manager.
|
* The plugin Event Manager.
|
||||||
*/
|
*/
|
||||||
@Getter
|
|
||||||
private final EventManager eventManager;
|
private final EventManager eventManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Config.yml.
|
* Config.yml.
|
||||||
*/
|
*/
|
||||||
@Getter
|
|
||||||
private final ConfigYml configYml;
|
private final ConfigYml configYml;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lang.yml.
|
* Lang.yml.
|
||||||
*/
|
*/
|
||||||
@Getter
|
|
||||||
private final LangYml langYml;
|
private final LangYml langYml;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The internal factory to produce {@link org.bukkit.NamespacedKey}s.
|
* The factory to produce {@link org.bukkit.NamespacedKey}s.
|
||||||
*/
|
*/
|
||||||
@Getter
|
|
||||||
private final NamespacedKeyFactory namespacedKeyFactory;
|
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.
|
||||||
*/
|
*/
|
||||||
@Getter
|
|
||||||
private final MetadataValueFactory metadataValueFactory;
|
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.
|
||||||
*/
|
*/
|
||||||
@Getter
|
|
||||||
private final RunnableFactory runnableFactory;
|
private final RunnableFactory runnableFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -130,19 +119,16 @@ public abstract class EcoPlugin extends JavaPlugin {
|
|||||||
*
|
*
|
||||||
* @see com.willfp.eco.core.extensions.Extension
|
* @see com.willfp.eco.core.extensions.Extension
|
||||||
*/
|
*/
|
||||||
@Getter
|
|
||||||
private final ExtensionLoader extensionLoader;
|
private final ExtensionLoader extensionLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The handler class for updatable classes.
|
* The handler class for updatable classes.
|
||||||
*/
|
*/
|
||||||
@Getter
|
|
||||||
private final ConfigHandler configHandler;
|
private final ConfigHandler configHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The display module for the plugin.
|
* The display module for the plugin.
|
||||||
*/
|
*/
|
||||||
@Getter
|
|
||||||
private DisplayModule displayModule;
|
private DisplayModule displayModule;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -153,30 +139,57 @@ public abstract class EcoPlugin extends JavaPlugin {
|
|||||||
/**
|
/**
|
||||||
* If the server is running an outdated version of the plugin.
|
* If the server is running an outdated version of the plugin.
|
||||||
*/
|
*/
|
||||||
@Getter
|
|
||||||
private boolean outdated = false;
|
private boolean outdated = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the plugin supports extensions.
|
* If the plugin supports extensions.
|
||||||
*/
|
*/
|
||||||
@Getter
|
|
||||||
private final boolean supportingExtensions;
|
private final boolean supportingExtensions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The proxy factory.
|
* The proxy factory.
|
||||||
*/
|
*/
|
||||||
@Getter
|
@Nullable
|
||||||
private final ProxyFactory proxyFactory;
|
private final ProxyFactory proxyFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new plugin without a specified color, proxy support, spigot, or bStats.
|
* 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>
|
||||||
|
* Will read from eco.yml (like plugin.yml) to fetch values that would otherwise be passed
|
||||||
|
* into the constructor. If no eco.yml is present, the plugin will load without extension
|
||||||
|
* support, without proxy support, with no update-checker or bStats, and with the color white.
|
||||||
*/
|
*/
|
||||||
protected EcoPlugin() {
|
protected EcoPlugin() {
|
||||||
this("&f");
|
this((PluginProps) null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new plugin without proxy support, spigot, or bStats.
|
* Create a new plugin without proxy support, polymart, or bStats.
|
||||||
*
|
*
|
||||||
* @param color The color.
|
* @param color The color.
|
||||||
*/
|
*/
|
||||||
@@ -186,7 +199,7 @@ public abstract class EcoPlugin extends JavaPlugin {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new plugin unlinked to spigot and bStats.
|
* Create a new plugin unlinked to polymart and bStats.
|
||||||
*
|
*
|
||||||
* @param proxyPackage The package where proxy implementations are stored.
|
* @param proxyPackage The package where proxy implementations are stored.
|
||||||
* @param color The color of the plugin (used in messages, using standard formatting)
|
* @param color The color of the plugin (used in messages, using standard formatting)
|
||||||
@@ -199,7 +212,7 @@ public abstract class EcoPlugin extends JavaPlugin {
|
|||||||
/**
|
/**
|
||||||
* Create a new plugin without proxy or extension support.
|
* Create a new plugin without proxy or extension support.
|
||||||
*
|
*
|
||||||
* @param resourceId The spigot resource ID for the plugin.
|
* @param resourceId The polymart resource ID for the plugin.
|
||||||
* @param bStatsId The bStats resource ID for the plugin.
|
* @param bStatsId The bStats resource ID for the plugin.
|
||||||
* @param color The color of the plugin (used in messages, using standard formatting)
|
* @param color The color of the plugin (used in messages, using standard formatting)
|
||||||
*/
|
*/
|
||||||
@@ -212,7 +225,7 @@ public abstract class EcoPlugin extends JavaPlugin {
|
|||||||
/**
|
/**
|
||||||
* Create a new plugin without proxy support.
|
* Create a new plugin without proxy support.
|
||||||
*
|
*
|
||||||
* @param resourceId The spigot resource ID for the plugin.
|
* @param resourceId The polymart resource ID for the plugin.
|
||||||
* @param bStatsId The bStats resource ID for the plugin.
|
* @param bStatsId The bStats resource ID for the plugin.
|
||||||
* @param color The color of the plugin (used in messages, using standard formatting)
|
* @param color The color of the plugin (used in messages, using standard formatting)
|
||||||
* @param supportingExtensions If the plugin supports extensions.
|
* @param supportingExtensions If the plugin supports extensions.
|
||||||
@@ -227,7 +240,7 @@ public abstract class EcoPlugin extends JavaPlugin {
|
|||||||
/**
|
/**
|
||||||
* Create a new plugin without extension support.
|
* Create a new plugin without extension support.
|
||||||
*
|
*
|
||||||
* @param resourceId The spigot resource ID for the plugin.
|
* @param resourceId The polymart resource ID for the plugin.
|
||||||
* @param bStatsId The bStats resource ID for the plugin.
|
* @param bStatsId The bStats resource ID for the plugin.
|
||||||
* @param proxyPackage The package where proxy implementations are stored.
|
* @param proxyPackage The package where proxy implementations are stored.
|
||||||
* @param color The color of the plugin (used in messages, using standard formatting)
|
* @param color The color of the plugin (used in messages, using standard formatting)
|
||||||
@@ -242,7 +255,7 @@ public abstract class EcoPlugin extends JavaPlugin {
|
|||||||
/**
|
/**
|
||||||
* Create a new plugin.
|
* Create a new plugin.
|
||||||
*
|
*
|
||||||
* @param resourceId The spigot resource ID for the plugin.
|
* @param resourceId The polymart resource ID for the plugin.
|
||||||
* @param bStatsId The bStats resource ID for the plugin.
|
* @param bStatsId The bStats resource ID for the plugin.
|
||||||
* @param proxyPackage The package where proxy implementations are stored.
|
* @param proxyPackage The package where proxy implementations are stored.
|
||||||
* @param color The color of the plugin (used in messages, using standard formatting)
|
* @param color The color of the plugin (used in messages, using standard formatting)
|
||||||
@@ -253,62 +266,104 @@ public abstract class EcoPlugin extends JavaPlugin {
|
|||||||
@NotNull final String proxyPackage,
|
@NotNull final String proxyPackage,
|
||||||
@NotNull final String color,
|
@NotNull final String color,
|
||||||
final boolean supportingExtensions) {
|
final boolean supportingExtensions) {
|
||||||
|
this(
|
||||||
|
PluginProps.createSimple(
|
||||||
|
resourceId,
|
||||||
|
bStatsId,
|
||||||
|
proxyPackage,
|
||||||
|
color,
|
||||||
|
supportingExtensions
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new plugin.
|
||||||
|
*
|
||||||
|
* @param pluginProps The props. If left null, it will read from eco.yml.
|
||||||
|
*/
|
||||||
|
protected EcoPlugin(@Nullable final PluginProps pluginProps) {
|
||||||
/*
|
/*
|
||||||
The handler must be initialized before any plugin's constructors
|
Eco must be initialized before any plugin's constructors
|
||||||
are called, as the constructors call Eco#getHandler().
|
are called, as the constructors call Eco#get().
|
||||||
|
|
||||||
To fix this, EcoSpigotPlugin an abstract class and the 'actual'
|
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
|
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.
|
spigot plugin, but it is what it is.
|
||||||
|
|
||||||
There is probably a better way of doing it - maybe with
|
There is probably a better way of doing it - maybe with
|
||||||
some sort of HandlerCreator interface in order to still have
|
some sort of EcoCrater interface in order to still have
|
||||||
a standalone handler class, but then there would be an interface
|
a standalone eco class, but then there would be an interface
|
||||||
left in the API that doesn't really help anything.
|
left in the API that doesn't really help anything.
|
||||||
|
|
||||||
The other alternative would be do use reflection to get a 'createHandler'
|
The other alternative would be to use reflection to get a 'createEco'
|
||||||
method that only exists in EcoSpigotPlugin - but that feels really dirty
|
method that only exists in EcoSpigotPlugin - but that feels filthy,
|
||||||
and I'd rather only use reflection where necessary.
|
and I'd rather only use reflection where necessary.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (Eco.getHandler() == null && this instanceof Handler) {
|
if (Eco.get() == null && this instanceof Eco) {
|
||||||
/*
|
/*
|
||||||
This code is only ever called by EcoSpigotPlugin (EcoHandler)
|
This code is only ever called by EcoSpigotPlugin (EcoImpl)
|
||||||
as it's the first plugin to load and it is a handler.
|
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
|
Any other plugins will never call this code as eco will have already
|
||||||
will have already been initialized.
|
been initialized.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Eco.setHandler((Handler) this);
|
Eco.Instance.set((Eco) this);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert Eco.getHandler() != null;
|
assert Eco.get() != null;
|
||||||
|
|
||||||
this.resourceId = resourceId;
|
PluginProps generatedProps = Eco.get().getProps(pluginProps, this.getClass());
|
||||||
this.bStatsId = bStatsId;
|
generatedProps.validate();
|
||||||
this.proxyPackage = proxyPackage;
|
PluginProps props = this.mutateProps(generatedProps);
|
||||||
this.color = color;
|
props.validate();
|
||||||
this.supportingExtensions = supportingExtensions;
|
|
||||||
|
|
||||||
this.scheduler = Eco.getHandler().createScheduler(this);
|
this.resourceId = props.getResourceId();
|
||||||
this.eventManager = Eco.getHandler().createEventManager(this);
|
this.bStatsId = props.getBStatsId();
|
||||||
this.namespacedKeyFactory = Eco.getHandler().createNamespacedKeyFactory(this);
|
this.proxyPackage = props.getProxyPackage();
|
||||||
this.metadataValueFactory = Eco.getHandler().createMetadataValueFactory(this);
|
this.color = props.getColor();
|
||||||
this.runnableFactory = Eco.getHandler().createRunnableFactory(this);
|
this.supportingExtensions = props.isSupportingExtensions();
|
||||||
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.langYml = new LangYml(this);
|
this.proxyFactory = this.proxyPackage.equalsIgnoreCase("") ? null : Eco.get().createProxyFactory(this);
|
||||||
this.configYml = new ConfigYml(this);
|
this.logger = Eco.get().createLogger(this);
|
||||||
|
|
||||||
Eco.getHandler().addNewPlugin(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();
|
||||||
|
this.configYml = this.createConfigYml();
|
||||||
|
|
||||||
|
Eco.get().addNewPlugin(this);
|
||||||
|
|
||||||
|
/*
|
||||||
|
The minimum eco version check was moved here because it's very common
|
||||||
|
to add a lot of code in the constructor of plugins; meaning that the plugin
|
||||||
|
can throw errors without it being obvious to the user that the reason is that
|
||||||
|
they have an outdated version of eco installed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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!");
|
||||||
|
this.getLogger().severe("You must be on at least" + this.getMinimumEcoVersion());
|
||||||
|
this.getLogger().severe("Download the newest version here:");
|
||||||
|
this.getLogger().severe("https://polymart.org/download/773/recent/JSpprMspkuyecf5y1wQ2Jn8OoLQSQ_IW");
|
||||||
|
Bukkit.getPluginManager().disablePlugin(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -321,48 +376,40 @@ public abstract class EcoPlugin extends JavaPlugin {
|
|||||||
this.getLogger().info("");
|
this.getLogger().info("");
|
||||||
this.getLogger().info("Loading " + this.getColor() + this.getName());
|
this.getLogger().info("Loading " + this.getColor() + this.getName());
|
||||||
|
|
||||||
if (this.getResourceId() != 0) {
|
if (this.getResourceId() != 0 && !Eco.get().getEcoPlugin().getConfigYml().getBool("no-update-checker")) {
|
||||||
new UpdateChecker(this).getVersion(version -> {
|
new UpdateChecker(this).getVersion(version -> {
|
||||||
DefaultArtifactVersion currentVersion = new DefaultArtifactVersion(this.getDescription().getVersion());
|
DefaultArtifactVersion currentVersion = new DefaultArtifactVersion(this.getDescription().getVersion());
|
||||||
DefaultArtifactVersion mostRecentVersion = new DefaultArtifactVersion(version);
|
DefaultArtifactVersion mostRecentVersion = new DefaultArtifactVersion(version);
|
||||||
if (!(currentVersion.compareTo(mostRecentVersion) > 0 || currentVersion.equals(mostRecentVersion))) {
|
if (!(currentVersion.compareTo(mostRecentVersion) > 0 || currentVersion.equals(mostRecentVersion))) {
|
||||||
this.outdated = true;
|
this.outdated = true;
|
||||||
this.getScheduler().runTimer(() -> {
|
this.getLogger().warning(this.getName() + " is out of date! (Version " + this.getDescription().getVersion() + ")");
|
||||||
this.getLogger().info("&c " + this.getName() + " is out of date! (Version " + this.getDescription().getVersion() + ")");
|
this.getLogger().warning("The newest version is " + version);
|
||||||
this.getLogger().info("&cThe newest version is &f" + version);
|
this.getLogger().warning("Download the new version!");
|
||||||
this.getLogger().info("&cDownload the new version!");
|
|
||||||
}, 0, 864000);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
DefaultArtifactVersion runningVersion = new DefaultArtifactVersion(Eco.getHandler().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!");
|
|
||||||
this.getLogger().severe("You must be on at least" + this.getMinimumEcoVersion());
|
|
||||||
this.getLogger().severe("Download the newest version here:");
|
|
||||||
this.getLogger().severe("https://polymart.org/download/773/recent/JSpprMspkuyecf5y1wQ2Jn8OoLQSQ_IW");
|
|
||||||
Bukkit.getPluginManager().disablePlugin(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.getBStatsId() != 0) {
|
if (this.getBStatsId() != 0) {
|
||||||
new Metrics(this, this.getBStatsId());
|
Eco.get().registerBStats(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<String> enabledPlugins = Arrays.stream(Bukkit.getPluginManager().getPlugins()).map(Plugin::getName).collect(Collectors.toSet());
|
Set<String> enabledPlugins = Arrays.stream(Bukkit.getPluginManager().getPlugins())
|
||||||
|
.map(Plugin::getName)
|
||||||
|
.map(String::toLowerCase)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
if (enabledPlugins.contains("PlaceholderAPI")) {
|
if (enabledPlugins.contains("PlaceholderAPI".toLowerCase())) {
|
||||||
this.loadedIntegrations.add("PlaceholderAPI");
|
Eco.get().createPAPIIntegration(this);
|
||||||
PlaceholderManager.addIntegration(Eco.getHandler().createPAPIIntegration(this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loadIntegrationLoaders().forEach((integrationLoader -> {
|
this.loadIntegrationLoaders().forEach(integrationLoader -> {
|
||||||
if (enabledPlugins.contains(integrationLoader.getPluginName())) {
|
if (enabledPlugins.contains(integrationLoader.getPluginName().toLowerCase())) {
|
||||||
this.loadedIntegrations.add(integrationLoader.getPluginName());
|
this.loadedIntegrations.add(integrationLoader.getPluginName());
|
||||||
integrationLoader.load();
|
integrationLoader.load();
|
||||||
}
|
}
|
||||||
}));
|
});
|
||||||
|
|
||||||
|
this.loadedIntegrations.removeIf(pl -> pl.equalsIgnoreCase(this.getName()));
|
||||||
|
|
||||||
this.getLogger().info("Loaded integrations: " + String.join(", ", this.getLoadedIntegrations()));
|
this.getLogger().info("Loaded integrations: " + String.join(", ", this.getLoadedIntegrations()));
|
||||||
|
|
||||||
@@ -392,10 +439,20 @@ public abstract class EcoPlugin extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.handleEnable();
|
this.handleEnable();
|
||||||
|
this.onEnable.forEach(Runnable::run);
|
||||||
|
|
||||||
this.getLogger().info("");
|
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.
|
* Default code to be executed on plugin disable.
|
||||||
*/
|
*/
|
||||||
@@ -405,16 +462,25 @@ public abstract class EcoPlugin extends JavaPlugin {
|
|||||||
|
|
||||||
this.getEventManager().unregisterAllListeners();
|
this.getEventManager().unregisterAllListeners();
|
||||||
this.getScheduler().cancelAll();
|
this.getScheduler().cancelAll();
|
||||||
this.getConfigHandler().saveAllConfigs();
|
|
||||||
|
|
||||||
this.handleDisable();
|
this.handleDisable();
|
||||||
|
this.onDisable.forEach(Runnable::run);
|
||||||
|
|
||||||
if (this.isSupportingExtensions()) {
|
if (this.isSupportingExtensions()) {
|
||||||
this.getExtensionLoader().unloadExtensions();
|
this.getExtensionLoader().unloadExtensions();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.getLogger().info("Cleaning up...");
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -425,6 +491,16 @@ public abstract class EcoPlugin extends JavaPlugin {
|
|||||||
super.onLoad();
|
super.onLoad();
|
||||||
|
|
||||||
this.handleLoad();
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -457,23 +533,64 @@ public abstract class EcoPlugin extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.handleAfterLoad();
|
this.handleAfterLoad();
|
||||||
|
this.afterLoad.forEach(Runnable::run);
|
||||||
|
|
||||||
this.reload();
|
this.reload();
|
||||||
|
|
||||||
|
for (Extension extension : this.getExtensionLoader().getLoadedExtensions()) {
|
||||||
|
extension.handleAfterLoad();
|
||||||
|
}
|
||||||
|
|
||||||
this.getLogger().info("Loaded " + this.color + this.getName());
|
this.getLogger().info("Loaded " + this.color + this.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default code to be executed on plugin reload.
|
* 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() {
|
public final void reload() {
|
||||||
this.getConfigHandler().updateConfigs();
|
this.getConfigHandler().updateConfigs();
|
||||||
|
|
||||||
|
this.getScheduler().cancelAll();
|
||||||
this.getConfigHandler().callUpdate();
|
this.getConfigHandler().callUpdate();
|
||||||
this.getConfigHandler().callUpdate(); // Call twice to fix issues
|
this.getConfigHandler().callUpdate(); // Call twice to fix issues
|
||||||
this.getScheduler().cancelAll();
|
|
||||||
|
|
||||||
this.handleReload();
|
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.
|
||||||
|
*
|
||||||
|
* @return The time.
|
||||||
|
*/
|
||||||
|
public final long reloadWithTime() {
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
this.reload();
|
||||||
|
|
||||||
|
return System.currentTimeMillis() - startTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -523,6 +640,21 @@ public abstract class EcoPlugin extends JavaPlugin {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mutate the plugin props.
|
||||||
|
* <p>
|
||||||
|
* Useful for eco-based plugin libraries to enforce certain properties, such as
|
||||||
|
* forcing extensions to be enabled.
|
||||||
|
* <p>
|
||||||
|
* Props are validated both before and after calling this method.
|
||||||
|
*
|
||||||
|
* @param props The props.
|
||||||
|
* @return The mutated props.
|
||||||
|
*/
|
||||||
|
protected PluginProps mutateProps(@NotNull final PluginProps props) {
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The plugin-specific integrations to be tested and loaded.
|
* The plugin-specific integrations to be tested and loaded.
|
||||||
*
|
*
|
||||||
@@ -559,6 +691,28 @@ public abstract class EcoPlugin extends JavaPlugin {
|
|||||||
*/
|
*/
|
||||||
protected abstract List<Listener> loadListeners();
|
protected abstract List<Listener> loadListeners();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Useful for custom LangYml implementations.
|
||||||
|
* <p>
|
||||||
|
* Override if needed.
|
||||||
|
*
|
||||||
|
* @return lang.yml.
|
||||||
|
*/
|
||||||
|
protected LangYml createLangYml() {
|
||||||
|
return new LangYml(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Useful for custom ConfigYml implementations.
|
||||||
|
* <p>
|
||||||
|
* Override if needed.
|
||||||
|
*
|
||||||
|
* @return config.yml.
|
||||||
|
*/
|
||||||
|
protected ConfigYml createConfigYml() {
|
||||||
|
return new ConfigYml(this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the display module for the plugin.
|
* Create the display module for the plugin.
|
||||||
*
|
*
|
||||||
@@ -601,8 +755,8 @@ public abstract class EcoPlugin extends JavaPlugin {
|
|||||||
* @param <T> The proxy type.
|
* @param <T> The proxy type.
|
||||||
* @return The proxy.
|
* @return The proxy.
|
||||||
*/
|
*/
|
||||||
public <T extends AbstractProxy> T getProxy(@NotNull final Class<T> proxyClass) {
|
public final <T> T getProxy(@NotNull final Class<T> proxyClass) {
|
||||||
Validate.notNull(proxyFactory, "Plugin does not support proxy!");
|
Validate.notNull(proxyFactory, "Plugin does not support proxies!");
|
||||||
|
|
||||||
return proxyFactory.getProxy(proxyClass);
|
return proxyFactory.getProxy(proxyClass);
|
||||||
}
|
}
|
||||||
@@ -620,7 +774,7 @@ public abstract class EcoPlugin extends JavaPlugin {
|
|||||||
public final FileConfiguration getConfig() {
|
public final FileConfiguration getConfig() {
|
||||||
this.getLogger().warning("Call to default config method in eco plugin!");
|
this.getLogger().warning("Call to default config method in eco plugin!");
|
||||||
|
|
||||||
return this.getConfigYml().getBukkitHandle();
|
return Objects.requireNonNull(this.getConfigYml().toBukkit());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -669,7 +823,7 @@ public abstract class EcoPlugin extends JavaPlugin {
|
|||||||
* @return The plugin.
|
* @return The plugin.
|
||||||
*/
|
*/
|
||||||
public static EcoPlugin getPlugin(@NotNull final String pluginName) {
|
public static EcoPlugin getPlugin(@NotNull final String pluginName) {
|
||||||
return Eco.getHandler().getPluginByName(pluginName);
|
return Eco.get().getPluginByName(pluginName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -678,6 +832,192 @@ public abstract class EcoPlugin extends JavaPlugin {
|
|||||||
* @return The set of names.
|
* @return The set of names.
|
||||||
*/
|
*/
|
||||||
public static Set<String> getPluginNames() {
|
public static Set<String> getPluginNames() {
|
||||||
return new HashSet<>(Eco.getHandler().getLoadedPlugins());
|
return new HashSet<>(Eco.get().getLoadedPlugins());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the polymart resource ID.
|
||||||
|
*
|
||||||
|
* @return The resource ID.
|
||||||
|
*/
|
||||||
|
public int getResourceId() {
|
||||||
|
return this.resourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the bStats ID.
|
||||||
|
*
|
||||||
|
* @return The ID.
|
||||||
|
*/
|
||||||
|
public int getBStatsId() {
|
||||||
|
return this.bStatsId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the proxy package.
|
||||||
|
*
|
||||||
|
* @return The package where proxies are contained.
|
||||||
|
*/
|
||||||
|
public String getProxyPackage() {
|
||||||
|
return this.proxyPackage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the plugin color (uses legacy formatting).
|
||||||
|
*
|
||||||
|
* @return The color.
|
||||||
|
*/
|
||||||
|
public String getColor() {
|
||||||
|
return this.color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all loaded integration names.
|
||||||
|
*
|
||||||
|
* @return The integrations.
|
||||||
|
*/
|
||||||
|
public Set<String> getLoadedIntegrations() {
|
||||||
|
return this.loadedIntegrations;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the scheduler.
|
||||||
|
*
|
||||||
|
* @return The scheduler.
|
||||||
|
*/
|
||||||
|
public Scheduler getScheduler() {
|
||||||
|
return this.scheduler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the event manager.
|
||||||
|
*
|
||||||
|
* @return The event manager.
|
||||||
|
*/
|
||||||
|
public EventManager getEventManager() {
|
||||||
|
return this.eventManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get config.yml.
|
||||||
|
*
|
||||||
|
* @return config.yml.
|
||||||
|
*/
|
||||||
|
public ConfigYml getConfigYml() {
|
||||||
|
return this.configYml;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get lang.yml.
|
||||||
|
*
|
||||||
|
* @return lang.yml.
|
||||||
|
*/
|
||||||
|
public LangYml getLangYml() {
|
||||||
|
return this.langYml;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the NamespacedKey factory.
|
||||||
|
*
|
||||||
|
* @return The factory.
|
||||||
|
*/
|
||||||
|
public NamespacedKeyFactory getNamespacedKeyFactory() {
|
||||||
|
return this.namespacedKeyFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the metadata value factory.
|
||||||
|
*
|
||||||
|
* @return The factory.
|
||||||
|
*/
|
||||||
|
public MetadataValueFactory getMetadataValueFactory() {
|
||||||
|
return this.metadataValueFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the runnable factory.
|
||||||
|
*
|
||||||
|
* @return The runnable factory.
|
||||||
|
*/
|
||||||
|
public RunnableFactory getRunnableFactory() {
|
||||||
|
return this.runnableFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the extension loader.
|
||||||
|
*
|
||||||
|
* @return The extension loader.
|
||||||
|
*/
|
||||||
|
public ExtensionLoader getExtensionLoader() {
|
||||||
|
return this.extensionLoader;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the config handler.
|
||||||
|
*
|
||||||
|
* @return The config handler.
|
||||||
|
*/
|
||||||
|
public ConfigHandler getConfigHandler() {
|
||||||
|
return this.configHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the plugin's display module.
|
||||||
|
*
|
||||||
|
* @return The display module.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public DisplayModule getDisplayModule() {
|
||||||
|
return this.displayModule;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get if the plugin is outdated.
|
||||||
|
*
|
||||||
|
* @return If outdated.
|
||||||
|
*/
|
||||||
|
public boolean isOutdated() {
|
||||||
|
return this.outdated;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get if the plugin supports extensions.
|
||||||
|
*
|
||||||
|
* @return If extensions are supported.
|
||||||
|
*/
|
||||||
|
public boolean isSupportingExtensions() {
|
||||||
|
return this.supportingExtensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the proxy factory.
|
||||||
|
*
|
||||||
|
* @return The proxy factory.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
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,161 +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.drops.DropQueueFactory;
|
|
||||||
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.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 org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see Eco
|
|
||||||
*/
|
|
||||||
public interface Handler {
|
|
||||||
/**
|
|
||||||
* Create a scheduler.
|
|
||||||
*
|
|
||||||
* @param plugin The plugin.
|
|
||||||
* @return The scheduler.
|
|
||||||
*/
|
|
||||||
Scheduler createScheduler(@NotNull EcoPlugin plugin);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an event manager.
|
|
||||||
*
|
|
||||||
* @param plugin The plugin.
|
|
||||||
* @return The event manager.
|
|
||||||
*/
|
|
||||||
EventManager createEventManager(@NotNull EcoPlugin plugin);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a NamespacedKey factory.
|
|
||||||
*
|
|
||||||
* @param plugin The plugin.
|
|
||||||
* @return The factory.
|
|
||||||
*/
|
|
||||||
NamespacedKeyFactory createNamespacedKeyFactory(@NotNull EcoPlugin plugin);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a MetadataValue factory.
|
|
||||||
*
|
|
||||||
* @param plugin The plugin.
|
|
||||||
* @return The factory.
|
|
||||||
*/
|
|
||||||
MetadataValueFactory createMetadataValueFactory(@NotNull EcoPlugin plugin);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a Runnable factory.
|
|
||||||
*
|
|
||||||
* @param plugin The plugin.
|
|
||||||
* @return The factory.
|
|
||||||
*/
|
|
||||||
RunnableFactory createRunnableFactory(@NotNull EcoPlugin plugin);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an ExtensionLoader.
|
|
||||||
*
|
|
||||||
* @param plugin The plugin.
|
|
||||||
* @return The factory.
|
|
||||||
*/
|
|
||||||
ExtensionLoader createExtensionLoader(@NotNull EcoPlugin plugin);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a config handler.
|
|
||||||
*
|
|
||||||
* @param plugin The plugin.
|
|
||||||
* @return The handler.
|
|
||||||
*/
|
|
||||||
ConfigHandler createConfigHandler(@NotNull EcoPlugin plugin);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a logger.
|
|
||||||
*
|
|
||||||
* @param plugin The plugin.
|
|
||||||
* @return The logger.
|
|
||||||
*/
|
|
||||||
Logger createLogger(@NotNull EcoPlugin plugin);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a PAPI integration.
|
|
||||||
*
|
|
||||||
* @param plugin The plugin.
|
|
||||||
* @return The integration.
|
|
||||||
*/
|
|
||||||
PlaceholderIntegration createPAPIIntegration(@NotNull EcoPlugin plugin);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a proxy factory.
|
|
||||||
*
|
|
||||||
* @param plugin The plugin.
|
|
||||||
* @return The factory.
|
|
||||||
*/
|
|
||||||
ProxyFactory createProxyFactory(@NotNull EcoPlugin plugin);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get eco Spigot plugin.
|
|
||||||
*
|
|
||||||
* @return The plugin.
|
|
||||||
*/
|
|
||||||
EcoPlugin getEcoPlugin();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get config factory.
|
|
||||||
*
|
|
||||||
* @return The factory.
|
|
||||||
*/
|
|
||||||
ConfigFactory getConfigFactory();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get drop queue factory.
|
|
||||||
*
|
|
||||||
* @return The factory.
|
|
||||||
*/
|
|
||||||
DropQueueFactory getDropQueueFactory();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get GUI factory.
|
|
||||||
*
|
|
||||||
* @return The factory.
|
|
||||||
*/
|
|
||||||
GUIFactory getGUIFactory();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get cleaner.
|
|
||||||
*
|
|
||||||
* @return The cleaner.
|
|
||||||
*/
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
EcoPlugin getPluginByName(@NotNull String name);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all loaded eco plugins.
|
|
||||||
*
|
|
||||||
* @return A list of plugin names in lowercase.
|
|
||||||
*/
|
|
||||||
List<String> getLoadedPlugins();
|
|
||||||
}
|
|
||||||
@@ -1,19 +1,26 @@
|
|||||||
package com.willfp.eco.core;
|
package com.willfp.eco.core;
|
||||||
|
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.Getter;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Quick DI class to manage passing eco plugins.
|
* Quick DI class to manage passing eco plugins.
|
||||||
|
* <p>
|
||||||
|
* Basically just a quick bit of laziness if you can't be bothered to add a private field
|
||||||
|
* and a protected getter, don't use this in kotlin as you can just specify
|
||||||
|
* {@code
|
||||||
|
* private val plugin: EcoPlugin
|
||||||
|
* }
|
||||||
|
* in the constructor.
|
||||||
*
|
*
|
||||||
* @param <T> The eco plugin type.
|
* @param <T> The eco plugin type.
|
||||||
|
* @deprecated Leaky inheritance, shouldn't exist.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(since = "6.43.0", forRemoval = true)
|
||||||
public abstract class PluginDependent<T extends EcoPlugin> {
|
public abstract class PluginDependent<T extends EcoPlugin> {
|
||||||
/**
|
/**
|
||||||
* The {@link EcoPlugin} that is stored.
|
* The {@link EcoPlugin} that is stored.
|
||||||
*/
|
*/
|
||||||
@Getter(AccessLevel.PROTECTED)
|
@NotNull
|
||||||
private final T plugin;
|
private final T plugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -24,4 +31,14 @@ public abstract class PluginDependent<T extends EcoPlugin> {
|
|||||||
protected PluginDependent(@NotNull final T plugin) {
|
protected PluginDependent(@NotNull final T plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the plugin.
|
||||||
|
*
|
||||||
|
* @return The plugin.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
protected T getPlugin() {
|
||||||
|
return this.plugin;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
37
eco-api/src/main/java/com/willfp/eco/core/PluginLike.java
Normal file
37
eco-api/src/main/java/com/willfp/eco/core/PluginLike.java
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package com.willfp.eco.core;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.config.updating.ConfigHandler;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents any class that acts like a plugin, for example {@link EcoPlugin}
|
||||||
|
* or {@link com.willfp.eco.core.extensions.Extension}. This exists to create
|
||||||
|
* things such as extension base configs rather than needing to pass an instance
|
||||||
|
* of the owning plugin.
|
||||||
|
*/
|
||||||
|
public interface PluginLike {
|
||||||
|
/**
|
||||||
|
* Get the data folder of the object.
|
||||||
|
* <p>
|
||||||
|
* Returns the plugin data folder for a plugin, or the extension's parent plugin's folder
|
||||||
|
*
|
||||||
|
* @return The data folder.
|
||||||
|
*/
|
||||||
|
File getDataFolder();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the handler class for updatable classes.
|
||||||
|
*
|
||||||
|
* @return The config handler.
|
||||||
|
*/
|
||||||
|
ConfigHandler getConfigHandler();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the logger.
|
||||||
|
*
|
||||||
|
* @return The logger.
|
||||||
|
*/
|
||||||
|
Logger getLogger();
|
||||||
|
}
|
||||||
273
eco-api/src/main/java/com/willfp/eco/core/PluginProps.java
Normal file
273
eco-api/src/main/java/com/willfp/eco/core/PluginProps.java
Normal file
@@ -0,0 +1,273 @@
|
|||||||
|
package com.willfp.eco.core;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plugin props are the arguments related to the plugin that are required on start-up.
|
||||||
|
* <p>
|
||||||
|
* This class is complex in how it works intentionally. This is done so that fields can be
|
||||||
|
* added to the props without breaking API backwards compatibility. Thus, there is no public
|
||||||
|
* constructor and no way to instantiate props without creating a parser.
|
||||||
|
*/
|
||||||
|
public final class PluginProps {
|
||||||
|
/**
|
||||||
|
* All registered parsers.
|
||||||
|
*/
|
||||||
|
private static final Map<Class<?>, PropsParser<?>> REGISTERED_PARSERS = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The polymart resource ID.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private Integer resourceId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The bStats ID.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private Integer bStatsId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The proxy package.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private String proxyPackage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The color.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private String color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If extensions are supported.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private Boolean supportingExtensions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new blank props.
|
||||||
|
*/
|
||||||
|
private PluginProps() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get resource ID.
|
||||||
|
*
|
||||||
|
* @return The resource ID.
|
||||||
|
*/
|
||||||
|
public int getResourceId() {
|
||||||
|
assert resourceId != null;
|
||||||
|
return resourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set resource ID.
|
||||||
|
*
|
||||||
|
* @param resourceId The resource ID.
|
||||||
|
*/
|
||||||
|
public void setResourceId(final int resourceId) {
|
||||||
|
this.resourceId = resourceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get bStats ID.
|
||||||
|
*
|
||||||
|
* @return The bStats ID.
|
||||||
|
*/
|
||||||
|
public int getBStatsId() {
|
||||||
|
assert bStatsId != null;
|
||||||
|
return bStatsId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set bStats ID.
|
||||||
|
*
|
||||||
|
* @param bStatsId The bStats ID.
|
||||||
|
*/
|
||||||
|
public void setBStatsId(final int bStatsId) {
|
||||||
|
this.bStatsId = bStatsId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the proxy package.
|
||||||
|
*
|
||||||
|
* @return The package.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public String getProxyPackage() {
|
||||||
|
assert proxyPackage != null;
|
||||||
|
return proxyPackage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the proxy package.
|
||||||
|
*
|
||||||
|
* @param proxyPackage The proxy package.
|
||||||
|
*/
|
||||||
|
public void setProxyPackage(@NotNull final String proxyPackage) {
|
||||||
|
this.proxyPackage = proxyPackage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get color.
|
||||||
|
*
|
||||||
|
* @return The color.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public String getColor() {
|
||||||
|
assert color != null;
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the color.
|
||||||
|
*
|
||||||
|
* @param color The color.
|
||||||
|
*/
|
||||||
|
public void setColor(@NotNull final String color) {
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get if extensions are supported.
|
||||||
|
*
|
||||||
|
* @return If supported.
|
||||||
|
*/
|
||||||
|
public boolean isSupportingExtensions() {
|
||||||
|
assert supportingExtensions != null;
|
||||||
|
return supportingExtensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set if extensions are supported.
|
||||||
|
*
|
||||||
|
* @param supportingExtensions If supported.
|
||||||
|
*/
|
||||||
|
public void setSupportingExtensions(final boolean supportingExtensions) {
|
||||||
|
this.supportingExtensions = supportingExtensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure that all required props have been set.
|
||||||
|
*/
|
||||||
|
public void validate() {
|
||||||
|
if (
|
||||||
|
supportingExtensions == null
|
||||||
|
|| proxyPackage == null
|
||||||
|
|| color == null
|
||||||
|
|| bStatsId == null
|
||||||
|
|| resourceId == null
|
||||||
|
) {
|
||||||
|
throw new IllegalStateException("Missing required props!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse props from source.
|
||||||
|
*
|
||||||
|
* @param source The source.
|
||||||
|
* @param sourceClass The source class.
|
||||||
|
* @param <T> The source type.
|
||||||
|
* @return The props.
|
||||||
|
*/
|
||||||
|
public static <T> PluginProps parse(@NotNull final T source,
|
||||||
|
@NotNull final Class<? extends T> sourceClass) {
|
||||||
|
for (Map.Entry<Class<?>, PropsParser<?>> entry : REGISTERED_PARSERS.entrySet()) {
|
||||||
|
Class<?> clazz = entry.getKey();
|
||||||
|
|
||||||
|
if (clazz.equals(sourceClass)) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
PropsParser<T> parser = (PropsParser<T>) entry.getValue();
|
||||||
|
return parser.parseFrom(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("No parser exists for class " + sourceClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a parser for a type.
|
||||||
|
*
|
||||||
|
* @param clazz The class.
|
||||||
|
* @param parser The parser.
|
||||||
|
* @param <T> The source type.
|
||||||
|
*/
|
||||||
|
public static <T> void registerParser(@NotNull final Class<T> clazz,
|
||||||
|
@NotNull final PropsParser<T> parser) {
|
||||||
|
REGISTERED_PARSERS.put(clazz, parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get if there is a registered parser for a class.
|
||||||
|
*
|
||||||
|
* @param clazz The class.
|
||||||
|
* @return If there is a parser registered.
|
||||||
|
*/
|
||||||
|
public static boolean hasParserFor(@NotNull final Class<?> clazz) {
|
||||||
|
for (Class<?> test : REGISTERED_PARSERS.keySet()) {
|
||||||
|
if (test.equals(clazz)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new props from known values.
|
||||||
|
*
|
||||||
|
* Marked as internal as this method will break whenever the properties themselves
|
||||||
|
* are updated (e.g. if a new property is added) - so to prevent any potential
|
||||||
|
* backwards-compatibility bugs, this method cannot be invoked outside eco itself.
|
||||||
|
*
|
||||||
|
* @param resourceId The ID of the plugin on polymart.
|
||||||
|
* @param bStatsId The ID of the plugin on bStats.
|
||||||
|
* @param proxyPackage The package where proxies can be found.
|
||||||
|
* @param color The primary color of the plugin.
|
||||||
|
* @param supportsExtensions If the plugin should attempt to look for extensions.
|
||||||
|
* @return The props.
|
||||||
|
*/
|
||||||
|
static PluginProps createSimple(final int resourceId,
|
||||||
|
final int bStatsId,
|
||||||
|
@NotNull final String proxyPackage,
|
||||||
|
@NotNull final String color,
|
||||||
|
final boolean supportsExtensions) {
|
||||||
|
PluginProps props = new PluginProps();
|
||||||
|
props.setResourceId(resourceId);
|
||||||
|
props.setBStatsId(bStatsId);
|
||||||
|
props.setProxyPackage(proxyPackage);
|
||||||
|
props.setColor(color);
|
||||||
|
props.setSupportingExtensions(supportsExtensions);
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse arguments into props for a plugin.
|
||||||
|
*
|
||||||
|
* @param <T> The type of source.
|
||||||
|
*/
|
||||||
|
public interface PropsParser<T> {
|
||||||
|
/**
|
||||||
|
* Parse props from a given source.
|
||||||
|
*
|
||||||
|
* @param source The source.
|
||||||
|
* @return The props.
|
||||||
|
*/
|
||||||
|
PluginProps parseFrom(@NotNull T source);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a new, blank props instance.
|
||||||
|
*
|
||||||
|
* @return Blank props.
|
||||||
|
*/
|
||||||
|
default PluginProps getBlankProps() {
|
||||||
|
return new PluginProps();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package com.willfp.eco.core;
|
package com.willfp.eco.core;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.integrations.economy.EconomyManager;
|
||||||
import com.willfp.eco.core.proxy.ProxyConstants;
|
import com.willfp.eco.core.proxy.ProxyConstants;
|
||||||
import com.willfp.eco.util.ClassUtils;
|
import com.willfp.eco.util.ClassUtils;
|
||||||
import lombok.Getter;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -26,22 +26,67 @@ public class Prerequisite {
|
|||||||
* Requires the server to be running an implementation of paper.
|
* Requires the server to be running an implementation of paper.
|
||||||
*/
|
*/
|
||||||
public static final Prerequisite HAS_PAPER = new Prerequisite(
|
public static final Prerequisite HAS_PAPER = new Prerequisite(
|
||||||
() -> ClassUtils.exists("com.destroystokyo.paper.event.player.PlayerElytraBoostEvent"),
|
() -> ClassUtils.exists("com.destroystokyo.paper.event.block.BeaconEffectEvent"),
|
||||||
"Requires server to be running paper (or a fork)"
|
"Requires server to be running paper (or a fork)"
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Requires the server to be running 1.17.
|
* Requires the server to have vault installed.
|
||||||
|
*
|
||||||
|
* @deprecated Use {@link EconomyManager#hasRegistrations()} instead.
|
||||||
*/
|
*/
|
||||||
|
@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") || HAS_1_19.isMet(),
|
||||||
|
"Requires server to be running 1.18+"
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requires the server to be running 1.17.
|
||||||
|
*
|
||||||
|
* @deprecated eco no longer supports versions before 1.17.
|
||||||
|
*/
|
||||||
|
@Deprecated(since = "6.25.2", forRemoval = true)
|
||||||
public static final Prerequisite HAS_1_17 = new Prerequisite(
|
public static final Prerequisite HAS_1_17 = new Prerequisite(
|
||||||
() -> ProxyConstants.NMS_VERSION.contains("17"),
|
() -> ProxyConstants.NMS_VERSION.contains("17") || HAS_1_18.isMet(),
|
||||||
"Requires server to be running 1.17+"
|
"Requires server to be running 1.17+"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requires the server to be running an implementation of BungeeCord.
|
||||||
|
*/
|
||||||
|
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)"
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requires the server to be running an implementation of Velocity.
|
||||||
|
*/
|
||||||
|
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)"
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the necessary prerequisite condition has been met.
|
* If the necessary prerequisite condition has been met.
|
||||||
*/
|
*/
|
||||||
@Getter
|
|
||||||
private boolean isMet;
|
private boolean isMet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -52,7 +97,6 @@ public class Prerequisite {
|
|||||||
/**
|
/**
|
||||||
* The description of the requirements of the prerequisite.
|
* The description of the requirements of the prerequisite.
|
||||||
*/
|
*/
|
||||||
@Getter
|
|
||||||
private final String description;
|
private final String description;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -97,4 +141,22 @@ public class Prerequisite {
|
|||||||
static {
|
static {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get if the prerequisite is met.
|
||||||
|
*
|
||||||
|
* @return If the condition is met.
|
||||||
|
*/
|
||||||
|
public boolean isMet() {
|
||||||
|
return this.isMet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the description.
|
||||||
|
*
|
||||||
|
* @return The description.
|
||||||
|
*/
|
||||||
|
public String getDescription() {
|
||||||
|
return this.description;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,18 @@
|
|||||||
package com.willfp.eco.core.command;
|
package com.willfp.eco.core.command;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.willfp.eco.core.EcoPlugin;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for all command implementations.
|
* Interface for all command implementations.
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("removal")
|
||||||
public interface CommandBase {
|
public interface CommandBase {
|
||||||
/**
|
/**
|
||||||
* Get command name.
|
* Get command name.
|
||||||
@@ -35,17 +43,108 @@ public interface CommandBase {
|
|||||||
*/
|
*/
|
||||||
CommandBase addSubcommand(@NotNull CommandBase command);
|
CommandBase addSubcommand(@NotNull CommandBase command);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle command execution.
|
||||||
|
*
|
||||||
|
* @param sender The sender.
|
||||||
|
* @param args The args.
|
||||||
|
*/
|
||||||
|
default void onExecute(@NotNull CommandSender sender,
|
||||||
|
@NotNull List<String> args) {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle command execution from players.
|
||||||
|
*
|
||||||
|
* @param sender The sender.
|
||||||
|
* @param args The args.
|
||||||
|
*/
|
||||||
|
default void onExecute(@NotNull Player sender,
|
||||||
|
@NotNull List<String> args) {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle tab completion.
|
||||||
|
*
|
||||||
|
* @param sender The sender.
|
||||||
|
* @param args The args.
|
||||||
|
* @return The results.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
default List<String> tabComplete(@NotNull CommandSender sender,
|
||||||
|
@NotNull List<String> args) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle tab completion.
|
||||||
|
*
|
||||||
|
* @param sender The sender.
|
||||||
|
* @param args The args.
|
||||||
|
* @return The results.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
default List<String> tabComplete(@NotNull Player sender,
|
||||||
|
@NotNull List<String> args) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the plugin.
|
||||||
|
*
|
||||||
|
* @return The plugin.
|
||||||
|
*/
|
||||||
|
EcoPlugin getPlugin();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the handler.
|
* Get the handler.
|
||||||
*
|
*
|
||||||
* @return The handler.
|
* @return The handler.
|
||||||
|
* @see CommandHandler
|
||||||
|
* @deprecated Use {@link CommandBase#onExecute(CommandSender, List)} instead.
|
||||||
*/
|
*/
|
||||||
CommandHandler getHandler();
|
@Deprecated(forRemoval = true)
|
||||||
|
default CommandHandler getHandler() {
|
||||||
|
return (a, b) -> {
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the handler.
|
||||||
|
*
|
||||||
|
* @param handler The handler.
|
||||||
|
* @see CommandHandler
|
||||||
|
* @deprecated Handlers have been deprecated.
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
|
default void setHandler(@NotNull final CommandHandler handler) {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the tab completer.
|
* Get the tab completer.
|
||||||
*
|
*
|
||||||
* @return The tab completer.
|
* @return The tab completer.
|
||||||
|
* @see TabCompleteHandler
|
||||||
|
* @deprecated Use {@link CommandBase#tabComplete(CommandSender, List)} instead.
|
||||||
*/
|
*/
|
||||||
TabCompleteHandler getTabCompleter();
|
@Deprecated(forRemoval = true)
|
||||||
|
default TabCompleteHandler getTabCompleter() {
|
||||||
|
return (a, b) -> ImmutableList.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the tab completer.
|
||||||
|
*
|
||||||
|
* @param handler The handler.
|
||||||
|
* @see TabCompleteHandler
|
||||||
|
* @deprecated Handlers have been deprecated.
|
||||||
|
*/
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
|
default void setTabCompleter(@NotNull final TabCompleteHandler handler) {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,9 +10,13 @@ import java.util.List;
|
|||||||
* A command handler handles the actual code for a command.
|
* A command handler handles the actual code for a command.
|
||||||
* <p>
|
* <p>
|
||||||
* The replacement for {@link org.bukkit.command.CommandExecutor#onCommand(CommandSender, Command, String, String[])}
|
* The replacement for {@link org.bukkit.command.CommandExecutor#onCommand(CommandSender, Command, String, String[])}
|
||||||
|
*
|
||||||
* @see CommandBase
|
* @see CommandBase
|
||||||
|
* @deprecated Handlers have been deprecated. This legacy system will eventually be removed,
|
||||||
|
* update to use the new system: {@link CommandBase#onExecute(CommandSender, List)}.
|
||||||
*/
|
*/
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
|
@Deprecated(since = "6.17.0", forRemoval = true)
|
||||||
public interface CommandHandler {
|
public interface CommandHandler {
|
||||||
/**
|
/**
|
||||||
* The code to be called on execution.
|
* The code to be called on execution.
|
||||||
|
|||||||
@@ -10,9 +10,13 @@ import java.util.List;
|
|||||||
* A Tab Complete handler handles the actual tab-completion code.
|
* A Tab Complete handler handles the actual tab-completion code.
|
||||||
* <p>
|
* <p>
|
||||||
* The replacement for {@link org.bukkit.command.TabCompleter#onTabComplete(CommandSender, Command, String, String[])}
|
* The replacement for {@link org.bukkit.command.TabCompleter#onTabComplete(CommandSender, Command, String, String[])}
|
||||||
|
*
|
||||||
* @see CommandBase
|
* @see CommandBase
|
||||||
|
* @deprecated Handlers have been deprecated. This legacy system will eventually be removed,
|
||||||
|
* update to use the new system: {@link CommandBase#tabComplete(CommandSender, List)}
|
||||||
*/
|
*/
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
|
@Deprecated(since = "6.17.0", forRemoval = true)
|
||||||
public interface TabCompleteHandler {
|
public interface TabCompleteHandler {
|
||||||
/**
|
/**
|
||||||
* Handle Tab Completion.
|
* Handle Tab Completion.
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
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 org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delegates a bukkit command to an eco command (for registrations).
|
||||||
|
*/
|
||||||
|
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 delegate.onCommand(commandSender, this, label, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> onTabComplete(@NotNull final CommandSender commandSender,
|
||||||
|
@NotNull final Command command,
|
||||||
|
@NotNull final String label,
|
||||||
|
@NotNull final String[] args) {
|
||||||
|
return delegate.onTabComplete(commandSender, command, label, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Plugin getPlugin() {
|
||||||
|
return this.delegate.getPlugin();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public 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,16 +1,12 @@
|
|||||||
package com.willfp.eco.core.command.impl;
|
package com.willfp.eco.core.command.impl;
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
import com.willfp.eco.core.EcoPlugin;
|
||||||
import com.willfp.eco.core.PluginDependent;
|
|
||||||
import com.willfp.eco.core.command.CommandBase;
|
import com.willfp.eco.core.command.CommandBase;
|
||||||
import com.willfp.eco.core.command.CommandHandler;
|
|
||||||
import com.willfp.eco.core.command.TabCompleteHandler;
|
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.Getter;
|
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.util.StringUtil;
|
import org.bukkit.util.StringUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -25,11 +21,16 @@ import java.util.stream.Collectors;
|
|||||||
* in order to execute the command-specific code. It's essentially an internal
|
* in order to execute the command-specific code. It's essentially an internal
|
||||||
* layer, hence why it's a package-private class.
|
* layer, hence why it's a package-private class.
|
||||||
*/
|
*/
|
||||||
abstract class HandledCommand extends PluginDependent<EcoPlugin> implements CommandBase {
|
@SuppressWarnings({"DeprecatedIsStillUsed", "removal"})
|
||||||
|
abstract class HandledCommand implements CommandBase {
|
||||||
|
/**
|
||||||
|
* The plugin.
|
||||||
|
*/
|
||||||
|
private final EcoPlugin plugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the command.
|
* The name of the command.
|
||||||
*/
|
*/
|
||||||
@Getter
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -37,7 +38,6 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
|
|||||||
* <p>
|
* <p>
|
||||||
* Written out as a string for flexibility with subclasses.
|
* Written out as a string for flexibility with subclasses.
|
||||||
*/
|
*/
|
||||||
@Getter
|
|
||||||
private final String permission;
|
private final String permission;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -45,13 +45,25 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
|
|||||||
* <p>
|
* <p>
|
||||||
* In other worlds, only allowed to be executed by console.
|
* In other worlds, only allowed to be executed by console.
|
||||||
*/
|
*/
|
||||||
@Getter
|
|
||||||
private final boolean playersOnly;
|
private final boolean playersOnly;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The actual code to be executed in the command.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Nullable
|
||||||
|
private com.willfp.eco.core.command.CommandHandler handler = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The tab completion code to be executed in the command.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Nullable
|
||||||
|
private com.willfp.eco.core.command.TabCompleteHandler tabCompleter = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All subcommands for the command.
|
* All subcommands for the command.
|
||||||
*/
|
*/
|
||||||
@Getter(AccessLevel.PROTECTED)
|
|
||||||
private final List<CommandBase> subcommands;
|
private final List<CommandBase> subcommands;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -68,7 +80,7 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
|
|||||||
@NotNull final String name,
|
@NotNull final String name,
|
||||||
@NotNull final String permission,
|
@NotNull final String permission,
|
||||||
final boolean playersOnly) {
|
final boolean playersOnly) {
|
||||||
super(plugin);
|
this.plugin = plugin;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.permission = permission;
|
this.permission = permission;
|
||||||
this.playersOnly = playersOnly;
|
this.playersOnly = playersOnly;
|
||||||
@@ -88,6 +100,16 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the plugin.
|
||||||
|
*
|
||||||
|
* @return The plugin.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public EcoPlugin getPlugin() {
|
||||||
|
return this.plugin;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle the command.
|
* Handle the command.
|
||||||
*
|
*
|
||||||
@@ -114,7 +136,19 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.getHandler().onExecute(sender, Arrays.asList(args));
|
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));
|
||||||
|
if (sender instanceof Player player) {
|
||||||
|
this.onExecute(player, Arrays.asList(args));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -136,7 +170,10 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
|
|||||||
|
|
||||||
StringUtil.copyPartialMatches(
|
StringUtil.copyPartialMatches(
|
||||||
args[0],
|
args[0],
|
||||||
this.getSubcommands().stream().map(CommandBase::getName).collect(Collectors.toList()),
|
this.getSubcommands().stream()
|
||||||
|
.filter(subCommand -> sender.hasPermission(subCommand.getPermission()))
|
||||||
|
.map(CommandBase::getName)
|
||||||
|
.collect(Collectors.toList()),
|
||||||
completions
|
completions
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -151,6 +188,10 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
|
|||||||
HandledCommand command = null;
|
HandledCommand command = null;
|
||||||
|
|
||||||
for (CommandBase subcommand : this.getSubcommands()) {
|
for (CommandBase subcommand : this.getSubcommands()) {
|
||||||
|
if (!sender.hasPermission(subcommand.getPermission())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (args[0].equalsIgnoreCase(subcommand.getName())) {
|
if (args[0].equalsIgnoreCase(subcommand.getName())) {
|
||||||
command = (HandledCommand) subcommand;
|
command = (HandledCommand) subcommand;
|
||||||
}
|
}
|
||||||
@@ -161,15 +202,15 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.getTabCompleter().tabComplete(sender, Arrays.asList(args));
|
if (this.getTabCompleter() != null) {
|
||||||
}
|
return this.getTabCompleter().tabComplete(sender, Arrays.asList(args));
|
||||||
|
} else {
|
||||||
@Override
|
List<String> completions = this.tabComplete(sender, Arrays.asList(args));
|
||||||
public abstract CommandHandler getHandler();
|
if (sender instanceof Player player) {
|
||||||
|
completions.addAll(this.tabComplete(player, Arrays.asList(args)));
|
||||||
@Override
|
}
|
||||||
public TabCompleteHandler getTabCompleter() {
|
return completions;
|
||||||
return (sender, args) -> new ArrayList<>();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -183,11 +224,6 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
|
|||||||
public static boolean canExecute(@NotNull final CommandSender sender,
|
public static boolean canExecute(@NotNull final CommandSender sender,
|
||||||
@NotNull final CommandBase command,
|
@NotNull final CommandBase command,
|
||||||
@NotNull final EcoPlugin plugin) {
|
@NotNull final EcoPlugin plugin) {
|
||||||
if (command.isPlayersOnly() && !(sender instanceof Player)) {
|
|
||||||
sender.sendMessage(plugin.getLangYml().getMessage("not-player"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sender.hasPermission(command.getPermission()) && sender instanceof Player) {
|
if (!sender.hasPermission(command.getPermission()) && sender instanceof Player) {
|
||||||
sender.sendMessage(plugin.getLangYml().getNoPermission());
|
sender.sendMessage(plugin.getLangYml().getNoPermission());
|
||||||
return false;
|
return false;
|
||||||
@@ -195,4 +231,64 @@ abstract class HandledCommand extends PluginDependent<EcoPlugin> implements Comm
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the command name.
|
||||||
|
*
|
||||||
|
* @return The name.
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the permission required to execute the command.
|
||||||
|
*
|
||||||
|
* @return The permission.
|
||||||
|
*/
|
||||||
|
public String getPermission() {
|
||||||
|
return this.permission;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get if the command can only be executed by players.
|
||||||
|
*
|
||||||
|
* @return If players only.
|
||||||
|
*/
|
||||||
|
public boolean isPlayersOnly() {
|
||||||
|
return this.playersOnly;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the subcommands of the command.
|
||||||
|
*
|
||||||
|
* @return The subcommands.
|
||||||
|
*/
|
||||||
|
public List<CommandBase> getSubcommands() {
|
||||||
|
return this.subcommands;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
|
@Override
|
||||||
|
public @Nullable com.willfp.eco.core.command.CommandHandler getHandler() {
|
||||||
|
return this.handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
|
@Override
|
||||||
|
public @Nullable com.willfp.eco.core.command.TabCompleteHandler getTabCompleter() {
|
||||||
|
return this.tabCompleter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
|
@Override
|
||||||
|
public void setHandler(@Nullable final com.willfp.eco.core.command.CommandHandler handler) {
|
||||||
|
this.handler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated(forRemoval = true)
|
||||||
|
@Override
|
||||||
|
public void setTabCompleter(@Nullable final com.willfp.eco.core.command.TabCompleteHandler tabCompleter) {
|
||||||
|
this.tabCompleter = tabCompleter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,24 @@
|
|||||||
package com.willfp.eco.core.command.impl;
|
package com.willfp.eco.core.command.impl;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.Eco;
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
import com.willfp.eco.core.EcoPlugin;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandExecutor;
|
import org.bukkit.command.CommandExecutor;
|
||||||
|
import org.bukkit.command.CommandMap;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.command.TabCompleter;
|
import org.bukkit.command.TabCompleter;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PluginCommands are the class to be used instead of CommandExecutor.
|
* PluginCommands are the class to be used instead of CommandExecutor,
|
||||||
|
* they function as the base command, e.g. {@code /ecoenchants} would be a base command, with each
|
||||||
|
* subsequent argument functioning as subcommands.
|
||||||
* <p>
|
* <p>
|
||||||
* The command will not be registered until register() is called.
|
* The command will not be registered until register() is called.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -36,14 +42,63 @@ public abstract class PluginCommand extends HandledCommand implements CommandExe
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers the command with the server,
|
* Registers the command with the server,
|
||||||
* <p>
|
|
||||||
* Requires the command name to exist, defined in plugin.yml.
|
|
||||||
*/
|
*/
|
||||||
public final void register() {
|
public final void register() {
|
||||||
org.bukkit.command.PluginCommand command = Bukkit.getPluginCommand(this.getName());
|
org.bukkit.command.PluginCommand command = Bukkit.getPluginCommand(this.getName());
|
||||||
assert command != null;
|
if (command != null) {
|
||||||
command.setExecutor(this);
|
command.setExecutor(this);
|
||||||
command.setTabCompleter(this);
|
command.setTabCompleter(this);
|
||||||
|
|
||||||
|
if (this.getDescription() != null) {
|
||||||
|
command.setDescription(this.getDescription());
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> aliases = new ArrayList<>(command.getAliases());
|
||||||
|
aliases.addAll(this.getAliases());
|
||||||
|
command.setAliases(aliases);
|
||||||
|
} else {
|
||||||
|
this.unregister();
|
||||||
|
|
||||||
|
CommandMap commandMap = getCommandMap();
|
||||||
|
|
||||||
|
commandMap.register(this.getPlugin().getName().toLowerCase(), new DelegatedBukkitCommand(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
Eco.get().syncCommands();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregisters the command from the server.
|
||||||
|
*/
|
||||||
|
public final void unregister() {
|
||||||
|
CommandMap commandMap = getCommandMap();
|
||||||
|
|
||||||
|
Command found = commandMap.getCommand(this.getName());
|
||||||
|
if (found != null) {
|
||||||
|
found.unregister(commandMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
Eco.get().syncCommands();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get aliases. Leave null if this command is from plugin.yml.
|
||||||
|
*
|
||||||
|
* @return The aliases.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public List<String> getAliases() {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get description.
|
||||||
|
*
|
||||||
|
* @return The description.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public String getDescription() {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -91,4 +146,19 @@ public abstract class PluginCommand extends HandledCommand implements CommandExe
|
|||||||
|
|
||||||
return this.handleTabCompletion(sender, args);
|
return this.handleTabCompletion(sender, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the internal server CommandMap.
|
||||||
|
*
|
||||||
|
* @return The CommandMap.
|
||||||
|
*/
|
||||||
|
public static CommandMap getCommandMap() {
|
||||||
|
try {
|
||||||
|
Field field = Bukkit.getServer().getClass().getDeclaredField("commandMap");
|
||||||
|
field.setAccessible(true);
|
||||||
|
return (CommandMap) field.get(Bukkit.getServer());
|
||||||
|
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||||
|
throw new NullPointerException("Command map wasn't found!");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package com.willfp.eco.core.config;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.Eco;
|
||||||
|
import com.willfp.eco.core.PluginLike;
|
||||||
|
import com.willfp.eco.core.config.wrapper.LoadableConfigWrapper;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
|
||||||
|
* <p>
|
||||||
|
* Automatically updates.
|
||||||
|
*/
|
||||||
|
public abstract class BaseConfig extends LoadableConfigWrapper {
|
||||||
|
/**
|
||||||
|
* Create new Base Config.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin or extension.
|
||||||
|
* @param configName The config name (excluding extension).
|
||||||
|
* @param removeUnused If unused sections should be removed.
|
||||||
|
* @param type The config type.
|
||||||
|
*/
|
||||||
|
protected BaseConfig(@NotNull final String configName,
|
||||||
|
@NotNull final PluginLike plugin,
|
||||||
|
final boolean removeUnused,
|
||||||
|
@NotNull final ConfigType type) {
|
||||||
|
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,
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package com.willfp.eco.core.config;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Config types, classified by file extension.
|
||||||
|
*/
|
||||||
|
public enum ConfigType {
|
||||||
|
/**
|
||||||
|
* .json config.
|
||||||
|
*/
|
||||||
|
JSON("json"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* .yml config.
|
||||||
|
*/
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package com.willfp.eco.core.config;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.Eco;
|
||||||
|
import com.willfp.eco.core.PluginLike;
|
||||||
|
import com.willfp.eco.core.config.wrapper.LoadableConfigWrapper;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Config implementation for configs present in one of two places:
|
||||||
|
* <ul>
|
||||||
|
* <li>Plugin base directory (eg config.yml, lang.json)</li>
|
||||||
|
* <li>Other extension's configs</li>
|
||||||
|
* </ul>
|
||||||
|
* <p>
|
||||||
|
* Automatically updates.
|
||||||
|
*/
|
||||||
|
public abstract class ExtendableConfig extends LoadableConfigWrapper {
|
||||||
|
/**
|
||||||
|
* @param configName The name of the config
|
||||||
|
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||||
|
* @param plugin The plugin.
|
||||||
|
* @param updateBlacklist Substring of keys to not add/remove keys for.
|
||||||
|
* @param subDirectoryPath The subdirectory path.
|
||||||
|
* @param type The config type.
|
||||||
|
* @param source The class that owns the resource.
|
||||||
|
*/
|
||||||
|
protected ExtendableConfig(@NotNull final String configName,
|
||||||
|
final boolean removeUnused,
|
||||||
|
@NotNull final PluginLike plugin,
|
||||||
|
@NotNull final Class<?> source,
|
||||||
|
@NotNull final String subDirectoryPath,
|
||||||
|
@NotNull final ConfigType type,
|
||||||
|
@NotNull final String... updateBlacklist) {
|
||||||
|
super(Eco.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));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.willfp.eco.core.config;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.Eco;
|
||||||
|
import com.willfp.eco.core.PluginLike;
|
||||||
|
import com.willfp.eco.core.config.wrapper.LoadableConfigWrapper;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Non-updatable yaml config that exists within a plugin jar.
|
||||||
|
*/
|
||||||
|
public abstract class StaticBaseConfig extends LoadableConfigWrapper {
|
||||||
|
/**
|
||||||
|
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
|
||||||
|
* <p>
|
||||||
|
* Does not automatically update.
|
||||||
|
*
|
||||||
|
* @param configName The name of the config
|
||||||
|
* @param plugin The plugin.
|
||||||
|
* @param type The config type.
|
||||||
|
*/
|
||||||
|
protected StaticBaseConfig(@NotNull final String configName,
|
||||||
|
@NotNull final PluginLike plugin,
|
||||||
|
@NotNull final ConfigType type) {
|
||||||
|
super(Eco.get().createLoadableConfig(
|
||||||
|
configName,
|
||||||
|
plugin,
|
||||||
|
"",
|
||||||
|
plugin.getClass(),
|
||||||
|
type,
|
||||||
|
true
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,125 @@
|
|||||||
|
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) {
|
||||||
|
this((ConfigurationSection) config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param stream The InputStream.
|
||||||
|
*/
|
||||||
|
public TransientConfig(@Nullable final InputStream stream) {
|
||||||
|
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.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() {
|
||||||
|
this(new HashMap<>(), ConfigType.JSON);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param contents The contents of the config.
|
||||||
|
* @param type The config type.
|
||||||
|
*/
|
||||||
|
public TransientConfig(@NotNull final String contents,
|
||||||
|
@NotNull final ConfigType 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 "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,19 +1,55 @@
|
|||||||
package com.willfp.eco.core.config.base;
|
package com.willfp.eco.core.config.base;
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
import com.willfp.eco.core.EcoPlugin;
|
||||||
import com.willfp.eco.core.config.yaml.YamlBaseConfig;
|
import com.willfp.eco.core.config.BaseConfig;
|
||||||
|
import com.willfp.eco.core.config.ConfigType;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default plugin config.yml.
|
* Default plugin config.yml.
|
||||||
*/
|
*/
|
||||||
public class ConfigYml extends YamlBaseConfig {
|
public class ConfigYml extends BaseConfig {
|
||||||
/**
|
/**
|
||||||
* Config.yml.
|
* Config.yml.
|
||||||
*
|
*
|
||||||
* @param plugin The plugin.
|
* @param plugin The plugin.
|
||||||
*/
|
*/
|
||||||
public ConfigYml(@NotNull final EcoPlugin plugin) {
|
public ConfigYml(@NotNull final EcoPlugin plugin) {
|
||||||
super("config", true, plugin);
|
super("config", plugin, true, ConfigType.YAML);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Config.yml.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin.
|
||||||
|
* @param removeUnused Remove unused.
|
||||||
|
*/
|
||||||
|
public ConfigYml(@NotNull final EcoPlugin plugin,
|
||||||
|
final boolean removeUnused) {
|
||||||
|
super("config", plugin, removeUnused, ConfigType.YAML);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Config.yml.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin.
|
||||||
|
* @param name The config name.
|
||||||
|
*/
|
||||||
|
public ConfigYml(@NotNull final EcoPlugin plugin,
|
||||||
|
@NotNull final String name) {
|
||||||
|
super(name, plugin, true, ConfigType.YAML);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Config.yml.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin.
|
||||||
|
* @param name The config name.
|
||||||
|
* @param removeUnused Remove unused.
|
||||||
|
*/
|
||||||
|
public ConfigYml(@NotNull final EcoPlugin plugin,
|
||||||
|
@NotNull final String name,
|
||||||
|
final boolean removeUnused) {
|
||||||
|
super(name, plugin, removeUnused, ConfigType.YAML);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,22 @@
|
|||||||
package com.willfp.eco.core.config.base;
|
package com.willfp.eco.core.config.base;
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
import com.willfp.eco.core.EcoPlugin;
|
||||||
import com.willfp.eco.core.config.yaml.YamlBaseConfig;
|
import com.willfp.eco.core.config.BaseConfig;
|
||||||
|
import com.willfp.eco.core.config.ConfigType;
|
||||||
|
import com.willfp.eco.util.StringUtils;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default plugin lang.yml.
|
* Default plugin lang.yml.
|
||||||
*/
|
*/
|
||||||
public class LangYml extends YamlBaseConfig {
|
public class LangYml extends BaseConfig {
|
||||||
/**
|
/**
|
||||||
* Lang.yml.
|
* Lang.yml.
|
||||||
*
|
*
|
||||||
* @param plugin The plugin.
|
* @param plugin The plugin.
|
||||||
*/
|
*/
|
||||||
public LangYml(@NotNull final EcoPlugin plugin) {
|
public LangYml(@NotNull final EcoPlugin plugin) {
|
||||||
super("lang", false, plugin);
|
super("lang", plugin, false, ConfigType.YAML);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -23,7 +25,7 @@ public class LangYml extends YamlBaseConfig {
|
|||||||
* @return The prefix.
|
* @return The prefix.
|
||||||
*/
|
*/
|
||||||
public String getPrefix() {
|
public String getPrefix() {
|
||||||
return this.getString("messages.prefix");
|
return this.getFormattedString("messages.prefix");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -32,7 +34,7 @@ public class LangYml extends YamlBaseConfig {
|
|||||||
* @return The message.
|
* @return The message.
|
||||||
*/
|
*/
|
||||||
public String getNoPermission() {
|
public String getNoPermission() {
|
||||||
return getPrefix() + this.getString("messages.no-permission");
|
return getPrefix() + this.getFormattedString("messages.no-permission");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,6 +44,18 @@ public class LangYml extends YamlBaseConfig {
|
|||||||
* @return The message with a prefix appended.
|
* @return The message with a prefix appended.
|
||||||
*/
|
*/
|
||||||
public String getMessage(@NotNull final String message) {
|
public String getMessage(@NotNull final String message) {
|
||||||
return getPrefix() + this.getString("messages." + message);
|
return getMessage(message, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a chat message.
|
||||||
|
*
|
||||||
|
* @param message The key of the message.
|
||||||
|
* @param option The format options.
|
||||||
|
* @return The message with a prefix appended.
|
||||||
|
*/
|
||||||
|
public String getMessage(@NotNull final String message,
|
||||||
|
@NotNull final StringUtils.FormatOption option) {
|
||||||
|
return getPrefix() + this.getFormattedString("messages." + message, option);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,44 @@
|
|||||||
package com.willfp.eco.core.config.interfaces;
|
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.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.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.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
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.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All canfigs implement this interface.
|
* All configs implement this interface.
|
||||||
* <p>
|
* <p>
|
||||||
* Contains all methods that must exist in yaml and json configurations.
|
* Contains all methods that must exist in yaml and json configurations.
|
||||||
*/
|
*/
|
||||||
public interface Config extends Cloneable {
|
@SuppressWarnings("unused")
|
||||||
|
public interface Config extends Cloneable, PlaceholderInjectable {
|
||||||
/**
|
/**
|
||||||
* Clears cache.
|
* 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.
|
* Convert the config into readable text.
|
||||||
@@ -40,9 +64,21 @@ public interface Config extends Cloneable {
|
|||||||
@NotNull
|
@NotNull
|
||||||
List<String> getKeys(boolean deep);
|
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.
|
* Get an object from config.
|
||||||
* Default implementations call {@link org.bukkit.configuration.file.YamlConfiguration#get(String)}.
|
|
||||||
*
|
*
|
||||||
* @param path The path.
|
* @param path The path.
|
||||||
* @return The object.
|
* @return The object.
|
||||||
@@ -52,7 +88,6 @@ public interface Config extends Cloneable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Set an object in config.
|
* Set an object in config.
|
||||||
* Default implementations call {@link org.bukkit.configuration.file.YamlConfiguration#set(String, Object)}
|
|
||||||
*
|
*
|
||||||
* @param path The path.
|
* @param path The path.
|
||||||
* @param object The object.
|
* @param object The object.
|
||||||
@@ -64,10 +99,12 @@ public interface Config extends Cloneable {
|
|||||||
* Get subsection from config.
|
* Get subsection from config.
|
||||||
*
|
*
|
||||||
* @param path The key to check.
|
* @param path The key to check.
|
||||||
* @return The subsection. Throws NPE if not found.
|
* @return The subsection. Returns an empty section if not found.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
Config getSubsection(@NotNull String path);
|
default Config getSubsection(@NotNull String path) {
|
||||||
|
return Objects.requireNonNullElse(getSubsectionOrNull(path), Configs.empty());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get subsection from config.
|
* Get subsection from config.
|
||||||
@@ -84,7 +121,58 @@ public interface Config extends Cloneable {
|
|||||||
* @param path The key to fetch the value from.
|
* @param path The key to fetch the value from.
|
||||||
* @return The found value, or 0 if not found.
|
* @return The found value, or 0 if not found.
|
||||||
*/
|
*/
|
||||||
int getInt(@NotNull String path);
|
default int getInt(@NotNull String path) {
|
||||||
|
return Objects.requireNonNullElse(getIntOrNull(path), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an integer from config with a specified default (not found) value.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @param def The value to default to if not found.
|
||||||
|
* @return The found value, or the default.
|
||||||
|
*/
|
||||||
|
default int getInt(@NotNull String path,
|
||||||
|
int def) {
|
||||||
|
return Objects.requireNonNullElse(getIntOrNull(path), def);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a decimal value via a mathematical expression.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The computed value, or 0 if not found or invalid.
|
||||||
|
*/
|
||||||
|
default int getIntFromExpression(@NotNull String path) {
|
||||||
|
return getIntFromExpression(path, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a decimal value via a mathematical expression.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @param player The player to evaluate placeholders with respect to.
|
||||||
|
* @return The computed value, or 0 if not found or invalid.
|
||||||
|
*/
|
||||||
|
default int getIntFromExpression(@NotNull String path,
|
||||||
|
@Nullable Player player) {
|
||||||
|
return Double.valueOf(getDoubleFromExpression(path, player)).intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a decimal value via a mathematical expression.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @param player The player to evaluate placeholders with respect to.
|
||||||
|
* @param additionalPlayers The additional players to evaluate placeholders with respect to.
|
||||||
|
* @return The computed value, or 0 if not found or invalid.
|
||||||
|
*/
|
||||||
|
default int getIntFromExpression(@NotNull String path,
|
||||||
|
@Nullable Player player,
|
||||||
|
@NotNull Collection<AdditionalPlayer> additionalPlayers) {
|
||||||
|
return Double.valueOf(getDoubleFromExpression(path, player, additionalPlayers)).intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an integer from config.
|
* Get an integer from config.
|
||||||
@@ -95,16 +183,6 @@ public interface Config extends Cloneable {
|
|||||||
@Nullable
|
@Nullable
|
||||||
Integer getIntOrNull(@NotNull String path);
|
Integer getIntOrNull(@NotNull String path);
|
||||||
|
|
||||||
/**
|
|
||||||
* Get an integer from config with a specified default (not found) value.
|
|
||||||
*
|
|
||||||
* @param path The key to fetch the value from.
|
|
||||||
* @param def The value to default to if not found.
|
|
||||||
* @return The found value, or the default.
|
|
||||||
*/
|
|
||||||
int getInt(@NotNull String path,
|
|
||||||
int def);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of integers from config.
|
* Get a list of integers from config.
|
||||||
*
|
*
|
||||||
@@ -112,7 +190,9 @@ public interface Config extends Cloneable {
|
|||||||
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
List<Integer> getInts(@NotNull String path);
|
default List<Integer> getInts(@NotNull String path) {
|
||||||
|
return Objects.requireNonNullElse(getIntsOrNull(path), new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of integers from config.
|
* Get a list of integers from config.
|
||||||
@@ -129,7 +209,9 @@ public interface Config extends Cloneable {
|
|||||||
* @param path The key to fetch the value from.
|
* @param path The key to fetch the value from.
|
||||||
* @return The found value, or false if not found.
|
* @return The found value, or false if not found.
|
||||||
*/
|
*/
|
||||||
boolean getBool(@NotNull String path);
|
default boolean getBool(@NotNull String path) {
|
||||||
|
return Objects.requireNonNullElse(getBoolOrNull(path), false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a boolean from config.
|
* Get a boolean from config.
|
||||||
@@ -147,7 +229,9 @@ public interface Config extends Cloneable {
|
|||||||
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
List<Boolean> getBools(@NotNull String path);
|
default List<Boolean> getBools(@NotNull String path) {
|
||||||
|
return Objects.requireNonNullElse(getBoolsOrNull(path), new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of booleans from config.
|
* Get a list of booleans from config.
|
||||||
@@ -159,44 +243,106 @@ public interface Config extends Cloneable {
|
|||||||
List<Boolean> getBoolsOrNull(@NotNull String path);
|
List<Boolean> getBoolsOrNull(@NotNull String path);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a string from config.
|
* Get a formatted string from config.
|
||||||
*
|
*
|
||||||
* @param path The key to fetch the value from.
|
* @param path The key to fetch the value from.
|
||||||
* @return The found value, or an empty string if not found.
|
* @return The found value, or an empty string if not found.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
String getString(@NotNull String path);
|
default String getFormattedString(@NotNull String path) {
|
||||||
|
return getString(path, true, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a formatted 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.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
default String getFormattedString(@NotNull String path,
|
||||||
|
@NotNull StringUtils.FormatOption option) {
|
||||||
|
return getString(path, true, option);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a string from config.
|
||||||
|
* <p>
|
||||||
|
* Not formatted.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The found value, or an empty string if not found.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
default String getString(@NotNull String path) {
|
||||||
|
return getString(path, false, StringUtils.FormatOption.WITHOUT_PLACEHOLDERS);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a string from config.
|
* Get a string from config.
|
||||||
*
|
*
|
||||||
* @param path The key to fetch the value from.
|
* @param path The key to fetch the value from.
|
||||||
* @param format If the string should be formatted.
|
* @param format If the string should be formatted.
|
||||||
|
* @param option The format option.
|
||||||
* @return The found value, or an empty string if not found.
|
* @return The found value, or an empty string if not found.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
String getString(@NotNull String path,
|
default String getString(@NotNull String path,
|
||||||
boolean format);
|
boolean format,
|
||||||
|
@NotNull StringUtils.FormatOption option) {
|
||||||
|
return Objects.requireNonNullElse(getStringOrNull(path, format, option), "");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a formatted string from config.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The found value, or an empty string if not found.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
default String getFormattedStringOrNull(@NotNull String path) {
|
||||||
|
return getStringOrNull(path, true, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a formatted 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.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
default String getFormattedStringOrNull(@NotNull String path,
|
||||||
|
@NotNull StringUtils.FormatOption option) {
|
||||||
|
return getStringOrNull(path, true, option);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a string from config.
|
* Get a string from config.
|
||||||
|
* <p>
|
||||||
|
* Formatted by default.
|
||||||
*
|
*
|
||||||
* @param path The key to fetch the value from.
|
* @param path The key to fetch the value from.
|
||||||
* @return The found value, or null if not found.
|
* @return The found value, or null if not found.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
String getStringOrNull(@NotNull String path);
|
default String getStringOrNull(@NotNull String path) {
|
||||||
|
return getStringOrNull(path, false, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a string from config.
|
* Get a string from config.
|
||||||
*
|
*
|
||||||
* @param path The key to fetch the value from.
|
* @param path The key to fetch the value from.
|
||||||
* @param format If the string should be formatted.
|
* @param format If the string should be formatted.
|
||||||
|
* @param option The format option. If format is false, this will be ignored.
|
||||||
* @return The found value, or null if not found.
|
* @return The found value, or null if not found.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
String getStringOrNull(@NotNull String path,
|
String getStringOrNull(@NotNull String path,
|
||||||
boolean format);
|
boolean format,
|
||||||
|
@NotNull StringUtils.FormatOption option);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of strings from config.
|
* Get a list of strings from config.
|
||||||
@@ -207,38 +353,108 @@ public interface Config extends Cloneable {
|
|||||||
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
List<String> getStrings(@NotNull String path);
|
default List<String> getFormattedStrings(@NotNull String path) {
|
||||||
|
return getStrings(path, true, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of strings from config.
|
||||||
|
* <p>
|
||||||
|
* Formatted by default.
|
||||||
|
*
|
||||||
|
* @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.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
default List<String> getFormattedStrings(@NotNull String path,
|
||||||
|
@NotNull StringUtils.FormatOption option) {
|
||||||
|
return getStrings(path, true, option);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of strings from config.
|
||||||
|
* <p>
|
||||||
|
* Not formatted.
|
||||||
|
*
|
||||||
|
* @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<String> getStrings(@NotNull String path) {
|
||||||
|
return getStrings(path, false, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of strings from config.
|
* Get a list of strings from config.
|
||||||
*
|
*
|
||||||
* @param path The key to fetch the value from.
|
* @param path The key to fetch the value from.
|
||||||
* @param format If the strings should be formatted.
|
* @param format If the strings should be formatted.
|
||||||
|
* @param option The option.
|
||||||
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
List<String> getStrings(@NotNull String path,
|
default List<String> getStrings(@NotNull String path,
|
||||||
boolean format);
|
boolean format,
|
||||||
|
@NotNull StringUtils.FormatOption option) {
|
||||||
|
return Objects.requireNonNullElse(getStringsOrNull(path, format, option), new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of strings from config.
|
* Get a list of strings from config.
|
||||||
|
* <p>
|
||||||
|
* Formatted.
|
||||||
*
|
*
|
||||||
* @param path The key to fetch the value from.
|
* @param path The key to fetch the value from.
|
||||||
* @return The found value, or null if not found.
|
* @return The found value, or null if not found.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
List<String> getStringsOrNull(@NotNull String path);
|
default List<String> getFormattedStringsOrNull(@NotNull String path) {
|
||||||
|
return getStringsOrNull(path, true, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of strings from config.
|
||||||
|
* <p>
|
||||||
|
* Formatted.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @param option The format option.
|
||||||
|
* @return The found value, or null if not found.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
default List<String> getFormattedStringsOrNull(@NotNull String path,
|
||||||
|
@NotNull StringUtils.FormatOption option) {
|
||||||
|
return getStringsOrNull(path, true, option);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of strings from config.
|
||||||
|
* <p>
|
||||||
|
* Not formatted.
|
||||||
|
* <p>
|
||||||
|
* This will be changed in newer versions to <b>not</b> format by default.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The found value, or null if not found.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
default List<String> getStringsOrNull(@NotNull String path) {
|
||||||
|
return getStringsOrNull(path, false, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of strings from config.
|
* Get a list of strings from config.
|
||||||
*
|
*
|
||||||
* @param path The key to fetch the value from.
|
* @param path The key to fetch the value from.
|
||||||
* @param format If the strings should be formatted.
|
* @param format If the strings should be formatted.
|
||||||
|
* @param option The format option.
|
||||||
* @return The found value, or null if not found.
|
* @return The found value, or null if not found.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
List<String> getStringsOrNull(@NotNull String path,
|
List<String> getStringsOrNull(@NotNull String path,
|
||||||
boolean format);
|
boolean format,
|
||||||
|
@NotNull StringUtils.FormatOption option);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a decimal from config.
|
* Get a decimal from config.
|
||||||
@@ -246,7 +462,45 @@ public interface Config extends Cloneable {
|
|||||||
* @param path The key to fetch the value from.
|
* @param path The key to fetch the value from.
|
||||||
* @return The found value, or 0 if not found.
|
* @return The found value, or 0 if not found.
|
||||||
*/
|
*/
|
||||||
double getDouble(@NotNull String path);
|
default double getDouble(@NotNull String path) {
|
||||||
|
return Objects.requireNonNullElse(getDoubleOrNull(path), 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a decimal value via a mathematical expression.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The computed value, or 0 if not found or invalid.
|
||||||
|
*/
|
||||||
|
default double getDoubleFromExpression(@NotNull String path) {
|
||||||
|
return getDoubleFromExpression(path, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a decimal value via a mathematical expression.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @param player The player to evaluate placeholders with respect to.
|
||||||
|
* @return The computed value, or 0 if not found or invalid.
|
||||||
|
*/
|
||||||
|
default double getDoubleFromExpression(@NotNull String path,
|
||||||
|
@Nullable Player player) {
|
||||||
|
return NumberUtils.evaluateExpression(this.getString(path), player, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a decimal from config.
|
* Get a decimal from config.
|
||||||
@@ -264,7 +518,9 @@ public interface Config extends Cloneable {
|
|||||||
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
List<Double> getDoubles(@NotNull String path);
|
default List<Double> getDoubles(@NotNull String path) {
|
||||||
|
return Objects.requireNonNullElse(getDoublesOrNull(path), new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of decimals from config.
|
* Get a list of decimals from config.
|
||||||
@@ -275,10 +531,82 @@ public interface Config extends Cloneable {
|
|||||||
@Nullable
|
@Nullable
|
||||||
List<Double> getDoublesOrNull(@NotNull String path);
|
List<Double> getDoublesOrNull(@NotNull String path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of subsections from config.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
default List<? extends Config> getSubsections(@NotNull String path) {
|
||||||
|
return Objects.requireNonNullElse(getSubsectionsOrNull(path), new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of subsections from config.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The found value, or null if not found.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
List<? extends Config> getSubsectionsOrNull(@NotNull String path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get config type.
|
||||||
|
*
|
||||||
|
* @return The type.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
ConfigType getType();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clone the config.
|
* Clone the config.
|
||||||
*
|
*
|
||||||
* @return The clone.
|
* @return The clone.
|
||||||
*/
|
*/
|
||||||
Config clone();
|
Config clone();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void addInjectablePlaceholder(@NotNull Iterable<InjectablePlaceholder> placeholders) {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default @NotNull List<InjectablePlaceholder> getPlaceholderInjections() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
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,34 +0,0 @@
|
|||||||
package com.willfp.eco.core.config.interfaces;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JSON configs have extra methods compared to yaml configs.
|
|
||||||
* <p>
|
|
||||||
* If you need to use them, then use JSONConfig instead.
|
|
||||||
*/
|
|
||||||
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
|
|
||||||
List<JSONConfig> getSubsections(@NotNull String path);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
JSONConfig clone();
|
|
||||||
}
|
|
||||||
@@ -1,12 +1,16 @@
|
|||||||
package com.willfp.eco.core.config.interfaces;
|
package com.willfp.eco.core.config.interfaces;
|
||||||
|
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for configs that physically exist as files in plugins.
|
* Interface for configs that physically exist as files in plugins.
|
||||||
*/
|
*/
|
||||||
public interface LoadableConfig {
|
public interface LoadableConfig extends Config {
|
||||||
/**
|
/**
|
||||||
* Create the file.
|
* Create the file.
|
||||||
*/
|
*/
|
||||||
@@ -34,9 +38,30 @@ public interface LoadableConfig {
|
|||||||
File getConfigFile();
|
File getConfigFile();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the config name (including extension)
|
* Get the config name (including extension).
|
||||||
*
|
*
|
||||||
* @return The name.
|
* @return The name.
|
||||||
*/
|
*/
|
||||||
String getName();
|
String getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get bukkit {@link YamlConfiguration}.
|
||||||
|
* <p>
|
||||||
|
* This used to represent the underlying config, but since 6.30.0 configs use
|
||||||
|
* their own implementations internally, without relying on bukkit.
|
||||||
|
*
|
||||||
|
* @return The config, or null if config is not yaml-based.
|
||||||
|
* @deprecated Use toBukkit() instead.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
@Deprecated(since = "6.30.0", forRemoval = true)
|
||||||
|
default YamlConfiguration getBukkitHandle() {
|
||||||
|
return this.toBukkit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert the config to a bukkit {@link YamlConfiguration}.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
YamlConfiguration toBukkit();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
package com.willfp.eco.core.config.interfaces;
|
|
||||||
|
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface for configs that wrap an {@link YamlConfiguration}.
|
|
||||||
*
|
|
||||||
* @see com.willfp.eco.core.config.yaml.wrapper.YamlConfigWrapper
|
|
||||||
*/
|
|
||||||
public interface WrappedYamlConfiguration {
|
|
||||||
/**
|
|
||||||
* Get the ConfigurationSection handle.
|
|
||||||
*
|
|
||||||
* @return The handle.
|
|
||||||
*/
|
|
||||||
YamlConfiguration getBukkitHandle();
|
|
||||||
}
|
|
||||||
@@ -1,24 +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.config.json.wrapper.LoadableJSONConfigWrapper;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Non-updatable JSON config that exists within a plugin jar.
|
|
||||||
*/
|
|
||||||
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 EcoPlugin plugin) {
|
|
||||||
super(Eco.getHandler().getConfigFactory().createLoadableJSONConfig(configName, plugin, "", plugin.getClass()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
package com.willfp.eco.core.config.json;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.Eco;
|
|
||||||
import com.willfp.eco.core.config.json.wrapper.JSONConfigWrapper;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Raw JSON config with a map of values at its core.
|
|
||||||
*/
|
|
||||||
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(Eco.getHandler().getConfigFactory().createJSONConfig(values));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,38 +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.
|
|
||||||
*/
|
|
||||||
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 JSONConfig clone() {
|
|
||||||
return this.getHandle().clone();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,51 +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.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper to handle the backend loadable JSON config implementations.
|
|
||||||
*/
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,7 +4,7 @@ import com.willfp.eco.core.config.interfaces.LoadableConfig;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Every {@link com.willfp.eco.core.EcoPlugin} has a config handler.
|
* Every {@link com.willfp.eco.core.PluginLike} has a config handler.
|
||||||
* <p>
|
* <p>
|
||||||
* Handles updating and saving configs.
|
* Handles updating and saving configs.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.willfp.eco.core.config.updating;
|
package com.willfp.eco.core.config.updating;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
@@ -23,10 +24,15 @@ import java.lang.annotation.Target;
|
|||||||
* <p>
|
* <p>
|
||||||
* The second:
|
* The second:
|
||||||
* <pre>{@code
|
* <pre>{@code
|
||||||
* public static void update(EcoPlugin plugin) {}
|
* public static void update(EcoPlugin plugin) {
|
||||||
* // Update code
|
* // Update code
|
||||||
|
* }
|
||||||
* }</pre>
|
* }</pre>
|
||||||
* <p>
|
* <p>
|
||||||
|
* If using kotlin, you have to annotate the method with {@code @JvmStatic}
|
||||||
|
* in order to prevent null pointer exceptions - 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
|
* Config update methods in all classes in a plugin jar will be called
|
||||||
* on reload.
|
* on reload.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -35,5 +41,6 @@ import java.lang.annotation.Target;
|
|||||||
*/
|
*/
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target(ElementType.METHOD)
|
@Target(ElementType.METHOD)
|
||||||
|
@Documented
|
||||||
public @interface ConfigUpdater {
|
public @interface ConfigUpdater {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,76 +0,0 @@
|
|||||||
package com.willfp.eco.core.config.wrapper;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
|
||||||
import com.willfp.eco.core.config.interfaces.Config;
|
|
||||||
import com.willfp.eco.core.config.interfaces.JSONConfig;
|
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal component to create backend config implementations.
|
|
||||||
*/
|
|
||||||
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 updateBlacklist Substring of keys to not add/remove keys for.
|
|
||||||
* @return The config implementation.
|
|
||||||
*/
|
|
||||||
Config createUpdatableYamlConfig(@NotNull String configName,
|
|
||||||
@NotNull EcoPlugin plugin,
|
|
||||||
@NotNull String subDirectoryPath,
|
|
||||||
@NotNull Class<?> source,
|
|
||||||
boolean removeUnused,
|
|
||||||
@NotNull String... updateBlacklist);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JSON loadable config.
|
|
||||||
*
|
|
||||||
* @param configName The name of the config
|
|
||||||
* @param plugin The plugin.
|
|
||||||
* @param subDirectoryPath The subdirectory path.
|
|
||||||
* @param source The class that owns the resource.
|
|
||||||
* @return The config implementation.
|
|
||||||
*/
|
|
||||||
JSONConfig createLoadableJSONConfig(@NotNull String configName,
|
|
||||||
@NotNull EcoPlugin plugin,
|
|
||||||
@NotNull String subDirectoryPath,
|
|
||||||
@NotNull Class<?> source);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Yaml loadable config.
|
|
||||||
*
|
|
||||||
* @param configName The name of the config
|
|
||||||
* @param plugin The plugin.
|
|
||||||
* @param subDirectoryPath The subdirectory path.
|
|
||||||
* @param source The class that owns the resource.
|
|
||||||
* @return The config implementation.
|
|
||||||
*/
|
|
||||||
Config createLoadableYamlConfig(@NotNull String configName,
|
|
||||||
@NotNull EcoPlugin plugin,
|
|
||||||
@NotNull String subDirectoryPath,
|
|
||||||
@NotNull Class<?> source);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Yaml config.
|
|
||||||
*
|
|
||||||
* @param config The handle.
|
|
||||||
* @return The config implementation.
|
|
||||||
*/
|
|
||||||
Config createYamlConfig(@NotNull YamlConfiguration config);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JSON config.
|
|
||||||
*
|
|
||||||
* @param values The values.
|
|
||||||
* @return The config implementation.
|
|
||||||
*/
|
|
||||||
JSONConfig createJSONConfig(@NotNull Map<String, Object> values);
|
|
||||||
}
|
|
||||||
@@ -1,11 +1,15 @@
|
|||||||
package com.willfp.eco.core.config.wrapper;
|
package com.willfp.eco.core.config.wrapper;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.config.ConfigType;
|
||||||
import com.willfp.eco.core.config.interfaces.Config;
|
import com.willfp.eco.core.config.interfaces.Config;
|
||||||
import lombok.Getter;
|
import com.willfp.eco.core.placeholder.InjectablePlaceholder;
|
||||||
|
import com.willfp.eco.util.StringUtils;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configs from eco have an internal implementation,
|
* Configs from eco have an internal implementation,
|
||||||
@@ -15,6 +19,7 @@ import java.util.List;
|
|||||||
*
|
*
|
||||||
* @param <T> The type of the handle.
|
* @param <T> The type of the handle.
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings({"MethodDoesntCallSuperMethod", "removal"})
|
||||||
public abstract class ConfigWrapper<T extends Config> implements Config {
|
public abstract class ConfigWrapper<T extends Config> implements Config {
|
||||||
/**
|
/**
|
||||||
* Configs from eco have an internal implementation,
|
* Configs from eco have an internal implementation,
|
||||||
@@ -26,7 +31,6 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
|
|||||||
* <p>
|
* <p>
|
||||||
* In general use, though, the handle isn't necessary.
|
* In general use, though, the handle isn't necessary.
|
||||||
*/
|
*/
|
||||||
@Getter
|
|
||||||
private final T handle;
|
private final T handle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,6 +43,7 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated(since = "6.31.1", forRemoval = true)
|
||||||
public void clearCache() {
|
public void clearCache() {
|
||||||
handle.clearCache();
|
handle.clearCache();
|
||||||
}
|
}
|
||||||
@@ -58,6 +63,12 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
|
|||||||
return handle.getKeys(deep);
|
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
|
@Override
|
||||||
public @Nullable Object get(@NotNull final String path) {
|
public @Nullable Object get(@NotNull final String path) {
|
||||||
return handle.get(path);
|
return handle.get(path);
|
||||||
@@ -69,109 +80,43 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
|
|||||||
handle.set(path, object);
|
handle.set(path, object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull Config getSubsection(@NotNull final String path) {
|
|
||||||
return handle.getSubsection(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable Config getSubsectionOrNull(@NotNull final String path) {
|
public @Nullable Config getSubsectionOrNull(@NotNull final String path) {
|
||||||
return handle.getSubsectionOrNull(path);
|
return handle.getSubsectionOrNull(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getInt(@NotNull final String path) {
|
|
||||||
return handle.getInt(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable Integer getIntOrNull(@NotNull final String path) {
|
public @Nullable Integer getIntOrNull(@NotNull final String path) {
|
||||||
return handle.getIntOrNull(path);
|
return handle.getIntOrNull(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getInt(@NotNull final String path,
|
|
||||||
final int def) {
|
|
||||||
return handle.getInt(path, def);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull List<Integer> getInts(@NotNull final String path) {
|
|
||||||
return handle.getInts(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable List<Integer> getIntsOrNull(@NotNull final String path) {
|
public @Nullable List<Integer> getIntsOrNull(@NotNull final String path) {
|
||||||
return handle.getIntsOrNull(path);
|
return handle.getIntsOrNull(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean getBool(@NotNull final String path) {
|
|
||||||
return handle.getBool(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable Boolean getBoolOrNull(@NotNull final String path) {
|
public @Nullable Boolean getBoolOrNull(@NotNull final String path) {
|
||||||
return handle.getBoolOrNull(path);
|
return handle.getBoolOrNull(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull List<Boolean> getBools(@NotNull final String path) {
|
|
||||||
return handle.getBools(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable List<Boolean> getBoolsOrNull(@NotNull final String path) {
|
public @Nullable List<Boolean> getBoolsOrNull(@NotNull final String path) {
|
||||||
return handle.getBoolsOrNull(path);
|
return handle.getBoolsOrNull(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull String getString(@NotNull final String path) {
|
|
||||||
return handle.getString(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull String getString(@NotNull final String path,
|
|
||||||
final boolean format) {
|
|
||||||
return handle.getString(path, format);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable String getStringOrNull(@NotNull final String path) {
|
|
||||||
return handle.getStringOrNull(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable String getStringOrNull(@NotNull final String path,
|
public @Nullable String getStringOrNull(@NotNull final String path,
|
||||||
final boolean format) {
|
final boolean format,
|
||||||
return handle.getStringOrNull(path, format);
|
@NotNull final StringUtils.FormatOption option) {
|
||||||
}
|
return handle.getStringOrNull(path, format, option);
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull List<String> getStrings(@NotNull final String path) {
|
|
||||||
return handle.getStrings(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull List<String> getStrings(@NotNull final String path,
|
|
||||||
final boolean format) {
|
|
||||||
return handle.getStrings(path, format);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable List<String> getStringsOrNull(@NotNull final String path) {
|
|
||||||
return handle.getStringsOrNull(path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable List<String> getStringsOrNull(@NotNull final String path,
|
public @Nullable List<String> getStringsOrNull(@NotNull final String path,
|
||||||
final boolean format) {
|
final boolean format,
|
||||||
return handle.getStringsOrNull(path, format);
|
@NotNull final StringUtils.FormatOption option) {
|
||||||
}
|
return handle.getStringsOrNull(path, format, option);
|
||||||
|
|
||||||
@Override
|
|
||||||
public double getDouble(@NotNull final String path) {
|
|
||||||
return handle.getDouble(path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -180,17 +125,51 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull List<Double> getDoubles(@NotNull final String path) {
|
public @Nullable List<Double> getDoublesOrNull(@NotNull final String path) {
|
||||||
return handle.getDoubles(path);
|
return handle.getDoublesOrNull(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable List<Double> getDoublesOrNull(@NotNull final String path) {
|
public @Nullable List<? extends Config> getSubsectionsOrNull(@NotNull final String path) {
|
||||||
return handle.getDoublesOrNull(path);
|
return handle.getSubsectionsOrNull(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Config clone() {
|
public Config clone() {
|
||||||
return handle.clone();
|
return handle.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ConfigType getType() {
|
||||||
|
return handle.getType();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addInjectablePlaceholder(@NotNull final Iterable<InjectablePlaceholder> placeholders) {
|
||||||
|
handle.addInjectablePlaceholder(placeholders);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull List<InjectablePlaceholder> getPlaceholderInjections() {
|
||||||
|
return handle.getPlaceholderInjections();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearInjectedPlaceholders() {
|
||||||
|
handle.clearInjectedPlaceholders();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> toMap() {
|
||||||
|
return this.handle.toMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the handle.
|
||||||
|
*
|
||||||
|
* @return The handle.
|
||||||
|
*/
|
||||||
|
public T getHandle() {
|
||||||
|
return this.handle;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
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 java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper to handle the backend loadable yaml config implementations.
|
||||||
|
*/
|
||||||
|
public abstract class LoadableConfigWrapper extends ConfigWrapper<LoadableConfig> implements LoadableConfig {
|
||||||
|
/**
|
||||||
|
* Create a config wrapper.
|
||||||
|
*
|
||||||
|
* @param handle The handle.
|
||||||
|
*/
|
||||||
|
protected LoadableConfigWrapper(@NotNull final LoadableConfig handle) {
|
||||||
|
super(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createFile() {
|
||||||
|
this.getHandle().createFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getResourcePath() {
|
||||||
|
return this.getHandle().getResourcePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void save() throws IOException {
|
||||||
|
this.getHandle().save();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File getConfigFile() {
|
||||||
|
return this.getHandle().getConfigFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return this.getHandle().getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull YamlConfiguration toBukkit() {
|
||||||
|
return this.getHandle().toBukkit();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,53 +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.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.
|
|
||||||
*/
|
|
||||||
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 EcoPlugin plugin,
|
|
||||||
@NotNull final String... updateBlacklist) {
|
|
||||||
super(
|
|
||||||
Eco.getHandler().getConfigFactory().createUpdatableYamlConfig(
|
|
||||||
configName,
|
|
||||||
plugin,
|
|
||||||
"",
|
|
||||||
plugin.getClass(),
|
|
||||||
removeUnused, 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) {
|
|
||||||
super(
|
|
||||||
Eco.getHandler().getConfigFactory().createUpdatableYamlConfig(
|
|
||||||
configName,
|
|
||||||
plugin,
|
|
||||||
"",
|
|
||||||
plugin.getClass(),
|
|
||||||
removeUnused
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,43 +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.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.
|
|
||||||
*/
|
|
||||||
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 EcoPlugin plugin,
|
|
||||||
@NotNull final Class<?> source,
|
|
||||||
@NotNull final String subDirectoryPath,
|
|
||||||
@NotNull final String... updateBlacklist) {
|
|
||||||
super(
|
|
||||||
Eco.getHandler().getConfigFactory().createUpdatableYamlConfig(
|
|
||||||
configName,
|
|
||||||
plugin,
|
|
||||||
subDirectoryPath,
|
|
||||||
source,
|
|
||||||
removeUnused,
|
|
||||||
updateBlacklist
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,24 +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.config.yaml.wrapper.LoadableYamlConfigWrapper;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Non-updatable yaml config that exists within a plugin jar.
|
|
||||||
*/
|
|
||||||
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 EcoPlugin plugin) {
|
|
||||||
super(Eco.getHandler().getConfigFactory().createLoadableYamlConfig(configName, plugin, "", plugin.getClass()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
package com.willfp.eco.core.config.yaml;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.Eco;
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
public class YamlTransientConfig extends YamlConfigWrapper {
|
|
||||||
/**
|
|
||||||
* @param config The YamlConfiguration handle.
|
|
||||||
*/
|
|
||||||
public YamlTransientConfig(@NotNull final YamlConfiguration config) {
|
|
||||||
super(Eco.getHandler().getConfigFactory().createYamlConfig(config));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param contents The contents of the config.
|
|
||||||
*/
|
|
||||||
public YamlTransientConfig(@NotNull final String contents) {
|
|
||||||
super(Eco.getHandler().getConfigFactory().createYamlConfig(YamlConfiguration.loadConfiguration(new StringReader(contents))));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,51 +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.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper to handle the backend loadable yaml config implementations.
|
|
||||||
*/
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +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.
|
|
||||||
*/
|
|
||||||
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package com.willfp.eco.core.data;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.Eco;
|
||||||
|
import org.bukkit.OfflinePlayer;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Persistent data storage interface for players.
|
||||||
|
* <p>
|
||||||
|
* Profiles save automatically, so there is no need to save after changes.
|
||||||
|
*/
|
||||||
|
public interface PlayerProfile extends Profile {
|
||||||
|
/**
|
||||||
|
* Load a player profile.
|
||||||
|
*
|
||||||
|
* @param player The player.
|
||||||
|
* @return The profile.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
static PlayerProfile load(@NotNull final OfflinePlayer player) {
|
||||||
|
return load(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load a player profile.
|
||||||
|
*
|
||||||
|
* @param uuid The player's UUID.
|
||||||
|
* @return The profile.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
static PlayerProfile load(@NotNull final UUID uuid) {
|
||||||
|
return Eco.get().loadPlayerProfile(uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
30
eco-api/src/main/java/com/willfp/eco/core/data/Profile.java
Normal file
30
eco-api/src/main/java/com/willfp/eco/core/data/Profile.java
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package com.willfp.eco.core.data;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.data.keys.PersistentDataKey;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Persistent data storage interface.
|
||||||
|
* <p>
|
||||||
|
* Profiles save automatically, so there is no need to save after changes.
|
||||||
|
*/
|
||||||
|
public interface Profile {
|
||||||
|
/**
|
||||||
|
* Write a key to persistent data.
|
||||||
|
*
|
||||||
|
* @param key The key.
|
||||||
|
* @param value The value.
|
||||||
|
* @param <T> The type of the key.
|
||||||
|
*/
|
||||||
|
<T> void write(@NotNull PersistentDataKey<T> key,
|
||||||
|
@NotNull T value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a key from persistent data.
|
||||||
|
*
|
||||||
|
* @param key The key.
|
||||||
|
* @param <T> The type of the key.
|
||||||
|
* @return The value, or the default value if not found.
|
||||||
|
*/
|
||||||
|
<T> @NotNull T read(@NotNull PersistentDataKey<T> key);
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.willfp.eco.core.data;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.Eco;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Persistent data storage interface for servers.
|
||||||
|
* <p>
|
||||||
|
* Profiles save automatically, so there is no need to save after changes.
|
||||||
|
*/
|
||||||
|
public interface ServerProfile extends Profile {
|
||||||
|
/**
|
||||||
|
* Load the server profile.
|
||||||
|
*
|
||||||
|
* @return The profile.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
static ServerProfile load() {
|
||||||
|
return Eco.get().getServerProfile();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
package com.willfp.eco.core.data.keys;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.Eco;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A persistent data key is a key with a type that can be stored about an offline player.
|
||||||
|
*
|
||||||
|
* @param <T> The type of the data.
|
||||||
|
*/
|
||||||
|
public final class PersistentDataKey<T> {
|
||||||
|
/**
|
||||||
|
* The key of the persistent data value.
|
||||||
|
*/
|
||||||
|
private final NamespacedKey key;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default value for the key.
|
||||||
|
*/
|
||||||
|
private final T defaultValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The persistent data key type.
|
||||||
|
*/
|
||||||
|
private final PersistentDataKeyType<T> type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new Persistent Data Key.
|
||||||
|
*
|
||||||
|
* @param key The key.
|
||||||
|
* @param type The data type.
|
||||||
|
* @param defaultValue The default value.
|
||||||
|
*/
|
||||||
|
public PersistentDataKey(@NotNull final NamespacedKey key,
|
||||||
|
@NotNull final PersistentDataKeyType<T> type,
|
||||||
|
@NotNull final T defaultValue) {
|
||||||
|
this.key = key;
|
||||||
|
this.defaultValue = defaultValue;
|
||||||
|
this.type = type;
|
||||||
|
|
||||||
|
Eco.get().registerPersistentKey(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "PersistentDataKey{"
|
||||||
|
+ "key=" + key
|
||||||
|
+ ", defaultValue=" + defaultValue
|
||||||
|
+ ", type=" + type
|
||||||
|
+ '}';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the key.
|
||||||
|
*
|
||||||
|
* @return The key.
|
||||||
|
*/
|
||||||
|
public NamespacedKey getKey() {
|
||||||
|
return this.key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the default value.
|
||||||
|
*
|
||||||
|
* @return The default value.
|
||||||
|
*/
|
||||||
|
public T getDefaultValue() {
|
||||||
|
return this.defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the data key type.
|
||||||
|
*
|
||||||
|
* @return The key type.
|
||||||
|
*/
|
||||||
|
public PersistentDataKeyType<T> getType() {
|
||||||
|
return this.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In older eco versions, keys would have to be categorized in order
|
||||||
|
* to register the columns in the MySQL database. This is no longer needed.
|
||||||
|
* <p>
|
||||||
|
* Old description is below:
|
||||||
|
* <p>
|
||||||
|
* Categorize key as a server key, will register new column to MySQL
|
||||||
|
* database immediately rather than waiting for auto-categorization.
|
||||||
|
* <p>
|
||||||
|
* This will improve performance.
|
||||||
|
*
|
||||||
|
* @return The key.
|
||||||
|
* @deprecated Not required since the new MySQL data handler was introduced.
|
||||||
|
*/
|
||||||
|
@Deprecated(since = "6.40.0", forRemoval = true)
|
||||||
|
public PersistentDataKey<T> server() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In older eco versions, keys would have to be categorized in order
|
||||||
|
* to register the columns in the MySQL database. This is no longer needed.
|
||||||
|
* <p>
|
||||||
|
* Old description is below:
|
||||||
|
* <p>
|
||||||
|
* Categorize key as a player key, will register new column to MySQL
|
||||||
|
* database immediately rather than waiting for auto-categorization.
|
||||||
|
* <p>
|
||||||
|
* This will improve performance.
|
||||||
|
*
|
||||||
|
* @return The key.
|
||||||
|
* @deprecated Not required since the new MySQL data handler was introduced.
|
||||||
|
*/
|
||||||
|
@Deprecated(since = "6.40.0", forRemoval = true)
|
||||||
|
public PersistentDataKey<T> player() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all persistent data keys.
|
||||||
|
*
|
||||||
|
* @return The keys.
|
||||||
|
*/
|
||||||
|
public static Set<PersistentDataKey<?>> values() {
|
||||||
|
return Eco.get().getRegisteredPersistentDataKeys();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(@Nullable final Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(o instanceof PersistentDataKey that)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return Objects.equals(this.getKey(), that.getKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(this.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,139 @@
|
|||||||
|
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.
|
||||||
|
*
|
||||||
|
* @param <T> The type.
|
||||||
|
*/
|
||||||
|
public final class PersistentDataKeyType<T> {
|
||||||
|
/**
|
||||||
|
* The registered key types.
|
||||||
|
*/
|
||||||
|
private static final List<PersistentDataKeyType<?>> VALUES = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String.
|
||||||
|
*/
|
||||||
|
public static final PersistentDataKeyType<String> STRING = new PersistentDataKeyType<>(String.class, "STRING");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Boolean.
|
||||||
|
*/
|
||||||
|
public static final PersistentDataKeyType<Boolean> BOOLEAN = new PersistentDataKeyType<>(Boolean.class, "BOOLEAN");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Int.
|
||||||
|
*/
|
||||||
|
public static final PersistentDataKeyType<Integer> INT = new PersistentDataKeyType<>(Integer.class, "INT");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Double.
|
||||||
|
*/
|
||||||
|
public static final PersistentDataKeyType<Double> DOUBLE = new PersistentDataKeyType<>(Double.class, "DOUBLE");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String List.
|
||||||
|
*/
|
||||||
|
public static final PersistentDataKeyType<List<String>> STRING_LIST = new PersistentDataKeyType<>(null, "STRING_LIST");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Config.
|
||||||
|
*/
|
||||||
|
public static final PersistentDataKeyType<Config> CONFIG = new PersistentDataKeyType<>(Config.class, "CONFIG");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class of the type.
|
||||||
|
*/
|
||||||
|
private final Class<T> typeClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the key type.
|
||||||
|
*/
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the class of the type.
|
||||||
|
*
|
||||||
|
* @return The class.
|
||||||
|
* @deprecated String list type will return null.
|
||||||
|
*/
|
||||||
|
@Deprecated(since = "6.36.0", forRemoval = true)
|
||||||
|
@Nullable
|
||||||
|
public Class<T> getTypeClass() {
|
||||||
|
return typeClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the name of the key type.
|
||||||
|
*
|
||||||
|
* @return The name.
|
||||||
|
*/
|
||||||
|
public String name() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new PersistentDataKeyType.
|
||||||
|
*
|
||||||
|
* @param typeClass The type class.
|
||||||
|
* @param name The name.
|
||||||
|
*/
|
||||||
|
private PersistentDataKeyType(@Nullable final Class<T> typeClass,
|
||||||
|
@NotNull final String name) {
|
||||||
|
VALUES.add(this);
|
||||||
|
|
||||||
|
this.typeClass = typeClass;
|
||||||
|
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.
|
||||||
|
*
|
||||||
|
* @return The registered types.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static PersistentDataKeyType<?>[] values() {
|
||||||
|
return VALUES.toArray(new PersistentDataKeyType[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a key type from a name.
|
||||||
|
*
|
||||||
|
* @param name The name.
|
||||||
|
* @return The type, or null if not found.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public static PersistentDataKeyType<?> valueOf(@NotNull final String name) {
|
||||||
|
for (PersistentDataKeyType<?> type : VALUES) {
|
||||||
|
if (type.name.equalsIgnoreCase(name)) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,54 +1,39 @@
|
|||||||
package com.willfp.eco.core.display;
|
package com.willfp.eco.core.display;
|
||||||
|
|
||||||
import lombok.experimental.UtilityClass;
|
import com.willfp.eco.core.fast.FastItemStack;
|
||||||
import org.apache.commons.lang.Validate;
|
import com.willfp.eco.util.NamespacedKeyUtils;
|
||||||
import org.bukkit.NamespacedKey;
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.Inventory;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
|
||||||
import org.bukkit.persistence.PersistentDataContainer;
|
|
||||||
import org.bukkit.persistence.PersistentDataType;
|
import org.bukkit.persistence.PersistentDataType;
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class to manage client-side item display.
|
* Utility class to manage client-side item display.
|
||||||
*/
|
*/
|
||||||
@UtilityClass
|
public final class Display {
|
||||||
public class Display {
|
|
||||||
/**
|
/**
|
||||||
* The prefix for client-side lore lines.
|
* The prefix for client-side lore lines.
|
||||||
*/
|
*/
|
||||||
public static final String PREFIX = "§z";
|
public static final String PREFIX = "§z";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All registered display modules.
|
* All registered modules.
|
||||||
*/
|
*/
|
||||||
private static final Map<DisplayPriority, List<DisplayModule>> MODULES = new HashMap<>();
|
private static final Map<Integer, List<DisplayModule>> REGISTERED_MODULES = new TreeMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NamespacedKey for finalizing.
|
* The finalize key.
|
||||||
*/
|
*/
|
||||||
private static NamespacedKey finalizeKey = null;
|
private static final NamespacedKey FINALIZE_KEY = NamespacedKeyUtils.createEcoKey("finalized");
|
||||||
|
|
||||||
/**
|
|
||||||
* Register display module.
|
|
||||||
*
|
|
||||||
* @param module The module.
|
|
||||||
*/
|
|
||||||
public void registerDisplayModule(@NotNull final DisplayModule module) {
|
|
||||||
List<DisplayModule> modules = MODULES.get(module.getPriority());
|
|
||||||
|
|
||||||
modules.removeIf(module1 -> module1.getPluginName().equalsIgnoreCase(module.getPluginName()));
|
|
||||||
|
|
||||||
modules.add(module);
|
|
||||||
|
|
||||||
MODULES.put(module.getPriority(), modules);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display on ItemStacks.
|
* Display on ItemStacks.
|
||||||
@@ -56,33 +41,58 @@ public class Display {
|
|||||||
* @param itemStack The item.
|
* @param itemStack The item.
|
||||||
* @return The ItemStack.
|
* @return The ItemStack.
|
||||||
*/
|
*/
|
||||||
public ItemStack display(@NotNull final ItemStack itemStack) {
|
public static ItemStack display(@NotNull final ItemStack itemStack) {
|
||||||
if (!itemStack.hasItemMeta()) {
|
return display(itemStack, null);
|
||||||
return itemStack; // return early if there's no customization of the item
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display on ItemStacks.
|
||||||
|
*
|
||||||
|
* @param itemStack The item.
|
||||||
|
* @param player The player.
|
||||||
|
* @return The ItemStack.
|
||||||
|
*/
|
||||||
|
public static ItemStack display(@NotNull final ItemStack itemStack,
|
||||||
|
@Nullable final Player player) {
|
||||||
Map<String, Object[]> pluginVarArgs = new HashMap<>();
|
Map<String, Object[]> pluginVarArgs = new HashMap<>();
|
||||||
|
|
||||||
for (DisplayPriority priority : DisplayPriority.values()) {
|
for (List<DisplayModule> modules : REGISTERED_MODULES.values()) {
|
||||||
List<DisplayModule> modules = MODULES.get(priority);
|
|
||||||
for (DisplayModule module : modules) {
|
for (DisplayModule module : modules) {
|
||||||
pluginVarArgs.put(module.getPluginName(), module.generateVarArgs(itemStack));
|
pluginVarArgs.put(module.getPluginName(), module.generateVarArgs(itemStack));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
revert(itemStack);
|
Display.revert(itemStack);
|
||||||
|
|
||||||
ItemMeta meta = itemStack.getItemMeta();
|
if (!itemStack.hasItemMeta()) {
|
||||||
|
|
||||||
if (meta == null) {
|
|
||||||
return itemStack;
|
return itemStack;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (DisplayPriority priority : DisplayPriority.values()) {
|
ItemStack original = itemStack.clone();
|
||||||
List<DisplayModule> modules = MODULES.get(priority);
|
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) {
|
for (DisplayModule module : modules) {
|
||||||
Object[] varargs = pluginVarArgs.get(module.getPluginName());
|
Object[] varargs = pluginVarArgs.get(module.getPluginName());
|
||||||
|
|
||||||
|
if (varargs == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
module.display(itemStack, varargs);
|
module.display(itemStack, varargs);
|
||||||
|
|
||||||
|
if (player != null) {
|
||||||
|
module.display(itemStack, player, varargs);
|
||||||
|
module.display(itemStack, player, properties, varargs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,8 +105,20 @@ public class Display {
|
|||||||
* @param itemStack The item.
|
* @param itemStack The item.
|
||||||
* @return The ItemStack.
|
* @return The ItemStack.
|
||||||
*/
|
*/
|
||||||
public ItemStack displayAndFinalize(@NotNull final ItemStack itemStack) {
|
public static ItemStack displayAndFinalize(@NotNull final ItemStack itemStack) {
|
||||||
return finalize(display(itemStack));
|
return finalize(display(itemStack, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display on ItemStacks and then finalize.
|
||||||
|
*
|
||||||
|
* @param itemStack The item.
|
||||||
|
* @param player The player.
|
||||||
|
* @return The ItemStack.
|
||||||
|
*/
|
||||||
|
public static ItemStack displayAndFinalize(@NotNull final ItemStack itemStack,
|
||||||
|
@Nullable final Player player) {
|
||||||
|
return finalize(display(itemStack, player));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -105,30 +127,20 @@ public class Display {
|
|||||||
* @param itemStack The item.
|
* @param itemStack The item.
|
||||||
* @return The ItemStack.
|
* @return The ItemStack.
|
||||||
*/
|
*/
|
||||||
public ItemStack revert(@NotNull final ItemStack itemStack) {
|
public static ItemStack revert(@NotNull final ItemStack itemStack) {
|
||||||
if (Display.isFinalized(itemStack)) {
|
if (Display.isFinalized(itemStack)) {
|
||||||
unfinalize(itemStack);
|
Display.unfinalize(itemStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!itemStack.hasItemMeta()) {
|
FastItemStack fast = FastItemStack.wrap(itemStack);
|
||||||
return itemStack;
|
|
||||||
|
List<String> lore = fast.getLore();
|
||||||
|
|
||||||
|
if (!lore.isEmpty() && lore.removeIf(line -> line.startsWith(Display.PREFIX))) {
|
||||||
|
fast.setLore(lore);
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemMeta meta = itemStack.getItemMeta();
|
for (List<DisplayModule> modules : REGISTERED_MODULES.values()) {
|
||||||
|
|
||||||
if (meta == null) {
|
|
||||||
return itemStack;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> lore = meta.getLore();
|
|
||||||
|
|
||||||
if (lore != null && lore.removeIf(line -> line.startsWith(Display.PREFIX))) { // only apply lore modification if needed
|
|
||||||
meta.setLore(lore);
|
|
||||||
itemStack.setItemMeta(meta);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (DisplayPriority priority : DisplayPriority.values()) {
|
|
||||||
List<DisplayModule> modules = MODULES.get(priority);
|
|
||||||
for (DisplayModule module : modules) {
|
for (DisplayModule module : modules) {
|
||||||
module.revert(itemStack);
|
module.revert(itemStack);
|
||||||
}
|
}
|
||||||
@@ -143,21 +155,15 @@ public class Display {
|
|||||||
* @param itemStack The item.
|
* @param itemStack The item.
|
||||||
* @return The ItemStack.
|
* @return The ItemStack.
|
||||||
*/
|
*/
|
||||||
public ItemStack finalize(@NotNull final ItemStack itemStack) {
|
public static ItemStack finalize(@NotNull final ItemStack itemStack) {
|
||||||
Validate.notNull(finalizeKey, "Key cannot be null!");
|
|
||||||
|
|
||||||
if (itemStack.getType().getMaxStackSize() > 1) {
|
if (itemStack.getType().getMaxStackSize() > 1) {
|
||||||
return itemStack;
|
return itemStack;
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemMeta meta = itemStack.getItemMeta();
|
FastItemStack.wrap(itemStack)
|
||||||
if (meta == null) {
|
.getPersistentDataContainer()
|
||||||
return itemStack;
|
.set(FINALIZE_KEY, PersistentDataType.INTEGER, 1);
|
||||||
}
|
|
||||||
|
|
||||||
PersistentDataContainer container = meta.getPersistentDataContainer();
|
|
||||||
container.set(finalizeKey, PersistentDataType.INTEGER, 1);
|
|
||||||
itemStack.setItemMeta(meta);
|
|
||||||
return itemStack;
|
return itemStack;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,18 +173,11 @@ public class Display {
|
|||||||
* @param itemStack The item.
|
* @param itemStack The item.
|
||||||
* @return The ItemStack.
|
* @return The ItemStack.
|
||||||
*/
|
*/
|
||||||
public ItemStack unfinalize(@NotNull final ItemStack itemStack) {
|
public static ItemStack unfinalize(@NotNull final ItemStack itemStack) {
|
||||||
Validate.notNull(finalizeKey, "Key cannot be null!");
|
FastItemStack.wrap(itemStack)
|
||||||
|
.getPersistentDataContainer()
|
||||||
|
.remove(FINALIZE_KEY);
|
||||||
|
|
||||||
ItemMeta meta = itemStack.getItemMeta();
|
|
||||||
|
|
||||||
if (meta == null) {
|
|
||||||
return itemStack;
|
|
||||||
}
|
|
||||||
|
|
||||||
PersistentDataContainer container = meta.getPersistentDataContainer();
|
|
||||||
container.remove(finalizeKey);
|
|
||||||
itemStack.setItemMeta(meta);
|
|
||||||
return itemStack;
|
return itemStack;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,32 +187,30 @@ public class Display {
|
|||||||
* @param itemStack The item.
|
* @param itemStack The item.
|
||||||
* @return If finalized.
|
* @return If finalized.
|
||||||
*/
|
*/
|
||||||
public boolean isFinalized(@NotNull final ItemStack itemStack) {
|
public static boolean isFinalized(@NotNull final ItemStack itemStack) {
|
||||||
Validate.notNull(finalizeKey, "Key cannot be null!");
|
return FastItemStack.wrap(itemStack)
|
||||||
|
.getPersistentDataContainer()
|
||||||
ItemMeta meta = itemStack.getItemMeta();
|
.has(FINALIZE_KEY, PersistentDataType.INTEGER);
|
||||||
|
|
||||||
if (meta == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
PersistentDataContainer container = meta.getPersistentDataContainer();
|
|
||||||
return container.has(finalizeKey, PersistentDataType.INTEGER);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set key to be used for finalization.
|
* Register a new display module.
|
||||||
*
|
*
|
||||||
* @param finalizeKey The key.
|
* @param module The module.
|
||||||
*/
|
*/
|
||||||
@ApiStatus.Internal
|
public static void registerDisplayModule(@NotNull final DisplayModule module) {
|
||||||
public static void setFinalizeKey(@NotNull final NamespacedKey finalizeKey) {
|
List<DisplayModule> modules = REGISTERED_MODULES.getOrDefault(
|
||||||
Display.finalizeKey = finalizeKey;
|
module.getWeight(),
|
||||||
|
new ArrayList<>()
|
||||||
|
);
|
||||||
|
|
||||||
|
modules.removeIf(it -> it.getPluginName().equalsIgnoreCase(module.getPluginName()));
|
||||||
|
modules.add(module);
|
||||||
|
|
||||||
|
REGISTERED_MODULES.put(module.getWeight(), modules);
|
||||||
}
|
}
|
||||||
|
|
||||||
static {
|
private Display() {
|
||||||
for (DisplayPriority priority : DisplayPriority.values()) {
|
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||||
MODULES.put(priority, new ArrayList<>());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,24 @@
|
|||||||
package com.willfp.eco.core.display;
|
package com.willfp.eco.core.display;
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
import com.willfp.eco.core.EcoPlugin;
|
||||||
import com.willfp.eco.core.PluginDependent;
|
import org.bukkit.entity.Player;
|
||||||
import lombok.Getter;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class for all plugin-specific client-side item display modules.
|
* Class for all plugin-specific client-side item display modules.
|
||||||
*/
|
*/
|
||||||
public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
|
public abstract class DisplayModule {
|
||||||
/**
|
/**
|
||||||
* The priority of the module.
|
* The priority of the module.
|
||||||
*/
|
*/
|
||||||
@Getter
|
private final int weight;
|
||||||
private final DisplayPriority priority;
|
|
||||||
|
/**
|
||||||
|
* The plugin.
|
||||||
|
*/
|
||||||
|
private final EcoPlugin plugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new display module.
|
* Create a new display module.
|
||||||
@@ -24,8 +28,19 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
|
|||||||
*/
|
*/
|
||||||
protected DisplayModule(@NotNull final EcoPlugin plugin,
|
protected DisplayModule(@NotNull final EcoPlugin plugin,
|
||||||
@NotNull final DisplayPriority priority) {
|
@NotNull final DisplayPriority priority) {
|
||||||
super(plugin);
|
this(plugin, priority.getWeight());
|
||||||
this.priority = priority;
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -34,8 +49,36 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
|
|||||||
* @param itemStack The item.
|
* @param itemStack The item.
|
||||||
* @param args Optional args for display.
|
* @param args Optional args for display.
|
||||||
*/
|
*/
|
||||||
protected void display(@NotNull final ItemStack itemStack,
|
public void display(@NotNull final ItemStack itemStack,
|
||||||
@NotNull final Object... args) {
|
@NotNull final Object... args) {
|
||||||
|
// Technically optional.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display an item.
|
||||||
|
*
|
||||||
|
* @param itemStack The item.
|
||||||
|
* @param player The player.
|
||||||
|
* @param args Optional args for display.
|
||||||
|
*/
|
||||||
|
public void display(@NotNull final ItemStack itemStack,
|
||||||
|
@Nullable final Player player,
|
||||||
|
@NotNull final Object... args) {
|
||||||
|
// 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.
|
// Technically optional.
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +87,7 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
|
|||||||
*
|
*
|
||||||
* @param itemStack The item.
|
* @param itemStack The item.
|
||||||
*/
|
*/
|
||||||
protected void revert(@NotNull final ItemStack itemStack) {
|
public void revert(@NotNull final ItemStack itemStack) {
|
||||||
// Technically optional.
|
// Technically optional.
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +97,7 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
|
|||||||
* @param itemStack The itemStack.
|
* @param itemStack The itemStack.
|
||||||
* @return The plugin-specific varargs.
|
* @return The plugin-specific varargs.
|
||||||
*/
|
*/
|
||||||
protected Object[] generateVarArgs(@NotNull final ItemStack itemStack) {
|
public Object[] generateVarArgs(@NotNull final ItemStack itemStack) {
|
||||||
return new Object[0];
|
return new Object[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,6 +107,41 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
|
|||||||
* @return The plugin name.
|
* @return The plugin name.
|
||||||
*/
|
*/
|
||||||
public final String getPluginName() {
|
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 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.
|
* The priority (order) of display modules.
|
||||||
*/
|
*/
|
||||||
public enum DisplayPriority {
|
public enum DisplayPriority {
|
||||||
|
/**
|
||||||
|
* Custom weight.
|
||||||
|
*/
|
||||||
|
CUSTOM(250),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ran first.
|
* Ran first.
|
||||||
*/
|
*/
|
||||||
LOWEST,
|
LOWEST(100),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ran second.
|
* Ran second.
|
||||||
*/
|
*/
|
||||||
LOW,
|
LOW(200),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ran third.
|
* Ran third.
|
||||||
*/
|
*/
|
||||||
HIGH,
|
HIGH(300),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ran last.
|
* Ran last.
|
||||||
*/
|
*/
|
||||||
HIGHEST
|
HIGHEST(400);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The display priority weight.
|
||||||
|
*/
|
||||||
|
private final int weight;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new display priority.
|
||||||
|
*
|
||||||
|
* @param weight The weight.
|
||||||
|
*/
|
||||||
|
DisplayPriority(final int weight) {
|
||||||
|
this.weight = weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the weight.
|
||||||
|
*
|
||||||
|
* @return The weight.
|
||||||
|
*/
|
||||||
|
public int getWeight() {
|
||||||
|
return weight;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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}.
|
* The internally used {@link DropQueue}.
|
||||||
*/
|
*/
|
||||||
private final InternalDropQueue handle;
|
private final DropQueue delegate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Create a new DropQueue.
|
||||||
|
*
|
||||||
* @param player The player.
|
* @param player The player.
|
||||||
*/
|
*/
|
||||||
public DropQueue(@NotNull final Player 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.
|
* @return The DropQueue.
|
||||||
*/
|
*/
|
||||||
public DropQueue addItem(@NotNull final ItemStack item) {
|
public DropQueue addItem(@NotNull final ItemStack item) {
|
||||||
handle.addItem(item);
|
if (delegate == null) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate.addItem(item);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +64,11 @@ public class DropQueue {
|
|||||||
* @return The DropQueue.
|
* @return The DropQueue.
|
||||||
*/
|
*/
|
||||||
public DropQueue addItems(@NotNull final Collection<ItemStack> itemStacks) {
|
public DropQueue addItems(@NotNull final Collection<ItemStack> itemStacks) {
|
||||||
handle.addItems(itemStacks);
|
if (delegate == null) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate.addItems(itemStacks);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,7 +79,11 @@ public class DropQueue {
|
|||||||
* @return The DropQueue.
|
* @return The DropQueue.
|
||||||
*/
|
*/
|
||||||
public DropQueue addXP(final int amount) {
|
public DropQueue addXP(final int amount) {
|
||||||
handle.addXP(amount);
|
if (delegate == null) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate.addXP(amount);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +94,11 @@ public class DropQueue {
|
|||||||
* @return The DropQueue.
|
* @return The DropQueue.
|
||||||
*/
|
*/
|
||||||
public DropQueue setLocation(@NotNull final Location location) {
|
public DropQueue setLocation(@NotNull final Location location) {
|
||||||
handle.setLocation(location);
|
if (delegate == null) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate.setLocation(location);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,7 +108,11 @@ public class DropQueue {
|
|||||||
* @return The DropQueue.
|
* @return The DropQueue.
|
||||||
*/
|
*/
|
||||||
public DropQueue forceTelekinesis() {
|
public DropQueue forceTelekinesis() {
|
||||||
handle.forceTelekinesis();
|
if (delegate == null) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate.forceTelekinesis();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,6 +120,10 @@ public class DropQueue {
|
|||||||
* Push the queue.
|
* Push the queue.
|
||||||
*/
|
*/
|
||||||
public void push() {
|
public void push() {
|
||||||
handle.push();
|
if (delegate == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate.push();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
package com.willfp.eco.core.drops;
|
|
||||||
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal component to create backend DropQueue implementations.
|
|
||||||
*/
|
|
||||||
public interface DropQueueFactory {
|
|
||||||
/**
|
|
||||||
* Create a DropQueue.
|
|
||||||
*
|
|
||||||
* @param player The player.
|
|
||||||
* @return The Queue.
|
|
||||||
*/
|
|
||||||
InternalDropQueue create(@NotNull Player player);
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
package com.willfp.eco.core.drops;
|
|
||||||
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal interface for backend DropQueue implementations.
|
|
||||||
*/
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
package com.willfp.eco.core.entities;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A custom entity has 3 components.
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li>The key to identify it</li>
|
||||||
|
* <li>The test to check if any entity is this custom entity</li>
|
||||||
|
* <li>The supplier to spawn the custom {@link org.bukkit.entity.Entity}</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
public class CustomEntity implements TestableEntity {
|
||||||
|
/**
|
||||||
|
* The key.
|
||||||
|
*/
|
||||||
|
private final NamespacedKey key;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The test for Entities to pass.
|
||||||
|
*/
|
||||||
|
private final Predicate<@NotNull Entity> test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The provider to spawn the entity.
|
||||||
|
*/
|
||||||
|
private final Function<Location, Entity> provider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new custom entity.
|
||||||
|
*
|
||||||
|
* @param key The entity key.
|
||||||
|
* @param test The test.
|
||||||
|
* @param provider The provider to spawn the entity.
|
||||||
|
*/
|
||||||
|
public CustomEntity(@NotNull final NamespacedKey key,
|
||||||
|
@NotNull final Predicate<@NotNull Entity> test,
|
||||||
|
@NotNull final Function<Location, Entity> provider) {
|
||||||
|
this.key = key;
|
||||||
|
this.test = test;
|
||||||
|
this.provider = provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(@Nullable final Entity entity) {
|
||||||
|
if (entity == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return test.test(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Entity spawn(@NotNull final Location location) {
|
||||||
|
Validate.notNull(location.getWorld());
|
||||||
|
|
||||||
|
return provider.apply(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the entity.
|
||||||
|
*/
|
||||||
|
public void register() {
|
||||||
|
Entities.registerCustomEntity(this.getKey(), this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the key.
|
||||||
|
*
|
||||||
|
* @return The key.
|
||||||
|
*/
|
||||||
|
public NamespacedKey getKey() {
|
||||||
|
return this.key;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package com.willfp.eco.core.entities;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for Dummy Entities in order to filter them using instanceof.
|
||||||
|
*/
|
||||||
|
public interface DummyEntity extends Entity {
|
||||||
|
|
||||||
|
}
|
||||||
232
eco-api/src/main/java/com/willfp/eco/core/entities/Entities.java
Normal file
232
eco-api/src/main/java/com/willfp/eco/core/entities/Entities.java
Normal file
@@ -0,0 +1,232 @@
|
|||||||
|
package com.willfp.eco.core.entities;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParseResult;
|
||||||
|
import com.willfp.eco.core.entities.args.EntityArgParser;
|
||||||
|
import com.willfp.eco.core.entities.impl.EmptyTestableEntity;
|
||||||
|
import com.willfp.eco.core.entities.impl.ModifiedTestableEntity;
|
||||||
|
import com.willfp.eco.core.entities.impl.SimpleTestableEntity;
|
||||||
|
import com.willfp.eco.util.NamespacedKeyUtils;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to manage all custom and vanilla entities.
|
||||||
|
*/
|
||||||
|
public final class Entities {
|
||||||
|
/**
|
||||||
|
* All entities.
|
||||||
|
*/
|
||||||
|
private static final Map<NamespacedKey, TestableEntity> REGISTRY = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All entity parsers.
|
||||||
|
*/
|
||||||
|
private static final List<EntityArgParser> ARG_PARSERS = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The lookup handler.
|
||||||
|
*/
|
||||||
|
private static final EntitiesLookupHandler ENTITIES_LOOKUP_HANDLER = new EntitiesLookupHandler(Entities::doParse);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a new custom item.
|
||||||
|
*
|
||||||
|
* @param key The key of the item.
|
||||||
|
* @param item The item.
|
||||||
|
*/
|
||||||
|
public static void registerCustomEntity(@NotNull final NamespacedKey key,
|
||||||
|
@NotNull final TestableEntity item) {
|
||||||
|
REGISTRY.put(key, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a new arg parser.
|
||||||
|
*
|
||||||
|
* @param parser The parser.
|
||||||
|
*/
|
||||||
|
public static void registerArgParser(@NotNull final EntityArgParser parser) {
|
||||||
|
ARG_PARSERS.add(parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove an entity.
|
||||||
|
*
|
||||||
|
* @param key The key of the entity.
|
||||||
|
*/
|
||||||
|
public static void removeCustomEntity(@NotNull final NamespacedKey key) {
|
||||||
|
REGISTRY.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the backbone of the entire eco entity system.
|
||||||
|
* <p>
|
||||||
|
* You can look up a TestableEntity for any type or custom entity,
|
||||||
|
* and it will return it with any modifiers passed as parameters.
|
||||||
|
* <p>
|
||||||
|
* If you want to get an Entity instance from this, then just call
|
||||||
|
* {@link TestableEntity#spawn(Location)}.
|
||||||
|
* <p>
|
||||||
|
* The advantages of the testable entity system are that there is the inbuilt
|
||||||
|
* {@link TestableEntity#matches(Entity)} - this allows to check if any entity
|
||||||
|
* is that testable entity; which may sound negligible, but actually it allows for
|
||||||
|
* much more power and flexibility. For example, you can have an entity with an
|
||||||
|
* extra metadata tag, extra lore lines, different display name - and it
|
||||||
|
* will still work as long as the test passes.
|
||||||
|
*
|
||||||
|
* @param key The lookup string.
|
||||||
|
* @return The testable entity, or an empty testable entity if not found.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static TestableEntity lookup(@NotNull final String key) {
|
||||||
|
return ENTITIES_LOOKUP_HANDLER.parseKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static TestableEntity doParse(@NotNull final String[] args) {
|
||||||
|
if (args.length == 0) {
|
||||||
|
return new EmptyTestableEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
TestableEntity entity;
|
||||||
|
|
||||||
|
String[] split = args[0].toLowerCase().split(":");
|
||||||
|
|
||||||
|
if (split.length == 1) {
|
||||||
|
EntityType type;
|
||||||
|
try {
|
||||||
|
type = EntityType.valueOf(args[0].toUpperCase());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
return new EmptyTestableEntity();
|
||||||
|
}
|
||||||
|
entity = new SimpleTestableEntity(type);
|
||||||
|
} else {
|
||||||
|
String namespace = split[0];
|
||||||
|
String keyID = split[1];
|
||||||
|
NamespacedKey namespacedKey = NamespacedKeyUtils.create(namespace, keyID);
|
||||||
|
|
||||||
|
TestableEntity part = REGISTRY.get(namespacedKey);
|
||||||
|
|
||||||
|
if (part == null) {
|
||||||
|
return new EmptyTestableEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
entity = part;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] modifierArgs = Arrays.copyOfRange(args, 1, args.length);
|
||||||
|
|
||||||
|
List<EntityArgParseResult> parseResults = new ArrayList<>();
|
||||||
|
|
||||||
|
for (EntityArgParser argParser : ARG_PARSERS) {
|
||||||
|
EntityArgParseResult result = argParser.parseArguments(modifierArgs);
|
||||||
|
if (result != null) {
|
||||||
|
parseResults.add(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Function<Location, Entity> spawner = entity::spawn;
|
||||||
|
|
||||||
|
if (!parseResults.isEmpty()) {
|
||||||
|
entity = new ModifiedTestableEntity(
|
||||||
|
entity,
|
||||||
|
test -> {
|
||||||
|
for (EntityArgParseResult parseResult : parseResults) {
|
||||||
|
if (!parseResult.test().test(test)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
location -> {
|
||||||
|
Entity spawned = spawner.apply(location);
|
||||||
|
|
||||||
|
for (EntityArgParseResult parseResult : parseResults) {
|
||||||
|
parseResult.modifier().accept(spawned);
|
||||||
|
}
|
||||||
|
|
||||||
|
return spawned;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a Testable Entity from an ItemStack.
|
||||||
|
* <p>
|
||||||
|
* Will search for registered entity first. If there are no matches in the registry,
|
||||||
|
* then it will return a {@link com.willfp.eco.core.entities.impl.SimpleTestableEntity} matching the entity type.
|
||||||
|
* <p>
|
||||||
|
* If the entity is not custom and has unknown type, this will return null.
|
||||||
|
*
|
||||||
|
* @param entity The Entity.
|
||||||
|
* @return The found Testable Entity.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public static TestableEntity getEntity(@Nullable final Entity entity) {
|
||||||
|
if (entity == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
TestableEntity customEntity = getEntity(entity);
|
||||||
|
|
||||||
|
if (customEntity != null) {
|
||||||
|
return customEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (TestableEntity known : REGISTRY.values()) {
|
||||||
|
if (known.matches(entity)) {
|
||||||
|
return known;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity.getType() == EntityType.UNKNOWN) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SimpleTestableEntity(entity.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get if entity is a custom entity.
|
||||||
|
*
|
||||||
|
* @param entity The entity to check.
|
||||||
|
* @return If is custom.
|
||||||
|
*/
|
||||||
|
public static boolean isCustomEntity(@NotNull final Entity entity) {
|
||||||
|
for (TestableEntity testable : REGISTRY.values()) {
|
||||||
|
if (testable.matches(entity)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all registered custom items.
|
||||||
|
*
|
||||||
|
* @return A set of all items.
|
||||||
|
*/
|
||||||
|
public static Set<TestableEntity> getCustomEntities() {
|
||||||
|
return new HashSet<>(REGISTRY.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Entities() {
|
||||||
|
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package com.willfp.eco.core.entities;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.entities.impl.EmptyTestableEntity;
|
||||||
|
import com.willfp.eco.core.entities.impl.GroupedTestableEntities;
|
||||||
|
import com.willfp.eco.core.lookup.LookupHandler;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle item lookup strings.
|
||||||
|
*/
|
||||||
|
public class EntitiesLookupHandler implements LookupHandler<TestableEntity> {
|
||||||
|
/**
|
||||||
|
* The parser.
|
||||||
|
*/
|
||||||
|
private final Function<String[], @NotNull TestableEntity> parser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new lookup handler.
|
||||||
|
*
|
||||||
|
* @param parser The parser.
|
||||||
|
*/
|
||||||
|
public EntitiesLookupHandler(@NotNull final Function<String[], @NotNull TestableEntity> parser) {
|
||||||
|
this.parser = parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull TestableEntity parse(@NotNull final String[] args) {
|
||||||
|
return parser.apply(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean validate(@NotNull final TestableEntity object) {
|
||||||
|
return !(object instanceof EmptyTestableEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull TestableEntity getFailsafe() {
|
||||||
|
return new EmptyTestableEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull TestableEntity join(@NotNull final Collection<TestableEntity> options) {
|
||||||
|
return new GroupedTestableEntities(options);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.willfp.eco.core.entities;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.lookup.Testable;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An item with a test to see if any item is that item.
|
||||||
|
*/
|
||||||
|
public interface TestableEntity extends Testable<Entity> {
|
||||||
|
/**
|
||||||
|
* If an Entity matches the test.
|
||||||
|
*
|
||||||
|
* @param entity The entity to test.
|
||||||
|
* @return If the entity matches.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
boolean matches(@Nullable Entity entity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spawn the entity.
|
||||||
|
*
|
||||||
|
* @param location The location.
|
||||||
|
* @return The entity.
|
||||||
|
*/
|
||||||
|
Entity spawn(@NotNull Location location);
|
||||||
|
}
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
package com.willfp.eco.core.entities.ai;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Mob;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base interface for all custom goals.
|
||||||
|
* <p>
|
||||||
|
* Can be used both for entity goals and target goals.
|
||||||
|
*
|
||||||
|
* @param <T> The type of mob that this goal can be applied to.
|
||||||
|
*/
|
||||||
|
public abstract class CustomGoal<T extends Mob> implements EntityGoal<T>, TargetGoal<T> {
|
||||||
|
/**
|
||||||
|
* The flags for the goal.
|
||||||
|
*/
|
||||||
|
private final Set<GoalFlag> flags = EnumSet.noneOf(GoalFlag.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the goal with a mob.
|
||||||
|
* <p>
|
||||||
|
* This will be run before any implementation code, treat this as the constructor.
|
||||||
|
*
|
||||||
|
* @param mob The mob.
|
||||||
|
*/
|
||||||
|
public abstract void initialize(@NotNull T mob);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get if the goal can be used.
|
||||||
|
* Will start the goal if this returns true.
|
||||||
|
*
|
||||||
|
* @return If the goal can be used.
|
||||||
|
*/
|
||||||
|
public abstract boolean canUse();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tick the goal.
|
||||||
|
* <p>
|
||||||
|
* Runs ever tick as long as canUse returns true.
|
||||||
|
* <p>
|
||||||
|
* Runs after start().
|
||||||
|
*/
|
||||||
|
public void tick() {
|
||||||
|
// Override when needed.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the goal.
|
||||||
|
* <p>
|
||||||
|
* Runs once canUse() returns true.
|
||||||
|
*/
|
||||||
|
public void start() {
|
||||||
|
// Override when needed.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop the goal.
|
||||||
|
* <p>
|
||||||
|
* Runs once canUse() returns false.
|
||||||
|
*/
|
||||||
|
public void stop() {
|
||||||
|
// Override when needed.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get if the goal can continue to be used.
|
||||||
|
*
|
||||||
|
* @return If the goal can continue to be used.
|
||||||
|
*/
|
||||||
|
public boolean canContinueToUse() {
|
||||||
|
return this.canUse();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get if the goal is interruptable.
|
||||||
|
*
|
||||||
|
* @return If interruptable.
|
||||||
|
*/
|
||||||
|
public boolean isInterruptable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the goal flags.
|
||||||
|
*
|
||||||
|
* @return The flags.
|
||||||
|
*/
|
||||||
|
public EnumSet<GoalFlag> getFlags() {
|
||||||
|
return EnumSet.copyOf(this.flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the flags for the goal.
|
||||||
|
*
|
||||||
|
* @param flags The flags.
|
||||||
|
*/
|
||||||
|
public final void setFlags(@NotNull final GoalFlag... flags) {
|
||||||
|
this.setFlags(EnumSet.copyOf(List.of(flags)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the flags for the goal.
|
||||||
|
*
|
||||||
|
* @param flags The flags.
|
||||||
|
*/
|
||||||
|
public void setFlags(@NotNull final EnumSet<GoalFlag> flags) {
|
||||||
|
this.flags.clear();
|
||||||
|
this.flags.addAll(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T addToEntity(@NotNull final T entity,
|
||||||
|
final int priority) {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"Shorthand syntax is not supported for custom goals by default as they can be both entity and target goals."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
package com.willfp.eco.core.entities.ai;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.Eco;
|
||||||
|
import org.bukkit.entity.Mob;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An entity controller allows for adding targets and goals to entities.
|
||||||
|
*
|
||||||
|
* @param <T> The wrapped mob.
|
||||||
|
*/
|
||||||
|
public interface EntityController<T extends Mob> {
|
||||||
|
/**
|
||||||
|
* Add a target goal to the entity.
|
||||||
|
* <p>
|
||||||
|
* Mutates the instance.
|
||||||
|
*
|
||||||
|
* @param priority The priority.
|
||||||
|
* @param goal The goal.
|
||||||
|
* @return The entity controller.
|
||||||
|
*/
|
||||||
|
EntityController<T> addTargetGoal(int priority,
|
||||||
|
@NotNull TargetGoal<? super T> goal);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove all target goals from the entity.
|
||||||
|
* <p>
|
||||||
|
* Mutates the instance.
|
||||||
|
*
|
||||||
|
* @return The entity controller.
|
||||||
|
*/
|
||||||
|
EntityController<T> clearTargetGoals();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a target goal from the entity.
|
||||||
|
* <p>
|
||||||
|
* Mutates the instance.
|
||||||
|
*
|
||||||
|
* @param goal The goal.
|
||||||
|
* @return The entity controller.
|
||||||
|
*/
|
||||||
|
EntityController<T> removeTargetGoal(@NotNull TargetGoal<? super T> goal);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an entity goal to the entity.
|
||||||
|
* <p>
|
||||||
|
* Mutates the instance.
|
||||||
|
*
|
||||||
|
* @param priority The priority.
|
||||||
|
* @param goal The goal.
|
||||||
|
* @return The entity controller.
|
||||||
|
*/
|
||||||
|
EntityController<T> addEntityGoal(int priority,
|
||||||
|
@NotNull EntityGoal<? super T> goal);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove an entity goal from the entity.
|
||||||
|
* <p>
|
||||||
|
* Mutates the instance.
|
||||||
|
*
|
||||||
|
* @param goal The goal.
|
||||||
|
* @return The entity controller.
|
||||||
|
*/
|
||||||
|
EntityController<T> removeEntityGoal(@NotNull EntityGoal<? super T> goal);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove all entity goals from the entity.
|
||||||
|
* <p>
|
||||||
|
* Mutates the instance.
|
||||||
|
*
|
||||||
|
* @return The entity controller.
|
||||||
|
*/
|
||||||
|
EntityController<T> clearEntityGoals();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove all goals from the entity.
|
||||||
|
* <p>
|
||||||
|
* Mutates the instance.
|
||||||
|
*
|
||||||
|
* @return The entity controller.
|
||||||
|
*/
|
||||||
|
default EntityController<T> clearAllGoals() {
|
||||||
|
this.clearTargetGoals();
|
||||||
|
return this.clearEntityGoals();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the mob back from the controlled entity.
|
||||||
|
* <p>
|
||||||
|
* Not required to apply changes, as the mob instance will be altered.
|
||||||
|
*
|
||||||
|
* @return The mob.
|
||||||
|
*/
|
||||||
|
T getEntity();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an entity controller for an entity in order to modify targets and goals.
|
||||||
|
*
|
||||||
|
* @param entity The entity.
|
||||||
|
* @param <T> The mob type.
|
||||||
|
* @return The entity controller.
|
||||||
|
*/
|
||||||
|
static <T extends Mob> EntityController<T> getFor(@NotNull final T entity) {
|
||||||
|
return Eco.get().createEntityController(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.willfp.eco.core.entities.ai;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Mob;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A goal for entity AI.
|
||||||
|
*
|
||||||
|
* @param <T> The type of mob that the goal can be applied to.
|
||||||
|
*/
|
||||||
|
public interface EntityGoal<T extends Mob> extends Goal<T> {
|
||||||
|
@Override
|
||||||
|
default T addToEntity(@NotNull T entity, int priority) {
|
||||||
|
return EntityController.getFor(entity)
|
||||||
|
.addEntityGoal(priority, this)
|
||||||
|
.getEntity();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,175 @@
|
|||||||
|
package com.willfp.eco.core.entities.ai;
|
||||||
|
|
||||||
|
import com.google.common.collect.HashBiMap;
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalAvoidEntity;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalBreakDoors;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalBreatheAir;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalBreed;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalCatLieOnBed;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalCatSitOnBed;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalEatGrass;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalFleeSun;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalFloat;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalFollowBoats;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalFollowMobs;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalIllusionerBlindnessSpell;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalIllusionerMirrorSpell;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalInteract;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalLeapAtTarget;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalLookAtPlayer;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalMeleeAttack;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalMoveBackToVillage;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalMoveThroughVillage;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalMoveTowardsRestriction;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalMoveTowardsTarget;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalOcelotAttack;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalOpenDoors;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalPanic;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalRandomLookAround;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalRandomStroll;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalRandomSwimming;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalRangedAttack;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalRangedBowAttack;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalRangedCrossbowAttack;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalRestrictSun;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalStrollThroughVillage;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalTempt;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalTryFindWater;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalUseItem;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalWaterAvoidingRandomFlying;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalWaterAvoidingRandomStroll;
|
||||||
|
import com.willfp.eco.core.entities.ai.entity.EntityGoalWolfBeg;
|
||||||
|
import com.willfp.eco.core.serialization.KeyedDeserializer;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.entity.Mob;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to manage entity goals.
|
||||||
|
*/
|
||||||
|
public final class EntityGoals {
|
||||||
|
/**
|
||||||
|
* All registered deserializers.
|
||||||
|
*/
|
||||||
|
private static final Map<NamespacedKey, KeyedDeserializer<? extends EntityGoal<?>>> BY_KEY = HashBiMap.create();
|
||||||
|
|
||||||
|
static {
|
||||||
|
register(EntityGoalAvoidEntity.DESERIALIZER);
|
||||||
|
register(EntityGoalBreakDoors.DESERIALIZER);
|
||||||
|
register(EntityGoalBreatheAir.DESERIALIZER);
|
||||||
|
register(EntityGoalEatGrass.DESERIALIZER);
|
||||||
|
register(EntityGoalFleeSun.DESERIALIZER);
|
||||||
|
register(EntityGoalFloat.DESERIALIZER);
|
||||||
|
register(EntityGoalFollowBoats.DESERIALIZER);
|
||||||
|
register(EntityGoalFollowMobs.DESERIALIZER);
|
||||||
|
register(EntityGoalInteract.DESERIALIZER);
|
||||||
|
register(EntityGoalLeapAtTarget.DESERIALIZER);
|
||||||
|
register(EntityGoalLookAtPlayer.DESERIALIZER);
|
||||||
|
register(EntityGoalMeleeAttack.DESERIALIZER);
|
||||||
|
register(EntityGoalMoveBackToVillage.DESERIALIZER);
|
||||||
|
register(EntityGoalMoveThroughVillage.DESERIALIZER);
|
||||||
|
register(EntityGoalMoveTowardsRestriction.DESERIALIZER);
|
||||||
|
register(EntityGoalMoveTowardsTarget.DESERIALIZER);
|
||||||
|
register(EntityGoalOcelotAttack.DESERIALIZER);
|
||||||
|
register(EntityGoalOpenDoors.DESERIALIZER);
|
||||||
|
register(EntityGoalPanic.DESERIALIZER);
|
||||||
|
register(EntityGoalRandomLookAround.DESERIALIZER);
|
||||||
|
register(EntityGoalRandomStroll.DESERIALIZER);
|
||||||
|
register(EntityGoalRandomSwimming.DESERIALIZER);
|
||||||
|
register(EntityGoalRangedAttack.DESERIALIZER);
|
||||||
|
register(EntityGoalRangedBowAttack.DESERIALIZER);
|
||||||
|
register(EntityGoalRangedCrossbowAttack.DESERIALIZER);
|
||||||
|
register(EntityGoalRestrictSun.DESERIALIZER);
|
||||||
|
register(EntityGoalStrollThroughVillage.DESERIALIZER);
|
||||||
|
register(EntityGoalTempt.DESERIALIZER);
|
||||||
|
register(EntityGoalTryFindWater.DESERIALIZER);
|
||||||
|
register(EntityGoalUseItem.DESERIALIZER);
|
||||||
|
register(EntityGoalWaterAvoidingRandomFlying.DESERIALIZER);
|
||||||
|
register(EntityGoalWaterAvoidingRandomStroll.DESERIALIZER);
|
||||||
|
register(EntityGoalWolfBeg.DESERIALIZER);
|
||||||
|
register(EntityGoalBreed.DESERIALIZER);
|
||||||
|
register(EntityGoalCatSitOnBed.DESERIALIZER);
|
||||||
|
register(EntityGoalCatLieOnBed.DESERIALIZER);
|
||||||
|
register(EntityGoalIllusionerBlindnessSpell.DESERIALIZER);
|
||||||
|
register(EntityGoalIllusionerMirrorSpell.DESERIALIZER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get deserializer by key.
|
||||||
|
*
|
||||||
|
* @param key The key.
|
||||||
|
* @return The deserializer, or null if not found.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public static KeyedDeserializer<? extends EntityGoal<? extends Mob>> getByKey(@NotNull final NamespacedKey key) {
|
||||||
|
return BY_KEY.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get deserializer by key, with a defined type (to prevent cluttering code with unsafe casts).
|
||||||
|
*
|
||||||
|
* @param key The key.
|
||||||
|
* @param clazz The type of target goal.
|
||||||
|
* @param <T> The type of mob the goal can be applied to.
|
||||||
|
* @return The deserializer, or null if not found.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
@SuppressWarnings({"unchecked", "unused"})
|
||||||
|
public static <T extends Mob> KeyedDeserializer<EntityGoal<T>> getByKeyOfType(@NotNull final NamespacedKey key,
|
||||||
|
@NotNull final Class<T> clazz) {
|
||||||
|
return (KeyedDeserializer<EntityGoal<T>>) BY_KEY.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply goal to entity given key and config.
|
||||||
|
* <p>
|
||||||
|
* If the key or config are invalid, the goal will not be applied.
|
||||||
|
*
|
||||||
|
* @param entity The entity.
|
||||||
|
* @param key The key.
|
||||||
|
* @param config The config.
|
||||||
|
* @param priority The priority.
|
||||||
|
* @param <T> The entity type.
|
||||||
|
* @return The entity.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T extends Mob> T applyToEntity(@NotNull final T entity,
|
||||||
|
@NotNull final NamespacedKey key,
|
||||||
|
@NotNull final Config config,
|
||||||
|
final int priority) {
|
||||||
|
KeyedDeserializer<EntityGoal<T>> deserializer = getByKeyOfType(key, (Class<T>) entity.getClass());
|
||||||
|
if (deserializer == null) {
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityGoal<T> goal = deserializer.deserialize(config);
|
||||||
|
|
||||||
|
if (goal == null) {
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
return goal.addToEntity(entity, priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a deserializer for an entity goal.
|
||||||
|
*
|
||||||
|
* @param toRegister The entity goal to register.
|
||||||
|
* @param <T> The type of deserializer.
|
||||||
|
* @return The deserializer.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static <T extends KeyedDeserializer<? extends EntityGoal<?>>> T register(@NotNull final T toRegister) {
|
||||||
|
BY_KEY.put(toRegister.getKey(), toRegister);
|
||||||
|
return toRegister;
|
||||||
|
}
|
||||||
|
|
||||||
|
private EntityGoals() {
|
||||||
|
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package com.willfp.eco.core.entities.ai;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Mob;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A generic goal for entity AI.
|
||||||
|
*
|
||||||
|
* @param <T> The type of mob that the goal can be applied to.
|
||||||
|
*/
|
||||||
|
public interface Goal<T extends Mob> {
|
||||||
|
/**
|
||||||
|
* Add the entity goal to an entity.
|
||||||
|
* <p>
|
||||||
|
* The lower the priority, the higher up the execution order; so
|
||||||
|
* priority 0 will execute first. Lower priority (higher number) goals
|
||||||
|
* will only execute if all higher priority goals are stopped.
|
||||||
|
*
|
||||||
|
* @param entity The entity.
|
||||||
|
* @param priority The priority.
|
||||||
|
* @return The entity, modified.
|
||||||
|
*/
|
||||||
|
T addToEntity(@NotNull T entity, int priority);
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package com.willfp.eco.core.entities.ai;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flags for ai goals.
|
||||||
|
*/
|
||||||
|
public enum GoalFlag {
|
||||||
|
/**
|
||||||
|
* Move.
|
||||||
|
*/
|
||||||
|
MOVE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look around.
|
||||||
|
*/
|
||||||
|
LOOK,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jump.
|
||||||
|
*/
|
||||||
|
JUMP,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Target.
|
||||||
|
*/
|
||||||
|
TARGET
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.willfp.eco.core.entities.ai;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Mob;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A goal for entity target AI.
|
||||||
|
*
|
||||||
|
* @param <T> The type of mob that the goal can be applied to.
|
||||||
|
*/
|
||||||
|
public interface TargetGoal<T extends Mob> extends Goal<T> {
|
||||||
|
@Override
|
||||||
|
default T addToEntity(@NotNull T entity, int priority) {
|
||||||
|
return EntityController.getFor(entity)
|
||||||
|
.addTargetGoal(priority, this)
|
||||||
|
.getEntity();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
package com.willfp.eco.core.entities.ai;
|
||||||
|
|
||||||
|
import com.google.common.collect.HashBiMap;
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config;
|
||||||
|
import com.willfp.eco.core.entities.ai.target.TargetGoalDefendVillage;
|
||||||
|
import com.willfp.eco.core.entities.ai.target.TargetGoalHurtBy;
|
||||||
|
import com.willfp.eco.core.entities.ai.target.TargetGoalNearestAttackable;
|
||||||
|
import com.willfp.eco.core.entities.ai.target.TargetGoalNearestAttackableWitch;
|
||||||
|
import com.willfp.eco.core.entities.ai.target.TargetGoalNearestHealableRaider;
|
||||||
|
import com.willfp.eco.core.entities.ai.target.TargetGoalNonTameRandom;
|
||||||
|
import com.willfp.eco.core.entities.ai.target.TargetGoalOwnerHurtBy;
|
||||||
|
import com.willfp.eco.core.entities.ai.target.TargetGoalOwnerTarget;
|
||||||
|
import com.willfp.eco.core.entities.ai.target.TargetGoalResetUniversalAnger;
|
||||||
|
import com.willfp.eco.core.serialization.KeyedDeserializer;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.entity.Mob;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to manage target goals.
|
||||||
|
*/
|
||||||
|
public final class TargetGoals {
|
||||||
|
/**
|
||||||
|
* All registered deserializers.
|
||||||
|
*/
|
||||||
|
private static final Map<NamespacedKey, KeyedDeserializer<? extends TargetGoal<?>>> BY_KEY = HashBiMap.create();
|
||||||
|
|
||||||
|
static {
|
||||||
|
register(TargetGoalDefendVillage.DESERIALIZER);
|
||||||
|
register(TargetGoalHurtBy.DESERIALIZER);
|
||||||
|
register(TargetGoalNearestAttackable.DESERIALIZER);
|
||||||
|
register(TargetGoalNearestAttackableWitch.DESERIALIZER);
|
||||||
|
register(TargetGoalNearestHealableRaider.DESERIALIZER);
|
||||||
|
register(TargetGoalNonTameRandom.DESERIALIZER);
|
||||||
|
register(TargetGoalOwnerTarget.DESERIALIZER);
|
||||||
|
register(TargetGoalOwnerHurtBy.DESERIALIZER);
|
||||||
|
register(TargetGoalResetUniversalAnger.DESERIALIZER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get deserializer by key.
|
||||||
|
*
|
||||||
|
* @param key The key.
|
||||||
|
* @return The deserializer, or null if not found.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public static KeyedDeserializer<? extends TargetGoal<? extends Mob>> getByKey(@NotNull final NamespacedKey key) {
|
||||||
|
return BY_KEY.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get deserializer by key, with a defined type (to prevent cluttering code with unsafe casts).
|
||||||
|
*
|
||||||
|
* @param key The key.
|
||||||
|
* @param clazz The type of target goal.
|
||||||
|
* @param <T> The type of mob the goal can be applied to.
|
||||||
|
* @return The deserializer, or null if not found.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
@SuppressWarnings({"unchecked", "unused"})
|
||||||
|
public static <T extends Mob> KeyedDeserializer<TargetGoal<T>> getByKeyOfType(@NotNull final NamespacedKey key,
|
||||||
|
@NotNull final Class<T> clazz) {
|
||||||
|
return (KeyedDeserializer<TargetGoal<T>>) BY_KEY.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply goal to entity given key and config.
|
||||||
|
* <p>
|
||||||
|
* If the key or config are invalid, the goal will not be applied.
|
||||||
|
*
|
||||||
|
* @param entity The entity.
|
||||||
|
* @param key The key.
|
||||||
|
* @param config The config.
|
||||||
|
* @param priority The priority.
|
||||||
|
* @param <T> The entity type.
|
||||||
|
* @return The entity.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T extends Mob> T applyToEntity(@NotNull final T entity,
|
||||||
|
@NotNull final NamespacedKey key,
|
||||||
|
@NotNull final Config config,
|
||||||
|
final int priority) {
|
||||||
|
KeyedDeserializer<TargetGoal<T>> deserializer = getByKeyOfType(key, (Class<T>) entity.getClass());
|
||||||
|
if (deserializer == null) {
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
TargetGoal<T> goal = deserializer.deserialize(config);
|
||||||
|
|
||||||
|
if (goal == null) {
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
return goal.addToEntity(entity, priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a deserializer for a target goal.
|
||||||
|
*
|
||||||
|
* @param toRegister The target goal to register.
|
||||||
|
* @param <T> The type of deserializer.
|
||||||
|
* @return The deserializer.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static <T extends KeyedDeserializer<? extends TargetGoal<?>>> T register(@NotNull final T toRegister) {
|
||||||
|
BY_KEY.put(toRegister.getKey(), toRegister);
|
||||||
|
return toRegister;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TargetGoals() {
|
||||||
|
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
package com.willfp.eco.core.entities.ai.entity;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config;
|
||||||
|
import com.willfp.eco.core.entities.Entities;
|
||||||
|
import com.willfp.eco.core.entities.TestableEntity;
|
||||||
|
import com.willfp.eco.core.entities.ai.EntityGoal;
|
||||||
|
import com.willfp.eco.core.serialization.KeyedDeserializer;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.entity.Mob;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Avoid entities.
|
||||||
|
*
|
||||||
|
* @param entity The entity type to avoid.
|
||||||
|
* @param distance The distance to flee to.
|
||||||
|
* @param slowSpeed The slow movement speed.
|
||||||
|
* @param fastSpeed The fast movement speed.
|
||||||
|
*/
|
||||||
|
public record EntityGoalAvoidEntity(
|
||||||
|
@NotNull TestableEntity entity,
|
||||||
|
double distance,
|
||||||
|
double slowSpeed,
|
||||||
|
double fastSpeed
|
||||||
|
) implements EntityGoal<Mob> {
|
||||||
|
/**
|
||||||
|
* The deserializer for the goal.
|
||||||
|
*/
|
||||||
|
public static final KeyedDeserializer<EntityGoalAvoidEntity> DESERIALIZER = new Deserializer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserialize configs into the goal.
|
||||||
|
*/
|
||||||
|
private static final class Deserializer implements KeyedDeserializer<EntityGoalAvoidEntity> {
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public EntityGoalAvoidEntity deserialize(@NotNull final Config config) {
|
||||||
|
if (!(
|
||||||
|
config.has("entity")
|
||||||
|
&& config.has("distance")
|
||||||
|
&& config.has("slowSpeed")
|
||||||
|
&& config.has("fastSpeed")
|
||||||
|
)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
TestableEntity entity = Entities.lookup(config.getString("entity"));
|
||||||
|
|
||||||
|
return new EntityGoalAvoidEntity(
|
||||||
|
entity,
|
||||||
|
config.getDouble("distance"),
|
||||||
|
config.getDouble("slowSpeed"),
|
||||||
|
config.getDouble("fastSpeed")
|
||||||
|
);
|
||||||
|
} catch (Exception e) {
|
||||||
|
/*
|
||||||
|
Exceptions could be caused by configs having values of a wrong type,
|
||||||
|
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
|
||||||
|
so we encapsulate them as null.
|
||||||
|
*/
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public NamespacedKey getKey() {
|
||||||
|
return NamespacedKey.minecraft("avoid_entity");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package com.willfp.eco.core.entities.ai.entity;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config;
|
||||||
|
import com.willfp.eco.core.entities.ai.EntityGoal;
|
||||||
|
import com.willfp.eco.core.serialization.KeyedDeserializer;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.entity.Mob;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows an entity to break down doors.
|
||||||
|
*
|
||||||
|
* @param ticks The time taken to break the door. Minimum value is 240, as set by the game.
|
||||||
|
*/
|
||||||
|
public record EntityGoalBreakDoors(
|
||||||
|
int ticks
|
||||||
|
) implements EntityGoal<Mob> {
|
||||||
|
/**
|
||||||
|
* The deserializer for the goal.
|
||||||
|
*/
|
||||||
|
public static final KeyedDeserializer<EntityGoalBreakDoors> DESERIALIZER = new EntityGoalBreakDoors.Deserializer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserialize configs into the goal.
|
||||||
|
*/
|
||||||
|
private static final class Deserializer implements KeyedDeserializer<EntityGoalBreakDoors> {
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public EntityGoalBreakDoors deserialize(@NotNull final Config config) {
|
||||||
|
if (!(
|
||||||
|
config.has("ticks")
|
||||||
|
)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return new EntityGoalBreakDoors(
|
||||||
|
config.getInt("ticks")
|
||||||
|
);
|
||||||
|
} catch (Exception e) {
|
||||||
|
/*
|
||||||
|
Exceptions could be caused by configs having values of a wrong type,
|
||||||
|
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
|
||||||
|
so we encapsulate them as null.
|
||||||
|
*/
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public NamespacedKey getKey() {
|
||||||
|
return NamespacedKey.minecraft("break_doors");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.willfp.eco.core.entities.ai.entity;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config;
|
||||||
|
import com.willfp.eco.core.entities.ai.EntityGoal;
|
||||||
|
import com.willfp.eco.core.serialization.KeyedDeserializer;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.entity.Mob;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Breathe air.
|
||||||
|
*/
|
||||||
|
public record EntityGoalBreatheAir(
|
||||||
|
) implements EntityGoal<Mob> {
|
||||||
|
/**
|
||||||
|
* The deserializer for the goal.
|
||||||
|
*/
|
||||||
|
public static final KeyedDeserializer<EntityGoalBreatheAir> DESERIALIZER = new EntityGoalBreatheAir.Deserializer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserialize configs into the goal.
|
||||||
|
*/
|
||||||
|
private static final class Deserializer implements KeyedDeserializer<EntityGoalBreatheAir> {
|
||||||
|
@Override
|
||||||
|
public EntityGoalBreatheAir deserialize(@NotNull final Config config) {
|
||||||
|
return new EntityGoalBreatheAir();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public NamespacedKey getKey() {
|
||||||
|
return NamespacedKey.minecraft("breathe_air");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package com.willfp.eco.core.entities.ai.entity;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config;
|
||||||
|
import com.willfp.eco.core.entities.ai.EntityGoal;
|
||||||
|
import com.willfp.eco.core.serialization.KeyedDeserializer;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.entity.Animals;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows animals to breed.
|
||||||
|
*
|
||||||
|
* @param speed The speed at which to move to a partner.
|
||||||
|
*/
|
||||||
|
public record EntityGoalBreed(
|
||||||
|
double speed
|
||||||
|
) implements EntityGoal<Animals> {
|
||||||
|
/**
|
||||||
|
* The deserializer for the goal.
|
||||||
|
*/
|
||||||
|
public static final KeyedDeserializer<EntityGoalBreed> DESERIALIZER = new EntityGoalBreed.Deserializer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserialize configs into the goal.
|
||||||
|
*/
|
||||||
|
private static final class Deserializer implements KeyedDeserializer<EntityGoalBreed> {
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public EntityGoalBreed deserialize(@NotNull final Config config) {
|
||||||
|
if (!(
|
||||||
|
config.has("speed")
|
||||||
|
)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return new EntityGoalBreed(
|
||||||
|
config.getDouble("speed")
|
||||||
|
);
|
||||||
|
} catch (Exception e) {
|
||||||
|
/*
|
||||||
|
Exceptions could be caused by configs having values of a wrong type,
|
||||||
|
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
|
||||||
|
so we encapsulate them as null.
|
||||||
|
*/
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public NamespacedKey getKey() {
|
||||||
|
return NamespacedKey.minecraft("breed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package com.willfp.eco.core.entities.ai.entity;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config;
|
||||||
|
import com.willfp.eco.core.entities.ai.EntityGoal;
|
||||||
|
import com.willfp.eco.core.serialization.KeyedDeserializer;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.entity.Cat;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows a cat to lie on a bed.
|
||||||
|
*
|
||||||
|
* @param speed The speed at which to move to the bed.
|
||||||
|
* @param range The range at which to search for beds.
|
||||||
|
*/
|
||||||
|
public record EntityGoalCatLieOnBed(
|
||||||
|
double speed,
|
||||||
|
int range
|
||||||
|
) implements EntityGoal<Cat> {
|
||||||
|
/**
|
||||||
|
* The deserializer for the goal.
|
||||||
|
*/
|
||||||
|
public static final KeyedDeserializer<EntityGoalCatLieOnBed> DESERIALIZER = new EntityGoalCatLieOnBed.Deserializer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserialize configs into the goal.
|
||||||
|
*/
|
||||||
|
private static final class Deserializer implements KeyedDeserializer<EntityGoalCatLieOnBed> {
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public EntityGoalCatLieOnBed deserialize(@NotNull final Config config) {
|
||||||
|
if (!(
|
||||||
|
config.has("speed")
|
||||||
|
&& config.has("range")
|
||||||
|
)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return new EntityGoalCatLieOnBed(
|
||||||
|
config.getDouble("speed"),
|
||||||
|
config.getInt("range")
|
||||||
|
);
|
||||||
|
} catch (Exception e) {
|
||||||
|
/*
|
||||||
|
Exceptions could be caused by configs having values of a wrong type,
|
||||||
|
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
|
||||||
|
so we encapsulate them as null.
|
||||||
|
*/
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public NamespacedKey getKey() {
|
||||||
|
return NamespacedKey.minecraft("cat_lie_on_bed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package com.willfp.eco.core.entities.ai.entity;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config;
|
||||||
|
import com.willfp.eco.core.entities.ai.EntityGoal;
|
||||||
|
import com.willfp.eco.core.serialization.KeyedDeserializer;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.entity.Cat;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows a cat to sit on a bed.
|
||||||
|
*
|
||||||
|
* @param speed The speed at which to move to the bed.
|
||||||
|
*/
|
||||||
|
public record EntityGoalCatSitOnBed(
|
||||||
|
double speed
|
||||||
|
) implements EntityGoal<Cat> {
|
||||||
|
/**
|
||||||
|
* The deserializer for the goal.
|
||||||
|
*/
|
||||||
|
public static final KeyedDeserializer<EntityGoalCatSitOnBed> DESERIALIZER = new EntityGoalCatSitOnBed.Deserializer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserialize configs into the goal.
|
||||||
|
*/
|
||||||
|
private static final class Deserializer implements KeyedDeserializer<EntityGoalCatSitOnBed> {
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public EntityGoalCatSitOnBed deserialize(@NotNull final Config config) {
|
||||||
|
if (!(
|
||||||
|
config.has("speed")
|
||||||
|
)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return new EntityGoalCatSitOnBed(
|
||||||
|
config.getDouble("speed")
|
||||||
|
);
|
||||||
|
} catch (Exception e) {
|
||||||
|
/*
|
||||||
|
Exceptions could be caused by configs having values of a wrong type,
|
||||||
|
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
|
||||||
|
so we encapsulate them as null.
|
||||||
|
*/
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public NamespacedKey getKey() {
|
||||||
|
return NamespacedKey.minecraft("cat_sit_on_bed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.willfp.eco.core.entities.ai.entity;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config;
|
||||||
|
import com.willfp.eco.core.entities.ai.EntityGoal;
|
||||||
|
import com.willfp.eco.core.serialization.KeyedDeserializer;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.entity.Mob;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows an entity to eat the ground.
|
||||||
|
*/
|
||||||
|
public record EntityGoalEatGrass(
|
||||||
|
) implements EntityGoal<Mob> {
|
||||||
|
/**
|
||||||
|
* The deserializer for the goal.
|
||||||
|
*/
|
||||||
|
public static final KeyedDeserializer<EntityGoalEatGrass> DESERIALIZER = new EntityGoalEatGrass.Deserializer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserialize configs into the goal.
|
||||||
|
*/
|
||||||
|
private static final class Deserializer implements KeyedDeserializer<EntityGoalEatGrass> {
|
||||||
|
@Override
|
||||||
|
public EntityGoalEatGrass deserialize(@NotNull final Config config) {
|
||||||
|
return new EntityGoalEatGrass();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public NamespacedKey getKey() {
|
||||||
|
return NamespacedKey.minecraft("eat_grass");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package com.willfp.eco.core.entities.ai.entity;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config;
|
||||||
|
import com.willfp.eco.core.entities.ai.EntityGoal;
|
||||||
|
import com.willfp.eco.core.serialization.KeyedDeserializer;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.entity.Mob;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will make the entity actively avoid the sunlight.
|
||||||
|
*
|
||||||
|
* @param speed The speed at which to flee.
|
||||||
|
*/
|
||||||
|
public record EntityGoalFleeSun(
|
||||||
|
double speed
|
||||||
|
) implements EntityGoal<Mob> {
|
||||||
|
/**
|
||||||
|
* The deserializer for the goal.
|
||||||
|
*/
|
||||||
|
public static final KeyedDeserializer<EntityGoalFleeSun> DESERIALIZER = new EntityGoalFleeSun.Deserializer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserialize configs into the goal.
|
||||||
|
*/
|
||||||
|
private static final class Deserializer implements KeyedDeserializer<EntityGoalFleeSun> {
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public EntityGoalFleeSun deserialize(@NotNull final Config config) {
|
||||||
|
if (!(
|
||||||
|
config.has("speed")
|
||||||
|
)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return new EntityGoalFleeSun(
|
||||||
|
config.getDouble("speed")
|
||||||
|
);
|
||||||
|
} catch (Exception e) {
|
||||||
|
/*
|
||||||
|
Exceptions could be caused by configs having values of a wrong type,
|
||||||
|
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
|
||||||
|
so we encapsulate them as null.
|
||||||
|
*/
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public NamespacedKey getKey() {
|
||||||
|
return NamespacedKey.minecraft("flee_sun");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.willfp.eco.core.entities.ai.entity;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config;
|
||||||
|
import com.willfp.eco.core.entities.ai.EntityGoal;
|
||||||
|
import com.willfp.eco.core.serialization.KeyedDeserializer;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.entity.Mob;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows an entity to float on water.
|
||||||
|
*/
|
||||||
|
public record EntityGoalFloat(
|
||||||
|
) implements EntityGoal<Mob> {
|
||||||
|
/**
|
||||||
|
* The deserializer for the goal.
|
||||||
|
*/
|
||||||
|
public static final KeyedDeserializer<EntityGoalFloat> DESERIALIZER = new EntityGoalFloat.Deserializer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserialize configs into the goal.
|
||||||
|
*/
|
||||||
|
private static final class Deserializer implements KeyedDeserializer<EntityGoalFloat> {
|
||||||
|
@Override
|
||||||
|
public EntityGoalFloat deserialize(@NotNull final Config config) {
|
||||||
|
return new EntityGoalFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public NamespacedKey getKey() {
|
||||||
|
return NamespacedKey.minecraft("float");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.willfp.eco.core.entities.ai.entity;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config;
|
||||||
|
import com.willfp.eco.core.entities.ai.EntityGoal;
|
||||||
|
import com.willfp.eco.core.serialization.KeyedDeserializer;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.entity.Mob;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Follow boats.
|
||||||
|
*/
|
||||||
|
public record EntityGoalFollowBoats(
|
||||||
|
) implements EntityGoal<Mob> {
|
||||||
|
/**
|
||||||
|
* The deserializer for the goal.
|
||||||
|
*/
|
||||||
|
public static final KeyedDeserializer<EntityGoalFollowBoats> DESERIALIZER = new EntityGoalFollowBoats.Deserializer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserialize configs into the goal.
|
||||||
|
*/
|
||||||
|
private static final class Deserializer implements KeyedDeserializer<EntityGoalFollowBoats> {
|
||||||
|
@Override
|
||||||
|
public EntityGoalFollowBoats deserialize(@NotNull final Config config) {
|
||||||
|
return new EntityGoalFollowBoats();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public NamespacedKey getKey() {
|
||||||
|
return NamespacedKey.minecraft("follow_boats");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
package com.willfp.eco.core.entities.ai.entity;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config;
|
||||||
|
import com.willfp.eco.core.entities.ai.EntityGoal;
|
||||||
|
import com.willfp.eco.core.serialization.KeyedDeserializer;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.entity.Mob;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows an entity to follow and gather around all types of mobs, both hostile and neutral mobs.
|
||||||
|
*
|
||||||
|
* @param speed The speed at which to follow.
|
||||||
|
* @param minDistance The minimum follow distance.
|
||||||
|
* @param maxDistance The maximum follow distance.
|
||||||
|
*/
|
||||||
|
public record EntityGoalFollowMobs(
|
||||||
|
double speed,
|
||||||
|
double minDistance,
|
||||||
|
double maxDistance
|
||||||
|
) implements EntityGoal<Mob> {
|
||||||
|
/**
|
||||||
|
* The deserializer for the goal.
|
||||||
|
*/
|
||||||
|
public static final KeyedDeserializer<EntityGoalFollowMobs> DESERIALIZER = new EntityGoalFollowMobs.Deserializer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserialize configs into the goal.
|
||||||
|
*/
|
||||||
|
private static final class Deserializer implements KeyedDeserializer<EntityGoalFollowMobs> {
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public EntityGoalFollowMobs deserialize(@NotNull final Config config) {
|
||||||
|
if (!(
|
||||||
|
config.has("speed")
|
||||||
|
&& config.has("minDistance")
|
||||||
|
&& config.has("maxDistance")
|
||||||
|
)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return new EntityGoalFollowMobs(
|
||||||
|
config.getDouble("speed"),
|
||||||
|
config.getDouble("minDistance"),
|
||||||
|
config.getDouble("maxDistance")
|
||||||
|
);
|
||||||
|
} catch (Exception e) {
|
||||||
|
/*
|
||||||
|
Exceptions could be caused by configs having values of a wrong type,
|
||||||
|
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
|
||||||
|
so we encapsulate them as null.
|
||||||
|
*/
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public NamespacedKey getKey() {
|
||||||
|
return NamespacedKey.minecraft("follow_mobs");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.willfp.eco.core.entities.ai.entity;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config;
|
||||||
|
import com.willfp.eco.core.entities.ai.EntityGoal;
|
||||||
|
import com.willfp.eco.core.serialization.KeyedDeserializer;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.entity.Illusioner;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows an illusioner to perform the blindness spell.
|
||||||
|
*/
|
||||||
|
public record EntityGoalIllusionerBlindnessSpell(
|
||||||
|
) implements EntityGoal<Illusioner> {
|
||||||
|
/**
|
||||||
|
* The deserializer for the goal.
|
||||||
|
*/
|
||||||
|
public static final KeyedDeserializer<EntityGoalIllusionerBlindnessSpell> DESERIALIZER = new EntityGoalIllusionerBlindnessSpell.Deserializer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserialize configs into the goal.
|
||||||
|
*/
|
||||||
|
private static final class Deserializer implements KeyedDeserializer<EntityGoalIllusionerBlindnessSpell> {
|
||||||
|
@Override
|
||||||
|
public EntityGoalIllusionerBlindnessSpell deserialize(@NotNull final Config config) {
|
||||||
|
return new EntityGoalIllusionerBlindnessSpell();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public NamespacedKey getKey() {
|
||||||
|
return NamespacedKey.minecraft("illusioner_blindness_spell");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.willfp.eco.core.entities.ai.entity;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config;
|
||||||
|
import com.willfp.eco.core.entities.ai.EntityGoal;
|
||||||
|
import com.willfp.eco.core.serialization.KeyedDeserializer;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.entity.Illusioner;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows an illusioner to perform the mirror spell.
|
||||||
|
*/
|
||||||
|
public record EntityGoalIllusionerMirrorSpell(
|
||||||
|
) implements EntityGoal<Illusioner> {
|
||||||
|
/**
|
||||||
|
* The deserializer for the goal.
|
||||||
|
*/
|
||||||
|
public static final KeyedDeserializer<EntityGoalIllusionerMirrorSpell> DESERIALIZER = new EntityGoalIllusionerMirrorSpell.Deserializer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserialize configs into the goal.
|
||||||
|
*/
|
||||||
|
private static final class Deserializer implements KeyedDeserializer<EntityGoalIllusionerMirrorSpell> {
|
||||||
|
@Override
|
||||||
|
public EntityGoalIllusionerMirrorSpell deserialize(@NotNull final Config config) {
|
||||||
|
return new EntityGoalIllusionerMirrorSpell();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public NamespacedKey getKey() {
|
||||||
|
return NamespacedKey.minecraft("illusioner_mirror_spell");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package com.willfp.eco.core.entities.ai.entity;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config;
|
||||||
|
import com.willfp.eco.core.entities.Entities;
|
||||||
|
import com.willfp.eco.core.entities.TestableEntity;
|
||||||
|
import com.willfp.eco.core.entities.ai.EntityGoal;
|
||||||
|
import com.willfp.eco.core.serialization.KeyedDeserializer;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.entity.Mob;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interact with other mobs.
|
||||||
|
*
|
||||||
|
* @param target The type of entity to interact with.
|
||||||
|
* @param range The range at which to interact.
|
||||||
|
* @param chance The chance for interaction, between 0 and 1.
|
||||||
|
*/
|
||||||
|
public record EntityGoalInteract(
|
||||||
|
@NotNull TestableEntity target,
|
||||||
|
double range,
|
||||||
|
double chance
|
||||||
|
) implements EntityGoal<Mob> {
|
||||||
|
/**
|
||||||
|
* The deserializer for the goal.
|
||||||
|
*/
|
||||||
|
public static final KeyedDeserializer<EntityGoalInteract> DESERIALIZER = new EntityGoalInteract.Deserializer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserialize configs into the goal.
|
||||||
|
*/
|
||||||
|
private static final class Deserializer implements KeyedDeserializer<EntityGoalInteract> {
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public EntityGoalInteract deserialize(@NotNull final Config config) {
|
||||||
|
if (!(
|
||||||
|
config.has("target")
|
||||||
|
&& config.has("range")
|
||||||
|
&& config.has("chance")
|
||||||
|
)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return new EntityGoalInteract(
|
||||||
|
Entities.lookup(config.getString("target")),
|
||||||
|
config.getDouble("range"),
|
||||||
|
config.getDouble("chance")
|
||||||
|
);
|
||||||
|
} catch (Exception e) {
|
||||||
|
/*
|
||||||
|
Exceptions could be caused by configs having values of a wrong type,
|
||||||
|
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
|
||||||
|
so we encapsulate them as null.
|
||||||
|
*/
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public NamespacedKey getKey() {
|
||||||
|
return NamespacedKey.minecraft("interact");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package com.willfp.eco.core.entities.ai.entity;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config;
|
||||||
|
import com.willfp.eco.core.entities.ai.EntityGoal;
|
||||||
|
import com.willfp.eco.core.serialization.KeyedDeserializer;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.entity.Mob;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows an entity to jump towards a target.
|
||||||
|
*
|
||||||
|
* @param velocity The leap velocity.
|
||||||
|
*/
|
||||||
|
public record EntityGoalLeapAtTarget(
|
||||||
|
double velocity
|
||||||
|
) implements EntityGoal<Mob> {
|
||||||
|
/**
|
||||||
|
* The deserializer for the goal.
|
||||||
|
*/
|
||||||
|
public static final KeyedDeserializer<EntityGoalLeapAtTarget> DESERIALIZER = new EntityGoalLeapAtTarget.Deserializer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserialize configs into the goal.
|
||||||
|
*/
|
||||||
|
private static final class Deserializer implements KeyedDeserializer<EntityGoalLeapAtTarget> {
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public EntityGoalLeapAtTarget deserialize(@NotNull final Config config) {
|
||||||
|
if (!(
|
||||||
|
config.has("velocity")
|
||||||
|
)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return new EntityGoalLeapAtTarget(
|
||||||
|
config.getDouble("velocity")
|
||||||
|
);
|
||||||
|
} catch (Exception e) {
|
||||||
|
/*
|
||||||
|
Exceptions could be caused by configs having values of a wrong type,
|
||||||
|
invalid enum parameters, etc. Serializers shouldn't throw exceptions,
|
||||||
|
so we encapsulate them as null.
|
||||||
|
*/
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public NamespacedKey getKey() {
|
||||||
|
return NamespacedKey.minecraft("leap_at_target");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user