mirror of
https://github.com/IntellectualSites/PlotSquared.git
synced 2025-04-23 19:56:24 +02:00
Compare commits
1806 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
52823f5024 | ||
![]() |
1326c257a0 | ||
![]() |
fc3137cd96 | ||
![]() |
c46cc73f52 | ||
![]() |
f11acacedd | ||
![]() |
d1bac90745 | ||
![]() |
e98f628d34 | ||
![]() |
b2ab61559c | ||
![]() |
dd6eb8e74f | ||
![]() |
97cdd03ea4 | ||
![]() |
f5118e6802 | ||
![]() |
94ca5cf679 | ||
![]() |
5a55a1f602 | ||
![]() |
ed33635a15 | ||
![]() |
888682e5d0 | ||
![]() |
72bb5f00b0 | ||
![]() |
773fd6f59f | ||
![]() |
5cce86d924 | ||
![]() |
84567bcb00 | ||
![]() |
d7c2ab1d16 | ||
![]() |
0d359ade0c | ||
![]() |
ffbec24290 | ||
![]() |
ab357deb48 | ||
![]() |
6130c3dfa5 | ||
![]() |
5787588500 | ||
![]() |
b40383b5a4 | ||
![]() |
be8903128d | ||
![]() |
08800ec16d | ||
![]() |
83e274ff9f | ||
![]() |
0dd8b1053c | ||
![]() |
0558fcf5d5 | ||
![]() |
c45bbe3ec5 | ||
![]() |
07e598e48f | ||
![]() |
f6f00dfcda | ||
![]() |
63a6bdc1d6 | ||
![]() |
abbac057ed | ||
![]() |
c978322036 | ||
![]() |
39d2f1a72c | ||
![]() |
86919b8841 | ||
![]() |
00722bc463 | ||
![]() |
6a34a1996f | ||
![]() |
1d201b04ba | ||
![]() |
e887a59158 | ||
![]() |
d1b8f652a7 | ||
![]() |
4aa7bc51bc | ||
![]() |
0f0030916f | ||
![]() |
bbf1e4fe61 | ||
![]() |
febac6fa40 | ||
![]() |
99ee8a780d | ||
![]() |
577a0d8ed9 | ||
![]() |
02ae14894a | ||
![]() |
78dbe7fbbc | ||
![]() |
669293566b | ||
![]() |
707c7be5bd | ||
![]() |
becd8c4eaf | ||
![]() |
339ca8e30f | ||
![]() |
742d78a505 | ||
![]() |
120bf37196 | ||
![]() |
2a40a6b35e | ||
![]() |
ea1f35b45a | ||
![]() |
15e63378a7 | ||
![]() |
f3bc504a6f | ||
![]() |
3a8fae47a0 | ||
![]() |
70cb1cd100 | ||
![]() |
2067cc1670 | ||
![]() |
e6338976dd | ||
![]() |
90ebd5d5ed | ||
![]() |
c973ee8649 | ||
![]() |
c1543f034c | ||
![]() |
6baf339ecb | ||
![]() |
11906ef1c9 | ||
![]() |
ee8902154a | ||
![]() |
b5bc1988e5 | ||
![]() |
2147012beb | ||
![]() |
52bb561689 | ||
![]() |
25ce7a83f1 | ||
![]() |
55c8a590e7 | ||
![]() |
28bd993680 | ||
![]() |
8330f37d8a | ||
![]() |
985fae65b6 | ||
![]() |
db2d590e8e | ||
![]() |
c8d356783a | ||
![]() |
4947450ff0 | ||
![]() |
de4e91ff62 | ||
![]() |
fe5e3d5f6d | ||
![]() |
b8b3098022 | ||
![]() |
0ae8fc46b8 | ||
![]() |
e0762f63a8 | ||
![]() |
9f3850000c | ||
![]() |
76c6be9ba7 | ||
![]() |
308a5aa781 | ||
![]() |
e244527538 | ||
![]() |
11dd013333 | ||
![]() |
b740d5854c | ||
![]() |
d5445cfbef | ||
![]() |
3effaefda7 | ||
![]() |
49b19e0eaf | ||
![]() |
caef3a923b | ||
![]() |
d4c3ceaf2b | ||
![]() |
25e6aecf13 | ||
![]() |
33c11fdee9 | ||
![]() |
316dd92667 | ||
![]() |
e53d2ac449 | ||
![]() |
5786e8cc7a | ||
![]() |
1b717c9b10 | ||
![]() |
35abae99ca | ||
![]() |
d1a85982fb | ||
![]() |
3446b913cd | ||
![]() |
8b8fd6aab7 | ||
![]() |
520bb64eca | ||
![]() |
60d266b2d7 | ||
![]() |
8deeef4f7d | ||
![]() |
9b0b071c0c | ||
![]() |
81a3f1098d | ||
![]() |
efc248dcdb | ||
![]() |
476f3d328d | ||
![]() |
69f5f88183 | ||
![]() |
6df63f7fc7 | ||
![]() |
295b8a0135 | ||
![]() |
fcc5bc5473 | ||
![]() |
408b834376 | ||
![]() |
986812b9e4 | ||
![]() |
8d4333ad9d | ||
![]() |
9ff9097ff9 | ||
![]() |
1ef424a2f1 | ||
![]() |
9fd96dbaa2 | ||
![]() |
b0a4e11c46 | ||
![]() |
77bce43ace | ||
![]() |
cba1927cc7 | ||
![]() |
3d19c5c2ad | ||
![]() |
e0eff15694 | ||
![]() |
0bdeeea83b | ||
![]() |
6f96daae56 | ||
![]() |
d1021d19da | ||
![]() |
ee589ac7f0 | ||
![]() |
3b747ffecf | ||
![]() |
4e5a2b9f96 | ||
![]() |
aeb4350ccb | ||
![]() |
9609990832 | ||
![]() |
0e4319b757 | ||
![]() |
c8f4907f77 | ||
![]() |
dcf98c2298 | ||
![]() |
ae59c7442f | ||
![]() |
98708118d8 | ||
![]() |
276d8f8e1e | ||
![]() |
87f89541b5 | ||
![]() |
93f6de7029 | ||
![]() |
73d2686b17 | ||
![]() |
c446a95b07 | ||
![]() |
3676e1df35 | ||
![]() |
12e2705260 | ||
![]() |
31e777a03a | ||
![]() |
7f436c405b | ||
![]() |
4d4d2ab087 | ||
![]() |
91017acce4 | ||
![]() |
e90fd231d9 | ||
![]() |
cd9f0789de | ||
![]() |
5f4c8d92df | ||
![]() |
263cb47a21 | ||
![]() |
005600c99e | ||
![]() |
26bec7fe2f | ||
![]() |
f4b886d977 | ||
![]() |
c09d0d882e | ||
![]() |
312cb2996c | ||
![]() |
f218902581 | ||
![]() |
f27009216c | ||
![]() |
dda52ebc2e | ||
![]() |
9ac8d38bab | ||
![]() |
6a54328f7d | ||
![]() |
7279862def | ||
![]() |
08ce4c872c | ||
![]() |
2b0c5b1e21 | ||
![]() |
3d5c694daa | ||
![]() |
d153232969 | ||
![]() |
bb0aa8d5cc | ||
![]() |
d69f3b0893 | ||
![]() |
565838ad43 | ||
![]() |
8b52461271 | ||
![]() |
d08381dfed | ||
![]() |
b6c45f2df3 | ||
![]() |
b9479405e1 | ||
![]() |
a238ff19bf | ||
![]() |
c93b08d0c7 | ||
![]() |
1470b7117a | ||
![]() |
7cbc67f4fc | ||
![]() |
0a76bbb2b0 | ||
![]() |
09cc59a1c1 | ||
![]() |
bf646be482 | ||
![]() |
cc7e17960b | ||
![]() |
3c75b170f0 | ||
![]() |
a79c474957 | ||
![]() |
4bb480a238 | ||
![]() |
9ffa935c0c | ||
![]() |
0a32268784 | ||
![]() |
ae3b8c06f6 | ||
![]() |
713c4ad0d2 | ||
![]() |
48386c0828 | ||
![]() |
625b3921e1 | ||
![]() |
48aa37d173 | ||
![]() |
2c2314e95c | ||
![]() |
5eb2fc3ad0 | ||
![]() |
82cd9a092c | ||
![]() |
62754362c2 | ||
![]() |
2e9dfd6f6f | ||
![]() |
fc9fe1462f | ||
![]() |
41f546ca6b | ||
![]() |
d037da33cb | ||
![]() |
dc2d08c67e | ||
![]() |
96dfc27411 | ||
![]() |
171d2e5e99 | ||
![]() |
4433892431 | ||
![]() |
98a07dad1b | ||
![]() |
0ffa22b7a6 | ||
![]() |
60a0129fe9 | ||
![]() |
d5f8a0842b | ||
![]() |
f7d55ce105 | ||
![]() |
85911646f3 | ||
![]() |
8b75dece69 | ||
![]() |
7d6e515ba8 | ||
![]() |
13d7357c85 | ||
![]() |
16e26b910c | ||
![]() |
faadebd30e | ||
![]() |
2aeacb3dcf | ||
![]() |
9db7791835 | ||
![]() |
f49ddb819d | ||
![]() |
d71c62771e | ||
![]() |
a6aaa9538f | ||
![]() |
0974fb2834 | ||
![]() |
8982b33b6c | ||
![]() |
a7b3b3b7df | ||
![]() |
888bb20e78 | ||
![]() |
b11bb6fa22 | ||
![]() |
e5764b958d | ||
![]() |
bfe3141ff1 | ||
![]() |
73c82deeb0 | ||
![]() |
38682ecff6 | ||
![]() |
6a54dc7eff | ||
![]() |
8454c29c91 | ||
![]() |
b2c9311a47 | ||
![]() |
c4aa497a2b | ||
![]() |
c13f544390 | ||
![]() |
c28177d6af | ||
![]() |
8a80f252cf | ||
![]() |
93571c72d1 | ||
![]() |
6fd7379221 | ||
![]() |
dc5c80d812 | ||
![]() |
96e9a61e7c | ||
![]() |
b9bd9b81e6 | ||
![]() |
ec77812879 | ||
![]() |
efc2083798 | ||
![]() |
3a6f845c01 | ||
![]() |
7efd42ae45 | ||
![]() |
f43f4cbf5d | ||
![]() |
104cc4b7a4 | ||
![]() |
218be43143 | ||
![]() |
308dba5601 | ||
![]() |
5f233bb5d1 | ||
![]() |
5e188d114f | ||
![]() |
660e05d27f | ||
![]() |
4c0ad148bf | ||
![]() |
5c7bfb988c | ||
![]() |
b46f486680 | ||
![]() |
05797d0c78 | ||
![]() |
36ef2cf9ba | ||
![]() |
26ec31a012 | ||
![]() |
fd4a542062 | ||
![]() |
dc13f2565f | ||
![]() |
9f632af0ae | ||
![]() |
d698c6a1e5 | ||
![]() |
40e1bd9897 | ||
![]() |
75f31c5bf6 | ||
![]() |
954c813cef | ||
![]() |
05e055e9cf | ||
![]() |
2ea21c150f | ||
![]() |
c2fd4edad5 | ||
![]() |
78b8696778 | ||
![]() |
e653961385 | ||
![]() |
b21d12fd52 | ||
![]() |
7557df96c7 | ||
![]() |
61797c3aff | ||
![]() |
78125ff1e2 | ||
![]() |
d7c8715b25 | ||
![]() |
34f005c244 | ||
![]() |
6fbd1376ca | ||
![]() |
951767dc64 | ||
![]() |
16928b05f1 | ||
![]() |
fff14b05cb | ||
![]() |
e619c867e9 | ||
![]() |
543284e016 | ||
![]() |
0d78ba5f35 | ||
![]() |
9ba2b62fc2 | ||
![]() |
f10ee27fdd | ||
![]() |
3278ce1fe9 | ||
![]() |
fefb0334bd | ||
![]() |
d06a827e31 | ||
![]() |
10bb520f3a | ||
![]() |
126aa53b61 | ||
![]() |
ac71046feb | ||
![]() |
7c290e6bd0 | ||
![]() |
4d297cc829 | ||
![]() |
5ab410a5c5 | ||
![]() |
1f28bac955 | ||
![]() |
92c54de5e9 | ||
![]() |
ff5d79699d | ||
![]() |
a0594c19ee | ||
![]() |
da41c136fe | ||
![]() |
6a5859ee0f | ||
![]() |
59e0b4b67a | ||
![]() |
5fc153d896 | ||
![]() |
a003836dbc | ||
![]() |
42bf413528 | ||
![]() |
827f46566c | ||
![]() |
6f4d2f6d5a | ||
![]() |
6073b96317 | ||
![]() |
74a490f9f0 | ||
![]() |
3a752db698 | ||
![]() |
7cdde5a822 | ||
![]() |
8b6e7b2f2b | ||
![]() |
06f0b42a97 | ||
![]() |
9a85080bf6 | ||
![]() |
d14d2caa2d | ||
![]() |
bcfe7c58dd | ||
![]() |
289f0f3bfd | ||
![]() |
6fc4005c72 | ||
![]() |
8f7c2e4c02 | ||
![]() |
b43d08f4aa | ||
![]() |
2c55c6a92e | ||
![]() |
31f48cc7d1 | ||
![]() |
4b77f1ab28 | ||
![]() |
7cc38b5fa8 | ||
![]() |
0c76d08b10 | ||
![]() |
9c474570c8 | ||
![]() |
7e1d56c849 | ||
![]() |
07d0f124b4 | ||
![]() |
8d6c621763 | ||
![]() |
cef7098014 | ||
![]() |
e1efa7266e | ||
![]() |
f363941719 | ||
![]() |
25095f4546 | ||
![]() |
fd0c2050d8 | ||
![]() |
07fdc94dd8 | ||
![]() |
b501a81e21 | ||
![]() |
eb334b3aac | ||
![]() |
a77a51b6f2 | ||
![]() |
7d981bc610 | ||
![]() |
3eb485e900 | ||
![]() |
9f4af889f7 | ||
![]() |
2559c889e2 | ||
![]() |
2cf268b99c | ||
![]() |
e6fad8309c | ||
![]() |
7551450cf9 | ||
![]() |
e042566bb7 | ||
![]() |
1f26808c7b | ||
![]() |
a7026047d0 | ||
![]() |
af2613202d | ||
![]() |
3da1e9255a | ||
![]() |
9394906a79 | ||
![]() |
d881cb6084 | ||
![]() |
b9d43897af | ||
![]() |
76b58485a9 | ||
![]() |
7002df0bc7 | ||
![]() |
958aac3cb1 | ||
![]() |
a93402e27b | ||
![]() |
92f41f43c5 | ||
![]() |
392ee9fa07 | ||
![]() |
8859871e89 | ||
![]() |
93d99630a9 | ||
![]() |
47ae79e123 | ||
![]() |
f9ad00c2c8 | ||
![]() |
566af259db | ||
![]() |
d9a6431078 | ||
![]() |
e9c9375e78 | ||
![]() |
7c99c8aabf | ||
![]() |
88eb8f88a7 | ||
![]() |
fd118c2c37 | ||
![]() |
858b6b5471 | ||
![]() |
f086826942 | ||
![]() |
9c84dc2bc0 | ||
![]() |
cba0f3ac1f | ||
![]() |
b9a130ab00 | ||
![]() |
688056352b | ||
![]() |
2a40f52dea | ||
![]() |
3ed369de19 | ||
![]() |
bec51401a3 | ||
![]() |
109f884b5f | ||
![]() |
8f3fa419c4 | ||
![]() |
a9f08bc885 | ||
![]() |
a8923ec729 | ||
![]() |
4eafd043a3 | ||
![]() |
826cc8c835 | ||
![]() |
d1dbf777a4 | ||
![]() |
823e78377b | ||
![]() |
87a2e81ec3 | ||
![]() |
88775334b7 | ||
![]() |
e126547e97 | ||
![]() |
c1163cdb2e | ||
![]() |
30d06b7801 | ||
![]() |
a5cf7bf2c2 | ||
![]() |
3d4d413de8 | ||
![]() |
b97e843849 | ||
![]() |
48c7a3e94e | ||
![]() |
7263290bbe | ||
![]() |
e99c4e3289 | ||
![]() |
87cb26189f | ||
![]() |
2dae336a5f | ||
![]() |
258ed1469b | ||
![]() |
6f3eabba0e | ||
![]() |
804228fa6c | ||
![]() |
be85708e5a | ||
![]() |
f2368f97df | ||
![]() |
df87bcb743 | ||
![]() |
5653d0f175 | ||
![]() |
b022a97196 | ||
![]() |
cb596ee6ea | ||
![]() |
4e391136c0 | ||
![]() |
a6a0e1d12f | ||
![]() |
d2776eed5a | ||
![]() |
6528c60f4d | ||
![]() |
7ee46be2ac | ||
![]() |
13bc231091 | ||
![]() |
55d1a40394 | ||
![]() |
d70f99b489 | ||
![]() |
fde9735da2 | ||
![]() |
20f0aa3656 | ||
![]() |
0b7bf2d26d | ||
![]() |
f10e38af63 | ||
![]() |
21727ebfc7 | ||
![]() |
e322ee85fd | ||
![]() |
541255fe7e | ||
![]() |
20c2f36f6c | ||
![]() |
744f7a18ae | ||
![]() |
18eece0b71 | ||
![]() |
4f12dcf966 | ||
![]() |
ee832528db | ||
![]() |
bb5d6c91da | ||
![]() |
6d4adecb32 | ||
![]() |
c37b13dcb3 | ||
![]() |
086dac2ea4 | ||
![]() |
b2b8598b5b | ||
![]() |
61e5d9f1b6 | ||
![]() |
c8989b3332 | ||
![]() |
9f54472dd6 | ||
![]() |
115932c65a | ||
![]() |
04821f777e | ||
![]() |
cfae804780 | ||
![]() |
4568b17c54 | ||
![]() |
7bc76a3824 | ||
![]() |
4b8180807c | ||
![]() |
d77a8c8fa4 | ||
![]() |
27a8fcd739 | ||
![]() |
c25a0c65a2 | ||
![]() |
b224a8d1b8 | ||
![]() |
87d134215f | ||
![]() |
93e280dba4 | ||
![]() |
732f79bbfc | ||
![]() |
8e5e33eec2 | ||
![]() |
da3fb1abec | ||
![]() |
62d6b21081 | ||
![]() |
4caaead7ee | ||
![]() |
be38086f6c | ||
![]() |
c18b0f943c | ||
![]() |
f036980dc5 | ||
![]() |
0e4f54e9c0 | ||
![]() |
7a3d5bd737 | ||
![]() |
2ab1973668 | ||
![]() |
387c6e79ba | ||
![]() |
e3e00d34ef | ||
![]() |
40e651188e | ||
![]() |
b2915d9bd7 | ||
![]() |
6ec136a03d | ||
![]() |
a8fc6662e0 | ||
![]() |
fb8e749411 | ||
![]() |
4b26a7e300 | ||
![]() |
8a53b41b52 | ||
![]() |
daa8ffc38f | ||
![]() |
34f0236e9f | ||
![]() |
8f0ae7e51d | ||
![]() |
2988ad6b11 | ||
![]() |
252d6a2866 | ||
![]() |
b8c9ae2b0b | ||
![]() |
bfe2dda5b1 | ||
![]() |
33a79595af | ||
![]() |
eb2848e5d7 | ||
![]() |
da4ae9f4f5 | ||
![]() |
b841a7c03b | ||
![]() |
4ee5e3d134 | ||
![]() |
0e05935ad4 | ||
![]() |
78a775530a | ||
![]() |
dd36036334 | ||
![]() |
3b2a04e4db | ||
![]() |
5ab8d50b86 | ||
![]() |
391476ba26 | ||
![]() |
25a69f4ca0 | ||
![]() |
c8c946cc10 | ||
![]() |
a405611b3a | ||
![]() |
fd4cec39c4 | ||
![]() |
e7fa057abe | ||
![]() |
a86c06bb81 | ||
![]() |
9afaead81c | ||
![]() |
6e7bd0a536 | ||
![]() |
89e17bb468 | ||
![]() |
8fc9e0b13f | ||
![]() |
6ad51bba65 | ||
![]() |
9d396fa91f | ||
![]() |
a8c3ac6cee | ||
![]() |
9a9365a04d | ||
![]() |
c9b012ea5b | ||
![]() |
9dd35e87d6 | ||
![]() |
82f0b4194f | ||
![]() |
3b27b6c850 | ||
![]() |
1e41734826 | ||
![]() |
a83a79c17e | ||
![]() |
8a77d5a450 | ||
![]() |
2676b76107 | ||
![]() |
51ff043af9 | ||
![]() |
fbde60fcf9 | ||
![]() |
a0557112a1 | ||
![]() |
6d71e0f8be | ||
![]() |
62e17f5fc5 | ||
![]() |
613a92eeb9 | ||
![]() |
31522b6502 | ||
![]() |
2e64ac6d25 | ||
![]() |
fe65a0c548 | ||
![]() |
cc60d50dd2 | ||
![]() |
a797d748ea | ||
![]() |
2d1e3b8c03 | ||
![]() |
635e18e7ed | ||
![]() |
b9cb6842e2 | ||
![]() |
991703914c | ||
![]() |
fdb6367351 | ||
![]() |
bbee330f4f | ||
![]() |
8b8ac76852 | ||
![]() |
3b5b51b40c | ||
![]() |
5395ddc6a3 | ||
![]() |
60c701d20b | ||
![]() |
eb11d9e3aa | ||
![]() |
7898313b0b | ||
![]() |
8e23b10f7c | ||
![]() |
c46647d491 | ||
![]() |
013e8fcda5 | ||
![]() |
f4ff9c0336 | ||
![]() |
7c4d96e176 | ||
![]() |
2c920bd016 | ||
![]() |
a5452012b5 | ||
![]() |
43dd35f54b | ||
![]() |
67bbd64fa1 | ||
![]() |
8f48b83c79 | ||
![]() |
6a57a5c369 | ||
![]() |
20df062d9f | ||
![]() |
9fa0a8b27b | ||
![]() |
9acf9f4f19 | ||
![]() |
0e84cf085b | ||
![]() |
ca9e371067 | ||
![]() |
56920fe833 | ||
![]() |
f2e6fd9692 | ||
![]() |
b2966cbc45 | ||
![]() |
45c566859e | ||
![]() |
654f7ed3ae | ||
![]() |
f1ef07bee0 | ||
![]() |
3e28d39285 | ||
![]() |
8eb8c24209 | ||
![]() |
4dbbf8f599 | ||
![]() |
a3ebabacb8 | ||
![]() |
440afcca5d | ||
![]() |
8220d4aa31 | ||
![]() |
b196c9ce8e | ||
![]() |
93568f9f7f | ||
![]() |
b01291c4ff | ||
![]() |
a9d896eb45 | ||
![]() |
3cd9b76805 | ||
![]() |
e2700d3b28 | ||
![]() |
942d799c9c | ||
![]() |
f0cbc4f23e | ||
![]() |
9bd14b142b | ||
![]() |
4ba1217b84 | ||
![]() |
50d4353045 | ||
![]() |
19e97a7738 | ||
![]() |
2ac5fe45e3 | ||
![]() |
7f3d3ecb00 | ||
![]() |
331a6ea1b3 | ||
![]() |
8f2f673438 | ||
![]() |
66e12e2a0c | ||
![]() |
2b3ecc178a | ||
![]() |
df842c355e | ||
![]() |
9b043b7444 | ||
![]() |
ce287cf218 | ||
![]() |
24945efc7d | ||
![]() |
a01ad5aa04 | ||
![]() |
fa14c40283 | ||
![]() |
d8f19cec66 | ||
![]() |
955341ff9f | ||
![]() |
cb342de934 | ||
![]() |
ea0342f100 | ||
![]() |
cd57741a51 | ||
![]() |
f4552e358d | ||
![]() |
1dc225362d | ||
![]() |
a6b3e97cda | ||
![]() |
8a244d12fc | ||
![]() |
5a5d1f5e62 | ||
![]() |
21214814b7 | ||
![]() |
3ac93dcfca | ||
![]() |
c509882a18 | ||
![]() |
c146d6207d | ||
![]() |
2045a4988d | ||
![]() |
dc7e6010cb | ||
![]() |
b1fc17e045 | ||
![]() |
daf0e6e1ba | ||
![]() |
6f263735f0 | ||
![]() |
1d2aa74e51 | ||
![]() |
a69b1d895c | ||
![]() |
399d77c60f | ||
![]() |
b768ee6d41 | ||
![]() |
58faffed6d | ||
![]() |
87706d471b | ||
![]() |
eb7eb15ee7 | ||
![]() |
a17085bb18 | ||
![]() |
cde27899dd | ||
![]() |
93ff778de0 | ||
![]() |
17f91c8eb9 | ||
![]() |
7775cd0073 | ||
![]() |
cc48f273c0 | ||
![]() |
c8406681d7 | ||
![]() |
a05dd19986 | ||
![]() |
aae350c1b3 | ||
![]() |
c48559410f | ||
![]() |
9c59bfde52 | ||
![]() |
eb9d7e97d9 | ||
![]() |
24eebe6711 | ||
![]() |
a2b8e4493f | ||
![]() |
7c4a85325c | ||
![]() |
94ba90d694 | ||
![]() |
e97bc25fb8 | ||
![]() |
73936bb10d | ||
![]() |
23e65ac5d3 | ||
![]() |
9dc0396411 | ||
![]() |
cc6db9ae9e | ||
![]() |
3748d8e246 | ||
![]() |
0341111f8f | ||
![]() |
a7c4b40fcc | ||
![]() |
e7fb3571ac | ||
![]() |
58ad9db5ed | ||
![]() |
6fd55b47c2 | ||
![]() |
3d7c191d1c | ||
![]() |
9344e1ca79 | ||
![]() |
68eb5cd74f | ||
![]() |
ca7ac71e76 | ||
![]() |
3a280f3b6a | ||
![]() |
19cea0e129 | ||
![]() |
2c40648a60 | ||
![]() |
48815649a8 | ||
![]() |
f690e14a14 | ||
![]() |
b37ad79e50 | ||
![]() |
a990205d41 | ||
![]() |
891230c78e | ||
![]() |
8bfdf8ecf2 | ||
![]() |
78655102b9 | ||
![]() |
491a171409 | ||
![]() |
b3aec8f839 | ||
![]() |
0106a4222d | ||
![]() |
11af33f2d5 | ||
![]() |
812442fbbc | ||
![]() |
1750dd3b97 | ||
![]() |
ffe298710d | ||
![]() |
5cdb7e76fd | ||
![]() |
361b936aa0 | ||
![]() |
9503b0bfc4 | ||
![]() |
823beaf268 | ||
![]() |
3ada55989f | ||
![]() |
de597391dc | ||
![]() |
59599261ff | ||
![]() |
e1fb8c1ae5 | ||
![]() |
ba4146f82c | ||
![]() |
a5c43bb823 | ||
![]() |
050cf3edb3 | ||
![]() |
84d5ebfa41 | ||
![]() |
6bc4e5b45c | ||
![]() |
496fe09f78 | ||
![]() |
19daf1bd52 | ||
![]() |
74a9c2f6b4 | ||
![]() |
dd9edb68b2 | ||
![]() |
b02177e1d0 | ||
![]() |
600d38d3e2 | ||
![]() |
07fd7e497f | ||
![]() |
932873ba02 | ||
![]() |
567f1d4247 | ||
![]() |
3f05dfe4bf | ||
![]() |
fbebcf57c1 | ||
![]() |
30d3a458e2 | ||
![]() |
7591d88d00 | ||
![]() |
22baabf751 | ||
![]() |
0cdda8b0ae | ||
![]() |
295a63087f | ||
![]() |
797d3ed362 | ||
![]() |
31de7de385 | ||
![]() |
5780ad370a | ||
![]() |
3833d2cd83 | ||
![]() |
38b60205e8 | ||
![]() |
027456fd77 | ||
![]() |
10e2d65221 | ||
![]() |
d9b5dc5dd7 | ||
![]() |
c7e6564667 | ||
![]() |
da45813a06 | ||
![]() |
6cc9b5c62b | ||
![]() |
1172e02f1b | ||
![]() |
46fbc05040 | ||
![]() |
fee1ffa2e9 | ||
![]() |
22be81b5cb | ||
![]() |
12d260ca82 | ||
![]() |
82e90553bc | ||
![]() |
18c1a0e4f6 | ||
![]() |
c42102d1c4 | ||
![]() |
aca2d2e510 | ||
![]() |
666938b738 | ||
![]() |
a75db92007 | ||
![]() |
aaf2fa8807 | ||
![]() |
e549235d83 | ||
![]() |
86e8457574 | ||
![]() |
8292ed9e31 | ||
![]() |
57fc51d013 | ||
![]() |
8b332adbe7 | ||
![]() |
ae0ee1ebdd | ||
![]() |
3cea734b9b | ||
![]() |
7ac3f7ca03 | ||
![]() |
0a5c73478d | ||
![]() |
495952acb0 | ||
![]() |
25a8f1522a | ||
![]() |
f13f7ce129 | ||
![]() |
cc90127af9 | ||
![]() |
98e8476a88 | ||
![]() |
ec8bdc9af6 | ||
![]() |
9598416932 | ||
![]() |
4c0bc79e49 | ||
![]() |
01dd2d8097 | ||
![]() |
e09444d94f | ||
![]() |
0c76833997 | ||
![]() |
ad99ca1723 | ||
![]() |
f47561b580 | ||
![]() |
4f60da292a | ||
![]() |
70fb86a1c3 | ||
![]() |
bf79639d07 | ||
![]() |
e8642df674 | ||
![]() |
b648717079 | ||
![]() |
3702caa25f | ||
![]() |
4200bbfd0a | ||
![]() |
0fcca4c141 | ||
![]() |
fafdae9ba9 | ||
![]() |
ef215b1b0c | ||
![]() |
1d0721034d | ||
![]() |
3cfbe9585a | ||
![]() |
71305e636c | ||
![]() |
ce23c153ee | ||
![]() |
019da4d2f4 | ||
![]() |
ffc31f565b | ||
![]() |
7f01f2d716 | ||
![]() |
bf20b0dd79 | ||
![]() |
867826759b | ||
![]() |
3be370071c | ||
![]() |
2b9a194244 | ||
![]() |
67a928b1ae | ||
![]() |
67a7211b77 | ||
![]() |
1d4fe01db0 | ||
![]() |
07491d8028 | ||
![]() |
7f1baca872 | ||
![]() |
8c3a0a8275 | ||
![]() |
eba6043d26 | ||
![]() |
397692d113 | ||
![]() |
035ecc1517 | ||
![]() |
bb52301200 | ||
![]() |
f4adf5d7e7 | ||
![]() |
e4a8459798 | ||
![]() |
14fa738fbe | ||
![]() |
4da7aa38ea | ||
![]() |
5147d67318 | ||
![]() |
cbc599cb20 | ||
![]() |
09c84e25bf | ||
![]() |
224e3b6ad4 | ||
![]() |
992a683ba2 | ||
![]() |
e8e116312a | ||
![]() |
de3ba9a25c | ||
![]() |
5e88cabb4b | ||
![]() |
6d71177394 | ||
![]() |
edd9ae5118 | ||
![]() |
23ae3b5830 | ||
![]() |
6746aab7ef | ||
![]() |
c85ff7ddda | ||
![]() |
cf70efabb0 | ||
![]() |
6eb2958afc | ||
![]() |
18f13b7d15 | ||
![]() |
0bb959d26a | ||
![]() |
b4f3e85001 | ||
![]() |
25100c46f7 | ||
![]() |
540f4c0958 | ||
![]() |
8930ebe572 | ||
![]() |
8f93f2b6d2 | ||
![]() |
9ba91889e0 | ||
![]() |
67683fbddb | ||
![]() |
824f9d7ad0 | ||
![]() |
3e99f90eb1 | ||
![]() |
3ca8a94419 | ||
![]() |
714837dd00 | ||
![]() |
bc1d3ddd5d | ||
![]() |
bf7b75b619 | ||
![]() |
469d6ab907 | ||
![]() |
a4dd5bb62f | ||
![]() |
60859de0bd | ||
![]() |
ff70d5db14 | ||
![]() |
c8ad936d26 | ||
![]() |
60b5f5fe48 | ||
![]() |
14ec7fb816 | ||
![]() |
b4ea230ff1 | ||
![]() |
410879d154 | ||
![]() |
f14121e99c | ||
![]() |
19d7444946 | ||
![]() |
d9aaed0035 | ||
![]() |
cfd3c159f9 | ||
![]() |
4ff50525ed | ||
![]() |
34e02e9f3a | ||
![]() |
62690c2a53 | ||
![]() |
5d30e0854f | ||
![]() |
ec683cdf88 | ||
![]() |
39feed6fac | ||
![]() |
ee7f683b76 | ||
![]() |
209d52e920 | ||
![]() |
585111ca38 | ||
![]() |
ef95334fe6 | ||
![]() |
4595534a6f | ||
![]() |
be9d9264ae | ||
![]() |
a8495c67d4 | ||
![]() |
eec369ea4f | ||
![]() |
abed07b613 | ||
![]() |
6cfdedb823 | ||
![]() |
db903ebb0a | ||
![]() |
e12c83fd83 | ||
![]() |
12861f6c07 | ||
![]() |
52065b8313 | ||
![]() |
f6ff843cfb | ||
![]() |
aedf402c17 | ||
![]() |
0745b03271 | ||
![]() |
bb5c0de367 | ||
![]() |
9478251d44 | ||
![]() |
47cb85d3db | ||
![]() |
ce7ceccc1c | ||
![]() |
5d4cf3b705 | ||
![]() |
f33fc092e3 | ||
![]() |
0ff8abcd6f | ||
![]() |
b0d55d434d | ||
![]() |
092690e9f0 | ||
![]() |
5b11175cf3 | ||
![]() |
7a203a12a3 | ||
![]() |
f7dd8af35e | ||
![]() |
7a9b3442d2 | ||
![]() |
b66e2359d1 | ||
![]() |
81c72ee5d9 | ||
![]() |
fed7f89f96 | ||
![]() |
aefa629509 | ||
![]() |
bc32581cbd | ||
![]() |
3f7f6af051 | ||
![]() |
ee9b2e8bf8 | ||
![]() |
0b968abfe4 | ||
![]() |
7e7ecd6a0f | ||
![]() |
7e9a9e14c7 | ||
![]() |
333493f351 | ||
![]() |
38333a6d11 | ||
![]() |
4213957d76 | ||
![]() |
565f9e3e29 | ||
![]() |
a1bfc1cb26 | ||
![]() |
cfd432886d | ||
![]() |
191666a2f2 | ||
![]() |
aeeae7c167 | ||
![]() |
08c7d4d15e | ||
![]() |
29b92659c7 | ||
![]() |
209f25a5cf | ||
![]() |
4622f4b51d | ||
![]() |
4d51dc9b6c | ||
![]() |
76b992509b | ||
![]() |
925978db8f | ||
![]() |
c0e90ddb33 | ||
![]() |
a7a29eaf97 | ||
![]() |
a451d2d6f2 | ||
![]() |
914429ab4f | ||
![]() |
f721a7c66c | ||
![]() |
bba499649b | ||
![]() |
f9cd54c445 | ||
![]() |
0d89125a8e | ||
![]() |
6b37d678df | ||
![]() |
02698b3a0e | ||
![]() |
6f0512c18c | ||
![]() |
e46b38b301 | ||
![]() |
5841817fb5 | ||
![]() |
e28fb49015 | ||
![]() |
841eef6a52 | ||
![]() |
2eee1ef203 | ||
![]() |
cd605f4996 | ||
![]() |
54a8482a88 | ||
![]() |
e15b5a07fb | ||
![]() |
c198305b5e | ||
![]() |
a637a8970b | ||
![]() |
d97f68eec0 | ||
![]() |
c3069a425d | ||
![]() |
9b1dc7d42e | ||
![]() |
ec23fcdd75 | ||
![]() |
544d57c720 | ||
![]() |
b55d836871 | ||
![]() |
a210f523a5 | ||
![]() |
e6237d68d0 | ||
![]() |
56e6922279 | ||
![]() |
6e2f738d86 | ||
![]() |
81d0bf6f04 | ||
![]() |
95f509d337 | ||
![]() |
2f5ce67154 | ||
![]() |
89318be5f4 | ||
![]() |
f80e8c8d11 | ||
![]() |
8c4bb4140a | ||
![]() |
ff83931a3f | ||
![]() |
2468be4736 | ||
![]() |
4e835ed3ff | ||
![]() |
41f494fbff | ||
![]() |
e974fe5dc7 | ||
![]() |
85a23442cc | ||
![]() |
a822a70f00 | ||
![]() |
819902c24e | ||
![]() |
554efbb057 | ||
![]() |
8547533210 | ||
![]() |
d843d1715d | ||
![]() |
1552a8e74b | ||
![]() |
f0e9a8c5fe | ||
![]() |
648953ec1f | ||
![]() |
9e85748b2e | ||
![]() |
a98b23af02 | ||
![]() |
5463f15633 | ||
![]() |
0c6113b0d1 | ||
![]() |
c5906e780a | ||
![]() |
f2355a76d6 | ||
![]() |
0aeca40137 | ||
![]() |
5c48e4ad19 | ||
![]() |
f6d1e2b3b8 | ||
![]() |
37010d92ee | ||
![]() |
babad3ab6d | ||
![]() |
b12e9832c9 | ||
![]() |
0f9554c717 | ||
![]() |
d19dde2f85 | ||
![]() |
7a529e156d | ||
![]() |
cba2474df7 | ||
![]() |
03c889383b | ||
![]() |
da54478767 | ||
![]() |
acf9c2554f | ||
![]() |
7c53bfc870 | ||
![]() |
32a8dcd411 | ||
![]() |
20b4cec0ca | ||
![]() |
c51c938e8d | ||
![]() |
49984f2560 | ||
![]() |
b3c77ef099 | ||
![]() |
97e34844b4 | ||
![]() |
e924a1920e | ||
![]() |
1441cc293c | ||
![]() |
311a2ddc75 | ||
![]() |
551d1d9f1a | ||
![]() |
a5dea9e7f6 | ||
![]() |
02bd83bd90 | ||
![]() |
c42d5390a4 | ||
![]() |
31ea7297c2 | ||
![]() |
c53cffb745 | ||
![]() |
26a99a122a | ||
![]() |
acb0bd95f2 | ||
![]() |
5d73b17415 | ||
![]() |
3a8fa9f5b6 | ||
![]() |
e93d7feb2c | ||
![]() |
116b870152 | ||
![]() |
667c7b07b6 | ||
![]() |
45e75cc06e | ||
![]() |
5c08db2f44 | ||
![]() |
28fc29c3ab | ||
![]() |
b2ac67692e | ||
![]() |
1064d777c2 | ||
![]() |
62f675adbe | ||
![]() |
cee0bbb805 | ||
![]() |
77eb75fcc6 | ||
![]() |
55211907f2 | ||
![]() |
e1e7cd1479 | ||
![]() |
2d3c729215 | ||
![]() |
f391cfd432 | ||
![]() |
352136f0c6 | ||
![]() |
b6e7f90f6a | ||
![]() |
86cfeb76b6 | ||
![]() |
d91357a807 | ||
![]() |
3c8d7a808b | ||
![]() |
d6a80c7ea5 | ||
![]() |
05a15ac689 | ||
![]() |
580cc359e5 | ||
![]() |
630284e7ae | ||
![]() |
cc562033e7 | ||
![]() |
fabb9b6fd7 | ||
![]() |
e8ffcaae46 | ||
![]() |
47d9895077 | ||
![]() |
aacf15757f | ||
![]() |
914b44069b | ||
![]() |
4789327378 | ||
![]() |
c55f2945ac | ||
![]() |
c6a368d6f2 | ||
![]() |
869a579655 | ||
![]() |
7cd1e8ea76 | ||
![]() |
351ae1b2c7 | ||
![]() |
457f3e25cc | ||
![]() |
41c670450b | ||
![]() |
f636db49f7 | ||
![]() |
505bba7612 | ||
![]() |
72507aba4b | ||
![]() |
9b086b3f2a | ||
![]() |
f9d7d2d1dd | ||
![]() |
e9efa3f2d3 | ||
![]() |
665a72a08f | ||
![]() |
61d1dcc231 | ||
![]() |
6c9b73b100 | ||
![]() |
a4c9ed90b7 | ||
![]() |
28d6d4db92 | ||
![]() |
12def37194 | ||
![]() |
ed2302e545 | ||
![]() |
618adb913d | ||
![]() |
4a220f9bfb | ||
![]() |
300abd868a | ||
![]() |
87f0b1fc97 | ||
![]() |
78a6e72fe1 | ||
![]() |
8f1b2a9d2a | ||
![]() |
5b27b652e7 | ||
![]() |
556ff0baf4 | ||
![]() |
8cc536b20f | ||
![]() |
5e20c871a5 | ||
![]() |
56fb892818 | ||
![]() |
7f104c249a | ||
![]() |
0eeface374 | ||
![]() |
ffe1e1e40d | ||
![]() |
5efdef19cf | ||
![]() |
c9fae6a070 | ||
![]() |
2b17f730d4 | ||
![]() |
808bddbfbb | ||
![]() |
d6dfa9a0b9 | ||
![]() |
924b73f070 | ||
![]() |
64181c6ab8 | ||
![]() |
a1b10a2900 | ||
![]() |
6315b9ea52 | ||
![]() |
7c756304b5 | ||
![]() |
9fd11fbe13 | ||
![]() |
7cd9a03b0f | ||
![]() |
f8bd844c6c | ||
![]() |
987d9a267c | ||
![]() |
98d1bb9264 | ||
![]() |
b46a19f5ca | ||
![]() |
6e16ef1246 | ||
![]() |
7bad242944 | ||
![]() |
74a5c48214 | ||
![]() |
11af906c79 | ||
![]() |
c31c4b4286 | ||
![]() |
7f29b5d1e8 | ||
![]() |
6012705e95 | ||
![]() |
21a97863ac | ||
![]() |
50cfecb3fd | ||
![]() |
1461804039 | ||
![]() |
dc3f45acd4 | ||
![]() |
6970dfa5f8 | ||
![]() |
48d3c2105d | ||
![]() |
18f630ba15 | ||
![]() |
f68eb9c778 | ||
![]() |
4a960d9f2c | ||
![]() |
c745b99922 | ||
![]() |
f1e3902fea | ||
![]() |
41a623a643 | ||
![]() |
d3fe1d3b2b | ||
![]() |
3fd3baaa47 | ||
![]() |
01d2b0024f | ||
![]() |
01e66f8833 | ||
![]() |
afd9b56e71 | ||
![]() |
e2f9b4245b | ||
![]() |
22a007b514 | ||
![]() |
38988b4819 | ||
![]() |
704e92c3d0 | ||
![]() |
97b1a60ae8 | ||
![]() |
3288721259 | ||
![]() |
ab121c7eee | ||
![]() |
240362a16d | ||
![]() |
f2dcbce490 | ||
![]() |
88df434404 | ||
![]() |
b3ddabda29 | ||
![]() |
b8b3e1e72a | ||
![]() |
615a5212bf | ||
![]() |
221d299052 | ||
![]() |
3180d2ddf2 | ||
![]() |
7aaa075ba8 | ||
![]() |
4fb590889a | ||
![]() |
115ca903b2 | ||
![]() |
e90170a384 | ||
![]() |
1d0760c630 | ||
![]() |
af44fe74ff | ||
![]() |
72c0021306 | ||
![]() |
18918eb3a3 | ||
![]() |
416e181992 | ||
![]() |
d7a49e3316 | ||
![]() |
cf13f13fbf | ||
![]() |
f53a8d3b06 | ||
![]() |
8c5c1922c9 | ||
![]() |
707559e023 | ||
![]() |
97a2ccbfe0 | ||
![]() |
95f2a7a908 | ||
![]() |
e53c53bb4a | ||
![]() |
d906a85095 | ||
![]() |
dc1f669a1f | ||
![]() |
0ea862b572 | ||
![]() |
fe7a57b2b7 | ||
![]() |
c9c62a1083 | ||
![]() |
5608c5a901 | ||
![]() |
722361aedb | ||
![]() |
d2f40612f4 | ||
![]() |
6a63e5bb51 | ||
![]() |
ad40ab7e1e | ||
![]() |
05ce67fbfe | ||
![]() |
555860cf83 | ||
![]() |
2575787bd0 | ||
![]() |
2cfb646065 | ||
![]() |
a1da452c41 | ||
![]() |
420e38bead | ||
![]() |
41c4018a27 | ||
![]() |
4d4f755607 | ||
![]() |
d8e5daf12b | ||
![]() |
c3322021d0 | ||
![]() |
45cc88091e | ||
![]() |
27498f68fb | ||
![]() |
d8e80daa93 | ||
![]() |
384a6730a4 | ||
![]() |
a7de76d150 | ||
![]() |
2154e237ff | ||
![]() |
5fda3e9765 | ||
![]() |
b302bb9379 | ||
![]() |
bfbb81030f | ||
![]() |
63ce3292aa | ||
![]() |
b9a8846ee9 | ||
![]() |
6ae1d28f80 | ||
![]() |
17d358f8fe | ||
![]() |
cfd71457d2 | ||
![]() |
87285e08dc | ||
![]() |
b3a63123fd | ||
![]() |
7fc8238fb0 | ||
![]() |
32a0765484 | ||
![]() |
c5e1b87c61 | ||
![]() |
603d1ee9bb | ||
![]() |
86a0816b26 | ||
![]() |
287cb0f5ad | ||
![]() |
3009db3aa7 | ||
![]() |
32e095ce15 | ||
![]() |
9d6744ec15 | ||
![]() |
532f2caa37 | ||
![]() |
da2fa24e74 | ||
![]() |
8d04728ebc | ||
![]() |
2aa5c276c9 | ||
![]() |
6dba31b257 | ||
![]() |
6040e1bb5e | ||
![]() |
20e9d13f60 | ||
![]() |
73e3572c72 | ||
![]() |
5f76cc4f7b | ||
![]() |
186a810bf6 | ||
![]() |
207e56969b | ||
![]() |
94b6a27cf3 | ||
![]() |
21693e344c | ||
![]() |
d2443f6de8 | ||
![]() |
ed27422e69 | ||
![]() |
d24c89405a | ||
![]() |
2d518dfe2b | ||
![]() |
f357fa74f3 | ||
![]() |
335cf5d2e9 | ||
![]() |
ed3eedd238 | ||
![]() |
23783b8b0b | ||
![]() |
193054f1fc | ||
![]() |
87a8ff742f | ||
![]() |
656700b5be | ||
![]() |
3e84f3b3a4 | ||
![]() |
5360df6012 | ||
![]() |
39fdaa367c | ||
![]() |
7e0cdb12d7 | ||
![]() |
03983e8886 | ||
![]() |
57af50ed49 | ||
![]() |
e80ade65c7 | ||
![]() |
4d24112ec7 | ||
![]() |
1a269a1227 | ||
![]() |
d077fafd29 | ||
![]() |
5478e70576 | ||
![]() |
66b94ab9f1 | ||
![]() |
74c6fc954e | ||
![]() |
22bd2eb238 | ||
![]() |
2a72f274c9 | ||
![]() |
3a1b56494a | ||
![]() |
932052772c | ||
![]() |
43d058d3db | ||
![]() |
020b030667 | ||
![]() |
5a3eacde0b | ||
![]() |
7f412f5472 | ||
![]() |
33b6ef66d6 | ||
![]() |
9fefe57c90 | ||
![]() |
ed77522c08 | ||
![]() |
09aca839a8 | ||
![]() |
def9a1bcf8 | ||
![]() |
57435fdf34 | ||
![]() |
01ff9a34c2 | ||
![]() |
ff3a94933a | ||
![]() |
97a356c4a0 | ||
![]() |
10ab28c1ec | ||
![]() |
2d9cf8b759 | ||
![]() |
32b28a4ca5 | ||
![]() |
4996d8bcd1 | ||
![]() |
e5963a8590 | ||
![]() |
e8c155763b | ||
![]() |
a52249513e | ||
![]() |
5d2d4ac12b | ||
![]() |
64f5580edd | ||
![]() |
b989531a60 | ||
![]() |
34655b8d41 | ||
![]() |
30327d2fa3 | ||
![]() |
2e4c43c251 | ||
![]() |
c0a0d36e5d | ||
![]() |
b68d7150f1 | ||
![]() |
198bcfdf4d | ||
![]() |
8eb903ad72 | ||
![]() |
c853147635 | ||
![]() |
0294397021 | ||
![]() |
97fed21811 | ||
![]() |
510ea56431 | ||
![]() |
7897d78f0d | ||
![]() |
25a58a5c46 | ||
![]() |
f9e5fd714d | ||
![]() |
55eefd09da | ||
![]() |
0ce1f3e0f6 | ||
![]() |
99be181aea | ||
![]() |
fbf6a3517d | ||
![]() |
1dc4da8beb | ||
![]() |
1908588fcb | ||
![]() |
af7db08036 | ||
![]() |
e72ce9c90e | ||
![]() |
32264ae5e3 | ||
![]() |
33f2ff7e6d | ||
![]() |
6664d49928 | ||
![]() |
d648a6d3db | ||
![]() |
a1f262b5b2 | ||
![]() |
b109b76120 | ||
![]() |
1388f280e6 | ||
![]() |
d141b040d6 | ||
![]() |
e84d82315c | ||
![]() |
c6962ef4d2 | ||
![]() |
f93714a44e | ||
![]() |
564efd77f7 | ||
![]() |
5442c7cc2e | ||
![]() |
0fa5a16cd0 | ||
![]() |
1881cdc9ab | ||
![]() |
fb2aa44f78 | ||
![]() |
e88da3cea9 | ||
![]() |
14b6f84816 | ||
![]() |
ac8841447c | ||
![]() |
6cf2c0ad97 | ||
![]() |
c045ef698c | ||
![]() |
5cdb3f4fd5 | ||
![]() |
5a5c5721cc | ||
![]() |
3a11ffc77a | ||
![]() |
916675fb08 | ||
![]() |
a2ec404014 | ||
![]() |
6f6cb4b630 | ||
![]() |
c0f69f321d | ||
![]() |
55bf41d2da | ||
![]() |
7687d7705b | ||
![]() |
21ad9a36c8 | ||
![]() |
afb72aa102 | ||
![]() |
d00dc658df | ||
![]() |
2dab7c8dda | ||
![]() |
c37cc40ad9 | ||
![]() |
5341015cb1 | ||
![]() |
2fb76e6636 | ||
![]() |
5b260ea8da | ||
![]() |
55139eb134 | ||
![]() |
5e44bb60c6 | ||
![]() |
96740fd282 | ||
![]() |
cf1b027db9 | ||
![]() |
fb050ac3da | ||
![]() |
b36c6427d1 | ||
![]() |
63c308971b | ||
![]() |
cfd389883b | ||
![]() |
4576cfd961 | ||
![]() |
89cb6450fb | ||
![]() |
699eb71e2a | ||
![]() |
6b07f38cff | ||
![]() |
904f5485ab | ||
![]() |
e05d817482 | ||
![]() |
db37077af7 | ||
![]() |
61de18190f | ||
![]() |
1310f9470e | ||
![]() |
d652225f36 | ||
![]() |
2936b806f3 | ||
![]() |
3fa532a3c0 | ||
![]() |
d267d1bb98 | ||
![]() |
9792d4cc4b | ||
![]() |
090bd69be5 | ||
![]() |
c36e311520 | ||
![]() |
f2191cb731 | ||
![]() |
265c10ec1c | ||
![]() |
51bd21a464 | ||
![]() |
5004005c5a | ||
![]() |
67a49a2ca7 | ||
![]() |
57127537f7 | ||
![]() |
3476522c00 | ||
![]() |
3d087b1bbe | ||
![]() |
c058614fcc | ||
![]() |
9e9db0f1df | ||
![]() |
e826836c36 | ||
![]() |
196df855ac | ||
![]() |
d76c9dad52 | ||
![]() |
298e65a394 | ||
![]() |
078b776f60 | ||
![]() |
4d61a345c6 | ||
![]() |
dc0358957e | ||
![]() |
42d648e338 | ||
![]() |
1c254984c1 | ||
![]() |
f287cc34e7 | ||
![]() |
c8a8806e7d | ||
![]() |
d061f728bd | ||
![]() |
b5818bfefc | ||
![]() |
6bf5bc60d1 | ||
![]() |
c784c69eb3 | ||
![]() |
e3759d059a | ||
![]() |
429f5e55c3 | ||
![]() |
0e7a6d7a62 | ||
![]() |
ad1ec42b12 | ||
![]() |
580212d66d | ||
![]() |
b71de856a8 | ||
![]() |
35cff29917 | ||
![]() |
2910176b97 | ||
![]() |
c5ec8e1931 | ||
![]() |
82a887fd3b | ||
![]() |
eff410d1da | ||
![]() |
cbe8875b94 | ||
![]() |
49c35ec084 | ||
![]() |
f80cadcd7f | ||
![]() |
fa2ad8ab22 | ||
![]() |
600f757046 | ||
![]() |
3a2e932d17 | ||
![]() |
a2aaa3633a | ||
![]() |
bd9bdc9e03 | ||
![]() |
3b793929d8 | ||
![]() |
e139550949 | ||
![]() |
181c5b134f | ||
![]() |
74876f9e64 | ||
![]() |
02f3c3ef50 | ||
![]() |
9c3d2cfb02 | ||
![]() |
9d609c2dfe | ||
![]() |
cb04c183a8 | ||
![]() |
38425a1eae | ||
![]() |
4b997d42df | ||
![]() |
d1ecf9232e | ||
![]() |
e833403e3c | ||
![]() |
f64026af1a | ||
![]() |
efab6e92f7 | ||
![]() |
f69cc5cc98 | ||
![]() |
f6f26c6102 | ||
![]() |
159b35c717 | ||
![]() |
7fbac4f286 | ||
![]() |
29080de860 | ||
![]() |
e17222dd19 | ||
![]() |
55cf34508a | ||
![]() |
c52603921d | ||
![]() |
f4724a3c87 | ||
![]() |
2b4e2fc793 | ||
![]() |
14baead342 | ||
![]() |
2d6e6ceaeb | ||
![]() |
1dcf8d3995 | ||
![]() |
d07d32e28b | ||
![]() |
cb969e37a6 | ||
![]() |
6259287dff | ||
![]() |
3e2e61d2be | ||
![]() |
a3586791b5 | ||
![]() |
bb298ab660 | ||
![]() |
8c0f581ff0 | ||
![]() |
033b87deb5 | ||
![]() |
b6f1610a7e | ||
![]() |
e3fbb32399 | ||
![]() |
67b80bb8e8 | ||
![]() |
ae1427b189 | ||
![]() |
5165c439fc | ||
![]() |
b15c48e074 | ||
![]() |
c5bfde330f | ||
![]() |
d12ecc8616 | ||
![]() |
950640a557 | ||
![]() |
86746e7843 | ||
![]() |
2c74d2479f | ||
![]() |
f1b79a3b0d | ||
![]() |
6442922d86 | ||
![]() |
edbacb8e47 | ||
![]() |
71e22f41b1 | ||
![]() |
b9b0d89b5f | ||
![]() |
fdf82d0d1e | ||
![]() |
09327b0128 | ||
![]() |
8a3ee4cdc2 | ||
![]() |
8d1033f725 | ||
![]() |
1d8bad3a80 | ||
![]() |
67fbfb0f2d | ||
![]() |
4b0df80878 | ||
![]() |
52b90b6757 | ||
![]() |
31b71ade69 | ||
![]() |
0021b114de | ||
![]() |
28a7d027f6 | ||
![]() |
e32a2e2723 | ||
![]() |
46b68e489d | ||
![]() |
2436a6a402 | ||
![]() |
862467c0fa | ||
![]() |
69cfb431b1 | ||
![]() |
172bd6f0f2 | ||
![]() |
a882555d1b | ||
![]() |
0b12c4e5b2 | ||
![]() |
0ac6383c2c | ||
![]() |
76913d4a78 | ||
![]() |
a0d1da3274 | ||
![]() |
1aa144e47d | ||
![]() |
6b31743fb3 | ||
![]() |
508fdce704 | ||
![]() |
e912909aad | ||
![]() |
98322d5d11 | ||
![]() |
7b97130af7 | ||
![]() |
cc168d5ae9 | ||
![]() |
d19df3b6eb | ||
![]() |
75dbc2db98 | ||
![]() |
2875b050c5 | ||
![]() |
6c6c2b57a1 | ||
![]() |
113da81f29 | ||
![]() |
4dd2613f2f | ||
![]() |
8c37cc5340 | ||
![]() |
47c74cfa6d | ||
![]() |
32a55127f1 | ||
![]() |
6d0458281b | ||
![]() |
6090c7ccac | ||
![]() |
5e6b27e21f | ||
![]() |
eee04ab87d | ||
![]() |
a833803bdf | ||
![]() |
d2af342a5d | ||
![]() |
93619b3988 | ||
![]() |
dd4c5014fc | ||
![]() |
1e3379b00a | ||
![]() |
bbde2f5e06 | ||
![]() |
b61dfd6f97 | ||
![]() |
f16fa0a3ed | ||
![]() |
d4bd08415a | ||
![]() |
9ad276eeae | ||
![]() |
a3179bf114 | ||
![]() |
0d20dad2a3 | ||
![]() |
7c080770f0 | ||
![]() |
9752e5f62b | ||
![]() |
3b7057ad4f | ||
![]() |
38a7c771be | ||
![]() |
1c6075df2b | ||
![]() |
3ede0447b0 | ||
![]() |
f01b242e4a | ||
![]() |
2417dace2d | ||
![]() |
f82a111518 | ||
![]() |
525ba648ae | ||
![]() |
0160c2bb55 | ||
![]() |
ea41c842bc | ||
![]() |
8efc78e1c9 | ||
![]() |
973c18623f | ||
![]() |
7aba70ea65 | ||
![]() |
123ca8efe9 | ||
![]() |
22c26fe962 | ||
![]() |
761803f777 | ||
![]() |
d5d18a60fb | ||
![]() |
37b065a097 | ||
![]() |
fdfc61cf97 | ||
![]() |
31c84ab18f | ||
![]() |
a47527857c | ||
![]() |
12f2cb0d58 | ||
![]() |
67bf90e92f | ||
![]() |
b5f92f5003 | ||
![]() |
58989c9311 | ||
![]() |
736004d88b | ||
![]() |
49f51f24f7 | ||
![]() |
95df62e59b | ||
![]() |
64cfe240f9 | ||
![]() |
29f2863cf4 | ||
![]() |
792fa1f11d | ||
![]() |
7591c440c2 | ||
![]() |
c58309b385 | ||
![]() |
5ae70743b1 | ||
![]() |
29e0479081 | ||
![]() |
441a73839e | ||
![]() |
ff8f7a0867 | ||
![]() |
31edffcb63 | ||
![]() |
5442d43918 | ||
![]() |
25d4d23958 | ||
![]() |
86edb20c15 | ||
![]() |
3d30885daf | ||
![]() |
194c5aa27b | ||
![]() |
20c487238a | ||
![]() |
6814b4bef2 | ||
![]() |
e1a25907f2 | ||
![]() |
5f896dd39a | ||
![]() |
f4729310fa | ||
![]() |
2f02f4392a | ||
![]() |
b7f708dcd6 | ||
![]() |
501fd9c8e6 | ||
![]() |
7ba7df5cb2 | ||
![]() |
9dd9201b67 | ||
![]() |
8fb9f29ab7 | ||
![]() |
dd852801cc | ||
![]() |
1fa41e6209 | ||
![]() |
a2db2e8268 | ||
![]() |
617abf89e6 | ||
![]() |
98b4ceab7d | ||
![]() |
86a996b2ff | ||
![]() |
e6a9daf31a | ||
![]() |
8c0f7b207e | ||
![]() |
ec347f8738 | ||
![]() |
19fe2efb6e | ||
![]() |
e6878d7804 | ||
![]() |
435d877262 | ||
![]() |
3deff629b0 | ||
![]() |
a038cb6d1b | ||
![]() |
637dd7d0c2 | ||
![]() |
d20fa39cf5 | ||
![]() |
be6910d5d9 | ||
![]() |
2d6a5a3804 | ||
![]() |
630e81fbfb | ||
![]() |
6488aafd9d | ||
![]() |
4ad90d423d | ||
![]() |
d2dae45082 | ||
![]() |
85c9bd7ceb | ||
![]() |
d0ee579069 | ||
![]() |
10dbcbcdbd | ||
![]() |
e8dd5fe903 | ||
![]() |
32c23e6ced | ||
![]() |
81aaba328a | ||
![]() |
3c5dd3d0d2 | ||
![]() |
2dc07d9321 | ||
![]() |
841dd5e189 | ||
![]() |
b2bc2887d2 | ||
![]() |
e20319f4e1 | ||
![]() |
d40160d205 | ||
![]() |
f7167d5e83 | ||
![]() |
282773a43f | ||
![]() |
8944be5319 | ||
![]() |
df01f9bea7 | ||
![]() |
3c17b76b1c | ||
![]() |
7a6909dab1 | ||
![]() |
3064ae80d1 | ||
![]() |
06bb6856a8 | ||
![]() |
702caa6feb | ||
![]() |
fc74c582bf | ||
![]() |
658361f825 | ||
![]() |
e0c9a802d8 | ||
![]() |
c4a70c0945 | ||
![]() |
f7d6ac00e4 | ||
![]() |
8ed5a21b36 | ||
![]() |
773a993ee1 | ||
![]() |
6fb63c9609 | ||
![]() |
079289eb74 | ||
![]() |
59f96d4455 | ||
![]() |
cdab52fcbe | ||
![]() |
63c9037b10 | ||
![]() |
bbc86eba39 | ||
![]() |
e0fb6f5440 | ||
![]() |
2bd30af361 | ||
![]() |
b136f44f12 | ||
![]() |
d0dbb495b0 | ||
![]() |
8715a27a93 | ||
![]() |
503fc44208 | ||
![]() |
d3bfaeb5a4 | ||
![]() |
7adecd0808 | ||
![]() |
c99e081ae0 | ||
![]() |
285b6bf62d | ||
![]() |
723e29cdd0 | ||
![]() |
667098268f | ||
![]() |
e6408b35a2 | ||
![]() |
3eb0de68c4 | ||
![]() |
dd1b944205 | ||
![]() |
ae11f0610e | ||
![]() |
55fc963673 | ||
![]() |
198c7ca58d | ||
![]() |
5a2f70238a | ||
![]() |
8257b0b563 | ||
![]() |
9b997d2195 | ||
![]() |
a19fa1b92c | ||
![]() |
2c060db9c0 | ||
![]() |
a8621a15ad | ||
![]() |
179e9e1e74 | ||
![]() |
df5feff9ec | ||
![]() |
9226aaff1f | ||
![]() |
afe874a59b | ||
![]() |
4ad9f12d5d | ||
![]() |
228c37815a | ||
![]() |
a37ab10414 | ||
![]() |
d73dbf0c81 | ||
![]() |
daee26681a | ||
![]() |
729469e030 | ||
![]() |
c6dc9ee189 | ||
![]() |
85a75ad868 | ||
![]() |
8ec8b8d803 | ||
![]() |
d864792d09 | ||
![]() |
ed2e9a80ed | ||
![]() |
36948ed351 | ||
![]() |
e06429f3b0 | ||
![]() |
fd4a9a16de | ||
![]() |
acba10ac09 | ||
![]() |
d6d49e0912 | ||
![]() |
b5de5f30ac | ||
![]() |
17698065a0 | ||
![]() |
135c6f2c15 | ||
![]() |
a263fe2f2d | ||
![]() |
cbe46539ca | ||
![]() |
5e842f1572 | ||
![]() |
b56d4d0fea | ||
![]() |
42106bb97a | ||
![]() |
e7216d4aef | ||
![]() |
0751e9cea3 | ||
![]() |
0091580ae0 | ||
![]() |
4a16f9c1a7 | ||
![]() |
894d673c90 | ||
![]() |
577fe3037f | ||
![]() |
53ca62e8fc | ||
![]() |
670f6d9f8b | ||
![]() |
8a21334e66 | ||
![]() |
a130d801d5 | ||
![]() |
51b6f41eff | ||
![]() |
a829799b36 | ||
![]() |
ccb43d0661 | ||
![]() |
5bd53436df | ||
![]() |
caa4a08b26 | ||
![]() |
0fa99d7940 | ||
![]() |
73dae7842d | ||
![]() |
92a18d810c | ||
![]() |
591eb60a71 | ||
![]() |
9081a5aff6 | ||
![]() |
8ff4566905 | ||
![]() |
c8d8fb6aff | ||
![]() |
6da4994955 | ||
![]() |
4780fcd534 | ||
![]() |
5b30711470 | ||
![]() |
336f27f078 | ||
![]() |
92ef0d723b | ||
![]() |
ffee7a518e | ||
![]() |
8d61e6f111 | ||
![]() |
67736bfbca | ||
![]() |
84108b60c2 | ||
![]() |
59f8f2fdff | ||
![]() |
5c6175badb | ||
![]() |
8db8a30455 | ||
![]() |
cbe8fda1df | ||
![]() |
558df450b5 | ||
![]() |
f1d10c96bc | ||
![]() |
4d1b08a628 | ||
![]() |
2eda56bc1f | ||
![]() |
c391fee100 | ||
![]() |
06d255ccc2 | ||
![]() |
bb291b947f | ||
![]() |
3c8b22688a | ||
![]() |
cdd1fad85c | ||
![]() |
ab6fd06657 | ||
![]() |
3bb32a5630 | ||
![]() |
bf5862942a | ||
![]() |
cbea595fa0 | ||
![]() |
952ea0b090 | ||
![]() |
af951ac11c | ||
![]() |
165614efe9 | ||
![]() |
95335df84d | ||
![]() |
100861484a | ||
![]() |
70eb588f1f | ||
![]() |
c206de263b | ||
![]() |
0c12972c03 | ||
![]() |
546c4defb7 | ||
![]() |
814fca3832 | ||
![]() |
3ee29297e0 | ||
![]() |
6d9d0fff10 | ||
![]() |
714b8dad87 | ||
![]() |
a44807d47b | ||
![]() |
4aac3bf7e4 | ||
![]() |
ee2ed8222d | ||
![]() |
edaf396894 | ||
![]() |
6f052f0001 | ||
![]() |
ba40a56c32 | ||
![]() |
780be3776a | ||
![]() |
98235b3fdc | ||
![]() |
f5a9abfc8d | ||
![]() |
a8619fe2ad | ||
![]() |
c812bb1295 | ||
![]() |
4e7bcc788b | ||
![]() |
79bd69e599 | ||
![]() |
5772af37fe | ||
![]() |
6324bb1134 | ||
![]() |
658f2a3fc3 | ||
![]() |
6e536f81ac | ||
![]() |
dd9450d36a | ||
![]() |
8ef3a90ce0 | ||
![]() |
e6c76ad3f3 | ||
![]() |
4a249843eb | ||
![]() |
5c1f0f51df | ||
![]() |
2377ce1123 | ||
![]() |
6f2b31f4a3 | ||
![]() |
c5590440d6 | ||
![]() |
7931390ae4 | ||
![]() |
546b857b9d | ||
![]() |
ce10d54a9c | ||
![]() |
965bbb9f3b | ||
![]() |
e88b331155 | ||
![]() |
ce177c3c46 | ||
![]() |
5a6dbfda36 | ||
![]() |
6c1caac731 | ||
![]() |
9c3c42c3e6 | ||
![]() |
5fc33dcc06 | ||
![]() |
c196ced0e2 | ||
![]() |
dfa977a020 | ||
![]() |
5be2dfa747 | ||
![]() |
f9ea99fa1d | ||
![]() |
79583c011f | ||
![]() |
172bcc7677 | ||
![]() |
fa51cb94a3 | ||
![]() |
c2060ea1a7 | ||
![]() |
7962004215 | ||
![]() |
45476f2867 | ||
![]() |
280ced7904 | ||
![]() |
474795367e | ||
![]() |
ce756411cf | ||
![]() |
bdba2b33fb | ||
![]() |
0d26111fa7 | ||
![]() |
dada7dbb86 | ||
![]() |
cb05d34d20 | ||
![]() |
7c25c60252 | ||
![]() |
86149224d1 | ||
![]() |
f717589074 | ||
![]() |
254a0541cc | ||
![]() |
271109a726 | ||
![]() |
38de74c4ff | ||
![]() |
865d11e844 | ||
![]() |
ebba9a2290 | ||
![]() |
bc45b8b695 | ||
![]() |
7ac389b698 | ||
![]() |
616d22ceac | ||
![]() |
f6332d2cd9 | ||
![]() |
4ca7a81e96 | ||
![]() |
ae2867136a | ||
![]() |
ef04ed9151 | ||
![]() |
1522632f5a | ||
![]() |
be6bcafccc | ||
![]() |
5d332e7d58 | ||
![]() |
283ff945f3 | ||
![]() |
0d4af3023d | ||
![]() |
7fdb7961ce | ||
![]() |
e161209a46 | ||
![]() |
5e2e4a8631 | ||
![]() |
e4a6bd0ca5 | ||
![]() |
5547185b3f | ||
![]() |
7841ee3dcc | ||
![]() |
099a680c85 | ||
![]() |
9764d4d226 | ||
![]() |
37336fffe2 | ||
![]() |
a285404847 | ||
![]() |
2994b2c158 | ||
![]() |
3a3a06631d | ||
![]() |
f9bf576d2e | ||
![]() |
f2f7fbce09 | ||
![]() |
412a3ee344 | ||
![]() |
2f4eea118a | ||
![]() |
7310506ed4 | ||
![]() |
26b5ee7482 | ||
![]() |
58280a20a8 | ||
![]() |
3d47d7e73f | ||
![]() |
d9f9d7dc34 | ||
![]() |
4bcd926543 | ||
![]() |
05626c2c8f | ||
![]() |
30b83faab6 | ||
![]() |
9868648fcb | ||
![]() |
b99631f1bd | ||
![]() |
6be26e8047 | ||
![]() |
c7de9379ad | ||
![]() |
86ea69b65e | ||
![]() |
f2aa9dccd1 | ||
![]() |
464f5e09ae | ||
![]() |
17e4bde720 | ||
![]() |
6d779dad05 | ||
![]() |
38d0cc1b29 | ||
![]() |
fc9a221127 | ||
![]() |
95394ec54f | ||
![]() |
a3759f93a2 | ||
![]() |
2632283431 | ||
![]() |
8a014e3ad5 | ||
![]() |
1b3427837e | ||
![]() |
b3c91d866b | ||
![]() |
10dd531cdb | ||
![]() |
6953187cac | ||
![]() |
7b83f0146e | ||
![]() |
4ed108b5c0 | ||
![]() |
24b6b23d25 | ||
![]() |
5ea03f12fb | ||
![]() |
99a53cb005 | ||
![]() |
d7af409d01 | ||
![]() |
0304e98b00 | ||
![]() |
b16db904cc | ||
![]() |
4b306d454b | ||
![]() |
e53ea2377c | ||
![]() |
f79f2ac29e | ||
![]() |
1516edbeca | ||
![]() |
54348d824c | ||
![]() |
f32cb0c16e | ||
![]() |
4a03cb0701 | ||
![]() |
76e25953b1 | ||
![]() |
2f0bf97162 | ||
![]() |
d0b6badf09 | ||
![]() |
30f37e1e8b | ||
![]() |
4e1c90bbcc | ||
![]() |
2efe604b9b |
387
.editorconfig
Normal file
387
.editorconfig
Normal file
@ -0,0 +1,387 @@
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
max_line_length = 130
|
||||
tab_width = 4
|
||||
ij_continuation_indent_size = 8
|
||||
ij_formatter_off_tag = @formatter:off
|
||||
ij_formatter_on_tag = @formatter:on
|
||||
ij_formatter_tags_enabled = false
|
||||
ij_smart_tabs = false
|
||||
ij_wrap_on_typing = true
|
||||
|
||||
[*.java]
|
||||
ij_java_align_consecutive_assignments = false
|
||||
ij_java_align_consecutive_variable_declarations = false
|
||||
ij_java_align_group_field_declarations = false
|
||||
ij_java_align_multiline_annotation_parameters = false
|
||||
ij_java_align_multiline_array_initializer_expression = false
|
||||
ij_java_align_multiline_assignment = false
|
||||
ij_java_align_multiline_binary_operation = false
|
||||
ij_java_align_multiline_chained_methods = false
|
||||
ij_java_align_multiline_extends_list = false
|
||||
ij_java_align_multiline_for = true
|
||||
ij_java_align_multiline_method_parentheses = false
|
||||
ij_java_align_multiline_parameters = true
|
||||
ij_java_align_multiline_parameters_in_calls = false
|
||||
ij_java_align_multiline_parenthesized_expression = false
|
||||
ij_java_align_multiline_records = true
|
||||
ij_java_align_multiline_resources = true
|
||||
ij_java_align_multiline_ternary_operation = false
|
||||
ij_java_align_multiline_text_blocks = false
|
||||
ij_java_align_multiline_throws_list = false
|
||||
ij_java_align_subsequent_simple_methods = false
|
||||
ij_java_align_throws_keyword = false
|
||||
ij_java_annotation_parameter_wrap = off
|
||||
ij_java_array_initializer_new_line_after_left_brace = false
|
||||
ij_java_array_initializer_right_brace_on_new_line = false
|
||||
ij_java_array_initializer_wrap = off
|
||||
ij_java_assert_statement_colon_on_next_line = false
|
||||
ij_java_assert_statement_wrap = off
|
||||
ij_java_assignment_wrap = off
|
||||
ij_java_binary_operation_sign_on_next_line = false
|
||||
ij_java_binary_operation_wrap = off
|
||||
ij_java_blank_lines_after_anonymous_class_header = 0
|
||||
ij_java_blank_lines_after_class_header = 1
|
||||
ij_java_blank_lines_after_imports = 1
|
||||
ij_java_blank_lines_after_package = 1
|
||||
ij_java_blank_lines_around_class = 1
|
||||
ij_java_blank_lines_around_field = 0
|
||||
ij_java_blank_lines_around_field_in_interface = 0
|
||||
ij_java_blank_lines_around_initializer = 1
|
||||
ij_java_blank_lines_around_method = 1
|
||||
ij_java_blank_lines_around_method_in_interface = 1
|
||||
ij_java_blank_lines_before_class_end = 1
|
||||
ij_java_blank_lines_before_imports = 1
|
||||
ij_java_blank_lines_before_method_body = 0
|
||||
ij_java_blank_lines_before_package = 0
|
||||
ij_java_block_brace_style = end_of_line
|
||||
ij_java_block_comment_at_first_column = true
|
||||
ij_java_call_parameters_new_line_after_left_paren = true
|
||||
ij_java_call_parameters_right_paren_on_new_line = true
|
||||
ij_java_call_parameters_wrap = on_every_item
|
||||
ij_java_case_statement_on_separate_line = true
|
||||
ij_java_catch_on_new_line = false
|
||||
ij_java_class_annotation_wrap = split_into_lines
|
||||
ij_java_class_brace_style = end_of_line
|
||||
ij_java_class_count_to_use_import_on_demand = 100000
|
||||
ij_java_class_names_in_javadoc = 1
|
||||
ij_java_do_not_indent_top_level_class_members = false
|
||||
ij_java_do_not_wrap_after_single_annotation = false
|
||||
ij_java_do_while_brace_force = always
|
||||
ij_java_doc_add_blank_line_after_description = true
|
||||
ij_java_doc_add_blank_line_after_param_comments = false
|
||||
ij_java_doc_add_blank_line_after_return = false
|
||||
ij_java_doc_add_p_tag_on_empty_lines = true
|
||||
ij_java_doc_align_exception_comments = true
|
||||
ij_java_doc_align_param_comments = true
|
||||
ij_java_doc_do_not_wrap_if_one_line = false
|
||||
ij_java_doc_enable_formatting = true
|
||||
ij_java_doc_enable_leading_asterisks = true
|
||||
ij_java_doc_indent_on_continuation = true
|
||||
ij_java_doc_keep_empty_lines = true
|
||||
ij_java_doc_keep_empty_parameter_tag = true
|
||||
ij_java_doc_keep_empty_return_tag = true
|
||||
ij_java_doc_keep_empty_throws_tag = true
|
||||
ij_java_doc_keep_invalid_tags = false
|
||||
ij_java_doc_param_description_on_new_line = false
|
||||
ij_java_doc_preserve_line_breaks = false
|
||||
ij_java_doc_use_throws_not_exception_tag = true
|
||||
ij_java_else_on_new_line = false
|
||||
ij_java_enum_constants_wrap = split_into_lines
|
||||
ij_java_extends_keyword_wrap = off
|
||||
ij_java_extends_list_wrap = normal
|
||||
ij_java_field_annotation_wrap = split_into_lines
|
||||
ij_java_finally_on_new_line = false
|
||||
ij_java_for_brace_force = always
|
||||
ij_java_for_statement_new_line_after_left_paren = false
|
||||
ij_java_for_statement_right_paren_on_new_line = false
|
||||
ij_java_for_statement_wrap = off
|
||||
ij_java_generate_final_locals = true
|
||||
ij_java_generate_final_parameters = true
|
||||
ij_java_if_brace_force = always
|
||||
ij_java_imports_layout = *, |, javax.**, java.**, |, $*
|
||||
ij_java_indent_case_from_switch = true
|
||||
ij_java_insert_inner_class_imports = false
|
||||
ij_java_insert_override_annotation = true
|
||||
ij_java_keep_blank_lines_before_right_brace = 2
|
||||
ij_java_keep_blank_lines_between_package_declaration_and_header = 2
|
||||
ij_java_keep_blank_lines_in_code = 2
|
||||
ij_java_keep_blank_lines_in_declarations = 2
|
||||
ij_java_keep_control_statement_in_one_line = true
|
||||
ij_java_keep_first_column_comment = true
|
||||
ij_java_keep_indents_on_empty_lines = false
|
||||
ij_java_keep_line_breaks = true
|
||||
ij_java_keep_multiple_expressions_in_one_line = false
|
||||
ij_java_keep_simple_blocks_in_one_line = false
|
||||
ij_java_keep_simple_classes_in_one_line = false
|
||||
ij_java_keep_simple_lambdas_in_one_line = false
|
||||
ij_java_keep_simple_methods_in_one_line = false
|
||||
ij_java_label_indent_absolute = false
|
||||
ij_java_label_indent_size = 0
|
||||
ij_java_lambda_brace_style = end_of_line
|
||||
ij_java_layout_static_imports_separately = true
|
||||
ij_java_line_comment_add_space = false
|
||||
ij_java_line_comment_at_first_column = true
|
||||
ij_java_method_annotation_wrap = split_into_lines
|
||||
ij_java_method_brace_style = end_of_line
|
||||
ij_java_method_call_chain_wrap = on_every_item
|
||||
ij_java_method_parameters_new_line_after_left_paren = true
|
||||
ij_java_method_parameters_right_paren_on_new_line = true
|
||||
ij_java_method_parameters_wrap = on_every_item
|
||||
ij_java_modifier_list_wrap = false
|
||||
ij_java_names_count_to_use_import_on_demand = 100000
|
||||
ij_java_new_line_after_lparen_in_record_header = false
|
||||
ij_java_parameter_annotation_wrap = off
|
||||
ij_java_parentheses_expression_new_line_after_left_paren = false
|
||||
ij_java_parentheses_expression_right_paren_on_new_line = false
|
||||
ij_java_place_assignment_sign_on_next_line = false
|
||||
ij_java_prefer_longer_names = false
|
||||
ij_java_prefer_parameters_wrap = true
|
||||
ij_java_record_components_wrap = normal
|
||||
ij_java_repeat_synchronized = true
|
||||
ij_java_replace_instanceof_and_cast = false
|
||||
ij_java_replace_null_check = true
|
||||
ij_java_replace_sum_lambda_with_method_ref = true
|
||||
ij_java_resource_list_new_line_after_left_paren = false
|
||||
ij_java_resource_list_right_paren_on_new_line = false
|
||||
ij_java_resource_list_wrap = off
|
||||
ij_java_rparen_on_new_line_in_record_header = false
|
||||
ij_java_space_after_closing_angle_bracket_in_type_argument = false
|
||||
ij_java_space_after_colon = true
|
||||
ij_java_space_after_comma = true
|
||||
ij_java_space_after_comma_in_type_arguments = true
|
||||
ij_java_space_after_for_semicolon = true
|
||||
ij_java_space_after_quest = true
|
||||
ij_java_space_after_type_cast = true
|
||||
ij_java_space_before_annotation_array_initializer_left_brace = false
|
||||
ij_java_space_before_annotation_parameter_list = false
|
||||
ij_java_space_before_array_initializer_left_brace = false
|
||||
ij_java_space_before_catch_keyword = true
|
||||
ij_java_space_before_catch_left_brace = true
|
||||
ij_java_space_before_catch_parentheses = true
|
||||
ij_java_space_before_class_left_brace = true
|
||||
ij_java_space_before_colon = true
|
||||
ij_java_space_before_colon_in_foreach = true
|
||||
ij_java_space_before_comma = false
|
||||
ij_java_space_before_do_left_brace = true
|
||||
ij_java_space_before_else_keyword = true
|
||||
ij_java_space_before_else_left_brace = true
|
||||
ij_java_space_before_finally_keyword = true
|
||||
ij_java_space_before_finally_left_brace = true
|
||||
ij_java_space_before_for_left_brace = true
|
||||
ij_java_space_before_for_parentheses = true
|
||||
ij_java_space_before_for_semicolon = false
|
||||
ij_java_space_before_if_left_brace = true
|
||||
ij_java_space_before_if_parentheses = true
|
||||
ij_java_space_before_method_call_parentheses = false
|
||||
ij_java_space_before_method_left_brace = true
|
||||
ij_java_space_before_method_parentheses = false
|
||||
ij_java_space_before_opening_angle_bracket_in_type_parameter = false
|
||||
ij_java_space_before_quest = true
|
||||
ij_java_space_before_switch_left_brace = true
|
||||
ij_java_space_before_switch_parentheses = true
|
||||
ij_java_space_before_synchronized_left_brace = true
|
||||
ij_java_space_before_synchronized_parentheses = true
|
||||
ij_java_space_before_try_left_brace = true
|
||||
ij_java_space_before_try_parentheses = true
|
||||
ij_java_space_before_type_parameter_list = false
|
||||
ij_java_space_before_while_keyword = true
|
||||
ij_java_space_before_while_left_brace = true
|
||||
ij_java_space_before_while_parentheses = true
|
||||
ij_java_space_inside_one_line_enum_braces = false
|
||||
ij_java_space_within_empty_array_initializer_braces = false
|
||||
ij_java_space_within_empty_method_call_parentheses = false
|
||||
ij_java_space_within_empty_method_parentheses = false
|
||||
ij_java_spaces_around_additive_operators = true
|
||||
ij_java_spaces_around_assignment_operators = true
|
||||
ij_java_spaces_around_bitwise_operators = true
|
||||
ij_java_spaces_around_equality_operators = true
|
||||
ij_java_spaces_around_lambda_arrow = true
|
||||
ij_java_spaces_around_logical_operators = true
|
||||
ij_java_spaces_around_method_ref_dbl_colon = false
|
||||
ij_java_spaces_around_multiplicative_operators = true
|
||||
ij_java_spaces_around_relational_operators = true
|
||||
ij_java_spaces_around_shift_operators = true
|
||||
ij_java_spaces_around_type_bounds_in_type_parameters = true
|
||||
ij_java_spaces_around_unary_operator = false
|
||||
ij_java_spaces_within_angle_brackets = false
|
||||
ij_java_spaces_within_annotation_parentheses = false
|
||||
ij_java_spaces_within_array_initializer_braces = false
|
||||
ij_java_spaces_within_braces = false
|
||||
ij_java_spaces_within_brackets = false
|
||||
ij_java_spaces_within_cast_parentheses = false
|
||||
ij_java_spaces_within_catch_parentheses = false
|
||||
ij_java_spaces_within_for_parentheses = false
|
||||
ij_java_spaces_within_if_parentheses = false
|
||||
ij_java_spaces_within_method_call_parentheses = false
|
||||
ij_java_spaces_within_method_parentheses = false
|
||||
ij_java_spaces_within_parentheses = false
|
||||
ij_java_spaces_within_switch_parentheses = false
|
||||
ij_java_spaces_within_synchronized_parentheses = false
|
||||
ij_java_spaces_within_try_parentheses = false
|
||||
ij_java_spaces_within_while_parentheses = false
|
||||
ij_java_special_else_if_treatment = true
|
||||
ij_java_subclass_name_suffix = Impl
|
||||
ij_java_ternary_operation_signs_on_next_line = true
|
||||
ij_java_ternary_operation_wrap = on_every_item
|
||||
ij_java_test_name_suffix = Test
|
||||
ij_java_throws_keyword_wrap = off
|
||||
ij_java_throws_list_wrap = normal
|
||||
ij_java_use_external_annotations = false
|
||||
ij_java_use_fq_class_names = false
|
||||
ij_java_use_relative_indents = false
|
||||
ij_java_use_single_class_imports = true
|
||||
ij_java_variable_annotation_wrap = off
|
||||
ij_java_visibility = public
|
||||
ij_java_while_brace_force = always
|
||||
ij_java_while_on_new_line = false
|
||||
ij_java_wrap_comments = false
|
||||
ij_java_wrap_first_method_in_call_chain = true
|
||||
ij_java_wrap_long_lines = false
|
||||
|
||||
[*.properties]
|
||||
ij_properties_align_group_field_declarations = false
|
||||
ij_properties_keep_blank_lines = false
|
||||
ij_properties_key_value_delimiter = equals
|
||||
ij_properties_spaces_around_key_value_delimiter = false
|
||||
|
||||
[.editorconfig]
|
||||
ij_editorconfig_align_group_field_declarations = false
|
||||
ij_editorconfig_space_after_colon = false
|
||||
ij_editorconfig_space_after_comma = true
|
||||
ij_editorconfig_space_before_colon = false
|
||||
ij_editorconfig_space_before_comma = false
|
||||
ij_editorconfig_spaces_around_assignment_operators = true
|
||||
|
||||
[{*.gradle.kts, *.kt, *.kts, *.main.kts}]
|
||||
ij_kotlin_align_in_columns_case_branch = false
|
||||
ij_kotlin_align_multiline_binary_operation = false
|
||||
ij_kotlin_align_multiline_extends_list = false
|
||||
ij_kotlin_align_multiline_method_parentheses = false
|
||||
ij_kotlin_align_multiline_parameters = true
|
||||
ij_kotlin_align_multiline_parameters_in_calls = false
|
||||
ij_kotlin_allow_trailing_comma = false
|
||||
ij_kotlin_allow_trailing_comma_on_call_site = false
|
||||
ij_kotlin_assignment_wrap = off
|
||||
ij_kotlin_blank_lines_after_class_header = 0
|
||||
ij_kotlin_blank_lines_around_block_when_branches = 0
|
||||
ij_kotlin_blank_lines_before_declaration_with_comment_or_annotation_on_separate_line = 1
|
||||
ij_kotlin_block_comment_at_first_column = true
|
||||
ij_kotlin_call_parameters_new_line_after_left_paren = false
|
||||
ij_kotlin_call_parameters_right_paren_on_new_line = false
|
||||
ij_kotlin_call_parameters_wrap = off
|
||||
ij_kotlin_catch_on_new_line = false
|
||||
ij_kotlin_class_annotation_wrap = split_into_lines
|
||||
ij_kotlin_continuation_indent_for_chained_calls = true
|
||||
ij_kotlin_continuation_indent_for_expression_bodies = true
|
||||
ij_kotlin_continuation_indent_in_argument_lists = true
|
||||
ij_kotlin_continuation_indent_in_elvis = true
|
||||
ij_kotlin_continuation_indent_in_if_conditions = true
|
||||
ij_kotlin_continuation_indent_in_parameter_lists = true
|
||||
ij_kotlin_continuation_indent_in_supertype_lists = true
|
||||
ij_kotlin_else_on_new_line = false
|
||||
ij_kotlin_enum_constants_wrap = off
|
||||
ij_kotlin_extends_list_wrap = off
|
||||
ij_kotlin_field_annotation_wrap = split_into_lines
|
||||
ij_kotlin_finally_on_new_line = false
|
||||
ij_kotlin_if_rparen_on_new_line = false
|
||||
ij_kotlin_import_nested_classes = false
|
||||
ij_kotlin_insert_whitespaces_in_simple_one_line_method = true
|
||||
ij_kotlin_keep_blank_lines_before_right_brace = 2
|
||||
ij_kotlin_keep_blank_lines_in_code = 2
|
||||
ij_kotlin_keep_blank_lines_in_declarations = 2
|
||||
ij_kotlin_keep_first_column_comment = true
|
||||
ij_kotlin_keep_indents_on_empty_lines = false
|
||||
ij_kotlin_keep_line_breaks = true
|
||||
ij_kotlin_lbrace_on_next_line = false
|
||||
ij_kotlin_line_comment_add_space = false
|
||||
ij_kotlin_line_comment_at_first_column = true
|
||||
ij_kotlin_method_annotation_wrap = split_into_lines
|
||||
ij_kotlin_method_call_chain_wrap = off
|
||||
ij_kotlin_method_parameters_new_line_after_left_paren = false
|
||||
ij_kotlin_method_parameters_right_paren_on_new_line = false
|
||||
ij_kotlin_method_parameters_wrap = off
|
||||
ij_kotlin_name_count_to_use_star_import = 5
|
||||
ij_kotlin_name_count_to_use_star_import_for_members = 3
|
||||
ij_kotlin_parameter_annotation_wrap = off
|
||||
ij_kotlin_space_after_comma = true
|
||||
ij_kotlin_space_after_extend_colon = true
|
||||
ij_kotlin_space_after_type_colon = true
|
||||
ij_kotlin_space_before_catch_parentheses = true
|
||||
ij_kotlin_space_before_comma = false
|
||||
ij_kotlin_space_before_extend_colon = true
|
||||
ij_kotlin_space_before_for_parentheses = true
|
||||
ij_kotlin_space_before_if_parentheses = true
|
||||
ij_kotlin_space_before_lambda_arrow = true
|
||||
ij_kotlin_space_before_type_colon = false
|
||||
ij_kotlin_space_before_when_parentheses = true
|
||||
ij_kotlin_space_before_while_parentheses = true
|
||||
ij_kotlin_spaces_around_additive_operators = true
|
||||
ij_kotlin_spaces_around_assignment_operators = true
|
||||
ij_kotlin_spaces_around_equality_operators = true
|
||||
ij_kotlin_spaces_around_function_type_arrow = true
|
||||
ij_kotlin_spaces_around_logical_operators = true
|
||||
ij_kotlin_spaces_around_multiplicative_operators = true
|
||||
ij_kotlin_spaces_around_range = false
|
||||
ij_kotlin_spaces_around_relational_operators = true
|
||||
ij_kotlin_spaces_around_unary_operator = false
|
||||
ij_kotlin_spaces_around_when_arrow = true
|
||||
ij_kotlin_variable_annotation_wrap = off
|
||||
ij_kotlin_while_on_new_line = false
|
||||
ij_kotlin_wrap_elvis_expressions = 1
|
||||
ij_kotlin_wrap_expression_body_functions = 0
|
||||
ij_kotlin_wrap_first_method_in_call_chain = false
|
||||
|
||||
|
||||
[*.json]
|
||||
indent_size = 2
|
||||
ij_json_keep_blank_lines_in_code = 0
|
||||
ij_json_keep_indents_on_empty_lines = false
|
||||
ij_json_keep_line_breaks = true
|
||||
ij_json_space_after_colon = true
|
||||
ij_json_space_after_comma = true
|
||||
ij_json_space_before_colon = true
|
||||
ij_json_space_before_comma = false
|
||||
ij_json_spaces_within_braces = false
|
||||
ij_json_spaces_within_brackets = false
|
||||
ij_json_wrap_long_lines = false
|
||||
|
||||
[{*.htm, *.html, *.sht, *.shtm, *.shtml}]
|
||||
ij_html_add_new_line_before_tags = body, div, p, form, h1, h2, h3
|
||||
ij_html_align_attributes = true
|
||||
ij_html_align_text = false
|
||||
ij_html_attribute_wrap = normal
|
||||
ij_html_block_comment_at_first_column = true
|
||||
ij_html_do_not_align_children_of_min_lines = 0
|
||||
ij_html_do_not_break_if_inline_tags = title, h1, h2, h3, h4, h5, h6, p
|
||||
ij_html_do_not_indent_children_of_tags = html, body, thead, tbody, tfoot
|
||||
ij_html_enforce_quotes = false
|
||||
ij_html_inline_tags = a, abbr, acronym, b, basefont, bdo, big, br, cite, cite, code, dfn, em, font, i, img, input, kbd, label, q, s, samp, select, small, span, strike, strong, sub, sup, textarea, tt, u, var
|
||||
ij_html_keep_blank_lines = 2
|
||||
ij_html_keep_indents_on_empty_lines = false
|
||||
ij_html_keep_line_breaks = true
|
||||
ij_html_keep_line_breaks_in_text = true
|
||||
ij_html_keep_whitespaces = false
|
||||
ij_html_keep_whitespaces_inside = span, pre, textarea
|
||||
ij_html_line_comment_at_first_column = true
|
||||
ij_html_new_line_after_last_attribute = never
|
||||
ij_html_new_line_before_first_attribute = never
|
||||
ij_html_quote_style = double
|
||||
ij_html_remove_new_line_before_tags = br
|
||||
ij_html_space_after_tag_name = false
|
||||
ij_html_space_around_equality_in_attribute = false
|
||||
ij_html_space_inside_empty_tag = false
|
||||
ij_html_text_wrap = normal
|
||||
ij_html_uniform_ident = false
|
||||
|
||||
[{*.yaml, *.yml}]
|
||||
indent_size = 2
|
||||
ij_yaml_keep_indents_on_empty_lines = false
|
||||
ij_yaml_keep_line_breaks = true
|
||||
ij_yaml_space_before_colon = false
|
||||
ij_yaml_spaces_within_braces = true
|
||||
ij_yaml_spaces_within_brackets = true
|
4
.gitattributes
vendored
Normal file
4
.gitattributes
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
* text=auto
|
||||
|
||||
*.java text
|
||||
*.jar binary
|
1
.github/CODEOWNERS
vendored
Normal file
1
.github/CODEOWNERS
vendored
Normal file
@ -0,0 +1 @@
|
||||
* @IntellectualSites/plotsquared-team
|
28
.github/ISSUE_TEMPLATE.md
vendored
28
.github/ISSUE_TEMPLATE.md
vendored
@ -1,28 +0,0 @@
|
||||
__*NOTICE: Bukkit/Spigot versions 1.7.10 to 1.12.2 are considered legacy and will receive limited support. Please consider upgrading to 1.13 for future support. Plugins exist for 1.13+ that bring back old behaviors found in 1.8*__
|
||||
# Bug report template
|
||||
<!--- In order to create a valid issue report you have to follow this template. -->
|
||||
<!--- Incomplete reports might be marked as invalid. -->
|
||||
<!-- Feature requests and enhancements may be suggested at https://github.com/IntellectualSites/PlotSquaredSuggestions. -->
|
||||
**Debug paste link:**
|
||||
<!--- Enter /plot debugpaste in game or in your console and copy the output here -->
|
||||
|
||||
**[REQUIRED] Spigot/Paper Version Number:**
|
||||
|
||||
**[REQUIRED] Minecraft Version Number:**
|
||||
|
||||
**[REQUIRED] Description of the problem:**
|
||||
|
||||
**Any relevant console output or screenshots:**
|
||||
|
||||
**Plugins being used on the server:**
|
||||
<!--- Optional but recommended --->
|
||||
|
||||
**How to replicate:**
|
||||
<!--- If you can reproduce the issue please tell us as detailed as possible step by step how to do that -->
|
||||
|
||||
**Checklist**:
|
||||
<!-- Make sure you have completed the following steps (put an "X" between of brackets): -->
|
||||
- [] I included all information required in the sections above
|
||||
- [] I made sure there are no duplicates of this report [(Use Search)](https://github.com/IntellectualSites/PlotSquared/issues?utf8=%E2%9C%93&q=is%3Aissue)
|
||||
- [] I made sure I am using an up-to-date version of PlotSquared
|
||||
- [] I made sure the bug/error is not caused by any other plugin
|
@ -1,98 +0,0 @@
|
||||
---
|
||||
name: Bug/Issue report for PlotSquared
|
||||
about: Bug / Issue report about this plugin
|
||||
title: ''
|
||||
labels: "[?] Testing Required"
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!--- READ THIS BEFORE SUBMITTING AN ISSUE REPORT!!! -->
|
||||
|
||||
<!--- ##### DO NOT REMOVE THIS TEMPLATE! YOUR ISSUE *WILL* FIT IN IT! ##### -->
|
||||
|
||||
<!--- # NOTICE:
|
||||
```diff
|
||||
! PlotSquared for Minecraft Java Edition versions between 1.7 through to 1.12.2 are considered
|
||||
! legacy, and will receive limited to no support. Please consider upgrading to 1.13+ for
|
||||
! future support. Plugins exist for 1.13+ which bring back behaviors found in 1.8.8
|
||||
! All versions of PlotSquared for Sponge and Nukkit(X) will receive limited to no support
|
||||
! due to lack of developer interest and time. Additionally, NukkitX has not had feature
|
||||
! updates since the Better Together, which prevents some PlotSquared features from ever
|
||||
! functioning. Contributions are always welcome however!
|
||||
```
|
||||
|
||||
**Feature requests & Suggestions are to be submitted at the [PlotSquared Suggestions tracker](https://github.com/IntellectualSites/PlotSquaredSuggestions)**
|
||||
|
||||
**Code contributions are to be done through [PRs](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request), tagging the specific issue ticket(s) if applicable.**
|
||||
|
||||
**[DISCORD INVITE LINK](https://discord.gg/cSMxtGn)** and please, for the love of the little sanity we have left, use the correct channels!
|
||||
-->
|
||||
|
||||
# Bug Report Template:
|
||||
<!--- Incomplete reports will most likely be marked as invalid, and closed, with few exceptions.-->
|
||||
## Required Information section:
|
||||
> ALL FIELDS IN THIS SECTION ARE REQUIRED, and must contain appropriate information
|
||||
### Server config info (/plot debugpaste / file paste links):
|
||||
<!--- Issue /plot debugpaste in game or in your console and copy the supplied URL here -->
|
||||
<!--- If you cannot perform the above, we require logs/latest.log; settings.yml; worlds.yml and possibly PlotSquared.use_THIS.yml -->
|
||||
<!--- If you are unwilling to supply the information we need, we reserve the right to not assist you. Redact IP addresses if you need to. -->
|
||||
|
||||
### Server type:
|
||||
**Select one**
|
||||
<!-- Select the type you are reporting the issue for (put an "X" between of brackets): -->
|
||||
- [] Spigot / Paper *(CraftBukkit should not be used, re-test with Spigot first!)*
|
||||
- [] Sponge *- NOTE: NOT ACTIVELY MAINTAINED*
|
||||
- [] NukkitX *- NOTE: NOT ACTIVELY MAINTAINED*
|
||||
|
||||
### Minecraft Version:
|
||||
**Select one**
|
||||
<!-- Select the type you are reporting the issue for (put an "X" between of brackets):
|
||||
The maintained versions are 1.14.4 and 1.15.x -->
|
||||
- [] Minecraft 1.15
|
||||
- [] Minecraft 1.14.4
|
||||
- [] Minecraft 1.13.2
|
||||
- [] Minecraft Java Edition *other versions, please specify*:
|
||||
- [] Minecraft Bedrock Edition *specify version*:
|
||||
|
||||
### Server build info:
|
||||
<!--- Run /version in-game or in console & paste the full output here: -->
|
||||
```
|
||||
Paste the output here, between the tick marks, replacing this text
|
||||
```
|
||||
|
||||
### WorldEdit/FAWE versions:
|
||||
<!--- Specify which plugin you are using, and add its version -->
|
||||
- [] FAWE *version*:
|
||||
- [] WorldEdit *version*:
|
||||
|
||||
### Description of the problem:
|
||||
<!--- Be as specific as possible. Don't lie, redact information, or use false names/situations. -->
|
||||
<!--- Who, What, When, Where, Why, How, Expected behavior, Resultant behavior, etc -->
|
||||
|
||||
### How to replicate:
|
||||
<!--- If you can reproduce the issue please tell us as detailed as possible step by step how to do that -->
|
||||
|
||||
## Additional Information:
|
||||
> The information here is optional for you to provide, however it may help us to more readily diagnose any compatibility and bug issues.
|
||||
|
||||
### Other plugins being used on the server:
|
||||
<!--- Optional but recommended - issue "/plugins" in-game or in console and copy/paste the list -->
|
||||
|
||||
### Relevant console output, log lines, and/or screenshots:
|
||||
<!--- Please use in-line code insertion
|
||||
```
|
||||
like this
|
||||
```
|
||||
for short (20 lines or less) text blobs, or a paste service for large blobs -->
|
||||
|
||||
### Additional relevant comments/remarks:
|
||||
<!--- Use this space to give us any additional information which may be relevant to this issue, such as: if you are using a Minecraft hosting provider; unusual installation environment; etc -->
|
||||
|
||||
# AFFIRMATION OF COMPLETION:
|
||||
<!-- Make sure you have completed the following steps (put an "X" between of brackets): -->
|
||||
- [] I included all information required in the sections above
|
||||
- [] I made sure there are no duplicates of this report [(Use Search)](https://github.com/IntellectualSites/PlotSquared/issues?utf8=%E2%9C%93&q=is%3Aissue)
|
||||
- [] I made sure I am using an up-to-date version of PlotSquared
|
||||
- [] I made sure the bug/error is not caused by any other plugin
|
||||
- [x] I didn't read but checked everything above.
|
105
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
105
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@ -0,0 +1,105 @@
|
||||
name: Bug report
|
||||
description: Create a report to help us improve
|
||||
labels: 'Requires Testing'
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report for PlotSquared! Fill out the following form to your best ability to help us fix the problem.
|
||||
Only use this if you're absolutely sure that you found a bug and can reproduce it. For anything else, use: [our Discord server](https://discord.gg/intellectualsites) or [the wiki](https://intellectualsites.github.io/plotsquared-documentation/).
|
||||
Do NOT use the public issue tracker to report security vulnerabilities! They are disclosed using [this](https://forms.gle/btgdRn9yhGtzEiGW8) form!
|
||||
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Server Implementation
|
||||
description: Which server Implementation are you using? If your server implementation is not listed, it is not supported. Switch to a supported version first.
|
||||
multiple: false
|
||||
options:
|
||||
- Paper
|
||||
- Spigot
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Server Version
|
||||
description: Which server version version you using? If your server version is not listed, it is not supported. Update to a supported version first.
|
||||
multiple: false
|
||||
options:
|
||||
- '1.19.3'
|
||||
- '1.19.2'
|
||||
- '1.19.1'
|
||||
- '1.19'
|
||||
- '1.18.2'
|
||||
- '1.18.1'
|
||||
- '1.17.1'
|
||||
- '1.16.5'
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the bug
|
||||
description: A clear and concise description of what the bug is.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: To Reproduce
|
||||
description: Steps to reproduce this behaviour
|
||||
placeholder: |
|
||||
1. Go to '...'
|
||||
2. Click on '...'
|
||||
3. Scroll down to '...'
|
||||
4. See error
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Expected behaviour
|
||||
description: A clear and concise description of what you expected to happen.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Screenshots / Videos
|
||||
description: If applicable, add screenshots to help explain your problem.
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
label: Error log (if applicable)
|
||||
description: If you are reporting a console error, upload any relevant log excerpts to either https://paste.gg/ or https://gist.github.com, save and the paste the link in this box.
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
label: Plot Debugpaste
|
||||
description: Run `/plot debugpaste` in your console or ingame and provide the output link here.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
label: PlotSquared Version
|
||||
description: What version of PlotSquared are you running? (`/version PlotSquared`)
|
||||
placeholder: "For example: PlotSquared version 5.13.11-Premium"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Checklist
|
||||
description: Make sure you have followed each of the steps outlined here.
|
||||
options:
|
||||
- label: I have included a Plot debugpaste.
|
||||
required: true
|
||||
- label: I am using the newest build from https://www.spigotmc.org/resources/77506/ and the issue still persists.
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Anything else?
|
||||
description: You can provide additional context below.
|
9
.github/ISSUE_TEMPLATE/config.yml
vendored
9
.github/ISSUE_TEMPLATE/config.yml
vendored
@ -1,5 +1,8 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: PlotSquared Suggestions
|
||||
url: https://github.com/IntellectualSites/PlotSquaredSuggestions
|
||||
about: If you want to submit feature or suggestion ideas, do that here
|
||||
- name: IntellectualSites Discord
|
||||
url: https://discord.gg/intellectualsites
|
||||
about: Our support Discord, please ask questions and seek support here.
|
||||
- name: PlotSquared Wiki
|
||||
url: https://intellectualsites.github.io/plotsquared-documentation/
|
||||
about: Take a look at the wiki page for instructions how to setup PlotSquared and use its commands.
|
||||
|
29
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
29
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
name: Feature request
|
||||
description: Suggest an idea for this project
|
||||
labels: 'Enhancement'
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this feature request for PlotSquared! Fill out the following form to your best ability to help us understand your feature request and greately improve the change of it getting added.
|
||||
For anything else than a feature request, use: [our Discord server](https://discord.gg/intellectualsites) or [the wiki](https://intellectualsites.github.io/plotsquared-documentation/).
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: What feature do you want to see added?
|
||||
description: A clear and concise description of your feature request.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Are there any alternatives?
|
||||
description: List any alternatives you might have tried
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Anything else?
|
||||
description: You can provide additional context below.
|
17
.github/PULL_REQUEST_TEMPLATE.md
vendored
17
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,17 +0,0 @@
|
||||
## Overview
|
||||
<!-- Please describe which issue this Pull Request targets
|
||||
|
||||
If there is no issue, please create one so we can look into it before approving your PR.
|
||||
You can do so here: https://github.com/IntellectualSites/PlotSquared/issues/new/choose
|
||||
-->
|
||||
|
||||
**Fixes #{issue number}**
|
||||
|
||||
## Description
|
||||
|
||||
## Checklist
|
||||
<!-- Make sure you have completed the following steps (put an "X" between of brackets): -->
|
||||
- [] I included all information required in the sections above
|
||||
- [] I tested my changes and approved their functionality
|
||||
- [] I ensured my changes do not break other parts of the code
|
||||
- [] I read and followed the [contribution guidelines](https://github.com/IntellectualSites/PlotSquared/blob/breaking/CONTRIBUTING.md)
|
8
.github/auto-comment.yml
vendored
8
.github/auto-comment.yml
vendored
@ -1,8 +0,0 @@
|
||||
# Comment to a new issue.
|
||||
issueOpened: >
|
||||
Thank your for raising a issue. We will try and get back to you as soon as possible.
|
||||
|
||||
Please make sure that you followed the issue template, and provided all neccessary information.
|
||||
Failure to do so will prevent us from resolving the issue in a timely manner.
|
||||
|
||||
Please note that suggestions are now to be submitted to https://git.io/fN5B4 rather than this issue tracker!
|
1
.github/release-drafter.yml
vendored
Normal file
1
.github/release-drafter.yml
vendored
Normal file
@ -0,0 +1 @@
|
||||
_extends: .github
|
26
.github/stale.yml
vendored
26
.github/stale.yml
vendored
@ -1,16 +1,18 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 60
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilStale: 30
|
||||
daysUntilClose: 7
|
||||
# Issues with these labels will never be considered stale
|
||||
only: issues
|
||||
exemptLabels:
|
||||
- [‼] high priority
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: Old
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
- "Bug"
|
||||
- "Enhancement"
|
||||
- "Approved"
|
||||
- "Priority"
|
||||
- "Under investigation"
|
||||
staleLabel: "resolution: stale"
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: false
|
||||
recent activity. It will be closed if no further activity occurs. If the issue is still present and can be reproduced, please let the team know.
|
||||
Thank you for your contributions.
|
||||
closeComment: >
|
||||
This issue has been automatically closed because it has not had activity in
|
||||
a long time. If the issue still applies to the most recent supported
|
||||
version, please reply to this issue and the team will reopen it.
|
||||
|
24
.github/workflows/announce-release-on-discord.yml
vendored
Normal file
24
.github/workflows/announce-release-on-discord.yml
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
name: Announce release on discord
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
jobs:
|
||||
send_announcement:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: send custom message with args
|
||||
env:
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
|
||||
DISCORD_USERNAME: PlotSquared Release
|
||||
DISCORD_AVATAR: https://raw.githubusercontent.com/IntellectualSites/Assets/main/plugins/PlotSquared/PlotSquared.png
|
||||
uses: Ilshidur/action-discord@08d9328877d6954120eef2b07abbc79249bb6210 # ratchet:Ilshidur/action-discord@0.3.2
|
||||
with:
|
||||
args: |
|
||||
"<@&525015541815967744> <@&679322738552471574> <@&699293353862496266>"
|
||||
""
|
||||
"<:plotsquared:730750385886593039> **PlotSquared ${{ github.event.release.tag_name }} has been released!**"
|
||||
""
|
||||
"Click here to view changelog: https://github.com/IntellectualSites/PlotSquared/releases/tag/${{ github.event.release.tag_name }}"
|
||||
""
|
||||
"The download is available at:"
|
||||
"- Spigot: <https://www.spigotmc.org/resources/77506/>"
|
21
.github/workflows/build-pr.yml
vendored
Normal file
21
.github/workflows/build-pr.yml
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
name: Build PR
|
||||
on: [pull_request]
|
||||
jobs:
|
||||
build_pr:
|
||||
if: github.repository_owner == 'IntellectualSites'
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v3
|
||||
- name: Validate Gradle Wrapper
|
||||
uses: gradle/wrapper-validation-action@55e685c48d84285a5b0418cd094606e199cca3b6 # v1
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 17
|
||||
- name: Clean Build
|
||||
run: ./gradlew clean build
|
67
.github/workflows/build.yml
vendored
Normal file
67
.github/workflows/build.yml
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
name: build
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- v6
|
||||
jobs:
|
||||
build:
|
||||
if: github.repository_owner == 'IntellectualSites'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v3
|
||||
- name: Validate Gradle Wrapper
|
||||
uses: gradle/wrapper-validation-action@55e685c48d84285a5b0418cd094606e199cca3b6 # v1
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: 17
|
||||
- name: Clean Build
|
||||
run: ./gradlew clean build
|
||||
- name: Determine release status
|
||||
if: ${{ runner.os == 'Linux' }}
|
||||
run: |
|
||||
if [ "$(./gradlew properties | awk '/^version:/ { print $2; }' | grep '\-SNAPSHOT')" ]; then
|
||||
echo "STATUS=snapshot" >> $GITHUB_ENV
|
||||
else
|
||||
echo "STATUS=release" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Publish Release
|
||||
if: ${{ runner.os == 'Linux' && env.STATUS == 'release' && github.event_name == 'push' && github.ref == 'refs/heads/v6'}}
|
||||
run: ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository
|
||||
env:
|
||||
ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.SONATYPE_USERNAME }}
|
||||
ORG_GRADLE_PROJECT_sonatypePassword: ${{ secrets.SONATYPE_PASSWORD }}
|
||||
ORG_GRADLE_PROJECT_signingKey: ${{ secrets.SIGNING_KEY }}
|
||||
ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.SIGNING_PASSWORD }}
|
||||
- name: Publish Snapshot
|
||||
if: ${{ runner.os == 'Linux' && env.STATUS != 'release' && github.event_name == 'push' && github.ref == 'refs/heads/v6' }}
|
||||
run: ./gradlew publishToSonatype
|
||||
env:
|
||||
ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.SONATYPE_USERNAME }}
|
||||
ORG_GRADLE_PROJECT_sonatypePassword: ${{ secrets.SONATYPE_PASSWORD }}
|
||||
- name: Publish core javadoc
|
||||
if: ${{ runner.os == 'Linux' && env.STATUS == 'release' && github.event_name == 'push' && github.ref == 'refs/heads/v6'}}
|
||||
uses: cpina/github-action-push-to-another-repository@0a14457bb28b04dfa1652e0ffdfda866d2845c73 # main
|
||||
env:
|
||||
SSH_DEPLOY_KEY: ${{ secrets.SSH_DEPLOY_KEY }}
|
||||
with:
|
||||
source-directory: 'Core/build/docs/javadoc'
|
||||
destination-github-username: 'IntellectualSites'
|
||||
destination-repository-name: 'plotsquared-javadocs'
|
||||
user-email: ${{ secrets.USER_EMAIL }}
|
||||
target-branch: main
|
||||
target-directory: core
|
||||
- name: Publish bukkit javadoc
|
||||
if: ${{ runner.os == 'Linux' && env.STATUS == 'release' && github.event_name == 'push' && github.ref == 'refs/heads/v6'}}
|
||||
uses: cpina/github-action-push-to-another-repository@0a14457bb28b04dfa1652e0ffdfda866d2845c73 # main
|
||||
env:
|
||||
SSH_DEPLOY_KEY: ${{ secrets.SSH_DEPLOY_KEY }}
|
||||
with:
|
||||
source-directory: 'Bukkit/build/docs/javadoc'
|
||||
destination-github-username: 'IntellectualSites'
|
||||
destination-repository-name: 'plotsquared-javadocs'
|
||||
user-email: ${{ secrets.USER_EMAIL }}
|
||||
target-branch: main
|
||||
target-directory: bukkit
|
28
.github/workflows/codeql.yml
vendored
Normal file
28
.github/workflows/codeql.yml
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
name: "CodeQL"
|
||||
on:
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [v6]
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: ['java']
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@32dc499307d133bb5085bae78498c0ac2cf762d5 # v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@32dc499307d133bb5085bae78498c0ac2cf762d5 # v2
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@32dc499307d133bb5085bae78498c0ac2cf762d5 # v2
|
26
.github/workflows/gradle.yml
vendored
26
.github/workflows/gradle.yml
vendored
@ -1,26 +0,0 @@
|
||||
name: Java CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- v4
|
||||
- v5
|
||||
- leagcy/1.8-1.12
|
||||
pull_request:
|
||||
branches:
|
||||
- v4
|
||||
- v5
|
||||
- leagcy/1.8-1.12
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-18.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Set up JDK 1.8
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 1.8
|
||||
- name: Test with Gradle
|
||||
run: ./gradlew clean build
|
17
.github/workflows/release-drafter.yml
vendored
Normal file
17
.github/workflows/release-drafter.yml
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
name: draft release
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- v6
|
||||
pull_request:
|
||||
types: [opened, reopened, synchronize]
|
||||
pull_request_target:
|
||||
types: [opened, reopened, synchronize]
|
||||
jobs:
|
||||
update_release_draft:
|
||||
if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: release-drafter/release-drafter@v5
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
282
.gitignore
vendored
282
.gitignore
vendored
@ -1,143 +1,139 @@
|
||||
### Others ###
|
||||
*.cmd
|
||||
*.sh
|
||||
*.prefs
|
||||
Sponge/build
|
||||
Core/build
|
||||
Bukkit/build
|
||||
Nukkit/build
|
||||
|
||||
### Maven ###
|
||||
/mvn
|
||||
/target/lib
|
||||
/target/maven-archiver
|
||||
/target/classes
|
||||
/target/maven-status
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
pom.xml.next
|
||||
release.properties
|
||||
dependency-reduced-pom.xml
|
||||
buildNumber.properties
|
||||
.mvn/timing.properties
|
||||
out/
|
||||
|
||||
|
||||
### Java ###
|
||||
*.class
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.war
|
||||
*.ear
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
|
||||
### Intellij ###
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
|
||||
|
||||
*.iml
|
||||
|
||||
## Directory-based project format:
|
||||
.idea/
|
||||
# if you remove the above rule, at least ignore the following:
|
||||
|
||||
# User-specific stuff:
|
||||
# .idea/workspace.xml
|
||||
# .idea/tasks.xml
|
||||
# .idea/dictionaries
|
||||
# .idea/shelf
|
||||
|
||||
# Sensitive or high-churn files:
|
||||
# .idea/dataSources.ids
|
||||
# .idea/dataSources.xml
|
||||
# .idea/sqlDataSources.xml
|
||||
# .idea/dynamic.xml
|
||||
# .idea/uiDesigner.xml
|
||||
|
||||
# Gradle:
|
||||
# .idea/gradle.xml
|
||||
# .idea/libraries
|
||||
.gradle
|
||||
|
||||
# Mongo Explorer plugin:
|
||||
# .idea/mongoSettings.xml
|
||||
|
||||
## File-based project format:
|
||||
*.ipr
|
||||
*.iws
|
||||
|
||||
## Plugin-specific files:
|
||||
|
||||
# IntelliJ
|
||||
/out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
|
||||
### Eclipse ###
|
||||
*.pydevproject
|
||||
.metadata
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.settings/
|
||||
.loadpath
|
||||
|
||||
# Eclipse Core
|
||||
.project
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# CDT-specific
|
||||
.cproject
|
||||
|
||||
# JDT-specific (Eclipse Java Development Tools)
|
||||
.classpath
|
||||
|
||||
# Java annotation processor (APT)
|
||||
.factorypath
|
||||
|
||||
# PDT-specific
|
||||
.buildpath
|
||||
|
||||
# sbteclipse plugin
|
||||
.target
|
||||
|
||||
# TeXlipse plugin
|
||||
.texlipse
|
||||
|
||||
# STS (Spring Tool Suite)
|
||||
.springBeans
|
||||
/target/
|
||||
Nukkit/build/classes/
|
||||
Nukkit/build/dependency-cache/
|
||||
checkstyle.xml
|
||||
classes/
|
||||
p2error.txt
|
||||
*.bat
|
||||
Nukkit/build/resources/main/plugin.yml
|
||||
docs/
|
||||
### Others ###
|
||||
*.cmd
|
||||
*.sh
|
||||
*.prefs
|
||||
Core/build
|
||||
|
||||
### Maven ###
|
||||
/mvn
|
||||
/target/lib
|
||||
/target/maven-archiver
|
||||
/target/classes
|
||||
/target/maven-status
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
pom.xml.next
|
||||
release.properties
|
||||
dependency-reduced-pom.xml
|
||||
buildNumber.properties
|
||||
.mvn/timing.properties
|
||||
out/
|
||||
|
||||
|
||||
### Java ###
|
||||
*.class
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.war
|
||||
*.ear
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
|
||||
### Intellij ###
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
|
||||
|
||||
*.iml
|
||||
|
||||
## Directory-based project format:
|
||||
/.idea/*
|
||||
!/.idea/icon.svg
|
||||
# if you remove the above rule, at least ignore the following:
|
||||
|
||||
# User-specific stuff:
|
||||
# .idea/workspace.xml
|
||||
# .idea/tasks.xml
|
||||
# .idea/dictionaries
|
||||
# .idea/shelf
|
||||
|
||||
# Sensitive or high-churn files:
|
||||
# .idea/dataSources.ids
|
||||
# .idea/dataSources.xml
|
||||
# .idea/sqlDataSources.xml
|
||||
# .idea/dynamic.xml
|
||||
# .idea/uiDesigner.xml
|
||||
|
||||
# Gradle:
|
||||
# .idea/gradle.xml
|
||||
# .idea/libraries
|
||||
.gradle
|
||||
|
||||
# Mongo Explorer plugin:
|
||||
# .idea/mongoSettings.xml
|
||||
|
||||
## File-based project format:
|
||||
*.ipr
|
||||
*.iws
|
||||
|
||||
## Plugin-specific files:
|
||||
|
||||
# IntelliJ
|
||||
/out/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
|
||||
### Eclipse ###
|
||||
*.pydevproject
|
||||
.metadata
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.settings/
|
||||
.loadpath
|
||||
|
||||
# Eclipse Core
|
||||
.project
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# CDT-specific
|
||||
.cproject
|
||||
|
||||
# JDT-specific (Eclipse Java Development Tools)
|
||||
.classpath
|
||||
|
||||
# Java annotation processor (APT)
|
||||
.factorypath
|
||||
|
||||
# PDT-specific
|
||||
.buildpath
|
||||
|
||||
# sbteclipse plugin
|
||||
.target
|
||||
|
||||
# TeXlipse plugin
|
||||
.texlipse
|
||||
|
||||
# STS (Spring Tool Suite)
|
||||
.springBeans
|
||||
/target/
|
||||
checkstyle.xml
|
||||
classes/
|
||||
*.bat
|
||||
|
||||
# Other
|
||||
docs/
|
||||
build/
|
||||
|
||||
.DS_Store
|
||||
|
50
.idea/icon.svg
generated
Normal file
50
.idea/icon.svg
generated
Normal file
@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.1" id="svg2" xml:space="preserve" width="4000" height="3333.3333" viewBox="0 0 4000 3333.3333" sodipodi:docname="PlotSquared.ai">
|
||||
<metadata id="metadata8">
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs id="defs6">
|
||||
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath18">
|
||||
<path d="M 0,2500 H 3000 V 0 H 0 Z" id="path16" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<sodipodi:namedview pagecolor="#ffffff" bordercolor="#666666" borderopacity="1" objecttolerance="10" gridtolerance="10" guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-width="640" inkscape:window-height="480" id="namedview4" />
|
||||
<g id="g10" inkscape:groupmode="layer" inkscape:label="PlotSquared" transform="matrix(1.3333333,0,0,-1.3333333,0,3333.3333)">
|
||||
<g id="g12">
|
||||
<g id="g14" clip-path="url(#clipPath18)">
|
||||
<g id="g20" transform="translate(1486.1511,2242.6453)">
|
||||
<path d="m 0,0 c 16.533,10.846 33.211,21.453 50.104,31.699 78.972,-48.281 153.985,-102.704 227.269,-159.144 148.61,-115.422 287.884,-243.01 414.393,-382.333 111.39,-122.861 212.751,-255.152 298.898,-396.971 52.744,-87.322 100.544,-177.884 139.514,-272.214 -11.638,-3.551 -23.108,-7.655 -34.362,-12.286 l -0.24,0.288 c -11.135,12.982 -24.141,24.212 -34.915,37.506 -22.557,23.013 -45.425,45.737 -68.03,68.678 -19.725,20.253 -40.601,39.45 -58.958,60.974 -36.355,36.451 -72.517,73.093 -108.944,109.471 -22.628,26.013 -48.064,49.385 -71.965,74.197 -19.029,19.485 -38.706,38.346 -57.519,57.999 -12.166,14.998 -26.684,27.716 -39.93,41.658 -27.668,27.524 -54.903,55.479 -82.571,82.979 -23.924,27.956 -51.664,52.264 -76.692,79.164 -4.68,4.487 -8.855,10.774 -15.886,11.326 -22.34,34.027 -58.311,57.327 -97.377,67.502 -104.312,99.153 -215.487,191.202 -332.661,274.782 -117.942,-83.94 -229.476,-176.781 -334.484,-276.39 -26.684,-0.024 -53.368,0.024 -80.076,-0.024 0.024,-26.564 0.048,-53.104 0,-79.668 -72.229,-73.021 -139.491,-150.937 -202.385,-232.092 -63.758,-82.619 -121.973,-169.51 -173.541,-260.264 131.932,-69.061 257.864,-149.521 375.926,-240.275 0.096,-26.444 -0.12,-52.888 0.096,-79.332 l 0.744,-0.984 c 20.109,-24.14 43.409,-45.233 65.126,-67.861 15.118,-15.382 30.571,-30.404 45.569,-45.881 17.565,-20.733 37.698,-39.042 56.607,-58.503 19.917,-20.781 41.25,-40.218 59.967,-62.151 29.156,-29.299 58.167,-58.815 87.515,-87.922 29.155,-33.043 61.502,-63.111 92.169,-94.738 13.726,-12.67 25.124,-27.571 38.634,-40.457 25.029,-25.365 50.129,-50.657 75.325,-75.853 -37.914,-51.208 -73.741,-103.952 -107.192,-158.183 -167.83,273.317 -397.235,507.305 -662.37,687.158 -81.875,55.335 -167.23,105.584 -255.681,149.641 -52.815,26.276 -106.831,50.248 -162.239,70.381 99.393,233.628 242.795,446.715 410.289,636.79 93.562,106.088 194.634,205.433 301.466,298.13 C -217.335,-155.808 -111.439,-73.789 0,0" style="fill:#062f4c;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path22" />
|
||||
</g>
|
||||
<g id="g24" transform="translate(1201.7948,1741.5303)">
|
||||
<path d="M 0,0 C 105.008,99.609 216.543,192.45 334.485,276.39 451.659,192.81 562.833,100.76 667.146,1.608 c -34.987,8.83 -71.51,9.718 -107.264,6.431 -41.202,-4.296 -82.907,-19.077 -112.543,-48.953 -33.019,-32.155 -49.456,-77.604 -55.311,-122.501 -28.124,27.908 -56.104,55.983 -84.035,84.083 -2.976,2.976 -6.839,4.823 -10.391,6.911 -19.029,26.348 -45.953,46.673 -76.62,57.495 C 187.555,-2.472 151.513,-0.12 116.166,0 Z" style="fill:#4c8fcc;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path26" />
|
||||
</g>
|
||||
<g id="g28" transform="translate(919.3342,1429.7462)">
|
||||
<path d="m 0,0 c 62.894,81.156 130.156,159.072 202.385,232.092 0.048,-244.21 0.024,-488.421 0,-732.631 C 84.323,-409.785 -41.61,-329.325 -173.541,-260.264 -121.973,-169.51 -63.758,-82.619 0,0" style="fill:#4c8fcc;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path30" />
|
||||
</g>
|
||||
<g id="g32" transform="translate(1649.134,1700.6166)">
|
||||
<path d="m 0,0 c 29.635,29.875 71.341,44.657 112.543,48.952 35.754,3.288 72.277,2.4 107.263,-6.431 39.066,-10.174 75.037,-33.474 97.377,-67.501 11.879,-17.661 20.181,-37.411 26.42,-57.687 10.871,-38.802 11.95,-79.356 11.446,-119.358 -44.345,-0.072 -88.69,0.048 -133.035,-0.072 -1.032,30.907 3.263,63.686 -10.175,92.626 -9.526,20.325 -32.107,31.243 -53.751,32.131 -21.453,1.44 -45.065,-4.32 -59.175,-21.597 -12.79,-15.861 -15.382,-37.002 -16.558,-56.655 -1.295,-29.132 3.696,-59.031 17.518,-84.923 16.821,-30.619 39.378,-57.783 64.526,-81.9 31.387,-32.634 67.501,-60.374 97.857,-94.041 27.332,-28.988 51.256,-61.479 68.005,-97.785 20.541,-41.13 26.972,-87.827 25.82,-133.372 -0.912,-32.107 -5.231,-64.406 -16.149,-94.737 -11.59,-31.699 -31.123,-61.047 -58.335,-81.371 -25.124,-19.125 -55.696,-29.852 -86.651,-34.771 -49.552,-6.743 -101.888,-4.847 -148.465,14.854 -35.227,14.829 -64.238,42.689 -81.708,76.548 -20.996,40.242 -27.115,86.339 -27.259,131.212 0.048,17.829 0,35.658 0.048,53.463 44.345,0.048 88.69,-0.023 133.059,0.048 1.728,-35.538 -4.055,-72.06 5.663,-106.807 5.783,-22.173 26.204,-37.794 48.185,-41.754 20.733,-3.431 43.577,-2.015 61.622,9.791 15.502,9.43 23.949,26.78 26.78,44.225 5.903,35.922 1.872,74.293 -15.381,106.688 -16.918,30.595 -39.474,57.711 -64.55,81.899 -33.187,34.099 -71.173,63.254 -102.585,99.081 -26.756,28.867 -49.408,61.646 -65.486,97.641 -24.572,52.48 -26.731,112.422 -20.18,169.102 C -49.456,-77.604 -33.019,-32.155 0,0" style="fill:#feeeee;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path34" />
|
||||
</g>
|
||||
<g id="g36" transform="translate(1262.7214,1613.126)">
|
||||
<path d="m 0,0 v -301.13 c 23.204,0.024 46.409,-0.048 69.613,0.024 18.525,0.288 38.202,6.575 50.153,21.429 12.43,17.277 13.917,39.522 14.613,60.111 0.024,43.985 -0.048,87.994 0.024,131.979 -0.48,23.637 -0.983,50.369 -17.277,69.23 C 104.864,-5.711 86.867,-0.24 69.589,0 46.385,0.048 23.204,0.024 0,0 m -141.002,128.38 c 26.708,0.048 53.392,0 80.075,0.024 H 55.24 c 35.346,-0.12 71.389,-2.471 104.815,-14.925 30.668,-10.823 57.592,-31.148 76.621,-57.496 26.852,-39.09 36.69,-87.202 38.058,-133.947 0.024,-48.833 0.096,-97.689 -0.024,-146.521 -1.728,-47.993 -11.974,-97.953 -41.514,-136.971 -22.748,-30.644 -57.495,-50.801 -94.281,-59.583 -45.377,-11.878 -92.578,-6.791 -138.891,-7.847 -0.072,-111.799 0,-223.574 -0.024,-335.373 -13.942,0 -27.86,0.024 -41.778,-0.024 -32.802,0.072 -65.605,0 -98.384,0.048 l -0.744,0.984 c -0.216,26.444 0,52.888 -0.096,79.332 0.024,244.211 0.048,488.421 0,732.632 0.048,26.563 0.024,53.103 0,79.667" style="fill:#feeeee;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path38" />
|
||||
</g>
|
||||
<g id="g40" transform="translate(1966.3174,1675.6364)">
|
||||
<path d="m 0,0 c 7.031,-0.552 11.206,-6.839 15.885,-11.326 25.029,-26.9 52.768,-51.208 76.693,-79.164 27.667,-27.5 54.903,-55.456 82.571,-82.979 13.246,-13.942 27.764,-26.66 39.93,-41.658 18.813,-19.653 38.49,-38.514 57.519,-57.999 23.9,-24.812 49.337,-48.185 71.965,-74.197 36.427,-36.378 72.589,-73.02 108.943,-109.471 18.358,-21.524 39.234,-40.722 58.959,-60.974 22.605,-22.941 45.473,-45.665 68.03,-68.678 10.774,-13.294 23.78,-24.524 34.914,-37.506 -103.904,-41.97 -203.488,-94.114 -298.922,-152.761 -246.994,-152.28 -466.224,-350.298 -639.333,-583.398 -25.197,25.196 -50.297,50.488 -75.325,75.852 -13.51,12.886 -24.908,27.788 -38.634,40.458 -30.667,31.627 -63.014,61.695 -92.17,94.738 -29.347,29.107 -58.359,58.623 -87.514,87.922 -18.717,21.933 -40.05,41.37 -59.967,62.151 -18.909,19.461 -39.042,37.77 -56.607,58.503 -14.998,15.477 -30.452,30.499 -45.569,45.88 -21.717,22.629 -45.017,43.722 -65.126,67.862 32.779,-0.048 65.582,0.024 98.384,-0.048 114.391,-98.097 220.407,-205.984 315.384,-322.99 92.914,114.318 196.242,220.022 307.753,316.271 30.955,4.919 61.526,15.646 86.65,34.771 27.212,20.325 46.745,49.672 58.335,81.371 107.312,77.988 219.327,149.929 337.509,210.376 -35.299,64.67 -75.829,126.437 -118.254,186.643 C 176.253,-228.037 104.24,-140.115 26.42,-57.687 20.181,-37.41 11.878,-17.661 0,0" style="fill:#042338;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path42" />
|
||||
</g>
|
||||
<g id="g44" transform="translate(1499.3971,1669.1094)">
|
||||
<path d="m 0,0 c 3.551,-2.088 7.415,-3.935 10.39,-6.911 27.932,-28.1 55.912,-56.175 84.036,-84.083 -6.551,-56.679 -4.392,-116.622 20.18,-169.102 16.078,-35.994 38.73,-68.774 65.486,-97.641 31.412,-35.826 69.398,-64.982 102.585,-99.081 25.076,-24.188 47.632,-51.304 64.55,-81.899 17.253,-32.395 21.284,-70.765 15.381,-106.688 -2.831,-17.445 -11.278,-34.794 -26.78,-44.225 -18.045,-11.806 -40.889,-13.222 -61.622,-9.79 -21.981,3.959 -42.402,19.58 -48.185,41.753 -9.718,34.747 -3.935,71.269 -5.663,106.808 -44.369,-0.072 -88.714,0 -133.059,-0.048 -0.048,-17.806 0,-35.635 -0.048,-53.464 0.144,-44.873 6.263,-90.97 27.259,-131.212 17.47,-33.859 46.481,-61.718 81.708,-76.548 46.577,-19.701 98.913,-21.597 148.465,-14.854 -111.511,-96.249 -214.839,-201.953 -307.753,-316.271 -94.977,117.006 -200.993,224.893 -315.383,322.99 13.918,0.048 27.836,0.024 41.777,0.024 0.024,111.799 -0.048,223.574 0.024,335.372 46.313,1.056 93.514,-4.031 138.891,7.847 36.786,8.783 71.533,28.94 94.282,59.583 29.539,39.018 39.785,88.978 41.513,136.971 0.12,48.833 0.048,97.689 0.024,146.522 C 36.69,-87.203 26.852,-39.09 0,0" style="fill:#1c72ba;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path46" />
|
||||
</g>
|
||||
<g id="g48" transform="translate(1748.0469,1601.6797)">
|
||||
<path d="M 0,0 C 14.11,17.277 37.722,23.036 59.175,21.597 80.82,20.709 103.4,9.791 112.927,-10.534 c 13.438,-28.94 9.142,-61.719 10.174,-92.626 44.345,0.12 88.691,0 133.036,0.072 0.504,40.002 -0.576,80.556 -11.447,119.358 77.82,-82.428 149.833,-170.35 215.583,-262.664 42.426,-60.207 82.956,-121.973 118.254,-186.643 -118.182,-60.447 -230.196,-132.388 -337.508,-210.376 10.918,30.331 15.238,62.63 16.149,94.737 1.152,45.545 -5.279,92.242 -25.82,133.372 -16.749,36.306 -40.673,68.797 -68.005,97.785 -30.355,33.667 -66.47,61.406 -97.857,94.041 -25.148,24.117 -47.705,51.28 -64.526,81.9 -13.822,25.892 -18.813,55.791 -17.517,84.923 C -15.382,-37.002 -12.79,-15.862 0,0" style="fill:#1c72ba;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path50" />
|
||||
</g>
|
||||
<g id="g52" transform="translate(1262.7214,1613.126)">
|
||||
<path d="m 0,0 c 23.204,0.024 46.385,0.048 69.589,0 17.278,-0.24 35.275,-5.711 47.537,-18.357 16.294,-18.861 16.797,-45.593 17.277,-69.23 -0.072,-43.985 0,-87.994 -0.024,-131.979 -0.696,-20.589 -2.183,-42.834 -14.613,-60.111 -11.951,-14.854 -31.628,-21.141 -50.153,-21.429 -23.204,-0.072 -46.409,0 -69.613,-0.024 z" style="fill:#1c72ba;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path54" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 11 KiB |
@ -1,104 +0,0 @@
|
||||
plugins {
|
||||
id "com.github.johnrengelman.shadow"
|
||||
}
|
||||
repositories {
|
||||
maven { url = "https://hub.spigotmc.org/nexus/content/repositories/snapshots/" }
|
||||
maven { url = "https://oss.sonatype.org/content/repositories/snapshots/" }
|
||||
maven { url = "http://nexus.hc.to/content/repositories/pub_releases" }
|
||||
maven { url = "https://repo.codemc.org/repository/maven-public" }
|
||||
maven {
|
||||
name = "papermc"
|
||||
url = "https://papermc.io/repo/repository/maven-public/"
|
||||
}
|
||||
mavenLocal()
|
||||
}
|
||||
|
||||
|
||||
dependencies {
|
||||
implementation(project(":Core"))
|
||||
compile(project(":Core"))
|
||||
compile("com.destroystokyo.paper:paper-api:1.14.4-R0.1-SNAPSHOT")
|
||||
//implementation 'com.onarandombox.multiversecore:Multiverse-Core:3.0.0-SNAPSHOT'
|
||||
implementation("org.spigotmc:spigot-api:1.15.2-R0.1-SNAPSHOT")
|
||||
compile(group: "com.sk89q.worldedit", name: "worldedit-bukkit", version: "7.0.1")
|
||||
compile("io.papermc:paperlib:1.0.2")
|
||||
compile(group: "com.squareup.retrofit2", name: "retrofit", version: "2.4.0")
|
||||
implementation("net.kyori:text-adapter-bukkit:3.0.3")
|
||||
compile("net.milkbowl.vault:VaultAPI:1.7") {
|
||||
exclude(module: "bukkit")
|
||||
}
|
||||
}
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
|
||||
processResources {
|
||||
from("src/main/resources") {
|
||||
include("plugin.yml")
|
||||
expand(
|
||||
name: project.parent.name,
|
||||
version: project.parent.version
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
//noinspection GroovyAssignabilityCheck
|
||||
jar.archiveFileName = "PlotSquared-BukkitAPI-${project.parent.version}.jar"
|
||||
jar.destinationDirectory = file("../mvn/com/github/intellectualsites/plotsquared/PlotSquared-BukkitAPI/" + project.parent.version)
|
||||
task createPom {
|
||||
doLast {
|
||||
pom {
|
||||
project {
|
||||
groupId = "com.github.intellectualsites.plotsquared"
|
||||
artifactId = "PlotSquared-BukkitAPI"
|
||||
version = project.parent.version
|
||||
}
|
||||
}.writeTo("../mvn/com/github/intellectualsites/plotsquared/PlotSquared-BukkitAPI/${project.parent.version}/PlotSquared-BukkitAPI-${project.parent.version}.pom")
|
||||
pom {
|
||||
project {
|
||||
groupId = "com.github.intellectualsites.plotsquared"
|
||||
artifactId = "PlotSquared-BukkitAPI"
|
||||
version = "latest"
|
||||
}
|
||||
}.writeTo("../mvn/com/github/intellectualsites/plotsquared/PlotSquared-BukkitAPI/latest/PlotSquared-BukkitAPI-latest.pom")
|
||||
}
|
||||
}
|
||||
|
||||
task copyFiles {
|
||||
doLast {
|
||||
copy {
|
||||
from("../mvn/com/github/intellectualsites/plotsquared/PlotSquared-BukkitAPI/${project.parent.version}/")
|
||||
into("../mvn/com/github/intellectualsites/plotsquared/PlotSquared-BukkitAPI/latest/")
|
||||
include("PlotSquared-BukkitAPI*.jar")
|
||||
rename("PlotSquared-BukkitAPI-${project.parent.version}.jar", "PlotSquared-BukkitAPI-latest.jar")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
shadowJar {
|
||||
dependencies {
|
||||
include(dependency(":Core"))
|
||||
// update notification stuff
|
||||
include(dependency("com.github.Sauilitired:Jenkins4J:2.0-SNAPSHOT"))
|
||||
include(dependency("com.squareup.retrofit2:retrofit:2.4.0"))
|
||||
include(dependency("com.squareup.okhttp3:okhttp:4.2.2"))
|
||||
include(dependency("com.squareup.okio:okio:2.4.1"))
|
||||
include(dependency("org.jetbrains.kotlin:kotlin-stdlib:1.3.61"))
|
||||
include(dependency("io.papermc:paperlib:1.0.2"))
|
||||
include(dependency("net.kyori:text-adapter-bukkit:3.0.3"))
|
||||
}
|
||||
relocate('net.kyori.text', 'com.github.intellectualsites.plotsquared.formatting.text')
|
||||
relocate("io.papermc.lib", "com.github.intellectualsites.plotsquared.bukkit.paperlib")
|
||||
archiveFileName = "${parent.name}-${project.name}-${parent.version}.jar"
|
||||
destinationDirectory = file "../target"
|
||||
}
|
||||
|
||||
shadowJar.doLast {
|
||||
task ->
|
||||
ant.checksum file: task.archivePath
|
||||
}
|
||||
|
||||
build.dependsOn(shadowJar)
|
||||
build.finalizedBy(copyFiles)
|
||||
copyFiles.dependsOn(createPom)
|
116
Bukkit/build.gradle.kts
Normal file
116
Bukkit/build.gradle.kts
Normal file
@ -0,0 +1,116 @@
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
name = "PlaceholderAPI"
|
||||
url = uri("https://repo.extendedclip.com/content/repositories/placeholderapi/")
|
||||
}
|
||||
|
||||
maven {
|
||||
name = "PaperMC"
|
||||
url = uri("https://repo.papermc.io/repository/maven-public/")
|
||||
}
|
||||
|
||||
maven {
|
||||
name = "EssentialsX"
|
||||
url = uri("https://repo.essentialsx.net/releases/")
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(projects.plotSquaredCore)
|
||||
|
||||
// Metrics
|
||||
implementation("org.bstats:bstats-bukkit")
|
||||
|
||||
// Paper
|
||||
compileOnly("io.papermc.paper:paper-api")
|
||||
implementation("io.papermc:paperlib")
|
||||
|
||||
// Plugins
|
||||
compileOnly(libs.worldeditBukkit) {
|
||||
exclude(group = "org.bukkit")
|
||||
exclude(group = "org.spigotmc")
|
||||
}
|
||||
compileOnly("com.fastasyncworldedit:FastAsyncWorldEdit-Bukkit") { isTransitive = false }
|
||||
testImplementation("com.fastasyncworldedit:FastAsyncWorldEdit-Bukkit") { isTransitive = false }
|
||||
compileOnly("com.github.MilkBowl:VaultAPI") {
|
||||
exclude(group = "org.bukkit")
|
||||
}
|
||||
compileOnly(libs.placeholderapi)
|
||||
compileOnly(libs.luckperms)
|
||||
compileOnly(libs.essentialsx)
|
||||
compileOnly(libs.mvdwapi) { isTransitive = false }
|
||||
|
||||
// Other libraries
|
||||
implementation(libs.squirrelid) { isTransitive = false }
|
||||
implementation("dev.notmyfault.serverlib:ServerLib")
|
||||
|
||||
// Our libraries
|
||||
implementation(libs.arkitektonika)
|
||||
implementation(libs.http4j)
|
||||
implementation("com.intellectualsites.paster:Paster")
|
||||
implementation("com.intellectualsites.informative-annotations:informative-annotations")
|
||||
|
||||
// Adventure
|
||||
implementation("net.kyori:adventure-platform-bukkit")
|
||||
}
|
||||
|
||||
tasks.processResources {
|
||||
filesMatching("plugin.yml") {
|
||||
expand("version" to project.version)
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named<ShadowJar>("shadowJar") {
|
||||
dependencies {
|
||||
exclude(dependency("org.checkerframework:"))
|
||||
}
|
||||
|
||||
relocate("net.kyori.adventure", "com.plotsquared.core.configuration.adventure")
|
||||
relocate("net.kyori.examination", "com.plotsquared.core.configuration.examination")
|
||||
relocate("io.papermc.lib", "com.plotsquared.bukkit.paperlib")
|
||||
relocate("org.bstats", "com.plotsquared.metrics")
|
||||
relocate("org.enginehub", "com.plotsquared.squirrelid")
|
||||
relocate("org.khelekore.prtree", "com.plotsquared.prtree")
|
||||
relocate("com.google.inject", "com.plotsquared.google")
|
||||
relocate("org.aopalliance", "com.plotsquared.core.aopalliance")
|
||||
relocate("cloud.commandframework.services", "com.plotsquared.core.services")
|
||||
relocate("io.leangen.geantyref", "com.plotsquared.core.geantyref")
|
||||
relocate("com.intellectualsites.arkitektonika", "com.plotsquared.core.arkitektonika")
|
||||
relocate("com.intellectualsites.http", "com.plotsquared.core.http")
|
||||
relocate("com.intellectualsites.paster", "com.plotsquared.core.paster")
|
||||
relocate("org.incendo.serverlib", "com.plotsquared.bukkit.serverlib")
|
||||
relocate("org.jetbrains", "com.plotsquared.core.annotations")
|
||||
relocate("org.intellij.lang", "com.plotsquared.core.intellij.annotations")
|
||||
relocate("javax.annotation", "com.plotsquared.core.annotation")
|
||||
relocate("com.github.spotbugs", "com.plotsquared.core.spotbugs")
|
||||
relocate("javax.inject", "com.plotsquared.core.annotation.inject")
|
||||
relocate("net.jcip", "com.plotsquared.core.annotations.jcip")
|
||||
relocate("edu.umd.cs.findbugs", "com.plotsquared.core.annotations.findbugs")
|
||||
relocate("com.intellectualsites.informative-annotations", "com.plotsquared.core.annotation.informative")
|
||||
|
||||
// Get rid of all the libs which are 100% unused.
|
||||
minimize()
|
||||
|
||||
mergeServiceFiles()
|
||||
}
|
||||
|
||||
tasks {
|
||||
withType<Javadoc> {
|
||||
val isRelease = if (rootProject.version.toString().endsWith("-SNAPSHOT")) "TODO" else rootProject.version.toString()
|
||||
val opt = options as StandardJavadocDocletOptions
|
||||
opt.links("https://jd.papermc.io/paper/1.18/")
|
||||
opt.links("https://docs.enginehub.org/javadoc/com.sk89q.worldedit/worldedit-bukkit/" + libs.worldeditBukkit.get().versionConstraint.toString())
|
||||
opt.links("https://intellectualsites.github.io/plotsquared-javadocs/core/")
|
||||
opt.links("https://jd.adventure.kyori.net/api/4.9.3/")
|
||||
opt.links("https://google.github.io/guice/api-docs/" + libs.guice.get().versionConstraint.toString() + "/javadoc/")
|
||||
opt.links("https://checkerframework.org/api/")
|
||||
opt.isLinkSource = true
|
||||
opt.bottom(File("$rootDir/javadocfooter.html").readText())
|
||||
opt.isUse = true
|
||||
opt.encoding("UTF-8")
|
||||
opt.keyWords()
|
||||
opt.addStringOption("-since", isRelease)
|
||||
}
|
||||
}
|
@ -1,848 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.bukkit.generator.BukkitPlotGenerator;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.listeners.ChunkListener;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.listeners.EntitySpawnListener;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.listeners.PlayerEvents;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.listeners.PlotPlusListener;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.listeners.SingleWorldListener;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.listeners.WorldEvents;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitChatManager;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitChunkManager;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitCommand;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitEconHandler;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitEventUtil;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitHybridUtils;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitInventoryUtil;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitSchematicHandler;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitSetupUtils;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitTaskManager;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitUtil;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.util.Metrics;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.util.SetGenCB;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.util.block.BukkitLocalQueue;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.uuid.DefaultUUIDWrapper;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.uuid.FileUUIDHandler;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.uuid.LowerOfflineUUIDWrapper;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.uuid.OfflineUUIDWrapper;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.uuid.SQLUUIDHandler;
|
||||
import com.github.intellectualsites.plotsquared.configuration.ConfigurationSection;
|
||||
import com.github.intellectualsites.plotsquared.plot.IPlotMain;
|
||||
import com.github.intellectualsites.plotsquared.plot.PlotSquared;
|
||||
import com.github.intellectualsites.plotsquared.plot.config.Captions;
|
||||
import com.github.intellectualsites.plotsquared.plot.config.ConfigurationNode;
|
||||
import com.github.intellectualsites.plotsquared.plot.config.Settings;
|
||||
import com.github.intellectualsites.plotsquared.plot.generator.GeneratorWrapper;
|
||||
import com.github.intellectualsites.plotsquared.plot.generator.HybridGen;
|
||||
import com.github.intellectualsites.plotsquared.plot.generator.HybridUtils;
|
||||
import com.github.intellectualsites.plotsquared.plot.generator.IndependentPlotGenerator;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotArea;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotId;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.SetupObject;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.chat.PlainChatManager;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.worlds.PlotAreaManager;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.worlds.SinglePlotArea;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.worlds.SinglePlotAreaManager;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.worlds.SingleWorldGenerator;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.ChatManager;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.ChunkManager;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.ConsoleColors;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.EconHandler;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.EventUtil;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.InventoryUtil;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.MainUtil;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.SchematicHandler;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.SetupUtils;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.StringMan;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.TaskManager;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.UUIDHandler;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.UUIDHandlerImplementation;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.UpdateUtility;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.WorldUtil;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.block.QueueProvider;
|
||||
import com.github.intellectualsites.plotsquared.plot.uuid.UUIDWrapper;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
import org.bukkit.metadata.MetadataValue;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.AbstractMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.getRefClass;
|
||||
|
||||
public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain {
|
||||
|
||||
@Getter private static WorldEdit worldEdit;
|
||||
|
||||
static {
|
||||
try {
|
||||
Settings.load(new File("plugins/PlotSquared/config/settings.yml"));
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
private int[] version;
|
||||
@Getter private String pluginName;
|
||||
@Getter private SingleWorldListener singleWorldListener;
|
||||
private Method methodUnloadChunk0;
|
||||
private boolean methodUnloadSetup = false;
|
||||
private boolean metricsStarted;
|
||||
private static final int BSTATS_ID = 1404;
|
||||
|
||||
@Override public int[] getServerVersion() {
|
||||
if (this.version == null) {
|
||||
try {
|
||||
this.version = new int[3];
|
||||
String[] split = Bukkit.getBukkitVersion().split("-")[0].split("\\.");
|
||||
this.version[0] = Integer.parseInt(split[0]);
|
||||
this.version[1] = Integer.parseInt(split[1]);
|
||||
if (split.length == 3) {
|
||||
this.version[2] = Integer.parseInt(split[2]);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
e.printStackTrace();
|
||||
PlotSquared.debug(StringMan.getString(Bukkit.getBukkitVersion()));
|
||||
PlotSquared.debug(
|
||||
StringMan.getString(Bukkit.getBukkitVersion().split("-")[0].split("\\.")));
|
||||
return new int[] {1, 13, 0};
|
||||
}
|
||||
}
|
||||
return this.version;
|
||||
}
|
||||
|
||||
@Override public String getServerImplementation() {
|
||||
return Bukkit.getVersion();
|
||||
}
|
||||
|
||||
@Override public void onEnable() {
|
||||
this.pluginName = getDescription().getName();
|
||||
PlotPlayer.registerConverter(Player.class, BukkitUtil::getPlayer);
|
||||
PaperLib.suggestPaper(this);
|
||||
|
||||
new PlotSquared(this, "Bukkit");
|
||||
|
||||
if (PlotSquared.get().IMP.getServerVersion()[1] < 13) {
|
||||
System.out.println(
|
||||
"You can't use this version of PlotSquared on a server less than Minecraft 1.13.2.");
|
||||
System.out
|
||||
.println("Please check the download page for the link to the legacy versions.");
|
||||
System.out.println("The server will now be shutdown to prevent any corruption.");
|
||||
Bukkit.shutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for updates
|
||||
if (PlotSquared.get().getUpdateUtility() != null) {
|
||||
final UpdateUtility updateUtility = PlotSquared.get().getUpdateUtility();
|
||||
updateUtility.checkForUpdate(PlotSquared.get().getVersion().versionString(),
|
||||
((updateDescription, throwable) -> {
|
||||
Bukkit.getScheduler().runTask(BukkitMain.this, () -> {
|
||||
getLogger().info("-------- PlotSquared Update Check --------");
|
||||
if (throwable != null) {
|
||||
getLogger().severe(String
|
||||
.format("Could not check for updates. Reason: %s",
|
||||
throwable.getMessage()));
|
||||
} else {
|
||||
if (updateDescription == null) {
|
||||
getLogger().info(
|
||||
"You appear to be running the latest version of PlotSquared. Congratulations!");
|
||||
} else {
|
||||
getLogger()
|
||||
.info("There appears to be a PlotSquared update available!");
|
||||
getLogger().info(String.format(
|
||||
"You are running version %s, the newest available version is %s",
|
||||
getPluginVersionString(), updateDescription.getVersion()));
|
||||
getLogger().info(
|
||||
String.format("Update URL: %s", updateDescription.getUrl()));
|
||||
}
|
||||
}
|
||||
getLogger().info("-------- PlotSquared Update Check --------");
|
||||
});
|
||||
}));
|
||||
} else {
|
||||
getLogger().warning("Update checking disabled. Skipping.");
|
||||
}
|
||||
|
||||
this.startMetrics();
|
||||
if (Settings.Enabled_Components.WORLDS) {
|
||||
TaskManager.IMP.taskRepeat(this::unload, 20);
|
||||
try {
|
||||
singleWorldListener = new SingleWorldListener(this);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void unload() {
|
||||
if (!this.methodUnloadSetup) {
|
||||
this.methodUnloadSetup = true;
|
||||
try {
|
||||
ReflectionUtils.RefClass classCraftWorld = getRefClass("{cb}.CraftWorld");
|
||||
this.methodUnloadChunk0 = classCraftWorld.getRealClass()
|
||||
.getDeclaredMethod("unloadChunk0", int.class, int.class, boolean.class);
|
||||
this.methodUnloadChunk0.setAccessible(true);
|
||||
} catch (Throwable event) {
|
||||
event.printStackTrace();
|
||||
}
|
||||
}
|
||||
final PlotAreaManager manager = PlotSquared.get().getPlotAreaManager();
|
||||
if (manager instanceof SinglePlotAreaManager) {
|
||||
long start = System.currentTimeMillis();
|
||||
final SinglePlotArea area = ((SinglePlotAreaManager) manager).getArea();
|
||||
|
||||
outer:
|
||||
for (final World world : Bukkit.getWorlds()) {
|
||||
final String name = world.getName();
|
||||
final char char0 = name.charAt(0);
|
||||
if (!Character.isDigit(char0) && char0 != '-') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!world.getPlayers().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PlotId id;
|
||||
try {
|
||||
id = PlotId.fromString(name);
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
continue;
|
||||
}
|
||||
final Plot plot = area.getOwnedPlot(id);
|
||||
if (plot != null) {
|
||||
if (!MainUtil.isServerOwned(plot) || PlotPlayer.wrap(plot.getOwner()) == null) {
|
||||
if (world.getKeepSpawnInMemory()) {
|
||||
world.setKeepSpawnInMemory(false);
|
||||
return;
|
||||
}
|
||||
final Chunk[] chunks = world.getLoadedChunks();
|
||||
if (chunks.length == 0) {
|
||||
if (!Bukkit.unloadWorld(world, true)) {
|
||||
PlotSquared.debug("Failed to unload " + world.getName());
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
int index = 0;
|
||||
do {
|
||||
final Chunk chunkI = chunks[index++];
|
||||
boolean result;
|
||||
if (methodUnloadChunk0 != null) {
|
||||
try {
|
||||
result = (boolean) methodUnloadChunk0
|
||||
.invoke(world, chunkI.getX(), chunkI.getZ(), true);
|
||||
} catch (Throwable e) {
|
||||
methodUnloadChunk0 = null;
|
||||
e.printStackTrace();
|
||||
continue outer;
|
||||
}
|
||||
} else {
|
||||
result = world.unloadChunk(chunkI.getX(), chunkI.getZ(), true);
|
||||
}
|
||||
if (!result) {
|
||||
continue outer;
|
||||
}
|
||||
if (System.currentTimeMillis() - start > 5) {
|
||||
return;
|
||||
}
|
||||
} while (index < chunks.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void onDisable() {
|
||||
PlotSquared.get().disable();
|
||||
Bukkit.getScheduler().cancelTasks(this);
|
||||
}
|
||||
|
||||
@Override public void log(@NonNull String message) {
|
||||
try {
|
||||
message = Captions.color(message);
|
||||
if (!Settings.Chat.CONSOLE_COLOR) {
|
||||
message = ChatColor.stripColor(message);
|
||||
}
|
||||
this.getServer().getConsoleSender().sendMessage(message);
|
||||
} catch (final Throwable ignored) {
|
||||
System.out.println(ConsoleColors.fromString(message));
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void shutdown() {
|
||||
this.getServer().getPluginManager().disablePlugin(this);
|
||||
}
|
||||
|
||||
@Override public int[] getPluginVersion() {
|
||||
String ver = getDescription().getVersion();
|
||||
if (ver.contains("-")) {
|
||||
ver = ver.split("-")[0];
|
||||
}
|
||||
String[] split = ver.split("\\.");
|
||||
return new int[] {Integer.parseInt(split[0]), Integer.parseInt(split[1]),
|
||||
Integer.parseInt(split[2])};
|
||||
}
|
||||
|
||||
@Override public String getPluginVersionString() {
|
||||
return getDescription().getVersion();
|
||||
}
|
||||
|
||||
@Override public void registerCommands() {
|
||||
final BukkitCommand bukkitCommand = new BukkitCommand();
|
||||
final PluginCommand plotCommand = getCommand("plots");
|
||||
if (plotCommand != null) {
|
||||
plotCommand.setExecutor(bukkitCommand);
|
||||
plotCommand.setAliases(Arrays.asList("p", "ps", "plotme", "plot"));
|
||||
plotCommand.setTabCompleter(bukkitCommand);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public File getDirectory() {
|
||||
return getDataFolder();
|
||||
}
|
||||
|
||||
@Override public File getWorldContainer() {
|
||||
return Bukkit.getWorldContainer();
|
||||
}
|
||||
|
||||
@Override public TaskManager getTaskManager() {
|
||||
return new BukkitTaskManager(this);
|
||||
}
|
||||
|
||||
@Override @SuppressWarnings("deprecation") public void runEntityTask() {
|
||||
PlotSquared.log(Captions.PREFIX + "KillAllEntities started.");
|
||||
TaskManager.runTaskRepeat(() -> PlotSquared.get().forEachPlotArea(plotArea -> {
|
||||
final World world = Bukkit.getWorld(plotArea.worldname);
|
||||
try {
|
||||
if (world == null) {
|
||||
return;
|
||||
}
|
||||
List<Entity> entities = world.getEntities();
|
||||
Iterator<Entity> iterator = entities.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Entity entity = iterator.next();
|
||||
switch (entity.getType()) {
|
||||
case EGG:
|
||||
case FISHING_HOOK:
|
||||
case ENDER_SIGNAL:
|
||||
case AREA_EFFECT_CLOUD:
|
||||
case EXPERIENCE_ORB:
|
||||
case LEASH_HITCH:
|
||||
case FIREWORK:
|
||||
case LIGHTNING:
|
||||
case WITHER_SKULL:
|
||||
case UNKNOWN:
|
||||
case PLAYER:
|
||||
// non moving / unmovable
|
||||
continue;
|
||||
case THROWN_EXP_BOTTLE:
|
||||
case SPLASH_POTION:
|
||||
case SNOWBALL:
|
||||
case SHULKER_BULLET:
|
||||
case SPECTRAL_ARROW:
|
||||
case ENDER_PEARL:
|
||||
case ARROW:
|
||||
case LLAMA_SPIT:
|
||||
case TRIDENT:
|
||||
// managed elsewhere | projectile
|
||||
continue;
|
||||
case ITEM_FRAME:
|
||||
case PAINTING:
|
||||
// Not vehicles
|
||||
continue;
|
||||
case ARMOR_STAND:
|
||||
// Temporarily classify as vehicle
|
||||
case MINECART:
|
||||
case MINECART_CHEST:
|
||||
case MINECART_COMMAND:
|
||||
case MINECART_FURNACE:
|
||||
case MINECART_HOPPER:
|
||||
case MINECART_MOB_SPAWNER:
|
||||
case ENDER_CRYSTAL:
|
||||
case MINECART_TNT:
|
||||
case BOAT:
|
||||
if (Settings.Enabled_Components.KILL_ROAD_VEHICLES) {
|
||||
com.github.intellectualsites.plotsquared.plot.object.Location
|
||||
location = BukkitUtil.getLocation(entity.getLocation());
|
||||
Plot plot = location.getPlot();
|
||||
if (plot == null) {
|
||||
if (location.isPlotArea()) {
|
||||
if (entity.hasMetadata("ps-tmp-teleport")) {
|
||||
continue;
|
||||
}
|
||||
iterator.remove();
|
||||
entity.remove();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
List<MetadataValue> meta = entity.getMetadata("plot");
|
||||
if (meta.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
Plot origin = (Plot) meta.get(0).value();
|
||||
if (!plot.equals(origin.getBasePlot(false))) {
|
||||
if (entity.hasMetadata("ps-tmp-teleport")) {
|
||||
continue;
|
||||
}
|
||||
iterator.remove();
|
||||
entity.remove();
|
||||
}
|
||||
}
|
||||
continue;
|
||||
case SMALL_FIREBALL:
|
||||
case FIREBALL:
|
||||
case DRAGON_FIREBALL:
|
||||
case DROPPED_ITEM:
|
||||
if (Settings.Enabled_Components.KILL_ROAD_ITEMS && plotArea
|
||||
.getOwnedPlotAbs(BukkitUtil.getLocation(entity.getLocation()))
|
||||
== null) {
|
||||
entity.remove();
|
||||
}
|
||||
// dropped item
|
||||
continue;
|
||||
case PRIMED_TNT:
|
||||
case FALLING_BLOCK:
|
||||
// managed elsewhere
|
||||
continue;
|
||||
case SHULKER:
|
||||
if (Settings.Enabled_Components.KILL_ROAD_MOBS) {
|
||||
LivingEntity livingEntity = (LivingEntity) entity;
|
||||
List<MetadataValue> meta = entity.getMetadata("shulkerPlot");
|
||||
if (!meta.isEmpty()) {
|
||||
if (livingEntity.isLeashed()) {
|
||||
continue;
|
||||
}
|
||||
List<MetadataValue> keep = entity.getMetadata("keep");
|
||||
if (!keep.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PlotId originalPlotId = (PlotId) meta.get(0).value();
|
||||
if (originalPlotId != null) {
|
||||
com.github.intellectualsites.plotsquared.plot.object.Location
|
||||
pLoc = BukkitUtil.getLocation(entity.getLocation());
|
||||
PlotArea area = pLoc.getPlotArea();
|
||||
if (area != null) {
|
||||
PlotId currentPlotId = PlotId.of(area.getPlotAbs(pLoc));
|
||||
if (!originalPlotId.equals(currentPlotId) && (
|
||||
currentPlotId == null || !area
|
||||
.getPlot(originalPlotId)
|
||||
.equals(area.getPlot(currentPlotId)))) {
|
||||
if (entity.hasMetadata("ps-tmp-teleport")) {
|
||||
continue;
|
||||
}
|
||||
iterator.remove();
|
||||
entity.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//This is to apply the metadata to already spawned shulkers (see EntitySpawnListener.java)
|
||||
com.github.intellectualsites.plotsquared.plot.object.Location
|
||||
pLoc = BukkitUtil.getLocation(entity.getLocation());
|
||||
PlotArea area = pLoc.getPlotArea();
|
||||
if (area != null) {
|
||||
PlotId currentPlotId = PlotId.of(area.getPlotAbs(pLoc));
|
||||
if (currentPlotId != null) {
|
||||
entity.setMetadata("shulkerPlot", new FixedMetadataValue(
|
||||
(Plugin) PlotSquared.get().IMP, currentPlotId));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
case LLAMA:
|
||||
case DONKEY:
|
||||
case MULE:
|
||||
case ZOMBIE_HORSE:
|
||||
case SKELETON_HORSE:
|
||||
case HUSK:
|
||||
case ELDER_GUARDIAN:
|
||||
case WITHER_SKELETON:
|
||||
case STRAY:
|
||||
case ZOMBIE_VILLAGER:
|
||||
case EVOKER:
|
||||
case EVOKER_FANGS:
|
||||
case VEX:
|
||||
case VINDICATOR:
|
||||
case POLAR_BEAR:
|
||||
case BAT:
|
||||
case BLAZE:
|
||||
case CAVE_SPIDER:
|
||||
case CHICKEN:
|
||||
case COW:
|
||||
case CREEPER:
|
||||
case ENDERMAN:
|
||||
case ENDERMITE:
|
||||
case ENDER_DRAGON:
|
||||
case GHAST:
|
||||
case GIANT:
|
||||
case GUARDIAN:
|
||||
case HORSE:
|
||||
case IRON_GOLEM:
|
||||
case MAGMA_CUBE:
|
||||
case MUSHROOM_COW:
|
||||
case OCELOT:
|
||||
case PIG:
|
||||
case PIG_ZOMBIE:
|
||||
case RABBIT:
|
||||
case SHEEP:
|
||||
case SILVERFISH:
|
||||
case SKELETON:
|
||||
case SLIME:
|
||||
case SNOWMAN:
|
||||
case SPIDER:
|
||||
case SQUID:
|
||||
case VILLAGER:
|
||||
case WITCH:
|
||||
case WITHER:
|
||||
case WOLF:
|
||||
case ZOMBIE:
|
||||
case PARROT:
|
||||
case SALMON:
|
||||
case DOLPHIN:
|
||||
case TROPICAL_FISH:
|
||||
case DROWNED:
|
||||
case COD:
|
||||
case TURTLE:
|
||||
case PUFFERFISH:
|
||||
case PHANTOM:
|
||||
case ILLUSIONER:
|
||||
case CAT:
|
||||
case PANDA:
|
||||
case FOX:
|
||||
case PILLAGER:
|
||||
case TRADER_LLAMA:
|
||||
case WANDERING_TRADER:
|
||||
case RAVAGER:
|
||||
//case BEE:
|
||||
default: {
|
||||
if (Settings.Enabled_Components.KILL_ROAD_MOBS) {
|
||||
Location location = entity.getLocation();
|
||||
if (BukkitUtil.getLocation(location).isPlotRoad()) {
|
||||
if (entity instanceof LivingEntity) {
|
||||
LivingEntity livingEntity = (LivingEntity) entity;
|
||||
if (!livingEntity.isLeashed() || !entity
|
||||
.hasMetadata("keep")) {
|
||||
Entity passenger = entity.getPassenger();
|
||||
if (!(passenger instanceof Player) && entity
|
||||
.getMetadata("keep").isEmpty()) {
|
||||
if (entity.hasMetadata("ps-tmp-teleport")) {
|
||||
continue;
|
||||
}
|
||||
iterator.remove();
|
||||
entity.remove();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Entity passenger = entity.getPassenger();
|
||||
if (!(passenger instanceof Player) && entity
|
||||
.getMetadata("keep").isEmpty()) {
|
||||
if (entity.hasMetadata("ps-tmp-teleport")) {
|
||||
continue;
|
||||
}
|
||||
iterator.remove();
|
||||
entity.remove();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}), 20);
|
||||
}
|
||||
|
||||
@Override @Nullable
|
||||
public final ChunkGenerator getDefaultWorldGenerator(@NotNull final String worldName,
|
||||
final String id) {
|
||||
final IndependentPlotGenerator result;
|
||||
if (id != null && id.equalsIgnoreCase("single")) {
|
||||
result = new SingleWorldGenerator();
|
||||
} else {
|
||||
result = PlotSquared.get().IMP.getDefaultGenerator();
|
||||
if (!PlotSquared.get().setupPlotWorld(worldName, id, result)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return (ChunkGenerator) result.specify(worldName);
|
||||
}
|
||||
|
||||
@Override public void registerPlayerEvents() {
|
||||
final PlayerEvents main = new PlayerEvents();
|
||||
getServer().getPluginManager().registerEvents(main, this);
|
||||
getServer().getPluginManager().registerEvents(new EntitySpawnListener(), this);
|
||||
}
|
||||
|
||||
@Override public void registerPlotPlusEvents() {
|
||||
PlotPlusListener.startRunnable(this);
|
||||
getServer().getPluginManager().registerEvents(new PlotPlusListener(), this);
|
||||
}
|
||||
|
||||
@Override public void registerForceFieldEvents() {
|
||||
}
|
||||
|
||||
@Override public boolean initWorldEdit() {
|
||||
if (getServer().getPluginManager().getPlugin("WorldEdit") != null) {
|
||||
worldEdit = WorldEdit.getInstance();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public EconHandler getEconomyHandler() {
|
||||
try {
|
||||
BukkitEconHandler econ = new BukkitEconHandler();
|
||||
if (econ.init()) {
|
||||
return econ;
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
PlotSquared.debug("No economy detected!");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override public QueueProvider initBlockQueue() {
|
||||
//TODO Figure out why this code is still here yet isn't being called anywhere.
|
||||
// try {
|
||||
// new SendChunk();
|
||||
// MainUtil.canSendChunk = true;
|
||||
// } catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) {
|
||||
// PlotSquared.debug(
|
||||
// SendChunk.class + " does not support " + StringMan.getString(getServerVersion()));
|
||||
// MainUtil.canSendChunk = false;
|
||||
// }
|
||||
return QueueProvider.of(BukkitLocalQueue.class, BukkitLocalQueue.class);
|
||||
}
|
||||
|
||||
@Override public WorldUtil initWorldUtil() {
|
||||
return new BukkitUtil();
|
||||
}
|
||||
|
||||
@Override @Nullable public GeneratorWrapper<?> getGenerator(@NonNull final String world,
|
||||
@Nullable final String name) {
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
final Plugin genPlugin = Bukkit.getPluginManager().getPlugin(name);
|
||||
if (genPlugin != null && genPlugin.isEnabled()) {
|
||||
ChunkGenerator gen = genPlugin.getDefaultWorldGenerator(world, "");
|
||||
if (gen instanceof GeneratorWrapper<?>) {
|
||||
return (GeneratorWrapper<?>) gen;
|
||||
}
|
||||
return new BukkitPlotGenerator(world, gen);
|
||||
} else {
|
||||
return new BukkitPlotGenerator(PlotSquared.get().IMP.getDefaultGenerator());
|
||||
}
|
||||
}
|
||||
|
||||
@Override public HybridUtils initHybridUtils() {
|
||||
return new BukkitHybridUtils();
|
||||
}
|
||||
|
||||
@Override public SetupUtils initSetupUtils() {
|
||||
return new BukkitSetupUtils();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
// Metrics are controlled via bstats config
|
||||
@Override public void startMetrics() {
|
||||
if (this.metricsStarted) {
|
||||
return;
|
||||
}
|
||||
this.metricsStarted = true;
|
||||
Metrics metrics = new Metrics(this, BSTATS_ID);// bstats
|
||||
PlotSquared.log(Captions.PREFIX + "&6Metrics enabled.");
|
||||
}
|
||||
|
||||
@Override public ChunkManager initChunkManager() {
|
||||
return new BukkitChunkManager();
|
||||
}
|
||||
|
||||
@Override public EventUtil initEventUtil() {
|
||||
return new BukkitEventUtil();
|
||||
}
|
||||
|
||||
@Override public void unregister(@NonNull final PlotPlayer player) {
|
||||
BukkitUtil.removePlayer(player.getName());
|
||||
}
|
||||
|
||||
@Override public void registerChunkProcessor() {
|
||||
getServer().getPluginManager().registerEvents(new ChunkListener(), this);
|
||||
}
|
||||
|
||||
@Override public void registerWorldEvents() {
|
||||
getServer().getPluginManager().registerEvents(new WorldEvents(), this);
|
||||
}
|
||||
|
||||
@NotNull @Override public IndependentPlotGenerator getDefaultGenerator() {
|
||||
return new HybridGen();
|
||||
}
|
||||
|
||||
@Override public InventoryUtil initInventoryUtil() {
|
||||
return new BukkitInventoryUtil();
|
||||
}
|
||||
|
||||
@Override public UUIDHandlerImplementation initUUIDHandler() {
|
||||
final UUIDWrapper wrapper;
|
||||
if (Settings.UUID.OFFLINE) {
|
||||
if (Settings.UUID.FORCE_LOWERCASE) {
|
||||
wrapper = new LowerOfflineUUIDWrapper();
|
||||
} else {
|
||||
wrapper = new OfflineUUIDWrapper();
|
||||
}
|
||||
Settings.UUID.OFFLINE = true;
|
||||
} else {
|
||||
wrapper = new DefaultUUIDWrapper();
|
||||
Settings.UUID.OFFLINE = false;
|
||||
}
|
||||
if (!Bukkit.getVersion().contains("git-Spigot")) {
|
||||
if (wrapper instanceof DefaultUUIDWrapper
|
||||
|| wrapper.getClass() == OfflineUUIDWrapper.class && !Bukkit.getOnlineMode()) {
|
||||
Settings.UUID.NATIVE_UUID_PROVIDER = true;
|
||||
}
|
||||
}
|
||||
if (Settings.UUID.OFFLINE) {
|
||||
PlotSquared.log(Captions.PREFIX + "&6" + getPluginName()
|
||||
+ " is using Offline Mode UUIDs either because of user preference, or because you are using an old version of "
|
||||
+ "Bukkit");
|
||||
} else {
|
||||
PlotSquared.log(Captions.PREFIX + "&6" + getPluginName() + " is using online UUIDs");
|
||||
}
|
||||
if (Settings.UUID.USE_SQLUUIDHANDLER) {
|
||||
return new SQLUUIDHandler(wrapper);
|
||||
} else {
|
||||
return new FileUUIDHandler(wrapper);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void setGenerator(@NonNull final String worldName) {
|
||||
World world = BukkitUtil.getWorld(worldName);
|
||||
if (world == null) {
|
||||
// create world
|
||||
ConfigurationSection worldConfig =
|
||||
PlotSquared.get().worlds.getConfigurationSection("worlds." + worldName);
|
||||
String manager = worldConfig.getString("generator.plugin", getPluginName());
|
||||
SetupObject setup = new SetupObject();
|
||||
setup.plotManager = manager;
|
||||
setup.setupGenerator = worldConfig.getString("generator.init", manager);
|
||||
setup.type = worldConfig.getInt("generator.type");
|
||||
setup.terrain = worldConfig.getInt("generator.terrain");
|
||||
setup.step = new ConfigurationNode[0];
|
||||
setup.world = worldName;
|
||||
SetupUtils.manager.setupWorld(setup);
|
||||
world = Bukkit.getWorld(worldName);
|
||||
} else {
|
||||
try {
|
||||
if (!PlotSquared.get().hasPlotArea(worldName)) {
|
||||
SetGenCB.setGenerator(BukkitUtil.getWorld(worldName));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
PlotSquared.log("Failed to reload world: " + world + " | " + e.getMessage());
|
||||
Bukkit.getServer().unloadWorld(world, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
assert world != null;
|
||||
ChunkGenerator gen = world.getGenerator();
|
||||
if (gen instanceof BukkitPlotGenerator) {
|
||||
PlotSquared.get().loadWorld(worldName, (BukkitPlotGenerator) gen);
|
||||
} else if (gen != null) {
|
||||
PlotSquared.get().loadWorld(worldName, new BukkitPlotGenerator(worldName, gen));
|
||||
} else if (PlotSquared.get().worlds.contains("worlds." + worldName)) {
|
||||
PlotSquared.get().loadWorld(worldName, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public SchematicHandler initSchematicHandler() {
|
||||
return new BukkitSchematicHandler();
|
||||
}
|
||||
|
||||
@Override @Nullable public PlotPlayer wrapPlayer(final Object player) {
|
||||
if (player instanceof Player) {
|
||||
return BukkitUtil.getPlayer((Player) player);
|
||||
}
|
||||
if (player instanceof OfflinePlayer) {
|
||||
return BukkitUtil.getPlayer((OfflinePlayer) player);
|
||||
}
|
||||
if (player instanceof String) {
|
||||
return UUIDHandler.getPlayer((String) player);
|
||||
}
|
||||
if (player instanceof UUID) {
|
||||
return UUIDHandler.getPlayer((UUID) player);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override public String getNMSPackage() {
|
||||
final String name = Bukkit.getServer().getClass().getPackage().getName();
|
||||
return name.substring(name.lastIndexOf('.') + 1);
|
||||
}
|
||||
|
||||
@Override public ChatManager<?> initChatManager() {
|
||||
if (Settings.Chat.INTERACTIVE) {
|
||||
return new BukkitChatManager();
|
||||
} else {
|
||||
return new PlainChatManager();
|
||||
}
|
||||
}
|
||||
|
||||
@Override public GeneratorWrapper<?> wrapPlotGenerator(@Nullable final String world,
|
||||
@NonNull final IndependentPlotGenerator generator) {
|
||||
return new BukkitPlotGenerator(generator);
|
||||
}
|
||||
|
||||
@Override public List<Map.Entry<Map.Entry<String, String>, Boolean>> getPluginIds() {
|
||||
List<Map.Entry<Map.Entry<String, String>, Boolean>> names = new ArrayList<>();
|
||||
for (final Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
|
||||
Map.Entry<String, String> id = new AbstractMap.SimpleEntry<>(plugin.getName(), plugin.getDescription().getVersion());
|
||||
names.add(new AbstractMap.SimpleEntry<>(id, plugin.isEnabled()));
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
@Override public Actor getConsole() {
|
||||
@NotNull ConsoleCommandSender console = Bukkit.getServer().getConsoleSender();
|
||||
WorldEditPlugin wePlugin = ((WorldEditPlugin) Bukkit.getPluginManager().getPlugin("WorldEdit"));
|
||||
return wePlugin.wrapCommandSender(console);
|
||||
}
|
||||
}
|
@ -1,107 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.chat;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Represents a wrapper around an array class of an arbitrary reference type,
|
||||
* which properly implements "value" hash code and equality functions.
|
||||
* <p>
|
||||
* This class is intended for use as a key to a map.
|
||||
* </p>
|
||||
*
|
||||
* @param <E> The type of elements in the array.
|
||||
* @author Glen Husman
|
||||
* @see Arrays
|
||||
*/
|
||||
public final class ArrayWrapper<E> {
|
||||
|
||||
private E[] _array;
|
||||
|
||||
/**
|
||||
* Creates an array wrapper with some elements.
|
||||
*
|
||||
* @param elements The elements of the array.
|
||||
*/
|
||||
public ArrayWrapper(E... elements) {
|
||||
setArray(elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an iterable element collection to an array of elements.
|
||||
* The iteration order of the specified object will be used as the array element order.
|
||||
*
|
||||
* @param list The iterable of objects which will be converted to an array.
|
||||
* @param c The type of the elements of the array.
|
||||
* @return An array of elements in the specified iterable.
|
||||
*/
|
||||
@SuppressWarnings("unchecked") public static <T> T[] toArray(Iterable<? extends T> list,
|
||||
Class<T> c) {
|
||||
int size = -1;
|
||||
if (list instanceof Collection<?>) {
|
||||
@SuppressWarnings("rawtypes") Collection coll = (Collection) list;
|
||||
size = coll.size();
|
||||
}
|
||||
|
||||
|
||||
if (size < 0) {
|
||||
size = 0;
|
||||
// Ugly hack: Count it ourselves
|
||||
for (@SuppressWarnings("unused") T element : list) {
|
||||
size++;
|
||||
}
|
||||
}
|
||||
|
||||
T[] result = (T[]) Array.newInstance(c, size);
|
||||
int i = 0;
|
||||
for (T element : list) { // Assumes iteration order is consistent
|
||||
result[i++] = element; // Assign array element at index THEN increment counter
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a reference to the wrapped array instance.
|
||||
*
|
||||
* @return The array wrapped by this instance.
|
||||
*/
|
||||
public E[] getArray() {
|
||||
return _array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this wrapper to wrap a new array instance.
|
||||
*
|
||||
* @param array The new wrapped array.
|
||||
*/
|
||||
public void setArray(E[] array) {
|
||||
Validate.notNull(array, "The array must not be null.");
|
||||
_array = array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if this object has a value equivalent to another object.
|
||||
*
|
||||
* @see Arrays#equals(Object[], Object[])
|
||||
*/
|
||||
@SuppressWarnings("rawtypes") @Override public boolean equals(Object other) {
|
||||
if (!(other instanceof ArrayWrapper)) {
|
||||
return false;
|
||||
}
|
||||
return Arrays.equals(_array, ((ArrayWrapper) other)._array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hash code represented by this objects value.
|
||||
*
|
||||
* @return This object's hash code.
|
||||
* @see Arrays#hashCode(Object[])
|
||||
*/
|
||||
@Override public int hashCode() {
|
||||
return Arrays.hashCode(_array);
|
||||
}
|
||||
|
||||
}
|
@ -1,905 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.chat;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Statistic;
|
||||
import org.bukkit.Statistic.Type;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerialization;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* Represents a formattable message. Such messages can use elements such as colors, formatting codes, hover and click data, and other features provided by the vanilla Minecraft <a href="http://minecraft.gamepedia.com/Tellraw#Raw_JSON_Text">JSON message formatter</a>.
|
||||
* This class allows plugins to emulate the functionality of the vanilla Minecraft <a href="http://minecraft.gamepedia.com/Commands#tellraw">tellraw command</a>.
|
||||
* <p>
|
||||
* This class follows the builder pattern, allowing for method chaining.
|
||||
* It is set up such that invocations of property-setting methods will affect the current editing component,
|
||||
* and a call to {@link #then()} or {@link #then(String)} will append a new editing component to the end of the message,
|
||||
* optionally initializing it with text. Further property-setting method calls will affect that editing component.
|
||||
* </p>
|
||||
*/
|
||||
public class FancyMessage
|
||||
implements JsonRepresentedObject, Cloneable, Iterable<MessagePart>, ConfigurationSerializable {
|
||||
|
||||
private static Constructor<?> nmsPacketPlayOutChatConstructor;
|
||||
// The ChatSerializer's instance of Gson
|
||||
private static Object nmsChatSerializerGsonInstance;
|
||||
private static Method fromJsonMethod;
|
||||
private static JsonParser _stringParser = new JsonParser();
|
||||
|
||||
static {
|
||||
ConfigurationSerialization.registerClass(FancyMessage.class);
|
||||
}
|
||||
|
||||
private List<MessagePart> messageParts;
|
||||
private String jsonString;
|
||||
private boolean dirty;
|
||||
|
||||
/**
|
||||
* Creates a JSON message with text.
|
||||
*
|
||||
* @param firstPartText The existing text in the message.
|
||||
*/
|
||||
public FancyMessage(final String firstPartText) {
|
||||
this(TextualComponent.rawText(firstPartText));
|
||||
}
|
||||
|
||||
private FancyMessage(final TextualComponent firstPartText) {
|
||||
messageParts = new ArrayList<>();
|
||||
messageParts.add(new MessagePart(firstPartText));
|
||||
jsonString = null;
|
||||
dirty = false;
|
||||
if (nmsPacketPlayOutChatConstructor == null) {
|
||||
try {
|
||||
nmsPacketPlayOutChatConstructor = Reflection.getNMSClass("PacketPlayOutChat")
|
||||
.getDeclaredConstructor(Reflection.getNMSClass("IChatBaseComponent"));
|
||||
nmsPacketPlayOutChatConstructor.setAccessible(true);
|
||||
} catch (NoSuchMethodException e) {
|
||||
Bukkit.getLogger()
|
||||
.log(Level.SEVERE, "Could not find Minecraft method or constructor.", e);
|
||||
} catch (SecurityException e) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Could not access constructor.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a JSON message without text.
|
||||
*/
|
||||
public FancyMessage() {
|
||||
this((TextualComponent) null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes a JSON-represented message from a mapping of key-value pairs.
|
||||
* This is called by the Bukkit serialization API.
|
||||
* It is not intended for direct public API consumption.
|
||||
*
|
||||
* @param serialized The key-value mapping which represents a fancy message.
|
||||
*/
|
||||
@SuppressWarnings("unchecked") public static FancyMessage deserialize(
|
||||
Map<String, Object> serialized) {
|
||||
FancyMessage msg = new FancyMessage();
|
||||
msg.messageParts = (List<MessagePart>) serialized.get("messageParts");
|
||||
msg.jsonString = serialized.containsKey("JSON") ? serialized.get("JSON").toString() : null;
|
||||
msg.dirty = !serialized.containsKey("JSON");
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes a fancy message from its JSON representation. This JSON representation is of the format of
|
||||
* that returned by {@link #toJSONString()}, and is compatible with vanilla inputs.
|
||||
*
|
||||
* @param json The JSON string which represents a fancy message.
|
||||
* @return A {@code FancyMessage} representing the parameterized JSON message.
|
||||
*/
|
||||
public static FancyMessage deserialize(String json) {
|
||||
JsonObject serialized = _stringParser.parse(json).getAsJsonObject();
|
||||
JsonArray extra = serialized.getAsJsonArray("extra"); // Get the extra component
|
||||
FancyMessage returnVal = new FancyMessage();
|
||||
returnVal.messageParts.clear();
|
||||
for (JsonElement mPrt : extra) {
|
||||
MessagePart component = new MessagePart();
|
||||
JsonObject messagePart = mPrt.getAsJsonObject();
|
||||
for (Map.Entry<String, JsonElement> entry : messagePart.entrySet()) {
|
||||
// Deserialize text
|
||||
if (TextualComponent.isTextKey(entry.getKey())) {
|
||||
// The map mimics the YAML serialization, which has a "key" field and one or more "value" fields
|
||||
Map<String, Object> serializedMapForm =
|
||||
new HashMap<>(); // Must be object due to Bukkit serializer API compliance
|
||||
serializedMapForm.put("key", entry.getKey());
|
||||
if (entry.getValue().isJsonPrimitive()) {
|
||||
// Assume string
|
||||
serializedMapForm.put("value", entry.getValue().getAsString());
|
||||
} else {
|
||||
// Composite object, but we assume each element is a string
|
||||
for (Map.Entry<String, JsonElement> compositeNestedElement : entry
|
||||
.getValue().getAsJsonObject().entrySet()) {
|
||||
serializedMapForm.put("value." + compositeNestedElement.getKey(),
|
||||
compositeNestedElement.getValue().getAsString());
|
||||
}
|
||||
}
|
||||
component.text = TextualComponent.deserialize(serializedMapForm);
|
||||
} else if (MessagePart.stylesToNames.inverse().containsKey(entry.getKey())) {
|
||||
if (entry.getValue().getAsBoolean()) {
|
||||
component.styles
|
||||
.add(MessagePart.stylesToNames.inverse().get(entry.getKey()));
|
||||
}
|
||||
} else if (entry.getKey().equals("color")) {
|
||||
component.color =
|
||||
ChatColor.valueOf(entry.getValue().getAsString().toUpperCase());
|
||||
} else if (entry.getKey().equals("clickEvent")) {
|
||||
JsonObject object = entry.getValue().getAsJsonObject();
|
||||
component.clickActionName = object.get("action").getAsString();
|
||||
component.clickActionData = object.get("value").getAsString();
|
||||
} else if (entry.getKey().equals("hoverEvent")) {
|
||||
JsonObject object = entry.getValue().getAsJsonObject();
|
||||
component.hoverActionName = object.get("action").getAsString();
|
||||
if (object.get("value").isJsonPrimitive()) {
|
||||
// Assume string
|
||||
component.hoverActionData =
|
||||
new JsonString(object.get("value").getAsString());
|
||||
} else {
|
||||
// Assume composite type
|
||||
// The only composite type we currently store is another FancyMessage
|
||||
// Therefore, recursion time!
|
||||
component.hoverActionData = deserialize(object.get("value")
|
||||
.toString() /* This should properly serialize the JSON object as a JSON string */);
|
||||
}
|
||||
} else if (entry.getKey().equals("insertion")) {
|
||||
component.insertionData = entry.getValue().getAsString();
|
||||
} else if (entry.getKey().equals("with")) {
|
||||
for (JsonElement object : entry.getValue().getAsJsonArray()) {
|
||||
if (object.isJsonPrimitive()) {
|
||||
component.translationReplacements
|
||||
.add(new JsonString(object.getAsString()));
|
||||
} else {
|
||||
// Only composite type stored in this array is - again - FancyMessages
|
||||
// Recurse within this function to parse this as a translation replacement
|
||||
component.translationReplacements.add(deserialize(object.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
returnVal.messageParts.add(component);
|
||||
}
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
@Override public FancyMessage clone() throws CloneNotSupportedException {
|
||||
FancyMessage instance = (FancyMessage) super.clone();
|
||||
instance.messageParts = new ArrayList<>(messageParts.size());
|
||||
for (int i = 0; i < messageParts.size(); i++) {
|
||||
instance.messageParts.add(i, messageParts.get(i).clone());
|
||||
}
|
||||
instance.dirty = false;
|
||||
instance.jsonString = null;
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text of the current editing component to a value.
|
||||
*
|
||||
* @param text The new text of the current editing component.
|
||||
* @return This builder instance.
|
||||
*/
|
||||
public FancyMessage text(String text) {
|
||||
MessagePart latest = latest();
|
||||
latest.text = TextualComponent.rawText(text);
|
||||
dirty = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text of the current editing component to a value.
|
||||
*
|
||||
* @param text The new text of the current editing component.
|
||||
* @return This builder instance.
|
||||
*/
|
||||
public FancyMessage text(TextualComponent text) {
|
||||
MessagePart latest = latest();
|
||||
latest.text = text;
|
||||
dirty = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the color of the current editing component to a value.
|
||||
*
|
||||
* @param color The new color of the current editing component.
|
||||
* @return This builder instance.
|
||||
* @throws IllegalArgumentException If the specified {@code ChatColor} enumeration value is not a color (but a format value).
|
||||
*/
|
||||
public FancyMessage color(final ChatColor color) {
|
||||
if (!color.isColor()) {
|
||||
throw new IllegalArgumentException(color.name() + " is not a color");
|
||||
}
|
||||
latest().color = color;
|
||||
dirty = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the stylization of the current editing component.
|
||||
*
|
||||
* @param styles The array of styles to apply to the editing component.
|
||||
* @return This builder instance.
|
||||
* @throws IllegalArgumentException If any of the enumeration values in the array do not represent formatters.
|
||||
*/
|
||||
public FancyMessage style(ChatColor... styles) {
|
||||
for (final ChatColor style : styles) {
|
||||
if (!style.isFormat()) {
|
||||
throw new IllegalArgumentException(style.name() + " is not a style");
|
||||
}
|
||||
}
|
||||
latest().styles.addAll(Arrays.asList(styles));
|
||||
dirty = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the behavior of the current editing component to instruct the client to open a file on the client side filesystem when the currently edited part of the {@code FancyMessage} is clicked.
|
||||
*
|
||||
* @param path The path of the file on the client filesystem.
|
||||
* @return This builder instance.
|
||||
*/
|
||||
public FancyMessage file(final String path) {
|
||||
onClick("open_file", path);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the behavior of the current editing component to instruct the client to open a webpage in the client's web browser when the currently edited part of the {@code FancyMessage} is clicked.
|
||||
*
|
||||
* @param url The URL of the page to open when the link is clicked.
|
||||
* @return This builder instance.
|
||||
*/
|
||||
public FancyMessage link(final String url) {
|
||||
onClick("open_url", url);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the behavior of the current editing component to instruct the client to replace the chat input box content with the specified string when the currently edited part of the {@code FancyMessage} is clicked.
|
||||
* The client will not immediately send the command to the server to be executed unless the client player submits the command/chat message, usually with the enter key.
|
||||
*
|
||||
* @param command The text to display in the chat bar of the client.
|
||||
* @return This builder instance.
|
||||
*/
|
||||
public FancyMessage suggest(final String command) {
|
||||
onClick("suggest_command", command);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the behavior of the current editing component to instruct the client to append the chat input box content with the specified string when the currently edited part of the {@code FancyMessage} is SHIFT-CLICKED.
|
||||
* The client will not immediately send the command to the server to be executed unless the client player submits the command/chat message, usually with the enter key.
|
||||
*
|
||||
* @param command The text to append to the chat bar of the client.
|
||||
* @return This builder instance.
|
||||
*/
|
||||
public FancyMessage insert(final String command) {
|
||||
latest().insertionData = command;
|
||||
dirty = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the behavior of the current editing component to instruct the client to send the specified string to the server as a chat message when the currently edited part of the {@code FancyMessage} is clicked.
|
||||
* The client <b>will</b> immediately send the command to the server to be executed when the editing component is clicked.
|
||||
*
|
||||
* @param command The text to display in the chat bar of the client.
|
||||
* @return This builder instance.
|
||||
*/
|
||||
public FancyMessage command(final String command) {
|
||||
onClick("run_command", command);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the behavior of the current editing component to display information about an achievement when the client hovers over the text.
|
||||
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
|
||||
*
|
||||
* @param name The name of the achievement to display, excluding the "achievement." prefix.
|
||||
* @return This builder instance.
|
||||
*/
|
||||
public FancyMessage achievementTooltip(final String name) {
|
||||
onHover("show_achievement", new JsonString("achievement." + name));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the behavior of the current editing component to display information about a parameterless statistic when the client hovers over the text.
|
||||
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
|
||||
*
|
||||
* @param which The statistic to display.
|
||||
* @return This builder instance.
|
||||
* @throws IllegalArgumentException If the statistic requires a parameter which was not supplied.
|
||||
*/
|
||||
public FancyMessage statisticTooltip(final Statistic which) {
|
||||
Type type = which.getType();
|
||||
if (type != Type.UNTYPED) {
|
||||
throw new IllegalArgumentException(
|
||||
"That statistic requires an additional " + type + " parameter!");
|
||||
}
|
||||
try {
|
||||
Object statistic = Reflection
|
||||
.getMethod(Reflection.getOBCClass("CraftStatistic"), "getNMSStatistic",
|
||||
Statistic.class).invoke(null, which);
|
||||
return achievementTooltip(
|
||||
(String) Reflection.getField(Reflection.getNMSClass("Statistic"), "name")
|
||||
.get(statistic));
|
||||
} catch (IllegalAccessException e) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
|
||||
return this;
|
||||
} catch (IllegalArgumentException e) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
|
||||
return this;
|
||||
} catch (InvocationTargetException e) {
|
||||
Bukkit.getLogger()
|
||||
.log(Level.WARNING, "A error has occurred during invoking of method.", e);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the behavior of the current editing component to display information about a statistic parameter with a material when the client hovers over the text.
|
||||
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
|
||||
*
|
||||
* @param which The statistic to display.
|
||||
* @param item The sole material parameter to the statistic.
|
||||
* @return This builder instance.
|
||||
* @throws IllegalArgumentException If the statistic requires a parameter which was not supplied, or was supplied a parameter that was not required.
|
||||
*/
|
||||
public FancyMessage statisticTooltip(final Statistic which, Material item) {
|
||||
Type type = which.getType();
|
||||
if (type == Type.UNTYPED) {
|
||||
throw new IllegalArgumentException("That statistic needs no additional parameter!");
|
||||
}
|
||||
if ((type == Type.BLOCK && item.isBlock()) || type == Type.ENTITY) {
|
||||
throw new IllegalArgumentException(
|
||||
"Wrong parameter type for that statistic - needs " + type + "!");
|
||||
}
|
||||
try {
|
||||
Object statistic = Reflection
|
||||
.getMethod(Reflection.getOBCClass("CraftStatistic"), "getMaterialStatistic",
|
||||
Statistic.class, Material.class).invoke(null, which, item);
|
||||
return achievementTooltip(
|
||||
(String) Reflection.getField(Reflection.getNMSClass("Statistic"), "name")
|
||||
.get(statistic));
|
||||
} catch (IllegalAccessException e) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
|
||||
return this;
|
||||
} catch (IllegalArgumentException e) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
|
||||
return this;
|
||||
} catch (InvocationTargetException e) {
|
||||
Bukkit.getLogger()
|
||||
.log(Level.WARNING, "A error has occurred during invoking of method.", e);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the behavior of the current editing component to display information about a statistic parameter with an entity type when the client hovers over the text.
|
||||
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
|
||||
*
|
||||
* @param which The statistic to display.
|
||||
* @param entity The sole entity type parameter to the statistic.
|
||||
* @return This builder instance.
|
||||
* @throws IllegalArgumentException If the statistic requires a parameter which was not supplied, or was supplied a parameter that was not required.
|
||||
*/
|
||||
public FancyMessage statisticTooltip(final Statistic which, EntityType entity) {
|
||||
Type type = which.getType();
|
||||
if (type == Type.UNTYPED) {
|
||||
throw new IllegalArgumentException("That statistic needs no additional parameter!");
|
||||
}
|
||||
if (type != Type.ENTITY) {
|
||||
throw new IllegalArgumentException(
|
||||
"Wrong parameter type for that statistic - needs " + type + "!");
|
||||
}
|
||||
try {
|
||||
Object statistic = Reflection
|
||||
.getMethod(Reflection.getOBCClass("CraftStatistic"), "getEntityStatistic",
|
||||
Statistic.class, EntityType.class).invoke(null, which, entity);
|
||||
return achievementTooltip(
|
||||
(String) Reflection.getField(Reflection.getNMSClass("Statistic"), "name")
|
||||
.get(statistic));
|
||||
} catch (IllegalAccessException e) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
|
||||
return this;
|
||||
} catch (IllegalArgumentException e) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
|
||||
return this;
|
||||
} catch (InvocationTargetException e) {
|
||||
Bukkit.getLogger()
|
||||
.log(Level.WARNING, "A error has occurred during invoking of method.", e);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the behavior of the current editing component to display information about an item when the client hovers over the text.
|
||||
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
|
||||
*
|
||||
* @param itemJSON A string representing the JSON-serialized NBT data tag of an {@link ItemStack}.
|
||||
* @return This builder instance.
|
||||
*/
|
||||
public FancyMessage itemTooltip(final String itemJSON) {
|
||||
onHover("show_item", new JsonString(
|
||||
itemJSON)); // Seems a bit hacky, considering we have a JSON object as a parameter
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the behavior of the current editing component to display information about an item when the client hovers over the text.
|
||||
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
|
||||
*
|
||||
* @param itemStack The stack for which to display information.
|
||||
* @return This builder instance.
|
||||
*/
|
||||
public FancyMessage itemTooltip(final ItemStack itemStack) {
|
||||
try {
|
||||
Object nmsItem = Reflection
|
||||
.getMethod(Reflection.getOBCClass("inventory.CraftItemStack"), "asNMSCopy",
|
||||
ItemStack.class).invoke(null, itemStack);
|
||||
return itemTooltip(Reflection.getMethod(Reflection.getNMSClass("ItemStack"), "save",
|
||||
Reflection.getNMSClass("NBTTagCompound"))
|
||||
.invoke(nmsItem, Reflection.getNMSClass("NBTTagCompound").newInstance())
|
||||
.toString());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the behavior of the current editing component to display raw text when the client hovers over the text.
|
||||
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
|
||||
*
|
||||
* @param text The text, which supports newlines, which will be displayed to the client upon hovering.
|
||||
* @return This builder instance.
|
||||
*/
|
||||
public FancyMessage tooltip(final String text) {
|
||||
onHover("show_text", new JsonString(text));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the behavior of the current editing component to display raw text when the client hovers over the text.
|
||||
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
|
||||
*
|
||||
* @param lines The lines of text which will be displayed to the client upon hovering. The iteration order of this object will be the order in which the lines of the tooltip are created.
|
||||
* @return This builder instance.
|
||||
*/
|
||||
public FancyMessage tooltip(final Iterable<String> lines) {
|
||||
tooltip(ArrayWrapper.toArray(lines, String.class));
|
||||
return this;
|
||||
}
|
||||
/*
|
||||
|
||||
/**
|
||||
* If the text is a translatable key, and it has replaceable values, this function can be used to set the replacements that will be used in the message.
|
||||
* @param replacements The replacements, in order, that will be used in the language-specific message.
|
||||
* @return This builder instance.
|
||||
*/ /* ------------
|
||||
public FancyMessage translationReplacements(final Iterable<? extends CharSequence> replacements){
|
||||
for(CharSequence str : replacements){
|
||||
latest().translationReplacements.add(new JsonString(str));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* Set the behavior of the current editing component to display raw text when the client hovers over the text.
|
||||
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
|
||||
*
|
||||
* @param lines The lines of text which will be displayed to the client upon hovering.
|
||||
* @return This builder instance.
|
||||
*/
|
||||
public FancyMessage tooltip(final String... lines) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
builder.append(lines[i]);
|
||||
if (i != lines.length - 1) {
|
||||
builder.append('\n');
|
||||
}
|
||||
}
|
||||
tooltip(builder.toString());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the behavior of the current editing component to display formatted text when the client hovers over the text.
|
||||
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
|
||||
*
|
||||
* @param text The formatted text which will be displayed to the client upon hovering.
|
||||
* @return This builder instance.
|
||||
*/
|
||||
public FancyMessage formattedTooltip(FancyMessage text) {
|
||||
for (MessagePart component : text.messageParts) {
|
||||
if (component.clickActionData != null && component.clickActionName != null) {
|
||||
throw new IllegalArgumentException("The tooltip text cannot have click data.");
|
||||
} else if (component.hoverActionData != null && component.hoverActionName != null) {
|
||||
throw new IllegalArgumentException("The tooltip text cannot have a tooltip.");
|
||||
}
|
||||
}
|
||||
onHover("show_text", text);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the behavior of the current editing component to display the specified lines of formatted text when the client hovers over the text.
|
||||
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
|
||||
*
|
||||
* @param lines The lines of formatted text which will be displayed to the client upon hovering.
|
||||
* @return This builder instance.
|
||||
*/
|
||||
public FancyMessage formattedTooltip(FancyMessage... lines) {
|
||||
if (lines.length < 1) {
|
||||
onHover(null, null); // Clear tooltip
|
||||
return this;
|
||||
}
|
||||
|
||||
FancyMessage result = new FancyMessage();
|
||||
result.messageParts
|
||||
.clear(); // Remove the one existing text component that exists by default, which destabilizes the object
|
||||
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
try {
|
||||
for (MessagePart component : lines[i]) {
|
||||
if (component.clickActionData != null && component.clickActionName != null) {
|
||||
throw new IllegalArgumentException(
|
||||
"The tooltip text cannot have click data.");
|
||||
} else if (component.hoverActionData != null
|
||||
&& component.hoverActionName != null) {
|
||||
throw new IllegalArgumentException(
|
||||
"The tooltip text cannot have a tooltip.");
|
||||
}
|
||||
if (component.hasText()) {
|
||||
result.messageParts.add(component.clone());
|
||||
}
|
||||
}
|
||||
if (i != lines.length - 1) {
|
||||
result.messageParts.add(new MessagePart(TextualComponent.rawText("\n")));
|
||||
}
|
||||
} catch (CloneNotSupportedException e) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Failed to clone object", e);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
return formattedTooltip(
|
||||
result.messageParts.isEmpty() ? null : result); // Throws NPE if size is 0, intended
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the behavior of the current editing component to display the specified lines of formatted text when the client hovers over the text.
|
||||
* <p>Tooltips do not inherit display characteristics, such as color and styles, from the message component on which they are applied.</p>
|
||||
*
|
||||
* @param lines The lines of text which will be displayed to the client upon hovering. The iteration order of this object will be the order in which the lines of the tooltip are created.
|
||||
* @return This builder instance.
|
||||
*/
|
||||
public FancyMessage formattedTooltip(final Iterable<FancyMessage> lines) {
|
||||
return formattedTooltip(ArrayWrapper.toArray(lines, FancyMessage.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* If the text is a translatable key, and it has replaceable values, this function can be used to set the replacements that will be used in the message.
|
||||
*
|
||||
* @param replacements The replacements, in order, that will be used in the language-specific message.
|
||||
* @return This builder instance.
|
||||
*/
|
||||
public FancyMessage translationReplacements(final String... replacements) {
|
||||
for (String str : replacements) {
|
||||
latest().translationReplacements.add(new JsonString(str));
|
||||
}
|
||||
dirty = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the text is a translatable key, and it has replaceable values, this function can be used to set the replacements that will be used in the message.
|
||||
*
|
||||
* @param replacements The replacements, in order, that will be used in the language-specific message.
|
||||
* @return This builder instance.
|
||||
*/
|
||||
public FancyMessage translationReplacements(final FancyMessage... replacements) {
|
||||
Collections.addAll(latest().translationReplacements, replacements);
|
||||
|
||||
dirty = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the text is a translatable key, and it has replaceable values, this function can be used to set the replacements that will be used in the message.
|
||||
*
|
||||
* @param replacements The replacements, in order, that will be used in the language-specific message.
|
||||
* @return This builder instance.
|
||||
*/
|
||||
public FancyMessage translationReplacements(final Iterable<FancyMessage> replacements) {
|
||||
return translationReplacements(ArrayWrapper.toArray(replacements, FancyMessage.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Terminate construction of the current editing component, and begin construction of a new message component.
|
||||
* After a successful call to this method, all setter methods will refer to a new message component, created as a result of the call to this method.
|
||||
*
|
||||
* @param text The text which will populate the new message component.
|
||||
* @return This builder instance.
|
||||
*/
|
||||
public FancyMessage then(final String text) {
|
||||
return then(TextualComponent.rawText(text));
|
||||
}
|
||||
|
||||
/**
|
||||
* Terminate construction of the current editing component, and begin construction of a new message component.
|
||||
* After a successful call to this method, all setter methods will refer to a new message component, created as a result of the call to this method.
|
||||
*
|
||||
* @param text The text which will populate the new message component.
|
||||
* @return This builder instance.
|
||||
*/
|
||||
public FancyMessage then(final TextualComponent text) {
|
||||
if (!latest().hasText()) {
|
||||
throw new IllegalStateException("previous message part has no text");
|
||||
}
|
||||
messageParts.add(new MessagePart(text));
|
||||
dirty = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Terminate construction of the current editing component, and begin construction of a new message component.
|
||||
* After a successful call to this method, all setter methods will refer to a new message component, created as a result of the call to this method.
|
||||
*
|
||||
* @return This builder instance.
|
||||
*/
|
||||
public FancyMessage then() {
|
||||
if (!latest().hasText()) {
|
||||
throw new IllegalStateException("previous message part has no text");
|
||||
}
|
||||
messageParts.add(new MessagePart());
|
||||
dirty = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override public void writeJson(JsonWriter writer) throws IOException {
|
||||
if (messageParts.size() == 1) {
|
||||
latest().writeJson(writer);
|
||||
} else {
|
||||
writer.beginObject().name("text").value("").name("extra").beginArray();
|
||||
for (final MessagePart part : this) {
|
||||
part.writeJson(writer);
|
||||
}
|
||||
writer.endArray().endObject();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize this fancy message, converting it into syntactically-valid JSON using a {@link JsonWriter}.
|
||||
* This JSON should be compatible with vanilla formatter commands such as {@code /tellraw}.
|
||||
*
|
||||
* @return The JSON string representing this object.
|
||||
*/
|
||||
public String toJSONString() {
|
||||
if (!dirty && jsonString != null) {
|
||||
return jsonString;
|
||||
}
|
||||
StringWriter string = new StringWriter();
|
||||
JsonWriter json = new JsonWriter(string);
|
||||
try {
|
||||
writeJson(json);
|
||||
json.close();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("invalid message");
|
||||
}
|
||||
jsonString = string.toString();
|
||||
dirty = false;
|
||||
return jsonString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends this message to a player. The player will receive the fully-fledged formatted display of this message.
|
||||
*
|
||||
* @param player The player who will receive the message.
|
||||
*/
|
||||
public void send(Player player) {
|
||||
send(player, toJSONString());
|
||||
}
|
||||
|
||||
private void send(CommandSender sender, String jsonString) {
|
||||
if (!(sender instanceof Player)) {
|
||||
sender.sendMessage(toOldMessageFormat());
|
||||
return;
|
||||
}
|
||||
Player player = (Player) sender;
|
||||
try {
|
||||
Object handle = Reflection.getHandle(player);
|
||||
Object connection =
|
||||
Reflection.getField(handle.getClass(), "playerConnection").get(handle);
|
||||
Reflection
|
||||
.getMethod(connection.getClass(), "sendPacket", Reflection.getNMSClass("Packet"))
|
||||
.invoke(connection, createChatPacket(jsonString));
|
||||
} catch (IllegalArgumentException e) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e);
|
||||
} catch (IllegalAccessException e) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Could not access method.", e);
|
||||
} catch (InstantiationException e) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Underlying class is abstract.", e);
|
||||
} catch (InvocationTargetException e) {
|
||||
Bukkit.getLogger()
|
||||
.log(Level.WARNING, "A error has occurred during invoking of method.", e);
|
||||
} catch (NoSuchMethodException e) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Could not find method.", e);
|
||||
} catch (ClassNotFoundException e) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Could not find class.", e);
|
||||
}
|
||||
}
|
||||
|
||||
private Object createChatPacket(String json)
|
||||
throws IllegalArgumentException, IllegalAccessException, InstantiationException,
|
||||
InvocationTargetException, NoSuchMethodException, ClassNotFoundException {
|
||||
if (nmsChatSerializerGsonInstance == null) {
|
||||
// Find the field and its value, completely bypassing obfuscation
|
||||
Class<?> chatSerializerClazz;
|
||||
|
||||
// Get the three parts of the version string (major version is currently unused)
|
||||
// vX_Y_RZ
|
||||
// X = major
|
||||
// Y = minor
|
||||
// Z = revision
|
||||
final String version = Reflection.getVersion();
|
||||
String[] split =
|
||||
version.substring(1, version.length() - 1).split("_"); // Remove trailing dot
|
||||
//int majorVersion = Integer.parseInt(split[0]);
|
||||
int minorVersion = Integer.parseInt(split[1]);
|
||||
int revisionVersion = Integer.parseInt(split[2].substring(1)); // Substring to ignore R
|
||||
|
||||
if (minorVersion < 8 || (minorVersion == 8 && revisionVersion == 1)) {
|
||||
chatSerializerClazz = Reflection.getNMSClass("ChatSerializer");
|
||||
} else {
|
||||
chatSerializerClazz = Reflection.getNMSClass("IChatBaseComponent$ChatSerializer");
|
||||
}
|
||||
|
||||
if (chatSerializerClazz == null) {
|
||||
throw new ClassNotFoundException("Can't find the ChatSerializer class");
|
||||
}
|
||||
|
||||
for (Field declaredField : chatSerializerClazz.getDeclaredFields()) {
|
||||
if (Modifier.isFinal(declaredField.getModifiers()) && Modifier
|
||||
.isStatic(declaredField.getModifiers()) && declaredField.getType().getName()
|
||||
.endsWith("Gson")) {
|
||||
// We've found our field
|
||||
declaredField.setAccessible(true);
|
||||
nmsChatSerializerGsonInstance = declaredField.get(null);
|
||||
fromJsonMethod = nmsChatSerializerGsonInstance.getClass()
|
||||
.getMethod("fromJson", String.class, Class.class);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Since the method is so simple, and all the obfuscated methods have the same name, it's easier to reimplement 'IChatBaseComponent a(String)' than to reflectively call it
|
||||
// Of course, the implementation may change, but fuzzy matches might break with signature changes
|
||||
Object serializedChatComponent = fromJsonMethod.invoke(nmsChatSerializerGsonInstance, json,
|
||||
Reflection.getNMSClass("IChatBaseComponent"));
|
||||
|
||||
return nmsPacketPlayOutChatConstructor.newInstance(serializedChatComponent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends this message to a command sender.
|
||||
* If the sender is a player, they will receive the fully-fledged formatted display of this message.
|
||||
* Otherwise, they will receive a version of this message with less formatting.
|
||||
*
|
||||
* @param sender The command sender who will receive the message.
|
||||
* @see #toOldMessageFormat()
|
||||
*/
|
||||
public void send(CommandSender sender) {
|
||||
send(sender, toJSONString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends this message to multiple command senders.
|
||||
*
|
||||
* @param senders The command senders who will receive the message.
|
||||
* @see #send(CommandSender)
|
||||
*/
|
||||
public void send(final Iterable<? extends CommandSender> senders) {
|
||||
String string = toJSONString();
|
||||
for (final CommandSender sender : senders) {
|
||||
send(sender, string);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert this message to a human-readable string with limited formatting.
|
||||
* This method is used to send this message to clients without JSON formatting support.
|
||||
* <p>
|
||||
* Serialization of this message by using this message will include (in this order for each message part):
|
||||
* <ol>
|
||||
* <li>The color of each message part.</li>
|
||||
* <li>The applicable stylizations for each message part.</li>
|
||||
* <li>The core text of the message part.</li>
|
||||
* </ol>
|
||||
* The primary omissions are tooltips and clickable actions. Consequently, this method should be used only as a last resort.
|
||||
* <p>
|
||||
* Color and formatting can be removed from the returned string by using {@link ChatColor#stripColor(String)}.</p>
|
||||
*
|
||||
* @return A human-readable string representing limited formatting in addition to the core text of this message.
|
||||
*/
|
||||
public String toOldMessageFormat() {
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (MessagePart part : this) {
|
||||
result.append(part.color == null ? "" : part.color);
|
||||
for (ChatColor formatSpecifier : part.styles) {
|
||||
result.append(formatSpecifier);
|
||||
}
|
||||
result.append(part.text);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private MessagePart latest() {
|
||||
return messageParts.get(messageParts.size() - 1);
|
||||
}
|
||||
|
||||
private void onClick(final String name, final String data) {
|
||||
final MessagePart latest = latest();
|
||||
latest.clickActionName = name;
|
||||
latest.clickActionData = data;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
private void onHover(final String name, final JsonRepresentedObject data) {
|
||||
final MessagePart latest = latest();
|
||||
latest.hoverActionName = name;
|
||||
latest.hoverActionData = data;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
// Doc copied from interface
|
||||
public Map<String, Object> serialize() {
|
||||
HashMap<String, Object> map = new HashMap<>();
|
||||
map.put("messageParts", messageParts);
|
||||
// map.put("JSON", toJSONString());
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Internally called method. Not for API consumption.</b>
|
||||
*/
|
||||
public Iterator<MessagePart> iterator() {
|
||||
return messageParts.iterator();
|
||||
}
|
||||
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.chat;
|
||||
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Represents an object that can be serialized to a JSON writer instance.
|
||||
*/
|
||||
interface JsonRepresentedObject {
|
||||
|
||||
/**
|
||||
* Writes the JSON representation of this object to the specified writer.
|
||||
*
|
||||
* @param writer The JSON writer which will receive the object.
|
||||
* @throws IOException If an error occurs writing to the stream.
|
||||
*/
|
||||
public void writeJson(JsonWriter writer) throws IOException;
|
||||
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.chat;
|
||||
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Represents a JSON string value.
|
||||
* Writes by this object will not write name values nor begin/end objects in the JSON stream.
|
||||
* All writes merely write the represented string value.
|
||||
*/
|
||||
final class JsonString implements JsonRepresentedObject, ConfigurationSerializable {
|
||||
|
||||
private String _value;
|
||||
|
||||
public JsonString(CharSequence value) {
|
||||
_value = value == null ? null : value.toString();
|
||||
}
|
||||
|
||||
public static JsonString deserialize(Map<String, Object> map) {
|
||||
return new JsonString(map.get("stringValue").toString());
|
||||
}
|
||||
|
||||
@Override public void writeJson(JsonWriter writer) throws IOException {
|
||||
writer.value(getValue());
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return _value;
|
||||
}
|
||||
|
||||
public Map<String, Object> serialize() {
|
||||
HashMap<String, Object> theSingleValue = new HashMap<String, Object>();
|
||||
theSingleValue.put("stringValue", _value);
|
||||
return theSingleValue;
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
return _value;
|
||||
}
|
||||
|
||||
}
|
@ -1,154 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.chat;
|
||||
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.ImmutableBiMap;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerialization;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* Internal class: Represents a component of a JSON-serializable {@link FancyMessage}.
|
||||
*/
|
||||
final class MessagePart implements JsonRepresentedObject, ConfigurationSerializable, Cloneable {
|
||||
|
||||
static final BiMap<ChatColor, String> stylesToNames;
|
||||
|
||||
static {
|
||||
ImmutableBiMap.Builder<ChatColor, String> builder = ImmutableBiMap.builder();
|
||||
for (final ChatColor style : ChatColor.values()) {
|
||||
if (!style.isFormat()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String styleName;
|
||||
switch (style) {
|
||||
case MAGIC:
|
||||
styleName = "obfuscated";
|
||||
break;
|
||||
case UNDERLINE:
|
||||
styleName = "underlined";
|
||||
break;
|
||||
default:
|
||||
styleName = style.name().toLowerCase();
|
||||
break;
|
||||
}
|
||||
|
||||
builder.put(style, styleName);
|
||||
}
|
||||
stylesToNames = builder.build();
|
||||
}
|
||||
|
||||
static {
|
||||
ConfigurationSerialization.registerClass(MessagePart.class);
|
||||
}
|
||||
|
||||
ChatColor color = ChatColor.WHITE;
|
||||
ArrayList<ChatColor> styles = new ArrayList<>();
|
||||
String clickActionName = null;
|
||||
String clickActionData = null;
|
||||
String hoverActionName = null;
|
||||
JsonRepresentedObject hoverActionData = null;
|
||||
TextualComponent text = null;
|
||||
String insertionData = null;
|
||||
ArrayList<JsonRepresentedObject> translationReplacements = new ArrayList<>();
|
||||
|
||||
MessagePart(final TextualComponent text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
MessagePart() {
|
||||
this.text = null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static MessagePart deserialize(Map<String, Object> serialized) {
|
||||
MessagePart part = new MessagePart((TextualComponent) serialized.get("text"));
|
||||
part.styles = (ArrayList<ChatColor>) serialized.get("styles");
|
||||
part.color = ChatColor.getByChar(serialized.get("color").toString());
|
||||
part.hoverActionName = (String) serialized.get("hoverActionName");
|
||||
part.hoverActionData = (JsonRepresentedObject) serialized.get("hoverActionData");
|
||||
part.clickActionName = (String) serialized.get("clickActionName");
|
||||
part.clickActionData = (String) serialized.get("clickActionData");
|
||||
part.insertionData = (String) serialized.get("insertion");
|
||||
part.translationReplacements =
|
||||
(ArrayList<JsonRepresentedObject>) serialized.get("translationReplacements");
|
||||
return part;
|
||||
}
|
||||
|
||||
boolean hasText() {
|
||||
return text != null;
|
||||
}
|
||||
|
||||
@Override @SuppressWarnings("unchecked") public MessagePart clone()
|
||||
throws CloneNotSupportedException {
|
||||
MessagePart obj = (MessagePart) super.clone();
|
||||
obj.styles = (ArrayList<ChatColor>) styles.clone();
|
||||
if (hoverActionData instanceof JsonString) {
|
||||
obj.hoverActionData = new JsonString(((JsonString) hoverActionData).getValue());
|
||||
} else if (hoverActionData instanceof FancyMessage) {
|
||||
obj.hoverActionData = ((FancyMessage) hoverActionData).clone();
|
||||
}
|
||||
obj.translationReplacements =
|
||||
(ArrayList<JsonRepresentedObject>) translationReplacements.clone();
|
||||
return obj;
|
||||
|
||||
}
|
||||
|
||||
public void writeJson(JsonWriter json) {
|
||||
try {
|
||||
json.beginObject();
|
||||
text.writeJson(json);
|
||||
json.name("color").value(color.name().toLowerCase());
|
||||
for (final ChatColor style : styles) {
|
||||
json.name(stylesToNames.get(style)).value(true);
|
||||
}
|
||||
if (clickActionName != null && clickActionData != null) {
|
||||
json.name("clickEvent").beginObject().name("action").value(clickActionName)
|
||||
.name("value").value(clickActionData).endObject();
|
||||
}
|
||||
if (hoverActionName != null && hoverActionData != null) {
|
||||
json.name("hoverEvent").beginObject().name("action").value(hoverActionName)
|
||||
.name("value");
|
||||
hoverActionData.writeJson(json);
|
||||
json.endObject();
|
||||
}
|
||||
if (insertionData != null) {
|
||||
json.name("insertion").value(insertionData);
|
||||
}
|
||||
if (translationReplacements.size() > 0 && TextualComponent.isTranslatableText(text)) {
|
||||
json.name("with").beginArray();
|
||||
for (JsonRepresentedObject obj : translationReplacements) {
|
||||
obj.writeJson(json);
|
||||
}
|
||||
json.endArray();
|
||||
}
|
||||
json.endObject();
|
||||
} catch (IOException e) {
|
||||
Bukkit.getLogger()
|
||||
.log(Level.WARNING, "A problem occurred during writing of JSON string", e);
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, Object> serialize() {
|
||||
HashMap<String, Object> map = new HashMap<>();
|
||||
map.put("text", text);
|
||||
map.put("styles", styles);
|
||||
map.put("color", color.getChar());
|
||||
map.put("hoverActionName", hoverActionName);
|
||||
map.put("hoverActionData", hoverActionData);
|
||||
map.put("clickActionName", clickActionName);
|
||||
map.put("clickActionData", clickActionData);
|
||||
map.put("insertion", insertionData);
|
||||
map.put("translationReplacements", translationReplacements);
|
||||
return map;
|
||||
}
|
||||
|
||||
}
|
@ -1,202 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.chat;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A class containing static utility methods and caches which are intended as reflective conveniences.
|
||||
* Unless otherwise noted, upon failure methods will return {@code null}.
|
||||
*/
|
||||
public final class Reflection {
|
||||
|
||||
/**
|
||||
* Stores loaded classes from the {@code net.minecraft.server} package.
|
||||
*/
|
||||
private static final Map<String, Class<?>> _loadedNMSClasses = new HashMap<>();
|
||||
/**
|
||||
* Stores loaded classes from the {@code org.bukkit.craftbukkit} package (and subpackages).
|
||||
*/
|
||||
private static final Map<String, Class<?>> _loadedOBCClasses = new HashMap<>();
|
||||
private static final Map<Class<?>, Map<String, Field>> _loadedFields = new HashMap<>();
|
||||
/**
|
||||
* Contains loaded methods in a cache.
|
||||
* The map maps [types to maps of [method names to maps of [parameter types to method instances]]].
|
||||
*/
|
||||
private static final Map<Class<?>, Map<String, Map<ArrayWrapper<Class<?>>, Method>>>
|
||||
_loadedMethods = new HashMap<>();
|
||||
private static String _versionString;
|
||||
|
||||
private Reflection() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the version string from the package name of the CraftBukkit server implementation.
|
||||
* This is needed to bypass the JAR package name changing on each update.
|
||||
*
|
||||
* @return The version string of the OBC and NMS packages, <em>including the trailing dot</em>.
|
||||
*/
|
||||
public synchronized static String getVersion() {
|
||||
if (_versionString == null) {
|
||||
String name = Bukkit.getServer().getClass().getPackage().getName();
|
||||
_versionString = name.substring(name.lastIndexOf('.') + 1) + ".";
|
||||
}
|
||||
|
||||
return _versionString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a {@link Class} object representing a type contained within the {@code net.minecraft.server} versioned package.
|
||||
* The class instances returned by this method are cached, such that no lookup will be done twice (unless multiple threads are accessing this method simultaneously).
|
||||
*
|
||||
* @param className The name of the class, excluding the package, within NMS.
|
||||
* @return The class instance representing the specified NMS class, or {@code null} if it could not be loaded.
|
||||
*/
|
||||
public synchronized static Class<?> getNMSClass(String className) {
|
||||
if (_loadedNMSClasses.containsKey(className)) {
|
||||
return _loadedNMSClasses.get(className);
|
||||
}
|
||||
|
||||
String fullName = "net.minecraft.server." + getVersion() + className;
|
||||
Class<?> clazz;
|
||||
try {
|
||||
clazz = Class.forName(fullName);
|
||||
} catch (ClassNotFoundException e) {
|
||||
_loadedNMSClasses.put(className, null);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
_loadedNMSClasses.put(className, clazz);
|
||||
return clazz;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a {@link Class} object representing a type contained within the {@code org.bukkit.craftbukkit} versioned package.
|
||||
* The class instances returned by this method are cached, such that no lookup will be done twice (unless multiple threads are accessing this method simultaneously).
|
||||
*
|
||||
* @param className The name of the class, excluding the package, within OBC. This name may contain a subpackage name, such as {@code inventory.CraftItemStack}.
|
||||
* @return The class instance representing the specified OBC class, or {@code null} if it could not be loaded.
|
||||
*/
|
||||
public synchronized static Class<?> getOBCClass(String className) {
|
||||
if (_loadedOBCClasses.containsKey(className)) {
|
||||
return _loadedOBCClasses.get(className);
|
||||
}
|
||||
|
||||
String fullName = "org.bukkit.craftbukkit." + getVersion() + className;
|
||||
Class<?> clazz;
|
||||
try {
|
||||
clazz = Class.forName(fullName);
|
||||
} catch (ClassNotFoundException e) {
|
||||
_loadedOBCClasses.put(className, null);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
_loadedOBCClasses.put(className, clazz);
|
||||
return clazz;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to get the NMS handle of a CraftBukkit object.
|
||||
* <p>
|
||||
* The only match currently attempted by this method is a retrieval by using a parameterless {@code getHandle()} method implemented by the runtime type of the specified object.
|
||||
* </p>
|
||||
*
|
||||
* @param obj The object for which to retrieve an NMS handle.
|
||||
* @return The NMS handle of the specified object, or {@code null} if it could not be retrieved using {@code getHandle()}.
|
||||
*/
|
||||
public synchronized static Object getHandle(Object obj)
|
||||
throws InvocationTargetException, IllegalAccessException, IllegalArgumentException {
|
||||
return getMethod(obj.getClass(), "getHandle").invoke(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a {@link Field} instance declared by the specified class with the specified name.
|
||||
* Java access modifiers are ignored during this retrieval. No guarantee is made as to whether the field
|
||||
* returned will be an instance or static field.
|
||||
* <p>
|
||||
* A global caching mechanism within this class is used to store fields. Combined with synchronization, this guarantees that
|
||||
* no field will be reflectively looked up twice.
|
||||
* </p>
|
||||
* <p>
|
||||
* If a field is deemed suitable for return, {@link Field#setAccessible(boolean) setAccessible} will be invoked with an argument of {@code true} before it is returned.
|
||||
* This ensures that callers do not have to check or worry about Java access modifiers when dealing with the returned instance.
|
||||
* </p>
|
||||
*
|
||||
* @param clazz The class which contains the field to retrieve.
|
||||
* @param name The declared name of the field in the class.
|
||||
* @return A field object with the specified name declared by the specified class.
|
||||
* @see Class#getDeclaredField(String)
|
||||
*/
|
||||
public synchronized static Field getField(Class<?> clazz, String name) {
|
||||
Map<String, Field> loaded;
|
||||
if (!_loadedFields.containsKey(clazz)) {
|
||||
loaded = new HashMap<>();
|
||||
_loadedFields.put(clazz, loaded);
|
||||
} else {
|
||||
loaded = _loadedFields.get(clazz);
|
||||
}
|
||||
if (loaded.containsKey(name)) {
|
||||
// If the field is loaded (or cached as not existing), return the relevant value, which might be null
|
||||
return loaded.get(name);
|
||||
}
|
||||
try {
|
||||
Field field = clazz.getDeclaredField(name);
|
||||
field.setAccessible(true);
|
||||
loaded.put(name, field);
|
||||
return field;
|
||||
} catch (NoSuchFieldException | SecurityException e) {
|
||||
// Error loading
|
||||
e.printStackTrace();
|
||||
// Cache field as not existing
|
||||
loaded.put(name, null);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a {@link Method} instance declared by the specified class with the specified name and argument types.
|
||||
* Java access modifiers are ignored during this retrieval. No guarantee is made as to whether the field
|
||||
* returned will be an instance or static field.
|
||||
* <p>
|
||||
* A global caching mechanism within this class is used to store method. Combined with synchronization, this guarantees that
|
||||
* no method will be reflectively looked up twice.
|
||||
* <p>
|
||||
* If a method is deemed suitable for return, {@link Method#setAccessible(boolean) setAccessible} will be invoked with an argument of {@code true} before it is returned.
|
||||
* This ensures that callers do not have to check or worry about Java access modifiers when dealing with the returned instance.
|
||||
* <p>
|
||||
* This method does <em>not</em> search superclasses of the specified type for methods with the specified signature.
|
||||
* Callers wishing this behavior should use {@link Class#getDeclaredMethod(String, Class...)}.
|
||||
*
|
||||
* @param clazz The class which contains the method to retrieve.
|
||||
* @param name The declared name of the method in the class.
|
||||
* @param args The formal argument types of the method.
|
||||
* @return A method object with the specified name declared by the specified class.
|
||||
*/
|
||||
public synchronized static Method getMethod(Class<?> clazz, String name, Class<?>... args) {
|
||||
_loadedMethods.computeIfAbsent(clazz, k -> new HashMap<>());
|
||||
|
||||
Map<String, Map<ArrayWrapper<Class<?>>, Method>> loadedMethodNames =
|
||||
_loadedMethods.get(clazz);
|
||||
loadedMethodNames.computeIfAbsent(name, k -> new HashMap<>());
|
||||
|
||||
Map<ArrayWrapper<Class<?>>, Method> loadedSignatures = loadedMethodNames.get(name);
|
||||
ArrayWrapper<Class<?>> wrappedArg = new ArrayWrapper<>(args);
|
||||
if (loadedSignatures.containsKey(wrappedArg)) {
|
||||
return loadedSignatures.get(wrappedArg);
|
||||
}
|
||||
|
||||
for (Method m : clazz.getMethods()) {
|
||||
if (m.getName().equals(name) && Arrays.equals(args, m.getParameterTypes())) {
|
||||
m.setAccessible(true);
|
||||
loadedSignatures.put(wrappedArg, m);
|
||||
return m;
|
||||
}
|
||||
}
|
||||
loadedSignatures.put(wrappedArg, null);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -1,313 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.chat;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerialization;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Represents a textual component of a message part.
|
||||
* This can be used to not only represent string literals in a JSON message,
|
||||
* but also to represent localized strings and other text values.
|
||||
* <p>Different instances of this class can be created with static constructor methods.</p>
|
||||
*/
|
||||
public abstract class TextualComponent implements Cloneable {
|
||||
|
||||
static {
|
||||
ConfigurationSerialization.registerClass(TextualComponent.ArbitraryTextTypeComponent.class);
|
||||
ConfigurationSerialization.registerClass(TextualComponent.ComplexTextTypeComponent.class);
|
||||
}
|
||||
|
||||
static TextualComponent deserialize(Map<String, Object> map) {
|
||||
if (map.containsKey("key") && map.size() == 2 && map.containsKey("value")) {
|
||||
// Arbitrary text component
|
||||
return ArbitraryTextTypeComponent.deserialize(map);
|
||||
} else if (map.size() >= 2 && map.containsKey("key") && !map
|
||||
.containsKey("value") /* It contains keys that START WITH value */) {
|
||||
// Complex JSON object
|
||||
return ComplexTextTypeComponent.deserialize(map);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static boolean isTextKey(String key) {
|
||||
return key.equals("translate") || key.equals("text") || key.equals("score") || key
|
||||
.equals("selector");
|
||||
}
|
||||
|
||||
static boolean isTranslatableText(TextualComponent component) {
|
||||
return component instanceof ComplexTextTypeComponent && component.getKey()
|
||||
.equals("translate");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a textual component representing a string literal.
|
||||
*
|
||||
* <p>This is the default type of textual component when a single string
|
||||
* literal is given to a method.
|
||||
*
|
||||
* @param textValue The text which will be represented.
|
||||
* @return The text component representing the specified literal text.
|
||||
*/
|
||||
public static TextualComponent rawText(String textValue) {
|
||||
return new ArbitraryTextTypeComponent("text", textValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a textual component representing a localized string.
|
||||
* The client will see this text component as their localized version of the specified string <em>key</em>, which can be overridden by a
|
||||
* resource pack.
|
||||
* <p>
|
||||
* If the specified translation key is not present on the client resource pack, the translation key will be displayed as a string literal to
|
||||
* the client.
|
||||
* </p>
|
||||
*
|
||||
* @param translateKey The string key which maps to localized text.
|
||||
* @return The text component representing the specified localized text.
|
||||
*/
|
||||
public static TextualComponent localizedText(String translateKey) {
|
||||
return new ArbitraryTextTypeComponent("translate", translateKey);
|
||||
}
|
||||
|
||||
private static void throwUnsupportedSnapshot() {
|
||||
throw new UnsupportedOperationException(
|
||||
"This feature is only supported in snapshot releases.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a textual component representing a scoreboard value.
|
||||
* The client will see their own score for the specified objective as the text represented by this component.
|
||||
* <p>
|
||||
* <b>This method is currently guaranteed to throw an {@code UnsupportedOperationException} as it is only supported on snapshot clients.</b>
|
||||
* </p>
|
||||
*
|
||||
* @param scoreboardObjective The name of the objective for which to display the score.
|
||||
* @return The text component representing the specified scoreboard score (for the viewing player), or {@code null} if an error occurs during
|
||||
* JSON serialization.
|
||||
*/
|
||||
public static TextualComponent objectiveScore(String scoreboardObjective) {
|
||||
return objectiveScore("*", scoreboardObjective);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a textual component representing a scoreboard value.
|
||||
* The client will see the score of the specified player for the specified objective as the text represented by this component.
|
||||
*
|
||||
* <p><b>This method is currently guaranteed to throw an {@code UnsupportedOperationException}
|
||||
* as it is only supported on snapshot clients.</b>
|
||||
*
|
||||
* @param playerName The name of the player whos score will be shown. If
|
||||
* this string represents the single-character sequence
|
||||
* "*", the viewing player's score will be displayed.
|
||||
* Standard minecraft selectors (@a, @p, etc)
|
||||
* are <em>not</em> supported.
|
||||
* @param scoreboardObjective The name of the objective for
|
||||
* which to display the score.
|
||||
* @return The text component representing the specified scoreboard score
|
||||
* for the specified player, or {@code null} if an error occurs during JSON serialization.
|
||||
*/
|
||||
public static TextualComponent objectiveScore(String playerName, String scoreboardObjective) {
|
||||
throwUnsupportedSnapshot(); // Remove this line when the feature is released to non-snapshot versions, in addition to updating ALL THE
|
||||
// OVERLOADS documentation accordingly
|
||||
|
||||
return new ComplexTextTypeComponent("score",
|
||||
ImmutableMap.<String, String>builder().put("name", playerName)
|
||||
.put("objective", scoreboardObjective).build());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a textual component representing a player name, retrievable by using a standard minecraft selector.
|
||||
* The client will see the players or entities captured by the specified selector as the text represented by this component.
|
||||
* <p>
|
||||
* <b>This method is currently guaranteed to throw an {@code UnsupportedOperationException} as it is only supported on snapshot clients.</b>
|
||||
* </p>
|
||||
*
|
||||
* @param selector The minecraft player or entity selector which will capture the entities whose string representations will be displayed in
|
||||
* the place of this text component.
|
||||
* @return The text component representing the name of the entities captured by the selector.
|
||||
*/
|
||||
public static TextualComponent selector(String selector) {
|
||||
throwUnsupportedSnapshot(); // Remove this line when the feature is released to non-snapshot versions, in addition to updating ALL THE
|
||||
// OVERLOADS documentation accordingly
|
||||
|
||||
return new ArbitraryTextTypeComponent("selector", selector);
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
return getReadableString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The JSON key used to represent text components of this type.
|
||||
*/
|
||||
public abstract String getKey();
|
||||
|
||||
/**
|
||||
* @return A readable String
|
||||
*/
|
||||
public abstract String getReadableString();
|
||||
|
||||
/**
|
||||
* Clones a textual component instance.
|
||||
* The returned object should not reference this textual component instance, but should maintain the same key and value.
|
||||
*/
|
||||
@Override public abstract TextualComponent clone() throws CloneNotSupportedException;
|
||||
|
||||
/**
|
||||
* Writes the text data represented by this textual component to the specified JSON writer object.
|
||||
* A new object within the writer is not started.
|
||||
*
|
||||
* @param writer The object to which to write the JSON data.
|
||||
* @throws IOException If an error occurs while writing to the stream.
|
||||
*/
|
||||
public abstract void writeJson(JsonWriter writer) throws IOException;
|
||||
|
||||
/**
|
||||
* Internal class used to represent all types of text components.
|
||||
* Exception validating done is on keys and values.
|
||||
*/
|
||||
private static final class ArbitraryTextTypeComponent extends TextualComponent
|
||||
implements ConfigurationSerializable {
|
||||
|
||||
private String key;
|
||||
private String value;
|
||||
|
||||
public ArbitraryTextTypeComponent(String key, String value) {
|
||||
setKey(key);
|
||||
setValue(value);
|
||||
}
|
||||
|
||||
public static ArbitraryTextTypeComponent deserialize(Map<String, Object> map) {
|
||||
return new ArbitraryTextTypeComponent(map.get("key").toString(),
|
||||
map.get("value").toString());
|
||||
}
|
||||
|
||||
@Override public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
Preconditions
|
||||
.checkArgument(key != null && !key.isEmpty(), "The key must be specified.");
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
Preconditions.checkArgument(value != null, "The value must be specified.");
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override public TextualComponent clone() throws CloneNotSupportedException {
|
||||
// Since this is a private and final class, we can just reinstantiate this class instead of casting super.clone
|
||||
return new ArbitraryTextTypeComponent(getKey(), getValue());
|
||||
}
|
||||
|
||||
@Override public void writeJson(JsonWriter writer) throws IOException {
|
||||
writer.name(getKey()).value(getValue());
|
||||
}
|
||||
|
||||
@Override @SuppressWarnings("serial") public Map<String, Object> serialize() {
|
||||
return new HashMap<String, Object>() {
|
||||
{
|
||||
put("key", getKey());
|
||||
put("value", getValue());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override public String getReadableString() {
|
||||
return getValue();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Internal class used to represent a text component with a nested JSON
|
||||
* value.
|
||||
*
|
||||
* <p>Exception validating done is on keys and values.
|
||||
*/
|
||||
private static final class ComplexTextTypeComponent extends TextualComponent
|
||||
implements ConfigurationSerializable {
|
||||
|
||||
private String key;
|
||||
private Map<String, String> value;
|
||||
|
||||
public ComplexTextTypeComponent(String key, Map<String, String> values) {
|
||||
setKey(key);
|
||||
setValue(values);
|
||||
}
|
||||
|
||||
public static ComplexTextTypeComponent deserialize(Map<String, Object> map) {
|
||||
String key = null;
|
||||
Map<String, String> value = new HashMap<>();
|
||||
for (Map.Entry<String, Object> valEntry : map.entrySet()) {
|
||||
if (valEntry.getKey().equals("key")) {
|
||||
key = (String) valEntry.getValue();
|
||||
} else if (valEntry.getKey().startsWith("value.")) {
|
||||
value.put(valEntry.getKey().substring(6) /* Strips out the value prefix */,
|
||||
valEntry.getValue().toString());
|
||||
}
|
||||
}
|
||||
return new ComplexTextTypeComponent(key, value);
|
||||
}
|
||||
|
||||
@Override public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
Preconditions
|
||||
.checkArgument(key != null && !key.isEmpty(), "The key must be specified.");
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public Map<String, String> getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(Map<String, String> value) {
|
||||
Preconditions.checkArgument(value != null, "The value must be specified.");
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override public TextualComponent clone() {
|
||||
// Since this is a private and final class, we can just reinstantiate this class instead of casting super.clone
|
||||
return new ComplexTextTypeComponent(getKey(), getValue());
|
||||
}
|
||||
|
||||
@Override public void writeJson(JsonWriter writer) throws IOException {
|
||||
writer.name(getKey());
|
||||
writer.beginObject();
|
||||
for (Map.Entry<String, String> jsonPair : value.entrySet()) {
|
||||
writer.name(jsonPair.getKey()).value(jsonPair.getValue());
|
||||
}
|
||||
writer.endObject();
|
||||
}
|
||||
|
||||
@Override @SuppressWarnings("serial") public Map<String, Object> serialize() {
|
||||
return new java.util.HashMap<String, Object>() {
|
||||
{
|
||||
put("key", getKey());
|
||||
for (Map.Entry<String, String> valEntry : getValue().entrySet()) {
|
||||
put("value." + valEntry.getKey(), valEntry.getValue());
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override public String getReadableString() {
|
||||
return getKey();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,295 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.commands;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.bukkit.uuid.DatFileFilter;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.uuid.DefaultUUIDWrapper;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.uuid.LowerOfflineUUIDWrapper;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.uuid.OfflineUUIDWrapper;
|
||||
import com.github.intellectualsites.plotsquared.commands.Argument;
|
||||
import com.github.intellectualsites.plotsquared.commands.CommandDeclaration;
|
||||
import com.github.intellectualsites.plotsquared.plot.PlotSquared;
|
||||
import com.github.intellectualsites.plotsquared.plot.commands.CommandCategory;
|
||||
import com.github.intellectualsites.plotsquared.plot.commands.RequiredType;
|
||||
import com.github.intellectualsites.plotsquared.plot.commands.SubCommand;
|
||||
import com.github.intellectualsites.plotsquared.plot.config.Captions;
|
||||
import com.github.intellectualsites.plotsquared.plot.database.DBFunc;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.OfflinePlotPlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.StringWrapper;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.MainUtil;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.StringMan;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.TaskManager;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.UUIDHandler;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.WorldUtil;
|
||||
import com.github.intellectualsites.plotsquared.plot.uuid.UUIDWrapper;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.UUID;
|
||||
|
||||
@CommandDeclaration(command = "uuidconvert", permission = "plots.admin",
|
||||
description = "Debug UUID conversion", usage = "/plot uuidconvert <lower|offline|online>",
|
||||
requiredType = RequiredType.CONSOLE, category = CommandCategory.DEBUG) public class DebugUUID
|
||||
extends SubCommand {
|
||||
|
||||
public DebugUUID() {
|
||||
super(Argument.String);
|
||||
}
|
||||
|
||||
@Override public boolean onCommand(final PlotPlayer player, String[] args) {
|
||||
final UUIDWrapper currentUUIDWrapper = UUIDHandler.getUUIDWrapper();
|
||||
final UUIDWrapper newWrapper;
|
||||
|
||||
switch (args[0].toLowerCase()) {
|
||||
case "lower":
|
||||
newWrapper = new LowerOfflineUUIDWrapper();
|
||||
break;
|
||||
case "offline":
|
||||
newWrapper = new OfflineUUIDWrapper();
|
||||
break;
|
||||
case "online":
|
||||
newWrapper = new DefaultUUIDWrapper();
|
||||
break;
|
||||
default:
|
||||
try {
|
||||
Class<?> clazz = Class.forName(args[0]);
|
||||
newWrapper = (UUIDWrapper) clazz.newInstance();
|
||||
} catch (ClassNotFoundException | IllegalAccessException | InstantiationException ignored) {
|
||||
MainUtil.sendMessage(player, Captions.COMMAND_SYNTAX,
|
||||
"/plot uuidconvert <lower|offline|online>");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (args.length != 2 || !"-o".equals(args[1])) {
|
||||
MainUtil.sendMessage(player, Captions.COMMAND_SYNTAX,
|
||||
"/plot uuidconvert " + args[0] + " -o");
|
||||
MainUtil.sendMessage(player, "&cBe aware of the following!");
|
||||
MainUtil.sendMessage(player,
|
||||
"&8 - &cUse the database command or another method to backup your plots beforehand");
|
||||
MainUtil.sendMessage(player,
|
||||
"&8 - &cIf the process is interrupted, all plots could be deleted");
|
||||
MainUtil.sendMessage(player, "&8 - &cIf an error occurs, all plots could be deleted");
|
||||
MainUtil.sendMessage(player, "&8 - &cPlot settings WILL be lost upon conversion");
|
||||
MainUtil
|
||||
.sendMessage(player, "&cTO REITERATE: BACK UP YOUR DATABASE BEFORE USING THIS!!!");
|
||||
MainUtil.sendMessage(player,
|
||||
"&7Retype the command with the override parameter when ready :)");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (currentUUIDWrapper.getClass().getCanonicalName()
|
||||
.equals(newWrapper.getClass().getCanonicalName())) {
|
||||
MainUtil.sendMessage(player, "&cUUID mode already in use!");
|
||||
return false;
|
||||
}
|
||||
MainUtil.sendMessage(player, "&6Beginning UUID mode conversion");
|
||||
MainUtil.sendMessage(player, "&7 - Disconnecting players");
|
||||
for (Entry<String, PlotPlayer> entry : UUIDHandler.getPlayers().entrySet()) {
|
||||
entry.getValue()
|
||||
.kick("UUID conversion has been initiated. You may reconnect when finished.");
|
||||
}
|
||||
|
||||
MainUtil.sendMessage(player, "&7 - Initializing map");
|
||||
|
||||
final HashMap<UUID, UUID> uCMap = new HashMap<>();
|
||||
final HashMap<UUID, UUID> uCReverse = new HashMap<>();
|
||||
|
||||
MainUtil.sendMessage(player, "&7 - Collecting playerdata");
|
||||
|
||||
HashSet<String> worlds = Sets.newHashSet(WorldUtil.IMP.getMainWorld(), "world");
|
||||
HashSet<UUID> uuids = new HashSet<>();
|
||||
HashSet<String> names = new HashSet<>();
|
||||
for (String worldName : worlds) {
|
||||
File playerDataFolder = new File(worldName + File.separator + "playerdata");
|
||||
String[] dat = playerDataFolder.list(new DatFileFilter());
|
||||
if (dat != null) {
|
||||
for (String current : dat) {
|
||||
String s = current.replaceAll(".dat$", "");
|
||||
try {
|
||||
UUID uuid = UUID.fromString(s);
|
||||
uuids.add(uuid);
|
||||
} catch (Exception ignored) {
|
||||
MainUtil.sendMessage(player,
|
||||
Captions.PREFIX + "Invalid playerdata: " + current);
|
||||
}
|
||||
}
|
||||
}
|
||||
File playersFolder = new File(worldName + File.separator + "players");
|
||||
dat = playersFolder.list(new DatFileFilter());
|
||||
if (dat != null) {
|
||||
for (String current : dat) {
|
||||
names.add(current.replaceAll(".dat$", ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MainUtil.sendMessage(player, "&7 - Populating map");
|
||||
UUID uuid2;
|
||||
UUIDWrapper wrapper = new DefaultUUIDWrapper();
|
||||
for (UUID uuid : uuids) {
|
||||
try {
|
||||
OfflinePlotPlayer op = wrapper.getOfflinePlayer(uuid);
|
||||
uuid = currentUUIDWrapper.getUUID(op);
|
||||
uuid2 = newWrapper.getUUID(op);
|
||||
if (!uuid.equals(uuid2) && !uCMap.containsKey(uuid) && !uCReverse
|
||||
.containsKey(uuid2)) {
|
||||
uCMap.put(uuid, uuid2);
|
||||
uCReverse.put(uuid2, uuid);
|
||||
}
|
||||
} catch (Throwable ignored) {
|
||||
MainUtil.sendMessage(player,
|
||||
Captions.PREFIX + "&6Invalid playerdata: " + uuid.toString() + ".dat");
|
||||
}
|
||||
}
|
||||
for (String name : names) {
|
||||
UUID uuid = currentUUIDWrapper.getUUID(name);
|
||||
uuid2 = newWrapper.getUUID(name);
|
||||
if (!uuid.equals(uuid2)) {
|
||||
uCMap.put(uuid, uuid2);
|
||||
uCReverse.put(uuid2, uuid);
|
||||
}
|
||||
}
|
||||
if (uCMap.isEmpty()) {
|
||||
MainUtil.sendMessage(player, "&c - Error! Attempting to repopulate");
|
||||
for (OfflinePlotPlayer op : currentUUIDWrapper.getOfflinePlayers()) {
|
||||
if (op.getLastPlayed() != 0) {
|
||||
// String name = op.getPluginName();
|
||||
// StringWrapper wrap = new StringWrapper(name);
|
||||
UUID uuid = currentUUIDWrapper.getUUID(op);
|
||||
uuid2 = newWrapper.getUUID(op);
|
||||
if (!uuid.equals(uuid2)) {
|
||||
uCMap.put(uuid, uuid2);
|
||||
uCReverse.put(uuid2, uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (uCMap.isEmpty()) {
|
||||
MainUtil.sendMessage(player, "&cError. Failed to collect UUIDs!");
|
||||
return false;
|
||||
} else {
|
||||
MainUtil.sendMessage(player, "&a - Successfully repopulated");
|
||||
}
|
||||
}
|
||||
|
||||
MainUtil.sendMessage(player, "&7 - Replacing cache");
|
||||
TaskManager.runTaskAsync(() -> {
|
||||
for (Entry<UUID, UUID> entry : uCMap.entrySet()) {
|
||||
String name = UUIDHandler.getName(entry.getKey());
|
||||
if (name != null) {
|
||||
UUIDHandler.add(new StringWrapper(name), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
MainUtil.sendMessage(player, "&7 - Scanning for applicable files (uuids.txt)");
|
||||
|
||||
File file = new File(PlotSquared.get().IMP.getDirectory(), "uuids.txt");
|
||||
if (file.exists()) {
|
||||
try {
|
||||
List<String> lines = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8);
|
||||
for (String line : lines) {
|
||||
try {
|
||||
line = line.trim();
|
||||
if (line.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
line = line.replaceAll("[\\|][0-9]+[\\|][0-9]+[\\|]", "");
|
||||
String[] split = line.split("\\|");
|
||||
String name = split[0];
|
||||
if (name.isEmpty() || name.length() > 16 || !StringMan
|
||||
.isAlphanumericUnd(name)) {
|
||||
continue;
|
||||
}
|
||||
UUID old = currentUUIDWrapper.getUUID(name);
|
||||
if (old == null) {
|
||||
continue;
|
||||
}
|
||||
UUID now = newWrapper.getUUID(name);
|
||||
UUIDHandler.add(new StringWrapper(name), now);
|
||||
uCMap.put(old, now);
|
||||
uCReverse.put(now, old);
|
||||
} catch (Exception e2) {
|
||||
e2.printStackTrace();
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
MainUtil.sendMessage(player, "&7 - Replacing wrapper");
|
||||
UUIDHandler.setUUIDWrapper(newWrapper);
|
||||
|
||||
MainUtil.sendMessage(player, "&7 - Updating plot objects");
|
||||
|
||||
for (Plot plot : PlotSquared.get().getPlots()) {
|
||||
UUID value = uCMap.get(plot.owner);
|
||||
if (value != null) {
|
||||
plot.owner = value;
|
||||
}
|
||||
plot.getTrusted().clear();
|
||||
plot.getMembers().clear();
|
||||
plot.getDenied().clear();
|
||||
}
|
||||
|
||||
MainUtil.sendMessage(player, "&7 - Deleting database");
|
||||
boolean result = DBFunc.deleteTables();
|
||||
|
||||
MainUtil.sendMessage(player, "&7 - Creating tables");
|
||||
|
||||
try {
|
||||
DBFunc.createTables();
|
||||
if (!result) {
|
||||
MainUtil.sendMessage(player, "&cConversion failed! Attempting recovery");
|
||||
for (Plot plot : PlotSquared.get().getPlots()) {
|
||||
UUID value = uCReverse.get(plot.owner);
|
||||
if (value != null) {
|
||||
plot.owner = value;
|
||||
}
|
||||
}
|
||||
DBFunc.createPlotsAndData(new ArrayList<>(PlotSquared.get().getPlots()),
|
||||
() -> MainUtil.sendMessage(player, "&6Recovery was successful!"));
|
||||
return;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
if (newWrapper instanceof OfflineUUIDWrapper) {
|
||||
PlotSquared.get().worlds.set("UUID.force-lowercase", false);
|
||||
PlotSquared.get().worlds.set("UUID.offline", true);
|
||||
} else if (newWrapper instanceof DefaultUUIDWrapper) {
|
||||
PlotSquared.get().worlds.set("UUID.force-lowercase", false);
|
||||
PlotSquared.get().worlds.set("UUID.offline", false);
|
||||
}
|
||||
try {
|
||||
PlotSquared.get().worlds.save(PlotSquared.get().worldsFile);
|
||||
} catch (IOException ignored) {
|
||||
MainUtil.sendMessage(player,
|
||||
"Could not save configuration. It will need to be manual set!");
|
||||
}
|
||||
|
||||
MainUtil.sendMessage(player, "&7 - Populating tables");
|
||||
|
||||
TaskManager.runTaskAsync(() -> {
|
||||
ArrayList<Plot> plots = new ArrayList<>(PlotSquared.get().getPlots());
|
||||
DBFunc.createPlotsAndData(plots,
|
||||
() -> MainUtil.sendMessage(player, "&aConversion complete!"));
|
||||
});
|
||||
|
||||
MainUtil.sendMessage(player, "&aIt is now safe for players to join");
|
||||
MainUtil.sendMessage(player,
|
||||
"&cConversion is still in progress, you will be notified when it is complete");
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.events;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.player.PlayerEvent;
|
||||
|
||||
public class PlayerClaimPlotEvent extends PlayerEvent implements Cancellable {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private final Plot plot;
|
||||
private final boolean auto;
|
||||
private boolean cancelled;
|
||||
|
||||
/**
|
||||
* PlayerClaimPlotEvent: Called when a plot is claimed.
|
||||
*
|
||||
* @param player Player that claimed the plot
|
||||
* @param plot Plot that was claimed
|
||||
*/
|
||||
public PlayerClaimPlotEvent(Player player, Plot plot, boolean auto) {
|
||||
super(player);
|
||||
this.plot = plot;
|
||||
this.auto = auto;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plot involved
|
||||
*
|
||||
* @return Plot
|
||||
*/
|
||||
public Plot getPlot() {
|
||||
return this.plot;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if it was an automated claim, else false
|
||||
*/
|
||||
public boolean wasAuto() {
|
||||
return this.auto;
|
||||
}
|
||||
|
||||
@Override public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@Override public boolean isCancelled() {
|
||||
return this.cancelled;
|
||||
}
|
||||
|
||||
@Override public void setCancelled(boolean b) {
|
||||
this.cancelled = b;
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.events;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.player.PlayerEvent;
|
||||
|
||||
public class PlayerEnterPlotEvent extends PlayerEvent {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private final Plot plot;
|
||||
|
||||
/**
|
||||
* Called when a player leaves a plot.
|
||||
*
|
||||
* @param player Player that entered the plot
|
||||
* @param plot Plot that was entered
|
||||
*/
|
||||
public PlayerEnterPlotEvent(Player player, Plot plot) {
|
||||
super(player);
|
||||
this.plot = plot;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plot involved.
|
||||
*
|
||||
* @return Plot
|
||||
*/
|
||||
public Plot getPlot() {
|
||||
return this.plot;
|
||||
}
|
||||
|
||||
@Override public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.events;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.player.PlayerEvent;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class PlayerLeavePlotEvent extends PlayerEvent {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private final Plot plot;
|
||||
|
||||
/**
|
||||
* PlayerLeavePlotEvent: Called when a player leaves a plot
|
||||
*
|
||||
* @param player Player that left the plot
|
||||
* @param plot Plot that was left
|
||||
*/
|
||||
public PlayerLeavePlotEvent(Player player, Plot plot) {
|
||||
super(player);
|
||||
this.plot = plot;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plot involved
|
||||
*
|
||||
* @return Plot
|
||||
*/
|
||||
public Plot getPlot() {
|
||||
return this.plot;
|
||||
}
|
||||
|
||||
@Override public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.events;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class PlayerPlotDeniedEvent extends PlotEvent {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private final Player initiator;
|
||||
private final boolean added;
|
||||
private final UUID player;
|
||||
|
||||
/**
|
||||
* PlayerPlotDeniedEvent: Called when the denied UUID list is modified for a plot.
|
||||
*
|
||||
* @param initiator Player that initiated the event
|
||||
* @param plot Plot in which the event occurred
|
||||
* @param player Player that was denied/un-denied
|
||||
* @param added true of add to deny list, false if removed
|
||||
*/
|
||||
public PlayerPlotDeniedEvent(Player initiator, Plot plot, UUID player, boolean added) {
|
||||
super(plot);
|
||||
this.initiator = initiator;
|
||||
this.added = added;
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* If a user was added.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean wasAdded() {
|
||||
return this.added;
|
||||
}
|
||||
|
||||
/**
|
||||
* The player added/removed.
|
||||
*
|
||||
* @return UUID
|
||||
*/
|
||||
public UUID getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
/**
|
||||
* The player initiating the action.
|
||||
*
|
||||
* @return Player
|
||||
*/
|
||||
public Player getInitiator() {
|
||||
return this.initiator;
|
||||
}
|
||||
|
||||
@Override public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.events;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class PlayerPlotHelperEvent extends PlotEvent {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private final Player initiator;
|
||||
private final boolean added;
|
||||
private final UUID player;
|
||||
|
||||
/**
|
||||
* PlayerPlotHelperEvent: Called when a plot helper is added/removed
|
||||
*
|
||||
* @param initiator Player that initiated the event
|
||||
* @param plot Plot in which the event occurred
|
||||
* @param player Player that was added/removed from the helper list
|
||||
* @param added true of the player was added, false if the player was removed
|
||||
*/
|
||||
public PlayerPlotHelperEvent(Player initiator, Plot plot, UUID player, boolean added) {
|
||||
super(plot);
|
||||
this.initiator = initiator;
|
||||
this.added = added;
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* If a player was added
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean wasAdded() {
|
||||
return this.added;
|
||||
}
|
||||
|
||||
/**
|
||||
* The UUID added/removed
|
||||
*
|
||||
* @return UUID
|
||||
*/
|
||||
public UUID getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
/**
|
||||
* The player initiating the action
|
||||
*
|
||||
* @return Player
|
||||
*/
|
||||
public Player getInitiator() {
|
||||
return this.initiator;
|
||||
}
|
||||
|
||||
@Override public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.events;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class PlayerPlotTrustedEvent extends PlotEvent {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private final Player initiator;
|
||||
private final boolean added;
|
||||
private final UUID player;
|
||||
|
||||
/**
|
||||
* PlayerPlotTrustedEvent: Called when a plot trusted user is added/removed
|
||||
*
|
||||
* @param initiator Player that initiated the event
|
||||
* @param plot Plot in which the event occurred
|
||||
* @param player Player that was added/removed from the trusted list
|
||||
* @param added true of the player was added, false if the player was removed
|
||||
*/
|
||||
public PlayerPlotTrustedEvent(Player initiator, Plot plot, UUID player, boolean added) {
|
||||
super(plot);
|
||||
this.initiator = initiator;
|
||||
this.added = added;
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* If a player was added
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean wasAdded() {
|
||||
return this.added;
|
||||
}
|
||||
|
||||
/**
|
||||
* The UUID added/removed
|
||||
*
|
||||
* @return UUID
|
||||
*/
|
||||
public UUID getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
/**
|
||||
* The player initiating the action
|
||||
*
|
||||
* @return Player
|
||||
*/
|
||||
public Player getInitiator() {
|
||||
return this.initiator;
|
||||
}
|
||||
|
||||
@Override public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.events;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Location;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.player.PlayerEvent;
|
||||
|
||||
/**
|
||||
* Called when a player teleports to a plot
|
||||
*/
|
||||
public class PlayerTeleportToPlotEvent extends PlayerEvent implements Cancellable {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private final Location from;
|
||||
private final Plot plot;
|
||||
private boolean cancelled;
|
||||
|
||||
/**
|
||||
* PlayerTeleportToPlotEvent: Called when a player teleports to a plot
|
||||
*
|
||||
* @param player That was teleported
|
||||
* @param from Start location
|
||||
* @param plot Plot to which the player was teleported
|
||||
*/
|
||||
public PlayerTeleportToPlotEvent(Player player, Location from, Plot plot) {
|
||||
super(player);
|
||||
this.from = from;
|
||||
this.plot = plot;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@Override public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the from location
|
||||
*
|
||||
* @return Location
|
||||
*/
|
||||
public Location getFrom() {
|
||||
return this.from;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plot involved
|
||||
*
|
||||
* @return Plot
|
||||
*/
|
||||
public Plot getPlot() {
|
||||
return this.plot;
|
||||
}
|
||||
|
||||
@Override public boolean isCancelled() {
|
||||
return this.cancelled;
|
||||
}
|
||||
|
||||
@Override public void setCancelled(boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.events;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotId;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Event called when plots are automatically merged with /plot auto
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public final class PlotAutoMergeEvent extends PlotEvent implements Cancellable {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private final List<PlotId> plots;
|
||||
@Getter private final World world;
|
||||
@Getter @Setter private boolean cancelled;
|
||||
|
||||
/**
|
||||
* PlotAutoMergeEvent: Called when plots are automatically merged with /plot auto
|
||||
*
|
||||
* @param world World in which the event occurred
|
||||
* @param plot Plot that was merged
|
||||
* @param plots A list of plots involved in the event
|
||||
*/
|
||||
public PlotAutoMergeEvent(@NotNull final World world, @NotNull final Plot plot,
|
||||
@NotNull final List<PlotId> plots) {
|
||||
super(plot);
|
||||
this.world = world;
|
||||
this.plots = plots;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plots being added.
|
||||
*
|
||||
* @return Unmodifiable list containing the merging plots
|
||||
*/
|
||||
public List<PlotId> getPlots() {
|
||||
return Collections.unmodifiableList(this.plots);
|
||||
}
|
||||
|
||||
@Override public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
@ -1,105 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.events;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotId;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class PlotChangeOwnerEvent extends PlotEvent implements Cancellable {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private final Player initiator;
|
||||
private final UUID newOwner;
|
||||
private final UUID oldOwner;
|
||||
private boolean hasOldOwner;
|
||||
private boolean cancelled;
|
||||
|
||||
/**
|
||||
* PlotChangeOwnerEvent: Called when a plot's owner is change.
|
||||
*
|
||||
* @param newOwner The new owner of the plot
|
||||
* @param oldOwner The old owner of the plot
|
||||
* @param plot The plot having its owner changed
|
||||
*/
|
||||
public PlotChangeOwnerEvent(Player initiator, Plot plot, UUID oldOwner, UUID newOwner,
|
||||
boolean hasOldOwner) {
|
||||
super(plot);
|
||||
this.initiator = initiator;
|
||||
this.newOwner = newOwner;
|
||||
this.oldOwner = oldOwner;
|
||||
this.hasOldOwner = hasOldOwner;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the PlotId.
|
||||
*
|
||||
* @return PlotId
|
||||
*/
|
||||
public PlotId getPlotId() {
|
||||
return getPlot().getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the world name.
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public String getWorld() {
|
||||
return getPlot().getWorldName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the change-owner initator
|
||||
*
|
||||
* @return Player
|
||||
*/
|
||||
public Player getInitiator() {
|
||||
return this.initiator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the old owner of the plot. Null if not exists.
|
||||
*
|
||||
* @return UUID
|
||||
*/
|
||||
public UUID getOldOwner() {
|
||||
return this.oldOwner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the new owner of the plot
|
||||
*
|
||||
* @return UUID
|
||||
*/
|
||||
public UUID getNewOwner() {
|
||||
return this.newOwner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if the plot had an old owner
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean hasOldOwner() {
|
||||
return this.hasOldOwner;
|
||||
}
|
||||
|
||||
@Override public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@Override public boolean isCancelled() {
|
||||
return this.cancelled;
|
||||
}
|
||||
|
||||
@Override public void setCancelled(boolean b) {
|
||||
this.cancelled = b;
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.events;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotId;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
/**
|
||||
* Called when a plot is cleared
|
||||
*/
|
||||
public class PlotClearEvent extends PlotEvent implements Cancellable {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private boolean cancelled;
|
||||
|
||||
public PlotClearEvent(Plot plot) {
|
||||
super(plot);
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the PlotId.
|
||||
*
|
||||
* @return PlotId
|
||||
*/
|
||||
public PlotId getPlotId() {
|
||||
return getPlot().getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the world name.
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public String getWorld() {
|
||||
return getPlot().getWorldName();
|
||||
}
|
||||
|
||||
@Override public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@Override public boolean isCancelled() {
|
||||
return this.cancelled;
|
||||
}
|
||||
|
||||
@Override public void setCancelled(boolean b) {
|
||||
this.cancelled = b;
|
||||
}
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.events;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotId;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
/**
|
||||
* Called when a plot component is set
|
||||
*/
|
||||
public class PlotComponentSetEvent extends PlotEvent {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private final String component;
|
||||
|
||||
public PlotComponentSetEvent(Plot plot, String component) {
|
||||
super(plot);
|
||||
this.component = component;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the PlotId
|
||||
*
|
||||
* @return PlotId
|
||||
*/
|
||||
public PlotId getPlotId() {
|
||||
return getPlot().getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the world name
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public String getWorld() {
|
||||
return getPlot().getWorldName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the component which was set
|
||||
*
|
||||
* @return Component name
|
||||
*/
|
||||
public String getComponent() {
|
||||
return this.component;
|
||||
}
|
||||
|
||||
@Override public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.events;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotId;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
/**
|
||||
* Called when a plot is deleted
|
||||
*/
|
||||
public class PlotDeleteEvent extends PlotEvent implements Cancellable {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private boolean cancelled;
|
||||
|
||||
public PlotDeleteEvent(Plot plot) {
|
||||
super(plot);
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the PlotId.
|
||||
*
|
||||
* @return PlotId
|
||||
*/
|
||||
public PlotId getPlotId() {
|
||||
return getPlot().getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the world name.
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public String getWorld() {
|
||||
return getPlot().getWorldName();
|
||||
}
|
||||
|
||||
@Override public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@Override public boolean isCancelled() {
|
||||
return this.cancelled;
|
||||
}
|
||||
|
||||
@Override public void setCancelled(boolean b) {
|
||||
this.cancelled = b;
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.events;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
||||
import org.bukkit.event.Event;
|
||||
|
||||
public abstract class PlotEvent extends Event {
|
||||
|
||||
private final Plot plot;
|
||||
|
||||
public PlotEvent(Plot plot) {
|
||||
this.plot = plot;
|
||||
}
|
||||
|
||||
public final Plot getPlot() {
|
||||
return this.plot;
|
||||
}
|
||||
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.events;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.plot.flag.Flag;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
/**
|
||||
* Called when a Flag is added to a plot.
|
||||
*/
|
||||
public class PlotFlagAddEvent extends PlotEvent implements Cancellable {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private final Flag flag;
|
||||
private boolean cancelled;
|
||||
|
||||
/**
|
||||
* PlotFlagAddEvent: Called when a Flag is added to a plot.
|
||||
*
|
||||
* @param flag Flag that was added
|
||||
* @param plot Plot to which the flag was added
|
||||
*/
|
||||
public PlotFlagAddEvent(Flag flag, Plot plot) {
|
||||
super(plot);
|
||||
this.flag = flag;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the flag involved.
|
||||
*
|
||||
* @return Flag
|
||||
*/
|
||||
public Flag getFlag() {
|
||||
return this.flag;
|
||||
}
|
||||
|
||||
@Override public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@Override public final boolean isCancelled() {
|
||||
return this.cancelled;
|
||||
}
|
||||
|
||||
@Override public final void setCancelled(boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.events;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.plot.flag.Flag;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
/**
|
||||
* Called when a flag is removed from a plot
|
||||
*/
|
||||
public class PlotFlagRemoveEvent extends PlotEvent implements Cancellable {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private final Flag flag;
|
||||
private boolean cancelled;
|
||||
|
||||
/**
|
||||
* PlotFlagRemoveEvent: Called when a flag is removed from a plot
|
||||
*
|
||||
* @param flag Flag that was removed
|
||||
* @param plot Plot from which the flag was removed
|
||||
*/
|
||||
public PlotFlagRemoveEvent(Flag flag, Plot plot) {
|
||||
super(plot);
|
||||
this.flag = flag;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the flag involved
|
||||
*
|
||||
* @return Flag
|
||||
*/
|
||||
public Flag getFlag() {
|
||||
return this.flag;
|
||||
}
|
||||
|
||||
@Override public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@Override public final boolean isCancelled() {
|
||||
return this.cancelled;
|
||||
}
|
||||
|
||||
@Override public final void setCancelled(boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.events;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Event called when several plots are merged
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public final class PlotMergeEvent extends PlotEvent implements Cancellable {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
@Getter private final int dir;
|
||||
@Getter private final int max;
|
||||
@Getter private final World world;
|
||||
@Getter @Setter private boolean cancelled;
|
||||
|
||||
/**
|
||||
* PlotMergeEvent: Called when plots are merged
|
||||
*
|
||||
* @param world World in which the event occurred
|
||||
* @param plot Plot that was merged
|
||||
* @param dir The direction of the merge
|
||||
* @param max Max merge size
|
||||
*/
|
||||
public PlotMergeEvent(@NotNull final World world, @NotNull final Plot plot,
|
||||
@NotNull final int dir, @NotNull final int max) {
|
||||
super(plot);
|
||||
this.world = world;
|
||||
this.dir = dir;
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@Override public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.events;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Rating;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
public class PlotRateEvent extends PlotEvent implements Cancellable {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private final PlotPlayer rater;
|
||||
private Rating rating;
|
||||
private boolean cancelled = false;
|
||||
|
||||
public PlotRateEvent(PlotPlayer rater, Rating rating, Plot plot) {
|
||||
super(plot);
|
||||
this.rater = rater;
|
||||
this.rating = rating;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public PlotPlayer getRater() {
|
||||
return this.rater;
|
||||
}
|
||||
|
||||
public Rating getRating() {
|
||||
return this.rating;
|
||||
}
|
||||
|
||||
public void setRating(Rating rating) {
|
||||
this.rating = rating;
|
||||
}
|
||||
|
||||
@Override public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@Override public boolean isCancelled() {
|
||||
return this.cancelled;
|
||||
}
|
||||
|
||||
@Override public void setCancelled(boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.events;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotArea;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotId;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Event called when several merged plots are unlinked
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public final class PlotUnlinkEvent extends Event implements Cancellable {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private final List<PlotId> plots;
|
||||
@Getter private final World world;
|
||||
@Getter private final PlotArea area;
|
||||
@Getter @Setter private boolean cancelled;
|
||||
|
||||
/**
|
||||
* Called when a mega-plot is unlinked.
|
||||
*
|
||||
* @param world World in which the event occurred
|
||||
* @param plots Plots that are involved in the event
|
||||
*/
|
||||
public PlotUnlinkEvent(@NotNull final World world, @NotNull final PlotArea area,
|
||||
@NotNull final List<PlotId> plots) {
|
||||
this.plots = plots;
|
||||
this.world = world;
|
||||
this.area = area;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plots involved.
|
||||
*
|
||||
* @return Unmodifiable list containing {@link PlotId PlotIds} of the plots involved
|
||||
*/
|
||||
public List<PlotId> getPlots() {
|
||||
return Collections.unmodifiableList(this.plots);
|
||||
}
|
||||
|
||||
@Override public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.generator;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.plot.generator.AugmentedUtils;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class BukkitAugmentedGenerator extends BlockPopulator {
|
||||
|
||||
private static BukkitAugmentedGenerator generator;
|
||||
|
||||
public static BukkitAugmentedGenerator get(World world) {
|
||||
for (BlockPopulator populator : world.getPopulators()) {
|
||||
if (populator instanceof BukkitAugmentedGenerator) {
|
||||
return (BukkitAugmentedGenerator) populator;
|
||||
}
|
||||
}
|
||||
if (generator == null) {
|
||||
generator = new BukkitAugmentedGenerator();
|
||||
}
|
||||
world.getPopulators().add(generator);
|
||||
return generator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk source) {
|
||||
AugmentedUtils.generate(world.getName(), source.getX(), source.getZ(), null);
|
||||
}
|
||||
}
|
@ -1,211 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.generator;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitUtil;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.util.block.GenChunk;
|
||||
import com.github.intellectualsites.plotsquared.plot.PlotSquared;
|
||||
import com.github.intellectualsites.plotsquared.plot.generator.GeneratorWrapper;
|
||||
import com.github.intellectualsites.plotsquared.plot.generator.IndependentPlotGenerator;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.ChunkWrapper;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotArea;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.worlds.SingleWorldGenerator;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.ChunkManager;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.MainUtil;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.block.ScopedLocalBlockQueue;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
public class BukkitPlotGenerator extends ChunkGenerator
|
||||
implements GeneratorWrapper<ChunkGenerator> {
|
||||
|
||||
@SuppressWarnings("unused") public final boolean PAPER_ASYNC_SAFE = true;
|
||||
|
||||
private final IndependentPlotGenerator plotGenerator;
|
||||
private final ChunkGenerator platformGenerator;
|
||||
private final boolean full;
|
||||
private List<BlockPopulator> populators;
|
||||
private boolean loaded = false;
|
||||
|
||||
public BukkitPlotGenerator(IndependentPlotGenerator generator) {
|
||||
if (generator == null) {
|
||||
throw new IllegalArgumentException("Generator may not be null!");
|
||||
}
|
||||
this.plotGenerator = generator;
|
||||
this.platformGenerator = this;
|
||||
this.populators = new ArrayList<>();
|
||||
this.populators.add(new BlockStatePopulator(this.plotGenerator));
|
||||
this.full = true;
|
||||
MainUtil.initCache();
|
||||
}
|
||||
|
||||
public BukkitPlotGenerator(final String world, final ChunkGenerator cg) {
|
||||
if (cg instanceof BukkitPlotGenerator) {
|
||||
throw new IllegalArgumentException("ChunkGenerator: " + cg.getClass().getName()
|
||||
+ " is already a BukkitPlotGenerator!");
|
||||
}
|
||||
this.full = false;
|
||||
this.platformGenerator = cg;
|
||||
this.plotGenerator = new DelegatePlotGenerator(cg, world);
|
||||
MainUtil.initCache();
|
||||
}
|
||||
|
||||
@Override public void augment(PlotArea area) {
|
||||
BukkitAugmentedGenerator.get(BukkitUtil.getWorld(area.worldname));
|
||||
}
|
||||
|
||||
@Override public boolean isFull() {
|
||||
return this.full;
|
||||
}
|
||||
|
||||
@Override public IndependentPlotGenerator getPlotGenerator() {
|
||||
return this.plotGenerator;
|
||||
}
|
||||
|
||||
@Override public ChunkGenerator getPlatformGenerator() {
|
||||
return this.platformGenerator;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public List<BlockPopulator> getDefaultPopulators(@NotNull World world) {
|
||||
try {
|
||||
if (!this.loaded) {
|
||||
String name = world.getName();
|
||||
PlotSquared.get().loadWorld(name, this);
|
||||
Set<PlotArea> areas = PlotSquared.get().getPlotAreas(name);
|
||||
if (!areas.isEmpty()) {
|
||||
PlotArea area = areas.iterator().next();
|
||||
if (!area.MOB_SPAWNING) {
|
||||
if (!area.SPAWN_EGGS) {
|
||||
world.setSpawnFlags(false, false);
|
||||
}
|
||||
world.setAmbientSpawnLimit(0);
|
||||
world.setAnimalSpawnLimit(0);
|
||||
world.setMonsterSpawnLimit(0);
|
||||
world.setWaterAnimalSpawnLimit(0);
|
||||
} else {
|
||||
world.setSpawnFlags(true, true);
|
||||
world.setAmbientSpawnLimit(-1);
|
||||
world.setAnimalSpawnLimit(-1);
|
||||
world.setMonsterSpawnLimit(-1);
|
||||
world.setWaterAnimalSpawnLimit(-1);
|
||||
}
|
||||
}
|
||||
this.loaded = true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
ArrayList<BlockPopulator> toAdd = new ArrayList<>();
|
||||
List<BlockPopulator> existing = world.getPopulators();
|
||||
if (populators == null && platformGenerator != null) {
|
||||
populators = new ArrayList<>(platformGenerator.getDefaultPopulators(world));
|
||||
}
|
||||
if (populators != null) {
|
||||
for (BlockPopulator populator : this.populators) {
|
||||
if (!existing.contains(populator)) {
|
||||
toAdd.add(populator);
|
||||
}
|
||||
}
|
||||
}
|
||||
return toAdd;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public ChunkData generateChunkData(@NotNull World world, @NotNull Random random, int x, int z,
|
||||
@NotNull BiomeGrid biome) {
|
||||
|
||||
GenChunk result = new GenChunk();
|
||||
if (this.getPlotGenerator() instanceof SingleWorldGenerator) {
|
||||
if (result.getChunkData() != null) {
|
||||
for (int chunkX = 0; chunkX < 16; chunkX++) {
|
||||
for (int chunkZ = 0; chunkZ < 16; chunkZ++) {
|
||||
biome.setBiome(chunkX, chunkZ, Biome.PLAINS);
|
||||
}
|
||||
}
|
||||
return result.getChunkData();
|
||||
}
|
||||
}
|
||||
// Set the chunk location
|
||||
result.setChunk(new ChunkWrapper(world.getName(), x, z));
|
||||
// Set the result data
|
||||
result.setChunkData(createChunkData(world));
|
||||
result.biomeGrid = biome;
|
||||
result.result = null;
|
||||
|
||||
// Catch any exceptions (as exceptions usually thrown)
|
||||
try {
|
||||
// Fill the result data if necessary
|
||||
if (this.platformGenerator != this) {
|
||||
return this.platformGenerator.generateChunkData(world, random, x, z, biome);
|
||||
} else {
|
||||
generate(BlockVector2.at(x, z), world, result);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// Return the result data
|
||||
return result.getChunkData();
|
||||
}
|
||||
|
||||
private void generate(BlockVector2 loc, World world, ScopedLocalBlockQueue result) {
|
||||
// Load if improperly loaded
|
||||
if (!this.loaded) {
|
||||
String name = world.getName();
|
||||
PlotSquared.get().loadWorld(name, this);
|
||||
this.loaded = true;
|
||||
}
|
||||
// Process the chunk
|
||||
if (ChunkManager.preProcessChunk(loc, result)) {
|
||||
return;
|
||||
}
|
||||
PlotArea area = PlotSquared.get().getPlotArea(world.getName(), null);
|
||||
try {
|
||||
this.plotGenerator.generateChunk(result, area);
|
||||
} catch (Throwable e) {
|
||||
// Recover from generator error
|
||||
e.printStackTrace();
|
||||
}
|
||||
ChunkManager.postProcessChunk(loc, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow spawning everywhere.
|
||||
*
|
||||
* @param world Ignored
|
||||
* @param x Ignored
|
||||
* @param z Ignored
|
||||
* @return always true
|
||||
*/
|
||||
@Override public boolean canSpawn(@NotNull final World world, final int x, final int z) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
if (this.platformGenerator == this) {
|
||||
return this.plotGenerator.getName();
|
||||
}
|
||||
if (this.platformGenerator == null) {
|
||||
return "null";
|
||||
} else {
|
||||
return this.platformGenerator.getClass().getName();
|
||||
}
|
||||
}
|
||||
|
||||
@Override public boolean equals(final Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
return toString().equals(obj.toString()) || toString().equals(obj.getClass().getName());
|
||||
}
|
||||
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.generator;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitUtil;
|
||||
import com.github.intellectualsites.plotsquared.plot.PlotSquared;
|
||||
import com.github.intellectualsites.plotsquared.plot.generator.IndependentPlotGenerator;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Location;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotArea;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotId;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.MathMan;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.block.ScopedLocalBlockQueue;
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Range;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
@RequiredArgsConstructor final class DelegatePlotGenerator extends IndependentPlotGenerator {
|
||||
|
||||
private final ChunkGenerator chunkGenerator;
|
||||
private final String world;
|
||||
|
||||
@Override public void initialize(PlotArea area) {
|
||||
}
|
||||
|
||||
@Override public String getName() {
|
||||
return this.chunkGenerator.getClass().getName();
|
||||
}
|
||||
|
||||
@Override public PlotArea getNewPlotArea(String world, String id, PlotId min, PlotId max) {
|
||||
return PlotSquared.get().IMP.getDefaultGenerator().getNewPlotArea(world, id, min, max);
|
||||
}
|
||||
|
||||
@Override public void generateChunk(final ScopedLocalBlockQueue result, PlotArea settings) {
|
||||
World world = BukkitUtil.getWorld(this.world);
|
||||
Location min = result.getMin();
|
||||
int chunkX = min.getX() >> 4;
|
||||
int chunkZ = min.getZ() >> 4;
|
||||
Random random = new Random(MathMan.pair((short) chunkX, (short) chunkZ));
|
||||
try {
|
||||
ChunkGenerator.BiomeGrid grid = new ChunkGenerator.BiomeGrid() {
|
||||
@Override public void setBiome(@Range(from = 0, to = 15) int x,
|
||||
@Range(from = 0, to = 15) int z, Biome biome) {
|
||||
result.setBiome(x, z, BukkitAdapter.adapt(biome));
|
||||
}
|
||||
|
||||
@Override @NotNull public Biome getBiome(int x, int z) {
|
||||
return Biome.FOREST;
|
||||
}
|
||||
};
|
||||
chunkGenerator.generateChunkData(world, random, chunkX, chunkZ, grid);
|
||||
return;
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
for (BlockPopulator populator : chunkGenerator.getDefaultPopulators(world)) {
|
||||
populator.populate(world, random, world.getChunkAt(chunkX, chunkZ));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.generator;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.plot.PlotSquared;
|
||||
import com.github.intellectualsites.plotsquared.plot.generator.IndependentPlotGenerator;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.ChunkWrapper;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotArea;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.block.GlobalBlockQueue;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.block.ScopedLocalBlockQueue;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
@RequiredArgsConstructor final class BlockStatePopulator extends BlockPopulator {
|
||||
|
||||
private final IndependentPlotGenerator plotGenerator;
|
||||
private LocalBlockQueue queue;
|
||||
|
||||
@Override public void populate(@NotNull final World world, @NotNull final Random random,
|
||||
@NotNull final Chunk source) {
|
||||
if (this.queue == null) {
|
||||
this.queue = GlobalBlockQueue.IMP.getNewQueue(world.getName(), false);
|
||||
}
|
||||
final PlotArea area = PlotSquared.get().getPlotArea(world.getName(), null);
|
||||
final ChunkWrapper wrap = new ChunkWrapper(area.worldname, source.getX(), source.getZ());
|
||||
final ScopedLocalBlockQueue chunk = this.queue.getForChunk(wrap.x, wrap.z);
|
||||
if (this.plotGenerator.populateChunk(chunk, area)) {
|
||||
this.queue.flush();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,283 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.listeners;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.plot.PlotSquared;
|
||||
import com.github.intellectualsites.plotsquared.plot.config.Settings;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Location;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.RefClass;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.RefField;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.RefMethod;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.TaskManager;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockPhysicsEvent;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
import org.bukkit.event.entity.ItemSpawnEvent;
|
||||
import org.bukkit.event.world.ChunkLoadEvent;
|
||||
import org.bukkit.event.world.ChunkUnloadEvent;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashSet;
|
||||
|
||||
import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.getRefClass;
|
||||
|
||||
@SuppressWarnings("unused") public class ChunkListener implements Listener {
|
||||
|
||||
private RefMethod methodGetHandleChunk;
|
||||
private RefField mustSave;
|
||||
private Chunk lastChunk;
|
||||
private boolean ignoreUnload = false;
|
||||
|
||||
public ChunkListener() {
|
||||
if (Settings.Chunk_Processor.AUTO_TRIM) {
|
||||
try {
|
||||
RefClass classChunk = getRefClass("{nms}.Chunk");
|
||||
RefClass classCraftChunk = getRefClass("{cb}.CraftChunk");
|
||||
this.mustSave = classChunk.getField("mustSave");
|
||||
this.methodGetHandleChunk = classCraftChunk.getMethod("getHandle");
|
||||
} catch (Throwable ignored) {
|
||||
PlotSquared.debug(PlotSquared.get().IMP.getPluginName()
|
||||
+ "/Server not compatible for chunk processor trim/gc");
|
||||
|
||||
Settings.Chunk_Processor.AUTO_TRIM = false;
|
||||
}
|
||||
}
|
||||
if (!Settings.Chunk_Processor.AUTO_TRIM) {
|
||||
return;
|
||||
}
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
world.setAutoSave(false);
|
||||
}
|
||||
TaskManager.runTaskRepeat(() -> {
|
||||
try {
|
||||
HashSet<Chunk> toUnload = new HashSet<>();
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
String worldName = world.getName();
|
||||
if (!PlotSquared.get().hasPlotArea(worldName)) {
|
||||
continue;
|
||||
}
|
||||
Object w = world.getClass().getDeclaredMethod("getHandle").invoke(world);
|
||||
Object chunkMap = w.getClass().getDeclaredMethod("getPlayerChunkMap").invoke(w);
|
||||
Method methodIsChunkInUse =
|
||||
chunkMap.getClass().getDeclaredMethod("isChunkInUse", int.class, int.class);
|
||||
Chunk[] chunks = world.getLoadedChunks();
|
||||
for (Chunk chunk : chunks) {
|
||||
if ((boolean) methodIsChunkInUse
|
||||
.invoke(chunkMap, chunk.getX(), chunk.getZ())) {
|
||||
continue;
|
||||
}
|
||||
int x = chunk.getX();
|
||||
int z = chunk.getZ();
|
||||
if (!shouldSave(worldName, x, z)) {
|
||||
unloadChunk(worldName, chunk, false);
|
||||
continue;
|
||||
}
|
||||
toUnload.add(chunk);
|
||||
}
|
||||
}
|
||||
if (toUnload.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
long start = System.currentTimeMillis();
|
||||
for (Chunk chunk : toUnload) {
|
||||
if (System.currentTimeMillis() - start > 5) {
|
||||
return;
|
||||
}
|
||||
chunk.unload(true);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}, 1);
|
||||
}
|
||||
|
||||
public boolean unloadChunk(String world, Chunk chunk, boolean safe) {
|
||||
if (safe && shouldSave(world, chunk.getX(), chunk.getZ())) {
|
||||
return false;
|
||||
}
|
||||
Object c = this.methodGetHandleChunk.of(chunk).call();
|
||||
RefField.RefExecutor field = this.mustSave.of(c);
|
||||
if ((Boolean) field.get()) {
|
||||
field.set(false);
|
||||
if (chunk.isLoaded()) {
|
||||
ignoreUnload = true;
|
||||
chunk.unload(false);
|
||||
ignoreUnload = false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean shouldSave(String world, int chunkX, int chunkZ) {
|
||||
int x = chunkX << 4;
|
||||
int z = chunkZ << 4;
|
||||
int x2 = x + 15;
|
||||
int z2 = z + 15;
|
||||
Plot plot = new Location(world, x, 1, z).getOwnedPlotAbs();
|
||||
if (plot != null && plot.hasOwner()) {
|
||||
return true;
|
||||
}
|
||||
plot = new Location(world, x2, 1, z2).getOwnedPlotAbs();
|
||||
if (plot != null && plot.hasOwner()) {
|
||||
return true;
|
||||
}
|
||||
plot = new Location(world, x2, 1, z).getOwnedPlotAbs();
|
||||
if (plot != null && plot.hasOwner()) {
|
||||
return true;
|
||||
}
|
||||
plot = new Location(world, x, 1, z2).getOwnedPlotAbs();
|
||||
if (plot != null && plot.hasOwner()) {
|
||||
return true;
|
||||
}
|
||||
plot = new Location(world, x + 7, 1, z + 7).getOwnedPlotAbs();
|
||||
return plot != null && plot.hasOwner();
|
||||
}
|
||||
|
||||
@EventHandler public void onChunkUnload(ChunkUnloadEvent event) {
|
||||
if (ignoreUnload) {
|
||||
return;
|
||||
}
|
||||
Chunk chunk = event.getChunk();
|
||||
if (Settings.Chunk_Processor.AUTO_TRIM) {
|
||||
String world = chunk.getWorld().getName();
|
||||
if (PlotSquared.get().hasPlotArea(world)) {
|
||||
if (unloadChunk(world, chunk, true)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (processChunk(event.getChunk(), true)) {
|
||||
chunk.setForceLoaded(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler public void onChunkLoad(ChunkLoadEvent event) {
|
||||
processChunk(event.getChunk(), false);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST) public void onItemSpawn(ItemSpawnEvent event) {
|
||||
Item entity = event.getEntity();
|
||||
PaperLib.getChunkAtAsync(event.getLocation()).thenAccept(chunk -> {
|
||||
if (chunk == this.lastChunk) {
|
||||
event.getEntity().remove();
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (!PlotSquared.get().hasPlotArea(chunk.getWorld().getName())) {
|
||||
return;
|
||||
}
|
||||
Entity[] entities = chunk.getEntities();
|
||||
if (entities.length > Settings.Chunk_Processor.MAX_ENTITIES) {
|
||||
event.getEntity().remove();
|
||||
event.setCancelled(true);
|
||||
this.lastChunk = chunk;
|
||||
} else {
|
||||
this.lastChunk = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onBlockPhysics(BlockPhysicsEvent event) {
|
||||
if (Settings.Chunk_Processor.DISABLE_PHYSICS) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onEntitySpawn(CreatureSpawnEvent event) {
|
||||
LivingEntity entity = event.getEntity();
|
||||
PaperLib.getChunkAtAsync(event.getLocation()).thenAccept(chunk -> {
|
||||
if (chunk == this.lastChunk) {
|
||||
event.getEntity().remove();
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (!PlotSquared.get().hasPlotArea(chunk.getWorld().getName())) {
|
||||
return;
|
||||
}
|
||||
Entity[] entities = chunk.getEntities();
|
||||
if (entities.length > Settings.Chunk_Processor.MAX_ENTITIES) {
|
||||
event.getEntity().remove();
|
||||
event.setCancelled(true);
|
||||
this.lastChunk = chunk;
|
||||
} else {
|
||||
this.lastChunk = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void cleanChunk(final Chunk chunk) {
|
||||
TaskManager.index.incrementAndGet();
|
||||
final Integer currentIndex = TaskManager.index.get();
|
||||
Integer task = TaskManager.runTaskRepeat(() -> {
|
||||
if (!chunk.isLoaded()) {
|
||||
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
|
||||
TaskManager.tasks.remove(currentIndex);
|
||||
PlotSquared.debug("Successfully processed and unloaded chunk!");
|
||||
chunk.unload(true);
|
||||
return;
|
||||
}
|
||||
BlockState[] tiles = chunk.getTileEntities();
|
||||
if (tiles.length == 0) {
|
||||
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
|
||||
TaskManager.tasks.remove(currentIndex);
|
||||
PlotSquared.debug("Successfully processed and unloaded chunk!");
|
||||
chunk.unload(true);
|
||||
return;
|
||||
}
|
||||
long start = System.currentTimeMillis();
|
||||
int i = 0;
|
||||
while (System.currentTimeMillis() - start < 250) {
|
||||
if (i >= tiles.length) {
|
||||
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
|
||||
TaskManager.tasks.remove(currentIndex);
|
||||
PlotSquared.debug("Successfully processed and unloaded chunk!");
|
||||
chunk.unload(true);
|
||||
return;
|
||||
}
|
||||
tiles[i].getBlock().setType(Material.AIR, false);
|
||||
i++;
|
||||
}
|
||||
}, 5);
|
||||
TaskManager.tasks.put(currentIndex, task);
|
||||
}
|
||||
|
||||
public boolean processChunk(Chunk chunk, boolean unload) {
|
||||
if (!PlotSquared.get().hasPlotArea(chunk.getWorld().getName())) {
|
||||
return false;
|
||||
}
|
||||
Entity[] entities = chunk.getEntities();
|
||||
BlockState[] tiles = chunk.getTileEntities();
|
||||
if (entities.length > Settings.Chunk_Processor.MAX_ENTITIES) {
|
||||
for (Entity ent : entities) {
|
||||
if (!(ent instanceof Player)) {
|
||||
ent.remove();
|
||||
}
|
||||
}
|
||||
PlotSquared.debug("PlotSquared detected unsafe chunk and processed: " + (chunk.getX() << 4) + "," + (chunk.getX() << 4));
|
||||
}
|
||||
if (tiles.length > Settings.Chunk_Processor.MAX_TILES) {
|
||||
if (unload) {
|
||||
PlotSquared.debug("PlotSquared detected unsafe chunk: " + (chunk.getX()<< 4) + "," + (chunk.getX() << 4));
|
||||
cleanChunk(chunk);
|
||||
return true;
|
||||
}
|
||||
for (BlockState tile : tiles) {
|
||||
tile.getBlock().setType(Material.AIR, false);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,173 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.listeners;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitUtil;
|
||||
import com.github.intellectualsites.plotsquared.plot.PlotSquared;
|
||||
import com.github.intellectualsites.plotsquared.plot.config.Settings;
|
||||
import com.github.intellectualsites.plotsquared.plot.flag.Flags;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Location;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotArea;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Vehicle;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
import org.bukkit.event.entity.EntitySpawnEvent;
|
||||
import org.bukkit.event.entity.EntityTeleportEvent;
|
||||
import org.bukkit.event.vehicle.VehicleBlockCollisionEvent;
|
||||
import org.bukkit.event.vehicle.VehicleCreateEvent;
|
||||
import org.bukkit.event.vehicle.VehicleMoveEvent;
|
||||
import org.bukkit.event.vehicle.VehicleUpdateEvent;
|
||||
import org.bukkit.event.world.ChunkLoadEvent;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
import org.bukkit.metadata.MetadataValue;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EntitySpawnListener implements Listener {
|
||||
|
||||
private final static String KEY = "P2";
|
||||
private static boolean ignoreTP = false;
|
||||
private static boolean hasPlotArea = false;
|
||||
private static String areaName = null;
|
||||
|
||||
public static void testNether(Entity entity) {
|
||||
@NotNull World world = entity.getWorld();
|
||||
if (world.getEnvironment() != World.Environment.NETHER
|
||||
&& world.getEnvironment() != World.Environment.THE_END) {
|
||||
return;
|
||||
}
|
||||
test(entity);
|
||||
}
|
||||
|
||||
public static void testCreate(Entity entity) {
|
||||
@NotNull World world = entity.getWorld();
|
||||
if (areaName == world.getName()) {
|
||||
} else {
|
||||
areaName = world.getName();
|
||||
hasPlotArea = PlotSquared.get().hasPlotArea(areaName);
|
||||
}
|
||||
if (!hasPlotArea)
|
||||
return;
|
||||
test(entity);
|
||||
}
|
||||
|
||||
public static void test(Entity entity) {
|
||||
@NotNull World world = entity.getWorld();
|
||||
List<MetadataValue> meta = entity.getMetadata(KEY);
|
||||
if (meta.isEmpty()) {
|
||||
if (PlotSquared.get().hasPlotArea(world.getName())) {
|
||||
entity.setMetadata(KEY,
|
||||
new FixedMetadataValue((Plugin) PlotSquared.get().IMP, entity.getLocation()));
|
||||
}
|
||||
} else {
|
||||
org.bukkit.Location origin = (org.bukkit.Location) meta.get(0).value();
|
||||
World originWorld = origin.getWorld();
|
||||
if (!originWorld.equals(world)) {
|
||||
if (!ignoreTP) {
|
||||
if (!world.getName().equalsIgnoreCase(originWorld + "_the_end")) {
|
||||
try {
|
||||
ignoreTP = true;
|
||||
PaperLib.teleportAsync(entity,origin);
|
||||
} finally {
|
||||
ignoreTP = false;
|
||||
}
|
||||
if (entity.getLocation().getWorld().equals(world)) {
|
||||
entity.remove();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
entity.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void creatureSpawnEvent(EntitySpawnEvent event) {
|
||||
Entity entity = event.getEntity();
|
||||
Location location = BukkitUtil.getLocation(entity.getLocation());
|
||||
PlotArea area = location.getPlotArea();
|
||||
if (!location.isPlotArea()) {
|
||||
return;
|
||||
}
|
||||
Plot plot = location.getOwnedPlotAbs();
|
||||
if (plot == null) {
|
||||
if (!area.MOB_SPAWNING) {
|
||||
EntityType type = entity.getType();
|
||||
switch (type) {
|
||||
case DROPPED_ITEM:
|
||||
if (Settings.Enabled_Components.KILL_ROAD_ITEMS) {
|
||||
event.setCancelled(true);
|
||||
break;
|
||||
}
|
||||
case PLAYER:
|
||||
return;
|
||||
}
|
||||
if (type.isAlive() || !area.MISC_SPAWN_UNOWNED) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (Settings.Done.RESTRICT_BUILDING && plot.hasFlag(Flags.DONE)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
switch (entity.getType()) {
|
||||
case ENDER_CRYSTAL:
|
||||
if (PlayerEvents.checkEntity(entity, plot)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
case SHULKER:
|
||||
if (!entity.hasMetadata("shulkerPlot")) {
|
||||
entity.setMetadata("shulkerPlot",
|
||||
new FixedMetadataValue((Plugin) PlotSquared.get().IMP, plot.getId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler public void onChunkLoad(ChunkLoadEvent event) {
|
||||
@NotNull Chunk chunk = event.getChunk();
|
||||
for (Entity entity : chunk.getEntities()) {
|
||||
testCreate(entity);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler public void onVehicle(VehicleUpdateEvent event) {
|
||||
testNether(event.getVehicle());
|
||||
}
|
||||
|
||||
@EventHandler public void onVehicle(VehicleCreateEvent event) {
|
||||
testCreate(event.getVehicle());
|
||||
}
|
||||
|
||||
@EventHandler public void onVehicle(VehicleBlockCollisionEvent event) {
|
||||
testNether(event.getVehicle());
|
||||
}
|
||||
|
||||
@EventHandler public void onTeleport(EntityTeleportEvent event) {
|
||||
Entity ent = event.getEntity();
|
||||
if (ent instanceof Vehicle || ent instanceof ArmorStand) {
|
||||
testNether(event.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void vehicleMove(VehicleMoveEvent event) {
|
||||
testNether(event.getVehicle());
|
||||
}
|
||||
|
||||
@EventHandler public void spawn(CreatureSpawnEvent event) {
|
||||
if (event.getEntityType() == EntityType.ARMOR_STAND) {
|
||||
testCreate(event.getEntity());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,106 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.listeners;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.bukkit.object.BukkitPlayer;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitUtil;
|
||||
import com.github.intellectualsites.plotsquared.plot.config.Captions;
|
||||
import com.github.intellectualsites.plotsquared.plot.flag.Flags;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Location;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.Permissions;
|
||||
import com.google.common.collect.Iterables;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
@SuppressWarnings("unused") public class ForceFieldListener {
|
||||
|
||||
private static Set<PlotPlayer> getNearbyPlayers(Player player, Plot plot) {
|
||||
Set<PlotPlayer> players = new HashSet<>();
|
||||
for (Player nearPlayer : Iterables
|
||||
.filter(player.getNearbyEntities(5d, 5d, 5d), Player.class)) {
|
||||
PlotPlayer plotPlayer;
|
||||
if ((plotPlayer = BukkitUtil.getPlayer(nearPlayer)) == null || !plot
|
||||
.equals(plotPlayer.getCurrentPlot())) {
|
||||
continue;
|
||||
}
|
||||
if (!plot.isAdded(plotPlayer.getUUID())) {
|
||||
players.add(plotPlayer);
|
||||
}
|
||||
}
|
||||
return players;
|
||||
}
|
||||
|
||||
private static PlotPlayer hasNearbyPermitted(Player player, Plot plot) {
|
||||
for (Player nearPlayer : Iterables
|
||||
.filter(player.getNearbyEntities(5d, 5d, 5d), Player.class)) {
|
||||
PlotPlayer plotPlayer;
|
||||
if ((plotPlayer = BukkitUtil.getPlayer(nearPlayer)) == null || !plot
|
||||
.equals(plotPlayer.getCurrentPlot())) {
|
||||
continue;
|
||||
}
|
||||
if (plot.isAdded(plotPlayer.getUUID())) {
|
||||
return plotPlayer;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Vector calculateVelocity(PlotPlayer player, PlotPlayer e) {
|
||||
Location playerLocation = player.getLocationFull();
|
||||
Location oPlayerLocation = e.getLocation();
|
||||
double playerX = playerLocation.getX();
|
||||
double playerY = playerLocation.getY();
|
||||
double playerZ = playerLocation.getZ();
|
||||
double oPlayerX = oPlayerLocation.getX();
|
||||
double oPlayerY = oPlayerLocation.getY();
|
||||
double oPlayerZ = oPlayerLocation.getZ();
|
||||
double x = 0d;
|
||||
if (playerX < oPlayerX) {
|
||||
x = 1.0d;
|
||||
} else if (playerX > oPlayerX) {
|
||||
x = -1.0d;
|
||||
}
|
||||
double y = 0d;
|
||||
if (playerY < oPlayerY) {
|
||||
y = 0.5d;
|
||||
} else if (playerY > oPlayerY) {
|
||||
y = -0.5d;
|
||||
}
|
||||
double z = 0d;
|
||||
if (playerZ < oPlayerZ) {
|
||||
z = 1.0d;
|
||||
} else if (playerZ > oPlayerZ) {
|
||||
z = -1.0d;
|
||||
}
|
||||
return new Vector(x, y, z);
|
||||
}
|
||||
|
||||
public static void handleForcefield(Player player, PlotPlayer plotPlayer, Plot plot) {
|
||||
if (Flags.FORCEFIELD.isTrue(plot)) {
|
||||
UUID uuid = plotPlayer.getUUID();
|
||||
if (plot.isAdded(uuid)) {
|
||||
Set<PlotPlayer> players = getNearbyPlayers(player, plot);
|
||||
for (PlotPlayer oPlayer : players) {
|
||||
if (!Permissions
|
||||
.hasPermission(oPlayer, Captions.PERMISSION_ADMIN_ENTRY_FORCEFIELD)) {
|
||||
((BukkitPlayer) oPlayer).player
|
||||
.setVelocity(calculateVelocity(plotPlayer, oPlayer));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
PlotPlayer oPlayer = hasNearbyPermitted(player, plot);
|
||||
if (oPlayer == null) {
|
||||
return;
|
||||
}
|
||||
if (!Permissions
|
||||
.hasPermission(plotPlayer, Captions.PERMISSION_ADMIN_ENTRY_FORCEFIELD)) {
|
||||
player.setVelocity(calculateVelocity(oPlayer, plotPlayer));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,189 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.listeners;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.bukkit.events.PlayerEnterPlotEvent;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.events.PlayerLeavePlotEvent;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitUtil;
|
||||
import com.github.intellectualsites.plotsquared.plot.flag.Flags;
|
||||
import com.github.intellectualsites.plotsquared.plot.flag.IntervalFlag;
|
||||
import com.github.intellectualsites.plotsquared.plot.listener.PlotListener;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockDamageEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.entity.EntityPickupItemEvent;
|
||||
import org.bukkit.event.player.PlayerDropItemEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@SuppressWarnings("unused") public class PlotPlusListener extends PlotListener implements Listener {
|
||||
|
||||
private static final HashMap<UUID, Interval> feedRunnable = new HashMap<>();
|
||||
private static final HashMap<UUID, Interval> healRunnable = new HashMap<>();
|
||||
|
||||
public static void startRunnable(JavaPlugin plugin) {
|
||||
plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, () -> {
|
||||
if (!healRunnable.isEmpty()) {
|
||||
for (Iterator<Entry<UUID, Interval>> iterator =
|
||||
healRunnable.entrySet().iterator(); iterator.hasNext(); ) {
|
||||
Entry<UUID, Interval> entry = iterator.next();
|
||||
Interval value = entry.getValue();
|
||||
++value.count;
|
||||
if (value.count == value.interval) {
|
||||
value.count = 0;
|
||||
Player player = Bukkit.getPlayer(entry.getKey());
|
||||
if (player == null) {
|
||||
iterator.remove();
|
||||
continue;
|
||||
}
|
||||
double level = player.getHealth();
|
||||
if (level != value.max) {
|
||||
player.setHealth(Math.min(level + value.amount, value.max));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!feedRunnable.isEmpty()) {
|
||||
for (Iterator<Entry<UUID, Interval>> iterator =
|
||||
feedRunnable.entrySet().iterator(); iterator.hasNext(); ) {
|
||||
Entry<UUID, Interval> entry = iterator.next();
|
||||
Interval value = entry.getValue();
|
||||
++value.count;
|
||||
if (value.count == value.interval) {
|
||||
value.count = 0;
|
||||
Player player = Bukkit.getPlayer(entry.getKey());
|
||||
if (player == null) {
|
||||
iterator.remove();
|
||||
continue;
|
||||
}
|
||||
int level = player.getFoodLevel();
|
||||
if (level != value.max) {
|
||||
player.setFoodLevel(Math.min(level + value.amount, value.max));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 0L, 20L);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH) public void onInteract(BlockDamageEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
if (player.getGameMode() != GameMode.SURVIVAL) {
|
||||
return;
|
||||
}
|
||||
Plot plot = BukkitUtil.getLocation(player).getOwnedPlot();
|
||||
if (plot == null) {
|
||||
return;
|
||||
}
|
||||
if (Flags.INSTABREAK.isTrue(plot)) {
|
||||
Block block = event.getBlock();
|
||||
BlockBreakEvent call = new BlockBreakEvent(block, player);
|
||||
Bukkit.getServer().getPluginManager().callEvent(call);
|
||||
if (!call.isCancelled()) {
|
||||
event.getBlock().breakNaturally();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH) public void onDamage(EntityDamageEvent event) {
|
||||
if (event.getEntityType() != EntityType.PLAYER) {
|
||||
return;
|
||||
}
|
||||
Plot plot = BukkitUtil.getLocation(event.getEntity()).getOwnedPlot();
|
||||
if (plot == null) {
|
||||
return;
|
||||
}
|
||||
if (Flags.INVINCIBLE.isTrue(plot)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler public void onItemDrop(PlayerDropItemEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
PlotPlayer pp = BukkitUtil.getPlayer(player);
|
||||
Plot plot = BukkitUtil.getLocation(player).getOwnedPlot();
|
||||
if (plot == null) {
|
||||
return;
|
||||
}
|
||||
UUID uuid = pp.getUUID();
|
||||
if (!plot.isAdded(uuid)) {
|
||||
if (Flags.ITEM_DROP.isFalse(plot)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler public void onPlotEnter(PlayerEnterPlotEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
Plot plot = event.getPlot();
|
||||
Optional<IntervalFlag.Interval> feed = plot.getFlag(Flags.FEED);
|
||||
feed.ifPresent(value -> feedRunnable
|
||||
.put(player.getUniqueId(), new Interval(value.getVal1(), value.getVal2(), 20)));
|
||||
Optional<IntervalFlag.Interval> heal = plot.getFlag(Flags.HEAL);
|
||||
heal.ifPresent(value -> healRunnable
|
||||
.put(player.getUniqueId(), new Interval(value.getVal1(), value.getVal2(), 20)));
|
||||
}
|
||||
|
||||
@EventHandler public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
feedRunnable.remove(player.getUniqueId());
|
||||
healRunnable.remove(player.getUniqueId());
|
||||
}
|
||||
|
||||
@EventHandler public void onPlotLeave(PlayerLeavePlotEvent event) {
|
||||
Player leaver = event.getPlayer();
|
||||
Plot plot = event.getPlot();
|
||||
if (!plot.hasOwner()) {
|
||||
return;
|
||||
}
|
||||
BukkitUtil.getPlayer(leaver);
|
||||
feedRunnable.remove(leaver.getUniqueId());
|
||||
healRunnable.remove(leaver.getUniqueId());
|
||||
}
|
||||
|
||||
@EventHandler public void onItemPickup(EntityPickupItemEvent event) {
|
||||
LivingEntity ent = event.getEntity();
|
||||
if (ent instanceof Player) {
|
||||
Player player = (Player) ent;
|
||||
PlotPlayer pp = BukkitUtil.getPlayer(player);
|
||||
Plot plot = BukkitUtil.getLocation(player).getOwnedPlot();
|
||||
if (plot == null) {
|
||||
return;
|
||||
}
|
||||
UUID uuid = pp.getUUID();
|
||||
if (!plot.isAdded(uuid) && Flags.DROP_PROTECTION.isTrue(plot)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class Interval {
|
||||
|
||||
final int interval;
|
||||
final int amount;
|
||||
final int max;
|
||||
int count = 0;
|
||||
|
||||
Interval(int interval, int amount, int max) {
|
||||
this.interval = interval;
|
||||
this.amount = amount;
|
||||
this.max = max;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.listeners;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.plot.PlotSquared;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.worlds.PlotAreaManager;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.worlds.SinglePlotAreaManager;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.world.ChunkEvent;
|
||||
import org.bukkit.event.world.ChunkLoadEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.getRefClass;
|
||||
|
||||
@SuppressWarnings("unused") public class SingleWorldListener implements Listener {
|
||||
|
||||
private Method methodGetHandleChunk;
|
||||
private Field mustSave;
|
||||
|
||||
public SingleWorldListener(Plugin plugin) throws Exception {
|
||||
ReflectionUtils.RefClass classChunk = getRefClass("{nms}.Chunk");
|
||||
ReflectionUtils.RefClass classCraftChunk = getRefClass("{cb}.CraftChunk");
|
||||
this.methodGetHandleChunk = classCraftChunk.getMethod("getHandle").getRealMethod();
|
||||
try {
|
||||
this.mustSave = classChunk.getField("mustSave").getRealField();
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
}
|
||||
|
||||
public void markChunkAsClean(Chunk chunk) {
|
||||
try {
|
||||
Object nmsChunk = methodGetHandleChunk.invoke(chunk);
|
||||
if (mustSave != null) {
|
||||
this.mustSave.set(nmsChunk, false);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void handle(ChunkEvent event) {
|
||||
World world = event.getWorld();
|
||||
String name = world.getName();
|
||||
PlotAreaManager man = PlotSquared.get().getPlotAreaManager();
|
||||
if (!(man instanceof SinglePlotAreaManager)) {
|
||||
return;
|
||||
}
|
||||
if (!isPlotId(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
markChunkAsClean(event.getChunk());
|
||||
}
|
||||
|
||||
// @EventHandler
|
||||
// public void onPopulate(ChunkPopulateEvent event) {
|
||||
// handle(event);
|
||||
// }
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST) public void onChunkLoad(ChunkLoadEvent event) {
|
||||
handle(event);
|
||||
}
|
||||
|
||||
private boolean isPlotId(String worldName) {
|
||||
int len = worldName.length();
|
||||
int separator = 0;
|
||||
for (int i = 0; i < len; i++) {
|
||||
switch (worldName.charAt(i)) {
|
||||
case ',':
|
||||
case ';':
|
||||
separator++;
|
||||
break;
|
||||
case '-':
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return separator == 1;
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.listeners;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.bukkit.generator.BukkitPlotGenerator;
|
||||
import com.github.intellectualsites.plotsquared.plot.PlotSquared;
|
||||
import com.github.intellectualsites.plotsquared.plot.generator.GeneratorWrapper;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.worlds.PlotAreaManager;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.worlds.SinglePlotAreaManager;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.world.WorldInitEvent;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class WorldEvents implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onWorldInit(WorldInitEvent event) {
|
||||
World world = event.getWorld();
|
||||
String name = world.getName();
|
||||
PlotAreaManager manager = PlotSquared.get().getPlotAreaManager();
|
||||
if (manager instanceof SinglePlotAreaManager) {
|
||||
SinglePlotAreaManager single = (SinglePlotAreaManager) manager;
|
||||
if (single.isWorld(name)) {
|
||||
world.setKeepSpawnInMemory(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ChunkGenerator gen = world.getGenerator();
|
||||
if (gen instanceof GeneratorWrapper) {
|
||||
PlotSquared.get().loadWorld(name, (GeneratorWrapper<?>) gen);
|
||||
} else {
|
||||
PlotSquared.get().loadWorld(name, new BukkitPlotGenerator(name, gen));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.object;
|
||||
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.item.ItemType;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class BukkitBlockUtil {
|
||||
public static Supplier<ItemType> supplyItem(Block block) {
|
||||
return new Supplier<ItemType>() {
|
||||
@Override public ItemType get() {
|
||||
return BukkitAdapter.asItemType(block.getType());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static Supplier<ItemType> supplyItem(Material type) {
|
||||
return () -> BukkitAdapter.asItemType(type);
|
||||
}
|
||||
|
||||
public static BlockState get(Block block) {
|
||||
return get(block.getType());
|
||||
}
|
||||
|
||||
public static BlockState get(Material material) {
|
||||
return BukkitAdapter.asBlockType(material).getDefaultState();
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.object;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.plot.object.OfflinePlotPlayer;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class BukkitOfflinePlayer implements OfflinePlotPlayer {
|
||||
|
||||
public final OfflinePlayer player;
|
||||
|
||||
/**
|
||||
* Please do not use this method. Instead use BukkitUtil.getPlayer(Player),
|
||||
* as it caches player objects.
|
||||
*
|
||||
* @param player
|
||||
*/
|
||||
public BukkitOfflinePlayer(OfflinePlayer player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
@NotNull @Override public UUID getUUID() {
|
||||
return this.player.getUniqueId();
|
||||
}
|
||||
|
||||
@Override public long getLastPlayed() {
|
||||
return this.player.getLastPlayed();
|
||||
}
|
||||
|
||||
@Override public boolean isOnline() {
|
||||
return this.player.isOnline();
|
||||
}
|
||||
|
||||
@Override public String getName() {
|
||||
return this.player.getName();
|
||||
}
|
||||
}
|
@ -1,314 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.object;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitEventUtil;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitUtil;
|
||||
import com.github.intellectualsites.plotsquared.plot.PlotSquared;
|
||||
import com.github.intellectualsites.plotsquared.plot.config.Captions;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Location;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.TeleportCause;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.EconHandler;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.EventUtil;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.MathMan;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.PlotWeather;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.StringMan;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.UUIDHandler;
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.world.item.ItemType;
|
||||
import com.sk89q.worldedit.world.item.ItemTypes;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.WeatherType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.EventException;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||
import org.bukkit.plugin.RegisteredListener;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.sk89q.worldedit.world.gamemode.GameModes.ADVENTURE;
|
||||
import static com.sk89q.worldedit.world.gamemode.GameModes.CREATIVE;
|
||||
import static com.sk89q.worldedit.world.gamemode.GameModes.SPECTATOR;
|
||||
import static com.sk89q.worldedit.world.gamemode.GameModes.SURVIVAL;
|
||||
|
||||
public class BukkitPlayer extends PlotPlayer {
|
||||
|
||||
private static boolean CHECK_EFFECTIVE = true;
|
||||
public final Player player;
|
||||
private boolean offline;
|
||||
private UUID uuid;
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* <p>Please do not use this method. Instead use
|
||||
* BukkitUtil.getPlayer(Player), as it caches player objects.</p>
|
||||
*
|
||||
* @param player Bukkit player instance
|
||||
*/
|
||||
public BukkitPlayer(@NotNull final Player player) {
|
||||
this.player = player;
|
||||
super.populatePersistentMetaMap();
|
||||
}
|
||||
|
||||
public BukkitPlayer(@NotNull final Player player, final boolean offline) {
|
||||
this.player = player;
|
||||
this.offline = offline;
|
||||
super.populatePersistentMetaMap();
|
||||
}
|
||||
|
||||
@Override public Actor toActor() {
|
||||
return BukkitAdapter.adapt(player);
|
||||
}
|
||||
|
||||
@NotNull @Override public Location getLocation() {
|
||||
final Location location = super.getLocation();
|
||||
return location == null ? BukkitUtil.getLocation(this.player) : location;
|
||||
}
|
||||
|
||||
@NotNull @Override public UUID getUUID() {
|
||||
if (this.uuid == null) {
|
||||
this.uuid = UUIDHandler.getUUID(this);
|
||||
}
|
||||
return this.uuid;
|
||||
}
|
||||
|
||||
@Override public long getLastPlayed() {
|
||||
return this.player.getLastPlayed();
|
||||
}
|
||||
|
||||
@Override public boolean canTeleport(@NotNull final Location location) {
|
||||
final org.bukkit.Location to = BukkitUtil.getLocation(location);
|
||||
final org.bukkit.Location from = player.getLocation();
|
||||
PlayerTeleportEvent event = new PlayerTeleportEvent(player, from, to);
|
||||
callEvent(event);
|
||||
if (event.isCancelled() || !event.getTo().equals(to)) {
|
||||
return false;
|
||||
}
|
||||
event = new PlayerTeleportEvent(player, to, from);
|
||||
callEvent(event);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendTitle(String title, String subtitle, int fadeIn, int stay, int fadeOut) {
|
||||
player.sendTitle(title, subtitle, fadeIn, stay, fadeOut);
|
||||
}
|
||||
|
||||
private void callEvent(@NotNull final Event event) {
|
||||
final RegisteredListener[] listeners = event.getHandlers().getRegisteredListeners();
|
||||
for (final RegisteredListener listener : listeners) {
|
||||
if (listener.getPlugin().getName().equals(PlotSquared.imp().getPluginName())) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
listener.callEvent(event);
|
||||
} catch (final EventException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override public boolean hasPermission(final String permission) {
|
||||
if (this.offline && EconHandler.manager != null) {
|
||||
return EconHandler.manager.hasPermission(getName(), permission);
|
||||
}
|
||||
return this.player.hasPermission(permission);
|
||||
}
|
||||
|
||||
@Override public int hasPermissionRange(final String stub, final int range) {
|
||||
if (hasPermission(Captions.PERMISSION_ADMIN.getTranslated())) {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
final String[] nodes = stub.split("\\.");
|
||||
final StringBuilder n = new StringBuilder();
|
||||
for (int i = 0; i < (nodes.length - 1); i++) {
|
||||
n.append(nodes[i]).append(".");
|
||||
if (!stub.equals(n + Captions.PERMISSION_STAR.getTranslated())) {
|
||||
if (hasPermission(n + Captions.PERMISSION_STAR.getTranslated())) {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hasPermission(stub + ".*")) {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
int max = 0;
|
||||
if (CHECK_EFFECTIVE) {
|
||||
boolean hasAny = false;
|
||||
String stubPlus = stub + ".";
|
||||
final Set<PermissionAttachmentInfo> effective = player.getEffectivePermissions();
|
||||
if (!effective.isEmpty()) {
|
||||
for (PermissionAttachmentInfo attach : effective) {
|
||||
String permStr = attach.getPermission();
|
||||
if (permStr.startsWith(stubPlus)) {
|
||||
hasAny = true;
|
||||
String end = permStr.substring(stubPlus.length());
|
||||
if (MathMan.isInteger(end)) {
|
||||
int val = Integer.parseInt(end);
|
||||
if (val > range) {
|
||||
return val;
|
||||
}
|
||||
if (val > max) {
|
||||
max = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hasAny) {
|
||||
return max;
|
||||
}
|
||||
// Workaround
|
||||
for (PermissionAttachmentInfo attach : effective) {
|
||||
String permStr = attach.getPermission();
|
||||
if (permStr.startsWith("plots.") && !permStr.equals("plots.use")) {
|
||||
return max;
|
||||
}
|
||||
}
|
||||
CHECK_EFFECTIVE = false;
|
||||
}
|
||||
}
|
||||
for (int i = range; i > 0; i--) {
|
||||
if (hasPermission(stub + "." + i)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
@Override public boolean isPermissionSet(final String permission) {
|
||||
return this.player.isPermissionSet(permission);
|
||||
}
|
||||
|
||||
@Override public void sendMessage(final String message) {
|
||||
if (!StringMan.isEqual(this.getMeta("lastMessage"), message) || (
|
||||
System.currentTimeMillis() - this.<Long>getMeta("lastMessageTime") > 5000)) {
|
||||
setMeta("lastMessage", message);
|
||||
setMeta("lastMessageTime", System.currentTimeMillis());
|
||||
this.player.sendMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void teleport(@NotNull final Location location, @NotNull final TeleportCause cause) {
|
||||
if (Math.abs(location.getX()) >= 30000000 || Math.abs(location.getZ()) >= 30000000) {
|
||||
return;
|
||||
}
|
||||
final org.bukkit.Location bukkitLocation = new org.bukkit.Location(BukkitUtil.getWorld(location.getWorld()), location.getX() + 0.5,
|
||||
location.getY(), location.getZ() + 0.5, location.getYaw(), location.getPitch());
|
||||
PaperLib.teleportAsync(player, bukkitLocation, ((BukkitEventUtil) EventUtil.manager).getTeleportCause(cause));
|
||||
}
|
||||
|
||||
@Override public String getName() {
|
||||
if (this.name == null) {
|
||||
this.name = this.player.getName();
|
||||
}
|
||||
return this.name;
|
||||
}
|
||||
|
||||
@Override public boolean isOnline() {
|
||||
return !this.offline && this.player.isOnline();
|
||||
}
|
||||
|
||||
@Override public void setCompassTarget(Location location) {
|
||||
this.player.setCompassTarget(
|
||||
new org.bukkit.Location(BukkitUtil.getWorld(location.getWorld()), location.getX(),
|
||||
location.getY(), location.getZ()));
|
||||
}
|
||||
|
||||
@Override public Location getLocationFull() {
|
||||
return BukkitUtil.getLocationFull(this.player);
|
||||
}
|
||||
|
||||
@Override public void setWeather(@NotNull final PlotWeather weather) {
|
||||
switch (weather) {
|
||||
case CLEAR:
|
||||
this.player.setPlayerWeather(WeatherType.CLEAR);
|
||||
break;
|
||||
case RAIN:
|
||||
this.player.setPlayerWeather(WeatherType.DOWNFALL);
|
||||
break;
|
||||
case RESET:
|
||||
default:
|
||||
this.player.resetPlayerWeather();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull @Override public com.sk89q.worldedit.world.gamemode.GameMode getGameMode() {
|
||||
switch (this.player.getGameMode()) {
|
||||
case ADVENTURE:
|
||||
return ADVENTURE;
|
||||
case CREATIVE:
|
||||
return CREATIVE;
|
||||
case SPECTATOR:
|
||||
return SPECTATOR;
|
||||
case SURVIVAL:
|
||||
default:
|
||||
return SURVIVAL;
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void setGameMode(@NotNull final com.sk89q.worldedit.world.gamemode.GameMode gameMode) {
|
||||
if (ADVENTURE.equals(gameMode)) {
|
||||
this.player.setGameMode(GameMode.ADVENTURE);
|
||||
} else if (CREATIVE.equals(gameMode)) {
|
||||
this.player.setGameMode(GameMode.CREATIVE);
|
||||
} else if (SPECTATOR.equals(gameMode)) {
|
||||
this.player.setGameMode(GameMode.SPECTATOR);
|
||||
} else {
|
||||
this.player.setGameMode(GameMode.SURVIVAL);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void setTime(final long time) {
|
||||
if (time != Long.MAX_VALUE) {
|
||||
this.player.setPlayerTime(time, false);
|
||||
} else {
|
||||
this.player.resetPlayerTime();
|
||||
}
|
||||
}
|
||||
|
||||
@Override public boolean getFlight() {
|
||||
return player.getAllowFlight();
|
||||
}
|
||||
|
||||
@Override public void setFlight(boolean fly) {
|
||||
this.player.setAllowFlight(fly);
|
||||
}
|
||||
|
||||
@Override public void playMusic(@NotNull final Location location, @NotNull final ItemType id) {
|
||||
if (id == ItemTypes.AIR) {
|
||||
// Let's just stop all the discs because why not?
|
||||
for (final Sound sound : Arrays.stream(Sound.values())
|
||||
.filter(sound -> sound.name().contains("DISC")).collect(Collectors.toList())) {
|
||||
player.stopSound(sound);
|
||||
}
|
||||
// this.player.playEffect(BukkitUtil.getLocation(location), Effect.RECORD_PLAY, Material.AIR);
|
||||
} else {
|
||||
// this.player.playEffect(BukkitUtil.getLocation(location), Effect.RECORD_PLAY, id.to(Material.class));
|
||||
this.player.playSound(BukkitUtil.getLocation(location),
|
||||
Sound.valueOf(BukkitAdapter.adapt(id).name()), Float.MAX_VALUE, 1f);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void kick(final String message) {
|
||||
this.player.kickPlayer(message);
|
||||
}
|
||||
|
||||
@Override public void stopSpectating() {
|
||||
if (getGameMode() == SPECTATOR) {
|
||||
this.player.setSpectatorTarget(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public boolean isBanned() {
|
||||
return this.player.isBanned();
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.object.entity;
|
||||
|
||||
class AgeableStats {
|
||||
|
||||
int age;
|
||||
boolean locked;
|
||||
boolean adult;
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.object.entity;
|
||||
|
||||
class ArmorStandStats {
|
||||
|
||||
final float[] head = new float[3];
|
||||
final float[] body = new float[3];
|
||||
final float[] leftLeg = new float[3];
|
||||
final float[] rightLeg = new float[3];
|
||||
final float[] leftArm = new float[3];
|
||||
final float[] rightArm = new float[3];
|
||||
boolean arms;
|
||||
boolean noPlate;
|
||||
boolean invisible;
|
||||
boolean small;
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.object.entity;
|
||||
|
||||
class EntityBaseStats {
|
||||
|
||||
EntityWrapper passenger;
|
||||
float fall;
|
||||
short fire;
|
||||
int age;
|
||||
double vZ;
|
||||
double vY;
|
||||
double vX;
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.object.entity;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
@Getter public abstract class EntityWrapper {
|
||||
|
||||
protected final float yaw;
|
||||
protected final float pitch;
|
||||
private final Entity entity;
|
||||
private final EntityType type;
|
||||
public double x;
|
||||
public double y;
|
||||
public double z;
|
||||
|
||||
EntityWrapper(@NonNull final Entity entity) {
|
||||
this.entity = entity;
|
||||
this.type = entity.getType();
|
||||
|
||||
final Location location = entity.getLocation();
|
||||
this.x = location.getX();
|
||||
this.y = location.getY();
|
||||
this.z = location.getZ();
|
||||
this.yaw = location.getYaw();
|
||||
this.pitch = location.getPitch();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation") @Override public String toString() {
|
||||
return String.format("[%s, x=%s, y=%s, z=%s]", type.getName(), x, y, z);
|
||||
}
|
||||
|
||||
public abstract Entity spawn(World world, int xOffset, int zOffset);
|
||||
|
||||
public abstract void saveEntity();
|
||||
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.object.entity;
|
||||
|
||||
import org.bukkit.entity.Horse;
|
||||
|
||||
class HorseStats {
|
||||
|
||||
double jump;
|
||||
boolean chest;
|
||||
Horse.Variant variant;
|
||||
Horse.Color color;
|
||||
Horse.Style style;
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.object.entity;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
class LivingEntityStats {
|
||||
|
||||
boolean loot;
|
||||
String name;
|
||||
boolean visible;
|
||||
float health;
|
||||
short air;
|
||||
boolean persistent;
|
||||
boolean leashed;
|
||||
short leashX;
|
||||
short leashY;
|
||||
short leashZ;
|
||||
boolean equipped;
|
||||
ItemStack mainHand;
|
||||
ItemStack helmet;
|
||||
ItemStack boots;
|
||||
ItemStack leggings;
|
||||
ItemStack chestplate;
|
||||
Collection<PotionEffect> potions;
|
||||
ItemStack offHand;
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.object.entity;
|
||||
|
||||
import org.bukkit.entity.AnimalTamer;
|
||||
|
||||
class TameableStats {
|
||||
|
||||
AnimalTamer owner;
|
||||
boolean tamed;
|
||||
}
|
@ -1,265 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.object.schematic;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitUtil;
|
||||
import com.github.intellectualsites.plotsquared.plot.PlotSquared;
|
||||
import com.github.intellectualsites.plotsquared.plot.config.Captions;
|
||||
import com.sk89q.jnbt.ByteTag;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.ShortTag;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Container;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class StateWrapper {
|
||||
|
||||
public org.bukkit.block.BlockState state = null;
|
||||
public CompoundTag tag = null;
|
||||
|
||||
public StateWrapper(org.bukkit.block.BlockState state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public StateWrapper(CompoundTag tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
public static String jsonToColourCode(String str) {
|
||||
str = str.replace("{\"extra\":", "").replace("],\"text\":\"\"}", "]")
|
||||
.replace("[{\"color\":\"black\",\"text\":\"", "&0")
|
||||
.replace("[{\"color\":\"dark_blue\",\"text\":\"", "&1")
|
||||
.replace("[{\"color\":\"dark_green\",\"text\":\"", "&2")
|
||||
.replace("[{\"color\":\"dark_aqua\",\"text\":\"", "&3")
|
||||
.replace("[{\"color\":\"dark_red\",\"text\":\"", "&4")
|
||||
.replace("[{\"color\":\"dark_purple\",\"text\":\"", "&5")
|
||||
.replace("[{\"color\":\"gold\",\"text\":\"", "&6")
|
||||
.replace("[{\"color\":\"gray\",\"text\":\"", "&7")
|
||||
.replace("[{\"color\":\"dark_gray\",\"text\":\"", "&8")
|
||||
.replace("[{\"color\":\"blue\",\"text\":\"", "&9")
|
||||
.replace("[{\"color\":\"green\",\"text\":\"", "&a")
|
||||
.replace("[{\"color\":\"aqua\",\"text\":\"", "&b")
|
||||
.replace("[{\"color\":\"red\",\"text\":\"", "&c")
|
||||
.replace("[{\"color\":\"light_purple\",\"text\":\"", "&d")
|
||||
.replace("[{\"color\":\"yellow\",\"text\":\"", "&e")
|
||||
.replace("[{\"color\":\"white\",\"text\":\"", "&f")
|
||||
.replace("[{\"obfuscated\":true,\"text\":\"", "&k")
|
||||
.replace("[{\"bold\":true,\"text\":\"", "&l")
|
||||
.replace("[{\"strikethrough\":true,\"text\":\"", "&m")
|
||||
.replace("[{\"underlined\":true,\"text\":\"", "&n")
|
||||
.replace("[{\"italic\":true,\"text\":\"", "&o").replace("[{\"color\":\"black\",", "&0")
|
||||
.replace("[{\"color\":\"dark_blue\",", "&1")
|
||||
.replace("[{\"color\":\"dark_green\",", "&2")
|
||||
.replace("[{\"color\":\"dark_aqua\",", "&3").replace("[{\"color\":\"dark_red\",", "&4")
|
||||
.replace("[{\"color\":\"dark_purple\",", "&5").replace("[{\"color\":\"gold\",", "&6")
|
||||
.replace("[{\"color\":\"gray\",", "&7").replace("[{\"color\":\"dark_gray\",", "&8")
|
||||
.replace("[{\"color\":\"blue\",", "&9").replace("[{\"color\":\"green\",", "&a")
|
||||
.replace("[{\"color\":\"aqua\",", "&b").replace("[{\"color\":\"red\",", "&c")
|
||||
.replace("[{\"color\":\"light_purple\",", "&d").replace("[{\"color\":\"yellow\",", "&e")
|
||||
.replace("[{\"color\":\"white\",", "&f").replace("[{\"obfuscated\":true,", "&k")
|
||||
.replace("[{\"bold\":true,", "&l").replace("[{\"strikethrough\":true,", "&m")
|
||||
.replace("[{\"underlined\":true,", "&n").replace("[{\"italic\":true,", "&o")
|
||||
.replace("{\"color\":\"black\",\"text\":\"", "&0")
|
||||
.replace("{\"color\":\"dark_blue\",\"text\":\"", "&1")
|
||||
.replace("{\"color\":\"dark_green\",\"text\":\"", "&2")
|
||||
.replace("{\"color\":\"dark_aqua\",\"text\":\"", "&3")
|
||||
.replace("{\"color\":\"dark_red\",\"text\":\"", "&4")
|
||||
.replace("{\"color\":\"dark_purple\",\"text\":\"", "&5")
|
||||
.replace("{\"color\":\"gold\",\"text\":\"", "&6")
|
||||
.replace("{\"color\":\"gray\",\"text\":\"", "&7")
|
||||
.replace("{\"color\":\"dark_gray\",\"text\":\"", "&8")
|
||||
.replace("{\"color\":\"blue\",\"text\":\"", "&9")
|
||||
.replace("{\"color\":\"green\",\"text\":\"", "&a")
|
||||
.replace("{\"color\":\"aqua\",\"text\":\"", "&b")
|
||||
.replace("{\"color\":\"red\",\"text\":\"", "&c")
|
||||
.replace("{\"color\":\"light_purple\",\"text\":\"", "&d")
|
||||
.replace("{\"color\":\"yellow\",\"text\":\"", "&e")
|
||||
.replace("{\"color\":\"white\",\"text\":\"", "&f")
|
||||
.replace("{\"obfuscated\":true,\"text\":\"", "&k")
|
||||
.replace("{\"bold\":true,\"text\":\"", "&l")
|
||||
.replace("{\"strikethrough\":true,\"text\":\"", "&m")
|
||||
.replace("{\"underlined\":true,\"text\":\"", "&n")
|
||||
.replace("{\"italic\":true,\"text\":\"", "&o").replace("{\"color\":\"black\",", "&0")
|
||||
.replace("{\"color\":\"dark_blue\",", "&1").replace("{\"color\":\"dark_green\",", "&2")
|
||||
.replace("{\"color\":\"dark_aqua\",", "&3").replace("{\"color\":\"dark_red\",", "&4")
|
||||
.replace("{\"color\":\"dark_purple\",", "&5").replace("{\"color\":\"gold\",", "&6")
|
||||
.replace("{\"color\":\"gray\",", "&7").replace("{\"color\":\"dark_gray\",", "&8")
|
||||
.replace("{\"color\":\"blue\",", "&9").replace("{\"color\":\"green\",", "&a")
|
||||
.replace("{\"color\":\"aqua\",", "&b").replace("{\"color\":\"red\",", "&c")
|
||||
.replace("{\"color\":\"light_purple\",", "&d").replace("{\"color\":\"yellow\",", "&e")
|
||||
.replace("{\"color\":\"white\",", "&f").replace("{\"obfuscated\":true,", "&k")
|
||||
.replace("{\"bold\":true,", "&l").replace("{\"strikethrough\":true,", "&m")
|
||||
.replace("{\"underlined\":true,", "&n").replace("{\"italic\":true,", "&o")
|
||||
.replace("\"color\":\"black\",\"text\":\"", "&0")
|
||||
.replace("\"color\":\"dark_blue\",\"text\":\"", "&1")
|
||||
.replace("\"color\":\"dark_green\",\"text\":\"", "&2")
|
||||
.replace("\"color\":\"dark_aqua\",\"text\":\"", "&3")
|
||||
.replace("\"color\":\"dark_red\",\"text\":\"", "&4")
|
||||
.replace("\"color\":\"dark_purple\",\"text\":\"", "&5")
|
||||
.replace("\"color\":\"gold\",\"text\":\"", "&6")
|
||||
.replace("\"color\":\"gray\",\"text\":\"", "&7")
|
||||
.replace("\"color\":\"dark_gray\",\"text\":\"", "&8")
|
||||
.replace("\"color\":\"blue\",\"text\":\"", "&9")
|
||||
.replace("\"color\":\"green\",\"text\":\"", "&a")
|
||||
.replace("\"color\":\"aqua\",\"text\":\"", "&b")
|
||||
.replace("\"color\":\"red\",\"text\":\"", "&c")
|
||||
.replace("\"color\":\"light_purple\",\"text\":\"", "&d")
|
||||
.replace("\"color\":\"yellow\",\"text\":\"", "&e")
|
||||
.replace("\"color\":\"white\",\"text\":\"", "&f")
|
||||
.replace("\"obfuscated\":true,\"text\":\"", "&k")
|
||||
.replace("\"bold\":true,\"text\":\"", "&l")
|
||||
.replace("\"strikethrough\":true,\"text\":\"", "&m")
|
||||
.replace("\"underlined\":true,\"text\":\"", "&n")
|
||||
.replace("\"italic\":true,\"text\":\"", "&o").replace("\"color\":\"black\",", "&0")
|
||||
.replace("\"color\":\"dark_blue\",", "&1").replace("\"color\":\"dark_green\",", "&2")
|
||||
.replace("\"color\":\"dark_aqua\",", "&3").replace("\"color\":\"dark_red\",", "&4")
|
||||
.replace("\"color\":\"dark_purple\",", "&5").replace("\"color\":\"gold\",", "&6")
|
||||
.replace("\"color\":\"gray\",", "&7").replace("\"color\":\"dark_gray\",", "&8")
|
||||
.replace("\"color\":\"blue\",", "&9").replace("\"color\":\"green\",", "&a")
|
||||
.replace("\"color\":\"aqua\",", "&b").replace("\"color\":\"red\",", "&c")
|
||||
.replace("\"color\":\"light_purple\",", "&d").replace("\"color\":\"yellow\",", "&e")
|
||||
.replace("\"color\":\"white\",", "&f").replace("\"obfuscated\":true,", "&k")
|
||||
.replace("\"bold\":true,", "&l").replace("\"strikethrough\":true,", "&m")
|
||||
.replace("\"underlined\":true,", "&n").replace("\"italic\":true,", "&o")
|
||||
.replace("[{\"text\":\"", "&0").replace("{\"text\":\"", "&0").replace("\"},", "")
|
||||
.replace("\"}]", "").replace("\"}", "");
|
||||
for (Entry<String, String> entry : Captions.replacements.entrySet()) {
|
||||
str = str.replace(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
public boolean restoreTag(String worldName, int x, int y, int z) {
|
||||
if (this.tag == null) {
|
||||
return false;
|
||||
}
|
||||
String tileid = this.tag.getString("id").toLowerCase();
|
||||
if (tileid.startsWith("minecraft:")) {
|
||||
tileid = tileid.replace("minecraft:", "");
|
||||
}
|
||||
World world = BukkitUtil.getWorld(worldName);
|
||||
Block block = world.getBlockAt(x, y, z);
|
||||
if (block == null) {
|
||||
return false;
|
||||
}
|
||||
org.bukkit.block.BlockState state = block.getState();
|
||||
switch (tileid) {
|
||||
case "chest":
|
||||
case "beacon":
|
||||
case "brewingstand":
|
||||
case "dispenser":
|
||||
case "dropper":
|
||||
case "furnace":
|
||||
case "hopper":
|
||||
case "shulkerbox":
|
||||
List<Tag> itemsTag = this.tag.getListTag("Items").getValue();
|
||||
int length = itemsTag.size();
|
||||
String[] ids = new String[length];
|
||||
byte[] amounts = new byte[length];
|
||||
byte[] slots = new byte[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
Tag itemTag = itemsTag.get(i);
|
||||
CompoundTag itemComp = (CompoundTag) itemTag;
|
||||
String id = itemComp.getString("id");
|
||||
if (id.startsWith("minecraft:")) {
|
||||
id = id.replace("minecraft:", "");
|
||||
}
|
||||
ids[i] = id;
|
||||
amounts[i] = itemComp.getByte("Count");
|
||||
slots[i] = itemComp.getByte("Slot");
|
||||
}
|
||||
if (state instanceof Container) {
|
||||
Container container = (Container) state;
|
||||
Inventory inv = container.getSnapshotInventory();
|
||||
for (int i = 0; i < ids.length; i++) {
|
||||
Material mat = Material.getMaterial(ids[i].toUpperCase());
|
||||
if (mat != null) {
|
||||
ItemStack item = new ItemStack(mat, (int) amounts[i]);
|
||||
inv.setItem(slots[i], item);
|
||||
PlotSquared.log(mat.name() + " " + slots[i]);
|
||||
}
|
||||
}
|
||||
PlotSquared.log(inv.getStorageContents());
|
||||
container.update(true, true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case "sign":
|
||||
if (state instanceof Sign) {
|
||||
Sign sign = (Sign) state;
|
||||
sign.setLine(0, jsonToColourCode(tag.getString("Text1")));
|
||||
sign.setLine(1, jsonToColourCode(tag.getString("Text2")));
|
||||
sign.setLine(2, jsonToColourCode(tag.getString("Text3")));
|
||||
sign.setLine(3, jsonToColourCode(tag.getString("Text4")));
|
||||
state.update(true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public CompoundTag getTag() {
|
||||
if (this.tag != null) {
|
||||
return this.tag;
|
||||
}
|
||||
if (this.state instanceof InventoryHolder) {
|
||||
InventoryHolder inv = (InventoryHolder) this.state;
|
||||
ItemStack[] contents = inv.getInventory().getContents();
|
||||
Map<String, Tag> values = new HashMap<>();
|
||||
values.put("Items", new ListTag(CompoundTag.class, serializeInventory(contents)));
|
||||
return new CompoundTag(values);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return "Chest";
|
||||
}
|
||||
|
||||
public List<CompoundTag> serializeInventory(ItemStack[] items) {
|
||||
List<CompoundTag> tags = new ArrayList<>();
|
||||
for (int i = 0; i < items.length; ++i) {
|
||||
if (items[i] != null) {
|
||||
Map<String, Tag> tagData = serializeItem(items[i]);
|
||||
tagData.put("Slot", new ByteTag((byte) i));
|
||||
tags.add(new CompoundTag(tagData));
|
||||
}
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
|
||||
public Map<String, Tag> serializeItem(ItemStack item) {
|
||||
Map<String, Tag> data = new HashMap<>();
|
||||
data.put("id", new StringTag(item.getType().name()));
|
||||
data.put("Damage", new ShortTag(item.getDurability()));
|
||||
data.put("Count", new ByteTag((byte) item.getAmount()));
|
||||
if (!item.getEnchantments().isEmpty()) {
|
||||
List<CompoundTag> enchantmentList = new ArrayList<>();
|
||||
for (Entry<Enchantment, Integer> entry : item.getEnchantments().entrySet()) {
|
||||
Map<String, Tag> enchantment = new HashMap<>();
|
||||
enchantment.put("id", new StringTag(entry.getKey().toString()));
|
||||
enchantment.put("lvl", new ShortTag(entry.getValue().shortValue()));
|
||||
enchantmentList.add(new CompoundTag(enchantment));
|
||||
}
|
||||
Map<String, Tag> auxData = new HashMap<>();
|
||||
auxData.put("ench", new ListTag(CompoundTag.class, enchantmentList));
|
||||
data.put("tag", new CompoundTag(auxData));
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.util;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.bukkit.chat.FancyMessage;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.object.BukkitPlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.config.Captions;
|
||||
import com.github.intellectualsites.plotsquared.plot.config.Settings;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.ConsolePlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotMessage;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.ChatManager;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class BukkitChatManager extends ChatManager<FancyMessage> {
|
||||
|
||||
@Override public FancyMessage builder() {
|
||||
return new FancyMessage("");
|
||||
}
|
||||
|
||||
@Override public void color(PlotMessage message, String color) {
|
||||
message.$(this).color(ChatColor.getByChar(Captions.color(color).substring(1)));
|
||||
}
|
||||
|
||||
@Override public void tooltip(PlotMessage message, PlotMessage... tooltips) {
|
||||
List<FancyMessage> lines =
|
||||
Arrays.stream(tooltips).map(tooltip -> tooltip.$(this)).collect(Collectors.toList());
|
||||
message.$(this).formattedTooltip(lines);
|
||||
}
|
||||
|
||||
@Override public void command(PlotMessage message, String command) {
|
||||
message.$(this).command(command);
|
||||
}
|
||||
|
||||
@Override public void text(PlotMessage message, String text) {
|
||||
message.$(this).then(ChatColor.stripColor(text));
|
||||
}
|
||||
|
||||
@Override public void send(PlotMessage plotMessage, PlotPlayer player) {
|
||||
if (player instanceof ConsolePlayer || !Settings.Chat.INTERACTIVE) {
|
||||
player.sendMessage(plotMessage.$(this).toOldMessageFormat());
|
||||
} else {
|
||||
plotMessage.$(this).send(((BukkitPlayer) player).player);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void suggest(PlotMessage plotMessage, String command) {
|
||||
plotMessage.$(this).suggest(command);
|
||||
}
|
||||
|
||||
}
|
@ -1,701 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.util;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.bukkit.object.entity.EntityWrapper;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.object.entity.ReplicatingEntityWrapper;
|
||||
import com.github.intellectualsites.plotsquared.plot.PlotSquared;
|
||||
import com.github.intellectualsites.plotsquared.plot.generator.AugmentedUtils;
|
||||
import com.github.intellectualsites.plotsquared.plot.listener.WEExtent;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Location;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotArea;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotLoc;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.RunnableVal;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.ChunkManager;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.TaskManager;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.block.GlobalBlockQueue;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.block.ScopedLocalBlockQueue;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.world.RegionUtil;
|
||||
import com.sk89q.worldedit.bukkit.BukkitWorld;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.entity.Animals;
|
||||
import org.bukkit.entity.Creature;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
public class BukkitChunkManager extends ChunkManager {
|
||||
|
||||
public static boolean isIn(CuboidRegion region, int x, int z) {
|
||||
return x >= region.getMinimumPoint().getX() && x <= region.getMaximumPoint().getX() && z >= region.getMinimumPoint().getZ() && z <= region.getMaximumPoint().getZ();
|
||||
}
|
||||
|
||||
public static ContentMap swapChunk(World world1, World world2, Chunk pos1, Chunk pos2,
|
||||
CuboidRegion r1, CuboidRegion r2) {
|
||||
ContentMap map = new ContentMap();
|
||||
int relX = r2.getMinimumPoint().getX() - r1.getMinimumPoint().getX();
|
||||
int relZ = r2.getMinimumPoint().getZ() - r1.getMinimumPoint().getZ();
|
||||
|
||||
map.saveEntitiesIn(pos1, r1, relX, relZ, true);
|
||||
map.saveEntitiesIn(pos2, r2, -relX, -relZ, true);
|
||||
|
||||
int sx = pos1.getX() << 4;
|
||||
int sz = pos1.getZ() << 4;
|
||||
|
||||
String worldName1 = world1.getName();
|
||||
String worldName2 = world2.getName();
|
||||
|
||||
BukkitWorld bukkitWorld1 = new BukkitWorld(world1);
|
||||
BukkitWorld bukkitWorld2 = new BukkitWorld(world2);
|
||||
|
||||
LocalBlockQueue queue1 = GlobalBlockQueue.IMP.getNewQueue(worldName1, false);
|
||||
LocalBlockQueue queue2 = GlobalBlockQueue.IMP.getNewQueue(worldName2, false);
|
||||
|
||||
for (int x = Math.max(r1.getMinimumPoint().getX(), sx); x <= Math.min(r1.getMaximumPoint().getX(), sx + 15); x++) {
|
||||
for (int z = Math.max(r1.getMinimumPoint().getZ(), sz); z <= Math.min(r1.getMaximumPoint().getZ(), sz + 15); z++) {
|
||||
for (int y = 0; y < 256; y++) {
|
||||
Block block1 = world1.getBlockAt(x, y, z);
|
||||
BaseBlock baseBlock1 = bukkitWorld1.getFullBlock(BlockVector3.at(x, y, z));
|
||||
BlockData data1 = block1.getBlockData();
|
||||
|
||||
int xx = x + relX;
|
||||
int zz = z + relZ;
|
||||
|
||||
Block block2 = world2.getBlockAt(xx, y, zz);
|
||||
BaseBlock baseBlock2 = bukkitWorld2.getFullBlock(BlockVector3.at(xx, y, zz));
|
||||
BlockData data2 = block2.getBlockData();
|
||||
|
||||
if (block1.isEmpty()) {
|
||||
if (!block2.isEmpty()) {
|
||||
queue1.setBlock(x, y, z, baseBlock2);
|
||||
queue2.setBlock(xx, y, zz, WEExtent.AIRBASE);
|
||||
}
|
||||
} else if (block2.isEmpty()) {
|
||||
queue1.setBlock(x, y, z, WEExtent.AIRBASE);
|
||||
queue2.setBlock(xx, y, zz, baseBlock1);
|
||||
} else if (block1.equals(block2)) {
|
||||
if (!data1.matches(data2)) {
|
||||
block1.setBlockData(data2);
|
||||
block2.setBlockData(data1);
|
||||
}
|
||||
} else {
|
||||
queue1.setBlock(x, y, z, baseBlock2);
|
||||
queue2.setBlock(xx, y, zz, baseBlock1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
queue1.enqueue();
|
||||
queue2.enqueue();
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override public Set<BlockVector2> getChunkChunks(String world) {
|
||||
Set<BlockVector2> chunks = super.getChunkChunks(world);
|
||||
for (Chunk chunk : Objects.requireNonNull(Bukkit.getWorld(world)).getLoadedChunks()) {
|
||||
BlockVector2 loc = BlockVector2.at(chunk.getX() >> 5, chunk.getZ() >> 5);
|
||||
chunks.add(loc);
|
||||
}
|
||||
return chunks;
|
||||
}
|
||||
|
||||
@Override public int[] countEntities(Plot plot) {
|
||||
int[] existing = (int[]) plot.getMeta("EntityCount");
|
||||
if (existing != null && (System.currentTimeMillis() - (long) plot.getMeta("EntityCountTime")
|
||||
< 1000)) {
|
||||
return existing;
|
||||
}
|
||||
PlotArea area = plot.getArea();
|
||||
World world = BukkitUtil.getWorld(area.worldname);
|
||||
|
||||
Location bot = plot.getBottomAbs();
|
||||
Location top = plot.getTopAbs();
|
||||
int bx = bot.getX() >> 4;
|
||||
int bz = bot.getZ() >> 4;
|
||||
|
||||
int tx = top.getX() >> 4;
|
||||
int tz = top.getZ() >> 4;
|
||||
|
||||
int size = tx - bx << 4;
|
||||
|
||||
Set<Chunk> chunks = new HashSet<>();
|
||||
for (int X = bx; X <= tx; X++) {
|
||||
for (int Z = bz; Z <= tz; Z++) {
|
||||
if (world.isChunkLoaded(X, Z)) {
|
||||
chunks.add(world.getChunkAt(X, Z));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean doWhole = false;
|
||||
List<Entity> entities = null;
|
||||
if (size > 200 && chunks.size() > 200) {
|
||||
entities = world.getEntities();
|
||||
if (entities.size() < 16 + size / 8) {
|
||||
doWhole = true;
|
||||
}
|
||||
}
|
||||
|
||||
int[] count = new int[6];
|
||||
if (doWhole) {
|
||||
for (Entity entity : entities) {
|
||||
org.bukkit.Location location = entity.getLocation();
|
||||
PaperLib.getChunkAtAsync(location).thenAccept( chunk -> {
|
||||
if (chunks.contains(chunk)) {
|
||||
int X = chunk.getX();
|
||||
int Z = chunk.getZ();
|
||||
if (X > bx && X < tx && Z > bz && Z < tz) {
|
||||
count(count, entity);
|
||||
} else {
|
||||
Plot other = area.getPlot(BukkitUtil.getLocation(location));
|
||||
if (plot.equals(other)) {
|
||||
count(count, entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
for (Chunk chunk : chunks) {
|
||||
int X = chunk.getX();
|
||||
int Z = chunk.getZ();
|
||||
Entity[] entities1 = chunk.getEntities();
|
||||
for (Entity entity : entities1) {
|
||||
if (X == bx || X == tx || Z == bz || Z == tz) {
|
||||
Plot other = area.getPlot(BukkitUtil.getLocation(entity));
|
||||
if (plot.equals(other)) {
|
||||
count(count, entity);
|
||||
}
|
||||
} else {
|
||||
count(count, entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override public boolean copyRegion(Location pos1, Location pos2, Location newPos,
|
||||
final Runnable whenDone) {
|
||||
final int relX = newPos.getX() - pos1.getX();
|
||||
final int relZ = newPos.getZ() - pos1.getZ();
|
||||
|
||||
final CuboidRegion region =
|
||||
RegionUtil.createRegion(pos1.getX(), pos2.getX(), pos1.getZ(), pos2.getZ());
|
||||
final World oldWorld = Bukkit.getWorld(pos1.getWorld());
|
||||
final BukkitWorld oldBukkitWorld = new BukkitWorld(oldWorld);
|
||||
final World newWorld = Bukkit.getWorld(newPos.getWorld());
|
||||
assert newWorld != null;
|
||||
assert oldWorld != null;
|
||||
final String newWorldName = newWorld.getName();
|
||||
final ContentMap map = new ContentMap();
|
||||
final LocalBlockQueue queue = GlobalBlockQueue.IMP.getNewQueue(newWorldName, false);
|
||||
ChunkManager.chunkTask(pos1, pos2, new RunnableVal<int[]>() {
|
||||
@Override public void run(int[] value) {
|
||||
int bx = value[2];
|
||||
int bz = value[3];
|
||||
int tx = value[4];
|
||||
int tz = value[5];
|
||||
BlockVector2 loc = BlockVector2.at(value[0], value[1]);
|
||||
int cxx = loc.getX() << 4;
|
||||
int czz = loc.getZ() << 4;
|
||||
PaperLib.getChunkAtAsync(oldWorld, loc.getX(), loc.getZ())
|
||||
.thenAccept(chunk1 -> map.saveEntitiesIn(chunk1, region)).thenRun(() -> {
|
||||
for (int x = bx & 15; x <= (tx & 15); x++) {
|
||||
for (int z = bz & 15; z <= (tz & 15); z++) {
|
||||
map.saveBlocks(oldBukkitWorld, 256, cxx + x, czz + z, relX, relZ);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}, () -> {
|
||||
for (Entry<PlotLoc, BaseBlock[]> entry : map.allBlocks.entrySet()) {
|
||||
PlotLoc loc = entry.getKey();
|
||||
BaseBlock[] blocks = entry.getValue();
|
||||
for (int y = 0; y < blocks.length; y++) {
|
||||
if (blocks[y] != null) {
|
||||
BaseBlock block = blocks[y];
|
||||
queue.setBlock(loc.getX(), y, loc.getZ(), block);
|
||||
}
|
||||
}
|
||||
}
|
||||
queue.enqueue();
|
||||
GlobalBlockQueue.IMP.addEmptyTask(() -> {
|
||||
//map.restoreBlocks(newWorld, 0, 0);
|
||||
map.restoreEntities(newWorld, relX, relZ);
|
||||
TaskManager.runTask(whenDone);
|
||||
});
|
||||
}, 5);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override public boolean regenerateRegion(final Location pos1, final Location pos2,
|
||||
final boolean ignoreAugment, final Runnable whenDone) {
|
||||
final String world = pos1.getWorld();
|
||||
|
||||
final int p1x = pos1.getX();
|
||||
final int p1z = pos1.getZ();
|
||||
final int p2x = pos2.getX();
|
||||
final int p2z = pos2.getZ();
|
||||
final int bcx = p1x >> 4;
|
||||
final int bcz = p1z >> 4;
|
||||
final int tcx = p2x >> 4;
|
||||
final int tcz = p2z >> 4;
|
||||
|
||||
final List<BlockVector2> chunks = new ArrayList<>();
|
||||
|
||||
for (int x = bcx; x <= tcx; x++) {
|
||||
for (int z = bcz; z <= tcz; z++) {
|
||||
chunks.add(BlockVector2.at(x, z));
|
||||
}
|
||||
}
|
||||
final World worldObj = Bukkit.getWorld(world);
|
||||
checkNotNull(worldObj, "Critical error during regeneration.");
|
||||
final BukkitWorld bukkitWorldObj = new BukkitWorld(worldObj);
|
||||
TaskManager.runTask(new Runnable() {
|
||||
@Override public void run() {
|
||||
long start = System.currentTimeMillis();
|
||||
while (!chunks.isEmpty() && System.currentTimeMillis() - start < 5) {
|
||||
final BlockVector2 chunk = chunks.remove(0);
|
||||
int x = chunk.getX();
|
||||
int z = chunk.getZ();
|
||||
int xxb = x << 4;
|
||||
int zzb = z << 4;
|
||||
int xxt = xxb + 15;
|
||||
int zzt = zzb + 15;
|
||||
Chunk chunkObj = worldObj.getChunkAt(x, z);
|
||||
if (!chunkObj.load(false)) {
|
||||
continue;
|
||||
}
|
||||
final LocalBlockQueue queue = GlobalBlockQueue.IMP.getNewQueue(world, false);
|
||||
if (xxb >= p1x && xxt <= p2x && zzb >= p1z && zzt <= p2z
|
||||
&& PlotSquared.imp().getServerVersion()[1] == 13) {
|
||||
AugmentedUtils
|
||||
.bypass(ignoreAugment, () -> queue.regenChunkSafe(chunk.getX(), chunk.getZ()));
|
||||
continue;
|
||||
}
|
||||
boolean checkX1 = false;
|
||||
|
||||
int xxb2;
|
||||
|
||||
if (x == bcx) {
|
||||
xxb2 = p1x - 1;
|
||||
checkX1 = true;
|
||||
} else {
|
||||
xxb2 = xxb;
|
||||
}
|
||||
boolean checkX2 = false;
|
||||
int xxt2;
|
||||
if (x == tcx) {
|
||||
xxt2 = p2x + 1;
|
||||
checkX2 = true;
|
||||
} else {
|
||||
xxt2 = xxt;
|
||||
}
|
||||
boolean checkZ1 = false;
|
||||
int zzb2;
|
||||
if (z == bcz) {
|
||||
zzb2 = p1z - 1;
|
||||
checkZ1 = true;
|
||||
} else {
|
||||
zzb2 = zzb;
|
||||
}
|
||||
boolean checkZ2 = false;
|
||||
int zzt2;
|
||||
if (z == tcz) {
|
||||
zzt2 = p2z + 1;
|
||||
checkZ2 = true;
|
||||
} else {
|
||||
zzt2 = zzt;
|
||||
}
|
||||
final ContentMap map = new ContentMap();
|
||||
if (checkX1) {
|
||||
map.saveRegion(bukkitWorldObj, xxb, xxb2, zzb2, zzt2); //
|
||||
}
|
||||
if (checkX2) {
|
||||
map.saveRegion(bukkitWorldObj, xxt2, xxt, zzb2, zzt2); //
|
||||
}
|
||||
if (checkZ1) {
|
||||
map.saveRegion(bukkitWorldObj, xxb2, xxt2, zzb, zzb2); //
|
||||
}
|
||||
if (checkZ2) {
|
||||
map.saveRegion(bukkitWorldObj, xxb2, xxt2, zzt2, zzt); //
|
||||
}
|
||||
if (checkX1 && checkZ1) {
|
||||
map.saveRegion(bukkitWorldObj, xxb, xxb2, zzb, zzb2); //
|
||||
}
|
||||
if (checkX2 && checkZ1) {
|
||||
map.saveRegion(bukkitWorldObj, xxt2, xxt, zzb, zzb2); // ?
|
||||
}
|
||||
if (checkX1 && checkZ2) {
|
||||
map.saveRegion(bukkitWorldObj, xxb, xxb2, zzt2, zzt); // ?
|
||||
}
|
||||
if (checkX2 && checkZ2) {
|
||||
map.saveRegion(bukkitWorldObj, xxt2, xxt, zzt2, zzt); //
|
||||
}
|
||||
CuboidRegion currentPlotClear =
|
||||
RegionUtil.createRegion(pos1.getX(), pos2.getX(), pos1.getZ(), pos2.getZ());
|
||||
map.saveEntitiesOut(chunkObj, currentPlotClear);
|
||||
AugmentedUtils.bypass(ignoreAugment,
|
||||
() -> setChunkInPlotArea(null, new RunnableVal<ScopedLocalBlockQueue>() {
|
||||
@Override public void run(ScopedLocalBlockQueue value) {
|
||||
Location min = value.getMin();
|
||||
int bx = min.getX();
|
||||
int bz = min.getZ();
|
||||
for (int x1 = 0; x1 < 16; x1++) {
|
||||
for (int z1 = 0; z1 < 16; z1++) {
|
||||
PlotLoc plotLoc = new PlotLoc(bx + x1, bz + z1);
|
||||
BaseBlock[] ids = map.allBlocks.get(plotLoc);
|
||||
if (ids != null) {
|
||||
for (int y = 0; y < Math.min(128, ids.length); y++) {
|
||||
BaseBlock id = ids[y];
|
||||
if (id != null) {
|
||||
value.setBlock(x1, y, z1, id);
|
||||
} else {
|
||||
value.setBlock(x1, y, z1, BlockTypes.AIR.getDefaultState());
|
||||
}
|
||||
}
|
||||
for (int y = Math.min(128, ids.length);
|
||||
y < ids.length; y++) {
|
||||
BaseBlock id = ids[y];
|
||||
if (id != null) {
|
||||
value.setBlock(x1, y, z1, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, world, chunk));
|
||||
//map.restoreBlocks(worldObj, 0, 0);
|
||||
map.restoreEntities(worldObj, 0, 0);
|
||||
}
|
||||
if (!chunks.isEmpty()) {
|
||||
TaskManager.runTaskLater(this, 1);
|
||||
} else {
|
||||
TaskManager.runTaskLater(whenDone, 1);
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override public CompletableFuture<?> loadChunk(String world, BlockVector2 chunkLoc, boolean force) {
|
||||
return PaperLib.getChunkAtAsync(BukkitUtil.getWorld(world),chunkLoc.getX(), chunkLoc.getZ(), force);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unloadChunk(final String world, final BlockVector2 chunkLoc, final boolean save) {
|
||||
if (!PlotSquared.get().isMainThread(Thread.currentThread())) {
|
||||
TaskManager.runTask(
|
||||
() -> BukkitUtil.getWorld(world).unloadChunk(chunkLoc.getX(), chunkLoc.getZ(), save));
|
||||
} else {
|
||||
BukkitUtil.getWorld(world).unloadChunk(chunkLoc.getX(), chunkLoc.getZ(), save);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void clearAllEntities(Location pos1, Location pos2) {
|
||||
String world = pos1.getWorld();
|
||||
List<Entity> entities = BukkitUtil.getEntities(world);
|
||||
int bx = pos1.getX();
|
||||
int bz = pos1.getZ();
|
||||
int tx = pos2.getX();
|
||||
int tz = pos2.getZ();
|
||||
for (Entity entity : entities) {
|
||||
if (!(entity instanceof Player)) {
|
||||
org.bukkit.Location location = entity.getLocation();
|
||||
if (location.getX() >= bx && location.getX() <= tx && location.getZ() >= bz
|
||||
&& location.getZ() <= tz) {
|
||||
if (entity.hasMetadata("ps-tmp-teleport")) {
|
||||
continue;
|
||||
}
|
||||
entity.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void swap(Location bot1, Location top1, Location bot2, Location top2,
|
||||
final Runnable whenDone) {
|
||||
CuboidRegion region1 =
|
||||
RegionUtil.createRegion(bot1.getX(), top1.getX(), bot1.getZ(), top1.getZ());
|
||||
CuboidRegion region2 =
|
||||
RegionUtil.createRegion(bot2.getX(), top2.getX(), bot2.getZ(), top2.getZ());
|
||||
final World world1 = Bukkit.getWorld(bot1.getWorld());
|
||||
final World world2 = Bukkit.getWorld(bot2.getWorld());
|
||||
checkNotNull(world1,"Critical error during swap.");
|
||||
checkNotNull(world2,"Critical error during swap.");
|
||||
int relX = bot2.getX() - bot1.getX();
|
||||
int relZ = bot2.getZ() - bot1.getZ();
|
||||
|
||||
final ArrayDeque<ContentMap> maps = new ArrayDeque<>();
|
||||
|
||||
for (int x = bot1.getX() >> 4; x <= top1.getX() >> 4; x++) {
|
||||
for (int z = bot1.getZ() >> 4; z <= top1.getZ() >> 4; z++) {
|
||||
Chunk chunk1 = world1.getChunkAt(x, z);
|
||||
Chunk chunk2 = world2.getChunkAt(x + (relX >> 4), z + (relZ >> 4));
|
||||
maps.add(swapChunk(world1, world2, chunk1, chunk2, region1, region2));
|
||||
}
|
||||
}
|
||||
GlobalBlockQueue.IMP.addEmptyTask(() -> {
|
||||
for (ContentMap map : maps) {
|
||||
map.restoreEntities(world1, 0, 0);
|
||||
TaskManager.runTaskLater(whenDone, 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void count(int[] count, Entity entity) {
|
||||
switch (entity.getType()) {
|
||||
case PLAYER:
|
||||
// not valid
|
||||
return;
|
||||
case SMALL_FIREBALL:
|
||||
case FIREBALL:
|
||||
case DROPPED_ITEM:
|
||||
case EGG:
|
||||
case THROWN_EXP_BOTTLE:
|
||||
case SPLASH_POTION:
|
||||
case SNOWBALL:
|
||||
case ENDER_PEARL:
|
||||
case ARROW:
|
||||
case TRIDENT:
|
||||
case SHULKER_BULLET:
|
||||
case SPECTRAL_ARROW:
|
||||
case DRAGON_FIREBALL:
|
||||
case LLAMA_SPIT:
|
||||
// projectile
|
||||
case PRIMED_TNT:
|
||||
case FALLING_BLOCK:
|
||||
// Block entities
|
||||
case ENDER_CRYSTAL:
|
||||
case FISHING_HOOK:
|
||||
case ENDER_SIGNAL:
|
||||
case EXPERIENCE_ORB:
|
||||
case LEASH_HITCH:
|
||||
case FIREWORK:
|
||||
case LIGHTNING:
|
||||
case WITHER_SKULL:
|
||||
case UNKNOWN:
|
||||
case AREA_EFFECT_CLOUD:
|
||||
case EVOKER_FANGS:
|
||||
// non moving / unremovable
|
||||
break;
|
||||
case ITEM_FRAME:
|
||||
case PAINTING:
|
||||
case ARMOR_STAND:
|
||||
count[5]++;
|
||||
break;
|
||||
// misc
|
||||
case MINECART:
|
||||
case MINECART_CHEST:
|
||||
case MINECART_COMMAND:
|
||||
case MINECART_FURNACE:
|
||||
case MINECART_HOPPER:
|
||||
case MINECART_MOB_SPAWNER:
|
||||
case MINECART_TNT:
|
||||
case BOAT:
|
||||
count[4]++;
|
||||
break;
|
||||
case POLAR_BEAR:
|
||||
case RABBIT:
|
||||
case SHEEP:
|
||||
case MUSHROOM_COW:
|
||||
case OCELOT:
|
||||
case PIG:
|
||||
case HORSE:
|
||||
case SQUID:
|
||||
case VILLAGER:
|
||||
case IRON_GOLEM:
|
||||
case WOLF:
|
||||
case CHICKEN:
|
||||
case COW:
|
||||
case SNOWMAN:
|
||||
case BAT:
|
||||
case DONKEY:
|
||||
case LLAMA:
|
||||
case SKELETON_HORSE:
|
||||
case ZOMBIE_HORSE:
|
||||
case MULE:
|
||||
case DOLPHIN:
|
||||
case TURTLE:
|
||||
case COD:
|
||||
case PARROT:
|
||||
case SALMON:
|
||||
case PUFFERFISH:
|
||||
case TROPICAL_FISH:
|
||||
case CAT:
|
||||
case FOX:
|
||||
case PANDA:
|
||||
// animal
|
||||
count[3]++;
|
||||
count[1]++;
|
||||
break;
|
||||
case BLAZE:
|
||||
case CAVE_SPIDER:
|
||||
case CREEPER:
|
||||
case ENDERMAN:
|
||||
case ENDERMITE:
|
||||
case ENDER_DRAGON:
|
||||
case GHAST:
|
||||
case GIANT:
|
||||
case GUARDIAN:
|
||||
case MAGMA_CUBE:
|
||||
case PIG_ZOMBIE:
|
||||
case SILVERFISH:
|
||||
case SKELETON:
|
||||
case SLIME:
|
||||
case SPIDER:
|
||||
case WITCH:
|
||||
case WITHER:
|
||||
case ZOMBIE:
|
||||
case SHULKER:
|
||||
case ELDER_GUARDIAN:
|
||||
case STRAY:
|
||||
case HUSK:
|
||||
case EVOKER:
|
||||
case VEX:
|
||||
case WITHER_SKELETON:
|
||||
case ZOMBIE_VILLAGER:
|
||||
case VINDICATOR:
|
||||
// monster
|
||||
count[3]++;
|
||||
count[2]++;
|
||||
break;
|
||||
default:
|
||||
if (entity instanceof Creature) {
|
||||
count[3]++;
|
||||
if (entity instanceof Animals) {
|
||||
count[1]++;
|
||||
} else {
|
||||
count[2]++;
|
||||
}
|
||||
} else {
|
||||
count[4]++;
|
||||
}
|
||||
}
|
||||
count[0]++;
|
||||
}
|
||||
|
||||
|
||||
public static class ContentMap {
|
||||
|
||||
final Set<EntityWrapper> entities;
|
||||
final Map<PlotLoc, BaseBlock[]> allBlocks;
|
||||
|
||||
ContentMap() {
|
||||
this.entities = new HashSet<>();
|
||||
this.allBlocks = new HashMap<>();
|
||||
}
|
||||
|
||||
public void saveRegion(BukkitWorld world, int x1, int x2, int z1, int z2) {
|
||||
if (z1 > z2) {
|
||||
int tmp = z1;
|
||||
z1 = z2;
|
||||
z2 = tmp;
|
||||
}
|
||||
if (x1 > x2) {
|
||||
int tmp = x1;
|
||||
x1 = x2;
|
||||
x2 = tmp;
|
||||
}
|
||||
for (int x = x1; x <= x2; x++) {
|
||||
for (int z = z1; z <= z2; z++) {
|
||||
saveBlocks(world, 256, x, z, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void saveEntitiesOut(Chunk chunk, CuboidRegion region) {
|
||||
for (Entity entity : chunk.getEntities()) {
|
||||
Location location = BukkitUtil.getLocation(entity);
|
||||
int x = location.getX();
|
||||
int z = location.getZ();
|
||||
if (isIn(region, x, z)) {
|
||||
continue;
|
||||
}
|
||||
if (entity.getVehicle() != null) {
|
||||
continue;
|
||||
}
|
||||
EntityWrapper wrap = new ReplicatingEntityWrapper(entity, (short) 2);
|
||||
wrap.saveEntity();
|
||||
this.entities.add(wrap);
|
||||
}
|
||||
}
|
||||
|
||||
void saveEntitiesIn(Chunk chunk, CuboidRegion region) {
|
||||
saveEntitiesIn(chunk, region, 0, 0, false);
|
||||
}
|
||||
|
||||
void saveEntitiesIn(Chunk chunk, CuboidRegion region, int offsetX, int offsetZ,
|
||||
boolean delete) {
|
||||
for (Entity entity : chunk.getEntities()) {
|
||||
Location location = BukkitUtil.getLocation(entity);
|
||||
int x = location.getX();
|
||||
int z = location.getZ();
|
||||
if (!isIn(region, x, z)) {
|
||||
continue;
|
||||
}
|
||||
if (entity.getVehicle() != null) {
|
||||
continue;
|
||||
}
|
||||
EntityWrapper wrap = new ReplicatingEntityWrapper(entity, (short) 2);
|
||||
wrap.x += offsetX;
|
||||
wrap.z += offsetZ;
|
||||
wrap.saveEntity();
|
||||
this.entities.add(wrap);
|
||||
if (delete) {
|
||||
if (!(entity instanceof Player)) {
|
||||
entity.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void restoreEntities(World world, int xOffset, int zOffset) {
|
||||
for (EntityWrapper entity : this.entities) {
|
||||
try {
|
||||
entity.spawn(world, xOffset, zOffset);
|
||||
} catch (Exception e) {
|
||||
PlotSquared.debug("Failed to restore entity (e): " + e.toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
this.entities.clear();
|
||||
}
|
||||
|
||||
//todo optimize maxY
|
||||
void saveBlocks(BukkitWorld world, int maxY, int x, int z, int offsetX, int offsetZ) {
|
||||
maxY = Math.min(255, maxY);
|
||||
BaseBlock[] ids = new BaseBlock[maxY + 1];
|
||||
for (short y = 0; y <= maxY; y++) {
|
||||
BaseBlock block = world.getFullBlock(BlockVector3.at(x, y, z));
|
||||
ids[y] = block;
|
||||
}
|
||||
PlotLoc loc = new PlotLoc(x + offsetX, z + offsetZ);
|
||||
this.allBlocks.put(loc, ids);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.util;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.bukkit.commands.DebugUUID;
|
||||
import com.github.intellectualsites.plotsquared.plot.commands.MainCommand;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.ConsolePlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.bukkit.command.ProxiedCommandSender;
|
||||
import org.bukkit.command.RemoteConsoleCommandSender;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class BukkitCommand implements CommandExecutor, TabCompleter {
|
||||
|
||||
public BukkitCommand() {
|
||||
new DebugUUID();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender commandSender, Command command, String commandLabel,
|
||||
String[] args) {
|
||||
if (commandSender instanceof Player) {
|
||||
return MainCommand.onCommand(BukkitUtil.getPlayer((Player) commandSender), args);
|
||||
}
|
||||
if (commandSender instanceof ConsoleCommandSender
|
||||
|| commandSender instanceof ProxiedCommandSender
|
||||
|| commandSender instanceof RemoteConsoleCommandSender) {
|
||||
return MainCommand.onCommand(ConsolePlayer.getConsole(), args);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender commandSender, Command command, String s,
|
||||
String[] args) {
|
||||
if (!(commandSender instanceof Player)) {
|
||||
return null;
|
||||
}
|
||||
PlotPlayer player = BukkitUtil.getPlayer((Player) commandSender);
|
||||
if (args.length == 0) {
|
||||
return Collections.singletonList("plots");
|
||||
}
|
||||
Collection<com.github.intellectualsites.plotsquared.commands.Command> objects = MainCommand.getInstance().tab(player, args, s.endsWith(" "));
|
||||
if (objects == null) {
|
||||
return null;
|
||||
}
|
||||
List<String> result = new ArrayList<>();
|
||||
for (com.github.intellectualsites.plotsquared.commands.Command o : objects) {
|
||||
result.add(o.toString());
|
||||
}
|
||||
return result.isEmpty() ? null : result;
|
||||
}
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.util;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.bukkit.object.BukkitOfflinePlayer;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.object.BukkitPlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.OfflinePlotPlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.EconHandler;
|
||||
import net.milkbowl.vault.economy.Economy;
|
||||
import net.milkbowl.vault.permission.Permission;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
|
||||
public class BukkitEconHandler extends EconHandler {
|
||||
|
||||
private Economy econ;
|
||||
private Permission perms;
|
||||
|
||||
public boolean init() {
|
||||
if (this.econ == null || this.perms == null) {
|
||||
setupPermissions();
|
||||
setupEconomy();
|
||||
}
|
||||
return this.econ != null && this.perms != null;
|
||||
}
|
||||
|
||||
private boolean setupPermissions() {
|
||||
RegisteredServiceProvider<Permission> permissionProvider =
|
||||
Bukkit.getServer().getServicesManager().getRegistration(Permission.class);
|
||||
if (permissionProvider != null) {
|
||||
this.perms = permissionProvider.getProvider();
|
||||
}
|
||||
return this.perms != null;
|
||||
}
|
||||
|
||||
private boolean setupEconomy() {
|
||||
if (Bukkit.getServer().getPluginManager().getPlugin("Vault") == null) {
|
||||
return false;
|
||||
}
|
||||
RegisteredServiceProvider<Economy> economyProvider =
|
||||
Bukkit.getServer().getServicesManager().getRegistration(Economy.class);
|
||||
if (economyProvider != null) {
|
||||
this.econ = economyProvider.getProvider();
|
||||
}
|
||||
return this.econ != null;
|
||||
}
|
||||
|
||||
@Override public double getMoney(PlotPlayer player) {
|
||||
double bal = super.getMoney(player);
|
||||
if (Double.isNaN(bal)) {
|
||||
return this.econ.getBalance(((BukkitPlayer) player).player);
|
||||
}
|
||||
return bal;
|
||||
}
|
||||
|
||||
@Override public void withdrawMoney(PlotPlayer player, double amount) {
|
||||
this.econ.withdrawPlayer(((BukkitPlayer) player).player, amount);
|
||||
}
|
||||
|
||||
@Override public void depositMoney(PlotPlayer player, double amount) {
|
||||
this.econ.depositPlayer(((BukkitPlayer) player).player, amount);
|
||||
}
|
||||
|
||||
@Override public void depositMoney(OfflinePlotPlayer player, double amount) {
|
||||
this.econ.depositPlayer(((BukkitOfflinePlayer) player).player, amount);
|
||||
}
|
||||
|
||||
@Override public boolean hasPermission(String world, String player, String perm) {
|
||||
return this.perms.playerHas(world, Bukkit.getOfflinePlayer(player), perm);
|
||||
}
|
||||
|
||||
@Override public double getBalance(PlotPlayer player) {
|
||||
return this.econ.getBalance(player.getName());
|
||||
}
|
||||
|
||||
public void setPermission(String world, String player, String perm, boolean value) {
|
||||
if (value) {
|
||||
this.perms.playerAdd(world, player, perm);
|
||||
} else {
|
||||
this.perms.playerRemove(world, player, perm);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,145 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.util;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.bukkit.events.PlayerClaimPlotEvent;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.events.PlayerEnterPlotEvent;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.events.PlayerLeavePlotEvent;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.events.PlayerPlotDeniedEvent;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.events.PlayerPlotHelperEvent;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.events.PlayerPlotTrustedEvent;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.events.PlayerTeleportToPlotEvent;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.events.PlotAutoMergeEvent;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.events.PlotChangeOwnerEvent;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.events.PlotClearEvent;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.events.PlotComponentSetEvent;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.events.PlotDeleteEvent;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.events.PlotFlagAddEvent;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.events.PlotFlagRemoveEvent;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.events.PlotMergeEvent;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.events.PlotRateEvent;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.events.PlotUnlinkEvent;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.object.BukkitPlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.flag.Flag;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Location;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotArea;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotId;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Rating;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.TeleportCause;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.EventUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Utility class for handling Bukkit Events.
|
||||
*/
|
||||
public final class BukkitEventUtil extends EventUtil {
|
||||
|
||||
@Nullable public Player getPlayer(final PlotPlayer player) {
|
||||
if (player instanceof BukkitPlayer) {
|
||||
return ((BukkitPlayer) player).player;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean callEvent(@NotNull final Event event) {
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
return !(event instanceof Cancellable) || !((Cancellable) event).isCancelled();
|
||||
}
|
||||
|
||||
@Override public boolean callClaim(PlotPlayer player, Plot plot, boolean auto) {
|
||||
return callEvent(new PlayerClaimPlotEvent(getPlayer(player), plot, auto));
|
||||
}
|
||||
|
||||
@Override public boolean callTeleport(PlotPlayer player, Location from, Plot plot) {
|
||||
return callEvent(new PlayerTeleportToPlotEvent(getPlayer(player), from, plot));
|
||||
}
|
||||
|
||||
@Override public boolean callComponentSet(Plot plot, String component) {
|
||||
return callEvent(new PlotComponentSetEvent(plot, component));
|
||||
}
|
||||
|
||||
@Override public boolean callClear(Plot plot) {
|
||||
return callEvent(new PlotClearEvent(plot));
|
||||
}
|
||||
|
||||
@Override public boolean callDelete(Plot plot) {
|
||||
return callEvent(new PlotDeleteEvent(plot));
|
||||
}
|
||||
|
||||
@Override public boolean callFlagAdd(Flag flag, Plot plot) {
|
||||
return callEvent(new PlotFlagAddEvent(flag, plot));
|
||||
}
|
||||
|
||||
@Override public boolean callFlagRemove(Flag<?> flag, Plot plot, Object value) {
|
||||
return callEvent(new PlotFlagRemoveEvent(flag, plot));
|
||||
}
|
||||
|
||||
@Override public boolean callMerge(Plot plot, int dir, int max) {
|
||||
return callEvent(
|
||||
new PlotMergeEvent(BukkitUtil.getWorld(plot.getWorldName()), plot, dir, max));
|
||||
}
|
||||
|
||||
@Override public boolean callAutoMerge(Plot plot, List<PlotId> plots) {
|
||||
return callEvent(
|
||||
new PlotAutoMergeEvent(BukkitUtil.getWorld(plot.getWorldName()), plot, plots));
|
||||
}
|
||||
|
||||
@Override public boolean callUnlink(PlotArea area, List<PlotId> plots) {
|
||||
return callEvent(new PlotUnlinkEvent(BukkitUtil.getWorld(area.worldname), area, plots));
|
||||
}
|
||||
|
||||
@Override public void callEntry(PlotPlayer player, Plot plot) {
|
||||
callEvent(new PlayerEnterPlotEvent(getPlayer(player), plot));
|
||||
}
|
||||
|
||||
@Override public void callLeave(PlotPlayer player, Plot plot) {
|
||||
callEvent(new PlayerLeavePlotEvent(getPlayer(player), plot));
|
||||
}
|
||||
|
||||
@Override public void callDenied(PlotPlayer initiator, Plot plot, UUID player, boolean added) {
|
||||
callEvent(new PlayerPlotDeniedEvent(getPlayer(initiator), plot, player, added));
|
||||
}
|
||||
|
||||
@Override public void callTrusted(PlotPlayer initiator, Plot plot, UUID player, boolean added) {
|
||||
callEvent(new PlayerPlotTrustedEvent(getPlayer(initiator), plot, player, added));
|
||||
}
|
||||
|
||||
@Override public void callMember(PlotPlayer initiator, Plot plot, UUID player, boolean added) {
|
||||
callEvent(new PlayerPlotHelperEvent(getPlayer(initiator), plot, player, added));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean callOwnerChange(PlotPlayer initiator, Plot plot, UUID oldOwner, UUID newOwner,
|
||||
boolean hasOldOwner) {
|
||||
return callEvent(
|
||||
new PlotChangeOwnerEvent(getPlayer(initiator), plot, oldOwner, newOwner, hasOldOwner));
|
||||
}
|
||||
|
||||
@Override @Nullable public Rating callRating(PlotPlayer player, Plot plot, Rating rating) {
|
||||
PlotRateEvent event = new PlotRateEvent(player, rating, plot);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return null;
|
||||
}
|
||||
return event.getRating();
|
||||
}
|
||||
|
||||
public PlayerTeleportEvent.TeleportCause getTeleportCause(@NotNull final TeleportCause cause) {
|
||||
switch (cause) {
|
||||
case COMMAND:
|
||||
return PlayerTeleportEvent.TeleportCause.COMMAND;
|
||||
case PLUGIN:
|
||||
return PlayerTeleportEvent.TeleportCause.PLUGIN;
|
||||
default: return PlayerTeleportEvent.TeleportCause.UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.util;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.plot.generator.HybridUtils;
|
||||
|
||||
public class BukkitHybridUtils extends HybridUtils {
|
||||
|
||||
|
||||
}
|
@ -1,126 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.util;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.bukkit.object.BukkitPlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotInventory;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotItemStack;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.InventoryUtil;
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class BukkitInventoryUtil extends InventoryUtil {
|
||||
|
||||
@Override public void open(PlotInventory inv) {
|
||||
BukkitPlayer bp = (BukkitPlayer) inv.player;
|
||||
Inventory inventory = Bukkit.createInventory(null, inv.size * 9, inv.getTitle());
|
||||
PlotItemStack[] items = inv.getItems();
|
||||
for (int i = 0; i < inv.size * 9; i++) {
|
||||
PlotItemStack item = items[i];
|
||||
if (item != null) {
|
||||
inventory.setItem(i, getItem(item));
|
||||
}
|
||||
}
|
||||
bp.player.openInventory(inventory);
|
||||
}
|
||||
|
||||
@Override public void close(PlotInventory inv) {
|
||||
if (!inv.isOpen()) {
|
||||
return;
|
||||
}
|
||||
BukkitPlayer bp = (BukkitPlayer) inv.player;
|
||||
bp.player.closeInventory();
|
||||
}
|
||||
|
||||
@Override public void setItem(PlotInventory inv, int index, PlotItemStack item) {
|
||||
BukkitPlayer bp = (BukkitPlayer) inv.player;
|
||||
InventoryView opened = bp.player.getOpenInventory();
|
||||
if (!inv.isOpen()) {
|
||||
return;
|
||||
}
|
||||
opened.setItem(index, getItem(item));
|
||||
bp.player.updateInventory();
|
||||
}
|
||||
|
||||
private static ItemStack getItem(PlotItemStack item) {
|
||||
if (item == null) {
|
||||
return null;
|
||||
}
|
||||
ItemStack stack = new ItemStack(BukkitAdapter.adapt(item.getType()), item.amount);
|
||||
ItemMeta meta = null;
|
||||
if (item.name != null) {
|
||||
meta = stack.getItemMeta();
|
||||
meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', item.name));
|
||||
}
|
||||
if (item.lore != null) {
|
||||
if (meta == null) {
|
||||
meta = stack.getItemMeta();
|
||||
}
|
||||
List<String> lore = new ArrayList<>();
|
||||
for (String entry : item.lore) {
|
||||
lore.add(ChatColor.translateAlternateColorCodes('&', entry));
|
||||
}
|
||||
meta.setLore(lore);
|
||||
}
|
||||
if (meta != null) {
|
||||
stack.setItemMeta(meta);
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
||||
public PlotItemStack getItem(ItemStack item) {
|
||||
if (item == null) {
|
||||
return null;
|
||||
}
|
||||
// int id = item.getTypeId();
|
||||
Material id = item.getType();
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
int amount = item.getAmount();
|
||||
String name = null;
|
||||
String[] lore = null;
|
||||
if (item.hasItemMeta()) {
|
||||
assert meta != null;
|
||||
if (meta.hasDisplayName()) {
|
||||
name = meta.getDisplayName();
|
||||
}
|
||||
if (meta.hasLore()) {
|
||||
List<String> itemLore = meta.getLore();
|
||||
assert itemLore != null;
|
||||
lore = itemLore.toArray(new String[0]);
|
||||
}
|
||||
}
|
||||
return new PlotItemStack(id.name(), amount, name, lore);
|
||||
}
|
||||
|
||||
@Override public PlotItemStack[] getItems(PlotPlayer player) {
|
||||
BukkitPlayer bp = (BukkitPlayer) player;
|
||||
PlayerInventory inv = bp.player.getInventory();
|
||||
return IntStream.range(0, 36).mapToObj(i -> getItem(inv.getItem(i)))
|
||||
.toArray(PlotItemStack[]::new);
|
||||
}
|
||||
|
||||
@Override public boolean isOpen(PlotInventory plotInventory) {
|
||||
if (!plotInventory.isOpen()) {
|
||||
return false;
|
||||
}
|
||||
BukkitPlayer bp = (BukkitPlayer) plotInventory.player;
|
||||
InventoryView opened = bp.player.getOpenInventory();
|
||||
if (plotInventory.isOpen()) {
|
||||
if (opened.getType() == InventoryType.CRAFTING) {
|
||||
opened.getTitle();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,213 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.util;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.bukkit.object.schematic.StateWrapper;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Location;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.RunnableVal;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.MainUtil;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.SchematicHandler;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.TaskManager;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue;
|
||||
import com.sk89q.jnbt.ByteArrayTag;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.IntArrayTag;
|
||||
import com.sk89q.jnbt.IntTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.ShortTag;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
/**
|
||||
* Schematic Handler.
|
||||
*/
|
||||
public class BukkitSchematicHandler extends SchematicHandler {
|
||||
|
||||
@Override public void getCompoundTag(final String world, final Set<CuboidRegion> regions,
|
||||
final RunnableVal<CompoundTag> whenDone) {
|
||||
// async
|
||||
TaskManager.runTaskAsync(new Runnable() {
|
||||
@Override public void run() {
|
||||
// Main positions
|
||||
Location[] corners = MainUtil.getCorners(world, regions);
|
||||
final Location bot = corners[0];
|
||||
final Location top = corners[1];
|
||||
|
||||
CuboidRegion cuboidRegion =
|
||||
new CuboidRegion(BukkitUtil.IMP.getWeWorld(world), bot.getBlockVector3(),
|
||||
top.getBlockVector3());
|
||||
|
||||
final int width = cuboidRegion.getWidth();
|
||||
int height = cuboidRegion.getHeight();
|
||||
final int length = cuboidRegion.getLength();
|
||||
Map<String, Tag> schematic = new HashMap<>();
|
||||
schematic.put("Version", new IntTag(1));
|
||||
|
||||
Map<String, Tag> metadata = new HashMap<>();
|
||||
metadata.put("WEOffsetX", new IntTag(0));
|
||||
metadata.put("WEOffsetY", new IntTag(0));
|
||||
metadata.put("WEOffsetZ", new IntTag(0));
|
||||
|
||||
schematic.put("Metadata", new CompoundTag(metadata));
|
||||
|
||||
schematic.put("Width", new ShortTag((short) width));
|
||||
schematic.put("Height", new ShortTag((short) height));
|
||||
schematic.put("Length", new ShortTag((short) length));
|
||||
|
||||
// The Sponge format Offset refers to the 'min' points location in the world. That's our 'Origin'
|
||||
schematic.put("Offset", new IntArrayTag(new int[] {0, 0, 0,}));
|
||||
|
||||
Map<String, Integer> palette = new HashMap<>();
|
||||
|
||||
List<CompoundTag> tileEntities = new ArrayList<>();
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream(width * height * length);
|
||||
// Queue
|
||||
final ArrayDeque<CuboidRegion> queue = new ArrayDeque<>(regions);
|
||||
TaskManager.runTask(new Runnable() {
|
||||
@Override public void run() {
|
||||
if (queue.isEmpty()) {
|
||||
TaskManager.runTaskAsync(() -> {
|
||||
schematic.put("PaletteMax", new IntTag(palette.size()));
|
||||
|
||||
Map<String, Tag> paletteTag = new HashMap<>();
|
||||
palette.forEach(
|
||||
(key, value) -> paletteTag.put(key, new IntTag(value)));
|
||||
|
||||
schematic.put("Palette", new CompoundTag(paletteTag));
|
||||
schematic.put("BlockData", new ByteArrayTag(buffer.toByteArray()));
|
||||
schematic.put("TileEntities",
|
||||
new ListTag(CompoundTag.class, tileEntities));
|
||||
whenDone.value = new CompoundTag(schematic);
|
||||
TaskManager.runTask(whenDone);
|
||||
});
|
||||
return;
|
||||
}
|
||||
final Runnable regionTask = this;
|
||||
CuboidRegion region = queue.poll();
|
||||
Location pos1 = new Location(world, region.getMinimumPoint().getX(), region.getMinimumPoint().getY(), region.getMinimumPoint().getZ());
|
||||
Location pos2 = new Location(world, region.getMaximumPoint().getX(), region.getMaximumPoint().getY(), region.getMaximumPoint().getZ());
|
||||
final int p1x = pos1.getX();
|
||||
final int sy = pos1.getY();
|
||||
final int p1z = pos1.getZ();
|
||||
final int p2x = pos2.getX();
|
||||
final int p2z = pos2.getZ();
|
||||
final int ey = pos2.getY();
|
||||
Iterator<Integer> yiter = IntStream.range(sy, ey + 1).iterator();
|
||||
final Runnable yTask = new Runnable() {
|
||||
@Override public void run() {
|
||||
long ystart = System.currentTimeMillis();
|
||||
while (yiter.hasNext()
|
||||
&& System.currentTimeMillis() - ystart < 20) {
|
||||
final int y = yiter.next();
|
||||
Iterator<Integer> ziter =
|
||||
IntStream.range(p1z, p2z + 1).iterator();
|
||||
final Runnable zTask = new Runnable() {
|
||||
@Override public void run() {
|
||||
long zstart = System.currentTimeMillis();
|
||||
while (ziter.hasNext()
|
||||
&& System.currentTimeMillis() - zstart < 20) {
|
||||
final int z = ziter.next();
|
||||
Iterator<Integer> xiter =
|
||||
IntStream.range(p1x, p2x + 1).iterator();
|
||||
final Runnable xTask = new Runnable() {
|
||||
@Override public void run() {
|
||||
long xstart = System.currentTimeMillis();
|
||||
final int ry = y - sy;
|
||||
final int rz = z - p1z;
|
||||
while (xiter.hasNext()
|
||||
&& System.currentTimeMillis() - xstart
|
||||
< 20) {
|
||||
final int x = xiter.next();
|
||||
final int rx = x - p1x;
|
||||
BlockVector3 point =
|
||||
BlockVector3.at(x, y, z);
|
||||
BaseBlock block =
|
||||
cuboidRegion.getWorld()
|
||||
.getFullBlock(point);
|
||||
if (block.getNbtData() != null) {
|
||||
Map<String, Tag> values =
|
||||
new HashMap<>();
|
||||
for (Map.Entry<String, Tag> entry : block
|
||||
.getNbtData().getValue()
|
||||
.entrySet()) {
|
||||
values.put(entry.getKey(),
|
||||
entry.getValue());
|
||||
}
|
||||
// Remove 'id' if it exists. We want 'Id'
|
||||
values.remove("id");
|
||||
|
||||
// Positions are kept in NBT, we don't want that.
|
||||
values.remove("x");
|
||||
values.remove("y");
|
||||
values.remove("z");
|
||||
|
||||
values.put("Id", new StringTag(
|
||||
block.getNbtId()));
|
||||
values.put("Pos", new IntArrayTag(
|
||||
new int[] {rx, ry, rz}));
|
||||
|
||||
tileEntities
|
||||
.add(new CompoundTag(values));
|
||||
}
|
||||
String blockKey =
|
||||
block.toImmutableState()
|
||||
.getAsString();
|
||||
int blockId;
|
||||
if (palette.containsKey(blockKey)) {
|
||||
blockId = palette.get(blockKey);
|
||||
} else {
|
||||
blockId = palette.size();
|
||||
palette
|
||||
.put(blockKey, palette.size());
|
||||
}
|
||||
|
||||
while ((blockId & -128) != 0) {
|
||||
buffer.write(blockId & 127 | 128);
|
||||
blockId >>>= 7;
|
||||
}
|
||||
buffer.write(blockId);
|
||||
}
|
||||
if (xiter.hasNext()) {
|
||||
this.run();
|
||||
}
|
||||
}
|
||||
};
|
||||
xTask.run();
|
||||
}
|
||||
if (ziter.hasNext()) {
|
||||
this.run();
|
||||
}
|
||||
}
|
||||
};
|
||||
zTask.run();
|
||||
}
|
||||
if (yiter.hasNext()) {
|
||||
TaskManager.runTaskLater(this, 1);
|
||||
} else {
|
||||
regionTask.run();
|
||||
}
|
||||
}
|
||||
};
|
||||
yTask.run();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean restoreTile(LocalBlockQueue queue, CompoundTag ct, int x, int y, int z) {
|
||||
return new StateWrapper(ct).restoreTag(queue.getWorld(), x, y, z);
|
||||
}
|
||||
}
|
@ -1,243 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.util;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.bukkit.generator.BukkitPlotGenerator;
|
||||
import com.github.intellectualsites.plotsquared.configuration.ConfigurationSection;
|
||||
import com.github.intellectualsites.plotsquared.configuration.file.YamlConfiguration;
|
||||
import com.github.intellectualsites.plotsquared.plot.PlotSquared;
|
||||
import com.github.intellectualsites.plotsquared.plot.config.ConfigurationNode;
|
||||
import com.github.intellectualsites.plotsquared.plot.generator.GeneratorWrapper;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotArea;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.SetupObject;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.SetupUtils;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.World.Environment;
|
||||
import org.bukkit.WorldCreator;
|
||||
import org.bukkit.WorldType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
|
||||
public class BukkitSetupUtils extends SetupUtils {
|
||||
|
||||
@Override public void updateGenerators() {
|
||||
if (!SetupUtils.generators.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
String testWorld = "CheckingPlotSquaredGenerator";
|
||||
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
|
||||
try {
|
||||
if (plugin.isEnabled()) {
|
||||
ChunkGenerator generator = plugin.getDefaultWorldGenerator(testWorld, "");
|
||||
if (generator != null) {
|
||||
PlotSquared.get().removePlotAreas(testWorld);
|
||||
String name = plugin.getDescription().getName();
|
||||
GeneratorWrapper<?> wrapped;
|
||||
if (generator instanceof GeneratorWrapper<?>) {
|
||||
wrapped = (GeneratorWrapper<?>) generator;
|
||||
} else {
|
||||
wrapped = new BukkitPlotGenerator(testWorld, generator);
|
||||
}
|
||||
SetupUtils.generators.put(name, wrapped);
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) { // Recover from third party generator error
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void unload(String worldName, boolean save) {
|
||||
World world = Bukkit.getWorld(worldName);
|
||||
if (world == null) {
|
||||
return;
|
||||
}
|
||||
World dw = Bukkit.getWorlds().get(0);
|
||||
for (Player player : world.getPlayers()) {
|
||||
PaperLib.teleportAsync(player,dw.getSpawnLocation());
|
||||
}
|
||||
if (save) {
|
||||
for (Chunk chunk : world.getLoadedChunks()) {
|
||||
chunk.unload(true);
|
||||
}
|
||||
} else {
|
||||
for (Chunk chunk : world.getLoadedChunks()) {
|
||||
chunk.unload(false);
|
||||
}
|
||||
}
|
||||
Bukkit.unloadWorld(world, false);
|
||||
}
|
||||
|
||||
@Override public String setupWorld(SetupObject object) {
|
||||
SetupUtils.manager.updateGenerators();
|
||||
ConfigurationNode[] steps = object.step == null ? new ConfigurationNode[0] : object.step;
|
||||
String world = object.world;
|
||||
int type = object.type;
|
||||
String worldPath = "worlds." + object.world;
|
||||
switch (type) {
|
||||
case 2: {
|
||||
if (object.id != null) {
|
||||
if (!PlotSquared.get().worlds.contains(worldPath)) {
|
||||
PlotSquared.get().worlds.createSection(worldPath);
|
||||
}
|
||||
ConfigurationSection worldSection =
|
||||
PlotSquared.get().worlds.getConfigurationSection(worldPath);
|
||||
String areaName = object.id + "-" + object.min + "-" + object.max;
|
||||
String areaPath = "areas." + areaName;
|
||||
if (!worldSection.contains(areaPath)) {
|
||||
worldSection.createSection(areaPath);
|
||||
}
|
||||
ConfigurationSection areaSection =
|
||||
worldSection.getConfigurationSection(areaPath);
|
||||
HashMap<String, Object> options = new HashMap<>();
|
||||
for (ConfigurationNode step : steps) {
|
||||
options.put(step.getConstant(), step.getValue());
|
||||
}
|
||||
options.put("generator.type", object.type);
|
||||
options.put("generator.terrain", object.terrain);
|
||||
options.put("generator.plugin", object.plotManager);
|
||||
if (object.setupGenerator != null && !object.setupGenerator
|
||||
.equals(object.plotManager)) {
|
||||
options.put("generator.init", object.setupGenerator);
|
||||
}
|
||||
for (Entry<String, Object> entry : options.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
if (worldSection.contains(key)) {
|
||||
Object current = worldSection.get(key);
|
||||
if (!Objects.equals(value, current)) {
|
||||
areaSection.set(key, value);
|
||||
}
|
||||
} else {
|
||||
worldSection.set(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
GeneratorWrapper<?> gen = SetupUtils.generators.get(object.setupGenerator);
|
||||
if (gen != null && gen.isFull()) {
|
||||
object.setupGenerator = null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
if (!object.plotManager.endsWith(":single")) {
|
||||
if (!PlotSquared.get().worlds.contains(worldPath)) {
|
||||
PlotSquared.get().worlds.createSection(worldPath);
|
||||
}
|
||||
if (steps.length != 0) {
|
||||
ConfigurationSection worldSection =
|
||||
PlotSquared.get().worlds.getConfigurationSection(worldPath);
|
||||
for (ConfigurationNode step : steps) {
|
||||
worldSection.set(step.getConstant(), step.getValue());
|
||||
}
|
||||
}
|
||||
PlotSquared.get().worlds
|
||||
.set("worlds." + world + ".generator.type", object.type);
|
||||
PlotSquared.get().worlds
|
||||
.set("worlds." + world + ".generator.terrain", object.terrain);
|
||||
PlotSquared.get().worlds
|
||||
.set("worlds." + world + ".generator.plugin", object.plotManager);
|
||||
if (object.setupGenerator != null && !object.setupGenerator
|
||||
.equals(object.plotManager)) {
|
||||
PlotSquared.get().worlds
|
||||
.set("worlds." + world + ".generator.init", object.setupGenerator);
|
||||
}
|
||||
}
|
||||
GeneratorWrapper<?> gen = SetupUtils.generators.get(object.setupGenerator);
|
||||
if (gen != null && gen.isFull()) {
|
||||
object.setupGenerator = null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0: {
|
||||
if (steps.length != 0) {
|
||||
if (!PlotSquared.get().worlds.contains(worldPath)) {
|
||||
PlotSquared.get().worlds.createSection(worldPath);
|
||||
}
|
||||
ConfigurationSection worldSection =
|
||||
PlotSquared.get().worlds.getConfigurationSection(worldPath);
|
||||
for (ConfigurationNode step : steps) {
|
||||
worldSection.set(step.getConstant(), step.getValue());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
try {
|
||||
PlotSquared.get().worlds.save(PlotSquared.get().worldsFile);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Plugin plugin = Bukkit.getPluginManager().getPlugin("Multiverse-Core");
|
||||
if (object.setupGenerator != null) {
|
||||
if (plugin != null && plugin.isEnabled()) {
|
||||
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(),
|
||||
"mv create " + world + " normal -g " + object.setupGenerator);
|
||||
setGenerator(world, object.setupGenerator);
|
||||
if (Bukkit.getWorld(world) != null) {
|
||||
return world;
|
||||
}
|
||||
}
|
||||
WorldCreator wc = new WorldCreator(object.world);
|
||||
wc.generator(object.setupGenerator);
|
||||
wc.environment(Environment.NORMAL);
|
||||
wc.type(WorldType.FLAT);
|
||||
Bukkit.createWorld(wc);
|
||||
setGenerator(world, object.setupGenerator);
|
||||
} else {
|
||||
if (plugin != null && plugin.isEnabled()) {
|
||||
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(),
|
||||
"mv create " + world + " normal");
|
||||
if (Bukkit.getWorld(world) != null) {
|
||||
return world;
|
||||
}
|
||||
}
|
||||
World bw =
|
||||
Bukkit.createWorld(new WorldCreator(object.world).environment(Environment.NORMAL));
|
||||
}
|
||||
return object.world;
|
||||
}
|
||||
|
||||
public void setGenerator(String world, String generator) {
|
||||
if (Bukkit.getWorlds().isEmpty() || !Bukkit.getWorlds().get(0).getName().equals(world)) {
|
||||
return;
|
||||
}
|
||||
File file = new File("bukkit.yml").getAbsoluteFile();
|
||||
YamlConfiguration yml = YamlConfiguration.loadConfiguration(file);
|
||||
yml.set("worlds." + world + ".generator", generator);
|
||||
try {
|
||||
yml.save(file);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override public String getGenerator(PlotArea plotArea) {
|
||||
if (SetupUtils.generators.isEmpty()) {
|
||||
updateGenerators();
|
||||
}
|
||||
World world = Bukkit.getWorld(plotArea.worldname);
|
||||
if (world == null) {
|
||||
return null;
|
||||
}
|
||||
ChunkGenerator generator = world.getGenerator();
|
||||
if (!(generator instanceof BukkitPlotGenerator)) {
|
||||
return null;
|
||||
}
|
||||
for (Entry<String, GeneratorWrapper<?>> entry : SetupUtils.generators.entrySet()) {
|
||||
GeneratorWrapper<?> current = entry.getValue();
|
||||
if (current.equals(generator)) {
|
||||
return entry.getKey();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.util;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.bukkit.BukkitMain;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.TaskManager;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
public class BukkitTaskManager extends TaskManager {
|
||||
|
||||
private final BukkitMain bukkitMain;
|
||||
|
||||
public BukkitTaskManager(BukkitMain bukkitMain) {
|
||||
this.bukkitMain = bukkitMain;
|
||||
}
|
||||
|
||||
@Override public int taskRepeat(Runnable runnable, int interval) {
|
||||
return this.bukkitMain.getServer().getScheduler()
|
||||
.scheduleSyncRepeatingTask(this.bukkitMain, runnable, interval, interval);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation") @Override
|
||||
public int taskRepeatAsync(Runnable runnable, int interval) {
|
||||
return this.bukkitMain.getServer().getScheduler()
|
||||
.scheduleAsyncRepeatingTask(this.bukkitMain, runnable, interval, interval);
|
||||
}
|
||||
|
||||
@Override public void taskAsync(Runnable runnable) {
|
||||
if (this.bukkitMain.isEnabled()) {
|
||||
this.bukkitMain.getServer().getScheduler()
|
||||
.runTaskAsynchronously(this.bukkitMain, runnable);
|
||||
} else {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void task(Runnable runnable) {
|
||||
this.bukkitMain.getServer().getScheduler().runTask(this.bukkitMain, runnable).getTaskId();
|
||||
}
|
||||
|
||||
@Override public void taskLater(Runnable runnable, int delay) {
|
||||
this.bukkitMain.getServer().getScheduler().runTaskLater(this.bukkitMain, runnable, delay)
|
||||
.getTaskId();
|
||||
}
|
||||
|
||||
@Override public void taskLaterAsync(Runnable runnable, int delay) {
|
||||
this.bukkitMain.getServer().getScheduler()
|
||||
.runTaskLaterAsynchronously(this.bukkitMain, runnable, delay);
|
||||
}
|
||||
|
||||
@Override public void cancelTask(int task) {
|
||||
if (task != -1) {
|
||||
Bukkit.getScheduler().cancelTask(task);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,441 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.util;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.bukkit.object.BukkitPlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.PlotSquared;
|
||||
import com.github.intellectualsites.plotsquared.plot.config.Captions;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Location;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.RunnableVal;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.schematic.PlotItem;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.MainUtil;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.MathMan;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.StringComparison;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.TaskManager;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.UUIDHandler;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.WorldUtil;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.world.BlockUtil;
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.bukkit.BukkitWorld;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import lombok.NonNull;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.block.data.Directional;
|
||||
import org.bukkit.block.data.type.WallSign;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@SuppressWarnings({"unused", "WeakerAccess"}) public class BukkitUtil extends WorldUtil {
|
||||
|
||||
private static String lastString = null;
|
||||
private static World lastWorld = null;
|
||||
|
||||
private static Player lastPlayer = null;
|
||||
private static PlotPlayer lastPlotPlayer = null;
|
||||
|
||||
public static void removePlayer(String player) {
|
||||
lastPlayer = null;
|
||||
lastPlotPlayer = null;
|
||||
}
|
||||
|
||||
public static PlotPlayer getPlayer(@NonNull final OfflinePlayer op) {
|
||||
if (op.isOnline()) {
|
||||
return getPlayer(op.getPlayer());
|
||||
}
|
||||
final Player player = OfflinePlayerUtil.loadPlayer(op);
|
||||
player.loadData();
|
||||
return new BukkitPlayer(player, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a plot based on the location.
|
||||
*
|
||||
* @param location the location to check
|
||||
* @return plot if found, otherwise it creates a temporary plot
|
||||
* @see Plot
|
||||
*/
|
||||
public static Plot getPlot(org.bukkit.Location location) {
|
||||
if (location == null) {
|
||||
return null;
|
||||
}
|
||||
return getLocation(location).getPlot();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a plot based on the player location.
|
||||
*
|
||||
* @param player the player to check
|
||||
* @return plot if found, otherwise it creates a temporary plot
|
||||
* @see #getPlot(org.bukkit.Location)
|
||||
* @see Plot
|
||||
*/
|
||||
public static Plot getPlot(Player player) {
|
||||
return getPlot(player.getLocation());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get home location.
|
||||
*
|
||||
* @param plot Plot that you want to get the location for
|
||||
* @return plot bottom location
|
||||
* @see Plot
|
||||
*/
|
||||
public static org.bukkit.Location getHomeLocation(Plot plot) {
|
||||
return BukkitUtil.getLocation(plot.getHome());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the PlotPlayer for an offline player.
|
||||
*
|
||||
* <p>Note that this will work if the player is offline, however not all
|
||||
* functionality will work.
|
||||
*
|
||||
* @param player the player to wrap
|
||||
* @return a {@code PlotPlayer}
|
||||
* @see PlotPlayer#wrap(Object)
|
||||
*/
|
||||
public static PlotPlayer wrapPlayer(OfflinePlayer player) {
|
||||
return PlotPlayer.wrap(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the PlotPlayer for a player. The PlotPlayer is usually cached and
|
||||
* will provide useful functions relating to players.
|
||||
*
|
||||
* @param player the player to wrap
|
||||
* @return a {@code PlotPlayer}
|
||||
* @see PlotPlayer#wrap(Object)
|
||||
*/
|
||||
public static PlotPlayer wrapPlayer(Player player) {
|
||||
return PlotPlayer.wrap(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of plots, which the player is able to build in.
|
||||
*
|
||||
* @param player player, for whom we're getting the plots
|
||||
* @return the number of allowed plots
|
||||
*/
|
||||
public static int getAllowedPlots(Player player) {
|
||||
PlotPlayer plotPlayer = PlotPlayer.wrap(player);
|
||||
return plotPlayer.getAllowedPlots();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether or not a player is in a plot.
|
||||
*
|
||||
* @param player who we're checking for
|
||||
* @return true if the player is in a plot, false if not-
|
||||
*/
|
||||
public static boolean isInPlot(Player player) {
|
||||
return getPlot(player) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a collection containing the players plots.
|
||||
*
|
||||
* @param world Specify the world we want to select the plots from
|
||||
* @param player Player, for whom we're getting the plots
|
||||
* @return a set containing the players plots
|
||||
* @see Plot
|
||||
*/
|
||||
public static Set<Plot> getPlayerPlots(String world, Player player) {
|
||||
if (world == null) {
|
||||
return new HashSet<>();
|
||||
}
|
||||
return PlotPlayer.wrap(player).getPlots(world);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message to a player. The message supports color codes.
|
||||
*
|
||||
* @param player the recipient of the message
|
||||
* @param string the message
|
||||
* @see MainUtil#sendMessage(PlotPlayer, String)
|
||||
*/
|
||||
public static void sendMessage(Player player, String string) {
|
||||
MainUtil.sendMessage(BukkitUtil.getPlayer(player), string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player plot count.
|
||||
*
|
||||
* @param world Specify the world we want to select the plots from
|
||||
* @param player Player, for whom we're getting the plot count
|
||||
* @return the number of plots the player has
|
||||
*/
|
||||
public static int getPlayerPlotCount(String world, Player player) {
|
||||
if (world == null) {
|
||||
return 0;
|
||||
}
|
||||
return BukkitUtil.getPlayer(player).getPlotCount(world);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message to a player.
|
||||
*
|
||||
* @param player the recipient of the message
|
||||
* @param caption the message
|
||||
* @see MainUtil#sendMessage(com.github.intellectualsites.plotsquared.commands.CommandCaller, Captions, String...)
|
||||
*/
|
||||
public static void sendMessage(Player player, Captions caption) {
|
||||
MainUtil.sendMessage(BukkitUtil.getPlayer(player), caption);
|
||||
}
|
||||
|
||||
public static PlotPlayer getPlayer(@NonNull final Player player) {
|
||||
if (player == lastPlayer) {
|
||||
return lastPlotPlayer;
|
||||
}
|
||||
final String name = player.getName();
|
||||
final PlotPlayer plotPlayer = UUIDHandler.getPlayer(name);
|
||||
if (plotPlayer != null) {
|
||||
return plotPlayer;
|
||||
}
|
||||
lastPlotPlayer = new BukkitPlayer(player);
|
||||
UUIDHandler.getPlayers().put(name, lastPlotPlayer);
|
||||
lastPlayer = player;
|
||||
return lastPlotPlayer;
|
||||
}
|
||||
|
||||
public static Location getLocation(@NonNull final org.bukkit.Location location) {
|
||||
return new Location(location.getWorld().getName(), MathMan.roundInt(location.getX()),
|
||||
MathMan.roundInt(location.getY()), MathMan.roundInt(location.getZ()));
|
||||
}
|
||||
|
||||
public static Location getLocationFull(@NonNull final org.bukkit.Location location) {
|
||||
return new Location(location.getWorld().getName(), MathMan.roundInt(location.getX()),
|
||||
MathMan.roundInt(location.getY()), MathMan.roundInt(location.getZ()),
|
||||
location.getYaw(), location.getPitch());
|
||||
}
|
||||
|
||||
public static org.bukkit.Location getLocation(@NonNull final Location location) {
|
||||
return new org.bukkit.Location(getWorld(location.getWorld()), location.getX(),
|
||||
location.getY(), location.getZ());
|
||||
}
|
||||
|
||||
public static World getWorld(@NonNull final String string) {
|
||||
return Bukkit.getWorld(string);
|
||||
}
|
||||
|
||||
public static String getWorld(@NonNull final Entity entity) {
|
||||
return entity.getWorld().getName();
|
||||
}
|
||||
|
||||
public static List<Entity> getEntities(@NonNull final String worldName) {
|
||||
World world = getWorld(worldName);
|
||||
if (world != null) {
|
||||
return world.getEntities();
|
||||
} else {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
public static Location getLocation(@NonNull final Entity entity) {
|
||||
final org.bukkit.Location location = entity.getLocation();
|
||||
String world = location.getWorld().getName();
|
||||
return new Location(world, location.getBlockX(), location.getBlockY(),
|
||||
location.getBlockZ());
|
||||
}
|
||||
|
||||
@NotNull public static Location getLocationFull(@NonNull final Entity entity) {
|
||||
final org.bukkit.Location location = entity.getLocation();
|
||||
return new Location(location.getWorld().getName(), MathMan.roundInt(location.getX()),
|
||||
MathMan.roundInt(location.getY()), MathMan.roundInt(location.getZ()), location.getYaw(),
|
||||
location.getPitch());
|
||||
}
|
||||
|
||||
public static Material getMaterial(@NonNull final BlockState plotBlock) {
|
||||
return BukkitAdapter.adapt(plotBlock.getBlockType());
|
||||
}
|
||||
|
||||
@Override public boolean isBlockSame(BlockState block1, BlockState block2) {
|
||||
if (block1.equals(block2)) {
|
||||
return true;
|
||||
}
|
||||
Material mat1 = getMaterial(block1), mat2 = getMaterial(block2);
|
||||
return mat1 == mat2;
|
||||
}
|
||||
|
||||
@Override public boolean isWorld(@NonNull final String worldName) {
|
||||
return getWorld(worldName) != null;
|
||||
}
|
||||
|
||||
@Override public BiomeType getBiome(String world, int x, int z) {
|
||||
return BukkitAdapter.adapt(getWorld(world).getBiome(x, z));
|
||||
}
|
||||
|
||||
@Override public int getHighestBlock(@NonNull final String world, final int x, final int z) {
|
||||
final World bukkitWorld = getWorld(world);
|
||||
// Skip top and bottom block
|
||||
int air = 1;
|
||||
for (int y = bukkitWorld.getMaxHeight() - 1; y >= 0; y--) {
|
||||
Block block = bukkitWorld.getBlockAt(x, y, z);
|
||||
Material type = block.getType();
|
||||
if (type.isSolid()) {
|
||||
if (air > 1) {
|
||||
return y;
|
||||
}
|
||||
air = 0;
|
||||
} else {
|
||||
if (block.isLiquid()) {
|
||||
return y;
|
||||
}
|
||||
air++;
|
||||
}
|
||||
}
|
||||
return bukkitWorld.getMaxHeight() - 1;
|
||||
}
|
||||
|
||||
@Override @Nullable public String[] getSign(@NonNull final Location location) {
|
||||
Block block = getWorld(location.getWorld()).getBlockAt(location.getX(), location.getY(), location.getZ());
|
||||
return TaskManager.IMP.sync(new RunnableVal<String[]>() {
|
||||
@Override public void run(String[] value) {
|
||||
if (block.getState() instanceof Sign) {
|
||||
Sign sign = (Sign) block.getState();
|
||||
this.value = sign.getLines();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override public Location getSpawn(@NonNull final String world) {
|
||||
final org.bukkit.Location temp = getWorld(world).getSpawnLocation();
|
||||
return new Location(world, temp.getBlockX(), temp.getBlockY(), temp.getBlockZ(),
|
||||
temp.getYaw(), temp.getPitch());
|
||||
}
|
||||
|
||||
@Override public void setSpawn(@NonNull final Location location) {
|
||||
final World world = getWorld(location.getWorld());
|
||||
if (world != null) {
|
||||
world.setSpawnLocation(location.getX(), location.getY(), location.getZ());
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void saveWorld(@NonNull final String worldName) {
|
||||
final World world = getWorld(worldName);
|
||||
if (world != null) {
|
||||
world.save();
|
||||
}
|
||||
}
|
||||
|
||||
@Override @SuppressWarnings("deprecation")
|
||||
public void setSign(@NonNull final String worldName, final int x, final int y, final int z,
|
||||
@NonNull final String[] lines) {
|
||||
final World world = getWorld(worldName);
|
||||
final Block block = world.getBlockAt(x, y, z);
|
||||
// block.setType(Material.AIR);
|
||||
final Material type = block.getType();
|
||||
if (type != Material.LEGACY_SIGN && type != Material.LEGACY_WALL_SIGN) {
|
||||
BlockFace facing = BlockFace.EAST;
|
||||
if (world.getBlockAt(x, y, z + 1).getType().isSolid()) {
|
||||
facing = BlockFace.NORTH;
|
||||
} else if (world.getBlockAt(x + 1, y, z).getType().isSolid()) {
|
||||
facing = BlockFace.WEST;
|
||||
} else if (world.getBlockAt(x, y, z - 1).getType().isSolid()) {
|
||||
facing = BlockFace.SOUTH;
|
||||
}
|
||||
if (PlotSquared.get().IMP.getServerVersion()[1] == 13) {
|
||||
block.setType(Material.valueOf("WALL_SIGN"), false);
|
||||
} else {
|
||||
block.setType(Material.valueOf("OAK_WALL_SIGN"), false);
|
||||
}
|
||||
if (!(block.getBlockData() instanceof WallSign)) {
|
||||
PlotSquared.debug(block.getBlockData().getAsString());
|
||||
throw new RuntimeException("Something went wrong generating a sign");
|
||||
}
|
||||
final Directional sign = (Directional) block.getBlockData();
|
||||
sign.setFacing(facing);
|
||||
block.setBlockData(sign, false);
|
||||
}
|
||||
final org.bukkit.block.BlockState blockstate = block.getState();
|
||||
if (blockstate instanceof Sign) {
|
||||
final Sign sign = (Sign) blockstate;
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
sign.setLine(i, lines[i]);
|
||||
}
|
||||
sign.update(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addItems(@NonNull final String worldName, @NonNull final PlotItem items) {
|
||||
final World world = getWorld(worldName);
|
||||
final Block block = world.getBlockAt(items.x, items.y, items.z);
|
||||
final org.bukkit.block.BlockState state = block.getState();
|
||||
if (state instanceof InventoryHolder) {
|
||||
InventoryHolder holder = (InventoryHolder) state;
|
||||
Inventory inv = holder.getInventory();
|
||||
for (int i = 0; i < items.types.length; i++) {
|
||||
// ItemStack item = new ItemStack(LegacyMappings.fromLegacyId(items.id[i]).getMaterial(), items.amount[i], items.data[i]);
|
||||
ItemStack item = new ItemStack(BukkitAdapter.adapt(items.types[i]), items.amount[i]);
|
||||
inv.addItem(item);
|
||||
}
|
||||
state.update(true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public boolean isBlockSolid(@NonNull final BlockState block) {
|
||||
return block.getBlockType().getMaterial().isSolid();
|
||||
}
|
||||
|
||||
@Override public String getClosestMatchingName(@NonNull final BlockState block) {
|
||||
try {
|
||||
return getMaterial(block).name();
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override @Nullable
|
||||
public StringComparison<BlockState>.ComparisonResult getClosestBlock(String name) {
|
||||
BlockState state = BlockUtil.get(name);
|
||||
return new StringComparison<BlockState>().new ComparisonResult(1, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBiomes(@NonNull final String worldName, @NonNull final CuboidRegion region,
|
||||
@NonNull final BiomeType biomeType) {
|
||||
final World world = getWorld(worldName);
|
||||
final Biome biome = BukkitAdapter.adapt(biomeType);
|
||||
for (int x = region.getMinimumPoint().getX(); x <= region.getMaximumPoint().getX(); x++) {
|
||||
for (int z = region.getMinimumPoint().getZ(); z <= region.getMaximumPoint().getZ(); z++) {
|
||||
world.setBiome(x, z, biome);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public com.sk89q.worldedit.world.World getWeWorld(String world) {
|
||||
return new BukkitWorld(Bukkit.getWorld(world));
|
||||
}
|
||||
|
||||
@Override public BlockState getBlock(@NonNull final Location location) {
|
||||
final World world = getWorld(location.getWorld());
|
||||
final Block block = world.getBlockAt(location.getX(), location.getY(), location.getZ());
|
||||
return BukkitAdapter.asBlockType(block.getType()).getDefaultState();
|
||||
}
|
||||
|
||||
@Override public String getMainWorld() {
|
||||
return Bukkit.getWorlds().get(0).getName();
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.util;
|
||||
|
||||
public class BukkitVersion {
|
||||
public static int[] v1_13_2 = {1, 13, 2};
|
||||
}
|
@ -1,714 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.util;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.logging.Level;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
/**
|
||||
* bStats collects some data for plugin authors.
|
||||
* <p>
|
||||
* Check out https://bStats.org/ to learn more about bStats!
|
||||
*/
|
||||
@SuppressWarnings({"WeakerAccess", "unused"})
|
||||
public class Metrics {
|
||||
|
||||
static {
|
||||
// You can use the property to disable the check in your test environment
|
||||
if (System.getProperty("bstats.relocatecheck") == null || !System.getProperty("bstats.relocatecheck").equals("false")) {
|
||||
// Maven's Relocate is clever and changes strings, too. So we have to use this little "trick" ... :D
|
||||
final String defaultPackage = new String(
|
||||
new byte[]{'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'k', 'k', 'i', 't'});
|
||||
final String examplePackage = new String(new byte[]{'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
|
||||
// We want to make sure nobody just copy & pastes the example and use the wrong package names
|
||||
|
||||
if (Metrics.class.getPackage().getName().equals(defaultPackage) || Metrics.class.getPackage().getName().equals(examplePackage)) {
|
||||
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The version of this bStats class
|
||||
public static final int B_STATS_VERSION = 1;
|
||||
|
||||
// The url to which the data is sent
|
||||
private static final String URL = "https://bStats.org/submitData/bukkit";
|
||||
|
||||
// Is bStats enabled on this server?
|
||||
private boolean enabled;
|
||||
|
||||
// Should failed requests be logged?
|
||||
private static boolean logFailedRequests;
|
||||
|
||||
// Should the sent data be logged?
|
||||
private static boolean logSentData;
|
||||
|
||||
// Should the response text be logged?
|
||||
private static boolean logResponseStatusText;
|
||||
|
||||
// The uuid of the server
|
||||
private static String serverUUID;
|
||||
|
||||
// The plugin
|
||||
private final Plugin plugin;
|
||||
|
||||
// The plugin id
|
||||
private final int bstatsId;
|
||||
|
||||
// A list with all custom charts
|
||||
private final List<CustomChart> charts = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param plugin The plugin which stats should be submitted.
|
||||
* @param bstatsId The ID of the plugin. It can be found in the url when you open the plugin on bStats.
|
||||
*/
|
||||
public Metrics(Plugin plugin, int bstatsId) {
|
||||
if (plugin == null) {
|
||||
throw new IllegalArgumentException("Plugin cannot be null!");
|
||||
}
|
||||
this.plugin = plugin;
|
||||
this.bstatsId = bstatsId;
|
||||
|
||||
// Get the config file
|
||||
File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
|
||||
File configFile = new File(bStatsFolder, "config.yml");
|
||||
YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
|
||||
|
||||
// Check if the config file exists
|
||||
if (!config.isSet("serverUuid")) {
|
||||
|
||||
// Add default values
|
||||
config.addDefault("enabled", true);
|
||||
// Every server gets it's unique random id.
|
||||
config.addDefault("serverUuid", UUID.randomUUID().toString());
|
||||
// Should failed request be logged?
|
||||
config.addDefault("logFailedRequests", false);
|
||||
// Should the sent data be logged?
|
||||
config.addDefault("logSentData", false);
|
||||
// Should the response text be logged?
|
||||
config.addDefault("logResponseStatusText", false);
|
||||
|
||||
// Inform the server owners about bStats
|
||||
config.options().header(
|
||||
"bStats collects some data for plugin authors like how many servers are using their plugins.\n" +
|
||||
"To honor their work, you should not disable it.\n" +
|
||||
"This has nearly no effect on the server performance!\n" +
|
||||
"Check out https://bStats.org/ to learn more :)"
|
||||
).copyDefaults(true);
|
||||
try {
|
||||
config.save(configFile);
|
||||
} catch (IOException ignored) { }
|
||||
}
|
||||
|
||||
// Load the data
|
||||
enabled = config.getBoolean("enabled", true);
|
||||
serverUUID = config.getString("serverUuid");
|
||||
logFailedRequests = config.getBoolean("logFailedRequests", false);
|
||||
logSentData = config.getBoolean("logSentData", false);
|
||||
logResponseStatusText = config.getBoolean("logResponseStatusText", false);
|
||||
|
||||
if (enabled) {
|
||||
boolean found = false;
|
||||
// Search for all other bStats Metrics classes to see if we are the first one
|
||||
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
|
||||
try {
|
||||
service.getField("B_STATS_VERSION"); // Our identifier :)
|
||||
found = true; // We aren't the first
|
||||
break;
|
||||
} catch (NoSuchFieldException ignored) { }
|
||||
}
|
||||
// Register our service
|
||||
Bukkit.getServicesManager().register(Metrics.class, this, plugin, ServicePriority.Normal);
|
||||
if (!found) {
|
||||
// We are the first!
|
||||
startSubmitting();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if bStats is enabled.
|
||||
*
|
||||
* @return Whether bStats is enabled or not.
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a custom chart.
|
||||
*
|
||||
* @param chart The chart to add.
|
||||
*/
|
||||
public void addCustomChart(CustomChart chart) {
|
||||
if (chart == null) {
|
||||
throw new IllegalArgumentException("Chart cannot be null!");
|
||||
}
|
||||
charts.add(chart);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the Scheduler which submits our data every 30 minutes.
|
||||
*/
|
||||
private void startSubmitting() {
|
||||
final Timer timer = new Timer(true); // We use a timer cause the Bukkit scheduler is affected by server lags
|
||||
timer.scheduleAtFixedRate(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!plugin.isEnabled()) { // Plugin was disabled
|
||||
timer.cancel();
|
||||
return;
|
||||
}
|
||||
// Nevertheless we want our code to run in the Bukkit main thread, so we have to use the Bukkit scheduler
|
||||
// Don't be afraid! The connection to the bStats server is still async, only the stats collection is sync ;)
|
||||
Bukkit.getScheduler().runTask(plugin, () -> submitData());
|
||||
}
|
||||
}, 1000 * 60 * 5, 1000 * 60 * 30);
|
||||
// Submit the data every 30 minutes, first time after 5 minutes to give other plugins enough time to start
|
||||
// WARNING: Changing the frequency has no effect but your plugin WILL be blocked/deleted!
|
||||
// WARNING: Just don't do it!
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the plugin specific data.
|
||||
* This method is called using Reflection.
|
||||
*
|
||||
* @return The plugin specific data.
|
||||
*/
|
||||
public JSONObject getPluginData() {
|
||||
JSONObject data = new JSONObject();
|
||||
|
||||
String pluginName = plugin.getDescription().getName();
|
||||
String pluginVersion = plugin.getDescription().getVersion();
|
||||
|
||||
data.put("pluginName", pluginName); // Append the name of the plugin
|
||||
data.put("id", bstatsId); // Append the id of the plugin
|
||||
data.put("pluginVersion", pluginVersion); // Append the version of the plugin
|
||||
JSONArray customCharts = new JSONArray();
|
||||
for (CustomChart customChart : charts) {
|
||||
// Add the data of the custom charts
|
||||
JSONObject chart = customChart.getRequestJsonObject();
|
||||
if (chart == null) { // If the chart is null, we skip it
|
||||
continue;
|
||||
}
|
||||
customCharts.add(chart);
|
||||
}
|
||||
data.put("customCharts", customCharts);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the server specific data.
|
||||
*
|
||||
* @return The server specific data.
|
||||
*/
|
||||
private JSONObject getServerData() {
|
||||
// Minecraft specific data
|
||||
int playerAmount;
|
||||
try {
|
||||
// Around MC 1.8 the return type was changed to a collection from an array,
|
||||
// This fixes java.lang.NoSuchMethodError: org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection;
|
||||
Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers");
|
||||
playerAmount = onlinePlayersMethod.getReturnType().equals(Collection.class)
|
||||
? ((Collection<?>) onlinePlayersMethod.invoke(Bukkit.getServer())).size()
|
||||
: ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length;
|
||||
} catch (Exception e) {
|
||||
playerAmount = Bukkit.getOnlinePlayers().size(); // Just use the new method if the Reflection failed
|
||||
}
|
||||
int onlineMode = Bukkit.getOnlineMode() ? 1 : 0;
|
||||
String bukkitVersion = Bukkit.getVersion();
|
||||
|
||||
// OS/Java specific data
|
||||
String javaVersion = System.getProperty("java.version");
|
||||
String osName = System.getProperty("os.name");
|
||||
String osArch = System.getProperty("os.arch");
|
||||
String osVersion = System.getProperty("os.version");
|
||||
int coreCount = Runtime.getRuntime().availableProcessors();
|
||||
|
||||
JSONObject data = new JSONObject();
|
||||
|
||||
data.put("serverUUID", serverUUID);
|
||||
|
||||
data.put("playerAmount", playerAmount);
|
||||
data.put("onlineMode", onlineMode);
|
||||
data.put("bukkitVersion", bukkitVersion);
|
||||
|
||||
data.put("javaVersion", javaVersion);
|
||||
data.put("osName", osName);
|
||||
data.put("osArch", osArch);
|
||||
data.put("osVersion", osVersion);
|
||||
data.put("coreCount", coreCount);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects the data and sends it afterwards.
|
||||
*/
|
||||
private void submitData() {
|
||||
final JSONObject data = getServerData();
|
||||
|
||||
JSONArray pluginData = new JSONArray();
|
||||
// Search for all other bStats Metrics classes to get their plugin data
|
||||
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
|
||||
try {
|
||||
service.getField("B_STATS_VERSION"); // Our identifier :)
|
||||
|
||||
for (RegisteredServiceProvider<?> provider : Bukkit.getServicesManager().getRegistrations(service)) {
|
||||
try {
|
||||
pluginData.add(provider.getService().getMethod("getPluginData").invoke(provider.getProvider()));
|
||||
} catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { }
|
||||
}
|
||||
} catch (NoSuchFieldException ignored) { }
|
||||
}
|
||||
|
||||
data.put("plugins", pluginData);
|
||||
|
||||
// Create a new thread for the connection to the bStats server
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
// Send the data
|
||||
sendData(plugin, data);
|
||||
} catch (Exception e) {
|
||||
// Something went wrong! :(
|
||||
if (logFailedRequests) {
|
||||
plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " + plugin.getName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the data to the bStats server.
|
||||
*
|
||||
* @param plugin Any plugin. It's just used to get a logger instance.
|
||||
* @param data The data to send.
|
||||
* @throws Exception If the request failed.
|
||||
*/
|
||||
private static void sendData(Plugin plugin, JSONObject data) throws Exception {
|
||||
if (data == null) {
|
||||
throw new IllegalArgumentException("Data cannot be null!");
|
||||
}
|
||||
if (Bukkit.isPrimaryThread()) {
|
||||
throw new IllegalAccessException("This method must not be called from the main thread!");
|
||||
}
|
||||
if (logSentData) {
|
||||
plugin.getLogger().info("Sending data to bStats: " + data.toString());
|
||||
}
|
||||
HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection();
|
||||
|
||||
// Compress the data to save bandwidth
|
||||
byte[] compressedData = compress(data.toString());
|
||||
|
||||
// Add headers
|
||||
connection.setRequestMethod("POST");
|
||||
connection.addRequestProperty("Accept", "application/json");
|
||||
connection.addRequestProperty("Connection", "close");
|
||||
connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request
|
||||
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
|
||||
connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format
|
||||
connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION);
|
||||
|
||||
// Send data
|
||||
connection.setDoOutput(true);
|
||||
DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
|
||||
outputStream.write(compressedData);
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
|
||||
InputStream inputStream = connection.getInputStream();
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
String line;
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
builder.append(line);
|
||||
}
|
||||
bufferedReader.close();
|
||||
if (logResponseStatusText) {
|
||||
plugin.getLogger().info("Sent data to bStats and received response: " + builder.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gzips the given String.
|
||||
*
|
||||
* @param str The string to gzip.
|
||||
* @return The gzipped String.
|
||||
* @throws IOException If the compression failed.
|
||||
*/
|
||||
private static byte[] compress(final String str) throws IOException {
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
GZIPOutputStream gzip = new GZIPOutputStream(outputStream);
|
||||
gzip.write(str.getBytes(StandardCharsets.UTF_8));
|
||||
gzip.close();
|
||||
return outputStream.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom chart.
|
||||
*/
|
||||
public static abstract class CustomChart {
|
||||
|
||||
// The id of the chart
|
||||
final String chartId;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
*/
|
||||
CustomChart(String chartId) {
|
||||
if (chartId == null || chartId.isEmpty()) {
|
||||
throw new IllegalArgumentException("ChartId cannot be null or empty!");
|
||||
}
|
||||
this.chartId = chartId;
|
||||
}
|
||||
|
||||
private JSONObject getRequestJsonObject() {
|
||||
JSONObject chart = new JSONObject();
|
||||
chart.put("chartId", chartId);
|
||||
try {
|
||||
JSONObject data = getChartData();
|
||||
if (data == null) {
|
||||
// If the data is null we don't send the chart.
|
||||
return null;
|
||||
}
|
||||
chart.put("data", data);
|
||||
} catch (Throwable t) {
|
||||
if (logFailedRequests) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Failed to get data for custom chart with id " + chartId, t);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return chart;
|
||||
}
|
||||
|
||||
protected abstract JSONObject getChartData() throws Exception;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom simple pie.
|
||||
*/
|
||||
public static class SimplePie extends CustomChart {
|
||||
|
||||
private final Callable<String> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SimplePie(String chartId, Callable<String> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
String value = callable.call();
|
||||
if (value == null || value.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.put("value", value);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom advanced pie.
|
||||
*/
|
||||
public static class AdvancedPie extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Integer>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public AdvancedPie(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
JSONObject values = new JSONObject();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
if (entry.getValue() == 0) {
|
||||
continue; // Skip this invalid
|
||||
}
|
||||
allSkipped = false;
|
||||
values.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.put("values", values);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom drilldown pie.
|
||||
*/
|
||||
public static class DrilldownPie extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Map<String, Integer>>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public DrilldownPie(String chartId, Callable<Map<String, Map<String, Integer>>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
JSONObject values = new JSONObject();
|
||||
Map<String, Map<String, Integer>> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean reallyAllSkipped = true;
|
||||
for (Map.Entry<String, Map<String, Integer>> entryValues : map.entrySet()) {
|
||||
JSONObject value = new JSONObject();
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> valueEntry : map.get(entryValues.getKey()).entrySet()) {
|
||||
value.put(valueEntry.getKey(), valueEntry.getValue());
|
||||
allSkipped = false;
|
||||
}
|
||||
if (!allSkipped) {
|
||||
reallyAllSkipped = false;
|
||||
values.put(entryValues.getKey(), value);
|
||||
}
|
||||
}
|
||||
if (reallyAllSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.put("values", values);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom single line chart.
|
||||
*/
|
||||
public static class SingleLineChart extends CustomChart {
|
||||
|
||||
private final Callable<Integer> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SingleLineChart(String chartId, Callable<Integer> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
int value = callable.call();
|
||||
if (value == 0) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.put("value", value);
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom multi line chart.
|
||||
*/
|
||||
public static class MultiLineChart extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Integer>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public MultiLineChart(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
JSONObject values = new JSONObject();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
if (entry.getValue() == 0) {
|
||||
continue; // Skip this invalid
|
||||
}
|
||||
allSkipped = false;
|
||||
values.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.put("values", values);
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom simple bar chart.
|
||||
*/
|
||||
public static class SimpleBarChart extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Integer>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SimpleBarChart(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
JSONObject values = new JSONObject();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
JSONArray categoryValues = new JSONArray();
|
||||
categoryValues.add(entry.getValue());
|
||||
values.put(entry.getKey(), categoryValues);
|
||||
}
|
||||
data.put("values", values);
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom advanced bar chart.
|
||||
*/
|
||||
public static class AdvancedBarChart extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, int[]>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public AdvancedBarChart(String chartId, Callable<Map<String, int[]>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JSONObject getChartData() throws Exception {
|
||||
JSONObject data = new JSONObject();
|
||||
JSONObject values = new JSONObject();
|
||||
Map<String, int[]> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, int[]> entry : map.entrySet()) {
|
||||
if (entry.getValue().length == 0) {
|
||||
continue; // Skip this invalid
|
||||
}
|
||||
allSkipped = false;
|
||||
JSONArray categoryValues = new JSONArray();
|
||||
for (int categoryValue : entry.getValue()) {
|
||||
categoryValues.add(categoryValue);
|
||||
}
|
||||
values.put(entry.getKey(), categoryValues);
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.put("values", values);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,87 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.util;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.callConstructor;
|
||||
import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.callMethod;
|
||||
import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.getCbClass;
|
||||
import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.getNmsClass;
|
||||
import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.getUtilClass;
|
||||
import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.makeConstructor;
|
||||
import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.makeMethod;
|
||||
|
||||
public class OfflinePlayerUtil {
|
||||
|
||||
public static Player loadPlayer(OfflinePlayer player) {
|
||||
if (player == null) {
|
||||
return null;
|
||||
}
|
||||
if (player instanceof Player) {
|
||||
return (Player) player;
|
||||
}
|
||||
return loadPlayer(player.getUniqueId(), player.getName());
|
||||
}
|
||||
|
||||
private static Player loadPlayer(UUID id, String name) {
|
||||
Object server = getMinecraftServer();
|
||||
Object interactManager = newPlayerInteractManager();
|
||||
Object worldServer = getWorldServer();
|
||||
Object profile = newGameProfile(id, name);
|
||||
Class<?> entityPlayerClass = getNmsClass("EntityPlayer");
|
||||
Constructor entityPlayerConstructor =
|
||||
makeConstructor(entityPlayerClass, getNmsClass("MinecraftServer"),
|
||||
getNmsClass("WorldServer"), getUtilClass("com.mojang.authlib.GameProfile"),
|
||||
getNmsClass("PlayerInteractManager"));
|
||||
Object entityPlayer =
|
||||
callConstructor(entityPlayerConstructor, server, worldServer, profile, interactManager);
|
||||
return (Player) getBukkitEntity(entityPlayer);
|
||||
}
|
||||
|
||||
private static Object newGameProfile(UUID id, String name) {
|
||||
Class<?> gameProfileClass = getUtilClass("com.mojang.authlib.GameProfile");
|
||||
if (gameProfileClass == null) { //Before uuids
|
||||
return name;
|
||||
}
|
||||
Constructor gameProfileConstructor =
|
||||
makeConstructor(gameProfileClass, UUID.class, String.class);
|
||||
if (gameProfileConstructor == null) { //Version has string constructor
|
||||
gameProfileConstructor = makeConstructor(gameProfileClass, String.class, String.class);
|
||||
return callConstructor(gameProfileConstructor, id.toString(), name);
|
||||
} else { //Version has uuid constructor
|
||||
return callConstructor(gameProfileConstructor, id, name);
|
||||
}
|
||||
}
|
||||
|
||||
private static Object newPlayerInteractManager() {
|
||||
Object worldServer = getWorldServer();
|
||||
Class<?> playerInteractClass = getNmsClass("PlayerInteractManager");
|
||||
Class<?> worldClass = getNmsClass("World");
|
||||
Constructor c = makeConstructor(playerInteractClass, worldClass);
|
||||
return callConstructor(c, worldServer);
|
||||
}
|
||||
|
||||
private static Object getWorldServer() {
|
||||
Object server = getMinecraftServer();
|
||||
Class<?> minecraftServerClass = getNmsClass("MinecraftServer");
|
||||
Method getWorldServer = makeMethod(minecraftServerClass, "getWorldServer", int.class);
|
||||
return callMethod(getWorldServer, server, 0);
|
||||
}
|
||||
|
||||
//NMS Utils
|
||||
|
||||
private static Object getMinecraftServer() {
|
||||
return callMethod(makeMethod(getCbClass("CraftServer"), "getServer"), Bukkit.getServer());
|
||||
}
|
||||
|
||||
private static Entity getBukkitEntity(Object o) {
|
||||
Method getBukkitEntity = makeMethod(o.getClass(), "getBukkitEntity");
|
||||
return callMethod(getBukkitEntity, o);
|
||||
}
|
||||
}
|
@ -1,142 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.util;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.bukkit.object.BukkitPlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.PlotSquared;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Location;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Plot;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.RefClass;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.RefConstructor;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.RefField;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.RefMethod;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.TaskManager;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.UUIDHandler;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import static com.github.intellectualsites.plotsquared.plot.util.ReflectionUtils.getRefClass;
|
||||
|
||||
/**
|
||||
* An utility that can be used to send chunks, rather than using bukkit code
|
||||
* to do so (uses heavy NMS).
|
||||
*/
|
||||
public class SendChunk {
|
||||
|
||||
private final RefMethod methodGetHandlePlayer;
|
||||
private final RefMethod methodGetHandleChunk;
|
||||
private final RefConstructor mapChunk;
|
||||
private final RefField connection;
|
||||
private final RefMethod send;
|
||||
private final RefMethod methodInitLighting;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public SendChunk() throws ClassNotFoundException, NoSuchMethodException, NoSuchFieldException {
|
||||
RefClass classCraftPlayer = getRefClass("{cb}.entity.CraftPlayer");
|
||||
this.methodGetHandlePlayer = classCraftPlayer.getMethod("getHandle");
|
||||
RefClass classCraftChunk = getRefClass("{cb}.CraftChunk");
|
||||
this.methodGetHandleChunk = classCraftChunk.getMethod("getHandle");
|
||||
RefClass classChunk = getRefClass("{nms}.Chunk");
|
||||
this.methodInitLighting = classChunk.getMethod("initLighting");
|
||||
RefClass classMapChunk = getRefClass("{nms}.PacketPlayOutMapChunk");
|
||||
this.mapChunk = classMapChunk.getConstructor(classChunk.getRealClass(), int.class);
|
||||
RefClass classEntityPlayer = getRefClass("{nms}.EntityPlayer");
|
||||
this.connection = classEntityPlayer.getField("playerConnection");
|
||||
RefClass classPacket = getRefClass("{nms}.Packet");
|
||||
RefClass classConnection = getRefClass("{nms}.PlayerConnection");
|
||||
this.send = classConnection.getMethod("sendPacket", classPacket.getRealClass());
|
||||
}
|
||||
|
||||
public void sendChunk(Collection<Chunk> input) {
|
||||
HashSet<Chunk> chunks = new HashSet<>(input);
|
||||
HashMap<String, ArrayList<Chunk>> map = new HashMap<>();
|
||||
int view = Bukkit.getServer().getViewDistance();
|
||||
for (Chunk chunk : chunks) {
|
||||
String world = chunk.getWorld().getName();
|
||||
ArrayList<Chunk> list = map.computeIfAbsent(world, k -> new ArrayList<>());
|
||||
list.add(chunk);
|
||||
Object c = this.methodGetHandleChunk.of(chunk).call();
|
||||
this.methodInitLighting.of(c).call();
|
||||
}
|
||||
for (Entry<String, PlotPlayer> entry : UUIDHandler.getPlayers().entrySet()) {
|
||||
PlotPlayer pp = entry.getValue();
|
||||
Plot plot = pp.getCurrentPlot();
|
||||
Location location = null;
|
||||
String world;
|
||||
if (plot != null) {
|
||||
world = plot.getWorldName();
|
||||
} else {
|
||||
location = pp.getLocation();
|
||||
world = location.getWorld();
|
||||
}
|
||||
ArrayList<Chunk> list = map.get(world);
|
||||
if (list == null) {
|
||||
continue;
|
||||
}
|
||||
if (location == null) {
|
||||
location = pp.getLocation();
|
||||
}
|
||||
int chunkX = location.getX() >> 4;
|
||||
int chunkZ = location.getZ() >> 4;
|
||||
Player player = ((BukkitPlayer) pp).player;
|
||||
Object entity = this.methodGetHandlePlayer.of(player).call();
|
||||
|
||||
for (Chunk chunk : list) {
|
||||
int dx = Math.abs(chunkX - chunk.getX());
|
||||
int dz = Math.abs(chunkZ - chunk.getZ());
|
||||
if ((dx > view) || (dz > view)) {
|
||||
continue;
|
||||
}
|
||||
Object c = this.methodGetHandleChunk.of(chunk).call();
|
||||
chunks.remove(chunk);
|
||||
Object con = this.connection.of(entity).get();
|
||||
Object packet = null;
|
||||
try {
|
||||
packet = this.mapChunk.create(c, 65535);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
if (packet == null) {
|
||||
PlotSquared.debug("Error with PacketPlayOutMapChunk reflection.");
|
||||
}
|
||||
this.send.of(con).call(packet);
|
||||
}
|
||||
}
|
||||
for (final Chunk chunk : chunks) {
|
||||
TaskManager.runTask(() -> {
|
||||
try {
|
||||
chunk.unload(true);
|
||||
} catch (Throwable ignored) {
|
||||
String worldName = chunk.getWorld().getName();
|
||||
PlotSquared.debug(
|
||||
"$4Could not save chunk: " + worldName + ';' + chunk.getX() + ";" + chunk
|
||||
.getZ());
|
||||
PlotSquared.debug("$3 - $4File may be open in another process (e.g. MCEdit)");
|
||||
PlotSquared.debug("$3 - $4" + worldName + "/level.dat or " + worldName
|
||||
+ "/level_old.dat may be corrupt (try repairing or removing these)");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void sendChunk(String worldName, Collection<BlockVector2> chunkLocations) {
|
||||
World myWorld = Bukkit.getWorld(worldName);
|
||||
ArrayList<Chunk> chunks = new ArrayList<>();
|
||||
for (BlockVector2 loc : chunkLocations) {
|
||||
if (myWorld.isChunkLoaded(loc.getX(), loc.getZ())) {
|
||||
PaperLib.getChunkAtAsync(myWorld, loc.getX(), loc.getZ()).thenAccept(chunks::add);
|
||||
}
|
||||
}
|
||||
sendChunk(chunks);
|
||||
}
|
||||
}
|
@ -1,147 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.util.block;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.bukkit.object.BukkitBlockUtil;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.object.schematic.StateWrapper;
|
||||
import com.github.intellectualsites.plotsquared.plot.PlotSquared;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.MainUtil;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.block.BasicLocalBlockQueue;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.world.BlockUtil;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import lombok.NonNull;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
public class BukkitLocalQueue extends BasicLocalBlockQueue {
|
||||
|
||||
public BukkitLocalQueue(String world) {
|
||||
super(world);
|
||||
}
|
||||
|
||||
@Override public LocalChunk getLocalChunk(int x, int z) {
|
||||
return new BasicLocalChunk(this, x, z) {
|
||||
// Custom stuff?
|
||||
};
|
||||
}
|
||||
|
||||
@Override public void optimize() {
|
||||
|
||||
}
|
||||
|
||||
@Override public BlockState getBlock(int x, int y, int z) {
|
||||
World worldObj = Bukkit.getWorld(getWorld());
|
||||
if (worldObj != null) {
|
||||
Block block = worldObj.getBlockAt(x, y, z);
|
||||
return BukkitBlockUtil.get(block);
|
||||
} else {
|
||||
return BlockUtil.get(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void refreshChunk(int x, int z) {
|
||||
World worldObj = Bukkit.getWorld(getWorld());
|
||||
if (worldObj != null) {
|
||||
worldObj.refreshChunk(x, z);
|
||||
} else {
|
||||
PlotSquared.debug("Error Refreshing Chunk");
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void fixChunkLighting(int x, int z) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override public final void regenChunk(int x, int z) {
|
||||
World worldObj = Bukkit.getWorld(getWorld());
|
||||
if (worldObj != null) {
|
||||
worldObj.regenerateChunk(x, z);
|
||||
} else {
|
||||
PlotSquared.debug("Error Regenerating Chunk");
|
||||
}
|
||||
}
|
||||
|
||||
@Override public final void setComponents(LocalChunk lc)
|
||||
throws ExecutionException, InterruptedException {
|
||||
setBaseBlocks(lc);
|
||||
}
|
||||
|
||||
public void setBaseBlocks(LocalChunk localChunk) {
|
||||
World worldObj = Bukkit.getWorld(getWorld());
|
||||
if (worldObj == null) {
|
||||
throw new NullPointerException("World cannot be null.");
|
||||
}
|
||||
PaperLib.getChunkAtAsync(worldObj, localChunk.getX(), localChunk.getZ(), true)
|
||||
.thenAccept(chunk -> {
|
||||
for (int layer = 0; layer < localChunk.baseblocks.length; layer++) {
|
||||
BaseBlock[] blocksLayer = localChunk.baseblocks[layer];
|
||||
if (blocksLayer != null) {
|
||||
for (int j = 0; j < blocksLayer.length; j++) {
|
||||
if (blocksLayer[j] != null) {
|
||||
BaseBlock block = blocksLayer[j];
|
||||
int x = MainUtil.x_loc[layer][j];
|
||||
int y = MainUtil.y_loc[layer][j];
|
||||
int z = MainUtil.z_loc[layer][j];
|
||||
|
||||
BlockData blockData = BukkitAdapter.adapt(block);
|
||||
|
||||
Block existing = chunk.getBlock(x, y, z);
|
||||
if (BukkitBlockUtil.get(existing).equals(block) && existing
|
||||
.getBlockData().matches(blockData)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
existing.setType(BukkitAdapter.adapt(block.getBlockType()), false);
|
||||
existing.setBlockData(blockData, false);
|
||||
if (block.hasNbtData()) {
|
||||
CompoundTag tag = block.getNbtData();
|
||||
StateWrapper sw = new StateWrapper(tag);
|
||||
|
||||
sw.restoreTag(worldObj.getName(), existing.getX(),
|
||||
existing.getY(), existing.getZ());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setMaterial(@NonNull final BlockState plotBlock, @NonNull final Block block) {
|
||||
Material material = BukkitAdapter.adapt(plotBlock.getBlockType());
|
||||
block.setType(material, false);
|
||||
}
|
||||
|
||||
private boolean equals(@NonNull final BlockState plotBlock, @NonNull final Block block) {
|
||||
return plotBlock.equals(BukkitBlockUtil.get(block));
|
||||
}
|
||||
|
||||
public void setBiomes(LocalChunk lc) {
|
||||
if (lc.biomes != null) {
|
||||
World worldObj = Bukkit.getWorld(getWorld());
|
||||
int bx = lc.getX() << 4;
|
||||
int bz = lc.getX() << 4;
|
||||
for (int x = 0; x < lc.biomes.length; x++) {
|
||||
BiomeType[] biomes2 = lc.biomes[x];
|
||||
if (biomes2 != null) {
|
||||
for (BiomeType biomeStr : biomes2) {
|
||||
if (biomeStr != null) {
|
||||
Biome biome = BukkitAdapter.adapt(biomeStr);
|
||||
worldObj.setBiome(bx, bz, biome);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,191 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.util.block;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.bukkit.object.BukkitBlockUtil;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.util.BukkitUtil;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.ChunkWrapper;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.Location;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.MainUtil;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.block.ScopedLocalBlockQueue;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.world.PatternUtil;
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.generator.ChunkGenerator.BiomeGrid;
|
||||
import org.bukkit.generator.ChunkGenerator.ChunkData;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class GenChunk extends ScopedLocalBlockQueue {
|
||||
|
||||
public final Biome[] biomes;
|
||||
public BlockState[][] result;
|
||||
public BiomeGrid biomeGrid;
|
||||
public Chunk chunk;
|
||||
public String world;
|
||||
public int chunkX;
|
||||
public int chunkZ;
|
||||
@Getter @Setter private ChunkData chunkData = null;
|
||||
|
||||
public GenChunk() {
|
||||
super(null, new Location(null, 0, 0, 0), new Location(null, 15, 255, 15));
|
||||
this.biomes = Biome.values();
|
||||
}
|
||||
|
||||
public Chunk getChunk() {
|
||||
if (chunk == null) {
|
||||
World worldObj = BukkitUtil.getWorld(world);
|
||||
if (worldObj != null) {
|
||||
this.chunk = worldObj.getChunkAt(chunkX, chunkZ);
|
||||
}
|
||||
}
|
||||
return chunk;
|
||||
}
|
||||
|
||||
public void setChunk(Chunk chunk) {
|
||||
this.chunk = chunk;
|
||||
}
|
||||
|
||||
public void setChunk(ChunkWrapper wrap) {
|
||||
chunk = null;
|
||||
world = wrap.world;
|
||||
chunkX = wrap.x;
|
||||
chunkZ = wrap.z;
|
||||
}
|
||||
|
||||
@Override public void fillBiome(BiomeType biomeType) {
|
||||
if (biomeGrid == null) {
|
||||
return;
|
||||
}
|
||||
Biome biome = BukkitAdapter.adapt(biomeType);
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
this.biomeGrid.setBiome(x, z, biome);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void setCuboid(Location pos1, Location pos2, BlockState block) {
|
||||
if (result != null && pos1.getX() == 0 && pos1.getZ() == 0 && pos2.getX() == 15
|
||||
&& pos2.getZ() == 15) {
|
||||
for (int y = pos1.getY(); y <= pos2.getY(); y++) {
|
||||
int layer = y >> 4;
|
||||
BlockState[] data = result[layer];
|
||||
if (data == null) {
|
||||
result[layer] = data = new BlockState[4096];
|
||||
}
|
||||
int start = y << 8;
|
||||
int end = start + 256;
|
||||
Arrays.fill(data, start, end, block);
|
||||
}
|
||||
}
|
||||
int minX = Math.min(pos1.getX(), pos2.getX());
|
||||
int minY = Math.min(pos1.getY(), pos2.getY());
|
||||
int minZ = Math.min(pos1.getZ(), pos2.getZ());
|
||||
int maxX = Math.max(pos1.getX(), pos2.getX());
|
||||
int maxY = Math.max(pos1.getY(), pos2.getY());
|
||||
int maxZ = Math.max(pos1.getZ(), pos2.getZ());
|
||||
chunkData.setRegion(minX, minY, minZ, maxX + 1, maxY + 1, maxZ + 1, BukkitAdapter.adapt(block));
|
||||
}
|
||||
|
||||
@Override public boolean setBiome(int x, int z, BiomeType biomeType) {
|
||||
return setBiome(x, z, BukkitAdapter.adapt(biomeType));
|
||||
}
|
||||
|
||||
public boolean setBiome(int x, int z, Biome biome) {
|
||||
if (this.biomeGrid != null) {
|
||||
this.biomeGrid.setBiome(x, z, biome);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public boolean setBlock(int x, int y, int z, Pattern pattern) {
|
||||
return setBlock(x, y, z, PatternUtil.apply(pattern, x, y, z));
|
||||
}
|
||||
|
||||
@Override public boolean setBlock(int x, int y, int z, BlockState id) {
|
||||
if (this.result == null) {
|
||||
this.chunkData.setBlock(x, y, z, BukkitAdapter.adapt(id));
|
||||
return true;
|
||||
}
|
||||
this.chunkData.setBlock(x, y, z, BukkitAdapter.adapt(id));
|
||||
this.storeCache(x, y, z, id);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void storeCache(final int x, final int y, final int z, final BlockState id) {
|
||||
int i = MainUtil.CACHE_I[y][x][z];
|
||||
BlockState[] v = this.result[i];
|
||||
if (v == null) {
|
||||
this.result[i] = v = new BlockState[4096];
|
||||
}
|
||||
int j = MainUtil.CACHE_J[y][x][z];
|
||||
v[j] = id;
|
||||
}
|
||||
|
||||
@Override public boolean setBlock(int x, int y, int z, BaseBlock id) {
|
||||
if (this.result == null) {
|
||||
this.chunkData.setBlock(x, y, z, BukkitAdapter.adapt(id));
|
||||
return true;
|
||||
}
|
||||
this.chunkData.setBlock(x, y, z, BukkitAdapter.adapt(id));
|
||||
this.storeCache(x, y, z, id.toImmutableState());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override public BlockState getBlock(int x, int y, int z) {
|
||||
int i = MainUtil.CACHE_I[y][x][z];
|
||||
if (result == null) {
|
||||
return BukkitBlockUtil.get(chunkData.getType(x, y, z));
|
||||
}
|
||||
BlockState[] array = result[i];
|
||||
if (array == null) {
|
||||
return BlockTypes.AIR.getDefaultState();
|
||||
}
|
||||
int j = MainUtil.CACHE_J[y][x][z];
|
||||
return array[j];
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return chunk == null ? chunkX : chunk.getX();
|
||||
}
|
||||
|
||||
public int getZ() {
|
||||
return chunk == null ? chunkZ : chunk.getZ();
|
||||
}
|
||||
|
||||
@Override public String getWorld() {
|
||||
return chunk == null ? world : chunk.getWorld().getName();
|
||||
}
|
||||
|
||||
@Override public Location getMax() {
|
||||
return new Location(getWorld(), 15 + (getX() << 4), 255, 15 + (getZ() << 4));
|
||||
}
|
||||
|
||||
@Override public Location getMin() {
|
||||
return new Location(getWorld(), getX() << 4, 0, getZ() << 4);
|
||||
}
|
||||
|
||||
public GenChunk clone() {
|
||||
GenChunk toReturn = new GenChunk();
|
||||
if (this.result != null) {
|
||||
for (int i = 0; i < this.result.length; i++) {
|
||||
BlockState[] matrix = this.result[i];
|
||||
if (matrix != null) {
|
||||
toReturn.result[i] = new BlockState[matrix.length];
|
||||
System.arraycopy(matrix, 0, toReturn.result[i], 0, matrix.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
toReturn.chunkData = this.chunkData;
|
||||
return toReturn;
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.uuid;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
|
||||
public class DatFileFilter implements FilenameFilter {
|
||||
|
||||
@Override public boolean accept(File dir, String name) {
|
||||
return name.endsWith(".dat");
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.uuid;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.bukkit.object.BukkitOfflinePlayer;
|
||||
import com.github.intellectualsites.plotsquared.bukkit.object.BukkitPlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.OfflinePlotPlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.uuid.UUIDWrapper;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.UUID;
|
||||
|
||||
public class DefaultUUIDWrapper extends UUIDWrapper {
|
||||
|
||||
@NotNull @Override public UUID getUUID(PlotPlayer player) {
|
||||
return ((BukkitPlayer) player).player.getUniqueId();
|
||||
}
|
||||
|
||||
@Override public UUID getUUID(OfflinePlotPlayer player) {
|
||||
return player.getUUID();
|
||||
}
|
||||
|
||||
@Override public OfflinePlotPlayer getOfflinePlayer(UUID uuid) {
|
||||
return new BukkitOfflinePlayer(Bukkit.getOfflinePlayer(uuid));
|
||||
}
|
||||
|
||||
@Override public UUID getUUID(String name) {
|
||||
return Bukkit.getOfflinePlayer(name).getUniqueId();
|
||||
}
|
||||
|
||||
@Override public OfflinePlotPlayer[] getOfflinePlayers() {
|
||||
OfflinePlayer[] ops = Bukkit.getOfflinePlayers();
|
||||
return Arrays.stream(ops).map(BukkitOfflinePlayer::new).toArray(BukkitOfflinePlayer[]::new);
|
||||
}
|
||||
|
||||
@Override public OfflinePlotPlayer getOfflinePlayer(String name) {
|
||||
return new BukkitOfflinePlayer(Bukkit.getOfflinePlayer(name));
|
||||
}
|
||||
}
|
@ -1,265 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.uuid;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.plot.PlotSquared;
|
||||
import com.github.intellectualsites.plotsquared.plot.config.Captions;
|
||||
import com.github.intellectualsites.plotsquared.plot.config.Settings;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.OfflinePlotPlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.RunnableVal;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.StringWrapper;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.StringMan;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.TaskManager;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.UUIDHandler;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.UUIDHandlerImplementation;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.expiry.ExpireManager;
|
||||
import com.github.intellectualsites.plotsquared.plot.uuid.UUIDWrapper;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.Map;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class FileUUIDHandler extends UUIDHandlerImplementation {
|
||||
|
||||
public FileUUIDHandler(UUIDWrapper wrapper) {
|
||||
super(wrapper);
|
||||
}
|
||||
|
||||
@Override public boolean startCaching(Runnable whenDone) {
|
||||
return super.startCaching(whenDone) && cache(whenDone);
|
||||
}
|
||||
|
||||
private Tag readTag(File file) throws IOException {
|
||||
// Don't chain the creation of the GZIP stream and the NBT stream, because their
|
||||
// constructors may throw an IOException.
|
||||
try (BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(file));
|
||||
GZIPInputStream gzipInputStream = new GZIPInputStream(inputStream);
|
||||
NBTInputStream nbtInputStream = new NBTInputStream(gzipInputStream)) {
|
||||
return nbtInputStream.readNamedTag().getTag();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean cache(final Runnable whenDone) {
|
||||
final File container = Bukkit.getWorldContainer();
|
||||
List<World> worlds = Bukkit.getWorlds();
|
||||
final String world;
|
||||
if (worlds.isEmpty()) {
|
||||
world = "world";
|
||||
} else {
|
||||
world = worlds.get(0).getName();
|
||||
}
|
||||
TaskManager.runTaskAsync(() -> {
|
||||
PlotSquared.debug(Captions.PREFIX + "Starting player data caching for: " + world);
|
||||
File uuidFile = new File(PlotSquared.get().IMP.getDirectory(), "uuids.txt");
|
||||
if (uuidFile.exists()) {
|
||||
try {
|
||||
List<String> lines =
|
||||
Files.readAllLines(uuidFile.toPath(), StandardCharsets.UTF_8);
|
||||
for (String line : lines) {
|
||||
try {
|
||||
line = line.trim();
|
||||
if (line.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
line = line.replaceAll("[\\|][0-9]+[\\|][0-9]+[\\|]", "");
|
||||
String[] split = line.split("\\|");
|
||||
String name = split[0];
|
||||
if (name.isEmpty() || (name.length() > 16) || !StringMan
|
||||
.isAlphanumericUnd(name)) {
|
||||
continue;
|
||||
}
|
||||
UUID uuid = FileUUIDHandler.this.uuidWrapper.getUUID(name);
|
||||
if (uuid == null) {
|
||||
continue;
|
||||
}
|
||||
UUIDHandler.add(new StringWrapper(name), uuid);
|
||||
} catch (Exception e2) {
|
||||
e2.printStackTrace();
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
HashBiMap<StringWrapper, UUID> toAdd = HashBiMap.create(new HashMap<>());
|
||||
if (Settings.UUID.NATIVE_UUID_PROVIDER) {
|
||||
HashSet<UUID> all = UUIDHandler.getAllUUIDS();
|
||||
PlotSquared.debug("Fast mode UUID caching enabled!");
|
||||
File playerDataFolder = new File(container, world + File.separator + "playerdata");
|
||||
String[] dat = playerDataFolder.list(new DatFileFilter());
|
||||
boolean check = all.isEmpty();
|
||||
if (dat != null) {
|
||||
for (String current : dat) {
|
||||
String s = current.replaceAll(".dat$", "");
|
||||
try {
|
||||
UUID uuid = UUID.fromString(s);
|
||||
if (check || all.remove(uuid)) {
|
||||
File file = new File(playerDataFolder, current);
|
||||
CompoundTag compound = (CompoundTag) readTag(file);
|
||||
if (!compound.containsKey("bukkit")) {
|
||||
PlotSquared.debug("ERROR: Player data (" + uuid.toString()
|
||||
+ ".dat) does not contain the the key \"bukkit\"");
|
||||
} else {
|
||||
Map<String, Tag> compoundMap = compound.getValue();
|
||||
CompoundTag bukkit = (CompoundTag) compoundMap.get("bukkit");
|
||||
Map<String, Tag> bukkitMap = bukkit.getValue();
|
||||
String name =
|
||||
(String) bukkitMap.get("lastKnownName").getValue();
|
||||
long last = (long) bukkitMap.get("lastPlayed").getValue();
|
||||
long first = (long) bukkitMap.get("firstPlayed").getValue();
|
||||
if (ExpireManager.IMP != null) {
|
||||
ExpireManager.IMP.storeDate(uuid, last);
|
||||
ExpireManager.IMP.storeAccountAge(uuid, last - first);
|
||||
}
|
||||
toAdd.put(new StringWrapper(name), uuid);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
PlotSquared.debug(Captions.PREFIX + "Invalid playerdata: " + current);
|
||||
}
|
||||
}
|
||||
}
|
||||
add(toAdd);
|
||||
if (all.isEmpty()) {
|
||||
if (whenDone != null) {
|
||||
whenDone.run();
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
PlotSquared.debug(
|
||||
"Failed to cache: " + all.size() + " uuids - slowly processing all files");
|
||||
}
|
||||
}
|
||||
HashSet<String> worlds1 = Sets.newHashSet(world, "world");
|
||||
HashSet<UUID> uuids = new HashSet<>();
|
||||
HashSet<String> names = new HashSet<>();
|
||||
File playerDataFolder = null;
|
||||
for (String worldName : worlds1) {
|
||||
// Getting UUIDs
|
||||
playerDataFolder = new File(container, worldName + File.separator + "playerdata");
|
||||
String[] dat = playerDataFolder.list(new DatFileFilter());
|
||||
if ((dat != null) && (dat.length != 0)) {
|
||||
for (String current : dat) {
|
||||
String s = current.replaceAll(".dat$", "");
|
||||
try {
|
||||
UUID uuid = UUID.fromString(s);
|
||||
uuids.add(uuid);
|
||||
} catch (Exception ignored) {
|
||||
PlotSquared.debug(Captions.PREFIX + "Invalid PlayerData: " + current);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Getting names
|
||||
File playersFolder = new File(worldName + File.separator + "players");
|
||||
dat = playersFolder.list(new DatFileFilter());
|
||||
if ((dat != null) && (dat.length != 0)) {
|
||||
for (String current : dat) {
|
||||
names.add(current.replaceAll(".dat$", ""));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (UUID uuid : uuids) {
|
||||
try {
|
||||
File file =
|
||||
new File(playerDataFolder + File.separator + uuid.toString() + ".dat");
|
||||
if (!file.exists()) {
|
||||
continue;
|
||||
}
|
||||
CompoundTag compound = (CompoundTag) readTag(file);
|
||||
if (!compound.containsKey("bukkit")) {
|
||||
PlotSquared.debug("ERROR: Player data (" + uuid.toString()
|
||||
+ ".dat) does not contain the the key \"bukkit\"");
|
||||
} else {
|
||||
Map<String, Tag> compoundMap = compound.getValue();
|
||||
CompoundTag bukkit = (CompoundTag) compoundMap.get("bukkit");
|
||||
Map<String, Tag> bukkitMap = bukkit.getValue();
|
||||
String name = (String) bukkitMap.get("lastKnownName").getValue();
|
||||
StringWrapper wrap = new StringWrapper(name);
|
||||
if (!toAdd.containsKey(wrap)) {
|
||||
long last = (long) bukkitMap.get("lastPlayed").getValue();
|
||||
long first = (long) bukkitMap.get("firstPlayed").getValue();
|
||||
if (Settings.UUID.OFFLINE) {
|
||||
if (Settings.UUID.FORCE_LOWERCASE && !name.toLowerCase()
|
||||
.equals(name)) {
|
||||
uuid = FileUUIDHandler.this.uuidWrapper.getUUID(name);
|
||||
} else {
|
||||
long most = (long) compoundMap.get("UUIDMost").getValue();
|
||||
long least = (long) compoundMap.get("UUIDLeast").getValue();
|
||||
uuid = new UUID(most, least);
|
||||
}
|
||||
}
|
||||
if (ExpireManager.IMP != null) {
|
||||
ExpireManager.IMP.storeDate(uuid, last);
|
||||
ExpireManager.IMP.storeAccountAge(uuid, last - first);
|
||||
}
|
||||
toAdd.put(wrap, uuid);
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
PlotSquared.debug(
|
||||
Captions.PREFIX + "&6Invalid PlayerData: " + uuid.toString() + ".dat");
|
||||
}
|
||||
}
|
||||
for (String name : names) {
|
||||
UUID uuid = FileUUIDHandler.this.uuidWrapper.getUUID(name);
|
||||
StringWrapper nameWrap = new StringWrapper(name);
|
||||
toAdd.put(nameWrap, uuid);
|
||||
}
|
||||
|
||||
if (getUUIDMap().isEmpty()) {
|
||||
for (OfflinePlotPlayer offlinePlotPlayer : FileUUIDHandler.this.uuidWrapper
|
||||
.getOfflinePlayers()) {
|
||||
long last = offlinePlotPlayer.getLastPlayed();
|
||||
if (last != 0) {
|
||||
String name = offlinePlotPlayer.getName();
|
||||
StringWrapper wrap = new StringWrapper(name);
|
||||
if (!toAdd.containsKey(wrap)) {
|
||||
UUID uuid = FileUUIDHandler.this.uuidWrapper.getUUID(offlinePlotPlayer);
|
||||
if (toAdd.containsValue(uuid)) {
|
||||
StringWrapper duplicate = toAdd.inverse().get(uuid);
|
||||
PlotSquared.debug(
|
||||
"The UUID: " + uuid.toString() + " is already mapped to "
|
||||
+ duplicate
|
||||
+ "\n It cannot be added to the Map with a key of " + wrap);
|
||||
}
|
||||
toAdd.putIfAbsent(wrap, uuid);
|
||||
if (ExpireManager.IMP != null) {
|
||||
ExpireManager.IMP.storeDate(uuid, last);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
add(toAdd);
|
||||
if (whenDone != null) {
|
||||
whenDone.run();
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override public void fetchUUID(final String name, final RunnableVal<UUID> ifFetch) {
|
||||
TaskManager.runTaskAsync(() -> {
|
||||
ifFetch.value = FileUUIDHandler.this.uuidWrapper.getUUID(name);
|
||||
TaskManager.runTask(ifFetch);
|
||||
});
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.uuid;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.plot.object.OfflinePlotPlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
|
||||
import com.google.common.base.Charsets;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
public class LowerOfflineUUIDWrapper extends OfflineUUIDWrapper {
|
||||
|
||||
@NotNull @Override public UUID getUUID(PlotPlayer player) {
|
||||
return UUID.nameUUIDFromBytes(("OfflinePlayer:" + player.getName().toLowerCase()).getBytes(Charsets.UTF_8));
|
||||
}
|
||||
|
||||
@Override public UUID getUUID(OfflinePlotPlayer player) {
|
||||
return UUID.nameUUIDFromBytes(
|
||||
("OfflinePlayer:" + player.getName().toLowerCase()).getBytes(Charsets.UTF_8));
|
||||
}
|
||||
|
||||
@Override public UUID getUUID(OfflinePlayer player) {
|
||||
return UUID.nameUUIDFromBytes(
|
||||
("OfflinePlayer:" + Objects.requireNonNull(player.getName()).toLowerCase()).getBytes(Charsets.UTF_8));
|
||||
}
|
||||
|
||||
@Override public UUID getUUID(String name) {
|
||||
return UUID
|
||||
.nameUUIDFromBytes(("OfflinePlayer:" + name.toLowerCase()).getBytes(Charsets.UTF_8));
|
||||
}
|
||||
|
||||
}
|
@ -1,105 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.uuid;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.bukkit.object.BukkitOfflinePlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.PlotSquared;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.OfflinePlotPlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.StringWrapper;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.UUIDHandler;
|
||||
import com.github.intellectualsites.plotsquared.plot.uuid.UUIDWrapper;
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.collect.BiMap;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
|
||||
public class OfflineUUIDWrapper extends UUIDWrapper {
|
||||
|
||||
private final Object[] arg = new Object[0];
|
||||
private Method getOnline = null;
|
||||
|
||||
public OfflineUUIDWrapper() {
|
||||
try {
|
||||
this.getOnline = Server.class.getMethod("getOnlinePlayers");
|
||||
} catch (NoSuchMethodException | SecurityException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull @Override public UUID getUUID(PlotPlayer player) {
|
||||
return UUID.nameUUIDFromBytes(("OfflinePlayer:" + player.getName()).getBytes(Charsets.UTF_8));
|
||||
}
|
||||
|
||||
@Override public UUID getUUID(OfflinePlotPlayer player) {
|
||||
return UUID
|
||||
.nameUUIDFromBytes(("OfflinePlayer:" + player.getName()).getBytes(Charsets.UTF_8));
|
||||
}
|
||||
|
||||
public UUID getUUID(OfflinePlayer player) {
|
||||
return UUID
|
||||
.nameUUIDFromBytes(("OfflinePlayer:" + player.getName()).getBytes(Charsets.UTF_8));
|
||||
}
|
||||
|
||||
@Override public OfflinePlotPlayer getOfflinePlayer(UUID uuid) {
|
||||
BiMap<UUID, StringWrapper> map = UUIDHandler.getUuidMap().inverse();
|
||||
String name = null;
|
||||
if (map.containsKey(uuid)) {
|
||||
name = map.get(uuid).value;
|
||||
}
|
||||
if (name != null) {
|
||||
OfflinePlayer op = Bukkit.getOfflinePlayer(name);
|
||||
if (op.hasPlayedBefore()) {
|
||||
return new BukkitOfflinePlayer(op);
|
||||
}
|
||||
}
|
||||
for (OfflinePlayer player : Bukkit.getOfflinePlayers()) {
|
||||
if (getUUID(player).equals(uuid)) {
|
||||
return new BukkitOfflinePlayer(player);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Player[] getOnlinePlayers() {
|
||||
if (this.getOnline == null) {
|
||||
Collection<? extends Player> onlinePlayers = Bukkit.getOnlinePlayers();
|
||||
return onlinePlayers.toArray(new Player[0]);
|
||||
}
|
||||
try {
|
||||
Object players = this.getOnline.invoke(Bukkit.getServer(), this.arg);
|
||||
if (players instanceof Player[]) {
|
||||
return (Player[]) players;
|
||||
} else {
|
||||
@SuppressWarnings("unchecked") Collection<? extends Player> p =
|
||||
(Collection<? extends Player>) players;
|
||||
return p.toArray(new Player[0]);
|
||||
}
|
||||
} catch (IllegalAccessException | InvocationTargetException | IllegalArgumentException ignored) {
|
||||
PlotSquared.debug("Failed to resolve online players");
|
||||
this.getOnline = null;
|
||||
Collection<? extends Player> onlinePlayers = Bukkit.getOnlinePlayers();
|
||||
return onlinePlayers.toArray(new Player[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public UUID getUUID(String name) {
|
||||
return UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(Charsets.UTF_8));
|
||||
}
|
||||
|
||||
@Override public OfflinePlotPlayer[] getOfflinePlayers() {
|
||||
OfflinePlayer[] ops = Bukkit.getOfflinePlayers();
|
||||
return Arrays.stream(ops).map(BukkitOfflinePlayer::new).toArray(BukkitOfflinePlayer[]::new);
|
||||
}
|
||||
|
||||
@Override public OfflinePlotPlayer getOfflinePlayer(String name) {
|
||||
return new BukkitOfflinePlayer(Bukkit.getOfflinePlayer(name));
|
||||
}
|
||||
}
|
@ -1,245 +0,0 @@
|
||||
package com.github.intellectualsites.plotsquared.bukkit.uuid;
|
||||
|
||||
import com.github.intellectualsites.plotsquared.plot.PlotSquared;
|
||||
import com.github.intellectualsites.plotsquared.plot.config.Captions;
|
||||
import com.github.intellectualsites.plotsquared.plot.config.Settings;
|
||||
import com.github.intellectualsites.plotsquared.plot.database.SQLite;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.RunnableVal;
|
||||
import com.github.intellectualsites.plotsquared.plot.object.StringWrapper;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.MainUtil;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.TaskManager;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.UUIDHandler;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.UUIDHandlerImplementation;
|
||||
import com.github.intellectualsites.plotsquared.plot.uuid.UUIDWrapper;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.json.simple.parser.ParseException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class SQLUUIDHandler extends UUIDHandlerImplementation {
|
||||
|
||||
final int MAX_REQUESTS = 500;
|
||||
private final String PROFILE_URL =
|
||||
"https://sessionserver.mojang.com/session/minecraft/profile/";
|
||||
private final JSONParser jsonParser = new JSONParser();
|
||||
private final SQLite sqlite;
|
||||
|
||||
public SQLUUIDHandler(UUIDWrapper wrapper) {
|
||||
super(wrapper);
|
||||
this.sqlite =
|
||||
new SQLite(MainUtil.getFile(PlotSquared.get().IMP.getDirectory(), "usercache.db"));
|
||||
try {
|
||||
this.sqlite.openConnection();
|
||||
} catch (ClassNotFoundException | SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try (PreparedStatement stmt = getConnection().prepareStatement(
|
||||
"CREATE TABLE IF NOT EXISTS `usercache` (uuid VARCHAR(32) NOT NULL, username VARCHAR(32) NOT NULL, PRIMARY KEY (uuid, username))")) {
|
||||
stmt.execute();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
startCaching(null);
|
||||
}
|
||||
|
||||
private Connection getConnection() {
|
||||
synchronized (this.sqlite) {
|
||||
return this.sqlite.getConnection();
|
||||
}
|
||||
}
|
||||
|
||||
@Override public boolean startCaching(final Runnable whenDone) {
|
||||
if (!super.startCaching(whenDone)) {
|
||||
return false;
|
||||
}
|
||||
TaskManager.runTaskAsync(() -> {
|
||||
try {
|
||||
HashBiMap<StringWrapper, UUID> toAdd = HashBiMap.create(new HashMap<>());
|
||||
try (PreparedStatement statement = getConnection()
|
||||
.prepareStatement("SELECT `uuid`, `username` FROM `usercache`");
|
||||
ResultSet resultSet = statement.executeQuery()) {
|
||||
while (resultSet.next()) {
|
||||
StringWrapper username = new StringWrapper(resultSet.getString("username"));
|
||||
UUID uuid = UUID.fromString(resultSet.getString("uuid"));
|
||||
toAdd.put(new StringWrapper(username.value), uuid);
|
||||
}
|
||||
}
|
||||
add(toAdd);
|
||||
// This should be called as long as there are some unknown plots
|
||||
final ArrayDeque<UUID> toFetch = new ArrayDeque<>();
|
||||
for (UUID u : UUIDHandler.getAllUUIDS()) {
|
||||
if (!uuidExists(u)) {
|
||||
toFetch.add(u);
|
||||
}
|
||||
}
|
||||
if (toFetch.isEmpty()) {
|
||||
if (whenDone != null) {
|
||||
whenDone.run();
|
||||
}
|
||||
return;
|
||||
}
|
||||
FileUUIDHandler fileHandler = new FileUUIDHandler(SQLUUIDHandler.this.uuidWrapper);
|
||||
fileHandler.startCaching(() -> {
|
||||
// If the file based UUID handler didn't cache it, then we can't cache offline mode
|
||||
// Also, trying to cache based on files again, is useless as that's what the file based uuid cacher does
|
||||
if (Settings.UUID.OFFLINE) {
|
||||
if (whenDone != null) {
|
||||
whenDone.run();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
TaskManager.runTaskAsync(() -> {
|
||||
while (!toFetch.isEmpty()) {
|
||||
try {
|
||||
for (int i = 0; i < Math.min(MAX_REQUESTS, toFetch.size()); i++) {
|
||||
UUID uuid = toFetch.pop();
|
||||
HttpURLConnection connection = (HttpURLConnection) new URL(
|
||||
SQLUUIDHandler.this.PROFILE_URL + uuid.toString()
|
||||
.replace("-", "")).openConnection();
|
||||
try (InputStream con = connection.getInputStream()) {
|
||||
InputStreamReader reader = new InputStreamReader(con);
|
||||
JSONObject response =
|
||||
(JSONObject) SQLUUIDHandler.this.jsonParser
|
||||
.parse(reader);
|
||||
String name = (String) response.get("name");
|
||||
if (name != null) {
|
||||
add(new StringWrapper(name), uuid);
|
||||
}
|
||||
}
|
||||
connection.disconnect();
|
||||
}
|
||||
} catch (IOException | ParseException e) {
|
||||
PlotSquared.debug(
|
||||
"Invalid response from Mojang: Some UUIDs will be cached later. (`unknown` until then or player joins)");
|
||||
}
|
||||
try {
|
||||
//Mojang allows requests every 10 minutes according to https://wiki.vg/Mojang_API
|
||||
//15 Minutes is chosen here since system timers are not always precise
|
||||
//and it should provide enough time where Mojang won't block requests.
|
||||
TimeUnit.MINUTES.sleep(15);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (whenDone != null) {
|
||||
whenDone.run();
|
||||
}
|
||||
});
|
||||
});
|
||||
} catch (SQLException e) {
|
||||
throw new SQLUUIDHandlerException("Couldn't select :s", e);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override public void fetchUUID(final String name, final RunnableVal<UUID> ifFetch) {
|
||||
PlotSquared.debug(Captions.PREFIX + "UUID for '" + name
|
||||
+ "' was null. We'll cache this from the Mojang servers!");
|
||||
if (ifFetch == null) {
|
||||
return;
|
||||
}
|
||||
TaskManager.runTaskAsync(() -> {
|
||||
try {
|
||||
URL url = new URL(SQLUUIDHandler.this.PROFILE_URL);
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod("POST");
|
||||
connection.setRequestProperty("Content-Type", "application/json");
|
||||
connection.setUseCaches(false);
|
||||
connection.setDoInput(true);
|
||||
connection.setDoOutput(true);
|
||||
String body = JSONArray.toJSONString(Collections.singletonList(name));
|
||||
OutputStream stream = connection.getOutputStream();
|
||||
stream.write(body.getBytes());
|
||||
stream.flush();
|
||||
stream.close();
|
||||
JSONArray array = (JSONArray) SQLUUIDHandler.this.jsonParser
|
||||
.parse(new InputStreamReader(connection.getInputStream()));
|
||||
JSONObject jsonProfile = (JSONObject) array.get(0);
|
||||
String id = (String) jsonProfile.get("id");
|
||||
String name1 = (String) jsonProfile.get("name");
|
||||
ifFetch.value = UUID.fromString(
|
||||
id.substring(0, 8) + '-' + id.substring(8, 12) + '-' + id.substring(12, 16)
|
||||
+ '-' + id.substring(16, 20) + '-' + id.substring(20, 32));
|
||||
} catch (IOException | ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
TaskManager.runTask(ifFetch);
|
||||
});
|
||||
}
|
||||
|
||||
@Override public void handleShutdown() {
|
||||
super.handleShutdown();
|
||||
try {
|
||||
getConnection().close();
|
||||
} catch (SQLException e) {
|
||||
throw new SQLUUIDHandlerException("Couldn't close database connection", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is useful for name changes
|
||||
*/
|
||||
@Override public void rename(final UUID uuid, final StringWrapper name) {
|
||||
super.rename(uuid, name);
|
||||
TaskManager.runTaskAsync(() -> {
|
||||
try (PreparedStatement statement = getConnection()
|
||||
.prepareStatement("UPDATE usercache SET `username`=? WHERE `uuid`=?")) {
|
||||
statement.setString(1, name.value);
|
||||
statement.setString(2, uuid.toString());
|
||||
statement.execute();
|
||||
PlotSquared.debug(
|
||||
Captions.PREFIX + "Name change for '" + uuid + "' to '" + name.value + '\'');
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override public boolean add(final StringWrapper name, final UUID uuid) {
|
||||
// Ignoring duplicates
|
||||
if (super.add(name, uuid)) {
|
||||
TaskManager.runTaskAsync(() -> {
|
||||
try (PreparedStatement statement = getConnection()
|
||||
.prepareStatement("REPLACE INTO usercache (`uuid`, `username`) VALUES(?, ?)")) {
|
||||
statement.setString(1, uuid.toString());
|
||||
statement.setString(2, name.toString());
|
||||
statement.execute();
|
||||
PlotSquared
|
||||
.debug(Captions.PREFIX + "&cAdded '&6" + uuid + "&c' - '&6" + name + "&c'");
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static class SQLUUIDHandlerException extends RuntimeException {
|
||||
|
||||
SQLUUIDHandlerException(String s, Throwable c) {
|
||||
super("SQLUUIDHandler caused an exception: " + s, c);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* PlotSquared, a land and world management plugin for Minecraft.
|
||||
* Copyright (C) IntellectualSites <https://intellectualsites.com>
|
||||
* Copyright (C) IntellectualSites team and contributors
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
package com.plotsquared.bukkit;
|
||||
|
||||
import com.plotsquared.bukkit.util.BukkitUtil;
|
||||
import com.plotsquared.core.command.MainCommand;
|
||||
import com.plotsquared.core.configuration.Settings;
|
||||
import com.plotsquared.core.player.ConsolePlayer;
|
||||
import com.plotsquared.core.player.PlotPlayer;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.bukkit.command.ProxiedCommandSender;
|
||||
import org.bukkit.command.RemoteConsoleCommandSender;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class BukkitCommand implements CommandExecutor, TabCompleter {
|
||||
|
||||
@Override
|
||||
public boolean onCommand(
|
||||
CommandSender commandSender, Command command, String commandLabel,
|
||||
String[] args
|
||||
) {
|
||||
if (commandSender instanceof Player) {
|
||||
return MainCommand.onCommand(BukkitUtil.adapt((Player) commandSender), args);
|
||||
}
|
||||
if (commandSender instanceof ConsoleCommandSender
|
||||
|| commandSender instanceof ProxiedCommandSender
|
||||
|| commandSender instanceof RemoteConsoleCommandSender) {
|
||||
return MainCommand.onCommand(ConsolePlayer.getConsole(), args);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(
|
||||
CommandSender commandSender, Command command, String label,
|
||||
String[] args
|
||||
) {
|
||||
if (!(commandSender instanceof Player)) {
|
||||
return null;
|
||||
}
|
||||
PlotPlayer<?> player = BukkitUtil.adapt((Player) commandSender);
|
||||
if (args.length == 0) {
|
||||
return Collections.singletonList("plots");
|
||||
}
|
||||
if (!Settings.Enabled_Components.TAB_COMPLETED_ALIASES.contains(label.toLowerCase(Locale.ENGLISH))) {
|
||||
return List.of();
|
||||
}
|
||||
Collection<com.plotsquared.core.command.Command> objects =
|
||||
MainCommand.getInstance().tab(player, args, label.endsWith(" "));
|
||||
if (objects == null) {
|
||||
return null;
|
||||
}
|
||||
List<String> result = new ArrayList<>();
|
||||
for (com.plotsquared.core.command.Command o : objects) {
|
||||
result.add(o.toString());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
1266
Bukkit/src/main/java/com/plotsquared/bukkit/BukkitPlatform.java
Normal file
1266
Bukkit/src/main/java/com/plotsquared/bukkit/BukkitPlatform.java
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* PlotSquared, a land and world management plugin for Minecraft.
|
||||
* Copyright (C) IntellectualSites <https://intellectualsites.com>
|
||||
* Copyright (C) IntellectualSites team and contributors
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
package com.plotsquared.bukkit.entity;
|
||||
|
||||
class AgeableStats {
|
||||
|
||||
int age;
|
||||
boolean locked;
|
||||
boolean adult;
|
||||
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* PlotSquared, a land and world management plugin for Minecraft.
|
||||
* Copyright (C) IntellectualSites <https://intellectualsites.com>
|
||||
* Copyright (C) IntellectualSites team and contributors
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
package com.plotsquared.bukkit.entity;
|
||||
|
||||
class ArmorStandStats {
|
||||
|
||||
final float[] head = new float[3];
|
||||
final float[] body = new float[3];
|
||||
final float[] leftLeg = new float[3];
|
||||
final float[] rightLeg = new float[3];
|
||||
final float[] leftArm = new float[3];
|
||||
final float[] rightArm = new float[3];
|
||||
boolean arms;
|
||||
boolean noPlate;
|
||||
boolean invisible;
|
||||
boolean small;
|
||||
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* PlotSquared, a land and world management plugin for Minecraft.
|
||||
* Copyright (C) IntellectualSites <https://intellectualsites.com>
|
||||
* Copyright (C) IntellectualSites team and contributors
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
package com.plotsquared.bukkit.entity;
|
||||
|
||||
class EntityBaseStats {
|
||||
|
||||
EntityWrapper passenger;
|
||||
float fall;
|
||||
short fire;
|
||||
int age;
|
||||
double vZ;
|
||||
double vY;
|
||||
double vX;
|
||||
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* PlotSquared, a land and world management plugin for Minecraft.
|
||||
* Copyright (C) IntellectualSites <https://intellectualsites.com>
|
||||
* Copyright (C) IntellectualSites team and contributors
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
package com.plotsquared.bukkit.entity;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
public abstract class EntityWrapper {
|
||||
|
||||
protected final float yaw;
|
||||
protected final float pitch;
|
||||
private final Entity entity;
|
||||
private final EntityType type;
|
||||
public double x;
|
||||
public double y;
|
||||
public double z;
|
||||
|
||||
EntityWrapper(final @NonNull Entity entity) {
|
||||
this.entity = entity;
|
||||
this.type = entity.getType();
|
||||
|
||||
final Location location = entity.getLocation();
|
||||
this.x = location.getX();
|
||||
this.y = location.getY();
|
||||
this.z = location.getZ();
|
||||
this.yaw = location.getYaw();
|
||||
this.pitch = location.getPitch();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("[%s, x=%s, y=%s, z=%s]", type.getName(), x, y, z);
|
||||
}
|
||||
|
||||
public abstract Entity spawn(World world, int xOffset, int zOffset);
|
||||
|
||||
public abstract void saveEntity();
|
||||
|
||||
public float getYaw() {
|
||||
return this.yaw;
|
||||
}
|
||||
|
||||
public float getPitch() {
|
||||
return this.pitch;
|
||||
}
|
||||
|
||||
public Entity getEntity() {
|
||||
return this.entity;
|
||||
}
|
||||
|
||||
public EntityType getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return this.y;
|
||||
}
|
||||
|
||||
public double getZ() {
|
||||
return this.z;
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user