mirror of
https://github.com/md5sha256/AreaShop.git
synced 2026-11-06 17:32:43 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
6886db8edc | ||
|
|
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 | ||
|
|
b3ea7f7e73 | ||
|
|
24ee8df215 | ||
|
|
63e8f10e20 | ||
|
|
7c03041ae1 | ||
|
|
fb03baf3ad | ||
|
|
c1ef15193c | ||
|
|
c1e89ef75e | ||
|
|
56a35d373b | ||
|
|
5aff3f1ce6 | ||
|
|
6a4b8f9d9a | ||
|
|
ef4b599897 | ||
|
|
a04b96d452 | ||
|
|
0728ce672d | ||
|
|
c42e1ccbe5 | ||
|
|
dfcd896cab | ||
|
|
69ee2d5c7f | ||
|
|
b42bb38e5f | ||
|
|
418b736fae | ||
|
|
bed4bbac23 | ||
|
|
f13534ae33 | ||
|
|
3b1522bad8 | ||
|
|
2995b59070 | ||
|
|
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@v2
|
||||
- uses: gradle/wrapper-validation-action@v1.0.4
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'zulu'
|
||||
cache: 'gradle'
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew clean build
|
||||
+194
@@ -0,0 +1,194 @@
|
||||
|
||||
# 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
|
||||
@@ -1,2 +0,0 @@
|
||||
/.project
|
||||
/.classpath
|
||||
@@ -1 +0,0 @@
|
||||
/org.eclipse.jdt.core.prefs
|
||||
@@ -1 +0,0 @@
|
||||
/nl
|
||||
@@ -0,0 +1,94 @@
|
||||
plugins {
|
||||
id("com.github.johnrengelman.shadow") version "7.1.2"
|
||||
}
|
||||
|
||||
description = "AreaShop"
|
||||
|
||||
dependencies {
|
||||
// Platform
|
||||
compileOnlyApi(libs.spigot)
|
||||
compileOnlyApi(libs.worldeditCore) {
|
||||
exclude("com.google.guava", "guava")
|
||||
}
|
||||
compileOnlyApi(libs.worldeditBukkit) {
|
||||
exclude("com.google.guava", "guava")
|
||||
}
|
||||
compileOnlyApi(libs.worldguardCore) {
|
||||
exclude("com.google.guava", "guava")
|
||||
}
|
||||
compileOnlyApi(libs.worldguardBukkit) {
|
||||
exclude("com.google.guava", "guava")
|
||||
}
|
||||
compileOnlyApi("com.github.MilkBowl:VaultAPI:1.7") {
|
||||
exclude("com.google.guava", "guava")
|
||||
}
|
||||
|
||||
// 3rd party libraries
|
||||
implementation(libs.findbugs)
|
||||
implementation("io.papermc:paperlib:1.0.7")
|
||||
implementation("com.github.NLthijs48:InteractiveMessenger:e7749258ca")
|
||||
implementation("com.github.NLthijs48:BukkitDo:819d51ec2b")
|
||||
implementation("io.github.baked-libs:dough-data:1.0.3")
|
||||
implementation("com.google.inject:guice:5.1.0") {
|
||||
exclude("com.google.guava", "guava")
|
||||
}
|
||||
implementation("com.google.inject.extensions:guice-assistedinject:5.1.0") {
|
||||
exclude("com.google.guava", "guava")
|
||||
}
|
||||
|
||||
// Project submodules
|
||||
implementation(projects.areashopInterface)
|
||||
implementation(projects.areashopNms)
|
||||
// Adapters
|
||||
runtimeOnly(projects.adapters.plugins.worldedit)
|
||||
runtimeOnly(projects.adapters.plugins.worldguard)
|
||||
runtimeOnly(projects.adapters.plugins.fastasyncworldedit)
|
||||
runtimeOnly(project(":adapters:platform:bukkit-1-17", "reobf"))
|
||||
runtimeOnly(project(":adapters:platform:bukkit-1-18", "reobf"))
|
||||
runtimeOnly(project(":adapters:platform:bukkit-1-19", "reobf"))
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
tasks {
|
||||
processResources {
|
||||
filesMatching("plugin.yml") {
|
||||
expand("version" to project.version)
|
||||
}
|
||||
}
|
||||
|
||||
assemble {
|
||||
dependsOn(shadowJar)
|
||||
}
|
||||
|
||||
jar {
|
||||
archiveClassifier.set("original")
|
||||
}
|
||||
|
||||
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("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("org.aopalliance", "${base}.aopalliance")
|
||||
relocate("javax.annotation", "${base}.javax.annotation")
|
||||
relocate("javax.inject", "${base}.javax.inject")
|
||||
}
|
||||
}
|
||||
@@ -1,64 +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 Prison server for a demo #
|
||||
##############################################
|
||||
|
||||
########## GENERAL ##########
|
||||
## Chatprefix used for all messages in the chat
|
||||
chatPrefix: '&2[AreaShop]&r '
|
||||
## The character used for the prices of regions, for the euro character use '%euro%'
|
||||
moneyCharacter: '$'
|
||||
## 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
|
||||
## Maximum total amount of rents and buys together
|
||||
maximumTotal: 1
|
||||
|
||||
########## RENTING ##########
|
||||
## The tag you have to write on the sign for renting a region
|
||||
rentSign: '[rent]'
|
||||
## The line that should be placed on the sign when the region is not rented
|
||||
signRentable: '&2&l[For Rent]'
|
||||
## The line that should be placed on the sign when the region is rented
|
||||
signRented: '&4&l[Rented]'
|
||||
## How much regions a player can rent at the same time, -1 for not limited
|
||||
maximumRents: 1
|
||||
## The percentage of the renting price you get back if you unrent the region (price of time left will be multiplied by this/100)
|
||||
rentMoneyBack: 100
|
||||
## How much seconds between checking if renting has expired (don't put this to low)
|
||||
checkDelay: 60
|
||||
## Flags for the 'For Rent' regions, flags and options to apply when the region is not rented
|
||||
## All region flags can be used + members, owners, priority and parent.
|
||||
flagsForRent:
|
||||
members: -%player%
|
||||
greeting: '%region% can be rented for %price% per %duration%'
|
||||
## Flags for the 'Rented' regions, flags and options to apply when the region is rented
|
||||
## All region flags can be used + members, owners, priority and parent.
|
||||
flagsRented:
|
||||
members: +%player%
|
||||
greeting: '%region% is rented by %player% until %until%'
|
||||
|
||||
########## BUYING ##########
|
||||
## The tag you have to write on the sign for renting a region
|
||||
buySign: '[buy]'
|
||||
## The line that should be placed on the sign when the region is not sold
|
||||
signBuyable: '&2&l[For Sale]'
|
||||
## The line that should be placed on the sign when the region is sold
|
||||
signBuyed: '&4&l[Sold]'
|
||||
## How much regions a player can buy at the same time, -1 for not limited
|
||||
maximumBuys: 1
|
||||
## The percentage of the buying price you get back if you sell the region
|
||||
buyMoneyBack: 100
|
||||
## Flags for the 'For Sale' regions, flags and options to apply when the region is for sale
|
||||
## All region flags can be used + members, owners, priority and parent.
|
||||
flagsForSale:
|
||||
members: -%player%
|
||||
greeting: '%region% can be bought for %price%'
|
||||
## Flags for the 'Sold' regions, flags and options to apply when the region is rented
|
||||
## All region flags can be used + members, owners, priority and parent.
|
||||
flagsSold:
|
||||
members: +%player%
|
||||
greeting: '%region% is bought by %player%'
|
||||
@@ -1,116 +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) #
|
||||
###################################################
|
||||
|
||||
########## Command 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"
|
||||
|
||||
rent-regionNotRentable: "That region is not available for renting"
|
||||
rent-help: "/as rent <regionname>"
|
||||
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 /rs 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"
|
||||
|
||||
buy-help: "/as buy <regionname>"
|
||||
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>"
|
||||
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>"
|
||||
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"
|
||||
|
||||
rentsigns-updated: "All signs for renting have been updated"
|
||||
rentsigns-notUpdated: "Not all signs have been updated, maybe reload fixes it"
|
||||
rentsgins-noPermission: "You don't have permission to update all rentsigns"
|
||||
|
||||
buysigns-updated: "All signs for selling have been updated"
|
||||
buysigns-notUpdated: "Not all signs have been updated, maybe reload fixes it"
|
||||
buysigns-noPermission: "You don't have permission to update all buysigns"
|
||||
|
||||
rentregions-updated: "All renting regions have been updated"
|
||||
rentregions-noPermission: "You don't have permission to update all renting regions"
|
||||
|
||||
buyregions-updated: "All buying regions have been updated"
|
||||
buyregions-noPermission: "You don't have permission to update all buying regions"
|
||||
|
||||
reload-reloaded: "The config has been reloaded successfully"
|
||||
reload-noPermission: "You don't have permission to reload the config"
|
||||
|
||||
info-help: "/rs info <all|rented|forrent|sold|forsale|player|region>"
|
||||
info-all-rents: "Regions registered for renting: %0%"
|
||||
info-all-noRents: "There are no regions registered for renting"
|
||||
info-all-buys: "Regions registered for buying: %0%"
|
||||
info-all-noBuys: "There are no regions registered for buying"
|
||||
info-rented: "Rented regions: %0%"
|
||||
info-noRented: "No regions are rented"
|
||||
info-unrented: "Unrented regions: %0%"
|
||||
info-noUnrented: "All regions are rented"
|
||||
info-sold: "Sold regions: %0%"
|
||||
info-noSold: "No regions are sold"
|
||||
info-forsale: "Regions for sale: %0%"
|
||||
info-noForsale: "All regions are sold"
|
||||
info-playerHelp: "/rs info player <name>"
|
||||
info-playerRents: "Regions rented by %0%: %1%"
|
||||
info-playerNoRents: "%0% has not rented a region"
|
||||
info-playerBuys: "Regions bought by %0%: %1%"
|
||||
info-playerNoBuys: "%0% has not bought a region"
|
||||
info-regionHelp: "/rs info region <name>"
|
||||
info-regionNoRenting: "%0% is not registered for renting"
|
||||
info-regionRenting: "&6Renting details for %0%"
|
||||
info-regionRentedBy: "Rented by: %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: %0%"
|
||||
info-regionSign: "Sign position: world=%0%, X=%1%, Y=%2%, Z=%3%"
|
||||
info-regionPriceDuration: "Price: %0% for each %1%"
|
||||
info-regionPrice: "Price: %0%"
|
||||
|
||||
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-updaterentsigns: "&6/as updaterentsigns &7-&r Update all rent signs"
|
||||
help-updatebuysigns: "&6/as updatebuysigns &7-&r Update all buy signs"
|
||||
help-updaterentregions: "&6/as updaterentregions &7-&r Update all rent regions"
|
||||
help-updatebuyregions: "&6/as updatebuyregions &7-&r Update all buy regions"
|
||||
help-reload: "&6/as reload &7-&r Reload the config and languages"
|
||||
@@ -1,116 +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) #
|
||||
###################################################
|
||||
|
||||
########## 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 '/rs 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 /rs 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"
|
||||
|
||||
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"
|
||||
|
||||
rentsigns-updated: "Alle bordjes voor de verhuur zijn geupdate"
|
||||
rentsigns-notUpdated: "Niet alle bordjes zijn geupdate, een reload zou het op kunnen lossen"
|
||||
rentsgins-noPermission: "Je hebt geen toestemming om alle verhuur bordjes te updaten"
|
||||
|
||||
buysigns-updated: "All bordjes voor de verkoop zijn geupdate"
|
||||
buysigns-notUpdated: "Niet alle bordjes zijn geupdate, een reload zou het op kunnen lossen"
|
||||
buysigns-noPermission: "Je hebt geen toestemming om alle verkoop bordjes te updaten"
|
||||
|
||||
rentregions-updated: "Alle verhuur gebieden zijn geupdate"
|
||||
rentregions-noPermission: "Je hebt geen toestemming om de verhuur gebieden te updaten"
|
||||
|
||||
buyregions-updated: "Alle verkoop gebieden zijn geupdate"
|
||||
buyregions-noPermission: "Je hebt geen toestemming om alle verkoop 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: "/rs 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: "/rs 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%"
|
||||
|
||||
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-updaterentsigns: "&6/as updaterentsigns &7-&r Update alle huur borden"
|
||||
help-updatebuysigns: "&6/as updatebuysigns &7-&r Update alle koop borden"
|
||||
help-updaterentregions: "&6/as updaterentregions &7-&r Update alle huur gebieden"
|
||||
help-updatebuyregions: "&6/as updatebuyregions &7-&r Update alle koop gebieden"
|
||||
help-reload: "&6/as reload &7-&r Herlaad de config en de taalbestanden"
|
||||
@@ -1,80 +0,0 @@
|
||||
name: AreaShop
|
||||
main: nl.evolutioncoding.AreaShop.AreaShop
|
||||
version: 1.0
|
||||
depend: [Vault, WorldGuard]
|
||||
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 RegionRent
|
||||
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.updaterentsigns: true
|
||||
areashop.updatebuysigns: true
|
||||
areashop.updaterentregions: true
|
||||
areashop.updatebuyregions: true
|
||||
areashop.reload: 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.updaterentsigns:
|
||||
description: Allows you to update all rent signs
|
||||
default: op
|
||||
areashop.updatebuysigns:
|
||||
description: Allows you to update all buy signs
|
||||
default: op
|
||||
areashop.updaterentregions:
|
||||
description: Allows you to update all rent regions
|
||||
default: op
|
||||
areashop.updatebuyregions:
|
||||
description: Allows you to update all buy regions
|
||||
default: op
|
||||
areashop.reload:
|
||||
description: Allows you to reload the config
|
||||
default: op
|
||||
@@ -0,0 +1,760 @@
|
||||
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 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.CommandManager;
|
||||
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.nms.NMS;
|
||||
import me.wiefferink.areashop.tools.GithubUpdateCheck;
|
||||
import me.wiefferink.areashop.tools.SimpleMessageBridge;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
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 javax.annotation.Nonnull;
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* 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 NMS nms;
|
||||
private MessageBridge messageBridge;
|
||||
private IFileManager fileManager = null;
|
||||
private LanguageManager languageManager = null;
|
||||
private CommandManager commandManager = 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;
|
||||
|
||||
// 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();
|
||||
signErrorLogger = new SignErrorLogger(new File(getDataFolder(), signLogFile));
|
||||
|
||||
// Setup NMS Impl
|
||||
String rawServerVersion = Bukkit.getServer().getClass().getPackageName();
|
||||
String[] split = rawServerVersion.split("\\.");
|
||||
String serverVersion = split[3];
|
||||
try {
|
||||
Class<?> nmsImpl = Class.forName("me.wiefferink.areashop.adapters.platform." + serverVersion + ".NMSImpl");
|
||||
this.nms = nmsImpl.asSubclass(NMS.class).getConstructor().newInstance();
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
ex.printStackTrace();
|
||||
error("Failed to initialize NMS implementation!");
|
||||
shutdownOnError();
|
||||
return;
|
||||
}
|
||||
|
||||
// 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, messageBridge, nms, worldEditInterface, worldGuardInterface, signErrorLogger, 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;
|
||||
}
|
||||
|
||||
setupLanguageManager();
|
||||
|
||||
featureManager = injector.getInstance(FeatureManager.class);
|
||||
featureManager.initializeFeatures(injector);
|
||||
managers.add(featureManager);
|
||||
signManager = new SignManager();
|
||||
managers.add(signManager);
|
||||
|
||||
// Register the event listeners
|
||||
getServer().getPluginManager().registerEvents(new PlayerLoginLogoutListener(this, messageBridge), this);
|
||||
|
||||
setupTasks();
|
||||
|
||||
// Startup the CommandManager (registers itself for the command)
|
||||
commandManager = injector.getInstance(CommandManager.class);
|
||||
managers.add(commandManager);
|
||||
|
||||
// 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) ->
|
||||
!cleanVersion(latestVersion).equals(cleanVersion(currentVersion))
|
||||
).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/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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup a new LanguageManager.
|
||||
*/
|
||||
private void setupLanguageManager() {
|
||||
languageManager = new LanguageManager(
|
||||
this,
|
||||
languageFolder,
|
||||
getConfig().getString("language"),
|
||||
"EN",
|
||||
chatprefix
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 NMS getNms() {
|
||||
return nms;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to get the CommandManager.
|
||||
* @return the CommandManager
|
||||
*/
|
||||
@Nonnull
|
||||
@Override
|
||||
public CommandManager getCommandManager() {
|
||||
return commandManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to get the Vault plugin.
|
||||
* @return Economy
|
||||
*/
|
||||
@Deprecated
|
||||
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
|
||||
*/
|
||||
@Deprecated
|
||||
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,39 @@
|
||||
package me.wiefferink.areashop;
|
||||
|
||||
import me.wiefferink.areashop.features.signs.SignManager;
|
||||
import me.wiefferink.areashop.interfaces.AreaShopInterface;
|
||||
import me.wiefferink.areashop.managers.CommandManager;
|
||||
import me.wiefferink.areashop.managers.FeatureManager;
|
||||
import me.wiefferink.areashop.managers.SignLinkerManager;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public interface AreaShopApi extends AreaShopInterface {
|
||||
|
||||
/**
|
||||
* Function to get the CommandManager.
|
||||
*
|
||||
* @return the CommandManager
|
||||
*/
|
||||
@Nonnull CommandManager getCommandManager();
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package me.wiefferink.areashop;
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -0,0 +1,346 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
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.WorldEditSelection;
|
||||
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 javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeSet;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Singleton
|
||||
public class AddCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
@Inject
|
||||
private AreaShop plugin;
|
||||
@Inject
|
||||
private WorldEditInterface worldEditInterface;
|
||||
@Inject
|
||||
private WorldGuardInterface worldGuardInterface;
|
||||
@Inject
|
||||
private RegionFactory regionFactory;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop add";
|
||||
}
|
||||
|
||||
@Override
|
||||
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
|
||||
public void execute(final CommandSender sender, final String[] args) {
|
||||
if(!sender.hasPermission("areashop.createrent")
|
||||
&& !sender.hasPermission("areashop.createrent.member")
|
||||
&& !sender.hasPermission("areashop.createrent.owner")
|
||||
|
||||
&& !sender.hasPermission("areashop.createbuy")
|
||||
&& !sender.hasPermission("areashop.createbuy.member")
|
||||
&& !sender.hasPermission("areashop.createbuy.owner")) {
|
||||
messageBridge.message(sender, "add-noPermission");
|
||||
return;
|
||||
}
|
||||
|
||||
if(args.length < 2 || args[1] == null || (!"rent".equalsIgnoreCase(args[1]) && !"buy".equalsIgnoreCase(args[1]))) {
|
||||
messageBridge.message(sender, "add-help");
|
||||
return;
|
||||
}
|
||||
Map<String, ProtectedRegion> regions = new HashMap<>();
|
||||
World world;
|
||||
Player player = null;
|
||||
if(sender instanceof Player) {
|
||||
player = (Player)sender;
|
||||
}
|
||||
if(args.length == 2) {
|
||||
if(player == null) {
|
||||
messageBridge.message(sender, "cmd-weOnlyByPlayer");
|
||||
return;
|
||||
}
|
||||
WorldEditSelection selection = worldEditInterface.getPlayerSelection(player);
|
||||
if(selection == null) {
|
||||
messageBridge.message(player, "cmd-noSelection");
|
||||
return;
|
||||
}
|
||||
world = selection.getWorld();
|
||||
regions = Utils.getWorldEditRegionsInSelection(selection).stream().collect(Collectors.toMap(ProtectedRegion::getId, region -> region));
|
||||
if(regions.isEmpty()) {
|
||||
messageBridge.message(player, "cmd-noWERegionsFound");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if(player != null) {
|
||||
if(args.length == 4) {
|
||||
world = Bukkit.getWorld(args[3]);
|
||||
if(world == null) {
|
||||
messageBridge.message(sender, "add-incorrectWorld", args[3]);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
world = ((Player)sender).getWorld();
|
||||
}
|
||||
} else {
|
||||
if(args.length < 4) {
|
||||
messageBridge.message(sender, "add-specifyWorld");
|
||||
return;
|
||||
} else {
|
||||
world = Bukkit.getWorld(args[3]);
|
||||
if(world == null) {
|
||||
messageBridge.message(sender, "add-incorrectWorld", args[3]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
ProtectedRegion region = plugin.getRegionManager(world).getRegion(args[2]);
|
||||
if(region == null) {
|
||||
messageBridge.message(sender, "cmd-noRegion", args[2]);
|
||||
return;
|
||||
}
|
||||
regions.put(args[2], region);
|
||||
}
|
||||
final boolean isRent = "rent".equalsIgnoreCase(args[1]);
|
||||
final Player finalPlayer = player;
|
||||
AreaShop.debug("Starting add task with " + regions.size() + " regions");
|
||||
|
||||
TreeSet<GeneralRegion> regionsSuccess = new TreeSet<>();
|
||||
TreeSet<GeneralRegion> regionsAlready = new TreeSet<>();
|
||||
TreeSet<GeneralRegion> regionsAlreadyOtherWorld = new TreeSet<>();
|
||||
TreeSet<GeneralRegion> regionsRentCancelled = new TreeSet<>(); // Denied by an event listener
|
||||
TreeSet<GeneralRegion> regionsBuyCancelled = new TreeSet<>(); // Denied by an event listener
|
||||
TreeSet<String> namesBlacklisted = new TreeSet<>();
|
||||
TreeSet<String> namesNoPermission = new TreeSet<>();
|
||||
TreeSet<String> namesAddCancelled = new TreeSet<>(); // Denied by an event listener
|
||||
Do.forAll(
|
||||
plugin.getConfig().getInt("adding.regionsPerTick"),
|
||||
regions.entrySet(),
|
||||
regionEntry -> {
|
||||
String regionName = regionEntry.getKey();
|
||||
ProtectedRegion region = regionEntry.getValue();
|
||||
// Determine if the player is an owner or member of the region
|
||||
boolean isMember = finalPlayer != null && worldGuardInterface.containsMember(region, finalPlayer.getUniqueId());
|
||||
boolean isOwner = finalPlayer != null && worldGuardInterface.containsOwner(region, finalPlayer.getUniqueId());
|
||||
String type;
|
||||
if(isRent) {
|
||||
type = "rent";
|
||||
} else {
|
||||
type = "buy";
|
||||
}
|
||||
IFileManager.AddResult result = plugin.getFileManager().checkRegionAdd(sender, region, world, isRent ? GeneralRegion.RegionType.RENT : GeneralRegion.RegionType.BUY);
|
||||
if(result == IFileManager.AddResult.ALREADYADDED) {
|
||||
regionsAlready.add(plugin.getFileManager().getRegion(regionName));
|
||||
} else if(result == IFileManager.AddResult.ALREADYADDEDOTHERWORLD) {
|
||||
regionsAlreadyOtherWorld.add(plugin.getFileManager().getRegion(regionName));
|
||||
} else if(result == IFileManager.AddResult.BLACKLISTED) {
|
||||
namesBlacklisted.add(regionName);
|
||||
} else if(result == IFileManager.AddResult.NOPERMISSION) {
|
||||
namesNoPermission.add(regionName);
|
||||
} else {
|
||||
// Check if the player should be landlord
|
||||
boolean landlord = (!sender.hasPermission("areashop.create" + type)
|
||||
&& ((sender.hasPermission("areashop.create" + type + ".owner") && isOwner)
|
||||
|| (sender.hasPermission("areashop.create" + type + ".member") && isMember)));
|
||||
List<UUID> existing = new ArrayList<>();
|
||||
existing.addAll(worldGuardInterface.getOwners(region).asUniqueIdList());
|
||||
existing.addAll(worldGuardInterface.getMembers(region).asUniqueIdList());
|
||||
|
||||
AreaShop.debug("regionAddLandlordStatus:", regionName,
|
||||
"landlord:", landlord,
|
||||
"existing:", existing,
|
||||
"isMember:", isMember,
|
||||
"isOwner:", isOwner,
|
||||
"createPermission:", sender.hasPermission("areashop.create" + type),
|
||||
"ownerPermission:", sender.hasPermission("areashop.create" + type + ".owner"),
|
||||
"memberPermission:", sender.hasPermission("areashop.create" + type + ".member"));
|
||||
|
||||
if(isRent) {
|
||||
RentRegion rent = regionFactory.createRentRegion(regionName, world);
|
||||
// Set landlord
|
||||
if(landlord) {
|
||||
rent.setLandlord(finalPlayer.getUniqueId(), finalPlayer.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.remove(0);
|
||||
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);
|
||||
} else {
|
||||
BuyRegion buy = regionFactory.createBuyRegion(regionName, world);
|
||||
// Set landlord
|
||||
if(landlord) {
|
||||
buy.setLandlord(finalPlayer.getUniqueId(), finalPlayer.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.remove(0);
|
||||
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);
|
||||
}
|
||||
}
|
||||
},
|
||||
() -> {
|
||||
if(!regionsSuccess.isEmpty()) {
|
||||
messageBridge.message(sender, "add-success", args[1], Utils.combinedMessage(regionsSuccess, "region"));
|
||||
}
|
||||
if(!regionsAlready.isEmpty()) {
|
||||
messageBridge.message(sender, "add-failed", Utils.combinedMessage(regionsAlready, "region"));
|
||||
}
|
||||
if(!regionsAlreadyOtherWorld.isEmpty()) {
|
||||
messageBridge.message(sender, "add-failedOtherWorld", Utils.combinedMessage(regionsAlreadyOtherWorld, "region"));
|
||||
}
|
||||
if(!regionsRentCancelled.isEmpty()) {
|
||||
messageBridge.message(sender, "add-rentCancelled", Utils.combinedMessage(regionsRentCancelled, "region"));
|
||||
}
|
||||
if(!regionsBuyCancelled.isEmpty()) {
|
||||
messageBridge.message(sender, "add-buyCancelled", Utils.combinedMessage(regionsBuyCancelled, "region"));
|
||||
}
|
||||
if(!namesBlacklisted.isEmpty()) {
|
||||
messageBridge.message(sender, "add-blacklisted", Utils.createCommaSeparatedList(namesBlacklisted));
|
||||
}
|
||||
if(!namesNoPermission.isEmpty()) {
|
||||
messageBridge.message(sender, "add-noPermissionRegions", Utils.createCommaSeparatedList(namesNoPermission));
|
||||
messageBridge.message(sender, "add-noPermissionOwnerMember");
|
||||
}
|
||||
if(!namesAddCancelled.isEmpty()) {
|
||||
messageBridge.message(sender, "add-rentCancelled", Utils.createCommaSeparatedList(namesAddCancelled));
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
List<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
if(sender.hasPermission("areashop.createrent")) {
|
||||
result.add("rent");
|
||||
}
|
||||
if(sender.hasPermission("areashop.createbuy")) {
|
||||
result.add("buy");
|
||||
}
|
||||
} else if(toComplete == 3) {
|
||||
if(sender instanceof Player) {
|
||||
Player player = (Player)sender;
|
||||
if(sender.hasPermission("areashop.createrent") || sender.hasPermission("areashop.createbuy")) {
|
||||
for(ProtectedRegion region : plugin.getRegionManager(player.getWorld()).getRegions().values()) {
|
||||
result.add(region.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
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.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Singleton
|
||||
public class AddfriendCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
@Inject
|
||||
private IFileManager fileManager;
|
||||
@Inject
|
||||
private Plugin plugin;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop addfriend";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.addfriendall") || target.hasPermission("areashop.addfriend")) {
|
||||
return "help-addFriend";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.addfriend") && !sender.hasPermission("areashop.addfriendall")) {
|
||||
messageBridge.message(sender, "addfriend-noPermission");
|
||||
return;
|
||||
}
|
||||
|
||||
if(args.length < 2) {
|
||||
messageBridge.message(sender, "addfriend-help");
|
||||
return;
|
||||
}
|
||||
|
||||
GeneralRegion region;
|
||||
if(args.length <= 2) {
|
||||
if(sender instanceof Player) {
|
||||
// get the region by location
|
||||
List<GeneralRegion> regions = Utils.getImportantRegions(((Player)sender).getLocation());
|
||||
if(regions.isEmpty()) {
|
||||
messageBridge.message(sender, "cmd-noRegionsAtLocation");
|
||||
return;
|
||||
} else if(regions.size() > 1) {
|
||||
messageBridge.message(sender, "cmd-moreRegionsAtLocation");
|
||||
return;
|
||||
} else {
|
||||
region = regions.get(0);
|
||||
}
|
||||
} else {
|
||||
messageBridge.message(sender, "cmd-automaticRegionOnlyByPlayer");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
region = fileManager.getRegion(args[2]);
|
||||
if(region == null) {
|
||||
messageBridge.message(sender, "cmd-notRegistered", args[2]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(sender.hasPermission("areashop.addfriendall")) {
|
||||
if((region instanceof RentRegion && !((RentRegion)region).isRented())
|
||||
|| (region instanceof BuyRegion && !((BuyRegion)region).isSold())) {
|
||||
messageBridge.message(sender, "addfriend-noOwner", region);
|
||||
return;
|
||||
}
|
||||
OfflinePlayer friend = Bukkit.getOfflinePlayer(args[1]);
|
||||
if(friend.getLastPlayed() == 0 && !friend.isOnline() && !plugin.getConfig().getBoolean("addFriendNotExistingPlayers")) {
|
||||
messageBridge.message(sender, "addfriend-notVisited", args[1], region);
|
||||
return;
|
||||
}
|
||||
if(region.getFriendsFeature().getFriends().contains(friend.getUniqueId())) {
|
||||
messageBridge.message(sender, "addfriend-alreadyAdded", friend.getName(), region);
|
||||
return;
|
||||
}
|
||||
if(region.isOwner(friend.getUniqueId())) {
|
||||
messageBridge.message(sender, "addfriend-self", friend.getName(), region);
|
||||
return;
|
||||
}
|
||||
if(region.getFriendsFeature().addFriend(friend.getUniqueId(), sender)) {
|
||||
region.update();
|
||||
messageBridge.message(sender, "addfriend-successOther", friend.getName(), region);
|
||||
}
|
||||
} else {
|
||||
if(sender.hasPermission("areashop.addfriend") && sender instanceof Player) {
|
||||
if(region.isOwner((Player)sender)) {
|
||||
OfflinePlayer friend = Bukkit.getOfflinePlayer(args[1]);
|
||||
if(friend.getLastPlayed() == 0 && !friend.isOnline() && !plugin.getConfig().getBoolean("addFriendNotExistingPlayers")) {
|
||||
messageBridge.message(sender, "addfriend-notVisited", args[1], region);
|
||||
return;
|
||||
}
|
||||
if(region.getFriendsFeature().getFriends().contains(friend.getUniqueId())) {
|
||||
messageBridge.message(sender, "addfriend-alreadyAdded", friend.getName(), region);
|
||||
return;
|
||||
}
|
||||
if(region.isOwner(friend.getUniqueId())) {
|
||||
messageBridge.message(sender, "addfriend-self", friend.getName(), region);
|
||||
return;
|
||||
}
|
||||
|
||||
if(region.getFriendsFeature().addFriend(friend.getUniqueId(), sender)) {
|
||||
region.update();
|
||||
messageBridge.message(sender, "addfriend-success", friend.getName(), region);
|
||||
}
|
||||
} else {
|
||||
messageBridge.message(sender, "addfriend-noPermissionOther", region);
|
||||
}
|
||||
} else {
|
||||
messageBridge.message(sender, "addfriend-noPermission", region);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
for(Player player : Utils.getOnlinePlayers()) {
|
||||
result.add(player.getName());
|
||||
}
|
||||
} else if(toComplete == 3) {
|
||||
result.addAll(fileManager.getRegionNames());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
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 me.wiefferink.areashop.tools.Utils;
|
||||
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 javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
@Singleton
|
||||
public class AddsignCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
@Inject
|
||||
private IFileManager fileManager;
|
||||
@Inject
|
||||
private SignManager signManager;
|
||||
@Inject
|
||||
private Plugin plugin;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop addsign";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.addsign")) {
|
||||
return "help-addsign";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.addsign")) {
|
||||
messageBridge.message(sender, "addsign-noPermission");
|
||||
return;
|
||||
}
|
||||
if(!(sender instanceof Player)) {
|
||||
messageBridge.message(sender, "cmd-onlyByPlayer");
|
||||
return;
|
||||
}
|
||||
Player player = (Player)sender;
|
||||
|
||||
// Get the sign
|
||||
Block block = null;
|
||||
BlockIterator blockIterator = new BlockIterator(player, 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;
|
||||
if(args.length > 1) {
|
||||
// Get region by argument
|
||||
region = fileManager.getRegion(args[1]);
|
||||
if(region == null) {
|
||||
messageBridge.message(sender, "cmd-notRegistered", args[1]);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Get region by sign position
|
||||
List<GeneralRegion> regions = Utils.getImportantRegions(block.getLocation());
|
||||
if(regions.isEmpty()) {
|
||||
messageBridge.message(sender, "addsign-noRegions");
|
||||
return;
|
||||
} else if(regions.size() > 1) {
|
||||
messageBridge.message(sender, "addsign-couldNotDetect", regions.get(0).getName(), regions.get(1).getName());
|
||||
return;
|
||||
}
|
||||
region = regions.get(0);
|
||||
}
|
||||
String profile = null;
|
||||
if(args.length > 2) {
|
||||
profile = args[2];
|
||||
Set<String> profiles = plugin.getConfig().getConfigurationSection("signProfiles").getKeys(false);
|
||||
if(!profiles.contains(profile)) {
|
||||
messageBridge.message(sender, "addsign-wrongProfile", Utils.createCommaSeparatedList(profiles), region);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Optional<RegionSign> optionalRegionSign = 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
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
List<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
result.addAll(fileManager.getRegionNames());
|
||||
} else if(toComplete == 3) {
|
||||
result.addAll(plugin.getConfig().getStringList("signProfiles"));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Singleton
|
||||
public class BuyCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
@Inject
|
||||
private Plugin plugin;
|
||||
@Inject
|
||||
private IFileManager fileManager;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop buy";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.buy")) {
|
||||
return "help-buy";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.buy")) {
|
||||
messageBridge.message(sender, "buy-noPermission");
|
||||
return;
|
||||
}
|
||||
if(!(sender instanceof Player)) {
|
||||
messageBridge.message(sender, "cmd-onlyByPlayer");
|
||||
return;
|
||||
}
|
||||
Player player = (Player)sender;
|
||||
if(args.length > 1 && args[1] != null) {
|
||||
BuyRegion region = fileManager.getBuy(args[1]);
|
||||
if(region == null) {
|
||||
messageBridge.message(player, "buy-notBuyable", args[1]);
|
||||
} else {
|
||||
region.buy(player);
|
||||
}
|
||||
} else {
|
||||
// get the region by location
|
||||
List<BuyRegion> regions = Utils.getImportantBuyRegions(((Player)sender).getLocation());
|
||||
if(regions.isEmpty()) {
|
||||
messageBridge.message(sender, "cmd-noRegionsAtLocation");
|
||||
} else if(regions.size() > 1) {
|
||||
messageBridge.message(sender, "cmd-moreRegionsAtLocation");
|
||||
} else {
|
||||
regions.get(0).buy(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
for(BuyRegion region : fileManager.getBuysRef()) {
|
||||
if(!region.isSold()) {
|
||||
result.add(region.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.interactivemessenger.processing.Message;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Abstract class for generalising command classes.
|
||||
*/
|
||||
public abstract class CommandAreaShop {
|
||||
|
||||
private final Map<String, CommandTime> lastUsed;
|
||||
|
||||
protected CommandAreaShop() {
|
||||
lastUsed = new HashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this Command instance can execute the given command and arguments.
|
||||
* @param command The command to check for execution
|
||||
* @param args The arguments to check
|
||||
* @return true if it can execute the command, false otherwise
|
||||
*/
|
||||
public boolean canExecute(Command command, String[] args) {
|
||||
String commandString = command.getName() + " " + StringUtils.join(args, " ");
|
||||
if(commandString.length() > getCommandStart().length()) {
|
||||
return commandString.toLowerCase().startsWith(getCommandStart().toLowerCase() + " ");
|
||||
}
|
||||
return commandString.toLowerCase().startsWith(getCommandStart().toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of string to complete a command with (raw list, not matching ones not filtered out).
|
||||
* @param toComplete The number of the argument that has to be completed
|
||||
* @param start The already given start of the command
|
||||
* @param sender The CommandSender that wants to tab complete
|
||||
* @return A collection with all the possibilities for argument to complete
|
||||
*/
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the argument that comes after the base command that this command reacts to.
|
||||
* @return The string that should be in front of the command for this class to act
|
||||
*/
|
||||
public abstract String getCommandStart();
|
||||
|
||||
/**
|
||||
* Returns the correct help string key to be used on the help page.
|
||||
* @param target The CommandSender that the help message is for
|
||||
* @return The help message key according to the permissions of the reciever
|
||||
*/
|
||||
public abstract String getHelp(CommandSender target);
|
||||
|
||||
/**
|
||||
* Execute a (sub)command if the conditions are met.
|
||||
* @param sender The commandSender that executed the command
|
||||
* @param args The arguments that are given
|
||||
*/
|
||||
public abstract void execute(CommandSender sender, String[] args);
|
||||
|
||||
/**
|
||||
* Confirm a command.
|
||||
* @param sender To confirm it for, or send a message to confirm
|
||||
* @param args Command args
|
||||
* @param message Message to send when confirmation is required
|
||||
* @return true if confirmed, false if confirmation is required
|
||||
*/
|
||||
public boolean confirm(CommandSender sender, String[] args, Message message) {
|
||||
String command = "/" + getCommandStart() + " " + StringUtils.join(args, " ", 1, args.length);
|
||||
long now = System.currentTimeMillis();
|
||||
CommandTime last = lastUsed.get(sender.getName());
|
||||
if(last != null && last.command.equalsIgnoreCase(command) && last.time > (now - 1000 * 60)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
message.prefix().append(Message.fromKey("confirm-yes").replacements(command)).send(sender);
|
||||
lastUsed.put(sender.getName(), new CommandTime(command, now));
|
||||
return false;
|
||||
}
|
||||
|
||||
private static class CommandTime {
|
||||
public final String command;
|
||||
public final long time;
|
||||
|
||||
CommandTime(String command, long time) {
|
||||
this.command = command;
|
||||
this.time = time;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.events.ask.DeletingRegionEvent;
|
||||
import me.wiefferink.areashop.interfaces.WorldEditInterface;
|
||||
import me.wiefferink.areashop.interfaces.WorldEditSelection;
|
||||
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 javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.TreeSet;
|
||||
|
||||
@Singleton
|
||||
public class DelCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
@Inject
|
||||
private WorldEditInterface worldEditInterface;
|
||||
@Inject
|
||||
private IFileManager fileManager;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop del";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(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
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.destroybuy")
|
||||
&& !sender.hasPermission("areashop.destroybuy.landlord")
|
||||
|
||||
&& !sender.hasPermission("areashop.destroyrent")
|
||||
&& !sender.hasPermission("areashop.destroyrent.landlord")) {
|
||||
messageBridge.message(sender, "del-noPermission");
|
||||
return;
|
||||
}
|
||||
if(args.length < 2) {
|
||||
// Only players can have a selection
|
||||
if(!(sender instanceof Player)) {
|
||||
messageBridge.message(sender, "cmd-weOnlyByPlayer");
|
||||
return;
|
||||
}
|
||||
Player player = (Player)sender;
|
||||
WorldEditSelection selection = worldEditInterface.getPlayerSelection(player);
|
||||
if(selection == null) {
|
||||
messageBridge.message(player, "cmd-noSelection");
|
||||
return;
|
||||
}
|
||||
List<GeneralRegion> regions = Utils.getRegionsInSelection(selection);
|
||||
if(regions == null || regions.isEmpty()) {
|
||||
messageBridge.message(player, "cmd-noRegionsFound");
|
||||
return;
|
||||
}
|
||||
// Start removing the regions that he has permission for
|
||||
ArrayList<String> namesSuccess = new ArrayList<>();
|
||||
TreeSet<GeneralRegion> regionsFailed = new TreeSet<>();
|
||||
TreeSet<GeneralRegion> regionsCancelled = new TreeSet<>();
|
||||
for(GeneralRegion region : regions) {
|
||||
boolean isLandlord = region.isLandlord(((Player)sender).getUniqueId());
|
||||
if(region instanceof RentRegion) {
|
||||
if(!sender.hasPermission("areashop.destroyrent") && !(isLandlord && sender.hasPermission("areashop.destroyrent.landlord"))) {
|
||||
regionsFailed.add(region);
|
||||
continue;
|
||||
}
|
||||
} else if(region instanceof BuyRegion) {
|
||||
if(!sender.hasPermission("areashop.destroybuy") && !(isLandlord && sender.hasPermission("areashop.destroybuy.landlord"))) {
|
||||
regionsFailed.add(region);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
DeletingRegionEvent event = fileManager.deleteRegion(region, true);
|
||||
if (event.isCancelled()) {
|
||||
regionsCancelled.add(region);
|
||||
} else {
|
||||
namesSuccess.add(region.getName());
|
||||
}
|
||||
}
|
||||
|
||||
// Send messages
|
||||
if(!namesSuccess.isEmpty()) {
|
||||
messageBridge.message(sender, "del-success", Utils.createCommaSeparatedList(namesSuccess));
|
||||
}
|
||||
if(!regionsFailed.isEmpty()) {
|
||||
messageBridge.message(sender, "del-failed", Utils.combinedMessage(regionsFailed, "region"));
|
||||
}
|
||||
if(!regionsCancelled.isEmpty()) {
|
||||
messageBridge.message(sender, "del-cancelled", Utils.combinedMessage(regionsCancelled, "region"));
|
||||
}
|
||||
} else {
|
||||
GeneralRegion region = fileManager.getRegion(args[1]);
|
||||
if(region == null) {
|
||||
messageBridge.message(sender, "cmd-notRegistered", args[1]);
|
||||
return;
|
||||
}
|
||||
boolean isLandlord = sender instanceof Player && region.isLandlord(((Player)sender).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()) {
|
||||
messageBridge.message(sender, "general-cancelled", event.getReason());
|
||||
} else {
|
||||
messageBridge.message(sender, "destroy-successRent", region);
|
||||
}
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
List<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
result = fileManager.getRegionNames();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
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.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Singleton
|
||||
public class DelfriendCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
@Inject
|
||||
private IFileManager fileManager;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop delfriend";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.delfriendall") || target.hasPermission("areashop.delfriend")) {
|
||||
return "help-delFriend";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 player = (Player)person;
|
||||
return region.isOwner(player) && player.hasPermission("areashop.delfriend");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.delfriend") && !sender.hasPermission("areashop.delfriendall")) {
|
||||
messageBridge.message(sender, "delfriend-noPermission");
|
||||
return;
|
||||
}
|
||||
if(args.length < 2) {
|
||||
messageBridge.message(sender, "delfriend-help");
|
||||
return;
|
||||
}
|
||||
GeneralRegion region;
|
||||
if(args.length <= 2) {
|
||||
if(sender instanceof Player) {
|
||||
// get the region by location
|
||||
List<GeneralRegion> regions = Utils.getImportantRegions(((Player)sender).getLocation());
|
||||
if(regions.isEmpty()) {
|
||||
messageBridge.message(sender, "cmd-noRegionsAtLocation");
|
||||
return;
|
||||
} else if(regions.size() > 1) {
|
||||
messageBridge.message(sender, "cmd-moreRegionsAtLocation");
|
||||
return;
|
||||
} else {
|
||||
region = regions.get(0);
|
||||
}
|
||||
} else {
|
||||
messageBridge.message(sender, "cmd-automaticRegionOnlyByPlayer");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
region = fileManager.getRegion(args[2]);
|
||||
if(region == null) {
|
||||
messageBridge.message(sender, "cmd-notRegistered", args[2]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(sender.hasPermission("areashop.delfriendall")) {
|
||||
if((region instanceof RentRegion && !((RentRegion)region).isRented())
|
||||
|| (region instanceof BuyRegion && !((BuyRegion)region).isSold())) {
|
||||
messageBridge.message(sender, "delfriend-noOwner", region);
|
||||
return;
|
||||
}
|
||||
OfflinePlayer friend = Bukkit.getOfflinePlayer(args[1]);
|
||||
if(!region.getFriendsFeature().getFriends().contains(friend.getUniqueId())) {
|
||||
messageBridge.message(sender, "delfriend-notAdded", friend.getName(), region);
|
||||
return;
|
||||
}
|
||||
if(region.getFriendsFeature().deleteFriend(friend.getUniqueId(), sender)) {
|
||||
region.update();
|
||||
messageBridge.message(sender, "delfriend-successOther", friend.getName(), region);
|
||||
}
|
||||
} else {
|
||||
if(sender.hasPermission("areashop.delfriend") && sender instanceof Player) {
|
||||
if(region.isOwner((Player)sender)) {
|
||||
OfflinePlayer friend = Bukkit.getOfflinePlayer(args[1]);
|
||||
if(!region.getFriendsFeature().getFriends().contains(friend.getUniqueId())) {
|
||||
messageBridge.message(sender, "delfriend-notAdded", friend.getName(), region);
|
||||
return;
|
||||
}
|
||||
if(region.getFriendsFeature().deleteFriend(friend.getUniqueId(), sender)) {
|
||||
region.update();
|
||||
messageBridge.message(sender, "delfriend-success", friend.getName(), region);
|
||||
}
|
||||
} else {
|
||||
messageBridge.message(sender, "delfriend-noPermissionOther", region);
|
||||
}
|
||||
} else {
|
||||
messageBridge.message(sender, "delfriend-noPermission", region);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
for(Player player : Utils.getOnlinePlayers()) {
|
||||
result.add(player.getName());
|
||||
}
|
||||
} else if(toComplete == 3) {
|
||||
result.addAll(fileManager.getRegionNames());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.features.signs.RegionSign;
|
||||
import me.wiefferink.areashop.features.signs.SignManager;
|
||||
import me.wiefferink.areashop.features.signs.SignsFeature;
|
||||
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 javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Singleton
|
||||
public class DelsignCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
@Inject
|
||||
private SignManager signManager;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop delsign";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.delsign")) {
|
||||
return "help-delsign";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.delsign")) {
|
||||
messageBridge.message(sender, "delsign-noPermission");
|
||||
return;
|
||||
}
|
||||
if(!(sender instanceof Player)) {
|
||||
messageBridge.message(sender, "cmd-onlyByPlayer");
|
||||
return;
|
||||
}
|
||||
Player player = (Player)sender;
|
||||
|
||||
// Get the sign
|
||||
Block block = null;
|
||||
BlockIterator blockIterator = new BlockIterator(player, 100);
|
||||
while(blockIterator.hasNext() && block == null) {
|
||||
Block next = blockIterator.next();
|
||||
if(!next.getType().isAir()) {
|
||||
block = next;
|
||||
}
|
||||
}
|
||||
if(block == null || !Materials.isSign(block.getType())) {
|
||||
messageBridge.message(sender, "delsign-noSign");
|
||||
return;
|
||||
}
|
||||
Optional<RegionSign> optionalSign = signManager.removeSign(block.getLocation());
|
||||
if(optionalSign.isEmpty()) {
|
||||
messageBridge.message(sender, "delsign-noRegion");
|
||||
return;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
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 javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
@Singleton
|
||||
public class FindCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
@Inject
|
||||
private Economy economy;
|
||||
@Inject
|
||||
private IFileManager fileManager;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop find";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.find")) {
|
||||
return "help-find";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.find")) {
|
||||
messageBridge.message(sender, "find-noPermission");
|
||||
return;
|
||||
}
|
||||
if(!(sender instanceof Player)) {
|
||||
messageBridge.message(sender, "cmd-onlyByPlayer");
|
||||
return;
|
||||
}
|
||||
if(args.length <= 1 || args[1] == null || (!args[1].equalsIgnoreCase("buy") && !args[1].equalsIgnoreCase("rent"))) {
|
||||
messageBridge.message(sender, "find-help");
|
||||
return;
|
||||
}
|
||||
Player player = (Player)sender;
|
||||
double balance = 0.0;
|
||||
if(economy != null) {
|
||||
balance = economy.getBalance(player);
|
||||
}
|
||||
double maxPrice = 0;
|
||||
boolean maxPriceSet = false;
|
||||
RegionGroup group = null;
|
||||
// Parse optional price argument
|
||||
if(args.length >= 3) {
|
||||
try {
|
||||
maxPrice = Double.parseDouble(args[2]);
|
||||
maxPriceSet = true;
|
||||
} catch(NumberFormatException e) {
|
||||
messageBridge.message(sender, "find-wrongMaxPrice", args[2]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Parse optional group argument
|
||||
if(args.length >= 4) {
|
||||
group = fileManager.getGroup(args[3]);
|
||||
if(group == null) {
|
||||
messageBridge.message(sender, "find-wrongGroup", args[3]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Find buy regions
|
||||
if(args[1].equalsIgnoreCase("buy")) {
|
||||
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") || player.getWorld().equals(region.getWorld()))) {
|
||||
results.add(region);
|
||||
}
|
||||
}
|
||||
if(!results.isEmpty()) {
|
||||
// Draw a random one
|
||||
BuyRegion region = results.get(new Random().nextInt(results.size()));
|
||||
Message onlyInGroup = Message.empty();
|
||||
if(group != null) {
|
||||
onlyInGroup = Message.fromKey("find-onlyInGroup").replacements(args[3]);
|
||||
}
|
||||
|
||||
// Teleport
|
||||
if(maxPriceSet) {
|
||||
messageBridge.message(player, "find-successMax", "buy", Utils.formatCurrency(maxPrice), onlyInGroup, region);
|
||||
} else {
|
||||
messageBridge.message(player, "find-success", "buy", Utils.formatCurrency(balance), onlyInGroup, region);
|
||||
}
|
||||
region.getTeleportFeature().teleportPlayer(player, region.getBooleanSetting("general.findTeleportToSign"), false);
|
||||
} else {
|
||||
Message onlyInGroup = Message.empty();
|
||||
if(group != null) {
|
||||
onlyInGroup = Message.fromKey("find-onlyInGroup").replacements(args[3]);
|
||||
}
|
||||
if(maxPriceSet) {
|
||||
messageBridge.message(player, "find-noneFoundMax", "buy", Utils.formatCurrency(maxPrice), onlyInGroup);
|
||||
} else {
|
||||
messageBridge.message(player, "find-noneFound", "buy", Utils.formatCurrency(balance), onlyInGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find rental regions
|
||||
else {
|
||||
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") || player.getWorld().equals(region.getWorld()))) {
|
||||
results.add(region);
|
||||
}
|
||||
}
|
||||
if(!results.isEmpty()) {
|
||||
// Draw a random one
|
||||
RentRegion region = results.get(new Random().nextInt(results.size()));
|
||||
Message onlyInGroup = Message.empty();
|
||||
if(group != null) {
|
||||
onlyInGroup = Message.fromKey("find-onlyInGroup").replacements(args[3]);
|
||||
}
|
||||
|
||||
// Teleport
|
||||
if(maxPriceSet) {
|
||||
messageBridge.message(player, "find-successMax", "rent", Utils.formatCurrency(maxPrice), onlyInGroup, region);
|
||||
} else {
|
||||
messageBridge.message(player, "find-success", "rent", Utils.formatCurrency(balance), onlyInGroup, region);
|
||||
}
|
||||
region.getTeleportFeature().teleportPlayer(player, region.getBooleanSetting("general.findTeleportToSign"), false);
|
||||
} else {
|
||||
Message onlyInGroup = Message.empty();
|
||||
if(group != null) {
|
||||
onlyInGroup = Message.fromKey("find-onlyInGroup").replacements(args[3]);
|
||||
}
|
||||
if(maxPriceSet) {
|
||||
messageBridge.message(player, "find-noneFoundMax", "rent", Utils.formatCurrency(maxPrice), onlyInGroup);
|
||||
} else {
|
||||
messageBridge.message(player, "find-noneFound", "rent", Utils.formatCurrency(balance), onlyInGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
result.add("buy");
|
||||
result.add("rent");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.interfaces.WorldEditInterface;
|
||||
import me.wiefferink.areashop.interfaces.WorldEditSelection;
|
||||
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.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.TreeSet;
|
||||
|
||||
@Singleton
|
||||
public class GroupaddCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
@Inject
|
||||
private IFileManager fileManager;
|
||||
@Inject
|
||||
private RegionFactory regionFactory;
|
||||
@Inject
|
||||
private WorldEditInterface worldEditInterface;
|
||||
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop groupadd";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.groupadd")) {
|
||||
return "help-groupadd";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.groupadd")) {
|
||||
messageBridge.message(sender, "groupadd-noPermission");
|
||||
return;
|
||||
}
|
||||
if(args.length < 2 || args[1] == null) {
|
||||
messageBridge.message(sender, "groupadd-help");
|
||||
return;
|
||||
}
|
||||
RegionGroup group = fileManager.getGroup(args[1]);
|
||||
if(group == null) {
|
||||
group = regionFactory.createRegionGroup(args[1]);
|
||||
fileManager.addGroup(group);
|
||||
}
|
||||
if(args.length == 2) {
|
||||
if(!(sender instanceof Player)) {
|
||||
messageBridge.message(sender, "cmd-weOnlyByPlayer");
|
||||
return;
|
||||
}
|
||||
Player player = (Player)sender;
|
||||
WorldEditSelection selection = worldEditInterface.getPlayerSelection(player);
|
||||
if(selection == null) {
|
||||
messageBridge.message(player, "cmd-noSelection");
|
||||
return;
|
||||
}
|
||||
List<GeneralRegion> regions = Utils.getRegionsInSelection(selection);
|
||||
if(regions.isEmpty()) {
|
||||
messageBridge.message(player, "cmd-noRegionsFound");
|
||||
return;
|
||||
}
|
||||
TreeSet<GeneralRegion> regionsSuccess = new TreeSet<>();
|
||||
TreeSet<GeneralRegion> regionsFailed = new TreeSet<>();
|
||||
for(GeneralRegion region : regions) {
|
||||
if(group.addMember(region)) {
|
||||
regionsSuccess.add(region);
|
||||
} else {
|
||||
regionsFailed.add(region);
|
||||
}
|
||||
}
|
||||
if(!regionsSuccess.isEmpty()) {
|
||||
messageBridge.message(player, "groupadd-weSuccess", group.getName(), Utils.combinedMessage(regionsSuccess, "region"));
|
||||
}
|
||||
if(!regionsFailed.isEmpty()) {
|
||||
messageBridge.message(player, "groupadd-weFailed", group.getName(), Utils.combinedMessage(regionsFailed, "region"));
|
||||
}
|
||||
// Update all regions, this does it in a task, updating them without lag
|
||||
fileManager.updateRegions(new ArrayList<>(regionsSuccess), player);
|
||||
} else {
|
||||
GeneralRegion region = fileManager.getRegion(args[2]);
|
||||
if(region == null) {
|
||||
messageBridge.message(sender, "cmd-notRegistered", args[2]);
|
||||
return;
|
||||
}
|
||||
if(group.addMember(region)) {
|
||||
region.update();
|
||||
messageBridge.message(sender, "groupadd-success", group.getName(), group.getMembers().size(), region);
|
||||
} else {
|
||||
messageBridge.message(sender, "groupadd-failed", group.getName(), region);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
List<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
result = fileManager.getGroupNames();
|
||||
} else if(toComplete == 3) {
|
||||
result = fileManager.getRegionNames();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.interfaces.WorldEditInterface;
|
||||
import me.wiefferink.areashop.interfaces.WorldEditSelection;
|
||||
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.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.TreeSet;
|
||||
|
||||
@Singleton
|
||||
public class GroupdelCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
@Inject
|
||||
private IFileManager fileManager;
|
||||
@Inject
|
||||
private RegionFactory regionFactory;
|
||||
@Inject
|
||||
private WorldEditInterface worldEditInterface;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop groupdel";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.groupdel")) {
|
||||
return "help-groupdel";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.groupdel")) {
|
||||
messageBridge.message(sender, "groupdel-noPermission");
|
||||
return;
|
||||
}
|
||||
if(args.length < 2 || args[1] == null) {
|
||||
messageBridge.message(sender, "groupdel-help");
|
||||
return;
|
||||
}
|
||||
RegionGroup group = fileManager.getGroup(args[1]);
|
||||
if(group == null) {
|
||||
messageBridge.message(sender, "groupdel-wrongGroup", args[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
if(args.length == 2) {
|
||||
if(!(sender instanceof Player)) {
|
||||
messageBridge.message(sender, "cmd-weOnlyByPlayer");
|
||||
return;
|
||||
}
|
||||
Player player = (Player)sender;
|
||||
WorldEditSelection selection = worldEditInterface.getPlayerSelection(player);
|
||||
if(selection == null) {
|
||||
messageBridge.message(player, "cmd-noSelection");
|
||||
return;
|
||||
}
|
||||
List<GeneralRegion> regions = Utils.getRegionsInSelection(selection);
|
||||
if(regions.isEmpty()) {
|
||||
messageBridge.message(player, "cmd-noRegionsFound");
|
||||
return;
|
||||
}
|
||||
TreeSet<GeneralRegion> regionsSuccess = new TreeSet<>();
|
||||
TreeSet<GeneralRegion> regionsFailed = new TreeSet<>();
|
||||
for(GeneralRegion region : regions) {
|
||||
if(group.removeMember(region)) {
|
||||
regionsSuccess.add(region);
|
||||
} else {
|
||||
regionsFailed.add(region);
|
||||
}
|
||||
}
|
||||
if(!regionsSuccess.isEmpty()) {
|
||||
messageBridge.message(player, "groupdel-weSuccess", group.getName(), Utils.combinedMessage(regionsSuccess, "region"));
|
||||
}
|
||||
if(!regionsFailed.isEmpty()) {
|
||||
messageBridge.message(player, "groupdel-weFailed", group.getName(), Utils.combinedMessage(regionsFailed, "region"));
|
||||
}
|
||||
// Update all regions, this does it in a task, updating them without lag
|
||||
fileManager.updateRegions(regionsSuccess, player);
|
||||
group.saveRequired();
|
||||
} else {
|
||||
GeneralRegion region = fileManager.getRegion(args[2]);
|
||||
if(region == null) {
|
||||
messageBridge.message(sender, "cmd-notRegistered", args[2]);
|
||||
return;
|
||||
}
|
||||
if(group.removeMember(region)) {
|
||||
region.update();
|
||||
messageBridge.message(sender, "groupdel-success", group.getName(), group.getMembers().size(), region);
|
||||
} else {
|
||||
messageBridge.message(sender, "groupdel-failed", group.getName(), region);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
List<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
result = fileManager.getGroupNames();
|
||||
} else if(toComplete == 3) {
|
||||
result = fileManager.getRegionNames();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.RegionGroup;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Singleton
|
||||
public class GroupinfoCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
@Inject
|
||||
private IFileManager fileManager;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop groupinfo";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.groupinfo")) {
|
||||
return "help-groupinfo";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.groupinfo")) {
|
||||
messageBridge.message(sender, "groupinfo-noPermission");
|
||||
return;
|
||||
}
|
||||
if(args.length < 2 || args[1] == null) {
|
||||
messageBridge.message(sender, "groupinfo-help");
|
||||
return;
|
||||
}
|
||||
RegionGroup group = fileManager.getGroup(args[1]);
|
||||
if(group == null) {
|
||||
messageBridge.message(sender, "groupinfo-noGroup", args[1]);
|
||||
return;
|
||||
}
|
||||
Set<String> members = group.getMembers();
|
||||
if(members.isEmpty()) {
|
||||
messageBridge.message(sender, "groupinfo-noMembers", group.getName());
|
||||
} else {
|
||||
messageBridge.message(sender, "groupinfo-members", group.getName(), Utils.createCommaSeparatedList(members));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
List<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
result = fileManager.getGroupNames();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Singleton
|
||||
public class GrouplistCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
@Inject
|
||||
private IFileManager fileManager;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop grouplist";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.grouplist")) {
|
||||
return "help-grouplist";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.grouplist")) {
|
||||
messageBridge.message(sender, "grouplist-noPermission");
|
||||
return;
|
||||
}
|
||||
List<String> groups = fileManager.getGroupNames();
|
||||
if(groups.isEmpty()) {
|
||||
messageBridge.message(sender, "grouplist-noGroups");
|
||||
} else {
|
||||
messageBridge.message(sender, "grouplist-success", Utils.createCommaSeparatedList(groups));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import me.wiefferink.areashop.managers.CommandManager;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class HelpCommand extends CommandAreaShop {
|
||||
|
||||
private final CommandManager commandManager;
|
||||
|
||||
public HelpCommand(@Nonnull CommandManager commandManager) {
|
||||
this.commandManager = commandManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop help";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.help")) {
|
||||
return "help-help";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
commandManager.showHelp(sender);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.regions.ImportJob;
|
||||
import me.wiefferink.areashop.regions.ImportJobFactory;
|
||||
import me.wiefferink.interactivemessenger.processing.Message;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Singleton
|
||||
public class ImportCommand extends CommandAreaShop {
|
||||
|
||||
/* 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)
|
||||
*/
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
@Inject
|
||||
private ImportJobFactory importJobFactory;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop import";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.import")) {
|
||||
return "help-import";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// - Landlord?
|
||||
// - Friends
|
||||
// - Region flags?
|
||||
// - Settings from the 'permissions' section in RegionForSale/config.yml?
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.import")) {
|
||||
messageBridge.message(sender, "import-noPermission");
|
||||
return;
|
||||
}
|
||||
|
||||
if(args.length < 2) {
|
||||
messageBridge.message(sender, "import-help");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!"RegionForSale".equalsIgnoreCase(args[1])) {
|
||||
messageBridge.message(sender, "import-wrongSource");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!confirm(sender, args, Message.fromKey("import-confirm"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
importJobFactory.createImportJob(sender).execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
List<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
result.add("RegionForSale");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,494 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import io.github.bakedlibs.dough.blocks.BlockPosition;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
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 org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
// TODO fix '/as info' help message hitting replacement limit (improve depth tracking?)
|
||||
// TODO add info about autoExtend
|
||||
@Singleton
|
||||
public class InfoCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
@Inject
|
||||
private IFileManager fileManager;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop info";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.info")) {
|
||||
return "help-info";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a page of a list of regions.
|
||||
* @param sender The CommandSender to send the messages to
|
||||
* @param regions 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, List<? extends GeneralRegion> regions, RegionGroup filterGroup, String keyHeader, String pageInput, String baseCommand) {
|
||||
int maximumItems = 20;
|
||||
int itemsPerPage = maximumItems - 2;
|
||||
int page = 1;
|
||||
if(pageInput != null && Utils.isNumeric(pageInput)) {
|
||||
try {
|
||||
page = Integer.parseInt(pageInput);
|
||||
} catch(NumberFormatException e) {
|
||||
messageBridge.message(sender, "info-wrongPage", pageInput);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(filterGroup != null) {
|
||||
regions.removeIf(generalRegion -> !filterGroup.isMember(generalRegion));
|
||||
}
|
||||
if(regions.isEmpty()) {
|
||||
messageBridge.message(sender, "info-noRegions");
|
||||
} else {
|
||||
// First sort by type, then by name
|
||||
regions.sort((one, two) -> {
|
||||
int typeCompare = getTypeOrder(two).compareTo(getTypeOrder(one));
|
||||
if(typeCompare != 0) {
|
||||
return typeCompare;
|
||||
} else {
|
||||
return one.getName().compareTo(two.getName());
|
||||
}
|
||||
});
|
||||
// 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 - 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 + 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(" ");
|
||||
}
|
||||
footer.send(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.info")) {
|
||||
messageBridge.message(sender, "info-noPermission");
|
||||
return;
|
||||
}
|
||||
if(args.length > 1 && args[1] != null) {
|
||||
// Get filter group (only used by some commands)
|
||||
RegionGroup filterGroup = null;
|
||||
Set<String> groupFilters = new HashSet<>(Arrays.asList("all", "rented", "forrent", "sold", "forsale", "reselling"));
|
||||
if(groupFilters.contains(args[1].toLowerCase()) && args.length > 2) {
|
||||
if(!Utils.isNumeric(args[2])) {
|
||||
filterGroup = fileManager.getGroup(args[2]);
|
||||
if(filterGroup == null) {
|
||||
messageBridge.message(sender, "info-noFiltergroup", args[2]);
|
||||
return;
|
||||
}
|
||||
// Pass page number to args[2] if available
|
||||
if(args.length > 3) {
|
||||
args[2] = args[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// All regions
|
||||
if(args[1].equalsIgnoreCase("all")) {
|
||||
showSortedPagedList(sender, new ArrayList<>(fileManager.getRegionsRef()), filterGroup, "info-allHeader", (args.length > 2 ? args[2] : null), "info all");
|
||||
}
|
||||
|
||||
// Rented regions
|
||||
else if(args[1].equalsIgnoreCase("rented")) {
|
||||
List<RentRegion> regions = new ArrayList<>(fileManager.getRentsRef());
|
||||
regions.removeIf(RentRegion::isAvailable);
|
||||
showSortedPagedList(sender, regions, filterGroup, "info-rentedHeader", (args.length > 2 ? args[2] : null), "info rented");
|
||||
}
|
||||
// Forrent regions
|
||||
else if(args[1].equalsIgnoreCase("forrent")) {
|
||||
List<RentRegion> regions = new ArrayList<>(fileManager.getRentsRef());
|
||||
regions.removeIf(RentRegion::isRented);
|
||||
showSortedPagedList(sender, regions, filterGroup, "info-forrentHeader", (args.length > 2 ? args[2] : null), "info forrent");
|
||||
}
|
||||
// Sold regions
|
||||
else if(args[1].equalsIgnoreCase("sold")) {
|
||||
List<BuyRegion> regions = new ArrayList<>(fileManager.getBuysRef());
|
||||
regions.removeIf(BuyRegion::isAvailable);
|
||||
showSortedPagedList(sender, regions, filterGroup, "info-soldHeader", (args.length > 2 ? args[2] : null), "info sold");
|
||||
}
|
||||
// Forsale regions
|
||||
else if(args[1].equalsIgnoreCase("forsale")) {
|
||||
List<BuyRegion> regions = new ArrayList<>(fileManager.getBuysRef());
|
||||
regions.removeIf(BuyRegion::isSold);
|
||||
showSortedPagedList(sender, regions, filterGroup, "info-forsaleHeader", (args.length > 2 ? args[2] : null), "info forsale");
|
||||
}
|
||||
// Reselling regions
|
||||
else if(args[1].equalsIgnoreCase("reselling")) {
|
||||
List<BuyRegion> regions = new ArrayList<>(fileManager.getBuysRef());
|
||||
regions.removeIf(region -> !region.isInResellingMode());
|
||||
showSortedPagedList(sender, regions, filterGroup, "info-resellingHeader", (args.length > 2 ? args[2] : null), "info reselling");
|
||||
}
|
||||
|
||||
// List of regions without a group
|
||||
else if(args[1].equalsIgnoreCase("nogroup")) {
|
||||
List<GeneralRegion> regions = new ArrayList<>(fileManager.getRegionsRef());
|
||||
for(RegionGroup group : fileManager.getGroups()) {
|
||||
regions.removeAll(group.getMemberRegions());
|
||||
}
|
||||
if(regions.isEmpty()) {
|
||||
messageBridge.message(sender, "info-nogroupNone");
|
||||
} else {
|
||||
showSortedPagedList(sender, regions, filterGroup, "info-nogroupHeader", (args.length > 2 ? args[2] : null), "info nogroup");
|
||||
}
|
||||
}
|
||||
|
||||
// Region info
|
||||
else if(args[1].equalsIgnoreCase("region")) {
|
||||
if(args.length > 1) {
|
||||
RentRegion rent = null;
|
||||
BuyRegion buy = null;
|
||||
if(args.length > 2) {
|
||||
rent = fileManager.getRent(args[2]);
|
||||
buy = fileManager.getBuy(args[2]);
|
||||
} else {
|
||||
if(sender instanceof Player) {
|
||||
// get the region by location
|
||||
List<GeneralRegion> regions = Utils.getImportantRegions(((Player)sender).getLocation());
|
||||
if(regions.isEmpty()) {
|
||||
messageBridge.message(sender, "cmd-noRegionsAtLocation");
|
||||
return;
|
||||
} else if(regions.size() > 1) {
|
||||
messageBridge.message(sender, "cmd-moreRegionsAtLocation");
|
||||
return;
|
||||
} else {
|
||||
if(regions.get(0) instanceof RentRegion) {
|
||||
rent = (RentRegion)regions.get(0);
|
||||
} else if(regions.get(0) instanceof BuyRegion) {
|
||||
buy = (BuyRegion)regions.get(0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
messageBridge.message(sender, "cmd-automaticRegionOnlyByPlayer");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(rent == null && buy == null) {
|
||||
messageBridge.message(sender, "info-regionNotExisting", args[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
if(rent != null) {
|
||||
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);
|
||||
}
|
||||
// Teleport
|
||||
Message tp = Message.fromKey("info-prefix");
|
||||
boolean foundSomething = false;
|
||||
if(TeleportCommand.canUse(sender, rent)) {
|
||||
foundSomething = true;
|
||||
tp.append(Message.fromKey("info-regionTeleport").replacements(rent));
|
||||
}
|
||||
if(SetteleportCommand.canUse(sender, rent)) {
|
||||
if(foundSomething) {
|
||||
tp.append(", ");
|
||||
}
|
||||
foundSomething = true;
|
||||
tp.append(Message.fromKey("info-setRegionTeleport").replacements(rent));
|
||||
}
|
||||
if(foundSomething) {
|
||||
tp.append(".");
|
||||
tp.send(sender);
|
||||
}
|
||||
// Signs
|
||||
List<String> signLocations = new ArrayList<>();
|
||||
for(BlockPosition location : rent.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));
|
||||
}
|
||||
// Groups
|
||||
if(sender.hasPermission("areashop.groupinfo") && !rent.getGroupNames().isEmpty()) {
|
||||
messageBridge.messageNoPrefix(sender, "info-regionGroups", Utils.createCommaSeparatedList(rent.getGroupNames()));
|
||||
}
|
||||
// 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);
|
||||
} else if(buy != null) {
|
||||
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);
|
||||
}
|
||||
// Teleport
|
||||
Message tp = Message.fromKey("info-prefix");
|
||||
boolean foundSomething = false;
|
||||
if(TeleportCommand.canUse(sender, buy)) {
|
||||
foundSomething = true;
|
||||
tp.append(Message.fromKey("info-regionTeleport").replacements(buy));
|
||||
}
|
||||
if(SetteleportCommand.canUse(sender, buy)) {
|
||||
if(foundSomething) {
|
||||
tp.append(", ");
|
||||
}
|
||||
foundSomething = true;
|
||||
tp.append(Message.fromKey("info-setRegionTeleport").replacements(buy));
|
||||
}
|
||||
if(foundSomething) {
|
||||
tp.append(".");
|
||||
tp.send(sender);
|
||||
}
|
||||
// Signs
|
||||
List<String> signLocations = new ArrayList<>();
|
||||
for(BlockPosition location : buy.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));
|
||||
}
|
||||
// Groups
|
||||
if(sender.hasPermission("areashop.groupinfo") && !buy.getGroupNames().isEmpty()) {
|
||||
messageBridge.messageNoPrefix(sender, "info-regionGroups", Utils.createCommaSeparatedList(buy.getGroupNames()));
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
} else {
|
||||
messageBridge.message(sender, "info-regionHelp");
|
||||
}
|
||||
} else {
|
||||
messageBridge.message(sender, "info-help");
|
||||
}
|
||||
} else {
|
||||
messageBridge.message(sender, "info-help");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
List<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
result.addAll(Arrays.asList("all", "rented", "forrent", "sold", "forsale", "player", "region", "nogroup", "reselling"));
|
||||
} else if(toComplete == 3) {
|
||||
if(start[2].equalsIgnoreCase("player")) {
|
||||
for(Player player : Utils.getOnlinePlayers()) {
|
||||
result.add(player.getName());
|
||||
}
|
||||
} else if(start[2].equalsIgnoreCase("region")) {
|
||||
result.addAll(fileManager.getBuyNames());
|
||||
result.addAll(fileManager.getRentNames());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
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.managers.SignLinkerManager;
|
||||
import me.wiefferink.interactivemessenger.processing.Message;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Singleton
|
||||
public class LinksignsCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private SignLinkerManager signLinkerManager;
|
||||
@Inject
|
||||
private AreaShop plugin;
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop linksigns";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.linksigns")) {
|
||||
return "help-linksigns";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.linksigns")) {
|
||||
messageBridge.message(sender, "linksigns-noPermission");
|
||||
return;
|
||||
}
|
||||
if(!(sender instanceof Player)) {
|
||||
messageBridge.message(sender, "cmd-onlyByPlayer");
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = (Player)sender;
|
||||
if(signLinkerManager.isInSignLinkMode(player)) {
|
||||
signLinkerManager.exitSignLinkMode(player);
|
||||
} else {
|
||||
// Get the profile
|
||||
String profile = null;
|
||||
if(args.length > 1) {
|
||||
profile = args[1];
|
||||
ConfigurationSection signProfilesSection = plugin.getConfig().getConfigurationSection("signProfiles");
|
||||
if(signProfilesSection != null) {
|
||||
Set<String> profiles = signProfilesSection.getKeys(false);
|
||||
if(!profiles.contains(profile)) {
|
||||
ArrayList<String> message = new ArrayList<>();
|
||||
for(String p : profiles) {
|
||||
if(!message.isEmpty()) {
|
||||
message.add(", ");
|
||||
}
|
||||
message.addAll(Message.fromKey("addsign-profile").replacements(p).get());
|
||||
}
|
||||
messageBridge.message(sender, "addsign-wrongProfile", Message.fromList(message));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
signLinkerManager.enterSignLinkMode(player, profile);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
List<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
result.addAll(plugin.getFileManager().getRegionNames());
|
||||
} else if(toComplete == 3) {
|
||||
result.addAll(plugin.getConfig().getStringList("signProfiles"));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
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.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Singleton
|
||||
public class MeCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
@Inject
|
||||
private IFileManager fileManager;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop me";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.me")) {
|
||||
return "help-me";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.me")) {
|
||||
messageBridge.message(sender, "me-noPermission");
|
||||
return;
|
||||
}
|
||||
OfflinePlayer player = null;
|
||||
if(!(sender instanceof Player)) {
|
||||
if(args.length <= 1) {
|
||||
messageBridge.message(sender, "me-notAPlayer");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
player = (OfflinePlayer)sender;
|
||||
}
|
||||
if(args.length > 1) {
|
||||
player = Bukkit.getOfflinePlayer(args[1]);
|
||||
if(!player.hasPlayedBefore()) {
|
||||
messageBridge.message(sender, "me-noPlayer", args[1]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(!player.hasPlayedBefore()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the regions owned by the player
|
||||
Set<RentRegion> rentRegions = new HashSet<>();
|
||||
for(RentRegion region : fileManager.getRentsRef()) {
|
||||
if(region.isOwner(player)) {
|
||||
rentRegions.add(region);
|
||||
}
|
||||
}
|
||||
Set<BuyRegion> buyRegions = new HashSet<>();
|
||||
for(BuyRegion region : fileManager.getBuysRef()) {
|
||||
if(region.isOwner(player)) {
|
||||
buyRegions.add(region);
|
||||
}
|
||||
}
|
||||
// Get the regions the player is added as friend
|
||||
Set<GeneralRegion> friendRegions = new HashSet<>();
|
||||
for(GeneralRegion region : fileManager.getRegionsRef()) {
|
||||
if(region.getFriendsFeature().getFriends().contains(player.getUniqueId())) {
|
||||
friendRegions.add(region);
|
||||
}
|
||||
}
|
||||
|
||||
// Send messages
|
||||
boolean foundSome = !rentRegions.isEmpty() || !buyRegions.isEmpty() || !friendRegions.isEmpty();
|
||||
if(foundSome) {
|
||||
messageBridge.message(sender, "me-header", player.getName());
|
||||
}
|
||||
if(!rentRegions.isEmpty()) {
|
||||
for(RentRegion region : rentRegions) {
|
||||
messageBridge.messageNoPrefix(sender, "me-rentLine", region);
|
||||
}
|
||||
}
|
||||
if(!buyRegions.isEmpty()) {
|
||||
for(BuyRegion region : buyRegions) {
|
||||
messageBridge.messageNoPrefix(sender, "me-buyLine", region);
|
||||
}
|
||||
}
|
||||
if(!friendRegions.isEmpty()) {
|
||||
for(GeneralRegion region : friendRegions) {
|
||||
messageBridge.messageNoPrefix(sender, "me-friendLine", region);
|
||||
}
|
||||
}
|
||||
|
||||
if(!foundSome) {
|
||||
messageBridge.message(sender, "me-nothing", player.getName());
|
||||
} else {
|
||||
messageBridge.messageNoPrefix(sender, "me-clickHint");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
for(Player player : Utils.getOnlinePlayers()) {
|
||||
result.add(player.getName());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import me.wiefferink.interactivemessenger.processing.Message;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Singleton
|
||||
public class MessageCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop message";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
// Internal command, no need to show in the help list
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(final CommandSender sender, final String[] args) {
|
||||
if(!sender.hasPermission("areashop.message")) {
|
||||
messageBridge.message(sender, "message-noPermission");
|
||||
return;
|
||||
}
|
||||
|
||||
if(args.length < 3) {
|
||||
messageBridge.message(sender, "message-help");
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = Bukkit.getPlayer(args[1]);
|
||||
if(player == null) {
|
||||
messageBridge.message(sender, "message-notOnline", args[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
String[] messageArgs = new String[args.length - 2];
|
||||
System.arraycopy(args, 2, messageArgs, 0, args.length - 2);
|
||||
String message = StringUtils.join(messageArgs, " ");
|
||||
|
||||
Message.fromString(message).send(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
List<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
for(Player player : Utils.getOnlinePlayers()) {
|
||||
result.add(player.getName());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
# Commands
|
||||
|
||||
This module contains all AreaShop commands.
|
||||
|
||||
* `CommandAreaShop` 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.
|
||||
* `CommandManager` class in the `managers` package handles incoming commands and dispatches them to the classes in this package.
|
||||
@@ -0,0 +1,40 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
@Singleton
|
||||
public class ReloadCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private AreaShop plugin;
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop reload";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.reload")) {
|
||||
return "help-reload";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(sender.hasPermission("areashop.reload")) {
|
||||
// Reload the configuration files and update all region flags/signs
|
||||
plugin.reload(sender);
|
||||
} else {
|
||||
messageBridge.message(sender, "reload-noPermission");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Singleton
|
||||
public class RentCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
@Inject
|
||||
private IFileManager fileManager;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop rent";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.rent")) {
|
||||
return "help-rent";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.rent")) {
|
||||
messageBridge.message(sender, "rent-noPermission");
|
||||
return;
|
||||
}
|
||||
if(!(sender instanceof Player)) {
|
||||
messageBridge.message(sender, "cmd-onlyByPlayer");
|
||||
return;
|
||||
}
|
||||
Player player = (Player)sender;
|
||||
if(args.length > 1 && args[1] != null) {
|
||||
RentRegion rent = fileManager.getRent(args[1]);
|
||||
if(rent == null) {
|
||||
messageBridge.message(sender, "rent-notRentable", args[1]);
|
||||
} else {
|
||||
rent.rent(player);
|
||||
}
|
||||
} else {
|
||||
// get the region by location
|
||||
List<RentRegion> regions = Utils.getImportantRentRegions(((Player)sender).getLocation());
|
||||
if(regions.isEmpty()) {
|
||||
messageBridge.message(sender, "cmd-noRegionsAtLocation");
|
||||
} else if(regions.size() > 1) {
|
||||
messageBridge.message(sender, "cmd-moreRegionsAtLocation");
|
||||
} else {
|
||||
regions.get(0).rent(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
for(RentRegion region : fileManager.getRentsRef()) {
|
||||
if(!region.isRented()) {
|
||||
result.add(region.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Singleton
|
||||
public class ResellCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
@Inject
|
||||
private IFileManager fileManager;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop resell";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.resellall") || target.hasPermission("areashop.resell")) {
|
||||
return "help-resell";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.resell") && !sender.hasPermission("areashop.resellall")) {
|
||||
messageBridge.message(sender, "resell-noPermissionOther");
|
||||
return;
|
||||
}
|
||||
|
||||
if(args.length <= 1) {
|
||||
messageBridge.message(sender, "resell-help");
|
||||
return;
|
||||
}
|
||||
double price;
|
||||
try {
|
||||
price = Double.parseDouble(args[1]);
|
||||
} catch(NumberFormatException e) {
|
||||
messageBridge.message(sender, "resell-wrongPrice", args[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
if(price < 0) {
|
||||
messageBridge.message(sender, "resell-wrongPrice", args[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
BuyRegion buy;
|
||||
if(args.length <= 2) {
|
||||
if(sender instanceof Player) {
|
||||
// get the region by location
|
||||
List<BuyRegion> regions = Utils.getImportantBuyRegions(((Player)sender).getLocation());
|
||||
if(regions.isEmpty()) {
|
||||
messageBridge.message(sender, "cmd-noRegionsAtLocation");
|
||||
return;
|
||||
} else if(regions.size() > 1) {
|
||||
messageBridge.message(sender, "cmd-moreRegionsAtLocation");
|
||||
return;
|
||||
} else {
|
||||
buy = regions.get(0);
|
||||
}
|
||||
} else {
|
||||
messageBridge.message(sender, "cmd-automaticRegionOnlyByPlayer");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
buy = fileManager.getBuy(args[2]);
|
||||
if(buy == null) {
|
||||
messageBridge.message(sender, "resell-notRegistered", args[2]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(buy == null) {
|
||||
messageBridge.message(sender, "cmd-noRegionsAtLocation");
|
||||
return;
|
||||
}
|
||||
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) {
|
||||
if(!buy.isOwner((Player)sender)) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
if(toComplete == 3) {
|
||||
for(BuyRegion region : fileManager.getBuysRef()) {
|
||||
if(region.isSold() && !region.isInResellingMode()) {
|
||||
result.add(region.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
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 javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@Singleton
|
||||
public class SchematiceventCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
@Inject
|
||||
private IFileManager fileManager;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop schemevent";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.schematicevents")) {
|
||||
return "help-schemevent";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.schematicevents")) {
|
||||
messageBridge.message(sender, "schemevent-noPermission");
|
||||
return;
|
||||
}
|
||||
|
||||
if(args.length < 3 || args[1] == null || args[2] == null) {
|
||||
messageBridge.message(sender, "schemevent-help");
|
||||
return;
|
||||
}
|
||||
GeneralRegion region = fileManager.getRegion(args[1]);
|
||||
if(region == null) {
|
||||
messageBridge.message(sender, "cmd-notRegistered", args[1]);
|
||||
return;
|
||||
}
|
||||
if(region.getRegion() == null) {
|
||||
messageBridge.message(sender, "general-noRegion", region);
|
||||
return;
|
||||
}
|
||||
GeneralRegion.RegionEvent event = null;
|
||||
boolean exception = false;
|
||||
try {
|
||||
event = GeneralRegion.RegionEvent.valueOf(args[2].toUpperCase());
|
||||
} catch(IllegalArgumentException e) {
|
||||
exception = true;
|
||||
}
|
||||
// Check for a totally wrong event or a non matching event
|
||||
if(exception) {
|
||||
ArrayList<String> values = new ArrayList<>();
|
||||
for(GeneralRegion.RegionEvent value : GeneralRegion.RegionEvent.values()) {
|
||||
values.add(value.getValue().toLowerCase());
|
||||
}
|
||||
messageBridge.message(sender, "schemevent-wrongEvent", args[2], Utils.createCommaSeparatedList(values), region);
|
||||
return;
|
||||
}
|
||||
region.handleSchematicEvent(event);
|
||||
region.update();
|
||||
messageBridge.message(sender, "schemevent-success", args[2], region);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
result.addAll(fileManager.getRegionNames());
|
||||
} else if(toComplete == 3) {
|
||||
GeneralRegion region = fileManager.getRegion(start[2]);
|
||||
if(region != null) {
|
||||
if(region instanceof RentRegion) {
|
||||
result.addAll(Arrays.asList("created", "deleted", "rented", "unrented"));
|
||||
} else if(region instanceof BuyRegion) {
|
||||
result.addAll(Arrays.asList("created", "deleted", "bought", "sold"));
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Singleton
|
||||
public class SellCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
@Inject
|
||||
private IFileManager fileManager;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop sell";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.sell") || target.hasPermission("areashop.sellown")) {
|
||||
return "help-sell";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.sell") && !sender.hasPermission("areashop.sellown")) {
|
||||
messageBridge.message(sender, "sell-noPermission");
|
||||
return;
|
||||
}
|
||||
BuyRegion buy;
|
||||
if(args.length <= 1) {
|
||||
if(sender instanceof Player player) {
|
||||
// get the region by location
|
||||
List<BuyRegion> regions = Utils.getImportantBuyRegions((player).getLocation());
|
||||
if(regions.isEmpty()) {
|
||||
messageBridge.message(sender, "cmd-noRegionsAtLocation");
|
||||
return;
|
||||
} else if(regions.size() > 1) {
|
||||
messageBridge.message(sender, "cmd-moreRegionsAtLocation");
|
||||
return;
|
||||
} else {
|
||||
buy = regions.get(0);
|
||||
}
|
||||
} else {
|
||||
messageBridge.message(sender, "cmd-automaticRegionOnlyByPlayer");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
buy = fileManager.getBuy(args[1]);
|
||||
}
|
||||
if(buy == null) {
|
||||
messageBridge.message(sender, "sell-notRegistered");
|
||||
return;
|
||||
}
|
||||
if(!buy.isSold()) {
|
||||
messageBridge.message(sender, "sell-notBought", buy);
|
||||
return;
|
||||
}
|
||||
buy.sell(true, sender);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
for(BuyRegion region : fileManager.getBuysRef()) {
|
||||
if(region.isSold()) {
|
||||
result.add(region.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Singleton
|
||||
public class SetdurationCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
@Inject
|
||||
private IFileManager fileManager;
|
||||
@Inject
|
||||
private Plugin plugin;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop setduration";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.setduration")) {
|
||||
return "help-setduration";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.setduration") && (!sender.hasPermission("areashop.setduration.landlord") && sender instanceof Player)) {
|
||||
messageBridge.message(sender, "setduration-noPermission");
|
||||
return;
|
||||
}
|
||||
if(args.length < 3 || args[1] == null || args[2] == null) {
|
||||
messageBridge.message(sender, "setduration-help");
|
||||
return;
|
||||
}
|
||||
int regionArgument = 3;
|
||||
if(args.length >= 2 && ("default".equalsIgnoreCase(args[1]) || "reset".equalsIgnoreCase(args[1]))) {
|
||||
regionArgument = 2;
|
||||
}
|
||||
RentRegion rent;
|
||||
if(args.length <= regionArgument) {
|
||||
if(sender instanceof Player) {
|
||||
// get the region by location
|
||||
List<RentRegion> regions = Utils.getImportantRentRegions(((Player)sender).getLocation());
|
||||
if(regions.isEmpty()) {
|
||||
messageBridge.message(sender, "cmd-noRegionsAtLocation");
|
||||
return;
|
||||
} else if(regions.size() > 1) {
|
||||
messageBridge.message(sender, "cmd-moreRegionsAtLocation");
|
||||
return;
|
||||
} else {
|
||||
rent = regions.get(0);
|
||||
}
|
||||
} else {
|
||||
messageBridge.message(sender, "cmd-automaticRegionOnlyByPlayer");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
rent = fileManager.getRent(args[regionArgument]);
|
||||
}
|
||||
if(rent == null) {
|
||||
messageBridge.message(sender, "setduration-notRegistered", args[regionArgument]);
|
||||
return;
|
||||
}
|
||||
if(!sender.hasPermission("areashop.setduration") && !(sender instanceof Player && rent.isLandlord(((Player)sender).getUniqueId()))) {
|
||||
messageBridge.message(sender, "setduration-noLandlord", rent);
|
||||
return;
|
||||
}
|
||||
if("default".equalsIgnoreCase(args[1]) || "reset".equalsIgnoreCase(args[1])) {
|
||||
rent.setDuration(null);
|
||||
rent.update();
|
||||
messageBridge.message(sender, "setduration-successRemoved", rent);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Integer.parseInt(args[1]);
|
||||
} catch(NumberFormatException e) {
|
||||
messageBridge.message(sender, "setduration-wrongAmount", args[1], rent);
|
||||
return;
|
||||
}
|
||||
if(!Utils.checkTimeFormat(args[1] + " " + args[2])) {
|
||||
messageBridge.message(sender, "setduration-wrongFormat", args[1] + " " + args[2], rent);
|
||||
return;
|
||||
}
|
||||
rent.setDuration(args[1] + " " + args[2]);
|
||||
rent.update();
|
||||
messageBridge.message(sender, "setduration-success", rent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
List<String> result = new ArrayList<>();
|
||||
if(toComplete == 3) {
|
||||
result.addAll(plugin.getConfig().getStringList("minutes"));
|
||||
result.addAll(plugin.getConfig().getStringList("hours"));
|
||||
result.addAll(plugin.getConfig().getStringList("days"));
|
||||
result.addAll(plugin.getConfig().getStringList("months"));
|
||||
result.addAll(plugin.getConfig().getStringList("years"));
|
||||
} else if(toComplete == 4) {
|
||||
result = fileManager.getRentNames();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Singleton
|
||||
public class SetlandlordCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
@Inject
|
||||
private IFileManager fileManager;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop setlandlord";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.setlandlord")) {
|
||||
return "help-setlandlord";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.setlandlord")) {
|
||||
messageBridge.message(sender, "setlandlord-noPermission");
|
||||
return;
|
||||
}
|
||||
if(args.length < 2) {
|
||||
messageBridge.message(sender, "setlandlord-help");
|
||||
return;
|
||||
}
|
||||
@SuppressWarnings("deprecation")
|
||||
OfflinePlayer player = Bukkit.getOfflinePlayer(args[1]);
|
||||
GeneralRegion region;
|
||||
if(args.length < 3) {
|
||||
if(sender instanceof Player) {
|
||||
// get the region by location
|
||||
List<GeneralRegion> regions = Utils.getImportantRegions(((Player)sender).getLocation());
|
||||
if(regions.isEmpty()) {
|
||||
messageBridge.message(sender, "cmd-noRegionsAtLocation");
|
||||
return;
|
||||
} else if(regions.size() > 1) {
|
||||
messageBridge.message(sender, "cmd-moreRegionsAtLocation");
|
||||
return;
|
||||
} else {
|
||||
region = regions.get(0);
|
||||
}
|
||||
} else {
|
||||
messageBridge.message(sender, "cmd-automaticRegionOnlyByPlayer");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
region = fileManager.getRegion(args[2]);
|
||||
}
|
||||
if(region == null) {
|
||||
messageBridge.message(sender, "cmd-notRegistered", args[2]);
|
||||
return;
|
||||
}
|
||||
String playerName = player.getName();
|
||||
if(playerName == null || playerName.isEmpty()) {
|
||||
playerName = args[1];
|
||||
}
|
||||
region.setLandlord(player.getUniqueId(), playerName);
|
||||
region.update();
|
||||
messageBridge.message(sender, "setlandlord-success", playerName, region);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
for(Player player : Utils.getOnlinePlayers()) {
|
||||
result.add(player.getName());
|
||||
}
|
||||
} else if(toComplete == 3) {
|
||||
result.addAll(fileManager.getRegionNames());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
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.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@Singleton
|
||||
public class SetownerCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
@Inject
|
||||
private IFileManager fileManager;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop setowner";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.setownerrent") || target.hasPermission("areashop.setownerbuy")) {
|
||||
return "help-setowner";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.setownerrent") && !sender.hasPermission("areashop.setownerbuy")) {
|
||||
messageBridge.message(sender, "setowner-noPermission");
|
||||
return;
|
||||
}
|
||||
GeneralRegion region;
|
||||
if(args.length < 2) {
|
||||
messageBridge.message(sender, "setowner-help");
|
||||
return;
|
||||
}
|
||||
if(args.length == 2) {
|
||||
if(sender instanceof Player) {
|
||||
// get the region by location
|
||||
List<GeneralRegion> regions = Utils.getImportantRegions(((Player)sender).getLocation());
|
||||
if(regions.isEmpty()) {
|
||||
messageBridge.message(sender, "cmd-noRegionsAtLocation");
|
||||
return;
|
||||
} else if(regions.size() > 1) {
|
||||
messageBridge.message(sender, "cmd-moreRegionsAtLocation");
|
||||
return;
|
||||
} else {
|
||||
region = regions.get(0);
|
||||
}
|
||||
} else {
|
||||
messageBridge.message(sender, "cmd-automaticRegionOnlyByPlayer");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
region = fileManager.getRegion(args[2]);
|
||||
}
|
||||
if(region == null) {
|
||||
messageBridge.message(sender, "setowner-notRegistered");
|
||||
return;
|
||||
}
|
||||
|
||||
if(region instanceof RentRegion && !sender.hasPermission("areashop.setownerrent")) {
|
||||
messageBridge.message(sender, "setowner-noPermissionRent", region);
|
||||
return;
|
||||
}
|
||||
if(region instanceof BuyRegion && !sender.hasPermission("areashop.setownerbuy")) {
|
||||
messageBridge.message(sender, "setowner-noPermissionBuy", region);
|
||||
return;
|
||||
}
|
||||
|
||||
UUID uuid = null;
|
||||
@SuppressWarnings("deprecation")
|
||||
OfflinePlayer player = Bukkit.getOfflinePlayer(args[1]);
|
||||
if(player != null) {
|
||||
uuid = player.getUniqueId();
|
||||
}
|
||||
if(uuid == null) {
|
||||
messageBridge.message(sender, "setowner-noPlayer", args[1], region);
|
||||
return;
|
||||
}
|
||||
|
||||
if(region instanceof RentRegion) {
|
||||
RentRegion rent = (RentRegion)region;
|
||||
if(rent.isRenter(uuid)) {
|
||||
// extend
|
||||
rent.setRentedUntil(rent.getRentedUntil() + rent.getDuration());
|
||||
rent.setRenter(uuid);
|
||||
messageBridge.message(sender, "setowner-succesRentExtend", region);
|
||||
} else {
|
||||
// change
|
||||
if(!rent.isRented()) {
|
||||
rent.setRentedUntil(Calendar.getInstance().getTimeInMillis() + rent.getDuration());
|
||||
}
|
||||
rent.setRenter(uuid);
|
||||
messageBridge.message(sender, "setowner-succesRent", region);
|
||||
}
|
||||
}
|
||||
if(region instanceof BuyRegion) {
|
||||
BuyRegion buy = (BuyRegion)region;
|
||||
buy.setBuyer(uuid);
|
||||
messageBridge.message(sender, "setowner-succesBuy", region);
|
||||
}
|
||||
region.getFriendsFeature().deleteFriend(region.getOwner(), null);
|
||||
region.update();
|
||||
region.saveRequired();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
for(Player player : Utils.getOnlinePlayers()) {
|
||||
result.add(player.getName());
|
||||
}
|
||||
} else if(toComplete == 3) {
|
||||
result.addAll(fileManager.getRegionNames());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
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 javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Singleton
|
||||
public class SetpriceCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
@Inject
|
||||
private IFileManager fileManager;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop setprice";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.setprice")) {
|
||||
return "help-setprice";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.setprice") && (!sender.hasPermission("areashop.setprice.landlord") && sender instanceof Player)) {
|
||||
messageBridge.message(sender, "setprice-noPermission");
|
||||
return;
|
||||
}
|
||||
if(args.length < 2 || args[1] == null) {
|
||||
messageBridge.message(sender, "setprice-help");
|
||||
return;
|
||||
}
|
||||
GeneralRegion region;
|
||||
if(args.length < 3) {
|
||||
if(sender instanceof Player) {
|
||||
// get the region by location
|
||||
List<GeneralRegion> regions = Utils.getImportantRegions(((Player)sender).getLocation());
|
||||
if(regions.isEmpty()) {
|
||||
messageBridge.message(sender, "cmd-noRegionsAtLocation");
|
||||
return;
|
||||
} else if(regions.size() > 1) {
|
||||
messageBridge.message(sender, "cmd-moreRegionsAtLocation");
|
||||
return;
|
||||
} else {
|
||||
region = regions.get(0);
|
||||
}
|
||||
} else {
|
||||
messageBridge.message(sender, "cmd-automaticRegionOnlyByPlayer");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
region = fileManager.getRegion(args[2]);
|
||||
}
|
||||
if(region == null) {
|
||||
messageBridge.message(sender, "setprice-notRegistered", args[2]);
|
||||
return;
|
||||
}
|
||||
if(!sender.hasPermission("areashop.setprice") && !(sender instanceof Player && region.isLandlord(((Player)sender).getUniqueId()))) {
|
||||
messageBridge.message(sender, "setprice-noLandlord", region);
|
||||
return;
|
||||
}
|
||||
if("default".equalsIgnoreCase(args[1]) || "reset".equalsIgnoreCase(args[1])) {
|
||||
if(region instanceof RentRegion) {
|
||||
((RentRegion)region).setPrice(null);
|
||||
} else if(region instanceof BuyRegion) {
|
||||
((BuyRegion)region).setPrice(null);
|
||||
}
|
||||
region.update();
|
||||
messageBridge.message(sender, "setprice-successRemoved", region);
|
||||
return;
|
||||
}
|
||||
double price;
|
||||
try {
|
||||
price = Double.parseDouble(args[1]);
|
||||
} catch(NumberFormatException e) {
|
||||
messageBridge.message(sender, "setprice-wrongPrice", args[1], region);
|
||||
return;
|
||||
}
|
||||
if(region instanceof RentRegion) {
|
||||
((RentRegion)region).setPrice(price);
|
||||
messageBridge.message(sender, "setprice-successRent", region);
|
||||
} else if(region instanceof BuyRegion) {
|
||||
((BuyRegion)region).setPrice(price);
|
||||
messageBridge.message(sender, "setprice-successBuy", region);
|
||||
}
|
||||
region.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
List<String> result = new ArrayList<>();
|
||||
if(toComplete == 3) {
|
||||
result = fileManager.getRegionNames();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Singleton
|
||||
public class SetrestoreCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
@Inject
|
||||
private IFileManager fileManager;
|
||||
@Inject
|
||||
private Plugin plugin;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop setrestore";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.setrestore")) {
|
||||
return "help-setrestore";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.setrestore")) {
|
||||
messageBridge.message(sender, "setrestore-noPermission");
|
||||
return;
|
||||
}
|
||||
if(args.length <= 2 || args[1] == null || args[2] == null) {
|
||||
messageBridge.message(sender, "setrestore-help");
|
||||
return;
|
||||
}
|
||||
GeneralRegion region = fileManager.getRegion(args[1]);
|
||||
if(region == null) {
|
||||
messageBridge.message(sender, "setrestore-notRegistered", args[1]);
|
||||
return;
|
||||
}
|
||||
Boolean value = null;
|
||||
if(args[2].equalsIgnoreCase("true")) {
|
||||
value = true;
|
||||
} else if(args[2].equalsIgnoreCase("false")) {
|
||||
value = false;
|
||||
}
|
||||
region.setRestoreSetting(value);
|
||||
String valueString = "general";
|
||||
if(value != null) {
|
||||
valueString = value + "";
|
||||
}
|
||||
if(args.length > 3) {
|
||||
region.setSchematicProfile(args[3]);
|
||||
messageBridge.message(sender, "setrestore-successProfile", valueString, args[3], region);
|
||||
} else {
|
||||
messageBridge.message(sender, "setrestore-success", valueString, region);
|
||||
}
|
||||
region.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
List<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
result = fileManager.getRegionNames();
|
||||
} else if(toComplete == 3) {
|
||||
result.add("true");
|
||||
result.add("false");
|
||||
result.add("general");
|
||||
} else if(toComplete == 4) {
|
||||
ConfigurationSection schemProfiles = fileManager.getConfig().getConfigurationSection("schematicProfiles");
|
||||
if (schemProfiles != null) {
|
||||
result.addAll(schemProfiles.getKeys(false));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
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 javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Singleton
|
||||
public class SetteleportCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
@Inject
|
||||
private IFileManager fileManager;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop settp";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.setteleportall") || target.hasPermission("areashop.setteleport")) {
|
||||
return "help-setteleport";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)) {
|
||||
return false;
|
||||
}
|
||||
Player player = (Player)person;
|
||||
return player.hasPermission("areashop.setteleportall")
|
||||
|| region.isOwner(player) && player.hasPermission("areashop.setteleport");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.setteleport") && !sender.hasPermission("areashop.setteleportall")) {
|
||||
messageBridge.message(sender, "setteleport-noPermission");
|
||||
return;
|
||||
}
|
||||
if(!(sender instanceof Player)) {
|
||||
messageBridge.message(sender, "onlyByPlayer");
|
||||
return;
|
||||
}
|
||||
Player player = (Player)sender;
|
||||
GeneralRegion region;
|
||||
if(args.length < 2) {
|
||||
// get the region by location
|
||||
List<GeneralRegion> regions = Utils.getImportantRegions(((Player)sender).getLocation());
|
||||
if(regions.isEmpty()) {
|
||||
messageBridge.message(sender, "cmd-noRegionsAtLocation");
|
||||
return;
|
||||
} else if(regions.size() > 1) {
|
||||
messageBridge.message(sender, "cmd-moreRegionsAtLocation");
|
||||
return;
|
||||
} else {
|
||||
region = regions.get(0);
|
||||
}
|
||||
} else {
|
||||
region = fileManager.getRegion(args[1]);
|
||||
}
|
||||
|
||||
boolean owner;
|
||||
|
||||
if(region == null) {
|
||||
messageBridge.message(player, "setteleport-noRentOrBuy", args[1]);
|
||||
return;
|
||||
}
|
||||
if(region instanceof RentRegion) {
|
||||
owner = player.getUniqueId().equals(((RentRegion)region).getRenter());
|
||||
} else {
|
||||
owner = player.getUniqueId().equals(((BuyRegion)region).getBuyer());
|
||||
}
|
||||
if(!player.hasPermission("areashop.setteleport")) {
|
||||
messageBridge.message(player, "setteleport-noPermission", region);
|
||||
return;
|
||||
} else if(!owner && !player.hasPermission("areashop.setteleportall")) {
|
||||
messageBridge.message(player, "setteleport-noPermissionOther", region);
|
||||
return;
|
||||
}
|
||||
|
||||
ProtectedRegion wgRegion = region.getRegion();
|
||||
if(args.length > 2 && args[2] != null && (args[2].equalsIgnoreCase("reset") || args[2].equalsIgnoreCase("yes") || args[2].equalsIgnoreCase("true"))) {
|
||||
region.getTeleportFeature().setTeleport(null);
|
||||
region.update();
|
||||
messageBridge.message(player, "setteleport-reset", region);
|
||||
return;
|
||||
}
|
||||
if(!player.hasPermission("areashop.setteleportoutsideregion") && (wgRegion == null || !wgRegion.contains(player.getLocation().getBlockX(), player.getLocation().getBlockY(), player.getLocation().getBlockZ()))) {
|
||||
messageBridge.message(player, "setteleport-notInside", region);
|
||||
return;
|
||||
}
|
||||
region.getTeleportFeature().setTeleport(player.getLocation());
|
||||
region.update();
|
||||
messageBridge.message(player, "setteleport-success", region);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
result.addAll(fileManager.getRegionNames());
|
||||
} else if(toComplete == 3) {
|
||||
result.add("reset");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,283 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
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 javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Singleton
|
||||
public class StackCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
@Inject
|
||||
private IFileManager fileManager;
|
||||
@Inject
|
||||
private WorldEditInterface worldEditInterface;
|
||||
@Inject
|
||||
private WorldGuardInterface worldGuardInterface;
|
||||
@Inject
|
||||
private RegionFactory regionFactory;
|
||||
@Inject
|
||||
private Plugin plugin;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop stack";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.stack")) {
|
||||
return "help-stack";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
// Check permission
|
||||
if(!sender.hasPermission("areashop.stack")) {
|
||||
messageBridge.message(sender, "stack-noPermission");
|
||||
return;
|
||||
}
|
||||
// Only from ingame
|
||||
if(!(sender instanceof Player)) {
|
||||
messageBridge.message(sender, "cmd-onlyByPlayer");
|
||||
return;
|
||||
}
|
||||
final Player player = (Player)sender;
|
||||
// Specify enough arguments
|
||||
if(args.length < 5) {
|
||||
messageBridge.message(sender, "stack-help");
|
||||
return;
|
||||
}
|
||||
// Check amount
|
||||
int tempAmount = -1;
|
||||
try {
|
||||
tempAmount = Integer.parseInt(args[1]);
|
||||
} catch(NumberFormatException e) {
|
||||
// Incorrect number
|
||||
}
|
||||
if(tempAmount <= 0) {
|
||||
messageBridge.message(player, "stack-wrongAmount", args[1]);
|
||||
return;
|
||||
}
|
||||
// Check gap
|
||||
int gap;
|
||||
try {
|
||||
gap = Integer.parseInt(args[2]);
|
||||
} catch(NumberFormatException e) {
|
||||
messageBridge.message(player, "stack-wrongGap", args[2]);
|
||||
return;
|
||||
}
|
||||
// Check region type
|
||||
if(!"rent".equalsIgnoreCase(args[4]) && !"buy".equalsIgnoreCase(args[4])) {
|
||||
messageBridge.message(sender, "stack-help");
|
||||
return;
|
||||
}
|
||||
// Get WorldEdit selection
|
||||
final WorldEditSelection selection = worldEditInterface.getPlayerSelection(player);
|
||||
if(selection == null) {
|
||||
messageBridge.message(player, "stack-noSelection");
|
||||
return;
|
||||
}
|
||||
// Get or create group
|
||||
RegionGroup group = null;
|
||||
if(args.length > 5) {
|
||||
group = fileManager.getGroup(args[5]);
|
||||
if(group == null) {
|
||||
group = regionFactory.createRegionGroup(args[5]);
|
||||
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)) {
|
||||
messageBridge.message(player, "stack-unclearDirection", facing.toString().toLowerCase().replace('_', '-'));
|
||||
return;
|
||||
}
|
||||
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);
|
||||
}
|
||||
AreaShop.debug(" calculated shift vector: " + shift + ", with facing=" + facing);
|
||||
// Create regions and add them to AreaShop
|
||||
final String nameTemplate = args[3];
|
||||
|
||||
|
||||
final int regionsPerTick = plugin.getConfig().getInt("adding.regionsPerTick");
|
||||
final boolean rentRegions = "rent".equalsIgnoreCase(args[4]);
|
||||
final int amount = tempAmount;
|
||||
final RegionGroup finalGroup = group;
|
||||
final Vector finalShift = shift;
|
||||
String type;
|
||||
if(rentRegions) {
|
||||
type = "rent";
|
||||
} else {
|
||||
type = "buy";
|
||||
}
|
||||
Message groupsMessage = Message.empty();
|
||||
if(group != null) {
|
||||
groupsMessage = Message.fromKey("stack-addToGroup").replacements(group.getName());
|
||||
}
|
||||
messageBridge.message(player, "stack-accepted", amount, type, gap, nameTemplate, groupsMessage);
|
||||
messageBridge.message(player, "stack-addStart", amount, regionsPerTick * 20);
|
||||
|
||||
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());
|
||||
new BukkitRunnable() {
|
||||
private int current = -1;
|
||||
private final RegionManager manager = AreaShop.getInstance().getRegionManager(selection.getWorld());
|
||||
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) {
|
||||
// Create the region name
|
||||
String regionName = countToName(nameTemplate, counter);
|
||||
while(manager.getRegion(regionName) != null || AreaShop.getInstance().getFileManager().getRegion(regionName) != null) {
|
||||
counter++;
|
||||
regionName = countToName(nameTemplate, 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(finalShift.clone().multiply(current));
|
||||
Vector maximum = maximumVector.clone().add(finalShift.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(rentRegions) {
|
||||
newRegion = regionFactory.createRentRegion(regionName, selection.getWorld());
|
||||
|
||||
} else {
|
||||
newRegion = regionFactory.createBuyRegion(regionName, selection.getWorld());
|
||||
}
|
||||
|
||||
if(finalGroup != null) {
|
||||
finalGroup.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();
|
||||
}
|
||||
}
|
||||
}.runTaskTimer(plugin, 1, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
List<String> result = new ArrayList<>();
|
||||
if(toComplete == 5) {
|
||||
result.add("rent");
|
||||
result.add("buy");
|
||||
} else if(toComplete == 6) {
|
||||
result.addAll(fileManager.getGroupNames());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Singleton
|
||||
public class StopresellCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
@Inject
|
||||
private IFileManager fileManager;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop stopresell";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.stopresellall") || target.hasPermission("areashop.stopresell")) {
|
||||
return "help-stopResell";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.stopresell") && !sender.hasPermission("areashop.stopresellall")) {
|
||||
messageBridge.message(sender, "stopresell-noPermissionOther");
|
||||
return;
|
||||
}
|
||||
|
||||
BuyRegion buy;
|
||||
if(args.length <= 1) {
|
||||
if(sender instanceof Player) {
|
||||
// get the region by location
|
||||
List<BuyRegion> regions = Utils.getImportantBuyRegions(((Player)sender).getLocation());
|
||||
if(regions.isEmpty()) {
|
||||
messageBridge.message(sender, "cmd-noRegionsAtLocation");
|
||||
return;
|
||||
} else if(regions.size() > 1) {
|
||||
messageBridge.message(sender, "cmd-moreRegionsAtLocation");
|
||||
return;
|
||||
} else {
|
||||
buy = regions.get(0);
|
||||
}
|
||||
} else {
|
||||
messageBridge.message(sender, "cmd-automaticRegionOnlyByPlayer");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
buy = fileManager.getBuy(args[1]);
|
||||
if(buy == null) {
|
||||
messageBridge.message(sender, "stopresell-notRegistered", args[1]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(buy == null) {
|
||||
messageBridge.message(sender, "cmd-noRegionsAtLocation");
|
||||
return;
|
||||
}
|
||||
if(!buy.isInResellingMode()) {
|
||||
messageBridge.message(sender, "stopresell-notResell", buy);
|
||||
return;
|
||||
}
|
||||
if(sender.hasPermission("areashop.stopresellall")) {
|
||||
buy.disableReselling();
|
||||
buy.update();
|
||||
messageBridge.message(sender, "stopresell-success", buy);
|
||||
} else if(sender.hasPermission("areashop.stopresell") && sender instanceof Player) {
|
||||
if(buy.isOwner((Player)sender)) {
|
||||
buy.disableReselling();
|
||||
buy.update();
|
||||
messageBridge.message(sender, "stopresell-success", buy);
|
||||
} else {
|
||||
messageBridge.message(sender, "stopresell-noPermissionOther", buy);
|
||||
}
|
||||
} else {
|
||||
messageBridge.message(sender, "stopresell-noPermission", buy);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
for(BuyRegion region : fileManager.getBuysRef()) {
|
||||
if(region.isSold() && region.isInResellingMode()) {
|
||||
result.add(region.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Singleton
|
||||
public class TeleportCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
@Inject
|
||||
private IFileManager fileManager;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop tp";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.teleportall") || target.hasPermission("areashop.teleport")) {
|
||||
return "help-teleport";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)) {
|
||||
return false;
|
||||
}
|
||||
Player player = (Player)person;
|
||||
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 void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.teleport") && !sender.hasPermission("areashop.teleportall") && !sender.hasPermission("areashop.teleportavailable") && !sender.hasPermission("areashop.teleportavailablesign") && !sender.hasPermission("areashop.teleportsign") && !sender.hasPermission("areashop.teleportsignall") && !sender.hasPermission("areashop.teleportfriend") && !sender.hasPermission("teleportfriendsign")) {
|
||||
messageBridge.message(sender, "teleport-noPermission");
|
||||
return;
|
||||
}
|
||||
if(!(sender instanceof Player)) {
|
||||
messageBridge.message(sender, "cmd-onlyByPlayer");
|
||||
return;
|
||||
}
|
||||
if(args.length <= 1 || args[1] == null) {
|
||||
messageBridge.message(sender, "teleport-help");
|
||||
return;
|
||||
}
|
||||
Player player = (Player)sender;
|
||||
GeneralRegion region = fileManager.getRegion(args[1]);
|
||||
if(region == null) {
|
||||
messageBridge.message(player, "teleport-noRentOrBuy", args[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean toSign = args.length >= 3 && (
|
||||
args[2].equalsIgnoreCase("sign")
|
||||
|| args[2].equalsIgnoreCase("yes")
|
||||
|| args[2].equalsIgnoreCase("true")
|
||||
);
|
||||
region.getTeleportFeature().teleportPlayer(player, toSign);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
result.addAll(fileManager.getRegionNames());
|
||||
} else if(toComplete == 3) {
|
||||
result.add("sign");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package me.wiefferink.areashop.commands;
|
||||
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
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 javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Singleton
|
||||
public class UnrentCommand extends CommandAreaShop {
|
||||
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
@Inject
|
||||
private IFileManager fileManager;
|
||||
|
||||
@Override
|
||||
public String getCommandStart() {
|
||||
return "areashop unrent";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelp(CommandSender target) {
|
||||
if(target.hasPermission("areashop.unrent") || target.hasPermission("areashop.unrentown")) {
|
||||
return "help-unrent";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 player = (Player)person;
|
||||
return region.isOwner(player) && person.hasPermission("areashop.unrentown");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!sender.hasPermission("areashop.unrent") && !sender.hasPermission("areashop.unrentown")) {
|
||||
messageBridge.message(sender, "unrent-noPermission");
|
||||
return;
|
||||
}
|
||||
RentRegion rent;
|
||||
if(args.length <= 1) {
|
||||
if(sender instanceof Player) {
|
||||
// get the region by location
|
||||
List<RentRegion> regions = Utils.getImportantRentRegions(((Player)sender).getLocation());
|
||||
if(regions.isEmpty()) {
|
||||
messageBridge.message(sender, "cmd-noRegionsAtLocation");
|
||||
return;
|
||||
} else if(regions.size() > 1) {
|
||||
messageBridge.message(sender, "cmd-moreRegionsAtLocation");
|
||||
return;
|
||||
} else {
|
||||
rent = regions.get(0);
|
||||
}
|
||||
} else {
|
||||
messageBridge.message(sender, "cmd-automaticRegionOnlyByPlayer");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
rent = fileManager.getRent(args[1]);
|
||||
}
|
||||
if(rent == null) {
|
||||
messageBridge.message(sender, "unrent-notRegistered");
|
||||
return;
|
||||
}
|
||||
if(!rent.isRented()) {
|
||||
messageBridge.message(sender, "unrent-notRented", rent);
|
||||
return;
|
||||
}
|
||||
rent.unRent(true, sender);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
|
||||
ArrayList<String> result = new ArrayList<>();
|
||||
if(toComplete == 2) {
|
||||
for(RentRegion region : fileManager.getRentsRef()) {
|
||||
if(region.isRented()) {
|
||||
result.add(region.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package me.wiefferink.areashop.events;
|
||||
|
||||
public class CancellableRegionEvent<T> extends RegionEvent<T> {
|
||||
|
||||
private boolean cancelled;
|
||||
private String reason;
|
||||
|
||||
public CancellableRegionEvent(T region) {
|
||||
super(region);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel the event from happening.
|
||||
* @param reason The reason of cancelling, used for display to the user, should end with a dot
|
||||
*/
|
||||
public void cancel(String reason) {
|
||||
this.cancelled = true;
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Let the event continue, possible overwriting a cancel() call from another plugin.
|
||||
*/
|
||||
public void allow() {
|
||||
this.cancelled = false;
|
||||
this.reason = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the event has been cancelled.
|
||||
* @return true if the event has been cancelled, otherwise false
|
||||
*/
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the reason why this event is cancelled.
|
||||
* @return null if there is no reason or the event is not cancelled, otherwise a string
|
||||
*/
|
||||
public String getReason() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package me.wiefferink.areashop.events;
|
||||
|
||||
public class NotifyRegionEvent<T> extends RegionEvent<T> {
|
||||
public NotifyRegionEvent(T region) {
|
||||
super(region);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
# Events
|
||||
|
||||
This package contains event classes that allow other plugins to listen to events about AreaShop regions.
|
||||
|
||||
* `RegionEvent` class represents a generic event.
|
||||
* `CancellableRegionEvent` represents an event that has a region and can be cancelled.
|
||||
* `NotifyRegionEvent` represents events that are to inform only, and cannot be cancelled anymore (an `CancellableRegionEvent` would be sent first).
|
||||
@@ -0,0 +1,31 @@
|
||||
package me.wiefferink.areashop.events;
|
||||
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
public class RegionEvent<T> extends Event {
|
||||
protected T region;
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
public RegionEvent(T region) {
|
||||
this.region = region;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
// Required by Bukkit/Spigot
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the region of this event.
|
||||
* @return The region the event is about
|
||||
*/
|
||||
public T getRegion() {
|
||||
return region;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package me.wiefferink.areashop.events.ask;
|
||||
|
||||
import me.wiefferink.areashop.events.CancellableRegionEvent;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
|
||||
/**
|
||||
* Broadcasted when a region has been added to AreaShop.
|
||||
*/
|
||||
public class AddingRegionEvent extends CancellableRegionEvent<GeneralRegion> {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param region The region that has been added
|
||||
*/
|
||||
public AddingRegionEvent(GeneralRegion region) {
|
||||
super(region);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package me.wiefferink.areashop.events.ask;
|
||||
|
||||
import me.wiefferink.areashop.events.CancellableRegionEvent;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
/**
|
||||
* Broadcasted when a player tries to buy a region.
|
||||
*/
|
||||
public class BuyingRegionEvent extends CancellableRegionEvent<BuyRegion> {
|
||||
|
||||
private final OfflinePlayer player;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param region The region that is about to get bought
|
||||
* @param player The player that tries to buy the region
|
||||
*/
|
||||
public BuyingRegionEvent(BuyRegion region, OfflinePlayer player) {
|
||||
super(region);
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player that is trying to buy the region.
|
||||
* @return The player that is trying to buy the region
|
||||
*/
|
||||
public OfflinePlayer getPlayer() {
|
||||
return player;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package me.wiefferink.areashop.events.ask;
|
||||
|
||||
import me.wiefferink.areashop.events.CancellableRegionEvent;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
|
||||
/**
|
||||
* Broadcasted when a region has been added to AreaShop.
|
||||
*/
|
||||
public class DeletingRegionEvent extends CancellableRegionEvent<GeneralRegion> {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param region The region that has been added
|
||||
*/
|
||||
public DeletingRegionEvent(GeneralRegion region) {
|
||||
super(region);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package me.wiefferink.areashop.events.ask;
|
||||
|
||||
import me.wiefferink.areashop.events.CancellableRegionEvent;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
/**
|
||||
* Broadcasted when a player tries to rent a region.
|
||||
*/
|
||||
public class RentingRegionEvent extends CancellableRegionEvent<RentRegion> {
|
||||
|
||||
private final OfflinePlayer player;
|
||||
private final boolean extending;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param region The region that is about to be rented
|
||||
* @param player The player that tries to rent the region
|
||||
* @param extending true if the player is extending the rental of the region, otherwise false
|
||||
*/
|
||||
public RentingRegionEvent(RentRegion region, OfflinePlayer player, boolean extending) {
|
||||
super(region);
|
||||
this.player = player;
|
||||
this.extending = extending;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player that is trying to rent the region.
|
||||
* @return The player that is trying to rent the region
|
||||
*/
|
||||
public OfflinePlayer getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the player is extending the region or renting it for the first time.
|
||||
* @return true if the player tries to extend the region, false if he tries to rent it the first time
|
||||
*/
|
||||
public boolean isExtending() {
|
||||
return extending;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package me.wiefferink.areashop.events.ask;
|
||||
|
||||
import me.wiefferink.areashop.events.CancellableRegionEvent;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
/**
|
||||
* Broadcasted when a player tries to resell a region.
|
||||
*/
|
||||
public class ResellingRegionEvent extends CancellableRegionEvent<BuyRegion> {
|
||||
|
||||
private final OfflinePlayer player;
|
||||
|
||||
/**
|
||||
* Contructor.
|
||||
* @param region The region that the player is trying to resell
|
||||
* @param player The player that is trying to buy this region from the current owner
|
||||
*/
|
||||
public ResellingRegionEvent(BuyRegion region, OfflinePlayer player) {
|
||||
super(region);
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player that is trying to buy the region.
|
||||
* @return The player that is trying to buy the region
|
||||
*/
|
||||
public OfflinePlayer getBuyer() {
|
||||
return player;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package me.wiefferink.areashop.events.ask;
|
||||
|
||||
import me.wiefferink.areashop.events.CancellableRegionEvent;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
|
||||
/**
|
||||
* Broadcasted when a region is about to get sold.
|
||||
*/
|
||||
public class SellingRegionEvent extends CancellableRegionEvent<BuyRegion> {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param region The region that is about to get sold
|
||||
*/
|
||||
public SellingRegionEvent(BuyRegion region) {
|
||||
super(region);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package me.wiefferink.areashop.events.ask;
|
||||
|
||||
import me.wiefferink.areashop.events.CancellableRegionEvent;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
|
||||
/**
|
||||
* Broadcasted when a region is about to be unrented.
|
||||
*/
|
||||
public class UnrentingRegionEvent extends CancellableRegionEvent<RentRegion> {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param region The region that is about to be unrented
|
||||
*/
|
||||
public UnrentingRegionEvent(RentRegion region) {
|
||||
super(region);
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package me.wiefferink.areashop.events.askandnotify;
|
||||
|
||||
import me.wiefferink.areashop.events.CancellableRegionEvent;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
/**
|
||||
* Broadcasted when a friend is being added to a region.
|
||||
*/
|
||||
public class AddedFriendEvent extends CancellableRegionEvent<GeneralRegion> {
|
||||
|
||||
private final OfflinePlayer friend;
|
||||
private final CommandSender by;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param region The region the friend is getting added to
|
||||
* @param friend The friend that is about to be added
|
||||
* @param by The CommandSender that is adding the friend, or null if none
|
||||
*/
|
||||
public AddedFriendEvent(GeneralRegion region, OfflinePlayer friend, CommandSender by) {
|
||||
super(region);
|
||||
this.friend = friend;
|
||||
this.by = by;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the OfflinePlayer that is getting added as friend.
|
||||
* @return The friend that is getting added
|
||||
*/
|
||||
public OfflinePlayer getFriend() {
|
||||
return friend;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the CommandSender that is adding the friend.
|
||||
* @return null if none, a CommandSender if done by someone (likely Player or ConsoleCommandSender)
|
||||
*/
|
||||
public CommandSender getBy() {
|
||||
return by;
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package me.wiefferink.areashop.events.askandnotify;
|
||||
|
||||
import me.wiefferink.areashop.events.CancellableRegionEvent;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
/**
|
||||
* Broadcasted when a friend is being added to a region.
|
||||
*/
|
||||
public class DeletedFriendEvent extends CancellableRegionEvent<GeneralRegion> {
|
||||
|
||||
private final OfflinePlayer friend;
|
||||
private final CommandSender by;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param region The region the friend is getting added to
|
||||
* @param friend The friend that is about to be added
|
||||
* @param by The CommandSender that is adding the friend, or null if none
|
||||
*/
|
||||
public DeletedFriendEvent(GeneralRegion region, OfflinePlayer friend, CommandSender by) {
|
||||
super(region);
|
||||
this.friend = friend;
|
||||
this.by = by;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the OfflinePlayer that is getting added as friend.
|
||||
* @return The friend that is getting added
|
||||
*/
|
||||
public OfflinePlayer getFriend() {
|
||||
return friend;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the CommandSender that is adding the friend.
|
||||
* @return null if none, a CommandSender if done by someone (likely Player or ConsoleCommandSender)
|
||||
*/
|
||||
public CommandSender getBy() {
|
||||
return by;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package me.wiefferink.areashop.events.notify;
|
||||
|
||||
import me.wiefferink.areashop.events.NotifyRegionEvent;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
|
||||
/**
|
||||
* Broadcasted when a region has been added to AreaShop.
|
||||
*/
|
||||
public class AddedRegionEvent extends NotifyRegionEvent<GeneralRegion> {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param region The region that has been added
|
||||
*/
|
||||
public AddedRegionEvent(GeneralRegion region) {
|
||||
super(region);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package me.wiefferink.areashop.events.notify;
|
||||
|
||||
import me.wiefferink.areashop.events.NotifyRegionEvent;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
|
||||
/**
|
||||
* Broadcasted when a region has been bought.
|
||||
*/
|
||||
public class BoughtRegionEvent extends NotifyRegionEvent<BuyRegion> {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param region The region that has been bought
|
||||
*/
|
||||
public BoughtRegionEvent(BuyRegion region) {
|
||||
super(region);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package me.wiefferink.areashop.events.notify;
|
||||
|
||||
import me.wiefferink.areashop.events.NotifyRegionEvent;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
|
||||
/**
|
||||
* Broadcasted when a region has been removed from AreaShop.
|
||||
*/
|
||||
public class DeletedRegionEvent extends NotifyRegionEvent<GeneralRegion> {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param region The region that has been removed
|
||||
*/
|
||||
public DeletedRegionEvent(GeneralRegion region) {
|
||||
super(region);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package me.wiefferink.areashop.events.notify;
|
||||
|
||||
import me.wiefferink.areashop.events.NotifyRegionEvent;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
|
||||
/**
|
||||
* Broadcasted when a region has been rented.
|
||||
*/
|
||||
public class RentedRegionEvent extends NotifyRegionEvent<RentRegion> {
|
||||
|
||||
private final boolean extended;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param region The region that has been rented
|
||||
* @param extended true if the region has been extended, false if this is the first time buying the region
|
||||
*/
|
||||
public RentedRegionEvent(RentRegion region, boolean extended) {
|
||||
super(region);
|
||||
this.region = region;
|
||||
this.extended = extended;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the region was extended or rented for the first time.
|
||||
* @return true if the region was extended, false when rented for the first time
|
||||
*/
|
||||
public boolean hasExtended() {
|
||||
return extended;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package me.wiefferink.areashop.events.notify;
|
||||
|
||||
import me.wiefferink.areashop.events.NotifyRegionEvent;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Broadcasted when a region has been resold.
|
||||
*/
|
||||
public class ResoldRegionEvent extends NotifyRegionEvent<BuyRegion> {
|
||||
|
||||
private final UUID from;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param region The region that has been resold
|
||||
* @param from The player from who the region has been resold to the current owner
|
||||
*/
|
||||
public ResoldRegionEvent(BuyRegion region, UUID from) {
|
||||
super(region);
|
||||
this.from = from;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player that the region has been bought from.
|
||||
* @return The UUID of the player that the region has been bought from
|
||||
*/
|
||||
public UUID getFromPlayer() {
|
||||
return from;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package me.wiefferink.areashop.events.notify;
|
||||
|
||||
import me.wiefferink.areashop.events.NotifyRegionEvent;
|
||||
import me.wiefferink.areashop.regions.BuyRegion;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Broadcasted when a region is sold.
|
||||
*/
|
||||
public class SoldRegionEvent extends NotifyRegionEvent<BuyRegion> {
|
||||
|
||||
private final UUID oldBuyer;
|
||||
private final double refundedMoney;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param region The region that has been sold
|
||||
* @param oldBuyer The player for which the region has been sold
|
||||
* @param refundedMoney The amount of money that has been refunded
|
||||
*/
|
||||
public SoldRegionEvent(BuyRegion region, UUID oldBuyer, double refundedMoney) {
|
||||
super(region);
|
||||
this.oldBuyer = oldBuyer;
|
||||
this.refundedMoney = refundedMoney;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player that the region is sold for.
|
||||
* @return The UUID of the player that the region is sold for
|
||||
*/
|
||||
public UUID getOldBuyer() {
|
||||
return oldBuyer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the amount that is paid back to the player.
|
||||
* @return The amount of money paid back to the player
|
||||
*/
|
||||
public double getRefundedMoney() {
|
||||
return refundedMoney;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package me.wiefferink.areashop.events.notify;
|
||||
|
||||
import me.wiefferink.areashop.events.NotifyRegionEvent;
|
||||
import me.wiefferink.areashop.regions.RentRegion;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Broadcasted when a region has been unrented.
|
||||
*/
|
||||
public class UnrentedRegionEvent extends NotifyRegionEvent<RentRegion> {
|
||||
|
||||
private final UUID oldRenter;
|
||||
private final double refundedMoney;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param region The region that has been unrented
|
||||
* @param oldRenter The player that rented the region before it was unrented
|
||||
* @param refundedMoney The amount of money that has been refunded
|
||||
*/
|
||||
public UnrentedRegionEvent(RentRegion region, UUID oldRenter, double refundedMoney) {
|
||||
super(region);
|
||||
this.oldRenter = oldRenter;
|
||||
this.refundedMoney = refundedMoney;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player that the region was unrented for.
|
||||
* @return The UUID of the player that the region was unrented for
|
||||
*/
|
||||
public UUID getOldRenter() {
|
||||
return oldRenter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the amount that is paid back to the player.
|
||||
* @return The amount of money paid back to the player
|
||||
*/
|
||||
public double getRefundedMoney() {
|
||||
return refundedMoney;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package me.wiefferink.areashop.events.notify;
|
||||
|
||||
import me.wiefferink.areashop.events.NotifyRegionEvent;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
|
||||
/**
|
||||
* Broadcasted when the data of a region changes.
|
||||
* Should be used for updating displays that use region data.
|
||||
*/
|
||||
public class UpdateRegionEvent extends NotifyRegionEvent<GeneralRegion> {
|
||||
|
||||
/**
|
||||
* Contructor.
|
||||
* @param region The region that has been updated
|
||||
*/
|
||||
public UpdateRegionEvent(GeneralRegion region) {
|
||||
super(region);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package me.wiefferink.areashop.features;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.events.ask.AddingRegionEvent;
|
||||
import me.wiefferink.areashop.events.ask.BuyingRegionEvent;
|
||||
import me.wiefferink.areashop.events.ask.DeletingRegionEvent;
|
||||
import me.wiefferink.areashop.events.ask.RentingRegionEvent;
|
||||
import me.wiefferink.areashop.events.ask.ResellingRegionEvent;
|
||||
import me.wiefferink.areashop.events.ask.SellingRegionEvent;
|
||||
import me.wiefferink.areashop.events.ask.UnrentingRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.AddedRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.BoughtRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.DeletedRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.RentedRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.ResoldRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.SoldRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.UnrentedRegionEvent;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.List;
|
||||
|
||||
@Singleton
|
||||
public class CommandsFeature extends RegionFeature {
|
||||
|
||||
@Inject
|
||||
CommandsFeature(AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run command for a certain event.
|
||||
* @param region Region to execute the events for
|
||||
* @param event The event
|
||||
* @param before The 'before' or 'after' commands
|
||||
*/
|
||||
public void runEventCommands(GeneralRegion region, GeneralRegion.RegionEvent event, boolean before) {
|
||||
ConfigurationSection eventCommandProfileSection = region.getConfigurationSectionSetting("general.eventCommandProfile", "eventCommandProfiles");
|
||||
if(eventCommandProfileSection == null) {
|
||||
return;
|
||||
}
|
||||
List<String> commands = eventCommandProfileSection.getStringList(event.getValue() + "." + (before ? "before" : "after"));
|
||||
if(commands.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
region.runCommands(Bukkit.getConsoleSender(), commands);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void addingRegion(AddingRegionEvent event) {
|
||||
runEventCommands(event.getRegion(), GeneralRegion.RegionEvent.CREATED, true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void addedRegion(AddedRegionEvent event) {
|
||||
runEventCommands(event.getRegion(), GeneralRegion.RegionEvent.CREATED, false);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void deletingRegion(DeletingRegionEvent event) {
|
||||
runEventCommands(event.getRegion(), GeneralRegion.RegionEvent.DELETED, true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void deletedRegion(DeletedRegionEvent event) {
|
||||
runEventCommands(event.getRegion(), GeneralRegion.RegionEvent.DELETED, false);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void rentingRegion(RentingRegionEvent event) {
|
||||
// Technically the rent can still be cancelled if the payment fails...
|
||||
runEventCommands(event.getRegion(), event.isExtending() ? GeneralRegion.RegionEvent.EXTENDED : GeneralRegion.RegionEvent.RENTED, true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void rentedRegion(RentedRegionEvent event) {
|
||||
runEventCommands(event.getRegion(), event.hasExtended() ? GeneralRegion.RegionEvent.EXTENDED : GeneralRegion.RegionEvent.RENTED, false);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void buyingRegion(BuyingRegionEvent event) {
|
||||
// Technically the buy can still be cancelled if the payment fails...
|
||||
runEventCommands(event.getRegion(), GeneralRegion.RegionEvent.BOUGHT, true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void boughtRegion(BoughtRegionEvent event) {
|
||||
runEventCommands(event.getRegion(), GeneralRegion.RegionEvent.BOUGHT, false);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void resellingRegion(ResellingRegionEvent event) {
|
||||
// Technically the resell can still be cancelled if the payment fails...
|
||||
runEventCommands(event.getRegion(), GeneralRegion.RegionEvent.RESELL, true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void resoldRegion(ResoldRegionEvent event) {
|
||||
runEventCommands(event.getRegion(), GeneralRegion.RegionEvent.RESELL, false);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void sellingRegion(SellingRegionEvent event) {
|
||||
runEventCommands(event.getRegion(), GeneralRegion.RegionEvent.SOLD, true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void soldRegion(SoldRegionEvent event) {
|
||||
runEventCommands(event.getRegion(), GeneralRegion.RegionEvent.SOLD, false);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void unrentingRegion(UnrentingRegionEvent event) {
|
||||
runEventCommands(event.getRegion(), GeneralRegion.RegionEvent.UNRENTED, true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void unrentedRegion(UnrentedRegionEvent event) {
|
||||
runEventCommands(event.getRegion(), GeneralRegion.RegionEvent.UNRENTED, false);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package me.wiefferink.areashop.features;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.events.ask.BuyingRegionEvent;
|
||||
import me.wiefferink.areashop.events.ask.RentingRegionEvent;
|
||||
import me.wiefferink.areashop.events.ask.ResellingRegionEvent;
|
||||
import me.wiefferink.areashop.events.ask.SellingRegionEvent;
|
||||
import me.wiefferink.areashop.events.ask.UnrentingRegionEvent;
|
||||
import me.wiefferink.areashop.events.askandnotify.AddedFriendEvent;
|
||||
import me.wiefferink.areashop.events.askandnotify.DeletedFriendEvent;
|
||||
import me.wiefferink.areashop.events.notify.AddedRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.BoughtRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.DeletedRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.RentedRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.ResoldRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.SoldRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.UnrentedRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.UpdateRegionEvent;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.event.EventHandler;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
@Singleton
|
||||
public class DebugFeature extends RegionFeature {
|
||||
|
||||
@Inject
|
||||
DebugFeature(@Nonnull AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void buyingRegion(BuyingRegionEvent event) {
|
||||
AreaShop.debug("BuyingRegionEvent: " + event.getPlayer().getName() + " is trying to buy " + event.getRegion().getName());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void boughtRegion(BoughtRegionEvent event) {
|
||||
AreaShop.debug("BoughtRegionEvent: " + event.getRegion().getPlayerName() + " bought " + event.getRegion().getName());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void sellingRegion(SellingRegionEvent event) {
|
||||
AreaShop.debug("SellingRegionEvent: " + event.getRegion().getName() + " is trying to sell " + event.getRegion().getName());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void soldRegion(SoldRegionEvent event) {
|
||||
AreaShop.debug("SoldRegionEvent: " + Utils.toName(event.getOldBuyer()) + " sold " + event.getRegion().getName());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void resellingRegion(ResellingRegionEvent event) {
|
||||
AreaShop.debug("ResellingRegionEvent: " + event.getRegion().getName() + " is trying to resell " + event.getRegion().getName());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void resoldRegion(ResoldRegionEvent event) {
|
||||
AreaShop.debug("ResoldRegionEvent: " + Utils.toName(event.getFromPlayer()) + " resold " + event.getRegion().getName() + " to " + event.getRegion().getPlayerName());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void rentingRegion(RentingRegionEvent event) {
|
||||
AreaShop.debug("RentingRegionEvent: " + event.getPlayer().getName() + " is trying to rent " + event.getRegion().getName() + ", extending=" + event.isExtending());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void rentedRegion(RentedRegionEvent event) {
|
||||
AreaShop.debug("RentedRegionEvent: " + event.getRegion().getPlayerName() + " rented " + event.getRegion().getName() + ", extending=" + event.hasExtended());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void unrentingRegion(UnrentingRegionEvent event) {
|
||||
AreaShop.debug("UnrentingRegionEvent: " + event.getRegion().getPlayerName() + " is trying to unrent " + event.getRegion().getName());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void unrentedRegion(UnrentedRegionEvent event) {
|
||||
AreaShop.debug("UnrentedRegionEvent: " + Utils.toName(event.getOldRenter()) + " unrented " + event.getRegion().getName());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void regionUpdate(UpdateRegionEvent event) {
|
||||
//AreaShop.debug("UpdateRegionEvent: " + event.getRegion().getName() + " updated");
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void addedRegion(AddedRegionEvent event) {
|
||||
AreaShop.debug("AddedRegionEvent: " + event.getRegion().getName());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void removedRegion(DeletedRegionEvent event) {
|
||||
AreaShop.debug("DeletedRegionEvent: " + event.getRegion().getName());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void addedFriend(AddedFriendEvent event) {
|
||||
AreaShop.debug("AddedFriendEvent: region " + event.getRegion().getName() + ", " + event.getFriend().getName() + " by " + (event.getBy() == null ? "<nobody>" : event.getBy().getName()));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void deleteFriend(DeletedFriendEvent event) {
|
||||
AreaShop.debug("DeletedFriendEvent: region " + event.getRegion().getName() + ", " + event.getFriend().getName() + " by " + (event.getBy() == null ? "<nobody>" : event.getBy().getName()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package me.wiefferink.areashop.features;
|
||||
|
||||
import me.wiefferink.areashop.features.signs.SignsFeature;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public interface FeatureFactory {
|
||||
|
||||
@Nonnull
|
||||
SignsFeature createSignsFeature(@Nonnull GeneralRegion generalRegion);
|
||||
|
||||
@Nonnull
|
||||
TeleportFeature createTeleportFeature(@Nonnull GeneralRegion generalRegion);
|
||||
|
||||
@Nonnull
|
||||
FriendsFeature createFriendsFeature(@Nonnull GeneralRegion generalRegion);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
package me.wiefferink.areashop.features;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.google.inject.assistedinject.AssistedInject;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.events.askandnotify.AddedFriendEvent;
|
||||
import me.wiefferink.areashop.events.askandnotify.DeletedFriendEvent;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class FriendsFeature extends RegionFeature {
|
||||
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
|
||||
@AssistedInject
|
||||
public FriendsFeature(@Nonnull AreaShop plugin, @Assisted @Nonnull GeneralRegion region) {
|
||||
super(plugin);
|
||||
setRegion(region);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a friend to the region.
|
||||
* @param player The UUID of the player to add
|
||||
* @param by The CommandSender that is adding the friend, or null
|
||||
* @return true if the friend has been added, false if adding a friend was cancelled by another plugin
|
||||
*/
|
||||
public boolean addFriend(UUID player, CommandSender by) {
|
||||
// Fire and check event
|
||||
AddedFriendEvent event = new AddedFriendEvent(getRegion(), Bukkit.getOfflinePlayer(player), by);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if(event.isCancelled()) {
|
||||
messageBridge.message(by, "general-cancelled", event.getReason(), this);
|
||||
return false;
|
||||
}
|
||||
|
||||
Set<String> friends = new HashSet<>(getRegion().getConfig().getStringList("general.friends"));
|
||||
friends.add(player.toString());
|
||||
List<String> list = new ArrayList<>(friends);
|
||||
getRegion().setSetting("general.friends", list);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a friend from the region.
|
||||
* @param player The UUID of the player to delete
|
||||
* @param by The CommandSender that is adding the friend, or null
|
||||
* @return true if the friend has been added, false if adding a friend was cancelled by another plugin
|
||||
*/
|
||||
public boolean deleteFriend(UUID player, CommandSender by) {
|
||||
// Fire and check event
|
||||
DeletedFriendEvent event = new DeletedFriendEvent(getRegion(), Bukkit.getOfflinePlayer(player), by);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if(event.isCancelled()) {
|
||||
messageBridge.message(by, "general-cancelled", event.getReason(), this);
|
||||
return false;
|
||||
}
|
||||
|
||||
Set<String> friends = new HashSet<>(getRegion().getConfig().getStringList("general.friends"));
|
||||
friends.remove(player.toString());
|
||||
List<String> list = new ArrayList<>(friends);
|
||||
if(list.isEmpty()) {
|
||||
getRegion().setSetting("general.friends", null);
|
||||
} else {
|
||||
getRegion().setSetting("general.friends", list);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of friends added to this region.
|
||||
* @return Friends added to this region
|
||||
*/
|
||||
public Set<UUID> getFriends() {
|
||||
HashSet<UUID> result = new HashSet<>();
|
||||
for(String friend : getRegion().getConfig().getStringList("general.friends")) {
|
||||
try {
|
||||
UUID id = UUID.fromString(friend);
|
||||
result.add(id);
|
||||
} catch(IllegalArgumentException e) {
|
||||
// Don't add it
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of friends added to this region.
|
||||
* @return Friends added to this region
|
||||
*/
|
||||
public Set<String> getFriendNames() {
|
||||
HashSet<String> result = new HashSet<>();
|
||||
for(UUID friend : getFriends()) {
|
||||
OfflinePlayer player = Bukkit.getOfflinePlayer(friend);
|
||||
if(player != null && player.getName() != null) {
|
||||
result.add(player.getName());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all friends that are added to this region.
|
||||
*/
|
||||
public void clearFriends() {
|
||||
getRegion().setSetting("general.friends", null);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
# Features
|
||||
|
||||
This package contains classes that represent a certain feature and implement it for all regions.
|
||||
|
||||
* `RegionFeature` represents a single feature, for each implementing class one instance is created without an assigned region, to listen for events etc, and an instance per region is created on-demand to handle region specific things.
|
||||
* More features will be moved from `GeneralRegion` to these kind of classes, to keep all code for a feature together and cleanup `GeneralRegion`.
|
||||
@@ -0,0 +1,77 @@
|
||||
package me.wiefferink.areashop.features;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/*
|
||||
Possible future feature classes:
|
||||
- RestrictedToRegion feature
|
||||
- rent/buy restricted to the region itself
|
||||
- RestrictedToWorld feature
|
||||
- rent/buy restricted to the world of the region
|
||||
- CountLimitsFeature:
|
||||
- Check region limits
|
||||
- TimeLimitsFeatures:
|
||||
- maxExtends
|
||||
- maxRentTime
|
||||
- SchematicFeature
|
||||
- save/load schematics
|
||||
- CommandsFeature
|
||||
- execute commands after extend/rent/etc
|
||||
- LandlordFeature
|
||||
- manage landlords
|
||||
- ExpirationWarningsFeature
|
||||
- sending rental expiration warnings
|
||||
*/
|
||||
|
||||
public abstract class RegionFeature implements Listener {
|
||||
|
||||
protected final AreaShop plugin;
|
||||
private GeneralRegion region;
|
||||
|
||||
protected RegionFeature(@Nonnull AreaShop plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the region for this feature.
|
||||
* @param region Feature region
|
||||
*/
|
||||
public void setRegion(GeneralRegion region) {
|
||||
this.region = region;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the region of this feature.
|
||||
* @return region of this feature, or null if generic
|
||||
*/
|
||||
public GeneralRegion getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start listening to events.
|
||||
*/
|
||||
public void listen() {
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy the feature and deregister everything.
|
||||
*/
|
||||
public void shutdownFeature() {
|
||||
HandlerList.unregisterAll(this);
|
||||
shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Dummy method a RegionFeature implementation can override.
|
||||
*/
|
||||
public void shutdown() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,572 @@
|
||||
package me.wiefferink.areashop.features;
|
||||
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.google.inject.assistedinject.AssistedInject;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.features.signs.RegionSign;
|
||||
import me.wiefferink.areashop.features.signs.SignManager;
|
||||
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import me.wiefferink.areashop.tools.Value;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Tag;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.inject.Inject;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
public class TeleportFeature extends RegionFeature {
|
||||
|
||||
@Inject
|
||||
private WorldGuardInterface worldGuardInterface;
|
||||
|
||||
@AssistedInject
|
||||
public TeleportFeature(@Nonnull AreaShop plugin, @Assisted @Nonnull GeneralRegion region) {
|
||||
super(plugin);
|
||||
setRegion(region);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the teleportlocation set for this region.
|
||||
* @return The teleport location, or null if not set
|
||||
*/
|
||||
public Location getTeleportLocation() {
|
||||
return Utils.configToLocation(getRegion().getConfigurationSectionSetting("general.teleportLocation"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the region has a teleportLocation specified.
|
||||
* @return true if the region has a teleportlocation, false otherwise
|
||||
*/
|
||||
public boolean hasTeleportLocation() {
|
||||
return getRegion().getConfigurationSectionSetting("general.teleportLocation") != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the teleport location of this region.
|
||||
* @param location The location to set as teleport location
|
||||
*/
|
||||
public void setTeleport(Location location) {
|
||||
if(location == null) {
|
||||
getRegion().setSetting("general.teleportLocation", null);
|
||||
} else {
|
||||
getRegion().setSetting("general.teleportLocation", Utils.locationToConfig(location, true));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Teleport a player to the region or sign.
|
||||
* @param player Player that should be teleported
|
||||
* @param toSign true to teleport to the first sign of the region, false for teleporting to the region itself
|
||||
* @param checkRestrictions Set to true if teleport permissions should be checked, false otherwise, also toggles cross-world check
|
||||
* @return true if the teleport succeeded, otherwise false
|
||||
*/
|
||||
public boolean teleportPlayer(Player player, boolean toSign, boolean checkRestrictions) {
|
||||
|
||||
// Check basics
|
||||
if(getRegion().getWorld() == null) {
|
||||
getRegion().message(player, "general-noWorld");
|
||||
return false;
|
||||
}
|
||||
if(getRegion().getRegion() == null) {
|
||||
getRegion().message(player, "general-noRegion");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(checkRestrictions) {
|
||||
// Check correct world
|
||||
if(!getRegion().getBooleanSetting("general.teleportCrossWorld") && !player.getWorld().equals(getRegion().getWorld())) {
|
||||
getRegion().message(player, "teleport-wrongWorld", player.getWorld().getName());
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean owner = player.getUniqueId().equals(getRegion().getOwner());
|
||||
boolean friend = getRegion().getFriendsFeature().getFriends().contains(player.getUniqueId());
|
||||
boolean available = getRegion().isAvailable();
|
||||
// Teleport to sign instead if they dont have permission for teleporting to region
|
||||
if((!toSign && owner && !player.hasPermission("areashop.teleport") && player.hasPermission("areashop.teleportsign")
|
||||
|| !toSign && !owner && !friend && !player.hasPermission("areashop.teleportall") && player.hasPermission("areashop.teleportsignall")
|
||||
|| !toSign && !owner && friend && !player.hasPermission("areashop.teleportfriend") && player.hasPermission("areashop.teleportfriendsign")
|
||||
|| !toSign && !owner && !friend && available && !player.hasPermission("areashop.teleportavailable") && player.hasPermission("areashop.teleportavailablesign"))) {
|
||||
getRegion().message(player, "teleport-changedToSign");
|
||||
toSign = true;
|
||||
}
|
||||
// Check permissions
|
||||
if(owner && !available && !player.hasPermission("areashop.teleport") && !toSign) {
|
||||
getRegion().message(player, "teleport-noPermission");
|
||||
return false;
|
||||
} else if(!owner && !available && !player.hasPermission("areashop.teleportall") && !toSign && !friend) {
|
||||
getRegion().message(player, "teleport-noPermissionOther");
|
||||
return false;
|
||||
} else if(!owner && !available && !player.hasPermission("areashop.teleportfriend") && !toSign && friend) {
|
||||
getRegion().message(player, "teleport-noPermissionFriend");
|
||||
return false;
|
||||
} else if(available && !player.hasPermission("areashop.teleportavailable") && !toSign) {
|
||||
getRegion().message(player, "teleport-noPermissionAvailable");
|
||||
return false;
|
||||
} else if(owner && !available && !player.hasPermission("areashop.teleportsign") && toSign) {
|
||||
getRegion().message(player, "teleport-noPermissionSign");
|
||||
return false;
|
||||
} else if(!owner && !available && !player.hasPermission("areashop.teleportsignall") && toSign && !friend) {
|
||||
getRegion().message(player, "teleport-noPermissionOtherSign");
|
||||
return false;
|
||||
} else if(!owner && !available && !player.hasPermission("areashop.teleportfriendsign") && toSign && friend) {
|
||||
getRegion().message(player, "teleport-noPermissionFriendSign");
|
||||
return false;
|
||||
} else if(available && !player.hasPermission("areashop.teleportavailablesign") && toSign) {
|
||||
getRegion().message(player, "teleport-noPermissionAvailableSign");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the starting location
|
||||
Value<Boolean> toSignRef = new Value<>(toSign);
|
||||
Location startLocation = getStartLocation(player, toSignRef);
|
||||
toSign = toSignRef.get();
|
||||
|
||||
boolean insideRegion;
|
||||
if(toSign) {
|
||||
insideRegion = getRegion().getBooleanSetting("general.teleportToSignIntoRegion");
|
||||
} else {
|
||||
insideRegion = getRegion().getBooleanSetting("general.teleportIntoRegion");
|
||||
}
|
||||
|
||||
// Check locations starting from startLocation and then a cube that increases
|
||||
// radius around that (until no block in the region is found at all cube sides)
|
||||
Location safeLocation = startLocation;
|
||||
ProtectedRegion worldguardRegion = getRegion().getRegion();
|
||||
boolean blocksInRegion = worldguardRegion.contains(startLocation.getBlockX(), startLocation.getBlockY(), startLocation.getBlockZ());
|
||||
if(!blocksInRegion && insideRegion) {
|
||||
getRegion().message(player, "teleport-blocked");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Tries limit tracking
|
||||
int radius = 1;
|
||||
int checked = 1;
|
||||
int maxTries = plugin.getConfig().getInt("maximumTries");
|
||||
|
||||
// Tracking of which sides to continue the search
|
||||
boolean done = isSafe(safeLocation);
|
||||
boolean northDone = false, eastDone = false, southDone = false, westDone = false, topDone = false, bottomDone = false;
|
||||
boolean continueThisDirection;
|
||||
|
||||
while((blocksInRegion || !insideRegion) && !done) {
|
||||
blocksInRegion = false;
|
||||
|
||||
// North side
|
||||
continueThisDirection = false;
|
||||
for(int x = -radius + 1; x <= radius && !done && !northDone; x++) {
|
||||
for(int y = -radius + 1; y < radius && !done; y++) {
|
||||
safeLocation = startLocation.clone().add(x, y, -radius);
|
||||
if(safeLocation.getBlockY() > 256 || safeLocation.getBlockY() < 0) {
|
||||
continue;
|
||||
}
|
||||
if(worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegion = true;
|
||||
continueThisDirection = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
northDone = northDone || !continueThisDirection;
|
||||
|
||||
// East side
|
||||
continueThisDirection = false;
|
||||
for(int z = -radius + 1; z <= radius && !done && !eastDone; z++) {
|
||||
for(int y = -radius + 1; y < radius && !done; y++) {
|
||||
safeLocation = startLocation.clone().add(radius, y, z);
|
||||
if(safeLocation.getBlockY() > 256 || safeLocation.getBlockY() < 0) {
|
||||
continue;
|
||||
}
|
||||
if(worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegion = true;
|
||||
continueThisDirection = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
eastDone = eastDone || !continueThisDirection;
|
||||
|
||||
// South side
|
||||
continueThisDirection = false;
|
||||
for(int x = radius - 1; x >= -radius && !done && !southDone; x--) {
|
||||
for(int y = -radius + 1; y < radius && !done; y++) {
|
||||
safeLocation = startLocation.clone().add(x, y, radius);
|
||||
if(safeLocation.getBlockY() > 256 || safeLocation.getBlockY() < 0) {
|
||||
continue;
|
||||
}
|
||||
if(worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegion = true;
|
||||
continueThisDirection = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
southDone = southDone || !continueThisDirection;
|
||||
|
||||
// West side
|
||||
continueThisDirection = false;
|
||||
for(int z = radius - 1; z >= -radius && !done && !westDone; z--) {
|
||||
for(int y = -radius + 1; y < radius && !done; y++) {
|
||||
safeLocation = startLocation.clone().add(-radius, y, z);
|
||||
if(safeLocation.getBlockY() > 256 || safeLocation.getBlockY() < 0) {
|
||||
continue;
|
||||
}
|
||||
if(worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegion = true;
|
||||
continueThisDirection = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
westDone = westDone || !continueThisDirection;
|
||||
|
||||
// Top side
|
||||
continueThisDirection = false;
|
||||
// Middle block of the top
|
||||
if((startLocation.getBlockY() + radius) > 256) {
|
||||
topDone = true;
|
||||
}
|
||||
if(!done && !topDone) {
|
||||
safeLocation = startLocation.clone().add(0, radius, 0);
|
||||
if(worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegion = true;
|
||||
continueThisDirection = true;
|
||||
}
|
||||
}
|
||||
for(int r = 1; r <= radius && !done && !topDone; r++) {
|
||||
// North
|
||||
for(int x = -r + 1; x <= r && !done; x++) {
|
||||
safeLocation = startLocation.clone().add(x, radius, -r);
|
||||
if(worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegion = true;
|
||||
continueThisDirection = true;
|
||||
}
|
||||
}
|
||||
// East
|
||||
for(int z = -r + 1; z <= r && !done; z++) {
|
||||
safeLocation = startLocation.clone().add(r, radius, z);
|
||||
if(worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegion = true;
|
||||
continueThisDirection = true;
|
||||
}
|
||||
}
|
||||
// South side
|
||||
for(int x = r - 1; x >= -r && !done; x--) {
|
||||
safeLocation = startLocation.clone().add(x, radius, r);
|
||||
if(worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegion = true;
|
||||
continueThisDirection = true;
|
||||
}
|
||||
}
|
||||
// West side
|
||||
for(int z = r - 1; z >= -r && !done; z--) {
|
||||
safeLocation = startLocation.clone().add(-r, radius, z);
|
||||
if(worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegion = true;
|
||||
continueThisDirection = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
topDone = topDone || !continueThisDirection;
|
||||
|
||||
// Bottom side
|
||||
continueThisDirection = false;
|
||||
// Middle block of the bottom
|
||||
if(startLocation.getBlockY() - radius < 0) {
|
||||
bottomDone = true;
|
||||
}
|
||||
if(!done && !bottomDone) {
|
||||
safeLocation = startLocation.clone().add(0, -radius, 0);
|
||||
if(worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegion = true;
|
||||
continueThisDirection = true;
|
||||
}
|
||||
}
|
||||
for(int r = 1; r <= radius && !done && !bottomDone; r++) {
|
||||
// North
|
||||
for(int x = -r + 1; x <= r && !done; x++) {
|
||||
safeLocation = startLocation.clone().add(x, -radius, -r);
|
||||
if(worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegion = true;
|
||||
continueThisDirection = true;
|
||||
}
|
||||
}
|
||||
// East
|
||||
for(int z = -r + 1; z <= r && !done; z++) {
|
||||
safeLocation = startLocation.clone().add(r, -radius, z);
|
||||
if(worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegion = true;
|
||||
continueThisDirection = true;
|
||||
}
|
||||
}
|
||||
// South side
|
||||
for(int x = r - 1; x >= -r && !done; x--) {
|
||||
safeLocation = startLocation.clone().add(x, -radius, r);
|
||||
if(worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegion = true;
|
||||
continueThisDirection = true;
|
||||
}
|
||||
}
|
||||
// West side
|
||||
for(int z = r - 1; z >= -r && !done; z--) {
|
||||
safeLocation = startLocation.clone().add(-r, -radius, z);
|
||||
if(worldguardRegion.contains(safeLocation.getBlockX(), safeLocation.getBlockY(), safeLocation.getBlockZ()) || !insideRegion) {
|
||||
checked++;
|
||||
done = isSafe(safeLocation) || checked > maxTries;
|
||||
blocksInRegion = true;
|
||||
continueThisDirection = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
bottomDone = bottomDone || !continueThisDirection;
|
||||
|
||||
// Increase cube radius
|
||||
radius++;
|
||||
}
|
||||
if(done && isSafe(safeLocation)) {
|
||||
if(toSign) {
|
||||
getRegion().message(player, "teleport-successSign");
|
||||
|
||||
// Let the player look at the sign
|
||||
Vector playerVector = safeLocation.toVector();
|
||||
playerVector.setY(playerVector.getY() + player.getEyeHeight(true));
|
||||
SignManager signManager = getRegion().getSignsFeature().signManager();
|
||||
Iterator<RegionSign> iterator = signManager.allSigns().iterator();
|
||||
Vector signVector = iterator.next().getLocation().toVector().add(new Vector(0.5, 0.5, 0.5));
|
||||
Vector direction = playerVector.clone().subtract(signVector).normalize();
|
||||
safeLocation.setYaw(180 - (float)Math.toDegrees(Math.atan2(direction.getX(), direction.getZ())));
|
||||
safeLocation.setPitch(90 - (float)Math.toDegrees(Math.acos(direction.getY())));
|
||||
} else {
|
||||
getRegion().message(player, "teleport-success");
|
||||
}
|
||||
|
||||
player.teleport(safeLocation);
|
||||
AreaShop.debug("Found location: " + safeLocation.toString() + " Tries: " + (checked - 1));
|
||||
return true;
|
||||
} else {
|
||||
getRegion().message(player, "teleport-noSafe", checked - 1, maxTries);
|
||||
AreaShop.debug("No location found, checked " + (checked - 1) + " spots of max " + maxTries);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Teleport a player to the region or sign when he has permissions for it.
|
||||
* @param player Player that should be teleported
|
||||
* @param toSign true to teleport to the first sign of the region, false for teleporting to the region itself
|
||||
* @return true if the teleport succeeded, otherwise false
|
||||
*/
|
||||
public boolean teleportPlayer(Player player, boolean toSign) {
|
||||
return teleportPlayer(player, toSign, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Teleport a player to the region when he has permissions for it.
|
||||
* @param player Player that should be teleported
|
||||
* @return true if the teleport succeeded, otherwise false
|
||||
*/
|
||||
public boolean teleportPlayer(Player player) {
|
||||
return teleportPlayer(player, false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a certain location is safe to teleport to.
|
||||
* @param location The location to check
|
||||
* @return true if it is safe, otherwise false
|
||||
*/
|
||||
private boolean isSafe(Location location) {
|
||||
Block feet = location.getBlock();
|
||||
Block head = feet.getRelative(BlockFace.UP);
|
||||
Block below = feet.getRelative(BlockFace.DOWN);
|
||||
Block above = head.getRelative(BlockFace.UP);
|
||||
|
||||
// Check the block at the feet and head of the player
|
||||
if((feet.getType().isSolid() && !canSpawnIn(feet.getType())) || feet.isLiquid()) {
|
||||
return false;
|
||||
} else if((head.getType().isSolid() && !canSpawnIn(head.getType())) || head.isLiquid()) {
|
||||
return false;
|
||||
} else if(!below.getType().isSolid() || cannotSpawnOn(below.getType()) || below.isLiquid()) {
|
||||
return false;
|
||||
} else if(above.isLiquid() || cannotSpawnBeside(above.getType())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get all blocks around the player (below foot level, foot level, head level and above head level)
|
||||
Set<Material> around = EnumSet.noneOf(Material.class);
|
||||
for(int y = 0; y <= 3; y++) {
|
||||
for(int x = -1; x <= 1; x++) {
|
||||
for(int z = -1; z <= 1; z++) {
|
||||
// Skip blocks in the column of the player
|
||||
if(x == 0 && z == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
around.add(below.getRelative(x, y, z).getType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check the blocks around the player
|
||||
for(Material material : around) {
|
||||
if(cannotSpawnBeside(material)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a player can spawn in here.
|
||||
* @param material Material to check (assumed that this is at the feet or head level)
|
||||
* @return true when it is safe to spawn inside, otherwise false
|
||||
*/
|
||||
private static boolean canSpawnIn(Material material) {
|
||||
return material == Material.DRAGON_EGG
|
||||
|| Tag.DOORS.isTagged(material)
|
||||
|| Tag.SIGNS.isTagged(material)
|
||||
|| Tag.PRESSURE_PLATES.isTagged(material);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a player can spawn on here.
|
||||
* @param material Material to check (assumed that this is below the feet)
|
||||
* @return true when it is safe to spawn on top of, otherwise false
|
||||
*/
|
||||
private static boolean cannotSpawnOn(Material material) {
|
||||
return material == Material.CACTUS
|
||||
|| material == Material.PISTON
|
||||
|| material == Material.PISTON_HEAD
|
||||
|| material == Material.MOVING_PISTON
|
||||
|| material == Material.DRAGON_EGG
|
||||
|| material == Material.MAGMA_BLOCK
|
||||
|| material == Material.REDSTONE_LAMP
|
||||
|| Tag.SIGNS.isTagged(material)
|
||||
|| Tag.DOORS.isTagged(material)
|
||||
|| Tag.FENCE_GATES.isTagged(material)
|
||||
|| Tag.FENCES.isTagged(material)
|
||||
|| material.name().contains("GLASS_PANE");
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a player can spawn next to it.
|
||||
* @param material Material to check (assumed that this is somewhere around the player)
|
||||
* @return true when it is safe to spawn next to, otherwise false
|
||||
*/
|
||||
private static boolean cannotSpawnBeside(Material material) {
|
||||
return material == Material.LAVA
|
||||
|| material == Material.FIRE
|
||||
|| material == Material.MAGMA_BLOCK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the start location of a safe teleport search.
|
||||
* @param player The player to get it for
|
||||
* @param toSign true to try teleporting to the first sign, false for teleporting to the region
|
||||
* @return The start location
|
||||
*/
|
||||
private Location getStartLocation(Player player, Value<Boolean> toSign) {
|
||||
Location startLocation = null;
|
||||
ProtectedRegion worldguardRegion = getRegion().getRegion();
|
||||
|
||||
// Try to get sign location
|
||||
|
||||
Collection<RegionSign> signs = getRegion().getSignsFeature().signManager().allSigns();
|
||||
if(toSign.get()) {
|
||||
boolean signAvailable = !signs.isEmpty();
|
||||
if(signAvailable) {
|
||||
RegionSign firstSign = signs.iterator().next();
|
||||
// Use the location 1 below the sign to prevent weird spawing above the sign
|
||||
startLocation = firstSign.getLocation(); //.subtract(0.0, 1.0, 0.0);
|
||||
startLocation.setPitch(player.getLocation().getPitch());
|
||||
startLocation.setYaw(player.getLocation().getYaw());
|
||||
|
||||
// Move player x blocks away from the sign
|
||||
double distance = getRegion().getDoubleSetting("general.teleportSignDistance");
|
||||
if(distance > 0) {
|
||||
BlockFace facing = firstSign.getFacing();
|
||||
Vector facingVector = new Vector(facing.getModX(), facing.getModY(), facing.getModZ())
|
||||
.normalize()
|
||||
.multiply(distance);
|
||||
startLocation.setX(startLocation.getBlockX() + 0.5);
|
||||
startLocation.setZ(startLocation.getBlockZ() + 0.5);
|
||||
startLocation.add(facingVector);
|
||||
}
|
||||
} else {
|
||||
// No sign available
|
||||
getRegion().message(player, "teleport-changedToNoSign");
|
||||
toSign.set(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Use teleportation location that is set for the region
|
||||
if(startLocation == null && hasTeleportLocation()) {
|
||||
startLocation = getTeleportLocation();
|
||||
}
|
||||
|
||||
// Calculate a default location
|
||||
if(startLocation == null) {
|
||||
// Set to block in the middle, y configured in the config
|
||||
Vector regionMin = worldGuardInterface.getMinimumPoint(worldguardRegion);
|
||||
Vector regionMax = worldGuardInterface.getMaximumPoint(worldguardRegion);
|
||||
Vector middle = regionMin.clone().midpoint(regionMax);
|
||||
String configSetting = getRegion().getStringSetting("general.teleportLocationY");
|
||||
if("bottom".equalsIgnoreCase(configSetting)) {
|
||||
middle = middle.setY(regionMin.getBlockY());
|
||||
} else if("top".equalsIgnoreCase(configSetting)) {
|
||||
middle = middle.setY(regionMax.getBlockY());
|
||||
} else if("middle".equalsIgnoreCase(configSetting)) {
|
||||
middle = middle.setY(middle.getBlockY());
|
||||
} else {
|
||||
try {
|
||||
int vertical = Integer.parseInt(configSetting);
|
||||
middle = middle.setY(vertical);
|
||||
} catch(NumberFormatException e) {
|
||||
AreaShop.warn("Could not parse general.teleportLocationY: '" + configSetting + "'");
|
||||
}
|
||||
}
|
||||
startLocation = new Location(getRegion().getWorld(), middle.getX(), middle.getY(), middle.getZ(), player.getLocation().getYaw(), player.getLocation().getPitch());
|
||||
}
|
||||
|
||||
// Set location in the center of the block
|
||||
startLocation.setX(startLocation.getBlockX() + 0.5);
|
||||
startLocation.setZ(startLocation.getBlockZ() + 0.5);
|
||||
|
||||
return startLocation;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+278
@@ -0,0 +1,278 @@
|
||||
package me.wiefferink.areashop.features;
|
||||
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.flags.InvalidFlagFormat;
|
||||
import com.sk89q.worldguard.protection.flags.RegionGroupFlag;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.events.notify.UpdateRegionEvent;
|
||||
import me.wiefferink.areashop.interfaces.RegionAccessSet;
|
||||
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.interactivemessenger.processing.Message;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.event.EventHandler;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
@Singleton
|
||||
public class WorldGuardRegionFlagsFeature extends RegionFeature {
|
||||
|
||||
@Inject
|
||||
private WorldGuardInterface worldGuardInterface;
|
||||
@Inject
|
||||
private WorldGuardPlugin worldGuard;
|
||||
|
||||
@Inject
|
||||
WorldGuardRegionFlagsFeature(@Nonnull AreaShop plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void regionUpdate(UpdateRegionEvent event) {
|
||||
updateRegionFlags(event.getRegion());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the region flags/options to the values of a ConfigurationSection.
|
||||
* @param region The region to update the flags for
|
||||
* @return true if the flags have been set correctly, otherwise false
|
||||
*/
|
||||
private boolean updateRegionFlags(GeneralRegion region) {
|
||||
boolean result = true;
|
||||
|
||||
// Get section defining the region flag profile
|
||||
ConfigurationSection flagProfileSection = region.getConfigurationSectionSetting("general.flagProfile", "flagProfiles");
|
||||
if(flagProfileSection == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Region flags for all states
|
||||
ConfigurationSection allFlags = flagProfileSection.getConfigurationSection("ALL");
|
||||
if(allFlags != null) {
|
||||
result = updateRegionFlags(region, allFlags);
|
||||
}
|
||||
|
||||
// Region flags for the current state
|
||||
ConfigurationSection stateFlags = flagProfileSection.getConfigurationSection(region.getState().getValue());
|
||||
|
||||
// If in reselling mode, fallback to 'resale' section if 'resell' is not found (legacy configuration problem: https://github.com/NLthijs48/AreaShop/issues/303)
|
||||
if(stateFlags == null && region.getState() == GeneralRegion.RegionState.RESELL) {
|
||||
stateFlags = flagProfileSection.getConfigurationSection("resale");
|
||||
}
|
||||
if(stateFlags != null) {
|
||||
result &= updateRegionFlags(region, stateFlags);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the region flags/options to the values of a ConfigurationSection.
|
||||
* @param region The region to update the flags for
|
||||
* @param flags The flags to apply
|
||||
* @return true if the flags have been set correctly, otherwise false
|
||||
*/
|
||||
private boolean updateRegionFlags(GeneralRegion region, ConfigurationSection flags) {
|
||||
boolean result = true;
|
||||
|
||||
Set<String> flagNames = flags.getKeys(false);
|
||||
|
||||
// Get the region
|
||||
ProtectedRegion worldguardRegion = region.getRegion();
|
||||
if(worldguardRegion == null) {
|
||||
AreaShop.debug("Region '" + region.getName() + "' does not exist, setting flags failed");
|
||||
return false;
|
||||
}
|
||||
// Loop through all flags that are set in the config
|
||||
for(String flagName : flagNames) {
|
||||
String value = Message.fromString(flags.getString(flagName)).replacements(region).getPlain();
|
||||
// In the config normal Bukkit color codes are used, those only need to be translated on 5.X WorldGuard versions
|
||||
if(worldGuard.getDescription().getVersion().startsWith("5.")) {
|
||||
value = translateBukkitToWorldGuardColors(value);
|
||||
}
|
||||
if(flagName.equalsIgnoreCase("members")) {
|
||||
worldGuardInterface.setMembers(worldguardRegion, parseAccessSet(value));
|
||||
//AreaShop.debug(" Flag " + flagName + " set: " + members.toUserFriendlyString());
|
||||
} else if(flagName.equalsIgnoreCase("owners")) {
|
||||
worldGuardInterface.setOwners(worldguardRegion, parseAccessSet(value));
|
||||
//AreaShop.debug(" Flag " + flagName + " set: " + owners.toUserFriendlyString());
|
||||
} else if(flagName.equalsIgnoreCase("priority")) {
|
||||
try {
|
||||
int priority = Integer.parseInt(value);
|
||||
if(worldguardRegion.getPriority() != priority) {
|
||||
worldguardRegion.setPriority(priority);
|
||||
}
|
||||
//AreaShop.debug(" Flag " + flagName + " set: " + value);
|
||||
} catch(NumberFormatException e) {
|
||||
AreaShop.warn("The value of flag " + flagName + " is not a number");
|
||||
result = false;
|
||||
}
|
||||
} else if(flagName.equalsIgnoreCase("parent")) {
|
||||
if(region.getWorld() == null || plugin.getRegionManager(region.getWorld()) == null) {
|
||||
continue;
|
||||
}
|
||||
ProtectedRegion parentRegion = plugin.getRegionManager(region.getWorld()).getRegion(value);
|
||||
if(parentRegion != null) {
|
||||
if(!parentRegion.equals(worldguardRegion.getParent())) {
|
||||
try {
|
||||
worldguardRegion.setParent(parentRegion);
|
||||
//AreaShop.debug(" Flag " + flagName + " set: " + value);
|
||||
} catch(ProtectedRegion.CircularInheritanceException e) {
|
||||
AreaShop.warn("The parent set in the config is not correct (circular inheritance)");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
AreaShop.warn("The parent set in the config is not correct (region does not exist)");
|
||||
}
|
||||
} else {
|
||||
// Parse all other normal flags (groups are also handled)
|
||||
String flagSetting = null;
|
||||
com.sk89q.worldguard.protection.flags.RegionGroup groupValue = null;
|
||||
|
||||
Flag<?> foundFlag = worldGuardInterface.fuzzyMatchFlag(flagName);
|
||||
if(foundFlag == null) {
|
||||
AreaShop.warn("Found wrong flag in flagProfiles section: " + flagName + ", check if that is the correct WorldGuard flag");
|
||||
continue;
|
||||
}
|
||||
RegionGroupFlag groupFlag = foundFlag.getRegionGroupFlag();
|
||||
if(value == null || value.isEmpty()) {
|
||||
if(worldguardRegion.getFlag(foundFlag) != null) {
|
||||
worldguardRegion.setFlag(foundFlag, null);
|
||||
}
|
||||
if(groupFlag != null && worldguardRegion.getFlag(groupFlag) != null) {
|
||||
worldguardRegion.setFlag(groupFlag, null);
|
||||
}
|
||||
//AreaShop.debug(" Flag " + flagName + " reset (+ possible group of flag)");
|
||||
} else {
|
||||
if(groupFlag == null) {
|
||||
flagSetting = value;
|
||||
} else {
|
||||
for(String part : value.split(" ")) {
|
||||
if(part.startsWith("g:")) {
|
||||
if(part.length() > 2) {
|
||||
try {
|
||||
groupValue = worldGuardInterface.parseFlagGroupInput(groupFlag, part.substring(2));
|
||||
} catch(InvalidFlagFormat e) {
|
||||
AreaShop.warn("Found wrong group value for flag " + flagName);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(flagSetting == null) {
|
||||
flagSetting = part;
|
||||
} else {
|
||||
flagSetting += " " + part;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(flagSetting != null) {
|
||||
try {
|
||||
setFlag(worldguardRegion, foundFlag, flagSetting);
|
||||
//AreaShop.debug(" Flag " + flagName + " set: " + flagSetting);
|
||||
} catch(InvalidFlagFormat e) {
|
||||
AreaShop.warn("Found wrong value for flag " + flagName);
|
||||
}
|
||||
}
|
||||
if(groupValue != null) {
|
||||
if(groupValue == groupFlag.getDefault()) {
|
||||
worldguardRegion.setFlag(groupFlag, null);
|
||||
//AreaShop.debug(" Group of flag " + flagName + " set to default: " + groupValue);
|
||||
} else {
|
||||
worldguardRegion.setFlag(groupFlag, groupValue);
|
||||
//AreaShop.debug(" Group of flag " + flagName + " set: " + groupValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Indicate that the regions needs to be saved
|
||||
if(worldGuard.getDescription().getVersion().startsWith("5.")) {
|
||||
plugin.getFileManager().saveIsRequiredForRegionWorld(region.getWorldName());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build an RegionAccessSet from an input that specifies player names, player uuids and groups.
|
||||
* @param input Input string defining the access set
|
||||
* @return RegionAccessSet containing the entities parsed from the input
|
||||
*/
|
||||
public RegionAccessSet parseAccessSet(String input) {
|
||||
RegionAccessSet result = new RegionAccessSet();
|
||||
|
||||
String[] inputParts = input.split(", ");
|
||||
for(String access : inputParts) {
|
||||
if(access != null && !access.isEmpty()) {
|
||||
// Check for groups
|
||||
if(access.startsWith("g:")) {
|
||||
if(access.length() > 2) {
|
||||
result.getGroupNames().add(access.substring(2));
|
||||
}
|
||||
} else if(access.startsWith("n:")) {
|
||||
if(access.length() > 2) {
|
||||
result.getPlayerNames().add(access.substring(2));
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
result.getPlayerUniqueIds().add(UUID.fromString(access));
|
||||
} catch(IllegalArgumentException e) {
|
||||
AreaShop.warn("Tried using '" + access + "' as uuid for a region member/owner, is your flagProfiles section correct?");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a WorldGuard region flag.
|
||||
* @param region The WorldGuard region to set
|
||||
* @param flag The flag to set
|
||||
* @param value The value to set the flag to
|
||||
* @param <V> They type of flag to set
|
||||
* @throws InvalidFlagFormat When the value of the flag is wrong
|
||||
*/
|
||||
private <V> void setFlag(ProtectedRegion region, Flag<V> flag, String value) throws InvalidFlagFormat {
|
||||
V current = region.getFlag(flag);
|
||||
V next = worldGuardInterface.parseFlagInput(flag, value);
|
||||
|
||||
if(!Objects.equals(current, next)) {
|
||||
region.setFlag(flag, next);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate the color codes you put in greeting/farewell messages to the weird color codes of WorldGuard.
|
||||
* @param message The message where the color codes should be translated (this message has bukkit color codes)
|
||||
* @return The string with the WorldGuard color codes
|
||||
*/
|
||||
private String translateBukkitToWorldGuardColors(String message) {
|
||||
String result = message;
|
||||
result = result.replace("&c", "&r");
|
||||
result = result.replace("&4", "&R");
|
||||
result = result.replace("&e", "&y");
|
||||
result = result.replace("&6", "&Y");
|
||||
result = result.replace("&a", "&g");
|
||||
result = result.replace("&2", "&G");
|
||||
result = result.replace("&b", "&c");
|
||||
result = result.replace("&3", "&C");
|
||||
result = result.replace("&9", "&b");
|
||||
result = result.replace("&1", "&B");
|
||||
result = result.replace("&d", "&p");
|
||||
result = result.replace("&5", "&P");
|
||||
result = result.replace("&0", "&0");
|
||||
result = result.replace("&8", "&1");
|
||||
result = result.replace("&7", "&2");
|
||||
result = result.replace("&f", "&w");
|
||||
result = result.replace("&r", "&x");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,295 @@
|
||||
package me.wiefferink.areashop.features.signs;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.google.inject.assistedinject.AssistedInject;
|
||||
import io.github.bakedlibs.dough.blocks.BlockPosition;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.managers.SignErrorLogger;
|
||||
import me.wiefferink.areashop.nms.BlockBehaviourHelper;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.tools.Materials;
|
||||
import me.wiefferink.areashop.tools.SignUtils;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import me.wiefferink.interactivemessenger.processing.Message;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.type.WallSign;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Sign that is connected to a region to display information and interact with the region.
|
||||
*/
|
||||
public class RegionSign {
|
||||
|
||||
private final BlockBehaviourHelper blockHelper;
|
||||
private final SignErrorLogger errorLogger;
|
||||
|
||||
private final SignsFeature signsFeature;
|
||||
private final String key;
|
||||
|
||||
|
||||
@AssistedInject
|
||||
RegionSign(
|
||||
@Nonnull BlockBehaviourHelper blockBehaviourHelper,
|
||||
@Nonnull SignErrorLogger signErrorLogger,
|
||||
@Assisted @Nonnull SignsFeature signsFeature,
|
||||
@Assisted @Nonnull String key
|
||||
) {
|
||||
this.blockHelper = blockBehaviourHelper;
|
||||
this.errorLogger = signErrorLogger;
|
||||
this.signsFeature = signsFeature;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public BlockPosition getPosition() {
|
||||
return new BlockPosition(getLocation());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the location of this sign.
|
||||
* @return The location of this sign
|
||||
*/
|
||||
public Location getLocation() {
|
||||
return Utils.configToLocation(getRegion().getConfig().getConfigurationSection("general.signs." + key + ".location"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Location string to be used as key in maps.
|
||||
* @return Location string
|
||||
*/
|
||||
public String getStringLocation() {
|
||||
return SignsFeature.locationToString(getLocation());
|
||||
}
|
||||
|
||||
/**
|
||||
* Chunk string to be used as key in maps.
|
||||
* @return Chunk string
|
||||
*/
|
||||
public String getStringChunk() {
|
||||
return SignsFeature.chunkToString(getLocation());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the region this sign is linked to.
|
||||
* @return The region this sign is linked to
|
||||
*/
|
||||
public GeneralRegion getRegion() {
|
||||
return signsFeature.getRegion();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove this sign from the region.
|
||||
*/
|
||||
public void remove() {
|
||||
Location location = getLocation();
|
||||
if (location != null && location.getWorld() != null) {
|
||||
location.getBlock().setType(Material.AIR);
|
||||
this.signsFeature.signManager().removeSign(this);
|
||||
}
|
||||
getRegion().setSetting("general.signs." + key, null);
|
||||
// Remove the sign from the region's sign manager
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ConfigurationSection defining the sign layout.
|
||||
* @return The sign layout config
|
||||
*/
|
||||
public ConfigurationSection getProfile() {
|
||||
return getRegion().getConfigurationSectionSetting("general.signProfile", "signProfiles", getRegion().getConfig().get("general.signs." + key + ".profile"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the facing of the sign as saved in the config.
|
||||
* @return BlockFace the sign faces, or null if unknown
|
||||
*/
|
||||
public BlockFace getFacing() {
|
||||
try {
|
||||
return BlockFace.valueOf(getRegion().getConfig().getString("general.signs." + key + ".facing"));
|
||||
} catch(NullPointerException | IllegalArgumentException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the material of the sign as saved in the config.
|
||||
* @return Material of the sign,Material.AIR if none.
|
||||
*/
|
||||
public Material getMaterial() {
|
||||
String name = getRegion().getConfig().getString("general.signs." + key + ".signType");
|
||||
Material result = Materials.signNameToMaterial(name);
|
||||
return result == null ? Material.AIR : result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update this sign.
|
||||
* @return true if the update was successful, otherwise false
|
||||
*/
|
||||
public boolean update() {
|
||||
// Ignore updates of signs in chunks that are not loaded
|
||||
Location signLocation = getLocation();
|
||||
if(signLocation == null
|
||||
|| signLocation.getWorld() == null
|
||||
|| !signLocation.getWorld().isChunkLoaded(signLocation.getBlockX() >> 4, signLocation.getBlockZ() >> 4)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(getRegion().isDeleted()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
YamlConfiguration regionConfig = getRegion().getConfig();
|
||||
ConfigurationSection signConfig = getProfile();
|
||||
Block block = signLocation.getBlock();
|
||||
if(signConfig == null || !signConfig.isSet(getRegion().getState().getValue())) {
|
||||
block.setType(Material.AIR);
|
||||
return true;
|
||||
}
|
||||
|
||||
ConfigurationSection stateConfig = signConfig.getConfigurationSection(getRegion().getState().getValue());
|
||||
|
||||
// Get the lines
|
||||
String[] signLines = new String[4];
|
||||
boolean signEmpty = true;
|
||||
for(int i = 0; i < 4; i++) {
|
||||
signLines[i] = stateConfig.getString("line" + (i + 1));
|
||||
signEmpty &= (signLines[i] == null || signLines[i].isEmpty());
|
||||
}
|
||||
if(signEmpty) {
|
||||
block.setType(Material.AIR);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Place the sign back (with proper rotation and type) after it has been hidden or (indirectly) destroyed
|
||||
if(!Materials.isSign(block.getType())) {
|
||||
Material signType = getMaterial();
|
||||
if (!blockHelper.canPlace(block.getLocation(), Bukkit.createBlockData(signType))) {
|
||||
errorLogger.submitWarning("Setting sign" + key + "of region" + getRegion().getName() + "failed, could not set sign block back");
|
||||
this.remove();
|
||||
return false;
|
||||
}
|
||||
// Don't do physics here, we first need to update the direction
|
||||
block.setType(signType, false);
|
||||
|
||||
BlockState blockState = PaperLib.getBlockState(block, false).getState();
|
||||
BlockData blockData = blockState.getBlockData();
|
||||
|
||||
if(blockData instanceof WallSign) {
|
||||
((WallSign) blockData).setFacing(getFacing());
|
||||
} else if(blockData instanceof org.bukkit.block.data.type.Sign) {
|
||||
((org.bukkit.block.data.type.Sign) blockData).setRotation(getFacing());
|
||||
} else {
|
||||
errorLogger.submitWarning("Failed to update the facing direction of the sign at" + getStringLocation() + "to " + getFacing() + ", region:" + getRegion().getName());
|
||||
return false;
|
||||
}
|
||||
block.setBlockData(blockData);
|
||||
|
||||
// Check if the sign has popped
|
||||
if(!Materials.isSign(block.getType())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Save current rotation and type
|
||||
if(!regionConfig.isString("general.signs." + key + ".signType")) {
|
||||
getRegion().setSetting("general.signs." + key + ".signType", block.getType().name());
|
||||
}
|
||||
if(!regionConfig.isString("general.signs." + key + ".facing")) {
|
||||
BlockFace signFacing = SignUtils.getSignFacing(block);
|
||||
getRegion().setSetting("general.signs." + key + ".facing", signFacing == null ? null : signFacing.toString());
|
||||
}
|
||||
|
||||
// Apply replacements and color and then set it on the sign
|
||||
Sign signState = (Sign) PaperLib.getBlockState(block, false).getState();
|
||||
for(int i = 0; i < signLines.length; i++) {
|
||||
if(signLines[i] == null) {
|
||||
signState.setLine(i, "");
|
||||
continue;
|
||||
}
|
||||
signLines[i] = Message.fromString(signLines[i]).replacements(getRegion()).getSingle();
|
||||
signLines[i] = Utils.applyColors(signLines[i]);
|
||||
signState.setLine(i, signLines[i]);
|
||||
}
|
||||
signState.update(false, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the sign needs to update periodically.
|
||||
* @return true if it needs periodic updates, otherwise false
|
||||
*/
|
||||
public boolean needsPeriodicUpdate() {
|
||||
ConfigurationSection signConfig = getProfile();
|
||||
if(signConfig == null || !signConfig.isSet(getRegion().getState().getValue().toLowerCase())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ConfigurationSection stateConfig = signConfig.getConfigurationSection(getRegion().getState().getValue().toLowerCase());
|
||||
if(stateConfig == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check the lines for the timeleft tag
|
||||
for(int i = 1; i <= 4; i++) {
|
||||
String line = stateConfig.getString("line" + i);
|
||||
if(line != null && line.contains(Message.VARIABLE_START + AreaShop.tagTimeLeft + Message.VARIABLE_END)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run commands when a player clicks a sign.
|
||||
* @param clicker The player that clicked the sign
|
||||
* @param clickType The type of clicking
|
||||
* @return true if the commands ran successfully, false if any of them failed
|
||||
*/
|
||||
public boolean runSignCommands(Player clicker, GeneralRegion.ClickType clickType) {
|
||||
ConfigurationSection signConfig = getProfile();
|
||||
if(signConfig == null) {
|
||||
return false;
|
||||
}
|
||||
ConfigurationSection stateConfig = signConfig.getConfigurationSection(getRegion().getState().getValue().toLowerCase());
|
||||
|
||||
// Run player commands if specified
|
||||
List<String> playerCommands = new ArrayList<>();
|
||||
for(String command : stateConfig.getStringList(clickType.getValue() + "Player")) {
|
||||
// TODO move variable checking code to InteractiveMessenger?
|
||||
playerCommands.add(command.replace(Message.VARIABLE_START + AreaShop.tagClicker + Message.VARIABLE_END, clicker.getName()));
|
||||
}
|
||||
getRegion().runCommands(clicker, playerCommands);
|
||||
|
||||
// Run console commands if specified
|
||||
List<String> consoleCommands = new ArrayList<>();
|
||||
for(String command : stateConfig.getStringList(clickType.getValue() + "Console")) {
|
||||
consoleCommands.add(command.replace(Message.VARIABLE_START + AreaShop.tagClicker + Message.VARIABLE_END, clicker.getName()));
|
||||
}
|
||||
getRegion().runCommands(Bukkit.getConsoleSender(), consoleCommands);
|
||||
|
||||
return !playerCommands.isEmpty() || !consoleCommands.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
return object instanceof RegionSign && ((RegionSign)object).getRegion().equals(this.getRegion()) && ((RegionSign)object).key.equals(this.key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(key, getRegion().getName());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package me.wiefferink.areashop.features.signs;
|
||||
|
||||
import io.github.bakedlibs.dough.blocks.BlockPosition;
|
||||
import io.github.bakedlibs.dough.blocks.ChunkPosition;
|
||||
import org.bukkit.Location;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class SignCache {
|
||||
|
||||
private final Map<Long, RegionSign> allSigns = new HashMap<>();
|
||||
private final Map<Long, Collection<RegionSign>> signsByChunk = new HashMap<>();
|
||||
|
||||
public Optional<RegionSign> signAtLocation(long position) {
|
||||
return Optional.ofNullable(this.allSigns.get(position));
|
||||
}
|
||||
|
||||
public Collection<RegionSign> signsAtChunk(long position) {
|
||||
return Collections.unmodifiableCollection(this.signsByChunk.getOrDefault(position, Collections.emptyList()));
|
||||
}
|
||||
|
||||
public Collection<RegionSign> allSigns() {
|
||||
return Collections.unmodifiableCollection(this.allSigns.values());
|
||||
}
|
||||
|
||||
public Collection<BlockPosition> allSignLocations() {
|
||||
Collection<BlockPosition> positions = new ArrayList<>(this.signsByChunk.size());
|
||||
for (RegionSign sign : this.allSigns.values()) {
|
||||
positions.add(sign.getPosition());
|
||||
}
|
||||
return positions;
|
||||
}
|
||||
|
||||
public void addSign(RegionSign regionSign) {
|
||||
BlockPosition blockPosition = regionSign.getPosition();
|
||||
this.allSigns.put(blockPosition.getPosition(), regionSign);
|
||||
ChunkPosition chunkPosition = new ChunkPosition(blockPosition.getChunk());
|
||||
Collection<RegionSign> signs = this.signsByChunk.computeIfAbsent(chunkPosition.getPosition(), x -> new HashSet<>());
|
||||
signs.add(regionSign);
|
||||
}
|
||||
|
||||
public Optional<RegionSign> removeSign(Location location) {
|
||||
return removeSign(new BlockPosition(location));
|
||||
}
|
||||
|
||||
public Optional<RegionSign> removeSign(BlockPosition position) {
|
||||
RegionSign removed = this.allSigns.remove(position.getPosition());
|
||||
if (removed != null) {
|
||||
Location location = position.toLocation();
|
||||
this.signsByChunk.remove(new ChunkPosition(location).getPosition());
|
||||
// Remove the sign from the region
|
||||
}
|
||||
return Optional.ofNullable(removed);
|
||||
}
|
||||
|
||||
public void removeSign(RegionSign regionSign) {
|
||||
BlockPosition blockPosition = regionSign.getPosition();
|
||||
this.allSigns.remove(blockPosition.getPosition());
|
||||
ChunkPosition chunkPosition = new ChunkPosition(blockPosition.getChunk());
|
||||
long packedChunkPos = chunkPosition.getPosition();
|
||||
Collection<RegionSign> signs = this.signsByChunk.get(packedChunkPos);
|
||||
if (signs != null) {
|
||||
signs.remove(regionSign);
|
||||
if (signs.isEmpty()) {
|
||||
this.signsByChunk.remove(packedChunkPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.allSigns.clear();
|
||||
this.signsByChunk.clear();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package me.wiefferink.areashop.features.signs;
|
||||
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public interface SignFactory {
|
||||
|
||||
@Nonnull RegionSign createRegionSign(@Nonnull SignsFeature signsFeature, @Nonnull String key);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,450 @@
|
||||
package me.wiefferink.areashop.features.signs;
|
||||
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import io.github.bakedlibs.dough.blocks.ChunkPosition;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.events.ask.AddingRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.UpdateRegionEvent;
|
||||
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.managers.SignLinkerManager;
|
||||
import me.wiefferink.areashop.nms.BlockBehaviourHelper;
|
||||
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.Materials;
|
||||
import me.wiefferink.areashop.tools.SignUtils;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import me.wiefferink.bukkitdo.Do;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockPhysicsEvent;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.world.ChunkLoadEvent;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public class SignListener implements Listener {
|
||||
|
||||
private final BlockBehaviourHelper behaviourHelper;
|
||||
private final AreaShop plugin;
|
||||
private final MessageBridge messageBridge;
|
||||
private final SignManager signManager;
|
||||
private final SignLinkerManager signLinkerManager;
|
||||
private final WorldGuardInterface worldGuardInterface;
|
||||
private final RegionFactory regionFactory;
|
||||
private final IFileManager fileManager;
|
||||
|
||||
public SignListener(
|
||||
@Nonnull AreaShop plugin,
|
||||
@Nonnull BlockBehaviourHelper behaviourHelper,
|
||||
@Nonnull RegionFactory regionFactory,
|
||||
@Nonnull MessageBridge messageBridge,
|
||||
@Nonnull SignLinkerManager signLinkerManager,
|
||||
@Nonnull WorldGuardInterface worldGuardInterface,
|
||||
@Nonnull SignManager signManager,
|
||||
@Nonnull IFileManager fileManager) {
|
||||
this.fileManager = fileManager;
|
||||
this.signManager = signManager;
|
||||
this.signLinkerManager = signLinkerManager;
|
||||
this.regionFactory = regionFactory;
|
||||
this.behaviourHelper = behaviourHelper;
|
||||
this.plugin = plugin;
|
||||
this.worldGuardInterface = worldGuardInterface;
|
||||
this.messageBridge = messageBridge;
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||
public void regionUpdate(UpdateRegionEvent event) {
|
||||
Optional<SignsFeature> signsFeature = event.getRegion().getFeature(SignsFeature.class);
|
||||
signsFeature.map(SignsFeature::signManager).ifPresent(SignManager::update);
|
||||
}
|
||||
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onChunkLoad(ChunkLoadEvent event) {
|
||||
Chunk chunk = event.getChunk();
|
||||
Optional<SignCache> optional = this.signManager.getCacheForWorld(chunk.getWorld());
|
||||
if (optional.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
final SignCache signCache = optional.get();
|
||||
Collection<RegionSign> chunkSigns = new ArrayList<>(signCache.signsAtChunk(ChunkPosition.getAsLong(chunk.getX(), chunk.getZ())));
|
||||
if(chunkSigns.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Do.forAll(chunkSigns, RegionSign::update);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onIndirectSignBreak(BlockPhysicsEvent event) {
|
||||
// Check if the block is a sign
|
||||
if(!Materials.isSign(event.getBlock().getType()) || behaviourHelper.isBlockValid(event.getBlock())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the sign is really the same as a saved rent
|
||||
final Optional<RegionSign> optionalSign = this.signManager.signFromLocation(event.getBlock().getLocation());
|
||||
if(optionalSign.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
RegionSign regionSign = optionalSign.get();
|
||||
|
||||
// Remove the sign so that it does not fall on the floor as an item (next region update will place it back when possible)
|
||||
AreaShop.debug("onIndirectSignBreak: Removed block of sign for", regionSign.getRegion().getName(), "at", regionSign.getStringLocation());
|
||||
event.getBlock().setType(Material.AIR);
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onSignBreak(BlockBreakEvent event) {
|
||||
if(event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
Block block = event.getBlock();
|
||||
// Check if it is a sign
|
||||
if(Materials.isSign(block.getType())) {
|
||||
// Check if the rent sign is really the same as a saved rent
|
||||
Optional<RegionSign> optional = signManager.signFromLocation(block.getLocation());
|
||||
if(optional.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
RegionSign regionSign = optional.get();
|
||||
// Remove the sign of the rental region if the player has permission
|
||||
if(event.getPlayer().hasPermission("areashop.delsign")) {
|
||||
signManager.removeSign(regionSign);
|
||||
messageBridge.message(event.getPlayer(), "delsign-success", regionSign.getRegion());
|
||||
} else { // Cancel the breaking of the sign
|
||||
event.setCancelled(true);
|
||||
messageBridge.message(event.getPlayer(), "delsign-noPermission", regionSign.getRegion());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void onSignClick(PlayerInteractEvent event) {
|
||||
Block block = event.getClickedBlock();
|
||||
if (block == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only listen to left and right clicks on blocks
|
||||
if (!(event.getAction() == Action.RIGHT_CLICK_BLOCK || event.getAction() == Action.LEFT_CLICK_BLOCK)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only care about clicking blocks
|
||||
if(!Materials.isSign(block.getType())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if this sign belongs to a region
|
||||
Optional<RegionSign> optional = signManager.signFromLocation(block.getLocation());
|
||||
if(optional.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
RegionSign regionSign = optional.get();
|
||||
|
||||
// Ignore players that are in sign link mode (which will handle the event itself)
|
||||
Player player = event.getPlayer();
|
||||
if(signLinkerManager.isInSignLinkMode(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the clicktype
|
||||
GeneralRegion.ClickType clickType = null;
|
||||
if(player.isSneaking() && event.getAction() == Action.LEFT_CLICK_BLOCK) {
|
||||
clickType = GeneralRegion.ClickType.SHIFTLEFTCLICK;
|
||||
} else if(!player.isSneaking() && event.getAction() == Action.LEFT_CLICK_BLOCK) {
|
||||
clickType = GeneralRegion.ClickType.LEFTCLICK;
|
||||
} else if(player.isSneaking() && event.getAction() == Action.RIGHT_CLICK_BLOCK) {
|
||||
clickType = GeneralRegion.ClickType.SHIFTRIGHTCLICK;
|
||||
} else if(!player.isSneaking() && event.getAction() == Action.RIGHT_CLICK_BLOCK) {
|
||||
clickType = GeneralRegion.ClickType.RIGHTCLICK;
|
||||
}
|
||||
|
||||
boolean ran = regionSign.runSignCommands(player, clickType);
|
||||
|
||||
// Only cancel event if at least one command has been executed
|
||||
event.setCancelled(ran);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onSignChange(SignChangeEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
if(!plugin.isReady()) {
|
||||
messageBridge.message(player, "general-notReady");
|
||||
return;
|
||||
}
|
||||
// Check if the sign is meant for this plugin
|
||||
if(event.getLine(0).contains(plugin.getConfig().getString("signTags.rent"))) {
|
||||
if(!player.hasPermission("areashop.createrent") && !player.hasPermission("areashop.createrent.member") && !player.hasPermission("areashop.createrent.owner")) {
|
||||
messageBridge.message(player, "setup-noPermissionRent");
|
||||
return;
|
||||
}
|
||||
// Get the other lines
|
||||
String secondLine = event.getLine(1);
|
||||
String thirdLine = event.getLine(2);
|
||||
String fourthLine = event.getLine(3);
|
||||
|
||||
// Get the regionManager for accessing regions
|
||||
RegionManager regionManager = plugin.getRegionManager(event.getPlayer().getWorld());
|
||||
|
||||
// If the secondLine does not contain a name try to find the region by location
|
||||
if(secondLine == null || secondLine.isEmpty()) {
|
||||
Set<ProtectedRegion> regions = worldGuardInterface.getApplicableRegionsSet(event.getBlock().getLocation());
|
||||
if(regions != null) {
|
||||
boolean first = true;
|
||||
ProtectedRegion candidate = null;
|
||||
for(ProtectedRegion pr : regions) {
|
||||
if(first) {
|
||||
candidate = pr;
|
||||
first = false;
|
||||
} else {
|
||||
if(pr.getPriority() > candidate.getPriority()) {
|
||||
candidate = pr;
|
||||
} else if(pr.getParent() != null && pr.getParent().equals(candidate)) {
|
||||
candidate = pr;
|
||||
} else {
|
||||
messageBridge.message(player, "setup-couldNotDetect", candidate.getId(), pr.getId());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(candidate != null) {
|
||||
secondLine = candidate.getId();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean priceSet = fourthLine != null && !fourthLine.isEmpty();
|
||||
boolean durationSet = thirdLine != null && !thirdLine.isEmpty();
|
||||
// check if all the lines are correct
|
||||
if(secondLine == null || secondLine.isEmpty()) {
|
||||
messageBridge.message(player, "setup-noRegion");
|
||||
return;
|
||||
}
|
||||
ProtectedRegion region = regionManager.getRegion(secondLine);
|
||||
if(region == null) {
|
||||
messageBridge.message(player, "cmd-noRegion", secondLine);
|
||||
return;
|
||||
}
|
||||
|
||||
IFileManager.AddResult addResult = fileManager.checkRegionAdd(player, regionManager.getRegion(secondLine), event.getPlayer().getWorld(), GeneralRegion.RegionType.RENT);
|
||||
if(addResult == IFileManager.AddResult.BLACKLISTED) {
|
||||
messageBridge.message(player, "setup-blacklisted", secondLine);
|
||||
} else if(addResult == IFileManager.AddResult.ALREADYADDED) {
|
||||
messageBridge.message(player, "setup-alreadyRentSign");
|
||||
} else if(addResult == IFileManager.AddResult.ALREADYADDEDOTHERWORLD) {
|
||||
messageBridge.message(player, "setup-alreadyOtherWorld");
|
||||
} else if(addResult == IFileManager.AddResult.NOPERMISSION) {
|
||||
messageBridge.message(player, "setup-noPermission", secondLine);
|
||||
} else if(thirdLine != null && !thirdLine.isEmpty() && !Utils.checkTimeFormat(thirdLine)) {
|
||||
messageBridge.message(player, "setup-wrongDuration");
|
||||
} else {
|
||||
double price = 0.0;
|
||||
if(priceSet) {
|
||||
// Check the fourth line
|
||||
try {
|
||||
price = Double.parseDouble(fourthLine);
|
||||
} catch(NumberFormatException e) {
|
||||
messageBridge.message(player, "setup-wrongPrice");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Add rent to the FileManager
|
||||
final RentRegion rent = regionFactory.createRentRegion(secondLine, event.getPlayer().getWorld());
|
||||
boolean isMember = worldGuardInterface.containsMember(rent.getRegion(), player.getUniqueId());
|
||||
boolean isOwner = worldGuardInterface.containsOwner(rent.getRegion(), player.getUniqueId());
|
||||
boolean landlord = (!player.hasPermission("areashop.createrent")
|
||||
&& ((player.hasPermission("areashop.createrent.owner") && isOwner)
|
||||
|| (player.hasPermission("areashop.createrent.member") && isMember)));
|
||||
|
||||
if(landlord) {
|
||||
rent.setLandlord(player.getUniqueId(), player.getName());
|
||||
}
|
||||
if(priceSet) {
|
||||
rent.setPrice(price);
|
||||
}
|
||||
if(durationSet) {
|
||||
rent.setDuration(thirdLine);
|
||||
}
|
||||
rent.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), SignUtils.getSignFacing(event.getBlock()), null);
|
||||
|
||||
AddingRegionEvent addingRegionEvent = plugin.getFileManager().addRegion(rent);
|
||||
if (addingRegionEvent.isCancelled()) {
|
||||
messageBridge.message(player, "general-cancelled", addingRegionEvent.getReason());
|
||||
return;
|
||||
}
|
||||
|
||||
rent.handleSchematicEvent(GeneralRegion.RegionEvent.CREATED);
|
||||
messageBridge.message(player, "setup-rentSuccess", rent);
|
||||
// Update the region after the event has written its lines
|
||||
Do.sync(rent::update);
|
||||
}
|
||||
} else if(event.getLine(0).contains(plugin.getConfig().getString("signTags.buy"))) {
|
||||
// Check for permission
|
||||
if(!player.hasPermission("areashop.createbuy") && !player.hasPermission("areashop.createbuy.member") && !player.hasPermission("areashop.createbuy.owner")) {
|
||||
messageBridge.message(player, "setup-noPermissionBuy");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the other lines
|
||||
String secondLine = event.getLine(1);
|
||||
String thirdLine = event.getLine(2);
|
||||
|
||||
// Get the regionManager for accessing regions
|
||||
RegionManager regionManager = plugin.getRegionManager(event.getPlayer().getWorld());
|
||||
|
||||
// If the secondLine does not contain a name try to find the region by location
|
||||
if(secondLine == null || secondLine.isEmpty()) {
|
||||
Set<ProtectedRegion> regions = worldGuardInterface.getApplicableRegionsSet(event.getBlock().getLocation());
|
||||
if(regions != null) {
|
||||
boolean first = true;
|
||||
ProtectedRegion candidate = null;
|
||||
for(ProtectedRegion pr : regions) {
|
||||
if(first) {
|
||||
candidate = pr;
|
||||
first = false;
|
||||
} else {
|
||||
if(pr.getPriority() > candidate.getPriority()) {
|
||||
candidate = pr;
|
||||
} else if(pr.getParent() != null && pr.getParent().equals(candidate)) {
|
||||
candidate = pr;
|
||||
} else {
|
||||
messageBridge.message(player, "setup-couldNotDetect", candidate.getId(), pr.getId());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(candidate != null) {
|
||||
secondLine = candidate.getId();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean priceSet = thirdLine != null && !thirdLine.isEmpty();
|
||||
// Check if all the lines are correct
|
||||
if(secondLine == null || secondLine.isEmpty()) {
|
||||
messageBridge.message(player, "setup-noRegion");
|
||||
return;
|
||||
}
|
||||
ProtectedRegion region = regionManager.getRegion(secondLine);
|
||||
if(region == null) {
|
||||
messageBridge.message(player, "cmd-noRegion", secondLine);
|
||||
return;
|
||||
}
|
||||
IFileManager.AddResult addResult = plugin.getFileManager().checkRegionAdd(player, region, event.getPlayer().getWorld(), GeneralRegion.RegionType.BUY);
|
||||
if(addResult == IFileManager.AddResult.BLACKLISTED) {
|
||||
messageBridge.message(player, "setup-blacklisted", secondLine);
|
||||
} else if(addResult == IFileManager.AddResult.ALREADYADDED) {
|
||||
messageBridge.message(player, "setup-alreadyRentSign");
|
||||
} else if(addResult == IFileManager.AddResult.ALREADYADDEDOTHERWORLD) {
|
||||
messageBridge.message(player, "setup-alreadyOtherWorld");
|
||||
} else if(addResult == IFileManager.AddResult.NOPERMISSION) {
|
||||
messageBridge.message(player, "setup-noPermission", secondLine);
|
||||
} else {
|
||||
double price = 0.0;
|
||||
if(priceSet) {
|
||||
// Check the fourth line
|
||||
try {
|
||||
price = Double.parseDouble(thirdLine);
|
||||
} catch(NumberFormatException e) {
|
||||
messageBridge.message(player, "setup-wrongPrice");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Add buy to the FileManager
|
||||
final BuyRegion buy = regionFactory.createBuyRegion(secondLine, event.getPlayer().getWorld());
|
||||
boolean isMember = worldGuardInterface.containsMember(buy.getRegion(), player.getUniqueId());
|
||||
boolean isOwner = worldGuardInterface.containsOwner(buy.getRegion(), player.getUniqueId());
|
||||
boolean landlord = (!player.hasPermission("areashop.createbuy")
|
||||
&& ((player.hasPermission("areashop.createbuy.owner") && isOwner)
|
||||
|| (player.hasPermission("areashop.createbuy.member") && isMember)));
|
||||
|
||||
if(landlord) {
|
||||
buy.setLandlord(player.getUniqueId(), player.getName());
|
||||
}
|
||||
if(priceSet) {
|
||||
buy.setPrice(price);
|
||||
}
|
||||
buy.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), SignUtils.getSignFacing(event.getBlock()), null);
|
||||
|
||||
AddingRegionEvent addingRegionEvent = plugin.getFileManager().addRegion(buy);
|
||||
if (addingRegionEvent.isCancelled()) {
|
||||
messageBridge.message(player, "general-cancelled", addingRegionEvent.getReason());
|
||||
return;
|
||||
}
|
||||
|
||||
buy.handleSchematicEvent(GeneralRegion.RegionEvent.CREATED);
|
||||
messageBridge.message(player, "setup-buySuccess", buy);
|
||||
// Update the region after the event has written its lines
|
||||
Do.sync(buy::update);
|
||||
}
|
||||
} else if(event.getLine(0).contains(plugin.getConfig().getString("signTags.add"))) {
|
||||
// Check for permission
|
||||
if(!player.hasPermission("areashop.addsign")) {
|
||||
messageBridge.message(player, "addsign-noPermission");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the other lines
|
||||
String secondLine = event.getLine(1);
|
||||
String thirdLine = event.getLine(2);
|
||||
|
||||
GeneralRegion region;
|
||||
if(secondLine != null && !secondLine.isEmpty()) {
|
||||
// Get region by secondLine of the sign
|
||||
region = fileManager.getRegion(secondLine);
|
||||
if(region == null) {
|
||||
messageBridge.message(player, "addSign-notRegistered", secondLine);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Get region by sign position
|
||||
List<GeneralRegion> regions = Utils.getImportantRegions(event.getBlock().getLocation());
|
||||
if(regions.isEmpty()) {
|
||||
messageBridge.message(player, "addsign-noRegions");
|
||||
return;
|
||||
} else if(regions.size() > 1) {
|
||||
messageBridge.message(player, "addsign-couldNotDetectSign", regions.get(0).getName(), regions.get(1).getName());
|
||||
return;
|
||||
}
|
||||
region = regions.get(0);
|
||||
}
|
||||
|
||||
if(thirdLine == null || thirdLine.isEmpty()) {
|
||||
region.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), SignUtils.getSignFacing(event.getBlock()), null);
|
||||
messageBridge.message(player, "addsign-success", region);
|
||||
} else {
|
||||
region.getSignsFeature().addSign(event.getBlock().getLocation(), event.getBlock().getType(), SignUtils.getSignFacing(event.getBlock()), thirdLine);
|
||||
messageBridge.message(player, "addsign-successProfile", thirdLine, region);
|
||||
}
|
||||
|
||||
// Update the region later because this event will do it first
|
||||
Do.sync(region::update);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package me.wiefferink.areashop.features.signs;
|
||||
|
||||
import io.github.bakedlibs.dough.blocks.BlockPosition;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.managers.Manager;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public class SignManager extends Manager {
|
||||
|
||||
private final Map<World, SignCache> signCacheMap = new HashMap<>();
|
||||
|
||||
public Collection<BlockPosition> allSignLocations() {
|
||||
final Set<BlockPosition> set = new HashSet<>(signCacheMap.size());
|
||||
for (SignCache signCache : signCacheMap.values()) {
|
||||
set.addAll(signCache.allSignLocations());
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
public Collection<RegionSign> allSigns() {
|
||||
final Set<RegionSign> signs = new HashSet<>(signCacheMap.size());
|
||||
for (SignCache signCache : signCacheMap.values()) {
|
||||
signs.addAll(signCache.allSigns());
|
||||
}
|
||||
return signs;
|
||||
}
|
||||
|
||||
public SignCache cacheForWorld(World world) {
|
||||
return this.signCacheMap.computeIfAbsent(world, x -> new SignCache());
|
||||
}
|
||||
|
||||
public Optional<SignCache> getCacheForWorld(World world) {
|
||||
return Optional.ofNullable(this.signCacheMap.get(world));
|
||||
}
|
||||
|
||||
public Optional<RegionSign> signFromLocation(Location location) {
|
||||
final World world = location.getWorld();
|
||||
return getCacheForWorld(world)
|
||||
.flatMap(cache -> cache.signAtLocation(BlockPosition.getAsLong(location)));
|
||||
}
|
||||
|
||||
public void addSign(RegionSign regionSign) {
|
||||
Location location = regionSign.getLocation();
|
||||
cacheForWorld(location.getWorld()).addSign(regionSign);
|
||||
}
|
||||
|
||||
public void removeSign(RegionSign regionSign) {
|
||||
Location location = regionSign.getLocation();
|
||||
if (location.getWorld() == null) {
|
||||
return;
|
||||
}
|
||||
cacheForWorld(location.getWorld()).removeSign(regionSign);
|
||||
}
|
||||
|
||||
public Optional<RegionSign> removeSign(Location location) {
|
||||
if (location == null || location.getWorld() == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return getCacheForWorld(location.getWorld()).flatMap(cache -> cache.removeSign(location));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update all signs connected to this region.
|
||||
* @return true if all signs are updated correctly, false if one or more updates failed
|
||||
*/
|
||||
public boolean update() {
|
||||
boolean result = true;
|
||||
for (SignCache signCache : this.signCacheMap.values())
|
||||
for(RegionSign sign : signCache.allSigns()) {
|
||||
result &= sign.update();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if any of the signs need periodic updating.
|
||||
* @return true if one or more of the signs need periodic updating, otherwise false
|
||||
*/
|
||||
public boolean needsPeriodicUpdate() {
|
||||
boolean result = false;
|
||||
for (SignCache signCache : this.signCacheMap.values()) {
|
||||
for (RegionSign sign : signCache.allSigns()) {
|
||||
if (result) {
|
||||
break;
|
||||
}
|
||||
if (sign.needsPeriodicUpdate()) {
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public void shutdown() {
|
||||
this.signCacheMap.values().forEach(SignCache::clear);
|
||||
this.signCacheMap.clear();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package me.wiefferink.areashop.features.signs;
|
||||
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.google.inject.assistedinject.AssistedInject;
|
||||
import io.github.bakedlibs.dough.blocks.BlockPosition;
|
||||
import io.github.bakedlibs.dough.blocks.ChunkPosition;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.features.RegionFeature;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class SignsFeature extends RegionFeature {
|
||||
|
||||
private final SignManager internalSignManager = new SignManager();
|
||||
private final SignManager globalSignManager;
|
||||
private final SignFactory signFactory;
|
||||
/**
|
||||
* Constructor.
|
||||
* @param region The region to bind to
|
||||
*/
|
||||
@AssistedInject
|
||||
SignsFeature(@Nonnull AreaShop plugin,
|
||||
@Nonnull SignManager signManager,
|
||||
@Nonnull SignFactory signFactory,
|
||||
@Assisted @Nonnull GeneralRegion region
|
||||
) {
|
||||
super(plugin);
|
||||
this.globalSignManager = signManager;
|
||||
this.signFactory = signFactory;
|
||||
setRegion(region);
|
||||
// Setup current signs
|
||||
ConfigurationSection signSection = region.getConfig().getConfigurationSection("general.signs");
|
||||
if (signSection == null) {
|
||||
return;
|
||||
}
|
||||
for(String signKey : signSection.getKeys(false)) {
|
||||
RegionSign sign = signFactory.createRegionSign(this, signKey);
|
||||
Location location = sign.getLocation();
|
||||
if(location == null) {
|
||||
AreaShop.warn("Sign with key " + signKey + " of region " + region.getName() + " does not have a proper location");
|
||||
continue;
|
||||
}
|
||||
this.globalSignManager.cacheForWorld(location.getWorld()).addSign(sign);
|
||||
this.internalSignManager.addSign(sign);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a location to a string to use as map key.
|
||||
* @param location The location to get the key for
|
||||
* @return A string to use in a map for a location
|
||||
*/
|
||||
public static String locationToString(Location location) {
|
||||
return location.getWorld().getName() + ";" + location.getBlockX() + ";" + location.getBlockY() + ";" + location.getBlockZ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a chunk to a string to use as map key.
|
||||
* @param location The location to get the key for
|
||||
* @return A string to use in a map for a chunk
|
||||
*/
|
||||
public static String chunkToString(Location location) {
|
||||
return location.getWorld().getName() + ";" + (location.getBlockX() >> 4) + ";" + (location.getBlockZ() >> 4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
|
||||
}
|
||||
|
||||
public SignManager signManager() {
|
||||
return this.internalSignManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a sign to this region.
|
||||
* @param location The location of the sign
|
||||
* @param signType The type of the sign (WALL_SIGN or SIGN_POST)
|
||||
* @param facing The orientation of the sign
|
||||
* @param profile The profile to use with this sign (null for default)
|
||||
*/
|
||||
public void addSign(Location location, Material signType, BlockFace facing, String profile) {
|
||||
int i = 0;
|
||||
while(getRegion().getConfig().isSet("general.signs." + i)) {
|
||||
i++;
|
||||
}
|
||||
String signPath = "general.signs." + i + ".";
|
||||
getRegion().setSetting(signPath + "location", Utils.locationToConfig(location));
|
||||
getRegion().setSetting(signPath + "facing", facing != null ? facing.name() : null);
|
||||
getRegion().setSetting(signPath + "signType", signType != null ? signType.name() : null);
|
||||
if(profile != null && !profile.isEmpty()) {
|
||||
getRegion().setSetting(signPath + "profile", profile);
|
||||
}
|
||||
// Add to the map
|
||||
RegionSign regionSign = this.signFactory.createRegionSign(this, String.valueOf(i));
|
||||
this.globalSignManager.addSign(regionSign);
|
||||
this.internalSignManager.addSign(regionSign);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package me.wiefferink.areashop.features.signs;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.Singleton;
|
||||
import com.google.inject.assistedinject.FactoryModuleBuilder;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.managers.SignLinkerManager;
|
||||
import me.wiefferink.areashop.nms.BlockBehaviourHelper;
|
||||
import me.wiefferink.areashop.regions.RegionFactory;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class SignsModule extends AbstractModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(SignManager.class).asEagerSingleton();
|
||||
install(new FactoryModuleBuilder().build(SignFactory.class));
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public SignListener provideSignListener(@Nonnull AreaShop plugin,
|
||||
@Nonnull BlockBehaviourHelper behaviourHelper,
|
||||
@Nonnull RegionFactory regionFactory,
|
||||
@Nonnull MessageBridge messageBridge,
|
||||
@Nonnull SignLinkerManager signLinkerManager,
|
||||
@Nonnull WorldGuardInterface worldGuardInterface,
|
||||
@Nonnull SignManager signManager,
|
||||
@Nonnull IFileManager fileManager
|
||||
) {
|
||||
final SignListener signListener = new SignListener(
|
||||
plugin,
|
||||
behaviourHelper,
|
||||
regionFactory,
|
||||
messageBridge,
|
||||
signLinkerManager,
|
||||
worldGuardInterface,
|
||||
signManager,
|
||||
fileManager
|
||||
);
|
||||
plugin.getServer().getPluginManager().registerEvents(signListener, plugin);
|
||||
return signListener;
|
||||
}
|
||||
|
||||
}
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
package me.wiefferink.areashop.listeners;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
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 me.wiefferink.bukkitdo.Do;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerKickEvent;
|
||||
import org.bukkit.event.player.PlayerLoginEvent;
|
||||
import org.bukkit.event.player.PlayerLoginEvent.Result;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Notify region expiry and track activity time.
|
||||
*/
|
||||
public final class PlayerLoginLogoutListener implements Listener {
|
||||
|
||||
private final AreaShop plugin;
|
||||
private final MessageBridge messageBridge;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param plugin The AreaShop plugin
|
||||
*/
|
||||
public PlayerLoginLogoutListener(@Nonnull AreaShop plugin, @Nonnull MessageBridge messageBridge) {
|
||||
this.plugin = plugin;
|
||||
this.messageBridge = messageBridge;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a sign is changed.
|
||||
* @param event The event
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerLogin(PlayerLoginEvent event) {
|
||||
if(event.getResult() != Result.ALLOWED) {
|
||||
return;
|
||||
}
|
||||
final Player player = event.getPlayer();
|
||||
|
||||
// Schedule task to check for notifications, prevents a lag spike at login
|
||||
Do.syncTimerLater(25, 25, () -> {
|
||||
// Delay until all regions are loaded
|
||||
if(!plugin.isReady()) {
|
||||
return true;
|
||||
}
|
||||
if(!player.isOnline()) {
|
||||
return false;
|
||||
}
|
||||
// Notify for rents that almost run out
|
||||
for(RentRegion region : plugin.getFileManager().getRentsRef()) {
|
||||
if(region.isRenter(player)) {
|
||||
String warningSetting = region.getStringSetting("rent.warningOnLoginTime");
|
||||
if(warningSetting == null || warningSetting.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
long warningTime = Utils.durationStringToLong(warningSetting);
|
||||
if(region.getTimeLeft() < warningTime) {
|
||||
// Send the warning message later to let it appear after general MOTD messages
|
||||
messageBridge.message(player, "rent-expireWarning", region);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Notify admins for plugin updates
|
||||
this.plugin.notifyUpdate(player);
|
||||
return false;
|
||||
});
|
||||
|
||||
// Check if the player has regions that use an old name of him and update them
|
||||
Do.syncTimerLater(22, 10, () -> {
|
||||
if(!plugin.isReady()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
List<GeneralRegion> regions = new ArrayList<>();
|
||||
for(GeneralRegion region : plugin.getFileManager().getRegionsRef()) {
|
||||
if(region.isOwner(player)) {
|
||||
regions.add(region);
|
||||
}
|
||||
}
|
||||
|
||||
Do.forAll(
|
||||
plugin.getConfig().getInt("nameupdate.regionsPerTick"),
|
||||
regions,
|
||||
region -> {
|
||||
if(region instanceof BuyRegion) {
|
||||
if(!player.getName().equals(region.getStringSetting("buy.buyerName"))) {
|
||||
region.setSetting("buy.buyerName", player.getName());
|
||||
region.update();
|
||||
}
|
||||
} else if(region instanceof RentRegion) {
|
||||
if(!player.getName().equals(region.getStringSetting("rent.renterName"))) {
|
||||
region.setSetting("rent.renterName", player.getName());
|
||||
region.update();
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
// Active time updates
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerLogout(PlayerQuitEvent event) {
|
||||
updateLastActive(event.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerKick(PlayerKickEvent event) {
|
||||
updateLastActive(event.getPlayer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the last active time for all regions the player is owner off.
|
||||
* @param player The player to update the active times for
|
||||
*/
|
||||
private void updateLastActive(Player player) {
|
||||
for(GeneralRegion region : plugin.getFileManager().getRegionsRef()) {
|
||||
if(region.isOwner(player)) {
|
||||
region.updateLastActiveTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,234 @@
|
||||
package me.wiefferink.areashop.managers;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
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.CommandAreaShop;
|
||||
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.ImportCommand;
|
||||
import me.wiefferink.areashop.commands.InfoCommand;
|
||||
import me.wiefferink.areashop.commands.LinksignsCommand;
|
||||
import me.wiefferink.areashop.commands.MeCommand;
|
||||
import me.wiefferink.areashop.commands.MessageCommand;
|
||||
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.StackCommand;
|
||||
import me.wiefferink.areashop.commands.StopresellCommand;
|
||||
import me.wiefferink.areashop.commands.TeleportCommand;
|
||||
import me.wiefferink.areashop.commands.UnrentCommand;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
@Singleton
|
||||
public class CommandManager extends Manager implements CommandExecutor, TabCompleter {
|
||||
private final List<CommandAreaShop> commands;
|
||||
private final AreaShop plugin;
|
||||
private final MessageBridge messageBridge;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
@Inject
|
||||
CommandManager(@Nonnull AreaShop plugin, @Nonnull MessageBridge messageBridge, @Nonnull
|
||||
Injector injector) {
|
||||
this.plugin = plugin;
|
||||
this.messageBridge = messageBridge;
|
||||
commands = new ArrayList<>(34);
|
||||
commands.add(new HelpCommand(this));
|
||||
commands.add(injector.getInstance(RentCommand.class));
|
||||
commands.add(injector.getInstance(UnrentCommand.class));
|
||||
commands.add(injector.getInstance(BuyCommand.class));
|
||||
commands.add(injector.getInstance(SellCommand.class));
|
||||
commands.add(injector.getInstance(MeCommand.class));
|
||||
commands.add(injector.getInstance(InfoCommand.class));
|
||||
commands.add(injector.getInstance(TeleportCommand.class));
|
||||
commands.add(injector.getInstance(SetteleportCommand.class));
|
||||
commands.add(injector.getInstance(AddfriendCommand.class));
|
||||
commands.add(injector.getInstance(DelfriendCommand.class));
|
||||
commands.add(injector.getInstance(FindCommand.class));
|
||||
commands.add(injector.getInstance(ResellCommand.class));
|
||||
commands.add(injector.getInstance(StopresellCommand.class));
|
||||
commands.add(injector.getInstance(SetrestoreCommand.class));
|
||||
commands.add(injector.getInstance(SetpriceCommand.class));
|
||||
commands.add(injector.getInstance(SetownerCommand.class));
|
||||
commands.add(injector.getInstance(SetdurationCommand.class));
|
||||
commands.add(injector.getInstance(ReloadCommand.class));
|
||||
commands.add(injector.getInstance(GroupaddCommand.class));
|
||||
commands.add(injector.getInstance(GroupdelCommand.class));
|
||||
commands.add(injector.getInstance(GrouplistCommand.class));
|
||||
commands.add(injector.getInstance(GroupinfoCommand.class));
|
||||
commands.add(injector.getInstance(SchematiceventCommand.class));
|
||||
commands.add(injector.getInstance(AddCommand.class));
|
||||
commands.add(injector.getInstance(DelCommand.class));
|
||||
commands.add(injector.getInstance(AddsignCommand.class));
|
||||
commands.add(injector.getInstance(DelsignCommand.class));
|
||||
commands.add(injector.getInstance(LinksignsCommand.class));
|
||||
commands.add(injector.getInstance(StackCommand.class));
|
||||
commands.add(injector.getInstance(SetlandlordCommand.class));
|
||||
commands.add(injector.getInstance(MessageCommand.class));
|
||||
commands.add(injector.getInstance(ImportCommand.class));
|
||||
|
||||
// Register commands in bukkit
|
||||
plugin.getCommand("AreaShop").setExecutor(this);
|
||||
plugin.getCommand("AreaShop").setTabCompleter(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list with AreaShop commands.
|
||||
* @return The list with AreaShop commands
|
||||
*/
|
||||
public List<CommandAreaShop> getCommands() {
|
||||
return commands;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the help page for the CommandSender.
|
||||
* @param target The CommandSender to show the help to
|
||||
*/
|
||||
public void showHelp(CommandSender target) {
|
||||
if(!target.hasPermission("areashop.help")) {
|
||||
messageBridge.message(target, "help-noPermission");
|
||||
return;
|
||||
}
|
||||
// Add all messages to a list
|
||||
ArrayList<String> messages = new ArrayList<>();
|
||||
messageBridge.message(target, "help-header");
|
||||
messageBridge.message(target, "help-alias");
|
||||
for(CommandAreaShop command : commands) {
|
||||
String help = command.getHelp(target);
|
||||
if(help != null && !help.isEmpty()) {
|
||||
messages.add(help);
|
||||
}
|
||||
}
|
||||
// Send the messages to the target
|
||||
for(String message : messages) {
|
||||
messageBridge.messageNoPrefix(target, message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String alias, String[] args) {
|
||||
if(!plugin.isReady()) {
|
||||
messageBridge.message(sender, "general-notReady");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Redirect `/as info player <player>` to `/as me <player>`
|
||||
if(args.length == 3 && "info".equals(args[0]) && "player".equals(args[1])) {
|
||||
args[0] = "me";
|
||||
args[1] = args[2];
|
||||
}
|
||||
|
||||
// Execute command
|
||||
boolean executed = false;
|
||||
for(int i = 0; i < commands.size() && !executed; i++) {
|
||||
if(commands.get(i).canExecute(command, args)) {
|
||||
commands.get(i).execute(sender, args);
|
||||
executed = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Show help
|
||||
if (!executed) {
|
||||
if (args.length == 0) {
|
||||
this.showHelp(sender);
|
||||
} else {
|
||||
// Indicate that the '/as updaterents' and '/as updatebuys' commands are removed
|
||||
if("updaterents".equalsIgnoreCase(args[0]) || "updatebuys".equalsIgnoreCase(args[0])) {
|
||||
messageBridge.message(sender, "reload-updateCommandChanged");
|
||||
} else {
|
||||
messageBridge.message(sender, "cmd-notValid");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
||||
List<String> result = new ArrayList<>();
|
||||
if(!sender.hasPermission("areashop.tabcomplete")) {
|
||||
return result;
|
||||
}
|
||||
int toCompleteNumber = args.length;
|
||||
String toCompletePrefix = args[args.length - 1].toLowerCase();
|
||||
//AreaShop.debug("toCompleteNumber=" + toCompleteNumber + ", toCompletePrefix=" + toCompletePrefix + ", length=" + toCompletePrefix.length());
|
||||
if(toCompleteNumber == 1) {
|
||||
for(CommandAreaShop c : commands) {
|
||||
String begin = c.getCommandStart();
|
||||
result.add(begin.substring(begin.indexOf(' ') + 1));
|
||||
}
|
||||
} else {
|
||||
String[] start = new String[args.length];
|
||||
start[0] = command.getName();
|
||||
System.arraycopy(args, 0, start, 1, args.length - 1);
|
||||
for(CommandAreaShop c : commands) {
|
||||
if(c.canExecute(command, args)) {
|
||||
result = c.getTabCompleteList(toCompleteNumber, start, sender);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Filter and sort the results
|
||||
if(!result.isEmpty()) {
|
||||
SortedSet<String> set = new TreeSet<>();
|
||||
for(String suggestion : result) {
|
||||
if(suggestion.toLowerCase().startsWith(toCompletePrefix)) {
|
||||
set.add(suggestion);
|
||||
}
|
||||
}
|
||||
result.clear();
|
||||
result.addAll(set);
|
||||
}
|
||||
//AreaShop.debug("Tabcomplete #" + toCompleteNumber + ", prefix="+ toCompletePrefix + ", result=" + result.toString());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
package me.wiefferink.areashop.managers;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.ProvisionException;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.features.CommandsFeature;
|
||||
import me.wiefferink.areashop.features.DebugFeature;
|
||||
import me.wiefferink.areashop.features.FeatureFactory;
|
||||
import me.wiefferink.areashop.features.FriendsFeature;
|
||||
import me.wiefferink.areashop.features.RegionFeature;
|
||||
import me.wiefferink.areashop.features.TeleportFeature;
|
||||
import me.wiefferink.areashop.features.WorldGuardRegionFlagsFeature;
|
||||
import me.wiefferink.areashop.features.signs.SignsFeature;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
@Singleton
|
||||
public class FeatureManager extends Manager {
|
||||
|
||||
private static final Collection<Class<? extends RegionFeature>> globalFeatureClasses = Arrays.asList(
|
||||
CommandsFeature.class,
|
||||
WorldGuardRegionFlagsFeature.class,
|
||||
DebugFeature.class
|
||||
);
|
||||
// One instance of each feature, registered for event handling
|
||||
private final Set<RegionFeature> globalFeatures = new HashSet<>();
|
||||
private final Map<Class<? extends RegionFeature>, Function<GeneralRegion, ? extends RegionFeature>> regionFeatureConstructors = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
@Inject
|
||||
FeatureManager(@Nonnull FeatureFactory featureFactory) {
|
||||
// Setup constructors for region specific features
|
||||
regionFeatureConstructors.put(SignsFeature.class, wrapInstantiator(SignsFeature.class, featureFactory::createSignsFeature));
|
||||
regionFeatureConstructors.put(TeleportFeature.class, wrapInstantiator(TeleportFeature.class, featureFactory::createTeleportFeature));
|
||||
regionFeatureConstructors.put(FriendsFeature.class, wrapInstantiator(FriendsFeature.class, featureFactory::createFriendsFeature));
|
||||
}
|
||||
|
||||
public void initializeFeatures(@Nonnull Injector injector) {
|
||||
// Instantiate and register global features (one per type, for event handling)
|
||||
for(Class<? extends RegionFeature> clazz : globalFeatureClasses) {
|
||||
try {
|
||||
RegionFeature feature = injector.getInstance(clazz);
|
||||
feature.listen();
|
||||
globalFeatures.add(feature);
|
||||
} catch(ProvisionException e) {
|
||||
AreaShop.error("Failed to instantiate global feature:", clazz, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private <T extends RegionFeature> Function<GeneralRegion, T> wrapInstantiator(Class<T> clazz, Function<GeneralRegion, T> function
|
||||
) {
|
||||
return region -> {
|
||||
try {
|
||||
return function.apply(region);
|
||||
} catch (Throwable e) {
|
||||
AreaShop.error("Failed to instantiate feature", clazz, "for region", region, e, e.getCause());
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
for(RegionFeature feature : globalFeatures) {
|
||||
feature.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Instanciate a feature for a certain region.
|
||||
* @param region The region to create a feature for
|
||||
* @param featureClazz The class of the feature to create
|
||||
* @return The feature class
|
||||
*/
|
||||
public RegionFeature getRegionFeature(GeneralRegion region, Class<? extends RegionFeature> featureClazz) {
|
||||
return regionFeatureConstructors.get(featureClazz).apply(region);
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,395 @@
|
||||
package me.wiefferink.areashop.managers;
|
||||
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import me.wiefferink.areashop.events.ask.AddingRegionEvent;
|
||||
import me.wiefferink.areashop.events.ask.DeletingRegionEvent;
|
||||
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 org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public interface IFileManager {
|
||||
|
||||
/**
|
||||
* Get the folder where schematics are stored.
|
||||
*
|
||||
* @return The folder where schematics are stored
|
||||
*/
|
||||
String getSchematicFolder();
|
||||
|
||||
/**
|
||||
* Get a group.
|
||||
*
|
||||
* @param name The name of the group to get (will be normalized)
|
||||
* @return The group if found, otherwise null
|
||||
*/
|
||||
RegionGroup getGroup(String name);
|
||||
|
||||
/**
|
||||
* Get all groups.
|
||||
*
|
||||
* @return Collection with all groups (safe to modify)
|
||||
*/
|
||||
Collection<RegionGroup> getGroups();
|
||||
|
||||
/**
|
||||
* Get the default region settings as provided by the user (default.yml).
|
||||
*
|
||||
* @return YamlConfiguration with the settings (might miss settings, which should be filled in with {@link #getFallbackRegionSettings()})
|
||||
*/
|
||||
YamlConfiguration getRegionSettings();
|
||||
|
||||
/**
|
||||
* Get the default regions settings as provided by AreaShop (default.yml).
|
||||
*
|
||||
* @return YamlConfiguration with the default settings
|
||||
*/
|
||||
YamlConfiguration getFallbackRegionSettings();
|
||||
|
||||
/**
|
||||
* Get the config file (config.yml).
|
||||
*
|
||||
* @return YamlConfiguration with the settings of users, with fallback to the settings provided by AreaShop
|
||||
*/
|
||||
YamlConfiguration getConfig();
|
||||
|
||||
/**
|
||||
* Get a region.
|
||||
*
|
||||
* @param name The name of the region to get (will be normalized)
|
||||
* @return The region if found, otherwise null
|
||||
*/
|
||||
@Nullable
|
||||
GeneralRegion getRegion(String name);
|
||||
|
||||
/**
|
||||
* Get a rental region.
|
||||
*
|
||||
* @param name The name of the rental region (will be normalized)
|
||||
* @return RentRegion if it could be found, otherwise null
|
||||
*/
|
||||
@Nullable
|
||||
RentRegion getRent(String name);
|
||||
|
||||
/**
|
||||
* Get a buy region.
|
||||
*
|
||||
* @param name The name of the buy region (will be normalized)
|
||||
* @return BuyRegion if it could be found, otherwise null
|
||||
*/
|
||||
@Nullable
|
||||
BuyRegion getBuy(String name);
|
||||
|
||||
/**
|
||||
* Get all rental regions.
|
||||
*
|
||||
* @return List of all rental regions
|
||||
*/
|
||||
Collection<RentRegion> getRents();
|
||||
|
||||
/**
|
||||
* Get all rental regions.
|
||||
*
|
||||
* @return List of all rental regions
|
||||
*/
|
||||
Collection<RentRegion> getRentsRef();
|
||||
|
||||
/**
|
||||
* Get all buy regions.
|
||||
*
|
||||
* @return List of all buy regions
|
||||
*/
|
||||
List<BuyRegion> getBuys();
|
||||
|
||||
Collection<BuyRegion> getBuysRef();
|
||||
|
||||
/**
|
||||
* Get all regions.
|
||||
*
|
||||
* @return List of all regions (it is safe to modify the list)
|
||||
*/
|
||||
List<GeneralRegion> getRegions();
|
||||
|
||||
/**
|
||||
* Get all regions.
|
||||
*
|
||||
* @return List of all regions (it is safe to modify the list)
|
||||
*/
|
||||
Collection<GeneralRegion> getRegionsRef();
|
||||
|
||||
/**
|
||||
* Get a list of names of all buy regions.
|
||||
*
|
||||
* @return A String list with all the names
|
||||
*/
|
||||
List<String> getBuyNames();
|
||||
|
||||
/**
|
||||
* Get a list of names of all rent regions.
|
||||
*
|
||||
* @return A String list with all the names
|
||||
*/
|
||||
List<String> getRentNames();
|
||||
|
||||
/**
|
||||
* Get a list of names of all regions.
|
||||
*
|
||||
* @return A String list with all the names
|
||||
*/
|
||||
List<String> getRegionNames();
|
||||
|
||||
/**
|
||||
* Get a list of names of all groups.
|
||||
*
|
||||
* @return A String list with all the names
|
||||
*/
|
||||
List<String> getGroupNames();
|
||||
|
||||
/**
|
||||
* Add a region to the list and mark it as to-be-saved.
|
||||
*
|
||||
* @param region Then region to add
|
||||
* @return true when successful, otherwise false (denied by an event listener)
|
||||
*/
|
||||
AddingRegionEvent addRegion(GeneralRegion region);
|
||||
|
||||
/**
|
||||
* Add a region to the list without saving it to disk (useful for loading at startup).
|
||||
*
|
||||
* @param region The region to add
|
||||
* @return true when successful, otherwise false (denied by an event listener)
|
||||
*/
|
||||
AddingRegionEvent addRegionNoSave(GeneralRegion region);
|
||||
|
||||
/**
|
||||
* Mark all RegionGroups that they should regenerate regions.
|
||||
*/
|
||||
void markGroupsAutoDirty();
|
||||
|
||||
/**
|
||||
* Add a RegionGroup.
|
||||
*
|
||||
* @param group The RegionGroup to add
|
||||
*/
|
||||
void addGroup(RegionGroup group);
|
||||
|
||||
/**
|
||||
* Check if a player can add a certain region as rent or buy region.
|
||||
*
|
||||
* @param sender The player/console that wants to add a region
|
||||
* @param region The WorldGuard region to add
|
||||
* @param world The world the ProtectedRegion is located in
|
||||
* @param type The type the region should have in AreaShop
|
||||
* @return The result if a player would want to add this region
|
||||
*/
|
||||
AddResult checkRegionAdd(CommandSender sender,
|
||||
ProtectedRegion region,
|
||||
World world,
|
||||
GeneralRegion.RegionType type);
|
||||
|
||||
/**
|
||||
* Remove a region from the list.
|
||||
*
|
||||
* @param region The region to remove
|
||||
* @param giveMoneyBack use true to give money back to the player if someone is currently holding this region, otherwise false
|
||||
* @return true if the region has been removed, false otherwise
|
||||
*/
|
||||
DeletingRegionEvent deleteRegion(GeneralRegion region, boolean giveMoneyBack);
|
||||
|
||||
/**
|
||||
* Remove a group.
|
||||
*
|
||||
* @param group Group to remove
|
||||
*/
|
||||
void removeGroup(RegionGroup group);
|
||||
|
||||
/**
|
||||
* Update all signs that need periodic updating.
|
||||
*/
|
||||
void performPeriodicSignUpdate();
|
||||
|
||||
/**
|
||||
* Send out rent expire warnings.
|
||||
*/
|
||||
void sendRentExpireWarnings();
|
||||
|
||||
/**
|
||||
* Update regions in a task to minimize lag.
|
||||
*
|
||||
* @param regions Regions to update
|
||||
* @param confirmationReceiver The CommandSender that should be notified at completion
|
||||
*/
|
||||
void updateRegions(Collection<GeneralRegion> regions, CommandSender confirmationReceiver);
|
||||
|
||||
/**
|
||||
* Update a list of regions.
|
||||
*
|
||||
* @param regions The list of regions to update.
|
||||
*/
|
||||
void updateRegions(Collection<GeneralRegion> regions);
|
||||
|
||||
/**
|
||||
* Update all regions, happens in a task to minimize lag.
|
||||
*/
|
||||
void updateAllRegions();
|
||||
|
||||
/**
|
||||
* Update all regions.
|
||||
*
|
||||
* @param confirmationReceiver Optional CommandSender that should receive progress messages
|
||||
*/
|
||||
void updateAllRegions(CommandSender confirmationReceiver);
|
||||
|
||||
/**
|
||||
* Save the group file to disk.
|
||||
*/
|
||||
void saveGroupsIsRequired();
|
||||
|
||||
/**
|
||||
* Check if saving the groups file is required.
|
||||
*
|
||||
* @return true if changes are made and saving is required, otherwise false
|
||||
*/
|
||||
boolean isSaveGroupsRequired();
|
||||
|
||||
/**
|
||||
* Save the groups file to disk synchronously.
|
||||
*/
|
||||
void saveGroupsNow();
|
||||
|
||||
/**
|
||||
* Save all region related files spread over time (low load).
|
||||
*/
|
||||
void saveRequiredFiles();
|
||||
|
||||
/**
|
||||
* Save all region related files directly (only for cases like onDisable()).
|
||||
*/
|
||||
void saveRequiredFilesAtOnce();
|
||||
|
||||
/**
|
||||
* Indicates that a/multiple WorldGuard regions need to be saved.
|
||||
*
|
||||
* @param worldName The world where the regions that should be saved is in
|
||||
*/
|
||||
void saveIsRequiredForRegionWorld(String worldName);
|
||||
|
||||
/**
|
||||
* Save all worldGuard regions that need saving.
|
||||
*/
|
||||
void saveWorldGuardRegions();
|
||||
|
||||
/**
|
||||
* Get the folder the region files are located in.
|
||||
*
|
||||
* @return The folder where the region.yml files are in
|
||||
*/
|
||||
String getRegionFolder();
|
||||
|
||||
/**
|
||||
* Check if a region is on the adding blacklist.
|
||||
*
|
||||
* @param region The region name to check
|
||||
* @return true if the region may not be added, otherwise false
|
||||
*/
|
||||
boolean isBlacklisted(String region);
|
||||
|
||||
/**
|
||||
* Unrent regions that have no time left, regions to check per tick is in the config.
|
||||
*/
|
||||
void checkRents();
|
||||
|
||||
/**
|
||||
* Check all regions and unrent/sell them if the player is inactive for too long.
|
||||
*/
|
||||
void checkForInactiveRegions();
|
||||
|
||||
/**
|
||||
* Load the file with the versions, used to check if the other files need conversion.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
void loadVersions();
|
||||
|
||||
/**
|
||||
* Save the versions file to disk.
|
||||
*/
|
||||
void saveVersions();
|
||||
|
||||
/**
|
||||
* Load all files from disk.
|
||||
*
|
||||
* @param thisTick Load files in the current tick or a tick later
|
||||
* @return true if the files are loaded correctly, otherwise false
|
||||
*/
|
||||
boolean loadFiles(boolean thisTick);
|
||||
|
||||
/**
|
||||
* Load the default.yml file
|
||||
*
|
||||
* @return true if it has been loaded successfully, otherwise false
|
||||
*/
|
||||
boolean loadDefaultFile();
|
||||
|
||||
/**
|
||||
* Load the default.yml file
|
||||
*
|
||||
* @return true if it has been loaded successfully, otherwise false
|
||||
*/
|
||||
boolean loadConfigFile();
|
||||
|
||||
/**
|
||||
* Load the groups.yml file from disk
|
||||
*
|
||||
* @return true if succeeded, otherwise false
|
||||
*/
|
||||
boolean loadGroupsFile();
|
||||
|
||||
/**
|
||||
* Load all region files.
|
||||
*/
|
||||
void loadRegionFiles();
|
||||
|
||||
/**
|
||||
* Get the settings of a group.
|
||||
*
|
||||
* @param groupName Name of the group to get the settings from
|
||||
* @return The settings of the group
|
||||
*/
|
||||
ConfigurationSection getGroupSettings(String groupName);
|
||||
|
||||
/**
|
||||
* Set a setting for a group.
|
||||
*
|
||||
* @param group The group to set it for
|
||||
* @param path The path to set
|
||||
* @param setting The value to set
|
||||
*/
|
||||
void setGroupSetting(RegionGroup group, String path, Object setting);
|
||||
|
||||
// Enum for region types
|
||||
public enum AddResult {
|
||||
BLACKLISTED("blacklisted"),
|
||||
NOPERMISSION("nopermission"),
|
||||
ALREADYADDED("alreadyadded"),
|
||||
ALREADYADDEDOTHERWORLD("alreadyaddedotherworld"),
|
||||
SUCCESS("success");
|
||||
|
||||
private final String value;
|
||||
|
||||
AddResult(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package me.wiefferink.areashop.managers;
|
||||
|
||||
public abstract class Manager {
|
||||
|
||||
/**
|
||||
* Called at shutdown of the plugin.
|
||||
*/
|
||||
public void shutdown() {
|
||||
// To override by extending classes
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package me.wiefferink.areashop.managers;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.sql.Date;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.Instant;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class SignErrorLogger {
|
||||
|
||||
public static final String PREFIX_WARN = "[Warning] [Sign Feature] ";
|
||||
public static final DateFormat FORMAT = new SimpleDateFormat("MM/dd/yy HH:mm:ss");
|
||||
|
||||
private final List<String> cache = new LinkedList<>();
|
||||
private final AtomicBoolean needsSaving = new AtomicBoolean(false);
|
||||
|
||||
private final File file;
|
||||
|
||||
public SignErrorLogger(File file) {
|
||||
this.file = Objects.requireNonNull(file);
|
||||
}
|
||||
|
||||
public void clearCache() {
|
||||
synchronized (this.cache) {
|
||||
this.cache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public SignErrorLogger submitWarning(String message) {
|
||||
final String actual = FORMAT.format(Date.from(Instant.now())) + PREFIX_WARN + message;
|
||||
synchronized (this.cache) {
|
||||
this.cache.add(actual);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public void queueSave() {
|
||||
this.needsSaving.set(true);
|
||||
}
|
||||
|
||||
public void saveIfDirty() {
|
||||
if (this.needsSaving.get()) {
|
||||
save();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void save() {
|
||||
AreaShop.debugTask("[Sign Feature] Dumping sign errors to disk...");
|
||||
final String[] copy;
|
||||
synchronized (this.cache) {
|
||||
copy = cache.toArray(new String[0]);
|
||||
}
|
||||
final StringJoiner joiner = new StringJoiner(System.lineSeparator());
|
||||
for (String s : copy) {
|
||||
joiner.add(s);
|
||||
}
|
||||
try (OutputStream os = new FileOutputStream(file);
|
||||
OutputStreamWriter writer = new OutputStreamWriter(os, StandardCharsets.UTF_8)) {
|
||||
writer.write(joiner.toString());
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
AreaShop.error("Failed to update the sign error log!");
|
||||
} finally {
|
||||
AreaShop.debugTask("[Sign Feature] Error dump complete.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
package me.wiefferink.areashop.managers;
|
||||
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.features.signs.RegionSign;
|
||||
import me.wiefferink.areashop.features.signs.SignManager;
|
||||
import me.wiefferink.areashop.regions.GeneralRegion;
|
||||
import me.wiefferink.areashop.tools.Materials;
|
||||
import me.wiefferink.areashop.tools.SignUtils;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.util.BlockIterator;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
@Singleton
|
||||
public class SignLinkerManager extends Manager implements Listener {
|
||||
private final Map<UUID, SignLinker> signLinkers;
|
||||
private boolean eventsRegistered;
|
||||
|
||||
@Inject
|
||||
private AreaShop plugin;
|
||||
@Inject
|
||||
private SignManager signManager;
|
||||
@Inject
|
||||
private MessageBridge messageBridge;
|
||||
|
||||
SignLinkerManager() {
|
||||
signLinkers = new HashMap<>();
|
||||
eventsRegistered = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
for(UUID uuid : signLinkers.keySet()) {
|
||||
exitSignLinkMode(Bukkit.getPlayer(uuid));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Let a player enter sign linking mode.
|
||||
* @param player The player that has to enter sign linking mode
|
||||
* @param profile The profile to use for the signs (null for default)
|
||||
*/
|
||||
public void enterSignLinkMode(Player player, String profile) {
|
||||
signLinkers.put(player.getUniqueId(), new SignLinker(player, profile));
|
||||
messageBridge.message(player, "linksigns-first");
|
||||
messageBridge.message(player, "linksigns-next");
|
||||
if(!eventsRegistered) {
|
||||
eventsRegistered = true;
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Let a player exit sign linking mode.
|
||||
* @param player The player that has to exit sign linking mode
|
||||
*/
|
||||
public void exitSignLinkMode(Player player) {
|
||||
signLinkers.remove(player.getUniqueId());
|
||||
if(eventsRegistered && signLinkers.isEmpty()) {
|
||||
eventsRegistered = false;
|
||||
HandlerList.unregisterAll(this);
|
||||
}
|
||||
messageBridge.message(player, "linksigns-stopped");
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the player is in sign linking mode.
|
||||
* @param player The player to check
|
||||
* @return true if the player is in sign linking mode, otherwise false
|
||||
*/
|
||||
public boolean isInSignLinkMode(Player player) {
|
||||
return signLinkers.containsKey(player.getUniqueId());
|
||||
}
|
||||
|
||||
/**
|
||||
* On player interactions.
|
||||
* @param event The PlayerInteractEvent
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||
if(isInSignLinkMode(event.getPlayer())) {
|
||||
event.setCancelled(true);
|
||||
Player player = event.getPlayer();
|
||||
SignLinker linker = signLinkers.get(event.getPlayer().getUniqueId());
|
||||
if(event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
|
||||
// Get the region
|
||||
BlockIterator blockIterator = new BlockIterator(player, 100);
|
||||
while(blockIterator.hasNext()) {
|
||||
Block next = blockIterator.next();
|
||||
List<GeneralRegion> regions = Utils.getRegions(next.getLocation());
|
||||
if(regions.size() == 1) {
|
||||
linker.setRegion(regions.get(0));
|
||||
return;
|
||||
} else if(regions.size() > 1) {
|
||||
Set<String> names = new HashSet<>();
|
||||
for(GeneralRegion region : regions) {
|
||||
names.add(region.getName());
|
||||
}
|
||||
messageBridge.message(player, "linksigns-multipleRegions", Utils.createCommaSeparatedList(names));
|
||||
messageBridge.message(player, "linksigns-multipleRegionsAdvice");
|
||||
return;
|
||||
}
|
||||
}
|
||||
// No regions found within the maximum range
|
||||
messageBridge.message(player, "linksigns-noRegions");
|
||||
} else if(event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_BLOCK) {
|
||||
Block block = null;
|
||||
BlockIterator blockIterator = new BlockIterator(player, 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(player, "linksigns-noSign");
|
||||
return;
|
||||
}
|
||||
|
||||
Optional<RegionSign> optional = signManager.signFromLocation(block.getLocation());
|
||||
if(optional.isPresent()) {
|
||||
RegionSign regionSign = optional.get();
|
||||
messageBridge.message(player, "linksigns-alreadyRegistered", regionSign.getRegion());
|
||||
return;
|
||||
}
|
||||
linker.setSign(block.getLocation(), block.getType(), SignUtils.getSignFacing(block));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle disconnection players.
|
||||
* @param event The PlayerQuitEvent
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerLeave(PlayerQuitEvent event) {
|
||||
exitSignLinkMode(event.getPlayer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Class to keep track of the signlinking data.
|
||||
*/
|
||||
private class SignLinker {
|
||||
private boolean hasSign = false;
|
||||
private boolean hasRegion = false;
|
||||
|
||||
public final Player linker;
|
||||
public final String profile;
|
||||
|
||||
public GeneralRegion region = null;
|
||||
|
||||
public Location location = null;
|
||||
public Material type = null;
|
||||
public BlockFace facing = null;
|
||||
|
||||
public SignLinker(Player linker, String profile) {
|
||||
this.linker = linker;
|
||||
this.profile = profile;
|
||||
}
|
||||
|
||||
public void setRegion(GeneralRegion region) {
|
||||
this.region = region;
|
||||
hasRegion = true;
|
||||
if(!isComplete()) {
|
||||
messageBridge.message(linker, "linksigns-regionFound", region);
|
||||
}
|
||||
finish();
|
||||
}
|
||||
|
||||
public void setSign(Location location, Material type, BlockFace facing) {
|
||||
this.location = location;
|
||||
this.type = type;
|
||||
this.facing = facing;
|
||||
hasSign = true;
|
||||
if(!isComplete()) {
|
||||
messageBridge.message(linker, "linksigns-signFound", location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
||||
}
|
||||
finish();
|
||||
}
|
||||
|
||||
public void finish() {
|
||||
if(isComplete()) {
|
||||
region.getSignsFeature().addSign(location, type, facing, profile);
|
||||
if(profile == null) {
|
||||
messageBridge.message(linker, "addsign-success", region);
|
||||
} else {
|
||||
messageBridge.message(linker, "addsign-successProfile", region, profile);
|
||||
}
|
||||
region.update();
|
||||
reset();
|
||||
|
||||
messageBridge.message(linker, "linksigns-next");
|
||||
}
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
hasSign = false;
|
||||
hasRegion = false;
|
||||
}
|
||||
|
||||
public boolean isComplete() {
|
||||
return hasSign && hasRegion;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
package me.wiefferink.areashop.modules;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Singleton;
|
||||
import com.google.inject.assistedinject.FactoryModuleBuilder;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.MessageBridge;
|
||||
import me.wiefferink.areashop.features.FeatureFactory;
|
||||
import me.wiefferink.areashop.features.signs.SignsModule;
|
||||
import me.wiefferink.areashop.interfaces.WorldEditInterface;
|
||||
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
|
||||
import me.wiefferink.areashop.managers.CommandManager;
|
||||
import me.wiefferink.areashop.managers.FeatureManager;
|
||||
import me.wiefferink.areashop.managers.IFileManager;
|
||||
import me.wiefferink.areashop.managers.FileManager;
|
||||
import me.wiefferink.areashop.managers.SignErrorLogger;
|
||||
import me.wiefferink.areashop.managers.SignLinkerManager;
|
||||
import me.wiefferink.areashop.nms.BlockBehaviourHelper;
|
||||
import me.wiefferink.areashop.nms.NMS;
|
||||
import me.wiefferink.areashop.regions.ImportJobFactory;
|
||||
import me.wiefferink.areashop.regions.RegionModule;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class AreaShopModule extends AbstractModule {
|
||||
|
||||
private final AreaShop instance;
|
||||
private final WorldGuardInterface worldGuardInterface;
|
||||
private final WorldEditInterface worldEditInterface;
|
||||
private final NMS nms;
|
||||
private final MessageBridge messageBridge;
|
||||
private final SignErrorLogger signErrorLogger;
|
||||
private final DependencyModule dependencyModule;
|
||||
|
||||
public AreaShopModule(@Nonnull AreaShop instance,
|
||||
@Nonnull MessageBridge messageBridge,
|
||||
@Nonnull NMS nms,
|
||||
@Nonnull WorldEditInterface worldEditInterface,
|
||||
@Nonnull WorldGuardInterface worldGuardInterface,
|
||||
@Nonnull SignErrorLogger signErrorLogger,
|
||||
@Nonnull DependencyModule dependencyModule
|
||||
) {
|
||||
this.instance = instance;
|
||||
this.messageBridge = messageBridge;
|
||||
this.nms = nms;
|
||||
this.signErrorLogger = signErrorLogger;
|
||||
this.worldEditInterface = worldEditInterface;
|
||||
this.worldGuardInterface = worldGuardInterface;
|
||||
this.dependencyModule = dependencyModule;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
install(this.dependencyModule);
|
||||
bind(Plugin.class).toInstance(this.instance);
|
||||
bind(AreaShop.class).toInstance(this.instance);
|
||||
bind(MessageBridge.class).toInstance(this.messageBridge);
|
||||
bind(NMS.class).toInstance(this.nms);
|
||||
bind(BlockBehaviourHelper.class).toInstance(this.nms.blockBehaviourHelper());
|
||||
bind(WorldGuardInterface.class).toInstance(this.worldGuardInterface);
|
||||
bind(WorldEditInterface.class).toInstance(this.worldEditInterface);
|
||||
bind(SignErrorLogger.class).toInstance(this.signErrorLogger);
|
||||
// Setup managers
|
||||
bind(IFileManager.class).to(FileManager.class).asEagerSingleton();
|
||||
bind(FeatureManager.class).in(Singleton.class);
|
||||
bind(CommandManager.class).in(Singleton.class);
|
||||
bind(SignLinkerManager.class).in(Singleton.class);
|
||||
install(new SignsModule());
|
||||
install(new RegionModule());
|
||||
install(new FactoryModuleBuilder().build(FeatureFactory.class));
|
||||
install(new FactoryModuleBuilder().build(ImportJobFactory.class));
|
||||
requestStaticInjection(Utils.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package me.wiefferink.areashop.modules;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.bukkit.inventory.ItemFactory;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.ServicesManager;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import org.bukkit.scoreboard.ScoreboardManager;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class BukkitModule extends AbstractModule {
|
||||
|
||||
private final Server server;
|
||||
|
||||
public BukkitModule(@Nonnull Server server) {
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(Server.class).toInstance(this.server);
|
||||
bind(PluginManager.class).toInstance(this.server.getPluginManager());
|
||||
bind(BukkitScheduler.class).toInstance(this.server.getScheduler());
|
||||
bind(PluginManager.class).toInstance(this.server.getPluginManager());
|
||||
bind(ServicesManager.class).toInstance(this.server.getServicesManager());
|
||||
bind(ItemFactory.class).toInstance(this.server.getItemFactory());
|
||||
bind(ConsoleCommandSender.class).toInstance(this.server.getConsoleSender());
|
||||
bind(ScoreboardManager.class).toInstance(this.server.getScoreboardManager());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package me.wiefferink.areashop.modules;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import net.milkbowl.vault.economy.Economy;
|
||||
import net.milkbowl.vault.permission.Permission;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class DependencyModule extends AbstractModule {
|
||||
|
||||
private final WorldEditPlugin worldEditPlugin;
|
||||
private final WorldGuardPlugin worldGuardPlugin;
|
||||
private final Economy economy;
|
||||
private final Permission permission;
|
||||
|
||||
public DependencyModule(@Nonnull WorldEditPlugin worldEditPlugin,
|
||||
@Nonnull WorldGuardPlugin worldGuardPlugin,
|
||||
@Nullable Economy economy,
|
||||
@Nullable Permission permission
|
||||
) {
|
||||
this.worldEditPlugin = worldEditPlugin;
|
||||
this.worldGuardPlugin = worldGuardPlugin;
|
||||
this.economy = economy;
|
||||
this.permission = permission;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(WorldEditPlugin.class).toInstance(this.worldEditPlugin);
|
||||
bind(WorldGuardPlugin.class).toInstance(this.worldGuardPlugin);
|
||||
bind(Economy.class).toInstance(this.economy);
|
||||
bind(Permission.class).toInstance(this.permission);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,617 @@
|
||||
package me.wiefferink.areashop.regions;
|
||||
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
import com.google.inject.assistedinject.AssistedInject;
|
||||
import me.wiefferink.areashop.AreaShop;
|
||||
import me.wiefferink.areashop.events.ask.BuyingRegionEvent;
|
||||
import me.wiefferink.areashop.events.ask.ResellingRegionEvent;
|
||||
import me.wiefferink.areashop.events.ask.SellingRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.BoughtRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.ResoldRegionEvent;
|
||||
import me.wiefferink.areashop.events.notify.SoldRegionEvent;
|
||||
import me.wiefferink.areashop.interfaces.WorldEditInterface;
|
||||
import me.wiefferink.areashop.interfaces.WorldGuardInterface;
|
||||
import me.wiefferink.areashop.managers.FeatureManager;
|
||||
import me.wiefferink.areashop.tools.Utils;
|
||||
import net.milkbowl.vault.economy.Economy;
|
||||
import net.milkbowl.vault.economy.EconomyResponse;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Calendar;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BuyRegion extends GeneralRegion {
|
||||
|
||||
private final Economy economy;
|
||||
|
||||
@AssistedInject
|
||||
BuyRegion(
|
||||
@Nonnull AreaShop plugin,
|
||||
@Nonnull FeatureManager featureManager,
|
||||
@Nonnull WorldEditInterface worldEditInterface,
|
||||
@Nonnull WorldGuardInterface worldGuardInterface,
|
||||
@Nullable Economy economy,
|
||||
@Assisted @Nonnull YamlConfiguration config
|
||||
) {
|
||||
super(plugin, featureManager, worldEditInterface, worldGuardInterface, config);
|
||||
this.economy = economy;
|
||||
}
|
||||
|
||||
@AssistedInject
|
||||
BuyRegion(
|
||||
@Nonnull AreaShop plugin,
|
||||
@Nonnull FeatureManager featureManager,
|
||||
@Nonnull WorldEditInterface worldEditInterface,
|
||||
@Nonnull WorldGuardInterface worldGuardInterface,
|
||||
@Nullable Economy economy,
|
||||
@Assisted @Nonnull String name,
|
||||
@Assisted @Nonnull World world
|
||||
) {
|
||||
super(plugin, featureManager, worldEditInterface, worldGuardInterface, name, world);
|
||||
this.economy = economy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegionType getType() {
|
||||
return RegionType.BUY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegionState getState() {
|
||||
if(isSold() && isInResellingMode()) {
|
||||
return RegionState.RESELL;
|
||||
} else if(isSold() && !isInResellingMode()) {
|
||||
return RegionState.SOLD;
|
||||
} else {
|
||||
return RegionState.FORSALE;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return !isSold();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the UUID of the owner of this region.
|
||||
* @return The UUID of the owner of this region
|
||||
*/
|
||||
public UUID getBuyer() {
|
||||
String buyer = config.getString("buy.buyer");
|
||||
if(buyer != null) {
|
||||
try {
|
||||
return UUID.fromString(buyer);
|
||||
} catch(IllegalArgumentException e) {
|
||||
// Incorrect UUID
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a player is the buyer of this region.
|
||||
* @param player Player to check
|
||||
* @return true if this player owns this region, otherwise false
|
||||
*/
|
||||
public boolean isBuyer(OfflinePlayer player) {
|
||||
return player != null && isBuyer(player.getUniqueId());
|
||||
}
|
||||
|
||||
public boolean isBuyer(UUID player) {
|
||||
UUID buyer = getBuyer();
|
||||
return !(buyer == null || player == null) && buyer.equals(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the buyer of this region.
|
||||
* @param buyer The UUID of the player that should be set as buyer
|
||||
*/
|
||||
public void setBuyer(UUID buyer) {
|
||||
if(buyer == null) {
|
||||
setSetting("buy.buyer", null);
|
||||
setSetting("buy.buyerName", null);
|
||||
} else {
|
||||
setSetting("buy.buyer", buyer.toString());
|
||||
setSetting("buy.buyerName", Utils.toName(buyer));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the player that owns this region.
|
||||
* @return The name of the player that owns this region, if unavailable by UUID it will return the old cached name, if that is unavailable it will return <UNKNOWN>
|
||||
*/
|
||||
public String getPlayerName() {
|
||||
String result = Utils.toName(getBuyer());
|
||||
if(result == null || result.isEmpty()) {
|
||||
result = getStringSetting("buy.buyerName");
|
||||
if(result == null || result.isEmpty()) {
|
||||
result = "<UNKNOWN>";
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the region is sold.
|
||||
* @return true if the region is sold, otherwise false
|
||||
*/
|
||||
public boolean isSold() {
|
||||
return getBuyer() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the region is being resold.
|
||||
* @return true if the region is available for reselling, otherwise false
|
||||
*/
|
||||
public boolean isInResellingMode() {
|
||||
return config.getBoolean("buy.resellMode");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the price of the region.
|
||||
* @return The price of the region
|
||||
*/
|
||||
public double getPrice() {
|
||||
return Math.max(0, Utils.evaluateToDouble(getStringSetting("buy.price"), this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the resell price of this region.
|
||||
* @return The resell price if isInResellingMode(), otherwise 0.0
|
||||
*/
|
||||
public double getResellPrice() {
|
||||
return Math.max(0, config.getDouble("buy.resellPrice"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the formatted string of the price (includes prefix and suffix).
|
||||
* @return The formatted string of the price
|
||||
*/
|
||||
public String getFormattedPrice() {
|
||||
return Utils.formatCurrency(getPrice());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the formatted string of the resellprice (includes prefix and suffix).
|
||||
* @return The formatted string of the resellprice
|
||||
*/
|
||||
public String getFormattedResellPrice() {
|
||||
return Utils.formatCurrency(getResellPrice());
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the price of the region.
|
||||
* @param price The price to set this region to
|
||||
*/
|
||||
public void setPrice(Double price) {
|
||||
setSetting("buy.price", price);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the region into resell mode with the given price.
|
||||
* @param price The price this region should be put up for sale
|
||||
*/
|
||||
public void enableReselling(double price) {
|
||||
setSetting("buy.resellMode", true);
|
||||
setSetting("buy.resellPrice", price);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop this region from being in resell mode.
|
||||
*/
|
||||
public void disableReselling() {
|
||||
setSetting("buy.resellMode", null);
|
||||
setSetting("buy.resellPrice", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the moneyBack percentage.
|
||||
* @return The % of money the player will get back when selling
|
||||
*/
|
||||
public double getMoneyBackPercentage() {
|
||||
return Utils.evaluateToDouble(getStringSetting("buy.moneyBack"), this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the amount of money that should be paid to the player when selling the region.
|
||||
* @return The amount of money the player should get back
|
||||
*/
|
||||
public double getMoneyBackAmount() {
|
||||
return getPrice() * (getMoneyBackPercentage() / 100.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the formatted string of the amount of the moneyBack amount.
|
||||
* @return String with currency symbols and proper fractional part
|
||||
*/
|
||||
public String getFormattedMoneyBackAmount() {
|
||||
return Utils.formatCurrency(getMoneyBackAmount());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object provideReplacement(String variable) {
|
||||
switch(variable) {
|
||||
case AreaShop.tagPrice:
|
||||
return getFormattedPrice();
|
||||
case AreaShop.tagRawPrice:
|
||||
return getPrice();
|
||||
case AreaShop.tagPlayerName:
|
||||
return getPlayerName();
|
||||
case AreaShop.tagPlayerUUID:
|
||||
return getBuyer();
|
||||
case AreaShop.tagResellPrice:
|
||||
return getFormattedResellPrice();
|
||||
case AreaShop.tagRawResellPrice:
|
||||
return getResellPrice();
|
||||
case AreaShop.tagMoneyBackAmount:
|
||||
return getFormattedMoneyBackAmount();
|
||||
case AreaShop.tagRawMoneyBackAmount:
|
||||
return getMoneyBackAmount();
|
||||
case AreaShop.tagMoneyBackPercentage:
|
||||
return getMoneyBackPercentage() % 1.0 == 0.0 ? (int)getMoneyBackPercentage() : getMoneyBackPercentage();
|
||||
case AreaShop.tagMaxInactiveTime:
|
||||
return this.getFormattedInactiveTimeUntilSell();
|
||||
|
||||
default:
|
||||
return super.provideReplacement(variable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Minutes until automatic unrent when player is offline.
|
||||
* @return The number of milliseconds until the region is unrented while player is offline
|
||||
*/
|
||||
public long getInactiveTimeUntilSell() {
|
||||
return Utils.getDurationFromMinutesOrStringInput(getStringSetting("buy.inactiveTimeUntilSell"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a human readable string indicating how long the player can be offline until automatic unrent.
|
||||
* @return String indicating the inactive time until unrent
|
||||
*/
|
||||
public String getFormattedInactiveTimeUntilSell() {
|
||||
return Utils.millisToHumanFormat(getInactiveTimeUntilSell());
|
||||
}
|
||||
|
||||
/**
|
||||
* Buy a region.
|
||||
* @param offlinePlayer The player that wants to buy the region
|
||||
* @return true if it succeeded and false if not
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean buy(OfflinePlayer offlinePlayer) {
|
||||
// Check if the player has permission
|
||||
if(!plugin.hasPermission(offlinePlayer, "areashop.buy")) {
|
||||
message(offlinePlayer, "buy-noPermission");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(economy == null) {
|
||||
message(offlinePlayer, "general-noEconomy");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(isInResellingMode()) {
|
||||
if(!plugin.hasPermission(offlinePlayer, "areashop.buyresell")) {
|
||||
message(offlinePlayer, "buy-noPermissionResell");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if(!plugin.hasPermission(offlinePlayer, "areashop.buynormal")) {
|
||||
message(offlinePlayer, "buy-noPermissionNoResell");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(getWorld() == null) {
|
||||
message(offlinePlayer, "general-noWorld");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(getRegion() == null) {
|
||||
message(offlinePlayer, "general-noRegion");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isSold() && !(isInResellingMode() && !isBuyer(offlinePlayer))) {
|
||||
if(isBuyer(offlinePlayer)) {
|
||||
message(offlinePlayer, "buy-yours");
|
||||
} else {
|
||||
message(offlinePlayer, "buy-someoneElse");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isResell = isInResellingMode();
|
||||
|
||||
// Only relevant if the player is online
|
||||
Player player = offlinePlayer.getPlayer();
|
||||
if(player != null) {
|
||||
// Check if the players needs to be in the region for buying
|
||||
if(restrictedToRegion() && (!player.getWorld().getName().equals(getWorldName())
|
||||
|| !getRegion().contains(player.getLocation().getBlockX(), player.getLocation().getBlockY(), player.getLocation().getBlockZ()))) {
|
||||
message(offlinePlayer, "buy-restrictedToRegion");
|
||||
return false;
|
||||
}
|
||||
// Check if the players needs to be in the world for buying
|
||||
if(restrictedToWorld() && !player.getWorld().getName().equals(getWorldName())) {
|
||||
message(offlinePlayer, "buy-restrictedToWorld", player.getWorld().getName());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check region limits
|
||||
LimitResult limitResult = this.limitsAllow(RegionType.BUY, offlinePlayer);
|
||||
AreaShop.debug("LimitResult: " + limitResult.toString());
|
||||
if(!limitResult.actionAllowed()) {
|
||||
if(limitResult.getLimitingFactor() == LimitType.TOTAL) {
|
||||
message(offlinePlayer, "total-maximum", limitResult.getMaximum(), limitResult.getCurrent(), limitResult.getLimitingGroup());
|
||||
return false;
|
||||
}
|
||||
if(limitResult.getLimitingFactor() == LimitType.BUYS) {
|
||||
message(offlinePlayer, "buy-maximum", limitResult.getMaximum(), limitResult.getCurrent(), limitResult.getLimitingGroup());
|
||||
return false;
|
||||
}
|
||||
// Should not be reached, but is safe like this
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the player has enough money
|
||||
if (isResell && !economy.has(offlinePlayer, getWorldName(), getResellPrice())) {
|
||||
message(offlinePlayer, "buy-lowMoneyResell", Utils.formatCurrency(economy.getBalance(offlinePlayer, getWorldName())));
|
||||
return false;
|
||||
}
|
||||
if (!isResell && !economy.has(offlinePlayer, getWorldName(), getPrice())) {
|
||||
message(offlinePlayer, "buy-lowMoney", Utils.formatCurrency(economy.getBalance(offlinePlayer, getWorldName())));
|
||||
return false;
|
||||
}
|
||||
|
||||
UUID oldOwner = getBuyer();
|
||||
if(isResell && oldOwner != null) {
|
||||
// Broadcast and check event
|
||||
ResellingRegionEvent event = new ResellingRegionEvent(this, offlinePlayer);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if(event.isCancelled()) {
|
||||
message(offlinePlayer, "general-cancelled", event.getReason());
|
||||
return false;
|
||||
}
|
||||
|
||||
getFriendsFeature().clearFriends();
|
||||
double resellPrice = getResellPrice();
|
||||
// Transfer the money to the previous owner
|
||||
EconomyResponse r = economy.withdrawPlayer(offlinePlayer, getWorldName(), getResellPrice());
|
||||
if(!r.transactionSuccess()) {
|
||||
message(offlinePlayer, "buy-payError");
|
||||
AreaShop.debug("Something went wrong with getting money from " + offlinePlayer.getName() + " while buying " + getName() + ": " + r.errorMessage);
|
||||
return false;
|
||||
}
|
||||
r = null;
|
||||
OfflinePlayer oldOwnerPlayer = Bukkit.getOfflinePlayer(oldOwner);
|
||||
String oldOwnerName = getPlayerName();
|
||||
if(oldOwnerPlayer != null && oldOwnerPlayer.getName() != null) {
|
||||
r = economy.depositPlayer(oldOwnerPlayer, getWorldName(), getResellPrice());
|
||||
oldOwnerName = oldOwnerPlayer.getName();
|
||||
} else if(oldOwnerName != null) {
|
||||
r = economy.depositPlayer(oldOwnerName, getWorldName(), getResellPrice());
|
||||
}
|
||||
if(r == null || !r.transactionSuccess()) {
|
||||
AreaShop.warn("Something went wrong with paying '" + oldOwnerName + "' " + getFormattedPrice() + " for his resell of region " + getName() + " to " + offlinePlayer.getName());
|
||||
}
|
||||
// Resell is done, disable that now
|
||||
disableReselling();
|
||||
|
||||
// Set the owner
|
||||
setBuyer(offlinePlayer.getUniqueId());
|
||||
updateLastActiveTime();
|
||||
|
||||
// Update everything
|
||||
handleSchematicEvent(RegionEvent.RESELL);
|
||||
|
||||
// Notify about updates
|
||||
this.notifyAndUpdate(new ResoldRegionEvent(this, oldOwner));
|
||||
|
||||
// Send message to the player
|
||||
message(offlinePlayer, "buy-successResale", oldOwnerName);
|
||||
Player seller = Bukkit.getPlayer(oldOwner);
|
||||
if(seller != null) {
|
||||
message(seller, "buy-successSeller", resellPrice);
|
||||
}
|
||||
} else {
|
||||
// Broadcast and check event
|
||||
BuyingRegionEvent event = new BuyingRegionEvent(this, offlinePlayer);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if(event.isCancelled()) {
|
||||
message(offlinePlayer, "general-cancelled", event.getReason());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Substract the money from the players balance
|
||||
EconomyResponse r = economy.withdrawPlayer(offlinePlayer, getWorldName(), getPrice());
|
||||
if(!r.transactionSuccess()) {
|
||||
message(offlinePlayer, "buy-payError");
|
||||
return false;
|
||||
}
|
||||
// Optionally give money to the landlord
|
||||
OfflinePlayer landlordPlayer = null;
|
||||
if(getLandlord() != null) {
|
||||
landlordPlayer = Bukkit.getOfflinePlayer(getLandlord());
|
||||
}
|
||||
String landlordName = getLandlordName();
|
||||
if(landlordName != null) {
|
||||
if(landlordPlayer != null && landlordPlayer.getName() != null) {
|
||||
r = economy.depositPlayer(landlordPlayer, getWorldName(), getPrice());
|
||||
} else {
|
||||
r = economy.depositPlayer(landlordName, getWorldName(), getPrice());
|
||||
}
|
||||
if(r != null && !r.transactionSuccess()) {
|
||||
AreaShop.warn("Something went wrong with paying '" + landlordName + "' " + getFormattedPrice() + " for his sell of region " + getName() + " to " + offlinePlayer.getName());
|
||||
}
|
||||
}
|
||||
|
||||
// Set the owner
|
||||
setBuyer(offlinePlayer.getUniqueId());
|
||||
updateLastActiveTime();
|
||||
|
||||
// Send message to the player
|
||||
message(offlinePlayer, "buy-succes");
|
||||
|
||||
// Update everything
|
||||
handleSchematicEvent(RegionEvent.BOUGHT);
|
||||
|
||||
// Notify about updates
|
||||
this.notifyAndUpdate(new BoughtRegionEvent(this));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sell a buyed region, get part of the money back.
|
||||
* @param giveMoneyBack true if the player should be given money back, otherwise false
|
||||
* @param executor CommandSender to receive a message when the sell fails, or null
|
||||
* @return true if the region has been sold, otherwise false
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean sell(boolean giveMoneyBack, CommandSender executor) {
|
||||
boolean own = executor instanceof Player player && this.isBuyer(player);
|
||||
if(executor != null) {
|
||||
if(!executor.hasPermission("areashop.sell") && !own) {
|
||||
message(executor, "sell-noPermissionOther");
|
||||
return false;
|
||||
}
|
||||
if(!executor.hasPermission("areashop.sell") && !executor.hasPermission("areashop.sellown") && own) {
|
||||
message(executor, "sell-noPermission");
|
||||
return false;
|
||||
}
|
||||
if(!executor.hasPermission("areashop.sell")
|
||||
&& executor.hasPermission("areashop.sellown")
|
||||
&& own
|
||||
&& getBooleanSetting("buy.sellDisabled")) {
|
||||
message(executor, "sell-disabled");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(economy == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Broadcast and check event
|
||||
SellingRegionEvent event = new SellingRegionEvent(this);
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
if(event.isCancelled()) {
|
||||
message(executor, "general-cancelled", event.getReason());
|
||||
return false;
|
||||
}
|
||||
|
||||
disableReselling();
|
||||
// Give part of the buying price back
|
||||
double moneyBack = getMoneyBackAmount();
|
||||
if(moneyBack > 0 && giveMoneyBack) {
|
||||
boolean noPayBack = false;
|
||||
OfflinePlayer landlordPlayer = null;
|
||||
if(getLandlord() != null) {
|
||||
landlordPlayer = Bukkit.getOfflinePlayer(getLandlord());
|
||||
}
|
||||
String landlordName = getLandlordName();
|
||||
EconomyResponse r;
|
||||
if(landlordName != null) {
|
||||
if(landlordPlayer != null && landlordPlayer.getName() != null) {
|
||||
r = economy.withdrawPlayer(landlordPlayer, getWorldName(), moneyBack);
|
||||
} else {
|
||||
r = economy.withdrawPlayer(landlordName, getWorldName(), moneyBack);
|
||||
}
|
||||
if(r == null || !r.transactionSuccess()) {
|
||||
noPayBack = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Give back the money
|
||||
OfflinePlayer player = Bukkit.getOfflinePlayer(getBuyer());
|
||||
if(player.hasPlayedBefore() && !noPayBack) {
|
||||
EconomyResponse response = null;
|
||||
boolean error = false;
|
||||
try {
|
||||
if(player.getName() != null) {
|
||||
response = economy.depositPlayer(player, getWorldName(), moneyBack);
|
||||
} else if(getPlayerName() != null) {
|
||||
response = economy.depositPlayer(getPlayerName(), getWorldName(), moneyBack);
|
||||
}
|
||||
} catch(Exception e) {
|
||||
error = true;
|
||||
}
|
||||
if(error || response == null || !response.transactionSuccess()) {
|
||||
AreaShop.warn("Something went wrong with paying back money to " + getPlayerName() + " while selling region " + getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle schematic save/restore (while %uuid% is still available)
|
||||
handleSchematicEvent(RegionEvent.SOLD);
|
||||
|
||||
// Send message: before actual removal of the buyer so that it is still available for variables
|
||||
message(executor, "sell-sold");
|
||||
|
||||
// Remove friends and the owner
|
||||
getFriendsFeature().clearFriends();
|
||||
UUID oldBuyer = getBuyer();
|
||||
setBuyer(null);
|
||||
removeLastActiveTime();
|
||||
|
||||
// Notify about updates
|
||||
this.notifyAndUpdate(new SoldRegionEvent(this, oldBuyer, Math.max(moneyBack, 0)));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkInactive() {
|
||||
if(isDeleted() || !isSold()) {
|
||||
return false;
|
||||
}
|
||||
long inactiveSetting = getInactiveTimeUntilSell();
|
||||
OfflinePlayer player = Bukkit.getOfflinePlayer(getBuyer());
|
||||
if(inactiveSetting <= 0 || player.isOp()) {
|
||||
return false;
|
||||
}
|
||||
long lastPlayed = getLastActiveTime();
|
||||
//AreaShop.debug("currentTime=" + Calendar.getInstance().getTimeInMillis() + ", getLastPlayed()=" + lastPlayed + ", timeInactive=" + (Calendar.getInstance().getTimeInMillis()-player.getLastPlayed()) + ", inactiveSetting=" + inactiveSetting);
|
||||
if(Calendar.getInstance().getTimeInMillis() > (lastPlayed + inactiveSetting)) {
|
||||
AreaShop.info("Region " + getName() + " unrented because of inactivity for player " + getPlayerName());
|
||||
AreaShop.debug("currentTime=" + Calendar.getInstance().getTimeInMillis() + ", getLastPlayed()=" + lastPlayed + ", timeInactive=" + (Calendar.getInstance().getTimeInMillis() - player.getLastPlayed()) + ", inactiveSetting=" + inactiveSetting);
|
||||
return this.sell(true, null);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
Loaded 100 of 178 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user