mirror of
https://github.com/md5sha256/AreaShop.git
synced 2026-11-07 09:52:38 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
88c7b7a4bd | ||
|
|
cd3a7e97a7 | ||
|
|
d33739491a | ||
|
|
5488deb0d7 | ||
|
|
ff59fa7f70 | ||
|
|
219ba0335e | ||
|
|
724439da7d | ||
|
|
7bebca5dca | ||
|
|
5989ecbcbc | ||
|
|
a6a38be0a5 | ||
|
|
5034aa358a | ||
|
|
4f7982f5b2 | ||
|
|
92c8eea23a | ||
|
|
4ff5852a9d | ||
|
|
b30a292398 | ||
|
|
5640a55d73 | ||
|
|
cd79e071a4 | ||
|
|
49a4b1420d | ||
|
|
7ef50fbcba | ||
|
|
f9b1920678 | ||
|
|
a9d388a12c | ||
|
|
d66b79ba67 | ||
|
|
a33e25d83c | ||
|
|
1b1e0c7225 | ||
|
|
a977433a22 | ||
|
|
81ef7b08ba | ||
|
|
1528668f01 | ||
|
|
51487b476b | ||
|
|
a1a64d8eb4 | ||
|
|
e0a451511c | ||
|
|
1bc2523b95 | ||
|
|
dba63b7cdd | ||
|
|
fbef0006d1 | ||
|
|
c1572eb754 | ||
|
|
82ab8dbbbc | ||
|
|
0a1d27488b | ||
|
|
a92b38e664 | ||
|
|
4e1f8f685e | ||
|
|
e02f14b041 | ||
|
|
7687a9be77 | ||
|
|
745895cdae | ||
|
|
0305ec3f1f | ||
|
|
ec36996385 | ||
|
|
2800bf469b | ||
|
|
d25fc9fd45 | ||
|
|
1172b1b775 | ||
|
|
0ba567cf90 | ||
|
|
74f0a8ed3b | ||
|
|
4c6b7233eb | ||
|
|
e00cc2c191 | ||
|
|
73346d241c | ||
|
|
e8a9c6b3c7 | ||
|
|
6c6f9fc8ed | ||
|
|
284d915ca5 | ||
|
|
1494d3a3fd | ||
|
|
abaf960613 | ||
|
|
0ca301970b | ||
|
|
c7c1d9e4f6 | ||
|
|
5a61cee351 | ||
|
|
a4195eb556 | ||
|
|
ddc5145539 | ||
|
|
5daa99c938 | ||
|
|
3c2bd89c8d | ||
|
|
3c3e8965a3 | ||
|
|
6898efb7d7 | ||
|
|
030826d343 | ||
|
|
b8625237a7 | ||
|
|
b0df7ba98d | ||
|
|
a8938dc492 | ||
|
|
9f0a6ee196 | ||
|
|
cb7016264f | ||
|
|
feff1c6e24 | ||
|
|
02d1881f6d | ||
|
|
aa61bc58ca | ||
|
|
4d467e0d05 | ||
|
|
32a84dd4c8 | ||
|
|
f141f78529 | ||
|
|
96d490836e | ||
|
|
7f7f50a650 | ||
|
|
91efe92ccc | ||
|
|
d308420f30 | ||
|
|
22e3785a07 | ||
|
|
ed55641c8b | ||
|
|
b9653b7382 | ||
|
|
7021b50cbc | ||
|
|
894cc9b99c | ||
|
|
2b5d0c6bd0 | ||
|
|
867b50c1f5 | ||
|
|
d6fdcb05ef | ||
|
|
c347e8de59 | ||
|
|
81457b0d0b | ||
|
|
d7006267ca | ||
|
|
31b345ffe0 | ||
|
|
1336cb78b2 | ||
|
|
7c6b80e392 | ||
|
|
46baea2c0d | ||
|
|
d2e61545ea | ||
|
|
a12fb49832 | ||
|
|
08be336499 | ||
|
|
3051e8b402 | ||
|
|
52c3742a2a | ||
|
|
5b16f40335 | ||
|
|
6c6a67928f | ||
|
|
06dd185205 | ||
|
|
02389b7d1b | ||
|
|
bee7f18bd0 | ||
|
|
63dc36c3bd | ||
|
|
4723043e9a | ||
|
|
703bbc6668 | ||
|
|
b524b1c88f | ||
|
|
f1546f8482 | ||
|
|
29ec5a2e3b | ||
|
|
3a15e3d025 | ||
|
|
90e010494a | ||
|
|
7541af37f3 | ||
|
|
36c74a32f0 | ||
|
|
129b144cb1 | ||
|
|
a79b0067f2 | ||
|
|
5c2e4f8f0c | ||
|
|
d639f61e8f | ||
|
|
65b9ffed18 | ||
|
|
ee94a3d549 | ||
|
|
44d8999b3c | ||
|
|
a09d6f9370 | ||
|
|
105cc1033c | ||
|
|
c3daff0842 | ||
|
|
3456bc6a37 | ||
|
|
58269daa45 | ||
|
|
bac50ed5d5 | ||
|
|
8d50a0d1a7 | ||
|
|
bf5436284a | ||
|
|
592a1b24f4 | ||
|
|
aacf75c170 | ||
|
|
4bf598ac5d | ||
|
|
4b4521b002 | ||
|
|
cd262fdf5e | ||
|
|
5b283d503b | ||
|
|
b9d5a29629 | ||
|
|
0b0f4b0289 | ||
|
|
75915f2ebf | ||
|
|
1395220edb | ||
|
|
a318293bbe | ||
|
|
0cbf14183d | ||
|
|
4c636856aa | ||
|
|
7bb3ed1859 | ||
|
|
909f6c4b45 | ||
|
|
adfc4334cc | ||
|
|
f8ae27c3f3 | ||
|
|
d2b2ca2b83 | ||
|
|
6f8afea58e | ||
|
|
113a1a4f63 | ||
|
|
6e7a659c80 | ||
|
|
1336858316 | ||
|
|
7b7b5abf2c | ||
|
|
9fd8a740db | ||
|
|
88a23650a0 | ||
|
|
4e1f9e6875 | ||
|
|
4fdf9d787f | ||
|
|
413f16a2d4 | ||
|
|
3c21ac1eba | ||
|
|
7670d1b479 | ||
|
|
73e04ccc68 | ||
|
|
52256c83b8 | ||
|
|
794854e9c2 | ||
|
|
2c7fc16f8b | ||
|
|
b7fc4175a1 | ||
|
|
6e686f5a3f | ||
|
|
324dae03eb | ||
|
|
8a3122ba93 | ||
|
|
aada9a4624 | ||
|
|
b74736f23b | ||
|
|
c54c8b32ac | ||
|
|
63c1b7474a | ||
|
|
192f34099a | ||
|
|
b933dfea72 | ||
|
|
3d08c9f7be | ||
|
|
52d5b4632b | ||
|
|
7e03db8b10 | ||
|
|
913d1c9b59 | ||
|
|
f24a922fec | ||
|
|
5871b3ba24 | ||
|
|
9d3818906c | ||
|
|
ac69d18dc0 | ||
|
|
2c3a78517d | ||
|
|
04d42c5444 | ||
|
|
172762356d | ||
|
|
aeb201c221 | ||
|
|
788ba7e2b6 | ||
|
|
89114ee126 | ||
|
|
d316f2e914 | ||
|
|
74219ff75b | ||
|
|
e13a5f2bb0 | ||
|
|
c3bc9457ef | ||
|
|
6dc97b019e | ||
|
|
41944102b6 | ||
|
|
90fecd1085 | ||
|
|
e1b4df8f25 | ||
|
|
f0e4bd12ca | ||
|
|
27d832f05a | ||
|
|
1ca846f1ec | ||
|
|
2472a14cae | ||
|
|
c2bfe2158e | ||
|
|
745d1dd7d7 | ||
|
|
f6977061f4 | ||
|
|
c922b83de4 | ||
|
|
444a769f37 | ||
|
|
6b81be9cbb | ||
|
|
cd07b899c8 | ||
|
|
6bd916facd | ||
|
|
d16ea37269 | ||
|
|
56ab7ef52b | ||
|
|
6ef2d89cfc | ||
|
|
94a807d7c2 | ||
|
|
0d01cb956e | ||
|
|
55c4f7f369 | ||
|
|
3348e5b697 | ||
|
|
381c8b2ebe | ||
|
|
6bf344e6be | ||
|
|
e2bcc57128 | ||
|
|
6df08bc713 | ||
|
|
0e0b085000 | ||
|
|
4f9fc950f0 | ||
|
|
fe16d732a2 | ||
|
|
8cc44cf79f | ||
|
|
4fd478dbc3 | ||
|
|
fe77bf0318 | ||
|
|
e4b53982b2 | ||
|
|
3c953ad9a3 | ||
|
|
88f55bb6a9 | ||
|
|
4ba8326314 | ||
|
|
de81d92da0 | ||
|
|
f636a98314 | ||
|
|
e4df5a8cc9 | ||
|
|
56818bebdb | ||
|
|
7e1d7168f1 | ||
|
|
ff1ea3ae51 | ||
|
|
c9dc8dd840 | ||
|
|
c0794daeeb | ||
|
|
d40b9c660b | ||
|
|
f7b010b3f3 | ||
|
|
a06d9271c4 | ||
|
|
dd343aa587 | ||
|
|
e09d4ebd83 | ||
|
|
5f435941e4 | ||
|
|
86316cdd5b | ||
|
|
61828d3cfd | ||
|
|
54241d5ce3 | ||
|
|
d048665530 | ||
|
|
23de68431c | ||
|
|
95b4543f19 | ||
|
|
d058bb7271 | ||
|
|
63d26be369 | ||
|
|
1020388aae | ||
|
|
e56107ffd6 | ||
|
|
06fceb4643 | ||
|
|
e2077c3b32 | ||
|
|
fcb64c2ddb | ||
|
|
cc51109720 | ||
|
|
0b48f4dd2e | ||
|
|
4d7f00b0ce | ||
|
|
b27ea83982 | ||
|
|
66da717a77 | ||
|
|
7f779d2df8 | ||
|
|
ed3bd01f2a | ||
|
|
ef03501d1c | ||
|
|
feb35cfd37 | ||
|
|
b6a8dcc24c | ||
|
|
5619612a6e | ||
|
|
26ac52cc0a | ||
|
|
5f6bd55afe | ||
|
|
aba2e12c5d | ||
|
|
2906de11de | ||
|
|
436672f85b | ||
|
|
5ba8ed7ad8 | ||
|
|
00d97f1beb | ||
|
|
f530fa40af | ||
|
|
a804df2257 | ||
|
|
c96e0b464e | ||
|
|
13e52aa4f1 | ||
|
|
9aeb531d16 | ||
|
|
44f83473d1 | ||
|
|
d7260998f5 | ||
|
|
638382eacf | ||
|
|
e18fe99161 | ||
|
|
bdc9e32c13 | ||
|
|
9a46d5ae3b | ||
|
|
6795fc43d9 | ||
|
|
dd9bd2c434 | ||
|
|
9438166180 | ||
|
|
9e06b9f268 | ||
|
|
4562bf23f6 | ||
|
|
24edb01754 | ||
|
|
2739bf6ad4 | ||
|
|
2ce84186ab | ||
|
|
279fa001ea | ||
|
|
b56d5320a6 | ||
|
|
30665908b9 | ||
|
|
0fd384833a | ||
|
|
09634de4bf | ||
|
|
7fafee82a7 | ||
|
|
2899b2978c | ||
|
|
7afcba79c9 | ||
|
|
72084b38f8 | ||
|
|
6a291feedd | ||
|
|
b85566882c | ||
|
|
c14407e14b | ||
|
|
ae9bd60d1b | ||
|
|
c689c2fae0 | ||
|
|
728cfb6dfa | ||
|
|
3abb6c06e4 | ||
|
|
51c11738af | ||
|
|
172b5a99f1 | ||
|
|
4c5d025e54 | ||
|
|
e93a2d04de | ||
|
|
af5980d555 | ||
|
|
3f7249f4a1 | ||
|
|
73c6fc858e | ||
|
|
360c3e7e21 | ||
|
|
73d0115b78 | ||
|
|
baf7eaabf1 | ||
|
|
ca8c0487a8 | ||
|
|
24156a03c4 | ||
|
|
ec677766d2 | ||
|
|
ef6c8fbf9d | ||
|
|
4f52fe9e6e | ||
|
|
3ebe5a6fa9 | ||
|
|
3cebe5d2c7 | ||
|
|
c76415c4f3 | ||
|
|
b7bc02aef3 | ||
|
|
d75094e191 | ||
|
|
4045914b48 | ||
|
|
1fac002ee0 | ||
|
|
64301e74e0 | ||
|
|
5a5a7fc5ef | ||
|
|
b928caf0c2 | ||
|
|
111f629787 | ||
|
|
718474ca95 | ||
|
|
93b9df3e54 | ||
|
|
bad983a0b8 | ||
|
|
e2c8b06b68 | ||
|
|
7249e39c02 | ||
|
|
9d9a58a170 | ||
|
|
e64e884c2a | ||
|
|
6ad4ff9deb | ||
|
|
eec9806492 | ||
|
|
43b2ae8278 | ||
|
|
6d5a92e389 | ||
|
|
7d7a62ffa0 | ||
|
|
44456d87b6 | ||
|
|
d92c710b27 | ||
|
|
3dceaf98cd | ||
|
|
33c29a3756 | ||
|
|
771734360f | ||
|
|
539e908d32 | ||
|
|
088471aa3c | ||
|
|
5a95c95670 | ||
|
|
5a5d627d51 | ||
|
|
9b5434a4b2 | ||
|
|
e13717950b | ||
|
|
03ed2803bd | ||
|
|
b3f1225934 | ||
|
|
68651899b7 | ||
|
|
4a7a4ca4ee | ||
|
|
0d272c8fe9 | ||
|
|
6b2c905939 | ||
|
|
7ab782799b | ||
|
|
bea82eae88 | ||
|
|
4ac0e045bd | ||
|
|
e5061b218e | ||
|
|
40fdfba47d | ||
|
|
e9260cede6 | ||
|
|
bb297c9ff1 | ||
|
|
666742ad56 | ||
|
|
36eb8c3a5e | ||
|
|
06a9f7b28e | ||
|
|
e101780420 | ||
|
|
6abe99e807 | ||
|
|
a1d18521ee | ||
|
|
363b416c59 | ||
|
|
7bf516108b | ||
|
|
7567cb5fe4 | ||
|
|
d2ca54e8ea | ||
|
|
e47cda4254 | ||
|
|
98d4c6a778 | ||
|
|
2a44dd29cc | ||
|
|
c1665c33ff | ||
|
|
2cdab9b6db | ||
|
|
72faf76619 | ||
|
|
ad66ce00b1 | ||
|
|
edc7126b87 | ||
|
|
a7f0ac248c | ||
|
|
675dee2cd3 | ||
|
|
c7226750ab | ||
|
|
2ecbb61053 | ||
|
|
fc132558a3 | ||
|
|
b172413b62 | ||
|
|
dcbb1f5896 | ||
|
|
6e3855c0c3 | ||
|
|
27991d17a2 | ||
|
|
159221d53d | ||
|
|
557d11dfb4 | ||
|
|
b9547e2c67 | ||
|
|
221785ae55 | ||
|
|
0d04676bce | ||
|
|
c8cd68c17b | ||
|
|
539887449c | ||
|
|
4cda8a9292 | ||
|
|
fe131dc157 | ||
|
|
41ced9ee6c | ||
|
|
03de0ff252 | ||
|
|
b057271394 | ||
|
|
d7cdff0b22 | ||
|
|
1035b6b41b | ||
|
|
e0bad7397c | ||
|
|
b7124e8cdd | ||
|
|
f0952c32c9 | ||
|
|
d3dfa86a65 | ||
|
|
8f73b8af3c | ||
|
|
51b24c74b4 | ||
|
|
9beb1eb61b | ||
|
|
de5fdafca0 | ||
|
|
0aea914d20 | ||
|
|
b4efe7d5bf | ||
|
|
ec7983e126 | ||
|
|
e45c353030 | ||
|
|
44b1cb0fc8 | ||
|
|
c7299fa56c | ||
|
|
12bf467714 | ||
|
|
5b327db316 | ||
|
|
b4f33589a1 | ||
|
|
530c74ccd2 | ||
|
|
fa4857cbce | ||
|
|
93fd4e96cb | ||
|
|
a6863ae782 | ||
|
|
e5e2c4ca08 | ||
|
|
b0341e2a3e | ||
|
|
c8e1ebb068 | ||
|
|
39c8eb5f73 | ||
|
|
2483cf1614 | ||
|
|
769f8ee4ca | ||
|
|
2c04b87a9f | ||
|
|
8ce1ed0264 | ||
|
|
035f8e1932 | ||
|
|
4d3482994f | ||
|
|
45f1c510e5 | ||
|
|
5c13223b9e | ||
|
|
8c47ae9b3c | ||
|
|
28d03a6a3a | ||
|
|
aa585e9b11 | ||
|
|
36d2ce60b9 | ||
|
|
bdea9448a4 | ||
|
|
bd2f40f5c8 | ||
|
|
9e908cee73 | ||
|
|
0d326d973d | ||
|
|
27eaa27765 | ||
|
|
fb35153eb2 | ||
|
|
aec6295516 | ||
|
|
38cd77e487 | ||
|
|
6b9866a4c4 | ||
|
|
5aceb81cfd | ||
|
|
50f6bce64e | ||
|
|
f713edc5b5 | ||
|
|
012920a51c | ||
|
|
6154454f96 | ||
|
|
e34daeb5ff | ||
|
|
0a2dc22c59 | ||
|
|
2482bd88c2 | ||
|
|
e86281ab28 | ||
|
|
5a9ca74b75 | ||
|
|
d301be2304 | ||
|
|
a23c6fa66f | ||
|
|
cd63517041 | ||
|
|
e3043c476b | ||
|
|
3be7573863 | ||
|
|
51161fffee | ||
|
|
c82067ad0b | ||
|
|
46dbb8d22c | ||
|
|
cace086466 | ||
|
|
06a716b1fd | ||
|
|
4530717045 | ||
|
|
741bbd879f | ||
|
|
8474edd29d | ||
|
|
d4df691166 | ||
|
|
3e247e6cb1 | ||
|
|
f3527134e8 | ||
|
|
0e14b121b8 | ||
|
|
8cc632fc05 | ||
|
|
77c1b3f288 | ||
|
|
21339cbf7c | ||
|
|
0351188671 | ||
|
|
47e1d80821 | ||
|
|
1d0472b052 | ||
|
|
22dcfc76af | ||
|
|
6b59176048 | ||
|
|
5dc4d11408 | ||
|
|
00bd305381 | ||
|
|
9daa50b23b | ||
|
|
33b73a0369 | ||
|
|
591540af30 | ||
|
|
4e1e50e993 | ||
|
|
9a52ca3d9b | ||
|
|
858b019806 | ||
|
|
b1dfe93088 | ||
|
|
0bf2314f2a | ||
|
|
33ddb8ae88 | ||
|
|
234e4b6261 | ||
|
|
ed2ffaeaa3 | ||
|
|
e073438862 | ||
|
|
07194f07da | ||
|
|
dfa3e0be66 | ||
|
|
8eef029400 | ||
|
|
c8d869ce15 | ||
|
|
053d75181d | ||
|
|
f0128c221b | ||
|
|
ce6c01c5d0 | ||
|
|
b835c4dded | ||
|
|
07e6782714 | ||
|
|
4002956aeb | ||
|
|
0b96b9cb42 | ||
|
|
0c192c2444 | ||
|
|
2381aaeacc | ||
|
|
906b331758 | ||
|
|
f0f2e09be0 | ||
|
|
395cc6de07 | ||
|
|
3b9d6187ca | ||
|
|
9d1585f513 | ||
|
|
9d6955039a | ||
|
|
747b47057b | ||
|
|
a973e254e6 | ||
|
|
a5105af3ad | ||
|
|
0bb0a05b76 | ||
|
|
dad502ec0c | ||
|
|
f471b9bbf0 | ||
|
|
f69d1c41e6 | ||
|
|
4ea6f59c49 | ||
|
|
0b7158290f | ||
|
|
e6757d23de | ||
|
|
7cda35f4da | ||
|
|
ee293d14b9 | ||
|
|
2e0fce4955 | ||
|
|
7afdefc9ed | ||
|
|
11f80e7ed1 | ||
|
|
40d45c7786 | ||
|
|
6b8e161e43 | ||
|
|
e1b2f7391c | ||
|
|
89ae8b9b4a | ||
|
|
fab415bf19 | ||
|
|
c7aa92be81 | ||
|
|
705c8d6891 | ||
|
|
429d87c9ff | ||
|
|
1fdd8b32cc | ||
|
|
7900f78a8c | ||
|
|
3a65a88849 | ||
|
|
7b491d0389 | ||
|
|
fd02c51492 | ||
|
|
bb1f592807 | ||
|
|
16c7a044ea | ||
|
|
152f183670 | ||
|
|
09b6e4c584 | ||
|
|
aeb70196a3 | ||
|
|
62148ea577 | ||
|
|
fcc9fb0945 | ||
|
|
b525c5902c | ||
|
|
b18a7cc6d5 | ||
|
|
54b6e84558 | ||
|
|
bae3c0a199 | ||
|
|
508270a280 | ||
|
|
87b2cb9ecd | ||
|
|
271b17b6be | ||
|
|
1dfedea50c | ||
|
|
d9abe2e347 | ||
|
|
1ba2e21ae9 | ||
|
|
fcdfdc6094 | ||
|
|
8a7e2ba5c2 | ||
|
|
0950452692 | ||
|
|
293978f068 | ||
|
|
5efe14b8e9 | ||
|
|
839d510151 | ||
|
|
9180d9b8ee | ||
|
|
7aa786f4ce | ||
|
|
10ea8540e7 | ||
|
|
dba00769f6 | ||
|
|
44c70c6a33 | ||
|
|
570f7b4055 | ||
|
|
feafa012dd | ||
|
|
82b340ce1a | ||
|
|
93809f27fc | ||
|
|
f8ed3654fd | ||
|
|
58a1afccf3 | ||
|
|
d9c3573225 | ||
|
|
1577443203 | ||
|
|
ab7a92c57d | ||
|
|
2e09b0f60f | ||
|
|
6e5c35f95b | ||
|
|
066ceedafd | ||
|
|
c8ebe24bd3 | ||
|
|
ad7db5ee23 | ||
|
|
f80a8178ff | ||
|
|
05c8e1a7e4 | ||
|
|
9904805310 | ||
|
|
0df2f429c0 | ||
|
|
b3408a2648 | ||
|
|
e1f89e7904 | ||
|
|
064b129205 | ||
|
|
8111387f32 | ||
|
|
a4b23bebba | ||
|
|
7421e685fa | ||
|
|
374b68d8fa | ||
|
|
ca7a9664f3 | ||
|
|
e957b4fc73 | ||
|
|
6493bc4f78 | ||
|
|
2db1b6a243 | ||
|
|
864662a3c4 | ||
|
|
59b960b87c | ||
|
|
2de653d73f | ||
|
|
4feee59834 | ||
|
|
816d136a62 | ||
|
|
121de7dc7e | ||
|
|
f7c86881cc | ||
|
|
351d51b664 | ||
|
|
5a28476cf0 | ||
|
|
8143bdae27 | ||
|
|
b62744fe10 | ||
|
|
fe0b63c760 | ||
|
|
def774c7a1 | ||
|
|
7c5cb5f5aa | ||
|
|
8af6e1d6f1 | ||
|
|
e0e6c39dae | ||
|
|
dabe46bd47 | ||
|
|
ec478a05d1 | ||
|
|
e21c0aafde | ||
|
|
52bf88f4a5 | ||
|
|
e4de560a65 | ||
|
|
6481da29e4 | ||
|
|
f287cc91a6 | ||
|
|
95b7b50346 | ||
|
|
21db2ff440 | ||
|
|
36dd978a92 | ||
|
|
6cc3f2a52f | ||
|
|
852731b1ad | ||
|
|
30faa77da9 | ||
|
|
ec57b922b8 | ||
|
|
c2bcc6008b | ||
|
|
72a05bedce | ||
|
|
bc73a8b20d | ||
|
|
832e8218b6 | ||
|
|
6fcb629133 | ||
|
|
7d6a1f35c1 | ||
|
|
60257d45c2 | ||
|
|
2300227d87 | ||
|
|
b1852b10bb | ||
|
|
88fdb0c3fc | ||
|
|
491e55fc77 | ||
|
|
c7b0a2c663 | ||
|
|
868f4d6b58 | ||
|
|
0d4b034181 | ||
|
|
5f20689ba3 | ||
|
|
38b658fccf | ||
|
|
28ed20c0b5 | ||
|
|
aaff36b2eb | ||
|
|
49b536cab0 | ||
|
|
9a9969dea3 | ||
|
|
84e4b49bfd | ||
|
|
6daaf6997d | ||
|
|
c445a62334 | ||
|
|
0d205b0d9e | ||
|
|
8c33826c2c | ||
|
|
51e1dbafb7 | ||
|
|
6edad3faff | ||
|
|
f89e0f861b | ||
|
|
770b1d98df | ||
|
|
8e5baa47af | ||
|
|
367466735e | ||
|
|
ade6bc3971 | ||
|
|
05fd8c0156 | ||
|
|
5403472476 | ||
|
|
c4ee7bc7aa | ||
|
|
940f1969b6 | ||
|
|
07eb5477b8 | ||
|
|
a4112092b5 | ||
|
|
872d81b0a9 | ||
|
|
b04871c553 | ||
|
|
fd1b8fba4c | ||
|
|
991e7b1961 | ||
|
|
aac963325a | ||
|
|
3e7c7ce76b | ||
|
|
c858d30481 | ||
|
|
b090fd5577 | ||
|
|
8d132c66c4 | ||
|
|
50e3e59543 | ||
|
|
eb21b9567e | ||
|
|
4dba305f6d | ||
|
|
7481d8287f | ||
|
|
4d41decbe5 | ||
|
|
7fc5a5af81 | ||
|
|
d26fa99b95 | ||
|
|
39d755d2db | ||
|
|
48ab46ecf7 | ||
|
|
b3fa31e1cc | ||
|
|
783085fbf7 | ||
|
|
aa093b0c8a | ||
|
|
9c357fe929 | ||
|
|
4d70571a23 | ||
|
|
29a4105ece | ||
|
|
edc7136063 | ||
|
|
6fabc75be4 | ||
|
|
085507bf8b | ||
|
|
73ed3366ae | ||
|
|
9ca029176d | ||
|
|
bf181d69d7 | ||
|
|
68c57515da | ||
|
|
903d6c309f | ||
|
|
0a02eb3254 | ||
|
|
bf04589fab | ||
|
|
14dd094803 | ||
|
|
02df35304c | ||
|
|
4321667ec5 | ||
|
|
5cf5df78c8 | ||
|
|
8608d6ce1d | ||
|
|
614336862e | ||
|
|
a4ea175f1b | ||
|
|
c96043aa38 | ||
|
|
d5a29f6c32 | ||
|
|
5176a1c2c5 | ||
|
|
89569ea182 | ||
|
|
f349657a59 | ||
|
|
40d3d4d8af | ||
|
|
0d5db8fa4e | ||
|
|
25c56e8ecb | ||
|
|
9f436a7eb4 | ||
|
|
f76c1b8a9f | ||
|
|
d466658f36 | ||
|
|
04e02c4ce4 | ||
|
|
3bf493109c | ||
|
|
2f9b6d3987 | ||
|
|
93d5612513 | ||
|
|
937db4620d | ||
|
|
a0239b8837 | ||
|
|
401f52e687 | ||
|
|
2f6874a16e | ||
|
|
c95f4e1c6c | ||
|
|
1a2d755727 | ||
|
|
c489e6eba4 | ||
|
|
b1a56b5230 | ||
|
|
dfbc7805b5 | ||
|
|
8f2c95f5c4 | ||
|
|
0b9bffe68f | ||
|
|
7ac6e34c89 | ||
|
|
5231f6e86e | ||
|
|
791b696aff | ||
|
|
c92bc716dc | ||
|
|
463b34e952 | ||
|
|
ff6e69196d | ||
|
|
76ad952bb6 | ||
|
|
0cdff5e143 | ||
|
|
9dc3013215 | ||
|
|
796b95c9f9 | ||
|
|
2785a72457 | ||
|
|
c2df0cd912 | ||
|
|
4cd32a0792 | ||
|
|
354e70af57 | ||
|
|
fde60e2a27 | ||
|
|
d1a3027e0b | ||
|
|
4e57f03fc0 | ||
|
|
83d4efc3a8 | ||
|
|
1395afffe9 | ||
|
|
5094d39a96 | ||
|
|
e664c1efd9 | ||
|
|
871eeed29c | ||
|
|
0d56762bfc | ||
|
|
c08763883f | ||
|
|
efb534f131 | ||
|
|
d9405a9f49 | ||
|
|
684add89cd | ||
|
|
d1848c0728 | ||
|
|
9fd16290c0 | ||
|
|
3bbca11cc9 | ||
|
|
b1be87014f | ||
|
|
badcd77cfe | ||
|
|
779d340bbb | ||
|
|
4e5061ba54 | ||
|
|
b0f3bdc560 | ||
|
|
5c9fdb6cc9 | ||
|
|
23ea679cd9 | ||
|
|
58680c8cc4 | ||
|
|
75b752a235 | ||
|
|
fb51da84ae | ||
|
|
22d214e59d | ||
|
|
175b531eb5 | ||
|
|
52591d3b6e | ||
|
|
825074479c | ||
|
|
cc8cf1e560 | ||
|
|
a4169d127e | ||
|
|
21340af89f | ||
|
|
db06eae6c9 | ||
|
|
5bae5ecf67 | ||
|
|
679ffe2145 | ||
|
|
e6c5653073 | ||
|
|
ea31dfdd65 | ||
|
|
9da31fed1f | ||
|
|
9baf0b7eec | ||
|
|
a14dc4e541 | ||
|
|
00d3256716 | ||
|
|
40338b66df | ||
|
|
715bbfd9e3 | ||
|
|
b679c49405 | ||
|
|
dd0930bcea | ||
|
|
5b961564e1 | ||
|
|
c12314fa98 | ||
|
|
e23ad74744 | ||
|
|
9957e02e65 | ||
|
|
07ea919aba | ||
|
|
2c1771cc52 | ||
|
|
83778ff803 | ||
|
|
0c79525144 | ||
|
|
e719930364 | ||
|
|
5568ee240b | ||
|
|
46abc8f83d | ||
|
|
cf3139f373 | ||
|
|
59627e1b97 | ||
|
|
a25b5a5752 | ||
|
|
aceb6945fd | ||
|
|
cbeffe9316 | ||
|
|
9ea97fdb5d | ||
|
|
ed1f73fdd7 | ||
|
|
09af826f88 | ||
|
|
1fd24d864d | ||
|
|
4125364a96 | ||
|
|
a6f5a2eb5e | ||
|
|
5eae75fef1 | ||
|
|
7982531e63 | ||
|
|
6ce15b27b7 | ||
|
|
b1809fb265 | ||
|
|
0344391588 | ||
|
|
8d254e17bb | ||
|
|
2098b9f4e3 | ||
|
|
95e3a4a120 | ||
|
|
9269279d44 | ||
|
|
d8fbeaf53a | ||
|
|
05df539189 | ||
|
|
f20c573b06 | ||
|
|
793e3dfd1b | ||
|
|
d7eff6c0df | ||
|
|
911115213f | ||
|
|
beeef8c757 | ||
|
|
60bdd50ab6 | ||
|
|
b5ba813410 | ||
|
|
7de0b34b3b | ||
|
|
b5077215ec | ||
|
|
98c45866a3 | ||
|
|
a96101519a | ||
|
|
fc18819a95 | ||
|
|
6dd0750bea | ||
|
|
36b73f57fd | ||
|
|
b111110251 | ||
|
|
555f648dfe | ||
|
|
4ac4c9ae35 | ||
|
|
97fe92588c | ||
|
|
8fc03b21f0 | ||
|
|
a74643d724 | ||
|
|
c309cbbbae | ||
|
|
73ceee6f27 | ||
|
|
9c57f434db | ||
|
|
f41e614d38 | ||
|
|
4fa1267971 | ||
|
|
e99ca02bcb | ||
|
|
3479bcd0d8 | ||
|
|
c0cd528f0e | ||
|
|
14f379f7c6 | ||
|
|
73c1f88d8c | ||
|
|
1bbca09fc6 | ||
|
|
8219269fbb | ||
|
|
bf283d52b6 | ||
|
|
def6005b92 | ||
|
|
62934ceab6 | ||
|
|
9124de9bb0 | ||
|
|
d5da1bb012 | ||
|
|
99d4cdb685 | ||
|
|
24ee8df215 | ||
|
|
c1ef15193c | ||
|
|
c1e89ef75e | ||
|
|
56a35d373b | ||
|
|
6a4b8f9d9a | ||
|
|
ef4b599897 | ||
|
|
a04b96d452 | ||
|
|
0728ce672d | ||
|
|
c42e1ccbe5 | ||
|
|
dfcd896cab | ||
|
|
69ee2d5c7f | ||
|
|
b42bb38e5f | ||
|
|
bed4bbac23 | ||
|
|
f13534ae33 | ||
|
|
0e46f01150 |
No files matched your search
@@ -0,0 +1,39 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Report a problem in the plugin
|
||||
title: ''
|
||||
labels: 'NEW, Type: Bug'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Current behavior**
|
||||
<!--- Tell what happens currently and/or show the stacktrace if an error occured -->
|
||||
|
||||
|
||||
**Expected behavior**
|
||||
<!--- Tell what you expected to happen instead -->
|
||||
|
||||
|
||||
**Steps to reproduce**
|
||||
<!--- Exactly show how this bug can be triggered -->
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
4.
|
||||
|
||||
|
||||
**Your environment**
|
||||
<!--- Indicate which versions you use -->
|
||||
<!--- Attention: "LATEST" or "NEWEST" are invalid answers! -->
|
||||
<!--- Use '/version' for the Platform version and '/version <plugin>' for plugin versions -->
|
||||
* Server platform (Bukkit, Spigot, etc.):
|
||||
* Server version:
|
||||
* AreaShop version:
|
||||
* WorldEdit version:
|
||||
* WorldGuard version:
|
||||
* Vault version:
|
||||
|
||||
|
||||
**Your config files**
|
||||
<!--- Attach a '.zip' file of the '/plugins/AreaShop' and '/plugins/WorldGuard' directories to show your configuration setup -->
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea
|
||||
title: ''
|
||||
labels: 'NEW, Type: Feature'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the problem you are trying to solve with this feature request**
|
||||
<!-- When I know the problem you are trying to solve I can help you to think about the best solution -->
|
||||
|
||||
|
||||
**Describe the solution you'd like**
|
||||
<!-- Describe the config settings, commands and other features that should be added -->
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
name: Support question
|
||||
about: Ask help with the setup or usage of the plugin
|
||||
title: ''
|
||||
labels: 'NEW, Type: Support'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Current behavior**
|
||||
<!--- Tell what happens currently -->
|
||||
|
||||
|
||||
**Desired behavior**
|
||||
<!--- Tell what you want to happen instead -->
|
||||
|
||||
|
||||
**Your environment**
|
||||
<!--- Indicate which versions you use -->
|
||||
<!--- Attention: "LATEST" or "NEWEST" are invalid answers! -->
|
||||
<!--- Use '/version' for the Platform version and '/version <plugin>' for plugin versions -->
|
||||
* Server platform (Bukkit, Spigot, etc.):
|
||||
* Server version:
|
||||
* AreaShop version:
|
||||
* WorldEdit version:
|
||||
* WorldGuard version:
|
||||
* Vault version:
|
||||
|
||||
|
||||
**Your config files**
|
||||
<!--- Attach a '.zip' file of the '/plugins/AreaShop' and '/plugins/WorldGuard' directories to show your configuration setup -->
|
||||
@@ -0,0 +1,23 @@
|
||||
name: Java CI with Gradle
|
||||
|
||||
on: [ push, pull_request ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
# Only run on PRs if the source branch is on someone else's repo
|
||||
if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: ["ubuntu-latest", "windows-latest"]
|
||||
runs-on: "${{ matrix.os }}"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: gradle/actions/wrapper-validation@v3
|
||||
- name: Set up JDK 21
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: '21'
|
||||
distribution: 'zulu'
|
||||
cache: 'gradle'
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew clean build
|
||||
+196
@@ -0,0 +1,196 @@
|
||||
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/macos,windows,intellij+all,gradle,maven
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=macos,windows,intellij+all,gradle,maven
|
||||
|
||||
### Intellij+all ###
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# AWS User-specific
|
||||
.idea/**/aws.xml
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/artifacts
|
||||
# .idea/compiler.xml
|
||||
# .idea/jarRepositories.xml
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# SonarLint plugin
|
||||
.idea/sonarlint/
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
### Intellij+all Patch ###
|
||||
# Ignores the whole .idea folder and all .iml files
|
||||
# See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360
|
||||
|
||||
.idea/*
|
||||
|
||||
# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023
|
||||
|
||||
*.iml
|
||||
modules.xml
|
||||
.idea/misc.xml
|
||||
*.ipr
|
||||
|
||||
# Sonarlint plugin
|
||||
.idea/sonarlint
|
||||
|
||||
### macOS ###
|
||||
# General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
### Maven ###
|
||||
target/
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
pom.xml.next
|
||||
release.properties
|
||||
dependency-reduced-pom.xml
|
||||
buildNumber.properties
|
||||
.mvn/timing.properties
|
||||
# https://github.com/takari/maven-wrapper#usage-without-binary-jar
|
||||
.mvn/wrapper/maven-wrapper.jar
|
||||
|
||||
# Eclipse m2e generated files
|
||||
# Eclipse Core
|
||||
.project
|
||||
# JDT-specific (Eclipse Java Development Tools)
|
||||
.classpath
|
||||
|
||||
### Windows ###
|
||||
# Windows thumbnail cache files
|
||||
Thumbs.db
|
||||
Thumbs.db:encryptable
|
||||
ehthumbs.db
|
||||
ehthumbs_vista.db
|
||||
|
||||
# Dump file
|
||||
*.stackdump
|
||||
|
||||
# Folder config file
|
||||
[Dd]esktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
### Gradle ###
|
||||
.gradle
|
||||
build/
|
||||
build-cache/
|
||||
|
||||
# Ignore Gradle GUI config
|
||||
gradle-app.setting
|
||||
|
||||
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
|
||||
!gradle-wrapper.jar
|
||||
|
||||
# Cache of project
|
||||
.gradletasknamecache
|
||||
|
||||
# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898
|
||||
# gradle/wrapper/gradle-wrapper.properties
|
||||
|
||||
### Gradle Patch ###
|
||||
**/build/
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/macos,windows,intellij+all,gradle,maven
|
||||
|
||||
**/run
|
||||
@@ -1,2 +0,0 @@
|
||||
/.project
|
||||
/.classpath
|
||||
@@ -1 +0,0 @@
|
||||
/org.eclipse.jdt.core.prefs
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,144 @@
|
||||
plugins {
|
||||
id("io.github.goooler.shadow") version "8.1.7"
|
||||
id("xyz.jpenilla.run-paper") version "2.3.0"
|
||||
}
|
||||
|
||||
idea {
|
||||
module {
|
||||
isDownloadSources = true
|
||||
}
|
||||
}
|
||||
|
||||
description = "AreaShop"
|
||||
|
||||
dependencies {
|
||||
// Platform
|
||||
compileOnlyApi(libs.spigot)
|
||||
compileOnlyApi(libs.worldeditCore)
|
||||
compileOnlyApi(libs.worldeditBukkit)
|
||||
compileOnlyApi(libs.worldguardCore)
|
||||
compileOnlyApi(libs.worldguardBukkit)
|
||||
compileOnlyApi("com.github.MilkBowl:VaultAPI:1.7")
|
||||
|
||||
// 3rd party libraries
|
||||
api("io.papermc:paperlib:1.0.8")
|
||||
api("com.github.NLthijs48:InteractiveMessenger:e7749258ca")
|
||||
api("com.github.NLthijs48:BukkitDo:819d51ec2b")
|
||||
api("io.github.baked-libs:dough-data:1.2.0")
|
||||
api("com.google.inject:guice:7.0.0") {
|
||||
exclude("com.google.guava")
|
||||
}
|
||||
api("com.google.inject.extensions:guice-assistedinject:7.0.0") {
|
||||
exclude("com.google.guava")
|
||||
}
|
||||
implementation("org.incendo:cloud-paper:2.0.0-beta.8") {
|
||||
exclude("com.google.guava")
|
||||
}
|
||||
implementation("org.incendo:cloud-processors-confirmation:1.0.0-beta.3") {
|
||||
exclude("com.google.guava")
|
||||
}
|
||||
implementation("net.kyori:adventure-text-minimessage:4.16.0")
|
||||
implementation("net.kyori:adventure-platform-bukkit:4.3.2")
|
||||
implementation("org.spongepowered:configurate-yaml:4.1.2")
|
||||
|
||||
// Project submodules
|
||||
api(projects.areashopInterface)
|
||||
api(projects.adapters.platform.platformInterface)
|
||||
api(projects.adapters.platform.paper)
|
||||
|
||||
if (!providers.environmentVariable("JITPACK").isPresent) {
|
||||
// We don't need these adapters if we are only publishing an api jar
|
||||
runtimeOnly(projects.adapters.plugins.worldedit)
|
||||
runtimeOnly(projects.adapters.plugins.worldguard)
|
||||
runtimeOnly(projects.adapters.plugins.fastasyncworldedit)
|
||||
runtimeOnly(projects.adapters.plugins.essentials)
|
||||
}
|
||||
testImplementation("io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT")
|
||||
testImplementation("com.github.seeseemelk:MockBukkit-v1.20:3.86.1")
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.1")
|
||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.10.1")
|
||||
}
|
||||
|
||||
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
tasks {
|
||||
processResources {
|
||||
filesMatching("plugin.yml") {
|
||||
expand("version" to project.version)
|
||||
}
|
||||
}
|
||||
|
||||
assemble {
|
||||
if (!providers.environmentVariable("JITPACK").isPresent) {
|
||||
dependsOn(shadowJar)
|
||||
}
|
||||
}
|
||||
|
||||
jar {
|
||||
archiveBaseName.set("AreaShop")
|
||||
if (!providers.environmentVariable("JITPACK").isPresent) {
|
||||
archiveClassifier.set("original")
|
||||
} else {
|
||||
archiveClassifier.set("")
|
||||
}
|
||||
}
|
||||
|
||||
if (providers.environmentVariable("JITPACK").isPresent) {
|
||||
artifacts {
|
||||
archives(jar)
|
||||
}
|
||||
}
|
||||
|
||||
java {
|
||||
withSourcesJar()
|
||||
}
|
||||
|
||||
val javaComponent = project.components["java"] as AdhocComponentWithVariants
|
||||
javaComponent.withVariantsFromConfiguration(configurations["shadowRuntimeElements"]) {
|
||||
skip()
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
archiveClassifier.set("")
|
||||
base {
|
||||
archiveBaseName.set("AreaShop")
|
||||
}
|
||||
val base = "me.wiefferink.areashop.libraries"
|
||||
relocate("org.incendo.cloud", "${base}.cloud")
|
||||
relocate("me.wiefferink.interactivemessenger", "${base}.interactivemessenger")
|
||||
relocate("me.wiefferink.bukkitdo", "${base}.bukkitdo")
|
||||
relocate("io.papermc.lib", "${base}.paperlib")
|
||||
relocate("io.github.bakedlibs.dough", "${base}.dough")
|
||||
relocate("com.google.inject", "${base}.inject")
|
||||
relocate("com.google.errorprone", "${base}.errorprone")
|
||||
relocate("org.aopalliance", "${base}.aopalliance")
|
||||
relocate("javax.annotation", "${base}.javax.annotation")
|
||||
relocate("jakarta.inject", "${base}.jakarta.inject")
|
||||
relocate("org.jetbrains.annotations", "${base}.jetbrains.annotations")
|
||||
relocate("io.leangen.geantyref", "${base}.geantyref")
|
||||
relocate("net.kyori", "${base}.kyori")
|
||||
relocate("org.checkerframework", "${base}.checkerframework")
|
||||
relocate("org.intellij", "${base}.intellij")
|
||||
relocate("org.spongepowered", "${base}.spongepowered")
|
||||
relocate("org.yaml.snakeyaml", "${base}.snakeyaml")
|
||||
}
|
||||
runServer {
|
||||
// Configure the Minecraft version for our task.
|
||||
// This is the only required configuration besides applying the plugin.
|
||||
// Your plugin's jar (or shadowJar if present) will be used automatically.
|
||||
minecraftVersion("1.20.6")
|
||||
|
||||
downloadPlugins {
|
||||
github("EssentialsX", "essentials", "2.20.1", "EssentialsX-2.20.1.jar")
|
||||
github("MilkBowl", "Vault", "1.7.3", "Vault.jar")
|
||||
// WorldEdit 7.3.3
|
||||
url("https://mediafilez.forgecdn.net/files/5400/331/worldedit-bukkit-7.3.3.jar")
|
||||
// WorldGuard 7.0.10
|
||||
url("https://mediafilez.forgecdn.net/files/5344/377/worldguard-bukkit-7.0.10-dist.jar")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,193 +0,0 @@
|
||||
##############################################
|
||||
# config.yml of the AreaShop plugin #
|
||||
# This plugin has been created by NLThijs48 #
|
||||
# Check the server minecraft.go-craft.com #
|
||||
# and then the Survival server for a demo #
|
||||
##############################################
|
||||
|
||||
########## GENERAL ##########
|
||||
## Chatprefix used for all messages in the chat
|
||||
chatPrefix: '&2[AreaShop]&r '
|
||||
## The characters used for the prices of regions, will appear before the number, for the euro character use '%euro%'
|
||||
moneyCharacter: '$'
|
||||
## The characters used after a currency number, '%euro%' will become the euro character
|
||||
moneyCharacterAfter: ''
|
||||
## Enables / disables debug messages in the console, no need to change
|
||||
debug: false
|
||||
## The .yml language file that should be used, provided by this plugin: EN, NL
|
||||
language: EN
|
||||
## Enable Schematic saving and restoring in general
|
||||
enableSchematics: true
|
||||
## Maximum number of blocks to save to or restore from a .schemetic
|
||||
maximumBlocks: 1000000
|
||||
## Maximum number of locations the teleport function should check to find a safe spot
|
||||
maximumTries: 50000
|
||||
## Enable sending stats to http://mcstats.org/ (Metrics plugin)
|
||||
sendStats: true
|
||||
## Use colors when sending messages to console and log files
|
||||
useColorsInConsole: false
|
||||
## Post error messages in the console when a command run from the config fails (from the 'runCommands' section for example)
|
||||
postCommandErrors: true
|
||||
## Version of the config, do not change!
|
||||
version: 2.0.0
|
||||
## The different tags you can write on the sign to trigger the plugin
|
||||
signTags:
|
||||
## Tag for adding a rent region
|
||||
rent: '[rent]'
|
||||
## Tag for adding a buy region
|
||||
buy: '[buy]'
|
||||
## Tag for adding a sign to an existing region
|
||||
add: '[as]'
|
||||
## Configure the max total regions, max rent regions and max buy regions with different groups (-1 is unlimited)
|
||||
## Assign a group to players by giving them the permission 'areashop.limits.<group>'
|
||||
## Every player already has the group 'default' and ops have the unlimited group
|
||||
## If a player has multiple groups the highest numbers are used
|
||||
limitGroups:
|
||||
default:
|
||||
total: 1
|
||||
rents: 1
|
||||
buys: 1
|
||||
unlimited:
|
||||
total: -1
|
||||
rents: -1
|
||||
buys: -1
|
||||
## Below are profiles for the signs, you can assign profiles to regions
|
||||
## by setting 'general.signProfile' in default.yml, groups or individual regions
|
||||
signProfiles:
|
||||
default:
|
||||
## Below is the format for each sign state, the following tags can be used for signs and commands:
|
||||
## %region%, %player%, %uuid%, %price%, %duration%, %world%, %type%, %until%, %untilshort%
|
||||
## The following sections can be added for performing certain commands when the sign is clicked:
|
||||
## rightClickPlayer, rightClickConsole, shiftRightClickPlayer, shiftRightClickConsole,
|
||||
## leftClickPlayer, leftClickConsole, shiftLeftClickPlayer, shiftLeftClickConsole
|
||||
## Sections with 'Player' at the end will be run by the clicking player and 'Console' ones from the console
|
||||
forrent:
|
||||
line1: '&2&l[For Rent]'
|
||||
line2: '%region%'
|
||||
line3: '%duration%'
|
||||
line4: '%price%'
|
||||
rightClickPlayer:
|
||||
- 'as rent %region%'
|
||||
leftClickPlayer:
|
||||
- 'as info region %region%'
|
||||
rented:
|
||||
line1: '&4&l[Rented]'
|
||||
line2: '%region%'
|
||||
line3: '%player%'
|
||||
line4: '%untilshort%'
|
||||
rightClickPlayer:
|
||||
- 'as rent %region%'
|
||||
leftClickPlayer:
|
||||
- 'as info region %region%'
|
||||
shiftRightClickPlayer:
|
||||
- 'as unrent %region%'
|
||||
forsale:
|
||||
line1: '&2&l[For Sale]'
|
||||
line2: '%region%'
|
||||
line3: '%price%'
|
||||
line4:
|
||||
rightClickPlayer:
|
||||
- 'as buy %region%'
|
||||
leftClickPlayer:
|
||||
- 'as info region %region%'
|
||||
sold:
|
||||
line1: '&4&l[Sold]'
|
||||
line2: '%region%'
|
||||
line3: '%player%'
|
||||
line4:
|
||||
rightClickPlayer:
|
||||
- 'as buy %region%'
|
||||
leftClickPlayer:
|
||||
- 'as info region %region%'
|
||||
shiftRightClickPlayer:
|
||||
- 'as sell %region%'
|
||||
## Option to run certain commands when one of these events happen
|
||||
## Commands at a 'before' section will execute before the region details are changed in the AreaShop system
|
||||
## and before any other actions occurred (changing signs, saving/loading schematics, etc.),
|
||||
## the 'after' commands will be run when all changes are done.
|
||||
## After 'before' or 'after' you can create a list of commands (see example at the created event)
|
||||
eventCommandProfiles:
|
||||
default:
|
||||
created:
|
||||
before:
|
||||
after:
|
||||
## - "say An AreaShop region has been created: %region%"
|
||||
deleted:
|
||||
before:
|
||||
after:
|
||||
rented:
|
||||
before:
|
||||
after:
|
||||
extended:
|
||||
before:
|
||||
after:
|
||||
unrented:
|
||||
before:
|
||||
after:
|
||||
bought:
|
||||
before:
|
||||
after:
|
||||
sold:
|
||||
before:
|
||||
after:
|
||||
## For the following events you can specify if you want to restore or save the region to a schematic
|
||||
## After 'save:' or 'restore:' you enter the name of the file, %region% will be replaced by the region name (.schematic will be added automatically)
|
||||
## %type% represents the type of the region, could be 'rent' or 'buy'
|
||||
## If your regions are all the same size you could use just 1 file as the restore file, just enter a name without %region%
|
||||
## Be carefull with these options, it could crash your server or destroy (parts of) your world if used wrong!
|
||||
schematicProfiles:
|
||||
default:
|
||||
created:
|
||||
save: '%type%-%region%'
|
||||
restore: ''
|
||||
deleted:
|
||||
save: ''
|
||||
restore: '%type%-%region%'
|
||||
rented:
|
||||
save: ''
|
||||
restore: ''
|
||||
unrented:
|
||||
save: ''
|
||||
restore: '%type%-%region%'
|
||||
bought:
|
||||
save: ''
|
||||
restore: ''
|
||||
sold:
|
||||
save: ''
|
||||
restore: '%type%-%region%'
|
||||
## Flag profiles to specify what flags should be set on the WorldGuard regions
|
||||
## All region flags can be used + members, owners, priority and parent.
|
||||
flagProfiles:
|
||||
default:
|
||||
forrent:
|
||||
members: -%player%
|
||||
greeting: '&2[AreaShop]&f %region% can be rented for %price% per %duration%'
|
||||
rented:
|
||||
members: +%player%
|
||||
greeting: '&2[AreaShop]&f %region% is rented by %player% until %until%'
|
||||
forsale:
|
||||
members: -%player%
|
||||
greeting: '&2[AreaShop]&f %region% can be bought for %price%'
|
||||
sold:
|
||||
members: +%player%
|
||||
greeting: '&2[AreaShop]&f %region% is bought by %player%'
|
||||
|
||||
|
||||
########## RENTING ##########
|
||||
## How much seconds between checking if renting has expired (don't put this to low)
|
||||
checkDelay: 60
|
||||
## Timeformat to use on the signs, default is like '30-06 14:52', US format: 'MM-dd KK:mm a'
|
||||
## Search for 'java SimpleDateFormat' for more options and documentation
|
||||
timeFormatSign: 'dd-MM HH:mm'
|
||||
## Timeformat used in the chat, default is like '30 june 2014 14:52', US format: 'MMMMMMMMMMMMMMMMM dd yyyy KK:mm a'
|
||||
## Search for 'java SimpleDateFormat' for more options and documentation
|
||||
timeFormatChat: 'dd MMMMMMMMMMMMMMMMM yyyy HH:mm'
|
||||
## Time indicators, used for specifing rent duration on the signs
|
||||
## Be careful with deleting words, will break signs using those, adding is no problem
|
||||
minutes: [m, min, mins, minute, minutes, minuten, minuut]
|
||||
hours: [h, hour, hours, uur, uren]
|
||||
days: [d, day, days, dag, dagen]
|
||||
months: [M, month, months, maanden, maand]
|
||||
years: [y, year, years, jaar, jaren]
|
||||
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
### All settings below are default settings and can be overridden
|
||||
### by group settings or region settings (copy a section to a region or group and change them there)
|
||||
|
||||
########## GENERAL ##########
|
||||
general:
|
||||
## Set this to true to enable saving/restoring for regions as specified in the profile below, which is specified in the config
|
||||
enableRestore: false
|
||||
## The schematic profile as specified in the config
|
||||
schematicProfile: 'default'
|
||||
## The event commands profile as specified in the config
|
||||
eventCommandProfile: 'default'
|
||||
## The profile for the format of the sign as specified in the config
|
||||
signProfile: 'default'
|
||||
## The profile for the WorldGuard flags as specified in the config
|
||||
flagProfile: 'default'
|
||||
## The y location within the region to start searching for safe teleport spots (x and z will be in the middle of the region)
|
||||
## Possible values: bottom, middle, top
|
||||
teleportLocationY: bottom
|
||||
## If true the teleportation algorithm only allows telportation to inside the region, otherwise it will expand algorithm
|
||||
## a cube from the starting point to check for safe spots (then it could end outside the region)
|
||||
## If you set a teleport location outside of the region with /as settp then setting this to true breaks that teleport (players cannot use it)
|
||||
teleportIntoRegion: true
|
||||
|
||||
########## RENTING ##########
|
||||
rent:
|
||||
## The default price of a renting region
|
||||
price: 1000
|
||||
## The default duration of a renting region
|
||||
duration: '1 day'
|
||||
## The percentage of the renting price you get back if you unrent the region (price of time left will be multiplied by this/100)
|
||||
moneyBack: 100
|
||||
## Maximum number of extends a player can do (-1 for infinite, 0 for no extending)
|
||||
maxExtends: -1
|
||||
|
||||
########## BUYING ##########
|
||||
buy:
|
||||
## The default price of a buying region
|
||||
price: 1000
|
||||
## The percentage of the buying price you get back if you sell the region
|
||||
moneyBack: 100
|
||||
@@ -1,274 +0,0 @@
|
||||
###################################################
|
||||
# English language file for the AreaShop plugin #
|
||||
###################################################
|
||||
# Copy this file and change the strings to your #
|
||||
# favor. Then change the 'language' setting in #
|
||||
# the config to the filename (excluding .yml) #
|
||||
###################################################
|
||||
|
||||
########## General strings
|
||||
total-maximum: "You can't rent and buy more than %0% region(s) in total"
|
||||
|
||||
cmd-notValid: "That command is not valid, use '/as help' for info"
|
||||
cmd-onlyByPlayer: "This command can only be run by a player"
|
||||
cmd-weOnlyByPlayer: "Using a WorldEdit selection is only possible as a player, specify the region name as extra argument"
|
||||
cmd-noSelection: "You don't have a WorldEdit selection"
|
||||
cmd-noRegionsFound: "No regions registered in AreaShop are found in your selection"
|
||||
cmd-noWERegionsFound: "No WorldEdit regions intersecting your selection are found"
|
||||
|
||||
########## Help command strings
|
||||
help-header: "Help page, commands that you can execute"
|
||||
help-alias: "Command aliases: /areashop, /as"
|
||||
help-help: "&6/as help &7-&r Shows this help page"
|
||||
help-info: "&6/as info &7-&r Get info about current regions"
|
||||
help-rent: "&6/as rent &7-&r Rent a region or extend your current rent"
|
||||
help-buy: "&6/as buy &7-&r Buy a region"
|
||||
help-unrent: "&6/as unrent &7-&r Unrent a region"
|
||||
help-unrentOwn: "&6/as unrent &7-&r Unrent your own region"
|
||||
help-sell: "&6/as sell &7-&r Sell a region"
|
||||
help-sellOwn: "&6/as sell &7-&r Sell your own region"
|
||||
help-updaterents: "&6/as updaterents &7-&r Update all rent signs and regions"
|
||||
help-updatebuys: "&6/as updatebuys &7-&r Update all buy signs and regions"
|
||||
help-reload: "&6/as reload &7-&r Reload the config and languages"
|
||||
help-setrestore: "&6/as setrestore &7-&r Set the profile for restoring and on/off "
|
||||
help-setprice: "&6/as setprice &7-&r Change the price of a rent region"
|
||||
help-rentduration: "&6/as rentduration &7-&r Change the duration of a rent region"
|
||||
help-teleport: "&6/as tp &7-&r Teleport to your bought/rented regions"
|
||||
help-teleportAll: "&6/as tp &7-&r Teleport to a rent/buy region"
|
||||
help-setteleport: "&6/as settp &7-&r Set teleport position for bought/rented regions"
|
||||
help-setteleportAll: "&6/as settp &7-&r Set teleport position for a region"
|
||||
help-find: "&6/as find &7-&r Find an empty buy or rent"
|
||||
help-groupadd: "&6/as groupadd &7-&r Add a region to a group"
|
||||
help-groupdel: "&6/as groupdel &7-&r Delete a region from a group"
|
||||
help-grouplist: "&6/as grouplist &7-&r Display all groups currently registered"
|
||||
help-groupinfo: "&6/as groupinfo &7-&r Display information about a group"
|
||||
help-schemevent: "&6/as schemevent &7-&r Trigger a schematic event for a region"
|
||||
help-add: "&6/as add &7-&r Register a region as rent or buy"
|
||||
help-del: "&6/as del &7-&r Delete a registered region from AreaShop"
|
||||
help-addsign: "&6/as addsign &7-&r Add a sign to an existing region"
|
||||
help-delsign: "&6/as delsign &7-&r Delete the sign you are looking at"
|
||||
|
||||
############ Other command strings
|
||||
rent-help: "/as rent [regionname], the region you stand in will be used if not specified"
|
||||
rent-noPermission: "You don't have permission to rent a region"
|
||||
rent-maximum: "You can't rent more than %0% region(s)"
|
||||
rent-payError: "Something went wrong with paying, try again later"
|
||||
rent-rented: "You rented %0% until %1%"
|
||||
rent-extended: "You extended your rent of %0% until %1%"
|
||||
rent-extend: "You can extend your rent by rightclicking the sign again or using /as rent"
|
||||
rent-lowMoneyExtend: "You don't have enough money to extend the rent (you have %0% and you need %1%)"
|
||||
rent-lowMoneyRent: "You don't have enough money to rent this region (you have %0% and you need %1%)"
|
||||
rent-someoneElse: "Someone else already rented this region"
|
||||
rent-notRentable: "That region is not available for renting"
|
||||
rent-maxExtends: "You cannot extend this rent anymore (the maximum is %0% times), however after the rent is over you can rent this region again"
|
||||
|
||||
buy-help: "/as buy [regionname], the region you stand in will be used if not specified"
|
||||
buy-noPermission: "You don't have permission to buy a region"
|
||||
buy-notBuyable: "That region is not available for buying"
|
||||
buy-maximum: "You can't buy more than %0% region(s)"
|
||||
buy-payError: "Something went wrong with paying, try again later"
|
||||
buy-succes: "You succesfully bought %0%"
|
||||
buy-lowMoney: "You don't have enough money to buy this region (you have %0% and you need %1%)"
|
||||
buy-yours: "You already own this region"
|
||||
buy-someoneElse: "Someone else already bought this region"
|
||||
|
||||
unrent-help: "/as unrent [regionname], the region you stand in will be used if not specified"
|
||||
unrent-noPermission: "You don't have permission to unrent a region"
|
||||
unrent-noPermissionOther: "You don't have permission to unrent another region"
|
||||
unrent-notRegistered: "The region can't be unrent because it is not registered for renting"
|
||||
unrent-notRented: "The region can't be unrent because it is not rented"
|
||||
unrent-unrented: "Your region has been unrented"
|
||||
unrent-other: "The region has been unrented for player %0%"
|
||||
unrent-expired: "Your rent of %0% has expired"
|
||||
|
||||
sell-help: "/as sell [regionname], the region you stand in will be used if not specified"
|
||||
sell-notRegistered: "The region can't be selled because it is not registered for buying"
|
||||
sell-notBought: "The region can't be selled because it is not someone's property"
|
||||
sell-sold: "The region has been sold for player %0%"
|
||||
sell-soldYours: "Your region has been sold"
|
||||
sell-noPermission: "You don't have permission to sell a region"
|
||||
sell-noPermissionOther: "You don't have permission to sell another region"
|
||||
|
||||
rents-updated: "All signs and regions for renting have been updated"
|
||||
rents-notUpdated: "Not all signs have been updated, maybe reload fixes it"
|
||||
rents-noPermission: "You don't have permission to update all rent signs and regions"
|
||||
|
||||
buys-updated: "All signs and regions for selling have been updated"
|
||||
buys-notUpdated: "Not all signs have been updated, maybe reload fixes it"
|
||||
buys-noPermission: "You don't have permission to update all buy signs and regions"
|
||||
|
||||
reload-reloaded: "The config has been reloaded successfully"
|
||||
reload-noPermission: "You don't have permission to reload the config"
|
||||
|
||||
info-help: "/as info <all|rented|forrent|sold|forsale|player|region>"
|
||||
info-all-rents: "Regions registered for renting: &7%0%"
|
||||
info-all-noRents: "There are no regions registered for renting"
|
||||
info-all-buys: "Regions registered for buying: &7%0%"
|
||||
info-all-noBuys: "There are no regions registered for buying"
|
||||
info-rented: "Rented regions: &7%0%"
|
||||
info-noRented: "No regions are rented"
|
||||
info-unrented: "Unrented regions: &7%0%"
|
||||
info-noUnrented: "All regions are rented"
|
||||
info-sold: "Sold regions: &7%0%"
|
||||
info-noSold: "No regions are sold"
|
||||
info-forsale: "Regions for sale: &7%0%"
|
||||
info-noForsale: "All regions are sold"
|
||||
info-playerHelp: "/as info player <name>"
|
||||
info-playerRents: "Regions rented by %0%: &7%1%"
|
||||
info-playerNoRents: "%0% has not rented a region"
|
||||
info-playerBuys: "Regions bought by %0%: &7%1%"
|
||||
info-playerNoBuys: "%0% has not bought a region"
|
||||
info-regionHelp: "/as info region [name], the region you stand in will be used if not specified"
|
||||
info-regionNoRenting: "%0% is not registered for renting"
|
||||
info-regionRenting: "&6Renting details for %0%:"
|
||||
info-regionRentedBy: "Rented by: &7%0% until %1%"
|
||||
info-regionNotRented: "Currently not rented"
|
||||
info-regionBuying: "&6Buying details for %0%:"
|
||||
info-regionNoBuying: "%0% is not registered for buying"
|
||||
info-regionNotBought: "Currently not sold"
|
||||
info-regionBoughtBy: "Bought by: &7%0%"
|
||||
info-regionSign: "Sign location(s): %0%"
|
||||
info-regionSignLocation: "&7(%0%, %1%, %2%, %3%)&r"
|
||||
info-regionNoSign: "There is no sign registered for this region"
|
||||
info-regionPriceDuration: "Price: &7%0% for each %1%"
|
||||
info-regionPrice: "Price: &7%0%"
|
||||
info-regionRestore: "Restoring enabled: &7%0%"
|
||||
info-regionRestoreProfile: "Restoring profile: &7%0%"
|
||||
info-regionTPLocation: "Teleport location: &7World=%0%, X=%1%, Y=%2%, Z=%3%, Pitch=%4%, Yaw=%5%"
|
||||
info-regionNoTP: "No teleport location set"
|
||||
info-regionNotExisting: "Region %0% is not registered"
|
||||
|
||||
setrestore-help: "/as setrestore <region> <true|false|general> [profile]"
|
||||
setrestore-noPermission: "You don't have permission to change the restore settings"
|
||||
setrestore-notRegistered: "%0% is not registered"
|
||||
setrestore-invalidSetting: "'%0%' is not a valid state, should be true, false or general"
|
||||
setrestore-success: "Succesfully set the restore setting of %0% to '%1%'"
|
||||
setrestore-successProfile: "Succesfully set the restore setting of %0% to '%1%' and the profile to '%2%'"
|
||||
|
||||
setprice-noPermission: "You don't have permission to change the price of a region"
|
||||
setprice-help: "/as setprice <price> [region], the region you stand in will be used if not specified"
|
||||
setprice-notRegistered: "%0% is not registered in AreaShop"
|
||||
setprice-wrongPrice: "'%0%' is not a valid price"
|
||||
setprice-successRent: "Price of region %0% changed to %1% per %2%"
|
||||
setprice-successBuy: "Price of region %0% changed to %1%"
|
||||
|
||||
rentduration-noPermission: "You don't have permission to change the duration of a rent"
|
||||
rentduration-help: "/as rentduration <amount> <identifier> [region], the region you stand in will be used if not specified"
|
||||
rentduration-notRegistered: "%0% is not registered as a rent"
|
||||
rentduration-wrongAmount: "'%0%' is not a valid amount, use a whole number"
|
||||
rentduration-wrongFormat: "'%0%' is not a proper timeformat, check the documentation on Bukkit"
|
||||
rentduration-success: "Duration of region %0% changed to '%1%'"
|
||||
|
||||
setup-noRegion: "You did not specify a region on the second line"
|
||||
setup-wrongRegion: "The region you specified does not exist"
|
||||
setup-alreadyRentSign: "The region you specified already has a sign for renting"
|
||||
setup-alreadyBuySign: "The region you specified already has a sign for buying"
|
||||
setup-noDuration: "You did not specify how long the region can be rented, do this on the third line"
|
||||
setup-wrongDuration: "The time specified is not in the correct format, example: 1 day"
|
||||
setup-noPrice: "You did not specify the price on the fourth line"
|
||||
setup-wrongPrice: "You did not specify the price correctly, use a number only"
|
||||
setup-rentSuccess: "Renting of region %0% is setup correctly"
|
||||
setup-buySuccess: "Buying of region %0% is setup correctly"
|
||||
setup-noPermissionRent: "You don't have permission for setting up renting of regions"
|
||||
setup-noPermissionBuy: "You don't have permission for setting up buying of regions"
|
||||
setup-couldNotDetect: "Found multiple regions with the same priority and/or parent/child relation, specify one on the second line (2 of the regions that were found: %0% and %1%)"
|
||||
|
||||
destroy-noPermissionRent: "You don't have permission for destroying a sign for renting a region"
|
||||
destroy-noPermissionBuy: "You don't have permission for destroying a sign for buying a region"
|
||||
destroy-successRent: "Renting of %0% successfully removed"
|
||||
destroy-successBuy: "Buying of %0% successfully removed"
|
||||
|
||||
teleport-help: "/as tp <region> [sign]"
|
||||
teleport-noRentOrBuy: "Region '%0%' is not registered as rent or buy"
|
||||
teleport-noPermission: "You don't have permission to teleport to a region"
|
||||
teleport-noPermissionOther: "You don't have permission to teleport to region you do not own"
|
||||
teleport-success: "You teleported to %0%"
|
||||
teleport-noSafe: "No safe position found in region %0%, no spots in region left or maximum tries exceeded (%1%/%2%)"
|
||||
|
||||
setteleport-help: "/as settp [region] [reset], the region you stand in will be used if not specified"
|
||||
setteleport-noPermission: "You don't have permission to set the teleport location"
|
||||
setteleport-noPermissionAll: "You don't have permission to set the teleport location for a region you do not own"
|
||||
setteleport-noRentOrBuy: "Region '%0%' is not registered as rent or buy"
|
||||
setteleport-success: "Teleport location of %0% set"
|
||||
setteleport-notInside: "The location has to be inside the region"
|
||||
setteleport-reset: "Teleport location of %0% has been reset"
|
||||
|
||||
find-help: "/as find <buy|rent> [maxprice]"
|
||||
find-noPermission: "You don't have permission to teleport to signs, so you can't use find"
|
||||
find-success: "Found a %0% region: %1%, while searching with a max price of your balance: %2%"
|
||||
find-successMax: "Found a %0% region: %1%, while searching with a max price of %2%"
|
||||
find-wrongMaxPrice: "The specified maximum price is not a correct number: %0%"
|
||||
find-noneFound: "No %0% region found while searching with a max price of your balance: %1%"
|
||||
find-noneFoundMax: "No %0% region found while searching with a max price of %1%"
|
||||
|
||||
groupadd-help: "/as groupadd <group> [region], if no region specified all regions from your WorldEdit selection are used"
|
||||
groupadd-noPermission: "You don't have permission to add regions to groups"
|
||||
groupadd-noRegion: "The specified region is not registered: %0%"
|
||||
groupadd-success: "Region %0% has been added to group '%1%', this group now has %2% member(s)"
|
||||
groupadd-failed: "Region %0% is already a member of group '%1%'"
|
||||
groupadd-weSuccess: "Added to group %0%: &7%1%"
|
||||
groupadd-weFailed: "Were already in group %0%: &7%1%"
|
||||
|
||||
groupdel-help: "/as groupdel <group> [region], if no region specified all regions from your WorldEdit selection are used"
|
||||
groupdel-noPermission: "You don't have permission to remove regions from groups"
|
||||
groupdel-noRegion: "The specified region is not registered: %0%"
|
||||
groupdel-success: "Region %0% has been removed from group '%1%', this group now has %2% member(s)"
|
||||
groupdel-failed: "Region %0% is not a member of group '%1%'"
|
||||
groupdel-weSuccess: "Removed from group %0%: &7%1%"
|
||||
groupdel-weFailed: "Were not in group %0% anyway: &7%1%"
|
||||
|
||||
grouplist-noPermission: "You don't have permission to display the registered groups"
|
||||
grouplist-noGroups: "There are currently no groups registered"
|
||||
grouplist-success: "The following groups are registered: &7%0%"
|
||||
|
||||
groupinfo-help: "/as groupinfo <group>"
|
||||
groupinfo-noPermission: "You don't have permission to display information about a group"
|
||||
groupinfo-noGroup: "There is no group registered with the name '%0%', use /as grouplist to check groups"
|
||||
groupinfo-members: "The following regions are member of group %0%: &7%1%"
|
||||
groupinfo-noMembers: "Group %0% does not have any members"
|
||||
|
||||
schemevent-help: "/as schemevent <region> <created|deleted|rented|unrented|bought|sold>"
|
||||
schemevent-noRegion: "The specified region is not registered: %0%"
|
||||
schemevent-wrongEvent: "The specified event '%0%' does not exist, use one of the following: &7%1%"
|
||||
schemevent-success: "Event '%0%' has succesfully been triggered for region %1%"
|
||||
schemevent-noPermission: "You don't have permission to trigger schematic events"
|
||||
|
||||
add-help: "/as add <rent|buy> [region] [world]"
|
||||
add-noPermission: "You don't have permission to add a region to AreaShop"
|
||||
add-success: "Added as %0%: &7%1%"
|
||||
add-failed: "Already registered: &7%0%"
|
||||
add-specifyWorld: "Specify the world of the region when using from console"
|
||||
add-incorrectWorld: "World '%0%' not found, try again (case-sensitive)"
|
||||
add-noRegion: "Region '%0%' does not exist in this world"
|
||||
|
||||
del-noRegion: "Region '%0%' is not registered in AreaShop"
|
||||
del-noPermission: "You don't have permission to remove regions"
|
||||
del-success: "Removed regions: &7%0%"
|
||||
del-failed: "No permission to remove or not registered: &7%0%"
|
||||
|
||||
addsign-help: "/as addsign [region] [profile]"
|
||||
addsign-noSign: "You are not looking at a sign"
|
||||
addsign-noRegion: "Region '%0%' cannot be found"
|
||||
addsign-noRegions: "No region found around the sign position"
|
||||
addsign-couldNotDetect: "Found multiple regions around the sign, specify region as extra argument (2 of the regions that were found: %0% and %1%)"
|
||||
addsign-couldNotDetectSign: "Found multiple regions around the sign, specify region on the second line (2 of the regions that were found: %0% and %1%)"
|
||||
addsign-wrongProfile: "The specified profile does not exist, use one of the following (check config): &7%0%"
|
||||
addsign-success: "The sign has been added to %0%"
|
||||
addsign-successProfile: "The sign has been added to %0% with profile %1%"
|
||||
addsign-alreadyRegistered: "That sign is already registered for region %0%"
|
||||
addsign-noPermission: "You don't have permission to add a sign"
|
||||
|
||||
delsign-noSign: "You are not looking at a sign"
|
||||
delsign-noPermission: "You don't have permission to delete a sign"
|
||||
delsign-noRegion: "That sign does not belong to an AreaShop region"
|
||||
delsign-success: "The sign has been removed from region %0%"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,173 +0,0 @@
|
||||
###################################################
|
||||
# Dutch language file for the AreaShop plugin #
|
||||
###################################################
|
||||
# Copy this file and change the strings to your #
|
||||
# favor. Then change the 'language' setting in #
|
||||
# the config to the filename (excluding .yml) #
|
||||
# NOT UPDATED since 1.2.1 #
|
||||
###################################################
|
||||
|
||||
########## Command strings
|
||||
total-maximum: "Je kunt niet meer dan %0% gebied(en) in totaal huren en kopen"
|
||||
|
||||
cmd-onlyByPlayer: "Dit commando kan alleen door een speler uitgevoert worden"
|
||||
cmd-notValid: "Dat commando is niet geldig , gebruik '/as help' voor informatie"
|
||||
|
||||
rent-regionNotRentable: "Dat gebied is niet beschikbaar om te huren"
|
||||
rent-help: "/as rent <gebiednaam>"
|
||||
rent-noPermission: "Je hebt geen toestemming om een gebied te huren"
|
||||
rent-maximum: "Je kunt niet meer dan %0% gebied(en) huren"
|
||||
rent-payError: "Er is iets mis gegaan met betalen, probeer het later opnieuw"
|
||||
rent-rented: "Je hebt %0% tot %1% gehuurd"
|
||||
rent-extended: "Je hebt je huur van %0% verlengt tot %1%"
|
||||
rent-extend: "Je kunt je huur verlengen door opnieuw op het bordje te klikken of gebruik te maken van /as rent"
|
||||
rent-lowMoneyExtend: "Je hebt niet genoeg geld om de huur te verlengen (je hebt %0% van de %1%)"
|
||||
rent-lowMoneyRent: "Je hebt niet genoeg geld om het gebied te huren (je hebt %0% van de %1%)"
|
||||
rent-someoneElse: "Iemand anders heeft dit gebied al gehuurd"
|
||||
rent-notRentable: "Dat gebied is niet beschikbaar om te huren"
|
||||
|
||||
buy-help: "/as buy <gebiednaam>"
|
||||
buy-noPermission: "Je hebt geen toestemming om een gebied te kopen"
|
||||
buy-notBuyable: "Dat gebied is niet beschikbaar om te kopen"
|
||||
buy-maximum: "Je kunt niet meer dan %0% gebied(en) kopen"
|
||||
buy-payError: "Er is iets mis gegaan met betalen, probeer het later opnieuw"
|
||||
buy-succes: "Je hebt %0% succesvol gekocht"
|
||||
buy-lowMoney: "Je hebt niet genoeg geld om het gebied te kopen (je hebt %0% van de %1%)"
|
||||
buy-yours: "Je hebt dit gebied al gekocht"
|
||||
buy-someoneElse: "Iemand anders heeft dit gebied al gekocht"
|
||||
|
||||
unrent-help: "/as unrent <gebiednaam>"
|
||||
unrent-noPermission: "Je hebt geen toestemming om te stoppen met huren"
|
||||
unrent-noPermissionOther: "Je hebt geen toestemming om iemand anders huur te stoppen"
|
||||
unrent-notRegistered: "De huur kan niet gestopt worden want het gebied is niet geregistreerd om te huren"
|
||||
unrent-notRented: "De huur kan niet gestopt worden want het gebied is niet gehuurd"
|
||||
unrent-unrented: "De huur van je gebied is gestopt"
|
||||
unrent-other: "De huur voor het gebied is gestopt voor speler %0%"
|
||||
unrent-expired: "De huur van je gebied %0% is gestopt"
|
||||
|
||||
sell-help: "/as sell <gebiednaam>"
|
||||
sell-notRegistered: "Het gebied kan niet verkocht worden want het staat niet geregistreerd om te kopen"
|
||||
sell-notBought: "Het gebied kan niet verkocht worden want het is niet gekocht"
|
||||
sell-sold: "Het gebied is verkocht voor speler %0%"
|
||||
sell-soldYours: "Je gebied is verkocht"
|
||||
sell-noPermission: "Je hebt geen toestemming om een gebied te verkopen"
|
||||
sell-noPermissionOther: "Je hebt geen toestemming om een gebied van iemand anders te verkopen"
|
||||
|
||||
rents-updated: "Alle borden en gebieden voor de verhuur zijn geupdate"
|
||||
rents-notUpdated: "Niet alle borden zijn geupdate, een reload zou het op kunnen lossen"
|
||||
rents-noPermission: "Je hebt geen toestemming om alle verhuur borden en gebieden te updaten"
|
||||
|
||||
buys-updated: "Alle borden en gebieden voor de verkoop zijn geupdate"
|
||||
buys-notUpdated: "Niet alle borden zijn geupdate, een reload zou het op kunnen lossen"
|
||||
buys-noPermission: "Je hebt geen toestemming om alle verkoop borden en gebieden te updaten"
|
||||
|
||||
reload-reloaded: "De config is succesvol opnieuw ingeladen"
|
||||
reload-noPermission: "Je hebt geen toestemming om de config opnieuw in te laden"
|
||||
|
||||
info-help: "/as info <all|rented|forrent|sold|forsale|player|region>"
|
||||
info-all-rents: "Gebieden geregistreerd voor de verhuur: %0%"
|
||||
info-all-noRents: "Er zijn geen gebieden geregistreerd voor de verhuur"
|
||||
info-all-buys: "Gebieden geregistreerd voor de verkoop: %0%"
|
||||
info-all-noBuys: "Er zijn geen gebieden geregistreerd voor de verkoop"
|
||||
info-rented: "Verhuurde gebieden: %0%"
|
||||
info-noRented: "Er zijn geen verhuurde gebieden"
|
||||
info-unrented: "Gebieden te huur: %0%"
|
||||
info-noUnrented: "Alle gebieden zijn verhuurd"
|
||||
info-sold: "Verkochte gebieden: %0%"
|
||||
info-noSold: "Alle gebieden zijn verkocht"
|
||||
info-forsale: "Gebieden te koop: %0%"
|
||||
info-noForsale: "Alle gebieden zijn verkocht"
|
||||
info-playerHelp: "/as info player <naam>"
|
||||
info-playerRents: "Gebieden gehuurd door %0%: %1%"
|
||||
info-playerNoRents: "%0% heeft geen gebied gehuurd"
|
||||
info-playerBuys: "Gebieden gekocht door %0%: %1%"
|
||||
info-playerNoBuys: "%0% heeft geen gebieden gekocht"
|
||||
info-regionHelp: "/as info region <naam>"
|
||||
info-regionNoRenting: "%0% is niet geregistreerd voor verhuur"
|
||||
info-regionRenting: "&6Huur informatie voor %0%"
|
||||
info-regionRentedBy: "Gehuurd door: %0% tot %1%"
|
||||
info-regionNotRented: "Nu niet verhuurd"
|
||||
info-regionBuying: "&6Verkoop informatie voor %0%"
|
||||
info-regionNoBuying: "%0% is niet geregistreerd voor verkoop"
|
||||
info-regionNotBought: "Nu niet verkocht"
|
||||
info-regionBoughtBy: "Gekocht door: %0%"
|
||||
info-regionSign: "Plek van het bordje: wereld=%0%, X=%1%, Y=%2%, Z=%3%"
|
||||
info-regionPriceDuration: "Prijs: %0% voor elke %1%"
|
||||
info-regionPrice: "Prijs: %0%"
|
||||
info-regionRestore: "Herstellen ingeschakeld: %0%"
|
||||
info-regionRestoreProfile: "Herstel profiel: %0%"
|
||||
|
||||
help-header: "Help pagina, commando's die jij kunt uitvoeren"
|
||||
help-alias: "Commando aliassen: /areashop, /as"
|
||||
help-help: "&6/as help &7-&r Laat deze help pagina zien"
|
||||
help-info: "&6/as info &7-&r Vraag informatie over gebieden op"
|
||||
help-rent: "&6/as rent &7-&r Huur een gebied of verleng de huur"
|
||||
help-buy: "&6/as buy &7-&r Koop een gebied"
|
||||
help-unrent: "&6/as unrent &7-&r Stop de huur van een gebied"
|
||||
help-unrentOwn: "&6/as unrent &7-&r Stop de huur van een eigen gebied"
|
||||
help-sell: "&6/as sell &7-&r Verkoop een gebied"
|
||||
help-sellOwn: "&6/as sell &7-&r Verkoop een eigen gebied"
|
||||
help-updaterents: "&6/as updaterents &7-&r Update alle huur borden en gebieden"
|
||||
help-updatebuys: "&6/as updatebuys &7-&r Update alle koop borden en gebieden"
|
||||
help-reload: "&6/as reload &7-&r Herlaad de config en de taalbestanden"
|
||||
help-rentrestore: "&6/as rentrestore &7-&r Laat dit huur gebied herstellen of niet"
|
||||
help-buyrestore: "&6/as buyrestore &7-&r Laat dit koop gebied herstellen of niet"
|
||||
help-rentprice: "&6/as rentprice &7-&r Verander de prijs van een huur gebied"
|
||||
help-buyprice: "&6/as buyprice &7-&r Verander de prijs van een koop gebied"
|
||||
help-rentduration: "&6/as rentduration &7-&r Verander de looptijd van een huur gebied"
|
||||
help-teleport: "&6/as tp &7-&r Teleporteer naar je gekochte/gehuurde gebieden"
|
||||
help-teleportAll: "&6/as tp &7-&r Teleporteer naar koop/huur gebieden"
|
||||
|
||||
rentrestore-help: "/as rentrestore <gebied> <true|false|general> [profiel]"
|
||||
rentrestore-noPermission: "Je hebt geen toestemming om herstel instellingen te veranderen bij een huur gebied"
|
||||
rentrestore-notRegistered: "%0% is niet geregistreerd als een huur gebied"
|
||||
rentrestore-invalidSetting: "'%0%' is geen goede optie, gebruik true, false of general"
|
||||
rentrestore-success: "Succesvol de herstel optie gezet van %0% naar '%1%'"
|
||||
rentrestore-successProfile: "Succesvol de herstel optie gezet van %0% naar '%1%' en het profiel naar '%2%'"
|
||||
|
||||
buyrestore-help: "/as buyrestore <gebied> <true|false|general> [profiel]"
|
||||
buyrestore-noPermission: "Je hebt geen toestemming om herstel instellingen te veranderen bij geen koop gebied"
|
||||
buyrestore-notRegistered: "%0% is niet geregistreerd als een koop gebied"
|
||||
buyrestore-invalidSetting: "'%0%' is geen goede optie, gebruik true, false of general"
|
||||
buyrestore-success: "Succesvol de herstel optie gezet van %0% naar '%1%'"
|
||||
buyrestore-successProfile: "Succesvol de herstel optie gezet van %0% naar '%1%' en het profiel naar '%2%'"
|
||||
|
||||
rentprice-noPermission: "Je hebt geen toestemming om de prijs van een huur gebied te veranderen"
|
||||
rentprice-help: "/as rentprice <gebied> <prijs>"
|
||||
rentprice-notRegistered: "%0% is niet geregistreerd als een huur gebied"
|
||||
rentprice-wrongPrice: "'%0%' is geen goede prijs"
|
||||
rentprice-success: "Prijs van gebied %0% is veranderd naar %1% per %2%"
|
||||
|
||||
buyprice-noPermission: "Je hebt geen toestemming om de prijs van een koop gebied te veranderen"
|
||||
buyprice-help: "/as buyprice <gebied> <prijs>"
|
||||
buyprice-notRegistered: "%0% is niet geregistreerd als koop gebied"
|
||||
buyprice-wrongPrice: "'%0%' is geen goede prijs"
|
||||
buyprice-success: "Prijs van gebied %0% is veranderd naar %1%"
|
||||
|
||||
rentduration-noPermission: "Je hebt geen toestemming om de looptijd van een huur gebied te veranderen"
|
||||
rentduration-help: "/as rentduration <gebied> <aantal> <soort>"
|
||||
rentduration-notRegistered: "%0% is niet geregistreerd als een huur gebied"
|
||||
rentduration-wrongPrice: "'%0%' is geen goede prijs, gebruik een geheel getal"
|
||||
rentduration-wrongFormat: "'%0%' is geen goed tijdformaat, bekijk de documentatie op Bukkit"
|
||||
rentduration-success: "Looptijd van gebeid %0% veranderd naar '%1%'"
|
||||
|
||||
setup-noRegion: "Je hebt geen gebied aangegeven op de tweede regel"
|
||||
setup-wrongRegion: "Het aangegeven gebied bestaat niet"
|
||||
setup-alreadyRentSign: "Het aangegeven gebied heeft al een bord voor huren"
|
||||
setup-alreadyBuySign: "Het aangegeven gebied heeft al een bord voor kopen"
|
||||
setup-noDuration: "Je hebt geen tijdsduur voor het huren aangegeven, zet dit op de derde regel"
|
||||
setup-wrongDuration: "De aangegeven tijdsduur is niet in het correcte formaat, voorbeeld: 1 dag"
|
||||
setup-noPrice: "Je hebt geen prijs aangegeven op de vierde regel"
|
||||
setup-wrongPrice: "Je hebt de prijs niet goed aangegeven, gebruik een nummer"
|
||||
setup-rentSuccess: "Huren van gebied %0% is goed opgezet"
|
||||
setup-buySuccess: "Kopen van gebied %0% is goed opgezet"
|
||||
setup-noPermissionRent: "Je hebt geen toestemming om huur gebieden op te zetten"
|
||||
setup-noPermissionBuy: "Je hebt geen toestemming om koop gebieden op te zetten"
|
||||
setup-couldNotDetect: "Meerdere gebieden gevonden met dezelfde prioriteit en/of parent/child relatie, geeft een specifieke aan op de tweede regel (2 van de gebieden die gevonden zijn: %0% en %1%)"
|
||||
|
||||
teleport-help: "/as tp <gebied> <aantal> <soort>"
|
||||
teleport-noRentOrBuy: "Gebied '%0%' is niet geregistreerd als koop of huur gebied"
|
||||
teleport-noPermission: "Je hebt geen toestemming om te teleporteren naar een gebied"
|
||||
teleport-noPermissionOther: "Je hebt geen toestemming om te teleporteren naar een gebied dat niet van jou is"
|
||||
teleport-success: "Je bent naar %0% geteleporteerd"
|
||||
teleport-noSafe: "Geen veilige plek gevonden in gebied %0%, verander het gebied of stel de teleporteer positie in"
|
||||
@@ -1,153 +0,0 @@
|
||||
name: AreaShop
|
||||
main: nl.evolutioncoding.AreaShop.AreaShop
|
||||
version: 2.0.1
|
||||
depend: [Vault, WorldGuard, WorldEdit]
|
||||
softdepend: [Multiverse-Core]
|
||||
commands:
|
||||
AreaShop:
|
||||
description: For all commands use /as help
|
||||
usage: /AreaShop or /AS
|
||||
permission: areashop.help
|
||||
permission-message: You don't have <permission>
|
||||
aliases: [as]
|
||||
permissions:
|
||||
areashop.*:
|
||||
description: Give access to all commands of AreaShop
|
||||
children:
|
||||
areashop.help: true
|
||||
areashop.createrent: true
|
||||
areashop.createbuy: true
|
||||
areashop.destroyrent: true
|
||||
areashop.destroybuy: true
|
||||
areashop.rent: true
|
||||
areashop.buy: true
|
||||
areashop.unrent: true
|
||||
areashop.info: true
|
||||
areashop.updaterents: true
|
||||
areashop.updatebuys: true
|
||||
areashop.reload: true
|
||||
areashop.setrestore: true
|
||||
areashop.setprice: true
|
||||
areashop.rentduration: true
|
||||
areashop.teleportall: true
|
||||
areashop.setteleportall: true
|
||||
areashop.teleportsign: true
|
||||
areashop.tabcomplete: true
|
||||
areashop.setteleportoutsideregion: true
|
||||
areashop.find: true
|
||||
areashop.groupadd: true
|
||||
areashop.groupdel: true
|
||||
areashop.grouplist: true
|
||||
areashop.groupinfo: true
|
||||
areashop.limits.unlimited: true
|
||||
areashop.schematicevents: true
|
||||
areashop.addsign: true
|
||||
areashop.delsign: true
|
||||
areashop.help:
|
||||
description: Allows you to see the help pages
|
||||
default: true
|
||||
areashop.rent:
|
||||
description: Allows you to rent a region
|
||||
default: true
|
||||
areashop.buy:
|
||||
description: Allows you to buy a region
|
||||
default: true
|
||||
areashop.unrent:
|
||||
description: Allows you to unrent a specific region
|
||||
default: op
|
||||
areashop.unrentown:
|
||||
description: Allows you to unrent your own region
|
||||
default: true
|
||||
areashop.sell:
|
||||
description: Allows you to sell a specific region
|
||||
default: op
|
||||
areashop.sellown:
|
||||
description: Allows you to sell your own region
|
||||
default: true
|
||||
areashop.createrent:
|
||||
description: Allows you to set up signs for renting regions
|
||||
default: op
|
||||
areashop.createbuy:
|
||||
description: Allows you to set up signs for buying regions
|
||||
default: op
|
||||
areashop.destroyrent:
|
||||
description: Allows you to break signs used for renting regions
|
||||
default: op
|
||||
areashop.destroybuy:
|
||||
description: Allows you to break signs used for renting regions
|
||||
default: op
|
||||
areashop.info:
|
||||
description: Allows you check the status of regions and players
|
||||
default: true
|
||||
areashop.updaterents:
|
||||
description: Allows you to update all rent signs and regions
|
||||
default: op
|
||||
areashop.updatebuys:
|
||||
description: Allows you to update all buy signs and regions
|
||||
default: op
|
||||
areashop.reload:
|
||||
description: Allows you to reload the config
|
||||
default: op
|
||||
areashop.setrestore:
|
||||
description: Allows you to change the restore settings
|
||||
default: op
|
||||
areashop.setprice:
|
||||
description: Allows you to change the price
|
||||
default: op
|
||||
areashop.rentduration:
|
||||
description: Allows you to change the duration of a rent
|
||||
default: op
|
||||
areashop.teleport:
|
||||
description: Teleport to your region
|
||||
default: true
|
||||
areashop.teleportall:
|
||||
description: Teleport to all regions
|
||||
default: true
|
||||
areashop.teleportsign:
|
||||
description: Teleport to signs of regions
|
||||
default: true
|
||||
areashop.setteleport:
|
||||
description: Set the teleport spot for your region
|
||||
default: true
|
||||
areashop.setteleportall:
|
||||
description: Set the teleport for other regions
|
||||
default: op
|
||||
areashop.setteleportoutsideregion:
|
||||
description: Set the teleport location outside the WorldGuard region
|
||||
default: op
|
||||
areashop.tabcomplete:
|
||||
description: Allows you to tabcomplete all commands (also where you dont have permission)
|
||||
default: op
|
||||
areashop.find:
|
||||
description: Allows you to teleport to a free region (/as find)
|
||||
default: true
|
||||
areashop.groupadd:
|
||||
description: Allows you to add regions to groups
|
||||
default: op
|
||||
areashop.groupdel:
|
||||
description: Allows you to delete regions from groups
|
||||
default: op
|
||||
areashop.grouplist:
|
||||
description: Allows you to list all the groups currently created
|
||||
default: op
|
||||
areashop.groupinfo:
|
||||
description: Allows you to display information about a group (all members)
|
||||
default: op
|
||||
areashop.rentextendbypass:
|
||||
description: Bypass the extend limit on rents
|
||||
default: op
|
||||
areashop.limits.default:
|
||||
description: Assign limits as set in the 'default' group in the 'limitGroups' section of the config
|
||||
default: not op
|
||||
areashop.limits.unlimited:
|
||||
description: Assign limits as set in the 'unlimited' group in the 'limitGroups' section of the config
|
||||
default: op
|
||||
areashop.schematicevents:
|
||||
description: Allows you to trigger schematic events for regions
|
||||
default: op
|
||||
areashop.addsign:
|
||||
description: Allows you to add signs to existing regions
|
||||
default: op
|
||||
areashop.delsign:
|
||||
description: Allows you to delete signs from existing regions
|
||||
default: op
|
||||
@@ -0,0 +1,190 @@
|
||||
package me.wiefferink.areashop;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import me.wiefferink.interactivemessenger.Log;
|
||||
import me.wiefferink.interactivemessenger.processing.Message;
|
||||
import me.wiefferink.interactivemessenger.source.LanguageManager;
|
||||
import me.wiefferink.interactivemessenger.translation.Transifex;
|
||||
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Collections;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
|
||||
public class ASLanguageManager extends LanguageManager {
|
||||
private JavaPlugin plugin;
|
||||
private String jarLanguagePath;
|
||||
private File languageFolder;
|
||||
private String wgPrefix;
|
||||
private List<String> chatPrefix;
|
||||
private Map<String, List<String>> currentLanguage, defaultLanguage;
|
||||
|
||||
public ASLanguageManager(JavaPlugin plugin,
|
||||
String jarLanguagePath,
|
||||
String currentLanguageName,
|
||||
String defaultLanguageName,
|
||||
List<String> chatPrefix,
|
||||
String wgPrefix) {
|
||||
super(plugin, jarLanguagePath, currentLanguageName, defaultLanguageName, chatPrefix);
|
||||
this.plugin = plugin;
|
||||
this.jarLanguagePath = jarLanguagePath;
|
||||
this.chatPrefix = chatPrefix;
|
||||
this.languageFolder = new File(plugin.getDataFolder() + File.separator + jarLanguagePath);
|
||||
|
||||
Message.init(this, plugin.getLogger());
|
||||
saveDefaults();
|
||||
currentLanguage = loadLanguage(currentLanguageName);
|
||||
if (defaultLanguageName.equals(currentLanguageName)) {
|
||||
defaultLanguage = currentLanguage;
|
||||
} else {
|
||||
defaultLanguage = loadLanguage(defaultLanguageName);
|
||||
}
|
||||
this.wgPrefix = wgPrefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMessage(String key) {
|
||||
List<String> message;
|
||||
if (key.equalsIgnoreCase(Message.CHATLANGUAGEVARIABLE)) {
|
||||
message = chatPrefix;
|
||||
} else if (key.equalsIgnoreCase("wgPrefix")) {
|
||||
message = new ArrayList<>();
|
||||
message.add(wgPrefix);
|
||||
} else if (currentLanguage.containsKey(key)) {
|
||||
message = currentLanguage.get(key);
|
||||
} else {
|
||||
message = defaultLanguage.get(key);
|
||||
}
|
||||
if (message == null) {
|
||||
Log.warn("Did not find message '" + key + "' in the current or default language");
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return new ArrayList<>(message);
|
||||
}
|
||||
|
||||
private void saveDefaults() {
|
||||
// Create the language folder if it not exists
|
||||
if (!languageFolder.exists()) {
|
||||
if (!languageFolder.mkdirs()) {
|
||||
Log.warn("Could not create language directory: " + languageFolder.getAbsolutePath());
|
||||
return;
|
||||
}
|
||||
}
|
||||
File jarPath;
|
||||
try {
|
||||
// Read jar as ZIP file
|
||||
jarPath = new File(plugin.getClass()
|
||||
.getProtectionDomain()
|
||||
.getCodeSource()
|
||||
.getLocation()
|
||||
.toURI());
|
||||
} catch (URISyntaxException e) {
|
||||
Log.error("Failed to find location of jar file:", ExceptionUtils.getStackTrace(e));
|
||||
return;
|
||||
}
|
||||
try (ZipFile jar = new ZipFile(jarPath)) {
|
||||
Enumeration<? extends ZipEntry> entries = jar.entries();
|
||||
|
||||
// Each entry is a file or directory
|
||||
while (entries.hasMoreElements()) {
|
||||
ZipEntry entry = entries.nextElement();
|
||||
|
||||
// Filter to YAML files in the language directory
|
||||
if (!entry.isDirectory() && entry.getName()
|
||||
.startsWith(jarLanguagePath + "/") && entry.getName()
|
||||
.endsWith(".yml")) {
|
||||
// Save the file to disk
|
||||
File targetFile = new File(languageFolder.getAbsolutePath() + File.separator + entry.getName()
|
||||
.substring(entry.getName().lastIndexOf("/")));
|
||||
try (
|
||||
InputStream input = jar.getInputStream(entry);
|
||||
OutputStream output = new FileOutputStream(targetFile)
|
||||
) {
|
||||
byte[] bytes = input.readAllBytes();
|
||||
output.write(bytes);
|
||||
} catch (IOException e) {
|
||||
Log.warn("Something went wrong saving a default language file: " + targetFile.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (
|
||||
IOException e) {
|
||||
Log.error("Failed to read zip file:", ExceptionUtils.getStackTrace(e));
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, List<String>> loadLanguage(String key) {
|
||||
return loadLanguage(key, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the specified language
|
||||
*
|
||||
* @param key The language to load
|
||||
* @param convert try conversion or not (infinite recursion prevention)
|
||||
* @return Map with the messages loaded from the file
|
||||
*/
|
||||
private Map<String, List<String>> loadLanguage(String key, boolean convert) {
|
||||
Map<String, List<String>> result = new HashMap<>();
|
||||
|
||||
// Load the language file
|
||||
boolean convertFromTransifex = false;
|
||||
File file = new File(languageFolder.getAbsolutePath() + File.separator + key + ".yml");
|
||||
try (
|
||||
InputStream inputStream = new FileInputStream(file);
|
||||
Reader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8)
|
||||
) {
|
||||
// Detect empty language files, happens when the YAML parsers prints an exception (it does return an empty YamlConfiguration though)
|
||||
YamlConfiguration ymlFile = YamlConfiguration.loadConfiguration(reader);
|
||||
if (ymlFile.getKeys(false).isEmpty()) {
|
||||
Log.warn("Language file " + key + ".yml has zero messages.");
|
||||
return result;
|
||||
}
|
||||
|
||||
// Retrieve the messages from the YAML file and create the result
|
||||
if (convert && Transifex.needsConversion(ymlFile)) {
|
||||
convertFromTransifex = true;
|
||||
} else {
|
||||
for (String messageKey : ymlFile.getKeys(false)) {
|
||||
List<String> toPut;
|
||||
if (ymlFile.isList(messageKey)) {
|
||||
toPut = ymlFile.getStringList(messageKey);
|
||||
} else {
|
||||
toPut = Collections.singletonList(ymlFile.getString(messageKey));
|
||||
}
|
||||
result.put(messageKey, new ArrayList<>(toPut));
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.warn("Could not load language file: " + file.getAbsolutePath());
|
||||
}
|
||||
|
||||
// Do conversion (after block above closed the reader)
|
||||
if (convertFromTransifex) {
|
||||
if (!Transifex.convertFrom(file)) {
|
||||
Log.warn("Failed to convert " + file.getName() + " from the Transifex layout to the AreaShop layout, check the errors above");
|
||||
}
|
||||
return loadLanguage(key, false);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,845 @@
|
||||
package me.wiefferink.areashop;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Stage;
|
||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import me.wiefferink.areashop.adapters.platform.MinecraftPlatform;
|
||||
import me.wiefferink.areashop.adapters.platform.paper.PaperPlatform;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommands;
|
||||
import me.wiefferink.areashop.extensions.AreashopExtension;
|
||||
import me.wiefferink.areashop.features.signs.SignManager;
|
||||
import me.wiefferink.areashop.interfaces.AreaShopInterface;
|
||||
import me.wiefferink.areashop.interfaces.WorldEditInterface;
|
||||
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
|
||||
import me.wiefferink.areashop.listeners.PlayerLoginLogoutListener;
|
||||
import me.wiefferink.areashop.managers.FeatureManager;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.managers.FileManager;
|
||||
import me.wiefferink.areashop.managers.Manager;
|
||||
import me.wiefferink.areashop.managers.SignErrorLogger;
|
||||
import me.wiefferink.areashop.managers.SignLinkerManager;
|
||||
import me.wiefferink.areashop.modules.AreaShopModule;
|
||||
import me.wiefferink.areashop.modules.BukkitModule;
|
||||
import me.wiefferink.areashop.modules.DependencyModule;
|
||||
import me.wiefferink.areashop.modules.PlatformModule;
|
||||
import me.wiefferink.areashop.services.ServiceManager;
|
||||
import me.wiefferink.areashop.tools.GithubUpdateCheck;
|
||||
import me.wiefferink.areashop.tools.LanguageConverter;
|
||||
import me.wiefferink.areashop.tools.SimpleMessageBridge;
|
||||
import me.wiefferink.areashop.tools.SpigotPlatform;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import me.wiefferink.areashop.tools.version.Version;
|
||||
import me.wiefferink.areashop.tools.version.VersionUtil;
|
||||
import me.wiefferink.bukkitdo.Do;
|
||||
import me.wiefferink.interactivemessenger.source.LanguageManager;
|
||||
import net.milkbowl.vault.economy.Economy;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* Main class for the AreaShop plugin.
|
||||
* Contains methods to get parts of the plugins functionality and definitions for constants.
|
||||
*/
|
||||
public final class AreaShop extends JavaPlugin implements AreaShopApi {
|
||||
// Statically available instance
|
||||
private static AreaShop instance = null;
|
||||
|
||||
// General variables
|
||||
private Injector injector;
|
||||
private WorldGuardPlugin worldGuard = null;
|
||||
private WorldGuardInterface worldGuardInterface = null;
|
||||
private WorldEditPlugin worldEdit = null;
|
||||
private WorldEditInterface worldEditInterface = null;
|
||||
private MessageBridge messageBridge;
|
||||
private IFileManager fileManager = null;
|
||||
private LanguageManager languageManager = null;
|
||||
private SignLinkerManager signLinkerManager = null;
|
||||
private FeatureManager featureManager = null;
|
||||
private SignManager signManager;
|
||||
private SignErrorLogger signErrorLogger;
|
||||
private Set<Manager> managers = null;
|
||||
private boolean debug = false;
|
||||
private List<String> chatprefix = null;
|
||||
private boolean ready = false;
|
||||
private GithubUpdateCheck githubUpdateCheck = null;
|
||||
|
||||
private final ServiceManager serviceManager = new ServiceManager();
|
||||
|
||||
// Folders and file names
|
||||
public static final String languageFolder = "lang";
|
||||
public static final String schematicFolder = "schem";
|
||||
public static final String regionsFolder = "regions";
|
||||
public static final String groupsFile = "groups.yml";
|
||||
public static final String defaultFile = "default.yml";
|
||||
public static final String configFile = "config.yml";
|
||||
public static final String configFileHidden = "hiddenConfig.yml";
|
||||
public static final String signLogFile = "sign-errors.log";
|
||||
public static final String versionFile = "versions";
|
||||
|
||||
// Euro tag for in the config
|
||||
public static final String currencyEuro = "%euro%";
|
||||
|
||||
// Constants for handling file versions
|
||||
public static final String versionFiles = "files";
|
||||
public static final int versionFilesCurrent = 3;
|
||||
|
||||
// Keys for replacing parts of flags, commands, strings
|
||||
public static final String tagPlayerName = "player";
|
||||
public static final String tagPlayerUUID = "uuid";
|
||||
public static final String tagWorldName = "world";
|
||||
public static final String tagRegionName = "region";
|
||||
public static final String tagRegionType = "type";
|
||||
public static final String tagPrice = "price";
|
||||
public static final String tagRawPrice = "rawprice";
|
||||
public static final String tagDuration = "duration";
|
||||
public static final String tagRentedUntil = "until";
|
||||
public static final String tagRentedUntilShort = "untilshort";
|
||||
public static final String tagWidth = "width"; // x-axis
|
||||
public static final String tagHeight = "height"; // y-axis
|
||||
public static final String tagDepth = "depth"; // z-axis
|
||||
public static final String tagVolume = "volume"; // Number of blocks in the region (accounting for polygon regions)
|
||||
public static final String tagTimeLeft = "timeleft";
|
||||
public static final String tagClicker = "clicker";
|
||||
public static final String tagResellPrice = "resellprice";
|
||||
public static final String tagRawResellPrice = "rawresellprice";
|
||||
public static final String tagFriends = "friends";
|
||||
public static final String tagFriendsUUID = "friendsuuid";
|
||||
public static final String tagMoneyBackPercentage = "moneybackpercent";
|
||||
public static final String tagMoneyBackAmount = "moneyback";
|
||||
public static final String tagRawMoneyBackAmount = "rawmoneyback";
|
||||
public static final String tagTimesExtended = "timesExtended";
|
||||
public static final String tagMaxExtends = "maxextends";
|
||||
public static final String tagExtendsLeft = "extendsleft";
|
||||
public static final String tagMaxRentTime = "maxrenttime";
|
||||
public static final String tagMaxInactiveTime = "inactivetime";
|
||||
public static final String tagLandlord = "landlord";
|
||||
public static final String tagLandlordUUID = "landlorduuid";
|
||||
public static final String tagDateTime = "datetime";
|
||||
public static final String tagDateTimeShort = "datetimeshort";
|
||||
public static final String tagYear = "year";
|
||||
public static final String tagMonth = "month";
|
||||
public static final String tagDay = "day";
|
||||
public static final String tagHour = "hour";
|
||||
public static final String tagMinute = "minute";
|
||||
public static final String tagSecond = "second";
|
||||
public static final String tagMillisecond = "millisecond";
|
||||
public static final String tagEpoch = "epoch";
|
||||
public static final String tagTeleportX = "tpx";
|
||||
public static final String tagTeleportY = "tpy";
|
||||
public static final String tagTeleportZ = "tpz";
|
||||
public static final String tagTeleportBlockX = "tpblockx";
|
||||
public static final String tagTeleportBlockY = "tpblocky";
|
||||
public static final String tagTeleportBlockZ = "tpblockz";
|
||||
public static final String tagTeleportPitch = "tppitch";
|
||||
public static final String tagTeleportYaw = "tpyaw";
|
||||
public static final String tagTeleportPitchRound = "tppitchround";
|
||||
public static final String tagTeleportYawRound = "tpyawround";
|
||||
public static final String tagTeleportWorld = "tpworld";
|
||||
|
||||
public static AreaShop getInstance() {
|
||||
return AreaShop.instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on start or reload of the server.
|
||||
*/
|
||||
@Override
|
||||
public void onEnable() {
|
||||
AreaShop.instance = this;
|
||||
Do.init(this);
|
||||
managers = new HashSet<>();
|
||||
messageBridge = new SimpleMessageBridge(this.serviceManager);
|
||||
signErrorLogger = new SignErrorLogger(new File(getDataFolder(), signLogFile));
|
||||
|
||||
// Setup NMS Impl
|
||||
Version currentServerVersion = VersionUtil.parseMinecraftVersion(Bukkit.getBukkitVersion());
|
||||
if (currentServerVersion.versionData().isOlderThan(VersionUtil.MC_1_20_6)) {
|
||||
error("Unsupported minecraft version: " + currentServerVersion + "! Minimum is 1.20.6");
|
||||
shutdownOnError();
|
||||
return;
|
||||
}
|
||||
|
||||
final MinecraftPlatform platform;
|
||||
if (PaperLib.isPaper()) {
|
||||
platform = new PaperPlatform(this);
|
||||
info("Detected Paper; using the PaperPlatform impl");
|
||||
} else {
|
||||
platform = new SpigotPlatform(this);
|
||||
info("Detected Spigot; using the SpigotPlatform impl");
|
||||
}
|
||||
final PlatformModule platformModule = new PlatformModule(platform);
|
||||
|
||||
// Check if Vault is present
|
||||
if(getServer().getPluginManager().getPlugin("Vault") == null) {
|
||||
error("Vault plugin is not present or has not loaded correctly");
|
||||
shutdownOnError();
|
||||
return;
|
||||
}
|
||||
|
||||
// Find WorldEdit integration version to load
|
||||
String weHandlerVersion;
|
||||
Plugin plugin = getServer().getPluginManager().getPlugin("WorldEdit");
|
||||
if(!(plugin instanceof WorldEditPlugin) || !plugin.isEnabled()) {
|
||||
error("WorldEdit plugin is not present or has not loaded correctly");
|
||||
return;
|
||||
} else {
|
||||
this.worldEdit = (WorldEditPlugin) plugin;
|
||||
Plugin fawePlugin = getServer().getPluginManager().getPlugin("FastAsyncWorldEdit");
|
||||
if (fawePlugin != null && fawePlugin.isEnabled()) {
|
||||
weHandlerVersion = "FastAsyncWorldEditHandler";
|
||||
info("Detected FastAsyncWorldEdit, using the fawe handler");
|
||||
} else {
|
||||
weHandlerVersion = "WorldEditHandler";
|
||||
}
|
||||
}
|
||||
|
||||
plugin = getServer().getPluginManager().getPlugin("WorldGuard");
|
||||
if(!(plugin instanceof WorldGuardPlugin) || !plugin.isEnabled()) {
|
||||
error("WorldGuard plugin is not present or has not loaded correctly");
|
||||
shutdownOnError();
|
||||
return;
|
||||
} else {
|
||||
this.worldGuard = (WorldGuardPlugin) plugin;
|
||||
}
|
||||
|
||||
DependencyModule dependencyModule = new DependencyModule(this.worldEdit, this.worldGuard, getEconomy(), getPermissionProvider());
|
||||
|
||||
// Load WorldEdit
|
||||
try {
|
||||
Class<?> clazz = Class.forName("me.wiefferink.areashop.adapters.plugins." + weHandlerVersion);
|
||||
if(WorldEditInterface.class.isAssignableFrom(clazz)) { // Make sure it actually implements WorldEditInterface
|
||||
worldEditInterface = (WorldEditInterface)clazz.getConstructor(AreaShopInterface.class).newInstance(this); // Set our handler
|
||||
}
|
||||
} catch(Exception e) {
|
||||
error("Could not load the handler for WorldEdit (tried to load " + weHandlerVersion + "), report this problem to the author: " + ExceptionUtils.getStackTrace(e));
|
||||
shutdownOnError();
|
||||
return;
|
||||
}
|
||||
|
||||
// Load WorldGuard
|
||||
try {
|
||||
Class<?> clazz = Class.forName("me.wiefferink.areashop.adapters.plugins.WorldGuardHandler");
|
||||
// Check if we have a NMSHandler class at that location.
|
||||
if(WorldGuardInterface.class.isAssignableFrom(clazz)) { // Make sure it actually implements WorldGuardInterface
|
||||
worldGuardInterface = (WorldGuardInterface)clazz.getConstructor(AreaShopInterface.class).newInstance(this); // Set our handler
|
||||
}
|
||||
} catch(Exception e) {
|
||||
error("Could not load the handler for WorldGuard, report this problem to the author:" + ExceptionUtils.getStackTrace(e));
|
||||
shutdownOnError();
|
||||
return;
|
||||
}
|
||||
|
||||
AreaShopModule asModule = new AreaShopModule(this,
|
||||
this.messageBridge,
|
||||
this.worldEditInterface,
|
||||
this.worldGuardInterface,
|
||||
this.signErrorLogger,
|
||||
this.serviceManager,
|
||||
platformModule,
|
||||
dependencyModule
|
||||
);
|
||||
injector = Guice.createInjector(Stage.PRODUCTION, new BukkitModule(getServer()), asModule);
|
||||
|
||||
// Load all data from files and check versions
|
||||
fileManager = injector.getInstance(IFileManager.class);
|
||||
managers.add((FileManager) fileManager);
|
||||
boolean loadFilesResult = fileManager.loadFiles(false);
|
||||
if (!loadFilesResult) {
|
||||
shutdownOnError();
|
||||
return;
|
||||
}
|
||||
|
||||
performLanguageMigrations();
|
||||
setupLanguageManager();
|
||||
|
||||
featureManager = injector.getInstance(FeatureManager.class);
|
||||
featureManager.initializeFeatures(injector);
|
||||
managers.add(featureManager);
|
||||
signManager = injector.getInstance(SignManager.class);
|
||||
managers.add(signManager);
|
||||
|
||||
loadExtensions();
|
||||
|
||||
// Register the event listeners
|
||||
getServer().getPluginManager().registerEvents(new PlayerLoginLogoutListener(this, messageBridge), this);
|
||||
|
||||
setupTasks();
|
||||
|
||||
// Register commands
|
||||
AreashopCommands commands = injector.getInstance(AreashopCommands.class);
|
||||
commands.registerCommands();
|
||||
|
||||
// Create a signLinkerManager
|
||||
signLinkerManager = injector.getInstance(SignLinkerManager.class);
|
||||
managers.add(signLinkerManager);
|
||||
|
||||
// Register dynamic permission (things declared in config)
|
||||
registerDynamicPermissions();
|
||||
|
||||
// Don't initialize the updatechecker if disabled in the config
|
||||
if(getConfig().getBoolean("checkForUpdates")) {
|
||||
githubUpdateCheck = new GithubUpdateCheck(
|
||||
this,
|
||||
"md5sha256",
|
||||
"AreaShop"
|
||||
).withVersionComparator((latestVersion, currentVersion) -> {
|
||||
Version latest = Version.parse(cleanVersion(latestVersion));
|
||||
Version current = Version.parse(cleanVersion(currentVersion));
|
||||
return latest.versionData().isNewerThan(current.versionData());
|
||||
}
|
||||
).checkUpdate(result -> {
|
||||
AreaShop.debug("Update check result:", result);
|
||||
if(!result.hasUpdate()) {
|
||||
return;
|
||||
}
|
||||
|
||||
AreaShop.info("Update from AreaShop V" + cleanVersion(result.getCurrentVersion()) + " to AreaShop V" + cleanVersion(result.getLatestVersion()) + " available, get the latest version at https://github.com/md5sha256/AreaShop/releases");
|
||||
for(Player player : Utils.getOnlinePlayers()) {
|
||||
notifyUpdate(player);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify a player about an update if he wants notifications about it and an update is available.
|
||||
* @param sender CommandSender to notify
|
||||
*/
|
||||
public void notifyUpdate(CommandSender sender) {
|
||||
if(githubUpdateCheck != null && githubUpdateCheck.hasUpdate() && sender.hasPermission("areashop.notifyupdate")) {
|
||||
messageBridge.message(sender, "update-playerNotify", cleanVersion(githubUpdateCheck.getCurrentVersion()), cleanVersion(githubUpdateCheck.getLatestVersion()));
|
||||
}
|
||||
}
|
||||
|
||||
private void shutdownOnError() {
|
||||
error("The plugin has not started, fix the errors listed above");
|
||||
getServer().getPluginManager().disablePlugin(this);
|
||||
}
|
||||
|
||||
private void loadExtensions() {
|
||||
if (this.getServer().getPluginManager().isPluginEnabled("Essentials")) {
|
||||
loadEssentialsExt().ifPresent(ext -> ext.init(this, this.injector));
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<AreashopExtension> loadEssentialsExt() {
|
||||
try {
|
||||
Class<?> clazz = Class.forName("me.wiefferink.areashop.adapters.plugins.essentials.EssentialsExtension");
|
||||
Class<? extends AreashopExtension> extClass = clazz.asSubclass(AreashopExtension.class);
|
||||
AreashopExtension extension = extClass.getConstructor().newInstance();
|
||||
return Optional.of(extension);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
error("Failed to initialize the essentials extension!");
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup a version number.
|
||||
* @param version Version to clean
|
||||
* @return Cleaned up version (removed prefixes and suffixes)
|
||||
*/
|
||||
private String cleanVersion(String version) {
|
||||
version = version.toLowerCase();
|
||||
|
||||
// Strip 'v' as used on Github tags
|
||||
if(version.startsWith("v")) {
|
||||
version = version.substring(1);
|
||||
}
|
||||
|
||||
// Strip build number as used by Jenkins
|
||||
if(version.contains("#")) {
|
||||
version = version.substring(0, version.indexOf("#"));
|
||||
}
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on shutdown or reload of the server.
|
||||
*/
|
||||
@Override
|
||||
public void onDisable() {
|
||||
|
||||
Bukkit.getServer().getScheduler().cancelTasks(this);
|
||||
|
||||
// Cleanup managers
|
||||
for(Manager manager : managers) {
|
||||
manager.shutdown();
|
||||
}
|
||||
signErrorLogger.saveIfDirty();
|
||||
HandlerList.unregisterAll(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if the plugin will be using MiniMessage or not
|
||||
* @return true if MiniMessage should be used, false otherwise
|
||||
*/
|
||||
public static boolean useMiniMessage() {
|
||||
return getInstance().getConfig().getBoolean("useMiniMessage");
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if the plugin is ready to be used.
|
||||
* @return true if the plugin is ready, false otherwise
|
||||
*/
|
||||
public boolean isReady() {
|
||||
return ready;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if the plugin is ready to be used or not (not to be used from another plugin!).
|
||||
* @param ready Indicate if the plugin is ready to be used
|
||||
*/
|
||||
public void setReady(boolean ready) {
|
||||
this.ready = ready;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if the plugin should output debug messages (loaded from config normally).
|
||||
* @param debug Indicates if the plugin should output debug messages or not
|
||||
*/
|
||||
public void setDebug(boolean debug) {
|
||||
this.debug = debug;
|
||||
}
|
||||
|
||||
private void performLanguageMigrations() {
|
||||
boolean migrateExisting = this.getConfig().getBoolean("migrateLanguages", false);
|
||||
if (!migrateExisting) {
|
||||
return;
|
||||
}
|
||||
getLogger().info("Performing language migration");
|
||||
List<String> chatPrefix = getConfig().getStringList("chatPrefix");
|
||||
List<String> convertedChatPrefix = LanguageConverter.convertRawList(chatPrefix);
|
||||
if (convertedChatPrefix.size() == 1) {
|
||||
getConfig().set("mmChatPrefix", convertedChatPrefix.getFirst());
|
||||
} else {
|
||||
getConfig().set("mmChatPrefix", convertedChatPrefix);
|
||||
}
|
||||
saveConfig();
|
||||
File existingLanguages = getDataFolder().toPath().resolve(languageFolder).toFile();
|
||||
File[] langFiles = existingLanguages.listFiles(file -> file.getName().endsWith(".yml"));
|
||||
if (langFiles == null) {
|
||||
return;
|
||||
}
|
||||
for (File file : langFiles) {
|
||||
String name = file.getName();
|
||||
String langName = name.substring(0, name.length() - 4);
|
||||
if (langName.endsWith("-MM")) {
|
||||
debug("Skipping migration for " + langName + " as it already exists.");
|
||||
continue;
|
||||
}
|
||||
File toMigrate = new File(existingLanguages, langName + "-MM.yml");
|
||||
try {
|
||||
LanguageConverter.performConversion(file, toMigrate);
|
||||
} catch (IOException ex) {
|
||||
getLogger().log(Level.SEVERE, "Failed to perform migration for lang: " + file.getName(), ex);
|
||||
}
|
||||
}
|
||||
getLogger().info("Language migration complete!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup a new LanguageManager.
|
||||
*/
|
||||
private void setupLanguageManager() {
|
||||
languageManager = new ASLanguageManager(
|
||||
this,
|
||||
languageFolder,
|
||||
useMiniMessage() ? getConfig().getString("mmLanguage") : getConfig().getString("language"),
|
||||
"EN",
|
||||
useMiniMessage() ? getConfig().getStringList("mmChatPrefix") : chatprefix,
|
||||
getConfig().getString("wgPrefix")
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the chatprefix to use in the chat (loaded from config normally).
|
||||
* @param chatprefix The string to use in front of chat messages (supports formatting codes)
|
||||
*/
|
||||
public void setChatprefix(List<String> chatprefix) {
|
||||
this.chatprefix = chatprefix;
|
||||
}
|
||||
|
||||
public SignErrorLogger getSignErrorLogger() {
|
||||
return signErrorLogger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to get the WorldGuard plugin.
|
||||
* @return WorldGuardPlugin
|
||||
*/
|
||||
@Override
|
||||
public WorldGuardPlugin getWorldGuard() {
|
||||
return worldGuard;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to get WorldGuardInterface for version dependent things.
|
||||
* @return WorldGuardInterface
|
||||
*/
|
||||
public WorldGuardInterface getWorldGuardHandler() {
|
||||
return this.worldGuardInterface;
|
||||
}
|
||||
|
||||
|
||||
@Nonnull
|
||||
public SignManager getSignManager() {
|
||||
return signManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the RegionManager.
|
||||
* @param world World to get the RegionManager for
|
||||
* @return RegionManager for the given world, if there is one, otherwise null
|
||||
*/
|
||||
public RegionManager getRegionManager(World world) {
|
||||
return this.worldGuardInterface.getRegionManager(world);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to get the WorldEdit plugin.
|
||||
* @return WorldEditPlugin
|
||||
*/
|
||||
@Override
|
||||
public WorldEditPlugin getWorldEdit() {
|
||||
return worldEdit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin pluginInstance() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to get WorldGuardInterface for version dependent things.
|
||||
* @return WorldGuardInterface
|
||||
*/
|
||||
public WorldEditInterface getWorldEditHandler() {
|
||||
return this.worldEditInterface;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to get the LanguageManager.
|
||||
* @return the LanguageManager
|
||||
*/
|
||||
public LanguageManager getLanguageManager() {
|
||||
return languageManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SignLinkerManager.
|
||||
* Handles sign linking mode.
|
||||
* @return The SignLinkerManager
|
||||
*/
|
||||
@Nonnull
|
||||
@Override
|
||||
public SignLinkerManager getSignlinkerManager() {
|
||||
return signLinkerManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the FeatureManager.
|
||||
* Manages region specific features.
|
||||
* @return The FeatureManager
|
||||
*/
|
||||
@Nonnull
|
||||
@Override
|
||||
public FeatureManager getFeatureManager() {
|
||||
return featureManager;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ServiceManager getServiceManager() {
|
||||
return this.serviceManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to get the Vault plugin.
|
||||
* @return Economy
|
||||
*/
|
||||
private Economy getEconomy() {
|
||||
RegisteredServiceProvider<Economy> economy = getServer().getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class);
|
||||
if(economy == null) {
|
||||
error("There is no economy provider to support Vault, make sure you installed an economy plugin");
|
||||
return null;
|
||||
}
|
||||
return economy.getProvider();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Vault permissions provider.
|
||||
* @return Vault permissions provider
|
||||
*/
|
||||
private net.milkbowl.vault.permission.Permission getPermissionProvider() {
|
||||
RegisteredServiceProvider<net.milkbowl.vault.permission.Permission> permissionProvider = getServer().getServicesManager().getRegistration(net.milkbowl.vault.permission.Permission.class);
|
||||
if (permissionProvider == null) {
|
||||
return null;
|
||||
}
|
||||
return permissionProvider.getProvider();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for a permission of a (possibly offline) player.
|
||||
* @param offlinePlayer OfflinePlayer to check
|
||||
* @param permission Permission to check
|
||||
* @return true if the player has the permission, false if the player does not have permission or, is offline and there is not Vault-compatible permission plugin
|
||||
*/
|
||||
public boolean hasPermission(OfflinePlayer offlinePlayer, String permission) {
|
||||
// Online, return through Bukkit
|
||||
if(offlinePlayer.getPlayer() != null) {
|
||||
return offlinePlayer.getPlayer().hasPermission(permission);
|
||||
}
|
||||
|
||||
// Resolve while offline if possible
|
||||
net.milkbowl.vault.permission.Permission permissionProvider = getPermissionProvider();
|
||||
if(permissionProvider != null) {
|
||||
// TODO: Should we provide a world here?
|
||||
return permissionProvider.playerHas(null, offlinePlayer, permission);
|
||||
}
|
||||
|
||||
// Player offline and no offline permission provider available, safely say that there is no permission
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to get the FileManager (loads/save regions and can be used to get regions).
|
||||
* @return The fileManager
|
||||
*/
|
||||
public IFileManager getFileManager() {
|
||||
return fileManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register dynamic permissions controlled by config settings.
|
||||
*/
|
||||
private void registerDynamicPermissions() {
|
||||
// Register limit groups of amount of regions a player can have
|
||||
ConfigurationSection section = getConfig().getConfigurationSection("limitGroups");
|
||||
if(section == null) {
|
||||
return;
|
||||
}
|
||||
for(String group : section.getKeys(false)) {
|
||||
if(!"default".equals(group)) {
|
||||
Permission perm = new Permission("areashop.limits." + group);
|
||||
try {
|
||||
Bukkit.getPluginManager().addPermission(perm);
|
||||
} catch(IllegalArgumentException e) {
|
||||
warn("Could not add the following permission to be used as limit: " + perm.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
Bukkit.getPluginManager().recalculatePermissionDefaults(Bukkit.getPluginManager().getPermission("playerwarps.limits"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register all required tasks.
|
||||
*/
|
||||
private void setupTasks() {
|
||||
|
||||
long signLogTicks = Utils.millisToTicks(TimeUnit.MINUTES.toMillis(5));
|
||||
Bukkit.getScheduler().runTaskTimerAsynchronously(this,
|
||||
() -> signErrorLogger.saveIfDirty(),
|
||||
signLogTicks,
|
||||
signLogTicks);
|
||||
|
||||
// Rent expiration timer
|
||||
long expirationCheck = Utils.millisToTicks(Utils.getDurationFromSecondsOrString("expiration.delay"));
|
||||
final AreaShop finalPlugin = this;
|
||||
if(expirationCheck > 0) {
|
||||
Do.syncTimer(expirationCheck, () -> {
|
||||
if(isReady()) {
|
||||
finalPlugin.getFileManager().checkRents();
|
||||
AreaShop.debugTask("Checking rent expirations...");
|
||||
} else {
|
||||
AreaShop.debugTask("Skipped checking rent expirations, plugin not ready");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Inactive unrenting/selling timer
|
||||
long inactiveCheck = Utils.millisToTicks(Utils.getDurationFromMinutesOrString("inactive.delay"));
|
||||
if(inactiveCheck > 0) {
|
||||
Do.syncTimer(inactiveCheck, () -> {
|
||||
if(isReady()) {
|
||||
finalPlugin.getFileManager().checkForInactiveRegions();
|
||||
AreaShop.debugTask("Checking for regions with players that are inactive too long...");
|
||||
} else {
|
||||
AreaShop.debugTask("Skipped checking for regions of inactive players, plugin not ready");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Periodic updating of signs for timeleft tags
|
||||
long periodicUpdate = Utils.millisToTicks(Utils.getDurationFromSecondsOrString("signs.delay"));
|
||||
if(periodicUpdate > 0) {
|
||||
Do.syncTimer(periodicUpdate, () -> {
|
||||
if(isReady()) {
|
||||
finalPlugin.getFileManager().performPeriodicSignUpdate();
|
||||
AreaShop.debugTask("Performing periodic sign update...");
|
||||
} else {
|
||||
AreaShop.debugTask("Skipped performing periodic sign update, plugin not ready");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Saving regions and group settings
|
||||
long saveFiles = Utils.millisToTicks(Utils.getDurationFromMinutesOrString("saving.delay"));
|
||||
if(saveFiles > 0) {
|
||||
Do.syncTimer(saveFiles, () -> {
|
||||
if(isReady()) {
|
||||
finalPlugin.getFileManager().saveRequiredFiles();
|
||||
AreaShop.debugTask("Saving required files...");
|
||||
} else {
|
||||
AreaShop.debugTask("Skipped saving required files, plugin not ready");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Sending warnings about rent regions to online players
|
||||
long expireWarning = Utils.millisToTicks(Utils.getDurationFromMinutesOrString("expireWarning.delay"));
|
||||
if(expireWarning > 0) {
|
||||
Do.syncTimer(expireWarning, () -> {
|
||||
if(isReady()) {
|
||||
finalPlugin.getFileManager().sendRentExpireWarnings();
|
||||
AreaShop.debugTask("Sending rent expire warnings...");
|
||||
} else {
|
||||
AreaShop.debugTask("Skipped sending rent expire warnings, plugin not ready");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Update all regions on startup
|
||||
if(getConfig().getBoolean("updateRegionsOnStartup")) {
|
||||
Do.syncLater(20, () -> {
|
||||
finalPlugin.getFileManager().updateAllRegions();
|
||||
AreaShop.debugTask("Updating all regions at startup...");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the config.
|
||||
*/
|
||||
@Override
|
||||
public YamlConfiguration getConfig() {
|
||||
return fileManager.getConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an debug message to the console.
|
||||
* @param message The message that should be printed to the console
|
||||
*/
|
||||
public static void debug(Object... message) {
|
||||
if(AreaShop.getInstance().debug) {
|
||||
info("Debug: " + StringUtils.join(message, " "));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Non-static debug to use as implementation of the interface.
|
||||
* @param message Object parts of the message that should be logged, toString() will be used
|
||||
*/
|
||||
@Override
|
||||
public void debugI(Object... message) {
|
||||
AreaShop.debug(StringUtils.join(message, " "));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debugI(Supplier<String> message) {
|
||||
if (debug) {
|
||||
info("Debug: " + message.get());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print an information message to the console.
|
||||
* @param message The message to print
|
||||
*/
|
||||
public static void info(Object... message) {
|
||||
AreaShop.getInstance().getLogger().info(() -> StringUtils.join(message, " "));
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a warning to the console.
|
||||
* @param message The message to print
|
||||
*/
|
||||
public static void warn(Object... message) {
|
||||
AreaShop.getInstance().getLogger().warning(() -> StringUtils.join(message, " "));
|
||||
}
|
||||
|
||||
/**
|
||||
* Print an error to the console.
|
||||
* @param message The message to print
|
||||
*/
|
||||
public static void error(Object... message) {
|
||||
AreaShop.getInstance().getLogger().severe(() -> StringUtils.join(message, " "));
|
||||
}
|
||||
|
||||
/**
|
||||
* Print debug message for periodic task.
|
||||
* @param message The message to print
|
||||
*/
|
||||
public static void debugTask(Object... message) {
|
||||
if(AreaShop.getInstance().getConfig().getBoolean("debugTask")) {
|
||||
AreaShop.debug(StringUtils.join(message, " "));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload all files of the plugin and update all regions.
|
||||
* @param confirmationReceiver The CommandSender which should be notified when complete, null for nobody
|
||||
*/
|
||||
public void reload(final CommandSender confirmationReceiver) {
|
||||
setReady(false);
|
||||
fileManager.saveRequiredFilesAtOnce();
|
||||
fileManager.loadFiles(true);
|
||||
setupLanguageManager();
|
||||
messageBridge.message(confirmationReceiver, "reload-reloading");
|
||||
fileManager.checkRents();
|
||||
fileManager.updateAllRegions(confirmationReceiver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload all files of the plugin and update all regions.
|
||||
*/
|
||||
public void reload() {
|
||||
reload(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package me.wiefferink.areashop;
|
||||
|
||||
import me.wiefferink.areashop.features.signs.SignManager;
|
||||
import me.wiefferink.areashop.interfaces.AreaShopInterface;
|
||||
import me.wiefferink.areashop.managers.FeatureManager;
|
||||
import me.wiefferink.areashop.managers.SignLinkerManager;
|
||||
import me.wiefferink.areashop.services.ServiceManager;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public interface AreaShopApi extends AreaShopInterface {
|
||||
|
||||
/**
|
||||
* Get the SignLinkerManager.
|
||||
* Handles sign linking mode.
|
||||
*
|
||||
* @return The SignLinkerManager
|
||||
*/
|
||||
@Nonnull SignLinkerManager getSignlinkerManager();
|
||||
|
||||
/**
|
||||
* Get the FeatureManager.
|
||||
* Manages region specific features.
|
||||
*
|
||||
* @return The FeatureManager
|
||||
*/
|
||||
@Nonnull FeatureManager getFeatureManager();
|
||||
|
||||
|
||||
@Nonnull SignManager getSignManager();
|
||||
|
||||
@Nonnull
|
||||
ServiceManager getServiceManager();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package me.wiefferink.areashop;
|
||||
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public interface MessageBridge {
|
||||
/**
|
||||
* Send a message to a target without a prefix.
|
||||
*
|
||||
* @param target The target to send the message to
|
||||
* @param key The key of the language string
|
||||
* @param replacements The replacements to insert in the message
|
||||
*/
|
||||
void messageNoPrefix(Object target, String key, Object... replacements);
|
||||
|
||||
/**
|
||||
* Send a message to a target, prefixed by the default chat prefix.
|
||||
*
|
||||
* @param target The target to send the message to
|
||||
* @param key The key of the language string
|
||||
* @param replacements The replacements to insert in the message
|
||||
*/
|
||||
void message(Object target, String key, Object... replacements);
|
||||
|
||||
void messagePersistent(@Nonnull OfflinePlayer target,
|
||||
@Nonnull String key,
|
||||
@Nonnull Object... replacements);
|
||||
}
|
||||
@@ -0,0 +1,453 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.WorldFlagUtil;
|
||||
import me.wiefferink.areashop.commands.util.WorldGuardRegionParser;
|
||||
import me.wiefferink.areashop.commands.util.WorldSelection;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
|
||||
import me.wiefferink.areashop.events.ask.AddingRegionEvent;
|
||||
import me.wiefferink.areashop.events.ask.BuyingRegionEvent;
|
||||
import me.wiefferink.areashop.events.ask.RentingRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.BoughtRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.RentedRegionEvent;
|
||||
import me.wiefferink.areashop.interfaces.WorldEditInterface;
|
||||
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RegionFactory;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import me.wiefferink.bukkitdo.Do;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.incendo.cloud.parser.standard.EnumParser;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Singleton
|
||||
public class AddCommand extends AreashopCommandBean {
|
||||
|
||||
private static final CloudKey<GeneralRegion.RegionType> KEY_REGION_TYPE = CloudKey.of("regionType",
|
||||
GeneralRegion.RegionType.class);
|
||||
private static final CloudKey<ProtectedRegion> KEY_REGION = CloudKey.of("region", ProtectedRegion.class);
|
||||
private final MessageBridge messageBridge;
|
||||
private final AreaShop plugin;
|
||||
private final WorldEditInterface worldEditInterface;
|
||||
private final WorldGuardInterface worldGuardInterface;
|
||||
private final RegionFactory regionFactory;
|
||||
|
||||
@Inject
|
||||
public AddCommand(
|
||||
@Nonnull MessageBridge messageBridge,
|
||||
@Nonnull AreaShop plugin,
|
||||
@Nonnull WorldEditInterface worldEditInterface,
|
||||
@Nonnull WorldGuardInterface worldGuardInterface,
|
||||
@Nonnull RegionFactory regionFactory) {
|
||||
this.messageBridge = messageBridge;
|
||||
this.plugin = plugin;
|
||||
this.worldEditInterface = worldEditInterface;
|
||||
this.worldGuardInterface = worldGuardInterface;
|
||||
this.regionFactory = regionFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(@NotNull CommandSender target) {
|
||||
if(target.hasPermission("areashop.createrent")
|
||||
|| target.hasPermission("areashop.createrent.member")
|
||||
|| target.hasPermission("areashop.createrent.owner")
|
||||
|
||||
|| target.hasPermission("areashop.createbuy")
|
||||
|| target.hasPermission("areashop.createbuy.member")
|
||||
|| target.hasPermission("areashop.createbuy.owner")) {
|
||||
return "help-add";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
|
||||
// /as add <rent|buy> [region] [world]
|
||||
var wgRegionParser = WorldGuardRegionParser.worldGuardRegionParser(WorldFlagUtil.DEFAULT_WORLD_FLAG, this.worldGuardInterface);
|
||||
return builder
|
||||
.literal("add")
|
||||
.senderType(PlayerCommandSource.class)
|
||||
.required(KEY_REGION_TYPE, EnumParser.enumParser(GeneralRegion.RegionType.class))
|
||||
.optional(KEY_REGION, wgRegionParser)
|
||||
.flag(WorldFlagUtil.DEFAULT_WORLD_FLAG)
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
private void handleCommand(CommandContext<PlayerCommandSource> context) {
|
||||
Player player = context.sender().sender();
|
||||
final GeneralRegion.RegionType regionType = context.get(KEY_REGION_TYPE);
|
||||
World world = WorldFlagUtil.parseOrDetectWorld(context, player);
|
||||
Map<String, ProtectedRegion> regions;
|
||||
Optional<ProtectedRegion> inputRegion = context.optional(KEY_REGION);
|
||||
if (inputRegion.isPresent()) {
|
||||
regions = new HashMap<>();
|
||||
regions.put(inputRegion.get().getId(), inputRegion.get());
|
||||
} else {
|
||||
WorldSelection selection = WorldSelection.fromPlayer(player, this.worldEditInterface);
|
||||
regions = Utils.getWorldEditRegionsInSelection(selection.selection()).stream()
|
||||
.collect(Collectors.toMap(ProtectedRegion::getId, region -> region));
|
||||
}
|
||||
if (regions.isEmpty()) {
|
||||
throw new AreaShopCommandException("cmd-noWERegionsFound");
|
||||
}
|
||||
AreaShop.debug("Starting add task with " + regions.size() + " regions");
|
||||
AddTaskState state = createState(player, regionType, world);
|
||||
int batchSize = plugin.getConfig().getInt("adding.regionsPerTick");
|
||||
Do.forAll(
|
||||
batchSize,
|
||||
regions.entrySet(),
|
||||
regionEntry -> processEntry(regionEntry, state),
|
||||
() -> onCompletion(state)
|
||||
);
|
||||
}
|
||||
|
||||
private AddTaskState createState(
|
||||
@Nonnull Player player,
|
||||
@Nonnull GeneralRegion.RegionType regionType,
|
||||
@Nonnull World world
|
||||
) {
|
||||
Set<GeneralRegion> regionsSuccess = new TreeSet<>();
|
||||
Set<GeneralRegion> regionsAlready = new TreeSet<>();
|
||||
Set<GeneralRegion> regionsAlreadyOtherWorld = new TreeSet<>();
|
||||
Set<GeneralRegion> regionsRentCancelled = new TreeSet<>(); // Denied by an event listener
|
||||
Set<GeneralRegion> regionsBuyCancelled = new TreeSet<>(); // Denied by an event listener
|
||||
Set<String> namesBlacklisted = new TreeSet<>();
|
||||
Set<String> namesNoPermission = new TreeSet<>();
|
||||
Set<String> namesAddCancelled = new TreeSet<>(); // Denied by an event listener
|
||||
return new AddTaskState(
|
||||
player,
|
||||
regionType,
|
||||
regionsSuccess,
|
||||
regionsAlready,
|
||||
regionsAlreadyOtherWorld,
|
||||
regionsRentCancelled,
|
||||
regionsBuyCancelled,
|
||||
namesBlacklisted,
|
||||
namesNoPermission,
|
||||
namesAddCancelled,
|
||||
world
|
||||
);
|
||||
}
|
||||
|
||||
private void processEntry(@Nonnull Map.Entry<String, ProtectedRegion> regionEntry,
|
||||
@Nonnull AddTaskState taskState) {
|
||||
Player player = taskState.sender();
|
||||
Set<GeneralRegion> regionsAlready = taskState.regionsAlready();
|
||||
Set<GeneralRegion> regionsAlreadyOtherWorld = taskState.regionsAlreadyOtherWorld();
|
||||
Set<String> namesBlacklisted = taskState.namesBlacklisted();
|
||||
Set<String> namesNoPermission = taskState.namesNoPermission();
|
||||
GeneralRegion.RegionType regionType = taskState.regionType();
|
||||
World world = taskState.world();
|
||||
String regionName = regionEntry.getKey();
|
||||
ProtectedRegion region = regionEntry.getValue();
|
||||
// Determine if the player is an owner or member of the region
|
||||
boolean isMember = this.worldGuardInterface.containsMember(region, player.getUniqueId());
|
||||
boolean isOwner = this.worldGuardInterface.containsOwner(region, player.getUniqueId());
|
||||
String type = regionType.toString().toLowerCase(Locale.ENGLISH);
|
||||
IFileManager.AddResult result = this.plugin.getFileManager()
|
||||
.checkRegionAdd(
|
||||
player,
|
||||
region,
|
||||
world,
|
||||
regionType
|
||||
);
|
||||
switch (result) {
|
||||
case ALREADYADDED -> regionsAlready.add(plugin.getFileManager().getRegion(regionName));
|
||||
case ALREADYADDEDOTHERWORLD -> regionsAlreadyOtherWorld.add(plugin.getFileManager().getRegion(regionName));
|
||||
case BLACKLISTED -> namesBlacklisted.add(regionName);
|
||||
case NOPERMISSION -> namesNoPermission.add(regionName);
|
||||
default -> {
|
||||
// Check if the player should be landlord
|
||||
boolean landlord = (!player.hasPermission("areashop.create" + type)
|
||||
&& ((player.hasPermission("areashop.create" + type + ".owner") && isOwner)
|
||||
|| (player.hasPermission("areashop.create" + type + ".member") && isMember)));
|
||||
List<UUID> existing = new ArrayList<>();
|
||||
existing.addAll(worldGuardInterface.getOwners(region).asUniqueIdList());
|
||||
existing.addAll(worldGuardInterface.getMembers(region).asUniqueIdList());
|
||||
debugResult(player, regionName, landlord, existing, isMember, isOwner, regionType);
|
||||
if (regionType == GeneralRegion.RegionType.BUY) {
|
||||
proccessBuy(region, landlord, existing, taskState);
|
||||
} else if (regionType == GeneralRegion.RegionType.RENT) {
|
||||
processRent(region, landlord, existing, taskState);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void debugResult(
|
||||
@Nonnull Player player,
|
||||
@Nonnull String regionName,
|
||||
boolean landlord,
|
||||
List<UUID> existing,
|
||||
boolean isMember,
|
||||
boolean isOwner,
|
||||
@Nonnull GeneralRegion.RegionType regionType
|
||||
) {
|
||||
String type = regionType.name().toLowerCase(Locale.ENGLISH);
|
||||
AreaShop.debug("regionAddLandlordStatus:",
|
||||
regionName,
|
||||
"landlord:",
|
||||
landlord,
|
||||
"existing:",
|
||||
existing,
|
||||
"isMember:",
|
||||
isMember,
|
||||
"isOwner:",
|
||||
isOwner,
|
||||
"createPermission:",
|
||||
player.hasPermission("areashop.create" + type),
|
||||
"ownerPermission:",
|
||||
player.hasPermission("areashop.create" + type + ".owner"),
|
||||
"memberPermission:",
|
||||
player.hasPermission("areashop.create" + type + ".member"));
|
||||
}
|
||||
|
||||
private void onCompletion(@Nonnull AddTaskState taskState) {
|
||||
CommandSender player = taskState.sender();
|
||||
GeneralRegion.RegionType regionType = taskState.regionType;
|
||||
Set<GeneralRegion> regionsSuccess = taskState.regionsSuccess();
|
||||
Set<GeneralRegion> regionsAlready = taskState.regionsAlready();
|
||||
Set<GeneralRegion> regionsAlreadyOtherWorld = taskState.regionsAlreadyOtherWorld();
|
||||
Set<GeneralRegion> regionsRentCancelled = taskState.regionsRentCancelled(); // Denied by an event listener
|
||||
Set<GeneralRegion> regionsBuyCancelled = taskState.regionsBuyCancelled(); // Denied by an event listener
|
||||
Set<String> namesBlacklisted = taskState.namesBlacklisted();
|
||||
Set<String> namesNoPermission = taskState.namesNoPermission();
|
||||
Set<String> namesAddCancelled = taskState.namesAddCancelled(); // Denied by an event listener
|
||||
if (!regionsSuccess.isEmpty()) {
|
||||
this.messageBridge.message(player,
|
||||
"add-success",
|
||||
regionType.name().toLowerCase(Locale.ENGLISH),
|
||||
Utils.combinedMessage(regionsSuccess, "region"));
|
||||
}
|
||||
if (!regionsAlready.isEmpty()) {
|
||||
this.messageBridge.message(player,
|
||||
"add-failed",
|
||||
Utils.combinedMessage(regionsAlready, "region"));
|
||||
}
|
||||
if (!regionsAlreadyOtherWorld.isEmpty()) {
|
||||
this.messageBridge.message(player,
|
||||
"add-failedOtherWorld",
|
||||
Utils.combinedMessage(regionsAlreadyOtherWorld, "region"));
|
||||
}
|
||||
if (!regionsRentCancelled.isEmpty()) {
|
||||
this.messageBridge.message(player,
|
||||
"add-rentCancelled",
|
||||
Utils.combinedMessage(regionsRentCancelled, "region"));
|
||||
}
|
||||
if (!regionsBuyCancelled.isEmpty()) {
|
||||
this.messageBridge.message(player,
|
||||
"add-buyCancelled",
|
||||
Utils.combinedMessage(regionsBuyCancelled, "region"));
|
||||
}
|
||||
if (!namesBlacklisted.isEmpty()) {
|
||||
this.messageBridge.message(player,
|
||||
"add-blacklisted",
|
||||
Utils.createCommaSeparatedList(namesBlacklisted));
|
||||
}
|
||||
if (!namesNoPermission.isEmpty()) {
|
||||
this.messageBridge.message(player,
|
||||
"add-noPermissionRegions",
|
||||
Utils.createCommaSeparatedList(namesNoPermission));
|
||||
this.messageBridge.message(player, "add-noPermissionOwnerMember");
|
||||
}
|
||||
if (!namesAddCancelled.isEmpty()) {
|
||||
this.messageBridge.message(player,
|
||||
"add-rentCancelled",
|
||||
Utils.createCommaSeparatedList(namesAddCancelled));
|
||||
}
|
||||
}
|
||||
|
||||
private void processRent(
|
||||
@Nonnull ProtectedRegion region,
|
||||
boolean landlord,
|
||||
List<UUID> existing,
|
||||
@Nonnull AddTaskState taskState
|
||||
) {
|
||||
Player player = taskState.sender();
|
||||
Set<GeneralRegion> regionsSuccess = taskState.regionsSuccess();
|
||||
Set<GeneralRegion> regionsRentCancelled = taskState.regionsRentCancelled(); // Denied by an event listener
|
||||
Set<String> namesAddCancelled = taskState.namesAddCancelled(); // Denied by an event listener
|
||||
World world = taskState.world();
|
||||
String regionName = region.getId();
|
||||
RentRegion rent = regionFactory.createRentRegion(regionName, world);
|
||||
// Set landlord
|
||||
if (landlord) {
|
||||
rent.setLandlord(player.getUniqueId(), player.getName());
|
||||
}
|
||||
|
||||
AddingRegionEvent event = plugin.getFileManager().addRegion(rent);
|
||||
if (event.isCancelled()) {
|
||||
namesAddCancelled.add(rent.getName());
|
||||
return;
|
||||
}
|
||||
rent.handleSchematicEvent(GeneralRegion.RegionEvent.CREATED);
|
||||
rent.update();
|
||||
|
||||
// Add existing owners/members if any
|
||||
if (!landlord && !existing.isEmpty()) {
|
||||
UUID rentBy = existing.removeFirst();
|
||||
OfflinePlayer rentByPlayer = Bukkit.getOfflinePlayer(rentBy);
|
||||
|
||||
RentingRegionEvent rentingRegionEvent = new RentingRegionEvent(rent,
|
||||
rentByPlayer,
|
||||
false);
|
||||
Bukkit.getPluginManager().callEvent(rentingRegionEvent);
|
||||
if (rentingRegionEvent.isCancelled()) {
|
||||
regionsRentCancelled.add(rent);
|
||||
} else {
|
||||
// Add values to the rent and send it to FileManager
|
||||
rent.setRentedUntil(Calendar.getInstance()
|
||||
.getTimeInMillis() + rent.getDuration());
|
||||
rent.setRenter(rentBy);
|
||||
rent.updateLastActiveTime();
|
||||
|
||||
// Fire schematic event and updated times extended
|
||||
rent.handleSchematicEvent(GeneralRegion.RegionEvent.RENTED);
|
||||
|
||||
// Add others as friends
|
||||
for (UUID friend : existing) {
|
||||
rent.getFriendsFeature().addFriend(friend, null);
|
||||
}
|
||||
|
||||
rent.notifyAndUpdate(new RentedRegionEvent(rent, false));
|
||||
}
|
||||
}
|
||||
|
||||
regionsSuccess.add(rent);
|
||||
}
|
||||
|
||||
private void proccessBuy(
|
||||
@Nonnull ProtectedRegion region,
|
||||
boolean landlord,
|
||||
List<UUID> existing,
|
||||
@Nonnull AddTaskState taskState
|
||||
) {
|
||||
Player player = taskState.sender();
|
||||
Set<GeneralRegion> regionsSuccess = taskState.regionsSuccess();
|
||||
Set<GeneralRegion> regionsBuyCancelled = taskState.regionsBuyCancelled(); // Denied by an event listener
|
||||
Set<String> namesAddCancelled = taskState.namesAddCancelled(); // Denied by an event listener
|
||||
World world = taskState.world();
|
||||
String regionName = region.getId();
|
||||
BuyRegion buy = regionFactory.createBuyRegion(regionName, world);
|
||||
// Set landlord
|
||||
if (landlord) {
|
||||
buy.setLandlord(player.getUniqueId(), player.getName());
|
||||
}
|
||||
|
||||
AddingRegionEvent event = plugin.getFileManager().addRegion(buy);
|
||||
if (event.isCancelled()) {
|
||||
namesAddCancelled.add(buy.getName());
|
||||
return;
|
||||
}
|
||||
|
||||
buy.handleSchematicEvent(GeneralRegion.RegionEvent.CREATED);
|
||||
buy.update();
|
||||
|
||||
// Add existing owners/members if any
|
||||
if (!landlord && !existing.isEmpty()) {
|
||||
UUID buyBy = existing.removeFirst();
|
||||
OfflinePlayer buyByPlayer = Bukkit.getOfflinePlayer(buyBy);
|
||||
|
||||
BuyingRegionEvent buyingRegionEvent = new BuyingRegionEvent(buy,
|
||||
buyByPlayer);
|
||||
Bukkit.getPluginManager().callEvent(buyingRegionEvent);
|
||||
if (buyingRegionEvent.isCancelled()) {
|
||||
regionsBuyCancelled.add(buy);
|
||||
} else {
|
||||
// Set the owner
|
||||
buy.setBuyer(buyBy);
|
||||
buy.updateLastActiveTime();
|
||||
|
||||
// Update everything
|
||||
buy.handleSchematicEvent(GeneralRegion.RegionEvent.BOUGHT);
|
||||
|
||||
// Add others as friends
|
||||
for (UUID friend : existing) {
|
||||
buy.getFriendsFeature().addFriend(friend, null);
|
||||
}
|
||||
|
||||
buy.notifyAndUpdate(new BoughtRegionEvent(buy));
|
||||
}
|
||||
}
|
||||
|
||||
regionsSuccess.add(buy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return "Add a region";
|
||||
}
|
||||
|
||||
public String getHelp(CommandSender target) {
|
||||
if (target.hasPermission("areashop.createrent")
|
||||
|| target.hasPermission("areashop.createrent.member")
|
||||
|| target.hasPermission("areashop.createrent.owner")
|
||||
|
||||
|| target.hasPermission("areashop.createbuy")
|
||||
|| target.hasPermission("areashop.createbuy.member")
|
||||
|| target.hasPermission("areashop.createbuy.owner")) {
|
||||
return "help-add";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull CommandProperties properties() {
|
||||
return CommandProperties.of("add");
|
||||
}
|
||||
|
||||
private record AddTaskState(
|
||||
@Nonnull Player sender,
|
||||
@Nonnull GeneralRegion.RegionType regionType,
|
||||
@Nonnull Set<GeneralRegion> regionsSuccess,
|
||||
@Nonnull Set<GeneralRegion> regionsAlready,
|
||||
@Nonnull Set<GeneralRegion> regionsAlreadyOtherWorld,
|
||||
@Nonnull Set<GeneralRegion> regionsRentCancelled,
|
||||
@Nonnull Set<GeneralRegion> regionsBuyCancelled,
|
||||
@Nonnull Set<String> namesBlacklisted,
|
||||
@Nonnull Set<String> namesNoPermission,
|
||||
@Nonnull Set<String> namesAddCancelled,
|
||||
@Nonnull World world) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.RegionParseUtil;
|
||||
import me.wiefferink.areashop.commands.util.ValidatedOfflinePlayerParser;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.incendo.cloud.parser.flag.CommandFlag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
@Singleton
|
||||
public class AddFriendCommand extends AreashopCommandBean {
|
||||
|
||||
private static final CloudKey<OfflinePlayer> KEY_FRIEND = CloudKey.of("friend", OfflinePlayer.class);
|
||||
private final CommandFlag<GeneralRegion> regionFlag;
|
||||
private final MessageBridge messageBridge;
|
||||
private final Plugin plugin;
|
||||
|
||||
@Inject
|
||||
public AddFriendCommand(
|
||||
@Nonnull MessageBridge messageBridge,
|
||||
@Nonnull IFileManager fileManager,
|
||||
@Nonnull Plugin plugin
|
||||
) {
|
||||
this.messageBridge = messageBridge;
|
||||
this.plugin = plugin;
|
||||
this.regionFlag = RegionParseUtil.createDefault(fileManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return "Allows you to add friends to your regions";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(@NotNull CommandSender target) {
|
||||
if (target.hasPermission("areashop.addfriendall") || target.hasPermission("areashop.addfriend")) {
|
||||
return "help-addFriend";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("addfriend")
|
||||
.senderType(PlayerCommandSource.class)
|
||||
.required(KEY_FRIEND, ValidatedOfflinePlayerParser.validatedOfflinePlayerParser())
|
||||
.flag(this.regionFlag)
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
private void handleCommand(CommandContext<PlayerCommandSource> context) {
|
||||
Player sender = context.sender().sender();
|
||||
if (!sender.hasPermission("areashop.addfriend") && !sender.hasPermission("areashop.addfriendall")) {
|
||||
this.messageBridge.message(sender, "addfriend-noPermission");
|
||||
return;
|
||||
}
|
||||
GeneralRegion region = RegionParseUtil.getOrParseRegion(context, sender, this.regionFlag);
|
||||
OfflinePlayer friend = context.get(KEY_FRIEND);
|
||||
if (sender.hasPermission("areashop.addfriendall") && ((region instanceof RentRegion rentRegion && !rentRegion.isRented())
|
||||
|| (region instanceof BuyRegion buyRegion && !buyRegion.isSold()))) {
|
||||
this.messageBridge.message(sender, "addfriend-noOwner", region);
|
||||
return;
|
||||
|
||||
}
|
||||
if (!sender.hasPermission("areashop.addfriend")) {
|
||||
this.messageBridge.message(sender, "addfriend-noPermission", region);
|
||||
return;
|
||||
}
|
||||
if (!region.isOwner(sender)) {
|
||||
this.messageBridge.message(sender, "addfriend-noPermissionOther", region);
|
||||
return;
|
||||
}
|
||||
if (!friend.hasPlayedBefore() && !friend.isOnline() && !plugin.getConfig()
|
||||
.getBoolean("addFriendNotExistingPlayers")) {
|
||||
this.messageBridge.message(sender, "addfriend-notVisited", friend.getName(), region);
|
||||
} else if (region.getFriendsFeature().getFriends().contains(friend.getUniqueId())) {
|
||||
this.messageBridge.message(sender, "addfriend-alreadyAdded", friend.getName(), region);
|
||||
} else if (region.isOwner(friend.getUniqueId())) {
|
||||
this.messageBridge.message(sender, "addfriend-self", friend.getName(), region);
|
||||
} else if (region.getFriendsFeature().addFriend(friend.getUniqueId(), sender)) {
|
||||
region.update();
|
||||
this.messageBridge.message(sender, "addfriend-success", friend.getName(), region);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull CommandProperties properties() {
|
||||
return CommandProperties.of("addfriend");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.GeneralRegionParser;
|
||||
import me.wiefferink.areashop.commands.util.RegionParseUtil;
|
||||
import me.wiefferink.areashop.commands.util.SignProfileUtil;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
|
||||
import me.wiefferink.areashop.features.signs.RegionSign;
|
||||
import me.wiefferink.areashop.features.signs.SignManager;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.tools.Materials;
|
||||
import me.wiefferink.areashop.tools.SignUtils;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.util.BlockIterator;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Optional;
|
||||
|
||||
@Singleton
|
||||
public class AddSignCommand extends AreashopCommandBean {
|
||||
|
||||
private static final CloudKey<GeneralRegion> KEY_REGION = CloudKey.of("region", GeneralRegion.class);
|
||||
|
||||
private final SignManager signManager;
|
||||
private final Plugin plugin;
|
||||
private final IFileManager fileManager;
|
||||
|
||||
private final MessageBridge messageBridge;
|
||||
|
||||
@Inject
|
||||
public AddSignCommand(
|
||||
@Nonnull MessageBridge messageBridge,
|
||||
@Nonnull IFileManager fileManager,
|
||||
@Nonnull SignManager signManager,
|
||||
@Nonnull Plugin plugin
|
||||
) {
|
||||
this.messageBridge = messageBridge;
|
||||
this.signManager = signManager;
|
||||
this.plugin = plugin;
|
||||
this.fileManager = fileManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return "Allows you to add signs to existing regions";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(@NotNull CommandSender target) {
|
||||
if(target.hasPermission("areashop.addsign")) {
|
||||
return "help-addsign";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("addsign")
|
||||
.senderType(PlayerCommandSource.class)
|
||||
.optional(KEY_REGION, GeneralRegionParser.generalRegionParser(this.fileManager))
|
||||
.flag(SignProfileUtil.DEFAULT_FLAG)
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<PlayerCommandSource> context) {
|
||||
Player sender = context.sender().sender();
|
||||
if (!sender.hasPermission("areashop.addsign")) {
|
||||
throw new AreaShopCommandException("addsign-noPermission");
|
||||
}
|
||||
// Get the sign
|
||||
Block block = null;
|
||||
BlockIterator blockIterator = new BlockIterator(sender, 100);
|
||||
while(blockIterator.hasNext() && block == null) {
|
||||
Block next = blockIterator.next();
|
||||
if(next.getType() != Material.AIR) {
|
||||
block = next;
|
||||
}
|
||||
}
|
||||
if(block == null || !Materials.isSign(block.getType())) {
|
||||
messageBridge.message(sender, "addsign-noSign");
|
||||
return;
|
||||
}
|
||||
|
||||
GeneralRegion region = RegionParseUtil.getOrParseRegion(context, sender, KEY_REGION);
|
||||
String profile = SignProfileUtil.getOrParseProfile(context, this.plugin);
|
||||
Optional<RegionSign> optionalRegionSign = this.signManager.signFromLocation(block.getLocation());
|
||||
if(optionalRegionSign.isPresent()) {
|
||||
RegionSign regionSign = optionalRegionSign.get();
|
||||
messageBridge.message(sender, "addsign-alreadyRegistered", regionSign.getRegion());
|
||||
return;
|
||||
}
|
||||
|
||||
region.getSignsFeature().addSign(block.getLocation(), block.getType(), SignUtils.getSignFacing(block), profile);
|
||||
if(profile == null) {
|
||||
messageBridge.message(sender, "addsign-success", region);
|
||||
} else {
|
||||
messageBridge.message(sender, "addsign-successProfile", profile, region);
|
||||
}
|
||||
region.update();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected @Nonnull CommandProperties properties() {
|
||||
return CommandProperties.of("addsign");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.RegionParseUtil;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.parser.flag.CommandFlag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
@Singleton
|
||||
public class BuyCommand extends AreashopCommandBean {
|
||||
|
||||
private final CommandFlag<BuyRegion> buyRegionFlag;
|
||||
|
||||
@Inject
|
||||
public BuyCommand(@Nonnull IFileManager fileManager) {
|
||||
this.buyRegionFlag = RegionParseUtil.createDefaultBuy(fileManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(@NotNull CommandSender target) {
|
||||
if(target.hasPermission("areashop.buy")) {
|
||||
return "help-buy";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return "Allows you to buy a region";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull CommandProperties properties() {
|
||||
return CommandProperties.of("buy");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
|
||||
return builder
|
||||
.literal("buy")
|
||||
.flag(this.buyRegionFlag)
|
||||
.senderType(PlayerCommandSource.class)
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<PlayerCommandSource> context) {
|
||||
if (!context.hasPermission("areashop.buy")) {
|
||||
throw new AreaShopCommandException("buy-noPermission");
|
||||
}
|
||||
Player sender = context.sender().sender();
|
||||
BuyRegion region = RegionParseUtil.getOrParseBuyRegion(context, sender, this.buyRegionFlag);
|
||||
region.buy(sender);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.GeneralRegionParser;
|
||||
import me.wiefferink.areashop.commands.util.WorldSelection;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.events.ask.DeletingRegionEvent;
|
||||
import me.wiefferink.areashop.interfaces.WorldEditInterface;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
@Singleton
|
||||
public class DelCommand extends AreashopCommandBean {
|
||||
|
||||
private static final CloudKey<GeneralRegion> KEY_REGION = CloudKey.of("region", GeneralRegion.class);
|
||||
private final WorldEditInterface worldEditInterface;
|
||||
private final IFileManager fileManager;
|
||||
private final MessageBridge messageBridge;
|
||||
|
||||
@Inject
|
||||
public DelCommand(
|
||||
@Nonnull MessageBridge messageBridge,
|
||||
@Nonnull WorldEditInterface worldEditInterface,
|
||||
@Nonnull IFileManager fileManager
|
||||
) {
|
||||
this.messageBridge = messageBridge;
|
||||
this.worldEditInterface = worldEditInterface;
|
||||
this.fileManager = fileManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return "Allows you to delete regions";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(@NotNull CommandSender target) {
|
||||
if (target.hasPermission("areashop.destroyrent") || target.hasPermission("areashop.destroybuy") || target.hasPermission(
|
||||
"areashop.destroyrent.landlord") || target.hasPermission("areashop.destroybuy.landlord")) {
|
||||
return "help-del";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull CommandProperties properties() {
|
||||
return CommandProperties.of("delete", "del");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("del", "delete")
|
||||
.optional(KEY_REGION, GeneralRegionParser.generalRegionParser(this.fileManager))
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
public void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
|
||||
CommandSender sender = context.sender().sender();
|
||||
if (!sender.hasPermission("areashop.destroybuy")
|
||||
&& !sender.hasPermission("areashop.destroybuy.landlord")
|
||||
&& !sender.hasPermission("areashop.destroyrent")
|
||||
&& !sender.hasPermission("areashop.destroyrent.landlord")) {
|
||||
throw new AreaShopCommandException("del-noPermission");
|
||||
}
|
||||
Optional<GeneralRegion> inputRegion = context.optional(KEY_REGION);
|
||||
if (inputRegion.isPresent()) {
|
||||
handleSingleDeletion(sender, inputRegion.get());
|
||||
return;
|
||||
}
|
||||
List<GeneralRegion> regions;
|
||||
if (sender instanceof Player player) {
|
||||
WorldSelection selection = WorldSelection.fromPlayer(player, this.worldEditInterface);
|
||||
regions = Utils.getWorldEditRegionsInSelection(selection.selection()).stream()
|
||||
.map(ProtectedRegion::getId)
|
||||
.map(this.fileManager::getRegion)
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
} else {
|
||||
throw new AreaShopCommandException("cmd-weOnlyByPlayer");
|
||||
}
|
||||
if (regions.isEmpty()) {
|
||||
throw new AreaShopCommandException("cmd-noWERegionsFound");
|
||||
}
|
||||
handleMassDeletion(player, regions);
|
||||
}
|
||||
|
||||
private void handleSingleDeletion(@Nonnull CommandSender sender, GeneralRegion region) {
|
||||
boolean isLandlord = sender instanceof Player player && region.isLandlord(player.getUniqueId());
|
||||
if (region instanceof RentRegion) {
|
||||
// Remove the rent if the player has permission
|
||||
if (sender.hasPermission("areashop.destroyrent") || (isLandlord && sender.hasPermission(
|
||||
"areashop.destroyrent.landlord"))) {
|
||||
DeletingRegionEvent event = fileManager.deleteRegion(region, true);
|
||||
if (event.isCancelled()) {
|
||||
this.messageBridge.message(sender, "general-cancelled", event.getReason());
|
||||
} else {
|
||||
this.messageBridge.message(sender, "destroy-successRent", region);
|
||||
}
|
||||
} else {
|
||||
this.messageBridge.message(sender, "destroy-noPermissionRent", region);
|
||||
}
|
||||
} else if (region instanceof BuyRegion) {
|
||||
// Remove the buy if the player has permission
|
||||
if (sender.hasPermission("areashop.destroybuy") || (isLandlord && sender.hasPermission(
|
||||
"areashop.destroybuy.landlord"))) {
|
||||
DeletingRegionEvent event = fileManager.deleteRegion(region, true);
|
||||
if (event.isCancelled()) {
|
||||
messageBridge.message(sender, "general-cancelled", event.getReason());
|
||||
} else {
|
||||
messageBridge.message(sender, "destroy-successBuy", region);
|
||||
}
|
||||
} else {
|
||||
messageBridge.message(sender, "destroy-noPermissionBuy", region);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleMassDeletion(@Nonnull Player sender, @Nonnull List<GeneralRegion> regions) {
|
||||
List<String> namesSuccess = new ArrayList<>();
|
||||
Set<GeneralRegion> regionsFailed = new TreeSet<>();
|
||||
Set<GeneralRegion> regionsCancelled = new TreeSet<>();
|
||||
for (GeneralRegion region : regions) {
|
||||
if (cannotDelete(sender, region)) {
|
||||
regionsFailed.add(region);
|
||||
continue;
|
||||
}
|
||||
|
||||
DeletingRegionEvent event = this.fileManager.deleteRegion(region, true);
|
||||
if (event.isCancelled()) {
|
||||
regionsCancelled.add(region);
|
||||
} else {
|
||||
namesSuccess.add(region.getName());
|
||||
}
|
||||
}
|
||||
|
||||
// Send messages
|
||||
if (!namesSuccess.isEmpty()) {
|
||||
this.messageBridge.message(sender, "del-success", Utils.createCommaSeparatedList(namesSuccess));
|
||||
}
|
||||
if (!regionsFailed.isEmpty()) {
|
||||
this.messageBridge.message(sender, "del-failed", Utils.combinedMessage(regionsFailed, "region"));
|
||||
}
|
||||
if (!regionsCancelled.isEmpty()) {
|
||||
this.messageBridge.message(sender, "del-cancelled", Utils.combinedMessage(regionsCancelled, "region"));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean cannotDelete(@Nonnull Player sender, @Nonnull GeneralRegion region) {
|
||||
boolean isLandlord = region.isLandlord(sender.getUniqueId());
|
||||
if (region instanceof RentRegion
|
||||
&& (!sender.hasPermission("areashop.destroyrent") && !(isLandlord && sender.hasPermission(
|
||||
"areashop.destroyrent.landlord")))) {
|
||||
return true;
|
||||
|
||||
}
|
||||
return region instanceof BuyRegion
|
||||
&& (!sender.hasPermission("areashop.destroybuy") && !(isLandlord && sender.hasPermission(
|
||||
"areashop.destroybuy.landlord")));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.RegionParseUtil;
|
||||
import me.wiefferink.areashop.commands.util.ValidatedOfflinePlayerParser;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.features.FriendsFeature;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.context.CommandInput;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.incendo.cloud.parser.flag.CommandFlag;
|
||||
import org.incendo.cloud.suggestion.Suggestion;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Singleton
|
||||
public class DelFriendCommand extends AreashopCommandBean {
|
||||
|
||||
|
||||
private static final CloudKey<OfflinePlayer> KEY_PLAYER = CloudKey.of("player", OfflinePlayer.class);
|
||||
private final MessageBridge messageBridge;
|
||||
private final CommandFlag<GeneralRegion> regionFlag;
|
||||
|
||||
@Inject
|
||||
public DelFriendCommand(
|
||||
@Nonnull MessageBridge messageBridge,
|
||||
@Nonnull IFileManager fileManager
|
||||
) {
|
||||
this.messageBridge = messageBridge;
|
||||
this.regionFlag = RegionParseUtil.createDefault(fileManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a person can remove friends.
|
||||
*
|
||||
* @param person The person to check
|
||||
* @param region The region to check for
|
||||
* @return true if the person can remove friends, otherwise false
|
||||
*/
|
||||
public static boolean canUse(CommandSender person, GeneralRegion region) {
|
||||
if (person.hasPermission("areashop.delfriendall")) {
|
||||
return true;
|
||||
}
|
||||
if (person instanceof Player player) {
|
||||
return region.isOwner(player) && player.hasPermission("areashop.delfriend");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(@NotNull CommandSender target) {
|
||||
if (target.hasPermission("areashop.delfriendall") || target.hasPermission("areashop.delfriend")) {
|
||||
return "help-delFriend";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull CommandProperties properties() {
|
||||
return CommandProperties.of("deletefriend", "delfriend");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("delfriend", "deletefriend")
|
||||
.required(KEY_PLAYER, ValidatedOfflinePlayerParser.validatedOfflinePlayerParser(), this::suggestFriends)
|
||||
.flag(this.regionFlag)
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
|
||||
CommandSender sender = context.sender().sender();
|
||||
if (!sender.hasPermission("areashop.delfriend") && !sender.hasPermission("areashop.delfriendall")) {
|
||||
throw new AreaShopCommandException("delfriend-noPermission");
|
||||
}
|
||||
GeneralRegion region = RegionParseUtil.getOrParseRegion(context, sender, this.regionFlag);
|
||||
OfflinePlayer friend = context.get(KEY_PLAYER);
|
||||
FriendsFeature friendsFeature = region.getFriendsFeature();
|
||||
if (sender.hasPermission("areashop.delfriendall")) {
|
||||
if ((region instanceof RentRegion rentRegion && !rentRegion.isRented())
|
||||
|| (region instanceof BuyRegion buyRegion && !buyRegion.isSold())) {
|
||||
throw new AreaShopCommandException("delfriend-noOwner", region);
|
||||
|
||||
}
|
||||
if (!friendsFeature.getFriends().contains(friend.getUniqueId())) {
|
||||
throw new AreaShopCommandException("delfriend-notAdded", friend.getName(), region);
|
||||
|
||||
}
|
||||
if (friendsFeature.deleteFriend(friend.getUniqueId(), sender)) {
|
||||
region.update();
|
||||
this.messageBridge.message(sender, "delfriend-successOther", friend.getName(), region);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!sender.hasPermission("areashop.delfriend") || !(sender instanceof Player player)) {
|
||||
throw new AreaShopCommandException("delfriend-noPermission", region);
|
||||
}
|
||||
if (!region.isOwner(player)) {
|
||||
throw new AreaShopCommandException("delfriend-noPermissionOther", region);
|
||||
}
|
||||
if (!friendsFeature.getFriends().contains(friend.getUniqueId())) {
|
||||
throw new AreaShopCommandException("delfriend-notAdded", friend.getName(), region);
|
||||
} else if (friendsFeature.deleteFriend(friend.getUniqueId(), sender)) {
|
||||
region.update();
|
||||
this.messageBridge.message(sender, "delfriend-success", friend.getName(), region);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private CompletableFuture<Iterable<Suggestion>> suggestFriends(
|
||||
@Nonnull CommandContext<CommandSource<?>> context,
|
||||
@Nonnull CommandInput input
|
||||
) {
|
||||
CommandSender sender = context.sender().sender();
|
||||
if (!sender.hasPermission("areashop.delfriend")) {
|
||||
return CompletableFuture.completedFuture(Collections.emptyList());
|
||||
}
|
||||
GeneralRegion region;
|
||||
try {
|
||||
region = RegionParseUtil.getOrParseRegion(context, sender, this.regionFlag);
|
||||
} catch (AreaShopCommandException ignored) {
|
||||
return CompletableFuture.completedFuture(Collections.emptyList());
|
||||
}
|
||||
if (!sender.hasPermission("areashop.delfriendall")
|
||||
&& sender instanceof Player player
|
||||
&& !region.isOwner(player)
|
||||
) {
|
||||
return CompletableFuture.completedFuture(Collections.emptyList());
|
||||
}
|
||||
String text = input.peekString();
|
||||
FriendsFeature friendsFeature = region.getFriendsFeature();
|
||||
Collection<Suggestion> suggestion = friendsFeature.getFriendNames().stream()
|
||||
.filter(name -> name.startsWith(text))
|
||||
.map(Suggestion::suggestion)
|
||||
.toList();
|
||||
return CompletableFuture.completedFuture(suggestion);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
|
||||
import me.wiefferink.areashop.features.signs.RegionSign;
|
||||
import me.wiefferink.areashop.features.signs.SignManager;
|
||||
import me.wiefferink.areashop.tools.Materials;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.BlockIterator;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Optional;
|
||||
|
||||
@Singleton
|
||||
public class DelSignCommand extends AreashopCommandBean {
|
||||
|
||||
private final SignManager signManager;
|
||||
private final MessageBridge messageBridge;
|
||||
|
||||
@Inject
|
||||
public DelSignCommand(@Nonnull MessageBridge messageBridge, @Nonnull SignManager signManager) {
|
||||
this.signManager = signManager;
|
||||
this.messageBridge = messageBridge;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected @Nonnull CommandProperties properties() {
|
||||
return CommandProperties.of("deletesign", "delsign");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("delsign", "deletesign")
|
||||
.senderType(PlayerCommandSource.class)
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(@NotNull CommandSender target) {
|
||||
if (target.hasPermission("areashop.delsign")) {
|
||||
return "help-delsign";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<PlayerCommandSource> context) {
|
||||
Player sender = context.sender().sender();
|
||||
if (!sender.hasPermission("areashop.delsign")) {
|
||||
throw new AreaShopCommandException("delsign-noPermission");
|
||||
}
|
||||
// Get the sign
|
||||
Block block = null;
|
||||
BlockIterator blockIterator = new BlockIterator(sender, 100);
|
||||
while (blockIterator.hasNext() && block == null) {
|
||||
Block next = blockIterator.next();
|
||||
if (!next.getType().isAir()) {
|
||||
block = next;
|
||||
}
|
||||
}
|
||||
if (block == null || !Materials.isSign(block.getType())) {
|
||||
throw new AreaShopCommandException("delsign-noSign");
|
||||
}
|
||||
Optional<RegionSign> optionalSign = signManager.removeSign(block.getLocation());
|
||||
if (optionalSign.isEmpty()) {
|
||||
throw new AreaShopCommandException("delsign-noRegion");
|
||||
}
|
||||
RegionSign regionSign = optionalSign.get();
|
||||
messageBridge.message(sender, "delsign-success", regionSign.getRegion());
|
||||
regionSign.remove();
|
||||
// Sometimes the RegionSign data is corrupted. Forcefully set the block to air
|
||||
block.setType(Material.AIR);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.RegionGroupParser;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RegionGroup;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import me.wiefferink.interactivemessenger.processing.Message;
|
||||
import net.milkbowl.vault.economy.Economy;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.incendo.cloud.parser.ParserDescriptor;
|
||||
import org.incendo.cloud.parser.flag.CommandFlag;
|
||||
import org.incendo.cloud.parser.standard.DoubleParser;
|
||||
import org.incendo.cloud.parser.standard.EnumParser;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
@Singleton
|
||||
public class FindCommand extends AreashopCommandBean {
|
||||
|
||||
private static final CloudKey<GeneralRegion.RegionType> KEY_REGION_TYPE = CloudKey.of("regionType",
|
||||
GeneralRegion.RegionType.class);
|
||||
private static final CloudKey<Double> KEY_PRICE = CloudKey.of("maxPrice", Double.class);
|
||||
|
||||
private final Economy economy;
|
||||
private final IFileManager fileManager;
|
||||
private final CommandFlag<RegionGroup> regionGroupFlag;
|
||||
|
||||
private final MessageBridge messageBridge;
|
||||
|
||||
@Inject
|
||||
public FindCommand(
|
||||
@Nonnull MessageBridge messageBridge,
|
||||
@Nonnull Economy economy,
|
||||
@Nonnull IFileManager fileManager
|
||||
) {
|
||||
this.messageBridge = messageBridge;
|
||||
this.economy = economy;
|
||||
this.fileManager = fileManager;
|
||||
this.regionGroupFlag = CommandFlag.builder("region")
|
||||
.withComponent(ParserDescriptor.of(new RegionGroupParser<>(fileManager, "find-wrongGroup"),
|
||||
RegionGroup.class))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(@NotNull CommandSender target) {
|
||||
if(target.hasPermission("areashop.find")) {
|
||||
return "help-find";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("find")
|
||||
.senderType(PlayerCommandSource.class)
|
||||
.required(KEY_REGION_TYPE, EnumParser.enumParser(GeneralRegion.RegionType.class))
|
||||
.optional(KEY_PRICE, DoubleParser.doubleParser(0))
|
||||
.flag(this.regionGroupFlag)
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull CommandProperties properties() {
|
||||
return CommandProperties.of("find");
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<PlayerCommandSource> context) {
|
||||
Player sender = context.sender().sender();
|
||||
if (!sender.hasPermission("areashop.find")) {
|
||||
throw new AreaShopCommandException("find-noPermission");
|
||||
}
|
||||
double balance;
|
||||
if (economy != null) {
|
||||
balance = economy.getBalance(sender);
|
||||
} else {
|
||||
balance = 0;
|
||||
}
|
||||
boolean maxPriceSet = context.contains(KEY_PRICE);
|
||||
double maxPrice = context.getOrDefault(KEY_PRICE, Double.MAX_VALUE);
|
||||
RegionGroup group = context.flags().get(this.regionGroupFlag);
|
||||
GeneralRegion.RegionType regionType = context.get(KEY_REGION_TYPE);
|
||||
Message onlyInGroup;
|
||||
if (group != null) {
|
||||
onlyInGroup = Message.fromKey("find-onlyInGroup").replacements(group.getName());
|
||||
} else {
|
||||
onlyInGroup = Message.empty();
|
||||
}
|
||||
switch (regionType) {
|
||||
case BUY -> handleBuy(sender, balance, maxPrice, maxPriceSet, onlyInGroup, group);
|
||||
case RENT -> handleRent(sender, balance, maxPrice, maxPriceSet, onlyInGroup, group);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleBuy(@Nonnull Player sender,
|
||||
double balance,
|
||||
double maxPrice,
|
||||
boolean maxPriceSet,
|
||||
@Nonnull Message onlyInGroup,
|
||||
RegionGroup group
|
||||
) {
|
||||
Collection<BuyRegion> regions = fileManager.getBuysRef();
|
||||
List<BuyRegion> results = new LinkedList<>();
|
||||
for (BuyRegion region : regions) {
|
||||
if (!region.isSold()
|
||||
&& ((region.getPrice() <= balance && !maxPriceSet) || (region.getPrice() <= maxPrice && maxPriceSet))
|
||||
&& (group == null || group.isMember(region))
|
||||
&& (region.getBooleanSetting("general.findCrossWorld") || sender.getWorld()
|
||||
.equals(region.getWorld()))
|
||||
) {
|
||||
results.add(region);
|
||||
}
|
||||
}
|
||||
if (results.isEmpty()) {
|
||||
double currency = maxPriceSet ? maxPrice : balance;
|
||||
String key = maxPriceSet ? "find-noneFoundMax" : "find-noneFound";
|
||||
throw new AreaShopCommandException(key, "buy", Utils.formatCurrency(currency), onlyInGroup);
|
||||
}
|
||||
// Draw a random one
|
||||
BuyRegion region = results.get(ThreadLocalRandom.current().nextInt(results.size()));
|
||||
// Teleport
|
||||
double currency = maxPriceSet ? maxPrice : balance;
|
||||
String key = maxPriceSet ? "find-successMax" : "find-success";
|
||||
this.messageBridge.message(sender,
|
||||
key,
|
||||
"buy",
|
||||
Utils.formatCurrency(currency),
|
||||
onlyInGroup,
|
||||
region);
|
||||
boolean tpToSign = region.getBooleanSetting("general.findTeleportToSign");
|
||||
region.getTeleportFeature().teleportPlayer(sender, tpToSign, false);
|
||||
}
|
||||
|
||||
private void handleRent(
|
||||
@Nonnull Player sender,
|
||||
double balance,
|
||||
double maxPrice,
|
||||
boolean maxPriceSet,
|
||||
@Nonnull Message onlyInGroup,
|
||||
RegionGroup group
|
||||
) {
|
||||
Collection<RentRegion> regions = fileManager.getRentsRef();
|
||||
List<RentRegion> results = new LinkedList<>();
|
||||
for (RentRegion region : regions) {
|
||||
if (!region.isRented()
|
||||
&& ((region.getPrice() <= balance && !maxPriceSet) || (region.getPrice() <= maxPrice && maxPriceSet))
|
||||
&& (group == null || group.isMember(region))
|
||||
&& (region.getBooleanSetting("general.findCrossWorld") || sender.getWorld()
|
||||
.equals(region.getWorld()))
|
||||
) {
|
||||
results.add(region);
|
||||
}
|
||||
}
|
||||
if (results.isEmpty()) {
|
||||
double currency = maxPriceSet ? maxPrice : balance;
|
||||
String key = maxPriceSet ? "find-noneFoundMax" : "find-noneFound";
|
||||
throw new AreaShopCommandException(key, "rent", Utils.formatCurrency(currency), onlyInGroup);
|
||||
}
|
||||
// Draw a random one
|
||||
RentRegion region = results.get(ThreadLocalRandom.current().nextInt(results.size()));
|
||||
// Teleport
|
||||
double currency = maxPriceSet ? maxPrice : balance;
|
||||
String key = maxPriceSet ? "find-successMax" : "find-success";
|
||||
this.messageBridge.message(sender,
|
||||
key,
|
||||
"rent",
|
||||
Utils.formatCurrency(currency),
|
||||
onlyInGroup,
|
||||
region);
|
||||
boolean tpToSign = region.getBooleanSetting("general.findTeleportToSign");
|
||||
region.getTeleportFeature().teleportPlayer(sender, tpToSign, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.RegionParseUtil;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RegionFactory;
|
||||
import me.wiefferink.areashop.regions.RegionGroup;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.context.CommandInput;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.incendo.cloud.parser.flag.CommandFlag;
|
||||
import org.incendo.cloud.parser.standard.StringParser;
|
||||
import org.incendo.cloud.suggestion.Suggestion;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Singleton
|
||||
public class GroupAddCommand extends AreashopCommandBean {
|
||||
|
||||
private static final CloudKey<String> KEY_GROUP = CloudKey.of("group", String.class);
|
||||
|
||||
private final IFileManager fileManager;
|
||||
private final RegionFactory regionFactory;
|
||||
private final MessageBridge messageBridge;
|
||||
private final CommandFlag<GeneralRegion> regionFlag;
|
||||
|
||||
@Inject
|
||||
public GroupAddCommand(
|
||||
@Nonnull MessageBridge messageBridge,
|
||||
@Nonnull IFileManager fileManager,
|
||||
@Nonnull RegionFactory regionFactory
|
||||
|
||||
) {
|
||||
this.messageBridge = messageBridge;
|
||||
this.fileManager = fileManager;
|
||||
this.regionFactory = regionFactory;
|
||||
this.regionFlag = RegionParseUtil.createDefault(fileManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(@NotNull CommandSender target) {
|
||||
if(target.hasPermission("areashop.groupadd")) {
|
||||
return "help-groupadd";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("groupadd")
|
||||
.required(KEY_GROUP, StringParser.stringParser(), this::suggestGroupNames)
|
||||
.flag(this.regionFlag)
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull CommandProperties properties() {
|
||||
return CommandProperties.of("groupadd");
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
|
||||
CommandSender sender = context.sender().sender();
|
||||
if (!sender.hasPermission("areashop.groupadd")) {
|
||||
throw new AreaShopCommandException("groupadd-noPermission");
|
||||
}
|
||||
String rawGroup = context.get(KEY_GROUP);
|
||||
RegionGroup group = fileManager.getGroup(rawGroup);
|
||||
if (group == null) {
|
||||
group = regionFactory.createRegionGroup(rawGroup);
|
||||
fileManager.addGroup(group);
|
||||
}
|
||||
GeneralRegion declaredRegion = context.flags().get(this.regionFlag);
|
||||
if (declaredRegion != null) {
|
||||
if (!group.addMember(declaredRegion)) {
|
||||
throw new AreaShopCommandException("groupadd-failed", group.getName(), declaredRegion);
|
||||
}
|
||||
declaredRegion.update();
|
||||
this.messageBridge.message(sender,
|
||||
"groupadd-success",
|
||||
group.getName(),
|
||||
group.getMembers().size(),
|
||||
declaredRegion);
|
||||
return;
|
||||
}
|
||||
|
||||
Collection<GeneralRegion> regions = RegionParseUtil.getOrParseRegionsInSel(context, sender, this.regionFlag);
|
||||
Set<GeneralRegion> regionsSuccess = new TreeSet<>();
|
||||
Set<GeneralRegion> regionsFailed = new TreeSet<>();
|
||||
for (GeneralRegion region : regions) {
|
||||
if (group.addMember(region)) {
|
||||
regionsSuccess.add(region);
|
||||
} else {
|
||||
regionsFailed.add(region);
|
||||
}
|
||||
}
|
||||
if (!regionsSuccess.isEmpty()) {
|
||||
messageBridge.message(sender,
|
||||
"groupadd-weSuccess",
|
||||
group.getName(),
|
||||
Utils.combinedMessage(regionsSuccess, "region"));
|
||||
}
|
||||
if (!regionsFailed.isEmpty()) {
|
||||
messageBridge.message(sender,
|
||||
"groupadd-weFailed",
|
||||
group.getName(),
|
||||
Utils.combinedMessage(regionsFailed, "region"));
|
||||
}
|
||||
// Update all regions, this does it in a task, updating them without lag
|
||||
fileManager.updateRegions(List.copyOf(regionsSuccess), sender);
|
||||
}
|
||||
|
||||
private CompletableFuture<Iterable<Suggestion>> suggestGroupNames(
|
||||
@Nonnull CommandContext<CommandSource<?>> context,
|
||||
@Nonnull CommandInput input
|
||||
) {
|
||||
String text = input.peekString();
|
||||
List<Suggestion> suggestions = this.fileManager.getGroupNames().stream()
|
||||
.filter(name -> name.startsWith(text))
|
||||
.map(Suggestion::suggestion)
|
||||
.toList();
|
||||
return CompletableFuture.completedFuture(suggestions);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.RegionParseUtil;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RegionFactory;
|
||||
import me.wiefferink.areashop.regions.RegionGroup;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.context.CommandInput;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.incendo.cloud.parser.flag.CommandFlag;
|
||||
import org.incendo.cloud.parser.standard.StringParser;
|
||||
import org.incendo.cloud.suggestion.Suggestion;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Singleton
|
||||
public class GroupDelCommand extends AreashopCommandBean {
|
||||
|
||||
private static final CloudKey<String> KEY_GROUP = CloudKey.of("group", String.class);
|
||||
|
||||
private final IFileManager fileManager;
|
||||
private final RegionFactory regionFactory;
|
||||
private final MessageBridge messageBridge;
|
||||
private final CommandFlag<GeneralRegion> regionFlag;
|
||||
|
||||
@Inject
|
||||
public GroupDelCommand(
|
||||
@Nonnull MessageBridge messageBridge,
|
||||
@Nonnull IFileManager fileManager,
|
||||
@Nonnull RegionFactory regionFactory
|
||||
|
||||
) {
|
||||
this.messageBridge = messageBridge;
|
||||
this.fileManager = fileManager;
|
||||
this.regionFactory = regionFactory;
|
||||
this.regionFlag = RegionParseUtil.createDefault(fileManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(@NotNull CommandSender target) {
|
||||
if(target.hasPermission("areashop.groupdel")) {
|
||||
return "help-groupdel";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("groupdel")
|
||||
.required(KEY_GROUP, StringParser.stringParser(), this::suggestGroupNames)
|
||||
.flag(this.regionFlag)
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull CommandProperties properties() {
|
||||
return CommandProperties.of("groupdel");
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
|
||||
CommandSender sender = context.sender().sender();
|
||||
if (!sender.hasPermission("groupdel")) {
|
||||
throw new AreaShopCommandException("groupdel-noPermission");
|
||||
}
|
||||
String rawGroup = context.get(KEY_GROUP);
|
||||
RegionGroup group = fileManager.getGroup(rawGroup);
|
||||
if (group == null) {
|
||||
group = regionFactory.createRegionGroup(rawGroup);
|
||||
fileManager.addGroup(group);
|
||||
}
|
||||
GeneralRegion declaredRegion = context.flags().get(this.regionFlag);
|
||||
if (declaredRegion != null) {
|
||||
if (!group.removeMember(declaredRegion)) {
|
||||
throw new AreaShopCommandException("groupdel-failed", group.getName(), declaredRegion);
|
||||
}
|
||||
this.messageBridge.message(sender,
|
||||
"groupdel-success",
|
||||
group.getName(),
|
||||
group.getMembers().size(),
|
||||
declaredRegion);
|
||||
return;
|
||||
}
|
||||
|
||||
Collection<GeneralRegion> regions = RegionParseUtil.getOrParseRegionsInSel(context, sender, this.regionFlag);
|
||||
Set<GeneralRegion> regionsSuccess = new TreeSet<>();
|
||||
Set<GeneralRegion> regionsFailed = new TreeSet<>();
|
||||
for (GeneralRegion region : regions) {
|
||||
if (group.removeMember(region)) {
|
||||
regionsSuccess.add(region);
|
||||
} else {
|
||||
regionsFailed.add(region);
|
||||
}
|
||||
}
|
||||
if (!regionsSuccess.isEmpty()) {
|
||||
messageBridge.message(sender,
|
||||
"groupdel-weSuccess",
|
||||
group.getName(),
|
||||
Utils.combinedMessage(regionsSuccess, "region"));
|
||||
}
|
||||
if (!regionsFailed.isEmpty()) {
|
||||
messageBridge.message(sender,
|
||||
"groupdel-weFailed",
|
||||
group.getName(),
|
||||
Utils.combinedMessage(regionsFailed, "region"));
|
||||
}
|
||||
// Update all regions, this does it in a task, updating them without lag
|
||||
fileManager.updateRegions(List.copyOf(regionsSuccess), sender);
|
||||
group.saveRequired();
|
||||
}
|
||||
|
||||
private CompletableFuture<Iterable<Suggestion>> suggestGroupNames(
|
||||
@Nonnull CommandContext<CommandSource<?>> context,
|
||||
@Nonnull CommandInput input
|
||||
) {
|
||||
String text = input.peekString();
|
||||
List<Suggestion> suggestions = this.fileManager.getGroupNames().stream()
|
||||
.filter(name -> name.startsWith(text))
|
||||
.map(Suggestion::suggestion)
|
||||
.toList();
|
||||
return CompletableFuture.completedFuture(suggestions);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.RegionGroupParser;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.RegionGroup;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.incendo.cloud.parser.ParserDescriptor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Set;
|
||||
|
||||
@Singleton
|
||||
public class GroupInfoCommand extends AreashopCommandBean {
|
||||
|
||||
private static final CloudKey<RegionGroup> KEY_GROUP = CloudKey.of("group", RegionGroup.class);
|
||||
|
||||
private final IFileManager fileManager;
|
||||
private final MessageBridge messageBridge;
|
||||
|
||||
@Inject
|
||||
public GroupInfoCommand(@Nonnull MessageBridge messageBridge, @Nonnull IFileManager fileManager) {
|
||||
this.messageBridge = messageBridge;
|
||||
this.fileManager = fileManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(@NotNull CommandSender target) {
|
||||
if(target.hasPermission("areashop.groupinfo")) {
|
||||
return "help-groupinfo";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
|
||||
ParserDescriptor<CommandSource<?>, RegionGroup> regionGroupParser = ParserDescriptor.of(
|
||||
new RegionGroupParser<>(this.fileManager, "groupinfo-noGroup"),
|
||||
RegionGroup.class);
|
||||
return builder
|
||||
.literal("groupinfo")
|
||||
.required(KEY_GROUP, regionGroupParser)
|
||||
.handler(this::handleCommand);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull CommandProperties properties() {
|
||||
return CommandProperties.of("groupinfo");
|
||||
}
|
||||
|
||||
public void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
|
||||
if (!context.hasPermission("groupinfo")) {
|
||||
throw new AreaShopCommandException("groupinfo-noPermission");
|
||||
}
|
||||
RegionGroup group = context.get(KEY_GROUP);
|
||||
Set<String> members = group.getMembers();
|
||||
if (members.isEmpty()) {
|
||||
throw new AreaShopCommandException("groupinfo-noMembers", group.getName());
|
||||
}
|
||||
String seperatedMembers = Utils.createCommaSeparatedList(members);
|
||||
this.messageBridge.message(context.sender(), "groupinfo-members", group.getName(), seperatedMembers);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
|
||||
@Singleton
|
||||
public class GroupListCommand extends AreashopCommandBean {
|
||||
|
||||
private final MessageBridge messageBridge;
|
||||
private final IFileManager fileManager;
|
||||
|
||||
@Inject
|
||||
public GroupListCommand(@Nonnull MessageBridge messageBridge, @Nonnull IFileManager fileManager) {
|
||||
this.messageBridge = messageBridge;
|
||||
this.fileManager = fileManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(CommandSender target) {
|
||||
if(target.hasPermission("areashop.grouplist")) {
|
||||
return "help-grouplist";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("grouplist", "groups")
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull CommandProperties properties() {
|
||||
return CommandProperties.of("grouplist", "groups");
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
|
||||
if (!context.hasPermission("areashop.grouplist")) {
|
||||
throw new AreaShopCommandException("grouplist-noPermission");
|
||||
}
|
||||
List<String> groups = this.fileManager.getGroupNames();
|
||||
CommandSender sender = context.sender().sender();
|
||||
if(groups.isEmpty()) {
|
||||
messageBridge.message(sender, "grouplist-noGroups");
|
||||
} else {
|
||||
messageBridge.message(sender, "grouplist-success", Utils.createCommaSeparatedList(groups));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommands;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
@Singleton
|
||||
public class HelpCommand extends AreashopCommandBean {
|
||||
private final AreashopCommands commands;
|
||||
|
||||
@Inject
|
||||
public HelpCommand(@Nonnull AreashopCommands commands) {
|
||||
this.commands = commands;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(@NotNull CommandSender target) {
|
||||
if (target.hasPermission("areashop.help")) {
|
||||
return "help-help";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("help")
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull CommandProperties properties() {
|
||||
return CommandProperties.of("help");
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
|
||||
CommandSender sender = context.sender().sender();
|
||||
if (!sender.hasPermission("areashop.help")) {
|
||||
throw new AreaShopCommandException("help-noPermission");
|
||||
}
|
||||
this.commands.showHelp(sender);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AcceptedValuesParser;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.regions.ImportJobFactory;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.incendo.cloud.parser.ParserDescriptor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
|
||||
@Singleton
|
||||
public class ImportCommand extends AreashopCommandBean {
|
||||
|
||||
private static final CloudKey<String> KEY_SOURCE = CloudKey.of("source", String.class);
|
||||
|
||||
/* RegionGroup priority usage:
|
||||
0: Settings from /config.yml
|
||||
1: Settings from /worlds/<world>/config.yml
|
||||
2: Settings from /worlds/<world>/parent-regions.yml (if their priority is set it is added to this value)
|
||||
*/
|
||||
private final ImportJobFactory importJobFactory;
|
||||
private final MessageBridge messageBridge;
|
||||
|
||||
@Inject
|
||||
public ImportCommand(@Nonnull MessageBridge messageBridge, @Nonnull ImportJobFactory importJobFactory) {
|
||||
this.messageBridge = messageBridge;
|
||||
this.importJobFactory = importJobFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(@NotNull CommandSender target) {
|
||||
if(target.hasPermission("areashop.import")) {
|
||||
return "help-import";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
|
||||
withConfirmation();
|
||||
var sourceParser = AcceptedValuesParser.ofConstant(List.of("RegionForSale"), "import-wrongSource", true);
|
||||
return builder.literal("import")
|
||||
.required(KEY_SOURCE, ParserDescriptor.of(sourceParser, String.class))
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull CommandProperties properties() {
|
||||
return CommandProperties.of("import");
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// - Landlord?
|
||||
// - Friends
|
||||
// - Region flags?
|
||||
// - Settings from the 'permissions' section in RegionForSale/config.yml?
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
|
||||
CommandSender sender = context.sender().sender();
|
||||
if (!sender.hasPermission("areashop.import")) {
|
||||
this.messageBridge.message(sender, "import-noPermission");
|
||||
return;
|
||||
}
|
||||
String importSource = context.get(KEY_SOURCE);
|
||||
if (!"RegionForSale".equalsIgnoreCase(importSource)) {
|
||||
throw new AreaShopCommandException("import-wrongSource");
|
||||
}
|
||||
importJobFactory.createImportJob(sender).execute();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
@Singleton
|
||||
public class InfoBaseCommand extends AreashopCommandBean {
|
||||
|
||||
private final MessageBridge messageBridge;
|
||||
|
||||
@Inject
|
||||
public InfoBaseCommand(
|
||||
@Nonnull MessageBridge messageBridge
|
||||
) {
|
||||
this.messageBridge = messageBridge;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(@NotNull CommandSender target) {
|
||||
if (target.hasPermission("areashop.info")) {
|
||||
return "help-info";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("info").handler(this::handleCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull CommandProperties properties() {
|
||||
return CommandProperties.of("info");
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
|
||||
CommandSender sender = context.sender().sender();
|
||||
if (!sender.hasPermission("areashop.info")) {
|
||||
messageBridge.message(sender, "info-noPermission");
|
||||
return;
|
||||
}
|
||||
this.messageBridge.message(sender, "info-help");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,296 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.RegionGroupParser;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RegionGroup;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import me.wiefferink.areashop.tools.SimpleMessageBridge;
|
||||
import me.wiefferink.interactivemessenger.processing.Message;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.incendo.cloud.parser.ParserDescriptor;
|
||||
import org.incendo.cloud.parser.flag.CommandFlag;
|
||||
import org.incendo.cloud.parser.standard.EnumParser;
|
||||
import org.incendo.cloud.parser.standard.IntegerParser;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Singleton
|
||||
public class InfoCommand extends AreashopCommandBean {
|
||||
|
||||
private static final CommandFlag<Integer> FLAG_PAGE = CommandFlag.builder("page")
|
||||
.withComponent(IntegerParser.integerParser(1))
|
||||
.build();
|
||||
private static final CloudKey<RegionStateFilterType> KEY_TYPE = CloudKey.of("type", RegionStateFilterType.class);
|
||||
|
||||
private final MessageBridge messageBridge;
|
||||
private final IFileManager fileManager;
|
||||
|
||||
private final CommandFlag<RegionGroup> filterGroupFlag;
|
||||
|
||||
@Inject
|
||||
public InfoCommand(
|
||||
@Nonnull MessageBridge messageBridge,
|
||||
@Nonnull IFileManager fileManager
|
||||
) {
|
||||
this.messageBridge = messageBridge;
|
||||
this.fileManager = fileManager;
|
||||
this.filterGroupFlag = CommandFlag.builder("group")
|
||||
.withComponent(ParserDescriptor.of(new RegionGroupParser<>(fileManager, "info-noFiltergroup"),
|
||||
RegionGroup.class))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(@NotNull CommandSender target) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("info")
|
||||
.required(KEY_TYPE, EnumParser.enumParser(RegionStateFilterType.class))
|
||||
.flag(FLAG_PAGE)
|
||||
.flag(this.filterGroupFlag)
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull CommandProperties properties() {
|
||||
return CommandProperties.of("info");
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
|
||||
CommandSender sender = context.sender().sender();
|
||||
if (!sender.hasPermission("areashop.info")) {
|
||||
messageBridge.message(sender, "info-noPermission");
|
||||
return;
|
||||
}
|
||||
RegionStateFilterType filterType = context.get(KEY_TYPE);
|
||||
processOtherFilters(context, filterType);
|
||||
}
|
||||
|
||||
private void processOtherFilters(@Nonnull CommandContext<CommandSource<?>> context,
|
||||
@Nonnull RegionStateFilterType filterType) {
|
||||
RegionGroup filterGroup = context.flags().get(this.filterGroupFlag);
|
||||
int page = context.flags().getValue(FLAG_PAGE).orElse(1);
|
||||
Stream<? extends GeneralRegion> toShow = switch (filterType) {
|
||||
case ALL -> fileManager.getRegionsRef().stream();
|
||||
case SOLD -> fileManager.getBuysRef().stream().filter(BuyRegion::isSold);
|
||||
case RENTED -> fileManager.getRentsRef().stream().filter(RentRegion::isRented);
|
||||
case FORRENT -> fileManager.getRentsRef().stream().filter(RentRegion::isAvailable);
|
||||
case FORSALE -> fileManager.getBuysRef().stream().filter(BuyRegion::isAvailable);
|
||||
case RESELLING -> fileManager.getBuysRef().stream().filter(BuyRegion::isInResellingMode);
|
||||
case NOGROUP -> {
|
||||
List<GeneralRegion> regions = new LinkedList<>(fileManager.getRegions());
|
||||
for (RegionGroup group : fileManager.getGroups()) {
|
||||
regions.removeAll(group.getMemberRegions());
|
||||
}
|
||||
yield regions.stream();
|
||||
}
|
||||
};
|
||||
String header = switch (filterType) {
|
||||
case ALL -> "info-allHeader";
|
||||
case SOLD -> "info-soldHeader";
|
||||
case RENTED -> "info-rentedHeader";
|
||||
case FORRENT -> "info-forrentHeader";
|
||||
case FORSALE -> "info-forsaleHeader";
|
||||
case RESELLING -> "info-resellingHeader";
|
||||
case NOGROUP -> "info-nogroupHeader";
|
||||
};
|
||||
String baseCommand = switch (filterType) {
|
||||
case ALL -> "info all";
|
||||
case SOLD -> "info sold";
|
||||
case RENTED -> "info rented";
|
||||
case FORRENT -> "info forrent";
|
||||
case FORSALE -> "info forsale";
|
||||
case RESELLING -> "info reselling";
|
||||
case NOGROUP -> "info nogroup";
|
||||
};
|
||||
showSortedPagedList(context.sender().sender(), toShow, filterGroup, header, page, baseCommand);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Display a page of a list of regions.
|
||||
*
|
||||
* @param sender The CommandSender to send the messages to
|
||||
* @param regionStream The regions to display
|
||||
* @param filterGroup The group to filter the regions by
|
||||
* @param keyHeader The header to print above the page
|
||||
* @param pageInput The page number, if any
|
||||
* @param baseCommand The command to execute for next/previous page (/areashop will be added)
|
||||
*/
|
||||
private void showSortedPagedList(
|
||||
CommandSender sender,
|
||||
Stream<? extends GeneralRegion> regionStream,
|
||||
RegionGroup filterGroup,
|
||||
String keyHeader,
|
||||
int pageInput,
|
||||
String baseCommand
|
||||
) {
|
||||
int page = pageInput;
|
||||
int maximumItems = 20;
|
||||
int itemsPerPage = maximumItems - 2;
|
||||
List<? extends GeneralRegion> regions;
|
||||
if (filterGroup != null) {
|
||||
regions = regionStream.filter(generalRegion -> !filterGroup.isMember(generalRegion)).toList();
|
||||
} else {
|
||||
regions = regionStream.toList();
|
||||
}
|
||||
if (regions.isEmpty()) {
|
||||
messageBridge.message(sender, "info-noRegions");
|
||||
return;
|
||||
}
|
||||
// First sort by type, then by name
|
||||
regions = regions.stream().sorted((one, two) -> {
|
||||
int typeCompare = getTypeOrder(two).compareTo(getTypeOrder(one));
|
||||
if (typeCompare != 0) {
|
||||
return typeCompare;
|
||||
} else {
|
||||
return one.getName().compareTo(two.getName());
|
||||
}
|
||||
}).toList();
|
||||
// Header
|
||||
Message limitedToGroup = Message.empty();
|
||||
if (filterGroup != null) {
|
||||
limitedToGroup = Message.fromKey("info-limitedToGroup").replacements(filterGroup.getName());
|
||||
}
|
||||
messageBridge.message(sender, keyHeader, limitedToGroup);
|
||||
// Page entries
|
||||
int totalPages = (int) Math.ceil(regions.size() / (double) itemsPerPage); // Clip page to correct boundaries, not much need to tell the user
|
||||
if (regions.size() == itemsPerPage + 1) { // 19 total items is mapped to 1 page of 19
|
||||
itemsPerPage++;
|
||||
totalPages = 1;
|
||||
}
|
||||
page = Math.max(1, Math.min(totalPages, page));
|
||||
int linesPrinted = 1; // header
|
||||
for (int i = (page - 1) * itemsPerPage; i < page * itemsPerPage && i < regions.size(); i++) {
|
||||
String state;
|
||||
GeneralRegion region = regions.get(i);
|
||||
if (region.getType() == GeneralRegion.RegionType.RENT) {
|
||||
if (region.getOwner() == null) {
|
||||
state = "Forrent";
|
||||
} else {
|
||||
state = "Rented";
|
||||
}
|
||||
} else {
|
||||
if (region.getOwner() == null) {
|
||||
state = "Forsale";
|
||||
} else if (!((BuyRegion) region).isInResellingMode()) {
|
||||
state = "Sold";
|
||||
} else {
|
||||
state = "Reselling";
|
||||
}
|
||||
}
|
||||
messageBridge.messageNoPrefix(sender, "info-entry" + state, region);
|
||||
linesPrinted++;
|
||||
}
|
||||
Message footer = Message.empty();
|
||||
// Previous button
|
||||
if (page > 1) {
|
||||
footer.append(Message.fromKey("info-pagePrevious").replacements(baseCommand + " --page " + (page - 1)));
|
||||
} else {
|
||||
footer.append(Message.fromKey("info-pageNoPrevious"));
|
||||
}
|
||||
// Page status
|
||||
if (totalPages > 1) {
|
||||
StringBuilder pageString = new StringBuilder("" + page);
|
||||
for (int i = pageString.length(); i < (totalPages + "").length(); i++) {
|
||||
pageString.insert(0, "0");
|
||||
}
|
||||
footer.append(Message.fromKey("info-pageStatus").replacements(page, totalPages));
|
||||
if (page < totalPages) {
|
||||
footer.append(Message.fromKey("info-pageNext").replacements(baseCommand + " --page " + (page + 1)));
|
||||
} else {
|
||||
footer.append(Message.fromKey("info-pageNoNext"));
|
||||
}
|
||||
// Fill up space if the page is not full (aligns header nicely)
|
||||
for (int i = linesPrinted; i < maximumItems - 1; i++) {
|
||||
sender.sendMessage(" ");
|
||||
}
|
||||
SimpleMessageBridge.send(footer, sender);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an integer to order by type, usable for Comparators.
|
||||
*
|
||||
* @param region The region to get the order for
|
||||
* @return An integer for sorting by type
|
||||
*/
|
||||
private Integer getTypeOrder(GeneralRegion region) {
|
||||
if (region.getType() == GeneralRegion.RegionType.RENT) {
|
||||
if (region.getOwner() == null) {
|
||||
return 1;
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
} else {
|
||||
if (region.getOwner() == null) {
|
||||
return 3;
|
||||
} else if (!((BuyRegion) region).isInResellingMode()) {
|
||||
return 4;
|
||||
} else {
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private enum RegionStateFilterType {
|
||||
ALL,
|
||||
RENTED,
|
||||
FORRENT,
|
||||
SOLD,
|
||||
FORSALE,
|
||||
RESELLING,
|
||||
NOGROUP
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.RegionInfoUtil;
|
||||
import me.wiefferink.areashop.commands.util.ValidatedOfflinePlayerParser;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
@Singleton
|
||||
public class InfoPlayerCommand extends AreashopCommandBean {
|
||||
|
||||
private static final CloudKey<OfflinePlayer> KEY_PLAYER = CloudKey.of("player", OfflinePlayer.class);
|
||||
|
||||
private final MessageBridge messageBridge;
|
||||
private final IFileManager fileManager;
|
||||
|
||||
@Inject
|
||||
public InfoPlayerCommand(
|
||||
@Nonnull MessageBridge messageBridge,
|
||||
@Nonnull IFileManager fileManager
|
||||
) {
|
||||
this.messageBridge = messageBridge;
|
||||
this.fileManager = fileManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(CommandSender target) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("info").literal("player")
|
||||
.required(KEY_PLAYER, ValidatedOfflinePlayerParser.validatedOfflinePlayerParser())
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull CommandProperties properties() {
|
||||
return CommandProperties.of("info region");
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
|
||||
CommandSender sender = context.sender().sender();
|
||||
if (!sender.hasPermission("areashop.info")) {
|
||||
messageBridge.message(sender, "info-noPermission");
|
||||
return;
|
||||
}
|
||||
OfflinePlayer offlinePlayer = context.get(KEY_PLAYER);
|
||||
RegionInfoUtil.showRegionInfo(this.messageBridge, this.fileManager, sender, offlinePlayer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,273 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import io.github.bakedlibs.dough.blocks.BlockPosition;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.RegionParseUtil;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import me.wiefferink.areashop.tools.SimpleMessageBridge;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import me.wiefferink.interactivemessenger.processing.Message;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.parser.flag.CommandFlag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Singleton
|
||||
public class InfoRegionCommand extends AreashopCommandBean {
|
||||
|
||||
private final CommandFlag<GeneralRegion> regionFlag;
|
||||
|
||||
private final MessageBridge messageBridge;
|
||||
|
||||
@Inject
|
||||
public InfoRegionCommand(
|
||||
@Nonnull MessageBridge messageBridge,
|
||||
@Nonnull IFileManager fileManager
|
||||
) {
|
||||
this.messageBridge = messageBridge;
|
||||
this.regionFlag = RegionParseUtil.createDefault(fileManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(@NotNull CommandSender target) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("info").literal("region")
|
||||
.flag(this.regionFlag)
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull CommandProperties properties() {
|
||||
return CommandProperties.of("info region");
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
|
||||
CommandSender sender = context.sender().sender();
|
||||
if (!sender.hasPermission("areashop.info")) {
|
||||
messageBridge.message(sender, "info-noPermission");
|
||||
return;
|
||||
}
|
||||
// Region info
|
||||
GeneralRegion region = RegionParseUtil.getOrParseRegion(context, sender, this.regionFlag);
|
||||
if (region instanceof RentRegion rent) {
|
||||
handleRent(sender, rent);
|
||||
} else if (region instanceof BuyRegion buy) {
|
||||
handleBuy(sender, buy);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleBuy(@Nonnull CommandSender sender, @Nonnull BuyRegion buy) {
|
||||
messageBridge.message(sender, "info-regionHeaderBuy", buy);
|
||||
if (buy.isSold()) {
|
||||
if (buy.isInResellingMode()) {
|
||||
messageBridge.messageNoPrefix(sender, "info-regionReselling", buy);
|
||||
messageBridge.messageNoPrefix(sender, "info-regionReselPrice", buy);
|
||||
} else {
|
||||
messageBridge.messageNoPrefix(sender, "info-regionBought", buy);
|
||||
}
|
||||
// Money back
|
||||
if (!buy.getBooleanSetting("buy.sellDisabled")) {
|
||||
if (SellCommand.canUse(sender, buy)) {
|
||||
messageBridge.messageNoPrefix(sender, "info-regionMoneyBackBuyClick", buy);
|
||||
} else {
|
||||
messageBridge.messageNoPrefix(sender, "info-regionMoneyBackBuy", buy);
|
||||
}
|
||||
}
|
||||
// Friends
|
||||
if (!buy.getFriendsFeature().getFriendNames().isEmpty()) {
|
||||
String messagePart = "info-friend";
|
||||
if (DelFriendCommand.canUse(sender, buy)) {
|
||||
messagePart = "info-friendRemove";
|
||||
}
|
||||
messageBridge.messageNoPrefix(sender,
|
||||
"info-regionFriends",
|
||||
buy,
|
||||
Utils.combinedMessage(buy.getFriendsFeature().getFriendNames(), messagePart));
|
||||
}
|
||||
} else {
|
||||
messageBridge.messageNoPrefix(sender, "info-regionCanBeBought", buy);
|
||||
}
|
||||
if (buy.getLandlord() != null) {
|
||||
messageBridge.messageNoPrefix(sender, "info-regionLandlord", buy);
|
||||
}
|
||||
if (buy.getInactiveTimeUntilSell() != -1) {
|
||||
messageBridge.messageNoPrefix(sender, "info-regionInactiveSell", buy);
|
||||
}
|
||||
// Restoring
|
||||
if (buy.isRestoreEnabled()) {
|
||||
messageBridge.messageNoPrefix(sender, "info-regionRestoringBuy", buy);
|
||||
}
|
||||
// Restrictions
|
||||
if (!buy.isSold()) {
|
||||
if (buy.restrictedToRegion()) {
|
||||
messageBridge.messageNoPrefix(sender, "info-regionRestrictedRegionBuy", buy);
|
||||
} else if (buy.restrictedToWorld()) {
|
||||
messageBridge.messageNoPrefix(sender, "info-regionRestrictedWorldBuy", buy);
|
||||
}
|
||||
}
|
||||
messageBridge.messageNoPrefix(sender, "info-regionFooterBuy", buy);
|
||||
}
|
||||
|
||||
private void handleRent(@Nonnull CommandSender sender, @Nonnull RentRegion rent) {
|
||||
messageBridge.message(sender, "info-regionHeaderRent", rent);
|
||||
if (rent.isRented()) {
|
||||
messageBridge.messageNoPrefix(sender, "info-regionRented", rent);
|
||||
messageBridge.messageNoPrefix(sender, "info-regionExtending", rent);
|
||||
// Money back
|
||||
if (UnrentCommand.canUse(sender, rent)) {
|
||||
messageBridge.messageNoPrefix(sender, "info-regionMoneyBackRentClick", rent);
|
||||
} else {
|
||||
messageBridge.messageNoPrefix(sender, "info-regionMoneyBackRent", rent);
|
||||
}
|
||||
// Friends
|
||||
if (!rent.getFriendsFeature().getFriendNames().isEmpty()) {
|
||||
String messagePart = "info-friend";
|
||||
if (DelFriendCommand.canUse(sender, rent)) {
|
||||
messagePart = "info-friendRemove";
|
||||
}
|
||||
messageBridge.messageNoPrefix(sender,
|
||||
"info-regionFriends",
|
||||
rent,
|
||||
Utils.combinedMessage(rent.getFriendsFeature().getFriendNames(), messagePart));
|
||||
}
|
||||
} else {
|
||||
messageBridge.messageNoPrefix(sender, "info-regionCanBeRented", rent);
|
||||
}
|
||||
if (rent.getLandlordName() != null) {
|
||||
messageBridge.messageNoPrefix(sender, "info-regionLandlord", rent);
|
||||
}
|
||||
// Maximum extends
|
||||
if (rent.getMaxExtends() != -1) {
|
||||
if (rent.getMaxExtends() == 0) {
|
||||
messageBridge.messageNoPrefix(sender, "info-regionNoExtending", rent);
|
||||
} else if (rent.isRented()) {
|
||||
messageBridge.messageNoPrefix(sender, "info-regionExtendsLeft", rent);
|
||||
} else {
|
||||
messageBridge.messageNoPrefix(sender, "info-regionMaxExtends", rent);
|
||||
}
|
||||
}
|
||||
// If maxExtends is zero it does not make sense to show this message
|
||||
if (rent.getMaxRentTime() != -1 && rent.getMaxExtends() != 0) {
|
||||
messageBridge.messageNoPrefix(sender, "info-regionMaxRentTime", rent);
|
||||
}
|
||||
if (rent.getInactiveTimeUntilUnrent() != -1) {
|
||||
messageBridge.messageNoPrefix(sender, "info-regionInactiveUnrent", rent);
|
||||
}
|
||||
displayMiscInfo(sender, rent);
|
||||
// Restoring
|
||||
if (rent.isRestoreEnabled()) {
|
||||
messageBridge.messageNoPrefix(sender, "info-regionRestoringRent", rent);
|
||||
}
|
||||
// Restrictions
|
||||
if (!rent.isRented()) {
|
||||
if (rent.restrictedToRegion()) {
|
||||
messageBridge.messageNoPrefix(sender, "info-regionRestrictedRegionRent", rent);
|
||||
} else if (rent.restrictedToWorld()) {
|
||||
messageBridge.messageNoPrefix(sender, "info-regionRestrictedWorldRent", rent);
|
||||
}
|
||||
}
|
||||
messageBridge.messageNoPrefix(sender, "info-regionFooterRent", rent);
|
||||
}
|
||||
|
||||
private void displayMiscInfo(@Nonnull CommandSender sender, @Nonnull GeneralRegion region) {
|
||||
displayTeleportInfo(sender, region);
|
||||
displaySignInfo(sender, region);
|
||||
displayGroupInfo(sender, region);
|
||||
}
|
||||
|
||||
private void displayGroupInfo(@Nonnull CommandSender sender, @Nonnull GeneralRegion region) {// Groups
|
||||
if (sender.hasPermission("areashop.groupinfo") && !region.getGroupNames().isEmpty()) {
|
||||
messageBridge.messageNoPrefix(sender,
|
||||
"info-regionGroups",
|
||||
Utils.createCommaSeparatedList(region.getGroupNames()));
|
||||
}
|
||||
}
|
||||
|
||||
private void displaySignInfo(@Nonnull CommandSender sender, @Nonnull GeneralRegion region) {
|
||||
// Signs
|
||||
List<String> signLocations = new ArrayList<>();
|
||||
for (BlockPosition location : region.getSignsFeature().signManager().allSignLocations()) {
|
||||
signLocations.add(Message.fromKey("info-regionSignLocation")
|
||||
.replacements(location.getWorld().getName(),
|
||||
location.getX(),
|
||||
location.getY(),
|
||||
location.getZ())
|
||||
.getPlain());
|
||||
}
|
||||
if (!signLocations.isEmpty()) {
|
||||
messageBridge.messageNoPrefix(sender,
|
||||
"info-regionSigns",
|
||||
Utils.createCommaSeparatedList(signLocations));
|
||||
}
|
||||
}
|
||||
|
||||
private void displayTeleportInfo(@Nonnull CommandSender sender, @Nonnull GeneralRegion region) {
|
||||
// Teleport
|
||||
Message tp = Message.fromKey("info-prefix");
|
||||
boolean foundSomething = false;
|
||||
if (TeleportCommand.canUse(sender, region)) {
|
||||
foundSomething = true;
|
||||
tp.append(Message.fromKey("info-regionTeleport").replacements(region));
|
||||
}
|
||||
if (SetTeleportCommand.canUse(sender, region)) {
|
||||
if (foundSomething) {
|
||||
tp.append(", ");
|
||||
}
|
||||
foundSomething = true;
|
||||
tp.append(Message.fromKey("info-setRegionTeleport").replacements(region));
|
||||
}
|
||||
if (foundSomething) {
|
||||
tp.append(".");
|
||||
SimpleMessageBridge.send(tp, sender);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.SignProfileUtil;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
|
||||
import me.wiefferink.areashop.managers.SignLinkerManager;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.parser.flag.CommandFlag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
@Singleton
|
||||
public class LinkSignsCommand extends AreashopCommandBean {
|
||||
|
||||
private final SignLinkerManager signLinkerManager;
|
||||
private final AreaShop plugin;
|
||||
|
||||
private final CommandFlag<String> profileFlag;
|
||||
|
||||
@Inject
|
||||
public LinkSignsCommand(
|
||||
@Nonnull MessageBridge messageBridge,
|
||||
@Nonnull SignLinkerManager signLinkerManager,
|
||||
@Nonnull AreaShop plugin
|
||||
) {
|
||||
this.signLinkerManager = signLinkerManager;
|
||||
this.plugin = plugin;
|
||||
this.profileFlag = SignProfileUtil.createDefault(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("linksign")
|
||||
.senderType(PlayerCommandSource.class)
|
||||
.flag(this.profileFlag)
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull CommandProperties properties() {
|
||||
return CommandProperties.of("linksign");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(CommandSender target) {
|
||||
if (target.hasPermission("areashop.linksigns")) {
|
||||
return "help-linksigns";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<PlayerCommandSource> context) {
|
||||
Player player = context.sender().sender();
|
||||
if (!player.hasPermission("linksigns")) {
|
||||
throw new AreaShopCommandException("linksigns-noPermission");
|
||||
}
|
||||
if (signLinkerManager.isInSignLinkMode(player)) {
|
||||
signLinkerManager.exitSignLinkMode(player);
|
||||
return;
|
||||
}
|
||||
// Get the profile
|
||||
String profile = SignProfileUtil.getOrParseProfile(context, this.plugin);
|
||||
this.signLinkerManager.enterSignLinkMode(player, profile);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.RegionInfoUtil;
|
||||
import me.wiefferink.areashop.commands.util.ValidatedOfflinePlayerParser;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
@Singleton
|
||||
public class MeCommand extends AreashopCommandBean {
|
||||
|
||||
private static final CloudKey<OfflinePlayer> KEY_PLAYER = CloudKey.of("player", OfflinePlayer.class);
|
||||
private final IFileManager fileManager;
|
||||
private final MessageBridge messageBridge;
|
||||
|
||||
@Inject
|
||||
public MeCommand(
|
||||
@Nonnull MessageBridge messageBridge,
|
||||
@Nonnull IFileManager fileManager
|
||||
) {
|
||||
this.messageBridge = messageBridge;
|
||||
this.fileManager = fileManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("me")
|
||||
.senderType(PlayerCommandSource.class)
|
||||
.optional(KEY_PLAYER, ValidatedOfflinePlayerParser.validatedOfflinePlayerParser())
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull CommandProperties properties() {
|
||||
return CommandProperties.of("me");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(@NotNull CommandSender target) {
|
||||
if (target.hasPermission("areashop.me")) {
|
||||
return "help-me";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<PlayerCommandSource> context) {
|
||||
Player sender = context.sender().sender();
|
||||
if (!sender.hasPermission("areashop.me")) {
|
||||
throw new AreaShopCommandException("me-noPermission");
|
||||
}
|
||||
OfflinePlayer player = context.getOrDefault(KEY_PLAYER, sender);
|
||||
RegionInfoUtil.showRegionInfo(this.messageBridge, this.fileManager, sender, player);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.tools.SimpleMessageBridge;
|
||||
import me.wiefferink.interactivemessenger.processing.Message;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.bukkit.parser.PlayerParser;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.incendo.cloud.parser.standard.StringParser;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
@Singleton
|
||||
public class MessageCommand extends AreashopCommandBean {
|
||||
|
||||
private static final CloudKey<Player> KEY_PLAYER = CloudKey.of("player", Player.class);
|
||||
private static final CloudKey<String> KEY_MESSAGE = CloudKey.of("message", String.class);
|
||||
|
||||
public String getHelpKey(@NotNull CommandSender target) {
|
||||
// Internal command, no need to show in the help list
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("message")
|
||||
.required(KEY_PLAYER, PlayerParser.playerParser())
|
||||
.required(KEY_MESSAGE, StringParser.greedyStringParser())
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull CommandProperties properties() {
|
||||
return CommandProperties.of("message");
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
|
||||
CommandSender sender = context.sender().sender();
|
||||
if(!sender.hasPermission("areashop.message")) {
|
||||
throw new AreaShopCommandException("message-noPermission");
|
||||
}
|
||||
Player player = context.get(KEY_PLAYER);
|
||||
String message = context.get(KEY_MESSAGE);
|
||||
Message m = Message.fromString(message);
|
||||
SimpleMessageBridge.send(m, player);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.ArgumentParseExceptionHandler;
|
||||
import me.wiefferink.areashop.commands.util.RegionCreationUtil;
|
||||
import me.wiefferink.areashop.commands.util.ValidatedOfflinePlayerParser;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.RegionFactory;
|
||||
import me.wiefferink.areashop.tools.BukkitSchedulerExecutor;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.exception.CommandExecutionException;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.incendo.cloud.parser.standard.DoubleParser;
|
||||
import org.incendo.cloud.parser.standard.StringParser;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@Singleton
|
||||
public class QuickBuyCommand extends AreashopCommandBean {
|
||||
|
||||
private static final CloudKey<String> KEY_REGION = CloudKey.of("region", String.class);
|
||||
private static final CloudKey<Double> KEY_PRICE = CloudKey.of("price", Double.class);
|
||||
private static final CloudKey<OfflinePlayer> KEY_LANDLORD = CloudKey.of("landlord", OfflinePlayer.class);
|
||||
private final RegionFactory regionFactory;
|
||||
private final IFileManager fileManager;
|
||||
private final MessageBridge messageBridge;
|
||||
private final RegionCreationUtil regionCreationUtil;
|
||||
private final BukkitSchedulerExecutor executor;
|
||||
|
||||
@Inject
|
||||
public QuickBuyCommand(
|
||||
@Nonnull MessageBridge messageBridge,
|
||||
@Nonnull RegionFactory regionFactory,
|
||||
@Nonnull IFileManager fileManager,
|
||||
@Nonnull RegionCreationUtil regionCreationUtil,
|
||||
@Nonnull BukkitSchedulerExecutor executor
|
||||
) {
|
||||
this.messageBridge = messageBridge;
|
||||
this.regionFactory = regionFactory;
|
||||
this.fileManager = fileManager;
|
||||
this.regionCreationUtil = regionCreationUtil;
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
protected Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("quickbuy")
|
||||
.permission("permission")
|
||||
.senderType(PlayerCommandSource.class)
|
||||
.required(KEY_REGION, StringParser.stringParser())
|
||||
.required(KEY_PRICE, DoubleParser.doubleParser(0))
|
||||
.required(KEY_LANDLORD, ValidatedOfflinePlayerParser.validatedOfflinePlayerParser())
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
// /as quickbuy <name> <price> <duration> <landlord>
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<PlayerCommandSource> context) {
|
||||
Player player = context.sender().sender();
|
||||
if (!player.hasPermission("areashop.quickbuy")) {
|
||||
player.sendMessage("Insufficient permission");
|
||||
return;
|
||||
}
|
||||
this.regionCreationUtil.createRegion(context, player, KEY_REGION)
|
||||
.exceptionally(throwable -> {
|
||||
if (throwable instanceof AreaShopCommandException exception) {
|
||||
ArgumentParseExceptionHandler.handleException(this.messageBridge, context.sender(), exception);
|
||||
} else {
|
||||
throw new CommandExecutionException(throwable, context);
|
||||
}
|
||||
return null;
|
||||
}).thenAcceptAsync(region -> {
|
||||
// Error handled previously
|
||||
if (region == null) {
|
||||
this.messageBridge.message(player, "quickadd-failedCreateWGRegion");
|
||||
return;
|
||||
}
|
||||
double price = context.get(KEY_PRICE);
|
||||
|
||||
OfflinePlayer landlord = context.get(KEY_LANDLORD);
|
||||
if (!landlord.isOnline() && !landlord.hasPlayedBefore()) {
|
||||
this.messageBridge.message(player, "me-noPlayer", landlord.getName());
|
||||
return;
|
||||
}
|
||||
String regionName = region.getId();
|
||||
World world = player.getWorld();
|
||||
|
||||
BuyRegion buyRegion = this.regionFactory.createBuyRegion(regionName, world);
|
||||
buyRegion.setPrice(price);
|
||||
buyRegion.setLandlord(landlord.getUniqueId(), landlord.getName());
|
||||
this.fileManager.addRegion(buyRegion);
|
||||
this.messageBridge.message(player, "add-success", "buy", regionName);
|
||||
}, this.executor);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getHelpKey(@Nonnull CommandSender target) {
|
||||
if (target.hasPermission("areashop.quickbuy")) {
|
||||
return "help-quickbuy";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull CommandProperties properties() {
|
||||
return CommandProperties.of("quickbuy");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.GeneralRegionParser;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
|
||||
import me.wiefferink.areashop.events.ask.DeletingRegionEvent;
|
||||
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.description.Description;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.incendo.cloud.parser.flag.CommandFlag;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@Singleton
|
||||
public class QuickDeleteCommand extends AreashopCommandBean {
|
||||
|
||||
private static final CloudKey<GeneralRegion> KEY_REGION = CloudKey.of("region", GeneralRegion.class);
|
||||
|
||||
private static final CommandFlag<Void> FLAG_RETURN_MONEY = CommandFlag.builder("return-money")
|
||||
.withDescription(Description.of(
|
||||
"If this flag is present, money is returned to the player if someone is currently holding this region"))
|
||||
.build();
|
||||
|
||||
private final IFileManager fileManager;
|
||||
private final WorldGuardInterface worldGuardInterface;
|
||||
private final MessageBridge messageBridge;
|
||||
|
||||
@Inject
|
||||
public QuickDeleteCommand(
|
||||
@Nonnull MessageBridge messageBridge,
|
||||
@Nonnull IFileManager fileManager,
|
||||
@Nonnull WorldGuardInterface worldGuardInterface
|
||||
) {
|
||||
this.fileManager = fileManager;
|
||||
this.worldGuardInterface = worldGuardInterface;
|
||||
this.messageBridge = messageBridge;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
protected Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("quickdelete", "quickdel")
|
||||
.permission("areashop.quickdelete")
|
||||
.senderType(PlayerCommandSource.class)
|
||||
.required(KEY_REGION, GeneralRegionParser.generalRegionParser(this.fileManager))
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<PlayerCommandSource> context) {
|
||||
Player player = context.sender().sender();
|
||||
GeneralRegion region = context.get(KEY_REGION);
|
||||
boolean giveMoneyBack = context.flags().isPresent(FLAG_RETURN_MONEY);
|
||||
DeletingRegionEvent event = this.fileManager.deleteRegion(region, giveMoneyBack);
|
||||
if (event.isCancelled()) {
|
||||
throw new AreaShopCommandException("general-cancelled", event.getReason());
|
||||
}
|
||||
this.messageBridge.message(player, "destroy-successRent", region);
|
||||
RegionManager regionManager = this.worldGuardInterface.getRegionManager(region.getWorld());
|
||||
regionManager.removeRegion(region.getRegion().getId());
|
||||
this.messageBridge.message(player, "quickdelete-WGRegionDeleted", region.getName());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getHelpKey(@Nonnull CommandSender target) {
|
||||
return "help-quickdelete";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull CommandProperties properties() {
|
||||
return CommandProperties.of("quickdelete", "quickdel");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.ArgumentParseExceptionHandler;
|
||||
import me.wiefferink.areashop.commands.util.DurationInputParser;
|
||||
import me.wiefferink.areashop.commands.util.RegionCreationUtil;
|
||||
import me.wiefferink.areashop.commands.util.ValidatedOfflinePlayerParser;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.RegionFactory;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import me.wiefferink.areashop.tools.BukkitSchedulerExecutor;
|
||||
import me.wiefferink.areashop.tools.DurationInput;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.exception.CommandExecutionException;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.incendo.cloud.parser.standard.DoubleParser;
|
||||
import org.incendo.cloud.parser.standard.StringParser;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@Singleton
|
||||
public class QuickRentCommand extends AreashopCommandBean {
|
||||
|
||||
private static final CloudKey<String> KEY_REGION = CloudKey.of("region", String.class);
|
||||
private static final CloudKey<Double> KEY_PRICE = CloudKey.of("price", Double.class);
|
||||
|
||||
private static final CloudKey<DurationInput> KEY_DURATION = CloudKey.of("duration", DurationInput.class);
|
||||
private static final CloudKey<OfflinePlayer> KEY_LANDLORD = CloudKey.of("landlord", OfflinePlayer.class);
|
||||
private final RegionFactory regionFactory;
|
||||
private final IFileManager fileManager;
|
||||
private final MessageBridge messageBridge;
|
||||
private final RegionCreationUtil regionCreationUtil;
|
||||
private final BukkitSchedulerExecutor executor;
|
||||
|
||||
@Inject
|
||||
public QuickRentCommand(
|
||||
@Nonnull MessageBridge messageBridge,
|
||||
@Nonnull RegionFactory regionFactory,
|
||||
@Nonnull IFileManager fileManager,
|
||||
@Nonnull RegionCreationUtil regionCreationUtil,
|
||||
@Nonnull BukkitSchedulerExecutor executor
|
||||
) {
|
||||
this.messageBridge = messageBridge;
|
||||
this.regionFactory = regionFactory;
|
||||
this.fileManager = fileManager;
|
||||
this.regionCreationUtil = regionCreationUtil;
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
protected Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("quickrent")
|
||||
.permission("permission")
|
||||
.senderType(PlayerCommandSource.class)
|
||||
.required(KEY_REGION, StringParser.stringParser())
|
||||
.required(KEY_PRICE, DoubleParser.doubleParser(0))
|
||||
.required(KEY_DURATION, DurationInputParser.durationInputParser())
|
||||
.required(KEY_LANDLORD, ValidatedOfflinePlayerParser.validatedOfflinePlayerParser())
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
// /as quickrent <name> <price> <duration> <landlord>
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<PlayerCommandSource> context) {
|
||||
Player player = context.sender().sender();
|
||||
if (!player.hasPermission("areashop.quickrent")) {
|
||||
player.sendMessage("Insufficient permission");
|
||||
return;
|
||||
}
|
||||
this.regionCreationUtil.createRegion(context, player, KEY_REGION)
|
||||
.exceptionally(throwable -> {
|
||||
if (throwable instanceof AreaShopCommandException exception) {
|
||||
ArgumentParseExceptionHandler.handleException(this.messageBridge, context.sender(), exception);
|
||||
} else {
|
||||
throw new CommandExecutionException(throwable, context);
|
||||
}
|
||||
return null;
|
||||
}).thenAcceptAsync(region -> {
|
||||
// Error handled previously
|
||||
if (region == null) {
|
||||
this.messageBridge.message(player, "quickadd-failedCreateWGRegion");
|
||||
return;
|
||||
}
|
||||
double price = context.get(KEY_PRICE);
|
||||
DurationInput duration = context.get(KEY_DURATION);
|
||||
|
||||
OfflinePlayer landlord = context.get(KEY_LANDLORD);
|
||||
if (!landlord.isOnline() && !landlord.hasPlayedBefore()) {
|
||||
this.messageBridge.message(player, "me-noPlayer");
|
||||
return;
|
||||
}
|
||||
String regionName = region.getId();
|
||||
World world = player.getWorld();
|
||||
|
||||
RentRegion rentRegion = this.regionFactory.createRentRegion(regionName, world);
|
||||
rentRegion.setPrice(price);
|
||||
rentRegion.setLandlord(landlord.getUniqueId(), landlord.getName());
|
||||
rentRegion.setDuration(duration.toTinySpacedString());
|
||||
this.fileManager.addRegion(rentRegion);
|
||||
this.messageBridge.message(player, "add-success", "rent", regionName);
|
||||
}, this.executor);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getHelpKey(@Nonnull CommandSender target) {
|
||||
if (target.hasPermission("areashop.quickrent")) {
|
||||
return "help-quickrent";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull CommandProperties properties() {
|
||||
return CommandProperties.of("quickrent");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
# Commands
|
||||
|
||||
This module contains all AreaShop commands.
|
||||
AreaShop uses https://cloud.incendo.org/
|
||||
|
||||
* `util/AreashopCommandBean` is extended by all other classes, and implements some general functionality and defines which methods should be implemented.
|
||||
* Other classes implement specific sub-commands, supply their help messages and tab completion.
|
||||
* `util/AreashopCommands` class in handles all command registration
|
||||
@@ -0,0 +1,59 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
@Singleton
|
||||
public class ReloadCommand extends AreashopCommandBean {
|
||||
private final AreaShop plugin;
|
||||
|
||||
@Inject
|
||||
public ReloadCommand(@Nonnull AreaShop plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
protected Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("reload")
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull CommandProperties properties() {
|
||||
return CommandProperties.of("reload");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getHelpKey(CommandSender target) {
|
||||
if (target.hasPermission("areashop.reload")) {
|
||||
return "help-reload";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
|
||||
if (!context.hasPermission("areashop.reload")) {
|
||||
throw new AreaShopCommandException("reload-noPermission");
|
||||
}
|
||||
this.plugin.reload(context.sender().sender());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.RegionParseUtil;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.parser.flag.CommandFlag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
@Singleton
|
||||
public class RentCommand extends AreashopCommandBean {
|
||||
|
||||
private final CommandFlag<RentRegion> rentRegionFlag;
|
||||
|
||||
@Inject
|
||||
public RentCommand(@Nonnull IFileManager fileManager) {
|
||||
this.rentRegionFlag = RegionParseUtil.createDefaultRent(fileManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return "Allows you to rent a region";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(@NotNull CommandSender target) {
|
||||
if(target.hasPermission("areashop.rent")) {
|
||||
return "help-rent";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nonnull CommandProperties properties() {
|
||||
return CommandProperties.of("rent");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
|
||||
return builder
|
||||
.literal("rent")
|
||||
.flag(this.rentRegionFlag)
|
||||
.senderType(PlayerCommandSource.class)
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<PlayerCommandSource> context) {
|
||||
if (!context.hasPermission("areashop.rent")) {
|
||||
throw new AreaShopCommandException("rent-noPermission");
|
||||
}
|
||||
Player sender = context.sender().sender();
|
||||
RentRegion region = RegionParseUtil.getOrParseRentRegion(context, sender, this.rentRegionFlag);
|
||||
region.rent(sender);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.BuyRegionParser;
|
||||
import me.wiefferink.areashop.commands.util.RegionParseUtil;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.context.CommandInput;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.incendo.cloud.parser.ParserDescriptor;
|
||||
import org.incendo.cloud.parser.flag.CommandFlag;
|
||||
import org.incendo.cloud.parser.standard.DoubleParser;
|
||||
import org.incendo.cloud.suggestion.Suggestion;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Singleton
|
||||
public class ResellCommand extends AreashopCommandBean {
|
||||
|
||||
private static final CloudKey<Double> KEY_PRICE = CloudKey.of("price", Double.class);
|
||||
private final CommandFlag<BuyRegion> regionFlag;
|
||||
private final MessageBridge messageBridge;
|
||||
private final IFileManager fileManager;
|
||||
|
||||
@Inject
|
||||
public ResellCommand(@Nonnull MessageBridge messageBridge, @Nonnull IFileManager fileManager) {
|
||||
this.messageBridge = messageBridge;
|
||||
this.fileManager = fileManager;
|
||||
ParserDescriptor<CommandSource<?>, BuyRegion> regionParser = ParserDescriptor.of(
|
||||
new BuyRegionParser<>(fileManager, this::suggestBuyRegions),
|
||||
BuyRegion.class
|
||||
);
|
||||
this.regionFlag = CommandFlag.<CommandSource<?>>builder("region").withComponent(regionParser).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
protected Command.Builder<? extends CommandSource<?>> configureCommand(@Nonnull Command.Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("resell")
|
||||
.required(KEY_PRICE, DoubleParser.doubleParser(0))
|
||||
.flag(this.regionFlag)
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull CommandProperties properties() {
|
||||
return CommandProperties.of("resell");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getHelpKey(@NotNull CommandSender target) {
|
||||
if (target.hasPermission("areashop.resellall") || target.hasPermission("areashop.resell")) {
|
||||
return "help-resell";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
|
||||
CommandSender sender = context.sender().sender();
|
||||
if (!sender.hasPermission("areashop.resell") && !sender.hasPermission("areashop.resellall")) {
|
||||
messageBridge.message(sender, "resell-noPermissionOther");
|
||||
return;
|
||||
}
|
||||
double price = context.get(KEY_PRICE);
|
||||
BuyRegion buy = RegionParseUtil.getOrParseBuyRegion(context, sender, this.regionFlag);
|
||||
if (!buy.isSold()) {
|
||||
messageBridge.message(sender, "resell-notBought", buy);
|
||||
return;
|
||||
}
|
||||
if (sender.hasPermission("areashop.resellall")) {
|
||||
buy.enableReselling(price);
|
||||
buy.update();
|
||||
messageBridge.message(sender, "resell-success", buy);
|
||||
} else if (sender.hasPermission("areashop.resell") && sender instanceof Player player) {
|
||||
if (!buy.isOwner(player)) {
|
||||
messageBridge.message(sender, "resell-noPermissionOther", buy);
|
||||
return;
|
||||
}
|
||||
|
||||
if (buy.getBooleanSetting("buy.resellDisabled")) {
|
||||
messageBridge.message(sender, "resell-disabled", buy);
|
||||
return;
|
||||
}
|
||||
|
||||
buy.enableReselling(price);
|
||||
buy.update();
|
||||
messageBridge.message(sender, "resell-success", buy);
|
||||
} else {
|
||||
messageBridge.message(sender, "resell-noPermission", buy);
|
||||
}
|
||||
}
|
||||
|
||||
private CompletableFuture<Iterable<Suggestion>> suggestBuyRegions(
|
||||
@Nonnull CommandContext<CommandSource<?>> context,
|
||||
@Nonnull CommandInput input
|
||||
) {
|
||||
String text = input.peekString();
|
||||
List<Suggestion> suggestions = this.fileManager.getBuysRef().stream()
|
||||
.filter(region -> region.isSold() && !region.isInResellingMode())
|
||||
.map(GeneralRegion::getName)
|
||||
.filter(name -> name.startsWith(text))
|
||||
.map(Suggestion::suggestion)
|
||||
.toList();
|
||||
return CompletableFuture.completedFuture(suggestions);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.GeneralRegionParser;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.incendo.cloud.parser.standard.EnumParser;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
@Singleton
|
||||
public class SchematicEventCommand extends AreashopCommandBean {
|
||||
|
||||
private static final CloudKey<GeneralRegion> KEY_REGION = CloudKey.of("region", GeneralRegion.class);
|
||||
private static final CloudKey<GeneralRegion.RegionEvent> KEY_EVENT_TYPE = CloudKey.of("eventType",
|
||||
GeneralRegion.RegionEvent.class);
|
||||
private final MessageBridge messageBridge;
|
||||
private final IFileManager fileManager;
|
||||
|
||||
@Inject
|
||||
public SchematicEventCommand(@Nonnull MessageBridge messageBridge, @Nonnull IFileManager fileManager) {
|
||||
this.messageBridge = messageBridge;
|
||||
this.fileManager = fileManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("schemevent")
|
||||
.required(KEY_REGION, GeneralRegionParser.generalRegionParser(this.fileManager))
|
||||
.required(KEY_EVENT_TYPE, EnumParser.enumParser(GeneralRegion.RegionEvent.class))
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull CommandProperties properties() {
|
||||
return CommandProperties.of("schemevent");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(@NotNull CommandSender target) {
|
||||
if (target.hasPermission("areashop.schematicevents")) {
|
||||
return "help-schemevent";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
|
||||
CommandSender sender = context.sender().sender();
|
||||
if (!sender.hasPermission("areashop.schematicevents")) {
|
||||
throw new AreaShopCommandException("schemevent-noPermission");
|
||||
}
|
||||
|
||||
GeneralRegion region = context.get(KEY_REGION);
|
||||
GeneralRegion.RegionEvent event = context.get(KEY_EVENT_TYPE);
|
||||
if (region.getRegion() == null) {
|
||||
throw new AreaShopCommandException("general-noRegion", region);
|
||||
}
|
||||
region.handleSchematicEvent(event);
|
||||
region.update();
|
||||
this.messageBridge.message(sender, "schemevent-success", event.getValue(), region);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.BuyRegionParser;
|
||||
import me.wiefferink.areashop.commands.util.RegionParseUtil;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.context.CommandInput;
|
||||
import org.incendo.cloud.parser.ParserDescriptor;
|
||||
import org.incendo.cloud.parser.flag.CommandFlag;
|
||||
import org.incendo.cloud.suggestion.Suggestion;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Singleton
|
||||
public class SellCommand extends AreashopCommandBean {
|
||||
|
||||
private final MessageBridge messageBridge;
|
||||
private final IFileManager fileManager;
|
||||
private final CommandFlag<BuyRegion> buyRegionFlag;
|
||||
|
||||
@Inject
|
||||
public SellCommand(@Nonnull MessageBridge messageBridge, @Nonnull IFileManager fileManager) {
|
||||
ParserDescriptor<CommandSource<?>, BuyRegion> regionParser =
|
||||
ParserDescriptor.of(new BuyRegionParser<>(fileManager, this::suggestBuyRegions), BuyRegion.class);
|
||||
this.messageBridge = messageBridge;
|
||||
this.fileManager = fileManager;
|
||||
this.buyRegionFlag = CommandFlag.<CommandSource<?>>builder("region").withComponent(regionParser).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a person can sell the region.
|
||||
*
|
||||
* @param person The person to check
|
||||
* @param region The region to check for
|
||||
* @return true if the person can sell it, otherwise false
|
||||
*/
|
||||
public static boolean canUse(CommandSender person, GeneralRegion region) {
|
||||
if (person.hasPermission("areashop.sell")) {
|
||||
return true;
|
||||
}
|
||||
if (person instanceof Player player) {
|
||||
return region.isOwner(player) && person.hasPermission("areashop.sellown");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("sell")
|
||||
.flag(this.buyRegionFlag)
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull CommandProperties properties() {
|
||||
return CommandProperties.of("sell");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(CommandSender target) {
|
||||
if (target.hasPermission("areashop.sell") || target.hasPermission("areashop.sellown")) {
|
||||
return "help-sell";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
|
||||
CommandSender sender = context.sender().sender();
|
||||
if (!sender.hasPermission("areashop.sell") && !sender.hasPermission("areashop.sellown")) {
|
||||
this.messageBridge.message(sender, "sell-noPermission");
|
||||
return;
|
||||
}
|
||||
BuyRegion buy = RegionParseUtil.getOrParseBuyRegion(context, sender, this.buyRegionFlag);
|
||||
if (!buy.isSold()) {
|
||||
messageBridge.message(sender, "sell-notBought", buy);
|
||||
return;
|
||||
}
|
||||
buy.sell(true, sender);
|
||||
}
|
||||
|
||||
private CompletableFuture<Iterable<Suggestion>> suggestBuyRegions(
|
||||
@Nonnull CommandContext<CommandSource<?>> context,
|
||||
@Nonnull CommandInput input
|
||||
) {
|
||||
String text = input.peekString();
|
||||
List<Suggestion> suggestions = this.fileManager.getBuysRef().stream()
|
||||
.filter(BuyRegion::isSold)
|
||||
.map(GeneralRegion::getName)
|
||||
.filter(name -> name.startsWith(text))
|
||||
.map(Suggestion::suggestion)
|
||||
.toList();
|
||||
return CompletableFuture.completedFuture(suggestions);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.RegionParseUtil;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import me.wiefferink.areashop.tools.DurationInput;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.incendo.cloud.parser.flag.CommandFlag;
|
||||
import org.incendo.cloud.parser.standard.StringParser;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Singleton
|
||||
public class SetDurationCommand extends AreashopCommandBean {
|
||||
|
||||
private static final CloudKey<String> KEY_DURATION = CloudKey.of("duration", String.class);
|
||||
private final MessageBridge messageBridge;
|
||||
private final CommandFlag<RentRegion> regionFlag;
|
||||
|
||||
@Inject
|
||||
public SetDurationCommand(
|
||||
@Nonnull MessageBridge messageBridge,
|
||||
@Nonnull IFileManager fileManager
|
||||
) {
|
||||
this.messageBridge = messageBridge;
|
||||
this.regionFlag = RegionParseUtil.createDefaultRent(fileManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(@NotNull CommandSender target) {
|
||||
if (target.hasPermission("areashop.setduration")) {
|
||||
return "help-setduration";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("setduration")
|
||||
.required(KEY_DURATION, StringParser.stringParser())
|
||||
.flag(this.regionFlag)
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull CommandProperties properties() {
|
||||
return CommandProperties.of("setduration");
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
|
||||
CommandSender sender = context.sender().sender();
|
||||
if (!sender.hasPermission("areashop.setduration") && (!sender.hasPermission("areashop.setduration.landlord") && sender instanceof Player)) {
|
||||
this.messageBridge.message(sender, "setduration-noPermission");
|
||||
return;
|
||||
}
|
||||
RentRegion rent = RegionParseUtil.getOrParseRentRegion(context, sender, this.regionFlag);
|
||||
if (!sender.hasPermission("areashop.setduration")
|
||||
&& !(sender instanceof Player player
|
||||
&& rent.isLandlord(player.getUniqueId()))
|
||||
) {
|
||||
this.messageBridge.message(sender, "setduration-noLandlord", rent);
|
||||
return;
|
||||
}
|
||||
String rawDuration = context.get(KEY_DURATION);
|
||||
if ("default".equalsIgnoreCase(rawDuration) || "reset".equalsIgnoreCase(rawDuration)) {
|
||||
rent.setDuration(null);
|
||||
rent.update();
|
||||
this.messageBridge.message(sender, "setduration-successRemoved", rent);
|
||||
return;
|
||||
}
|
||||
DurationInput duration = parseInternalDuration(rawDuration);
|
||||
sender.sendMessage(duration.toTinySpacedString());
|
||||
rent.setDuration(duration.toTinySpacedString());
|
||||
rent.update();
|
||||
this.messageBridge.message(sender, "setduration-success", rent);
|
||||
}
|
||||
|
||||
private DurationInput parseInternalDuration(String rawDuration) {
|
||||
int start = 0;
|
||||
for (int i = 0; i < rawDuration.length(); i++) {
|
||||
if (Character.isAlphabetic(rawDuration.charAt(i))) {
|
||||
start = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (start == 0) {
|
||||
throw new AreaShopCommandException("setduration-wrongFormat", rawDuration);
|
||||
}
|
||||
String duration = rawDuration.substring(0, start);
|
||||
String durationUnit = rawDuration.substring(start);
|
||||
int durationInt;
|
||||
try {
|
||||
durationInt = Integer.parseInt(duration);
|
||||
} catch (NumberFormatException ex) {
|
||||
throw new AreaShopCommandException("setduration-wrongAmount", duration);
|
||||
}
|
||||
TimeUnit timeUnit = DurationInput.getTimeUnit(durationUnit)
|
||||
.orElseThrow(() -> new AreaShopCommandException("setduration-wrongFormat", durationUnit));
|
||||
|
||||
boolean invalid = !switch (timeUnit) {
|
||||
case DAYS, HOURS, MINUTES, SECONDS -> true;
|
||||
default -> false;
|
||||
};
|
||||
if (invalid) {
|
||||
throw new AreaShopCommandException("setduration-wrongFormat", durationUnit);
|
||||
}
|
||||
return new DurationInput(durationInt, timeUnit);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.RegionParseUtil;
|
||||
import me.wiefferink.areashop.commands.util.ValidatedOfflinePlayerParser;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.incendo.cloud.parser.flag.CommandFlag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
@Singleton
|
||||
public class SetLandlordCommand extends AreashopCommandBean {
|
||||
|
||||
private static final CloudKey<OfflinePlayer> KEY_PLAYER = CloudKey.of("player", OfflinePlayer.class);
|
||||
|
||||
private final MessageBridge messageBridge;
|
||||
private final CommandFlag<GeneralRegion> regionFlag;
|
||||
|
||||
@Inject
|
||||
public SetLandlordCommand(
|
||||
@Nonnull MessageBridge messageBridge,
|
||||
@Nonnull IFileManager fileManager
|
||||
) {
|
||||
this.messageBridge = messageBridge;
|
||||
this.regionFlag = RegionParseUtil.createDefault(fileManager);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getHelpKey(@NotNull CommandSender target) {
|
||||
if (target.hasPermission("areashop.setlandlord")) {
|
||||
return "help-setlandlord";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("setlandlord")
|
||||
.required(KEY_PLAYER, ValidatedOfflinePlayerParser.validatedOfflinePlayerParser())
|
||||
.flag(this.regionFlag)
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull CommandProperties properties() {
|
||||
return CommandProperties.of("setlandlord");
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
|
||||
CommandSender sender = context.sender().sender();
|
||||
if (!sender.hasPermission("areashop.setlandlord")) {
|
||||
throw new AreaShopCommandException("setlandlord-noPermission");
|
||||
}
|
||||
GeneralRegion region = RegionParseUtil.getOrParseRegion(context, sender, this.regionFlag);
|
||||
OfflinePlayer player = context.get(KEY_PLAYER);
|
||||
String playerName = player.getName();
|
||||
region.setLandlord(player.getUniqueId(), playerName);
|
||||
region.update();
|
||||
this.messageBridge.message(sender, "setlandlord-success", playerName, region);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.RegionParseUtil;
|
||||
import me.wiefferink.areashop.commands.util.ValidatedOfflinePlayerParser;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.incendo.cloud.parser.flag.CommandFlag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Calendar;
|
||||
import java.util.UUID;
|
||||
|
||||
@Singleton
|
||||
public class SetOwnerCommand extends AreashopCommandBean {
|
||||
|
||||
private static final CloudKey<OfflinePlayer> KEY_PLAYER = CloudKey.of("player", OfflinePlayer.class);
|
||||
private final CommandFlag<GeneralRegion> regionFlag;
|
||||
|
||||
private final MessageBridge messageBridge;
|
||||
|
||||
@Inject
|
||||
public SetOwnerCommand(
|
||||
@Nonnull MessageBridge messageBridge,
|
||||
@Nonnull IFileManager fileManager
|
||||
) {
|
||||
this.messageBridge = messageBridge;
|
||||
this.regionFlag = RegionParseUtil.createDefault(fileManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(@NotNull CommandSender target) {
|
||||
if (target.hasPermission("areashop.setownerrent") || target.hasPermission("areashop.setownerbuy")) {
|
||||
return "help-setowner";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("setowner")
|
||||
.required(KEY_PLAYER, ValidatedOfflinePlayerParser.validatedOfflinePlayerParser())
|
||||
.flag(this.regionFlag)
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull CommandProperties properties() {
|
||||
return CommandProperties.of("setowner");
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
|
||||
CommandSender sender = context.sender().sender();
|
||||
if (!sender.hasPermission("areashop.setownerrent") && !sender.hasPermission("areashop.setownerbuy")) {
|
||||
this.messageBridge.message(sender, "setowner-noPermission");
|
||||
return;
|
||||
}
|
||||
GeneralRegion region = RegionParseUtil.getOrParseRegion(context, sender, this.regionFlag);
|
||||
if (region instanceof RentRegion && !sender.hasPermission("areashop.setownerrent")) {
|
||||
this.messageBridge.message(sender, "setowner-noPermissionRent", region);
|
||||
return;
|
||||
}
|
||||
if (region instanceof BuyRegion && !sender.hasPermission("areashop.setownerbuy")) {
|
||||
this.messageBridge.message(sender, "setowner-noPermissionBuy", region);
|
||||
return;
|
||||
}
|
||||
OfflinePlayer player = context.get(KEY_PLAYER);
|
||||
if (!player.hasPlayedBefore()) {
|
||||
this.messageBridge.message(sender, "setowner-noPlayer", player.getName(), region);
|
||||
return;
|
||||
}
|
||||
final UUID uuid = player.getUniqueId();
|
||||
if (region instanceof RentRegion rent) {
|
||||
if (rent.isRenter(uuid)) {
|
||||
// extend
|
||||
rent.setRentedUntil(rent.getRentedUntil() + rent.getDuration());
|
||||
rent.setRenter(uuid);
|
||||
this.messageBridge.message(sender, "setowner-succesRentExtend", region);
|
||||
} else {
|
||||
// change
|
||||
if (!rent.isRented()) {
|
||||
rent.setRentedUntil(Calendar.getInstance().getTimeInMillis() + rent.getDuration());
|
||||
}
|
||||
rent.setRenter(uuid);
|
||||
this.messageBridge.message(sender, "setowner-succesRent", region);
|
||||
}
|
||||
} else if (region instanceof BuyRegion buy) {
|
||||
buy.setBuyer(uuid);
|
||||
this.messageBridge.message(sender, "setowner-succesBuy", region);
|
||||
}
|
||||
region.getFriendsFeature().deleteFriend(region.getOwner(), null);
|
||||
region.update();
|
||||
region.saveRequired();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.RegionParseUtil;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.incendo.cloud.parser.flag.CommandFlag;
|
||||
import org.incendo.cloud.parser.standard.StringParser;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
@Singleton
|
||||
public class SetPriceCommand extends AreashopCommandBean {
|
||||
|
||||
|
||||
private static final CloudKey<String> KEY_PRICE = CloudKey.of("price", String.class);
|
||||
private final CommandFlag<GeneralRegion> regionFlag;
|
||||
private final MessageBridge messageBridge;
|
||||
|
||||
@Inject
|
||||
public SetPriceCommand(@Nonnull MessageBridge messageBridge, @Nonnull IFileManager fileManager) {
|
||||
this.messageBridge = messageBridge;
|
||||
this.regionFlag = RegionParseUtil.createDefault(fileManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(CommandSender target) {
|
||||
if (target.hasPermission("areashop.setprice")) {
|
||||
return "help-setprice";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("setprice")
|
||||
.required(KEY_PRICE, StringParser.stringParser())
|
||||
.flag(this.regionFlag)
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull CommandProperties properties() {
|
||||
return CommandProperties.of("setprice");
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
|
||||
CommandSender sender = context.sender().sender();
|
||||
if (!sender.hasPermission("areashop.setprice") && (!sender.hasPermission("areashop.setprice.landlord") && sender instanceof Player)) {
|
||||
this.messageBridge.message(sender, "setprice-noPermission");
|
||||
return;
|
||||
}
|
||||
GeneralRegion region = RegionParseUtil.getOrParseRegion(context, sender, this.regionFlag);
|
||||
if (!sender.hasPermission("areashop.setprice")
|
||||
&& !(sender instanceof Player player && region.isLandlord(player.getUniqueId()))) {
|
||||
this.messageBridge.message(sender, "setprice-noLandlord", region);
|
||||
return;
|
||||
}
|
||||
String rawPrice = context.get(KEY_PRICE);
|
||||
if ("default".equalsIgnoreCase(rawPrice) || "reset".equalsIgnoreCase(rawPrice)) {
|
||||
if (region instanceof RentRegion rentRegion) {
|
||||
rentRegion.setPrice(null);
|
||||
} else if (region instanceof BuyRegion buyRegion) {
|
||||
buyRegion.setPrice(null);
|
||||
}
|
||||
region.update();
|
||||
this.messageBridge.message(sender, "setprice-successRemoved", region);
|
||||
return;
|
||||
}
|
||||
double price;
|
||||
try {
|
||||
price = Double.parseDouble(rawPrice);
|
||||
} catch (NumberFormatException e) {
|
||||
this.messageBridge.message(sender, "setprice-wrongPrice", rawPrice, region);
|
||||
return;
|
||||
}
|
||||
if (region instanceof RentRegion rentRegion) {
|
||||
rentRegion.setPrice(price);
|
||||
this.messageBridge.message(sender, "setprice-successRent", region);
|
||||
} else if (region instanceof BuyRegion buyRegion) {
|
||||
buyRegion.setPrice(price);
|
||||
this.messageBridge.message(sender, "setprice-successBuy", region);
|
||||
}
|
||||
region.update();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.GeneralRegionParser;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.context.CommandInput;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.incendo.cloud.parser.standard.StringParser;
|
||||
import org.incendo.cloud.suggestion.Suggestion;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Singleton
|
||||
public class SetRestoreCommand extends AreashopCommandBean {
|
||||
|
||||
private static final List<String> RESTORE_TYPES = List.of("true", "false", "general");
|
||||
private static final CloudKey<GeneralRegion> KEY_REGION = CloudKey.of("region", GeneralRegion.class);
|
||||
private static final CloudKey<String> KEY_RESTORE = CloudKey.of("restore", String.class);
|
||||
|
||||
private static final CloudKey<String> KEY_PROFILE = CloudKey.of("profile", String.class);
|
||||
private final MessageBridge messageBridge;
|
||||
private final IFileManager fileManager;
|
||||
|
||||
@Inject
|
||||
public SetRestoreCommand(@Nonnull MessageBridge messageBridge, @Nonnull IFileManager fileManager) {
|
||||
this.messageBridge = messageBridge;
|
||||
this.fileManager = fileManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(@NotNull CommandSender target) {
|
||||
if (target.hasPermission("areashop.setrestore")) {
|
||||
return "help-setrestore";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("setrestore")
|
||||
.required(KEY_REGION, GeneralRegionParser.generalRegionParser(this.fileManager))
|
||||
.required(KEY_RESTORE, StringParser.stringParser(), this::suggestRestoreType)
|
||||
.optional(KEY_PROFILE, StringParser.stringParser(), this::suggestSchematicProfiles)
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull CommandProperties properties() {
|
||||
return CommandProperties.of("setrestore");
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
|
||||
CommandSender sender = context.sender().sender();
|
||||
if (!sender.hasPermission("areashop.setrestore")) {
|
||||
throw new AreaShopCommandException("setrestore-noPermission");
|
||||
}
|
||||
GeneralRegion region = context.get(KEY_REGION);
|
||||
String restoreType = context.get(KEY_RESTORE);
|
||||
Optional<String> optionalProfile = context.optional(KEY_PROFILE);
|
||||
Boolean value = null;
|
||||
if (restoreType.equalsIgnoreCase("true")) {
|
||||
value = true;
|
||||
} else if (restoreType.equalsIgnoreCase("false")) {
|
||||
value = false;
|
||||
}
|
||||
region.setRestoreSetting(value);
|
||||
String valueString = "general";
|
||||
if (value != null) {
|
||||
valueString = value + "";
|
||||
}
|
||||
if (optionalProfile.isPresent()) {
|
||||
String profile = optionalProfile.get();
|
||||
region.setSchematicProfile(profile);
|
||||
this.messageBridge.message(sender, "setrestore-successProfile", valueString, profile, region);
|
||||
} else {
|
||||
this.messageBridge.message(sender, "setrestore-success", valueString, region);
|
||||
}
|
||||
region.update();
|
||||
}
|
||||
|
||||
private CompletableFuture<Iterable<Suggestion>> suggestRestoreType(
|
||||
@Nonnull CommandContext<CommandSource<?>> context,
|
||||
@Nonnull CommandInput input
|
||||
) {
|
||||
String text = input.peekString();
|
||||
List<Suggestion> suggestions = RESTORE_TYPES.stream()
|
||||
.filter(type -> type.startsWith(text))
|
||||
.map(Suggestion::suggestion)
|
||||
.toList();
|
||||
return CompletableFuture.completedFuture(suggestions);
|
||||
}
|
||||
|
||||
private CompletableFuture<Iterable<Suggestion>> suggestSchematicProfiles(
|
||||
@Nonnull CommandContext<CommandSource<?>> context,
|
||||
@Nonnull CommandInput input
|
||||
) {
|
||||
ConfigurationSection schemProfiles = fileManager.getConfig().getConfigurationSection("schematicProfiles");
|
||||
if (schemProfiles == null) {
|
||||
return CompletableFuture.completedFuture(Collections.emptyList());
|
||||
}
|
||||
String text = input.peekString();
|
||||
List<Suggestion> suggestions = schemProfiles.getKeys(false).stream()
|
||||
.filter(profile -> profile.startsWith(text))
|
||||
.map(Suggestion::suggestion)
|
||||
.toList();
|
||||
return CompletableFuture.completedFuture(suggestions);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.RegionParseUtil;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.parser.flag.CommandFlag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
@Singleton
|
||||
public class SetTeleportCommand extends AreashopCommandBean {
|
||||
|
||||
private static final CommandFlag<Void> FLAG_RESET = CommandFlag.builder("reset").build();
|
||||
private final CommandFlag<GeneralRegion> regionFlag;
|
||||
|
||||
private final MessageBridge messageBridge;
|
||||
|
||||
@Inject
|
||||
public SetTeleportCommand(@Nonnull MessageBridge messageBridge, @Nonnull IFileManager fileManager) {
|
||||
this.messageBridge = messageBridge;
|
||||
this.regionFlag = RegionParseUtil.createDefault(fileManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a person can set the teleport location of the region.
|
||||
*
|
||||
* @param person The person to check
|
||||
* @param region The region to check for
|
||||
* @return true if the person can set the teleport location, otherwise false
|
||||
*/
|
||||
public static boolean canUse(CommandSender person, GeneralRegion region) {
|
||||
if (!(person instanceof Player player)) {
|
||||
return false;
|
||||
}
|
||||
return player.hasPermission("areashop.setteleportall")
|
||||
|| region.isOwner(player) && player.hasPermission("areashop.setteleport");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(@NotNull CommandSender target) {
|
||||
if (target.hasPermission("areashop.setteleportall") || target.hasPermission("areashop.setteleport")) {
|
||||
return "help-setteleport";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("settp")
|
||||
.senderType(PlayerCommandSource.class)
|
||||
.flag(this.regionFlag)
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull CommandProperties properties() {
|
||||
return CommandProperties.of("settp");
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<PlayerCommandSource> context) {
|
||||
Player player = context.sender().sender();
|
||||
if (!player.hasPermission("areashop.setteleport") && !player.hasPermission("areashop.setteleportall")) {
|
||||
this.messageBridge.message(player, "setteleport-noPermission");
|
||||
return;
|
||||
}
|
||||
GeneralRegion region = RegionParseUtil.getOrParseRegion(context, player, this.regionFlag);
|
||||
|
||||
boolean owner;
|
||||
if (region instanceof RentRegion rentRegion) {
|
||||
owner = player.getUniqueId().equals(rentRegion.getRenter());
|
||||
} else if (region instanceof BuyRegion buyRegion) {
|
||||
owner = player.getUniqueId().equals(buyRegion.getBuyer());
|
||||
} else {
|
||||
// FIXME log error
|
||||
return;
|
||||
}
|
||||
if (!player.hasPermission("areashop.setteleport")) {
|
||||
throw new AreaShopCommandException("setteleport-noPermission", region);
|
||||
} else if (!owner && !player.hasPermission("areashop.setteleportall")) {
|
||||
throw new AreaShopCommandException("setteleport-noPermissionOther", region);
|
||||
}
|
||||
boolean reset = context.flags().contains(FLAG_RESET);
|
||||
if (reset) {
|
||||
region.getTeleportFeature().setTeleport(null);
|
||||
region.update();
|
||||
this.messageBridge.message(player, "setteleport-reset", region);
|
||||
}
|
||||
ProtectedRegion wgRegion = region.getRegion();
|
||||
Location location = player.getLocation();
|
||||
if (!player.hasPermission("areashop.setteleportoutsideregion") && (wgRegion == null || !wgRegion.contains(
|
||||
location.getBlockX(),
|
||||
location.getBlockY(),
|
||||
location.getBlockZ()))
|
||||
) {
|
||||
this.messageBridge.message(player, "setteleport-notInside", region);
|
||||
return;
|
||||
}
|
||||
region.getTeleportFeature().setTeleport(location);
|
||||
region.update();
|
||||
this.messageBridge.message(player, "setteleport-success", region);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.RegionParseUtil;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.incendo.cloud.parser.flag.CommandFlag;
|
||||
import org.incendo.cloud.parser.standard.BooleanParser;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
@Singleton
|
||||
public class SetTransferCommand extends AreashopCommandBean {
|
||||
|
||||
private static final CloudKey<Boolean> KEY_ENABLED = CloudKey.of("enabled", Boolean.class);
|
||||
private final MessageBridge messageBridge;
|
||||
private final CommandFlag<GeneralRegion> regionFlag;
|
||||
|
||||
@Inject
|
||||
public SetTransferCommand(
|
||||
@Nonnull MessageBridge messageBridge,
|
||||
@Nonnull IFileManager fileManager
|
||||
) {
|
||||
this.messageBridge = messageBridge;
|
||||
this.regionFlag = RegionParseUtil.createDefault(fileManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(CommandSender target) {
|
||||
if (target.hasPermission("areashop.settransfer")) {
|
||||
return "help-settransfer";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("settransfer")
|
||||
.required(KEY_ENABLED, BooleanParser.booleanParser(true))
|
||||
.flag(this.regionFlag)
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull CommandProperties properties() {
|
||||
return CommandProperties.of("settransfer");
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
|
||||
CommandSender sender = context.sender().sender();
|
||||
if (!sender.hasPermission("areashop.settransfer")) {
|
||||
throw new AreaShopCommandException("settransfer-noPermission");
|
||||
}
|
||||
GeneralRegion region = RegionParseUtil.getOrParseRegion(context, sender, this.regionFlag);
|
||||
boolean enabled = context.get(KEY_ENABLED);
|
||||
region.setTransferEnabled(enabled);
|
||||
messageBridge.message(sender, "settransfer-success", enabled, region);
|
||||
region.update();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,294 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
|
||||
import me.wiefferink.areashop.events.ask.AddingRegionEvent;
|
||||
import me.wiefferink.areashop.interfaces.WorldEditInterface;
|
||||
import me.wiefferink.areashop.interfaces.WorldEditSelection;
|
||||
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RegionFactory;
|
||||
import me.wiefferink.areashop.regions.RegionGroup;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import me.wiefferink.interactivemessenger.processing.Message;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.incendo.cloud.parser.flag.CommandFlag;
|
||||
import org.incendo.cloud.parser.standard.EnumParser;
|
||||
import org.incendo.cloud.parser.standard.IntegerParser;
|
||||
import org.incendo.cloud.parser.standard.StringParser;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Optional;
|
||||
|
||||
@Singleton
|
||||
public class StackCommand extends AreashopCommandBean {
|
||||
|
||||
private static final CloudKey<Integer> KEY_AMOUNT = CloudKey.of("amount", Integer.class);
|
||||
private static final CloudKey<Integer> KEY_GAP = CloudKey.of("gap", Integer.class);
|
||||
private static final CloudKey<String> KEY_NAME = CloudKey.of("name", String.class);
|
||||
private static final CloudKey<GeneralRegion.RegionType> KEY_TYPE = CloudKey.of("type",
|
||||
GeneralRegion.RegionType.class);
|
||||
private static final CommandFlag<String> FLAG_GROUP = CommandFlag.builder("group")
|
||||
.withComponent(StringParser.stringParser())
|
||||
.build();
|
||||
private final MessageBridge messageBridge;
|
||||
private final Plugin plugin;
|
||||
private final WorldEditInterface worldEditInterface;
|
||||
private final WorldGuardInterface worldGuardInterface;
|
||||
private final RegionFactory regionFactory;
|
||||
private final IFileManager fileManager;
|
||||
|
||||
@Inject
|
||||
public StackCommand(
|
||||
@Nonnull MessageBridge messageBridge,
|
||||
@Nonnull Plugin plugin,
|
||||
@Nonnull WorldEditInterface worldEditInterface,
|
||||
@Nonnull WorldGuardInterface worldGuardInterface,
|
||||
@Nonnull RegionFactory regionFactory,
|
||||
@Nonnull IFileManager fileManager
|
||||
|
||||
) {
|
||||
this.messageBridge = messageBridge;
|
||||
this.plugin = plugin;
|
||||
this.worldEditInterface = worldEditInterface;
|
||||
this.worldGuardInterface = worldGuardInterface;
|
||||
this.regionFactory = regionFactory;
|
||||
this.fileManager = fileManager;
|
||||
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Vector calculateShift(BlockFace facing, WorldEditSelection selection, int gap) {
|
||||
Vector shift = new Vector(0, 0, 0);
|
||||
if (facing == BlockFace.SOUTH) {
|
||||
shift = shift.setZ(-selection.getLength() - gap);
|
||||
} else if (facing == BlockFace.WEST) {
|
||||
shift = shift.setX(selection.getWidth() + gap);
|
||||
} else if (facing == BlockFace.NORTH) {
|
||||
shift = shift.setZ(selection.getLength() + gap);
|
||||
} else if (facing == BlockFace.EAST) {
|
||||
shift = shift.setX(-selection.getWidth() - gap);
|
||||
} else if (facing == BlockFace.DOWN) {
|
||||
shift = shift.setY(-selection.getHeight() - gap);
|
||||
} else if (facing == BlockFace.UP) {
|
||||
shift = shift.setY(selection.getHeight() + gap);
|
||||
}
|
||||
return shift;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(@NotNull CommandSender target) {
|
||||
if (target.hasPermission("areashop.stack")) {
|
||||
return "help-stack";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("stack")
|
||||
.senderType(PlayerCommandSource.class)
|
||||
.required(KEY_AMOUNT, IntegerParser.integerParser(0))
|
||||
.required(KEY_GAP, IntegerParser.integerParser(0))
|
||||
.required(KEY_NAME, StringParser.stringParser())
|
||||
.required(KEY_TYPE, EnumParser.enumParser(GeneralRegion.RegionType.class))
|
||||
.flag(FLAG_GROUP)
|
||||
.handler(this::handleCommand);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull CommandProperties properties() {
|
||||
return CommandProperties.of("stack");
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<PlayerCommandSource> context) {
|
||||
Player player = context.sender().sender();
|
||||
if (!player.hasPermission("areashop.stack")) {
|
||||
throw new AreaShopCommandException("stack-noPermission");
|
||||
}
|
||||
int amount = context.get(KEY_AMOUNT);
|
||||
int gap = context.get(KEY_GAP);
|
||||
String name = context.get(KEY_NAME);
|
||||
GeneralRegion.RegionType regionType = context.get(KEY_TYPE);
|
||||
Optional<String> optionalGroup = context.flags().getValue(FLAG_GROUP);
|
||||
// Get WorldEdit selection
|
||||
final WorldEditSelection selection = worldEditInterface.getPlayerSelection(player);
|
||||
if (selection == null) {
|
||||
this.messageBridge.message(player, "stack-noSelection");
|
||||
return;
|
||||
}
|
||||
// Get or create group
|
||||
RegionGroup group = null;
|
||||
if (optionalGroup.isPresent()) {
|
||||
String groupName = optionalGroup.get();
|
||||
group = fileManager.getGroup(groupName);
|
||||
if (group == null) {
|
||||
group = regionFactory.createRegionGroup(groupName);
|
||||
fileManager.addGroup(group);
|
||||
}
|
||||
}
|
||||
// Get facing of the player (must be clearly one of the four directions to make sure it is no mistake)
|
||||
BlockFace facing = Utils.yawToFacing(player.getLocation().getYaw());
|
||||
if (player.getLocation().getPitch() > 45) {
|
||||
facing = BlockFace.DOWN;
|
||||
} else if (player.getLocation().getPitch() < -45) {
|
||||
facing = BlockFace.UP;
|
||||
}
|
||||
if (!(facing == BlockFace.NORTH || facing == BlockFace.EAST || facing == BlockFace.SOUTH || facing == BlockFace.WEST || facing == BlockFace.UP || facing == BlockFace.DOWN)) {
|
||||
this.messageBridge.message(player,
|
||||
"stack-unclearDirection",
|
||||
facing.toString().toLowerCase().replace('_', '-'));
|
||||
return;
|
||||
}
|
||||
Vector shift = calculateShift(facing, selection, gap);
|
||||
BukkitRunnable task = stackTask(player, name, amount, selection, regionType, shift, group);
|
||||
task.runTaskTimer(plugin, 1, 1);
|
||||
}
|
||||
|
||||
private BukkitRunnable stackTask(
|
||||
@Nonnull Player player,
|
||||
@Nonnull String name,
|
||||
int amount,
|
||||
@Nonnull WorldEditSelection selection,
|
||||
GeneralRegion.RegionType regionType,
|
||||
@Nonnull Vector shift,
|
||||
@Nullable RegionGroup group
|
||||
) {
|
||||
final int regionsPerTick = plugin.getConfig().getInt("adding.regionsPerTick");
|
||||
|
||||
Location minimumLocation = selection.getMinimumLocation();
|
||||
Vector minimumVector = new Vector(minimumLocation.getX(), minimumLocation.getY(), minimumLocation.getZ());
|
||||
Location maximumLocation = selection.getMaximumLocation();
|
||||
Vector maximumVector = new Vector(maximumLocation.getX(), maximumLocation.getY(), maximumLocation.getZ());
|
||||
return new BukkitRunnable() {
|
||||
private final RegionManager manager = worldGuardInterface.getRegionManager(selection.getWorld());
|
||||
private int current = -1;
|
||||
private int counter = 1;
|
||||
private int tooLow = 0;
|
||||
private int tooHigh = 0;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for (int i = 0; i < regionsPerTick; i++) {
|
||||
current++;
|
||||
if (current >= amount) {
|
||||
continue;
|
||||
}
|
||||
// Create the region name
|
||||
String regionName = countToName(name, counter);
|
||||
while (manager.getRegion(regionName) != null || fileManager.getRegion(regionName) != null) {
|
||||
counter++;
|
||||
regionName = countToName(name, counter);
|
||||
}
|
||||
|
||||
// Add the region to WorldGuard (at startposition shifted by the number of this region times the blocks it should shift)
|
||||
Vector minimum = minimumVector.clone().add(shift.clone().multiply(current));
|
||||
Vector maximum = maximumVector.clone().add(shift.clone().multiply(current));
|
||||
|
||||
// Check for out of bounds
|
||||
if (minimum.getBlockY() < 0) {
|
||||
tooLow++;
|
||||
continue;
|
||||
} else if (maximum.getBlockY() > 256) {
|
||||
tooHigh++;
|
||||
continue;
|
||||
}
|
||||
ProtectedCuboidRegion region = worldGuardInterface.createCuboidRegion(regionName, minimum, maximum);
|
||||
manager.addRegion(region);
|
||||
|
||||
// Add the region to AreaShop
|
||||
GeneralRegion newRegion;
|
||||
if (regionType == GeneralRegion.RegionType.BUY) {
|
||||
newRegion = regionFactory.createRentRegion(regionName, selection.getWorld());
|
||||
} else {
|
||||
newRegion = regionFactory.createBuyRegion(regionName, selection.getWorld());
|
||||
}
|
||||
|
||||
if (group != null) {
|
||||
group.addMember(newRegion);
|
||||
}
|
||||
AddingRegionEvent event = fileManager.addRegion(newRegion);
|
||||
if (event.isCancelled()) {
|
||||
messageBridge.message(player, "general-cancelled", event.getReason());
|
||||
continue;
|
||||
}
|
||||
newRegion.handleSchematicEvent(GeneralRegion.RegionEvent.CREATED);
|
||||
newRegion.update();
|
||||
}
|
||||
if (current >= amount) {
|
||||
if (player.isOnline()) {
|
||||
int added = amount - tooLow - tooHigh;
|
||||
Message wrong = Message.empty();
|
||||
if (tooHigh > 0) {
|
||||
wrong.append(Message.fromKey("stack-tooHigh").replacements(tooHigh));
|
||||
}
|
||||
if (tooLow > 0) {
|
||||
wrong.append(Message.fromKey("stack-tooLow").replacements(tooLow));
|
||||
}
|
||||
messageBridge.message(player, "stack-addComplete", added, wrong);
|
||||
}
|
||||
this.cancel();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a name from a count, with the right length.
|
||||
*
|
||||
* @param template Template to put the name in (# to put the count there, otherwise count is appended)
|
||||
* @param count Number to use
|
||||
* @return name with prepended 0's
|
||||
*/
|
||||
private String countToName(String template, int count) {
|
||||
StringBuilder counterName = new StringBuilder().append(count);
|
||||
int minimumLength = plugin.getConfig().getInt("stackRegionNumberLength");
|
||||
while (counterName.length() < minimumLength) {
|
||||
counterName.insert(0, "0");
|
||||
}
|
||||
|
||||
if (template.contains("#")) {
|
||||
return template.replace("#", counterName);
|
||||
} else {
|
||||
return template + counterName;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.BuyRegionParser;
|
||||
import me.wiefferink.areashop.commands.util.RegionParseUtil;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.context.CommandInput;
|
||||
import org.incendo.cloud.parser.ParserDescriptor;
|
||||
import org.incendo.cloud.parser.flag.CommandFlag;
|
||||
import org.incendo.cloud.suggestion.Suggestion;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Singleton
|
||||
public class StopResellCommand extends AreashopCommandBean {
|
||||
|
||||
private final MessageBridge messageBridge;
|
||||
private final IFileManager fileManager;
|
||||
|
||||
private final CommandFlag<BuyRegion> regionFlag;
|
||||
|
||||
@Inject
|
||||
public StopResellCommand(@Nonnull MessageBridge messageBridge, @Nonnull IFileManager fileManager) {
|
||||
ParserDescriptor<CommandSource<?>, BuyRegion> regionParser =
|
||||
ParserDescriptor.of(new BuyRegionParser<>(fileManager, this::suggestBuyRegions), BuyRegion.class);
|
||||
this.messageBridge = messageBridge;
|
||||
this.fileManager = fileManager;
|
||||
this.regionFlag = CommandFlag.<CommandSource<?>>builder("region")
|
||||
.withComponent(regionParser)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(CommandSender target) {
|
||||
if (target.hasPermission("areashop.stopresellall") || target.hasPermission("areashop.stopresell")) {
|
||||
return "help-stopResell";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("stopresell")
|
||||
.flag(this.regionFlag)
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull CommandProperties properties() {
|
||||
return CommandProperties.of("stopresell");
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
|
||||
CommandSender sender = context.sender().sender();
|
||||
if (!sender.hasPermission("areashop.stopresell") && !sender.hasPermission("areashop.stopresellall")) {
|
||||
this.messageBridge.message(sender, "stopresell-noPermissionOther");
|
||||
return;
|
||||
}
|
||||
|
||||
BuyRegion buy = RegionParseUtil.getOrParseBuyRegion(context, sender, this.regionFlag);
|
||||
if (!buy.isInResellingMode()) {
|
||||
this.messageBridge.message(sender, "stopresell-notResell", buy);
|
||||
return;
|
||||
}
|
||||
if (sender.hasPermission("areashop.stopresellall")) {
|
||||
buy.disableReselling();
|
||||
buy.update();
|
||||
this.messageBridge.message(sender, "stopresell-success", buy);
|
||||
} else if (sender.hasPermission("areashop.stopresell") && sender instanceof Player player) {
|
||||
if (buy.isOwner(player)) {
|
||||
buy.disableReselling();
|
||||
buy.update();
|
||||
this.messageBridge.message(sender, "stopresell-success", buy);
|
||||
} else {
|
||||
this.messageBridge.message(sender, "stopresell-noPermissionOther", buy);
|
||||
}
|
||||
} else {
|
||||
this.messageBridge.message(sender, "stopresell-noPermission", buy);
|
||||
}
|
||||
}
|
||||
|
||||
private CompletableFuture<Iterable<Suggestion>> suggestBuyRegions(
|
||||
@Nonnull CommandContext<CommandSource<?>> context,
|
||||
@Nonnull CommandInput input
|
||||
) {
|
||||
String text = input.peekString();
|
||||
List<Suggestion> suggestions = this.fileManager.getBuysRef().stream()
|
||||
.filter(region -> region.isSold() && region.isInResellingMode())
|
||||
.map(GeneralRegion::getName)
|
||||
.filter(name -> name.startsWith(text))
|
||||
.map(Suggestion::suggestion)
|
||||
.toList();
|
||||
return CompletableFuture.completedFuture(suggestions);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.GeneralRegionParser;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.incendo.cloud.parser.flag.CommandFlag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
@Singleton
|
||||
public class TeleportCommand extends AreashopCommandBean {
|
||||
|
||||
private static final CloudKey<GeneralRegion> KEY_REGION = CloudKey.of("region", GeneralRegion.class);
|
||||
private static final CommandFlag<Void> KEY_TO_SIGN = CommandFlag.builder("to-sign").build();
|
||||
private final MessageBridge messageBridge;
|
||||
|
||||
private final IFileManager fileManager;
|
||||
|
||||
@Inject
|
||||
public TeleportCommand(@Nonnull MessageBridge messageBridge, @Nonnull IFileManager fileManager) {
|
||||
this.messageBridge = messageBridge;
|
||||
this.fileManager = fileManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a person can teleport to the region (assuming he is not teleporting to a sign).
|
||||
*
|
||||
* @param person The person to check
|
||||
* @param region The region to check for
|
||||
* @return true if the person can teleport to it, otherwise false
|
||||
*/
|
||||
public static boolean canUse(CommandSender person, GeneralRegion region) {
|
||||
if (!(person instanceof Player player)) {
|
||||
return false;
|
||||
}
|
||||
return player.hasPermission("areashop.teleportall")
|
||||
|| region.isOwner(player) && player.hasPermission("areashop.teleport")
|
||||
|| region.isAvailable() && player.hasPermission("areashop.teleportavailable")
|
||||
|| region.getFriendsFeature().getFriends().contains(player.getUniqueId()) && player.hasPermission(
|
||||
"areashop.teleportfriend");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(@NotNull CommandSender target) {
|
||||
if (target.hasPermission("areashop.teleportall") || target.hasPermission("areashop.teleport")) {
|
||||
return "help-teleport";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("tp", "teleport")
|
||||
.senderType(PlayerCommandSource.class)
|
||||
.required(KEY_REGION, GeneralRegionParser.generalRegionParser(this.fileManager))
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull CommandProperties properties() {
|
||||
return CommandProperties.of("teleport", "tp");
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<PlayerCommandSource> context) {
|
||||
Player player = context.sender().sender();
|
||||
if (!player.hasPermission("areashop.teleport") && !player.hasPermission("areashop.teleportall") && !player.hasPermission(
|
||||
"areashop.teleportavailable") && !player.hasPermission("areashop.teleportavailablesign") && !player.hasPermission(
|
||||
"areashop.teleportsign") && !player.hasPermission("areashop.teleportsignall") && !player.hasPermission(
|
||||
"areashop.teleportfriend") && !player.hasPermission("teleportfriendsign")) {
|
||||
this.messageBridge.message(player, "teleport-noPermission");
|
||||
return;
|
||||
}
|
||||
GeneralRegion region = context.get(KEY_REGION);
|
||||
boolean toSign = context.flags().contains(KEY_TO_SIGN);
|
||||
region.getTeleportFeature().teleportPlayer(player, toSign);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.GeneralRegionParser;
|
||||
import me.wiefferink.areashop.commands.util.RegionParseUtil;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.features.homeaccess.HomeAccessFeature;
|
||||
import me.wiefferink.areashop.features.homeaccess.HomeAccessType;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.component.CommandComponent;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.context.CommandInput;
|
||||
import org.incendo.cloud.description.Description;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.incendo.cloud.parser.flag.CommandFlag;
|
||||
import org.incendo.cloud.parser.standard.EnumParser;
|
||||
import org.incendo.cloud.suggestion.Suggestion;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Singleton
|
||||
public final class ToggleHomeCommand extends AreashopCommandBean {
|
||||
|
||||
private static final CloudKey<HomeAccessType> KEY_ACCESS_TYPE = CloudKey.of("accessType", HomeAccessType.class);
|
||||
private final MessageBridge messageBridge;
|
||||
private final IFileManager fileManager;
|
||||
private final CommandFlag<GeneralRegion> regionFlag;
|
||||
|
||||
@Inject
|
||||
public ToggleHomeCommand(@Nonnull MessageBridge messageBridge, @Nonnull IFileManager fileManager) {
|
||||
this.messageBridge = messageBridge;
|
||||
this.fileManager = fileManager;
|
||||
this.regionFlag = CommandFlag.<CommandSource<?>>builder("region")
|
||||
.withComponent(
|
||||
CommandComponent.<CommandSource<?>, GeneralRegion>builder()
|
||||
.name("region")
|
||||
.description(Description.EMPTY)
|
||||
.valueType(GeneralRegion.class)
|
||||
.parser(GeneralRegionParser.generalRegionParser(fileManager))
|
||||
.suggestionProvider(this::suggestRegions)
|
||||
.build()
|
||||
).build();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getHelpKey(@NotNull CommandSender target) {
|
||||
if (!target.hasPermission("sethomecontrol.control")) {
|
||||
return null;
|
||||
}
|
||||
return "help-togglehome";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("togglehome")
|
||||
.required(KEY_ACCESS_TYPE, EnumParser.enumParser(HomeAccessType.class))
|
||||
.flag(this.regionFlag)
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull CommandProperties properties() {
|
||||
return CommandProperties.of("togglehome");
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
|
||||
CommandSender sender = context.sender().sender();
|
||||
if (!sender.hasPermission("areashop.togglehome")) {
|
||||
throw new AreaShopCommandException("togglehome-noPermission");
|
||||
}
|
||||
final HomeAccessType accessType = context.get(KEY_ACCESS_TYPE);
|
||||
final GeneralRegion region = RegionParseUtil.getOrParseRegion(context, sender, this.regionFlag);
|
||||
if (!(sender instanceof Player) && !sender.hasPermission("sethome.control.other")) {
|
||||
return;
|
||||
}
|
||||
if (sender instanceof Player player && !region.isOwner(player)) {
|
||||
throw new AreaShopCommandException("togglehome-noPermission");
|
||||
}
|
||||
region.getOrCreateFeature(HomeAccessFeature.class).homeAccessType(accessType);
|
||||
this.messageBridge.message(sender, "togglehome-success", accessType.name());
|
||||
}
|
||||
|
||||
private CompletableFuture<Iterable<Suggestion>> suggestRegions(
|
||||
@Nonnull CommandContext<CommandSource<?>> context,
|
||||
@Nonnull CommandInput input
|
||||
) {
|
||||
String text = input.peekString();
|
||||
CommandSender sender = context.sender().sender();
|
||||
Stream<GeneralRegion> regions;
|
||||
if (sender.hasPermission("sethome.control.other")) {
|
||||
regions = this.fileManager.getRegionsRef().stream();
|
||||
} else if (!sender.hasPermission("sethome.control.other") && sender instanceof Player player) {
|
||||
regions = this.fileManager.getRegionsRef().stream()
|
||||
.filter(region -> region.isOwner(player.getUniqueId()));
|
||||
} else {
|
||||
regions = Stream.empty();
|
||||
}
|
||||
List<Suggestion> suggestions = regions.map(GeneralRegion::getName)
|
||||
.filter(name -> name.startsWith(text))
|
||||
.map(Suggestion::suggestion)
|
||||
.toList();
|
||||
return CompletableFuture.completedFuture(suggestions);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.GeneralRegionParser;
|
||||
import me.wiefferink.areashop.commands.util.RegionParseUtil;
|
||||
import me.wiefferink.areashop.commands.util.ValidatedOfflinePlayerParser;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.PlayerCommandSource;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.context.CommandInput;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.incendo.cloud.parser.ParserDescriptor;
|
||||
import org.incendo.cloud.parser.flag.CommandFlag;
|
||||
import org.incendo.cloud.suggestion.Suggestion;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Singleton
|
||||
public class TransferCommand extends AreashopCommandBean {
|
||||
|
||||
private static final CloudKey<OfflinePlayer> KEY_PLAYER = CloudKey.of("player", OfflinePlayer.class);
|
||||
private final MessageBridge messageBridge;
|
||||
private final IFileManager fileManager;
|
||||
private final CommandFlag<GeneralRegion> regionFlag;
|
||||
|
||||
@Inject
|
||||
public TransferCommand(
|
||||
@Nonnull MessageBridge messageBridge,
|
||||
@Nonnull IFileManager fileManager
|
||||
) {
|
||||
ParserDescriptor<PlayerCommandSource, GeneralRegion> regionParser =
|
||||
ParserDescriptor.of(new GeneralRegionParser<>(fileManager, this::suggestRegions), GeneralRegion.class);
|
||||
this.messageBridge = messageBridge;
|
||||
this.fileManager = fileManager;
|
||||
this.regionFlag = CommandFlag.<PlayerCommandSource>builder("region")
|
||||
.withComponent(regionParser)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(@NotNull CommandSender target) {
|
||||
if (!target.hasPermission("areashop.transfer")) {
|
||||
return null;
|
||||
}
|
||||
return "help-transfer";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("transfer")
|
||||
.senderType(PlayerCommandSource.class)
|
||||
.required(KEY_PLAYER, ValidatedOfflinePlayerParser.validatedOfflinePlayerParser())
|
||||
.flag(this.regionFlag)
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull CommandProperties properties() {
|
||||
return CommandProperties.of("transfer");
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<PlayerCommandSource> context) {
|
||||
Player sender = context.sender().sender();
|
||||
if (!sender.hasPermission("areashop.transfer")) {
|
||||
throw new AreaShopCommandException("transfer-noPermission");
|
||||
}
|
||||
GeneralRegion region = RegionParseUtil.getOrParseRegion(context, sender, this.regionFlag);
|
||||
if (!region.isTransferEnabled()) {
|
||||
throw new AreaShopCommandException("transfer-disabled");
|
||||
}
|
||||
OfflinePlayer targetPlayer = context.get(KEY_PLAYER);
|
||||
String targetPlayerName = targetPlayer.getName();
|
||||
if (Objects.equals(sender, targetPlayer)) {
|
||||
throw new AreaShopCommandException("transfer-transferSelf");
|
||||
}
|
||||
if (!targetPlayer.hasPlayedBefore()) {
|
||||
// Unknown player
|
||||
throw new AreaShopCommandException("transfer-noPlayer", targetPlayerName);
|
||||
}
|
||||
if (region.isLandlord(sender.getUniqueId())) {
|
||||
// Transfer ownership if same as landlord
|
||||
region.getFriendsFeature().deleteFriend(region.getOwner(), null);
|
||||
region.setOwner(targetPlayer.getUniqueId());
|
||||
region.setLandlord(targetPlayer.getUniqueId(), targetPlayerName);
|
||||
this.messageBridge.message(sender, "transfer-transferred-owner", targetPlayerName, region);
|
||||
this.messageBridge.messagePersistent(targetPlayer, "transfer-transferred-owner", targetPlayerName, region);
|
||||
region.update();
|
||||
region.saveRequired();
|
||||
return;
|
||||
}
|
||||
if (!region.isOwner(sender.getUniqueId())) {
|
||||
// Cannot transfer tenant if we aren't the current tenant
|
||||
throw new AreaShopCommandException("transfer-notCurrentTenant");
|
||||
}
|
||||
region.getFriendsFeature().deleteFriend(region.getOwner(), null);
|
||||
// Swap the owner/occupant (renter or buyer)
|
||||
region.setOwner(targetPlayer.getUniqueId());
|
||||
|
||||
this.messageBridge.message(sender, "transfer-transferred-tenant", targetPlayerName, region);
|
||||
this.messageBridge.messagePersistent(targetPlayer, "transfer-transferred-tenant", targetPlayerName, region);
|
||||
region.update();
|
||||
region.saveRequired();
|
||||
}
|
||||
|
||||
private CompletableFuture<Iterable<Suggestion>> suggestRegions(
|
||||
@Nonnull CommandContext<PlayerCommandSource> context,
|
||||
@Nonnull CommandInput input
|
||||
) {
|
||||
String text = input.peekString();
|
||||
UUID uuid = context.sender().sender().getUniqueId();
|
||||
List<Suggestion> suggestions = this.fileManager.getRegions()
|
||||
.stream()
|
||||
.filter(region -> region.isOwner(uuid) || region.isLandlord(uuid))
|
||||
.map(GeneralRegion::getName)
|
||||
.filter(name -> name.startsWith(text))
|
||||
.map(Suggestion::suggestion)
|
||||
.toList();
|
||||
return CompletableFuture.completedFuture(suggestions);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import me.wiefferink.areashop.commands.util.AreaShopCommandException;
|
||||
import me.wiefferink.areashop.commands.util.AreashopCommandBean;
|
||||
import me.wiefferink.areashop.commands.util.RegionParseUtil;
|
||||
import me.wiefferink.areashop.commands.util.RentRegionParser;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandProperties;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.context.CommandInput;
|
||||
import org.incendo.cloud.parser.ParserDescriptor;
|
||||
import org.incendo.cloud.parser.flag.CommandFlag;
|
||||
import org.incendo.cloud.suggestion.Suggestion;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Singleton
|
||||
public class UnrentCommand extends AreashopCommandBean {
|
||||
private final IFileManager fileManager;
|
||||
private final CommandFlag<RentRegion> regionFlag;
|
||||
|
||||
@Inject
|
||||
public UnrentCommand(@Nonnull IFileManager fileManager) {
|
||||
ParserDescriptor<CommandSource<?>, RentRegion> regionParser =
|
||||
ParserDescriptor.of(new RentRegionParser<>(fileManager, this::suggestRegions), RentRegion.class);
|
||||
this.fileManager = fileManager;
|
||||
this.regionFlag = CommandFlag.<CommandSource<?>>builder("region")
|
||||
.withComponent(regionParser)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a person can unrent the region.
|
||||
*
|
||||
* @param person The person to check
|
||||
* @param region The region to check for
|
||||
* @return true if the person can unrent it, otherwise false
|
||||
*/
|
||||
public static boolean canUse(CommandSender person, GeneralRegion region) {
|
||||
if (person.hasPermission("areashop.unrent")) {
|
||||
return true;
|
||||
}
|
||||
if (person instanceof Player player) {
|
||||
return region.isOwner(player) && person.hasPermission("areashop.unrentown");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpKey(CommandSender target) {
|
||||
if (target.hasPermission("areashop.unrent") || target.hasPermission("areashop.unrentown")) {
|
||||
return "help-unrent";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringDescription() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Command.Builder<? extends CommandSource<?>> configureCommand(Command.@NotNull Builder<CommandSource<?>> builder) {
|
||||
return builder.literal("unrent")
|
||||
.flag(this.regionFlag)
|
||||
.handler(this::handleCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull CommandProperties properties() {
|
||||
return CommandProperties.of("unrent");
|
||||
}
|
||||
|
||||
private void handleCommand(@Nonnull CommandContext<CommandSource<?>> context) {
|
||||
CommandSender sender = context.sender().sender();
|
||||
if (!sender.hasPermission("areashop.unrent") && !sender.hasPermission("areashop.unrentown")) {
|
||||
throw new AreaShopCommandException("unrent-noPermission");
|
||||
}
|
||||
RentRegion rent = RegionParseUtil.getOrParseRentRegion(context, sender, this.regionFlag);
|
||||
if (!rent.isRented()) {
|
||||
throw new AreaShopCommandException("unrent-notRented", rent);
|
||||
}
|
||||
rent.unRent(true, sender);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private CompletableFuture<Iterable<Suggestion>> suggestRegions(
|
||||
@Nonnull CommandContext<CommandSource<?>> context,
|
||||
@Nonnull CommandInput input
|
||||
) {
|
||||
String text = input.peekString();
|
||||
List<Suggestion> suggestions = this.fileManager.getRentsRef().stream()
|
||||
.filter(RentRegion::isRented)
|
||||
.map(GeneralRegion::getName)
|
||||
.filter(name -> name.startsWith(text))
|
||||
.map(Suggestion::suggestion)
|
||||
.toList();
|
||||
return CompletableFuture.completedFuture(suggestions);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
package me.wiefferink.areashop.commands.util;
|
||||
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.context.CommandInput;
|
||||
import org.incendo.cloud.parser.ArgumentParseResult;
|
||||
import org.incendo.cloud.parser.ArgumentParser;
|
||||
import org.incendo.cloud.suggestion.Suggestion;
|
||||
import org.incendo.cloud.suggestion.SuggestionProvider;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class AcceptedValuesParser<C> implements ArgumentParser<C, String>, SuggestionProvider<C> {
|
||||
|
||||
private final Supplier< Collection<String>> valuesProvider;
|
||||
private final boolean caseSensitive;
|
||||
|
||||
private final String failureMessageKey;
|
||||
|
||||
private AcceptedValuesParser(
|
||||
@Nonnull Supplier< Collection<String>> valuesProvider,
|
||||
@Nonnull String failureMessageKey,
|
||||
boolean caseSensitive
|
||||
|
||||
) {
|
||||
this.valuesProvider = valuesProvider;
|
||||
this.failureMessageKey = failureMessageKey;
|
||||
this.caseSensitive = caseSensitive;
|
||||
}
|
||||
|
||||
public static <C> AcceptedValuesParser<C> ofConstant(
|
||||
@Nonnull Collection<String> acceptedValues,
|
||||
@Nonnull String failureMessageKey,
|
||||
boolean caseSensitive
|
||||
) {
|
||||
Collection<String> copy = List.copyOf(acceptedValues);
|
||||
return new AcceptedValuesParser<>(() -> copy, failureMessageKey, caseSensitive);
|
||||
}
|
||||
|
||||
public static <C> AcceptedValuesParser<C> of(
|
||||
@Nonnull Supplier< Collection<String>> supplier,
|
||||
@Nonnull String failureMessageKey,
|
||||
boolean caseSensitive
|
||||
) {
|
||||
return new AcceptedValuesParser<>(supplier, failureMessageKey, caseSensitive);
|
||||
}
|
||||
|
||||
public static <C> AcceptedValuesParser<C> ofCached(
|
||||
@Nonnull Supplier< Collection<String>> supplier,
|
||||
@Nonnull String failureMessageKey,
|
||||
boolean caseSensitive
|
||||
) {
|
||||
return ofConstant(supplier.get(), failureMessageKey, caseSensitive);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nonnull ArgumentParseResult<String> parse(@Nonnull CommandContext<C> commandContext,
|
||||
@Nonnull CommandInput commandInput) {
|
||||
String toTest;
|
||||
if (this.caseSensitive) {
|
||||
toTest = commandInput.peekString().toLowerCase(Locale.ENGLISH);
|
||||
} else {
|
||||
toTest = commandInput.peekString();
|
||||
}
|
||||
Collection<String> acceptedValues = this.valuesProvider.get();
|
||||
if (acceptedValues.contains(toTest)) {
|
||||
return ArgumentParseResult.success(toTest);
|
||||
}
|
||||
return ArgumentParseResult.failure(new AreaShopCommandException(this.failureMessageKey));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nonnull CompletableFuture<Iterable<Suggestion>> suggestionsFuture(
|
||||
@Nonnull CommandContext<C> context,
|
||||
@Nonnull CommandInput input
|
||||
) {
|
||||
String text = input.peekString();
|
||||
Iterable<Suggestion> suggestions = this.valuesProvider.get().stream()
|
||||
.filter(s -> s.startsWith(text))
|
||||
.map(Suggestion::suggestion)
|
||||
.toList();
|
||||
return CompletableFuture.completedFuture(suggestions);
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package me.wiefferink.areashop.commands.util;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class AreaShopCommandException extends RuntimeException {
|
||||
|
||||
private static final Object[] EMPTY = new Object[0];
|
||||
|
||||
private final String messageKey;
|
||||
private final Object[] replacements;
|
||||
|
||||
public AreaShopCommandException(@Nonnull String messageKey, @Nullable Object... replacements) {
|
||||
this.messageKey = messageKey;
|
||||
this.replacements = replacements == null ? EMPTY : replacements;
|
||||
}
|
||||
|
||||
public String messageKey() {
|
||||
return this.messageKey;
|
||||
}
|
||||
|
||||
public Object[] replacements() {
|
||||
return this.replacements;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return this.messageKey;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package me.wiefferink.areashop.commands.util;
|
||||
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.bean.CommandBean;
|
||||
import org.incendo.cloud.key.CloudKey;
|
||||
import org.incendo.cloud.processors.confirmation.ConfirmationManager;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* An extension of {@link CommandBean} which does extra pre-processing of the commands.
|
||||
* Adapted from <a href="https://github.com/Incendo/kitchensink">KitchenSink</a>
|
||||
*/
|
||||
public abstract class AreashopCommandBean extends CommandBean<CommandSource<?>> implements HelpProvider {
|
||||
|
||||
private boolean requireConfirmation;
|
||||
|
||||
protected void withConfirmation() {
|
||||
this.requireConfirmation = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final @Nonnull Command.Builder<? extends CommandSource<?>> configure(
|
||||
final @Nonnull Command.Builder<CommandSource<?>> builder
|
||||
) {
|
||||
return this.configureCommand(builder)
|
||||
.meta(CloudKey.of("bukkit_description", String.class), this.stringDescription())
|
||||
.meta(ConfirmationManager.META_CONFIRMATION_REQUIRED, this.requireConfirmation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a simple string description of this command.
|
||||
*
|
||||
* <p>This is primarily used in the platform-native help menus.</p>
|
||||
*
|
||||
* @return command description
|
||||
*/
|
||||
public abstract String stringDescription();
|
||||
|
||||
/**
|
||||
* Configures the command and returns the updated builder.
|
||||
*
|
||||
* @param builder builder to configure
|
||||
* @return the updated builder
|
||||
*/
|
||||
protected abstract @Nonnull Command.Builder<? extends CommandSource<?>> configureCommand(
|
||||
@Nonnull Command.Builder<CommandSource<?>> builder
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
package me.wiefferink.areashop.commands.util;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Singleton;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.commands.AddCommand;
|
||||
import me.wiefferink.areashop.commands.AddFriendCommand;
|
||||
import me.wiefferink.areashop.commands.AddSignCommand;
|
||||
import me.wiefferink.areashop.commands.BuyCommand;
|
||||
import me.wiefferink.areashop.commands.DelCommand;
|
||||
import me.wiefferink.areashop.commands.DelFriendCommand;
|
||||
import me.wiefferink.areashop.commands.DelSignCommand;
|
||||
import me.wiefferink.areashop.commands.FindCommand;
|
||||
import me.wiefferink.areashop.commands.GroupAddCommand;
|
||||
import me.wiefferink.areashop.commands.GroupDelCommand;
|
||||
import me.wiefferink.areashop.commands.GroupInfoCommand;
|
||||
import me.wiefferink.areashop.commands.GroupListCommand;
|
||||
import me.wiefferink.areashop.commands.HelpCommand;
|
||||
import me.wiefferink.areashop.commands.InfoBaseCommand;
|
||||
import me.wiefferink.areashop.commands.InfoCommand;
|
||||
import me.wiefferink.areashop.commands.InfoPlayerCommand;
|
||||
import me.wiefferink.areashop.commands.InfoRegionCommand;
|
||||
import me.wiefferink.areashop.commands.LinkSignsCommand;
|
||||
import me.wiefferink.areashop.commands.MeCommand;
|
||||
import me.wiefferink.areashop.commands.MessageCommand;
|
||||
import me.wiefferink.areashop.commands.QuickBuyCommand;
|
||||
import me.wiefferink.areashop.commands.QuickDeleteCommand;
|
||||
import me.wiefferink.areashop.commands.QuickRentCommand;
|
||||
import me.wiefferink.areashop.commands.ReloadCommand;
|
||||
import me.wiefferink.areashop.commands.RentCommand;
|
||||
import me.wiefferink.areashop.commands.ResellCommand;
|
||||
import me.wiefferink.areashop.commands.SchematicEventCommand;
|
||||
import me.wiefferink.areashop.commands.SellCommand;
|
||||
import me.wiefferink.areashop.commands.SetDurationCommand;
|
||||
import me.wiefferink.areashop.commands.SetLandlordCommand;
|
||||
import me.wiefferink.areashop.commands.SetOwnerCommand;
|
||||
import me.wiefferink.areashop.commands.SetPriceCommand;
|
||||
import me.wiefferink.areashop.commands.SetRestoreCommand;
|
||||
import me.wiefferink.areashop.commands.SetTeleportCommand;
|
||||
import me.wiefferink.areashop.commands.SetTransferCommand;
|
||||
import me.wiefferink.areashop.commands.StackCommand;
|
||||
import me.wiefferink.areashop.commands.StopResellCommand;
|
||||
import me.wiefferink.areashop.commands.TeleportCommand;
|
||||
import me.wiefferink.areashop.commands.ToggleHomeCommand;
|
||||
import me.wiefferink.areashop.commands.TransferCommand;
|
||||
import me.wiefferink.areashop.commands.UnrentCommand;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSource;
|
||||
import me.wiefferink.areashop.commands.util.commandsource.CommandSourceMapper;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.incendo.cloud.exception.ArgumentParseException;
|
||||
import org.incendo.cloud.exception.CommandExecutionException;
|
||||
import org.incendo.cloud.exception.InvalidCommandSenderException;
|
||||
import org.incendo.cloud.exception.handling.ExceptionController;
|
||||
import org.incendo.cloud.exception.handling.ExceptionHandler;
|
||||
import org.incendo.cloud.execution.ExecutionCoordinator;
|
||||
import org.incendo.cloud.paper.PaperCommandManager;
|
||||
import org.incendo.cloud.processors.cache.GuavaCache;
|
||||
import org.incendo.cloud.processors.confirmation.ConfirmationConfiguration;
|
||||
import org.incendo.cloud.processors.confirmation.ConfirmationManager;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Singleton
|
||||
public class AreashopCommands {
|
||||
|
||||
private static final List<Class<? extends AreashopCommandBean>> COMMAND_CLASSES = List.of(
|
||||
AddCommand.class,
|
||||
AddFriendCommand.class,
|
||||
AddSignCommand.class,
|
||||
BuyCommand.class,
|
||||
DelCommand.class,
|
||||
DelFriendCommand.class,
|
||||
DelSignCommand.class,
|
||||
FindCommand.class,
|
||||
GroupAddCommand.class,
|
||||
GroupDelCommand.class,
|
||||
GroupInfoCommand.class,
|
||||
GroupListCommand.class,
|
||||
HelpCommand.class,
|
||||
InfoCommand.class,
|
||||
InfoBaseCommand.class,
|
||||
InfoPlayerCommand.class,
|
||||
InfoRegionCommand.class,
|
||||
LinkSignsCommand.class,
|
||||
MeCommand.class,
|
||||
MessageCommand.class,
|
||||
QuickBuyCommand.class,
|
||||
QuickDeleteCommand.class,
|
||||
QuickRentCommand.class,
|
||||
ReloadCommand.class,
|
||||
RentCommand.class,
|
||||
ResellCommand.class,
|
||||
SchematicEventCommand.class,
|
||||
SellCommand.class,
|
||||
SetDurationCommand.class,
|
||||
SetLandlordCommand.class,
|
||||
SetOwnerCommand.class,
|
||||
SetPriceCommand.class,
|
||||
SetRestoreCommand.class,
|
||||
SetTeleportCommand.class,
|
||||
SetTransferCommand.class,
|
||||
StackCommand.class,
|
||||
StopResellCommand.class,
|
||||
TeleportCommand.class,
|
||||
ToggleHomeCommand.class,
|
||||
TransferCommand.class,
|
||||
UnrentCommand.class
|
||||
);
|
||||
|
||||
private final MessageBridge messageBridge;
|
||||
|
||||
private final Injector injector;
|
||||
private final PaperCommandManager<CommandSource<?>> commandManager;
|
||||
|
||||
private final List<AreashopCommandBean> commands = new ArrayList<>();
|
||||
private HelpRenderer helpRenderer;
|
||||
|
||||
@Inject
|
||||
AreashopCommands(@Nonnull Injector injector, @Nonnull Plugin plugin, @Nonnull MessageBridge messageBridge) {
|
||||
this.injector = injector;
|
||||
this.commandManager = PaperCommandManager.builder(new CommandSourceMapper())
|
||||
.executionCoordinator(ExecutionCoordinator.simpleCoordinator())
|
||||
.buildOnEnable(plugin);
|
||||
this.messageBridge = messageBridge;
|
||||
}
|
||||
|
||||
public void registerCommands() {
|
||||
this.commands.clear();
|
||||
initCommandManager();
|
||||
var builder = this.commandManager.commandBuilder("areashop", "as");
|
||||
for (Class<? extends AreashopCommandBean> commandClass : COMMAND_CLASSES) {
|
||||
AreashopCommandBean commandBean = injector.getInstance(commandClass);
|
||||
this.commands.add(commandBean);
|
||||
var configuredBuilder = commandBean.configureCommand(builder);
|
||||
this.commandManager.command(configuredBuilder);
|
||||
}
|
||||
// Show help by default
|
||||
this.commandManager.command(builder.handler(context -> showHelp(context.sender().sender())));
|
||||
this.helpRenderer = new HelpRenderer(this.messageBridge, this.commands);
|
||||
}
|
||||
|
||||
private void initCommandManager() {
|
||||
ExceptionController<CommandSource<?>> exceptionController = this.commandManager.exceptionController();
|
||||
// We need to unwrap ArgumentParseException because they wrap the custom exception messages
|
||||
exceptionController.registerHandler(ArgumentParseException.class,
|
||||
ExceptionHandler.unwrappingHandler(AreaShopCommandException.class));
|
||||
exceptionController.registerHandler(CommandExecutionException.class,
|
||||
ExceptionHandler.unwrappingHandler(AreaShopCommandException.class));
|
||||
exceptionController.registerHandler(InvalidCommandSenderException.class,
|
||||
new InvalidCommandSenderHandler(this.messageBridge));
|
||||
exceptionController.registerHandler(AreaShopCommandException.class,
|
||||
new ArgumentParseExceptionHandler<>(this.messageBridge));
|
||||
var confirmationConfiguration = ConfirmationConfiguration.<CommandSource<?>>builder()
|
||||
.cache(GuavaCache.of(CacheBuilder.newBuilder().build()))
|
||||
.noPendingCommandNotifier(x -> {
|
||||
})
|
||||
.confirmationRequiredNotifier((x, y) -> {
|
||||
})
|
||||
.build();
|
||||
var confirmationManager = ConfirmationManager.confirmationManager(confirmationConfiguration);
|
||||
commandManager.registerCommandPostProcessor(confirmationManager.createPostprocessor());
|
||||
}
|
||||
|
||||
public void showHelp(@Nonnull CommandSender sender) {
|
||||
if (this.helpRenderer == null) {
|
||||
throw new IllegalStateException("Command handler not yet initialized!");
|
||||
}
|
||||
this.helpRenderer.showHelp(sender);
|
||||
}
|
||||
|
||||
}
|
||||
Loaded 100 of 304 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user