Compare commits
1697 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f01e18950c | ||
|
|
d4a6bf105b | ||
|
|
a9a961ff2b | ||
|
|
25d572c0db | ||
|
|
8a4243e434 | ||
|
|
6c40670f5e | ||
|
|
6e94f3cee8 | ||
|
|
4968d3ff22 | ||
|
|
eecd80be1c | ||
|
|
52c1b52f6d | ||
|
|
f321296227 | ||
|
|
ddd12db420 | ||
|
|
bd09791b5b | ||
|
|
ce9549f03d | ||
|
|
52367dbb95 | ||
|
|
0080c32c23 | ||
|
|
581094a930 | ||
|
|
5d9c8775e8 | ||
|
|
9ab51d2c87 | ||
|
|
b0de341d7f | ||
|
|
1bada835ea | ||
|
|
de04833f0c | ||
|
|
75dd6be539 | ||
|
|
9b47e4777a | ||
|
|
e2a6d6d9ac | ||
|
|
4c1bc76ee2 | ||
|
|
61c90d85ac | ||
|
|
6faaac2257 | ||
|
|
9ad489b9d9 | ||
|
|
3a0e1eaf4d | ||
|
|
80afa9127f | ||
|
|
ad44891f5f | ||
|
|
303f5eedac | ||
|
|
830199d8ca | ||
|
|
aa86426895 | ||
|
|
edf20d8ab8 | ||
|
|
d99121ad47 | ||
|
|
f71fa64ccd | ||
|
|
697e0b7c9c | ||
|
|
08f6715305 | ||
|
|
bff502c281 | ||
|
|
2500258166 | ||
|
|
a8d6aaad30 | ||
|
|
160635a2a7 | ||
|
|
6fd4eb7e4c | ||
|
|
5941060479 | ||
|
|
a9ba317e7d | ||
|
|
1adbcc105e | ||
|
|
c4c0f38969 | ||
|
|
9059ddf856 | ||
|
|
4209161046 | ||
|
|
79ac0838d0 | ||
|
|
cf0a96426c | ||
|
|
5ccb9ca30a | ||
|
|
033cc44200 | ||
|
|
67ae0ec8cd | ||
|
|
c8329d050c | ||
|
|
ab73c2202a | ||
|
|
af640881b0 | ||
|
|
9bd5cb5046 | ||
|
|
2829baf5b0 | ||
|
|
7ef928c360 | ||
|
|
17db6dbf7f | ||
|
|
446e7a9534 | ||
|
|
dbbab8518e | ||
|
|
1908d9a5c2 | ||
|
|
4ab7e888ef | ||
|
|
47c8617d3d | ||
|
|
c977cb2602 | ||
|
|
2402fd6736 | ||
|
|
db41e11dab | ||
|
|
6b46ea7e67 | ||
|
|
7defdcc1ff | ||
|
|
35496c60fc | ||
|
|
9b4af3eeab | ||
|
|
b6b4d7e2f8 | ||
|
|
74a8dcea90 | ||
|
|
e0f631b3b4 | ||
|
|
67981b4f9a | ||
|
|
03eb2f5d0a | ||
|
|
2df60bffee | ||
|
|
b97506ae70 | ||
|
|
747e702d54 | ||
|
|
9e583f18de | ||
|
|
75afe1f2b0 | ||
|
|
4464d3bf75 | ||
|
|
75f217b141 | ||
|
|
2387849adb | ||
|
|
e7a5d8d155 | ||
|
|
d6e50e34e1 | ||
|
|
89e58be1a3 | ||
|
|
8a8606bea4 | ||
|
|
3f751e8865 | ||
|
|
6a035426b4 | ||
|
|
f9bf97c90c | ||
|
|
476faeec61 | ||
|
|
64647e3dad | ||
|
|
dba640f8ee | ||
|
|
f52a760bbe | ||
|
|
c80cdf7b60 | ||
|
|
749f6229ac | ||
|
|
e6318c0727 | ||
|
|
989118a653 | ||
|
|
6134e8de04 | ||
|
|
5a8c2828f7 | ||
|
|
0dba790bb2 | ||
|
|
85991b6d7e | ||
|
|
ad272a2f6b | ||
|
|
9c4a65dc19 | ||
|
|
8d2d6153e5 | ||
|
|
6248dafc70 | ||
|
|
9ad12c2578 | ||
|
|
24d9052080 | ||
|
|
e2d2e955a4 | ||
|
|
c5cbdc2449 | ||
|
|
1a4e8be1b2 | ||
|
|
1a75dd8e5b | ||
|
|
77de51b1fd | ||
|
|
3495d2317d | ||
|
|
0284aec119 | ||
|
|
0d4289b756 | ||
|
|
6931ba0393 | ||
|
|
cb49fa2690 | ||
|
|
4898ca4a25 | ||
|
|
67d70098ef | ||
|
|
d072ac15a0 | ||
|
|
fea3152660 | ||
|
|
8fc9c718ce | ||
|
|
1fe6a3caeb | ||
|
|
8668d36304 | ||
|
|
72608c381e | ||
|
|
80cdaf6ea0 | ||
|
|
de6a3e76fd | ||
|
|
80d24b8366 | ||
|
|
4d6399dd6c | ||
|
|
f1815aee4f | ||
|
|
18e05da958 | ||
|
|
12d6ff180e | ||
|
|
1c0f40880f | ||
|
|
6625385e1c | ||
|
|
75ca3dc9a6 | ||
|
|
1db2671bc5 | ||
|
|
70dd3c0d64 | ||
|
|
8665df51cc | ||
|
|
e306190109 | ||
|
|
3e0a8b1838 | ||
|
|
29d69d77b4 | ||
|
|
9e625c004e | ||
|
|
59dfeeb012 | ||
|
|
6fdbb2d63f | ||
|
|
e77c8ab9aa | ||
|
|
48e1618c84 | ||
|
|
19f60afaf9 | ||
|
|
26e2282385 | ||
|
|
2e9d5c36f2 | ||
|
|
b4fb66ffa0 | ||
|
|
ba0bf5ee8f | ||
|
|
3bf9589cd2 | ||
|
|
510034af0d | ||
|
|
8052ffa706 | ||
|
|
ed41c1091c | ||
|
|
4fcf8c0368 | ||
|
|
4ae4af6f1d | ||
|
|
bba0900183 | ||
|
|
641aee3965 | ||
|
|
18ea6cc568 | ||
|
|
8335f6bae5 | ||
|
|
514a8e76f9 | ||
|
|
f34af36690 | ||
|
|
143148d93e | ||
|
|
4f6c023217 | ||
|
|
620e1d3042 | ||
|
|
d3c831c19b | ||
|
|
47e87fa6ce | ||
|
|
22d9dbdf66 | ||
|
|
238ea86e09 | ||
|
|
5cfb87e03c | ||
|
|
ff61527939 | ||
|
|
7ff578f89b | ||
|
|
27da03e8db | ||
|
|
f1bef38046 | ||
|
|
ee237f9c58 | ||
|
|
0a80518755 | ||
|
|
134859fea0 | ||
|
|
5c267d500a | ||
|
|
4c9735583c | ||
|
|
739d9cfffb | ||
|
|
4301d83e91 | ||
|
|
84d5c5e665 | ||
|
|
50f217eebe | ||
|
|
041fce69cc | ||
|
|
238bd08502 | ||
|
|
940e6e8b5b | ||
|
|
eb07622496 | ||
|
|
841ed52bdd | ||
|
|
342f6dbc7b | ||
|
|
245b577adc | ||
|
|
1258305755 | ||
|
|
cd8ed5a823 | ||
|
|
795ead57bf | ||
|
|
910cdaf992 | ||
|
|
85c02d3402 | ||
|
|
b4ad2fd4d7 | ||
|
|
3c5190da3a | ||
|
|
0f0f003f23 | ||
|
|
7e5e5162c3 | ||
|
|
09417d0834 | ||
|
|
c85b8c08c7 | ||
|
|
a65ac0aa4f | ||
|
|
9d03ba2bd2 | ||
|
|
8eb62d65b4 | ||
|
|
178f21b1f3 | ||
|
|
a3fe4f97ff | ||
|
|
ff356fcde5 | ||
|
|
59b57b17ba | ||
|
|
c8f710161d | ||
|
|
f840a55734 | ||
|
|
36677fe503 | ||
|
|
7e74223352 | ||
|
|
b6f2b9d4ea | ||
|
|
f320e77008 | ||
|
|
c8b255b358 | ||
|
|
5b5e161062 | ||
|
|
ffa511176f | ||
|
|
8515ff2b7b | ||
|
|
74aeaec257 | ||
|
|
0ce3d294d1 | ||
|
|
7c7052f5b9 | ||
|
|
a6b7dda82d | ||
|
|
04aaefb9ea | ||
|
|
d2fdb4f8e0 | ||
|
|
87f90d8b26 | ||
|
|
899d5cc054 | ||
|
|
c1ed771eb3 | ||
|
|
08a4d9d6b1 | ||
|
|
7ef8dcfd64 | ||
|
|
5bedf88b4c | ||
|
|
1d241651b5 | ||
|
|
3ff2bfa412 | ||
|
|
3a508c693b | ||
|
|
a4c5ff921e | ||
|
|
137e9dc7d6 | ||
|
|
710cec4bc1 | ||
|
|
fa0ec7d6b0 | ||
|
|
5093799775 | ||
|
|
8535f23ede | ||
|
|
8e09ae7f4c | ||
|
|
bbc2513b40 | ||
|
|
c7f8063a3a | ||
|
|
14b0f1be0c | ||
|
|
af20bb315b | ||
|
|
6645e216d5 | ||
|
|
eddf240f0c | ||
|
|
4f406353ba | ||
|
|
095494dd2e | ||
|
|
fd92645500 | ||
|
|
1a6ac29083 | ||
|
|
7edc00d459 | ||
|
|
a51bad058f | ||
|
|
89ebb8ba59 | ||
|
|
f0ae8f4f84 | ||
|
|
7d6cf78442 | ||
|
|
780d8f3b86 | ||
|
|
146a0130f9 | ||
|
|
df8c3411cb | ||
|
|
4fc3c22a7d | ||
|
|
cfc4808bb8 | ||
|
|
4ac6325a41 | ||
|
|
4aed33751d | ||
|
|
3fe1c2c69f | ||
|
|
5feaa84b2c | ||
|
|
d8793bc2bb | ||
|
|
15c512f3ca | ||
|
|
15ff2fb1d6 | ||
|
|
862b588c8d | ||
|
|
3c2a99b5f4 | ||
|
|
2d23c05c47 | ||
|
|
8fc55d3393 | ||
|
|
5900a756e4 | ||
|
|
c18b85f223 | ||
|
|
85116108c2 | ||
|
|
044f141bd0 | ||
|
|
9ca7f99fdb | ||
|
|
7aa7770a3e | ||
|
|
10202917fa | ||
|
|
43df79e3b1 | ||
|
|
5ef244f0bc | ||
|
|
861f076c11 | ||
|
|
7bed43059f | ||
|
|
37e271c96c | ||
|
|
3dad48e24d | ||
|
|
ae77e4810b | ||
|
|
3d50e37c37 | ||
|
|
421fd3bd04 | ||
|
|
5ecae0a366 | ||
|
|
5de4914fd7 | ||
|
|
0f9bf094ae | ||
|
|
e67680f397 | ||
|
|
73c0a5d655 | ||
|
|
220ed26f4a | ||
|
|
edf2ea41c7 | ||
|
|
16859b8ce5 | ||
|
|
10fe7d190a | ||
|
|
60a1f2429c | ||
|
|
cc6dc1e67c | ||
|
|
f4f5941691 | ||
|
|
f973281dd9 | ||
|
|
8acd76f363 | ||
|
|
4a165a86dc | ||
|
|
43b7c393b9 | ||
|
|
714952bc45 | ||
|
|
322e179b81 | ||
|
|
469be73ada | ||
|
|
7eac60146f | ||
|
|
ad0223e1bb | ||
|
|
430117f342 | ||
|
|
fa87cae81e | ||
|
|
5695750fc5 | ||
|
|
45e8a57880 | ||
|
|
17fcd2c1b5 | ||
|
|
0c1e17c351 | ||
|
|
9415515849 | ||
|
|
d0e957ea37 | ||
|
|
69514e2f85 | ||
|
|
259e35c978 | ||
|
|
40aec26f15 | ||
|
|
67b2fdd594 | ||
|
|
83f86983f6 | ||
|
|
3ba98a9a5e | ||
|
|
f19e565fbe | ||
|
|
ee3ecb643b | ||
|
|
3aefb0e481 | ||
|
|
d9eb1e1c26 | ||
|
|
70631e67c5 | ||
|
|
82797e7342 | ||
|
|
d2917341b1 | ||
|
|
760f42be0c | ||
|
|
bb01af2ab2 | ||
|
|
517d890c05 | ||
|
|
f02fc56778 | ||
|
|
4417b09c14 | ||
|
|
6b37fafa90 | ||
|
|
f8c5c9f06d | ||
|
|
0fd6cbaa08 | ||
|
|
81afa32eb0 | ||
|
|
7387fe2332 | ||
|
|
80fa05da98 | ||
|
|
77754249ad | ||
|
|
1843cf0f8a | ||
|
|
05eb5ee993 | ||
|
|
7bc11ee716 | ||
|
|
f566aec00e | ||
|
|
36d47c55a1 | ||
|
|
40463213ac | ||
|
|
6ec80d30ad | ||
|
|
7ccee60a0c | ||
|
|
0805b48763 | ||
|
|
d737322aaa | ||
|
|
4ddc150e1c | ||
|
|
0da119d89d | ||
|
|
fc0a07d1c5 | ||
|
|
4ce2850138 | ||
|
|
58316c2a06 | ||
|
|
d96ad10960 | ||
|
|
21283b0928 | ||
|
|
2797687f01 | ||
|
|
9c68d1fbc3 | ||
|
|
9371d9b88d | ||
|
|
14e2ead488 | ||
|
|
5473bb8ef8 | ||
|
|
90c55849ae | ||
|
|
9809140cf9 | ||
|
|
49a82dc005 | ||
|
|
92dec03b9a | ||
|
|
7453c70b87 | ||
|
|
3038ea43d0 | ||
|
|
3c6ddd8255 | ||
|
|
925ee04cc1 | ||
|
|
6f7de8716b | ||
|
|
a17b951a8b | ||
|
|
f003ed06a8 | ||
|
|
f864953da2 | ||
|
|
6ef31444ac | ||
|
|
99258116de | ||
|
|
a59c68102e | ||
|
|
2482525fe2 | ||
|
|
acb326c0c8 | ||
|
|
11d947e24b | ||
|
|
3cced3012c | ||
|
|
520523e903 | ||
|
|
ee36cc74f8 | ||
|
|
55344e0550 | ||
|
|
75f6f05c7d | ||
|
|
17fa519501 | ||
|
|
1a72cf3ca9 | ||
|
|
d11f355c44 | ||
|
|
1852ff86ec | ||
|
|
ffe9219f45 | ||
|
|
f67a5d3b3d | ||
|
|
bbd541abe0 | ||
|
|
3de8d0fed9 | ||
|
|
df4abe39eb | ||
|
|
f5e289966f | ||
|
|
bcfa4bd82e | ||
|
|
229c9e58c3 | ||
|
|
4f30a6e04e | ||
|
|
9ea45ee0d0 | ||
|
|
192316214d | ||
|
|
feb8898a87 | ||
|
|
1e64815e47 | ||
|
|
dc10648c25 | ||
|
|
70131a6cae | ||
|
|
6d23cc7141 | ||
|
|
473202527a | ||
|
|
bc24aaeb3c | ||
|
|
52072bd935 | ||
|
|
ad47b7898e | ||
|
|
19d6533db6 | ||
|
|
3a37d40271 | ||
|
|
cb3ccbb39a | ||
|
|
5c3bb678b3 | ||
|
|
4f4ee82e6b | ||
|
|
32d88f55f8 | ||
|
|
bc8d615079 | ||
|
|
55b7c3c16f | ||
|
|
9535986f59 | ||
|
|
fb17fc1383 | ||
|
|
4221368388 | ||
|
|
d4432d0cb8 | ||
|
|
f9093c2ed6 | ||
|
|
15f4d5c098 | ||
|
|
dc47bc7995 | ||
|
|
29ce0deb1b | ||
|
|
fd78402bf5 | ||
|
|
5f65e3f520 | ||
|
|
ceaf4d34a5 | ||
|
|
2d2e5f8150 | ||
|
|
323a4aefef | ||
|
|
af486580c1 | ||
|
|
7955a94f14 | ||
|
|
c99a1bd50a | ||
|
|
93364247de | ||
|
|
49612eddcb | ||
|
|
834c29f843 | ||
|
|
a806ac039d | ||
|
|
0ca2651af0 | ||
|
|
6157fdcfa1 | ||
|
|
36cfcd24c2 | ||
|
|
d4558db40c | ||
|
|
3f8448fee1 | ||
|
|
8b6e15457c | ||
|
|
b99e822db3 | ||
|
|
02f8d33a81 | ||
|
|
76042bea68 | ||
|
|
51ad09c536 | ||
|
|
264c591020 | ||
|
|
6bd3ca0f5c | ||
|
|
98df14a23a | ||
|
|
ccb6e38064 | ||
|
|
50f1ba6a19 | ||
|
|
501e7b05a6 | ||
|
|
ebf8abf764 | ||
|
|
aff8fa8e88 | ||
|
|
1accad88fe | ||
|
|
a3a5e4df38 | ||
|
|
6e8dc1d729 | ||
|
|
a8556008f9 | ||
|
|
ab18a8bd29 | ||
|
|
a053f512f8 | ||
|
|
add5390787 | ||
|
|
49687f9a91 | ||
|
|
5480c70f8c | ||
|
|
ef922f6d3f | ||
|
|
026bc55ffb | ||
|
|
270fdbb18c | ||
|
|
fbf5967d17 | ||
|
|
4102be1201 | ||
|
|
f6bdb9cc65 | ||
|
|
c8282d1acf | ||
|
|
b056b537ef | ||
|
|
f69b458731 | ||
|
|
b035fa8940 | ||
|
|
25c087592d | ||
|
|
083cb39771 | ||
|
|
eb3e0f5c09 | ||
|
|
08f43ddafd | ||
|
|
9d3efb5e83 | ||
|
|
8a5d1a604a | ||
|
|
ef67c6d6ae | ||
|
|
5b2654db15 | ||
|
|
eccd793317 | ||
|
|
1bc44755a0 | ||
|
|
ec606d9ebe | ||
|
|
c5556f15ab | ||
|
|
399cce21f5 | ||
|
|
b25feffdfa | ||
|
|
1a96fdf465 | ||
|
|
cee1ac4cc2 | ||
|
|
ac10fa46dc | ||
|
|
7c616e64ae | ||
|
|
708f9130c6 | ||
|
|
9118d49c67 | ||
|
|
a1ce72476f | ||
|
|
2cfab99644 | ||
|
|
cc9b3f7710 | ||
|
|
5bfe48c8d9 | ||
|
|
22ff157ffc | ||
|
|
720dbe789c | ||
|
|
b51dd51941 | ||
|
|
f3ffaa4cf6 | ||
|
|
085032e315 | ||
|
|
3d920ee2b4 | ||
|
|
06a04e4375 | ||
|
|
7349f15784 | ||
|
|
a4c77857d5 | ||
|
|
999fafc8df | ||
|
|
0d533850f6 | ||
|
|
569f9cfcb4 | ||
|
|
f0619f2374 | ||
|
|
7e8d97e11d | ||
|
|
d3414f25ad | ||
|
|
f0cf118448 | ||
|
|
297bb10b85 | ||
|
|
751624bc8d | ||
|
|
8b1b15a3e4 | ||
|
|
7fe330bafb | ||
|
|
20584b2a9b | ||
|
|
bd7594a117 | ||
|
|
f1bfa21270 | ||
|
|
01aa1e708a | ||
|
|
8424baa285 | ||
|
|
d9a8d26990 | ||
|
|
4d3eeaaefc | ||
|
|
d54a2b9516 | ||
|
|
f7f12b6255 | ||
|
|
42eb1344a6 | ||
|
|
4c2a8585cc | ||
|
|
8cccc67b0d | ||
|
|
396d74497c | ||
|
|
49602dce04 | ||
|
|
5da811ba74 | ||
|
|
a4d57e21fe | ||
|
|
4b8efdc79f | ||
|
|
610110efde | ||
|
|
a87f675269 | ||
|
|
a371d314b8 | ||
|
|
9a9097adc5 | ||
|
|
0669a57e4b | ||
|
|
692eaf6836 | ||
|
|
7f9052c64d | ||
|
|
55a841b3f5 | ||
|
|
85f02c5ca2 | ||
|
|
74c428b90d | ||
|
|
fd8c67fa66 | ||
|
|
a396754e2e | ||
|
|
6f97f47712 | ||
|
|
d1109e485a | ||
|
|
476e5c7cae | ||
|
|
dc2b7a6fda | ||
|
|
00f18519b0 | ||
|
|
f7ea5fd182 | ||
|
|
70d29c872a | ||
|
|
f79f4a84c3 | ||
|
|
9af63907ef | ||
|
|
c9aa92895b | ||
|
|
c57c824027 | ||
|
|
7cb905e65a | ||
|
|
31a2c7e338 | ||
|
|
1759b52f82 | ||
|
|
ccf93e3a4d | ||
|
|
abd07389ab | ||
|
|
80ad738bb2 | ||
|
|
b01105819a | ||
|
|
a7c08b0731 | ||
|
|
7e4c071698 | ||
|
|
f94f7ead08 | ||
|
|
b21c5bf3a9 | ||
|
|
7a9e8c5c10 | ||
|
|
a6ddbc46ab | ||
|
|
ffaee137d8 | ||
|
|
18d882dac6 | ||
|
|
52841f7f04 | ||
|
|
47b72e9243 | ||
|
|
854a10e8fd | ||
|
|
823ef6477b | ||
|
|
eccb146852 | ||
|
|
d877b707d6 | ||
|
|
bcb7401c74 | ||
|
|
f05c5f3cd6 | ||
|
|
3bd8bccb81 | ||
|
|
6f55787c84 | ||
|
|
eb4dc168fc | ||
|
|
c5085de5d1 | ||
|
|
019cdbf9c8 | ||
|
|
d5ddcaea4b | ||
|
|
d3a7ef72e8 | ||
|
|
a311ce1227 | ||
|
|
5c0d4540a8 | ||
|
|
7e66ee8071 | ||
|
|
fd233df736 | ||
|
|
6baf636e6a | ||
|
|
9ee579f2c4 | ||
|
|
3b5ea87353 | ||
|
|
00d32ed218 | ||
|
|
5ce9a1c04e | ||
|
|
966549065d | ||
|
|
ee2911b57c | ||
|
|
f15ec5eec0 | ||
|
|
a9c32000d8 | ||
|
|
b68459951f | ||
|
|
b520c76169 | ||
|
|
d081afbd8e | ||
|
|
46fd0439a5 | ||
|
|
ad58ce4a74 | ||
|
|
b5cd8f42e0 | ||
|
|
d0baf50709 | ||
|
|
2496f318fa | ||
|
|
048c200c95 | ||
|
|
17446acb2e | ||
|
|
7929113c91 | ||
|
|
6acc5864bd | ||
|
|
fa64950d28 | ||
|
|
730c20dbc0 | ||
|
|
0c5ae54c3a | ||
|
|
b48e80837d | ||
|
|
17eb4cf5f8 | ||
|
|
890f85fa56 | ||
|
|
86b427c95e | ||
|
|
8c1fde57b0 | ||
|
|
2efc040a8e | ||
|
|
54b2b42512 | ||
|
|
e67d9d634c | ||
|
|
39fb676b9a | ||
|
|
ec8936b765 | ||
|
|
cf347de4b8 | ||
|
|
2b7122c5c2 | ||
|
|
062b5c9b92 | ||
|
|
052cd74756 | ||
|
|
082b39a2e4 | ||
|
|
616fa032d9 | ||
|
|
ea997239fc | ||
|
|
ad04abab73 | ||
|
|
f440ef922b | ||
|
|
933271fb4a | ||
|
|
9679d3100f | ||
|
|
6e20763522 | ||
|
|
18dea2c20c | ||
|
|
62b666559c | ||
|
|
465563523b | ||
|
|
f0f014ed89 | ||
|
|
58811c5d77 | ||
|
|
81d495e76e | ||
|
|
c78e397959 | ||
|
|
95740f155e | ||
|
|
5638d5e152 | ||
|
|
4d3712057c | ||
|
|
458fcd78b3 | ||
|
|
ee13de31f4 | ||
|
|
9588d49788 | ||
|
|
8e7ce298b0 | ||
|
|
32a11ce5b8 | ||
|
|
960f62cc8b | ||
|
|
28ceb83eb5 | ||
|
|
6f748b6b8a | ||
|
|
190ea5d49f | ||
|
|
c0ed083a5c | ||
|
|
04f04bb7a6 | ||
|
|
b8a3806ff9 | ||
|
|
ae49d41542 | ||
|
|
5f2255a3bc | ||
|
|
065ccfbe67 | ||
|
|
17727c9015 | ||
|
|
ea64e69b4d | ||
|
|
07ca6c2359 | ||
|
|
162558b1c2 | ||
|
|
10f9e8dce0 | ||
|
|
b02943d7ff | ||
|
|
40ad970ffa | ||
|
|
aefdfa786d | ||
|
|
1cf08955a0 | ||
|
|
4077a4c28b | ||
|
|
6c375ef297 | ||
|
|
f77fc5d182 | ||
|
|
6d1cc4c05d | ||
|
|
0775f0992f | ||
|
|
debb39105d | ||
|
|
3b4aa59bfb | ||
|
|
4e902c3964 | ||
|
|
3e325697e7 | ||
|
|
13b3e1e440 | ||
|
|
2b2406a4d0 | ||
|
|
048982c74a | ||
|
|
29b63a2ebb | ||
|
|
2a9cbdacfd | ||
|
|
35cfcdf4a9 | ||
|
|
06c1dc9afb | ||
|
|
18b58d584f | ||
|
|
a774791e65 | ||
|
|
bc22adae84 | ||
|
|
0eba82b221 | ||
|
|
4822ec3955 | ||
|
|
b845001467 | ||
|
|
25b6a15c9c | ||
|
|
1a3d035f78 | ||
|
|
a69f9f6e11 | ||
|
|
6efd9e4fcd | ||
|
|
3e948beb7a | ||
|
|
a8a491a0b7 | ||
|
|
2c0330898c | ||
|
|
e9794cfbf4 | ||
|
|
1694d858bc | ||
|
|
b79955ae9e | ||
|
|
803a8c5d17 | ||
|
|
c5cd15ad92 | ||
|
|
489b170888 | ||
|
|
9f57a322e8 | ||
|
|
86e113214d | ||
|
|
e791bb8893 | ||
|
|
f1220bd186 | ||
|
|
21d933cb11 | ||
|
|
e1c063d5f4 | ||
|
|
27d2b5c8a4 | ||
|
|
3b34d6ef27 | ||
|
|
bc1c8b8f46 | ||
|
|
2fa926ec02 | ||
|
|
d7891e1218 | ||
|
|
11685cd352 | ||
|
|
785127fe16 | ||
|
|
4a13bc5fea | ||
|
|
c7ad122050 | ||
|
|
28d63fc2e3 | ||
|
|
bb62cc0bcd | ||
|
|
740c79f087 | ||
|
|
33ab8e04a0 | ||
|
|
fcd3aac363 | ||
|
|
753d148d1b | ||
|
|
1bb47a9f13 | ||
|
|
40b4c26e0f | ||
|
|
97adae7b32 | ||
|
|
3d35a91314 | ||
|
|
0caa328b1e | ||
|
|
ab8c946914 | ||
|
|
e667537404 | ||
|
|
6bd2f2b823 | ||
|
|
8d8a8045c0 | ||
|
|
d5c669c72c | ||
|
|
28b268e175 | ||
|
|
33937d1ce7 | ||
|
|
e971778cc3 | ||
|
|
f99612ded3 | ||
|
|
50272bbbcf | ||
|
|
9a703f6190 | ||
|
|
f8fec7eec4 | ||
|
|
f6aadda4ed | ||
|
|
d8fca0f348 | ||
|
|
65ff4c4a31 | ||
|
|
90702bc7aa | ||
|
|
e81b788a1b | ||
|
|
ebc0ee7940 | ||
|
|
82d269daf1 | ||
|
|
9d5300d6ae | ||
|
|
8870e4d6fb | ||
|
|
d826a9f71f | ||
|
|
7ec3355237 | ||
|
|
e59a8cc2e6 | ||
|
|
88f974fd10 | ||
|
|
7767e48e51 | ||
|
|
dfe2f1361b | ||
|
|
3826f9f713 | ||
|
|
c2d2303c91 | ||
|
|
b1158ceb3d | ||
|
|
af4048afbe | ||
|
|
fce12020d5 | ||
|
|
7e37332b64 | ||
|
|
52dbf9ff52 | ||
|
|
78b6292367 | ||
|
|
09705e787b | ||
|
|
9c86069a85 | ||
|
|
0a7acceb83 | ||
|
|
40aa8b17dd | ||
|
|
71eb386a19 | ||
|
|
c857df2360 | ||
|
|
f4fc611f3b | ||
|
|
0d91324d47 | ||
|
|
e9dbc3ec73 | ||
|
|
493d1b1b6d | ||
|
|
68221d5912 | ||
|
|
7f2ef4e038 | ||
|
|
be0a19175b | ||
|
|
5afdcd75f7 | ||
|
|
a1c0b8c857 | ||
|
|
0442ccf58f | ||
|
|
1c1a796610 | ||
|
|
eacb243493 | ||
|
|
7bbed31d4e | ||
|
|
58bccf3cd7 | ||
|
|
4502e1e311 | ||
|
|
054a8d5a5e | ||
|
|
dbdd4785ba | ||
|
|
35f800b62a | ||
|
|
591800dba8 | ||
|
|
46673e8d24 | ||
|
|
bb7c300074 | ||
|
|
b003ec96f7 | ||
|
|
a526f51780 | ||
|
|
dd14fc666a | ||
|
|
ae0150f012 | ||
|
|
04418fa038 | ||
|
|
bcb9523315 | ||
|
|
43e7972ca3 | ||
|
|
7ea61eb393 | ||
|
|
5245a9b1d8 | ||
|
|
195932463c | ||
|
|
3cf60a7e2c | ||
|
|
0f9f57fca2 | ||
|
|
fe21616dd5 | ||
|
|
396144abaa | ||
|
|
50b4fa59ab | ||
|
|
a6754379e8 | ||
|
|
bbd0182c2a | ||
|
|
0370e9f454 | ||
|
|
8d585b58cb | ||
|
|
0bfbd4c036 | ||
|
|
881839955e | ||
|
|
8ffc5f9c0f | ||
|
|
709de3bb5f | ||
|
|
f2aa2ffd9b | ||
|
|
5ce70399f0 | ||
|
|
3f8759b08a | ||
|
|
abecaa6e9f | ||
|
|
4744bfc78b | ||
|
|
487e68221a | ||
|
|
1c68992a8e | ||
|
|
c5b7d0b644 | ||
|
|
0f91aec3b7 | ||
|
|
d2bf38c5c9 | ||
|
|
2c96b79aba | ||
|
|
d539b9e59e | ||
|
|
b0b06ef402 | ||
|
|
7a84c3de3b | ||
|
|
9431321e1c | ||
|
|
4816284fba | ||
|
|
a9874c9386 | ||
|
|
fe68760184 | ||
|
|
5ae8e72a98 | ||
|
|
15fc6053c8 | ||
|
|
1f7cf78491 | ||
|
|
fc3c80f633 | ||
|
|
2bcbf181a9 | ||
|
|
7adcdd572d | ||
|
|
f6eba21006 | ||
|
|
cc02f26807 | ||
|
|
60f552ce65 | ||
|
|
9fe8d4ad15 | ||
|
|
b835988eec | ||
|
|
22366835de | ||
|
|
cdd1baec6c | ||
|
|
1ea0da365a | ||
|
|
852d40372d | ||
|
|
999c831dd7 | ||
|
|
80fa5d346a | ||
|
|
336cdc3716 | ||
|
|
a49a9e92b4 | ||
|
|
1c6e64832e | ||
|
|
44a141cddc | ||
|
|
ea4956870e | ||
|
|
9207d1782b | ||
|
|
9debcb7089 | ||
|
|
ef53ee2ed3 | ||
|
|
4c90360038 | ||
|
|
d4b5102913 | ||
|
|
f4553c544a | ||
|
|
5ad1db72fc | ||
|
|
c761df9ee6 | ||
|
|
b6d79da4e1 | ||
|
|
42f41618ca | ||
|
|
de878fd423 | ||
|
|
7782657d57 | ||
|
|
7778425936 | ||
|
|
6446cef255 | ||
|
|
8dacecbcba | ||
|
|
5f8ec4f94a | ||
|
|
d7847e9efc | ||
|
|
930ecd4896 | ||
|
|
af8d6a4167 | ||
|
|
361f0a0103 | ||
|
|
eb545a7d9e | ||
|
|
d3c64deef4 | ||
|
|
31db9dcb95 | ||
|
|
4938ad84bc | ||
|
|
06b2301da1 | ||
|
|
c307878c09 | ||
|
|
3b10ff01ec | ||
|
|
e042754f5d | ||
|
|
c2b8a80560 | ||
|
|
07c0e72564 | ||
|
|
de9b961d83 | ||
|
|
83958c719c | ||
|
|
9c3dfaeb01 | ||
|
|
7e61340285 | ||
|
|
78b76cb453 | ||
|
|
bb1da29704 | ||
|
|
cf152215d3 | ||
|
|
e6a59fbc91 | ||
|
|
b787f8b76a | ||
|
|
ccc83da5b0 | ||
|
|
f11068f2f1 | ||
|
|
a5cc1a5d32 | ||
|
|
7440749ba5 | ||
|
|
75010d25fa | ||
|
|
bb95376b93 | ||
|
|
ab6d4c7aa2 | ||
|
|
9ab8827e55 | ||
|
|
991290095b | ||
|
|
8735478fc3 | ||
|
|
6e44f09621 | ||
|
|
060106881e | ||
|
|
96cc9706b3 | ||
|
|
3d87b1eb73 | ||
|
|
4c4247b4ec | ||
|
|
b94dc4ac3a | ||
|
|
06bcb10958 | ||
|
|
295095e9ce | ||
|
|
ba9c5865e3 | ||
|
|
d24be4121f | ||
|
|
bcc5e4ef08 | ||
|
|
bf8609666a | ||
|
|
1a02335825 | ||
|
|
f5ef98ec5c | ||
|
|
45135e2b55 | ||
|
|
758b42ff8e | ||
|
|
4a134402da | ||
|
|
e6ad4c9268 | ||
|
|
809dcbae85 | ||
|
|
d7fce6834c | ||
|
|
ac807a991b | ||
|
|
ba315ced3c | ||
|
|
f2e65174f9 | ||
|
|
bd5555ff01 | ||
|
|
d5584e863b | ||
|
|
d9c0e8e763 | ||
|
|
b223f8457d | ||
|
|
694d57edf4 | ||
|
|
02afe7d788 | ||
|
|
0593e631ea | ||
|
|
2f22e02ff1 | ||
|
|
fb240bfd0a | ||
|
|
11c49a543f | ||
|
|
c565f5248d | ||
|
|
fac4f40430 | ||
|
|
a20cb63755 | ||
|
|
f17f67227f | ||
|
|
106c9b37fc | ||
|
|
f7cfcd5cbb | ||
|
|
44d9581222 | ||
|
|
0fa30a5f62 | ||
|
|
84f439976c | ||
|
|
01bcb62b31 | ||
|
|
47c8ea3341 | ||
|
|
e28c4288a3 | ||
|
|
386792d7ca | ||
|
|
8c6d98a666 | ||
|
|
6f42224593 | ||
|
|
36c857086b | ||
|
|
014bcddc0a | ||
|
|
96c56b0291 | ||
|
|
c1fe633e72 | ||
|
|
c9a9d86160 | ||
|
|
e79c7e9881 | ||
|
|
be617241e7 | ||
|
|
cb9b59ae01 | ||
|
|
a993acae72 | ||
|
|
e6cdc7d2ba | ||
|
|
94534b2f61 | ||
|
|
fe6b7805c7 | ||
|
|
be25f2f4fc | ||
|
|
a19cc7df1e | ||
|
|
13dbd08dcc | ||
|
|
5f80b6052d | ||
|
|
a48885b79a | ||
|
|
350c2d8775 | ||
|
|
5988dfb1fd | ||
|
|
57687859e4 | ||
|
|
ef42e689ae | ||
|
|
9a3aac9a66 | ||
|
|
7be5fbfbc4 | ||
|
|
4b344ccd18 | ||
|
|
3f50ae0a44 | ||
|
|
afb498b4bf | ||
|
|
6b18b06763 | ||
|
|
033e334877 | ||
|
|
eb9112e480 | ||
|
|
b75e4d59e4 | ||
|
|
c69bb6904f | ||
|
|
9f193b7206 | ||
|
|
6fce2c13fe | ||
|
|
02342c11a6 | ||
|
|
2fde56df0d | ||
|
|
cb64dedd74 | ||
|
|
a7c489413e | ||
|
|
f9ed174e31 | ||
|
|
496d878a14 | ||
|
|
00853d4a92 | ||
|
|
5eb0d2380a | ||
|
|
d19cff9a42 | ||
|
|
234b5fdd8e | ||
|
|
2dbe6c7fe4 | ||
|
|
9d4d1ace08 | ||
|
|
364550d228 | ||
|
|
d5e8cbaf33 | ||
|
|
c4d532fda9 | ||
|
|
aa097cf7e2 | ||
|
|
6f4ca40a94 | ||
|
|
2ef9b4033c | ||
|
|
9aa22ffc86 | ||
|
|
d81c1e6fcb | ||
|
|
ac72e0770a | ||
|
|
5e3e09c4bc | ||
|
|
ee945d5901 | ||
|
|
7f747f3afc | ||
|
|
2d47593f51 | ||
|
|
df529ba239 | ||
|
|
2fea736631 | ||
|
|
9df4fae2dc | ||
|
|
ca964a1a40 | ||
|
|
ada2832839 | ||
|
|
4d92cbb7ff | ||
|
|
d6ab36929b | ||
|
|
e06623d3fe | ||
|
|
8b70a37459 | ||
|
|
daab3829bc | ||
|
|
d09021707b | ||
|
|
bea8cb5757 | ||
|
|
bde546efcb | ||
|
|
e1ffc851a3 | ||
|
|
828229b3e5 | ||
|
|
f36e2f5349 | ||
|
|
cdbe5b141a | ||
|
|
08c3fc0cfa | ||
|
|
8f758fb100 | ||
|
|
ec339b0ecd | ||
|
|
9dedfb86a5 | ||
|
|
0146cff8d3 | ||
|
|
2454d99d84 | ||
|
|
7d9b1bc266 | ||
|
|
77c56c46a8 | ||
|
|
85303098a7 | ||
|
|
821dc62d56 | ||
|
|
f9af4a9e66 | ||
|
|
41b9d6b01d | ||
|
|
7a521acccf | ||
|
|
49233aef88 | ||
|
|
c5b47ed073 | ||
|
|
ddcef7cf0c | ||
|
|
0f86e1c1c1 | ||
|
|
f0f7e229ea | ||
|
|
ea674a3757 | ||
|
|
b7c51eba5e | ||
|
|
1127bf1700 | ||
|
|
376e3284fb | ||
|
|
12f355b205 | ||
|
|
f4b02591e8 | ||
|
|
f843725cf5 | ||
|
|
ed0536c188 | ||
|
|
849e005095 | ||
|
|
927d61dd6b | ||
|
|
9285cffc56 | ||
|
|
1b6c90e87d | ||
|
|
c79de6fbc1 | ||
|
|
fc83ebbb34 | ||
|
|
f330cc954c | ||
|
|
df4f98251c | ||
|
|
74861e9c01 | ||
|
|
7dad9d7875 | ||
|
|
338b9b2d4e | ||
|
|
f6d83867f3 | ||
|
|
bb632ac849 | ||
|
|
793f946b44 | ||
|
|
519a59cc88 | ||
|
|
79b1bff547 | ||
|
|
17ee1ac2ff | ||
|
|
a6fa446d95 | ||
|
|
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 | ||
|
|
a3ba7cdcf2 |
1
.github/CODEOWNERS
vendored
Normal file
1
.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
* @WillFP
|
||||||
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.
|
||||||
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, workflow_dispatch ]
|
||||||
|
|
||||||
|
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 21
|
||||||
|
uses: actions/setup-java@v2
|
||||||
|
with:
|
||||||
|
distribution: 'temurin'
|
||||||
|
java-version: 21
|
||||||
|
|
||||||
|
- 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
|
||||||
21
.github/workflows/master-pr.yml
vendored
Normal file
21
.github/workflows/master-pr.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
name: PR Alert for Master Branch
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
alert:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Comment PR
|
||||||
|
uses: actions/github-script@v5
|
||||||
|
with:
|
||||||
|
github-token: ${{secrets.GITHUB_TOKEN}}
|
||||||
|
script: |
|
||||||
|
github.issues.createComment({
|
||||||
|
issue_number: context.issue.number,
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
body: '⚠️ PRs should not be opened against the `master` branch directly. Please use the `develop` branch as the base for your PRs. ⚠️'
|
||||||
|
})
|
||||||
8
.github/workflows/publish-release.yml
vendored
8
.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 21
|
||||||
uses: actions/setup-java@v2
|
uses: actions/setup-java@v2
|
||||||
with:
|
with:
|
||||||
distribution: 'adopt'
|
distribution: 'temurin'
|
||||||
java-version: 16
|
java-version: 21
|
||||||
|
|
||||||
- name: Setup build cache
|
- name: Setup build cache
|
||||||
uses: actions/cache@v2.1.6
|
uses: actions/cache@v2.1.6
|
||||||
@@ -28,6 +28,8 @@ jobs:
|
|||||||
- name: Publish artifact
|
- name: Publish artifact
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }}
|
||||||
|
MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}
|
||||||
|
|
||||||
# The GITHUB_REF tag comes in the format 'refs/tags/xxx'.
|
# The GITHUB_REF tag comes in the format 'refs/tags/xxx'.
|
||||||
# So if we split on '/' and take the 3rd value, we can get the release name.
|
# So if we split on '/' and take the 3rd value, we can get the release name.
|
||||||
|
|||||||
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 21
|
||||||
|
uses: actions/setup-java@v2
|
||||||
|
with:
|
||||||
|
distribution: 'temurin'
|
||||||
|
java-version: 21
|
||||||
|
|
||||||
|
- 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,24 +1,7 @@
|
|||||||
# How to contribute to eco
|
# How to contribute to eco
|
||||||
|
|
||||||
## Codestyle
|
Please open any Pull Requests into the `develop` branch or ideally into a new branch for your changes. PRs that go into `master` won't be ignored, but I have to checkout and merge manually, which makes your PR show as being closed.
|
||||||
1. The eco checkstyle is in /config/checkstyle.xml
|
|
||||||
- The pull request must not have any checkstyle issues.
|
|
||||||
- Every method and field must have a javadoc attached.
|
|
||||||
|
|
||||||
2. Use JetBrains annotations
|
Do not write any Kotlin-only APIs; all API components should be written in Java, Kotlin extensions should not have functionality that isn't available in java. The same applies the other way round, do not write any backend code in Java, it should be Kotlin-exclusive.
|
||||||
- Every parameter should be annotated with @NotNull or @Nullable
|
|
||||||
- Use @NotNull over lombok @NonNull
|
|
||||||
|
|
||||||
3. Imports
|
If you have any questions about contributing, feel free to ask in the [Discord](https://discord.gg/ZcwpSsE)!
|
||||||
- No group (*) imports.
|
|
||||||
- No static imports.
|
|
||||||
|
|
||||||
## Dependency Injection
|
|
||||||
- eco uses Dependency Injection
|
|
||||||
- Any calls to Eco#getHandler#getEcoPlugin are code smells and should never be used unless **absolutely necessary**.
|
|
||||||
- NamespacedKeys, FixedMetadataValues, Runnables, and Schedules should be managed using AbstractEcoPlugin through DI.
|
|
||||||
- Any DI class should extend PluginDependent where possible. If the class extends another, then you **must** store the plugin instance in a private final variable called **plugin** with a private or protected getter.
|
|
||||||
|
|
||||||
## Other
|
|
||||||
- All drops **must** be sent through a DropQueue - calls to World#dropItem will get your PR rejected.
|
|
||||||
- eco is built with java 16.
|
|
||||||
697
LICENSE.md
697
LICENSE.md
@@ -1,674 +1,23 @@
|
|||||||
GNU GENERAL PUBLIC LICENSE
|
The MIT License (MIT)
|
||||||
Version 3, 29 June 2007
|
=====================
|
||||||
|
|
||||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
Permission is hereby granted, free of charge, to any person
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
obtaining a copy of this software and associated documentation
|
||||||
of this license document, but changing it is not allowed.
|
files (the “Software”), to deal in the Software without
|
||||||
|
restriction, including without limitation the rights to use,
|
||||||
Preamble
|
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the
|
||||||
The GNU General Public License is a free, copyleft license for
|
Software is furnished to do so, subject to the following
|
||||||
software and other kinds of works.
|
conditions:
|
||||||
|
|
||||||
The licenses for most software and other practical works are designed
|
The above copyright notice and this permission notice shall be
|
||||||
to take away your freedom to share and change the works. By contrast,
|
included in all copies or substantial portions of the Software.
|
||||||
the GNU General Public License is intended to guarantee your freedom to
|
|
||||||
share and change all versions of a program--to make sure it remains free
|
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
||||||
software for all its users. We, the Free Software Foundation, use the
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
GNU General Public License for most of our software; it applies also to
|
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
any other work released this way by its authors. You can apply it to
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
your programs, too.
|
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
When we speak of free software, we are referring to freedom, not
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
OTHER DEALINGS IN THE SOFTWARE.
|
||||||
have the freedom to distribute copies of free software (and charge for
|
|
||||||
them if you wish), that you receive source code or can get it if you
|
|
||||||
want it, that you can change the software or use pieces of it in new
|
|
||||||
free programs, and that you know you can do these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to prevent others from denying you
|
|
||||||
these rights or asking you to surrender the rights. Therefore, you have
|
|
||||||
certain responsibilities if you distribute copies of the software, or if
|
|
||||||
you modify it: responsibilities to respect the freedom of others.
|
|
||||||
|
|
||||||
For example, if you distribute copies of such a program, whether
|
|
||||||
gratis or for a fee, you must pass on to the recipients the same
|
|
||||||
freedoms that you received. You must make sure that they, too, receive
|
|
||||||
or can get the source code. And you must show them these terms so they
|
|
||||||
know their rights.
|
|
||||||
|
|
||||||
Developers that use the GNU GPL protect your rights with two steps:
|
|
||||||
(1) assert copyright on the software, and (2) offer you this License
|
|
||||||
giving you legal permission to copy, distribute and/or modify it.
|
|
||||||
|
|
||||||
For the developers' and authors' protection, the GPL clearly explains
|
|
||||||
that there is no warranty for this free software. For both users' and
|
|
||||||
authors' sake, the GPL requires that modified versions be marked as
|
|
||||||
changed, so that their problems will not be attributed erroneously to
|
|
||||||
authors of previous versions.
|
|
||||||
|
|
||||||
Some devices are designed to deny users access to install or run
|
|
||||||
modified versions of the software inside them, although the manufacturer
|
|
||||||
can do so. This is fundamentally incompatible with the aim of
|
|
||||||
protecting users' freedom to change the software. The systematic
|
|
||||||
pattern of such abuse occurs in the area of products for individuals to
|
|
||||||
use, which is precisely where it is most unacceptable. Therefore, we
|
|
||||||
have designed this version of the GPL to prohibit the practice for those
|
|
||||||
products. If such problems arise substantially in other domains, we
|
|
||||||
stand ready to extend this provision to those domains in future versions
|
|
||||||
of the GPL, as needed to protect the freedom of users.
|
|
||||||
|
|
||||||
Finally, every program is threatened constantly by software patents.
|
|
||||||
States should not allow patents to restrict development and use of
|
|
||||||
software on general-purpose computers, but in those that do, we wish to
|
|
||||||
avoid the special danger that patents applied to a free program could
|
|
||||||
make it effectively proprietary. To prevent this, the GPL assures that
|
|
||||||
patents cannot be used to render the program non-free.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow.
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
0. Definitions.
|
|
||||||
|
|
||||||
"This License" refers to version 3 of the GNU General Public License.
|
|
||||||
|
|
||||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
|
||||||
works, such as semiconductor masks.
|
|
||||||
|
|
||||||
"The Program" refers to any copyrightable work licensed under this
|
|
||||||
License. Each licensee is addressed as "you". "Licensees" and
|
|
||||||
"recipients" may be individuals or organizations.
|
|
||||||
|
|
||||||
To "modify" a work means to copy from or adapt all or part of the work
|
|
||||||
in a fashion requiring copyright permission, other than the making of an
|
|
||||||
exact copy. The resulting work is called a "modified version" of the
|
|
||||||
earlier work or a work "based on" the earlier work.
|
|
||||||
|
|
||||||
A "covered work" means either the unmodified Program or a work based
|
|
||||||
on the Program.
|
|
||||||
|
|
||||||
To "propagate" a work means to do anything with it that, without
|
|
||||||
permission, would make you directly or secondarily liable for
|
|
||||||
infringement under applicable copyright law, except executing it on a
|
|
||||||
computer or modifying a private copy. Propagation includes copying,
|
|
||||||
distribution (with or without modification), making available to the
|
|
||||||
public, and in some countries other activities as well.
|
|
||||||
|
|
||||||
To "convey" a work means any kind of propagation that enables other
|
|
||||||
parties to make or receive copies. Mere interaction with a user through
|
|
||||||
a computer network, with no transfer of a copy, is not conveying.
|
|
||||||
|
|
||||||
An interactive user interface displays "Appropriate Legal Notices"
|
|
||||||
to the extent that it includes a convenient and prominently visible
|
|
||||||
feature that (1) displays an appropriate copyright notice, and (2)
|
|
||||||
tells the user that there is no warranty for the work (except to the
|
|
||||||
extent that warranties are provided), that licensees may convey the
|
|
||||||
work under this License, and how to view a copy of this License. If
|
|
||||||
the interface presents a list of user commands or options, such as a
|
|
||||||
menu, a prominent item in the list meets this criterion.
|
|
||||||
|
|
||||||
1. Source Code.
|
|
||||||
|
|
||||||
The "source code" for a work means the preferred form of the work
|
|
||||||
for making modifications to it. "Object code" means any non-source
|
|
||||||
form of a work.
|
|
||||||
|
|
||||||
A "Standard Interface" means an interface that either is an official
|
|
||||||
standard defined by a recognized standards body, or, in the case of
|
|
||||||
interfaces specified for a particular programming language, one that
|
|
||||||
is widely used among developers working in that language.
|
|
||||||
|
|
||||||
The "System Libraries" of an executable work include anything, other
|
|
||||||
than the work as a whole, that (a) is included in the normal form of
|
|
||||||
packaging a Major Component, but which is not part of that Major
|
|
||||||
Component, and (b) serves only to enable use of the work with that
|
|
||||||
Major Component, or to implement a Standard Interface for which an
|
|
||||||
implementation is available to the public in source code form. A
|
|
||||||
"Major Component", in this context, means a major essential component
|
|
||||||
(kernel, window system, and so on) of the specific operating system
|
|
||||||
(if any) on which the executable work runs, or a compiler used to
|
|
||||||
produce the work, or an object code interpreter used to run it.
|
|
||||||
|
|
||||||
The "Corresponding Source" for a work in object code form means all
|
|
||||||
the source code needed to generate, install, and (for an executable
|
|
||||||
work) run the object code and to modify the work, including scripts to
|
|
||||||
control those activities. However, it does not include the work's
|
|
||||||
System Libraries, or general-purpose tools or generally available free
|
|
||||||
programs which are used unmodified in performing those activities but
|
|
||||||
which are not part of the work. For example, Corresponding Source
|
|
||||||
includes interface definition files associated with source files for
|
|
||||||
the work, and the source code for shared libraries and dynamically
|
|
||||||
linked subprograms that the work is specifically designed to require,
|
|
||||||
such as by intimate data communication or control flow between those
|
|
||||||
subprograms and other parts of the work.
|
|
||||||
|
|
||||||
The Corresponding Source need not include anything that users
|
|
||||||
can regenerate automatically from other parts of the Corresponding
|
|
||||||
Source.
|
|
||||||
|
|
||||||
The Corresponding Source for a work in source code form is that
|
|
||||||
same work.
|
|
||||||
|
|
||||||
2. Basic Permissions.
|
|
||||||
|
|
||||||
All rights granted under this License are granted for the term of
|
|
||||||
copyright on the Program, and are irrevocable provided the stated
|
|
||||||
conditions are met. This License explicitly affirms your unlimited
|
|
||||||
permission to run the unmodified Program. The output from running a
|
|
||||||
covered work is covered by this License only if the output, given its
|
|
||||||
content, constitutes a covered work. This License acknowledges your
|
|
||||||
rights of fair use or other equivalent, as provided by copyright law.
|
|
||||||
|
|
||||||
You may make, run and propagate covered works that you do not
|
|
||||||
convey, without conditions so long as your license otherwise remains
|
|
||||||
in force. You may convey covered works to others for the sole purpose
|
|
||||||
of having them make modifications exclusively for you, or provide you
|
|
||||||
with facilities for running those works, provided that you comply with
|
|
||||||
the terms of this License in conveying all material for which you do
|
|
||||||
not control copyright. Those thus making or running the covered works
|
|
||||||
for you must do so exclusively on your behalf, under your direction
|
|
||||||
and control, on terms that prohibit them from making any copies of
|
|
||||||
your copyrighted material outside their relationship with you.
|
|
||||||
|
|
||||||
Conveying under any other circumstances is permitted solely under
|
|
||||||
the conditions stated below. Sublicensing is not allowed; section 10
|
|
||||||
makes it unnecessary.
|
|
||||||
|
|
||||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
|
||||||
|
|
||||||
No covered work shall be deemed part of an effective technological
|
|
||||||
measure under any applicable law fulfilling obligations under article
|
|
||||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
|
||||||
similar laws prohibiting or restricting circumvention of such
|
|
||||||
measures.
|
|
||||||
|
|
||||||
When you convey a covered work, you waive any legal power to forbid
|
|
||||||
circumvention of technological measures to the extent such circumvention
|
|
||||||
is effected by exercising rights under this License with respect to
|
|
||||||
the covered work, and you disclaim any intention to limit operation or
|
|
||||||
modification of the work as a means of enforcing, against the work's
|
|
||||||
users, your or third parties' legal rights to forbid circumvention of
|
|
||||||
technological measures.
|
|
||||||
|
|
||||||
4. Conveying Verbatim Copies.
|
|
||||||
|
|
||||||
You may convey verbatim copies of the Program's source code as you
|
|
||||||
receive it, in any medium, provided that you conspicuously and
|
|
||||||
appropriately publish on each copy an appropriate copyright notice;
|
|
||||||
keep intact all notices stating that this License and any
|
|
||||||
non-permissive terms added in accord with section 7 apply to the code;
|
|
||||||
keep intact all notices of the absence of any warranty; and give all
|
|
||||||
recipients a copy of this License along with the Program.
|
|
||||||
|
|
||||||
You may charge any price or no price for each copy that you convey,
|
|
||||||
and you may offer support or warranty protection for a fee.
|
|
||||||
|
|
||||||
5. Conveying Modified Source Versions.
|
|
||||||
|
|
||||||
You may convey a work based on the Program, or the modifications to
|
|
||||||
produce it from the Program, in the form of source code under the
|
|
||||||
terms of section 4, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) The work must carry prominent notices stating that you modified
|
|
||||||
it, and giving a relevant date.
|
|
||||||
|
|
||||||
b) The work must carry prominent notices stating that it is
|
|
||||||
released under this License and any conditions added under section
|
|
||||||
7. This requirement modifies the requirement in section 4 to
|
|
||||||
"keep intact all notices".
|
|
||||||
|
|
||||||
c) You must license the entire work, as a whole, under this
|
|
||||||
License to anyone who comes into possession of a copy. This
|
|
||||||
License will therefore apply, along with any applicable section 7
|
|
||||||
additional terms, to the whole of the work, and all its parts,
|
|
||||||
regardless of how they are packaged. This License gives no
|
|
||||||
permission to license the work in any other way, but it does not
|
|
||||||
invalidate such permission if you have separately received it.
|
|
||||||
|
|
||||||
d) If the work has interactive user interfaces, each must display
|
|
||||||
Appropriate Legal Notices; however, if the Program has interactive
|
|
||||||
interfaces that do not display Appropriate Legal Notices, your
|
|
||||||
work need not make them do so.
|
|
||||||
|
|
||||||
A compilation of a covered work with other separate and independent
|
|
||||||
works, which are not by their nature extensions of the covered work,
|
|
||||||
and which are not combined with it such as to form a larger program,
|
|
||||||
in or on a volume of a storage or distribution medium, is called an
|
|
||||||
"aggregate" if the compilation and its resulting copyright are not
|
|
||||||
used to limit the access or legal rights of the compilation's users
|
|
||||||
beyond what the individual works permit. Inclusion of a covered work
|
|
||||||
in an aggregate does not cause this License to apply to the other
|
|
||||||
parts of the aggregate.
|
|
||||||
|
|
||||||
6. Conveying Non-Source Forms.
|
|
||||||
|
|
||||||
You may convey a covered work in object code form under the terms
|
|
||||||
of sections 4 and 5, provided that you also convey the
|
|
||||||
machine-readable Corresponding Source under the terms of this License,
|
|
||||||
in one of these ways:
|
|
||||||
|
|
||||||
a) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by the
|
|
||||||
Corresponding Source fixed on a durable physical medium
|
|
||||||
customarily used for software interchange.
|
|
||||||
|
|
||||||
b) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by a
|
|
||||||
written offer, valid for at least three years and valid for as
|
|
||||||
long as you offer spare parts or customer support for that product
|
|
||||||
model, to give anyone who possesses the object code either (1) a
|
|
||||||
copy of the Corresponding Source for all the software in the
|
|
||||||
product that is covered by this License, on a durable physical
|
|
||||||
medium customarily used for software interchange, for a price no
|
|
||||||
more than your reasonable cost of physically performing this
|
|
||||||
conveying of source, or (2) access to copy the
|
|
||||||
Corresponding Source from a network server at no charge.
|
|
||||||
|
|
||||||
c) Convey individual copies of the object code with a copy of the
|
|
||||||
written offer to provide the Corresponding Source. This
|
|
||||||
alternative is allowed only occasionally and noncommercially, and
|
|
||||||
only if you received the object code with such an offer, in accord
|
|
||||||
with subsection 6b.
|
|
||||||
|
|
||||||
d) Convey the object code by offering access from a designated
|
|
||||||
place (gratis or for a charge), and offer equivalent access to the
|
|
||||||
Corresponding Source in the same way through the same place at no
|
|
||||||
further charge. You need not require recipients to copy the
|
|
||||||
Corresponding Source along with the object code. If the place to
|
|
||||||
copy the object code is a network server, the Corresponding Source
|
|
||||||
may be on a different server (operated by you or a third party)
|
|
||||||
that supports equivalent copying facilities, provided you maintain
|
|
||||||
clear directions next to the object code saying where to find the
|
|
||||||
Corresponding Source. Regardless of what server hosts the
|
|
||||||
Corresponding Source, you remain obligated to ensure that it is
|
|
||||||
available for as long as needed to satisfy these requirements.
|
|
||||||
|
|
||||||
e) Convey the object code using peer-to-peer transmission, provided
|
|
||||||
you inform other peers where the object code and Corresponding
|
|
||||||
Source of the work are being offered to the general public at no
|
|
||||||
charge under subsection 6d.
|
|
||||||
|
|
||||||
A separable portion of the object code, whose source code is excluded
|
|
||||||
from the Corresponding Source as a System Library, need not be
|
|
||||||
included in conveying the object code work.
|
|
||||||
|
|
||||||
A "User Product" is either (1) a "consumer product", which means any
|
|
||||||
tangible personal property which is normally used for personal, family,
|
|
||||||
or household purposes, or (2) anything designed or sold for incorporation
|
|
||||||
into a dwelling. In determining whether a product is a consumer product,
|
|
||||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
|
||||||
product received by a particular user, "normally used" refers to a
|
|
||||||
typical or common use of that class of product, regardless of the status
|
|
||||||
of the particular user or of the way in which the particular user
|
|
||||||
actually uses, or expects or is expected to use, the product. A product
|
|
||||||
is a consumer product regardless of whether the product has substantial
|
|
||||||
commercial, industrial or non-consumer uses, unless such uses represent
|
|
||||||
the only significant mode of use of the product.
|
|
||||||
|
|
||||||
"Installation Information" for a User Product means any methods,
|
|
||||||
procedures, authorization keys, or other information required to install
|
|
||||||
and execute modified versions of a covered work in that User Product from
|
|
||||||
a modified version of its Corresponding Source. The information must
|
|
||||||
suffice to ensure that the continued functioning of the modified object
|
|
||||||
code is in no case prevented or interfered with solely because
|
|
||||||
modification has been made.
|
|
||||||
|
|
||||||
If you convey an object code work under this section in, or with, or
|
|
||||||
specifically for use in, a User Product, and the conveying occurs as
|
|
||||||
part of a transaction in which the right of possession and use of the
|
|
||||||
User Product is transferred to the recipient in perpetuity or for a
|
|
||||||
fixed term (regardless of how the transaction is characterized), the
|
|
||||||
Corresponding Source conveyed under this section must be accompanied
|
|
||||||
by the Installation Information. But this requirement does not apply
|
|
||||||
if neither you nor any third party retains the ability to install
|
|
||||||
modified object code on the User Product (for example, the work has
|
|
||||||
been installed in ROM).
|
|
||||||
|
|
||||||
The requirement to provide Installation Information does not include a
|
|
||||||
requirement to continue to provide support service, warranty, or updates
|
|
||||||
for a work that has been modified or installed by the recipient, or for
|
|
||||||
the User Product in which it has been modified or installed. Access to a
|
|
||||||
network may be denied when the modification itself materially and
|
|
||||||
adversely affects the operation of the network or violates the rules and
|
|
||||||
protocols for communication across the network.
|
|
||||||
|
|
||||||
Corresponding Source conveyed, and Installation Information provided,
|
|
||||||
in accord with this section must be in a format that is publicly
|
|
||||||
documented (and with an implementation available to the public in
|
|
||||||
source code form), and must require no special password or key for
|
|
||||||
unpacking, reading or copying.
|
|
||||||
|
|
||||||
7. Additional Terms.
|
|
||||||
|
|
||||||
"Additional permissions" are terms that supplement the terms of this
|
|
||||||
License by making exceptions from one or more of its conditions.
|
|
||||||
Additional permissions that are applicable to the entire Program shall
|
|
||||||
be treated as though they were included in this License, to the extent
|
|
||||||
that they are valid under applicable law. If additional permissions
|
|
||||||
apply only to part of the Program, that part may be used separately
|
|
||||||
under those permissions, but the entire Program remains governed by
|
|
||||||
this License without regard to the additional permissions.
|
|
||||||
|
|
||||||
When you convey a copy of a covered work, you may at your option
|
|
||||||
remove any additional permissions from that copy, or from any part of
|
|
||||||
it. (Additional permissions may be written to require their own
|
|
||||||
removal in certain cases when you modify the work.) You may place
|
|
||||||
additional permissions on material, added by you to a covered work,
|
|
||||||
for which you have or can give appropriate copyright permission.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, for material you
|
|
||||||
add to a covered work, you may (if authorized by the copyright holders of
|
|
||||||
that material) supplement the terms of this License with terms:
|
|
||||||
|
|
||||||
a) Disclaiming warranty or limiting liability differently from the
|
|
||||||
terms of sections 15 and 16 of this License; or
|
|
||||||
|
|
||||||
b) Requiring preservation of specified reasonable legal notices or
|
|
||||||
author attributions in that material or in the Appropriate Legal
|
|
||||||
Notices displayed by works containing it; or
|
|
||||||
|
|
||||||
c) Prohibiting misrepresentation of the origin of that material, or
|
|
||||||
requiring that modified versions of such material be marked in
|
|
||||||
reasonable ways as different from the original version; or
|
|
||||||
|
|
||||||
d) Limiting the use for publicity purposes of names of licensors or
|
|
||||||
authors of the material; or
|
|
||||||
|
|
||||||
e) Declining to grant rights under trademark law for use of some
|
|
||||||
trade names, trademarks, or service marks; or
|
|
||||||
|
|
||||||
f) Requiring indemnification of licensors and authors of that
|
|
||||||
material by anyone who conveys the material (or modified versions of
|
|
||||||
it) with contractual assumptions of liability to the recipient, for
|
|
||||||
any liability that these contractual assumptions directly impose on
|
|
||||||
those licensors and authors.
|
|
||||||
|
|
||||||
All other non-permissive additional terms are considered "further
|
|
||||||
restrictions" within the meaning of section 10. If the Program as you
|
|
||||||
received it, or any part of it, contains a notice stating that it is
|
|
||||||
governed by this License along with a term that is a further
|
|
||||||
restriction, you may remove that term. If a license document contains
|
|
||||||
a further restriction but permits relicensing or conveying under this
|
|
||||||
License, you may add to a covered work material governed by the terms
|
|
||||||
of that license document, provided that the further restriction does
|
|
||||||
not survive such relicensing or conveying.
|
|
||||||
|
|
||||||
If you add terms to a covered work in accord with this section, you
|
|
||||||
must place, in the relevant source files, a statement of the
|
|
||||||
additional terms that apply to those files, or a notice indicating
|
|
||||||
where to find the applicable terms.
|
|
||||||
|
|
||||||
Additional terms, permissive or non-permissive, may be stated in the
|
|
||||||
form of a separately written license, or stated as exceptions;
|
|
||||||
the above requirements apply either way.
|
|
||||||
|
|
||||||
8. Termination.
|
|
||||||
|
|
||||||
You may not propagate or modify a covered work except as expressly
|
|
||||||
provided under this License. Any attempt otherwise to propagate or
|
|
||||||
modify it is void, and will automatically terminate your rights under
|
|
||||||
this License (including any patent licenses granted under the third
|
|
||||||
paragraph of section 11).
|
|
||||||
|
|
||||||
However, if you cease all violation of this License, then your
|
|
||||||
license from a particular copyright holder is reinstated (a)
|
|
||||||
provisionally, unless and until the copyright holder explicitly and
|
|
||||||
finally terminates your license, and (b) permanently, if the copyright
|
|
||||||
holder fails to notify you of the violation by some reasonable means
|
|
||||||
prior to 60 days after the cessation.
|
|
||||||
|
|
||||||
Moreover, your license from a particular copyright holder is
|
|
||||||
reinstated permanently if the copyright holder notifies you of the
|
|
||||||
violation by some reasonable means, this is the first time you have
|
|
||||||
received notice of violation of this License (for any work) from that
|
|
||||||
copyright holder, and you cure the violation prior to 30 days after
|
|
||||||
your receipt of the notice.
|
|
||||||
|
|
||||||
Termination of your rights under this section does not terminate the
|
|
||||||
licenses of parties who have received copies or rights from you under
|
|
||||||
this License. If your rights have been terminated and not permanently
|
|
||||||
reinstated, you do not qualify to receive new licenses for the same
|
|
||||||
material under section 10.
|
|
||||||
|
|
||||||
9. Acceptance Not Required for Having Copies.
|
|
||||||
|
|
||||||
You are not required to accept this License in order to receive or
|
|
||||||
run a copy of the Program. Ancillary propagation of a covered work
|
|
||||||
occurring solely as a consequence of using peer-to-peer transmission
|
|
||||||
to receive a copy likewise does not require acceptance. However,
|
|
||||||
nothing other than this License grants you permission to propagate or
|
|
||||||
modify any covered work. These actions infringe copyright if you do
|
|
||||||
not accept this License. Therefore, by modifying or propagating a
|
|
||||||
covered work, you indicate your acceptance of this License to do so.
|
|
||||||
|
|
||||||
10. Automatic Licensing of Downstream Recipients.
|
|
||||||
|
|
||||||
Each time you convey a covered work, the recipient automatically
|
|
||||||
receives a license from the original licensors, to run, modify and
|
|
||||||
propagate that work, subject to this License. You are not responsible
|
|
||||||
for enforcing compliance by third parties with this License.
|
|
||||||
|
|
||||||
An "entity transaction" is a transaction transferring control of an
|
|
||||||
organization, or substantially all assets of one, or subdividing an
|
|
||||||
organization, or merging organizations. If propagation of a covered
|
|
||||||
work results from an entity transaction, each party to that
|
|
||||||
transaction who receives a copy of the work also receives whatever
|
|
||||||
licenses to the work the party's predecessor in interest had or could
|
|
||||||
give under the previous paragraph, plus a right to possession of the
|
|
||||||
Corresponding Source of the work from the predecessor in interest, if
|
|
||||||
the predecessor has it or can get it with reasonable efforts.
|
|
||||||
|
|
||||||
You may not impose any further restrictions on the exercise of the
|
|
||||||
rights granted or affirmed under this License. For example, you may
|
|
||||||
not impose a license fee, royalty, or other charge for exercise of
|
|
||||||
rights granted under this License, and you may not initiate litigation
|
|
||||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
|
||||||
any patent claim is infringed by making, using, selling, offering for
|
|
||||||
sale, or importing the Program or any portion of it.
|
|
||||||
|
|
||||||
11. Patents.
|
|
||||||
|
|
||||||
A "contributor" is a copyright holder who authorizes use under this
|
|
||||||
License of the Program or a work on which the Program is based. The
|
|
||||||
work thus licensed is called the contributor's "contributor version".
|
|
||||||
|
|
||||||
A contributor's "essential patent claims" are all patent claims
|
|
||||||
owned or controlled by the contributor, whether already acquired or
|
|
||||||
hereafter acquired, that would be infringed by some manner, permitted
|
|
||||||
by this License, of making, using, or selling its contributor version,
|
|
||||||
but do not include claims that would be infringed only as a
|
|
||||||
consequence of further modification of the contributor version. For
|
|
||||||
purposes of this definition, "control" includes the right to grant
|
|
||||||
patent sublicenses in a manner consistent with the requirements of
|
|
||||||
this License.
|
|
||||||
|
|
||||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
|
||||||
patent license under the contributor's essential patent claims, to
|
|
||||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
|
||||||
propagate the contents of its contributor version.
|
|
||||||
|
|
||||||
In the following three paragraphs, a "patent license" is any express
|
|
||||||
agreement or commitment, however denominated, not to enforce a patent
|
|
||||||
(such as an express permission to practice a patent or covenant not to
|
|
||||||
sue for patent infringement). To "grant" such a patent license to a
|
|
||||||
party means to make such an agreement or commitment not to enforce a
|
|
||||||
patent against the party.
|
|
||||||
|
|
||||||
If you convey a covered work, knowingly relying on a patent license,
|
|
||||||
and the Corresponding Source of the work is not available for anyone
|
|
||||||
to copy, free of charge and under the terms of this License, through a
|
|
||||||
publicly available network server or other readily accessible means,
|
|
||||||
then you must either (1) cause the Corresponding Source to be so
|
|
||||||
available, or (2) arrange to deprive yourself of the benefit of the
|
|
||||||
patent license for this particular work, or (3) arrange, in a manner
|
|
||||||
consistent with the requirements of this License, to extend the patent
|
|
||||||
license to downstream recipients. "Knowingly relying" means you have
|
|
||||||
actual knowledge that, but for the patent license, your conveying the
|
|
||||||
covered work in a country, or your recipient's use of the covered work
|
|
||||||
in a country, would infringe one or more identifiable patents in that
|
|
||||||
country that you have reason to believe are valid.
|
|
||||||
|
|
||||||
If, pursuant to or in connection with a single transaction or
|
|
||||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
|
||||||
covered work, and grant a patent license to some of the parties
|
|
||||||
receiving the covered work authorizing them to use, propagate, modify
|
|
||||||
or convey a specific copy of the covered work, then the patent license
|
|
||||||
you grant is automatically extended to all recipients of the covered
|
|
||||||
work and works based on it.
|
|
||||||
|
|
||||||
A patent license is "discriminatory" if it does not include within
|
|
||||||
the scope of its coverage, prohibits the exercise of, or is
|
|
||||||
conditioned on the non-exercise of one or more of the rights that are
|
|
||||||
specifically granted under this License. You may not convey a covered
|
|
||||||
work if you are a party to an arrangement with a third party that is
|
|
||||||
in the business of distributing software, under which you make payment
|
|
||||||
to the third party based on the extent of your activity of conveying
|
|
||||||
the work, and under which the third party grants, to any of the
|
|
||||||
parties who would receive the covered work from you, a discriminatory
|
|
||||||
patent license (a) in connection with copies of the covered work
|
|
||||||
conveyed by you (or copies made from those copies), or (b) primarily
|
|
||||||
for and in connection with specific products or compilations that
|
|
||||||
contain the covered work, unless you entered into that arrangement,
|
|
||||||
or that patent license was granted, prior to 28 March 2007.
|
|
||||||
|
|
||||||
Nothing in this License shall be construed as excluding or limiting
|
|
||||||
any implied license or other defenses to infringement that may
|
|
||||||
otherwise be available to you under applicable patent law.
|
|
||||||
|
|
||||||
12. No Surrender of Others' Freedom.
|
|
||||||
|
|
||||||
If conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot convey a
|
|
||||||
covered work so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you may
|
|
||||||
not convey it at all. For example, if you agree to terms that obligate you
|
|
||||||
to collect a royalty for further conveying from those to whom you convey
|
|
||||||
the Program, the only way you could satisfy both those terms and this
|
|
||||||
License would be to refrain entirely from conveying the Program.
|
|
||||||
|
|
||||||
13. Use with the GNU Affero General Public License.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, you have
|
|
||||||
permission to link or combine any covered work with a work licensed
|
|
||||||
under version 3 of the GNU Affero General Public License into a single
|
|
||||||
combined work, and to convey the resulting work. The terms of this
|
|
||||||
License will continue to apply to the part which is the covered work,
|
|
||||||
but the special requirements of the GNU Affero General Public License,
|
|
||||||
section 13, concerning interaction through a network will apply to the
|
|
||||||
combination as such.
|
|
||||||
|
|
||||||
14. Revised Versions of this License.
|
|
||||||
|
|
||||||
The Free Software Foundation may publish revised and/or new versions of
|
|
||||||
the GNU General Public License from time to time. Such new versions will
|
|
||||||
be similar in spirit to the present version, but may differ in detail to
|
|
||||||
address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the
|
|
||||||
Program specifies that a certain numbered version of the GNU General
|
|
||||||
Public License "or any later version" applies to it, you have the
|
|
||||||
option of following the terms and conditions either of that numbered
|
|
||||||
version or of any later version published by the Free Software
|
|
||||||
Foundation. If the Program does not specify a version number of the
|
|
||||||
GNU General Public License, you may choose any version ever published
|
|
||||||
by the Free Software Foundation.
|
|
||||||
|
|
||||||
If the Program specifies that a proxy can decide which future
|
|
||||||
versions of the GNU General Public License can be used, that proxy's
|
|
||||||
public statement of acceptance of a version permanently authorizes you
|
|
||||||
to choose that version for the Program.
|
|
||||||
|
|
||||||
Later license versions may give you additional or different
|
|
||||||
permissions. However, no additional obligations are imposed on any
|
|
||||||
author or copyright holder as a result of your choosing to follow a
|
|
||||||
later version.
|
|
||||||
|
|
||||||
15. Disclaimer of Warranty.
|
|
||||||
|
|
||||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
|
||||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
|
||||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
|
||||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
|
||||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
|
||||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
16. Limitation of Liability.
|
|
||||||
|
|
||||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
|
||||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
|
||||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
|
||||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
|
||||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
|
||||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
|
||||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
|
||||||
SUCH DAMAGES.
|
|
||||||
|
|
||||||
17. Interpretation of Sections 15 and 16.
|
|
||||||
|
|
||||||
If the disclaimer of warranty and limitation of liability provided
|
|
||||||
above cannot be given local legal effect according to their terms,
|
|
||||||
reviewing courts shall apply local law that most closely approximates
|
|
||||||
an absolute waiver of all civil liability in connection with the
|
|
||||||
Program, unless a warranty or assumption of liability accompanies a
|
|
||||||
copy of the Program in return for a fee.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
How to Apply These Terms to Your New Programs
|
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
|
||||||
possible use to the public, the best way to achieve this is to make it
|
|
||||||
free software which everyone can redistribute and change under these terms.
|
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest
|
|
||||||
to attach them to the start of each source file to most effectively
|
|
||||||
state the exclusion of warranty; and each file should have at least
|
|
||||||
the "copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
If the program does terminal interaction, make it output a short
|
|
||||||
notice like this when it starts in an interactive mode:
|
|
||||||
|
|
||||||
<program> Copyright (C) <year> <name of author>
|
|
||||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
|
||||||
This is free software, and you are welcome to redistribute it
|
|
||||||
under certain conditions; type `show c' for details.
|
|
||||||
|
|
||||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
|
||||||
parts of the General Public License. Of course, your program's commands
|
|
||||||
might be different; for a GUI interface, you would use an "about box".
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or school,
|
|
||||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
|
||||||
For more information on this, and how to apply and follow the GNU GPL, see
|
|
||||||
<https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The GNU General Public License does not permit incorporating your program
|
|
||||||
into proprietary programs. If your program is a subroutine library, you
|
|
||||||
may consider it more useful to permit linking proprietary applications with
|
|
||||||
the library. If this is what you want to do, use the GNU Lesser General
|
|
||||||
Public License instead of this License. But first, please read
|
|
||||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
|
||||||
70
README.md
70
README.md
@@ -1,5 +1,5 @@
|
|||||||
# eco
|
# eco
|
||||||
eco is a powerful Spigot development library that simplifies the process of plugin creation and supercharges
|
eco is a powerful Spigot plugin framework that simplifies the process of plugin creation and supercharges
|
||||||
your plugins.
|
your plugins.
|
||||||
It's the engine behind [EcoEnchants](https://polymart.org/resource/490), [Reforges](https://polymart.org/resource/1330),
|
It's the engine behind [EcoEnchants](https://polymart.org/resource/490), [Reforges](https://polymart.org/resource/1330),
|
||||||
[EcoItems](https://polymart.org/resource/1247), [EcoSkills](https://polymart.org/resource/1351),
|
[EcoItems](https://polymart.org/resource/1247), [EcoSkills](https://polymart.org/resource/1351),
|
||||||
@@ -16,22 +16,54 @@ and many more.
|
|||||||
<a href="https://bstats.org/plugin/bukkit/EcoEnchants" alt="bstats players">
|
<a href="https://bstats.org/plugin/bukkit/EcoEnchants" alt="bstats players">
|
||||||
<img src="https://img.shields.io/bstats/players/7666?color=informational"/>
|
<img src="https://img.shields.io/bstats/players/7666?color=informational"/>
|
||||||
</a>
|
</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">
|
<a href="https://discord.gg/ZcwpSsE/" alt="Discord">
|
||||||
<img src="https://img.shields.io/discord/452518336627081236?label=discord&color=informational"/>
|
<img src="https://img.shields.io/discord/452518336627081236?label=discord&color=informational"/>
|
||||||
</a>
|
</a>
|
||||||
|
<a href="https://github.com/Auxilor/eco/actions/workflows/java-ci.yml" alt="Latest Dev Build">
|
||||||
|
<img src="https://img.shields.io/github/actions/workflow/status/Auxilor/eco/java-ci.yml?branch=develop&color=informational"/>
|
||||||
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
eco comes packed with all the tools you need in your plugins:
|
||||||
|
|
||||||
|
- Modern command API
|
||||||
|
- Native color parsing with full hex/RGB/MiniMessage support
|
||||||
|
- Yaml/JSON/TOML config system
|
||||||
|
- Persistent data storage API with Yaml/MySQL/MongoDB support
|
||||||
|
- Packet item display system
|
||||||
|
- Lightweight event loop based packet API
|
||||||
|
- Entity AI API with near-1:1 NMS mappings
|
||||||
|
- More events
|
||||||
|
- Extension API, essentially plugins for plugins
|
||||||
|
- Fluent dependency injection for NamespacedKey, Metadata values, etc.
|
||||||
|
- Ultra-fast ItemStack reimplementation bypassing ItemMeta
|
||||||
|
- Complete GUI API with pre-made components available from [ecomponent](https://github.com/Auxilor/ecomponent)
|
||||||
|
- Over 30 native integrations for other plugins
|
||||||
|
- First-class custom item support with lookup strings
|
||||||
|
- Math expression parsing via [Crunch](https://github.com/Redempt/Crunch)
|
||||||
|
- Particle lookups
|
||||||
|
- Complete Placeholder API
|
||||||
|
- Price system, supporting economy plugins, XP, Items, etc.
|
||||||
|
- NMS/Version-specific tooling
|
||||||
|
- Custom crafting recipe API with support for stacks and custom items
|
||||||
|
- Native plugin update checking
|
||||||
|
- Native bStats support
|
||||||
|
- Full Kotlin support and native extensions
|
||||||
|
- Tooling to make meta-frameworks, like [libreforge](https://github.com/Auxilor/libreforge)
|
||||||
|
- And much more
|
||||||
|
|
||||||
# For server owners
|
# For server owners
|
||||||
- Requires ProtocolLib to be installed: get the latest version [here](https://www.spigotmc.org/resources/protocollib.1997/)
|
- Supports 1.17+
|
||||||
- Supports 1.16.5+
|
|
||||||
|
## Downloads
|
||||||
|
|
||||||
|
- Stable: [GitHub](https://github.com/Auxilor/eco/releases), [Polymart](https://polymart.org/resource/eco.773)
|
||||||
|
- Dev: [GitHub](https://github.com/Auxilor/eco/actions/workflows/java-ci.yml) (Open latest run and download)
|
||||||
|
|
||||||
# For developers
|
# For developers
|
||||||
|
|
||||||
## Javadoc
|
## Javadoc
|
||||||
The 6.13.0 Javadoc can be found [here](https://javadoc.jitpack.io/com/willfp/eco/6.13.0/javadoc/)
|
The 6.53.0 Javadoc can be found [here](https://javadoc.jitpack.io/com/willfp/eco/6.53.0/javadoc/)
|
||||||
|
|
||||||
## Plugin Information
|
## Plugin Information
|
||||||
|
|
||||||
@@ -43,37 +75,31 @@ depend:
|
|||||||
- eco
|
- eco
|
||||||
```
|
```
|
||||||
|
|
||||||
eco is available from any of these places:
|
## Dependency Information:
|
||||||
|
|
||||||
- [GitHub](https://github.com/Auxilor/eco/releases)
|
|
||||||
- [Polymart](https://polymart.org/resource/eco.773)
|
|
||||||
- [Build it locally](https://github.com/Auxilor/eco#build-locally).
|
|
||||||
|
|
||||||
## Get from JitPack:
|
|
||||||
|
|
||||||
Gradle:
|
Gradle:
|
||||||
|
|
||||||
```groovy
|
```kts
|
||||||
repositories {
|
repositories {
|
||||||
maven { url 'https://jitpack.io' }
|
maven("https://repo.auxilor.io/repository/maven-public/")
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```groovy
|
```groovy
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly 'com.willfp:eco:Tag'
|
compileOnly("com.willfp:eco:Tag")
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Replace `Tag` with a release tag for eco, eg `6.13.0`.
|
Replace `Tag` with a release tag for eco, eg `6.53.0`.
|
||||||
|
|
||||||
Maven:
|
Maven:
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<repository>
|
<repository>
|
||||||
<id>jitpack.io</id>
|
<id>auxilor</id>
|
||||||
<url>https://jitpack.io</url>
|
<url>https://repo.auxilor.io/repository/maven-public/</url>
|
||||||
</repository>
|
</repository>
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -86,7 +112,7 @@ Maven:
|
|||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
|
|
||||||
Replace `Tag` with a release tag for eco, eg `6.13.0`.
|
Replace `Tag` with a release tag for eco, eg `6.53.0`.
|
||||||
|
|
||||||
## Build locally:
|
## Build locally:
|
||||||
|
|
||||||
@@ -101,7 +127,7 @@ cd eco
|
|||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
*Click here to read [the entire license](https://github.com/Auxilor/eco/blob/master/LICENSE.md).*
|
eco is licensed under the MIT license. *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!
|
Check out our partners!
|
||||||
|
|||||||
124
build.gradle
124
build.gradle
@@ -1,124 +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:core-plugin")
|
|
||||||
implementation project(":eco-core:core-proxy")
|
|
||||||
implementation project(":eco-core:core-backend")
|
|
||||||
implementation project(":eco-core:core-nms:v1_16_R3")
|
|
||||||
implementation project(path: ":eco-core:core-nms:v1_17_R1", configuration: 'mapped')
|
|
||||||
}
|
|
||||||
|
|
||||||
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' }
|
|
||||||
|
|
||||||
// SuperiorSkyblock2
|
|
||||||
maven { url 'https://repo.bg-software.com/repository/api/' }
|
|
||||||
|
|
||||||
// NMS (for jitpack compilation)
|
|
||||||
maven { url 'https://repo.codemc.org/repository/nms/' }
|
|
||||||
|
|
||||||
// bStats, mcMMO, BentoBox
|
|
||||||
maven { url 'https://repo.codemc.org/repository/maven-public/' }
|
|
||||||
|
|
||||||
// Spigot API, Bungee 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/' }
|
|
||||||
|
|
||||||
// IridiumSkyblock
|
|
||||||
maven { url 'https://nexus.iridiumdevelopment.net/repository/maven-releases/' }
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
compileOnly 'org.jetbrains:annotations:19.0.0'
|
|
||||||
|
|
||||||
// Test
|
|
||||||
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.1'
|
|
||||||
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
|
|
||||||
}
|
|
||||||
|
|
||||||
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', 'com.willfp.eco.shaded.bstats')
|
|
||||||
relocate('net.kyori.adventure.text.minimessage', 'com.willfp.eco.shaded.minimessage')
|
|
||||||
}
|
|
||||||
|
|
||||||
jar {
|
|
||||||
onlyIf { !sourceSets.main.allSource.files.isEmpty() }
|
|
||||||
}
|
|
||||||
|
|
||||||
compileJava {
|
|
||||||
onlyIf { !sourceSets.main.allSource.files.isEmpty() }
|
|
||||||
}
|
|
||||||
|
|
||||||
java {
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_16
|
|
||||||
targetCompatibility = JavaVersion.VERSION_16
|
|
||||||
withSourcesJar()
|
|
||||||
}
|
|
||||||
|
|
||||||
test {
|
|
||||||
useJUnitPlatform()
|
|
||||||
|
|
||||||
// Always run tests, even when nothing changed.
|
|
||||||
dependsOn cleanTest
|
|
||||||
|
|
||||||
// Show test results.
|
|
||||||
testLogging {
|
|
||||||
events "passed", "skipped", "failed"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
compileJava.options.encoding = 'UTF-8'
|
|
||||||
compileJava.dependsOn clean
|
|
||||||
|
|
||||||
build.dependsOn shadowJar
|
|
||||||
}
|
|
||||||
|
|
||||||
group = 'com.willfp'
|
|
||||||
archivesBaseName = project.name
|
|
||||||
version = findProperty("version")
|
|
||||||
229
build.gradle.kts
Normal file
229
build.gradle.kts
Normal file
@@ -0,0 +1,229 @@
|
|||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.21")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id("java-library")
|
||||||
|
id("io.github.goooler.shadow") version "8.1.7"
|
||||||
|
id("maven-publish")
|
||||||
|
id("java")
|
||||||
|
kotlin("jvm") version "1.9.21"
|
||||||
|
kotlin("plugin.serialization") version "1.9.21"
|
||||||
|
}
|
||||||
|
|
||||||
|
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(":eco-core:core-backend-modern"))
|
||||||
|
implementation(project(path = ":eco-core:core-nms:v1_17_R1", configuration = "reobf"))
|
||||||
|
implementation(project(path = ":eco-core:core-nms:v1_18_R1", configuration = "reobf"))
|
||||||
|
implementation(project(path = ":eco-core:core-nms:v1_18_R2", configuration = "reobf"))
|
||||||
|
implementation(project(path = ":eco-core:core-nms:v1_19_R1", configuration = "reobf"))
|
||||||
|
implementation(project(path = ":eco-core:core-nms:v1_19_R2", configuration = "reobf"))
|
||||||
|
implementation(project(path = ":eco-core:core-nms:v1_19_R3", configuration = "reobf"))
|
||||||
|
implementation(project(path = ":eco-core:core-nms:v1_20_R1", configuration = "reobf"))
|
||||||
|
implementation(project(path = ":eco-core:core-nms:v1_20_R2", configuration = "reobf"))
|
||||||
|
implementation(project(path = ":eco-core:core-nms:v1_20_R3", configuration = "reobf"))
|
||||||
|
implementation(project(path = ":eco-core:core-nms:v1_21", configuration = "reobf"))
|
||||||
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
apply(plugin = "java")
|
||||||
|
apply(plugin = "java-library")
|
||||||
|
apply(plugin = "maven-publish")
|
||||||
|
apply(plugin = "io.github.goooler.shadow")
|
||||||
|
apply(plugin = "kotlin")
|
||||||
|
apply(plugin = "org.jetbrains.kotlin.plugin.serialization")
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
maven("https://repo.auxilor.io/repository/maven-public/")
|
||||||
|
maven("https://jitpack.io") {
|
||||||
|
content { includeGroupByRegex("com\\.github\\..*") }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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/")
|
||||||
|
|
||||||
|
// PlayerPoints
|
||||||
|
maven("https://repo.rosewooddev.io/repository/public/")
|
||||||
|
|
||||||
|
// Denizen
|
||||||
|
maven("https://maven.citizensnpcs.co/repo")
|
||||||
|
|
||||||
|
// IridiumSkyblock
|
||||||
|
maven("https://nexus.iridiumdevelopment.net/repository/maven-releases/")
|
||||||
|
|
||||||
|
// HuskPlugins
|
||||||
|
maven("https://repo.william278.net/releases")
|
||||||
|
|
||||||
|
// FancyHolograms
|
||||||
|
maven("https://repo.fancyplugins.de/releases")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
// Kotlin
|
||||||
|
implementation(kotlin("stdlib", version = "1.9.21"))
|
||||||
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
|
||||||
|
|
||||||
|
// 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.9.2")
|
||||||
|
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.9.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.5")
|
||||||
|
implementation("org.apache.maven:maven-artifact:3.9.0")
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
withType<Jar> {
|
||||||
|
duplicatesStrategy = DuplicatesStrategy.WARN
|
||||||
|
}
|
||||||
|
|
||||||
|
compileKotlin {
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = "17"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
compileJava {
|
||||||
|
dependsOn(clean)
|
||||||
|
options.encoding = "UTF-8"
|
||||||
|
}
|
||||||
|
|
||||||
|
test {
|
||||||
|
useJUnitPlatform()
|
||||||
|
|
||||||
|
// Show test results.
|
||||||
|
testLogging {
|
||||||
|
events("passed", "skipped", "failed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
build {
|
||||||
|
dependsOn(shadowJar)
|
||||||
|
}
|
||||||
|
|
||||||
|
withType<JavaCompile>().configureEach {
|
||||||
|
options.release = 17
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
java {
|
||||||
|
withSourcesJar()
|
||||||
|
toolchain {
|
||||||
|
languageVersion = JavaLanguageVersion.of(21)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
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("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")
|
||||||
|
relocate("com.willfp.modelenginebridge", "com.willfp.eco.libs.modelenginebridge")
|
||||||
|
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|||||||
@@ -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,48 +0,0 @@
|
|||||||
plugins {
|
|
||||||
id 'com.github.johnrengelman.shadow'
|
|
||||||
}
|
|
||||||
|
|
||||||
group 'com.willfp'
|
|
||||||
version rootProject.version
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
// Adventure
|
|
||||||
compileOnly 'net.kyori:adventure-platform-bukkit:4.0.0'
|
|
||||||
compileOnly 'net.kyori:adventure-text-minimessage:4.1.0-SNAPSHOT'
|
|
||||||
compileOnly 'net.kyori:adventure-api:4.9.2'
|
|
||||||
compileOnly 'net.kyori:adventure-text-serializer-gson:4.9.2'
|
|
||||||
compileOnly 'net.kyori:adventure-text-serializer-legacy:4.9.2'
|
|
||||||
|
|
||||||
// Other
|
|
||||||
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
|
|
||||||
compileOnly 'org.apache.maven:maven-artifact:3.8.1'
|
|
||||||
compileOnly 'com.comphenix.protocol:ProtocolLib:4.7.1-SNAPSHOT'
|
|
||||||
compileOnly 'com.google.code.gson:gson:2.8.8'
|
|
||||||
}
|
|
||||||
|
|
||||||
java {
|
|
||||||
withJavadocJar()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
build.dependsOn publishToMavenLocal
|
|
||||||
|
|
||||||
publishing {
|
|
||||||
publications {
|
|
||||||
shadow(MavenPublication) {
|
|
||||||
from components.java
|
|
||||||
artifactId 'eco'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
maven {
|
|
||||||
name = "GitHubPackages"
|
|
||||||
url = uri("https://maven.pkg.github.com/Auxilor/eco")
|
|
||||||
credentials {
|
|
||||||
username = System.getenv("GITHUB_ACTOR")
|
|
||||||
password = System.getenv("GITHUB_TOKEN")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
56
eco-api/build.gradle.kts
Normal file
56
eco-api/build.gradle.kts
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
dependencies {
|
||||||
|
// Adventure
|
||||||
|
compileOnly("net.kyori:adventure-platform-bukkit:4.1.0")
|
||||||
|
|
||||||
|
// Other
|
||||||
|
compileOnly("org.spigotmc:spigot-api:1.20.2-R0.1-SNAPSHOT")
|
||||||
|
compileOnly("commons-lang:commons-lang:2.6")
|
||||||
|
compileOnly("com.comphenix.protocol:ProtocolLib:4.6.1-SNAPSHOT")
|
||||||
|
compileOnly("com.google.code.gson:gson:2.8.8")
|
||||||
|
}
|
||||||
|
|
||||||
|
group = "com.willfp"
|
||||||
|
version = rootProject.version
|
||||||
|
|
||||||
|
java {
|
||||||
|
withJavadocJar()
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
build {
|
||||||
|
dependsOn(publishToMavenLocal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
publishing {
|
||||||
|
publications {
|
||||||
|
create<MavenPublication>("shadow") {
|
||||||
|
from(components["java"])
|
||||||
|
artifactId = "eco"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
name = "GitHubPackages"
|
||||||
|
url = uri("https://maven.pkg.github.com/Auxilor/eco")
|
||||||
|
credentials {
|
||||||
|
username = System.getenv("GITHUB_ACTOR")
|
||||||
|
password = System.getenv("GITHUB_TOKEN")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
publishing {
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
name = "Auxilor"
|
||||||
|
url = uri("https://repo.auxilor.io/repository/maven-releases/")
|
||||||
|
credentials {
|
||||||
|
username = System.getenv("MAVEN_USERNAME")
|
||||||
|
password = System.getenv("MAVEN_PASSWORD")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,27 +13,30 @@ import java.util.Collections;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper class for ProtocolLib packets.
|
* Wrapper class for ProtocolLib packets.
|
||||||
|
*
|
||||||
|
* @deprecated ProtocolLib is no longer used by eco. Use {@link com.willfp.eco.core.packet.PacketListener} instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(since = "6.51.0")
|
||||||
public abstract class AbstractPacketAdapter extends PacketAdapter {
|
public abstract class AbstractPacketAdapter extends PacketAdapter {
|
||||||
/**
|
/**
|
||||||
* The packet type to listen for.
|
* The handle type to listen for.
|
||||||
*/
|
*/
|
||||||
private final PacketType type;
|
private final PacketType type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the packet adapter should be registered after the server has loaded.
|
* Whether the handle adapter should be registered after the server has loaded.
|
||||||
* <p>
|
* <p>
|
||||||
* Useful for monitor priority adapters that <b>must</b> be ran last.
|
* Useful for monitor priority adapters that <b>must</b> be ran last.
|
||||||
*/
|
*/
|
||||||
private final boolean postLoad;
|
private final boolean postLoad;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new packet adapter for a specified plugin and type.
|
* Create a new handle adapter for a specified plugin and type.
|
||||||
*
|
*
|
||||||
* @param plugin The plugin that ProtocolLib should mark as the owner.
|
* @param plugin The plugin that ProtocolLib should mark as the owner.
|
||||||
* @param type The {@link PacketType} to listen for.
|
* @param type The {@link PacketType} to listen for.
|
||||||
* @param priority The priority at which the adapter should be ran on packet send/receive.
|
* @param priority The priority at which the adapter should be ran on handle send/receive.
|
||||||
* @param postLoad If the packet adapter should be registered after the server has loaded.
|
* @param postLoad If the handle adapter should be registered after the server has loaded.
|
||||||
*/
|
*/
|
||||||
protected AbstractPacketAdapter(@NotNull final EcoPlugin plugin,
|
protected AbstractPacketAdapter(@NotNull final EcoPlugin plugin,
|
||||||
@NotNull final PacketType type,
|
@NotNull final PacketType type,
|
||||||
@@ -45,11 +48,11 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new packet adapter for a specified plugin and type.
|
* Create a new handle adapter for a specified plugin and type.
|
||||||
*
|
*
|
||||||
* @param plugin The plugin that ProtocolLib should mark as the owner.
|
* @param plugin The plugin that ProtocolLib should mark as the owner.
|
||||||
* @param type The {@link PacketType} to listen for.
|
* @param type The {@link PacketType} to listen for.
|
||||||
* @param postLoad If the packet adapter should be registered after the server has loaded.
|
* @param postLoad If the handle adapter should be registered after the server has loaded.
|
||||||
*/
|
*/
|
||||||
protected AbstractPacketAdapter(@NotNull final EcoPlugin plugin,
|
protected AbstractPacketAdapter(@NotNull final EcoPlugin plugin,
|
||||||
@NotNull final PacketType type,
|
@NotNull final PacketType type,
|
||||||
@@ -58,9 +61,9 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The code that should be executed once the packet has been received.
|
* The code that should be executed once the handle has been received.
|
||||||
*
|
*
|
||||||
* @param packet The packet.
|
* @param packet The handle.
|
||||||
* @param player The player.
|
* @param player The player.
|
||||||
* @param event The event.
|
* @param event The event.
|
||||||
*/
|
*/
|
||||||
@@ -71,9 +74,9 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* THe code that should be executed once the packet has been sent.
|
* THe code that should be executed once the handle has been sent.
|
||||||
*
|
*
|
||||||
* @param packet The packet.
|
* @param packet The handle.
|
||||||
* @param player The player.
|
* @param player The player.
|
||||||
* @param event The event.
|
* @param event The event.
|
||||||
*/
|
*/
|
||||||
@@ -84,7 +87,7 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Boilerplate to assert that the packet is of the specified type.
|
* Boilerplate to assert that the handle is of the specified type.
|
||||||
*
|
*
|
||||||
* @param event The ProtocolLib event.
|
* @param event The ProtocolLib event.
|
||||||
*/
|
*/
|
||||||
@@ -102,7 +105,7 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Boilerplate to assert that the packet is of the specified type.
|
* Boilerplate to assert that the handle is of the specified type.
|
||||||
*
|
*
|
||||||
* @param event The ProtocolLib event.
|
* @param event The ProtocolLib event.
|
||||||
*/
|
*/
|
||||||
@@ -125,7 +128,7 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register the packet adapter with ProtocolLib.
|
* Register the handle adapter with ProtocolLib.
|
||||||
*/
|
*/
|
||||||
public final void register() {
|
public final void register() {
|
||||||
if (!ProtocolLibrary.getProtocolManager().getPacketListeners().contains(this)) {
|
if (!ProtocolLibrary.getProtocolManager().getPacketListeners().contains(this)) {
|
||||||
@@ -134,7 +137,7 @@ public abstract class AbstractPacketAdapter extends PacketAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get if the packet adapter should be loaded last.
|
* Get if the handle adapter should be loaded last.
|
||||||
*
|
*
|
||||||
* @return If post load.
|
* @return If post load.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,54 +1,652 @@
|
|||||||
package com.willfp.eco.core;
|
package com.willfp.eco.core;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.command.CommandBase;
|
||||||
|
import com.willfp.eco.core.command.PluginCommandBase;
|
||||||
|
import com.willfp.eco.core.command.impl.PluginCommand;
|
||||||
|
import com.willfp.eco.core.config.ConfigType;
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config;
|
||||||
|
import com.willfp.eco.core.config.interfaces.LoadableConfig;
|
||||||
|
import com.willfp.eco.core.config.updating.ConfigHandler;
|
||||||
|
import com.willfp.eco.core.data.ExtendedPersistentDataContainer;
|
||||||
|
import com.willfp.eco.core.data.PlayerProfile;
|
||||||
|
import com.willfp.eco.core.data.ServerProfile;
|
||||||
|
import com.willfp.eco.core.data.keys.PersistentDataKey;
|
||||||
|
import com.willfp.eco.core.drops.DropQueue;
|
||||||
|
import com.willfp.eco.core.entities.ai.EntityController;
|
||||||
|
import com.willfp.eco.core.events.EventManager;
|
||||||
|
import com.willfp.eco.core.extensions.ExtensionLoader;
|
||||||
|
import com.willfp.eco.core.factory.MetadataValueFactory;
|
||||||
|
import com.willfp.eco.core.factory.NamespacedKeyFactory;
|
||||||
|
import com.willfp.eco.core.factory.RunnableFactory;
|
||||||
|
import com.willfp.eco.core.fast.FastItemStack;
|
||||||
|
import com.willfp.eco.core.gui.menu.Menu;
|
||||||
|
import com.willfp.eco.core.gui.menu.MenuBuilder;
|
||||||
|
import com.willfp.eco.core.gui.menu.MenuType;
|
||||||
|
import com.willfp.eco.core.gui.slot.SlotBuilder;
|
||||||
|
import com.willfp.eco.core.gui.slot.functional.SlotProvider;
|
||||||
|
import com.willfp.eco.core.items.TestableItem;
|
||||||
|
import com.willfp.eco.core.packet.Packet;
|
||||||
|
import com.willfp.eco.core.placeholder.context.PlaceholderContext;
|
||||||
|
import com.willfp.eco.core.proxy.ProxyFactory;
|
||||||
|
import com.willfp.eco.core.scheduling.Scheduler;
|
||||||
|
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
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.LivingEntity;
|
||||||
|
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()
|
||||||
*/
|
*/
|
||||||
public final class Eco {
|
@ApiStatus.Internal
|
||||||
/**
|
public interface Eco {
|
||||||
* Instance of eco handler.
|
|
||||||
*/
|
|
||||||
@ApiStatus.Internal
|
|
||||||
private static Handler handler;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the handler.
|
* Create a scheduler.
|
||||||
* @param handler The handler.
|
|
||||||
*/
|
|
||||||
@ApiStatus.Internal
|
|
||||||
public static void setHandler(@NotNull final Handler handler) {
|
|
||||||
Validate.isTrue(Eco.handler == null, "Already initialized!");
|
|
||||||
|
|
||||||
Eco.handler = handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the instance of the eco handler.
|
|
||||||
* <p>
|
|
||||||
* The handler is, in essence, a way to interface between the eco-api
|
|
||||||
* frontend module, and the eco-backend implementations.
|
|
||||||
* <p>
|
|
||||||
* There shouldn't really be any reason to ever use the handler
|
|
||||||
* in your own plugins, and you are likely to break things. All parts of
|
|
||||||
* the handler are abstracted into logically named parts of the API.
|
|
||||||
* <p>
|
|
||||||
* In versions of eco before 6.12.0, the handler was considered part of
|
|
||||||
* the eco API, however it has since been moved into an internal component
|
|
||||||
* that shouldn't be used in your plugins.
|
|
||||||
*
|
*
|
||||||
|
* @param plugin The plugin.
|
||||||
|
* @return The scheduler.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
Scheduler createScheduler(@NotNull EcoPlugin plugin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an event manager.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin.F
|
||||||
|
* @return The event manager.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
EventManager createEventManager(@NotNull EcoPlugin plugin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a NamespacedKey factory.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin.
|
||||||
|
* @return The factory.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
NamespacedKeyFactory createNamespacedKeyFactory(@NotNull EcoPlugin plugin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a MetadataValue factory.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin.
|
||||||
|
* @return The factory.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
MetadataValueFactory createMetadataValueFactory(@NotNull EcoPlugin plugin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a Runnable factory.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin.
|
||||||
|
* @return The factory.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
RunnableFactory createRunnableFactory(@NotNull EcoPlugin plugin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an ExtensionLoader.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin.
|
||||||
|
* @return The factory.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
ExtensionLoader createExtensionLoader(@NotNull EcoPlugin plugin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a config handler.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin.
|
||||||
* @return The handler.
|
* @return The handler.
|
||||||
*/
|
*/
|
||||||
|
@NotNull
|
||||||
|
ConfigHandler createConfigHandler(@NotNull EcoPlugin plugin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a logger.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin.
|
||||||
|
* @return The logger.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
Logger createLogger(@NotNull EcoPlugin plugin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get NOOP logger.
|
||||||
|
*
|
||||||
|
* @return The logger.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
Logger getNOOPLogger();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a PAPI integration.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin.
|
||||||
|
*/
|
||||||
|
void createPAPIIntegration(@NotNull EcoPlugin plugin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a proxy factory.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin.
|
||||||
|
* @return The factory.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
ProxyFactory createProxyFactory(@NotNull EcoPlugin plugin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get eco Spigot plugin.
|
||||||
|
*
|
||||||
|
* @return The plugin.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
EcoPlugin getEcoPlugin();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create PluginCommandBase implementation of {@link PluginCommand}.
|
||||||
|
*
|
||||||
|
* @param parentDelegate the enclosing class of this implementation.
|
||||||
|
* @param plugin the plugin.
|
||||||
|
* @param name the name of the command.
|
||||||
|
* @param permission the permission of the command.
|
||||||
|
* @param playersOnly if the command is players only.
|
||||||
|
* @return The PluginCommandBase implementation
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
PluginCommandBase createPluginCommand(@NotNull PluginCommandBase parentDelegate,
|
||||||
|
@NotNull EcoPlugin plugin,
|
||||||
|
@NotNull String name,
|
||||||
|
@NotNull String permission,
|
||||||
|
boolean playersOnly);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create CommandBase implementation of {@link com.willfp.eco.core.command.impl.Subcommand Subcommand}.
|
||||||
|
*
|
||||||
|
* @param parentDelegate the enclosing class of this implementation.
|
||||||
|
* @param plugin the plugin.
|
||||||
|
* @param name the name of the command.
|
||||||
|
* @param permission the permission of the command.
|
||||||
|
* @param playersOnly if the command is players only.
|
||||||
|
* @return The CommandBase implementation
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
CommandBase createSubcommand(@NotNull CommandBase parentDelegate,
|
||||||
|
@NotNull EcoPlugin plugin,
|
||||||
|
@NotNull String name,
|
||||||
|
@NotNull String permission,
|
||||||
|
boolean playersOnly);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updatable config.
|
||||||
|
*
|
||||||
|
* @param configName The name of the config
|
||||||
|
* @param plugin The plugin.
|
||||||
|
* @param subDirectoryPath The subdirectory path.
|
||||||
|
* @param source The class that owns the resource.
|
||||||
|
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||||
|
* @param type The config type.
|
||||||
|
* @param updateBlacklist Substring of keys to not add/remove keys for.
|
||||||
|
* @param requiresChangesToSave If the config must be changed in order to save the config.
|
||||||
|
* @return The config implementation.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
LoadableConfig createUpdatableConfig(@NotNull String configName,
|
||||||
|
@NotNull PluginLike plugin,
|
||||||
|
@NotNull String subDirectoryPath,
|
||||||
|
@NotNull Class<?> source,
|
||||||
|
boolean removeUnused,
|
||||||
|
@NotNull ConfigType type,
|
||||||
|
boolean requiresChangesToSave,
|
||||||
|
@NotNull String... updateBlacklist);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loadable config.
|
||||||
|
*
|
||||||
|
* @param configName The name of the config
|
||||||
|
* @param plugin The plugin.
|
||||||
|
* @param subDirectoryPath The subdirectory path.
|
||||||
|
* @param source The class that owns the resource.
|
||||||
|
* @param type The config type.
|
||||||
|
* @param requiresChangesToSave If the config must be changed in order to save the config.
|
||||||
|
* @return The config implementation.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
LoadableConfig createLoadableConfig(@NotNull String configName,
|
||||||
|
@NotNull PluginLike plugin,
|
||||||
|
@NotNull String subDirectoryPath,
|
||||||
|
@NotNull Class<?> source,
|
||||||
|
@NotNull ConfigType type,
|
||||||
|
boolean requiresChangesToSave);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create config.
|
||||||
|
*
|
||||||
|
* @param config The handle.
|
||||||
|
* @return The config implementation.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
Config wrapConfigurationSection(@NotNull ConfigurationSection config);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create config.
|
||||||
|
*
|
||||||
|
* @param values The values.
|
||||||
|
* @param type The config type.
|
||||||
|
* @return The config implementation.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
Config createConfig(@NotNull Map<String, Object> values,
|
||||||
|
@NotNull ConfigType type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create config.
|
||||||
|
*
|
||||||
|
* @param contents The file contents.
|
||||||
|
* @param type The type.
|
||||||
|
* @return The config implementation.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
Config createConfig(@NotNull String contents,
|
||||||
|
@NotNull ConfigType type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a Drop Queue.
|
||||||
|
*
|
||||||
|
* @param player The player.
|
||||||
|
* @return The drop queue.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
DropQueue createDropQueue(@NotNull Player player);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create slot builder.
|
||||||
|
*
|
||||||
|
* @param provider The provider.
|
||||||
|
* @return The builder.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
SlotBuilder createSlotBuilder(@NotNull SlotProvider provider);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create menu builder.
|
||||||
|
*
|
||||||
|
* @param rows The amount of rows.
|
||||||
|
* @param type The type.
|
||||||
|
* @return The builder.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
MenuBuilder createMenuBuilder(int rows,
|
||||||
|
@NotNull MenuType type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Combine the state of two menus together.
|
||||||
|
*
|
||||||
|
* @param base The base menu.
|
||||||
|
* @param additional The additional state.
|
||||||
|
* @return The menu.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
Menu blendMenuState(@NotNull Menu base,
|
||||||
|
@NotNull Menu additional);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean up ClassLoader (etc.) to allow PlugMan support.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin to clean up.
|
||||||
|
*/
|
||||||
|
void clean(@NotNull EcoPlugin plugin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add new plugin.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin.
|
||||||
|
*/
|
||||||
|
void addNewPlugin(@NotNull EcoPlugin plugin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get plugin by name.
|
||||||
|
*
|
||||||
|
* @param name The name.
|
||||||
|
* @return The plugin.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
EcoPlugin getPluginByName(@NotNull String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all loaded eco plugins.
|
||||||
|
*
|
||||||
|
* @return A list of plugin names in lowercase.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
List<String> getLoadedPlugins();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a FastItemStack.
|
||||||
|
*
|
||||||
|
* @param itemStack The base ItemStack.
|
||||||
|
* @return The FastItemStack.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
FastItemStack createFastItemStack(@NotNull ItemStack itemStack);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register bStats metrics.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin.
|
||||||
|
*/
|
||||||
|
void registerBStats(@NotNull EcoPlugin plugin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Adventure audiences.
|
||||||
|
*
|
||||||
|
* @return The audiences.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
BukkitAudiences getAdventure();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a persistent data key to be stored.
|
||||||
|
*
|
||||||
|
* @param key The key.
|
||||||
|
*/
|
||||||
|
void registerPersistentKey(@NotNull PersistentDataKey<?> key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all registered keys.
|
||||||
|
*
|
||||||
|
* @return The keys.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
Set<PersistentDataKey<?>> getRegisteredPersistentDataKeys();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load a player profile.
|
||||||
|
*
|
||||||
|
* @param uuid The UUID.
|
||||||
|
* @return The profile.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
PlayerProfile loadPlayerProfile(@NotNull UUID uuid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the server profile.
|
||||||
|
*
|
||||||
|
* @return The profile.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
ServerProfile getServerProfile();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create dummy entity - never spawned, exists purely in code.
|
||||||
|
*
|
||||||
|
* @param location The location.
|
||||||
|
* @return The entity.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
Entity createDummyEntity(@NotNull Location location);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a {@link NamespacedKey} quickly
|
||||||
|
* <p>
|
||||||
|
* Bypasses the constructor, allowing for the creation of invalid keys, therefore this is
|
||||||
|
* considered unsafe and should only be called after the key has been confirmed to be valid.
|
||||||
|
*
|
||||||
|
* @param namespace The namespace.
|
||||||
|
* @param key The key.
|
||||||
|
* @return The key.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
NamespacedKey createNamespacedKey(@NotNull String namespace,
|
||||||
|
@NotNull String key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return or get props for a plugin.
|
||||||
|
*
|
||||||
|
* @param existing The existing constructor props.
|
||||||
|
* @param plugin The plugin.
|
||||||
|
* @return The props.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
PluginProps getProps(@Nullable PluginProps existing,
|
||||||
|
@NotNull Class<? extends EcoPlugin> plugin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format a string with MiniMessage.
|
||||||
|
*
|
||||||
|
* @param message The message.
|
||||||
|
* @return The formatted string.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
String formatMiniMessage(@NotNull String message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create controlled entity from a mob.
|
||||||
|
*
|
||||||
|
* @param mob The mob.
|
||||||
|
* @param <T> The mob type.
|
||||||
|
* @return The controlled entity.
|
||||||
|
*/
|
||||||
|
@NotNull <T extends Mob> EntityController<T> createEntityController(@NotNull T mob);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adapt base PDC to extended PDC.
|
||||||
|
*
|
||||||
|
* @param container The container.
|
||||||
|
* @return The extended container.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
ExtendedPersistentDataContainer adaptPdc(@NotNull PersistentDataContainer container);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new PDC.
|
||||||
|
*
|
||||||
|
* @return The container.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
PersistentDataContainer newPdc();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get item from SNBT.
|
||||||
|
*
|
||||||
|
* @param snbt The NBT string.
|
||||||
|
* @return The ItemStack, or null if invalid.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
ItemStack fromSNBT(@NotNull String snbt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert item to SNBT.
|
||||||
|
*
|
||||||
|
* @param itemStack The item.
|
||||||
|
* @return The NBT string.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
String toSNBT(@NotNull ItemStack itemStack);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make TestableItem from SNBT.
|
||||||
|
*
|
||||||
|
* @param snbt The NBT string.
|
||||||
|
* @return The TestableItem.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
TestableItem testableItemFromSNBT(@NotNull String snbt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the texture of a skull.
|
||||||
|
*
|
||||||
|
* @param meta The skull meta.
|
||||||
|
* @return The texture, or null if not found.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
String getSkullTexture(@NotNull SkullMeta meta);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the texture of a skull.
|
||||||
|
*
|
||||||
|
* @param meta The skull meta.
|
||||||
|
* @param base64 The texture.
|
||||||
|
*/
|
||||||
|
void setSkullTexture(@NotNull SkullMeta meta,
|
||||||
|
@NotNull String base64);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current server TPS.
|
||||||
|
*
|
||||||
|
* @return The TPS.
|
||||||
|
*/
|
||||||
|
double getTPS();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluate an expression.
|
||||||
|
*
|
||||||
|
* @param expression The expression.
|
||||||
|
* @param context The context.
|
||||||
|
* @return The value of the expression, or null if invalid.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
Double evaluate(@NotNull String expression,
|
||||||
|
@NotNull PlaceholderContext context);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the menu a player currently has open.
|
||||||
|
*
|
||||||
|
* @param player The player.
|
||||||
|
* @return The menu, or null if no menu open.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
Menu getOpenMenu(@NotNull Player player);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sync commands.
|
||||||
|
*/
|
||||||
|
void syncCommands();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregister a command.
|
||||||
|
*
|
||||||
|
* @param command The command.
|
||||||
|
*/
|
||||||
|
void unregisterCommand(@NotNull PluginCommandBase command);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a packet.
|
||||||
|
*
|
||||||
|
* @param player The player.
|
||||||
|
* @param packet The packet.
|
||||||
|
*/
|
||||||
|
void sendPacket(@NotNull Player player,
|
||||||
|
@NotNull Packet packet);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translate placeholders in a string.
|
||||||
|
*
|
||||||
|
* @param text The text.
|
||||||
|
* @param context The context.
|
||||||
|
* @return The translated text.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
String translatePlaceholders(@NotNull String text,
|
||||||
|
@NotNull PlaceholderContext context);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of a placeholder.
|
||||||
|
*
|
||||||
|
* @param plugin The plugin that owns the placeholder.
|
||||||
|
* @param args The placeholder arguments.
|
||||||
|
* @param context The context.
|
||||||
|
* @return The value, or null if invalid.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
String getPlaceholderValue(@Nullable EcoPlugin plugin,
|
||||||
|
@NotNull String args,
|
||||||
|
@NotNull PlaceholderContext context);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a client-side entity display name.
|
||||||
|
*
|
||||||
|
* @param entity The entity.
|
||||||
|
* @param player The player.
|
||||||
|
* @param name The display name.
|
||||||
|
* @param visible If the display name should be forcibly visible.
|
||||||
|
*/
|
||||||
|
void setClientsideDisplayName(@NotNull LivingEntity entity,
|
||||||
|
@NotNull Player player,
|
||||||
|
@NotNull Component name,
|
||||||
|
boolean visible);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 static Handler getHandler() {
|
static Eco get() {
|
||||||
return handler;
|
return Instance.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Eco() {
|
/**
|
||||||
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
* 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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,234 +0,0 @@
|
|||||||
package com.willfp.eco.core;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.config.updating.ConfigHandler;
|
|
||||||
import com.willfp.eco.core.config.wrapper.ConfigFactory;
|
|
||||||
import com.willfp.eco.core.data.keys.KeyRegistry;
|
|
||||||
import com.willfp.eco.core.data.PlayerProfileHandler;
|
|
||||||
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.fast.FastItemStack;
|
|
||||||
import com.willfp.eco.core.gui.GUIFactory;
|
|
||||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderIntegration;
|
|
||||||
import com.willfp.eco.core.proxy.Cleaner;
|
|
||||||
import com.willfp.eco.core.proxy.ProxyFactory;
|
|
||||||
import com.willfp.eco.core.requirement.RequirementFactory;
|
|
||||||
import com.willfp.eco.core.scheduling.Scheduler;
|
|
||||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see Eco#getHandler()
|
|
||||||
*/
|
|
||||||
@ApiStatus.Internal
|
|
||||||
public interface Handler {
|
|
||||||
/**
|
|
||||||
* Create a scheduler.
|
|
||||||
*
|
|
||||||
* @param plugin The plugin.
|
|
||||||
* @return The scheduler.
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
Scheduler createScheduler(@NotNull EcoPlugin plugin);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an event manager.
|
|
||||||
*
|
|
||||||
* @param plugin The plugin.
|
|
||||||
* @return The event manager.
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
EventManager createEventManager(@NotNull EcoPlugin plugin);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a NamespacedKey factory.
|
|
||||||
*
|
|
||||||
* @param plugin The plugin.
|
|
||||||
* @return The factory.
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
NamespacedKeyFactory createNamespacedKeyFactory(@NotNull EcoPlugin plugin);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a MetadataValue factory.
|
|
||||||
*
|
|
||||||
* @param plugin The plugin.
|
|
||||||
* @return The factory.
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
MetadataValueFactory createMetadataValueFactory(@NotNull EcoPlugin plugin);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a Runnable factory.
|
|
||||||
*
|
|
||||||
* @param plugin The plugin.
|
|
||||||
* @return The factory.
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
RunnableFactory createRunnableFactory(@NotNull EcoPlugin plugin);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an ExtensionLoader.
|
|
||||||
*
|
|
||||||
* @param plugin The plugin.
|
|
||||||
* @return The factory.
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
ExtensionLoader createExtensionLoader(@NotNull EcoPlugin plugin);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a config handler.
|
|
||||||
*
|
|
||||||
* @param plugin The plugin.
|
|
||||||
* @return The handler.
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
ConfigHandler createConfigHandler(@NotNull EcoPlugin plugin);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a logger.
|
|
||||||
*
|
|
||||||
* @param plugin The plugin.
|
|
||||||
* @return The logger.
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
Logger createLogger(@NotNull EcoPlugin plugin);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a PAPI integration.
|
|
||||||
*
|
|
||||||
* @param plugin The plugin.
|
|
||||||
* @return The integration.
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
PlaceholderIntegration createPAPIIntegration(@NotNull EcoPlugin plugin);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a proxy factory.
|
|
||||||
*
|
|
||||||
* @param plugin The plugin.
|
|
||||||
* @return The factory.
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
ProxyFactory createProxyFactory(@NotNull EcoPlugin plugin);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get eco Spigot plugin.
|
|
||||||
*
|
|
||||||
* @return The plugin.
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
EcoPlugin getEcoPlugin();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get config factory.
|
|
||||||
*
|
|
||||||
* @return The factory.
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
ConfigFactory getConfigFactory();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get drop queue factory.
|
|
||||||
*
|
|
||||||
* @return The factory.
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
DropQueueFactory getDropQueueFactory();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get GUI factory.
|
|
||||||
*
|
|
||||||
* @return The factory.
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
GUIFactory getGUIFactory();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get cleaner.
|
|
||||||
*
|
|
||||||
* @return The cleaner.
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
Cleaner getCleaner();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add new plugin.
|
|
||||||
*
|
|
||||||
* @param plugin The plugin.
|
|
||||||
*/
|
|
||||||
void addNewPlugin(@NotNull EcoPlugin plugin);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get plugin by name.
|
|
||||||
*
|
|
||||||
* @param name The name.
|
|
||||||
* @return The plugin.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
EcoPlugin getPluginByName(@NotNull String name);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all loaded eco plugins.
|
|
||||||
*
|
|
||||||
* @return A list of plugin names in lowercase.
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
List<String> getLoadedPlugins();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a FastItemStack.
|
|
||||||
*
|
|
||||||
* @param itemStack The base ItemStack.
|
|
||||||
* @return The FastItemStack.
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
FastItemStack createFastItemStack(@NotNull ItemStack itemStack);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register bStats metrics.
|
|
||||||
*
|
|
||||||
* @param plugin The plugin.
|
|
||||||
*/
|
|
||||||
void registerBStats(@NotNull EcoPlugin plugin);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the requirement factory.
|
|
||||||
*
|
|
||||||
* @return The factory.
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
RequirementFactory getRequirementFactory();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Adventure audiences.
|
|
||||||
*
|
|
||||||
* @return The audiences.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
BukkitAudiences getAdventure();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the key registry.
|
|
||||||
*
|
|
||||||
* @return The registry.
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
KeyRegistry getKeyRegistry();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the PlayerProfile handler.
|
|
||||||
*
|
|
||||||
* @return The handler.
|
|
||||||
*/
|
|
||||||
PlayerProfileHandler getPlayerProfileHandler();
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.willfp.eco.core;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks a position in a lifecycle (e.g. enable, reload, etc).
|
||||||
|
*/
|
||||||
|
public enum LifecyclePosition {
|
||||||
|
/**
|
||||||
|
* Run at the start of the lifecycle.
|
||||||
|
*/
|
||||||
|
START,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run at the end of the lifecycle.
|
||||||
|
*/
|
||||||
|
END
|
||||||
|
}
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
package com.willfp.eco.core;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Quick DI class to manage passing eco plugins.
|
|
||||||
*
|
|
||||||
* @param <T> The eco plugin type.
|
|
||||||
*/
|
|
||||||
public abstract class PluginDependent<T extends EcoPlugin> {
|
|
||||||
/**
|
|
||||||
* The {@link EcoPlugin} that is stored.
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
private final T plugin;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pass an {@link EcoPlugin} in order to interface with it.
|
|
||||||
*
|
|
||||||
* @param plugin The plugin to manage.
|
|
||||||
*/
|
|
||||||
protected PluginDependent(@NotNull final T plugin) {
|
|
||||||
this.plugin = plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the plugin.
|
|
||||||
*
|
|
||||||
* @return The plugin.
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
protected T getPlugin() {
|
|
||||||
return this.plugin;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
package com.willfp.eco.core;
|
package com.willfp.eco.core;
|
||||||
|
|
||||||
import com.willfp.eco.core.config.updating.ConfigHandler;
|
import com.willfp.eco.core.config.updating.ConfigHandler;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents any class that acts like a plugin, for example {@link EcoPlugin}
|
* Represents any class that acts like a plugin, for example {@link EcoPlugin}
|
||||||
@@ -12,12 +15,13 @@ import java.io.File;
|
|||||||
*/
|
*/
|
||||||
public interface PluginLike {
|
public interface PluginLike {
|
||||||
/**
|
/**
|
||||||
* Get the data folder of the object.
|
* Get the data folder.
|
||||||
* <p>
|
* <p>
|
||||||
* Returns the plugin data folder for a plugin, or the extension's parent plugin's folder
|
* Returns the plugin data folder for a plugin, or the extension's parent plugin's folder
|
||||||
*
|
*
|
||||||
* @return The data folder.
|
* @return The data folder.
|
||||||
*/
|
*/
|
||||||
|
@NotNull
|
||||||
File getDataFolder();
|
File getDataFolder();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -25,5 +29,24 @@ public interface PluginLike {
|
|||||||
*
|
*
|
||||||
* @return The config handler.
|
* @return The config handler.
|
||||||
*/
|
*/
|
||||||
|
@NotNull
|
||||||
ConfigHandler getConfigHandler();
|
ConfigHandler getConfigHandler();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the logger.
|
||||||
|
*
|
||||||
|
* @return The logger.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
Logger getLogger();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the actual file.
|
||||||
|
*
|
||||||
|
* @return The file, i.e. the jar file.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
default File getFile() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
325
eco-api/src/main/java/com/willfp/eco/core/PluginProps.java
Normal file
325
eco-api/src/main/java/com/willfp/eco/core/PluginProps.java
Normal file
@@ -0,0 +1,325 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The environment variables.
|
||||||
|
*/
|
||||||
|
private final Map<String, String> environment = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the plugin uses reflective reload.
|
||||||
|
*/
|
||||||
|
private boolean usesReflectiveReload = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an environment variable.
|
||||||
|
*
|
||||||
|
* @param name The name.
|
||||||
|
* @return The value of the variable.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public String getEnvironmentVariable(@NotNull final String name) {
|
||||||
|
return environment.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set an environment variable.
|
||||||
|
*
|
||||||
|
* @param name The name.
|
||||||
|
* @param value The value.
|
||||||
|
*/
|
||||||
|
public void setEnvironmentVariable(@NotNull final String name,
|
||||||
|
@NotNull final String value) {
|
||||||
|
environment.put(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set if the plugin uses reflective reload.
|
||||||
|
*
|
||||||
|
* @return If the plugin uses reflective reload.
|
||||||
|
*/
|
||||||
|
public boolean isUsingReflectiveReload() {
|
||||||
|
return usesReflectiveReload;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set if the plugin uses reflective reload.
|
||||||
|
*
|
||||||
|
* @param usesReflectiveReload If the plugin uses reflective reload.
|
||||||
|
*/
|
||||||
|
public void setUsesReflectiveReload(final boolean usesReflectiveReload) {
|
||||||
|
this.usesReflectiveReload = usesReflectiveReload;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure that all required props have been set.
|
||||||
|
*/
|
||||||
|
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.
|
||||||
|
* <p>
|
||||||
|
* Marked as internal as this method will break whenever the properties themselves
|
||||||
|
* are updated (e.g. if a new property is added) - so to prevent any potential
|
||||||
|
* backwards-compatibility bugs, this method cannot be invoked outside eco itself.
|
||||||
|
*
|
||||||
|
* @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.
|
||||||
|
* @deprecated Moving to force the usage of eco.yml.
|
||||||
|
*/
|
||||||
|
@Deprecated(since = "6.53.0")
|
||||||
|
static PluginProps createSimple(final int resourceId,
|
||||||
|
final int bStatsId,
|
||||||
|
@NotNull final String proxyPackage,
|
||||||
|
@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,6 +1,5 @@
|
|||||||
package com.willfp.eco.core;
|
package com.willfp.eco.core;
|
||||||
|
|
||||||
import com.willfp.eco.core.integrations.economy.EconomyManager;
|
|
||||||
import com.willfp.eco.core.proxy.ProxyConstants;
|
import com.willfp.eco.core.proxy.ProxyConstants;
|
||||||
import com.willfp.eco.util.ClassUtils;
|
import com.willfp.eco.util.ClassUtils;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -26,32 +25,81 @@ 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 have vault installed.
|
* Requires the server to be running an implementation of paper.
|
||||||
*
|
|
||||||
* @deprecated Use {@link EconomyManager#hasRegistrations()} instead.
|
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
public static final Prerequisite HAS_PROTOCOLLIB = new Prerequisite(
|
||||||
public static final Prerequisite HAS_VAULT = new Prerequisite(
|
() -> ClassUtils.exists("com.comphenix.protocol.events.PacketAdapter"),
|
||||||
() -> ClassUtils.exists("net.milkbowl.vault.economy.Economy"),
|
"Requires server to have ProtocolLib"
|
||||||
"Requires server to have vault"
|
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Requires the server to be running 1.17.
|
* Requires the server to be running 1.21.
|
||||||
*/
|
*/
|
||||||
public static final Prerequisite HAS_1_17 = new Prerequisite(
|
public static final Prerequisite HAS_1_21 = new Prerequisite(
|
||||||
() -> ProxyConstants.NMS_VERSION.contains("17"),
|
() -> ProxyConstants.NMS_VERSION.contains("1_21"),
|
||||||
"Requires server to be running 1.17+"
|
"Requires server to be running 1.21+"
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requires the server to be running 1.20.5.
|
||||||
|
*/
|
||||||
|
public static final Prerequisite HAS_1_20_5 = new Prerequisite(
|
||||||
|
() -> (ProxyConstants.NMS_VERSION.contains("1_20_") && !ProxyConstants.NMS_VERSION.contains("R"))
|
||||||
|
|| HAS_1_21.isMet(),
|
||||||
|
"Requires server to be running 1.20.5+"
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requires the server to be running 1.20.3.
|
||||||
|
*/
|
||||||
|
public static final Prerequisite HAS_1_20_3 = new Prerequisite(
|
||||||
|
() -> ProxyConstants.NMS_VERSION.contains("20_R3") || HAS_1_20_5.isMet(),
|
||||||
|
"Requires server to be running 1.20.3+"
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requires the server to be running 1.20.
|
||||||
|
*/
|
||||||
|
public static final Prerequisite HAS_1_20 = new Prerequisite(
|
||||||
|
() -> ProxyConstants.NMS_VERSION.contains("20") || HAS_1_20_3.isMet(),
|
||||||
|
"Requires server to be running 1.20+"
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requires the server to be running 1.19.4.
|
||||||
|
*/
|
||||||
|
public static final Prerequisite HAS_1_19_4 = new Prerequisite(
|
||||||
|
() -> ProxyConstants.NMS_VERSION.contains("19_R3") || HAS_1_20.isMet(),
|
||||||
|
"Requires server to be running 1.19.4+"
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requires the server to be running 1.19.
|
||||||
|
*/
|
||||||
|
public static final Prerequisite HAS_1_19 = new Prerequisite(
|
||||||
|
() -> ProxyConstants.NMS_VERSION.contains("19") || HAS_1_20.isMet(),
|
||||||
|
"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 an implementation of BungeeCord.
|
* Requires the server to be running an implementation of BungeeCord.
|
||||||
|
*
|
||||||
|
* @deprecated This will never return true.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(since = "6.49.0", forRemoval = true)
|
||||||
public static final Prerequisite HAS_BUNGEECORD = new Prerequisite(
|
public static final Prerequisite HAS_BUNGEECORD = new Prerequisite(
|
||||||
() -> ClassUtils.exists("net.md_5.bungee.api.event.ServerConnectedEvent"),
|
() -> ClassUtils.exists("net.md_5.bungee.api.event.ServerConnectedEvent"),
|
||||||
"Requires server to be running BungeeCord (or a fork)"
|
"Requires server to be running BungeeCord (or a fork)"
|
||||||
@@ -59,7 +107,10 @@ public class Prerequisite {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Requires the server to be running an implementation of Velocity.
|
* Requires the server to be running an implementation of Velocity.
|
||||||
|
*
|
||||||
|
* @deprecated This will never return true.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(since = "6.49.0", forRemoval = true)
|
||||||
public static final Prerequisite HAS_VELOCITY = new Prerequisite(
|
public static final Prerequisite HAS_VELOCITY = new Prerequisite(
|
||||||
() -> ClassUtils.exists("com.velocitypowered.api.event.player.ServerConnectedEvent"),
|
() -> ClassUtils.exists("com.velocitypowered.api.event.player.ServerConnectedEvent"),
|
||||||
"Requires server to be running Velocity (or a fork)"
|
"Requires server to be running Velocity (or a fork)"
|
||||||
|
|||||||
@@ -1,24 +1,37 @@
|
|||||||
package com.willfp.eco.core.command;
|
package com.willfp.eco.core.command;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.OfflinePlayer;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for all command implementations.
|
* Generic interface for commands.
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("null")
|
||||||
public interface CommandBase {
|
public interface CommandBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get command name.
|
* Get command name.
|
||||||
*
|
*
|
||||||
* @return The name.
|
* @return The name.
|
||||||
*/
|
*/
|
||||||
String getName();
|
@NotNull String getName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get command permission.
|
* Get command permission.
|
||||||
*
|
*
|
||||||
* @return The permission.
|
* @return The permission.
|
||||||
*/
|
*/
|
||||||
String getPermission();
|
@NotNull String getPermission();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If only players can execute the command.
|
* If only players can execute the command.
|
||||||
@@ -33,33 +46,237 @@ public interface CommandBase {
|
|||||||
* @param command The subcommand.
|
* @param command The subcommand.
|
||||||
* @return The parent command.
|
* @return The parent command.
|
||||||
*/
|
*/
|
||||||
CommandBase addSubcommand(@NotNull CommandBase command);
|
@NotNull CommandBase addSubcommand(@NotNull CommandBase command);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the handler.
|
* Get the subcommands of the command.
|
||||||
*
|
*
|
||||||
* @return The handler.
|
* @return The subcommands.
|
||||||
*/
|
*/
|
||||||
CommandHandler getHandler();
|
@NotNull List<CommandBase> getSubcommands();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the handler.
|
* Intended for returning the enclosing CommandBase,
|
||||||
|
* when this instance is serving as the delegate command base.
|
||||||
*
|
*
|
||||||
* @param handler The handler.
|
* @return the wrapping object of this delegate.
|
||||||
*/
|
*/
|
||||||
void setHandler(@NotNull CommandHandler handler);
|
default @NotNull CommandBase getWrapped() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the tab completer.
|
* Handle command execution.
|
||||||
|
* <p>
|
||||||
|
* This will always be called on command execution.
|
||||||
*
|
*
|
||||||
* @return The tab completer.
|
* @param sender The sender.
|
||||||
|
* @param args The args.
|
||||||
|
* @throws NotificationException naturally, this is handled as a part of the command system.
|
||||||
*/
|
*/
|
||||||
TabCompleteHandler getTabCompleter();
|
default void onExecute(@NotNull final CommandSender sender, @NotNull final List<String> args) throws NotificationException {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the tab completer.
|
* Handle command execution from players.
|
||||||
|
* <p>
|
||||||
|
* This will only be called if the sender is a player.
|
||||||
*
|
*
|
||||||
* @param handler The handler.
|
* @param sender The sender.
|
||||||
|
* @param args The args.
|
||||||
|
* @throws NotificationException naturally, this is handled as a part of the command system.
|
||||||
*/
|
*/
|
||||||
void setTabCompleter(@NotNull TabCompleteHandler handler);
|
default void onExecute(@NotNull final Player sender, @NotNull final List<String> args) throws NotificationException {
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle tab completion.
|
||||||
|
* <p>
|
||||||
|
* This will always be called on tab completion.
|
||||||
|
*
|
||||||
|
* @param sender The sender.
|
||||||
|
* @param args The args.
|
||||||
|
* @return The results.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
default List<String> tabComplete(@NotNull final CommandSender sender, @NotNull final List<String> args) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle tab completion.
|
||||||
|
* <p>
|
||||||
|
* This will only be called if the sender is a player.
|
||||||
|
*
|
||||||
|
* @param sender The sender.
|
||||||
|
* @param args The args.
|
||||||
|
* @return The results.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
default List<String> tabComplete(@NotNull final Player sender, @NotNull final List<String> args) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws an {@link NotificationException} relating to a specific lang.yml key.
|
||||||
|
* <p>
|
||||||
|
* This is automatically handled with eco, and should not be surrounded by a
|
||||||
|
* try/catch block.
|
||||||
|
*
|
||||||
|
* @param key The lang.yml key for the message to be sent.
|
||||||
|
* @throws NotificationException always.
|
||||||
|
*/
|
||||||
|
default void notify(@NotNull final String key) throws NotificationException {
|
||||||
|
throw new NotificationException(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws an {@link NotificationException} relating to a specific lang.yml key
|
||||||
|
* if the passed object is null.
|
||||||
|
* <p>
|
||||||
|
* This is automatically handled with eco, and should not be surrounded by a
|
||||||
|
* try/catch block.
|
||||||
|
*
|
||||||
|
* @param obj The object to test.
|
||||||
|
* @param key The lang.yml key for the message to be sent.
|
||||||
|
* @param <T> The object type.
|
||||||
|
* @return Returns the object, definitely not-null.
|
||||||
|
* @throws NotificationException If the object is null.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
default <T> T notifyNull(@Nullable final T obj,
|
||||||
|
@NotNull final String key) throws NotificationException {
|
||||||
|
if (Objects.isNull(obj)) {
|
||||||
|
notify(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Objects.requireNonNull(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws an {@link NotificationException} relating to a specific lang.yml key
|
||||||
|
* if the passed object doesn't match the predicate.
|
||||||
|
* <p>
|
||||||
|
* This is automatically handled with eco, and should not be surrounded by a
|
||||||
|
* try/catch block.
|
||||||
|
*
|
||||||
|
* @param obj The object to test.
|
||||||
|
* @param key The lang.yml key for the message to be sent.
|
||||||
|
* @param predicate The predicate to test the object against.
|
||||||
|
* @param <T> The type of the object.
|
||||||
|
* @return Returns the object, definitely not-null.
|
||||||
|
* @throws NotificationException If the object doesn't satisfy the predicate.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
default <T> T notifyFalse(@NotNull final T obj,
|
||||||
|
@NotNull final String key,
|
||||||
|
@NotNull final Predicate<T> predicate) throws NotificationException {
|
||||||
|
notifyFalse(predicate.test(obj), key);
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws an {@link NotificationException} relating to a specific lang.yml key
|
||||||
|
* if a condition is false.
|
||||||
|
* <p>
|
||||||
|
* This is automatically handled with eco, and should not be surrounded by a
|
||||||
|
* try/catch block.
|
||||||
|
*
|
||||||
|
* @param condition The condition to test.
|
||||||
|
* @param key The lang.yml key for the message to be sent.
|
||||||
|
* @return True.
|
||||||
|
* @throws NotificationException If the condition is false.
|
||||||
|
*/
|
||||||
|
default boolean notifyFalse(final boolean condition,
|
||||||
|
@NotNull final String key) throws NotificationException {
|
||||||
|
if (!condition) {
|
||||||
|
notify(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws an {@link NotificationException} relating to a specific lang.yml key
|
||||||
|
* if the passed string doesn't relate to a currently online player.
|
||||||
|
* <p>
|
||||||
|
* This is automatically handled with eco, and should not be surrounded by a
|
||||||
|
* try/catch block.
|
||||||
|
*
|
||||||
|
* @param playerName The player name.
|
||||||
|
* @param key The lang.yml key for the message to be sent.
|
||||||
|
* @return Returns the player, definitely not-null.
|
||||||
|
* @throws NotificationException If the player name is invalid.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
default Player notifyPlayerRequired(@Nullable final String playerName, @NotNull final String key) throws NotificationException {
|
||||||
|
if (playerName == null) {
|
||||||
|
notify(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert playerName != null;
|
||||||
|
|
||||||
|
final Player player = Bukkit.getPlayer(playerName);
|
||||||
|
|
||||||
|
notifyNull(player, key);
|
||||||
|
|
||||||
|
return Objects.requireNonNull(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws an {@link NotificationException} relating to a specific lang.yml key
|
||||||
|
* if the passed string doesn't relate to a player on the server.
|
||||||
|
* <p>
|
||||||
|
* This is automatically handled with eco, and should not be surrounded by a
|
||||||
|
* try/catch block.
|
||||||
|
*
|
||||||
|
* @param playerName The player name.
|
||||||
|
* @param key The lang.yml key for the message to be sent.
|
||||||
|
* @return Returns the offline player, definitely not-null.
|
||||||
|
* @throws NotificationException If the player name is invalid.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
default OfflinePlayer notifyOfflinePlayerRequired(@Nullable final String playerName,
|
||||||
|
@NotNull final String key) throws NotificationException {
|
||||||
|
if (playerName == null) {
|
||||||
|
notify(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert playerName != null;
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation") final OfflinePlayer player = Bukkit.getOfflinePlayer(playerName);
|
||||||
|
|
||||||
|
boolean hasPlayedBefore = player.hasPlayedBefore() || player.isOnline();
|
||||||
|
|
||||||
|
notifyFalse(!hasPlayedBefore, key);
|
||||||
|
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws an exception containing a langYml key if player doesn't have permission.
|
||||||
|
*
|
||||||
|
* @param player The player.
|
||||||
|
* @param permission The permission.
|
||||||
|
* @param key The lang.yml key for the message to be sent.
|
||||||
|
* @return The player.
|
||||||
|
* @throws NotificationException If the player doesn't have the required permission.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
default Player notifyPermissionRequired(@NotNull final Player player,
|
||||||
|
@NotNull final String permission,
|
||||||
|
@NotNull final String key) throws NotificationException {
|
||||||
|
return notifyFalse(player, key, p -> p.hasPermission(permission));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the plugin.
|
||||||
|
*
|
||||||
|
* @return The plugin.
|
||||||
|
*/
|
||||||
|
EcoPlugin getPlugin();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
package com.willfp.eco.core.command;
|
|
||||||
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A command handler handles the actual code for a command.
|
|
||||||
* <p>
|
|
||||||
* The replacement for {@link org.bukkit.command.CommandExecutor#onCommand(CommandSender, Command, String, String[])}
|
|
||||||
* @see CommandBase
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface CommandHandler {
|
|
||||||
/**
|
|
||||||
* The code to be called on execution.
|
|
||||||
*
|
|
||||||
* @param sender The sender.
|
|
||||||
* @param args The arguments.
|
|
||||||
*/
|
|
||||||
void onExecute(@NotNull CommandSender sender,
|
|
||||||
@NotNull List<String> args);
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package com.willfp.eco.core.command;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A notification exception is thrown when {@link org.bukkit.command.CommandSender}s don't
|
||||||
|
* specify valid arguments in commands.
|
||||||
|
* <p>
|
||||||
|
* Methods in eco that throw this will contain automatic handling and thus
|
||||||
|
* should not be surrounded by try / catch blocks.
|
||||||
|
*/
|
||||||
|
public class NotificationException extends Exception {
|
||||||
|
/**
|
||||||
|
* The key for the lang.yml message to be sent.
|
||||||
|
*/
|
||||||
|
private final String key;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a notification exception.
|
||||||
|
*
|
||||||
|
* @param key The lang key of the notification.
|
||||||
|
*/
|
||||||
|
public NotificationException(@NotNull final String key) {
|
||||||
|
super(key);
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the lang key.
|
||||||
|
*
|
||||||
|
* @return The lang key.
|
||||||
|
*/
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package com.willfp.eco.core.command;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plugin command bases can be registered directly with the server,
|
||||||
|
* this essentially functions as the interface that is implemented generically
|
||||||
|
* via {@link com.willfp.eco.core.command.impl.PluginCommand}.
|
||||||
|
*/
|
||||||
|
public interface PluginCommandBase extends CommandBase {
|
||||||
|
/**
|
||||||
|
* Register the PluginCommandBase to the bukkit commandMap.
|
||||||
|
*/
|
||||||
|
void register();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregister the PluginCommandBase from the bukkit commandMap.
|
||||||
|
*/
|
||||||
|
void unregister();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get aliases. Leave null if this command is from plugin.yml.
|
||||||
|
*
|
||||||
|
* @return The aliases.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
default List<String> getAliases() {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get description.
|
||||||
|
*
|
||||||
|
* @return The description.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
default String getDescription() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
package com.willfp.eco.core.command;
|
|
||||||
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A Tab Complete handler handles the actual tab-completion code.
|
|
||||||
* <p>
|
|
||||||
* The replacement for {@link org.bukkit.command.TabCompleter#onTabComplete(CommandSender, Command, String, String[])}
|
|
||||||
* @see CommandBase
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface TabCompleteHandler {
|
|
||||||
/**
|
|
||||||
* Handle Tab Completion.
|
|
||||||
*
|
|
||||||
* @param sender The sender.
|
|
||||||
* @param args The arguments.
|
|
||||||
* @return The tab completion results.
|
|
||||||
*/
|
|
||||||
List<String> tabComplete(@NotNull CommandSender sender,
|
|
||||||
@NotNull List<String> args);
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
package com.willfp.eco.core.command.impl;
|
||||||
|
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.command.PluginIdentifiableCommand;
|
||||||
|
import org.bukkit.command.TabCompleter;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delegates a bukkit command to an eco command (for registrations).
|
||||||
|
*
|
||||||
|
* @deprecated Internal command implementations have been removed from the API.
|
||||||
|
*/
|
||||||
|
@Deprecated(since = "6.49.0", forRemoval = true)
|
||||||
|
public final class DelegatedBukkitCommand extends Command implements TabCompleter, PluginIdentifiableCommand {
|
||||||
|
/**
|
||||||
|
* The delegate command.
|
||||||
|
*/
|
||||||
|
private final PluginCommand delegate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new delegated command.
|
||||||
|
*
|
||||||
|
* @param delegate The delegate.
|
||||||
|
*/
|
||||||
|
public DelegatedBukkitCommand(@NotNull final PluginCommand delegate) {
|
||||||
|
super(delegate.getName());
|
||||||
|
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(@NotNull final CommandSender commandSender,
|
||||||
|
@NotNull final String label,
|
||||||
|
@NotNull final String[] args) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> onTabComplete(@NotNull final CommandSender commandSender,
|
||||||
|
@NotNull final Command command,
|
||||||
|
@NotNull final String label,
|
||||||
|
@NotNull final String[] args) {
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Plugin getPlugin() {
|
||||||
|
return this.delegate.getPlugin();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getPermission() {
|
||||||
|
return this.delegate.getPermission();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return this.delegate.getDescription() == null ? "" : this.delegate.getDescription();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public List<String> getAliases() {
|
||||||
|
return this.delegate.getAliases();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,268 +0,0 @@
|
|||||||
package com.willfp.eco.core.command.impl;
|
|
||||||
|
|
||||||
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.CommandHandler;
|
|
||||||
import com.willfp.eco.core.command.TabCompleteHandler;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.util.StringUtil;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract class for commands that can be handled.
|
|
||||||
* <p>
|
|
||||||
* Handled commands have a method to pass in raw input from bukkit commands
|
|
||||||
* in order to execute the command-specific code. It's essentially an internal
|
|
||||||
* layer, hence why it's a package-private class.
|
|
||||||
*/
|
|
||||||
abstract class HandledCommand extends PluginDependent<EcoPlugin> implements CommandBase {
|
|
||||||
/**
|
|
||||||
* The name of the command.
|
|
||||||
*/
|
|
||||||
private final String name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The permission required to execute the command.
|
|
||||||
* <p>
|
|
||||||
* Written out as a string for flexibility with subclasses.
|
|
||||||
*/
|
|
||||||
private final String permission;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Should the command only be allowed to be executed by players?
|
|
||||||
* <p>
|
|
||||||
* In other worlds, only allowed to be executed by console.
|
|
||||||
*/
|
|
||||||
private final boolean playersOnly;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The actual code to be executed in the command.
|
|
||||||
*/
|
|
||||||
private CommandHandler handler = (sender, args) -> {
|
|
||||||
// Do nothing by default
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The tab completion code to be executed in the command.
|
|
||||||
*/
|
|
||||||
private TabCompleteHandler tabCompleter = (sender, args) -> new ArrayList<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* All subcommands for the command.
|
|
||||||
*/
|
|
||||||
private final List<CommandBase> subcommands;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new command.
|
|
||||||
* <p>
|
|
||||||
* The name cannot be the same as an existing command as this will conflict.
|
|
||||||
*
|
|
||||||
* @param plugin Instance of a plugin.
|
|
||||||
* @param name The name used in execution.
|
|
||||||
* @param permission The permission required to execute the command.
|
|
||||||
* @param playersOnly If only players should be able to execute this command.
|
|
||||||
*/
|
|
||||||
HandledCommand(@NotNull final EcoPlugin plugin,
|
|
||||||
@NotNull final String name,
|
|
||||||
@NotNull final String permission,
|
|
||||||
final boolean playersOnly) {
|
|
||||||
super(plugin);
|
|
||||||
this.name = name;
|
|
||||||
this.permission = permission;
|
|
||||||
this.playersOnly = playersOnly;
|
|
||||||
this.subcommands = new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a subcommand to the command.
|
|
||||||
*
|
|
||||||
* @param subcommand The subcommand.
|
|
||||||
* @return The parent command.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public final CommandBase addSubcommand(@NotNull final CommandBase subcommand) {
|
|
||||||
subcommands.add(subcommand);
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle the command.
|
|
||||||
*
|
|
||||||
* @param sender The sender.
|
|
||||||
* @param args The arguments.
|
|
||||||
*/
|
|
||||||
protected final void handle(@NotNull final CommandSender sender,
|
|
||||||
@NotNull final String[] args) {
|
|
||||||
if (!canExecute(sender, this, this.getPlugin())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.length > 0) {
|
|
||||||
for (CommandBase subcommand : this.getSubcommands()) {
|
|
||||||
if (subcommand.getName().equalsIgnoreCase(args[0])) {
|
|
||||||
if (!canExecute(sender, subcommand, this.getPlugin())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
((HandledCommand) subcommand).handle(sender, Arrays.copyOfRange(args, 1, args.length));
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.getHandler().onExecute(sender, Arrays.asList(args));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle the tab completion.
|
|
||||||
*
|
|
||||||
* @param sender The sender.
|
|
||||||
* @param args The arguments.
|
|
||||||
* @return The tab completion results.
|
|
||||||
*/
|
|
||||||
protected final List<String> handleTabCompletion(@NotNull final CommandSender sender,
|
|
||||||
@NotNull final String[] args) {
|
|
||||||
|
|
||||||
if (!sender.hasPermission(this.getPermission())) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.length == 1) {
|
|
||||||
List<String> completions = new ArrayList<>();
|
|
||||||
|
|
||||||
StringUtil.copyPartialMatches(
|
|
||||||
args[0],
|
|
||||||
this.getSubcommands().stream().map(CommandBase::getName).collect(Collectors.toList()),
|
|
||||||
completions
|
|
||||||
);
|
|
||||||
|
|
||||||
Collections.sort(completions);
|
|
||||||
|
|
||||||
if (!completions.isEmpty()) {
|
|
||||||
return completions;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.length >= 2) {
|
|
||||||
HandledCommand command = null;
|
|
||||||
|
|
||||||
for (CommandBase subcommand : this.getSubcommands()) {
|
|
||||||
if (args[0].equalsIgnoreCase(subcommand.getName())) {
|
|
||||||
command = (HandledCommand) subcommand;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (command != null) {
|
|
||||||
return command.handleTabCompletion(sender, Arrays.copyOfRange(args, 1, args.length));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.getTabCompleter().tabComplete(sender, Arrays.asList(args));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If a sender can execute the command.
|
|
||||||
*
|
|
||||||
* @param sender The sender.
|
|
||||||
* @param command The command.
|
|
||||||
* @param plugin The plugin.
|
|
||||||
* @return If the sender can execute.
|
|
||||||
*/
|
|
||||||
public static boolean canExecute(@NotNull final CommandSender sender,
|
|
||||||
@NotNull final CommandBase command,
|
|
||||||
@NotNull final EcoPlugin plugin) {
|
|
||||||
if (command.isPlayersOnly() && !(sender instanceof Player)) {
|
|
||||||
sender.sendMessage(plugin.getLangYml().getMessage("not-player"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sender.hasPermission(command.getPermission()) && sender instanceof Player) {
|
|
||||||
sender.sendMessage(plugin.getLangYml().getNoPermission());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the command name.
|
|
||||||
*
|
|
||||||
* @return The name.
|
|
||||||
*/
|
|
||||||
public String getName() {
|
|
||||||
return this.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the permission required to execute the command.
|
|
||||||
*
|
|
||||||
* @return The permission.
|
|
||||||
*/
|
|
||||||
public String getPermission() {
|
|
||||||
return this.permission;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get if the command can only be executed by players.
|
|
||||||
*
|
|
||||||
* @return If players only.
|
|
||||||
*/
|
|
||||||
public boolean isPlayersOnly() {
|
|
||||||
return this.playersOnly;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the actual code to be executed in the command.
|
|
||||||
*
|
|
||||||
* @return The code.
|
|
||||||
*/
|
|
||||||
public CommandHandler getHandler() {
|
|
||||||
return this.handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the tab completion code to be executed in the command.
|
|
||||||
*
|
|
||||||
* @return The code.
|
|
||||||
*/
|
|
||||||
public TabCompleteHandler getTabCompleter() {
|
|
||||||
return this.tabCompleter;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the subcommands of the command.
|
|
||||||
*
|
|
||||||
* @return The subcommands.
|
|
||||||
*/
|
|
||||||
public List<CommandBase> getSubcommands() {
|
|
||||||
return this.subcommands;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the command handler.
|
|
||||||
*
|
|
||||||
* @param handler The handler.
|
|
||||||
*/
|
|
||||||
public void setHandler(@NotNull final CommandHandler handler) {
|
|
||||||
this.handler = handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the tab completer.
|
|
||||||
*
|
|
||||||
* @param tabCompleter The tab completer.
|
|
||||||
*/
|
|
||||||
public void setTabCompleter(@NotNull final TabCompleteHandler tabCompleter) {
|
|
||||||
this.tabCompleter = tabCompleter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,24 +1,28 @@
|
|||||||
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 com.willfp.eco.core.command.CommandBase;
|
||||||
import org.bukkit.command.Command;
|
import com.willfp.eco.core.command.PluginCommandBase;
|
||||||
import org.bukkit.command.CommandExecutor;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.command.TabCompleter;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PluginCommands are the class to be used instead of CommandExecutor.
|
* PluginCommands are the class to be used instead of CommandExecutor, they function as the base
|
||||||
|
* command, e.g. {@code /ecoenchants} would be a base command, with each subsequent argument
|
||||||
|
* functioning as subcommands.
|
||||||
* <p>
|
* <p>
|
||||||
* The command will not be registered until register() is called.
|
* The command will not be registered until register() is called.
|
||||||
* <p>
|
* <p>
|
||||||
* The name cannot be the same as an existing command as this will conflict.
|
* The name cannot be the same as an existing command as this will conflict.
|
||||||
*/
|
*/
|
||||||
public abstract class PluginCommand extends HandledCommand implements CommandExecutor, TabCompleter {
|
public abstract class PluginCommand implements PluginCommandBase {
|
||||||
|
/**
|
||||||
|
* The delegate command.
|
||||||
|
*/
|
||||||
|
private final PluginCommandBase delegate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new command.
|
* Create a new command.
|
||||||
*
|
*
|
||||||
@@ -31,64 +35,51 @@ public abstract class PluginCommand extends HandledCommand implements CommandExe
|
|||||||
@NotNull final String name,
|
@NotNull final String name,
|
||||||
@NotNull final String permission,
|
@NotNull final String permission,
|
||||||
final boolean playersOnly) {
|
final boolean playersOnly) {
|
||||||
super(plugin, name, permission, playersOnly);
|
this.delegate = Eco.get().createPluginCommand(this, plugin, name, permission, playersOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers the command with the server,
|
|
||||||
* <p>
|
|
||||||
* Requires the command name to exist, defined in plugin.yml.
|
|
||||||
*/
|
|
||||||
public final void register() {
|
|
||||||
org.bukkit.command.PluginCommand command = Bukkit.getPluginCommand(this.getName());
|
|
||||||
assert command != null;
|
|
||||||
command.setExecutor(this);
|
|
||||||
command.setTabCompleter(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal implementation used to clean up boilerplate.
|
|
||||||
* Used for parity with {@link CommandExecutor#onCommand(CommandSender, Command, String, String[])}.
|
|
||||||
*
|
|
||||||
* @param sender The executor of the command.
|
|
||||||
* @param command The bukkit command.
|
|
||||||
* @param label The name of the executed command.
|
|
||||||
* @param args The arguments of the command (anything after the physical command name)
|
|
||||||
* @return If the command was processed by the linked {@link EcoPlugin}
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public final boolean onCommand(@NotNull final CommandSender sender,
|
public @NotNull String getName() {
|
||||||
@NotNull final Command command,
|
return delegate.getName();
|
||||||
@NotNull final String label,
|
|
||||||
@NotNull final String[] args) {
|
|
||||||
if (!command.getName().equalsIgnoreCase(this.getName())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.handle(sender, args);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal implementation used to clean up boilerplate.
|
|
||||||
* Used for parity with {@link TabCompleter#onTabComplete(CommandSender, Command, String, String[])}.
|
|
||||||
*
|
|
||||||
* @param sender The executor of the command.
|
|
||||||
* @param command The bukkit command.
|
|
||||||
* @param label The name of the executed command.
|
|
||||||
* @param args The arguments of the command (anything after the physical command name).
|
|
||||||
* @return The list of tab-completions.
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable List<String> onTabComplete(@NotNull final CommandSender sender,
|
public @NotNull String getPermission() {
|
||||||
@NotNull final Command command,
|
return delegate.getPermission();
|
||||||
@NotNull final String label,
|
}
|
||||||
@NotNull final String[] args) {
|
|
||||||
if (!command.getName().equalsIgnoreCase(this.getName())) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.handleTabCompletion(sender, args);
|
@Override
|
||||||
|
public boolean isPlayersOnly() {
|
||||||
|
return delegate.isPlayersOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull CommandBase addSubcommand(@NotNull CommandBase command) {
|
||||||
|
return delegate.addSubcommand(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull List<CommandBase> getSubcommands() {
|
||||||
|
return delegate.getSubcommands();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull CommandBase getWrapped() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void register() {
|
||||||
|
delegate.register();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unregister() {
|
||||||
|
delegate.unregister();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EcoPlugin getPlugin() {
|
||||||
|
return delegate.getPlugin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,21 @@
|
|||||||
package com.willfp.eco.core.command.impl;
|
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 com.willfp.eco.core.command.CommandBase;
|
import com.willfp.eco.core.command.CommandBase;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subcommands can be added to PluginCommands or to other Subcommands.
|
* A command implementation that must exist as a subcommand (i.e. cannot be registered directly).
|
||||||
*/
|
*/
|
||||||
public abstract class Subcommand extends HandledCommand {
|
public abstract class Subcommand implements CommandBase {
|
||||||
|
/**
|
||||||
|
* The delegate command.
|
||||||
|
*/
|
||||||
|
private final CommandBase delegate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create subcommand.
|
* Create subcommand.
|
||||||
*
|
*
|
||||||
@@ -20,7 +28,7 @@ public abstract class Subcommand extends HandledCommand {
|
|||||||
@NotNull final String name,
|
@NotNull final String name,
|
||||||
@NotNull final String permission,
|
@NotNull final String permission,
|
||||||
final boolean playersOnly) {
|
final boolean playersOnly) {
|
||||||
super(plugin, name, permission, playersOnly);
|
this.delegate = Eco.get().createSubcommand(this, plugin, name, permission, playersOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -33,6 +41,41 @@ public abstract class Subcommand extends HandledCommand {
|
|||||||
protected Subcommand(@NotNull final EcoPlugin plugin,
|
protected Subcommand(@NotNull final EcoPlugin plugin,
|
||||||
@NotNull final String name,
|
@NotNull final String name,
|
||||||
@NotNull final CommandBase parent) {
|
@NotNull final CommandBase parent) {
|
||||||
super(plugin, name, parent.getPermission(), parent.isPlayersOnly());
|
this(plugin, name, parent.getPermission(), parent.isPlayersOnly());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getName() {
|
||||||
|
return delegate.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull String getPermission() {
|
||||||
|
return delegate.getPermission();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPlayersOnly() {
|
||||||
|
return delegate.isPlayersOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull CommandBase addSubcommand(@NotNull CommandBase command) {
|
||||||
|
return delegate.addSubcommand(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull List<CommandBase> getSubcommands() {
|
||||||
|
return delegate.getSubcommands();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull CommandBase getWrapped() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EcoPlugin getPlugin() {
|
||||||
|
return delegate.getPlugin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,47 @@
|
|||||||
|
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 {
|
||||||
|
/**
|
||||||
|
* Create a new extendable config.
|
||||||
|
*
|
||||||
|
* @param configName The name of the config
|
||||||
|
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||||
|
* @param plugin The plugin.
|
||||||
|
* @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,124 @@
|
|||||||
|
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> {
|
||||||
|
/**
|
||||||
|
* Create new transient config from bukkit 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a transient config from an input stream.
|
||||||
|
*
|
||||||
|
* @param stream The InputStream.
|
||||||
|
*/
|
||||||
|
public TransientConfig(@Nullable final InputStream stream) {
|
||||||
|
super(stream != null ? Eco.get().wrapConfigurationSection(YamlConfiguration.loadConfiguration(
|
||||||
|
new InputStreamReader(stream)
|
||||||
|
)) : new TransientConfig());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load a file to a config.
|
||||||
|
*
|
||||||
|
* @param file The file.
|
||||||
|
* @param type The config type to try read from.
|
||||||
|
*/
|
||||||
|
public TransientConfig(@Nullable final File file,
|
||||||
|
@NotNull final ConfigType type) {
|
||||||
|
super(file != null ? Eco.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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load a config from a string.
|
||||||
|
*
|
||||||
|
* @param contents The contents of the config.
|
||||||
|
* @param type The config type.
|
||||||
|
*/
|
||||||
|
public TransientConfig(@NotNull final String contents,
|
||||||
|
@NotNull final ConfigType type) {
|
||||||
|
super(Eco.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,69 @@
|
|||||||
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 {
|
||||||
|
/**
|
||||||
|
* The use local storage key.
|
||||||
|
*/
|
||||||
|
public static final String KEY_USES_LOCAL_STORAGE = "use-local-storage";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get if the plugin is using local storage.
|
||||||
|
*
|
||||||
|
* @return The prefix.
|
||||||
|
*/
|
||||||
|
public boolean isUsingLocalStorage() {
|
||||||
|
return this.getBool(KEY_USES_LOCAL_STORAGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,62 @@
|
|||||||
package com.willfp.eco.core.config.base;
|
package com.willfp.eco.core.config.base;
|
||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
import com.willfp.eco.core.EcoPlugin;
|
||||||
import com.willfp.eco.core.config.yaml.YamlBaseConfig;
|
import com.willfp.eco.core.config.BaseConfig;
|
||||||
|
import com.willfp.eco.core.config.ConfigType;
|
||||||
import com.willfp.eco.util.StringUtils;
|
import com.willfp.eco.util.StringUtils;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default plugin lang.yml.
|
* Default plugin lang.yml.
|
||||||
*/
|
*/
|
||||||
public class LangYml extends YamlBaseConfig {
|
public class LangYml extends BaseConfig {
|
||||||
|
/**
|
||||||
|
* The messages key.
|
||||||
|
*/
|
||||||
|
public static final String KEY_MESSAGES = "messages";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The prefix key.
|
||||||
|
*/
|
||||||
|
public static final String KEY_PREFIX = "messages.prefix";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The no permission key.
|
||||||
|
*/
|
||||||
|
public static final String KEY_NO_PERMISSION = "messages.no-permission";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The not player key.
|
||||||
|
*/
|
||||||
|
public static final String KEY_NOT_PLAYER = "messages.not-player";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lang.yml.
|
* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* lang.yml requires certain keys to be present.
|
||||||
|
* <p>
|
||||||
|
* If the lang.yml does not contain these keys, it is considered to be
|
||||||
|
* invalid and thus will show a warning in console.
|
||||||
|
*
|
||||||
|
* @return If valid.
|
||||||
|
*/
|
||||||
|
public boolean isValid() {
|
||||||
|
for (String key : List.of(KEY_MESSAGES, KEY_PREFIX, KEY_NO_PERMISSION, KEY_NOT_PLAYER)) {
|
||||||
|
if (!this.has(key)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -24,7 +65,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(KEY_PREFIX);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -33,7 +74,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(KEY_NO_PERMISSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -55,6 +96,6 @@ public class LangYml extends YamlBaseConfig {
|
|||||||
*/
|
*/
|
||||||
public String getMessage(@NotNull final String message,
|
public String getMessage(@NotNull final String message,
|
||||||
@NotNull final StringUtils.FormatOption option) {
|
@NotNull final StringUtils.FormatOption option) {
|
||||||
return getPrefix() + this.getString("messages." + message, option);
|
return getPrefix() + this.getFormattedString(KEY_MESSAGES + "." + message, option);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,37 @@
|
|||||||
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.core.placeholder.context.PlaceholderContext;
|
||||||
|
import com.willfp.eco.util.NumberUtils;
|
||||||
import com.willfp.eco.util.StringUtils;
|
import com.willfp.eco.util.StringUtils;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.bukkit.configuration.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.math.BigDecimal;
|
||||||
|
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.
|
|
||||||
*/
|
|
||||||
void clearCache();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the config into readable text.
|
* Convert the config into readable text.
|
||||||
*
|
*
|
||||||
@@ -41,9 +56,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.
|
||||||
@@ -53,7 +80,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.
|
||||||
@@ -65,10 +91,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.
|
||||||
@@ -85,7 +113,70 @@ 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, PlaceholderContext.of(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.
|
||||||
|
* @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 a decimal value via a mathematical expression.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @param context The placeholder context.
|
||||||
|
* @return The computed value, or 0 if not found or invalid.
|
||||||
|
*/
|
||||||
|
default int getIntFromExpression(@NotNull String path,
|
||||||
|
@NotNull PlaceholderContext context) {
|
||||||
|
return Double.valueOf(getDoubleFromExpression(path, context)).intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an integer from config.
|
* Get an integer from config.
|
||||||
@@ -96,16 +187,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.
|
||||||
*
|
*
|
||||||
@@ -113,7 +194,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.
|
||||||
@@ -130,7 +213,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.
|
||||||
@@ -148,7 +233,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,41 +246,57 @@ public interface Config extends Cloneable {
|
|||||||
@Nullable
|
@Nullable
|
||||||
List<Boolean> getBoolsOrNull(@NotNull String path);
|
List<Boolean> getBoolsOrNull(@NotNull String path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
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 formatted string from config.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @param context The placeholder context.
|
||||||
|
* @return The found value, or an empty string if not found.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
default String getFormattedString(@NotNull String path,
|
||||||
|
@NotNull PlaceholderContext context) {
|
||||||
|
return Objects.requireNonNullElse(
|
||||||
|
getFormattedStringOrNull(path, context),
|
||||||
|
""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a string from config.
|
* Get a string from config.
|
||||||
|
* <p>
|
||||||
|
* Not formatted.
|
||||||
*
|
*
|
||||||
* @param path The key to fetch the value from.
|
* @param path The key to fetch the value from.
|
||||||
* @return The found value, or an empty string if not found.
|
* @return The found value, or an empty string if not found.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
default String getString(@NotNull String path) {
|
default String getString(@NotNull String path) {
|
||||||
return getString(path, true);
|
return getString(path, false, StringUtils.FormatOption.WITHOUT_PLACEHOLDERS);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a string from config.
|
|
||||||
*
|
|
||||||
* @param path The key to fetch the value from.
|
|
||||||
* @param format If the string should be formatted.
|
|
||||||
* @return The found value, or an empty string if not found.
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
default String getString(@NotNull String path,
|
|
||||||
boolean format) {
|
|
||||||
return this.getString(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a string from config.
|
|
||||||
*
|
|
||||||
* @param path The key to fetch the value from.
|
|
||||||
* @param option The format option.
|
|
||||||
* @return The found value, or an empty string if not found.
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
default String getString(@NotNull String path,
|
|
||||||
@NotNull final StringUtils.FormatOption option) {
|
|
||||||
return this.getString(path, true, option);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -205,19 +308,66 @@ public interface Config extends Cloneable {
|
|||||||
* @return The found value, or an empty string if not found.
|
* @return The found value, or an empty string if not found.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
String getString(@NotNull String path,
|
default String getString(@NotNull String path,
|
||||||
boolean format,
|
boolean format,
|
||||||
@NotNull StringUtils.FormatOption option);
|
@NotNull StringUtils.FormatOption option) {
|
||||||
|
return Objects.requireNonNullElse(getStringOrNull(path, format, option), "");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a formatted string from config.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The found value, or null 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 null if not found.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
default String getFormattedStringOrNull(@NotNull String path,
|
||||||
|
@NotNull StringUtils.FormatOption option) {
|
||||||
|
return getStringOrNull(path, true, option);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a formatted string from config.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @param context The placeholder context.
|
||||||
|
* @return The found value, or null if not found.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
default String getFormattedStringOrNull(@NotNull String path,
|
||||||
|
@NotNull PlaceholderContext context) {
|
||||||
|
String nullable = getStringOrNull(path);
|
||||||
|
|
||||||
|
if (nullable == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return StringUtils.format(nullable, context.withInjectableContext(this));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a string from config.
|
* Get a string from config.
|
||||||
|
* <p>
|
||||||
|
* 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
|
||||||
default String getStringOrNull(@NotNull String path) {
|
default String getStringOrNull(@NotNull String path) {
|
||||||
return getStringOrNull(path, true);
|
return getStringOrNull(path, false, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -225,33 +375,7 @@ public interface Config extends Cloneable {
|
|||||||
*
|
*
|
||||||
* @param path The key to fetch the value from.
|
* @param path The key to fetch the value from.
|
||||||
* @param format If the string should be formatted.
|
* @param format If the string should be formatted.
|
||||||
* @return The found value, or null if not found.
|
* @param option The format option. If format is false, this will be ignored.
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
default String getStringOrNull(@NotNull String path,
|
|
||||||
boolean format) {
|
|
||||||
return this.getStringOrNull(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a string from config.
|
|
||||||
*
|
|
||||||
* @param path The key to fetch the value from.
|
|
||||||
* @param option The format option.
|
|
||||||
* @return The found value, or null if not found.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
default String getStringOrNull(@NotNull String path,
|
|
||||||
@NotNull StringUtils.FormatOption option) {
|
|
||||||
return this.getStringOrNull(path, true, option);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a string from config.
|
|
||||||
*
|
|
||||||
* @param path The key to fetch the value from.
|
|
||||||
* @param format If the string 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
|
||||||
@@ -268,36 +392,56 @@ 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
|
||||||
default List<String> getStrings(@NotNull String path) {
|
default List<String> getFormattedStrings(@NotNull String path) {
|
||||||
return getStrings(path, true);
|
return getStrings(path, true, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a list of strings from config.
|
|
||||||
*
|
|
||||||
* @param path The key to fetch the value from.
|
|
||||||
* @param format If the strings should be formatted.
|
|
||||||
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
|
||||||
*/
|
|
||||||
@NotNull
|
|
||||||
default List<String> getStrings(@NotNull String path,
|
|
||||||
boolean format) {
|
|
||||||
return this.getStrings(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of strings from config.
|
* Get a list of strings from config.
|
||||||
|
* <p>
|
||||||
|
* Formatted by default.
|
||||||
*
|
*
|
||||||
* @param path The key to fetch the value from.
|
* @param path The key to fetch the value from.
|
||||||
* @param option The format option.
|
* @param option The format option.
|
||||||
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@NotNull
|
||||||
default List<String> getStrings(@NotNull String path,
|
default List<String> getFormattedStrings(@NotNull String path,
|
||||||
@NotNull StringUtils.FormatOption option) {
|
@NotNull StringUtils.FormatOption option) {
|
||||||
return getStrings(path, true, option);
|
return getStrings(path, true, option);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of strings from config.
|
||||||
|
* <p>
|
||||||
|
* Formatted.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @param context The placeholder context.
|
||||||
|
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
default List<String> getFormattedStrings(@NotNull String path,
|
||||||
|
@NotNull PlaceholderContext context) {
|
||||||
|
return Objects.requireNonNullElse(
|
||||||
|
getFormattedStringsOrNull(path, context),
|
||||||
|
new ArrayList<>()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of strings from config.
|
||||||
|
* <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.
|
||||||
*
|
*
|
||||||
@@ -307,47 +451,79 @@ public interface Config extends Cloneable {
|
|||||||
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
List<String> getStrings(@NotNull String path,
|
default List<String> getStrings(@NotNull String path,
|
||||||
boolean format,
|
boolean format,
|
||||||
@NotNull StringUtils.FormatOption option);
|
@NotNull StringUtils.FormatOption option) {
|
||||||
|
return Objects.requireNonNullElse(getStringsOrNull(path, format, option), new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of strings from config.
|
* Get a list of strings from config.
|
||||||
|
* <p>
|
||||||
|
* 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
|
||||||
default List<String> getStringsOrNull(@NotNull String path) {
|
default List<String> getFormattedStringsOrNull(@NotNull String path) {
|
||||||
return getStringsOrNull(path, true);
|
return getStringsOrNull(path, true, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a list of strings from config.
|
|
||||||
*
|
|
||||||
* @param path The key to fetch the value from.
|
|
||||||
* @param format If the strings should be formatted.
|
|
||||||
* @return The found value, or null if not found.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
default List<String> getStringsOrNull(@NotNull String path,
|
|
||||||
boolean format) {
|
|
||||||
return getStringsOrNull(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
||||||
* @param option The format option.
|
* @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
|
||||||
default List<String> getStringsOrNull(@NotNull String path,
|
default List<String> getFormattedStringsOrNull(@NotNull String path,
|
||||||
@NotNull StringUtils.FormatOption option) {
|
@NotNull StringUtils.FormatOption option) {
|
||||||
return getStringsOrNull(path, true, option);
|
return getStringsOrNull(path, true, option);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of strings from config.
|
||||||
|
* <p>
|
||||||
|
* Formatted.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @param context The placeholder context.
|
||||||
|
* @return The found value, or null if not found.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
default List<String> getFormattedStringsOrNull(@NotNull String path,
|
||||||
|
@NotNull PlaceholderContext context) {
|
||||||
|
List<String> nullable = getStringsOrNull(path);
|
||||||
|
|
||||||
|
if (nullable == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return StringUtils.formatList(
|
||||||
|
nullable,
|
||||||
|
context.withInjectableContext(this)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of strings from config.
|
||||||
|
* <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.
|
||||||
*
|
*
|
||||||
@@ -367,7 +543,65 @@ 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, PlaceholderContext.of(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.
|
||||||
|
* @return The computed value, or 0 if not found or invalid.
|
||||||
|
*/
|
||||||
|
default double getDoubleFromExpression(@NotNull String path,
|
||||||
|
@Nullable Player player) {
|
||||||
|
return getDoubleFromExpression(path, player, Collections.emptyList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 getDoubleFromExpression(path, new PlaceholderContext(
|
||||||
|
player,
|
||||||
|
null,
|
||||||
|
this,
|
||||||
|
additionalPlayers
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a decimal value via a mathematical expression.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @param context The placeholder context.
|
||||||
|
* @return The computed value, or 0 if not found or invalid.
|
||||||
|
*/
|
||||||
|
default double getDoubleFromExpression(@NotNull String path,
|
||||||
|
@NotNull PlaceholderContext context) {
|
||||||
|
return Objects.requireNonNullElseGet(
|
||||||
|
this.getDoubleOrNull(path),
|
||||||
|
() -> NumberUtils.evaluateExpression(this.getString(path), context.withInjectableContext(this))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a decimal from config.
|
* Get a decimal from config.
|
||||||
@@ -385,7 +619,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.
|
||||||
@@ -396,10 +632,108 @@ 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 a big decimal from config.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The found value, or 0 if not found.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
default BigDecimal getBigDecimal(@NotNull final String path) {
|
||||||
|
return Objects.requireNonNullElse(getBigDecimalOrNull(path), BigDecimal.ZERO);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a big decimal from config.
|
||||||
|
*
|
||||||
|
* @param path The key to fetch the value from.
|
||||||
|
* @return The found value, or null if not found.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
default BigDecimal getBigDecimalOrNull(@NotNull final String path) {
|
||||||
|
if (this.has(path)) {
|
||||||
|
return new BigDecimal(this.getString(path));
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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,55 +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);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get subsection from config.
|
|
||||||
*
|
|
||||||
* @param path The key to check.
|
|
||||||
* @return The subsection. Throws NPE if not found.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
JSONConfig getSubsection(@NotNull String path);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get subsection from config.
|
|
||||||
*
|
|
||||||
* @param path The key to check.
|
|
||||||
* @return The subsection, or null if not found.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
JSONConfig getSubsectionOrNull(@NotNull String path);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
JSONConfig clone();
|
|
||||||
}
|
|
||||||
@@ -1,12 +1,15 @@
|
|||||||
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 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.
|
||||||
*/
|
*/
|
||||||
@@ -26,6 +29,22 @@ public interface LoadableConfig {
|
|||||||
*/
|
*/
|
||||||
void save() throws IOException;
|
void save() throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the config asynchronously.
|
||||||
|
*/
|
||||||
|
default void saveAsync() {
|
||||||
|
// This default implementation exists purely for backwards compatibility
|
||||||
|
// with legacy Config implementations that don't have saveAsync().
|
||||||
|
// Default eco implementations of Config have saveAsync() implemented.
|
||||||
|
new Thread(() -> {
|
||||||
|
try {
|
||||||
|
this.save();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the config file.
|
* Get the config file.
|
||||||
*
|
*
|
||||||
@@ -39,4 +58,10 @@ public interface LoadableConfig {
|
|||||||
* @return The name.
|
* @return The name.
|
||||||
*/
|
*/
|
||||||
String getName();
|
String getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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,78 +0,0 @@
|
|||||||
package com.willfp.eco.core.config.json;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.Eco;
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
|
||||||
import com.willfp.eco.core.PluginLike;
|
|
||||||
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Config implementation for configs present in the plugin's base directory (eg config.json).
|
|
||||||
* <p>
|
|
||||||
* Automatically updates.
|
|
||||||
*/
|
|
||||||
public abstract class JSONBaseConfig extends LoadableJSONConfigWrapper {
|
|
||||||
/**
|
|
||||||
* @param configName The name of the config
|
|
||||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
|
||||||
* @param plugin The plugin.
|
|
||||||
* @param updateBlacklist Substring of keys to not add/remove keys for.
|
|
||||||
*/
|
|
||||||
protected JSONBaseConfig(@NotNull final String configName,
|
|
||||||
final boolean removeUnused,
|
|
||||||
@NotNull final PluginLike plugin,
|
|
||||||
@NotNull final String... updateBlacklist) {
|
|
||||||
super(
|
|
||||||
Eco.getHandler().getConfigFactory().createUpdatableJSONConfig(
|
|
||||||
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 JSONBaseConfig(@NotNull final String configName,
|
|
||||||
final boolean removeUnused,
|
|
||||||
@NotNull final PluginLike plugin) {
|
|
||||||
super(
|
|
||||||
Eco.getHandler().getConfigFactory().createUpdatableJSONConfig(
|
|
||||||
configName,
|
|
||||||
plugin,
|
|
||||||
"",
|
|
||||||
plugin.getClass(),
|
|
||||||
removeUnused
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param configName The name of the config
|
|
||||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
|
||||||
* @param plugin The plugin.
|
|
||||||
* @param updateBlacklist Substring of keys to not add/remove keys for.
|
|
||||||
*/
|
|
||||||
protected JSONBaseConfig(@NotNull final String configName,
|
|
||||||
final boolean removeUnused,
|
|
||||||
@NotNull final EcoPlugin plugin,
|
|
||||||
@NotNull final String... updateBlacklist) {
|
|
||||||
this(configName, removeUnused, (PluginLike) plugin, updateBlacklist);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param configName The name of the config
|
|
||||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
|
||||||
* @param plugin The plugin.
|
|
||||||
*/
|
|
||||||
protected JSONBaseConfig(@NotNull final String configName,
|
|
||||||
final boolean removeUnused,
|
|
||||||
@NotNull final EcoPlugin plugin) {
|
|
||||||
this(configName, removeUnused, (PluginLike) plugin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
package com.willfp.eco.core.config.json;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.Eco;
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
|
||||||
import com.willfp.eco.core.PluginLike;
|
|
||||||
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Config implementation for configs present in one of two places:
|
|
||||||
* <ul>
|
|
||||||
* <li>Plugin base directory (eg config.yml, lang.yml)</li>
|
|
||||||
* <li>Other extension's configs</li>
|
|
||||||
* </ul>
|
|
||||||
* <p>
|
|
||||||
* Automatically updates.
|
|
||||||
*/
|
|
||||||
public abstract class JSONExtendableConfig extends LoadableJSONConfigWrapper {
|
|
||||||
/**
|
|
||||||
* @param configName The name of the config
|
|
||||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
|
||||||
* @param plugin The plugin.
|
|
||||||
* @param updateBlacklist Substring of keys to not add/remove keys for.
|
|
||||||
* @param subDirectoryPath The subdirectory path.
|
|
||||||
* @param source The class that owns the resource.
|
|
||||||
*/
|
|
||||||
protected JSONExtendableConfig(@NotNull final String configName,
|
|
||||||
final boolean removeUnused,
|
|
||||||
@NotNull final PluginLike plugin,
|
|
||||||
@NotNull final Class<?> source,
|
|
||||||
@NotNull final String subDirectoryPath,
|
|
||||||
@NotNull final String... updateBlacklist) {
|
|
||||||
super(
|
|
||||||
Eco.getHandler().getConfigFactory().createUpdatableJSONConfig(
|
|
||||||
configName,
|
|
||||||
plugin,
|
|
||||||
subDirectoryPath,
|
|
||||||
source,
|
|
||||||
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.
|
|
||||||
* @param updateBlacklist Substring of keys to not add/remove keys for.
|
|
||||||
* @param subDirectoryPath The subdirectory path.
|
|
||||||
* @param source The class that owns the resource.
|
|
||||||
*/
|
|
||||||
protected JSONExtendableConfig(@NotNull final String configName,
|
|
||||||
final boolean removeUnused,
|
|
||||||
@NotNull final EcoPlugin plugin,
|
|
||||||
@NotNull final Class<?> source,
|
|
||||||
@NotNull final String subDirectoryPath,
|
|
||||||
@NotNull final String... updateBlacklist) {
|
|
||||||
this(configName, removeUnused, (PluginLike) plugin, source, subDirectoryPath, updateBlacklist);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
package com.willfp.eco.core.config.json;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.Eco;
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
|
||||||
import com.willfp.eco.core.PluginLike;
|
|
||||||
import com.willfp.eco.core.config.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 PluginLike plugin) {
|
|
||||||
super(Eco.getHandler().getConfigFactory().createLoadableJSONConfig(configName, plugin, "", plugin.getClass()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Config implementation for configs present in the plugin's base directory (eg config.json, lang.json).
|
|
||||||
* <p>
|
|
||||||
* Does not automatically update.
|
|
||||||
*
|
|
||||||
* @param configName The name of the config
|
|
||||||
* @param plugin The plugin.
|
|
||||||
*/
|
|
||||||
protected JSONStaticBaseConfig(@NotNull final String configName,
|
|
||||||
@NotNull final EcoPlugin plugin) {
|
|
||||||
this(configName, (PluginLike) plugin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,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,48 +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 @NotNull JSONConfig getSubsection(@NotNull final String path) {
|
|
||||||
return this.getHandle().getSubsection(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable JSONConfig getSubsectionOrNull(@NotNull final String path) {
|
|
||||||
return this.getHandle().getSubsectionOrNull(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JSONConfig clone() {
|
|
||||||
return this.getHandle().clone();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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,17 +24,30 @@ 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>
|
||||||
* By having a plugin as a parameter, you shouldn't really need getInstance()
|
* By having a plugin as a parameter, you shouldn't really need getInstance()
|
||||||
* calls in your code.
|
* calls in your code.
|
||||||
|
* <p>
|
||||||
|
* While flexible, this can lead to long initialization times, so this feature
|
||||||
|
* can be disabled in eco.yml with the uses-reflective-reload option.
|
||||||
|
*
|
||||||
|
* @deprecated This has been deprecated due to the poor control flow and long startup times.
|
||||||
*/
|
*/
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target(ElementType.METHOD)
|
@Target(ElementType.METHOD)
|
||||||
|
@Documented
|
||||||
|
@Deprecated(since = "6.67.0", forRemoval = true)
|
||||||
|
@SuppressWarnings("DeprecatedIsStillUsed")
|
||||||
public @interface ConfigUpdater {
|
public @interface ConfigUpdater {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,94 +0,0 @@
|
|||||||
package com.willfp.eco.core.config.wrapper;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.PluginLike;
|
|
||||||
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 PluginLike plugin,
|
|
||||||
@NotNull String subDirectoryPath,
|
|
||||||
@NotNull Class<?> source,
|
|
||||||
boolean removeUnused,
|
|
||||||
@NotNull String... updateBlacklist);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
JSONConfig createUpdatableJSONConfig(@NotNull String configName,
|
|
||||||
@NotNull PluginLike 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 PluginLike plugin,
|
|
||||||
@NotNull String subDirectoryPath,
|
|
||||||
@NotNull Class<?> source);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Yaml loadable config.
|
|
||||||
*
|
|
||||||
* @param configName The name of the config
|
|
||||||
* @param plugin The plugin.
|
|
||||||
* @param subDirectoryPath The subdirectory path.
|
|
||||||
* @param source The class that owns the resource.
|
|
||||||
* @return The config implementation.
|
|
||||||
*/
|
|
||||||
Config createLoadableYamlConfig(@NotNull String configName,
|
|
||||||
@NotNull PluginLike plugin,
|
|
||||||
@NotNull String subDirectoryPath,
|
|
||||||
@NotNull Class<?> source);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Yaml config.
|
|
||||||
*
|
|
||||||
* @param config The handle.
|
|
||||||
* @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 com.willfp.eco.core.placeholder.InjectablePlaceholder;
|
||||||
import com.willfp.eco.util.StringUtils;
|
import com.willfp.eco.util.StringUtils;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
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")
|
||||||
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,
|
||||||
@@ -37,11 +42,6 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
|
|||||||
this.handle = handle;
|
this.handle = handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clearCache() {
|
|
||||||
handle.clearCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toPlaintext() {
|
public String toPlaintext() {
|
||||||
return handle.toPlaintext();
|
return handle.toPlaintext();
|
||||||
@@ -57,6 +57,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);
|
||||||
@@ -68,70 +74,31 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
|
|||||||
handle.set(path, object);
|
handle.set(path, object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull Config getSubsection(@NotNull final String path) {
|
|
||||||
return handle.getSubsection(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable Config getSubsectionOrNull(@NotNull final String path) {
|
public @Nullable Config getSubsectionOrNull(@NotNull final String path) {
|
||||||
return handle.getSubsectionOrNull(path);
|
return handle.getSubsectionOrNull(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getInt(@NotNull final String path) {
|
|
||||||
return handle.getInt(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable Integer getIntOrNull(@NotNull final String path) {
|
public @Nullable Integer getIntOrNull(@NotNull final String path) {
|
||||||
return handle.getIntOrNull(path);
|
return handle.getIntOrNull(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getInt(@NotNull final String path,
|
|
||||||
final int def) {
|
|
||||||
return handle.getInt(path, def);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull List<Integer> getInts(@NotNull final String path) {
|
|
||||||
return handle.getInts(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable List<Integer> getIntsOrNull(@NotNull final String path) {
|
public @Nullable List<Integer> getIntsOrNull(@NotNull final String path) {
|
||||||
return handle.getIntsOrNull(path);
|
return handle.getIntsOrNull(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean getBool(@NotNull final String path) {
|
|
||||||
return handle.getBool(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable Boolean getBoolOrNull(@NotNull final String path) {
|
public @Nullable Boolean getBoolOrNull(@NotNull final String path) {
|
||||||
return handle.getBoolOrNull(path);
|
return handle.getBoolOrNull(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull List<Boolean> getBools(@NotNull final String path) {
|
|
||||||
return handle.getBools(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable List<Boolean> getBoolsOrNull(@NotNull final String path) {
|
public @Nullable List<Boolean> getBoolsOrNull(@NotNull final String path) {
|
||||||
return handle.getBoolsOrNull(path);
|
return handle.getBoolsOrNull(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull String getString(@NotNull final String path,
|
|
||||||
final boolean format,
|
|
||||||
@NotNull final StringUtils.FormatOption option) {
|
|
||||||
return handle.getString(path, format, option);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable String getStringOrNull(@NotNull final String path,
|
public @Nullable String getStringOrNull(@NotNull final String path,
|
||||||
final boolean format,
|
final boolean format,
|
||||||
@@ -139,13 +106,6 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
|
|||||||
return handle.getStringOrNull(path, format, option);
|
return handle.getStringOrNull(path, format, option);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull List<String> getStrings(@NotNull final String path,
|
|
||||||
final boolean format,
|
|
||||||
@NotNull final StringUtils.FormatOption option) {
|
|
||||||
return handle.getStrings(path, format, option);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable List<String> getStringsOrNull(@NotNull final String path,
|
public @Nullable List<String> getStringsOrNull(@NotNull final String path,
|
||||||
final boolean format,
|
final boolean format,
|
||||||
@@ -153,31 +113,51 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
|
|||||||
return handle.getStringsOrNull(path, format, option);
|
return handle.getStringsOrNull(path, format, option);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public double getDouble(@NotNull final String path) {
|
|
||||||
return handle.getDouble(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable Double getDoubleOrNull(@NotNull final String path) {
|
public @Nullable Double getDoubleOrNull(@NotNull final String path) {
|
||||||
return handle.getDoubleOrNull(path);
|
return handle.getDoubleOrNull(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull List<Double> getDoubles(@NotNull final String path) {
|
|
||||||
return handle.getDoubles(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable List<Double> getDoublesOrNull(@NotNull final String path) {
|
public @Nullable List<Double> getDoublesOrNull(@NotNull final String path) {
|
||||||
return handle.getDoublesOrNull(path);
|
return handle.getDoublesOrNull(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable List<? extends Config> getSubsectionsOrNull(@NotNull final String path) {
|
||||||
|
return handle.getSubsectionsOrNull(path);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Config clone() {
|
public Config clone() {
|
||||||
return handle.clone();
|
return handle.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ConfigType getType() {
|
||||||
|
return handle.getType();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void 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.
|
* Get the 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,78 +0,0 @@
|
|||||||
package com.willfp.eco.core.config.yaml;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.Eco;
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
|
||||||
import com.willfp.eco.core.PluginLike;
|
|
||||||
import com.willfp.eco.core.config.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 PluginLike 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 PluginLike plugin) {
|
|
||||||
super(
|
|
||||||
Eco.getHandler().getConfigFactory().createUpdatableYamlConfig(
|
|
||||||
configName,
|
|
||||||
plugin,
|
|
||||||
"",
|
|
||||||
plugin.getClass(),
|
|
||||||
removeUnused
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param configName The name of the config
|
|
||||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
|
||||||
* @param plugin The plugin.
|
|
||||||
* @param updateBlacklist Substring of keys to not add/remove keys for.
|
|
||||||
*/
|
|
||||||
protected YamlBaseConfig(@NotNull final String configName,
|
|
||||||
final boolean removeUnused,
|
|
||||||
@NotNull final EcoPlugin plugin,
|
|
||||||
@NotNull final String... updateBlacklist) {
|
|
||||||
this(configName, removeUnused, (PluginLike) plugin, updateBlacklist);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param configName The name of the config
|
|
||||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
|
||||||
* @param plugin The plugin.
|
|
||||||
*/
|
|
||||||
protected YamlBaseConfig(@NotNull final String configName,
|
|
||||||
final boolean removeUnused,
|
|
||||||
@NotNull final EcoPlugin plugin) {
|
|
||||||
this(configName, removeUnused, (PluginLike) plugin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
package com.willfp.eco.core.config.yaml;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.Eco;
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
|
||||||
import com.willfp.eco.core.PluginLike;
|
|
||||||
import com.willfp.eco.core.config.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 PluginLike plugin,
|
|
||||||
@NotNull final Class<?> source,
|
|
||||||
@NotNull final String subDirectoryPath,
|
|
||||||
@NotNull final String... updateBlacklist) {
|
|
||||||
super(
|
|
||||||
Eco.getHandler().getConfigFactory().createUpdatableYamlConfig(
|
|
||||||
configName,
|
|
||||||
plugin,
|
|
||||||
subDirectoryPath,
|
|
||||||
source,
|
|
||||||
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.
|
|
||||||
* @param updateBlacklist Substring of keys to not add/remove keys for.
|
|
||||||
* @param subDirectoryPath The subdirectory path.
|
|
||||||
* @param source The class that owns the resource.
|
|
||||||
*/
|
|
||||||
protected YamlExtendableConfig(@NotNull final String configName,
|
|
||||||
final boolean removeUnused,
|
|
||||||
@NotNull final EcoPlugin plugin,
|
|
||||||
@NotNull final Class<?> source,
|
|
||||||
@NotNull final String subDirectoryPath,
|
|
||||||
@NotNull final String... updateBlacklist) {
|
|
||||||
this(configName, removeUnused, (PluginLike) plugin, source, subDirectoryPath, updateBlacklist);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
package com.willfp.eco.core.config.yaml;
|
|
||||||
|
|
||||||
import com.willfp.eco.core.Eco;
|
|
||||||
import com.willfp.eco.core.EcoPlugin;
|
|
||||||
import com.willfp.eco.core.PluginLike;
|
|
||||||
import com.willfp.eco.core.config.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 PluginLike plugin) {
|
|
||||||
super(Eco.getHandler().getConfigFactory().createLoadableYamlConfig(configName, plugin, "", plugin.getClass()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Config implementation for configs present in the plugin's base directory (eg config.yml, lang.yml).
|
|
||||||
* <p>
|
|
||||||
* Does not automatically update.
|
|
||||||
*
|
|
||||||
* @param configName The name of the config
|
|
||||||
* @param plugin The plugin.
|
|
||||||
*/
|
|
||||||
protected YamlStaticBaseConfig(@NotNull final String configName,
|
|
||||||
@NotNull final EcoPlugin plugin) {
|
|
||||||
this(configName, (PluginLike) plugin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,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,26 +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,105 @@
|
|||||||
|
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) {
|
||||||
|
if (base instanceof ExtendedPersistentDataContainer) {
|
||||||
|
return (ExtendedPersistentDataContainer) 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,148 @@
|
|||||||
|
package com.willfp.eco.core.data;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple store key-value store for data to be stored outside of plugins.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public final class ExternalDataStore {
|
||||||
|
/**
|
||||||
|
* The store.
|
||||||
|
*/
|
||||||
|
private static final Map<String, Object> DATA = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The store adapters.
|
||||||
|
*/
|
||||||
|
private static final List<ExternalDataStoreObjectAdapter<?, ?>> STORE_ADAPTERS = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put data into the store.
|
||||||
|
*
|
||||||
|
* @param key The key.
|
||||||
|
* @param value The value.
|
||||||
|
*/
|
||||||
|
public static void put(@NotNull final String key,
|
||||||
|
@NotNull final Object value) {
|
||||||
|
doPut(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put data into the store.
|
||||||
|
*
|
||||||
|
* @param key The key.
|
||||||
|
* @param value The value.
|
||||||
|
* @param <A> The stored type.
|
||||||
|
*/
|
||||||
|
private static <A> void doPut(@NotNull final String key,
|
||||||
|
@NotNull final A value) {
|
||||||
|
Object storedValue = value;
|
||||||
|
|
||||||
|
for (ExternalDataStoreObjectAdapter<?, ?> unknownAdapter : STORE_ADAPTERS) {
|
||||||
|
if (unknownAdapter.getAccessedClass().isInstance(value)) {
|
||||||
|
ExternalDataStoreObjectAdapter<A, ?> adapter = (ExternalDataStoreObjectAdapter<A, ?>) unknownAdapter;
|
||||||
|
storedValue = adapter.toStoredObject(value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DATA.put(key, storedValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get data from the store.
|
||||||
|
*
|
||||||
|
* @param key The key.
|
||||||
|
* @param clazz The class.
|
||||||
|
* @param <T> The type.
|
||||||
|
* @return The value.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public static <T> T get(@NotNull final String key,
|
||||||
|
@NotNull final Class<T> clazz) {
|
||||||
|
return doGet(key, clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get data from the store.
|
||||||
|
*
|
||||||
|
* @param key The key.
|
||||||
|
* @param clazz The class.
|
||||||
|
* @param <A> The accessed type.
|
||||||
|
* @param <S> The stored type.
|
||||||
|
* @return The value.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private static <A, S> A doGet(@NotNull final String key,
|
||||||
|
@NotNull final Class<A> clazz) {
|
||||||
|
Object value = DATA.get(key);
|
||||||
|
|
||||||
|
for (ExternalDataStoreObjectAdapter<?, ?> unknownAdapter : STORE_ADAPTERS) {
|
||||||
|
if (unknownAdapter.getStoredClass().isInstance(value) && unknownAdapter.getAccessedClass().equals(clazz)) {
|
||||||
|
ExternalDataStoreObjectAdapter<A, S> adapter = (ExternalDataStoreObjectAdapter<A, S>) unknownAdapter;
|
||||||
|
value = adapter.toAccessedObject((S) value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clazz.isInstance(value)) {
|
||||||
|
return clazz.cast(value);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get data from the store.
|
||||||
|
*
|
||||||
|
* @param key The key.
|
||||||
|
* @param clazz The class.
|
||||||
|
* @param defaultValue The default value.
|
||||||
|
* @param <T> The type.
|
||||||
|
* @return The value.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static <T> T get(@NotNull final String key,
|
||||||
|
@NotNull final Class<T> clazz,
|
||||||
|
@NotNull final T defaultValue) {
|
||||||
|
T value = get(key, clazz);
|
||||||
|
return value == null ? defaultValue : value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get data from the store.
|
||||||
|
*
|
||||||
|
* @param key The key.
|
||||||
|
* @param clazz The class.
|
||||||
|
* @param defaultValue The default value.
|
||||||
|
* @param <T> The type.
|
||||||
|
* @return The value.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static <T> T get(@NotNull final String key,
|
||||||
|
@NotNull final Class<T> clazz,
|
||||||
|
@NotNull final Supplier<T> defaultValue) {
|
||||||
|
return get(key, clazz, defaultValue.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a new adapter.
|
||||||
|
*
|
||||||
|
* @param adapter The adapter.
|
||||||
|
*/
|
||||||
|
public static void registerAdapter(@NotNull final ExternalDataStoreObjectAdapter<?, ?> adapter) {
|
||||||
|
STORE_ADAPTERS.add(adapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ExternalDataStore() {
|
||||||
|
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
package com.willfp.eco.core.data;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An adapter for objects stored in {@link ExternalDataStore}.
|
||||||
|
*
|
||||||
|
* @param <A> The accessed class.
|
||||||
|
* @param <S> The stored class.
|
||||||
|
*/
|
||||||
|
public abstract class ExternalDataStoreObjectAdapter<A, S> {
|
||||||
|
/**
|
||||||
|
* The class that is accessed (read / written).
|
||||||
|
*/
|
||||||
|
private final Class<? extends A> accessedClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class that is stored internally.
|
||||||
|
*/
|
||||||
|
private final Class<? extends S> storedClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new adapter.
|
||||||
|
*
|
||||||
|
* @param accessedClass The class that is accessed (read / written).
|
||||||
|
* @param storedClass The class that is stored internally.
|
||||||
|
*/
|
||||||
|
protected ExternalDataStoreObjectAdapter(@NotNull final Class<? extends A> accessedClass,
|
||||||
|
@NotNull final Class<? extends S> storedClass) {
|
||||||
|
this.accessedClass = accessedClass;
|
||||||
|
this.storedClass = storedClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert an object to the stored object.
|
||||||
|
*
|
||||||
|
* @param obj The object.
|
||||||
|
* @return The stored object.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public abstract S toStoredObject(@NotNull final A obj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert an object to the accessed object.
|
||||||
|
*
|
||||||
|
* @param obj The object.
|
||||||
|
* @return The accessed object.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public abstract A toAccessedObject(@NotNull final S obj);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the class that is accessed (read / written).
|
||||||
|
*
|
||||||
|
* @return The class.
|
||||||
|
*/
|
||||||
|
public Class<? extends A> getAccessedClass() {
|
||||||
|
return accessedClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the class that is stored internally.
|
||||||
|
*
|
||||||
|
* @return The class.
|
||||||
|
*/
|
||||||
|
public Class<? extends S> getStoredClass() {
|
||||||
|
return storedClass;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package com.willfp.eco.core.data;
|
package com.willfp.eco.core.data;
|
||||||
|
|
||||||
import com.willfp.eco.core.Eco;
|
import com.willfp.eco.core.Eco;
|
||||||
import com.willfp.eco.core.data.keys.PersistentDataKey;
|
|
||||||
import org.bukkit.OfflinePlayer;
|
import org.bukkit.OfflinePlayer;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
@@ -12,26 +11,7 @@ import java.util.UUID;
|
|||||||
* <p>
|
* <p>
|
||||||
* Profiles save automatically, so there is no need to save after changes.
|
* Profiles save automatically, so there is no need to save after changes.
|
||||||
*/
|
*/
|
||||||
public interface PlayerProfile {
|
public interface PlayerProfile extends Profile {
|
||||||
/**
|
|
||||||
* Write a key to a player's persistent data.
|
|
||||||
*
|
|
||||||
* @param key The key.
|
|
||||||
* @param value The value.
|
|
||||||
* @param <T> The type of the key.
|
|
||||||
*/
|
|
||||||
<T> void write(@NotNull PersistentDataKey<T> key,
|
|
||||||
@NotNull T value);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read a key from a player's persistent data.
|
|
||||||
*
|
|
||||||
* @param key The key.
|
|
||||||
* @param <T> The type of the key.
|
|
||||||
* @return The value, or the default value if not found.
|
|
||||||
*/
|
|
||||||
<T> @NotNull T read(@NotNull PersistentDataKey<T> key);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a player profile.
|
* Load a player profile.
|
||||||
*
|
*
|
||||||
@@ -51,6 +31,6 @@ public interface PlayerProfile {
|
|||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
static PlayerProfile load(@NotNull final UUID uuid) {
|
static PlayerProfile load(@NotNull final UUID uuid) {
|
||||||
return Eco.getHandler().getPlayerProfileHandler().load(uuid);
|
return Eco.get().loadPlayerProfile(uuid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
package com.willfp.eco.core.data;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* API to handle player profiles.
|
|
||||||
*/
|
|
||||||
public interface PlayerProfileHandler {
|
|
||||||
/**
|
|
||||||
* Load a player profile.
|
|
||||||
*
|
|
||||||
* @param uuid The UUID.
|
|
||||||
* @return The profile.
|
|
||||||
*/
|
|
||||||
PlayerProfile load(@NotNull UUID uuid);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save a player profile.
|
|
||||||
*
|
|
||||||
* @param uuid The uuid.
|
|
||||||
*/
|
|
||||||
void savePlayer(@NotNull UUID uuid);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save all player data.
|
|
||||||
*
|
|
||||||
* @param async If the saving should be done asynchronously.
|
|
||||||
* @deprecated async is now handled automatically depending on implementation.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
default void saveAll(boolean async) {
|
|
||||||
saveAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save all player data.
|
|
||||||
*/
|
|
||||||
void saveAll();
|
|
||||||
}
|
|
||||||
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,37 @@
|
|||||||
|
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 {
|
||||||
|
/**
|
||||||
|
* Get the server ID.
|
||||||
|
*
|
||||||
|
* @return The server ID.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
String getServerID();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the local server ID.
|
||||||
|
*
|
||||||
|
* @return The local server ID.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
String getLocalServerID();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the server profile.
|
||||||
|
*
|
||||||
|
* @return The profile.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
static ServerProfile load() {
|
||||||
|
return Eco.get().getServerProfile();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
package com.willfp.eco.core.data.keys;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* API to register persistent data keys.
|
|
||||||
*/
|
|
||||||
public interface KeyRegistry {
|
|
||||||
/**
|
|
||||||
* Register a persistent data key to be stored.
|
|
||||||
*
|
|
||||||
* @param key The key.
|
|
||||||
*/
|
|
||||||
void registerKey(@NotNull PersistentDataKey<?> key);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all registered keys.
|
|
||||||
*
|
|
||||||
* @return The keys.
|
|
||||||
*/
|
|
||||||
Set<PersistentDataKey<?>> getRegisteredKeys();
|
|
||||||
}
|
|
||||||
@@ -3,7 +3,9 @@ package com.willfp.eco.core.data.keys;
|
|||||||
import com.willfp.eco.core.Eco;
|
import com.willfp.eco.core.Eco;
|
||||||
import org.bukkit.NamespacedKey;
|
import org.bukkit.NamespacedKey;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -11,7 +13,7 @@ import java.util.Set;
|
|||||||
*
|
*
|
||||||
* @param <T> The type of the data.
|
* @param <T> The type of the data.
|
||||||
*/
|
*/
|
||||||
public class PersistentDataKey<T> {
|
public final class PersistentDataKey<T> {
|
||||||
/**
|
/**
|
||||||
* The key of the persistent data value.
|
* The key of the persistent data value.
|
||||||
*/
|
*/
|
||||||
@@ -25,7 +27,32 @@ public class PersistentDataKey<T> {
|
|||||||
/**
|
/**
|
||||||
* The persistent data key type.
|
* The persistent data key type.
|
||||||
*/
|
*/
|
||||||
private final PersistentDataKeyType type;
|
private final PersistentDataKeyType<T> type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the key uses local storage.
|
||||||
|
*/
|
||||||
|
private final boolean isLocal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new Persistent Data Key.
|
||||||
|
*
|
||||||
|
* @param key The key.
|
||||||
|
* @param type The data type.
|
||||||
|
* @param defaultValue The default value.
|
||||||
|
* @param isLocal If the key uses local storage.
|
||||||
|
*/
|
||||||
|
public PersistentDataKey(@NotNull final NamespacedKey key,
|
||||||
|
@NotNull final PersistentDataKeyType<T> type,
|
||||||
|
@NotNull final T defaultValue,
|
||||||
|
final boolean isLocal) {
|
||||||
|
this.key = key;
|
||||||
|
this.defaultValue = defaultValue;
|
||||||
|
this.type = type;
|
||||||
|
this.isLocal = isLocal;
|
||||||
|
|
||||||
|
Eco.get().registerPersistentKey(this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new Persistent Data Key.
|
* Create a new Persistent Data Key.
|
||||||
@@ -35,13 +62,14 @@ public class PersistentDataKey<T> {
|
|||||||
* @param defaultValue The default value.
|
* @param defaultValue The default value.
|
||||||
*/
|
*/
|
||||||
public PersistentDataKey(@NotNull final NamespacedKey key,
|
public PersistentDataKey(@NotNull final NamespacedKey key,
|
||||||
@NotNull final PersistentDataKeyType type,
|
@NotNull final PersistentDataKeyType<T> type,
|
||||||
@NotNull final T defaultValue) {
|
@NotNull final T defaultValue) {
|
||||||
this.key = key;
|
this.key = key;
|
||||||
this.defaultValue = defaultValue;
|
this.defaultValue = defaultValue;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
this.isLocal = false;
|
||||||
|
|
||||||
Eco.getHandler().getKeyRegistry().registerKey(this);
|
Eco.get().registerPersistentKey(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -53,15 +81,6 @@ public class PersistentDataKey<T> {
|
|||||||
+ '}';
|
+ '}';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all persistent data keys.
|
|
||||||
*
|
|
||||||
* @return The keys.
|
|
||||||
*/
|
|
||||||
public static Set<PersistentDataKey<?>> values() {
|
|
||||||
return Eco.getHandler().getKeyRegistry().getRegisteredKeys();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the key.
|
* Get the key.
|
||||||
*
|
*
|
||||||
@@ -85,7 +104,41 @@ public class PersistentDataKey<T> {
|
|||||||
*
|
*
|
||||||
* @return The key type.
|
* @return The key type.
|
||||||
*/
|
*/
|
||||||
public PersistentDataKeyType getType() {
|
public PersistentDataKeyType<T> getType() {
|
||||||
return this.type;
|
return this.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get if the key uses local storage.
|
||||||
|
*
|
||||||
|
* @return If the key uses local storage.
|
||||||
|
*/
|
||||||
|
public boolean isLocal() {
|
||||||
|
return this.isLocal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,125 @@
|
|||||||
package com.willfp.eco.core.data.keys;
|
package com.willfp.eco.core.data.keys;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All storable data key types.
|
* All storable data key types.
|
||||||
|
*
|
||||||
|
* @param <T> The type.
|
||||||
*/
|
*/
|
||||||
public enum PersistentDataKeyType {
|
public final class PersistentDataKeyType<T> {
|
||||||
|
/**
|
||||||
|
* The registered key types.
|
||||||
|
*/
|
||||||
|
private static final List<PersistentDataKeyType<?>> VALUES = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* String.
|
* String.
|
||||||
*/
|
*/
|
||||||
STRING,
|
public static final PersistentDataKeyType<String> STRING = new PersistentDataKeyType<>("STRING");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Boolean.
|
* Boolean.
|
||||||
*/
|
*/
|
||||||
BOOLEAN,
|
public static final PersistentDataKeyType<Boolean> BOOLEAN = new PersistentDataKeyType<>("BOOLEAN");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Integer.
|
* Int.
|
||||||
*/
|
*/
|
||||||
INT,
|
public static final PersistentDataKeyType<Integer> INT = new PersistentDataKeyType<>("INT");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Double.
|
* Double.
|
||||||
*/
|
*/
|
||||||
DOUBLE
|
public static final PersistentDataKeyType<Double> DOUBLE = new PersistentDataKeyType<>("DOUBLE");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String List.
|
||||||
|
*/
|
||||||
|
public static final PersistentDataKeyType<List<String>> STRING_LIST = new PersistentDataKeyType<>("STRING_LIST");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Config.
|
||||||
|
*/
|
||||||
|
public static final PersistentDataKeyType<Config> CONFIG = new PersistentDataKeyType<>("CONFIG");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Big Decimal.
|
||||||
|
*/
|
||||||
|
public static final PersistentDataKeyType<BigDecimal> BIG_DECIMAL = new PersistentDataKeyType<>("BIG_DECIMAL");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the key type.
|
||||||
|
*/
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the name of the key type.
|
||||||
|
*
|
||||||
|
* @return The name.
|
||||||
|
*/
|
||||||
|
public String name() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new PersistentDataKeyType.
|
||||||
|
*
|
||||||
|
* @param name The name.
|
||||||
|
*/
|
||||||
|
private PersistentDataKeyType(@NotNull final String name) {
|
||||||
|
VALUES.add(this);
|
||||||
|
|
||||||
|
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,13 +1,28 @@
|
|||||||
package com.willfp.eco.core.display;
|
package com.willfp.eco.core.display;
|
||||||
|
|
||||||
|
import com.willfp.eco.core.Eco;
|
||||||
|
import com.willfp.eco.core.fast.FastItemStack;
|
||||||
|
import com.willfp.eco.core.integrations.guidetection.GUIDetectionManager;
|
||||||
|
import com.willfp.eco.util.NamespacedKeyUtils;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.Inventory;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.bukkit.persistence.PersistentDataType;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class to manage client-side item display.
|
* Utility class to manage client-side item display.
|
||||||
|
* <p>
|
||||||
|
* Packet display is not done on the main thread, so make sure
|
||||||
|
* all your modules are thread-safe.
|
||||||
*/
|
*/
|
||||||
public final class Display {
|
public final class Display {
|
||||||
/**
|
/**
|
||||||
@@ -16,9 +31,14 @@ public final class Display {
|
|||||||
public static final String PREFIX = "§z";
|
public static final String PREFIX = "§z";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The display handler.
|
* All registered modules.
|
||||||
*/
|
*/
|
||||||
private static DisplayHandler handler = null;
|
private static final Map<Integer, List<DisplayModule>> REGISTERED_MODULES = new TreeMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The finalize key.
|
||||||
|
*/
|
||||||
|
private static final NamespacedKey FINALIZE_KEY = NamespacedKeyUtils.createEcoKey("finalized");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display on ItemStacks.
|
* Display on ItemStacks.
|
||||||
@@ -39,7 +59,51 @@ public final class Display {
|
|||||||
*/
|
*/
|
||||||
public static ItemStack display(@NotNull final ItemStack itemStack,
|
public static ItemStack display(@NotNull final ItemStack itemStack,
|
||||||
@Nullable final Player player) {
|
@Nullable final Player player) {
|
||||||
return handler.display(itemStack, player);
|
Map<String, Object[]> pluginVarArgs = new HashMap<>();
|
||||||
|
|
||||||
|
for (List<DisplayModule> modules : REGISTERED_MODULES.values()) {
|
||||||
|
for (DisplayModule module : modules) {
|
||||||
|
pluginVarArgs.put(module.getPluginName(), module.generateVarArgs(itemStack));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Display.revert(itemStack);
|
||||||
|
|
||||||
|
if (!Eco.get().getEcoPlugin().getConfigYml().getBool("display-without-meta")) {
|
||||||
|
if (!itemStack.hasItemMeta()) {
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack original = itemStack.clone();
|
||||||
|
Inventory inventory = player == null ? null : player.getOpenInventory().getTopInventory();
|
||||||
|
boolean inInventory = inventory != null && inventory.contains(original);
|
||||||
|
boolean inGui = player != null && GUIDetectionManager.hasGUIOpen(player);
|
||||||
|
|
||||||
|
DisplayProperties properties = new DisplayProperties(
|
||||||
|
inInventory,
|
||||||
|
inGui,
|
||||||
|
original
|
||||||
|
);
|
||||||
|
|
||||||
|
for (List<DisplayModule> modules : REGISTERED_MODULES.values()) {
|
||||||
|
for (DisplayModule module : modules) {
|
||||||
|
Object[] varargs = pluginVarArgs.get(module.getPluginName());
|
||||||
|
|
||||||
|
if (varargs == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.display(itemStack, varargs);
|
||||||
|
|
||||||
|
if (player != null) {
|
||||||
|
module.display(itemStack, player, varargs);
|
||||||
|
module.display(itemStack, player, properties, varargs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return itemStack;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -60,7 +124,7 @@ public final class Display {
|
|||||||
* @return The ItemStack.
|
* @return The ItemStack.
|
||||||
*/
|
*/
|
||||||
public static ItemStack displayAndFinalize(@NotNull final ItemStack itemStack,
|
public static ItemStack displayAndFinalize(@NotNull final ItemStack itemStack,
|
||||||
@Nullable final Player player) {
|
@Nullable final Player player) {
|
||||||
return finalize(display(itemStack, player));
|
return finalize(display(itemStack, player));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +135,25 @@ public final class Display {
|
|||||||
* @return The ItemStack.
|
* @return The ItemStack.
|
||||||
*/
|
*/
|
||||||
public static ItemStack revert(@NotNull final ItemStack itemStack) {
|
public static ItemStack revert(@NotNull final ItemStack itemStack) {
|
||||||
return handler.revert(itemStack);
|
if (Display.isFinalized(itemStack)) {
|
||||||
|
Display.unfinalize(itemStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
FastItemStack fast = FastItemStack.wrap(itemStack);
|
||||||
|
|
||||||
|
List<String> lore = fast.getLore();
|
||||||
|
|
||||||
|
if (!lore.isEmpty() && lore.removeIf(line -> line.startsWith(Display.PREFIX))) {
|
||||||
|
fast.setLore(lore);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (List<DisplayModule> modules : REGISTERED_MODULES.values()) {
|
||||||
|
for (DisplayModule module : modules) {
|
||||||
|
module.revert(itemStack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return itemStack;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -81,7 +163,15 @@ public final class Display {
|
|||||||
* @return The ItemStack.
|
* @return The ItemStack.
|
||||||
*/
|
*/
|
||||||
public static ItemStack finalize(@NotNull final ItemStack itemStack) {
|
public static ItemStack finalize(@NotNull final ItemStack itemStack) {
|
||||||
return handler.finalize(itemStack);
|
if (itemStack.getType().getMaxStackSize() > 1) {
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
FastItemStack.wrap(itemStack)
|
||||||
|
.getPersistentDataContainer()
|
||||||
|
.set(FINALIZE_KEY, PersistentDataType.INTEGER, 1);
|
||||||
|
|
||||||
|
return itemStack;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -91,7 +181,11 @@ public final class Display {
|
|||||||
* @return The ItemStack.
|
* @return The ItemStack.
|
||||||
*/
|
*/
|
||||||
public static ItemStack unfinalize(@NotNull final ItemStack itemStack) {
|
public static ItemStack unfinalize(@NotNull final ItemStack itemStack) {
|
||||||
return handler.unfinalize(itemStack);
|
FastItemStack.wrap(itemStack)
|
||||||
|
.getPersistentDataContainer()
|
||||||
|
.remove(FINALIZE_KEY);
|
||||||
|
|
||||||
|
return itemStack;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -101,7 +195,9 @@ public final class Display {
|
|||||||
* @return If finalized.
|
* @return If finalized.
|
||||||
*/
|
*/
|
||||||
public static boolean isFinalized(@NotNull final ItemStack itemStack) {
|
public static boolean isFinalized(@NotNull final ItemStack itemStack) {
|
||||||
return handler.isFinalized(itemStack);
|
return FastItemStack.wrap(itemStack)
|
||||||
|
.getPersistentDataContainer()
|
||||||
|
.has(FINALIZE_KEY, PersistentDataType.INTEGER);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -110,69 +206,25 @@ public final class Display {
|
|||||||
* @param module The module.
|
* @param module The module.
|
||||||
*/
|
*/
|
||||||
public static void registerDisplayModule(@NotNull final DisplayModule module) {
|
public static void registerDisplayModule(@NotNull final DisplayModule module) {
|
||||||
handler.registerDisplayModule(module);
|
List<DisplayModule> modules = REGISTERED_MODULES.getOrDefault(
|
||||||
|
module.getWeight(),
|
||||||
|
new ArrayList<>()
|
||||||
|
);
|
||||||
|
|
||||||
|
modules.add(module);
|
||||||
|
|
||||||
|
REGISTERED_MODULES.put(module.getWeight(), modules);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the display system.
|
* Unregister a display module.
|
||||||
*
|
*
|
||||||
* @param handler The handler.
|
* @param module The module.
|
||||||
*/
|
*/
|
||||||
@ApiStatus.Internal
|
public static void unregisterDisplayModule(@NotNull final DisplayModule module) {
|
||||||
public static void init(@NotNull final DisplayHandler handler) {
|
for (List<DisplayModule> modules : REGISTERED_MODULES.values()) {
|
||||||
if (Display.handler != null) {
|
modules.remove(module);
|
||||||
throw new IllegalArgumentException("Already Initialized!");
|
|
||||||
}
|
}
|
||||||
Display.handler = handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extremely janky method - also internal, so don't use it. <b>This method is
|
|
||||||
* NOT part of the API and may be removed at any time!</b>
|
|
||||||
* <p>
|
|
||||||
* This calls a display module with the specified parameters, now
|
|
||||||
* you might ask why I need a static java method when the DisplayHandler
|
|
||||||
* implementation could just call it itself? Well, kotlin doesn't really
|
|
||||||
* like dealing with vararg ambiguity, and so while kotlin can't figure out
|
|
||||||
* what is and isn't a vararg when I call display with a player, java can.
|
|
||||||
* <p>
|
|
||||||
* Because of this, I need to have this part of the code in java.
|
|
||||||
*
|
|
||||||
* <b>Don't call this method as part of your plugins!</b>
|
|
||||||
* <p>
|
|
||||||
* No, seriously - don't. This skips a bunch of checks and you'll almost
|
|
||||||
* definitely break something.
|
|
||||||
*
|
|
||||||
* @param module The display module.
|
|
||||||
* @param itemStack The ItemStack.
|
|
||||||
* @param player The player.
|
|
||||||
* @param args The args.
|
|
||||||
*/
|
|
||||||
@ApiStatus.Internal
|
|
||||||
public static void callDisplayModule(@NotNull final DisplayModule module,
|
|
||||||
@NotNull final ItemStack itemStack,
|
|
||||||
@Nullable final Player player,
|
|
||||||
@NotNull final Object... args) {
|
|
||||||
module.display(itemStack, args);
|
|
||||||
if (player != null) {
|
|
||||||
module.display(itemStack, player, args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the display handler.
|
|
||||||
* <p>
|
|
||||||
* Internal API component, you will cause bugs if you create your own handler.
|
|
||||||
*
|
|
||||||
* @param handler The handler.
|
|
||||||
*/
|
|
||||||
@ApiStatus.Internal
|
|
||||||
public static void setHandler(@NotNull final DisplayHandler handler) {
|
|
||||||
if (Display.handler != null) {
|
|
||||||
throw new IllegalStateException("Display already initialized!");
|
|
||||||
}
|
|
||||||
|
|
||||||
Display.handler = handler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Display() {
|
private Display() {
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
package com.willfp.eco.core.display;
|
|
||||||
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface for display implementations.
|
|
||||||
*/
|
|
||||||
public interface DisplayHandler {
|
|
||||||
/**
|
|
||||||
* Register display module.
|
|
||||||
*
|
|
||||||
* @param module The module.
|
|
||||||
*/
|
|
||||||
void registerDisplayModule(@NotNull DisplayModule module);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Display on ItemStacks.
|
|
||||||
*
|
|
||||||
* @param itemStack The item.
|
|
||||||
* @param player The player.
|
|
||||||
* @return The ItemStack.
|
|
||||||
*/
|
|
||||||
ItemStack display(@NotNull ItemStack itemStack,
|
|
||||||
@Nullable Player player);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Revert on ItemStacks.
|
|
||||||
*
|
|
||||||
* @param itemStack The item.
|
|
||||||
* @return The ItemStack.
|
|
||||||
*/
|
|
||||||
ItemStack revert(@NotNull ItemStack itemStack);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finalize an ItemStacks.
|
|
||||||
*
|
|
||||||
* @param itemStack The item.
|
|
||||||
* @return The ItemStack.
|
|
||||||
*/
|
|
||||||
ItemStack finalize(@NotNull ItemStack itemStack);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unfinalize an ItemStacks.
|
|
||||||
*
|
|
||||||
* @param itemStack The item.
|
|
||||||
* @return The ItemStack.
|
|
||||||
*/
|
|
||||||
ItemStack unfinalize(@NotNull ItemStack itemStack);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If an item is finalized.
|
|
||||||
*
|
|
||||||
* @param itemStack The item.
|
|
||||||
* @return If finalized.
|
|
||||||
*/
|
|
||||||
boolean isFinalized(@NotNull ItemStack itemStack);
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package com.willfp.eco.core.display;
|
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 org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -9,12 +8,19 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Class for all plugin-specific client-side item display modules.
|
* Class for all plugin-specific client-side item display modules.
|
||||||
|
* <p>
|
||||||
|
* Display modules are called in the netty thread, so make sure they are thread-safe.
|
||||||
*/
|
*/
|
||||||
public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
|
public abstract class DisplayModule {
|
||||||
/**
|
/**
|
||||||
* The priority of the module.
|
* The priority of the module.
|
||||||
*/
|
*/
|
||||||
private final DisplayPriority priority;
|
private final int weight;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The plugin.
|
||||||
|
*/
|
||||||
|
private final EcoPlugin plugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new display module.
|
* Create a new display module.
|
||||||
@@ -24,8 +30,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -52,6 +69,21 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
|
|||||||
// Technically optional.
|
// Technically optional.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display an item.
|
||||||
|
*
|
||||||
|
* @param itemStack The item.
|
||||||
|
* @param player The player.
|
||||||
|
* @param properties The properties.
|
||||||
|
* @param args Optional args for display.
|
||||||
|
*/
|
||||||
|
public void display(@NotNull final ItemStack itemStack,
|
||||||
|
@Nullable final Player player,
|
||||||
|
@NotNull final DisplayProperties properties,
|
||||||
|
@NotNull final Object... args) {
|
||||||
|
// Technically optional.
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Revert an item.
|
* Revert an item.
|
||||||
*
|
*
|
||||||
@@ -77,15 +109,24 @@ 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.
|
* Get the display weight.
|
||||||
*
|
*
|
||||||
* @return The priority.
|
* @return The weight.
|
||||||
*/
|
*/
|
||||||
public DisplayPriority getPriority() {
|
public int getWeight() {
|
||||||
return this.priority;
|
return this.weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the plugin.
|
||||||
|
*
|
||||||
|
* @return The plugin.
|
||||||
|
*/
|
||||||
|
public EcoPlugin getPlugin() {
|
||||||
|
return plugin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,23 +4,54 @@ 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.
|
||||||
|
*
|
||||||
|
* @deprecated Will never be used.
|
||||||
|
*/
|
||||||
|
@Deprecated(since = "6.53.0", forRemoval = true)
|
||||||
|
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,129 @@
|
|||||||
|
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);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new custom goal.
|
||||||
|
*/
|
||||||
|
protected CustomGoal() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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,64 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
TestableEntity entity = Entities.lookup(config.getString("entity"));
|
||||||
|
|
||||||
|
return new EntityGoalAvoidEntity(
|
||||||
|
entity,
|
||||||
|
config.getDouble("distance"),
|
||||||
|
config.getDouble("slowSpeed"),
|
||||||
|
config.getDouble("fastSpeed")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public NamespacedKey getKey() {
|
||||||
|
return NamespacedKey.minecraft("avoid_entity");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new EntityGoalBreakDoors(
|
||||||
|
config.getInt("ticks")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@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,48 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new EntityGoalBreed(
|
||||||
|
config.getDouble("speed")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public NamespacedKey getKey() {
|
||||||
|
return NamespacedKey.minecraft("breed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user