Compare commits
1121
Commits
5.5
..
commandbook-3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
494d9bec4e | ||
|
|
b835ee39d5 | ||
|
|
4a7552e6be | ||
|
|
c6c0fc9d74 | ||
|
|
f43a4eaad8 | ||
|
|
abfa5cb6a5 | ||
|
|
05f7d68705 | ||
|
|
9adac4f239 | ||
|
|
c5355adb4b | ||
|
|
fb37342b3c | ||
|
|
1fd94a3655 | ||
|
|
c413cf4123 | ||
|
|
87162acf11 | ||
|
|
2c14acc28c | ||
|
|
26477406f1 | ||
|
|
121b34ecb9 | ||
|
|
3ebaaf9c8b | ||
|
|
4c9812db04 | ||
|
|
e792dd6f98 | ||
|
|
d410e1f84e | ||
|
|
d07f95952d | ||
|
|
cb9ab3a7b2 | ||
|
|
1c3cf02ebd | ||
|
|
fc0f7acab5 | ||
|
|
20db92541b | ||
|
|
5fca3b3c3d | ||
|
|
c633a2d070 | ||
|
|
effbd62e68 | ||
|
|
056eaa6587 | ||
|
|
cb2c0870ec | ||
|
|
179c324c80 | ||
|
|
96d15d6dbf | ||
|
|
120d2e223d | ||
|
|
70ea6bad6e | ||
|
|
e59d61e1cf | ||
|
|
bbed280f62 | ||
|
|
f165ae3d95 | ||
|
|
124898ec91 | ||
|
|
ba32d24363 | ||
|
|
0bba822295 | ||
|
|
7538af2686 | ||
|
|
48922118b1 | ||
|
|
14fe2d0e79 | ||
|
|
11a1ac6742 | ||
|
|
c5bfdcb0e6 | ||
|
|
93dae282b2 | ||
|
|
3468e3d47e | ||
|
|
b7ad0257b7 | ||
|
|
070f6e005f | ||
|
|
cc3f4d4d44 | ||
|
|
21e65be110 | ||
|
|
61494fd76e | ||
|
|
556b638d04 | ||
|
|
825b3a3f36 | ||
|
|
afe042ef4d | ||
|
|
4044e2b122 | ||
|
|
aa4137822f | ||
|
|
f37acd3de6 | ||
|
|
b0e4cf148b | ||
|
|
248ffd0ba8 | ||
|
|
3272759f25 | ||
|
|
456a16591b | ||
|
|
79f6635b8a | ||
|
|
1f362bef59 | ||
|
|
63209d1174 | ||
|
|
f546700189 | ||
|
|
35e0db36d3 | ||
|
|
ab7751e046 | ||
|
|
a9cd23c6ef | ||
|
|
8ca01b37a4 | ||
|
|
aa8997aeca | ||
|
|
b757fcc88b | ||
|
|
7593e1a01c | ||
|
|
af3eb85962 | ||
|
|
aabb0b2345 | ||
|
|
6d25513739 | ||
|
|
96b61743b9 | ||
|
|
ff7209a58b | ||
|
|
fe4f0cfc49 | ||
|
|
9cf1e02506 | ||
|
|
b0f8852198 | ||
|
|
cce9c39e01 | ||
|
|
11c95861f9 | ||
|
|
75bb0adbe6 | ||
|
|
32ec74aed7 | ||
|
|
b152cdc4ec | ||
|
|
d019e43a81 | ||
|
|
8c778ed861 | ||
|
|
1b842204e9 | ||
|
|
8aa4c25186 | ||
|
|
026361ae0b | ||
|
|
426a709e43 | ||
|
|
903a831248 | ||
|
|
1792bcb18a | ||
|
|
23ab79c999 | ||
|
|
a29afe8cc1 | ||
|
|
029f867a41 | ||
|
|
ce35798f67 | ||
|
|
0f989fc1b4 | ||
|
|
4871752f49 | ||
|
|
c4b31cf085 | ||
|
|
6e30f98322 | ||
|
|
4b320ab733 | ||
|
|
f516999087 | ||
|
|
2b854f0d72 | ||
|
|
36d25c08c6 | ||
|
|
3e899a70c4 | ||
|
|
d6c2504bbf | ||
|
|
f2d2f47394 | ||
|
|
aefebf32c2 | ||
|
|
7102f6204c | ||
|
|
d542ba78ff | ||
|
|
e7ef6af012 | ||
|
|
1ffa4b48b8 | ||
|
|
d4c49a7539 | ||
|
|
2e2be7092d | ||
|
|
ec4c53da77 | ||
|
|
024a51549d | ||
|
|
8c345cb64b | ||
|
|
461f3e1faf | ||
|
|
6fd7190ff2 | ||
|
|
5180673878 | ||
|
|
c57dd20f24 | ||
|
|
71df9c0011 | ||
|
|
b27f18788c | ||
|
|
18365bbe42 | ||
|
|
82451595cb | ||
|
|
c516eb2174 | ||
|
|
7199b8e70f | ||
|
|
fc4c67ff29 | ||
|
|
d9bb321f83 | ||
|
|
7692e30721 | ||
|
|
5f88bef5ac | ||
|
|
5b0bfd50d3 | ||
|
|
5c0be800ae | ||
|
|
ac505f0064 | ||
|
|
2aee42cbf2 | ||
|
|
5c8b6d3f95 | ||
|
|
eab7b5c47f | ||
|
|
36eba9c9dd | ||
|
|
3b8b67da84 | ||
|
|
d9b09ab7f1 | ||
|
|
50e62bd0e7 | ||
|
|
abfe3a2eb9 | ||
|
|
e94af1d77e | ||
|
|
1dbd25d15e | ||
|
|
c3675a10a2 | ||
|
|
ef2783f30a | ||
|
|
2c2b475513 | ||
|
|
0ebb4e0ffa | ||
|
|
47fb9bd30d | ||
|
|
5ffade9787 | ||
|
|
ca92464cca | ||
|
|
453740b56a | ||
|
|
397a71a602 | ||
|
|
44c4e5816f | ||
|
|
41268ca443 | ||
|
|
c7ed49388c | ||
|
|
874e429779 | ||
|
|
9c5eee90da | ||
|
|
4f088e5bf0 | ||
|
|
c2f96c9587 | ||
|
|
c181a86fd1 | ||
|
|
e2ffab5ee8 | ||
|
|
8a3f066023 | ||
|
|
c53ed56b3a | ||
|
|
6144ca82ac | ||
|
|
d091cb578f | ||
|
|
b2fe4c9c71 | ||
|
|
ea47e93323 | ||
|
|
10100bd194 | ||
|
|
91687dc204 | ||
|
|
e091a59063 | ||
|
|
ee7dc27283 | ||
|
|
54c3cdad77 | ||
|
|
ff37cc7935 | ||
|
|
b6e2bca5bc | ||
|
|
1f85a53117 | ||
|
|
bd4726f887 | ||
|
|
9ea2312751 | ||
|
|
cc988c0b5a | ||
|
|
af93530dbe | ||
|
|
43d8cf8cba | ||
|
|
090a00d6d8 | ||
|
|
a233be1df8 | ||
|
|
f9339e144e | ||
|
|
1f1e6eedf6 | ||
|
|
96e7c43f56 | ||
|
|
f8e129f33e | ||
|
|
144c31645c | ||
|
|
d24157e693 | ||
|
|
d5dddba8bc | ||
|
|
72a392aca2 | ||
|
|
c6442e6669 | ||
|
|
0102dbb9bc | ||
|
|
3f7a9f9bc8 | ||
|
|
ae51d74afb | ||
|
|
e51a22032e | ||
|
|
84017bffc4 | ||
|
|
60731f9836 | ||
|
|
3ea7c9fc08 | ||
|
|
9804c69044 | ||
|
|
cd39387e7f | ||
|
|
b48e145508 | ||
|
|
405b210fb5 | ||
|
|
d4d7601125 | ||
|
|
fdd9064170 | ||
|
|
803c2055c3 | ||
|
|
344c6cf814 | ||
|
|
863f6cc13b | ||
|
|
3dd35dabec | ||
|
|
80aec378d8 | ||
|
|
6dbd731c92 | ||
|
|
aea129889c | ||
|
|
2757a001c0 | ||
|
|
693314c7f7 | ||
|
|
db35c908ba | ||
|
|
14ce7d1be2 | ||
|
|
015f192193 | ||
|
|
83b375b6e1 | ||
|
|
91696533cf | ||
|
|
0dc5781326 | ||
|
|
5ad21521be | ||
|
|
e0b91e9529 | ||
|
|
7e0ff24c57 | ||
|
|
be426e92df | ||
|
|
a6261b9071 | ||
|
|
f235e870a7 | ||
|
|
a26eb87603 | ||
|
|
7fb7d59856 | ||
|
|
01dfebe531 | ||
|
|
87e5770405 | ||
|
|
d3c4681c49 | ||
|
|
e43daa726a | ||
|
|
8e819f7a82 | ||
|
|
ee4259b88d | ||
|
|
8771173146 | ||
|
|
d28a31f255 | ||
|
|
b4bda6bfaf | ||
|
|
44e3f720de | ||
|
|
7f47e31686 | ||
|
|
b2e64498a8 | ||
|
|
e31fa306ab | ||
|
|
1123270a07 | ||
|
|
b850b5caf8 | ||
|
|
ba61919168 | ||
|
|
34efb6e40e | ||
|
|
3203a81710 | ||
|
|
d8dba47c0f | ||
|
|
a6cfe7d0c9 | ||
|
|
f19d2ee73d | ||
|
|
bd89bd9d2f | ||
|
|
66eb8fa553 | ||
|
|
dcdd0497d8 | ||
|
|
8ac5f8f6f2 | ||
|
|
45a4e59965 | ||
|
|
43ed630034 | ||
|
|
3189b1ac13 | ||
|
|
e94083045f | ||
|
|
acce59edd4 | ||
|
|
bb29883fe0 | ||
|
|
e7ff99ae96 | ||
|
|
b10cf6adbc | ||
|
|
2e8d14c995 | ||
|
|
89db0d9fee | ||
|
|
6c5319f355 | ||
|
|
8eeab682db | ||
|
|
2ae6f39a09 | ||
|
|
d2c52f7c1b | ||
|
|
3a332fd87d | ||
|
|
0f72811bfc | ||
|
|
95b88ea64b | ||
|
|
f76259df82 | ||
|
|
3a8e3e84b8 | ||
|
|
84bc322de7 | ||
|
|
129bbd8ea1 | ||
|
|
4dc6e27660 | ||
|
|
4cb29796c1 | ||
|
|
85693b91b3 | ||
|
|
1c29e85f19 | ||
|
|
e019890f1d | ||
|
|
fb90b1446f | ||
|
|
22ef224a81 | ||
|
|
c0f3171a33 | ||
|
|
67ece5c5d7 | ||
|
|
46cca2b950 | ||
|
|
6e56763a7f | ||
|
|
f147402d30 | ||
|
|
8e35db0f35 | ||
|
|
9b2eff0a71 | ||
|
|
104cdc023d | ||
|
|
deb283c44b | ||
|
|
324e90c68a | ||
|
|
c60502ffd8 | ||
|
|
26e59955ed | ||
|
|
4746e95249 | ||
|
|
9cafb07e4d | ||
|
|
b2b0fe65c6 | ||
|
|
06e6ce589b | ||
|
|
12fc1438c2 | ||
|
|
e5e1f71a2a | ||
|
|
2aaa14261b | ||
|
|
f006a9584c | ||
|
|
03cf9a668b | ||
|
|
db70e6f346 | ||
|
|
e0df194ff2 | ||
|
|
ab55137f59 | ||
|
|
bbb79526b2 | ||
|
|
cde9a403f7 | ||
|
|
43a9228304 | ||
|
|
c1b8d12d05 | ||
|
|
a25674e9a5 | ||
|
|
778ec404ff | ||
|
|
4ab38e5b89 | ||
|
|
8b842e3a0d | ||
|
|
e38d98da00 | ||
|
|
5c9ba2e22e | ||
|
|
e9ecb6d2a8 | ||
|
|
f5a554f4a4 | ||
|
|
53aadca45b | ||
|
|
6c3dd4234d | ||
|
|
5bd2125963 | ||
|
|
8765bbb192 | ||
|
|
53e8b780bc | ||
|
|
0e252e41b2 | ||
|
|
15a9c50ea4 | ||
|
|
d3acbdf382 | ||
|
|
4239bdc96d | ||
|
|
43a5bf1638 | ||
|
|
a8591e536a | ||
|
|
38dcdff0b6 | ||
|
|
65e48d17d4 | ||
|
|
c9b8e9f6a2 | ||
|
|
93d454c675 | ||
|
|
ca4bb7a53d | ||
|
|
c2054615db | ||
|
|
6db2df4e29 | ||
|
|
536132a250 | ||
|
|
7c3b1ad20f | ||
|
|
729f66afdf | ||
|
|
a7c2026414 | ||
|
|
9222b3d364 | ||
|
|
adcc41413d | ||
|
|
ec08d7d73a | ||
|
|
3d5ee7b571 | ||
|
|
32341393fe | ||
|
|
0fcd42fdd5 | ||
|
|
e28b236a52 | ||
|
|
96e0ffd293 | ||
|
|
0ddc011a3c | ||
|
|
d320356045 | ||
|
|
95bf6bc9b2 | ||
|
|
1c4c213ed7 | ||
|
|
c9eaec0ae8 | ||
|
|
fc0be7db09 | ||
|
|
dbbc31a4f4 | ||
|
|
0f3e893aaf | ||
|
|
aa668916e4 | ||
|
|
a426d2a42c | ||
|
|
5ff8b37ae8 | ||
|
|
2d28e8db6d | ||
|
|
463a356020 | ||
|
|
21d13cc72c | ||
|
|
9cf85caf3c | ||
|
|
2f1343f408 | ||
|
|
3cb6c4e46f | ||
|
|
7f9b850288 | ||
|
|
e8d4f2fd84 | ||
|
|
f3891aaaf9 | ||
|
|
ea75549a29 | ||
|
|
fbd8206038 | ||
|
|
522ac459db | ||
|
|
255dd2d41a | ||
|
|
cf1716ff37 | ||
|
|
a277e69e9c | ||
|
|
ec5bb32510 | ||
|
|
8ddb7d4b99 | ||
|
|
3258bff2d1 | ||
|
|
8d7d32a2d2 | ||
|
|
a907eb2348 | ||
|
|
32132b5b0a | ||
|
|
c0c7c3215e | ||
|
|
ddf0f41061 | ||
|
|
d3ecbcb18a | ||
|
|
b7f4262978 | ||
|
|
60e6f92c64 | ||
|
|
98af7966cd | ||
|
|
99d042d260 | ||
|
|
c9d6166fcb | ||
|
|
752ccec150 | ||
|
|
91ccb95672 | ||
|
|
4caff457d3 | ||
|
|
a1a6ee7107 | ||
|
|
af157b88bd | ||
|
|
ea4f4c088b | ||
|
|
6559ed5c1a | ||
|
|
deddcf8dd2 | ||
|
|
dfe536a2d2 | ||
|
|
5bfb348354 | ||
|
|
afcf93b7b1 | ||
|
|
e1843624bb | ||
|
|
0f4e7b5061 | ||
|
|
869ead63bc | ||
|
|
6a6de7802b | ||
|
|
b50302d9d0 | ||
|
|
c841d74aaf | ||
|
|
09cce39aff | ||
|
|
e5b76a571b | ||
|
|
7c58fa4be6 | ||
|
|
f150a41d72 | ||
|
|
bca1c2bdb3 | ||
|
|
47a8bcc442 | ||
|
|
83cad75916 | ||
|
|
6b5a12105e | ||
|
|
451b679323 | ||
|
|
66a8bfd5b1 | ||
|
|
2a2b2f6f64 | ||
|
|
73dea11de2 | ||
|
|
9998a6c930 | ||
|
|
5111d40aaf | ||
|
|
972ccaed7e | ||
|
|
f7d36bc1f3 | ||
|
|
8073945af0 | ||
|
|
91353d6b01 | ||
|
|
bfbcc8dcf8 | ||
|
|
8f65798141 | ||
|
|
fdddb17d2f | ||
|
|
520f9e3fcf | ||
|
|
a3d2a1b127 | ||
|
|
7ecf73165b | ||
|
|
e90a7ed075 | ||
|
|
aae521b727 | ||
|
|
643345b459 | ||
|
|
a62d9f5617 | ||
|
|
2f3f76c8cf | ||
|
|
a03aaa45b1 | ||
|
|
372155b5c3 | ||
|
|
159de771bf | ||
|
|
41d922cb27 | ||
|
|
6a4fac63e8 | ||
|
|
3daf8db113 | ||
|
|
9c62a35e07 | ||
|
|
931f438b14 | ||
|
|
3109612c1b | ||
|
|
e4d63ffbcc | ||
|
|
866a554d30 | ||
|
|
ab2811ed2d | ||
|
|
8cc7bcc849 | ||
|
|
547e89b85d | ||
|
|
477f1188df | ||
|
|
d9e4b27cd2 | ||
|
|
37f39eaf66 | ||
|
|
223d22e79f | ||
|
|
04214a96eb | ||
|
|
f40cb69f38 | ||
|
|
6c1489d434 | ||
|
|
6fe63838f5 | ||
|
|
d883c22d64 | ||
|
|
3bd1c869f1 | ||
|
|
e7273aaf6f | ||
|
|
6e02f80f6c | ||
|
|
01276dfc62 | ||
|
|
f516fd5e54 | ||
|
|
79612915a7 | ||
|
|
f04f9093bc | ||
|
|
9dac950faf | ||
|
|
f2a8ff3f64 | ||
|
|
b78317dd42 | ||
|
|
048dd25099 | ||
|
|
0900289437 | ||
|
|
d8dd86dfe8 | ||
|
|
9a569d7ed8 | ||
|
|
53132ce83a | ||
|
|
c3bdc33215 | ||
|
|
c6bf8ceb5c | ||
|
|
792d041078 | ||
|
|
cb965c9bf9 | ||
|
|
f33889b88f | ||
|
|
e747e3a3fa | ||
|
|
fd460337f4 | ||
|
|
38c9479385 | ||
|
|
da032cb04e | ||
|
|
37a80338f5 | ||
|
|
8a5f233e84 | ||
|
|
e3a9131929 | ||
|
|
bab98d5463 | ||
|
|
4333b39377 | ||
|
|
8bd427a6ab | ||
|
|
d3493a3361 | ||
|
|
51982cda28 | ||
|
|
a2e14bc76a | ||
|
|
c050d274f5 | ||
|
|
bdff22cbac | ||
|
|
7da10198e3 | ||
|
|
b11e2b3d11 | ||
|
|
c95b619974 | ||
|
|
e61b2e18c1 | ||
|
|
e9d64dbf03 | ||
|
|
3c8121d088 | ||
|
|
93ced5ca7a | ||
|
|
7580583fbf | ||
|
|
41c68664d7 | ||
|
|
c8393cdcec | ||
|
|
42d12e4fa8 | ||
|
|
bed9bd77a6 | ||
|
|
f3c2390fbb | ||
|
|
83a7ed58a5 | ||
|
|
ddc1f77825 | ||
|
|
88169236cb | ||
|
|
0cb36b3b8b | ||
|
|
ce169461a3 | ||
|
|
18ec3db1bb | ||
|
|
53fdff1d9b | ||
|
|
9a91336958 | ||
|
|
7bd69bebf4 | ||
|
|
57b6f04b79 | ||
|
|
c7442c2a9e | ||
|
|
df985013eb | ||
|
|
41f520845a | ||
|
|
dac09c64c8 | ||
|
|
a2defe5971 | ||
|
|
ba4e5d6ea9 | ||
|
|
25f12e9733 | ||
|
|
ca37dc0fc6 | ||
|
|
7d41835794 | ||
|
|
b37014463f | ||
|
|
2b94883e70 | ||
|
|
5c7468ffb5 | ||
|
|
343632cbf2 | ||
|
|
2a3ccec429 | ||
|
|
d6f12804ea | ||
|
|
f858c175f9 | ||
|
|
cdab004505 | ||
|
|
59bd11e742 | ||
|
|
2e6faff8c1 | ||
|
|
722cc2e38c | ||
|
|
669c0e9651 | ||
|
|
d2252c6142 | ||
|
|
eab4101d1c | ||
|
|
db31c35d8e | ||
|
|
125595e6b9 | ||
|
|
6d5d9934cc | ||
|
|
bd2a8daad3 | ||
|
|
c4b3c1d033 | ||
|
|
eb051bc194 | ||
|
|
1a12faf5ab | ||
|
|
73fe9cd62f | ||
|
|
7ab4a283fe | ||
|
|
46138c9abe | ||
|
|
841cc8e033 | ||
|
|
cb0844c64d | ||
|
|
6e8e59aee5 | ||
|
|
358eebf96b | ||
|
|
01892b609f | ||
|
|
096981bd27 | ||
|
|
0852fc0d65 | ||
|
|
40ceb3d0b8 | ||
|
|
b52a6bd6d6 | ||
|
|
992e53856d | ||
|
|
f776d15e03 | ||
|
|
438bc59fbc | ||
|
|
453f253e77 | ||
|
|
550df20f18 | ||
|
|
e8ee0a8c5b | ||
|
|
5fcd7ddf7a | ||
|
|
b11d416035 | ||
|
|
f7e216ba84 | ||
|
|
f6406b668c | ||
|
|
7cd4a1d411 | ||
|
|
bd558bb527 | ||
|
|
8d29f6971a | ||
|
|
300f69597f | ||
|
|
8e320b6dbe | ||
|
|
fa422bef32 | ||
|
|
e8cd1cc253 | ||
|
|
5e9ffe9e29 | ||
|
|
edebb0efc9 | ||
|
|
913d5d64ae | ||
|
|
6da8fabb1f | ||
|
|
ee022d7cd7 | ||
|
|
c126a0ac38 | ||
|
|
4a3dac0aa4 | ||
|
|
f4700ded12 | ||
|
|
8570921049 | ||
|
|
612b953b63 | ||
|
|
02777c370d | ||
|
|
7a8ab1df99 | ||
|
|
182c5f6a17 | ||
|
|
7c7673af20 | ||
|
|
9282fc25de | ||
|
|
f66e47c01f | ||
|
|
f00d73d60e | ||
|
|
c5b08781f7 | ||
|
|
4b80c4e4e6 | ||
|
|
7da3cc224b | ||
|
|
0659a5263a | ||
|
|
0f8614519f | ||
|
|
541f828db4 | ||
|
|
70aedb4a84 | ||
|
|
4f24f2631e | ||
|
|
ddb910e2ea | ||
|
|
b5c4eb3587 | ||
|
|
a0553bfa34 | ||
|
|
241f053b8a | ||
|
|
6174c9e486 | ||
|
|
d7629acb61 | ||
|
|
8169b6f650 | ||
|
|
7b174683ba | ||
|
|
88e7327af6 | ||
|
|
b7d8562ece | ||
|
|
439826ddc6 | ||
|
|
b94641f1b5 | ||
|
|
0ddf56f7f6 | ||
|
|
74e64d0641 | ||
|
|
858b0b2c1c | ||
|
|
54237c0038 | ||
|
|
0edb948a40 | ||
|
|
f85aeecde7 | ||
|
|
69a0f26a52 | ||
|
|
8bb28b5ef1 | ||
|
|
a6118c3aa4 | ||
|
|
59494233e3 | ||
|
|
d0ff1815aa | ||
|
|
9b7970475a | ||
|
|
88c0bdfffb | ||
|
|
b43bc4a57a | ||
|
|
bd8e1a35f6 | ||
|
|
722dabcf1a | ||
|
|
09207367c0 | ||
|
|
3336b73536 | ||
|
|
0d7e3ad2de | ||
|
|
95d1bd8ee0 | ||
|
|
6c97e04c7c | ||
|
|
24f72cb07f | ||
|
|
ef56a32f00 | ||
|
|
d8da89703b | ||
|
|
e47c563ced | ||
|
|
bd0917d34b | ||
|
|
8098211d01 | ||
|
|
83c95bbb8c | ||
|
|
4d4e1c6c26 | ||
|
|
3045dc0293 | ||
|
|
e649973318 | ||
|
|
2d147bb7e1 | ||
|
|
f57afb2944 | ||
|
|
95052546a5 | ||
|
|
768532cb8b | ||
|
|
6b7e1286f2 | ||
|
|
577cfd0954 | ||
|
|
06df4585c2 | ||
|
|
416006dbde | ||
|
|
5ff9f5c175 | ||
|
|
fa14184eb4 | ||
|
|
d29f66563b | ||
|
|
53957e7b26 | ||
|
|
2c81cb2f84 | ||
|
|
711fe7ad2f | ||
|
|
f6f94571ea | ||
|
|
985629c196 | ||
|
|
bb64079d17 | ||
|
|
c3363f0d70 | ||
|
|
937a5758f7 | ||
|
|
bb1826bdb1 | ||
|
|
1a781fc5b0 | ||
|
|
039d174477 | ||
|
|
929f9e99cd | ||
|
|
ae8bf63c86 | ||
|
|
3eb5c65a3d | ||
|
|
095f2aa67e | ||
|
|
0f10e89f7c | ||
|
|
3a2b453e3f | ||
|
|
c43a24d78f | ||
|
|
d43eb3bc34 | ||
|
|
3ca147e405 | ||
|
|
41fb8a0722 | ||
|
|
ff3fa759d1 | ||
|
|
cab42af53b | ||
|
|
d9d665ab14 | ||
|
|
fac6ebef40 | ||
|
|
a4fd29c30c | ||
|
|
59c7197229 | ||
|
|
e7c9703ced | ||
|
|
5a63115fb2 | ||
|
|
4597849466 | ||
|
|
a35aaf9659 | ||
|
|
bfb3f9e840 | ||
|
|
91e34601ec | ||
|
|
7481acba8c | ||
|
|
4d43ef5305 | ||
|
|
b1fb143fd4 | ||
|
|
d07e81288a | ||
|
|
c0d4ba5c6c | ||
|
|
8a11752253 | ||
|
|
1d24be8c34 | ||
|
|
d3f3489c7e | ||
|
|
3f16fef57e | ||
|
|
608d782321 | ||
|
|
5d6dad4c6d | ||
|
|
28c538e981 | ||
|
|
a35cb9277e | ||
|
|
e43ce420a3 | ||
|
|
501a7aa77a | ||
|
|
76f7ac8d8e | ||
|
|
518d5958c9 | ||
|
|
7e25de38da | ||
|
|
bf8ef39871 | ||
|
|
cd62af698b | ||
|
|
709ce9eb08 | ||
|
|
e24d7ccb10 | ||
|
|
98bbd900cb | ||
|
|
19b87b628a | ||
|
|
dc2652f87b | ||
|
|
99660920d7 | ||
|
|
ad1c10a3e9 | ||
|
|
5b685e71d3 | ||
|
|
5ddc4b9251 | ||
|
|
38587a1c61 | ||
|
|
eb23e28c16 | ||
|
|
4379c7e989 | ||
|
|
989ce82c5d | ||
|
|
f92e55e061 | ||
|
|
0fc3d21b90 | ||
|
|
26d3645f86 | ||
|
|
110aa2e56b | ||
|
|
05369b69b6 | ||
|
|
4a501a49db | ||
|
|
2a69d1c7c9 | ||
|
|
573204caad | ||
|
|
7a01168781 | ||
|
|
b5dfed9e01 | ||
|
|
29f804b9f0 | ||
|
|
504fceceeb | ||
|
|
9a852f4cbe | ||
|
|
fafd3aba6a | ||
|
|
d87a335e85 | ||
|
|
471b4496c9 | ||
|
|
32e39f5c7c | ||
|
|
bf48361b10 | ||
|
|
387431c9c7 | ||
|
|
9b69c07663 | ||
|
|
a1d59373ac | ||
|
|
81a727fe7f | ||
|
|
189fd15498 | ||
|
|
1a602f2f8a | ||
|
|
7986238936 | ||
|
|
a2fc9c94fd | ||
|
|
51f98c9eb7 | ||
|
|
418b8ff6a7 | ||
|
|
9cab51dac8 | ||
|
|
26ac987024 | ||
|
|
e44875532d | ||
|
|
956d1b4248 | ||
|
|
3aa8bbe947 | ||
|
|
f46b1cb138 | ||
|
|
5b5022b0b8 | ||
|
|
d93c7fa09d | ||
|
|
2c1d1ef0a3 | ||
|
|
bf97e41697 | ||
|
|
c0852d63fe | ||
|
|
acc39e11b1 | ||
|
|
b4880ae982 | ||
|
|
1a1acae588 | ||
|
|
1581390092 | ||
|
|
cd221ea19c | ||
|
|
abeab91be4 | ||
|
|
227f54d315 | ||
|
|
ac88367f6c | ||
|
|
f788f0e0d9 | ||
|
|
9a4bc70cdd | ||
|
|
ab46fd6244 | ||
|
|
6deafa660d | ||
|
|
0d2adc5707 | ||
|
|
b0ed119585 | ||
|
|
ff2462b084 | ||
|
|
894a42ea13 | ||
|
|
d827e01760 | ||
|
|
5e6de8b76d | ||
|
|
b298bedea0 | ||
|
|
fb5ae838d9 | ||
|
|
3bfcd69fd9 | ||
|
|
c66adf0119 | ||
|
|
2119b274fd | ||
|
|
22f45c45ee | ||
|
|
0dd9729b35 | ||
|
|
ff46c2cf54 | ||
|
|
1537fc879e | ||
|
|
f00352cde0 | ||
|
|
fdc74b1c0d | ||
|
|
83a3c61b66 | ||
|
|
4422d536b7 | ||
|
|
1f40908c04 | ||
|
|
b707289284 | ||
|
|
43486bda63 | ||
|
|
7086a1d0d2 | ||
|
|
4dd13bd925 | ||
|
|
4ce97bca0e | ||
|
|
ec9712f30e | ||
|
|
0162910964 | ||
|
|
c252a79c1a | ||
|
|
89739d4efe | ||
|
|
9c7fb6a1d3 | ||
|
|
2df3290d38 | ||
|
|
4805df2f03 | ||
|
|
5bc670db8b | ||
|
|
ffda88f193 | ||
|
|
96a69aa2ef | ||
|
|
2d90fddbee | ||
|
|
bbd1a0ef10 | ||
|
|
6b16ed79b3 | ||
|
|
73b9a7fb0d | ||
|
|
4a0ae833f0 | ||
|
|
5f32ebe2de | ||
|
|
723928d239 | ||
|
|
d024ed7b81 | ||
|
|
ec4143d3dc | ||
|
|
071fdaabd3 | ||
|
|
23766f20dd | ||
|
|
31739c647b | ||
|
|
faa016180a | ||
|
|
e26238e814 | ||
|
|
f8ed1a3e3e | ||
|
|
d47c255168 | ||
|
|
d1e7796f81 | ||
|
|
1095064c5e | ||
|
|
a15c9d289b | ||
|
|
c0f95bebf0 | ||
|
|
0a54779fc4 | ||
|
|
ac525958c5 | ||
|
|
458cf64501 | ||
|
|
4acef77623 | ||
|
|
d38d7fc492 | ||
|
|
2510c3eeb5 | ||
|
|
326d53fd09 | ||
|
|
75b3082b12 | ||
|
|
1f214aadee | ||
|
|
174b3fad15 | ||
|
|
07531f67d4 | ||
|
|
291c45064a | ||
|
|
6f56cb29a5 | ||
|
|
977c7d2f29 | ||
|
|
ecb87efe8d | ||
|
|
a57c162cd8 | ||
|
|
60c3ed4f6b | ||
|
|
714e75eb95 | ||
|
|
636819c801 | ||
|
|
9a6c2e0685 | ||
|
|
736eecc13b | ||
|
|
4718c5dab0 | ||
|
|
7e9bd49da2 | ||
|
|
a0d0ff0b92 | ||
|
|
b41be0c319 | ||
|
|
17a466059e | ||
|
|
2d9e95a63e | ||
|
|
532a45f9e7 | ||
|
|
d61e32ebb5 | ||
|
|
b7d38e94c8 | ||
|
|
ae158742f6 | ||
|
|
c35686f8d1 | ||
|
|
a5b6651582 | ||
|
|
54973fdf82 | ||
|
|
0bee631385 | ||
|
|
6283382837 | ||
|
|
39bb522051 | ||
|
|
bf80d57abe | ||
|
|
865b94006a | ||
|
|
874248f8b5 | ||
|
|
cef7d5bb12 | ||
|
|
2a8131780f | ||
|
|
7094f70f4a | ||
|
|
df5af6129c | ||
|
|
a6888c3767 | ||
|
|
1bd367ddde | ||
|
|
0cf87ae561 | ||
|
|
fa80f5f67f | ||
|
|
7f080f920d | ||
|
|
13658323b4 | ||
|
|
2d440ab5ba | ||
|
|
dc55673691 | ||
|
|
92bb3948a6 | ||
|
|
f67ad6478c | ||
|
|
1d984198ce | ||
|
|
f2ca980771 | ||
|
|
b826697aea | ||
|
|
89430c13ec | ||
|
|
f07acea3e1 | ||
|
|
e9402c55e6 | ||
|
|
2eb6c76da8 | ||
|
|
a34e48a145 | ||
|
|
2d50659b48 | ||
|
|
327ae2b807 | ||
|
|
e831b7facc | ||
|
|
dfb6114584 | ||
|
|
5085841d9d | ||
|
|
7a98944469 | ||
|
|
3d2b455cda | ||
|
|
460d5d0691 | ||
|
|
b5f80351ec | ||
|
|
72a9472a57 | ||
|
|
7eb820c688 | ||
|
|
886b279da6 | ||
|
|
f2d7135fc5 | ||
|
|
d214a859c3 | ||
|
|
d1e221c2b7 | ||
|
|
e0e4207a4d | ||
|
|
4398c781c5 | ||
|
|
3e06000fd9 | ||
|
|
833795ebe1 | ||
|
|
6e270d5ec3 | ||
|
|
09a9bea3a7 | ||
|
|
035ccee2a6 | ||
|
|
17aa2a4153 | ||
|
|
f5bc5c0b47 | ||
|
|
e7a4afde7d | ||
|
|
8758c9b940 | ||
|
|
a569d20779 | ||
|
|
88e01fa083 | ||
|
|
7b435f9283 | ||
|
|
a240e5d128 | ||
|
|
0d0ba31d3a | ||
|
|
e79bb3533d | ||
|
|
f94c4ec831 | ||
|
|
d5afb76105 | ||
|
|
dd7e9ba05e | ||
|
|
ee54698fdb | ||
|
|
955b0e991c | ||
|
|
c1b98b9e40 | ||
|
|
d6939b7916 | ||
|
|
5f0ca37879 | ||
|
|
548bdb7eb5 | ||
|
|
5c85f39228 | ||
|
|
85b2cbc03a | ||
|
|
cc78011da6 | ||
|
|
d016da1895 | ||
|
|
8593f1c80a | ||
|
|
0b3c40dc3e | ||
|
|
2e7ecc59c0 | ||
|
|
942ce95dbf | ||
|
|
03f77d5ab7 | ||
|
|
8dec32fa6a | ||
|
|
8f409d47d9 | ||
|
|
93f062d4e3 | ||
|
|
b8f9ceafbb | ||
|
|
75d07b6dad | ||
|
|
6060a0a430 | ||
|
|
647ba1572c | ||
|
|
051e0cb811 | ||
|
|
b8c9e78910 | ||
|
|
2d7d9c6093 | ||
|
|
0f32f56208 | ||
|
|
5addfd8975 | ||
|
|
7f108ce8f0 | ||
|
|
8c883e1ca8 | ||
|
|
d18fe6ffa0 | ||
|
|
80a8ac9e98 | ||
|
|
671fd58568 | ||
|
|
c4ea3b59f0 | ||
|
|
5d5def206d | ||
|
|
b2ebbb9b55 | ||
|
|
3734c071bf | ||
|
|
b1a419f2a2 | ||
|
|
bf5e292160 | ||
|
|
df57d91270 | ||
|
|
4da1741578 | ||
|
|
7a3774e730 | ||
|
|
e6e21caeea | ||
|
|
200d47ab09 | ||
|
|
ab274151d4 | ||
|
|
aec1e3a529 | ||
|
|
916caa1eb2 | ||
|
|
50b29f8ad6 | ||
|
|
88d662cf27 | ||
|
|
5316130ae8 | ||
|
|
4f36dbc636 | ||
|
|
230a8697bf | ||
|
|
121449b230 | ||
|
|
fede549b51 | ||
|
|
1bdd7f9a6b | ||
|
|
b3f9da67b7 | ||
|
|
1ba7d623b4 | ||
|
|
47902e1177 | ||
|
|
a035bcc671 | ||
|
|
9bcc6b9605 | ||
|
|
282c3a864e | ||
|
|
eb083a8934 | ||
|
|
0fc71ff79e | ||
|
|
68a7455496 | ||
|
|
fcfc3acbb8 | ||
|
|
aa53c0aa6a | ||
|
|
f098905a92 | ||
|
|
eec78092b5 | ||
|
|
34fa5eceb8 | ||
|
|
c32d2dd6f8 | ||
|
|
da80d3536a | ||
|
|
e9361022d2 | ||
|
|
dd0c1a5ab5 | ||
|
|
bb9dff7b8c | ||
|
|
7e419c116e | ||
|
|
2cbc2f5226 | ||
|
|
68b5e3e0a8 | ||
|
|
1502ec12a9 | ||
|
|
6d09b18479 | ||
|
|
08ce207636 | ||
|
|
f199b977eb | ||
|
|
5715e2c835 | ||
|
|
b8642b7ca3 | ||
|
|
2c4d4708d8 | ||
|
|
0edb6e6157 | ||
|
|
4f394b5668 | ||
|
|
9834c30e3a | ||
|
|
f3f1b0870f | ||
|
|
915d314c18 | ||
|
|
02b3ae6aa5 | ||
|
|
f725e73653 | ||
|
|
c5858ef202 | ||
|
|
ba2fd2ca2e | ||
|
|
1075d36748 | ||
|
|
3ee3799e55 | ||
|
|
6654b0a67a | ||
|
|
9577c93edb | ||
|
|
7cd67281bc | ||
|
|
d21c226183 | ||
|
|
4322236b9e | ||
|
|
05e408ee65 | ||
|
|
3d1012ba94 | ||
|
|
94937e41ef | ||
|
|
3957aa83fc | ||
|
|
8aa79d1c4c | ||
|
|
578eeff0e1 | ||
|
|
5f2f1c67f5 | ||
|
|
c92b9c3d97 | ||
|
|
0951d00da3 | ||
|
|
6df9c3660b | ||
|
|
19be2bf96e | ||
|
|
e10ed6ac7a | ||
|
|
479ebf4d89 | ||
|
|
1f1e36e9f7 | ||
|
|
27e634ae03 | ||
|
|
e60b20b37b | ||
|
|
684214ff6a | ||
|
|
ba5be6071f | ||
|
|
6c8d13690e | ||
|
|
3e0b2ef3e4 | ||
|
|
c5304d2775 | ||
|
|
ca95ae04a5 | ||
|
|
1ab9f85ca6 | ||
|
|
01ff1b2f8f | ||
|
|
9b17fe68e7 | ||
|
|
0fed35a80f | ||
|
|
25280c9fa9 | ||
|
|
a98ebfdb21 | ||
|
|
acb1d18654 | ||
|
|
18b5a4e106 | ||
|
|
bab420a359 | ||
|
|
4f14f1f736 | ||
|
|
166831447c | ||
|
|
f2bd5961d0 | ||
|
|
2cc990a530 | ||
|
|
f0e6008563 | ||
|
|
93f19cca0a | ||
|
|
1cbe508f82 | ||
|
|
0c178c3155 | ||
|
|
e67304389d | ||
|
|
ad5b1cdcba | ||
|
|
fe1e09289f | ||
|
|
583ea76e4b | ||
|
|
a7d198893e | ||
|
|
fe62c8d0c5 | ||
|
|
16ce56c1ad | ||
|
|
15f0bfb9db | ||
|
|
22db589742 | ||
|
|
69119e6db7 | ||
|
|
690da2332b | ||
|
|
f2fead1444 | ||
|
|
c4f6267921 | ||
|
|
0dc65d083f | ||
|
|
40c1d93f02 | ||
|
|
2024a93126 | ||
|
|
88d79a42e6 | ||
|
|
b01b2cce9b | ||
|
|
c5b1089c96 | ||
|
|
679e43758b | ||
|
|
90e6e5a96c | ||
|
|
4fb003c4df | ||
|
|
9d5f349a04 | ||
|
|
f4f4a47a7f | ||
|
|
6a3e987668 | ||
|
|
83f943965f | ||
|
|
c9fdff169f | ||
|
|
5454832918 | ||
|
|
3d6d774b17 | ||
|
|
1463547af4 | ||
|
|
0bcf4b3597 | ||
|
|
824e8dcb4b | ||
|
|
4b2f0c8020 | ||
|
|
7fd424cf65 | ||
|
|
5ff2855eb0 | ||
|
|
8c8c162a54 | ||
|
|
37d52f3688 | ||
|
|
f361cbfa71 | ||
|
|
ddefbfe2cf | ||
|
|
10296cb736 | ||
|
|
49dc0599c9 | ||
|
|
14348e170b | ||
|
|
59d1f0d817 | ||
|
|
e024f134a4 | ||
|
|
cf5a5b5b47 | ||
|
|
e957f92496 | ||
|
|
9484bb9941 | ||
|
|
d781f9822f | ||
|
|
7845ef2de4 | ||
|
|
a9d4ecf33d | ||
|
|
6f4a62c7a3 | ||
|
|
6b4f872742 | ||
|
|
ef4f00f8f5 | ||
|
|
a27deb3936 | ||
|
|
18814c7373 | ||
|
|
1d9908e1f6 | ||
|
|
29529e4a06 | ||
|
|
74b1003c4c | ||
|
|
27ffdec323 | ||
|
|
d9e5fc2b60 |
No files matched your search
+2
-2
@@ -1,2 +1,2 @@
|
||||
*.java diff=java
|
||||
|
||||
*.java diff=java
|
||||
|
||||
+13
-2
@@ -1,6 +1,17 @@
|
||||
.classpath
|
||||
.project
|
||||
.settings
|
||||
target
|
||||
.settings/
|
||||
target/
|
||||
|
||||
.DS_Store
|
||||
|
||||
**/*.iml
|
||||
**/.idea
|
||||
|
||||
bin/
|
||||
dependency-reduced-pom.xml
|
||||
*-private.sh
|
||||
|
||||
.gradle/
|
||||
**/build/
|
||||
out/
|
||||
@@ -0,0 +1,8 @@
|
||||
language: java
|
||||
dist: trusty
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
notifications:
|
||||
email: false
|
||||
before_install: chmod +x gradlew
|
||||
script: ./gradlew build -S
|
||||
+915
@@ -0,0 +1,915 @@
|
||||
# Changelog
|
||||
|
||||
## 7.0.1
|
||||
* Add `/rg toggle-bypass` command which temporarily turns off region bypassing until used again.
|
||||
* More improvements to `/rg flag` and `/rg flags` commands.
|
||||
* Fix some checks for adding owners to unclaimed regions.
|
||||
* Fix an issue with time-/weather-lock flags when logging in to a region with the flag set.
|
||||
* Fix cause tracking in vehicles (incl. breaking lilypads in a boat)
|
||||
* Use async teleports on Paper.
|
||||
* Include hopper minecarts in the ignore hoppers config setting.
|
||||
* Add sugar cane and cacti to the crop-growth flag. Bamboo is also included pending Spigot throwing an event for it.
|
||||
* Specifically track when players ignite creepers with flint and steel.
|
||||
* Fix fuzziness when using bonemeal near a protected region.
|
||||
* Fix color codes not applying in greeting, etc flags when placed after a newline (\n).
|
||||
* Add applicable region information to `/wg report`.
|
||||
* Fix pistons flag not applying to sticky pistons pulling blocks.
|
||||
* Add some custom metrics for bStats.
|
||||
* Everything in the RC/beta changelog below.
|
||||
|
||||
## 7.0.1 RC 2 (inc. beta 1)
|
||||
* Due to breaking changes in important Bukkit API, this is not compatible with MC 1.13!
|
||||
* Update to MC 1.14. Adds protection for new blocks, etc.
|
||||
* To allow players to read from lecterns, but not take the book, flag interact allow, and then flag chest-access -g nonmembers deny.
|
||||
* Add ravager-grief flag.
|
||||
* Fix overprotection of unsaddled pigs with the ride flag.
|
||||
* Fix lava fire defaulting to off (won't change existing configs).
|
||||
* Fix damaged/chipped anvils not respecting use flag like regular anvils.
|
||||
* Add on-equip blacklist event. Note that it is overprotective due to deficiencies in Bukkit API.
|
||||
* Update WorldEdit CUI when using /rg select.
|
||||
* Add config option to disable villagers getting zapped into witches. ("weather.disable-villager-witchification")
|
||||
* Add entity support to interact-whitelist config option (use the Material of the corresponding item).
|
||||
* Fix vehicle-place protecting the rails at the very top of region boundaries incorrectly.
|
||||
* Fix for emptying buckets on waterloggable blocks.
|
||||
* Whitelist all player -> player interactions (previously was spammy in pvp).
|
||||
* Fix sleep flag not protecting against explosions in nether/end.
|
||||
* Add config for the teleport-on-void to reset fall distance.
|
||||
* Fix config options taking material lists requiring "minecraft:" namespace.
|
||||
* Fix disallowed-lightning-blocks situationally not working.
|
||||
* Fix errors that occurred when plugins used falling block entities with non-item materials.
|
||||
* Add special support for Paper servers (papermc.io): Paper's API allows us to track who launched fireworks.
|
||||
* Fireworks are now protected by default. On Paper servers, members can use them by default (to deal damage),
|
||||
on non-Paper servers, flag firework-damage allow to revert to old behavior (everyone can deal damage with fireworks by default).
|
||||
* Misc performance enhancements for Paper servers.
|
||||
* Add 'regions.use-paper-entity-origin' as an experimental setting (default off) for Paper servers. Enabling it will make non-player entities be treated as members of the place they spawned, instead of their current location when flags are checked.
|
||||
|
||||
## 7.0.0
|
||||
* Added support for MC 1.13, dropped support for previous versions.
|
||||
* Added lots of interactive text in e.g. `/rg info` command.
|
||||
* Added `/rg flags` command which allows viewing and interactively setting all flags on a region.
|
||||
* Large behind-the-scenes changes to WorldGuard's API (developers, see https://worldguard.enginehub.org/en/latest/developer/)
|
||||
* Places that used numeric block ids (e.g. blacklist) should now use Minecraft's new string IDs.
|
||||
* Fix various interactions with NPCs and region protection.
|
||||
* Sponge-simulation now destroys kelp and seagrass, and de-waterlogs blocks.
|
||||
* Added an option to block conduit effects.
|
||||
* Fix using newlines in string flags such as greeting and farewell.
|
||||
* Add item-frame-rotation flag.
|
||||
* Ender chests no longer require chest-access (since they don't have inventories).
|
||||
* Add kelp to vine-growth flag/config.
|
||||
* Add block-trampling flag (for turtle eggs and farmland).
|
||||
* Add snowman-trails flag.
|
||||
* Track potion area-of-effect cloud causes for pvp etc. protection.
|
||||
* Add confirmation to /stoplag command.
|
||||
* Forcefully eject players from vehicles trying to force their way into entry deny regions (and out of exit deny).
|
||||
* Fix removing child regions when removing a region with children.
|
||||
* Fix some over-protectiveness of pistons.
|
||||
* Chat and command flags (send-/receive- and allowed-/blocked-) now respect deny-message flag.
|
||||
* Misc fixes.
|
||||
|
||||
## 6.2.2
|
||||
* Added support for MC 1.12.
|
||||
* Changed flower pots to fall under the build flag.
|
||||
* Fix heal flag not functioning.
|
||||
* Add option to allow Forge clients with host-keys setting.
|
||||
* Add mobs.block-armor-stand-destroy config.
|
||||
* Add firework-damage flag.
|
||||
* Add config option to ignore hopper checks.
|
||||
* Misc fixes.
|
||||
|
||||
## 6.2
|
||||
* Added support for MC 1.11.
|
||||
* Add a custom flag and session API (for developers, see https://worldguard.enginehub.org/en/latest/developer/)
|
||||
* Add a config option to ensure location flags (teleport, spawn) are inside their region.
|
||||
* Misc fixes.
|
||||
|
||||
## 6.1.2
|
||||
* Added support for new blocks in 1.8, 1.9, and 1.10.
|
||||
* Added protection from nether portals being created in protected region (enable via config `nether-portal-protection`).
|
||||
* Added protection from slime block piston contraptions pushing into or pulling from regions.
|
||||
* Added `chorus-fruit-teleport` flag, works similar to `enderpearl` to prevent teleportation.
|
||||
* Added protection from pulling armor stands, items, and entities from protected regions.
|
||||
* Changed order of greeting and farewell flags on adjacent regions. When leaving a region with a farewell flag and entering one with a greeting flag, the farewell message will be shown first now.
|
||||
* Changed /heal command to also fill food/saturation meters.
|
||||
* Changed fall damage prevention to also prevent flying into walls with elytra being fatal.
|
||||
* Fixed fire-spread flag only preventing destruction, now prevents spreading too as per its name.
|
||||
* Fixed creepers targeting players being able to blow things up in certain cases.
|
||||
* Fixed armor stands being removed by /stoplag.
|
||||
* Fixed some issues with fireballs being able to explode when ghast-fireball was set to deny.
|
||||
* Fixed a lot of other minor issues.
|
||||
|
||||
## 6.1
|
||||
|
||||
* Added `exit-via-teleport` flag (default allow) to control exiting an exit=deny region via teleportation.
|
||||
* Added a `fall-damage` flag to control player damage caused by falling.
|
||||
* Added a `time-lock` flag to lock players' time of day. Valid values are from 0 to 24000 for absolute time, or +- any number for relative time.
|
||||
* Added a `weather-lock` flag to lock players' weather. Valid values are "clear" or "downfall". Unset to restore to normal world weather.
|
||||
* Added `-s` to the event debugging commands to show a stack trace rather than attempt to detect the causing plugin.
|
||||
* Added support for using the `-e` argument (sets an empty value for the flag) in the flag set command when the type of flag is of the 'set' type.
|
||||
* Added NPCs from the Citizens plugin to a whitelist so they are not protected.
|
||||
* Added support for Spigot's BlockExplodeEvent.
|
||||
* Changed tripwire to fall under the `use` flag.
|
||||
* Changed enderchests to fall under the `use` flag.
|
||||
* Changed vehicles and animals so they are not included in the `interact` flag.
|
||||
* Changed the display of custom blacklist messages to no longer include a period at the end.
|
||||
* Changed protection logic to consider connected chests.
|
||||
* Changed the heal and feed flags to increase values for players who are invincible (or in creative mode) but not decrease them.
|
||||
* Changed PvP protection to consider both attacker and defender locations.
|
||||
* Fixed missing protection data for some 1.8-added blocks.
|
||||
* Fixed compatibility issues with MC 1.7.
|
||||
* Fixed inverted daylight detectors not being protected.
|
||||
* Fixed spawn eggs not being included in protection.
|
||||
* Fixed piston blocking not working due to a bug in Spigot.
|
||||
* Fixed the blocking of certain invalid entity damage events.
|
||||
* Fixed creeper explosions not being blocked in certain situations with explosion related flags set.
|
||||
* Fixed "stickiness" with some position-related flags, sometimes resulting in rubber banding in the exit flags.
|
||||
* Fixed armor stands so that they are treated more like item frames than mobs.
|
||||
* Fixed blocks (e.g. sugar canes) adjacent to physics blocks (e.g. sand) not updating.
|
||||
* Fixed a NullPointerException that occurred sometimes when generating the scheduler section of the report function (`/wg report`).
|
||||
* Fixed the "no XP drops" configuration not functioning following a previous release.
|
||||
* Fixed changes to region ownership sometimes not triggering a region database save.
|
||||
* Fixed bucket protection displaying the "deny effect" even if bucket use was not prevented.
|
||||
* Fixed CommandFilter matching emoticons and other unwanted characters.
|
||||
* Fixed an exception occurring sometimes during game mode changes.
|
||||
* Fixed primed TNT being checked twice for TNT flags.
|
||||
|
||||
## 6.0 beta 5
|
||||
|
||||
MC 1.7.9, 1.7.10 and 1.8 (Spigot only) are supported.
|
||||
|
||||
* Added a feature to detect when another plugin (incorrectly) includes WorldGuard's files, causing errors.
|
||||
* Added a new `exit-override` flag that can be used on an entry=allow region that players can walk into from an entry=deny region.
|
||||
* Added a new `entry-deny-message` to change the "entry denied" message.
|
||||
* Added a new `exit-deny-message` to change the "exit denied" message.
|
||||
* Changed entry/exit blocking to disembark players from their vehicles.
|
||||
* Changed the PvP flag to no longer apply to self-attack.
|
||||
* Fixed [#3220](http://youtrack.sk89q.com/issue/WORLDGUARD-3220): Polygon regions sharing points
|
||||
* Fixed [#3216](http://youtrack.sk89q.com/issue/WORLDGUARD-3216): Polygon regions 'disappearing' or not working correctly
|
||||
* Fixed [#3315](http://youtrack.sk89q.com/issue/WORLDGUARD-3315): Invincibility flag and mode not blocking knockback from snowballs, etc.
|
||||
* Fixed [#3314](http://youtrack.sk89q.com/issue/WORLDGUARD-3314): Protection bypassable by getting a skeleton or creeper to target a player
|
||||
* Fixed [#3326](http://youtrack.sk89q.com/issue/WORLDGUARD-3326): Enderchests cannot be protected with the use flag
|
||||
* Fixed [#3327](http://youtrack.sk89q.com/issue/WORLDGUARD-3327): Fake players from some Forge mods are not being detected properly
|
||||
* Fixed [#3328](http://youtrack.sk89q.com/issue/WORLDGUARD-3328): TypeToken error with CraftBukkit 1.7 in `/wg report`
|
||||
* Fixed [#3086](http://youtrack.sk89q.com/issue/WORLDGUARD-3086): Region entry / exit messages overlap between seprate worlds
|
||||
* Fixed [#2542](http://youtrack.sk89q.com/issue/WORLDGUARD-2542): Exit deny regions don't handle respawn / logout consistently
|
||||
* Fixed [#2731](http://youtrack.sk89q.com/issue/WORLDGUARD-2731): Greeting / farewell messages don't understand region inheritance
|
||||
* Fixed [#3308](http://youtrack.sk89q.com/issue/WORLDGUARD-3308): Enderchest interaction block not functioning with blacklist.txt
|
||||
* Fixed [#3312](http://youtrack.sk89q.com/issue/WORLDGUARD-3312): PVP flag blocking enderpearl teleport fall damage
|
||||
* Fixed [#3309](http://youtrack.sk89q.com/issue/WORLDGUARD-3309): Inventory view commands being blocked in protected regions
|
||||
* Fixed [#3310](http://youtrack.sk89q.com/issue/WORLDGUARD-3310): USE flag is not allowing workbench usage
|
||||
* Fixed [#3330](http://youtrack.sk89q.com/issue/WORLDGUARD-3330): Build permissions preventing block placement
|
||||
* API: Added `BukkitUtil.toRegion(Chunk)`
|
||||
|
||||
## 6.0 beta 4
|
||||
|
||||
MC 1.7.9, 1.7.10 and 1.8 (Spigot only) are supported.
|
||||
|
||||
* Added better support for MC 1.8 blocks (regarding the use flag, etc.).
|
||||
* Added an an experimental "lite" version of WarmRoast to CPU profile your server (try it: `/wg profile -p`)
|
||||
* Added permissions for individual flag values (i.e. `worldguard.region.flag.flags.use.allow`).
|
||||
* Added support for slightly older versions of Bukkit 1.7.9.
|
||||
* Improved `/wg report`'s output (try it: `/wg report -p`)
|
||||
* Fixed armor stands not being protected properly.
|
||||
* Fixed lack of wood plate support with the `USE` flag.
|
||||
* Fixed left click also being blocked when only right click needed to be blocked.
|
||||
* Fixed items and paintings/item frames not decaying under some versions of Spigot.
|
||||
* Fixed parent-child inheritance so the child will always inherit the parent.
|
||||
* Fixed inheritance issues with a flag is set with a region group on a parent region.
|
||||
* Fixed high CPU usage when Citizens is also installed.
|
||||
* Fixed `on-acquire` in the blacklist so it also handles item transfers between inventories.
|
||||
* Fixed the blacklist not supporting color codes.
|
||||
* Changed the PvP flag so it applies to self-attack like in WG 5 (this change *may* be reverted).
|
||||
|
||||
## 6.0 beta 3
|
||||
|
||||
MC 1.7.10 and 1.8 (Spigot only) are supported.
|
||||
|
||||
* Support both MC 1.7.10 and 1.8.
|
||||
* Don't apply the region override permission to PvP.
|
||||
* Fix incorrect detection of hostile and ambient creatures when protecting against PvE.
|
||||
* Fix the splash potion flag not working with the other flags.
|
||||
* Fix potion blocking.
|
||||
* Fix inability to blacklist the enchantment table and the workbench.
|
||||
* Make PASSTHROUGH=DENY useful on ``__global__``.
|
||||
* Fix issues (pistons broken, etc.) caused by adding members to ``__global__``.
|
||||
* Make the EXP_DROPS flag a build-compat flag and set its deny message.
|
||||
* Give the player back his/her XP bottle if it was blocked.
|
||||
* Expand the interaction whitelist configuration to "physical" events.
|
||||
* Catch command prefixes in the command flags.
|
||||
* Add a RIDE flag for vehicles.
|
||||
* Check for names in addition to UUIDs with /rg list.
|
||||
* Whitelist hoppers and let them cross regions regardless of region protection.
|
||||
* Revert USE flag's functionality to 5.x, add new INTERACT flag.
|
||||
* Fix spawn egg blocking.
|
||||
* Fix failed detection of incorrect blacklist block and item names.
|
||||
* Fix command prefix bypass with the op command blocking configuration.
|
||||
* Rewrite and update report generation (wg report).
|
||||
* Add event cancellation debug commands.
|
||||
* Fix location flags causing NullPointerExceptions.
|
||||
* Show more details in error log which world the error belongs to.
|
||||
* Add missing color codes when parsing input.
|
||||
* Let players use NPCs always.
|
||||
* Fix [WorldGuard] in log messages stacking on reloads.
|
||||
* Better handle empty group / player names due to bad region data.
|
||||
* Fix players being invincible with BUILD=deny.
|
||||
* Fix certain entities not being damaged in protected regions.
|
||||
* Improve entity detection in Entities utility class, add Entities.isNonPlayerCreature().
|
||||
* Add missing SQL table prefix in statement selecting world names.
|
||||
|
||||
## 6.0 beta 2
|
||||
|
||||
* Added an `-e` parameter to `/rg flag` that sets the flag to an empty value. You can use this to, for example, make it so the `deny-message` flag is empty, meaning that players won't get a message at all.
|
||||
* Added a visual smoke effect when an action on a block has been denied.
|
||||
* Added `event-handling.interaction-whitelist`, a list of items or blocks that should never be protected. For example, adding `wooden_door` to the list would make it so that doors could be used by anyone regardless if they have permission or not. You may still protect the blocks via other means.
|
||||
* Added `event-handling.emit-block-use-at-feet`, a list of items that, when used, will also be considered as the player using that item on the block at the player's feet. The purpose of this setting is, for example, to allow you to (sort of) prevent the use of a mod-added item that does not emit events.
|
||||
* Added `-s` to silently turn toggle `/stoplag` and `-i` to show the current state of the setting. (Thanks, [stuntguy3000](https://github.com/stuntguy3000)).
|
||||
* Added support for Bukkit [Material](http://jd.bukkit.org/rb/apidocs/org/bukkit/Material.html) names in the blacklist.
|
||||
* Fixed [#3167](http://youtrack.sk89q.com/issue/WORLDGUARD-3167): Saplings can be used without permission although it won't place blocks inside the region
|
||||
* Fixed [#3168](http://youtrack.sk89q.com/issue/WORLDGUARD-3168): Grown saplings that are partially prevented from placing all of its leaves may not remove the sapling
|
||||
* Fixed [#3169](http://youtrack.sk89q.com/issue/WORLDGUARD-3169): Bonemeal usage falls under the USE flag when it should really fall under building
|
||||
* Fixed [#3174](http://youtrack.sk89q.com/issue/WORLDGUARD-3174): Boat placement is not properly prevented in a protected region
|
||||
* Fixed [#3130](http://youtrack.sk89q.com/issue/WORLDGUARD-3130): Polygonal selections allow unlimited claim volumes with /rg claim
|
||||
* Fixed [#3137](http://youtrack.sk89q.com/issue/WORLDGUARD-3137): Claiming infinite regions is possible due to integer overflow
|
||||
* Fixed [#3171](http://youtrack.sk89q.com/issue/WORLDGUARD-3171): Can't pickup XP in protected regions without permission
|
||||
* Fixed [#3170](http://youtrack.sk89q.com/issue/WORLDGUARD-3170): Boats without a driver can be used to break lily pads
|
||||
* Fixed [#3172](http://youtrack.sk89q.com/issue/WORLDGUARD-3172): Players cannot be damaged by mobs in protected regions unless they have permission
|
||||
* Fixed [#3152](http://youtrack.sk89q.com/issue/WORLDGUARD-3152): BUILD overrides all other flags, unlike in WG 5
|
||||
* Fixed [#3154](http://youtrack.sk89q.com/issue/WORLDGUARD-3154): notify-enterflag doesn't work with horses and other vehicles
|
||||
* Fixed [#3166](http://youtrack.sk89q.com/issue/WORLDGUARD-3166): Trees do not grow naturally within protected regions
|
||||
|
||||
## 6.0 beta 1
|
||||
|
||||
### UUID support
|
||||
|
||||
Regions now fully support the use of UUIDs rather than names for storing the owners and members of a region. Commands still accept names, but they are translated into UUIDs in the background. For users who already have existing region data, names will be automatically converted to UUIDs on the first run of WorldGuard.
|
||||
|
||||
It is still possible to specify names rather than a UUID by using the `-n` flag with the region membership commands.
|
||||
|
||||
### 'Deny by default'
|
||||
|
||||
Previously, a pre-determined list of blocks and entities was used to determine whether an action by the player should be blocked. However, this has been reversed so that every action on a block or entity is denied (in a protected region) unless it has been deemed safe (such as, for example, right clicking with steak). Mods are now supported as a result.
|
||||
|
||||
The `USE` flag has been repurposed as a general "interaction" flag and covers every left click or right click of a block or entity. It also covers interaction that falls outside clicking.
|
||||
|
||||
### Exhaustive protection
|
||||
|
||||
More events are now handled in the protection code. For example,
|
||||
|
||||
* It is no longer possible to drop sand or gravel into a protected region from outside.
|
||||
* It is no longer possible to grief a region by growing a tree into it.
|
||||
* The entry and exit flags now handle players sitting on vehicles properly.
|
||||
* Piston-moved blocks cannot be pushed into a different protected region.
|
||||
* Owners of tamable animals are now considered in protection code.
|
||||
|
||||
Even water and lava flow can also be checked, although this requires that it be explicitly enabled in the configuration (flow events are very frequent, so they incur extra CPU cost).
|
||||
|
||||
The goal is to provide extremely exhaustive protection.
|
||||
|
||||
### Large performance boost for spatial queries
|
||||
|
||||
The performance of spatial queries for regions has been substantially increased at least an order of magnitude. Spatial queries are a necessity for the region code to query the list of regions that apply to a location in the world. There should be a negligible difference between 4, 40, and 4000 regions as long as too many regions are not overlapping.
|
||||
|
||||
### Background region operations
|
||||
|
||||
Region commands are now executed in the background. Notably, saves and loads will not lock up your server while they complete. Additionally, changes to regions are now saved periodically rather than immediately after every change.
|
||||
|
||||
### Updated MySQL region support
|
||||
|
||||
MySQL support has been completely overhauled. It should now be faster, no longer crash on foreign key index errors, use transactions, and support automatic creation and migration of tables (including support for table prefixes).
|
||||
|
||||
### Partial region data saving
|
||||
|
||||
For users of MySQL, WorldGuard now only saves changed and deleted regions when saving region data. No longer does WorldGuard have to rewrite the entire region database on each save.
|
||||
|
||||
### Improved handling of related flags
|
||||
|
||||
Multiple flags that apply to an event are now evaluated together if they are similar. For example, if a player right clicks a bed to sleep in it, both the `USE` and `SLEEP` flag are checked since they are both interaction-related. If one of them is `DENY`, then sleeping is denied (remember, `DENY` overrides `ALLOW`). If one of them is `ALLOW` and the other is not `DENY`, then sleeping is permitted.
|
||||
|
||||
Only one "category" of flags needs to evaluate to true to permit an action. `DENY` will not cross categories. For example, if `BUILD` is deny, it will not override `SLEEP`, so if `SLEEP` is set to `ALLOW`, sleeping will be permitted. This is fairly similar to how it worked on WorldGuard 5.
|
||||
|
||||
### Flag groups now work properly
|
||||
|
||||
While you could always set a group to a flag's value, the functionality was incomplete and did not work most of the time.
|
||||
|
||||
Now that groups are supported, you can change a flag so it only applies to a certain group of players. For example, `/rg flag example sleep deny -g members` would deny sleeping for only members of the `example` region.
|
||||
|
||||
### Inheritance now works as expected
|
||||
|
||||
Previously, a region only inherited flags and other details from its parents if the parent and the child overlapped at the location queried. This is no longer the case and inheritance is now always applied.
|
||||
|
||||
In addition, a new `-g` flag for `/rg define` lets you create a region with no physical area so that you can assign flags and use this region as a "template region."
|
||||
|
||||
### Settable deny message
|
||||
|
||||
It is now possible to change the message that users get when they are prevented from interacting with blocks or entities. This message is defined as a region flag, so you can set it on the `__global__` region or override it in a specific region. In addition, the tone and color of the default message has been softened, but you are free to change it entirely.
|
||||
|
||||
### Blacklist support for data values (and later, variants)
|
||||
|
||||
The blacklist was rewritten to support more than just block and item IDs. The immediate result is that you can now use data values, but as those are in the process of being deprecated by Mojang, it also allows support for Minecraft's new block variants in the future.
|
||||
|
||||
### Debounced events
|
||||
|
||||
Events that tend to reoccur very frequently (such as the ones that occur when you stand on a pressure plate continuously) have been "debounced" to reduce the number of checks that WorldGuard has to perform, reducing the amount of wasted CPU. In addition, the "you don't have permission" message is rate limited so players are not flooded with the message.
|
||||
|
||||
### New block place and break flags
|
||||
|
||||
A long requested feature was the availability of block place and break flags. These newly added flags work in tandem with the `BUILD` flag but can override `BUILD`. At the moment, it is not possible to allow explicit types of blocks to be placed or broken yet.
|
||||
|
||||
### Build permission nodes
|
||||
|
||||
A new optional (disabled by default in the configuration) feature is the checking of build permission nodes. For every block, entity, and item, the following permission nodes are checked:
|
||||
|
||||
* Block place: `worldguard.build.block.place.<material>`
|
||||
* Block break: `worldguard.build.block.remove.<material>`
|
||||
* Block interact: `worldguard.build.block.interact.<material>`
|
||||
* Entity spawn: `worldguard.build.entity.place.<type>`
|
||||
* Entity destroy: `worldguard.build.entity.remove.<type>`
|
||||
* Entity interact: `worldguard.build.entity.interact.<type>`
|
||||
* Entity damage: `worldguard.build.entity.damage.<type>`
|
||||
* Item use: `worldguard.build.item.use.<material>`
|
||||
|
||||
In addition, the permissions are also checked in the style of `worldguard.build.block.<material>.<action>`, so `worldguard.build.block.<material>.place` would work too.
|
||||
|
||||
The list of usable material names comes from the [Material enumeration in Bukkit](http://jd.bukkit.org/rb/apidocs/org/bukkit/Material.html). For example, the permission for placing the bed block would be `worldguard.build.build.place.bed_block`. Be aware that _Material_ contains both item and block names.
|
||||
|
||||
For entity names, see [EntityType](http://jd.bukkit.org/rb/apidocs/org/bukkit/entity/EntityType.html).
|
||||
|
||||
### Other changes
|
||||
|
||||
* Added a setting to permit "fake players" to bypass protection. Fake players are used by some servers and some mods to allow events to be thrown for mod blocks. WorldGuard considers a player to be a fake player if the name starts with `[` and ends with `]`.
|
||||
* Added a check so players can no longer disembark in a region from their tamed animal if they don't have permission to get back on.
|
||||
* Added an item pickup flag to go along with the item drop flag.
|
||||
* Added a new `//running` command was added to show currently running background tasks.
|
||||
* Added a blacklist `on-dispense` event.
|
||||
* Added more detailed error messages when parsing the YAML regions file.
|
||||
* Added the `-Dworldguard.debug.listener=true` option that can be set on your server's command line to see how WorldGuard processes events, although this will result in a lot of log messages.
|
||||
* Added log messages that occur on player join when a player had auto-god mode or auto-amphibious mode.
|
||||
* Fixed the heal command so that it now sets a player's health to the maximum rather than 20.
|
||||
* Fixed `ProtectedCuboidRegion.getPoints()` returning points in wrong order.
|
||||
* Fixed the obsidian generator disable option to also apply to tripwire.
|
||||
* Fixed an error with the blocked commands flag.
|
||||
* Fixed a connection leak with the MySQL region code.
|
||||
* Fixed `/wg reload` sometimes not applying new changes right away.
|
||||
* Changed the region removal command so that child regions are no longer removed without warning when removing the parent region.
|
||||
* Changed the YAML region data save code to first write the data to a temporary file before replacing the final file.
|
||||
* Changed how region data is handled when region support is disabled: it is no longer loaded.
|
||||
* Changed sponges to now be disabled by default. However, if you had previously installed WorldGuard, sponges will still be enabled. Sponges are being added in Minecraft and they work differently than in Minecraft Classic (which WorldGuard emulates). In addition, enabling sponge support in WorldGuard incurs extra CPU cost even if no sponges exist in the world.
|
||||
* Changed how region data is loaded and saved so failures are now more graceful. If the region data fails to load for a world, then the entire world will be protected by default. In addition, periodic attempts will be made to load the region data in the background.
|
||||
* Changed the `FEED` flag to maximize the player's saturation level if the hunger level is raised.
|
||||
* Changed the `wg-invincible` and `wg-amphibious` groups feature so that it now must be enabled in the configuration.
|
||||
* Removed the ability for WorldGuard to upgrade from a version for Minecraft Alpha.
|
||||
|
||||
### API changes
|
||||
|
||||
* You can use a new `WorldGuardPlugin.createProtectionQuery()` method to easily check build permissions.
|
||||
* The listener classes were moved. Consider them internal -- if you want to make use of the listener somehow, please put in a ticket in our issue tracker.
|
||||
* Much of the protection-related handling was previously scattered throughout the code. Now WorldGuard funnels events into an internal event system and then processes protection queries in a more consistent matter. These events are for internal use so it is strongly recommended that you do not use them (they may change without notice drastically). A lot of the protection-related flag handling was moved there.
|
||||
* A significant portion of classes under the package of `com.sk89q.worldguard.protection` were changed or removed. However, the basic calls (testing the value of a flag, etc.) should still work, but they may be deprecated. Some of the utility `Domain`-related classes were removed.
|
||||
* The old region database (load/save) API was removed and replaced with a new one. The new one no longer needs to pointless store a collection of regions on itself -- it has `collection = load()` and `save(collection)` methods.
|
||||
* Previously, there were subclasses of `RegionManager` that implemented different spatial indices. However, now `RegionManager` is a final class and the spatial indices are separate (see the `RegionIndex` interface).
|
||||
* A hash table was implemented that caches a list of regions within each loaded chunk. This increases performance of spatial queries substantially.
|
||||
* A cache of recent spatial queries now exists (a cache of `ApplicableRegionSets`), but you need to make use of `RegionQuery` to make use of this cache. However, if you need to do a spatial query to modify region data, then the old method is better (get a `RegionManager`, etc.).
|
||||
* `ApplicableRegionSet` was converted into an interface. In addition, there are now "virtual" `ApplicableRegionSet` instances that are returned by `RegionQuery` for certain special cases (such as, for example, region support being disabled by the user or region data being unavailable for a world due to an error). A new `isVirtual()` method is available. This is not an issue if you are getting `ApplicableRegionSet` instances from a `RegionManager`.
|
||||
* `ApplicableRegionSet` now can accept a pre-sorted collection and its use of a `TreeSet` was removed for performance reasons.
|
||||
* `FileNotFoundException` is now properly handled in the YAML region file class. It creates the new file and continues on.
|
||||
* Player names are deprecated by Mojang and so they need to be converted into UUIDs. As this will take some time, you should do this conversion in a background task. To check whether a region contains a player, it recommended that `contains(LocalPlayer)` be used because it's possible that the user may be still using names. A new `WorldGuardPlugin.wrapOfflinePlayer()` method was added for this specific purposes.
|
||||
* All flags now use `RegionGroup.ALL` as the default region group.
|
||||
* `StateFlag.getDefault()` now returns a `State` rather than a `boolean`.
|
||||
* The priority R-tree index now uses the R-tree for region intersection queries. Previously, it was only used for single point containment queries.
|
||||
* Regions now keep a "dirty" flag and changes it whenever data within the region is changed. When WorldGuard decides to periodically save region data, it may only save changed regions. Calling `save()` on the `RegionManager` is no longer needed as periodical saves happen automatically.
|
||||
* The old region data migration API was removed in favor of region store drivers. There is no longer a need to have an implementation for every possible conversion (i.e. YAML -> MySQL, MySQL -> YAML, etc.).
|
||||
* `ProtectedRegion.copyFrom()` was added to copy region settings from another region.
|
||||
* `@Nullable` annotations were added throughout the code. If you use IntelliJ IDEA, you may notice that it now warns you when a return value may be `null`.
|
||||
|
||||
## 5.9
|
||||
|
||||
* Added a config option to allow explosion flags to only prevent block damage
|
||||
* Added allow-tamed-spawns setting, on by default. This will stop WorldGuard from culling tamed animals.
|
||||
* Added config option and flag to prevent soil from drying naturally.
|
||||
* Added formatting codes, &k/l/m/n/o and &x (reset).
|
||||
* Added snow-fall-blocks option to config to restrict snow fall to certain blocks
|
||||
* Allow players to add newlines (\n) via command, not just manually in yml.
|
||||
* Allow the console to load/save all region managers with one command.
|
||||
* Changed entity report format slightly.
|
||||
* Check bypass perms for item-drop flag.
|
||||
* Check for entities and projectiles removing items from frames too.
|
||||
* Fix being able to use bonemeal to turn tall grass into double plants.
|
||||
* Fix number of arguments for migratedb command.
|
||||
* Fixed addowner/addmember commands adding command artifacts. Specifically, "-w <world>" will no longer be added when using it.
|
||||
* Fixed milking cows in protected areas due to changes in Bukkit.
|
||||
* Fixed ProtectedCuboidRegion::getPoints() returning points in wrong order.
|
||||
* Fixed snowman trails being treated as snow fall.
|
||||
* Make /rg list default to own regions if the player doesn't have permission otherwise.
|
||||
* Protected items in item frames in protected regions.
|
||||
* Resolved an issue where explosions of type OTHER_EXPLOSION were ignoring the world configuration settings.
|
||||
* Send item-use blacklist event when right-clicking entities.
|
||||
* Transformed the BlockFadeEvent handler into a switch.
|
||||
|
||||
## 5.8
|
||||
|
||||
* BREAKING CHANGE: This version has been built for versions of Bukkit for MC 1.6.1 and newer. Do not try to use this version of WG on an older Bukkit version.
|
||||
* Added support for Minecraft 1.6+. Actual support of new 1.6 additions is dependant on Bukkit. Please use a newer build of Bukkit if, for example, you seem to be unable to add "Horses" to your lists of entities.
|
||||
* Added mobs.disable-snowman-trails to disable the trails left by walking snowmen.
|
||||
* Added -a flag to /region removeowner and /region removemember to remove all objects.
|
||||
* Teleporting is now handled by entry/exit flags. If this is causing people to get entirely stuck inside entry/exit deny regions, set the new setting 'use-player-teleports' to 'false' in your configuration.
|
||||
* Updated formatting for region commands, especially /region info.
|
||||
* Changed permissions checking for /region commands to be more consistent, checking for region IDs as a sub-node. This means that if some permissions for some region commands no longer work, add '.*' to the end of permission lines for WG in your permission plugin.
|
||||
|
||||
## 5.7.5
|
||||
|
||||
* Refixed a few issues from 5.7.4.
|
||||
|
||||
## 5.7.4
|
||||
|
||||
* BREAKING CHANGE: Removed the cyan "**" in front of greeting and farewell messages to allow more customizability. You can re-add them by adding "&c**" to the flag.
|
||||
* Fixed an issue enderpearling inside exit/entry deny regions.
|
||||
* Added checks to players teleporting in and out of exit/entry regions.
|
||||
* Fix bad matching in blocked and allowed command flags.
|
||||
* Fixed heal flag bugs when player max health was increased.
|
||||
* Add fishing to xp blocker.
|
||||
* Applied other-explosion flag to entity damage as well.
|
||||
* Fixed an issue with interaction that should allow blacklisting item use actions with no block involved (eg fishing rods, potions)
|
||||
* Fix witherskull/fireball settings not being differentiated in one case
|
||||
* Allow cow milking in no-build areas
|
||||
* Fix infinite durability breaking items instantly.
|
||||
|
||||
## 5.7.3
|
||||
|
||||
* Fixed the error caused by Bukkit's change of the TNT minecart API.
|
||||
|
||||
## 5.7.2
|
||||
|
||||
* Updated to MineCraft 1.5.
|
||||
* Added TNT Minecart support. They are handled with the same flags/settings as TNT.
|
||||
* Added mining and smelting xp handling to the xp drops flag and setting.
|
||||
* Fixed a few edge cases for placing items on region borders.
|
||||
* Legacy: Fixed issue with //stack not respecting item metadata.
|
||||
|
||||
## 5.7.1
|
||||
|
||||
* Added a vine growth config option and flag.
|
||||
* Added support for many commands to be used from console. Usage is with -w flag and a world name e.g. /rg addmem <id> <player> -w <worldname> /rg flag <id> <flag> -w <worldname> <flagvalue>
|
||||
* Fixed bug that blocks placing plants in flower pots.
|
||||
* Fixed permissions check for /rg tp
|
||||
* Fixed enderchests not being accessible (they are now part of the USE flag)
|
||||
* Fixed an issue with slabs being placable in protected regions. This was also fixed in CraftBukkit but has been left in for users running other versions.
|
||||
* Fixed wither skulls being handled with other fireballs, despite having their own settings.
|
||||
* Fixed item frames being placable on region borders.
|
||||
* Fixed a bug that made explosions more ineffective than they should have been.
|
||||
* Fixed bonemeal usage in protected regions.
|
||||
* Fixed special minecarts being placable in protected regions.
|
||||
* Fixed bugs being placable on region borders.
|
||||
* Fixed wolves bypassing pvp flags.
|
||||
|
||||
## 5.7
|
||||
|
||||
* Fixed thread sync issue with FlagStateManager.
|
||||
* Fixed dragon egg region protection not working in certain cases.
|
||||
* Added beacon and anvil usage protection in regions.
|
||||
* Add mobs.block-enderdragon-portal-creation to stop enderdragons from making portals on death.
|
||||
* Fix TNT being lethal in some case when damage was disabled.
|
||||
* Fix snowballs and enderpearls being able to knock players back in pvp deny regions.
|
||||
* Add subcommand support for allowed and blocked command flags.
|
||||
* Add max-players-allowed and max-players-reject-message flags to limit the numbers of players in a region.
|
||||
* Fix players being able to plant cocoa beans in protected areas.
|
||||
* Add an enderpearl flag to prevent players from teleporting to and from regions.
|
||||
* Added mobs.block-other-explosions config setting and other-explosion flag to block explosions caused by uncovered things, such as other plugins. (It doesn't actually have to be a mob)
|
||||
* Fix mob damage setting and flag not blocking the DoT wither effect.
|
||||
* Ghast fireball flag will not block blaze fireballs from lighting things on fire.
|
||||
* Fixed players without region permissions being able to trigger tripwires, use enderchests, use wooden buttons, and put plants in flower pots.
|
||||
* Added mobs.block-zombie-door-destruction setting to stop zombies from breaking down doors while difficulty is set to hard.
|
||||
|
||||
Thank you to thvortex, Dilandau, tophathacker, and Dark_arc for their contributions this release.
|
||||
|
||||
## 5.6.5
|
||||
|
||||
* Fixed a regression that caused paintings and item frames to no longer be properly protected.
|
||||
|
||||
## 5.6.4
|
||||
|
||||
* Added mobs.block-above-ground-slimes to block slimes spawning naturally above ground.
|
||||
* Added security.deop-everyone-on-join to de-op all players when they join.
|
||||
* Added security.block-in-game-op-command to prevent usage of /op from in-game.
|
||||
* Fixed a NullPointerException in PlayerInteract involving water potions and potion blocking.
|
||||
* Fixed an issue with snowballs being blocked in regions.
|
||||
* Changed dragon eggs to be checked like it is a broken block in regions.
|
||||
* Moved developer's WGBukkit class to package com.sk89q.worldguard.bukkit.
|
||||
|
||||
## 5.6.3
|
||||
|
||||
* Added helper WGBukkit class to get references to WorldGuard from other plugins.
|
||||
* Added physics.vine-like-rope-ladders to make ladders work like vines. As long as the top ladder block is present, ladder blocks will hold even if they have no block behind them, like a rope ladder.
|
||||
* Fixed NullPointerException in PlayerInteractEvent caused by potion blocking.
|
||||
* Fixed mobs.block-{item-frame,painting}-destroy not working.
|
||||
|
||||
Thank you to def for testing the above fixes and features.
|
||||
|
||||
## 5.6.2
|
||||
|
||||
* Fixed potion blocking not working well for splash potions.
|
||||
|
||||
## 5.6.1
|
||||
|
||||
* Added a mycelium-spread region flag.
|
||||
* Added a dynamics.disable-mycelium-spread configuration setting.
|
||||
* Added new gameplay.block-potions option. For example: gameplay: block-potions: [invisibility, speed]
|
||||
* Fixed a bug in the entity explosion event handler that caused a NullPointerException.
|
||||
|
||||
Thank you for gabizou for his contribution in this release.
|
||||
|
||||
## 5.6
|
||||
|
||||
* Added official support for Minecraft 1.4. Support for 1.3.2 (and below) is still provided in this release.
|
||||
* Added support for new and existing explosion types.
|
||||
* Added support for blocking withers with the following settings: mobs: block-wither-explosions: false block-wither-block-damage: false block-wither-skull-explosions: false block-wither-skull-block-damage: true
|
||||
* Added support for blocking item frames (and their use) in protected regions.
|
||||
* Added item frame destruction region flags (if you wish to disable item frame destruction completely).
|
||||
* (Re-)added support for priority R-tree region indexes. This means quicker region lookup, and better support for servers with thousands of regions.
|
||||
* Improved /region info output for -g group flags.
|
||||
* Allowed removing of -g group flags with /region flag.
|
||||
* Allowed /region flag to set group and value at once.
|
||||
* Deleting a region flag now also deletes group flag.
|
||||
* Fixed detection of attack by projectiles to be more accurate.
|
||||
* Fixed support for saving non-string flags in the MySQL region support.
|
||||
* Fixed spurious comma in "Flags:" /region info output.
|
||||
* Fixed players who are not in god mode not receiving damage in PVP areas from enderpearls.
|
||||
* Players will now be told that they are in a no-PvP area if they are in one and attempting to attack someone, or that the player they are attacking is in a no-PvP area, if that is the case instead.
|
||||
* Fixed an issue where region.getId() was lowercase'd each pass of a for loop in MySQLDatabase.updatePoly2dPoints().
|
||||
* Fixed mob damage from projectiles not being properly blocked in regions where applicable.
|
||||
* Changed default region wand to leather (#334).
|
||||
|
||||
Thank you to the following individuals for their contribution:
|
||||
thvortex, Rutr, Glitchfinder, and DarthAndroid.
|
||||
|
||||
## 5.5.4
|
||||
|
||||
* Minecraft 1.3 support.
|
||||
* Fixed /stack dupe bugs.
|
||||
* Added regions.use-creature-spawn-event.
|
||||
* Update for Async chat issue.
|
||||
* Add use flag to cakes.
|
||||
* Report number of plugins loaded in report writer.
|
||||
* Updated fireblal item blocking.
|
||||
* Fixed permissions for /region reload.
|
||||
|
||||
## 5.5.3
|
||||
|
||||
* Added game mode flag.
|
||||
* Added item drop pickup flag to regions.
|
||||
* Added support for fireball item blocking (385).
|
||||
* Added configuration option to allow creature spawns from plugins.
|
||||
* Added host key check.
|
||||
* Added a new line split feature to region greetings.
|
||||
* Prevented commands in the allow commands list from being blocked and vice versa.
|
||||
|
||||
## 5.5.2
|
||||
|
||||
* Added potion-splash flag to block splash potions
|
||||
* Add entity-painting-destroy which can be used to prevent entities from destroying paintings (skeletons firing arrows)
|
||||
* Added send-chat and receive-chat flags
|
||||
* Fixed having regions in multiple worlds with the same name not working with MySQL
|
||||
* A cancellable event is now fired if WorldGuard disallows PvP. (for developers!)
|
||||
* Made /region setparent check worldguard.region.setparent.own/member.<parent> instead of worldguard.region.setparent.own/member.<child>.
|
||||
* Allowed passing #<index> in place of a region ID, where <index> is the index as displayed by /region list.
|
||||
* Fixed an error that occured when clearing a non-existant region's parent.
|
||||
* Added a -s flag to /region teleport, which sends you to the spawn point instead of the teleport point of a region.
|
||||
* Added region/role-based permissions to /region teleport.
|
||||
* BREAKING CHANGE: Added a LocationFlag class and made the teleport and spawn flags use it.
|
||||
* /region info -s now selects the region being queried.
|
||||
* Added /region teleport <id>.
|
||||
* Vector flags can now be set to the current location with the value "here" and to a specific position with x,y,z.
|
||||
* Made /region info show the region you're in if you don't specify an id explicitly.
|
||||
* Prevent block ignition from lightning strikes if lightning is blocked in region. Fixes #1175
|
||||
* Correctly check both WEPIF and superperms in WorldGurdPlugin.broadcastNotification()
|
||||
* Destroy fire blocks when fire-spread is disallowed
|
||||
* Added a construct flag that can be used to restrict block placing/destroying in zones to certain roles.
|
||||
* Added FallingSand to list of intensive entities to be removed with /halt-activiy.
|
||||
* Replaced all usage of CreatureType by EntityType.
|
||||
* Updated to support Bukkit 1.2-R0.3 and newer
|
||||
* Made auto-god-mode disabled by default again.
|
||||
* Added sign protection check disable.
|
||||
* Cleaned up javadoc, deprecated duplicate methods, other cleanup
|
||||
* Added a RegionGroupFlag to evey region flag Using the /region flag command with -g, the region group that the region flag applies to can be set.
|
||||
|
||||
## 5.5.1
|
||||
|
||||
* Fixed attacking with arrows from non-PVP to PVP areas
|
||||
* Compatibility with Bukkit 1.1-R5
|
||||
* Removed broken suppress-tick-sync-warnings config option. See bukkit.yml's setings.warn-on-overload option instead.
|
||||
* Add region and 'can build' information to CommandBook's /whois
|
||||
|
||||
Contributions thanks to: NolanSyKinsley
|
||||
|
||||
## 5.5
|
||||
|
||||
* Removed WorldEdit.jar from the classpath to stop conflicts with Bukkit's plugin loader
|
||||
* Now using Bukkit's tagged logging
|
||||
* Updated to new event system
|
||||
* Flush player flag state cache on world change
|
||||
* Improved compatibility with versions of CommandBook without GodComponent and updated pom dep for 2.0
|
||||
* Added MySQL region storage method.
|
||||
* Made explosions display their animations even when the event was blocked.
|
||||
* Added fallback support for those who don't have a version of CommandBook with GodComponent
|
||||
* Added LIGHTNING flag to DefaultFlag's flagsList Fixes #1026
|
||||
* Removed /god, /heal, /locate, and /stack from WorldGuard to CommandBook. CommandBook is now checked to see whether a player is godded.
|
||||
* Removed remaining usages of org.bukkit.util.config.Configuration
|
||||
* Removed some unused configuration options
|
||||
* Added permission worldguard.region.wand to the region wand
|
||||
* Fixed ProtectedRegion.compareTo.
|
||||
* Fixed FlatRegionManager.getApplicableRegions to return parent regions as well.
|
||||
* Added exp-drops flag to disable experience drops per-region.
|
||||
* Fixed some warnings.
|
||||
* Updated dependency version for WorldGuard from 5.0 to 5.1-SNAPSHOT.
|
||||
* Added support for fireballs shot by players being blocked by the PVP flag.
|
||||
* Now using dynamic command registration
|
||||
* Split off ender dragon block damage from creeper block damage.
|
||||
|
||||
Contributions thanks to: narthollis, DarkArc, Wolvereness, and skeight
|
||||
|
||||
## 5.4
|
||||
|
||||
* Fixed configuration generation on Windows
|
||||
* Fixed intersection calculation for regions
|
||||
* Fixed timer and feeding delay for food flags
|
||||
* Fixed region managers not being created properly (This caused errors related to CREATURE_SPAWN)
|
||||
* Added support for Minecraft 1.0.1 blocks
|
||||
* Added support for enchantments and tool damage (worldguard.stack.damaged is the node) with /stack
|
||||
* Made being in the wg-invincible group respect the configuration's auto-invincible setting
|
||||
* Added per-group region claim limit maximum
|
||||
* Added worldguard.region.addowner.unclaimed.* permission for non-economy region 'buying'
|
||||
* Checking allowed/blocked commands now occurs earlier to override more plugins
|
||||
* Made PVP flag check whether either player is in a pvp deny region for blocking
|
||||
|
||||
Contributions thanks to: epuidokas, wizjany, Turtle9598, and DerFlash
|
||||
|
||||
## 5.3
|
||||
|
||||
* Added new config options and flags to better handle explosions of all types
|
||||
* Added config options and flags for snow, ice, mushroom spread, grass spread, and leaf decay
|
||||
* Added min and max health flags to clamp the values for the existing healing flags
|
||||
* Added hunger flags similar to the existing healing flags
|
||||
* Added an option to disable the use of the move event. This can boost performance on large servers but will disable the greeting/farewell and entry/exit flags
|
||||
* Added flag to prevent pistons (including those that are outside the region, but would affect blocks inside the region)
|
||||
* Added a /wg flushstates [player] command to free players stuck in a region that was exit-deny but no longer exists or the flag was removed
|
||||
* Added a config option to disable xp orb dropping
|
||||
* Added config option to disable redstone wire obsidian generators
|
||||
* Added a vehicle-destroy flag
|
||||
* Added enderman protection config and flag
|
||||
* Allowed and blocked command flags will now fall back to the global region
|
||||
* The worldguard.region.flag.own/member permissions are now worldguard.region.flag.regions.own/member! Please change your permissions accordingly.
|
||||
* Made //stack respect max stack sizes unless the player has the worldguard.stack.illegitimate permission
|
||||
* Setting invincibility flag to deny will override god mode unless the player has worldguard.god.override-regions
|
||||
* The sleep flag will now prevent beds in the nether from exploding if set to deny
|
||||
* Existing regions can no longer be accidentally overwritten. Use /region redefine to move an existing region.
|
||||
* The info command will now sort players alphabetically
|
||||
* Priming TNT by punching it with flint and steal should throw a blacklist event (consistent with old Minecraft versions)
|
||||
* The /stoplag command will now remove xp orbs
|
||||
* Permissions system will use per-world permissions if the provider supports it
|
||||
* Players in vehicles are now subject to entry/exit and greeting/farewell flags
|
||||
* Fixed interact blacklist event not logging correctly
|
||||
* Fixed heal flag taking effect half a block northeast of the region
|
||||
* Fixed a infinite sign dropping bug
|
||||
* Fixed players being able to douse fire by punching it in regions they couldn't build it
|
||||
* Fixed players being able to eat protected cake
|
||||
* Fence gate usage can be blocked with the use flag
|
||||
* Fixed chests being unprotected when they should be in 1.8
|
||||
* Fixed weather config settings not applying when a world was loaded
|
||||
* Fixed explosion handling in certain cases
|
||||
* Fixed arrows working in non-pvp zones
|
||||
* Fixed buckets working on the border of protected regions in certain cases
|
||||
Contributions thanks to:
|
||||
wizjany, zml2008, imjake9, Droolio, epuidokas,
|
||||
EduardBaer, TomyLobo, and halvors
|
||||
|
||||
## 5.2.2
|
||||
|
||||
* Changed configuration saving so empty lists will be added to the configuration files.
|
||||
|
||||
## 5.2.1
|
||||
|
||||
* Add region bounds to /region info
|
||||
* Added the ability to add owners/members to the global region for handling guest groups. Now if there's owners or members on the global region, then those that are not on the list cannot build.
|
||||
* Fixed some flag algorithm issues.
|
||||
* API: Fixed DefaultDomain.size() not counting players.
|
||||
* API: Undeprecated ApplicableRegionSet.allows(StateFlag).
|
||||
|
||||
## 5.2
|
||||
|
||||
* Gave the ability to use color colors and macros in greeting and farewell messages.
|
||||
* Added disable-ice-melting, disable-snow-formation, disable-mushroom-spread, disable-snow-melting, disable-ice-formation.
|
||||
* Added paintings to blacklist support.
|
||||
* Added default.disable-health-regain.
|
||||
* Added auto-invincible-permission setting, which lets you use the permission 'worldguard.auto-invincible' to become invincible on join automatically.
|
||||
* Flames won't appear if you are /god'ed now.
|
||||
* Added blocked-cmds region flag to block commands.
|
||||
* Added allowed-cmds region flag to whitelist commands.
|
||||
* Added entry region flag to block entry. Use entry-group to determine who this affects.
|
||||
* Added exit region flag to block exit. Use exit-group to determine who this affects.
|
||||
* Made negative healing possible via the healing flag.
|
||||
* Changed the configuration header messages to be more helpful to new users.
|
||||
* Added a warning about modifying region files by hand.
|
||||
* Improved the API for plugin developers.
|
||||
|
||||
## 5.1
|
||||
|
||||
* A lot of changes.
|
||||
|
||||
## 4.0-alpha1
|
||||
|
||||
* This release is only to fix WorldGuard for Bukkit. Ignore the 4.0 label. Just move along. Nothing to see.
|
||||
|
||||
## 3.2.2
|
||||
|
||||
* Changed disable-water-damage to disable-drowning-damage.
|
||||
* Fixed suffocation disable option.
|
||||
* Fixed fire spread blocking.
|
||||
* stopfire and allowfire now work in server console, just like in hMod.
|
||||
|
||||
## 3.2.1
|
||||
|
||||
* Updated for recent Bukkit ItemStack change.
|
||||
|
||||
## 3.2
|
||||
|
||||
* Added regions.default.pvp to control default PvP setting.
|
||||
* Updated WorldGuard for the newer builds of Bukkit.
|
||||
* Fixed creeper explosion blocking.
|
||||
* Added redstone support to sponges, removed classic water.
|
||||
* Fixed item durability disable for hoes.
|
||||
|
||||
|
||||
## 3.1.2
|
||||
|
||||
* Increased the priority of WorldGuard's event handling.
|
||||
|
||||
## 3.1.1
|
||||
|
||||
* Fixed creeper and chest flag conflicting.
|
||||
|
||||
## 3.1
|
||||
|
||||
* Added ability to disable chest protection. New configuration setting (regions.build.chest-access) and new chest flag.
|
||||
* Possibly fixed projectile blocking in no-PvP zones.
|
||||
* Added /regionmembership permission that lets people only change the owners and members of regions they own.
|
||||
|
||||
## 3.0b2
|
||||
|
||||
* Fixed issue where built-in permissions were not (re)loaded.
|
||||
* Fixed /god not working for others.
|
||||
|
||||
## 3.0b1
|
||||
|
||||
* Added parent-child relationships to regions.
|
||||
* Added global build flag.
|
||||
* Improved flag support.
|
||||
* Fixed no-PvP zone messages being sent to the wrong person.
|
||||
* Fixed commands so that they work in a recent version of Bukkit.
|
||||
* Fixed NullPointerException in explode hook.
|
||||
|
||||
## 2.3.1
|
||||
|
||||
* Fixed various cast exceptions with the blacklist loggers.
|
||||
* Added checks for unchecked exceptions when resolving permissions.
|
||||
* Fixed the item durability disable setting changing the damage value on an empty hand.
|
||||
|
||||
## 2.3
|
||||
|
||||
* /god now works very well.
|
||||
* Item (TNT, flint and steel, etc.) blocking should now work.
|
||||
* The TNT blocking configuration variable should now work.
|
||||
* Re-added /heal (not sure where that went), added /slay.
|
||||
* Implemented contact damage disable toggle.
|
||||
* Made all player damage disabling configuration parameters work.
|
||||
* Fixed teleport-on-suffocation setting.
|
||||
* Added /locate <name>, /locate <x> <y> <z>, and /locate that lets you program/change your compass bearing to point to a player's position (not yet live), a position, or back to spawn.
|
||||
* Fixed CSVDatabase spitting an error if the owners list was empty.
|
||||
|
||||
## 2.2
|
||||
|
||||
* Now supports GroupUsers.
|
||||
* Added support for blocking creeper explosions.
|
||||
* Fixed a bug where a player's groups were not being loaded correctly, causing the blacklist group ignore option to not work.
|
||||
|
||||
## 2.1.1
|
||||
|
||||
* Fixed fire spread disable preventing flint and steel too.
|
||||
* Fixed NullPointerException related to the player item event.
|
||||
* Made setup simpler.
|
||||
|
||||
## 2.1
|
||||
|
||||
* Improved Bukkit support.
|
||||
|
||||
## 2.0beta3
|
||||
|
||||
* Fixed NullPointerException inside the ignite hook.
|
||||
|
||||
## 2.0beta2
|
||||
|
||||
* Fixed a NullPointerException in the damage hook.
|
||||
|
||||
## 2.0beta1
|
||||
|
||||
* Added area protection. Use /region or /rg to define regions.
|
||||
|
||||
## 1.8.1
|
||||
|
||||
* Fixed NullPointerException.
|
||||
|
||||
## 1.8
|
||||
|
||||
* Updated for Minecraft beta.
|
||||
* Blacklist hooks have CHANGED. The new hooks are work better. on-create has been replaced with on-place (for block placement) and on-use (for item usage, light buckets and lighters). The old on-use is now on-right-click although it currently does nothing.
|
||||
* Added coordinates to blacklist file logger.
|
||||
* Added suffocation damage prevention.
|
||||
|
||||
## 1.7.1
|
||||
|
||||
* Updated for v0.2.8.
|
||||
|
||||
## 1.7
|
||||
|
||||
* Updated for v0.2.6_02 and hMod b129.
|
||||
* Added option to prevent water from damaging particular blocks (Redstone wire, Minecart tracks, etc.). See disable-water-damage-blocks.
|
||||
* /reload WorldGuard should now reload WorldGuard's configuration.
|
||||
* Added wg-invincible and wg-amphibious groups that let you give certain players invincibility or underwater breathing.
|
||||
* Added the ability to disable fall, water, lava, and/or fire damage.
|
||||
* Water/lava bucket blocking should now be more reliable.
|
||||
* Added /stack (alias /;) commands to stack items in your inventory into piles up to 64 items in size. Even unstackable items like signs can be stacked.
|
||||
* /god mode should now let you gain health.
|
||||
* /god mode should now work more reliably.
|
||||
* Caught an error message for when the configuration file does not exist.
|
||||
|
||||
## 1.6
|
||||
|
||||
* Added spawn protection that prevents damage when a player spawns.
|
||||
* Added login protection that prevents damage when a player joins.
|
||||
* Added /god. /god can be used on others, provided that the /godother permission is set for the command's user.
|
||||
|
||||
## 1.5.1
|
||||
|
||||
* Removed the 'java.lang.NoSuchMethodError: Item.setDamage(I)V' error generated.
|
||||
|
||||
## 1.5
|
||||
|
||||
* Removed the block lag fix.
|
||||
* WorldGuard now conditionally loads features so you can use any up-to-date build of hMod and the unsupported features won't break the entire plugin. When WG loads, check the server console for a report of features that are not supported by your version of hMod.
|
||||
* Changed some configuration defaults: disable-lava-fire=true simulate-sponge=true item-durability=false
|
||||
|
||||
## 1.4.1
|
||||
|
||||
* Fixed issue with the block lag fix dropping item stacks of 0 quantity.
|
||||
|
||||
## 1.4
|
||||
|
||||
* New on-acquire hook. This does both a total inventory check on inventory change and item pick up denial. The item pick up denial is largely thanks to Dinnerbone for fulfilling my request to add a particular hook.
|
||||
* Item durability can now be toggled with item-durability. Thanks to Dinnerbone for figuring this out while filfilling my request. The default setting is to fix item durability.
|
||||
* New no-physics-gravel and no-physics-sand options allow you to prevent gravel and sand from falling.
|
||||
* New allow-portal-anywhere option allows you to create portal blocks anywhere.
|
||||
|
||||
## 1.3
|
||||
|
||||
* UPGRADE WARNING: If you are using database logging, you must add a NULL 'comment' VARCHAR field to the table. The line of SQL that you can run for MySQL can be found in blacklist_table.sql.
|
||||
* Improved plugin compatibility with the block lag fix. For maximum compatibility, you must now list WorldGuard as the first plugin in server.properties and you cannot reload or enable the plugin while the server is up. This is for bad plugins that unnecessarily use the "critical" priority for its hooks like the LWC. Most plugins don't do that though, so this won't apply for most people.
|
||||
* Fixed signs being blank if they were denied via the blacklist.
|
||||
* Added on-break event to the blacklist.
|
||||
* Added comments and messages. Comments are only for your own use and they are printed with the log and notify actions of the blacklist. The message replaces the message that is shown the user and it is optional.
|
||||
* The blacklist notification messages are now more compact and are light grey instead of light purple.
|
||||
* The notify, log, and tell actions will now trigger every time for the on-break, on-create, on-drop events rather than wait 3 seconds between events for the same item or block for a player.
|
||||
|
||||
## 1.2
|
||||
|
||||
* /stopfire and /allowfire disable and enable fire spreading globally.
|
||||
* Block lag fix slightly improved in accuracy for item drops.
|
||||
* Sponge updated to remove water when the sponge block is set. Sponge radius can now be controlled using the 'sponge-radius' parameter and the default is now set to simulate Classic.
|
||||
* Updated for a newer build of "b126," meaning that lava spread control now works well!
|
||||
* A new summary of the status of some core protections is now printed on start. Disable this with 'summary-on-start'.
|
||||
* Blacklist system has been overhauled. Check README.txt for changed configuration settings!
|
||||
* The blacklist's method of preventing notification repeats is now better, instead waiting 3 seconds before notifying again (before it didn't notify again at all unless the user started using another blocked action).
|
||||
* To give users the ability to receive notifications, the command to give permission to has been changed to /worldguardnotify, although the old one (that was never mentioned anywhere) still works.
|
||||
* Water and lava buckets are now psuedo-blocked using an unreliable method that risks the stability of your server (no other plugin does it better though). Use it as your own risk.
|
||||
* Added on item drop and on item use (i.e. chest) events.
|
||||
* Chests, signs, and furnaces can now be blocked better with the blacklist system.
|
||||
* The event names in the blacklist configuration have changed but the old event names should still work. The new names should make "more sense."
|
||||
* A new "ban" action has been added to the blacklist.
|
||||
* Action messages have been improved, now longer saying "destroyed" for everything.
|
||||
* Logging to file has been completely changed, allowing you to use the date and time and the player's username in the log filename. It no longer rotates log files based on size, however.
|
||||
* Logging to database is now supported.
|
||||
* Tools can now be destroyed on drop to alleviate the durability cheat. You can do this with either with the blacklist or with the 'item-drop-blacklist' configuration option. The configuration option prints more friendly messages than the 'tell' action of blacklists.
|
||||
|
||||
## 1.1.2
|
||||
|
||||
* Block lag fix: Snow and glass should no longer drop items.
|
||||
* Block lag fix: Block object now reset after hook call.
|
||||
|
||||
## 1.1.1
|
||||
|
||||
* Fixed redstone wire dropping wood blocks with the block lag fix.
|
||||
* The block lag fix now consults other plugins so that ALL protection mechanisms and plugins should work.
|
||||
|
||||
## 1.1
|
||||
|
||||
* Added block lag fix.
|
||||
|
||||
## 1.0
|
||||
|
||||
* Initial release.
|
||||
-358
@@ -1,358 +0,0 @@
|
||||
5.5:
|
||||
- Removed WorldEdit.jar from the classpath to stop conflicts with Bukkit's plugin loader
|
||||
- Now using Bukkit's tagged logging
|
||||
- Updated to new event system
|
||||
- Flush player flag state cache on world change
|
||||
- Improved compatibility with versions of CommandBook without GodComponent and updated pom dep for 2.0
|
||||
- Added MySQL region storage method.
|
||||
- Made explosions display their animations even when the event was blocked.
|
||||
- Added fallback support for those who don't have a version of CommandBook with GodComponent
|
||||
- Added LIGHTNING flag to DefaultFlag's flagsList Fixes #1026
|
||||
- Removed /god, /heal, /locate, and /stack from WorldGuard to CommandBook. CommandBook is now checked to see whether a player is godded.
|
||||
- Removed remaining usages of org.bukkit.util.config.Configuration
|
||||
- Removed some unused configuration options
|
||||
- Added permission worldguard.region.wand to the region wand
|
||||
- Fixed ProtectedRegion.compareTo.
|
||||
- Fixed FlatRegionManager.getApplicableRegions to return parent regions as well.
|
||||
- Added exp-drops flag to disable experience drops per-region.
|
||||
- Fixed some warnings.
|
||||
- Updated dependency version for WorldGuard from 5.0 to 5.1-SNAPSHOT.
|
||||
- Added support for fireballs shot by players being blocked by the PVP flag.
|
||||
- Now using dynamic command registration
|
||||
- Split off ender dragon block damage from creeper block damage.
|
||||
|
||||
Contributions thanks to: narthollis, DarkArc, Wolvereness, and skeight
|
||||
|
||||
5.4:
|
||||
- Fixed configuration generation on Windows
|
||||
- Fixed intersection calculation for regions
|
||||
- Fixed timer and feeding delay for food flags
|
||||
- Fixed region managers not being created properly (This caused errors related to CREATURE_SPAWN)
|
||||
- Added support for Minecraft 1.0.1 blocks
|
||||
- Added support for enchantments and tool damage (worldguard.stack.damaged is the node) with /stack
|
||||
- Made being in the wg-invincible group respect the configuration's auto-invincible setting
|
||||
- Added per-group region claim limit maximum
|
||||
- Added worldguard.region.addowner.unclaimed.* permission for non-economy region 'buying'
|
||||
- Checking allowed/blocked commands now occurs earlier to override more plugins
|
||||
- Made PVP flag check whether either player is in a pvp deny region for blocking
|
||||
|
||||
Contributions thanks to: epuidokas, wizjany, Turtle9598, and DerFlash
|
||||
|
||||
5.3:
|
||||
- Added new config options and flags to better handle explosions of all types
|
||||
- Added config options and flags for snow, ice, mushroom spread, grass spread,
|
||||
and leaf decay
|
||||
- Added min and max health flags to clamp the values for the existing healing
|
||||
flags
|
||||
- Added hunger flags similar to the existing healing flags
|
||||
- Added an option to disable the use of the move event. This can boost
|
||||
performance on large servers but will disable the greeting/farewell
|
||||
and entry/exit flags
|
||||
- Added flag to prevent pistons (including those that are outside the
|
||||
region, but would affect blocks inside the region)
|
||||
- Added a /wg flushstates [player] command to free players stuck in a
|
||||
region that was exit-deny but no longer exists or the flag was removed
|
||||
- Added a config option to disable xp orb dropping
|
||||
- Added config option to disable redstone wire obsidian generators
|
||||
- Added a vehicle-destroy flag
|
||||
- Added enderman protection config and flag
|
||||
- Allowed and blocked command flags will now fall back to the global region
|
||||
- The worldguard.region.flag.own/member permissions are now
|
||||
worldguard.region.flag.regions.own/member! Please change your permissions
|
||||
accordingly.
|
||||
- Made //stack respect max stack sizes unless the player has the
|
||||
worldguard.stack.illegitimate permission
|
||||
- Setting invincibility flag to deny will override god mode unless the player
|
||||
has worldguard.god.override-regions
|
||||
- The sleep flag will now prevent beds in the nether from
|
||||
exploding if set to deny
|
||||
- Existing regions can no longer be accidentally overwritten.
|
||||
Use /region redefine to move an existing region.
|
||||
- The info command will now sort players alphabetically
|
||||
- Priming TNT by punching it with flint and steal should throw a blacklist
|
||||
event (consistent with old Minecraft versions)
|
||||
- The /stoplag command will now remove xp orbs
|
||||
- Permissions system will use per-world permissions if the provider supports it
|
||||
- Players in vehicles are now subject to entry/exit and greeting/farewell flags
|
||||
- Fixed interact blacklist event not logging correctly
|
||||
- Fixed heal flag taking effect half a block northeast of the region
|
||||
- Fixed a infinite sign dropping bug
|
||||
- Fixed players being able to douse fire by punching it in regions they
|
||||
couldn't build it
|
||||
- Fixed players being able to eat protected cake
|
||||
- Fence gate usage can be blocked with the use flag
|
||||
- Fixed chests being unprotected when they should be in 1.8
|
||||
- Fixed weather config settings not applying when a world was loaded
|
||||
- Fixed explosion handling in certain cases
|
||||
- Fixed arrows working in non-pvp zones
|
||||
- Fixed buckets working on the border of protected regions in certain cases
|
||||
Contributions thanks to:
|
||||
wizjany, zml2008, imjake9, Droolio, epuidokas,
|
||||
EduardBaer, TomyLobo, and halvors
|
||||
|
||||
5.2.2:
|
||||
- Changed configuration saving so empty lists will be added to
|
||||
the configuration files.
|
||||
|
||||
5.2.1:
|
||||
- Add region bounds to /region info
|
||||
- Added the ability to add owners/members to the global region for
|
||||
handling guest groups. Now if there's owners or members on the global
|
||||
region, then those that are not on the list cannot build.
|
||||
- Fixed some flag algorithm issues.
|
||||
- API: Fixed DefaultDomain.size() not counting players.
|
||||
- API: Undeprecated ApplicableRegionSet.allows(StateFlag).
|
||||
|
||||
5.2:
|
||||
- Gave the ability to use color colors and macros in greeting
|
||||
and farewell messages.
|
||||
- Added disable-ice-melting, disable-snow-formation, disable-mushroom-spread,
|
||||
disable-snow-melting, disable-ice-formation.
|
||||
- Added paintings to blacklist support.
|
||||
- Added default.disable-health-regain.
|
||||
- Added auto-invincible-permission setting, which lets you use the permission
|
||||
'worldguard.auto-invincible' to become invincible on join automatically.
|
||||
- Flames won't appear if you are /god'ed now.
|
||||
- Added blocked-cmds region flag to block commands.
|
||||
- Added allowed-cmds region flag to whitelist commands.
|
||||
- Added entry region flag to block entry. Use entry-group to determine who
|
||||
this affects.
|
||||
- Added exit region flag to block exit. Use exit-group to determine who
|
||||
this affects.
|
||||
- Made negative healing possible via the healing flag.
|
||||
- Changed the configuration header messages to be more helpful to new users.
|
||||
- Added a warning about modifying region files by hand.
|
||||
- Improved the API for plugin developers.
|
||||
|
||||
5.1:
|
||||
- A lot of changes.
|
||||
|
||||
4.0-alpha1:
|
||||
- This release is only to fix WorldGuard for Bukkit. Ignore the 4.0
|
||||
label. Just move along. Nothing to see.
|
||||
|
||||
3.2.2:
|
||||
- Changed disable-water-damage to disable-drowning-damage.
|
||||
- Fixed suffocation disable option.
|
||||
- Fixed fire spread blocking.
|
||||
- stopfire and allowfire now work in server console, just like in hMod.
|
||||
|
||||
3.2.1:
|
||||
- Updated for recent Bukkit ItemStack change.
|
||||
|
||||
3.2:
|
||||
- Added regions.default.pvp to control default PvP setting.
|
||||
- Updated WorldGuard for the newer builds of Bukkit.
|
||||
- Fixed creeper explosion blocking.
|
||||
- Added redstone support to sponges, removed classic water.
|
||||
- Fixed item durability disable for hoes.
|
||||
|
||||
|
||||
3.1.2:
|
||||
- Increased the priority of WorldGuard's event handling.
|
||||
|
||||
3.1.1:
|
||||
- Fixed creeper and chest flag conflicting.
|
||||
|
||||
3.1:
|
||||
- Added ability to disable chest protection. New configuration setting
|
||||
(regions.build.chest-access) and new chest flag.
|
||||
- Possibly fixed projectile blocking in no-PvP zones.
|
||||
- Added /regionmembership permission that lets people only change
|
||||
the owners and members of regions they own.
|
||||
|
||||
3.0b2:
|
||||
- Fixed issue where built-in permissions were not (re)loaded.
|
||||
- Fixed /god not working for others.
|
||||
|
||||
3.0b1:
|
||||
- Added parent-child relationships to regions.
|
||||
- Added global build flag.
|
||||
- Improved flag support.
|
||||
- Fixed no-PvP zone messages being sent to the wrong person.
|
||||
- Fixed commands so that they work in a recent version of Bukkit.
|
||||
- Fixed NullPointerException in explode hook.
|
||||
|
||||
2.3.1:
|
||||
- Fixed various cast exceptions with the blacklist loggers.
|
||||
- Added checks for unchecked exceptions when resolving permissions.
|
||||
- Fixed the item durability disable setting changing the damage value on
|
||||
an empty hand.
|
||||
|
||||
2.3:
|
||||
- /god now works very well.
|
||||
- Item (TNT, flint and steel, etc.) blocking should now work.
|
||||
- The TNT blocking configuration variable should now work.
|
||||
- Re-added /heal (not sure where that went), added /slay.
|
||||
- Implemented contact damage disable toggle.
|
||||
- Made all player damage disabling configuration parameters work.
|
||||
- Fixed teleport-on-suffocation setting.
|
||||
- Added /locate <name>, /locate <x> <y> <z>, and /locate that lets you
|
||||
program/change your compass bearing to point to a player's position
|
||||
(not yet live), a position, or back to spawn.
|
||||
- Fixed CSVDatabase spitting an error if the owners list was empty.
|
||||
|
||||
2.2:
|
||||
- Now supports GroupUsers.
|
||||
- Added support for blocking creeper explosions.
|
||||
- Fixed a bug where a player's groups were not being loaded correctly,
|
||||
causing the blacklist group ignore option to not work.
|
||||
|
||||
2.1.1:
|
||||
- Fixed fire spread disable preventing flint and steel too.
|
||||
- Fixed NullPointerException related to the player item event.
|
||||
- Made setup simpler.
|
||||
|
||||
2.1:
|
||||
- Improved Bukkit support.
|
||||
|
||||
2.0beta3:
|
||||
- Fixed NullPointerException inside the ignite hook.
|
||||
|
||||
2.0beta2:
|
||||
- Fixed a NullPointerException in the damage hook.
|
||||
|
||||
2.0beta1:
|
||||
- Added area protection. Use /region or /rg to define regions.
|
||||
|
||||
1.8.1
|
||||
- Fixed NullPointerException.
|
||||
|
||||
1.8
|
||||
- Updated for Minecraft beta.
|
||||
- Blacklist hooks have CHANGED. The new hooks are work better. on-create has
|
||||
been replaced with on-place (for block placement) and on-use
|
||||
(for item usage, light buckets and lighters). The old on-use is now
|
||||
on-right-click although it currently does nothing.
|
||||
- Added coordinates to blacklist file logger.
|
||||
- Added suffocation damage prevention.
|
||||
|
||||
1.7.1
|
||||
- Updated for v0.2.8.
|
||||
|
||||
1.7
|
||||
- Updated for v0.2.6_02 and hMod b129.
|
||||
- Added option to prevent water from damaging particular blocks
|
||||
(Redstone wire, Minecart tracks, etc.). See disable-water-damage-blocks.
|
||||
- /reload WorldGuard should now reload WorldGuard's configuration.
|
||||
- Added wg-invincible and wg-amphibious groups that let you give certain
|
||||
players invincibility or underwater breathing.
|
||||
- Added the ability to disable fall, water, lava, and/or fire damage.
|
||||
- Water/lava bucket blocking should now be more reliable.
|
||||
- Added /stack (alias /;) commands to stack items in your inventory into
|
||||
piles up to 64 items in size. Even unstackable items like signs can be
|
||||
stacked.
|
||||
- /god mode should now let you gain health.
|
||||
- /god mode should now work more reliably.
|
||||
- Caught an error message for when the configuration file does not exist.
|
||||
|
||||
1.6
|
||||
- Added spawn protection that prevents damage when a player spawns.
|
||||
- Added login protection that prevents damage when a player joins.
|
||||
- Added /god. /god can be used on others, provided that the /godother
|
||||
permission is set for the command's user.
|
||||
|
||||
1.5.1
|
||||
- Removed the 'java.lang.NoSuchMethodError: Item.setDamage(I)V' error
|
||||
generated.
|
||||
|
||||
1.5
|
||||
- Removed the block lag fix.
|
||||
- WorldGuard now conditionally loads features so you can use any up-to-date
|
||||
build of hMod and the unsupported features won't break the entire
|
||||
plugin. When WG loads, check the server console for a report of
|
||||
features that are not supported by your version of hMod.
|
||||
- Changed some configuration defaults:
|
||||
disable-lava-fire=true
|
||||
simulate-sponge=true
|
||||
item-durability=false
|
||||
|
||||
1.4.1
|
||||
- Fixed issue with the block lag fix dropping item stacks of 0 quantity.
|
||||
|
||||
1.4
|
||||
- New on-acquire hook. This does both a total inventory check on inventory
|
||||
change and item pick up denial. The item pick up denial is largely
|
||||
thanks to Dinnerbone for fulfilling my request to add a particular hook.
|
||||
- Item durability can now be toggled with item-durability. Thanks to
|
||||
Dinnerbone for figuring this out while filfilling my request. The
|
||||
default setting is to fix item durability.
|
||||
- New no-physics-gravel and no-physics-sand options allow you to
|
||||
prevent gravel and sand from falling.
|
||||
- New allow-portal-anywhere option allows you to create portal blocks
|
||||
anywhere.
|
||||
|
||||
1.3
|
||||
- UPGRADE WARNING: If you are using database logging, you must add a
|
||||
NULL 'comment' VARCHAR field to the table. The line of SQL that you
|
||||
can run for MySQL can be found in blacklist_table.sql.
|
||||
- Improved plugin compatibility with the block lag fix. For maximum
|
||||
compatibility, you must now list WorldGuard as the first plugin in
|
||||
server.properties and you cannot reload or enable the plugin
|
||||
while the server is up. This is for bad plugins that unnecessarily
|
||||
use the "critical" priority for its hooks like the LWC. Most plugins
|
||||
don't do that though, so this won't apply for most people.
|
||||
- Fixed signs being blank if they were denied via the blacklist.
|
||||
- Added on-break event to the blacklist.
|
||||
- Added comments and messages. Comments are only for your own use and they
|
||||
are printed with the log and notify actions of the blacklist. The
|
||||
message replaces the message that is shown the user and it is optional.
|
||||
- The blacklist notification messages are now more compact and are
|
||||
light grey instead of light purple.
|
||||
- The notify, log, and tell actions will now trigger every time for the
|
||||
on-break, on-create, on-drop events rather than wait 3 seconds between
|
||||
events for the same item or block for a player.
|
||||
|
||||
1.2
|
||||
- /stopfire and /allowfire disable and enable fire spreading globally.
|
||||
- Block lag fix slightly improved in accuracy for item drops.
|
||||
- Sponge updated to remove water when the sponge block is set. Sponge radius
|
||||
can now be controlled using the 'sponge-radius' parameter and the
|
||||
default is now set to simulate Classic.
|
||||
- Updated for a newer build of "b126," meaning that lava spread control
|
||||
now works well!
|
||||
- A new summary of the status of some core protections is now printed
|
||||
on start. Disable this with 'summary-on-start'.
|
||||
- Blacklist system has been overhauled. Check README.txt for changed
|
||||
configuration settings!
|
||||
- The blacklist's method of preventing notification repeats is now better,
|
||||
instead waiting 3 seconds before notifying again (before it didn't
|
||||
notify again at all unless the user started using another blocked
|
||||
action).
|
||||
- To give users the ability to receive notifications, the command to give
|
||||
permission to has been changed to /worldguardnotify, although the
|
||||
old one (that was never mentioned anywhere) still works.
|
||||
- Water and lava buckets are now psuedo-blocked using an unreliable
|
||||
method that risks the stability of your server (no other plugin
|
||||
does it better though). Use it as your own risk.
|
||||
- Added on item drop and on item use (i.e. chest) events.
|
||||
- Chests, signs, and furnaces can now be blocked better with the
|
||||
blacklist system.
|
||||
- The event names in the blacklist configuration have changed but the old
|
||||
event names should still work. The new names should make "more sense."
|
||||
- A new "ban" action has been added to the blacklist.
|
||||
- Action messages have been improved, now longer saying "destroyed"
|
||||
for everything.
|
||||
- Logging to file has been completely changed, allowing you to use
|
||||
the date and time and the player's username in the log filename. It
|
||||
no longer rotates log files based on size, however.
|
||||
- Logging to database is now supported.
|
||||
- Tools can now be destroyed on drop to alleviate the durability cheat.
|
||||
You can do this with either with the blacklist or with the
|
||||
'item-drop-blacklist' configuration option. The configuration option
|
||||
prints more friendly messages than the 'tell' action of blacklists.
|
||||
|
||||
1.1.2
|
||||
- Block lag fix: Snow and glass should no longer drop items.
|
||||
- Block lag fix: Block object now reset after hook call.
|
||||
|
||||
1.1.1
|
||||
- Fixed redstone wire dropping wood blocks with the block lag fix.
|
||||
- The block lag fix now consults other plugins so that ALL protection
|
||||
mechanisms and plugins should work.
|
||||
|
||||
1.1
|
||||
- Added block lag fix.
|
||||
|
||||
1.0
|
||||
- Initial release.
|
||||
@@ -0,0 +1,68 @@
|
||||
# Contributing
|
||||
|
||||
Thank you for your interest in contributing to WorldGuard! We appreciate your
|
||||
effort, but to make sure that the inclusion of your patch is a smooth process, we
|
||||
ask that you make note of the following guidelines.
|
||||
|
||||
* **Follow the [Oracle coding conventions](https://www.oracle.com/technetwork/java/javase/documentation/codeconvtoc-136057.html).**
|
||||
We can't stress this enough; if your code has notable issues, it may delay
|
||||
the process significantly.
|
||||
* **Target Java 6 for source and compilation.** Make sure to mark methods with
|
||||
` @Override` that override methods of parent classes, or that implement
|
||||
methods of interfaces (Java 6+).
|
||||
* **Use only spaces for indentation.** Our indents are 4-spaces long, and tabs
|
||||
are unacceptable.
|
||||
* **Wrap code to a 89 column limit.** We do this to make side by side diffs
|
||||
and other such tasks easier. Ignore this guideline if it makes the code
|
||||
too unreadable.
|
||||
* **Write complete Javadocs.** Do so only for public methods, and make sure
|
||||
that your `@param` and `@return` fields are not just blank.
|
||||
* **Don't tag classes with @author.** Some legacy classes may have this tag,
|
||||
but we are phasing it out.
|
||||
* **Make sure the code is efficient.** One way you can achieve this is to spend
|
||||
around ten minutes to think about what the code is doing and whether it
|
||||
seems awfully roundabout. If you had to copy the same large piece of
|
||||
code in several places, that's bad.
|
||||
* **Keep commit summaries under 70 characters.** For more details, place two
|
||||
new lines after the summary line and write away!
|
||||
* **Test your code.** We're not interested in broken code, for the obvious reasons.
|
||||
* **Write unit tests.** While this is strictly optional, we recommend it for
|
||||
complicated algorithms.
|
||||
|
||||
|
||||
Checklist
|
||||
---------
|
||||
|
||||
Ready to submit? Perform the checklist below:
|
||||
|
||||
1. Have all tabs been replaced into four spaces? Are indentations 4-space wide?
|
||||
2. Have I written proper Javadocs for my public methods? Are the @param and
|
||||
@return fields actually filled out?
|
||||
3. Have I `git rebase`d my pull request to the latest commit of the target
|
||||
branch?
|
||||
4. Have I combined my commits into a reasonably small number (if not one)
|
||||
commit using `git rebase`?
|
||||
5. Have I made my pull request too large? Pull requests should introduce
|
||||
small sets of changes at a time. Major changes should be discussed with
|
||||
the team prior to starting work.
|
||||
6. Are my commit messages descriptive?
|
||||
|
||||
You should be aware of [`git rebase`](http://learn.github.com/p/rebasing.html).
|
||||
It allows you to modify existing commit messages, and combine, break apart, or
|
||||
adjust past changes.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
This is **GOOD:**
|
||||
|
||||
if (var.func(param1, param2)) {
|
||||
// do things
|
||||
}
|
||||
|
||||
This is **EXTREMELY BAD:**
|
||||
|
||||
if(var.func( param1, param2 ))
|
||||
{
|
||||
// do things
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
WorldGuard, a suite of tools for Minecraft
|
||||
Copyright (C) sk89q <http://www.sk89q.com>
|
||||
Copyright (C) WorldGuard team and contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by the
|
||||
Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+200
-202
@@ -1,203 +1,201 @@
|
||||
----------------------------------------------------------------------------
|
||||
WorldGuard License
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
PRTree License
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2008-2010 Robert Olofsson.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the authors nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
This work includes Robert Olofsson's Priority R-Tree implementation, for which
|
||||
its license is reproduced below.
|
||||
|
||||
Copyright (c) 2008-2010 Robert Olofsson.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the authors nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
-116
@@ -1,116 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>WorldGuard ${version}</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
background: #efefef;
|
||||
color: #333;
|
||||
}
|
||||
#wrapper {
|
||||
margin: 20px auto 20px auto;
|
||||
width: 600px;
|
||||
background: #fff;
|
||||
padding: 40px;
|
||||
border: 1px solid #fff;
|
||||
border-radius: 10px;
|
||||
-moz-border-radius: 10px;
|
||||
-webkit-border-radius: 10px;
|
||||
box-shadow: 0 0 2px #999;
|
||||
-webkit-box-shadow: 0 0 3px #999;
|
||||
}
|
||||
a img {
|
||||
border: 0;
|
||||
}
|
||||
body, th, td, input {
|
||||
font: 13px/17px "Lucida Grande", "Lucida Sans Unicode", Arial, Verdana, sans-serif;
|
||||
}
|
||||
a:link, a:visited {
|
||||
color: #00688f;
|
||||
text-decoration: underline;
|
||||
}
|
||||
a:hover, a:active {
|
||||
color: #000;
|
||||
border: 0;
|
||||
}
|
||||
h1 {
|
||||
font: 170% "Trebuchet MS", Georgia, serif;
|
||||
font-weight: bold;
|
||||
color: #b90000;
|
||||
margin: 15px 0 5px 0;
|
||||
}
|
||||
h2 {
|
||||
font: 130% "Trebuchet MS", Georgia, serif;
|
||||
font-weight: bold;
|
||||
color: #6a45ac;
|
||||
margin: 50px 0 5px 0;
|
||||
padding: 0 0 3px 0;
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
.warning {
|
||||
background: #fffedf;
|
||||
padding: 8px;
|
||||
border: 1px dashed #ccc;
|
||||
border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
font-size: 90%;
|
||||
}
|
||||
.subtle {
|
||||
color: #999;
|
||||
}
|
||||
.optional {
|
||||
background: none repeat scroll 0 0 #FFE081;
|
||||
border-radius: 3px 3px 3px 3px;
|
||||
font-size: 80%;
|
||||
font-weight: normal;
|
||||
padding: 1px 4px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="wrapper">
|
||||
|
||||
<h1>WorldGuard ${version}</h1>
|
||||
<p>Thanks for choosing WorldGuard!</p>
|
||||
<h2>Getting Started</h2>
|
||||
|
||||
<p>Now, to begin, you want to:</p>
|
||||
<ol>
|
||||
<li><strong>Install the plugin:</strong> Copy WorldGuard.jar into your Bukkit server's "plugins" directory.</li>
|
||||
<li><strong>Change the configuration:</strong> Run your server once (with WorldGuard) to generate the default configuration files. There are <em>two</em> types of configuration files:
|
||||
<ul>
|
||||
<li>The main config.yml file inside "plugins/WorldGuard" is the main configuration. </li>
|
||||
<li>Each world has a configuration file in "plugins/WorldGuard/worlds" that you can use to override any setting in the main configuration file for that specific world.</li>
|
||||
</ul>
|
||||
</li>
|
||||
Use <em>/wg reload</em> in the console to reload the configuration.
|
||||
<li><strong>Learn how to use WorldGuard:</strong> Check <a href="http://wiki.sk89q.com/wiki/WorldGuard">out the wiki</a> to learn how to disable things like fire and to protect regions.</li>
|
||||
</ol>
|
||||
<p class="warning"><strong>Note:</strong> <a href="http://www.sk89q.com/projects/worldedit/">WorldEdit</a> must be installed, but if you do not want it, put WorldEdit.jar into your Bukkit root folder (outside of plugins/). Note that region protection requires WorldEdit in plugins/.</p>
|
||||
<p>Be sure to:</p>
|
||||
<ul>
|
||||
<li>Subscribe to <a href="http://minecraftnews.sk89q.com/">SK's Minecraft blog</a> for news about WorldGuard</li>
|
||||
<li>Idle with us in IRC at <a href="http://skq.me/irc/irc.esper.net/worldguard">irc.esper.net in #worldguard</a></li>
|
||||
</ul>
|
||||
<h2>Getting Help</h2>
|
||||
<p>If you need help, the best two ways to ask are:</p>
|
||||
<ul>
|
||||
<li><a href="http://forum.sk89q.com/">Visit the WorldGuard forum</a></li>
|
||||
<li>Ask in IRC chat on <a href="http://skq.me/irc/irc.esper.net/worldguard">irc.esper.net in #worldguard</a> (idle with us!)</li>
|
||||
<li>Submit bug reports and suggestions to the <a href="http://redmine.sk89q.com/projects/worldguard/issues">issue tracker</a></li>
|
||||
</ul>
|
||||
<h2>Contributing</h2>
|
||||
<p>WorldGuard is entirely open source! You can download all of the plugin code to learn from it, modify it for your own self, or even contribute back!</p>
|
||||
<ul>
|
||||
<li><a href="https://github.com/sk89q/worldguard">Download WorldGuard code from GitHub</a></li>
|
||||
<li>You can also <a href="http://www.sk89q.com/donate/">donate</a></li>
|
||||
</ul>
|
||||
<p>The code is covered under the GNU General Public License v3.</p>
|
||||
<p class="subtle">Maven information: ${groupId}/${artifactId}/${version}</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,25 +1,46 @@
|
||||
WorldGuard
|
||||
==========
|
||||
|
||||
WorldGuard protects your Minecraft server. As Minecraft's oldest surviving world protection mod, you know you're in safe hands.
|
||||
|
||||
Compiling
|
||||
---------
|
||||
|
||||
You need to have Maven installed (http://maven.apache.org). Once installed,
|
||||
simply run:
|
||||
|
||||
mvn clean install
|
||||
|
||||
Maven will automatically download dependencies for you. Note: For that to work,
|
||||
be sure to add Maven to your "PATH".
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
We happily accept contributions. The best way to do this is to fork WorldGuard
|
||||
on GitHub, add your changes, and then submit a pull request. We'll look at it,
|
||||
make comments, and merge it into WorldGuard if everything works out.
|
||||
|
||||
By submitting code, you agree to place to license your code under the
|
||||
GNU General Public License v3.
|
||||
# 
|
||||
|
||||
WorldGuard lets you and players guard areas of land against griefers and undesirables, as well as tweak and disable various gameplay features of Minecraft.
|
||||
|
||||
* Block creeper and wither block damage, falling damage, etc.;
|
||||
* Disable fire spread, lava fire spread, ice formation, Endermen picking up blocks, etc.;
|
||||
* Blacklist certain items and blocks so they can't be used;
|
||||
* Warn moderators when certain items and blocks are used;
|
||||
* Protect areas of your world so only certain people can build in them;
|
||||
* Set areas where PVP, TNT, mob damage, and other features are disabled;
|
||||
* Protect your server from various 'exploits' like magical obsidian creation machines;
|
||||
* Disable, or enable, various Minecraft features, like sponges from classic;
|
||||
* Add useful commands like an immediate "STOP ALL FIRE SPREAD" command.
|
||||
* Enable only features you want! Everything is off by default.
|
||||
|
||||
WorldGuard is open source and is available under the GNU Lesser
|
||||
General Public License v3.
|
||||
|
||||
Currently, Bukkit is required to use WorldGuard. You can get a release copy of WorldGuard from the [BukkitDev site](http://dev.bukkit.org/bukkit-plugins/worldguard/).
|
||||
|
||||
Compiling
|
||||
---------
|
||||
|
||||
The project is written for Java 8 and our build process makes use of
|
||||
[Gradle](http://gradle.org).
|
||||
|
||||
Dependencies are automatically handled by Gradle.
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
We happily accept contributions, especially through pull requests on GitHub.
|
||||
|
||||
Please read CONTRIBUTING.md for important guidelines to follow.
|
||||
|
||||
Submissions must be licensed under the GNU Lesser General Public License v3.
|
||||
|
||||
Links
|
||||
-----
|
||||
|
||||
* [Homepage](http://enginehub.org/worldguard)
|
||||
* [Discord](https://discord.gg/enginehub)
|
||||
* [IRC channel](https://webchat.esper.net/?join=sk89q) (#sk89q on irc.esper.net)
|
||||
* [Issue tracker](https://dev.enginehub.org/issues/WORLDGUARD)
|
||||
* [Continuous integration](http://builds.enginehub.org) [](http://ci.enginehub.org/viewType.html?buildTypeId=bt11&guest=1)
|
||||
* [End-user documentation](https://worldguard.enginehub.org/en/latest/)
|
||||
@@ -0,0 +1,26 @@
|
||||
import org.ajoberstar.grgit.Grgit
|
||||
|
||||
logger.lifecycle("""
|
||||
*******************************************
|
||||
You are building WorldGuard!
|
||||
If you encounter trouble:
|
||||
1) Try running 'build' in a separate Gradle run
|
||||
2) Use gradlew and not gradle
|
||||
3) If you still need help, ask on Discord! https://discord.gg/enginehub
|
||||
|
||||
Output files will be in [subproject]/build/libs
|
||||
*******************************************
|
||||
""")
|
||||
|
||||
applyRootArtifactoryConfig()
|
||||
|
||||
if (!project.hasProperty("gitCommitHash")) {
|
||||
apply(plugin = "org.ajoberstar.grgit")
|
||||
ext["gitCommitHash"] = try {
|
||||
(ext["grgit"] as Grgit?)?.head()?.abbreviatedId
|
||||
} catch (e: Exception) {
|
||||
logger.warn("Error getting commit hash", e)
|
||||
|
||||
"no_git_id"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
plugins {
|
||||
`kotlin-dsl`
|
||||
kotlin("jvm") version embeddedKotlinVersion
|
||||
}
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(gradleApi())
|
||||
implementation("gradle.plugin.net.minecrell:licenser:0.4.1")
|
||||
implementation("org.ajoberstar.grgit:grgit-gradle:3.1.1")
|
||||
implementation("com.github.jengelman.gradle.plugins:shadow:5.1.0")
|
||||
implementation("net.ltgt.apt-eclipse:net.ltgt.apt-eclipse.gradle.plugin:0.21")
|
||||
implementation("net.ltgt.apt-idea:net.ltgt.apt-idea.gradle.plugin:0.21")
|
||||
implementation("org.jfrog.buildinfo:build-info-extractor-gradle:4.9.7")
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.apply
|
||||
import org.gradle.kotlin.dsl.configure
|
||||
import org.gradle.kotlin.dsl.named
|
||||
import org.jfrog.gradle.plugin.artifactory.dsl.ArtifactoryPluginConvention
|
||||
import org.jfrog.gradle.plugin.artifactory.task.ArtifactoryTask
|
||||
|
||||
private const val ARTIFACTORY_CONTEXT_URL = "artifactory_contextUrl"
|
||||
private const val ARTIFACTORY_USER = "artifactory_user"
|
||||
private const val ARTIFACTORY_PASSWORD = "artifactory_password"
|
||||
|
||||
fun Project.applyRootArtifactoryConfig() {
|
||||
if (!project.hasProperty(ARTIFACTORY_CONTEXT_URL)) ext[ARTIFACTORY_CONTEXT_URL] = "http://localhost"
|
||||
if (!project.hasProperty(ARTIFACTORY_USER)) ext[ARTIFACTORY_USER] = "guest"
|
||||
if (!project.hasProperty(ARTIFACTORY_PASSWORD)) ext[ARTIFACTORY_PASSWORD] = ""
|
||||
|
||||
apply(plugin = "com.jfrog.artifactory")
|
||||
configure<ArtifactoryPluginConvention> {
|
||||
setContextUrl("${project.property(ARTIFACTORY_CONTEXT_URL)}")
|
||||
clientConfig.publisher.run {
|
||||
repoKey = when {
|
||||
"${project.version}".contains("SNAPSHOT") -> "libs-snapshot-local"
|
||||
else -> "libs-release-local"
|
||||
}
|
||||
username = "${project.property(ARTIFACTORY_USER)}"
|
||||
password = "${project.property(ARTIFACTORY_PASSWORD)}"
|
||||
isMaven = true
|
||||
isIvy = false
|
||||
}
|
||||
}
|
||||
tasks.named<ArtifactoryTask>("artifactoryPublish") {
|
||||
isSkip = true
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.applyCommonArtifactoryConfig() {
|
||||
val named = tasks.named<ArtifactoryTask>("artifactoryPublish") {
|
||||
publishConfigs("archives")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.repositories
|
||||
|
||||
fun Project.applyCommonConfiguration() {
|
||||
group = rootProject.group
|
||||
version = rootProject.version
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url = uri("https://maven.sk89q.com/repo/") }
|
||||
maven { url = uri("https://oss.sonatype.org/content/repositories/snapshots/") }
|
||||
}
|
||||
configurations.all {
|
||||
resolutionStrategy {
|
||||
cacheChangingModulesFor(5, "minutes")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.plugins.ExtraPropertiesExtension
|
||||
import org.gradle.api.plugins.JavaPluginConvention
|
||||
import org.gradle.api.tasks.SourceSetContainer
|
||||
import org.gradle.kotlin.dsl.getByType
|
||||
import org.gradle.kotlin.dsl.the
|
||||
|
||||
val Project.ext: ExtraPropertiesExtension
|
||||
get() = extensions.getByType()
|
||||
|
||||
val Project.sourceSets: SourceSetContainer
|
||||
get() = the<JavaPluginConvention>().sourceSets
|
||||
@@ -0,0 +1,96 @@
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.ModuleDependency
|
||||
import org.gradle.api.internal.HasConvention
|
||||
import org.gradle.api.plugins.MavenRepositoryHandlerConvention
|
||||
import org.gradle.api.tasks.Upload
|
||||
import org.gradle.api.tasks.bundling.Jar
|
||||
import org.gradle.kotlin.dsl.apply
|
||||
import org.gradle.kotlin.dsl.get
|
||||
import org.gradle.kotlin.dsl.getPlugin
|
||||
import org.gradle.kotlin.dsl.invoke
|
||||
import org.gradle.kotlin.dsl.register
|
||||
|
||||
fun Project.applyLibrariesConfiguration() {
|
||||
applyCommonConfiguration()
|
||||
apply(plugin = "java-base")
|
||||
apply(plugin = "maven")
|
||||
apply(plugin = "com.github.johnrengelman.shadow")
|
||||
apply(plugin = "com.jfrog.artifactory")
|
||||
|
||||
configurations {
|
||||
create("shade")
|
||||
getByName("archives").extendsFrom(getByName("default"))
|
||||
}
|
||||
|
||||
group = "${rootProject.group}.worldguard-libs"
|
||||
|
||||
tasks.register<ShadowJar>("jar") {
|
||||
configurations = listOf(project.configurations["shade"])
|
||||
archiveClassifier.set("")
|
||||
|
||||
dependencies {
|
||||
exclude(dependency("com.google.code.findbugs:jsr305:1.3.9"))
|
||||
}
|
||||
|
||||
relocate("com.sk89q.squirrelid", "com.sk89q.worldguard.util.profile")
|
||||
}
|
||||
val altConfigFiles = { artifactType: String ->
|
||||
val deps = configurations["shade"].incoming.dependencies
|
||||
.filterIsInstance<ModuleDependency>()
|
||||
.map { it.copy() }
|
||||
.map { dependency ->
|
||||
dependency.artifact {
|
||||
name = dependency.name
|
||||
type = artifactType
|
||||
extension = "jar"
|
||||
classifier = artifactType
|
||||
}
|
||||
dependency
|
||||
}
|
||||
|
||||
files(configurations.detachedConfiguration(*deps.toTypedArray())
|
||||
.resolvedConfiguration.lenientConfiguration.artifacts
|
||||
.filter { it.classifier == artifactType }
|
||||
.map { zipTree(it.file) })
|
||||
}
|
||||
tasks.register<Jar>("sourcesJar") {
|
||||
from({
|
||||
altConfigFiles("sources")
|
||||
})
|
||||
val filePattern = Regex("(.*)com/sk89q/squirrelid((?:/|$).*)")
|
||||
val textPattern = Regex("com\\.sk89q\\.squirrelid")
|
||||
eachFile {
|
||||
filter {
|
||||
it.replaceFirst(textPattern, "com.sk89q.worldguard.util.profile")
|
||||
}
|
||||
path = path.replaceFirst(filePattern, "$1com/sk89q/worldguard/util/profile$2")
|
||||
}
|
||||
archiveClassifier.set("sources")
|
||||
}
|
||||
|
||||
tasks.named("assemble").configure {
|
||||
dependsOn("jar", "sourcesJar")
|
||||
}
|
||||
|
||||
artifacts {
|
||||
val jar = tasks.named("jar")
|
||||
add("default", jar) {
|
||||
builtBy(jar)
|
||||
}
|
||||
val sourcesJar = tasks.named("sourcesJar")
|
||||
add("archives", sourcesJar) {
|
||||
builtBy(sourcesJar)
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register<Upload>("install") {
|
||||
configuration = configurations["archives"]
|
||||
(repositories as HasConvention).convention.getPlugin<MavenRepositoryHandlerConvention>().mavenInstaller {
|
||||
pom.version = project.version.toString()
|
||||
pom.artifactId = project.name
|
||||
}
|
||||
}
|
||||
|
||||
applyCommonArtifactoryConfig()
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import net.minecrell.gradle.licenser.LicenseExtension
|
||||
import org.gradle.api.JavaVersion
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.plugins.JavaPluginConvention
|
||||
import org.gradle.api.plugins.quality.CheckstyleExtension
|
||||
import org.gradle.api.tasks.bundling.Jar
|
||||
import org.gradle.api.tasks.javadoc.Javadoc
|
||||
import org.gradle.api.tasks.testing.Test
|
||||
import org.gradle.external.javadoc.CoreJavadocOptions
|
||||
import org.gradle.kotlin.dsl.apply
|
||||
import org.gradle.kotlin.dsl.configure
|
||||
import org.gradle.kotlin.dsl.dependencies
|
||||
import org.gradle.kotlin.dsl.get
|
||||
import org.gradle.kotlin.dsl.getByName
|
||||
import org.gradle.kotlin.dsl.named
|
||||
import org.gradle.kotlin.dsl.register
|
||||
import org.gradle.kotlin.dsl.withType
|
||||
|
||||
fun Project.applyPlatformAndCoreConfiguration() {
|
||||
applyCommonConfiguration()
|
||||
apply(plugin = "java")
|
||||
apply(plugin = "eclipse")
|
||||
apply(plugin = "idea")
|
||||
apply(plugin = "maven")
|
||||
apply(plugin = "checkstyle")
|
||||
apply(plugin = "com.github.johnrengelman.shadow")
|
||||
apply(plugin = "com.jfrog.artifactory")
|
||||
apply(plugin = "net.minecrell.licenser")
|
||||
|
||||
ext["internalVersion"] = "$version;${rootProject.ext["gitCommitHash"]}"
|
||||
|
||||
configure<JavaPluginConvention> {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
configure<CheckstyleExtension> {
|
||||
configFile = rootProject.file("config/checkstyle/checkstyle.xml")
|
||||
toolVersion = "7.6.1"
|
||||
}
|
||||
|
||||
tasks.withType<Test>().configureEach {
|
||||
useJUnit()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
"testCompile"("junit:junit:${Versions.JUNIT}")
|
||||
// TODO switch to jupiter - doesn't support abstract test classes so tests need rewriting
|
||||
//"testImplementation"("org.junit.jupiter:junit-jupiter-api:${Versions.JUNIT}")
|
||||
//"testRuntime"("org.junit.jupiter:junit-jupiter-engine:${Versions.JUNIT}")
|
||||
}
|
||||
|
||||
// Java 8 turns on doclint which we fail
|
||||
tasks.withType<Javadoc>().configureEach {
|
||||
(options as CoreJavadocOptions).addStringOption("Xdoclint:none", "-quiet")
|
||||
}
|
||||
|
||||
tasks.register<Jar>("javadocJar") {
|
||||
dependsOn("javadoc")
|
||||
archiveClassifier.set("javadoc")
|
||||
from(tasks.getByName<Javadoc>("javadoc").destinationDir)
|
||||
}
|
||||
|
||||
tasks.named("assemble").configure {
|
||||
dependsOn("javadocJar")
|
||||
}
|
||||
|
||||
artifacts {
|
||||
add("archives", tasks.named("jar"))
|
||||
add("archives", tasks.named("javadocJar"))
|
||||
}
|
||||
|
||||
if (name == "worldguard-core" || name == "worldguard-bukkit") {
|
||||
tasks.register<Jar>("sourcesJar") {
|
||||
dependsOn("classes")
|
||||
archiveClassifier.set("sources")
|
||||
from(sourceSets["main"].allSource)
|
||||
}
|
||||
|
||||
artifacts {
|
||||
add("archives", tasks.named("sourcesJar"))
|
||||
}
|
||||
tasks.named("assemble").configure {
|
||||
dependsOn("sourcesJar")
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named("check").configure {
|
||||
dependsOn("checkstyleMain", "checkstyleTest")
|
||||
}
|
||||
|
||||
applyCommonArtifactoryConfig()
|
||||
|
||||
configure<LicenseExtension> {
|
||||
header = rootProject.file("HEADER.txt")
|
||||
include("**/*.java")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun Project.applyShadowConfiguration() {
|
||||
tasks.named<ShadowJar>("shadowJar") {
|
||||
archiveClassifier.set("dist")
|
||||
dependencies {
|
||||
include(project(":worldguard-libs:core"))
|
||||
//include(project(":worldguard-libs:${project.name.replace("worldguard-", "")}"))
|
||||
include(project(":worldguard-core"))
|
||||
|
||||
relocate("org.flywaydb", "com.sk89q.worldguard.internal.flywaydb") {
|
||||
include(dependency("org.flywaydb:flyway-core:3.0"))
|
||||
}
|
||||
relocate("com.sk89q.squirrelid", "com.sk89q.worldguard.util.profile")
|
||||
}
|
||||
exclude("GradleStart**")
|
||||
exclude(".cache")
|
||||
exclude("LICENSE*")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
object Versions {
|
||||
// const val PISTON = "0.4.3"
|
||||
// const val AUTO_VALUE = "1.6.5"
|
||||
const val WORLDEDIT = "7.1.0-SNAPSHOT"
|
||||
const val JUNIT = "4.11"
|
||||
const val SQUIRRELID = "0.2.0"
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE module PUBLIC
|
||||
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
|
||||
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
|
||||
<module name="Checker">
|
||||
<!-- Tabs are strictly banned -->
|
||||
<module name="FileTabCharacter"/>
|
||||
|
||||
<module name="SuppressionFilter">
|
||||
<property name="file" value="${config_loc}/suppressions.xml"/>
|
||||
</module>
|
||||
|
||||
|
||||
|
||||
<module name="TreeWalker">
|
||||
<!-- Important basics -->
|
||||
<!-- <module name="PackageDeclaration"/> Unlikely that we would miss this in a PR -->
|
||||
<module name="OuterTypeFilename"/> <!-- TypeName -> TypeName.java -->
|
||||
|
||||
<!--
|
||||
Control package usage, so people don't insert Bukkit into WG where it shouldn't belong, etc.
|
||||
It is a bit draconian, so update as necessary!
|
||||
-->
|
||||
<module name="ImportControl">
|
||||
<property name="file" value="${config_loc}/import-control.xml"/>
|
||||
</module>
|
||||
|
||||
<!-- Code -->
|
||||
<module name="HideUtilityClassConstructor"/> <!-- Utility classes should not have a constructor -->
|
||||
<module name="CovariantEquals"/>
|
||||
<module name="EqualsHashCode"/> <!-- equals() and hashCode() go together -->
|
||||
<module name="NestedTryDepth"> <!-- SHOULD not need to adjust this -->
|
||||
<property name="max" value="2"/>
|
||||
</module>
|
||||
<module name="SuperFinalize"/> <!-- We don't actually use this -->
|
||||
|
||||
<!-- Style -->
|
||||
<module name="LeftCurly"> <!-- Left brace never goes on another line -->
|
||||
<property name="option" value="eol"/>
|
||||
</module> <!-- We don't check right brace -->
|
||||
<module name="DefaultComesLast"/> <!-- default case in switch should be last -->
|
||||
<module name="GenericWhitespace"/>
|
||||
|
||||
<!-- Naming -->
|
||||
<module name="ClassTypeParameterName">
|
||||
<property name="format" value="^[A-Z][a-zA-Z0-9]*$"/>
|
||||
</module>
|
||||
<module name="LocalFinalVariableName"/>
|
||||
<module name="LocalVariableName">
|
||||
<property name="format" value="^[a-z_][a-zA-Z0-9]*$"/>
|
||||
</module>
|
||||
<module name="MemberName">
|
||||
<property name="format" value="^[a-z_][a-zA-Z0-9]*$"/>
|
||||
</module>
|
||||
<module name="MethodName">
|
||||
<property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
|
||||
</module>
|
||||
<!-- <module name="PackageName"/> Unlikely that we would miss this in a PR -->
|
||||
<module name="ParameterName"/>
|
||||
<!-- <module name="TypeName"/> Unlikely that we would miss this in a PR -->
|
||||
</module>
|
||||
|
||||
</module>
|
||||
@@ -0,0 +1,36 @@
|
||||
<!DOCTYPE import-control PUBLIC
|
||||
"-//Puppy Crawl//DTD Import Control 1.1//EN"
|
||||
"http://www.puppycrawl.com/dtds/import_control_1_1.dtd">
|
||||
|
||||
<import-control pkg="com.sk89q">
|
||||
<allow pkg="java"/>
|
||||
<allow pkg="javax"/>
|
||||
<allow pkg="org.junit"/>
|
||||
<allow pkg="org.hamcrest"/>
|
||||
<allow pkg="org.mockito"/>
|
||||
<allow pkg="junit.framework"/>
|
||||
<allow pkg="com.sk89q"/>
|
||||
<allow pkg="com.google.common"/>
|
||||
|
||||
<subpackage name="worldguard">
|
||||
<allow pkg="org.khelekore"/>
|
||||
<allow pkg="org.flywaydb"/>
|
||||
<allow pkg="org.yaml"/>
|
||||
<allow pkg="org.enginehub.piston"/>
|
||||
|
||||
<subpackage name="util.profile.resolver">
|
||||
<allow pkg="org.bukkit"/>
|
||||
<allow pkg="io.papermc.lib"/>
|
||||
<allow pkg="com.destroystokyo.paper"/>
|
||||
</subpackage>
|
||||
|
||||
<subpackage name="bukkit">
|
||||
<allow pkg="org.bukkit"/>
|
||||
<allow pkg="org.bstats.bukkit"/>
|
||||
<allow pkg="io.papermc.lib"/>
|
||||
<allow pkg="com.destroystokyo.paper"/>
|
||||
</subpackage>
|
||||
|
||||
</subpackage>
|
||||
|
||||
</import-control>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE suppressions PUBLIC
|
||||
"-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN"
|
||||
"https://checkstyle.org/dtds/suppressions_1_2.dtd">
|
||||
<suppressions>
|
||||
<suppress files="ProtectedRegion.java" checks="EqualsHashCode"/>
|
||||
</suppressions>
|
||||
@@ -0,0 +1,2 @@
|
||||
group=com.sk89q.worldguard
|
||||
version=7.0.2-SNAPSHOT
|
||||
Vendored
BIN
Binary file not shown.
+5
@@ -0,0 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
@@ -0,0 +1,172 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
Vendored
+84
@@ -0,0 +1,84 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@@ -1,205 +0,0 @@
|
||||
<!--
|
||||
Maven build file for WorldGuard
|
||||
Copyright (c) 2011 sk89q <http://www.sk89q.com>
|
||||
WorldGuard is available under the GNU General Public License v3
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.sk89q</groupId>
|
||||
<artifactId>worldguard</artifactId>
|
||||
<version>5.5</version>
|
||||
<name>WorldGuard</name>
|
||||
<description>WorldGuard protects your Minecraft servers</description>
|
||||
|
||||
<scm>
|
||||
<connection>scm:git:git://github.com/sk89q/worldguard.git</connection>
|
||||
<url>https://github.com/sk89q/worldguard</url>
|
||||
<developerConnection>scm:git:git@github.com:sk89q/worldguard.git</developerConnection>
|
||||
</scm>
|
||||
|
||||
<repositories>
|
||||
<!-- Repository for zml's stuff -->
|
||||
<repository>
|
||||
<id>zml-repo</id>
|
||||
<url>http://files.zachsthings.com/repo</url>
|
||||
</repository>
|
||||
<!-- Repository for other dependencies of SK's -->
|
||||
<repository>
|
||||
<id>sk89q-mvn2</id>
|
||||
<url>http://mvn2.sk89q.com/repo</url>
|
||||
</repository>
|
||||
<!-- Repository for Bukkit -->
|
||||
<repository>
|
||||
<id>bukkit-repo</id>
|
||||
<url>http://repo.bukkit.org/content/groups/public</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<!-- Required component -->
|
||||
<dependency>
|
||||
<groupId>com.sk89q</groupId>
|
||||
<artifactId>worldedit</artifactId>
|
||||
<version>5.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Bukkit -->
|
||||
<dependency>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
<version>1.1-R3</version>
|
||||
</dependency>
|
||||
|
||||
<!-- CommandBook -->
|
||||
<dependency>
|
||||
<groupId>com.sk89q</groupId>
|
||||
<artifactId>commandbook</artifactId>
|
||||
<version>2.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Additional libraries -->
|
||||
<dependency>
|
||||
<groupId>com.nijikokun</groupId>
|
||||
<artifactId>iconomy</artifactId>
|
||||
<version>5.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.khelekore</groupId>
|
||||
<artifactId>prtree</artifactId>
|
||||
<version>1.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sf.opencsv</groupId>
|
||||
<artifactId>opencsv</artifactId>
|
||||
<version>2.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.8.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
|
||||
|
||||
<!-- Resources -->
|
||||
<resources>
|
||||
<resource>
|
||||
<targetPath>.</targetPath>
|
||||
<filtering>true</filtering>
|
||||
<directory>${basedir}/src/main/resources/</directory>
|
||||
<includes>
|
||||
<include>plugin.yml</include>
|
||||
</includes>
|
||||
</resource>
|
||||
<resource>
|
||||
<targetPath>defaults/</targetPath>
|
||||
<filtering>true</filtering>
|
||||
<directory>${basedir}/src/main/resources/</directory>
|
||||
<includes>
|
||||
<include>config.yml</include>
|
||||
<include>config_world.yml</include>
|
||||
<include>blacklist.txt</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
<plugins>
|
||||
<!-- Compile plugin -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>2.3.2</version>
|
||||
</plugin>
|
||||
|
||||
<!-- JAR creation plugin -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.3.1</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<addMavenDescriptor>true</addMavenDescriptor>
|
||||
<manifest>
|
||||
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
|
||||
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
|
||||
</manifest>
|
||||
<manifestEntries>
|
||||
<Class-Path>WorldGuard/WorldEdit.jar lib/WorldEdit.jar ../lib/WorldEdit.jar ../WorldEdit.jar</Class-Path>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!-- Shade -->
|
||||
<!-- We want to bundle in some dependencies -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>1.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<artifactSet>
|
||||
<!-- We want to bundle in the modified CSV library -->
|
||||
<includes>
|
||||
<include>net.sf.opencsv:opencsv</include>
|
||||
</includes>
|
||||
</artifactSet>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- Assembly -->
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>2.2.1</version>
|
||||
<configuration>
|
||||
<descriptor>${basedir}/src/main/assembly/default.xml</descriptor>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>release</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- Release -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-release-plugin</artifactId>
|
||||
<version>2.2.2</version>
|
||||
<configuration>
|
||||
<preparationGoals>assembly:assembly</preparationGoals>
|
||||
<goals>assembly:assembly</goals>
|
||||
<tagNameFormat>@{project.version}</tagNameFormat>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<reporting>
|
||||
<plugins>
|
||||
<!-- Javadocs -->
|
||||
<!-- TODO: Get Doclava working -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.8</version>
|
||||
<configuration>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
</project>
|
||||
@@ -1,184 +0,0 @@
|
||||
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
|
||||
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
|
||||
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL';
|
||||
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `user`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `user` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
|
||||
`name` VARCHAR(64) NOT NULL UNIQUE,
|
||||
PRIMARY KEY (`id`))
|
||||
ENGINE = InnoDB;
|
||||
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `group`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `group` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
|
||||
`name` VARCHAR(64) NOT NULL UNIQUE,
|
||||
PRIMARY KEY (`id`))
|
||||
ENGINE = InnoDB;
|
||||
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `world`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `world` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
|
||||
`name` VARCHAR(128) NOT NULL UNIQUE,
|
||||
PRIMARY KEY (`id`))
|
||||
ENGINE = InnoDB;
|
||||
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `region`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `region` (
|
||||
`id` VARCHAR(128) NOT NULL ,
|
||||
`world_id` INT UNSIGNED NOT NULL ,
|
||||
`type` ENUM('cuboid','poly2d','global') NOT NULL ,
|
||||
`priority` SMALLINT NOT NULL DEFAULT 0 ,
|
||||
`parent` VARCHAR(128) NULL ,
|
||||
PRIMARY KEY (`id`, `world_id`) ,
|
||||
INDEX `parent` (`parent` ASC) ,
|
||||
INDEX `fk_region_world` (`world_id` ASC) ,
|
||||
CONSTRAINT `parent`
|
||||
FOREIGN KEY (`parent` )
|
||||
REFERENCES `region` (`id` )
|
||||
ON DELETE SET NULL
|
||||
ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_region_world1`
|
||||
FOREIGN KEY (`world_id` )
|
||||
REFERENCES `world` (`id` )
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE)
|
||||
ENGINE = InnoDB;
|
||||
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `region_flag`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `region_flag` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
|
||||
`region_id` VARCHAR(128) NOT NULL ,
|
||||
`flag` VARCHAR(64) NOT NULL ,
|
||||
`value` VARCHAR(256) NOT NULL ,
|
||||
INDEX `fk_flags_region` (`region_id` ASC) ,
|
||||
PRIMARY KEY (`id`) ,
|
||||
CONSTRAINT `fk_flags_region1`
|
||||
FOREIGN KEY (`region_id` )
|
||||
REFERENCES `region` (`id` )
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE)
|
||||
ENGINE = InnoDB;
|
||||
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `region_cuboid`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `region_cuboid` (
|
||||
`region_id` VARCHAR(128) NOT NULL ,
|
||||
`min_z` BIGINT NOT NULL ,
|
||||
`min_y` BIGINT NOT NULL ,
|
||||
`min_x` BIGINT NOT NULL ,
|
||||
`max_z` BIGINT NOT NULL ,
|
||||
`max_y` BIGINT NOT NULL ,
|
||||
`max_x` BIGINT NOT NULL ,
|
||||
PRIMARY KEY (`region_id`) ,
|
||||
INDEX `fk_region_cuboid_region` (`region_id` ASC) ,
|
||||
CONSTRAINT `fk_region_cuboid_region`
|
||||
FOREIGN KEY (`region_id` )
|
||||
REFERENCES `region` (`id` )
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE)
|
||||
ENGINE = InnoDB;
|
||||
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `region_poly2d`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `region_poly2d` (
|
||||
`region_id` VARCHAR(128) NOT NULL ,
|
||||
`max_y` INT NOT NULL ,
|
||||
`min_y` INT NOT NULL ,
|
||||
PRIMARY KEY (`region_id`) ,
|
||||
INDEX `fk_region_poly2d_region` (`region_id` ASC) ,
|
||||
CONSTRAINT `fk_region_poly2d_region`
|
||||
FOREIGN KEY (`region_id` )
|
||||
REFERENCES `region` (`id` )
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE)
|
||||
ENGINE = InnoDB;
|
||||
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `region_players`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `region_players` (
|
||||
`region_id` VARCHAR(128) NOT NULL ,
|
||||
`user_id` INT UNSIGNED NOT NULL ,
|
||||
`owner` TINYINT(1) NOT NULL ,
|
||||
PRIMARY KEY (`region_id`, `user_id`) ,
|
||||
INDEX `fk_region_players_region` (`region_id` ASC) ,
|
||||
INDEX `fk_region_players_user` (`user_id` ASC) ,
|
||||
CONSTRAINT `fk_region_players_region`
|
||||
FOREIGN KEY (`region_id` )
|
||||
REFERENCES `region` (`id` )
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_region_players_user`
|
||||
FOREIGN KEY (`user_id` )
|
||||
REFERENCES `user` (`id` )
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE)
|
||||
ENGINE = InnoDB;
|
||||
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `region_groups`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `region_groups` (
|
||||
`region_id` VARCHAR(128) NOT NULL ,
|
||||
`group_id` INT UNSIGNED NOT NULL ,
|
||||
`owner` TINYINT(1) NOT NULL ,
|
||||
PRIMARY KEY (`region_id`, `group_id`) ,
|
||||
INDEX `fk_region_groups_region` (`region_id` ASC) ,
|
||||
INDEX `fk_region_groups_group` (`group_id` ASC) ,
|
||||
CONSTRAINT `fk_region_groups_region`
|
||||
FOREIGN KEY (`region_id` )
|
||||
REFERENCES `region` (`id` )
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_region_groups_group`
|
||||
FOREIGN KEY (`group_id` )
|
||||
REFERENCES `group` (`id` )
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE)
|
||||
ENGINE = InnoDB;
|
||||
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `region_poly2d_point`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `region_poly2d_point` (
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT ,
|
||||
`region_id` VARCHAR(128) NOT NULL ,
|
||||
`z` BIGINT NOT NULL ,
|
||||
`x` BIGINT NOT NULL ,
|
||||
PRIMARY KEY (`id`) ,
|
||||
INDEX `fk_region_poly2d_point_region_poly2d` (`region_id` ASC) ,
|
||||
CONSTRAINT `fk_region_poly2d_point_region_poly2d`
|
||||
FOREIGN KEY (`region_id` )
|
||||
REFERENCES `region_poly2d` (`region_id` )
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE)
|
||||
ENGINE = InnoDB;
|
||||
|
||||
|
||||
|
||||
SET SQL_MODE=@OLD_SQL_MODE;
|
||||
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
|
||||
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
|
||||
@@ -0,0 +1,7 @@
|
||||
rootProject.name = "worldguard"
|
||||
|
||||
include("worldguard-libs")
|
||||
include("worldguard-libs:core")
|
||||
include("worldguard-core")
|
||||
//include("worldguard-libs:bukkit")
|
||||
include("worldguard-bukkit")
|
||||
@@ -1,36 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<assembly
|
||||
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
|
||||
<id>default</id>
|
||||
<includeBaseDirectory>false</includeBaseDirectory>
|
||||
<formats>
|
||||
<format>tar.gz</format>
|
||||
<format>tar.bz2</format>
|
||||
<format>zip</format>
|
||||
</formats>
|
||||
<files>
|
||||
<file>
|
||||
<source>${project.build.directory}/${artifactId}-${project.version}.jar</source>
|
||||
<destName>WorldGuard.jar</destName>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
<filtered>false</filtered>
|
||||
</file>
|
||||
<file>
|
||||
<source>README.html</source>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
<filtered>true</filtered>
|
||||
</file>
|
||||
</files>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<includes>
|
||||
<include>LICENSE.txt</include>
|
||||
<include>NOTICE.txt</include>
|
||||
<include>CHANGELOG.txt</include>
|
||||
<include>blacklist_table.sql</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
</assembly>
|
||||
@@ -1,96 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard;
|
||||
|
||||
import com.sk89q.worldedit.Vector;
|
||||
|
||||
public abstract class LocalPlayer {
|
||||
/**
|
||||
* Get a player's name.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public abstract String getName();
|
||||
|
||||
/**
|
||||
* Returns true if the player is inside a group.
|
||||
*
|
||||
* @param group
|
||||
* @return
|
||||
*/
|
||||
public abstract boolean hasGroup(String group);
|
||||
|
||||
/**
|
||||
* Get the player's position.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public abstract Vector getPosition();
|
||||
|
||||
/**
|
||||
* Kick the player.
|
||||
*
|
||||
* @param msg
|
||||
*/
|
||||
public abstract void kick(String msg);
|
||||
|
||||
/**
|
||||
* Ban the player.
|
||||
*
|
||||
* @param msg
|
||||
*/
|
||||
public abstract void ban(String msg);
|
||||
|
||||
/**
|
||||
* Send the player a message;
|
||||
*
|
||||
* @param msg
|
||||
*/
|
||||
public abstract void printRaw(String msg);
|
||||
|
||||
/**
|
||||
* Get the player's list of groups.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public abstract String[] getGroups();
|
||||
|
||||
/**
|
||||
* Returns whether a player has permission.
|
||||
*
|
||||
* @param perm
|
||||
* @return
|
||||
*/
|
||||
public abstract boolean hasPermission(String perm);
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof LocalPlayer)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ((LocalPlayer)obj).getName().equals(getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getName().hashCode();
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard;
|
||||
|
||||
import java.util.logging.Filter;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.LogRecord;
|
||||
|
||||
public class TickSyncDelayLoggerFilter implements Filter {
|
||||
public boolean isLoggable(LogRecord record) {
|
||||
if (record.getLevel() == Level.WARNING
|
||||
&& record.getMessage().equals("Can't keep up! Did the system time change, or is the server overloaded?")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,332 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.blacklist;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
import com.sk89q.worldedit.blocks.ItemType;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.blacklist.events.BlacklistEvent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public abstract class Blacklist {
|
||||
|
||||
/**
|
||||
* List of entries by block ID.
|
||||
*/
|
||||
private Map<Integer,List<BlacklistEntry>> blacklist
|
||||
= new HashMap<Integer,List<BlacklistEntry>>();
|
||||
/**
|
||||
* Logger.
|
||||
*/
|
||||
private BlacklistLogger blacklistLogger = new BlacklistLogger();
|
||||
/**
|
||||
* Last event.
|
||||
*/
|
||||
private BlacklistEvent lastEvent;
|
||||
/**
|
||||
* Used to prevent flooding.
|
||||
*/
|
||||
Map<String,BlacklistTrackedEvent> lastAffected =
|
||||
new HashMap<String,BlacklistTrackedEvent>();
|
||||
|
||||
private boolean useAsWhitelist;
|
||||
|
||||
private final Logger logger;
|
||||
|
||||
public Blacklist(Boolean useAsWhitelist, Logger logger) {
|
||||
this.useAsWhitelist = useAsWhitelist;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the list is empty.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return blacklist.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the entries for an item or list.
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
public List<BlacklistEntry> getEntries(int id) {
|
||||
return blacklist.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of individual items that have blacklist entries.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getItemCount() {
|
||||
return blacklist.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the blacklist is used as a whitelist.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isWhitelist() {
|
||||
return useAsWhitelist;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the logger.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public BlacklistLogger getLogger() {
|
||||
return blacklistLogger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to handle the event.
|
||||
*
|
||||
* @param event
|
||||
* @param forceRepeat
|
||||
* @param silent
|
||||
* @return
|
||||
*/
|
||||
public boolean check(BlacklistEvent event, boolean forceRepeat, boolean silent) {
|
||||
List<BlacklistEntry> entries = getEntries(event.getType());
|
||||
if (entries == null) {
|
||||
return true;
|
||||
}
|
||||
boolean ret = true;
|
||||
for (BlacklistEntry entry : entries) {
|
||||
if (!entry.check(useAsWhitelist, event, forceRepeat, silent)) {
|
||||
ret = false;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the blacklist.
|
||||
*
|
||||
* @param file
|
||||
* @throws IOException
|
||||
*/
|
||||
public void load(File file) throws IOException {
|
||||
FileReader input = null;
|
||||
Map<Integer,List<BlacklistEntry>> blacklist =
|
||||
new HashMap<Integer,List<BlacklistEntry>>();
|
||||
|
||||
try {
|
||||
input = new FileReader(file);
|
||||
BufferedReader buff = new BufferedReader(input);
|
||||
|
||||
String line;
|
||||
List<BlacklistEntry> currentEntries = null;
|
||||
while ((line = buff.readLine()) != null) {
|
||||
line = line.trim();
|
||||
|
||||
// Blank line
|
||||
if (line.length() == 0) {
|
||||
continue;
|
||||
} else if (line.charAt(0) == ';' || line.charAt(0) == '#') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line.matches("^\\[.*\\]$")) {
|
||||
String[] items = line.substring(1, line.length() - 1).split(",");
|
||||
currentEntries = new ArrayList<BlacklistEntry>();
|
||||
|
||||
for (String item : items) {
|
||||
int id = 0;
|
||||
|
||||
try {
|
||||
id = Integer.parseInt(item.trim());
|
||||
} catch (NumberFormatException e) {
|
||||
id = getItemID(item.trim());
|
||||
if (id == 0) {
|
||||
logger.log(Level.WARNING, "Unknown block name: "
|
||||
+ item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BlacklistEntry entry = new BlacklistEntry(this);
|
||||
if (blacklist.containsKey(id)) {
|
||||
blacklist.get(id).add(entry);
|
||||
} else {
|
||||
List<BlacklistEntry> entries = new ArrayList<BlacklistEntry>();
|
||||
entries.add(entry);
|
||||
blacklist.put(id, entries);
|
||||
}
|
||||
currentEntries.add(entry);
|
||||
}
|
||||
} else if (currentEntries != null) {
|
||||
String[] parts = line.split("=");
|
||||
|
||||
if (parts.length == 1) {
|
||||
logger.log(Level.WARNING, "Found option with no value "
|
||||
+ file.getName() + " for '" + line + "'");
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean unknownOption = false;
|
||||
|
||||
for (BlacklistEntry entry : currentEntries) {
|
||||
if (parts[0].equalsIgnoreCase("ignore-groups")) {
|
||||
entry.setIgnoreGroups(parts[1].split(","));
|
||||
} else if (parts[0].equalsIgnoreCase("ignore-perms")) {
|
||||
entry.setIgnorePermissions(parts[1].split(","));
|
||||
} else if (parts[0].equalsIgnoreCase("on-break")) {
|
||||
entry.setBreakActions(parts[1].split(","));
|
||||
} else if (parts[0].equalsIgnoreCase("on-destroy-with")) {
|
||||
entry.setDestroyWithActions(parts[1].split(","));
|
||||
} else if (parts[0].equalsIgnoreCase("on-place")) {
|
||||
entry.setPlaceActions(parts[1].split(","));
|
||||
} else if (parts[0].equalsIgnoreCase("on-interact")) {
|
||||
entry.setInteractActions(parts[1].split(","));
|
||||
} else if (parts[0].equalsIgnoreCase("on-use")) {
|
||||
entry.setUseActions(parts[1].split(","));
|
||||
} else if (parts[0].equalsIgnoreCase("on-drop")) {
|
||||
entry.setDropActions(parts[1].split(","));
|
||||
} else if (parts[0].equalsIgnoreCase("on-acquire")) {
|
||||
entry.setAcquireActions(parts[1].split(","));
|
||||
} else if (parts[0].equalsIgnoreCase("message")) {
|
||||
entry.setMessage(parts[1].trim());
|
||||
} else if (parts[0].equalsIgnoreCase("comment")) {
|
||||
entry.setComment(parts[1].trim());
|
||||
} else {
|
||||
unknownOption = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (unknownOption) {
|
||||
logger.log(Level.WARNING, "Unknown option '" + parts[0]
|
||||
+ "' in " + file.getName() + " for '" + line + "'");
|
||||
}
|
||||
} else {
|
||||
logger.log(Level.WARNING, "Found option with no heading "
|
||||
+ file.getName() + " for '" + line + "'");
|
||||
}
|
||||
}
|
||||
|
||||
this.blacklist = blacklist;
|
||||
} finally {
|
||||
try {
|
||||
if (input != null) {
|
||||
input.close();
|
||||
}
|
||||
} catch (IOException e2) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last event.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public BlacklistEvent getLastEvent() {
|
||||
return lastEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify administrators.
|
||||
*
|
||||
* @param event
|
||||
* @param comment
|
||||
*/
|
||||
public void notify(BlacklistEvent event, String comment) {
|
||||
lastEvent = event;
|
||||
|
||||
broadcastNotification(ChatColor.GRAY + "WG: "
|
||||
+ ChatColor.LIGHT_PURPLE + event.getPlayer().getName()
|
||||
+ ChatColor.GOLD + " (" + event.getDescription() + ") "
|
||||
+ ChatColor.WHITE
|
||||
+ getFriendlyItemName(event.getType())
|
||||
+ (comment != null ? " (" + comment + ")" : "") + ".");
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a notification to all subscribing users.
|
||||
*
|
||||
* @param msg
|
||||
*/
|
||||
public abstract void broadcastNotification(String msg);
|
||||
|
||||
/**
|
||||
* Forget a player.
|
||||
*
|
||||
* @param player
|
||||
*/
|
||||
public void forgetPlayer(LocalPlayer player) {
|
||||
lastAffected.remove(player.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Forget all players.
|
||||
*/
|
||||
public void forgetAllPlayers() {
|
||||
lastAffected.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an item's ID from its name.
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
private static int getItemID(String name) {
|
||||
ItemType type = ItemType.lookup(name);
|
||||
if (type != null) {
|
||||
return type.getID();
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an item's friendly name with its ID.
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
private static String getFriendlyItemName(int id) {
|
||||
ItemType type = ItemType.fromID(id);
|
||||
if (type != null) {
|
||||
return type.getName() + " (#" + id + ")";
|
||||
} else {
|
||||
return "#" + id + "";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,425 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.blacklist;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
import com.sk89q.worldedit.blocks.ItemType;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.blacklist.events.BlacklistEvent;
|
||||
import com.sk89q.worldguard.blacklist.events.BlockBreakBlacklistEvent;
|
||||
import com.sk89q.worldguard.blacklist.events.BlockInteractBlacklistEvent;
|
||||
import com.sk89q.worldguard.blacklist.events.BlockPlaceBlacklistEvent;
|
||||
import com.sk89q.worldguard.blacklist.events.DestroyWithBlacklistEvent;
|
||||
import com.sk89q.worldguard.blacklist.events.ItemAcquireBlacklistEvent;
|
||||
import com.sk89q.worldguard.blacklist.events.ItemDropBlacklistEvent;
|
||||
import com.sk89q.worldguard.blacklist.events.ItemUseBlacklistEvent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class BlacklistEntry {
|
||||
/**
|
||||
* Parent blacklist entry.
|
||||
*/
|
||||
private Blacklist blacklist;
|
||||
|
||||
/**
|
||||
* List of groups to not affect.
|
||||
*/
|
||||
private Set<String> ignoreGroups;
|
||||
|
||||
/**
|
||||
* List of permissions to not affect.
|
||||
*/
|
||||
private Set<String> ignorePermissions;
|
||||
|
||||
private String[] breakActions;
|
||||
private String[] destroyWithActions;
|
||||
private String[] placeActions;
|
||||
private String[] interactActions;
|
||||
private String[] useActions;
|
||||
private String[] dropActions;
|
||||
private String[] acquireActions;
|
||||
|
||||
private String message;
|
||||
private String comment;
|
||||
|
||||
/**
|
||||
* Construct the object.
|
||||
*
|
||||
* @param blacklist
|
||||
*/
|
||||
public BlacklistEntry(Blacklist blacklist) {
|
||||
this.blacklist = blacklist;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the ignoreGroups
|
||||
*/
|
||||
public String[] getIgnoreGroups() {
|
||||
return ignoreGroups.toArray(new String[ignoreGroups.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the ignoreGroups
|
||||
*/
|
||||
public String[] getIgnorePermissions() {
|
||||
return ignorePermissions.toArray(new String[ignorePermissions.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ignoreGroups the ignoreGroups to set
|
||||
*/
|
||||
public void setIgnoreGroups(String[] ignoreGroups) {
|
||||
Set<String> ignoreGroupsSet = new HashSet<String>();
|
||||
for (String group : ignoreGroups) {
|
||||
ignoreGroupsSet.add(group.toLowerCase());
|
||||
}
|
||||
this.ignoreGroups = ignoreGroupsSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ignorePermissions the ignorePermissions to set
|
||||
*/
|
||||
public void setIgnorePermissions(String[] ignorePermissions) {
|
||||
Set<String> ignorePermissionsSet = new HashSet<String>();
|
||||
for (String perm : ignorePermissions) {
|
||||
ignorePermissionsSet.add(perm);
|
||||
}
|
||||
this.ignorePermissions = ignorePermissionsSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public String[] getBreakActions() {
|
||||
return breakActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param actions
|
||||
*/
|
||||
public void setBreakActions(String[] actions) {
|
||||
this.breakActions = actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public String[] getDestroyWithActions() {
|
||||
return destroyWithActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param actions
|
||||
*/
|
||||
public void setDestroyWithActions(String[] actions) {
|
||||
this.destroyWithActions = actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public String[] getPlaceActions() {
|
||||
return placeActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param actions
|
||||
*/
|
||||
public void setPlaceActions(String[] actions) {
|
||||
this.placeActions = actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public String[] getInteractActions() {
|
||||
return interactActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param actions
|
||||
*/
|
||||
public void setInteractActions(String[] actions) {
|
||||
this.interactActions = actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public String[] getUseActions() {
|
||||
return useActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param actions
|
||||
*/
|
||||
public void setUseActions(String[] actions) {
|
||||
this.useActions = actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public String[] getDropActions() {
|
||||
return dropActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param actions
|
||||
*/
|
||||
public void setDropActions(String[] actions) {
|
||||
this.dropActions = actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public String[] getAcquireActions() {
|
||||
return acquireActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param actions
|
||||
*/
|
||||
public void setAcquireActions(String[] actions) {
|
||||
this.acquireActions = actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the message
|
||||
*/
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param message the message to set
|
||||
*/
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the comment
|
||||
*/
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param comment the comment to set
|
||||
*/
|
||||
public void setComment(String comment) {
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this player should be ignored.
|
||||
*
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
public boolean shouldIgnore(LocalPlayer player) {
|
||||
if (ignoreGroups != null) {
|
||||
for (String group : player.getGroups()) {
|
||||
if (ignoreGroups.contains(group.toLowerCase())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ignorePermissions != null) {
|
||||
for (String perm : ignorePermissions) {
|
||||
if (player.hasPermission(perm)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the associated actions with an event.
|
||||
*
|
||||
* @param event
|
||||
* @return
|
||||
*/
|
||||
private String[] getActions(BlacklistEvent event) {
|
||||
if (event instanceof BlockBreakBlacklistEvent) {
|
||||
return breakActions;
|
||||
|
||||
} else if (event instanceof BlockPlaceBlacklistEvent) {
|
||||
return placeActions;
|
||||
|
||||
} else if (event instanceof BlockInteractBlacklistEvent) {
|
||||
return interactActions;
|
||||
|
||||
} else if (event instanceof DestroyWithBlacklistEvent) {
|
||||
return destroyWithActions;
|
||||
|
||||
} else if (event instanceof ItemAcquireBlacklistEvent) {
|
||||
return acquireActions;
|
||||
|
||||
} else if (event instanceof ItemDropBlacklistEvent) {
|
||||
return dropActions;
|
||||
|
||||
} else if (event instanceof ItemUseBlacklistEvent) {
|
||||
return useActions;
|
||||
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to handle the event.
|
||||
*
|
||||
* @param useAsWhitelist
|
||||
* @param event
|
||||
* @param forceRepeat
|
||||
* @param silent
|
||||
* @return
|
||||
*/
|
||||
public boolean check(boolean useAsWhitelist, BlacklistEvent event, boolean forceRepeat, boolean silent) {
|
||||
LocalPlayer player = event.getPlayer();
|
||||
|
||||
if (shouldIgnore(player)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
String name = player.getName();
|
||||
long now = System.currentTimeMillis();
|
||||
boolean repeating = false;
|
||||
|
||||
// Check to see whether this event is being repeated
|
||||
BlacklistTrackedEvent tracked = blacklist.lastAffected.get(name);
|
||||
if (tracked != null) {
|
||||
if (tracked.matches(event, now)) {
|
||||
repeating = true;
|
||||
}
|
||||
} else {
|
||||
blacklist.lastAffected.put(name, new BlacklistTrackedEvent(event, now));
|
||||
}
|
||||
|
||||
String actions[] = getActions(event);
|
||||
|
||||
|
||||
boolean ret = useAsWhitelist ? false : true;
|
||||
|
||||
// Nothing to do
|
||||
if (actions == null) {
|
||||
return useAsWhitelist ? false : true;
|
||||
}
|
||||
|
||||
for (String action : actions) {
|
||||
// Deny
|
||||
if (action.equalsIgnoreCase("deny")) {
|
||||
if (silent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = false;
|
||||
|
||||
// Allow
|
||||
} else if (action.equalsIgnoreCase("allow")) {
|
||||
if (silent) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ret = true;
|
||||
|
||||
// Kick
|
||||
} else if (action.equalsIgnoreCase("kick")) {
|
||||
if (silent) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (this.message != null) {
|
||||
player.kick(String.format(this.message,
|
||||
getFriendlyItemName(event.getType())));
|
||||
} else {
|
||||
player.kick("You can't " + event.getDescription() + " "
|
||||
+ getFriendlyItemName(event.getType()));
|
||||
}
|
||||
|
||||
// Ban
|
||||
} else if (action.equalsIgnoreCase("ban")) {
|
||||
if (silent) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (this.message != null) {
|
||||
player.ban("Banned: " + String.format(this.message,
|
||||
getFriendlyItemName(event.getType())));
|
||||
} else {
|
||||
player.ban("Banned: You can't "
|
||||
+ event.getDescription() + " "
|
||||
+ getFriendlyItemName(event.getType()));
|
||||
}
|
||||
|
||||
} else if (!silent && (!repeating || forceRepeat)) {
|
||||
// Notify
|
||||
if (action.equalsIgnoreCase("notify")) {
|
||||
blacklist.notify(event, comment);
|
||||
|
||||
// Log
|
||||
} else if (action.equalsIgnoreCase("log")) {
|
||||
blacklist.getLogger().logEvent(event, comment);
|
||||
|
||||
// Tell
|
||||
} else if (action.equalsIgnoreCase("tell")) {
|
||||
if (this.message != null) {
|
||||
player.printRaw(ChatColor.YELLOW +
|
||||
String.format(message, getFriendlyItemName(event.getType()))
|
||||
+ ".");
|
||||
} else {
|
||||
player.printRaw(ChatColor.YELLOW + "You're not allowed to "
|
||||
+ event.getDescription() + " "
|
||||
+ getFriendlyItemName(event.getType()) + ".");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an item's friendly name with its ID.
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
private static String getFriendlyItemName(int id) {
|
||||
ItemType type = ItemType.fromID(id);
|
||||
if (type != null) {
|
||||
return type.getName() + " (#" + id + ")";
|
||||
} else {
|
||||
return "#" + id + "";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.blacklist;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import com.sk89q.worldguard.blacklist.events.BlacklistEvent;
|
||||
import com.sk89q.worldguard.blacklist.loggers.BlacklistLoggerHandler;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class BlacklistLogger implements BlacklistLoggerHandler {
|
||||
/**
|
||||
* List of logger handlers.
|
||||
*/
|
||||
private Set<BlacklistLoggerHandler> handlers
|
||||
= new HashSet<BlacklistLoggerHandler>();
|
||||
|
||||
/**
|
||||
* Add a handler.
|
||||
*
|
||||
* @param handler
|
||||
*/
|
||||
public void addHandler(BlacklistLoggerHandler handler) {
|
||||
handlers.add(handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a handler.
|
||||
*
|
||||
* @param handler
|
||||
*/
|
||||
public void removeHandler(BlacklistLoggerHandler handler) {
|
||||
handlers.remove(handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a handler.
|
||||
*/
|
||||
public void clearHandlers() {
|
||||
handlers.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Log an event.
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
public void logEvent(BlacklistEvent event, String comment) {
|
||||
for (BlacklistLoggerHandler handler : handlers) {
|
||||
handler.logEvent(event, comment);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the connection.
|
||||
*/
|
||||
public void close() {
|
||||
for (BlacklistLoggerHandler handler : handlers) {
|
||||
handler.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.blacklist;
|
||||
|
||||
import com.sk89q.worldguard.blacklist.events.BlacklistEvent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class BlacklistTrackedEvent {
|
||||
private BlacklistEvent event;
|
||||
private long time;
|
||||
|
||||
/**
|
||||
* Construct the object.
|
||||
*
|
||||
* @param event
|
||||
* @param time
|
||||
*/
|
||||
public BlacklistTrackedEvent(BlacklistEvent event, long time) {
|
||||
this.event = event;
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public boolean matches(BlacklistEvent other, long now) {
|
||||
return other.getType() == event.getType()
|
||||
&& time > now - 3000
|
||||
&& other.getClass() == event.getClass();
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.blacklist.events;
|
||||
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
|
||||
/**
|
||||
* Represents a blacklist event.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public abstract class BlacklistEvent {
|
||||
private Vector pos;
|
||||
private int type;
|
||||
|
||||
/**
|
||||
* Holds the player that triggered the event.
|
||||
*/
|
||||
private LocalPlayer player;
|
||||
|
||||
/**
|
||||
* Construct the object.
|
||||
*
|
||||
* @param player
|
||||
* @param pos
|
||||
* @param type
|
||||
*/
|
||||
public BlacklistEvent(LocalPlayer player, Vector pos, int type) {
|
||||
this.player = player;
|
||||
this.pos = pos;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public LocalPlayer getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the position.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Vector getPosition() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a short description such as "break" or "destroy with."
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public abstract String getDescription();
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.blacklist.events;
|
||||
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
|
||||
public abstract class BlockBlacklistEvent extends BlacklistEvent {
|
||||
public BlockBlacklistEvent(LocalPlayer player, Vector pos, int type) {
|
||||
super(player, pos, type);
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.blacklist.events;
|
||||
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
|
||||
public class BlockBreakBlacklistEvent extends BlockBlacklistEvent {
|
||||
public BlockBreakBlacklistEvent(LocalPlayer player, Vector pos, int type) {
|
||||
super(player, pos, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a short description such as "break" or "destroy with."
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "break";
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.blacklist.events;
|
||||
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
|
||||
public class BlockInteractBlacklistEvent extends BlockBlacklistEvent {
|
||||
public BlockInteractBlacklistEvent(LocalPlayer player, Vector pos, int type) {
|
||||
super(player, pos, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a short description such as "break" or "destroy with."
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "interact with";
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.blacklist.events;
|
||||
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
|
||||
public class BlockPlaceBlacklistEvent extends BlockBlacklistEvent {
|
||||
public BlockPlaceBlacklistEvent(LocalPlayer player, Vector pos, int type) {
|
||||
super(player, pos, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a short description such as "break" or "destroy with."
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "place";
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.blacklist.events;
|
||||
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
|
||||
public class DestroyWithBlacklistEvent extends BlacklistEvent {
|
||||
public DestroyWithBlacklistEvent(LocalPlayer player, Vector pos, int type) {
|
||||
super(player, pos, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a short description such as "break" or "destroy with."
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "destroy with";
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.blacklist.events;
|
||||
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
|
||||
public class ItemAcquireBlacklistEvent extends ItemBlacklistEvent {
|
||||
public ItemAcquireBlacklistEvent(LocalPlayer player, Vector pos, int type) {
|
||||
super(player, pos, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a short description such as "break" or "destroy with."
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "acquire";
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.blacklist.events;
|
||||
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
|
||||
public abstract class ItemBlacklistEvent extends BlacklistEvent {
|
||||
public ItemBlacklistEvent(LocalPlayer player, Vector pos, int type) {
|
||||
super(player, pos, type);
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.blacklist.events;
|
||||
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
|
||||
public class ItemDropBlacklistEvent extends ItemBlacklistEvent {
|
||||
public ItemDropBlacklistEvent(LocalPlayer player, Vector pos, int type) {
|
||||
super(player, pos, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a short description such as "break" or "destroy with."
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "drop";
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.blacklist.events;
|
||||
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
|
||||
public class ItemUseBlacklistEvent extends ItemBlacklistEvent {
|
||||
public ItemUseBlacklistEvent(LocalPlayer player, Vector pos, int type) {
|
||||
super(player, pos, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a short description such as "break" or "destroy with."
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "use";
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.blacklist.loggers;
|
||||
|
||||
import com.sk89q.worldguard.blacklist.events.BlacklistEvent;
|
||||
|
||||
/**
|
||||
* Interface for loggers for the blacklist.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public interface BlacklistLoggerHandler {
|
||||
/**
|
||||
* Log an event.
|
||||
*
|
||||
* @param event
|
||||
* @param comment
|
||||
*/
|
||||
public void logEvent(BlacklistEvent event, String comment);
|
||||
|
||||
/**
|
||||
* Close the logger.
|
||||
*/
|
||||
public void close();
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.blacklist.loggers;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sk89q.worldedit.blocks.ItemType;
|
||||
import com.sk89q.worldguard.blacklist.events.BlacklistEvent;
|
||||
import com.sk89q.worldguard.blacklist.events.BlockBreakBlacklistEvent;
|
||||
import com.sk89q.worldguard.blacklist.events.BlockInteractBlacklistEvent;
|
||||
import com.sk89q.worldguard.blacklist.events.BlockPlaceBlacklistEvent;
|
||||
import com.sk89q.worldguard.blacklist.events.DestroyWithBlacklistEvent;
|
||||
import com.sk89q.worldguard.blacklist.events.ItemAcquireBlacklistEvent;
|
||||
import com.sk89q.worldguard.blacklist.events.ItemDropBlacklistEvent;
|
||||
import com.sk89q.worldguard.blacklist.events.ItemUseBlacklistEvent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class ConsoleLoggerHandler implements BlacklistLoggerHandler {
|
||||
|
||||
|
||||
private String worldName;
|
||||
|
||||
private final Logger logger;
|
||||
|
||||
public ConsoleLoggerHandler(String worldName, Logger logger) {
|
||||
this.worldName = worldName;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log an event.
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
public void logEvent(BlacklistEvent event, String comment) {
|
||||
// Block break
|
||||
if (event instanceof BlockBreakBlacklistEvent) {
|
||||
BlockBreakBlacklistEvent evt = (BlockBreakBlacklistEvent)event;
|
||||
logger.log(Level.INFO, "[" + worldName + "] " + event.getPlayer().getName()
|
||||
+ " tried to break " + getFriendlyItemName(evt.getType())
|
||||
+ (comment != null ? " (" + comment + ")" : ""));
|
||||
|
||||
// Block place
|
||||
} else if (event instanceof BlockPlaceBlacklistEvent) {
|
||||
BlockPlaceBlacklistEvent evt = (BlockPlaceBlacklistEvent)event;
|
||||
logger.log(Level.INFO, "[" + worldName + "] " + event.getPlayer().getName()
|
||||
+ " tried to place " + getFriendlyItemName(evt.getType())
|
||||
+ (comment != null ? " (" + comment + ")" : ""));
|
||||
|
||||
// Block interact
|
||||
} else if (event instanceof BlockInteractBlacklistEvent) {
|
||||
BlockInteractBlacklistEvent evt = (BlockInteractBlacklistEvent)event;
|
||||
logger.log(Level.INFO, "[" + worldName + "] " + event.getPlayer().getName()
|
||||
+ " tried to interact with " + getFriendlyItemName(evt.getType())
|
||||
+ (comment != null ? " (" + comment + ")" : ""));
|
||||
|
||||
// Destroy with
|
||||
} else if (event instanceof DestroyWithBlacklistEvent) {
|
||||
DestroyWithBlacklistEvent evt = (DestroyWithBlacklistEvent)event;
|
||||
logger.log(Level.INFO, "[" + worldName + "] " + event.getPlayer().getName()
|
||||
+ " tried to destroy with " + getFriendlyItemName(evt.getType())
|
||||
+ (comment != null ? " (" + comment + ")" : ""));
|
||||
|
||||
// Acquire
|
||||
} else if (event instanceof ItemAcquireBlacklistEvent) {
|
||||
ItemAcquireBlacklistEvent evt = (ItemAcquireBlacklistEvent)event;
|
||||
logger.log(Level.INFO, "[" + worldName + "] " + event.getPlayer().getName()
|
||||
+ " tried to acquire " + getFriendlyItemName(evt.getType())
|
||||
+ (comment != null ? " (" + comment + ")" : ""));
|
||||
|
||||
// Drop
|
||||
} else if (event instanceof ItemDropBlacklistEvent) {
|
||||
ItemDropBlacklistEvent evt = (ItemDropBlacklistEvent)event;
|
||||
logger.log(Level.INFO, "[" + worldName + "] " + event.getPlayer().getName()
|
||||
+ " tried to drop " + getFriendlyItemName(evt.getType())
|
||||
+ (comment != null ? " (" + comment + ")" : ""));
|
||||
|
||||
// Use
|
||||
} else if (event instanceof ItemUseBlacklistEvent) {
|
||||
ItemUseBlacklistEvent evt = (ItemUseBlacklistEvent)event;
|
||||
logger.log(Level.INFO, "[" + worldName + "] " + event.getPlayer().getName()
|
||||
+ " tried to use " + getFriendlyItemName(evt.getType())
|
||||
+ (comment != null ? " (" + comment + ")" : ""));
|
||||
|
||||
// Unknown
|
||||
} else {
|
||||
logger.log(Level.INFO, "[" + worldName + "] " + event.getPlayer().getName()
|
||||
+ " caught unknown event: " + event.getClass().getCanonicalName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an item's friendly name with its ID.
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
private static String getFriendlyItemName(int id) {
|
||||
ItemType type = ItemType.fromID(id);
|
||||
if (type != null) {
|
||||
return type.getName() + " (#" + id + ")";
|
||||
} else {
|
||||
return "#" + id + "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the connection.
|
||||
*/
|
||||
public void close() {
|
||||
}
|
||||
}
|
||||
@@ -1,204 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.blacklist.loggers;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.blacklist.events.BlacklistEvent;
|
||||
import com.sk89q.worldguard.blacklist.events.BlockBreakBlacklistEvent;
|
||||
import com.sk89q.worldguard.blacklist.events.BlockPlaceBlacklistEvent;
|
||||
import com.sk89q.worldguard.blacklist.events.BlockInteractBlacklistEvent;
|
||||
import com.sk89q.worldguard.blacklist.events.DestroyWithBlacklistEvent;
|
||||
import com.sk89q.worldguard.blacklist.events.ItemAcquireBlacklistEvent;
|
||||
import com.sk89q.worldguard.blacklist.events.ItemDropBlacklistEvent;
|
||||
import com.sk89q.worldguard.blacklist.events.ItemUseBlacklistEvent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class DatabaseLoggerHandler implements BlacklistLoggerHandler {
|
||||
|
||||
/**
|
||||
* DSN.
|
||||
*/
|
||||
private final String dsn;
|
||||
/**
|
||||
* Username.
|
||||
*/
|
||||
private final String user;
|
||||
/**
|
||||
* Password.
|
||||
*/
|
||||
private final String pass;
|
||||
/**
|
||||
* Table.
|
||||
*/
|
||||
private final String table;
|
||||
/**
|
||||
* World name.
|
||||
*/
|
||||
private final String worldName;
|
||||
/**
|
||||
* Database connection.
|
||||
*/
|
||||
private Connection conn;
|
||||
|
||||
private final Logger logger;
|
||||
|
||||
/**
|
||||
* Construct the object.
|
||||
*
|
||||
* @param dsn
|
||||
* @param user
|
||||
* @param pass
|
||||
* @param table
|
||||
* @param worldName
|
||||
*/
|
||||
public DatabaseLoggerHandler(String dsn, String user, String pass, String table, String worldName, Logger logger) {
|
||||
this.dsn = dsn;
|
||||
this.user = user;
|
||||
this.pass = pass;
|
||||
this.table = table;
|
||||
this.worldName = worldName;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the database connection.
|
||||
*
|
||||
* @return
|
||||
* @throws SQLException
|
||||
*/
|
||||
private Connection getConnection() throws SQLException {
|
||||
if (conn == null || conn.isClosed()) {
|
||||
conn = DriverManager.getConnection(dsn, user, pass);
|
||||
}
|
||||
return conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log an event to the database.
|
||||
*
|
||||
* @param event
|
||||
* @param player
|
||||
* @param pos
|
||||
* @param item
|
||||
* @param comment
|
||||
*/
|
||||
private void logEvent(String event, LocalPlayer player, Vector pos, int item,
|
||||
String comment) {
|
||||
try {
|
||||
Connection conn = getConnection();
|
||||
PreparedStatement stmt = conn.prepareStatement(
|
||||
"INSERT INTO " + table
|
||||
+ "(event, world, player, x, y, z, item, time, comment) VALUES "
|
||||
+ "(?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
stmt.setString(1, event);
|
||||
stmt.setString(2, worldName);
|
||||
stmt.setString(3, player.getName());
|
||||
stmt.setInt(4, pos.getBlockX());
|
||||
stmt.setInt(5, pos.getBlockY());
|
||||
stmt.setInt(6, pos.getBlockZ());
|
||||
stmt.setInt(7, item);
|
||||
stmt.setInt(8, (int)(System.currentTimeMillis() / 1000));
|
||||
stmt.setString(9, comment);
|
||||
stmt.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
logger.log(Level.SEVERE, "Failed to log blacklist event to database: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log an event.
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
public void logEvent(BlacklistEvent event, String comment) {
|
||||
// Block break
|
||||
if (event instanceof BlockBreakBlacklistEvent) {
|
||||
BlockBreakBlacklistEvent evt = (BlockBreakBlacklistEvent)event;
|
||||
logEvent("BREAK", evt.getPlayer(), evt.getPosition(),
|
||||
evt.getType(), comment);
|
||||
|
||||
// Block place
|
||||
} else if (event instanceof BlockPlaceBlacklistEvent) {
|
||||
BlockPlaceBlacklistEvent evt = (BlockPlaceBlacklistEvent)event;
|
||||
logEvent("PLACE", evt.getPlayer(), evt.getPosition(),
|
||||
evt.getType(), comment);
|
||||
|
||||
// Block interact
|
||||
} else if (event instanceof BlockInteractBlacklistEvent) {
|
||||
BlockInteractBlacklistEvent evt = (BlockInteractBlacklistEvent)event;
|
||||
logEvent("INTERACT", evt.getPlayer(), evt.getPosition(),
|
||||
evt.getType(), comment);
|
||||
|
||||
// Destroy with
|
||||
} else if (event instanceof DestroyWithBlacklistEvent) {
|
||||
DestroyWithBlacklistEvent evt = (DestroyWithBlacklistEvent)event;
|
||||
logEvent("DESTROY_WITH", evt.getPlayer(), evt.getPosition(),
|
||||
evt.getType(), comment);
|
||||
|
||||
// Acquire
|
||||
} else if (event instanceof ItemAcquireBlacklistEvent) {
|
||||
ItemAcquireBlacklistEvent evt = (ItemAcquireBlacklistEvent)event;
|
||||
logEvent("ACQUIRE", evt.getPlayer(), evt.getPlayer().getPosition(),
|
||||
evt.getType(), comment);
|
||||
|
||||
// Drop
|
||||
} else if (event instanceof ItemDropBlacklistEvent) {
|
||||
ItemDropBlacklistEvent evt = (ItemDropBlacklistEvent)event;
|
||||
logEvent("DROP", evt.getPlayer(), evt.getPlayer().getPosition(),
|
||||
evt.getType(), comment);
|
||||
|
||||
// Use
|
||||
} else if (event instanceof ItemUseBlacklistEvent) {
|
||||
ItemUseBlacklistEvent evt = (ItemUseBlacklistEvent)event;
|
||||
logEvent("USE", evt.getPlayer(), evt.getPlayer().getPosition(),
|
||||
evt.getType(), comment);
|
||||
|
||||
// Unknown
|
||||
} else {
|
||||
logEvent("UNKNOWN", event.getPlayer(), event.getPlayer().getPosition(),
|
||||
-1, comment);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the connection.
|
||||
*/
|
||||
public void close() {
|
||||
try {
|
||||
if (conn != null && !conn.isClosed()) {
|
||||
conn.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.blacklist.loggers;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class FileLoggerWriter implements Comparable<FileLoggerWriter> {
|
||||
/**
|
||||
* Path.
|
||||
*/
|
||||
public String path;
|
||||
/**
|
||||
* Writer.
|
||||
*/
|
||||
private BufferedWriter writer;
|
||||
/**
|
||||
* Last use.
|
||||
*/
|
||||
private long lastUse;
|
||||
|
||||
/**
|
||||
* Construct the object.
|
||||
*
|
||||
* @param path
|
||||
* @param writer
|
||||
*/
|
||||
public FileLoggerWriter(String path, BufferedWriter writer) {
|
||||
this.path = path;
|
||||
this.writer = writer;
|
||||
lastUse = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* File path.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the writer
|
||||
*/
|
||||
public BufferedWriter getWriter() {
|
||||
return writer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the lastUse
|
||||
*/
|
||||
public long getLastUse() {
|
||||
return lastUse;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update last use time.
|
||||
*/
|
||||
public void updateLastUse() {
|
||||
lastUse = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparison function.
|
||||
*
|
||||
* @param other
|
||||
* @return
|
||||
*/
|
||||
public int compareTo(FileLoggerWriter other) {
|
||||
if (lastUse > other.lastUse) {
|
||||
return 1;
|
||||
} else if (lastUse < other.lastUse) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.bukkit;
|
||||
|
||||
import com.sk89q.worldguard.blacklist.Blacklist;
|
||||
|
||||
public class BukkitBlacklist extends Blacklist {
|
||||
private WorldGuardPlugin plugin;
|
||||
|
||||
public BukkitBlacklist(Boolean useAsWhitelist, WorldGuardPlugin plugin) {
|
||||
super(useAsWhitelist, plugin.getLogger());
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void broadcastNotification(String msg) {
|
||||
plugin.broadcastNotification(msg);
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.bukkit;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
|
||||
public class BukkitPlayer extends LocalPlayer {
|
||||
private Player player;
|
||||
private WorldGuardPlugin plugin;
|
||||
|
||||
public BukkitPlayer(WorldGuardPlugin plugin, Player player) {
|
||||
this.plugin = plugin;
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return player.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasGroup(String group) {
|
||||
return plugin.inGroup(player, group);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector getPosition() {
|
||||
Location loc = player.getLocation();
|
||||
return new Vector(loc.getX(), loc.getY(), loc.getZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void kick(String msg) {
|
||||
player.kickPlayer(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ban(String msg) {
|
||||
player.kickPlayer(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getGroups() {
|
||||
return plugin.getGroups(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printRaw(String msg) {
|
||||
player.sendMessage(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(String perm) {
|
||||
return plugin.hasPermission(player, perm);
|
||||
}
|
||||
}
|
||||
@@ -1,249 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.bukkit;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.sk89q.worldedit.blocks.BlockID;
|
||||
import com.sk89q.worldedit.blocks.ItemID;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.ExperienceOrb;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import com.sk89q.worldedit.BlockVector;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.blocks.BlockType;
|
||||
|
||||
public class BukkitUtil {
|
||||
|
||||
private BukkitUtil() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the location of a Bukkit block to a WorldEdit vector.
|
||||
*
|
||||
* @param block
|
||||
* @return
|
||||
*/
|
||||
public static BlockVector toVector(Block block) {
|
||||
return new BlockVector(block.getX(), block.getY(), block.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a Bukkit location to a WorldEdit vector.
|
||||
*
|
||||
* @param loc
|
||||
* @return
|
||||
*/
|
||||
public static Vector toVector(Location loc) {
|
||||
return new Vector(loc.getX(), loc.getY(), loc.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a Bukkit vector to a WorldEdit vector.
|
||||
*
|
||||
* @param vector
|
||||
* @return
|
||||
*/
|
||||
public static Vector toVector(org.bukkit.util.Vector vector) {
|
||||
return new Vector(vector.getX(), vector.getY(), vector.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a WorldEdit vector to a Bukkit location.
|
||||
*
|
||||
* @param world
|
||||
* @param vec
|
||||
* @return
|
||||
*/
|
||||
public static Location toLocation(World world, Vector vec) {
|
||||
return new Location(world, vec.getX(), vec.getY(), vec.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches one player based on name.
|
||||
*
|
||||
* @param server
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
public static Player matchSinglePlayer(Server server, String name) {
|
||||
List<Player> players = server.matchPlayer(name);
|
||||
if (players.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
return players.get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drops a sign item and removes a sign.
|
||||
*
|
||||
* @param block
|
||||
*/
|
||||
public static void dropSign(Block block) {
|
||||
block.setTypeId(0);
|
||||
block.getWorld().dropItemNaturally(block.getLocation(),
|
||||
new ItemStack(ItemID.SIGN, 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the given block to fluid water.
|
||||
* Used by addSpongeWater()
|
||||
*
|
||||
* @param world
|
||||
* @param ox
|
||||
* @param oy
|
||||
* @param oz
|
||||
*/
|
||||
public static void setBlockToWater(World world, int ox, int oy, int oz) {
|
||||
Block block = world.getBlockAt(ox, oy, oz);
|
||||
int id = block.getTypeId();
|
||||
if (id == 0) {
|
||||
block.setTypeId(8);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given block is water
|
||||
*
|
||||
* @param world
|
||||
* @param ox
|
||||
* @param oy
|
||||
* @param oz
|
||||
* @return
|
||||
*/
|
||||
public static boolean isBlockWater(World world, int ox, int oy, int oz) {
|
||||
Block block = world.getBlockAt(ox, oy, oz);
|
||||
int id = block.getTypeId();
|
||||
if (id == 8 || id == 9) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a position for the player to stand that is not inside a block.
|
||||
* Blocks above the player will be iteratively tested until there is
|
||||
* a series of two free blocks. The player will be teleported to
|
||||
* that free position.
|
||||
*
|
||||
* @param player
|
||||
*/
|
||||
public static void findFreePosition(Player player) {
|
||||
Location loc = player.getLocation();
|
||||
int x = loc.getBlockX();
|
||||
int y = Math.max(0, loc.getBlockY());
|
||||
int origY = y;
|
||||
int z = loc.getBlockZ();
|
||||
World world = player.getWorld();
|
||||
|
||||
byte free = 0;
|
||||
|
||||
while (y <= 129) {
|
||||
if (BlockType.canPassThrough(world.getBlockTypeIdAt(x, y, z))) {
|
||||
free++;
|
||||
} else {
|
||||
free = 0;
|
||||
}
|
||||
|
||||
if (free == 2) {
|
||||
if (y - 1 != origY || y == 1) {
|
||||
loc.setX(x + 0.5);
|
||||
loc.setY(y);
|
||||
loc.setZ(z + 0.5);
|
||||
if (y <= 2 && world.getBlockAt(x,0,z).getTypeId() == BlockID.AIR) {
|
||||
world.getBlockAt(x,0,z).setTypeId(20);
|
||||
loc.setY(2);
|
||||
}
|
||||
player.setFallDistance(0F);
|
||||
player.teleport(loc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
y++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace color macros in a string. The macros are in the form of `[char]
|
||||
* where char represents the color. R is for red, Y is for yellow,
|
||||
* G is for green, C is for cyan, B is for blue, and P is for purple.
|
||||
* The uppercase versions of those are the darker shades, while the
|
||||
* lowercase versions are the lighter shades. For white, it's 'w', and
|
||||
* 0-2 are black, dark grey, and grey, respectively.
|
||||
*
|
||||
* @param str
|
||||
* @return color-coded string
|
||||
*/
|
||||
public static String replaceColorMacros(String str) {
|
||||
str = str.replace("&r", ChatColor.RED.toString());
|
||||
str = str.replace("&R", ChatColor.DARK_RED.toString());
|
||||
|
||||
str = str.replace("&y", ChatColor.YELLOW.toString());
|
||||
str = str.replace("&Y", ChatColor.GOLD.toString());
|
||||
|
||||
str = str.replace("&g", ChatColor.GREEN.toString());
|
||||
str = str.replace("&G", ChatColor.DARK_GREEN.toString());
|
||||
|
||||
str = str.replace("&c", ChatColor.AQUA.toString());
|
||||
str = str.replace("&C", ChatColor.DARK_AQUA.toString());
|
||||
|
||||
str = str.replace("&b", ChatColor.BLUE.toString());
|
||||
str = str.replace("&B", ChatColor.DARK_BLUE.toString());
|
||||
|
||||
str = str.replace("&p", ChatColor.LIGHT_PURPLE.toString());
|
||||
str = str.replace("&P", ChatColor.DARK_PURPLE.toString());
|
||||
|
||||
str = str.replace("&0", ChatColor.BLACK.toString());
|
||||
str = str.replace("&1", ChatColor.DARK_GRAY.toString());
|
||||
str = str.replace("&2", ChatColor.GRAY.toString());
|
||||
str = str.replace("&w", ChatColor.WHITE.toString());
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an entity should be removed for the halt activity mode.
|
||||
*
|
||||
* @param entity
|
||||
* @return
|
||||
*/
|
||||
public static boolean isIntensiveEntity(Entity entity) {
|
||||
return entity instanceof Item
|
||||
|| entity instanceof TNTPrimed
|
||||
|| entity instanceof ExperienceOrb
|
||||
|| (entity instanceof LivingEntity
|
||||
&& !(entity instanceof Tameable)
|
||||
&& !(entity instanceof Player));
|
||||
}
|
||||
}
|
||||
@@ -1,290 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.sk89q.worldguard.bukkit;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.sk89q.commandbook.CommandBook;
|
||||
import com.sk89q.commandbook.GodComponent;
|
||||
import com.sk89q.util.yaml.YAMLFormat;
|
||||
import com.sk89q.util.yaml.YAMLProcessor;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.blacklist.Blacklist;
|
||||
|
||||
/**
|
||||
* Represents the global configuration and also delegates configuration
|
||||
* for individual worlds.
|
||||
*
|
||||
* @author sk89q
|
||||
* @author Michael
|
||||
*/
|
||||
public class ConfigurationManager {
|
||||
|
||||
private static final String CONFIG_HEADER = "#\r\n" +
|
||||
"# WorldGuard's main configuration file\r\n" +
|
||||
"#\r\n" +
|
||||
"# This is the global configuration file. Anything placed into here will\r\n" +
|
||||
"# be applied to all worlds. However, each world has its own configuration\r\n" +
|
||||
"# file to allow you to replace most settings in here for that world only.\r\n" +
|
||||
"#\r\n" +
|
||||
"# About editing this file:\r\n" +
|
||||
"# - DO NOT USE TABS. You MUST use spaces or Bukkit will complain. If\r\n" +
|
||||
"# you use an editor like Notepad++ (recommended for Windows users), you\r\n" +
|
||||
"# must configure it to \"replace tabs with spaces.\" In Notepad++, this can\r\n" +
|
||||
"# be changed in Settings > Preferences > Language Menu.\r\n" +
|
||||
"# - Don't get rid of the indents. They are indented so some entries are\r\n" +
|
||||
"# in categories (like \"enforce-single-session\" is in the \"protection\"\r\n" +
|
||||
"# category.\r\n" +
|
||||
"# - If you want to check the format of this file before putting it\r\n" +
|
||||
"# into WorldGuard, paste it into http://yaml-online-parser.appspot.com/\r\n" +
|
||||
"# and see if it gives \"ERROR:\".\r\n" +
|
||||
"# - Lines starting with # are comments and so they are ignored.\r\n" +
|
||||
"#\r\n";
|
||||
|
||||
/**
|
||||
* Reference to the plugin.
|
||||
*/
|
||||
private WorldGuardPlugin plugin;
|
||||
|
||||
/**
|
||||
* Holds configurations for different worlds.
|
||||
*/
|
||||
private Map<String, WorldConfiguration> worlds;
|
||||
|
||||
/**
|
||||
* The global configuration for use when loading worlds
|
||||
*/
|
||||
private YAMLProcessor config;
|
||||
|
||||
/**
|
||||
* List of people with god mode.
|
||||
*/
|
||||
@Deprecated
|
||||
private Set<String> hasGodMode = new HashSet<String>();
|
||||
|
||||
/**
|
||||
* List of people who can breathe underwater.
|
||||
*/
|
||||
private Set<String> hasAmphibious = new HashSet<String>();
|
||||
|
||||
private boolean hasCommandBookGodMode = false;
|
||||
|
||||
public boolean suppressTickSyncWarnings;
|
||||
public boolean useRegionsScheduler;
|
||||
public boolean activityHaltToggle = false;
|
||||
public boolean autoGodMode;
|
||||
public boolean usePlayerMove;
|
||||
|
||||
/**
|
||||
* Region Storage Configuration method, and config values
|
||||
*/
|
||||
public boolean useSqlDatabase = false;
|
||||
public String sqlDsn;
|
||||
public String sqlUsername;
|
||||
public String sqlPassword;
|
||||
|
||||
/**
|
||||
* Construct the object.
|
||||
*
|
||||
* @param plugin
|
||||
*/
|
||||
public ConfigurationManager(WorldGuardPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
this.worlds = new HashMap<String, WorldConfiguration>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the configuration.
|
||||
*/
|
||||
public void load() {
|
||||
// Create the default configuration file
|
||||
plugin.createDefaultConfiguration(
|
||||
new File(plugin.getDataFolder(), "config.yml"), "config.yml");
|
||||
|
||||
config = new YAMLProcessor(new File(plugin.getDataFolder(), "config.yml"), true, YAMLFormat.EXTENDED);
|
||||
try {
|
||||
config.load();
|
||||
} catch (IOException e) {
|
||||
plugin.getLogger().severe("Error reading configuration for global config: ");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
suppressTickSyncWarnings = config.getBoolean(
|
||||
"suppress-tick-sync-warnings", false);
|
||||
useRegionsScheduler = config.getBoolean(
|
||||
"regions.use-scheduler", true);
|
||||
autoGodMode = config.getBoolean(
|
||||
"auto-invincible", config.getBoolean("auto-invincible-permission", true));
|
||||
usePlayerMove = config.getBoolean(
|
||||
"use-player-move-event", true);
|
||||
|
||||
useSqlDatabase = config.getBoolean(
|
||||
"regions.sql.use", false);
|
||||
|
||||
sqlDsn = config.getString("regions.sql.dsn", "jdbc:mysql://localhost/worldguard");
|
||||
sqlUsername = config.getString("regions.sql.username", "worldguard");
|
||||
sqlPassword = config.getString("regions.sql.password", "worldguard");
|
||||
|
||||
// Load configurations for each world
|
||||
for (World world : plugin.getServer().getWorlds()) {
|
||||
get(world);
|
||||
}
|
||||
|
||||
try {
|
||||
config.setHeader(CONFIG_HEADER);
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
|
||||
if (!config.save()) {
|
||||
plugin.getLogger().severe("Error saving configuration!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unload the configuration.
|
||||
*/
|
||||
public void unload() {
|
||||
worlds.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the configuration for a world.
|
||||
*
|
||||
* @param world
|
||||
* @return
|
||||
*/
|
||||
public WorldConfiguration get(World world) {
|
||||
String worldName = world.getName();
|
||||
WorldConfiguration config = worlds.get(worldName);
|
||||
|
||||
if (config == null) {
|
||||
config = new WorldConfiguration(plugin, worldName, this.config);
|
||||
worlds.put(worldName, config);
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forget a player.
|
||||
*
|
||||
* @param player
|
||||
*/
|
||||
public void forgetPlayer(LocalPlayer player) {
|
||||
for (Map.Entry<String, WorldConfiguration> entry
|
||||
: worlds.entrySet()) {
|
||||
|
||||
// The blacklist needs to forget players
|
||||
Blacklist bl = entry.getValue().getBlacklist();
|
||||
if (bl != null) {
|
||||
bl.forgetPlayer(player);
|
||||
}
|
||||
}
|
||||
|
||||
hasGodMode.remove(player.getName());
|
||||
hasAmphibious.remove(player.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable god mode for a player.
|
||||
*
|
||||
* @param player
|
||||
*/
|
||||
@Deprecated
|
||||
public void enableGodMode(Player player) {
|
||||
hasGodMode.add(player.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable god mode for a player.
|
||||
*
|
||||
* @param player
|
||||
*/
|
||||
@Deprecated
|
||||
public void disableGodMode(Player player) {
|
||||
hasGodMode.remove(player.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if god mode is enabled for a player.
|
||||
*
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
public boolean hasGodMode(Player player) {
|
||||
if (hasCommandBookGodMode) {
|
||||
GodComponent god = CommandBook.inst().getComponentManager().getComponent(GodComponent.class);
|
||||
if (god != null) {
|
||||
return god.hasGodMode(player);
|
||||
}
|
||||
}
|
||||
return hasGodMode.contains(player.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable amphibious mode for a player.
|
||||
*
|
||||
* @param player
|
||||
*/
|
||||
public void enableAmphibiousMode(Player player) {
|
||||
hasAmphibious.add(player.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable amphibious mode for a player.
|
||||
*
|
||||
* @param player
|
||||
*/
|
||||
public void disableAmphibiousMode(Player player) {
|
||||
hasAmphibious.remove(player.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if amphibious mode is enabled for a player.
|
||||
*
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
public boolean hasAmphibiousMode(Player player) {
|
||||
return hasAmphibious.contains(player.getName());
|
||||
}
|
||||
|
||||
public void updateCommandBookGodMode() {
|
||||
try {
|
||||
if (plugin.getServer().getPluginManager().isPluginEnabled("CommandBook")) {
|
||||
Class.forName("com.sk89q.commandbook.GodComponent");
|
||||
hasCommandBookGodMode = true;
|
||||
return;
|
||||
}
|
||||
} catch (ClassNotFoundException ignore) {}
|
||||
hasCommandBookGodMode = false;
|
||||
}
|
||||
|
||||
public boolean hasCommandBookGodMode() {
|
||||
return hasCommandBookGodMode;
|
||||
}
|
||||
}
|
||||
@@ -1,234 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.bukkit;
|
||||
|
||||
import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.flags.DefaultFlag;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
|
||||
/**
|
||||
* This processes per-player state information and is also meant to be used
|
||||
* as a scheduled task.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class FlagStateManager implements Runnable {
|
||||
|
||||
public static final int RUN_DELAY = 20;
|
||||
|
||||
private WorldGuardPlugin plugin;
|
||||
private Map<String, PlayerFlagState> states;
|
||||
|
||||
/**
|
||||
* Construct the object.
|
||||
*
|
||||
* @param plugin
|
||||
*/
|
||||
public FlagStateManager(WorldGuardPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
|
||||
states = new HashMap<String, PlayerFlagState>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the task.
|
||||
*/
|
||||
public void run() {
|
||||
Player[] players = plugin.getServer().getOnlinePlayers();
|
||||
ConfigurationManager config = plugin.getGlobalStateManager();
|
||||
|
||||
for (Player player : players) {
|
||||
WorldConfiguration worldConfig = config.get(player.getWorld());
|
||||
|
||||
if (!worldConfig.useRegions) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PlayerFlagState state;
|
||||
|
||||
synchronized (this) {
|
||||
state = states.get(player.getName());
|
||||
|
||||
if (state == null) {
|
||||
state = new PlayerFlagState();
|
||||
states.put(player.getName(), state);
|
||||
}
|
||||
}
|
||||
|
||||
Vector playerLocation = toVector(player.getLocation());
|
||||
RegionManager regionManager = plugin.getGlobalRegionManager()
|
||||
.get(player.getWorld());
|
||||
ApplicableRegionSet applicable = regionManager
|
||||
.getApplicableRegions(playerLocation);
|
||||
|
||||
if (!RegionQueryUtil.isInvincible(plugin, player, applicable)
|
||||
&& !plugin.getGlobalStateManager().hasGodMode(player)
|
||||
&& !(player.getGameMode() == GameMode.CREATIVE)) {
|
||||
processHeal(applicable, player, state);
|
||||
processFeed(applicable, player, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process healing for a player.
|
||||
*
|
||||
* @param applicable
|
||||
* @param player
|
||||
* @param state
|
||||
*/
|
||||
private void processHeal(ApplicableRegionSet applicable, Player player,
|
||||
PlayerFlagState state) {
|
||||
|
||||
if (player.getHealth() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
Integer healAmount = applicable.getFlag(DefaultFlag.HEAL_AMOUNT);
|
||||
Integer healDelay = applicable.getFlag(DefaultFlag.HEAL_DELAY);
|
||||
Integer minHealth = applicable.getFlag(DefaultFlag.MIN_HEAL);
|
||||
Integer maxHealth = applicable.getFlag(DefaultFlag.MAX_HEAL);
|
||||
|
||||
if (healAmount == null || healDelay == null || healAmount == 0 || healDelay < 0) {
|
||||
return;
|
||||
}
|
||||
if (minHealth == null) minHealth = 0;
|
||||
if (maxHealth == null) maxHealth = 20;
|
||||
|
||||
if (player.getHealth() >= maxHealth && healAmount > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (healDelay <= 0) {
|
||||
player.setHealth(healAmount > 0 ? maxHealth : minHealth); // this will insta-kill if the flag is unset
|
||||
state.lastHeal = now;
|
||||
} else if (now - state.lastHeal > healDelay * 1000) {
|
||||
// clamp health between minimum and maximum
|
||||
player.setHealth(Math.min(maxHealth, Math.max(minHealth, player.getHealth() + healAmount)));
|
||||
state.lastHeal = now;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process restoring hunger for a player.
|
||||
*
|
||||
* @param applicable
|
||||
* @param player
|
||||
* @param state
|
||||
*/
|
||||
private void processFeed(ApplicableRegionSet applicable, Player player,
|
||||
PlayerFlagState state) {
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
Integer feedAmount = applicable.getFlag(DefaultFlag.FEED_AMOUNT);
|
||||
Integer feedDelay = applicable.getFlag(DefaultFlag.FEED_DELAY);
|
||||
Integer minHunger = applicable.getFlag(DefaultFlag.MIN_FOOD);
|
||||
Integer maxHunger = applicable.getFlag(DefaultFlag.MAX_FOOD);
|
||||
|
||||
if (feedAmount == null || feedDelay == null || feedAmount == 0 || feedDelay < 0) {
|
||||
return;
|
||||
}
|
||||
if (minHunger == null) minHunger = 0;
|
||||
if (maxHunger == null) maxHunger = 20;
|
||||
|
||||
if (player.getFoodLevel() >= maxHunger && feedAmount > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (feedDelay <= 0) {
|
||||
player.setFoodLevel(feedAmount > 0 ? maxHunger : minHunger);
|
||||
state.lastFeed = now;
|
||||
} else if (now - state.lastFeed > feedDelay * 1000) {
|
||||
// clamp health between minimum and maximum
|
||||
player.setFoodLevel(Math.min(maxHunger, Math.max(minHunger, player.getFoodLevel() + feedAmount)));
|
||||
state.lastFeed = now;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Forget a player.
|
||||
*
|
||||
* @param player
|
||||
*/
|
||||
public synchronized void forget(Player player) {
|
||||
states.remove(player.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Forget all managed players. Use with caution.
|
||||
*/
|
||||
public synchronized void forgetAll() {
|
||||
states.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a player's flag state.
|
||||
*
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
public synchronized PlayerFlagState getState(Player player) {
|
||||
PlayerFlagState state = states.get(player.getName());
|
||||
|
||||
if (state == null) {
|
||||
state = new PlayerFlagState();
|
||||
states.put(player.getName(), state);
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Keeps state per player.
|
||||
*/
|
||||
public static class PlayerFlagState {
|
||||
public long lastHeal;
|
||||
public long lastFeed;
|
||||
public String lastGreeting;
|
||||
public String lastFarewell;
|
||||
public Boolean lastExitAllowed = null;
|
||||
public Boolean notifiedForLeave = false;
|
||||
public Boolean notifiedForEnter = false;
|
||||
public World lastWorld;
|
||||
public int lastBlockX;
|
||||
public int lastBlockY;
|
||||
public int lastBlockZ;
|
||||
|
||||
/* Used to cache invincibility status */
|
||||
public World lastInvincibleWorld;
|
||||
public int lastInvincibleX;
|
||||
public int lastInvincibleY;
|
||||
public int lastInvincibleZ;
|
||||
public boolean wasInvincible;
|
||||
}
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.bukkit;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.bukkit.World;
|
||||
|
||||
import com.sk89q.worldguard.protection.databases.ProtectionDatabaseException;
|
||||
import com.sk89q.worldguard.protection.databases.CSVDatabase;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
|
||||
/**
|
||||
* Utility methods for porting from legacy versions.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class LegacyWorldGuardMigration {
|
||||
|
||||
/**
|
||||
* Port over the blacklist.
|
||||
*
|
||||
* @param plugin
|
||||
*/
|
||||
public static void migrateBlacklist(WorldGuardPlugin plugin) {
|
||||
World mainWorld = plugin.getServer().getWorlds().get(0);
|
||||
String mainWorldName = mainWorld.getName();
|
||||
String newPath = "worlds/" + mainWorldName + "/blacklist.txt";
|
||||
|
||||
File oldFile = new File(plugin.getDataFolder(), "blacklist.txt");
|
||||
File newFile = new File(plugin.getDataFolder(), newPath);
|
||||
|
||||
if (!newFile.exists() && oldFile.exists()) {
|
||||
plugin.getLogger().warning("WorldGuard will now update your blacklist "
|
||||
+ "from an older version of WorldGuard.");
|
||||
|
||||
// Need to make root directories
|
||||
newFile.getParentFile().mkdirs();
|
||||
|
||||
if (copyFile(oldFile, newFile)) {
|
||||
oldFile.renameTo(new File(plugin.getDataFolder(),
|
||||
"blacklist.txt.old"));
|
||||
} else {
|
||||
plugin.getLogger().warning("blacklist.txt has been converted " +
|
||||
"for the main world at " + newPath + "");
|
||||
plugin.getLogger().warning("Your other worlds currently have no " +
|
||||
"blacklist defined!");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate region settings.
|
||||
*
|
||||
* @param plugin
|
||||
*/
|
||||
public static void migrateRegions(WorldGuardPlugin plugin) {
|
||||
try {
|
||||
File oldDatabase = new File(plugin.getDataFolder(), "regions.txt");
|
||||
if (!oldDatabase.exists()) return;
|
||||
|
||||
plugin.getLogger().info("The regions database has changed in 5.x. "
|
||||
+ "Your old regions database will be converted to the new format "
|
||||
+ "and set as your primary world's database.");
|
||||
|
||||
World w = plugin.getServer().getWorlds().get(0);
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(w);
|
||||
|
||||
// First load up the old database using the CSV loader
|
||||
CSVDatabase db = new CSVDatabase(oldDatabase, plugin.getLogger());
|
||||
db.load();
|
||||
|
||||
// Then save the new database
|
||||
mgr.setRegions(db.getRegions());
|
||||
mgr.save();
|
||||
|
||||
oldDatabase.renameTo(new File(plugin.getDataFolder(), "regions.txt.old"));
|
||||
|
||||
plugin.getLogger().info("Regions database converted!");
|
||||
} catch (ProtectionDatabaseException e) {
|
||||
plugin.getLogger().warning("Failed to load regions: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies a file.
|
||||
*
|
||||
* @param from
|
||||
* @param to
|
||||
* @return true if successful
|
||||
*/
|
||||
private static boolean copyFile(File from, File to) {
|
||||
InputStream in = null;
|
||||
OutputStream out = null;
|
||||
|
||||
try {
|
||||
in = new FileInputStream(from);
|
||||
out = new FileOutputStream(to);
|
||||
|
||||
byte[] buf = new byte[1024];
|
||||
int len;
|
||||
while ((len = in.read(buf)) > 0) {
|
||||
out.write(buf, 0, len);
|
||||
}
|
||||
|
||||
in.close();
|
||||
out.close();
|
||||
|
||||
return true;
|
||||
} catch (FileNotFoundException ex) {
|
||||
} catch (IOException e) {
|
||||
} finally {
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
if (out != null) {
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.bukkit;
|
||||
|
||||
import java.util.logging.Handler;
|
||||
import java.util.logging.LogRecord;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
/**
|
||||
* Sends all logger messages to a player.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class LoggerToChatHandler extends Handler {
|
||||
/**
|
||||
* Player.
|
||||
*/
|
||||
private CommandSender player;
|
||||
|
||||
/**
|
||||
* Construct the object.
|
||||
*
|
||||
* @param player
|
||||
*/
|
||||
public LoggerToChatHandler(CommandSender player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the handler.
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush the output.
|
||||
*/
|
||||
@Override
|
||||
public void flush() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish a log record.
|
||||
*/
|
||||
@Override
|
||||
public void publish(LogRecord record) {
|
||||
player.sendMessage(ChatColor.GRAY + record.getLevel().getName() + ": "
|
||||
+ ChatColor.WHITE + record.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.bukkit;
|
||||
|
||||
import com.sk89q.commandbook.CommandBook;
|
||||
import com.sk89q.commandbook.GodComponent;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.flags.DefaultFlag;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
|
||||
public class RegionQueryUtil {
|
||||
|
||||
public static boolean isInvincible(WorldGuardPlugin plugin, Player player) {
|
||||
return isInvincible(plugin, player, null);
|
||||
}
|
||||
|
||||
public static boolean isInvincible(WorldGuardPlugin plugin, Player player,
|
||||
ApplicableRegionSet set) {
|
||||
Location loc = player.getLocation();
|
||||
World world = player.getWorld();
|
||||
|
||||
FlagStateManager.PlayerFlagState state = plugin.getFlagStateManager().getState(player);
|
||||
|
||||
if (state.lastInvincibleWorld == null ||
|
||||
!state.lastInvincibleWorld.equals(world) ||
|
||||
state.lastInvincibleX != loc.getBlockX() ||
|
||||
state.lastInvincibleY != loc.getBlockY() ||
|
||||
state.lastInvincibleZ != loc.getBlockZ()) {
|
||||
state.lastInvincibleX = loc.getBlockX();
|
||||
state.lastInvincibleY = loc.getBlockY();
|
||||
state.lastInvincibleZ = loc.getBlockZ();
|
||||
state.lastInvincibleWorld = world;
|
||||
|
||||
if (set == null) {
|
||||
Vector vec = new Vector(state.lastInvincibleX,
|
||||
state.lastInvincibleY, state.lastInvincibleZ);
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
|
||||
set = mgr.getApplicableRegions(vec);
|
||||
}
|
||||
|
||||
state.wasInvincible = set.allows(DefaultFlag.INVINCIBILITY);
|
||||
}
|
||||
|
||||
return state.wasInvincible;
|
||||
}
|
||||
|
||||
public static Boolean isAllowedInvinciblity(WorldGuardPlugin plugin, Player player) {
|
||||
World world = player.getWorld();
|
||||
FlagStateManager.PlayerFlagState state = plugin.getFlagStateManager().getState(player);
|
||||
Vector vec = new Vector(state.lastInvincibleX, state.lastInvincibleY, state.lastInvincibleZ);
|
||||
|
||||
StateFlag.State regionState = plugin.getGlobalRegionManager().get(world).
|
||||
getApplicableRegions(vec).getFlag(DefaultFlag.INVINCIBILITY);
|
||||
if (regionState == StateFlag.State.ALLOW) {
|
||||
return Boolean.TRUE;
|
||||
} else if (regionState == StateFlag.State.DENY) {
|
||||
return Boolean.FALSE;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,337 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.bukkit;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import com.sk89q.worldguard.protection.GlobalRegionManager;
|
||||
import com.sk89q.worldguard.protection.flags.DefaultFlag;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import com.sk89q.worldguard.util.LogListBlock;
|
||||
|
||||
public class ReportWriter {
|
||||
|
||||
private static final SimpleDateFormat dateFmt =
|
||||
new SimpleDateFormat("yyyy-MM-dd kk:mm Z");
|
||||
|
||||
private Date date = new Date();
|
||||
private StringBuilder output = new StringBuilder();
|
||||
|
||||
public ReportWriter(WorldGuardPlugin plugin) {
|
||||
appendReportHeader(plugin);
|
||||
appendServerInformation(plugin.getServer());
|
||||
appendPluginInformation(plugin.getServer().getPluginManager().getPlugins());
|
||||
appendWorldInformation(plugin.getServer().getWorlds());
|
||||
appendGlobalConfiguration(plugin.getGlobalStateManager());
|
||||
appendWorldConfigurations(plugin, plugin.getServer().getWorlds(),
|
||||
plugin.getGlobalRegionManager(), plugin.getGlobalStateManager());
|
||||
appendln("-------------");
|
||||
appendln("END OF REPORT");
|
||||
appendln();
|
||||
}
|
||||
|
||||
protected static String repeat(String str, int n) {
|
||||
if(str == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < n; i++) {
|
||||
sb.append(str);
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
protected void appendln(String text) {
|
||||
output.append(text);
|
||||
output.append("\r\n");
|
||||
}
|
||||
|
||||
protected void appendln(String text, Object ... args) {
|
||||
output.append(String.format(text, args));
|
||||
output.append("\r\n");
|
||||
}
|
||||
|
||||
protected void append(LogListBlock log) {
|
||||
output.append(log.toString());
|
||||
}
|
||||
|
||||
protected void appendln() {
|
||||
output.append("\r\n");
|
||||
}
|
||||
|
||||
protected void appendHeader(String text) {
|
||||
String rule = repeat("-", text.length());
|
||||
output.append(rule);
|
||||
output.append("\r\n");
|
||||
appendln(text);
|
||||
output.append(rule);
|
||||
output.append("\r\n");
|
||||
appendln();
|
||||
}
|
||||
|
||||
private void appendReportHeader(WorldGuardPlugin plugin) {
|
||||
appendln("WorldGuard Configuration Report");
|
||||
appendln("Generated " + dateFmt.format(date));
|
||||
appendln();
|
||||
appendln("Version: " + plugin.getDescription().getVersion());
|
||||
appendln();
|
||||
}
|
||||
|
||||
private void appendGlobalConfiguration(ConfigurationManager config) {
|
||||
appendHeader("Global Configuration");
|
||||
|
||||
LogListBlock log = new LogListBlock();
|
||||
LogListBlock configLog = log.putChild("Configuration");
|
||||
|
||||
Class<? extends ConfigurationManager> cls = config.getClass();
|
||||
for (Field field : cls.getFields()) {
|
||||
try {
|
||||
if (field.getName().equalsIgnoreCase("CONFIG_HEADER")) continue;
|
||||
Object val = field.get(config);
|
||||
configLog.put(field.getName(), val);
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
}
|
||||
}
|
||||
|
||||
append(log);
|
||||
appendln();
|
||||
}
|
||||
|
||||
private void appendServerInformation(Server server) {
|
||||
appendHeader("Server Information");
|
||||
|
||||
LogListBlock log = new LogListBlock();
|
||||
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
|
||||
log.put("Java", "%s %s (%s)",
|
||||
System.getProperty("java.vendor"),
|
||||
System.getProperty("java.version"),
|
||||
System.getProperty("java.vendor.url"));
|
||||
log.put("Operating system", "%s %s (%s)",
|
||||
System.getProperty("os.name"),
|
||||
System.getProperty("os.version"),
|
||||
System.getProperty("os.arch"));
|
||||
log.put("Available processors", runtime.availableProcessors());
|
||||
log.put("Free memory", runtime.freeMemory() / 1024 / 1024 + " MB");
|
||||
log.put("Max memory", runtime.maxMemory() / 1024 / 1024 + " MB");
|
||||
log.put("Total memory", runtime.totalMemory() / 1024 / 1024 + " MB");
|
||||
log.put("Server ID", server.getServerId());
|
||||
log.put("Server name", server.getServerName());
|
||||
log.put("Implementation", server.getVersion());
|
||||
//log.put("Address", server.getIp(), server.getPort());
|
||||
log.put("Player count", "%d/%d",
|
||||
server.getOnlinePlayers().length, server.getMaxPlayers());
|
||||
|
||||
append(log);
|
||||
appendln();
|
||||
}
|
||||
|
||||
private void appendPluginInformation(Plugin[] plugins) {
|
||||
appendHeader("Plugins");
|
||||
|
||||
LogListBlock log = new LogListBlock();
|
||||
|
||||
for (Plugin plugin : plugins) {
|
||||
log.put(plugin.getDescription().getName(), plugin.getDescription().getVersion());
|
||||
}
|
||||
|
||||
append(log);
|
||||
appendln();
|
||||
|
||||
/*appendHeader("Plugin Information");
|
||||
|
||||
log = new LogListBlock();
|
||||
|
||||
for (Plugin plugin : plugins) {
|
||||
log.putChild(plugin.getDescription().getName())
|
||||
.put("Data folder", plugin.getDataFolder())
|
||||
.put("Website", plugin.getDescription().getWebsite())
|
||||
.put("Entry point", plugin.getDescription().getMain());
|
||||
}
|
||||
|
||||
append(log);
|
||||
appendln();*/
|
||||
}
|
||||
|
||||
private void appendWorldInformation(List<World> worlds) {
|
||||
appendHeader("Worlds");
|
||||
|
||||
LogListBlock log = new LogListBlock();
|
||||
|
||||
int i = 0;
|
||||
for (World world : worlds) {
|
||||
int loadedChunkCount = world.getLoadedChunks().length;
|
||||
|
||||
LogListBlock worldLog = log.putChild(world.getName() + " (" + i + ")");
|
||||
LogListBlock infoLog = worldLog.putChild("Information");
|
||||
LogListBlock entitiesLog = worldLog.putChild("Entities");
|
||||
|
||||
infoLog.put("Seed", world.getSeed());
|
||||
infoLog.put("Environment", world.getEnvironment().toString());
|
||||
infoLog.put("Player count", world.getPlayers().size());
|
||||
infoLog.put("Entity count", world.getEntities().size());
|
||||
infoLog.put("Loaded chunk count", loadedChunkCount);
|
||||
infoLog.put("Spawn location", world.getSpawnLocation());
|
||||
infoLog.put("Raw time", world.getFullTime());
|
||||
|
||||
Map<Class<? extends Entity>, Integer> entityCounts =
|
||||
new HashMap<Class<? extends Entity>, Integer>();
|
||||
|
||||
// Collect entities
|
||||
for (Entity entity : world.getEntities()) {
|
||||
Class<? extends Entity> cls = entity.getClass();
|
||||
|
||||
if (entityCounts.containsKey(cls)) {
|
||||
entityCounts.put(cls, entityCounts.get(cls) + 1);
|
||||
} else {
|
||||
entityCounts.put(cls, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Print entities
|
||||
for (Map.Entry<Class<? extends Entity>, Integer> entry
|
||||
: entityCounts.entrySet()) {
|
||||
entitiesLog.put(entry.getKey().getSimpleName(),
|
||||
"%d [%f]",
|
||||
entry.getValue(),
|
||||
(float) (entry.getValue() / (double) loadedChunkCount));
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
append(log);
|
||||
appendln();
|
||||
}
|
||||
|
||||
private void appendWorldConfigurations(WorldGuardPlugin plugin, List<World> worlds,
|
||||
GlobalRegionManager regionMgr, ConfigurationManager mgr) {
|
||||
appendHeader("World Configurations");
|
||||
|
||||
LogListBlock log = new LogListBlock();
|
||||
|
||||
int i = 0;
|
||||
for (World world : worlds) {
|
||||
LogListBlock worldLog = log.putChild(world.getName() + " (" + i + ")");
|
||||
LogListBlock infoLog = worldLog.putChild("Information");
|
||||
LogListBlock configLog = worldLog.putChild("Configuration");
|
||||
LogListBlock blacklistLog = worldLog.putChild("Blacklist");
|
||||
LogListBlock regionsLog = worldLog.putChild("Region manager");
|
||||
|
||||
infoLog.put("Configuration file", (new File(plugin.getDataFolder(), "worlds/"
|
||||
+ world.getName() + "/config.yml")).getAbsoluteFile());
|
||||
|
||||
infoLog.put("Blacklist file", (new File(plugin.getDataFolder(), "worlds/"
|
||||
+ world.getName() + "/blacklist.txt")).getAbsoluteFile());
|
||||
infoLog.put("Regions file", (new File(plugin.getDataFolder(), "worlds/"
|
||||
+ world.getName() + "/regions.yml")).getAbsoluteFile());
|
||||
|
||||
WorldConfiguration config = mgr.get(world);
|
||||
|
||||
Class<? extends WorldConfiguration> cls = config.getClass();
|
||||
for (Field field : cls.getFields()) {
|
||||
try {
|
||||
Object val = field.get(config);
|
||||
configLog.put(field.getName(), String.valueOf(val));
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
}
|
||||
}
|
||||
|
||||
if (config.getBlacklist() == null) {
|
||||
blacklistLog.put("State", "DISABLED");
|
||||
} else {
|
||||
blacklistLog.put("State", "Enabled");
|
||||
blacklistLog.put("Number of items",
|
||||
config.getBlacklist().getItemCount());
|
||||
blacklistLog.put("Is whitelist",
|
||||
config.getBlacklist().isWhitelist());
|
||||
}
|
||||
|
||||
RegionManager worldRegions = regionMgr.get(world);
|
||||
|
||||
regionsLog.put("Type", worldRegions.getClass().getCanonicalName());
|
||||
regionsLog.put("Number of regions", worldRegions.getRegions().size());
|
||||
LogListBlock globalRegionLog = regionsLog.putChild("Global region");
|
||||
|
||||
ProtectedRegion globalRegion = worldRegions.getRegion("__global__");
|
||||
if (globalRegion == null) {
|
||||
globalRegionLog.put("Status", "UNDEFINED");
|
||||
} else {
|
||||
for (Flag<?> flag : DefaultFlag.getFlags()) {
|
||||
if (flag instanceof StateFlag) {
|
||||
globalRegionLog.put(flag.getName(),
|
||||
globalRegion.getFlag(flag));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
append(log);
|
||||
appendln();
|
||||
}
|
||||
|
||||
public void write(File file) throws IOException {
|
||||
FileWriter writer = null;
|
||||
BufferedWriter out;
|
||||
|
||||
try {
|
||||
writer = new FileWriter(file);
|
||||
out = new BufferedWriter(writer);
|
||||
out.write(output.toString());
|
||||
out.close();
|
||||
} finally {
|
||||
if (writer != null) {
|
||||
try {
|
||||
writer.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return output.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.bukkit;
|
||||
|
||||
import static com.sk89q.worldguard.bukkit.BukkitUtil.isBlockWater;
|
||||
import static com.sk89q.worldguard.bukkit.BukkitUtil.setBlockToWater;
|
||||
|
||||
import org.bukkit.World;
|
||||
|
||||
public class SpongeUtil {
|
||||
|
||||
/**
|
||||
* Remove water around a sponge.
|
||||
*
|
||||
* @param plugin
|
||||
* @param world
|
||||
* @param ox
|
||||
* @param oy
|
||||
* @param oz
|
||||
*/
|
||||
public static void clearSpongeWater(WorldGuardPlugin plugin, World world, int ox, int oy, int oz) {
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(world);
|
||||
|
||||
for (int cx = -wcfg.spongeRadius; cx <= wcfg.spongeRadius; cx++) {
|
||||
for (int cy = -wcfg.spongeRadius; cy <= wcfg.spongeRadius; cy++) {
|
||||
for (int cz = -wcfg.spongeRadius; cz <= wcfg.spongeRadius; cz++) {
|
||||
if (isBlockWater(world, ox + cx, oy + cy, oz + cz)) {
|
||||
world.getBlockAt(ox + cx, oy + cy, oz + cz).setTypeId(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add water around a sponge.
|
||||
*
|
||||
* @param plugin
|
||||
* @param world
|
||||
* @param ox
|
||||
* @param oy
|
||||
* @param oz
|
||||
*/
|
||||
public static void addSpongeWater(WorldGuardPlugin plugin, World world, int ox, int oy, int oz) {
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(world);
|
||||
|
||||
// The negative x edge
|
||||
int cx = ox - wcfg.spongeRadius - 1;
|
||||
for (int cy = oy - wcfg.spongeRadius - 1; cy <= oy + wcfg.spongeRadius + 1; cy++) {
|
||||
for (int cz = oz - wcfg.spongeRadius - 1; cz <= oz + wcfg.spongeRadius + 1; cz++) {
|
||||
if (isBlockWater(world, cx, cy, cz)) {
|
||||
setBlockToWater(world, cx + 1, cy, cz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The positive x edge
|
||||
cx = ox + wcfg.spongeRadius + 1;
|
||||
for (int cy = oy - wcfg.spongeRadius - 1; cy <= oy + wcfg.spongeRadius + 1; cy++) {
|
||||
for (int cz = oz - wcfg.spongeRadius - 1; cz <= oz + wcfg.spongeRadius + 1; cz++) {
|
||||
if (isBlockWater(world, cx, cy, cz)) {
|
||||
setBlockToWater(world, cx - 1, cy, cz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The negative y edge
|
||||
int cy = oy - wcfg.spongeRadius - 1;
|
||||
for (cx = ox - wcfg.spongeRadius - 1; cx <= ox + wcfg.spongeRadius + 1; cx++) {
|
||||
for (int cz = oz - wcfg.spongeRadius - 1; cz <= oz + wcfg.spongeRadius + 1; cz++) {
|
||||
if (isBlockWater(world, cx, cy, cz)) {
|
||||
setBlockToWater(world, cx, cy + 1, cz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The positive y edge
|
||||
cy = oy + wcfg.spongeRadius + 1;
|
||||
for (cx = ox - wcfg.spongeRadius - 1; cx <= ox + wcfg.spongeRadius + 1; cx++) {
|
||||
for (int cz = oz - wcfg.spongeRadius - 1; cz <= oz + wcfg.spongeRadius + 1; cz++) {
|
||||
if (isBlockWater(world, cx, cy, cz)) {
|
||||
setBlockToWater(world, cx, cy - 1, cz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The negative z edge
|
||||
int cz = oz - wcfg.spongeRadius - 1;
|
||||
for (cx = ox - wcfg.spongeRadius - 1; cx <= ox + wcfg.spongeRadius + 1; cx++) {
|
||||
for (cy = oy - wcfg.spongeRadius - 1; cy <= oy + wcfg.spongeRadius + 1; cy++) {
|
||||
if (isBlockWater(world, cx, cy, cz)) {
|
||||
setBlockToWater(world, cx, cy, cz + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The positive z edge
|
||||
cz = oz + wcfg.spongeRadius + 1;
|
||||
for (cx = ox - wcfg.spongeRadius - 1; cx <= ox + wcfg.spongeRadius + 1; cx++) {
|
||||
for (cy = oy - wcfg.spongeRadius - 1; cy <= oy + wcfg.spongeRadius + 1; cy++) {
|
||||
if (isBlockWater(world, cx, cy, cz)) {
|
||||
setBlockToWater(world, cx, cy, cz - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,548 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.bukkit;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sk89q.util.yaml.YAMLFormat;
|
||||
import com.sk89q.util.yaml.YAMLProcessor;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.CreatureType;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.sk89q.worldguard.blacklist.Blacklist;
|
||||
import com.sk89q.worldguard.blacklist.BlacklistLogger;
|
||||
import com.sk89q.worldguard.blacklist.loggers.ConsoleLoggerHandler;
|
||||
import com.sk89q.worldguard.blacklist.loggers.DatabaseLoggerHandler;
|
||||
import com.sk89q.worldguard.blacklist.loggers.FileLoggerHandler;
|
||||
import com.sk89q.worldguard.chest.ChestProtection;
|
||||
import com.sk89q.worldguard.chest.SignChestProtection;
|
||||
|
||||
/**
|
||||
* Holds the configuration for individual worlds.
|
||||
*
|
||||
* @author sk89q
|
||||
* @author Michael
|
||||
*/
|
||||
public class WorldConfiguration {
|
||||
|
||||
public static final String CONFIG_HEADER = "#\r\n" +
|
||||
"# WorldGuard's world configuration file\r\n" +
|
||||
"#\r\n" +
|
||||
"# This is a world configuration file. Anything placed into here will only\r\n" +
|
||||
"# affect this world. If you don't put anything in this file, then the\r\n" +
|
||||
"# settings will be inherited from the main configuration file.\r\n" +
|
||||
"#\r\n" +
|
||||
"# If you see {} below, that means that there are NO entries in this file.\r\n" +
|
||||
"# Remove the {} and add your own entries.\r\n" +
|
||||
"#\r\n";
|
||||
|
||||
private WorldGuardPlugin plugin;
|
||||
|
||||
private String worldName;
|
||||
private YAMLProcessor parentConfig;
|
||||
private YAMLProcessor config;
|
||||
private File configFile;
|
||||
private File blacklistFile;
|
||||
|
||||
private Blacklist blacklist;
|
||||
private ChestProtection chestProtection = new SignChestProtection();
|
||||
|
||||
/* Configuration data start */
|
||||
public boolean opPermissions;
|
||||
public boolean fireSpreadDisableToggle;
|
||||
public boolean itemDurability;
|
||||
public boolean simulateSponge;
|
||||
public int spongeRadius;
|
||||
public boolean disableExpDrops;
|
||||
public boolean pumpkinScuba;
|
||||
public boolean redstoneSponges;
|
||||
public boolean noPhysicsGravel;
|
||||
public boolean noPhysicsSand;
|
||||
public boolean allowPortalAnywhere;
|
||||
public Set<Integer> preventWaterDamage;
|
||||
public boolean blockLighter;
|
||||
public boolean disableFireSpread;
|
||||
public Set<Integer> disableFireSpreadBlocks;
|
||||
public boolean preventLavaFire;
|
||||
public Set<Integer> allowedLavaSpreadOver;
|
||||
public boolean blockTNTExplosions;
|
||||
public boolean blockTNTBlockDamage;
|
||||
public boolean blockCreeperExplosions;
|
||||
public boolean blockCreeperBlockDamage;
|
||||
public boolean blockEnderDragonBlockDamage;
|
||||
public boolean blockFireballExplosions;
|
||||
public boolean blockFireballBlockDamage;
|
||||
public boolean disableContactDamage;
|
||||
public boolean disableFallDamage;
|
||||
public boolean disableLavaDamage;
|
||||
public boolean disableFireDamage;
|
||||
public boolean disableLightningDamage;
|
||||
public boolean disableDrowningDamage;
|
||||
public boolean disableSuffocationDamage;
|
||||
public boolean teleportOnSuffocation;
|
||||
public boolean disableVoidDamage;
|
||||
public boolean teleportOnVoid;
|
||||
public boolean disableExplosionDamage;
|
||||
public boolean disableMobDamage;
|
||||
public boolean useRegions;
|
||||
public boolean highFreqFlags;
|
||||
public int regionWand = 287;
|
||||
public Set<CreatureType> blockCreatureSpawn;
|
||||
// public boolean useiConomy;
|
||||
// public boolean buyOnClaim;
|
||||
// public double buyOnClaimPrice;
|
||||
public int maxClaimVolume;
|
||||
public boolean claimOnlyInsideExistingRegions;
|
||||
public int maxRegionCountPerPlayer;
|
||||
public boolean antiWolfDumbness;
|
||||
public boolean signChestProtection;
|
||||
public boolean removeInfiniteStacks;
|
||||
public boolean disableCreatureCropTrampling;
|
||||
public boolean disablePlayerCropTrampling;
|
||||
public boolean preventLightningFire;
|
||||
public Set<Integer> disallowedLightningBlocks;
|
||||
public boolean disableThunder;
|
||||
public boolean disableWeather;
|
||||
public boolean alwaysRaining;
|
||||
public boolean alwaysThundering;
|
||||
public boolean disablePigZap;
|
||||
public boolean disableCreeperPower;
|
||||
public boolean disableHealthRegain;
|
||||
public boolean disableMushroomSpread;
|
||||
public boolean disableIceMelting;
|
||||
public boolean disableSnowMelting;
|
||||
public boolean disableSnowFormation;
|
||||
public boolean disableIceFormation;
|
||||
public boolean disableLeafDecay;
|
||||
public boolean disableGrassGrowth;
|
||||
public boolean disableEndermanGriefing;
|
||||
public boolean regionInvinciblityRemovesMobs;
|
||||
public boolean disableDeathMessages;
|
||||
public boolean disableObsidianGenerators;
|
||||
|
||||
private Map<String, Integer> maxRegionCounts;
|
||||
|
||||
/* Configuration data end */
|
||||
|
||||
/**
|
||||
* Construct the object.
|
||||
*
|
||||
* @param plugin The WorldGuardPlugin instance
|
||||
* @param worldName The world name that this WorldConfiguration is for.
|
||||
* @param parentConfig The parent configuration to read defaults from
|
||||
*/
|
||||
public WorldConfiguration(WorldGuardPlugin plugin, String worldName, YAMLProcessor parentConfig) {
|
||||
File baseFolder = new File(plugin.getDataFolder(), "worlds/" + worldName);
|
||||
configFile = new File(baseFolder, "config.yml");
|
||||
blacklistFile = new File(baseFolder, "blacklist.txt");
|
||||
|
||||
this.plugin = plugin;
|
||||
this.worldName = worldName;
|
||||
this.parentConfig = parentConfig;
|
||||
|
||||
plugin.createDefaultConfiguration(configFile, "config_world.yml");
|
||||
plugin.createDefaultConfiguration(blacklistFile, "blacklist.txt");
|
||||
|
||||
config = new YAMLProcessor(this.configFile, true, YAMLFormat.EXTENDED);
|
||||
loadConfiguration();
|
||||
|
||||
plugin.getLogger().info("Loaded configuration for world '" + worldName + '"');
|
||||
}
|
||||
|
||||
private boolean getBoolean(String node, boolean def) {
|
||||
boolean val = parentConfig.getBoolean(node, def);
|
||||
|
||||
if (config.getProperty(node) != null) {
|
||||
return config.getBoolean(node, def);
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
private String getString(String node, String def) {
|
||||
String val = parentConfig.getString(node, def);
|
||||
|
||||
if (config.getProperty(node) != null) {
|
||||
return config.getString(node, def);
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
private int getInt(String node, int def) {
|
||||
int val = parentConfig.getInt(node, def);
|
||||
|
||||
if (config.getProperty(node) != null) {
|
||||
return config.getInt(node, def);
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private double getDouble(String node, double def) {
|
||||
double val = parentConfig.getDouble(node, def);
|
||||
|
||||
if (config.getProperty(node) != null) {
|
||||
return config.getDouble(node, def);
|
||||
} else {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
private List<Integer> getIntList(String node, List<Integer> def) {
|
||||
List<Integer> res = parentConfig.getIntList(node, def);
|
||||
|
||||
if (res == null || res.size() == 0) {
|
||||
parentConfig.setProperty(node, new ArrayList<Integer>());
|
||||
}
|
||||
|
||||
if (config.getProperty(node) != null) {
|
||||
res = config.getIntList(node, def);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
private List<String> getStringList(String node, List<String> def) {
|
||||
List<String> res = parentConfig.getStringList(node, def);
|
||||
|
||||
if (res == null || res.size() == 0) {
|
||||
parentConfig.setProperty(node, new ArrayList<String>());
|
||||
}
|
||||
|
||||
if (config.getProperty(node) != null) {
|
||||
res = config.getStringList(node, def);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
private List<String> getKeys(String node) {
|
||||
List<String> res = parentConfig.getKeys(node);
|
||||
|
||||
if (res == null || res.size() == 0) {
|
||||
res = config.getKeys(node);
|
||||
}
|
||||
if (res == null) {
|
||||
res = new ArrayList<String>();
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
private Object getProperty(String node) {
|
||||
Object res = parentConfig.getProperty(node);
|
||||
|
||||
if (config.getProperty(node) != null) {
|
||||
res = config.getProperty(node);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the configuration.
|
||||
*/
|
||||
private void loadConfiguration() {
|
||||
try {
|
||||
config.load();
|
||||
} catch (IOException e) {
|
||||
plugin.getLogger().severe("Error reading configuration for world " + worldName + ": ");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
opPermissions = getBoolean("op-permissions", true);
|
||||
|
||||
itemDurability = getBoolean("protection.item-durability", true);
|
||||
removeInfiniteStacks = getBoolean("protection.remove-infinite-stacks", false);
|
||||
disableExpDrops = getBoolean("protection.disable-xp-orb-drops", false);
|
||||
disableObsidianGenerators = getBoolean("protection.disable-obsidian-generators", false);
|
||||
|
||||
simulateSponge = getBoolean("simulation.sponge.enable", true);
|
||||
spongeRadius = Math.max(1, getInt("simulation.sponge.radius", 3)) - 1;
|
||||
redstoneSponges = getBoolean("simulation.sponge.redstone", false);
|
||||
|
||||
pumpkinScuba = getBoolean("default.pumpkin-scuba", false);
|
||||
disableHealthRegain = getBoolean("default.disable-health-regain", false);
|
||||
|
||||
noPhysicsGravel = getBoolean("physics.no-physics-gravel", false);
|
||||
noPhysicsSand = getBoolean("physics.no-physics-sand", false);
|
||||
allowPortalAnywhere = getBoolean("physics.allow-portal-anywhere", false);
|
||||
preventWaterDamage = new HashSet<Integer>(getIntList("physics.disable-water-damage-blocks", null));
|
||||
|
||||
blockTNTExplosions = getBoolean("ignition.block-tnt", false);
|
||||
blockTNTBlockDamage = getBoolean("ignition.block-tnt-block-damage", false);
|
||||
blockLighter = getBoolean("ignition.block-lighter", false);
|
||||
|
||||
preventLavaFire = getBoolean("fire.disable-lava-fire-spread", true);
|
||||
disableFireSpread = getBoolean("fire.disable-all-fire-spread", false);
|
||||
disableFireSpreadBlocks = new HashSet<Integer>(getIntList("fire.disable-fire-spread-blocks", null));
|
||||
allowedLavaSpreadOver = new HashSet<Integer>(getIntList("fire.lava-spread-blocks", null));
|
||||
|
||||
blockCreeperExplosions = getBoolean("mobs.block-creeper-explosions", false);
|
||||
blockCreeperBlockDamage = getBoolean("mobs.block-creeper-block-damage", false);
|
||||
blockEnderDragonBlockDamage = getBoolean("mobs.block-enderdragon-block-damage", false);
|
||||
blockFireballExplosions = getBoolean("mobs.block-fireball-explosions", false);
|
||||
blockFireballBlockDamage = getBoolean("mobs.block-fireball-block-damage", false);
|
||||
antiWolfDumbness = getBoolean("mobs.anti-wolf-dumbness", false);
|
||||
disableEndermanGriefing = getBoolean("mobs.disable-enderman-griefing", false);
|
||||
|
||||
disableFallDamage = getBoolean("player-damage.disable-fall-damage", false);
|
||||
disableLavaDamage = getBoolean("player-damage.disable-lava-damage", false);
|
||||
disableFireDamage = getBoolean("player-damage.disable-fire-damage", false);
|
||||
disableLightningDamage = getBoolean("player-damage.disable-lightning-damage", false);
|
||||
disableDrowningDamage = getBoolean("player-damage.disable-drowning-damage", false);
|
||||
disableSuffocationDamage = getBoolean("player-damage.disable-suffocation-damage", false);
|
||||
disableContactDamage = getBoolean("player-damage.disable-contact-damage", false);
|
||||
teleportOnSuffocation = getBoolean("player-damage.teleport-on-suffocation", false);
|
||||
disableVoidDamage = getBoolean("player-damage.disable-void-damage", false);
|
||||
teleportOnVoid = getBoolean("player-damage.teleport-on-void-falling", false);
|
||||
disableExplosionDamage = getBoolean("player-damage.disable-explosion-damage", false);
|
||||
disableMobDamage = getBoolean("player-damage.disable-mob-damage", false);
|
||||
disableDeathMessages = getBoolean("player-damage.disable-death-messages", false);
|
||||
|
||||
signChestProtection = getBoolean("chest-protection.enable", false);
|
||||
|
||||
disableCreatureCropTrampling = getBoolean("crops.disable-creature-trampling", false);
|
||||
disablePlayerCropTrampling = getBoolean("crops.disable-player-trampling", false);
|
||||
|
||||
disallowedLightningBlocks = new HashSet<Integer>(getIntList("weather.prevent-lightning-strike-blocks", null));
|
||||
preventLightningFire = getBoolean("weather.disable-lightning-strike-fire", false);
|
||||
disableThunder = getBoolean("weather.disable-thunderstorm", false);
|
||||
disableWeather = getBoolean("weather.disable-weather", false);
|
||||
disablePigZap = getBoolean("weather.disable-pig-zombification", false);
|
||||
disableCreeperPower = getBoolean("weather.disable-powered-creepers", false);
|
||||
alwaysRaining = getBoolean("weather.always-raining", false);
|
||||
alwaysThundering = getBoolean("weather.always-thundering", false);
|
||||
|
||||
disableMushroomSpread = getBoolean("dynamics.disable-mushroom-spread", false);
|
||||
disableIceMelting = getBoolean("dynamics.disable-ice-melting", false);
|
||||
disableSnowMelting = getBoolean("dynamics.disable-snow-melting", false);
|
||||
disableSnowFormation = getBoolean("dynamics.disable-snow-formation", false);
|
||||
disableIceFormation = getBoolean("dynamics.disable-ice-formation", false);
|
||||
disableLeafDecay = getBoolean("dynamics.disable-leaf-decay", false);
|
||||
disableGrassGrowth = getBoolean("dynamics.disable-grass-growth", false);
|
||||
|
||||
useRegions = getBoolean("regions.enable", true);
|
||||
regionInvinciblityRemovesMobs = getBoolean("regions.invincibility-removes-mobs", false);
|
||||
highFreqFlags = getBoolean("regions.high-frequency-flags", false);
|
||||
regionWand = getInt("regions.wand", 287);
|
||||
maxClaimVolume = getInt("regions.max-claim-volume", 30000);
|
||||
claimOnlyInsideExistingRegions = getBoolean("regions.claim-only-inside-existing-regions", false);
|
||||
|
||||
maxRegionCountPerPlayer = getInt("regions.max-region-count-per-player.default", 7);
|
||||
maxRegionCounts = new HashMap<String, Integer>();
|
||||
maxRegionCounts.put(null, maxRegionCountPerPlayer);
|
||||
|
||||
for (String key : getKeys("regions.max-region-count-per-player")) {
|
||||
if (!key.equalsIgnoreCase("default")) {
|
||||
Object val = getProperty("regions.max-region-count-per-player." + key);
|
||||
if (val != null && val instanceof Number) {
|
||||
maxRegionCounts.put(key, ((Number) val).intValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// useiConomy = getBoolean("iconomy.enable", false);
|
||||
// buyOnClaim = getBoolean("iconomy.buy-on-claim", false);
|
||||
// buyOnClaimPrice = getDouble("iconomy.buy-on-claim-price", 1.0);
|
||||
|
||||
blockCreatureSpawn = new HashSet<CreatureType>();
|
||||
for (String creatureName : getStringList("mobs.block-creature-spawn", null)) {
|
||||
CreatureType creature = CreatureType.fromName(creatureName);
|
||||
|
||||
if (creature == null) {
|
||||
plugin.getLogger().warning("Unknown mob type '" + creatureName + "'");
|
||||
} else {
|
||||
blockCreatureSpawn.add(creature);
|
||||
}
|
||||
}
|
||||
|
||||
boolean useBlacklistAsWhitelist = getBoolean("blacklist.use-as-whitelist", false);
|
||||
|
||||
// Console log configuration
|
||||
boolean logConsole = getBoolean("blacklist.logging.console.enable", true);
|
||||
|
||||
// Database log configuration
|
||||
boolean logDatabase = getBoolean("blacklist.logging.database.enable", false);
|
||||
String dsn = getString("blacklist.logging.database.dsn", "jdbc:mysql://localhost:3306/minecraft");
|
||||
String user = getString("blacklist.logging.database.user", "root");
|
||||
String pass = getString("blacklist.logging.database.pass", "");
|
||||
String table = getString("blacklist.logging.database.table", "blacklist_events");
|
||||
|
||||
// File log configuration
|
||||
boolean logFile = getBoolean("blacklist.logging.file.enable", false);
|
||||
String logFilePattern = getString("blacklist.logging.file.path", "worldguard/logs/%Y-%m-%d.log");
|
||||
int logFileCacheSize = Math.max(1, getInt("blacklist.logging.file.open-files", 10));
|
||||
|
||||
// Load the blacklist
|
||||
try {
|
||||
// If there was an existing blacklist, close loggers
|
||||
if (blacklist != null) {
|
||||
blacklist.getLogger().close();
|
||||
}
|
||||
|
||||
// First load the blacklist data from worldguard-blacklist.txt
|
||||
Blacklist blist = new BukkitBlacklist(useBlacklistAsWhitelist, plugin);
|
||||
blist.load(blacklistFile);
|
||||
|
||||
// If the blacklist is empty, then set the field to null
|
||||
// and save some resources
|
||||
if (blist.isEmpty()) {
|
||||
this.blacklist = null;
|
||||
} else {
|
||||
this.blacklist = blist;
|
||||
plugin.getLogger().log(Level.INFO, "Blacklist loaded.");
|
||||
|
||||
BlacklistLogger blacklistLogger = blist.getLogger();
|
||||
|
||||
if (logDatabase) {
|
||||
blacklistLogger.addHandler(new DatabaseLoggerHandler(dsn, user, pass, table, worldName, plugin.getLogger()));
|
||||
}
|
||||
|
||||
if (logConsole) {
|
||||
blacklistLogger.addHandler(new ConsoleLoggerHandler(worldName, plugin.getLogger()));
|
||||
}
|
||||
|
||||
if (logFile) {
|
||||
FileLoggerHandler handler =
|
||||
new FileLoggerHandler(logFilePattern, logFileCacheSize, worldName, plugin.getLogger());
|
||||
blacklistLogger.addHandler(handler);
|
||||
}
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
plugin.getLogger().log(Level.WARNING, "WorldGuard blacklist does not exist.");
|
||||
} catch (IOException e) {
|
||||
plugin.getLogger().log(Level.WARNING, "Could not load WorldGuard blacklist: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
|
||||
// Print an overview of settings
|
||||
if (getBoolean("summary-on-start", true)) {
|
||||
plugin.getLogger().log(Level.INFO, blockTNTExplosions
|
||||
? "(" + worldName + ") TNT ignition is blocked."
|
||||
: "(" + worldName + ") TNT ignition is PERMITTED.");
|
||||
plugin.getLogger().log(Level.INFO, blockLighter
|
||||
? "(" + worldName + ") Lighters are blocked."
|
||||
: "(" + worldName + ") Lighters are PERMITTED.");
|
||||
plugin.getLogger().log(Level.INFO, preventLavaFire
|
||||
? "(" + worldName + ") Lava fire is blocked."
|
||||
: "(" + worldName + ") Lava fire is PERMITTED.");
|
||||
|
||||
if (disableFireSpread) {
|
||||
plugin.getLogger().log(Level.INFO, "(" + worldName + ") All fire spread is disabled.");
|
||||
} else {
|
||||
if (disableFireSpreadBlocks.size() > 0) {
|
||||
plugin.getLogger().log(Level.INFO, "(" + worldName
|
||||
+ ") Fire spread is limited to "
|
||||
+ disableFireSpreadBlocks.size() + " block types.");
|
||||
} else {
|
||||
plugin.getLogger().log(Level.INFO, "(" + worldName
|
||||
+ ") Fire spread is UNRESTRICTED.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
config.setHeader(CONFIG_HEADER);
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
|
||||
config.save();
|
||||
}
|
||||
|
||||
public Blacklist getBlacklist() {
|
||||
return this.blacklist;
|
||||
}
|
||||
|
||||
public String getWorldName() {
|
||||
return this.worldName;
|
||||
}
|
||||
|
||||
public boolean isChestProtected(Block block, Player player) {
|
||||
if (!signChestProtection) {
|
||||
return false;
|
||||
}
|
||||
if (plugin.hasPermission(player, "worldguard.chest-protection.override")
|
||||
|| plugin.hasPermission(player, "worldguard.override.chest-protection")) {
|
||||
return false;
|
||||
}
|
||||
return chestProtection.isProtected(block, player);
|
||||
}
|
||||
|
||||
public boolean isChestProtected(Block block) {
|
||||
if (!signChestProtection) {
|
||||
return false;
|
||||
}
|
||||
return chestProtection.isProtected(block, null);
|
||||
}
|
||||
|
||||
public boolean isChestProtectedPlacement(Block block, Player player) {
|
||||
if (!signChestProtection) {
|
||||
return false;
|
||||
}
|
||||
if (plugin.hasPermission(player, "worldguard.chest-protection.override")
|
||||
|| plugin.hasPermission(player, "worldguard.override.chest-protection")) {
|
||||
return false;
|
||||
}
|
||||
return chestProtection.isProtectedPlacement(block, player);
|
||||
}
|
||||
|
||||
public boolean isAdjacentChestProtected(Block block, Player player) {
|
||||
if (!signChestProtection) {
|
||||
return false;
|
||||
}
|
||||
if (plugin.hasPermission(player, "worldguard.chest-protection.override")
|
||||
|| plugin.hasPermission(player, "worldguard.override.chest-protection")) {
|
||||
return false;
|
||||
}
|
||||
return chestProtection.isAdjacentChestProtected(block, player);
|
||||
}
|
||||
|
||||
public ChestProtection getChestProtection() {
|
||||
return chestProtection;
|
||||
}
|
||||
|
||||
public int getMaxRegionCount(Player player) {
|
||||
int max = -1;
|
||||
for (String group : plugin.getGroups(player)) {
|
||||
if (maxRegionCounts.containsKey(group)) {
|
||||
int groupMax = maxRegionCounts.get(group);
|
||||
if (max < groupMax) max = groupMax;
|
||||
}
|
||||
}
|
||||
if (max <= -1) {
|
||||
max = maxRegionCountPerPlayer;
|
||||
}
|
||||
return max;
|
||||
}
|
||||
}
|
||||
@@ -1,834 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.sk89q.worldguard.bukkit;
|
||||
|
||||
import static com.sk89q.worldguard.bukkit.BukkitUtil.dropSign;
|
||||
import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.World;
|
||||
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.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockBurnEvent;
|
||||
import org.bukkit.event.block.BlockDamageEvent;
|
||||
import org.bukkit.event.block.BlockFadeEvent;
|
||||
import org.bukkit.event.block.BlockFormEvent;
|
||||
import org.bukkit.event.block.BlockFromToEvent;
|
||||
import org.bukkit.event.block.BlockIgniteEvent;
|
||||
import org.bukkit.event.block.BlockPhysicsEvent;
|
||||
import org.bukkit.event.block.BlockPistonExtendEvent;
|
||||
import org.bukkit.event.block.BlockPistonRetractEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.block.BlockRedstoneEvent;
|
||||
import org.bukkit.event.block.BlockSpreadEvent;
|
||||
import org.bukkit.event.block.LeavesDecayEvent;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
import org.bukkit.event.block.BlockIgniteEvent.IgniteCause;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.blocks.BlockType;
|
||||
import com.sk89q.worldedit.blocks.ItemType;
|
||||
import com.sk89q.worldedit.blocks.BlockID;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.blacklist.events.BlockBreakBlacklistEvent;
|
||||
import com.sk89q.worldguard.blacklist.events.BlockPlaceBlacklistEvent;
|
||||
import com.sk89q.worldguard.blacklist.events.DestroyWithBlacklistEvent;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.flags.DefaultFlag;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
|
||||
/**
|
||||
* The listener for block events.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class WorldGuardBlockListener implements Listener {
|
||||
|
||||
private WorldGuardPlugin plugin;
|
||||
|
||||
/**
|
||||
* Construct the object.
|
||||
*
|
||||
* @param plugin
|
||||
*/
|
||||
public WorldGuardBlockListener(WorldGuardPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register events.
|
||||
*/
|
||||
public void registerEvents() {
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the world configuration given a world.
|
||||
*
|
||||
* @param world
|
||||
* @return
|
||||
*/
|
||||
protected WorldConfiguration getWorldConfig(World world) {
|
||||
return plugin.getGlobalStateManager().get(world);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the world configuration given a player.
|
||||
*
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
protected WorldConfiguration getWorldConfig(Player player) {
|
||||
return plugin.getGlobalStateManager().get(player.getWorld());
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a block is damaged.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onBlockDamage(BlockDamageEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = event.getPlayer();
|
||||
Block blockDamaged = event.getBlock();
|
||||
|
||||
// Cake are damaged and not broken when they are eaten, so we must
|
||||
// handle them a bit separately
|
||||
if (blockDamaged.getTypeId() == BlockID.CAKE_BLOCK) {
|
||||
if (!plugin.getGlobalRegionManager().canBuild(player, blockDamaged)) {
|
||||
player.sendMessage(ChatColor.DARK_RED + "You're not invited to this tea party!");
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a block is broken.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onBlockBreak(BlockBreakEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = event.getPlayer();
|
||||
WorldConfiguration wcfg = getWorldConfig(player);
|
||||
|
||||
if (!wcfg.itemDurability) {
|
||||
ItemStack held = player.getItemInHand();
|
||||
if (held.getTypeId() > 0
|
||||
&& !(ItemType.usesDamageValue(held.getTypeId())
|
||||
|| BlockType.usesData(held.getTypeId()))) {
|
||||
held.setDurability((short) -1);
|
||||
player.setItemInHand(held);
|
||||
}
|
||||
}
|
||||
|
||||
if (!plugin.getGlobalRegionManager().canBuild(player, event.getBlock())) {
|
||||
player.sendMessage(ChatColor.DARK_RED + "You don't have permission for this area.");
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.getBlacklist() != null) {
|
||||
if (!wcfg.getBlacklist().check(
|
||||
new BlockBreakBlacklistEvent(plugin.wrapPlayer(player),
|
||||
toVector(event.getBlock()),
|
||||
event.getBlock().getTypeId()), false, false)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!wcfg.getBlacklist().check(
|
||||
new DestroyWithBlacklistEvent(plugin.wrapPlayer(player),
|
||||
toVector(event.getBlock()),
|
||||
player.getItemInHand().getTypeId()), false, false)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (wcfg.isChestProtected(event.getBlock(), player)) {
|
||||
player.sendMessage(ChatColor.DARK_RED + "The chest is protected.");
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when fluids flow.
|
||||
*/
|
||||
@EventHandler
|
||||
public void onBlockFromTo(BlockFromToEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
World world = event.getBlock().getWorld();
|
||||
Block blockFrom = event.getBlock();
|
||||
Block blockTo = event.getToBlock();
|
||||
|
||||
boolean isWater = blockFrom.getTypeId() == 8 || blockFrom.getTypeId() == 9;
|
||||
boolean isLava = blockFrom.getTypeId() == 10 || blockFrom.getTypeId() == 11;
|
||||
boolean isAir = blockFrom.getTypeId() == 0;
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld());
|
||||
|
||||
if (cfg.activityHaltToggle) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.simulateSponge && isWater) {
|
||||
int ox = blockTo.getX();
|
||||
int oy = blockTo.getY();
|
||||
int oz = blockTo.getZ();
|
||||
|
||||
for (int cx = -wcfg.spongeRadius; cx <= wcfg.spongeRadius; cx++) {
|
||||
for (int cy = -wcfg.spongeRadius; cy <= wcfg.spongeRadius; cy++) {
|
||||
for (int cz = -wcfg.spongeRadius; cz <= wcfg.spongeRadius; cz++) {
|
||||
Block sponge = world.getBlockAt(ox + cx, oy + cy, oz + cz);
|
||||
if (sponge.getTypeId() == 19
|
||||
&& (!wcfg.redstoneSponges || !sponge.isBlockIndirectlyPowered())) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*if (plugin.classicWater && isWater) {
|
||||
int blockBelow = blockFrom.getRelative(0, -1, 0).getTypeId();
|
||||
if (blockBelow != 0 && blockBelow != 8 && blockBelow != 9) {
|
||||
blockFrom.setTypeId(9);
|
||||
if (blockTo.getTypeId() == 0) {
|
||||
blockTo.setTypeId(9);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
|
||||
// Check the fluid block (from) whether it is air.
|
||||
// If so and the target block is protected, cancel the event
|
||||
if (wcfg.preventWaterDamage.size() > 0) {
|
||||
int targetId = blockTo.getTypeId();
|
||||
|
||||
if ((isAir || isWater) &&
|
||||
wcfg.preventWaterDamage.contains(targetId)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (wcfg.allowedLavaSpreadOver.size() > 0 && isLava) {
|
||||
int targetId = blockTo.getRelative(0, -1, 0).getTypeId();
|
||||
|
||||
if (!wcfg.allowedLavaSpreadOver.contains(targetId)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (wcfg.highFreqFlags && isWater
|
||||
&& !plugin.getGlobalRegionManager().allows(DefaultFlag.WATER_FLOW,
|
||||
blockFrom.getLocation())) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.highFreqFlags && isLava
|
||||
&& !plugin.getGlobalRegionManager().allows(DefaultFlag.LAVA_FLOW,
|
||||
blockFrom.getLocation())) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.disableObsidianGenerators && (isAir || isLava)
|
||||
&& blockTo.getTypeId() == 55) {
|
||||
blockTo.setTypeId(0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a block gets ignited.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onBlockIgnite(BlockIgniteEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
IgniteCause cause = event.getCause();
|
||||
Block block = event.getBlock();
|
||||
World world = block.getWorld();
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(world);
|
||||
|
||||
if (cfg.activityHaltToggle) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isFireSpread = cause == IgniteCause.SPREAD;
|
||||
|
||||
if (wcfg.preventLightningFire && cause == IgniteCause.LIGHTNING) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.preventLavaFire && cause == IgniteCause.LAVA) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.disableFireSpread && isFireSpread) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.blockLighter && cause == IgniteCause.FLINT_AND_STEEL
|
||||
&& event.getPlayer() != null
|
||||
&& !plugin.hasPermission(event.getPlayer(), "worldguard.override.lighter")) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.fireSpreadDisableToggle && isFireSpread) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.disableFireSpreadBlocks.size() > 0 && isFireSpread) {
|
||||
int x = block.getX();
|
||||
int y = block.getY();
|
||||
int z = block.getZ();
|
||||
|
||||
if (wcfg.disableFireSpreadBlocks.contains(world.getBlockTypeIdAt(x, y - 1, z))
|
||||
|| wcfg.disableFireSpreadBlocks.contains(world.getBlockTypeIdAt(x + 1, y, z))
|
||||
|| wcfg.disableFireSpreadBlocks.contains(world.getBlockTypeIdAt(x - 1, y, z))
|
||||
|| wcfg.disableFireSpreadBlocks.contains(world.getBlockTypeIdAt(x, y, z - 1))
|
||||
|| wcfg.disableFireSpreadBlocks.contains(world.getBlockTypeIdAt(x, y, z + 1))) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (wcfg.useRegions) {
|
||||
Vector pt = toVector(block);
|
||||
Player player = event.getPlayer();
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
|
||||
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
|
||||
|
||||
if (player != null && !plugin.getGlobalRegionManager().hasBypass(player, world)) {
|
||||
LocalPlayer localPlayer = plugin.wrapPlayer(player);
|
||||
|
||||
if (cause == IgniteCause.FLINT_AND_STEEL) {
|
||||
if (!set.canBuild(localPlayer)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (!set.allows(DefaultFlag.LIGHTER)
|
||||
&& !plugin.hasPermission(player, "worldguard.override.lighter")) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (wcfg.highFreqFlags && isFireSpread
|
||||
&& !set.allows(DefaultFlag.FIRE_SPREAD)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.highFreqFlags && cause == IgniteCause.LAVA
|
||||
&& !set.allows(DefaultFlag.LAVA_FIRE)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a block is destroyed from burning.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onBlockBurn(BlockBurnEvent event) {
|
||||
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld());
|
||||
|
||||
if (cfg.activityHaltToggle) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.disableFireSpread) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.fireSpreadDisableToggle) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.disableFireSpreadBlocks.size() > 0) {
|
||||
Block block = event.getBlock();
|
||||
|
||||
if (wcfg.disableFireSpreadBlocks.contains(block.getTypeId())) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (wcfg.isChestProtected(event.getBlock())) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.useRegions) {
|
||||
Block block = event.getBlock();
|
||||
Vector pt = toVector(block);
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(block.getWorld());
|
||||
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
|
||||
|
||||
if (!set.allows(DefaultFlag.FIRE_SPREAD)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when block physics occurs.
|
||||
*/
|
||||
@EventHandler
|
||||
public void onBlockPhysics(BlockPhysicsEvent event) {
|
||||
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld());
|
||||
|
||||
if (cfg.activityHaltToggle) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
int id = event.getChangedTypeId();
|
||||
|
||||
if (id == 13 && wcfg.noPhysicsGravel) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (id == 12 && wcfg.noPhysicsSand) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (id == 90 && wcfg.allowPortalAnywhere) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a player places a block.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onBlockPlace(BlockPlaceEvent event) {
|
||||
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Block blockPlaced = event.getBlock();
|
||||
Player player = event.getPlayer();
|
||||
World world = blockPlaced.getWorld();
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(world);
|
||||
|
||||
if (wcfg.useRegions) {
|
||||
if (!plugin.getGlobalRegionManager().canBuild(player, blockPlaced.getLocation())) {
|
||||
player.sendMessage(ChatColor.DARK_RED + "You don't have permission for this area.");
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (wcfg.getBlacklist() != null) {
|
||||
if (!wcfg.getBlacklist().check(
|
||||
new BlockPlaceBlacklistEvent(plugin.wrapPlayer(player), toVector(blockPlaced),
|
||||
blockPlaced.getTypeId()), false, false)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (wcfg.signChestProtection && wcfg.getChestProtection().isChest(blockPlaced.getTypeId())) {
|
||||
if (wcfg.isAdjacentChestProtected(event.getBlock(), player)) {
|
||||
player.sendMessage(ChatColor.DARK_RED + "This spot is for a chest that you don't have permission for.");
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (wcfg.simulateSponge && blockPlaced.getTypeId() == 19) {
|
||||
if (wcfg.redstoneSponges && blockPlaced.isBlockIndirectlyPowered()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int ox = blockPlaced.getX();
|
||||
int oy = blockPlaced.getY();
|
||||
int oz = blockPlaced.getZ();
|
||||
|
||||
SpongeUtil.clearSpongeWater(plugin, world, ox, oy, oz);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when redstone changes.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onBlockRedstoneChange(BlockRedstoneEvent event) {
|
||||
|
||||
Block blockTo = event.getBlock();
|
||||
World world = blockTo.getWorld();
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(world);
|
||||
|
||||
if (wcfg.simulateSponge && wcfg.redstoneSponges) {
|
||||
int ox = blockTo.getX();
|
||||
int oy = blockTo.getY();
|
||||
int oz = blockTo.getZ();
|
||||
|
||||
for (int cx = -1; cx <= 1; cx++) {
|
||||
for (int cy = -1; cy <= 1; cy++) {
|
||||
for (int cz = -1; cz <= 1; cz++) {
|
||||
Block sponge = world.getBlockAt(ox + cx, oy + cy, oz + cz);
|
||||
if (sponge.getTypeId() == 19
|
||||
&& sponge.isBlockIndirectlyPowered()) {
|
||||
SpongeUtil.clearSpongeWater(plugin, world, ox + cx, oy + cy, oz + cz);
|
||||
} else if (sponge.getTypeId() == 19
|
||||
&& !sponge.isBlockIndirectlyPowered()) {
|
||||
SpongeUtil.addSpongeWater(plugin, world, ox + cx, oy + cy, oz + cz);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a sign is changed.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onSignChange(SignChangeEvent event) {
|
||||
|
||||
Player player = event.getPlayer();
|
||||
WorldConfiguration wcfg = getWorldConfig(player);
|
||||
|
||||
if (wcfg.signChestProtection) {
|
||||
if (event.getLine(0).equalsIgnoreCase("[Lock]")) {
|
||||
if (wcfg.isChestProtectedPlacement(event.getBlock(), player)) {
|
||||
player.sendMessage(ChatColor.DARK_RED + "You do not own the adjacent chest.");
|
||||
dropSign(event.getBlock());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.getBlock().getTypeId() != BlockID.SIGN_POST) {
|
||||
player.sendMessage(ChatColor.RED
|
||||
+ "The [Lock] sign must be a sign post, not a wall sign.");
|
||||
|
||||
dropSign(event.getBlock());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!event.getLine(1).equalsIgnoreCase(player.getName())) {
|
||||
player.sendMessage(ChatColor.RED
|
||||
+ "The first owner line must be your name.");
|
||||
|
||||
dropSign(event.getBlock());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
int below = event.getBlock().getRelative(0, -1, 0).getTypeId();
|
||||
|
||||
if (below == BlockID.TNT || below == BlockID.SAND
|
||||
|| below == BlockID.GRAVEL || below == BlockID.SIGN_POST) {
|
||||
player.sendMessage(ChatColor.RED
|
||||
+ "That is not a safe block that you're putting this sign on.");
|
||||
|
||||
dropSign(event.getBlock());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
event.setLine(0, "[Lock]");
|
||||
player.sendMessage(ChatColor.YELLOW
|
||||
+ "A chest or double chest above is now protected.");
|
||||
}
|
||||
} else {
|
||||
if (event.getLine(0).equalsIgnoreCase("[Lock]")) {
|
||||
player.sendMessage(ChatColor.RED
|
||||
+ "WorldGuard's sign chest protection is disabled.");
|
||||
|
||||
dropSign(event.getBlock());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!plugin.getGlobalRegionManager().canBuild(player, event.getBlock())) {
|
||||
player.sendMessage(ChatColor.DARK_RED + "You don't have permission for this area.");
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onLeavesDecay(LeavesDecayEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld());
|
||||
|
||||
if (cfg.activityHaltToggle) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.disableLeafDecay) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.useRegions) {
|
||||
if (!plugin.getGlobalRegionManager().allows(DefaultFlag.LEAF_DECAY,
|
||||
event.getBlock().getLocation())) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a block is formed based on world conditions.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onBlockForm(BlockFormEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld());
|
||||
|
||||
if (cfg.activityHaltToggle) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
int type = event.getNewState().getTypeId();
|
||||
|
||||
if (type == BlockID.ICE) {
|
||||
if (wcfg.disableIceFormation) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows(
|
||||
DefaultFlag.ICE_FORM, event.getBlock().getLocation())) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (type == BlockID.SNOW) {
|
||||
if (wcfg.disableSnowFormation) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows(
|
||||
DefaultFlag.SNOW_FALL, event.getBlock().getLocation())) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a block spreads based on world conditions.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onBlockSpread(BlockSpreadEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld());
|
||||
|
||||
if (cfg.activityHaltToggle) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
int fromType = event.getSource().getTypeId();
|
||||
|
||||
if (fromType == BlockID.RED_MUSHROOM || fromType == BlockID.BROWN_MUSHROOM) {
|
||||
if (wcfg.disableMushroomSpread) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows(
|
||||
DefaultFlag.MUSHROOMS, event.getBlock().getLocation())) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (fromType == BlockID.GRASS) {
|
||||
if (wcfg.disableGrassGrowth) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows(
|
||||
DefaultFlag.GRASS_SPREAD, event.getBlock().getLocation())) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a block fades.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onBlockFade(BlockFadeEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld());
|
||||
|
||||
int type = event.getBlock().getTypeId();
|
||||
|
||||
if (type == BlockID.ICE) {
|
||||
if (wcfg.disableIceMelting) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows(
|
||||
DefaultFlag.ICE_MELT, event.getBlock().getLocation())) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (type == BlockID.SNOW) {
|
||||
if (wcfg.disableSnowMelting) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows(
|
||||
DefaultFlag.SNOW_MELT, event.getBlock().getLocation())) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a piston extends
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onBlockPistonExtend(BlockPistonExtendEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld());
|
||||
|
||||
if (wcfg.useRegions) {
|
||||
if (!plugin.getGlobalRegionManager().allows(DefaultFlag.PISTONS, event.getBlock().getLocation())) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
for (Block block : event.getBlocks()) {
|
||||
if (!plugin.getGlobalRegionManager().allows(DefaultFlag.PISTONS, block.getLocation())) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a piston retracts
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onBlockPistonRetract(BlockPistonRetractEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld());
|
||||
|
||||
if (wcfg.useRegions && event.isSticky()) {
|
||||
if (!(plugin.getGlobalRegionManager().allows(DefaultFlag.PISTONS, event.getRetractLocation()))
|
||||
|| !(plugin.getGlobalRegionManager().allows(DefaultFlag.PISTONS, event.getBlock().getLocation()))) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,911 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.sk89q.worldguard.bukkit;
|
||||
|
||||
import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sk89q.worldedit.blocks.BlockID;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Creature;
|
||||
import org.bukkit.entity.CreatureType;
|
||||
import org.bukkit.entity.Creeper;
|
||||
import org.bukkit.entity.EnderDragon;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Fireball;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Painting;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.entity.Skeleton;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.entity.Wolf;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
import org.bukkit.event.entity.CreeperPowerEvent;
|
||||
import org.bukkit.event.entity.EndermanPickupEvent;
|
||||
import org.bukkit.event.entity.EndermanPlaceEvent;
|
||||
import org.bukkit.event.entity.EntityCombustEvent;
|
||||
import org.bukkit.event.entity.EntityDamageByBlockEvent;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.entity.EntityDeathEvent;
|
||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||
import org.bukkit.event.entity.EntityInteractEvent;
|
||||
import org.bukkit.event.entity.EntityRegainHealthEvent;
|
||||
import org.bukkit.event.entity.ExplosionPrimeEvent;
|
||||
import org.bukkit.event.entity.FoodLevelChangeEvent;
|
||||
import org.bukkit.event.entity.PigZapEvent;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
import org.bukkit.event.painting.PaintingBreakByEntityEvent;
|
||||
import org.bukkit.event.painting.PaintingBreakEvent;
|
||||
import org.bukkit.event.painting.PaintingPlaceEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.blacklist.events.BlockBreakBlacklistEvent;
|
||||
import com.sk89q.worldguard.blacklist.events.ItemUseBlacklistEvent;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.flags.DefaultFlag;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
|
||||
/**
|
||||
* Listener for entity related events.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class WorldGuardEntityListener implements Listener {
|
||||
|
||||
private WorldGuardPlugin plugin;
|
||||
|
||||
/**
|
||||
* Construct the object;
|
||||
*
|
||||
* @param plugin
|
||||
*/
|
||||
public WorldGuardEntityListener(WorldGuardPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register events.
|
||||
*/
|
||||
public void registerEvents() {
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an entity interacts with another object.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onEntityInteract(EntityInteractEvent event) {
|
||||
Entity entity = event.getEntity();
|
||||
Block block = event.getBlock();
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(entity.getWorld());
|
||||
|
||||
if (block.getTypeId() == BlockID.SOIL) {
|
||||
if (entity instanceof Creature && wcfg.disableCreatureCropTrampling) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an entity dies.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onEntityDeath(EntityDeathEvent event) {
|
||||
WorldConfiguration wcfg = plugin.getGlobalStateManager().get(event.getEntity().getWorld());
|
||||
|
||||
if (wcfg.disableExpDrops || !plugin.getGlobalRegionManager().allows(DefaultFlag.EXP_DROPS,
|
||||
event.getEntity().getLocation())) {
|
||||
event.setDroppedExp(0);
|
||||
}
|
||||
|
||||
try {
|
||||
if (event instanceof PlayerDeathEvent && wcfg.disableDeathMessages) {
|
||||
((PlayerDeathEvent) event).setDeathMessage("");
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
// old CraftBukkit, eat it
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on entity damage by a block.
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
private void onEntityDamageByBlock(EntityDamageByBlockEvent event) {
|
||||
Entity defender = event.getEntity();
|
||||
DamageCause type = event.getCause();
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(defender.getWorld());
|
||||
|
||||
if (defender instanceof Wolf && ((Wolf) defender).isTamed()) {
|
||||
if (wcfg.antiWolfDumbness && !(type == DamageCause.VOID)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
} else if (defender instanceof Player) {
|
||||
Player player = (Player) defender;
|
||||
|
||||
if (isInvincible(player)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.disableLavaDamage && type == DamageCause.LAVA) {
|
||||
event.setCancelled(true);
|
||||
player.setFireTicks(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.disableContactDamage && type == DamageCause.CONTACT) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.teleportOnVoid && type == DamageCause.VOID) {
|
||||
BukkitUtil.findFreePosition(player);
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.disableVoidDamage && type == DamageCause.VOID) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.disableExplosionDamage && type == DamageCause.BLOCK_EXPLOSION) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on entity damage by an entity.
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
private void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
|
||||
if (event.getCause() == DamageCause.PROJECTILE) {
|
||||
onEntityDamageByProjectile(event);
|
||||
return;
|
||||
}
|
||||
|
||||
Entity attacker = event.getDamager();
|
||||
Entity defender = event.getEntity();
|
||||
|
||||
if (attacker instanceof Player) {
|
||||
Player player = (Player) attacker;
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(player.getWorld());
|
||||
|
||||
ItemStack held = player.getInventory().getItemInHand();
|
||||
|
||||
if (held != null) {
|
||||
if (wcfg.getBlacklist() != null) {
|
||||
if (!wcfg.getBlacklist().check(
|
||||
new ItemUseBlacklistEvent(plugin.wrapPlayer(player),
|
||||
toVector(player.getLocation()), held.getTypeId()), false, false)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (defender instanceof Player) {
|
||||
Player player = (Player) defender;
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(player.getWorld());
|
||||
|
||||
if (isInvincible(player)) {
|
||||
if (wcfg.regionInvinciblityRemovesMobs
|
||||
&& attacker instanceof LivingEntity && !(attacker instanceof Player)
|
||||
&& !(attacker instanceof Tameable && ((Tameable) attacker).isTamed())) {
|
||||
attacker.remove();
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.disableLightningDamage && event.getCause() == DamageCause.LIGHTNING) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.disableExplosionDamage && event.getCause() == DamageCause.ENTITY_EXPLOSION) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (attacker != null && attacker instanceof Player) {
|
||||
if (wcfg.useRegions) {
|
||||
Vector pt = toVector(defender.getLocation());
|
||||
Vector pt2 = toVector(attacker.getLocation());
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld());
|
||||
|
||||
if (!mgr.getApplicableRegions(pt).allows(DefaultFlag.PVP) || !mgr.getApplicableRegions(pt2).allows(DefaultFlag.PVP)) {
|
||||
((Player) attacker).sendMessage(ChatColor.DARK_RED + "You are in a no-PvP area.");
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (attacker != null && attacker instanceof TNTPrimed) {
|
||||
if (wcfg.blockTNTExplosions) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (wcfg.useRegions) {
|
||||
Vector pt = toVector(defender.getLocation());
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld());
|
||||
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
|
||||
if (!set.allows(DefaultFlag.TNT)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (attacker != null && attacker instanceof Fireball) {
|
||||
if (wcfg.blockFireballExplosions) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (wcfg.useRegions) {
|
||||
Fireball fireball = (Fireball) attacker;
|
||||
Vector pt = toVector(defender.getLocation());
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld());
|
||||
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
|
||||
if (fireball.getShooter() instanceof Player) {
|
||||
Vector pt2 = toVector(fireball.getShooter().getLocation());
|
||||
if (!set.allows(DefaultFlag.PVP) || !mgr.getApplicableRegions(pt2).allows(DefaultFlag.PVP)) {
|
||||
((Player) fireball.getShooter()).sendMessage(ChatColor.DARK_RED + "You are in a no-PvP area.");
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!set.allows(DefaultFlag.GHAST_FIREBALL)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (attacker != null && attacker instanceof LivingEntity
|
||||
&& !(attacker instanceof Player)) {
|
||||
if (attacker instanceof Creeper && wcfg.blockCreeperExplosions) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.disableMobDamage) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.useRegions) {
|
||||
Vector pt = toVector(defender.getLocation());
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld());
|
||||
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
|
||||
|
||||
if (!set.allows(DefaultFlag.MOB_DAMAGE)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (attacker instanceof Creeper) {
|
||||
if (!set.allows(DefaultFlag.CREEPER_EXPLOSION)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on entity damage by a projectile.
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
private void onEntityDamageByProjectile(EntityDamageByEntityEvent event) {
|
||||
Entity defender = event.getEntity();
|
||||
Entity attacker = ((Projectile) event.getDamager()).getShooter();
|
||||
|
||||
if (defender instanceof Player) {
|
||||
Player player = (Player) defender;
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(player.getWorld());
|
||||
|
||||
if (isInvincible(player)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (attacker != null && attacker instanceof Player) {
|
||||
if (wcfg.useRegions) {
|
||||
Vector pt = toVector(defender.getLocation());
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld());
|
||||
|
||||
if (!mgr.getApplicableRegions(pt).allows(DefaultFlag.PVP)) {
|
||||
((Player) attacker).sendMessage(ChatColor.DARK_RED + "You are in a no-PvP area.");
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (attacker != null && attacker instanceof Skeleton) {
|
||||
if (wcfg.disableMobDamage) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (wcfg.useRegions) {
|
||||
Vector pt = toVector(defender.getLocation());
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld());
|
||||
|
||||
if (!mgr.getApplicableRegions(pt).allows(DefaultFlag.MOB_DAMAGE)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on entity damage.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onEntityDamage(EntityDamageEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event instanceof EntityDamageByEntityEvent) {
|
||||
this.onEntityDamageByEntity((EntityDamageByEntityEvent) event);
|
||||
return;
|
||||
} else if (event instanceof EntityDamageByBlockEvent) {
|
||||
this.onEntityDamageByBlock((EntityDamageByBlockEvent) event);
|
||||
return;
|
||||
}
|
||||
|
||||
Entity defender = event.getEntity();
|
||||
DamageCause type = event.getCause();
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(defender.getWorld());
|
||||
|
||||
if (defender instanceof Wolf && ((Wolf) defender).isTamed()) {
|
||||
if (wcfg.antiWolfDumbness) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
} else if (defender instanceof Player) {
|
||||
Player player = (Player) defender;
|
||||
|
||||
if (isInvincible(player)) {
|
||||
event.setCancelled(true);
|
||||
player.setFireTicks(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == DamageCause.DROWNING && cfg.hasAmphibiousMode(player)) {
|
||||
player.setRemainingAir(player.getMaximumAir());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == DamageCause.DROWNING && wcfg.pumpkinScuba
|
||||
&& (player.getInventory().getHelmet().getTypeId() == BlockID.PUMPKIN
|
||||
|| player.getInventory().getHelmet().getTypeId() == BlockID.JACKOLANTERN)) {
|
||||
player.setRemainingAir(player.getMaximumAir());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.disableFallDamage && type == DamageCause.FALL) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.disableFireDamage && (type == DamageCause.FIRE
|
||||
|| type == DamageCause.FIRE_TICK)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.disableDrowningDamage && type == DamageCause.DROWNING) {
|
||||
player.setRemainingAir(player.getMaximumAir());
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.teleportOnSuffocation && type == DamageCause.SUFFOCATION) {
|
||||
BukkitUtil.findFreePosition(player);
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.disableSuffocationDamage && type == DamageCause.SUFFOCATION) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on entity combust.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onEntityCombust(EntityCombustEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Entity entity = event.getEntity();
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(entity.getWorld());
|
||||
|
||||
if (entity instanceof Player) {
|
||||
Player player = (Player) entity;
|
||||
|
||||
if (cfg.hasGodMode(player) || (wcfg.useRegions && RegionQueryUtil.isInvincible(plugin, player))) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on entity explode.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onEntityExplode(EntityExplodeEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
Location l = event.getLocation();
|
||||
World world = l.getWorld();
|
||||
WorldConfiguration wcfg = cfg.get(world);
|
||||
Entity ent = event.getEntity();
|
||||
|
||||
if (cfg.activityHaltToggle) {
|
||||
ent.remove();
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ent instanceof Creeper) {
|
||||
if (wcfg.blockCreeperBlockDamage) {
|
||||
event.blockList().clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.blockCreeperExplosions) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.useRegions) {
|
||||
if (wcfg.useRegions) {
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
|
||||
|
||||
for (Block block : event.blockList()) {
|
||||
if (!mgr.getApplicableRegions(toVector(block)).allows(DefaultFlag.CREEPER_EXPLOSION)) {
|
||||
event.blockList().clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (ent instanceof EnderDragon) {
|
||||
if (wcfg.blockEnderDragonBlockDamage) {
|
||||
event.blockList().clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.useRegions) {
|
||||
if (wcfg.useRegions) {
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
|
||||
|
||||
for (Block block : event.blockList()) {
|
||||
if (!mgr.getApplicableRegions(toVector(block)).allows(DefaultFlag.ENDERDRAGON_BLOCK_DAMAGE)) {
|
||||
event.blockList().clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (ent instanceof TNTPrimed) {
|
||||
if (wcfg.blockTNTBlockDamage) {
|
||||
event.blockList().clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.blockTNTExplosions) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.useRegions) {
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
|
||||
|
||||
for (Block block : event.blockList()) {
|
||||
if (!mgr.getApplicableRegions(toVector(block)).allows(DefaultFlag.TNT)) {
|
||||
event.blockList().clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (ent instanceof Fireball) {
|
||||
if (wcfg.blockFireballBlockDamage) {
|
||||
event.blockList().clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.blockFireballExplosions) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.useRegions) {
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
|
||||
|
||||
for (Block block : event.blockList()) {
|
||||
if (!mgr.getApplicableRegions(toVector(block)).allows(DefaultFlag.GHAST_FIREBALL)) {
|
||||
event.blockList().clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (wcfg.signChestProtection) {
|
||||
for (Block block : event.blockList()) {
|
||||
if (wcfg.isChestProtected(block)) {
|
||||
event.blockList().clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on explosion prime
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onExplosionPrime(ExplosionPrimeEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
Entity ent = event.getEntity();
|
||||
|
||||
if (cfg.activityHaltToggle) {
|
||||
ent.remove();
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on creature spawn.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onCreatureSpawn(CreatureSpawnEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
|
||||
if (cfg.activityHaltToggle) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
WorldConfiguration wcfg = cfg.get(event.getEntity().getWorld());
|
||||
CreatureType creaType = event.getCreatureType();
|
||||
|
||||
if (wcfg.blockCreatureSpawn.contains(creaType)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
Location eventLoc = event.getLocation();
|
||||
|
||||
if (wcfg.useRegions) {
|
||||
Vector pt = toVector(eventLoc);
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(eventLoc.getWorld());
|
||||
// @TODO get victims' stacktraces and find out why it's null anyway
|
||||
if (mgr == null) return;
|
||||
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
|
||||
|
||||
if (!set.allows(DefaultFlag.MOB_SPAWNING)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
Set<CreatureType> creatureTypes = set.getFlag(DefaultFlag.DENY_SPAWN);
|
||||
if (creatureTypes != null && creatureTypes.contains(creaType)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on pig zap.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onPigZap(PigZapEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(event.getEntity().getWorld());
|
||||
|
||||
if (wcfg.disablePigZap) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on creeper power.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onCreeperPower(CreeperPowerEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(event.getEntity().getWorld());
|
||||
|
||||
if (wcfg.disableCreeperPower) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a painting is removed.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onPaintingBreak(PaintingBreakEvent breakEvent) {
|
||||
if (breakEvent.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(breakEvent instanceof PaintingBreakByEntityEvent)) {
|
||||
return;
|
||||
}
|
||||
|
||||
PaintingBreakByEntityEvent event = (PaintingBreakByEntityEvent) breakEvent;
|
||||
if (!(event.getRemover() instanceof Player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Painting painting= event.getPainting();
|
||||
Player player = (Player) event.getRemover();
|
||||
World world = painting.getWorld();
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(world);
|
||||
|
||||
if (wcfg.getBlacklist() != null) {
|
||||
if (!wcfg.getBlacklist().check(
|
||||
new BlockBreakBlacklistEvent(plugin.wrapPlayer(player),
|
||||
toVector(player.getLocation()), 321), false, false)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (wcfg.useRegions) {
|
||||
if (!plugin.getGlobalRegionManager().canBuild(player, painting.getLocation())) {
|
||||
player.sendMessage(ChatColor.DARK_RED + "You don't have permission for this area.");
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on painting place.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onPaintingPlace(PaintingPlaceEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Block placedOn = event.getBlock();
|
||||
Player player = event.getPlayer();
|
||||
World world = placedOn.getWorld();
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(world);
|
||||
|
||||
if (wcfg.getBlacklist() != null) {
|
||||
if (!wcfg.getBlacklist().check(
|
||||
new ItemUseBlacklistEvent(plugin.wrapPlayer(player),
|
||||
toVector(player.getLocation()), 321), false, false)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (wcfg.useRegions) {
|
||||
if (!plugin.getGlobalRegionManager().canBuild(player, placedOn.getLocation())) {
|
||||
player.sendMessage(ChatColor.DARK_RED + "You don't have permission for this area.");
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on entity health regain.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onEntityRegainHealth(EntityRegainHealthEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Entity ent = event.getEntity();
|
||||
World world = ent.getWorld();
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(world);
|
||||
|
||||
if (wcfg.disableHealthRegain) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an enderman picks a block up.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onEndermanPickup(EndermanPickupEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Entity ent = event.getEntity();
|
||||
Block block = event.getBlock();
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(ent.getWorld());
|
||||
|
||||
if (wcfg.disableEndermanGriefing) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.useRegions) {
|
||||
if (!plugin.getGlobalRegionManager().allows(DefaultFlag.ENDER_BUILD, block.getLocation())) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an enderman places a block.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onEndermanPlace(EndermanPlaceEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Entity ent = event.getEntity();
|
||||
Location loc = event.getLocation();
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(ent.getWorld());
|
||||
|
||||
if (wcfg.disableEndermanGriefing) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcfg.useRegions) {
|
||||
if (!plugin.getGlobalRegionManager().allows(DefaultFlag.ENDER_BUILD, loc)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onFoodLevelChange(FoodLevelChangeEvent event) {
|
||||
if (event.getEntity() instanceof Player) {
|
||||
Player player = (Player) event.getEntity();
|
||||
if (event.getFoodLevel() < player.getFoodLevel() && isInvincible(player)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a player is invincible, via either god mode or region flag. If
|
||||
* the region denies invincibility, the player must have an extra permission
|
||||
* to override it. (worldguard.god.override-regions)
|
||||
*
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
private boolean isInvincible(Player player) {
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(player.getWorld());
|
||||
|
||||
boolean god = cfg.hasGodMode(player);
|
||||
if (wcfg.useRegions) {
|
||||
Boolean flag = RegionQueryUtil.isAllowedInvinciblity(plugin, player);
|
||||
boolean allowed = flag == null || flag == true;
|
||||
boolean invincible = RegionQueryUtil.isInvincible(plugin, player);
|
||||
|
||||
if (allowed) {
|
||||
return god || invincible;
|
||||
} else {
|
||||
return (god && plugin.hasPermission(player, "worldguard.god.override-regions"))
|
||||
|| invincible;
|
||||
}
|
||||
} else {
|
||||
return god;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,808 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.bukkit;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.logging.Filter;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
import com.sk89q.bukkit.util.CommandsManagerRegistration;
|
||||
import com.sk89q.minecraft.util.commands.*;
|
||||
import com.sk89q.wepif.PermissionsResolverManager;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.World.Environment;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.TickSyncDelayLoggerFilter;
|
||||
import com.sk89q.worldguard.bukkit.commands.GeneralCommands;
|
||||
import com.sk89q.worldguard.bukkit.commands.ProtectionCommands;
|
||||
import com.sk89q.worldguard.bukkit.commands.ToggleCommands;
|
||||
import com.sk89q.worldguard.protection.GlobalRegionManager;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
|
||||
/**
|
||||
* The main class for WorldGuard as a Bukkit plugin.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class WorldGuardPlugin extends JavaPlugin {
|
||||
|
||||
/**
|
||||
* Manager for commands. This automatically handles nested commands,
|
||||
* permissions checking, and a number of other fancy command things.
|
||||
* We just set it up and register commands against it.
|
||||
*/
|
||||
private final CommandsManager<CommandSender> commands;
|
||||
|
||||
/**
|
||||
* Handles the region databases for all worlds.
|
||||
*/
|
||||
private final GlobalRegionManager globalRegionManager;
|
||||
|
||||
/**
|
||||
* Handles all configuration.
|
||||
*/
|
||||
private final ConfigurationManager configuration;
|
||||
|
||||
/**
|
||||
* Used for scheduling flags.
|
||||
*/
|
||||
private FlagStateManager flagStateManager;
|
||||
|
||||
/**
|
||||
* Construct objects. Actual loading occurs when the plugin is enabled, so
|
||||
* this merely instantiates the objects.
|
||||
*/
|
||||
public WorldGuardPlugin() {
|
||||
configuration = new ConfigurationManager(this);
|
||||
globalRegionManager = new GlobalRegionManager(this);
|
||||
|
||||
final WorldGuardPlugin plugin = this;
|
||||
commands = new CommandsManager<CommandSender>() {
|
||||
@Override
|
||||
public boolean hasPermission(CommandSender player, String perm) {
|
||||
return plugin.hasPermission(player, perm);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on plugin enable.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public void onEnable() {
|
||||
|
||||
// Set the proper command injector
|
||||
commands.setInjector(new SimpleInjector(this));
|
||||
|
||||
// Register command classes
|
||||
final CommandsManagerRegistration reg = new CommandsManagerRegistration(this, commands);
|
||||
reg.register(ToggleCommands.class);
|
||||
reg.register(ProtectionCommands.class);
|
||||
|
||||
getServer().getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!getGlobalStateManager().hasCommandBookGodMode()) {
|
||||
reg.register(GeneralCommands.class);
|
||||
}
|
||||
}
|
||||
}, 0L);
|
||||
|
||||
// Need to create the plugins/WorldGuard folder
|
||||
getDataFolder().mkdirs();
|
||||
|
||||
PermissionsResolverManager.initialize(this);
|
||||
|
||||
// This must be done before configuration is loaded
|
||||
LegacyWorldGuardMigration.migrateBlacklist(this);
|
||||
|
||||
// Load the configuration
|
||||
configuration.load();
|
||||
globalRegionManager.preload();
|
||||
|
||||
// Migrate regions after the regions were loaded because
|
||||
// the migration code reuses the loaded region managers
|
||||
LegacyWorldGuardMigration.migrateRegions(this);
|
||||
|
||||
flagStateManager = new FlagStateManager(this);
|
||||
|
||||
if (configuration.useRegionsScheduler) {
|
||||
getServer().getScheduler().scheduleAsyncRepeatingTask(this, flagStateManager, FlagStateManager.RUN_DELAY, FlagStateManager.RUN_DELAY);
|
||||
}
|
||||
|
||||
if (configuration.suppressTickSyncWarnings) {
|
||||
Logger.getLogger("Minecraft").setFilter(
|
||||
new TickSyncDelayLoggerFilter());
|
||||
} else {
|
||||
Filter filter = Logger.getLogger("Minecraft").getFilter();
|
||||
if (filter != null && filter instanceof TickSyncDelayLoggerFilter) {
|
||||
Logger.getLogger("Minecraft").setFilter(null);
|
||||
}
|
||||
}
|
||||
|
||||
// Register events
|
||||
(new WorldGuardPlayerListener(this)).registerEvents();
|
||||
(new WorldGuardBlockListener(this)).registerEvents();
|
||||
(new WorldGuardEntityListener(this)).registerEvents();
|
||||
(new WorldGuardWeatherListener(this)).registerEvents();
|
||||
(new WorldGuardVehicleListener(this)).registerEvents();
|
||||
(new WorldGuardServerListener(this)).registerEvents();
|
||||
|
||||
// handle worlds separately to initialize already loaded worlds
|
||||
WorldGuardWorldListener worldListener = (new WorldGuardWorldListener(this));
|
||||
for (World world : getServer().getWorlds()) {
|
||||
worldListener.initWorld(world);
|
||||
}
|
||||
worldListener.registerEvents();
|
||||
|
||||
if (!configuration.hasCommandBookGodMode()) {
|
||||
// Check god mode for existing players, if any
|
||||
for (Player player : getServer().getOnlinePlayers()) {
|
||||
if (inGroup(player, "wg-invincible") ||
|
||||
(configuration.autoGodMode && hasPermission(player, "worldguard.auto-invincible"))) {
|
||||
configuration.enableGodMode(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on plugin disable.
|
||||
*/
|
||||
public void onDisable() {
|
||||
globalRegionManager.unload();
|
||||
configuration.unload();
|
||||
this.getServer().getScheduler().cancelTasks(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a command.
|
||||
*/
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command cmd, String label,
|
||||
String[] args) {
|
||||
try {
|
||||
commands.execute(cmd.getName(), args, sender, sender);
|
||||
} catch (CommandPermissionsException e) {
|
||||
sender.sendMessage(ChatColor.RED + "You don't have permission.");
|
||||
} catch (MissingNestedCommandException e) {
|
||||
sender.sendMessage(ChatColor.RED + e.getUsage());
|
||||
} catch (CommandUsageException e) {
|
||||
sender.sendMessage(ChatColor.RED + e.getMessage());
|
||||
sender.sendMessage(ChatColor.RED + e.getUsage());
|
||||
} catch (WrappedCommandException e) {
|
||||
if (e.getCause() instanceof NumberFormatException) {
|
||||
sender.sendMessage(ChatColor.RED + "Number expected, string received instead.");
|
||||
} else {
|
||||
sender.sendMessage(ChatColor.RED + "An error has occurred. See console.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (CommandException e) {
|
||||
sender.sendMessage(ChatColor.RED + e.getMessage());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the GlobalRegionManager.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public GlobalRegionManager getGlobalRegionManager() {
|
||||
return globalRegionManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the WorldGuardConfiguraton.
|
||||
*
|
||||
* @return
|
||||
* @deprecated Use {@link #getGlobalStateManager()} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public ConfigurationManager getGlobalConfiguration() {
|
||||
return getGlobalStateManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the flag state manager.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public FlagStateManager getFlagStateManager() {
|
||||
return flagStateManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the WorldGuardConfiguraton.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public ConfigurationManager getGlobalStateManager() {
|
||||
return configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a player is in a group.
|
||||
*
|
||||
* @param player
|
||||
* @param group
|
||||
* @return
|
||||
*/
|
||||
public boolean inGroup(Player player, String group) {
|
||||
try {
|
||||
return PermissionsResolverManager.getInstance().inGroup(player, group);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the groups of a player.
|
||||
*
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
public String[] getGroups(Player player) {
|
||||
try {
|
||||
return PermissionsResolverManager.getInstance().getGroups(player);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
return new String[0];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of a command sender. This is a unique name and this
|
||||
* method should never return a "display name".
|
||||
*
|
||||
* @param sender
|
||||
* @return
|
||||
*/
|
||||
public String toUniqueName(CommandSender sender) {
|
||||
if (sender instanceof Player) {
|
||||
return ((Player) sender).getName();
|
||||
} else {
|
||||
return "*Console*";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of a command sender. This play be a display name.
|
||||
*
|
||||
* @param sender
|
||||
* @return
|
||||
*/
|
||||
public String toName(CommandSender sender) {
|
||||
if (sender instanceof Player) {
|
||||
return ((Player) sender).getName();
|
||||
} else {
|
||||
return "*Console*";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks permissions.
|
||||
*
|
||||
* @param sender
|
||||
* @param perm
|
||||
* @return
|
||||
*/
|
||||
public boolean hasPermission(CommandSender sender, String perm) {
|
||||
if (sender.isOp()) {
|
||||
if (sender instanceof Player) {
|
||||
if (this.getGlobalStateManager().get(((Player) sender).
|
||||
getWorld()).opPermissions) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Invoke the permissions resolver
|
||||
if (sender instanceof Player) {
|
||||
Player player = (Player) sender;
|
||||
return PermissionsResolverManager.getInstance().hasPermission(player.getWorld().getName(), player.getName(), perm);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks permissions and throws an exception if permission is not met.
|
||||
*
|
||||
* @param sender
|
||||
* @param perm
|
||||
* @throws CommandPermissionsException
|
||||
*/
|
||||
public void checkPermission(CommandSender sender, String perm)
|
||||
throws CommandPermissionsException {
|
||||
if (!hasPermission(sender, perm)) {
|
||||
throw new CommandPermissionsException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the sender is a player, otherwise throw an exception.
|
||||
*
|
||||
* @param sender
|
||||
* @return
|
||||
* @throws CommandException
|
||||
*/
|
||||
public Player checkPlayer(CommandSender sender)
|
||||
throws CommandException {
|
||||
if (sender instanceof Player) {
|
||||
return (Player) sender;
|
||||
} else {
|
||||
throw new CommandException("A player is expected.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Match player names.
|
||||
*
|
||||
* @param filter
|
||||
* @return
|
||||
*/
|
||||
public List<Player> matchPlayerNames(String filter) {
|
||||
Player[] players = getServer().getOnlinePlayers();
|
||||
|
||||
filter = filter.toLowerCase();
|
||||
|
||||
// Allow exact name matching
|
||||
if (filter.charAt(0) == '@' && filter.length() >= 2) {
|
||||
filter = filter.substring(1);
|
||||
|
||||
for (Player player : players) {
|
||||
if (player.getName().equalsIgnoreCase(filter)) {
|
||||
List<Player> list = new ArrayList<Player>();
|
||||
list.add(player);
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
return new ArrayList<Player>();
|
||||
// Allow partial name matching
|
||||
} else if (filter.charAt(0) == '*' && filter.length() >= 2) {
|
||||
filter = filter.substring(1);
|
||||
|
||||
List<Player> list = new ArrayList<Player>();
|
||||
|
||||
for (Player player : players) {
|
||||
if (player.getName().toLowerCase().contains(filter)) {
|
||||
list.add(player);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
|
||||
// Start with name matching
|
||||
} else {
|
||||
List<Player> list = new ArrayList<Player>();
|
||||
|
||||
for (Player player : players) {
|
||||
if (player.getName().toLowerCase().startsWith(filter)) {
|
||||
list.add(player);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given list of players is greater than size 0, otherwise
|
||||
* throw an exception.
|
||||
*
|
||||
* @param players
|
||||
* @return
|
||||
* @throws CommandException
|
||||
*/
|
||||
protected Iterable<Player> checkPlayerMatch(List<Player> players)
|
||||
throws CommandException {
|
||||
// Check to see if there were any matches
|
||||
if (players.size() == 0) {
|
||||
throw new CommandException("No players matched query.");
|
||||
}
|
||||
|
||||
return players;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks permissions and throws an exception if permission is not met.
|
||||
*
|
||||
* @param source
|
||||
* @param filter
|
||||
* @return iterator for players
|
||||
* @throws CommandException no matches found
|
||||
*/
|
||||
public Iterable<Player> matchPlayers(CommandSender source, String filter)
|
||||
throws CommandException {
|
||||
|
||||
if (getServer().getOnlinePlayers().length == 0) {
|
||||
throw new CommandException("No players matched query.");
|
||||
}
|
||||
|
||||
if (filter.equals("*")) {
|
||||
return checkPlayerMatch(Arrays.asList(getServer().getOnlinePlayers()));
|
||||
}
|
||||
|
||||
// Handle special hash tag groups
|
||||
if (filter.charAt(0) == '#') {
|
||||
// Handle #world, which matches player of the same world as the
|
||||
// calling source
|
||||
if (filter.equalsIgnoreCase("#world")) {
|
||||
List<Player> players = new ArrayList<Player>();
|
||||
Player sourcePlayer = checkPlayer(source);
|
||||
World sourceWorld = sourcePlayer.getWorld();
|
||||
|
||||
for (Player player : getServer().getOnlinePlayers()) {
|
||||
if (player.getWorld().equals(sourceWorld)) {
|
||||
players.add(player);
|
||||
}
|
||||
}
|
||||
|
||||
return checkPlayerMatch(players);
|
||||
|
||||
// Handle #near, which is for nearby players.
|
||||
} else if (filter.equalsIgnoreCase("#near")) {
|
||||
List<Player> players = new ArrayList<Player>();
|
||||
Player sourcePlayer = checkPlayer(source);
|
||||
World sourceWorld = sourcePlayer.getWorld();
|
||||
org.bukkit.util.Vector sourceVector
|
||||
= sourcePlayer.getLocation().toVector();
|
||||
|
||||
for (Player player : getServer().getOnlinePlayers()) {
|
||||
if (player.getWorld().equals(sourceWorld)
|
||||
&& player.getLocation().toVector().distanceSquared(
|
||||
sourceVector) < 900) {
|
||||
players.add(player);
|
||||
}
|
||||
}
|
||||
|
||||
return checkPlayerMatch(players);
|
||||
|
||||
} else {
|
||||
throw new CommandException("Invalid group '" + filter + "'.");
|
||||
}
|
||||
}
|
||||
|
||||
List<Player> players = matchPlayerNames(filter);
|
||||
|
||||
return checkPlayerMatch(players);
|
||||
}
|
||||
|
||||
/**
|
||||
* Match only a single player.
|
||||
*
|
||||
* @param sender
|
||||
* @param filter
|
||||
* @return
|
||||
* @throws CommandException
|
||||
*/
|
||||
public Player matchSinglePlayer(CommandSender sender, String filter)
|
||||
throws CommandException {
|
||||
// This will throw an exception if there are no matches
|
||||
Iterator<Player> players = matchPlayers(sender, filter).iterator();
|
||||
|
||||
Player match = players.next();
|
||||
|
||||
// We don't want to match the wrong person, so fail if if multiple
|
||||
// players were found (we don't want to just pick off the first one,
|
||||
// as that may be the wrong player)
|
||||
if (players.hasNext()) {
|
||||
throw new CommandException("More than one player found! " +
|
||||
"Use @<name> for exact matching.");
|
||||
}
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
/**
|
||||
* Match only a single player or console.
|
||||
*
|
||||
* @param sender
|
||||
* @param filter
|
||||
* @return
|
||||
* @throws CommandException
|
||||
*/
|
||||
public CommandSender matchPlayerOrConsole(CommandSender sender, String filter)
|
||||
throws CommandException {
|
||||
|
||||
// Let's see if console is wanted
|
||||
if (filter.equalsIgnoreCase("#console")
|
||||
|| filter.equalsIgnoreCase("*console*")
|
||||
|| filter.equalsIgnoreCase("!")) {
|
||||
return getServer().getConsoleSender();
|
||||
}
|
||||
|
||||
return matchSinglePlayer(sender, filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a single player as an iterator for players.
|
||||
*
|
||||
* @param player
|
||||
* @return iterator for players
|
||||
*/
|
||||
public Iterable<Player> matchPlayers(Player player) {
|
||||
return Arrays.asList(new Player[] {player});
|
||||
}
|
||||
|
||||
/**
|
||||
* Match a world.
|
||||
* @param sender
|
||||
*
|
||||
* @param filter
|
||||
* @return
|
||||
* @throws CommandException
|
||||
*/
|
||||
public World matchWorld(CommandSender sender, String filter) throws CommandException {
|
||||
List<World> worlds = getServer().getWorlds();
|
||||
|
||||
// Handle special hash tag groups
|
||||
if (filter.charAt(0) == '#') {
|
||||
// #main for the main world
|
||||
if (filter.equalsIgnoreCase("#main")) {
|
||||
return worlds.get(0);
|
||||
|
||||
// #normal for the first normal world
|
||||
} else if (filter.equalsIgnoreCase("#normal")) {
|
||||
for (World world : worlds) {
|
||||
if (world.getEnvironment() == Environment.NORMAL) {
|
||||
return world;
|
||||
}
|
||||
}
|
||||
|
||||
throw new CommandException("No normal world found.");
|
||||
|
||||
// #nether for the first nether world
|
||||
} else if (filter.equalsIgnoreCase("#nether")) {
|
||||
for (World world : worlds) {
|
||||
if (world.getEnvironment() == Environment.NETHER) {
|
||||
return world;
|
||||
}
|
||||
}
|
||||
|
||||
throw new CommandException("No nether world found.");
|
||||
|
||||
// Handle getting a world from a player
|
||||
} else if (filter.matches("^#player$")) {
|
||||
String parts[] = filter.split(":", 2);
|
||||
|
||||
// They didn't specify an argument for the player!
|
||||
if (parts.length == 1) {
|
||||
throw new CommandException("Argument expected for #player.");
|
||||
}
|
||||
|
||||
return matchPlayers(sender, parts[1]).iterator().next().getWorld();
|
||||
} else {
|
||||
throw new CommandException("Invalid identifier '" + filter + "'.");
|
||||
}
|
||||
}
|
||||
|
||||
for (World world : worlds) {
|
||||
if (world.getName().equals(filter)) {
|
||||
return world;
|
||||
}
|
||||
}
|
||||
|
||||
throw new CommandException("No world by that exact name found.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a copy of the WorldEdit plugin.
|
||||
*
|
||||
* @return
|
||||
* @throws CommandException
|
||||
*/
|
||||
public WorldEditPlugin getWorldEdit() throws CommandException {
|
||||
Plugin worldEdit = getServer().getPluginManager().getPlugin("WorldEdit");
|
||||
if (worldEdit == null) {
|
||||
throw new CommandException("WorldEdit does not appear to be installed.");
|
||||
}
|
||||
|
||||
if (worldEdit instanceof WorldEditPlugin) {
|
||||
return (WorldEditPlugin) worldEdit;
|
||||
} else {
|
||||
throw new CommandException("WorldEdit detection failed (report error).");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap a player as a LocalPlayer.
|
||||
*
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
public LocalPlayer wrapPlayer(Player player) {
|
||||
return new BukkitPlayer(this, player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a default configuration file from the .jar.
|
||||
*
|
||||
* @param actual
|
||||
* @param defaultName
|
||||
*/
|
||||
public void createDefaultConfiguration(File actual,
|
||||
String defaultName) {
|
||||
|
||||
// Make parent directories
|
||||
File parent = actual.getParentFile();
|
||||
if (!parent.exists()) {
|
||||
parent.mkdirs();
|
||||
}
|
||||
|
||||
if (actual.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
InputStream input =
|
||||
null;
|
||||
try {
|
||||
JarFile file = new JarFile(getFile());
|
||||
ZipEntry copy = file.getEntry("defaults/" + defaultName);
|
||||
if (copy == null) throw new FileNotFoundException();
|
||||
input = file.getInputStream(copy);
|
||||
} catch (IOException e) {
|
||||
getLogger().severe("Unable to read default configuration: " + defaultName);
|
||||
}
|
||||
|
||||
if (input != null) {
|
||||
FileOutputStream output = null;
|
||||
|
||||
try {
|
||||
output = new FileOutputStream(actual);
|
||||
byte[] buf = new byte[8192];
|
||||
int length = 0;
|
||||
while ((length = input.read(buf)) > 0) {
|
||||
output.write(buf, 0, length);
|
||||
}
|
||||
|
||||
getLogger().info("Default configuration file written: "
|
||||
+ actual.getAbsolutePath());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (input != null) {
|
||||
input.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
|
||||
try {
|
||||
if (output != null) {
|
||||
output.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies all with the notify permission.
|
||||
*
|
||||
* @param msg
|
||||
*/
|
||||
public void broadcastNotification(String msg) {
|
||||
for (Player player : getServer().getOnlinePlayers()) {
|
||||
if (hasPermission(player, "worldguard.notify")) {
|
||||
player.sendMessage(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Forgets a player.
|
||||
*
|
||||
* @param player
|
||||
*/
|
||||
public void forgetPlayer(Player player) {
|
||||
flagStateManager.forget(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a player can build at a location. This will return
|
||||
* true if region protection is disabled.
|
||||
*
|
||||
* @param player
|
||||
* @param loc
|
||||
* @return
|
||||
*/
|
||||
public boolean canBuild(Player player, Location loc) {
|
||||
return getGlobalRegionManager().canBuild(player, loc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a player can build at a location. This will return
|
||||
* true if region protection is disabled.
|
||||
*
|
||||
* @param player
|
||||
* @param block
|
||||
* @return
|
||||
*/
|
||||
public boolean canBuild(Player player, Block block) {
|
||||
return getGlobalRegionManager().canBuild(player, block);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the region manager for a world.
|
||||
*
|
||||
* @param world world to get the region manager for
|
||||
* @return the region manager or null if regions are not enabled
|
||||
*/
|
||||
public RegionManager getRegionManager(World world) {
|
||||
if (!getGlobalStateManager().get(world).useRegions) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return getGlobalRegionManager().get(world);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace macros in the text.
|
||||
*
|
||||
* @param sender
|
||||
* @param message
|
||||
* @return
|
||||
*/
|
||||
public String replaceMacros(CommandSender sender, String message) {
|
||||
Player[] online = getServer().getOnlinePlayers();
|
||||
|
||||
message = message.replace("%name%", toName(sender));
|
||||
message = message.replace("%id%", toUniqueName(sender));
|
||||
message = message.replace("%online%", String.valueOf(online.length));
|
||||
|
||||
if (sender instanceof Player) {
|
||||
Player player = (Player) sender;
|
||||
World world = player.getWorld();
|
||||
|
||||
message = message.replace("%world%", world.getName());
|
||||
message = message.replace("%health%", String.valueOf(player.getHealth()));
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package com.sk89q.worldguard.bukkit;
|
||||
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.server.PluginDisableEvent;
|
||||
import org.bukkit.event.server.PluginEnableEvent;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
/**
|
||||
* @author zml2008
|
||||
*/
|
||||
public class WorldGuardServerListener implements Listener {
|
||||
|
||||
private final WorldGuardPlugin plugin;
|
||||
|
||||
public WorldGuardServerListener(WorldGuardPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public void registerEvents() {
|
||||
PluginManager pm = plugin.getServer().getPluginManager();
|
||||
pm.registerEvents(this, plugin);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPluginEnable(PluginEnableEvent event) {
|
||||
plugin.getGlobalStateManager().updateCommandBookGodMode();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPluginDisable(PluginDisableEvent event) {
|
||||
plugin.getGlobalStateManager().updateCommandBookGodMode();
|
||||
}
|
||||
}
|
||||
@@ -1,186 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
* All rights reserved.
|
||||
*/
|
||||
package com.sk89q.worldguard.bukkit;
|
||||
|
||||
import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Vehicle;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.vehicle.VehicleDestroyEvent;
|
||||
import org.bukkit.event.vehicle.VehicleMoveEvent;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.bukkit.FlagStateManager.PlayerFlagState;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.flags.DefaultFlag;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
|
||||
public class WorldGuardVehicleListener implements Listener {
|
||||
|
||||
private WorldGuardPlugin plugin;
|
||||
|
||||
/**
|
||||
* Construct the object;
|
||||
*
|
||||
* @param plugin
|
||||
*/
|
||||
public WorldGuardVehicleListener(WorldGuardPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register events.
|
||||
*/
|
||||
public void registerEvents() {
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a vehicle is destroyed.
|
||||
*/
|
||||
@EventHandler
|
||||
public void onVehicleDestroy(VehicleDestroyEvent event) {
|
||||
Vehicle vehicle = event.getVehicle();
|
||||
Entity destroyer = event.getAttacker();
|
||||
|
||||
if (!(destroyer instanceof Player)) return; // don't care
|
||||
Player player = (Player) destroyer;
|
||||
World world = vehicle.getWorld();
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(world);
|
||||
|
||||
if (wcfg.useRegions) {
|
||||
Vector pt = toVector(vehicle.getLocation());
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
|
||||
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
|
||||
LocalPlayer localPlayer = plugin.wrapPlayer(player);
|
||||
|
||||
if (!plugin.getGlobalRegionManager().hasBypass(player, world)
|
||||
&& !set.canBuild(localPlayer)
|
||||
&& !set.allows(DefaultFlag.DESTROY_VEHICLE)) {
|
||||
player.sendMessage(ChatColor.DARK_RED + "You don't have permission to destroy vehicles here.");
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a vehicle moves.
|
||||
*/
|
||||
@EventHandler
|
||||
public void onVehicleMove(VehicleMoveEvent event) {
|
||||
Vehicle vehicle = event.getVehicle();
|
||||
if (vehicle.getPassenger() == null
|
||||
|| !(vehicle.getPassenger() instanceof Player)) return;
|
||||
Player player = (Player) vehicle.getPassenger();
|
||||
World world = vehicle.getWorld();
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(world);
|
||||
|
||||
// unfortunate code duplication
|
||||
if (wcfg.useRegions) {
|
||||
// Did we move a block?
|
||||
if (event.getFrom().getBlockX() != event.getTo().getBlockX()
|
||||
|| event.getFrom().getBlockY() != event.getTo().getBlockY()
|
||||
|| event.getFrom().getBlockZ() != event.getTo().getBlockZ()) {
|
||||
PlayerFlagState state = plugin.getFlagStateManager().getState(player);
|
||||
LocalPlayer localPlayer = plugin.wrapPlayer(player);
|
||||
boolean hasBypass = plugin.getGlobalRegionManager().hasBypass(player, world);
|
||||
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
|
||||
Vector pt = new Vector(event.getTo().getBlockX(), event.getTo().getBlockY(), event.getTo().getBlockZ());
|
||||
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
|
||||
|
||||
boolean entryAllowed = set.allows(DefaultFlag.ENTRY, localPlayer);
|
||||
if (!hasBypass && !entryAllowed) {
|
||||
|
||||
vehicle.setVelocity(new org.bukkit.util.Vector(0,0,0));
|
||||
vehicle.teleport(event.getFrom());
|
||||
return;
|
||||
}
|
||||
|
||||
// Have to set this state
|
||||
if (state.lastExitAllowed == null) {
|
||||
state.lastExitAllowed = mgr.getApplicableRegions(toVector(event.getFrom()))
|
||||
.allows(DefaultFlag.EXIT, localPlayer);
|
||||
}
|
||||
|
||||
boolean exitAllowed = set.allows(DefaultFlag.EXIT, localPlayer);
|
||||
if (!hasBypass && exitAllowed && !state.lastExitAllowed) {
|
||||
player.sendMessage(ChatColor.DARK_RED + "You are not permitted to leave this area.");
|
||||
|
||||
vehicle.setVelocity(new org.bukkit.util.Vector(0,0,0));
|
||||
vehicle.teleport(event.getFrom());
|
||||
return;
|
||||
}
|
||||
|
||||
String greeting = set.getFlag(DefaultFlag.GREET_MESSAGE);
|
||||
String farewell = set.getFlag(DefaultFlag.FAREWELL_MESSAGE);
|
||||
Boolean notifyEnter = set.getFlag(DefaultFlag.NOTIFY_ENTER);
|
||||
Boolean notifyLeave = set.getFlag(DefaultFlag.NOTIFY_LEAVE);
|
||||
|
||||
if (state.lastFarewell != null && (farewell == null
|
||||
|| !state.lastFarewell.equals(farewell))) {
|
||||
String replacedFarewell = plugin.replaceMacros(
|
||||
player, BukkitUtil.replaceColorMacros(state.lastFarewell));
|
||||
player.sendMessage(ChatColor.AQUA + " ** " + replacedFarewell);
|
||||
}
|
||||
|
||||
if (greeting != null && (state.lastGreeting == null
|
||||
|| !state.lastGreeting.equals(greeting))) {
|
||||
String replacedGreeting = plugin.replaceMacros(
|
||||
player, BukkitUtil.replaceColorMacros(greeting));
|
||||
player.sendMessage(ChatColor.AQUA + " ** " + replacedGreeting);
|
||||
}
|
||||
|
||||
if ((notifyLeave == null || !notifyLeave)
|
||||
&& state.notifiedForLeave != null && state.notifiedForLeave) {
|
||||
plugin.broadcastNotification(ChatColor.GRAY + "WG: "
|
||||
+ ChatColor.LIGHT_PURPLE + player.getName()
|
||||
+ ChatColor.GOLD + " left NOTIFY region");
|
||||
}
|
||||
|
||||
if (notifyEnter != null && notifyEnter && (state.notifiedForEnter == null
|
||||
|| !state.notifiedForEnter)) {
|
||||
StringBuilder regionList = new StringBuilder();
|
||||
|
||||
for (ProtectedRegion region : set) {
|
||||
if (regionList.length() != 0) {
|
||||
regionList.append(", ");
|
||||
}
|
||||
regionList.append(region.getId());
|
||||
}
|
||||
|
||||
plugin.broadcastNotification(ChatColor.GRAY + "WG: "
|
||||
+ ChatColor.LIGHT_PURPLE + player.getName()
|
||||
+ ChatColor.GOLD + " entered NOTIFY region: "
|
||||
+ ChatColor.WHITE
|
||||
+ regionList);
|
||||
}
|
||||
|
||||
state.lastGreeting = greeting;
|
||||
state.lastFarewell = farewell;
|
||||
state.notifiedForEnter = notifyEnter;
|
||||
state.notifiedForLeave = notifyLeave;
|
||||
state.lastExitAllowed = exitAllowed;
|
||||
state.lastWorld = event.getTo().getWorld();
|
||||
state.lastBlockX = event.getTo().getBlockX();
|
||||
state.lastBlockY = event.getTo().getBlockY();
|
||||
state.lastBlockZ = event.getTo().getBlockZ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.sk89q.worldguard.bukkit;
|
||||
|
||||
import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.weather.LightningStrikeEvent;
|
||||
import org.bukkit.event.weather.ThunderChangeEvent;
|
||||
import org.bukkit.event.weather.WeatherChangeEvent;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.flags.DefaultFlag;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
|
||||
public class WorldGuardWeatherListener implements Listener {
|
||||
|
||||
/**
|
||||
* Plugin.
|
||||
*/
|
||||
private WorldGuardPlugin plugin;
|
||||
|
||||
/**
|
||||
* Construct the object;
|
||||
*
|
||||
* @param plugin
|
||||
*/
|
||||
public WorldGuardWeatherListener(WorldGuardPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public void registerEvents() {
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onWeatherChange(WeatherChangeEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(event.getWorld());
|
||||
|
||||
if (event.toWeatherState()) {
|
||||
if (wcfg.disableWeather) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
} else {
|
||||
if (!wcfg.disableWeather && wcfg.alwaysRaining) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onThunderChange(ThunderChangeEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(event.getWorld());
|
||||
|
||||
if (event.toThunderState()) {
|
||||
if (wcfg.disableThunder) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
} else {
|
||||
if (!wcfg.disableWeather && wcfg.alwaysThundering) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onLightningStrike(LightningStrikeEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(event.getWorld());
|
||||
|
||||
if (wcfg.disallowedLightningBlocks.size() > 0) {
|
||||
int targetId = event.getLightning().getLocation().getBlock().getTypeId();
|
||||
if (wcfg.disallowedLightningBlocks.contains(targetId)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
Location loc = event.getLightning().getLocation();
|
||||
if (wcfg.useRegions) {
|
||||
Vector pt = toVector(loc);
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(loc.getWorld());
|
||||
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
|
||||
|
||||
if (!set.allows(DefaultFlag.LIGHTNING)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
* All rights reserved.
|
||||
*/
|
||||
package com.sk89q.worldguard.bukkit;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.world.ChunkLoadEvent;
|
||||
import org.bukkit.event.world.WorldLoadEvent;
|
||||
|
||||
public class WorldGuardWorldListener implements Listener {
|
||||
|
||||
private WorldGuardPlugin plugin;
|
||||
|
||||
/**
|
||||
* Construct the object;
|
||||
*
|
||||
* @param plugin
|
||||
*/
|
||||
public WorldGuardWorldListener(WorldGuardPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register events.
|
||||
*/
|
||||
public void registerEvents() {
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a chunk is loaded.
|
||||
*/
|
||||
@EventHandler
|
||||
public void onChunkLoad(ChunkLoadEvent event) {
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
|
||||
if (cfg.activityHaltToggle) {
|
||||
int removed = 0;
|
||||
|
||||
for (Entity entity : event.getChunk().getEntities()) {
|
||||
if (BukkitUtil.isIntensiveEntity(entity)) {
|
||||
entity.remove();
|
||||
removed++;
|
||||
}
|
||||
}
|
||||
|
||||
if (removed > 50) {
|
||||
plugin.getLogger().info("Halt-Act: " + removed + " entities (>50) auto-removed from "
|
||||
+ event.getChunk().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a world is loaded.
|
||||
*/
|
||||
@EventHandler
|
||||
public void onWorldLoad(WorldLoadEvent event) {
|
||||
initWorld(event.getWorld());
|
||||
}
|
||||
|
||||
public void initWorld(World world) {
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(world);
|
||||
if (wcfg.alwaysRaining && !wcfg.disableWeather) {
|
||||
world.setStorm(true);
|
||||
} else if (wcfg.disableWeather && !wcfg.alwaysRaining) {
|
||||
world.setStorm(false);
|
||||
}
|
||||
if (wcfg.alwaysThundering && !wcfg.disableThunder) {
|
||||
world.setThundering(true);
|
||||
} else if (wcfg.disableThunder && !wcfg.alwaysThundering) {
|
||||
world.setStorm(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,303 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.bukkit.commands;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||
import com.sk89q.worldedit.blocks.ItemType;
|
||||
import com.sk89q.worldguard.bukkit.ConfigurationManager;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
|
||||
public class GeneralCommands {
|
||||
private final WorldGuardPlugin plugin;
|
||||
|
||||
public GeneralCommands(WorldGuardPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Command(aliases = {"god"}, usage = "[player]",
|
||||
desc = "Enable godmode on a player", flags = "s", max = 1)
|
||||
public void god(CommandContext args, CommandSender sender) throws CommandException {
|
||||
ConfigurationManager config = plugin.getGlobalStateManager();
|
||||
|
||||
Iterable<Player> targets = null;
|
||||
boolean included = false;
|
||||
|
||||
// Detect arguments based on the number of arguments provided
|
||||
if (args.argsLength() == 0) {
|
||||
targets = plugin.matchPlayers(plugin.checkPlayer(sender));
|
||||
|
||||
// Check permissions!
|
||||
plugin.checkPermission(sender, "worldguard.god");
|
||||
} else if (args.argsLength() == 1) {
|
||||
targets = plugin.matchPlayers(sender, args.getString(0));
|
||||
|
||||
// Check permissions!
|
||||
plugin.checkPermission(sender, "worldguard.god.other");
|
||||
}
|
||||
|
||||
for (Player player : targets) {
|
||||
config.enableGodMode(player);
|
||||
player.setFireTicks(0);
|
||||
|
||||
// Tell the user
|
||||
if (player.equals(sender)) {
|
||||
player.sendMessage(ChatColor.YELLOW + "God mode enabled! Use /ungod to disable.");
|
||||
|
||||
// Keep track of this
|
||||
included = true;
|
||||
} else {
|
||||
player.sendMessage(ChatColor.YELLOW + "God enabled by "
|
||||
+ plugin.toName(sender) + ".");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// The player didn't receive any items, then we need to send the
|
||||
// user a message so s/he know that something is indeed working
|
||||
if (!included && args.hasFlag('s')) {
|
||||
sender.sendMessage(ChatColor.YELLOW.toString() + "Players now have god mode.");
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Command(aliases = {"ungod"}, usage = "[player]",
|
||||
desc = "Disable godmode on a player", flags = "s", max = 1)
|
||||
public void ungod(CommandContext args, CommandSender sender) throws CommandException {
|
||||
ConfigurationManager config = plugin.getGlobalStateManager();
|
||||
|
||||
Iterable<Player> targets = null;
|
||||
boolean included = false;
|
||||
|
||||
// Detect arguments based on the number of arguments provided
|
||||
if (args.argsLength() == 0) {
|
||||
targets = plugin.matchPlayers(plugin.checkPlayer(sender));
|
||||
|
||||
// Check permissions!
|
||||
plugin.checkPermission(sender, "worldguard.god");
|
||||
} else if (args.argsLength() == 1) {
|
||||
targets = plugin.matchPlayers(sender, args.getString(0));
|
||||
|
||||
// Check permissions!
|
||||
plugin.checkPermission(sender, "worldguard.god.other");
|
||||
}
|
||||
|
||||
for (Player player : targets) {
|
||||
config.disableGodMode(player);
|
||||
|
||||
// Tell the user
|
||||
if (player.equals(sender)) {
|
||||
player.sendMessage(ChatColor.YELLOW + "God mode disabled!");
|
||||
|
||||
// Keep track of this
|
||||
included = true;
|
||||
} else {
|
||||
player.sendMessage(ChatColor.YELLOW + "God disabled by "
|
||||
+ plugin.toName(sender) + ".");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// The player didn't receive any items, then we need to send the
|
||||
// user a message so s/he know that something is indeed working
|
||||
if (!included && args.hasFlag('s')) {
|
||||
sender.sendMessage(ChatColor.YELLOW.toString() + "Players no longer have god mode.");
|
||||
}
|
||||
}
|
||||
|
||||
@Command(aliases = {"heal"}, usage = "[player]", desc = "Heal a player", flags = "s", max = 1)
|
||||
public void heal(CommandContext args,CommandSender sender) throws CommandException {
|
||||
|
||||
Iterable<Player> targets = null;
|
||||
boolean included = false;
|
||||
|
||||
// Detect arguments based on the number of arguments provided
|
||||
if (args.argsLength() == 0) {
|
||||
targets = plugin.matchPlayers(plugin.checkPlayer(sender));
|
||||
|
||||
// Check permissions!
|
||||
plugin.checkPermission(sender, "worldguard.heal");
|
||||
} else if (args.argsLength() == 1) {
|
||||
targets = plugin.matchPlayers(sender, args.getString(0));
|
||||
|
||||
// Check permissions!
|
||||
plugin.checkPermission(sender, "worldguard.heal.other");
|
||||
}
|
||||
|
||||
for (Player player : targets) {
|
||||
player.setHealth(20);
|
||||
player.setFoodLevel(20);
|
||||
|
||||
// Tell the user
|
||||
if (player.equals(sender)) {
|
||||
player.sendMessage(ChatColor.YELLOW + "Healed!");
|
||||
|
||||
// Keep track of this
|
||||
included = true;
|
||||
} else {
|
||||
player.sendMessage(ChatColor.YELLOW + "Healed by "
|
||||
+ plugin.toName(sender) + ".");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// The player didn't receive any items, then we need to send the
|
||||
// user a message so s/he know that something is indeed working
|
||||
if (!included && args.hasFlag('s')) {
|
||||
sender.sendMessage(ChatColor.YELLOW.toString() + "Players healed.");
|
||||
}
|
||||
}
|
||||
|
||||
@Command(aliases = {"slay"}, usage = "[player]", desc = "Slay a player", flags = "s", max = 1)
|
||||
public void slay(CommandContext args, CommandSender sender) throws CommandException {
|
||||
|
||||
Iterable<Player> targets = null;
|
||||
boolean included = false;
|
||||
|
||||
// Detect arguments based on the number of arguments provided
|
||||
if (args.argsLength() == 0) {
|
||||
targets = plugin.matchPlayers(plugin.checkPlayer(sender));
|
||||
|
||||
// Check permissions!
|
||||
plugin.checkPermission(sender, "worldguard.slay");
|
||||
} else if (args.argsLength() == 1) {
|
||||
targets = plugin.matchPlayers(sender, args.getString(0));
|
||||
|
||||
// Check permissions!
|
||||
plugin.checkPermission(sender, "worldguard.slay.other");
|
||||
}
|
||||
|
||||
for (Player player : targets) {
|
||||
player.setHealth(0);
|
||||
|
||||
// Tell the user
|
||||
if (player.equals(sender)) {
|
||||
player.sendMessage(ChatColor.YELLOW + "Slain!");
|
||||
|
||||
// Keep track of this
|
||||
included = true;
|
||||
} else {
|
||||
player.sendMessage(ChatColor.YELLOW + "Slain by "
|
||||
+ plugin.toName(sender) + ".");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// The player didn't receive any items, then we need to send the
|
||||
// user a message so s/he know that something is indeed working
|
||||
if (!included && args.hasFlag('s')) {
|
||||
sender.sendMessage(ChatColor.YELLOW.toString() + "Players slain.");
|
||||
}
|
||||
}
|
||||
|
||||
@Command(aliases = {"locate"}, usage = "[player]", desc = "Locate a player", max = 1)
|
||||
@CommandPermissions({"worldguard.locate"})
|
||||
public void locate(CommandContext args, CommandSender sender) throws CommandException {
|
||||
|
||||
Player player = plugin.checkPlayer(sender);
|
||||
|
||||
if (args.argsLength() == 0) {
|
||||
player.setCompassTarget(player.getWorld().getSpawnLocation());
|
||||
|
||||
sender.sendMessage(ChatColor.YELLOW.toString() + "Compass reset to spawn.");
|
||||
} else {
|
||||
Player target = plugin.matchSinglePlayer(sender, args.getString(0));
|
||||
player.setCompassTarget(target.getLocation());
|
||||
|
||||
sender.sendMessage(ChatColor.YELLOW.toString() + "Compass repointed.");
|
||||
}
|
||||
}
|
||||
|
||||
@Command(aliases = {"stack", ";"}, usage = "", desc = "Stack items", max = 0)
|
||||
@CommandPermissions({"worldguard.stack"})
|
||||
public void stack(CommandContext args, CommandSender sender) throws CommandException {
|
||||
|
||||
Player player = plugin.checkPlayer(sender);
|
||||
boolean ignoreMax = plugin.hasPermission(player, "worldguard.stack.illegitimate");
|
||||
boolean ignoreDamaged = plugin.hasPermission(player, "worldguard.stack.damaged");
|
||||
|
||||
ItemStack[] items = player.getInventory().getContents();
|
||||
int len = items.length;
|
||||
|
||||
int affected = 0;
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
ItemStack item = items[i];
|
||||
|
||||
// Avoid infinite stacks and stacks with durability
|
||||
if (item == null || item.getAmount() <= 0
|
||||
|| (!ignoreMax && item.getMaxStackSize() == 1)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int max = ignoreMax ? 64 : item.getMaxStackSize();
|
||||
|
||||
if (item.getAmount() < max) {
|
||||
int needed = max - item.getAmount(); // Number of needed items until max
|
||||
|
||||
// Find another stack of the same type
|
||||
for (int j = i + 1; j < len; j++) {
|
||||
ItemStack item2 = items[j];
|
||||
|
||||
// Avoid infinite stacks and stacks with durability
|
||||
if (item2 == null || item2.getAmount() <= 0
|
||||
|| (!ignoreMax && item.getMaxStackSize() == 1)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Same type?
|
||||
// Blocks store their color in the damage value
|
||||
if (item2.getTypeId() == item.getTypeId() &&
|
||||
((!ItemType.usesDamageValue(item.getTypeId()) && ignoreDamaged)
|
||||
|| item.getDurability() == item2.getDurability()) &&
|
||||
item.getEnchantments().equals(item2.getEnchantments())) {
|
||||
// This stack won't fit in the parent stack
|
||||
if (item2.getAmount() > needed) {
|
||||
item.setAmount(64);
|
||||
item2.setAmount(item2.getAmount() - needed);
|
||||
break;
|
||||
// This stack will
|
||||
} else {
|
||||
items[j] = null;
|
||||
item.setAmount(item.getAmount() + item2.getAmount());
|
||||
needed = 64 - item.getAmount();
|
||||
}
|
||||
|
||||
affected++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (affected > 0) {
|
||||
player.getInventory().setContents(items);
|
||||
}
|
||||
|
||||
player.sendMessage(ChatColor.YELLOW + "Items compacted into stacks!");
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.bukkit.commands;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
import com.sk89q.minecraft.util.commands.NestedCommand;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
|
||||
public class ProtectionCommands {
|
||||
@SuppressWarnings("unused")
|
||||
private final WorldGuardPlugin plugin;
|
||||
|
||||
public ProtectionCommands(WorldGuardPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Command(aliases = {"region", "regions", "rg"}, desc = "Region management commands")
|
||||
@NestedCommand({RegionCommands.class, RegionMemberCommands.class})
|
||||
public void region(CommandContext args, CommandSender sender) {}
|
||||
|
||||
@Command(aliases = {"worldguard", "wg"}, desc = "WorldGuard commands")
|
||||
@NestedCommand({WorldGuardCommands.class})
|
||||
public void worldGuard(CommandContext args, CommandSender sender) {}
|
||||
}
|
||||
@@ -1,981 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.bukkit.commands;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||
import com.sk89q.minecraft.util.commands.CommandPermissionsException;
|
||||
import com.sk89q.worldedit.BlockVector;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||
import com.sk89q.worldedit.bukkit.selections.CuboidSelection;
|
||||
import com.sk89q.worldedit.bukkit.selections.Polygonal2DSelection;
|
||||
import com.sk89q.worldedit.bukkit.selections.Selection;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.bukkit.WorldConfiguration;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.domains.DefaultDomain;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.flags.DefaultFlag;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.flags.InvalidFlagFormat;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.regions.GlobalProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion.CircularInheritanceException;
|
||||
import com.sk89q.worldguard.protection.databases.ProtectionDatabaseException;
|
||||
import com.sk89q.worldguard.protection.databases.migrators.AbstractDatabaseMigrator;
|
||||
import com.sk89q.worldguard.protection.databases.migrators.MigrationException;
|
||||
import com.sk89q.worldguard.protection.databases.migrators.MigratorKey;
|
||||
import com.sk89q.worldguard.util.RegionUtil;
|
||||
|
||||
public class RegionCommands {
|
||||
private final WorldGuardPlugin plugin;
|
||||
|
||||
private MigratorKey migrateDBRequest;
|
||||
private Date migrateDBRequestDate;
|
||||
|
||||
public RegionCommands(WorldGuardPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Command(aliases = {"define", "def", "d"}, usage = "<id> [<owner1> [<owner2> [<owners...>]]]",
|
||||
desc = "Defines a region", min = 1)
|
||||
@CommandPermissions({"worldguard.region.define"})
|
||||
public void define(CommandContext args, CommandSender sender) throws CommandException {
|
||||
|
||||
Player player = plugin.checkPlayer(sender);
|
||||
WorldEditPlugin worldEdit = plugin.getWorldEdit();
|
||||
String id = args.getString(0);
|
||||
|
||||
if (!ProtectedRegion.isValidId(id)) {
|
||||
throw new CommandException("Invalid region ID specified!");
|
||||
}
|
||||
|
||||
if (id.equalsIgnoreCase("__global__")) {
|
||||
throw new CommandException("A region cannot be named __global__");
|
||||
}
|
||||
|
||||
// Attempt to get the player's selection from WorldEdit
|
||||
Selection sel = worldEdit.getSelection(player);
|
||||
|
||||
if (sel == null) {
|
||||
throw new CommandException("Select a region with WorldEdit first.");
|
||||
}
|
||||
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(sel.getWorld());
|
||||
if (mgr.hasRegion(id)) {
|
||||
throw new CommandException("That region is already defined. Use redefine instead.");
|
||||
}
|
||||
|
||||
ProtectedRegion region;
|
||||
|
||||
// Detect the type of region from WorldEdit
|
||||
if (sel instanceof Polygonal2DSelection) {
|
||||
Polygonal2DSelection polySel = (Polygonal2DSelection) sel;
|
||||
int minY = polySel.getNativeMinimumPoint().getBlockY();
|
||||
int maxY = polySel.getNativeMaximumPoint().getBlockY();
|
||||
region = new ProtectedPolygonalRegion(id, polySel.getNativePoints(), minY, maxY);
|
||||
} else if (sel instanceof CuboidSelection) {
|
||||
BlockVector min = sel.getNativeMinimumPoint().toBlockVector();
|
||||
BlockVector max = sel.getNativeMaximumPoint().toBlockVector();
|
||||
region = new ProtectedCuboidRegion(id, min, max);
|
||||
} else {
|
||||
throw new CommandException(
|
||||
"The type of region selected in WorldEdit is unsupported in WorldGuard!");
|
||||
}
|
||||
|
||||
// Get the list of region owners
|
||||
if (args.argsLength() > 1) {
|
||||
region.setOwners(RegionUtil.parseDomainString(args.getSlice(1), 1));
|
||||
}
|
||||
|
||||
mgr.addRegion(region);
|
||||
|
||||
try {
|
||||
mgr.save();
|
||||
sender.sendMessage(ChatColor.YELLOW + "Region saved as " + id + ".");
|
||||
} catch (ProtectionDatabaseException e) {
|
||||
throw new CommandException("Failed to write regions: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Command(aliases = {"redefine", "update", "move"}, usage = "<id>",
|
||||
desc = "Re-defines the shape of a region", min = 1, max = 1)
|
||||
public void redefine(CommandContext args, CommandSender sender) throws CommandException {
|
||||
|
||||
Player player = plugin.checkPlayer(sender);
|
||||
World world = player.getWorld();
|
||||
WorldEditPlugin worldEdit = plugin.getWorldEdit();
|
||||
LocalPlayer localPlayer = plugin.wrapPlayer(player);
|
||||
String id = args.getString(0);
|
||||
|
||||
if (id.equalsIgnoreCase("__global__")) {
|
||||
throw new CommandException("The region cannot be named __global__");
|
||||
}
|
||||
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
|
||||
ProtectedRegion existing = mgr.getRegion(id);
|
||||
|
||||
if (existing == null) {
|
||||
throw new CommandException("Could not find a region by that ID.");
|
||||
}
|
||||
|
||||
if (existing.isOwner(localPlayer)) {
|
||||
plugin.checkPermission(sender, "worldguard.region.redefine.own");
|
||||
} else if (existing.isMember(localPlayer)) {
|
||||
plugin.checkPermission(sender, "worldguard.region.redefine.member");
|
||||
} else {
|
||||
plugin.checkPermission(sender, "worldguard.region.redefine");
|
||||
}
|
||||
|
||||
// Attempt to get the player's selection from WorldEdit
|
||||
Selection sel = worldEdit.getSelection(player);
|
||||
|
||||
if (sel == null) {
|
||||
throw new CommandException("Select a region with WorldEdit first.");
|
||||
}
|
||||
|
||||
ProtectedRegion region;
|
||||
|
||||
// Detect the type of region from WorldEdit
|
||||
if (sel instanceof Polygonal2DSelection) {
|
||||
Polygonal2DSelection polySel = (Polygonal2DSelection) sel;
|
||||
int minY = polySel.getNativeMinimumPoint().getBlockY();
|
||||
int maxY = polySel.getNativeMaximumPoint().getBlockY();
|
||||
region = new ProtectedPolygonalRegion(id, polySel.getNativePoints(), minY, maxY);
|
||||
} else if (sel instanceof CuboidSelection) {
|
||||
BlockVector min = sel.getNativeMinimumPoint().toBlockVector();
|
||||
BlockVector max = sel.getNativeMaximumPoint().toBlockVector();
|
||||
region = new ProtectedCuboidRegion(id, min, max);
|
||||
} else {
|
||||
throw new CommandException(
|
||||
"The type of region selected in WorldEdit is unsupported in WorldGuard!");
|
||||
}
|
||||
|
||||
region.setMembers(existing.getMembers());
|
||||
region.setOwners(existing.getOwners());
|
||||
region.setFlags(existing.getFlags());
|
||||
region.setPriority(existing.getPriority());
|
||||
try {
|
||||
region.setParent(existing.getParent());
|
||||
} catch (CircularInheritanceException e) {
|
||||
}
|
||||
|
||||
mgr.addRegion(region);
|
||||
|
||||
sender.sendMessage(ChatColor.YELLOW + "Region updated with new area.");
|
||||
|
||||
try {
|
||||
mgr.save();
|
||||
} catch (ProtectionDatabaseException e) {
|
||||
throw new CommandException("Failed to write regions: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Command(aliases = {"claim"}, usage = "<id> [<owner1> [<owner2> [<owners...>]]]",
|
||||
desc = "Claim a region", min = 1)
|
||||
@CommandPermissions({"worldguard.region.claim"})
|
||||
public void claim(CommandContext args, CommandSender sender) throws CommandException {
|
||||
|
||||
Player player = plugin.checkPlayer(sender);
|
||||
LocalPlayer localPlayer = plugin.wrapPlayer(player);
|
||||
WorldEditPlugin worldEdit = plugin.getWorldEdit();
|
||||
String id = args.getString(0);
|
||||
|
||||
if (!ProtectedRegion.isValidId(id)) {
|
||||
throw new CommandException("Invalid region ID specified!");
|
||||
}
|
||||
|
||||
if (id.equalsIgnoreCase("__global__")) {
|
||||
throw new CommandException("A region cannot be named __global__");
|
||||
}
|
||||
|
||||
// Attempt to get the player's selection from WorldEdit
|
||||
Selection sel = worldEdit.getSelection(player);
|
||||
|
||||
if (sel == null) {
|
||||
throw new CommandException("Select a region with WorldEdit first.");
|
||||
}
|
||||
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(sel.getWorld());
|
||||
|
||||
if (mgr.hasRegion(id)) {
|
||||
throw new CommandException("That region already exists. Please choose a different name.");
|
||||
}
|
||||
|
||||
ProtectedRegion region;
|
||||
|
||||
// Detect the type of region from WorldEdit
|
||||
if (sel instanceof Polygonal2DSelection) {
|
||||
Polygonal2DSelection polySel = (Polygonal2DSelection) sel;
|
||||
int minY = polySel.getNativeMinimumPoint().getBlockY();
|
||||
int maxY = polySel.getNativeMaximumPoint().getBlockY();
|
||||
region = new ProtectedPolygonalRegion(id, polySel.getNativePoints(), minY, maxY);
|
||||
} else if (sel instanceof CuboidSelection) {
|
||||
BlockVector min = sel.getNativeMinimumPoint().toBlockVector();
|
||||
BlockVector max = sel.getNativeMaximumPoint().toBlockVector();
|
||||
region = new ProtectedCuboidRegion(id, min, max);
|
||||
} else {
|
||||
throw new CommandException(
|
||||
"The type of region selected in WorldEdit is unsupported in WorldGuard!");
|
||||
}
|
||||
|
||||
// Get the list of region owners
|
||||
if (args.argsLength() > 1) {
|
||||
region.setOwners(RegionUtil.parseDomainString(args.getSlice(1), 1));
|
||||
}
|
||||
|
||||
WorldConfiguration wcfg = plugin.getGlobalStateManager().get(player.getWorld());
|
||||
|
||||
if (!plugin.hasPermission(sender, "worldguard.region.unlimited")) {
|
||||
// Check whether the player has created too many regions
|
||||
int maxRegionCount = wcfg.getMaxRegionCount(player);
|
||||
if (maxRegionCount >= 0
|
||||
&& mgr.getRegionCountOfPlayer(localPlayer) >= maxRegionCount) {
|
||||
throw new CommandException("You own too many regions, delete one first to claim a new one.");
|
||||
}
|
||||
}
|
||||
|
||||
ProtectedRegion existing = mgr.getRegion(id);
|
||||
|
||||
// Check for an existing region
|
||||
if (existing != null) {
|
||||
if (!existing.getOwners().contains(localPlayer)) {
|
||||
throw new CommandException("This region already exists and you don't own it.");
|
||||
}
|
||||
}
|
||||
|
||||
ApplicableRegionSet regions = mgr.getApplicableRegions(region);
|
||||
|
||||
// Check if this region overlaps any other region
|
||||
if (regions.size() > 0) {
|
||||
if (!regions.isOwnerOfAll(localPlayer)) {
|
||||
throw new CommandException("This region overlaps with someone else's region.");
|
||||
}
|
||||
} else {
|
||||
if (wcfg.claimOnlyInsideExistingRegions) {
|
||||
throw new CommandException("You may only claim regions inside " +
|
||||
"existing regions that you or your group own.");
|
||||
}
|
||||
}
|
||||
|
||||
/*if (plugin.getGlobalConfiguration().getiConomy() != null && wcfg.useiConomy && wcfg.buyOnClaim) {
|
||||
if (iConomy.getBank().hasAccount(player.getName())) {
|
||||
Account account = iConomy.getBank().getAccount(player.getName());
|
||||
double balance = account.getBalance();
|
||||
double regionCosts = region.countBlocks() * wcfg.buyOnClaimPrice;
|
||||
if (balance >= regionCosts) {
|
||||
account.subtract(regionCosts);
|
||||
player.sendMessage(ChatColor.YELLOW + "You have bought that region for "
|
||||
+ iConomy.getBank().format(regionCosts));
|
||||
account.save();
|
||||
} else {
|
||||
player.sendMessage(ChatColor.RED + "You have not enough money.");
|
||||
player.sendMessage(ChatColor.RED + "The region you want to claim costs "
|
||||
+ iConomy.getBank().format(regionCosts));
|
||||
player.sendMessage(ChatColor.RED + "You have " + iConomy.getBank().format(balance));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
player.sendMessage(ChatColor.YELLOW + "You have not enough money.");
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
|
||||
if (!plugin.hasPermission(sender, "worldguard.region.unlimited")) {
|
||||
if (region.volume() > wcfg.maxClaimVolume) {
|
||||
player.sendMessage(ChatColor.RED + "This region is too large to claim.");
|
||||
player.sendMessage(ChatColor.RED +
|
||||
"Max. volume: " + wcfg.maxClaimVolume + ", your volume: " + region.volume());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
region.getOwners().addPlayer(player.getName());
|
||||
mgr.addRegion(region);
|
||||
|
||||
try {
|
||||
mgr.save();
|
||||
sender.sendMessage(ChatColor.YELLOW + "Region saved as " + id + ".");
|
||||
} catch (ProtectionDatabaseException e) {
|
||||
throw new CommandException("Failed to write regions: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Command(aliases = {"select", "sel", "s"}, usage = "<id>",
|
||||
desc = "Load a region as a WorldEdit selection", min = 1, max = 1)
|
||||
public void select(CommandContext args, CommandSender sender) throws CommandException {
|
||||
|
||||
Player player = plugin.checkPlayer(sender);
|
||||
World world = player.getWorld();
|
||||
WorldEditPlugin worldEdit = plugin.getWorldEdit();
|
||||
LocalPlayer localPlayer = plugin.wrapPlayer(player);
|
||||
|
||||
String id = args.getString(0);
|
||||
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
|
||||
ProtectedRegion region = mgr.getRegion(id);
|
||||
|
||||
if (region == null) {
|
||||
throw new CommandException("Could not find a region by that ID.");
|
||||
}
|
||||
|
||||
if (region.isOwner(localPlayer)) {
|
||||
plugin.checkPermission(sender, "worldguard.region.select.own." + id.toLowerCase());
|
||||
} else if (region.isMember(localPlayer)) {
|
||||
plugin.checkPermission(sender, "worldguard.region.select.member." + id.toLowerCase());
|
||||
} else {
|
||||
plugin.checkPermission(sender, "worldguard.region.select." + id.toLowerCase());
|
||||
}
|
||||
|
||||
if (region instanceof ProtectedCuboidRegion) {
|
||||
ProtectedCuboidRegion cuboid = (ProtectedCuboidRegion) region;
|
||||
Vector pt1 = cuboid.getMinimumPoint();
|
||||
Vector pt2 = cuboid.getMaximumPoint();
|
||||
CuboidSelection selection = new CuboidSelection(world, pt1, pt2);
|
||||
worldEdit.setSelection(player, selection);
|
||||
sender.sendMessage(ChatColor.YELLOW + "Region selected as a cuboid.");
|
||||
} else if (region instanceof ProtectedPolygonalRegion) {
|
||||
ProtectedPolygonalRegion poly2d = (ProtectedPolygonalRegion) region;
|
||||
Polygonal2DSelection selection = new Polygonal2DSelection(world, poly2d.getPoints(),
|
||||
poly2d.getMinimumPoint().getBlockY(), poly2d.getMaximumPoint().getBlockY());
|
||||
worldEdit.setSelection(player, selection);
|
||||
sender.sendMessage(ChatColor.YELLOW + "Region selected as a polygon.");
|
||||
} else if (region instanceof GlobalProtectedRegion) {
|
||||
throw new CommandException("Can't select global regions.");
|
||||
} else {
|
||||
throw new CommandException("Unknown region type: " + region.getClass().getCanonicalName());
|
||||
}
|
||||
}
|
||||
|
||||
@Command(aliases = {"info", "i"}, usage = "[world] <id>",
|
||||
desc = "Get information about a region", min = 1, max = 2)
|
||||
public void info(CommandContext args, CommandSender sender) throws CommandException {
|
||||
|
||||
Player player = null;
|
||||
LocalPlayer localPlayer = null;
|
||||
World world;
|
||||
String id;
|
||||
|
||||
// Get different values based on provided arguments
|
||||
if (args.argsLength() == 1) {
|
||||
player = plugin.checkPlayer(sender);
|
||||
localPlayer = plugin.wrapPlayer(player);
|
||||
world = player.getWorld();
|
||||
id = args.getString(0).toLowerCase();
|
||||
} else {
|
||||
world = plugin.matchWorld(sender, args.getString(0));
|
||||
id = args.getString(1).toLowerCase();
|
||||
}
|
||||
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
|
||||
|
||||
if (!mgr.hasRegion(id)) {
|
||||
if (!ProtectedRegion.isValidId(id)) {
|
||||
throw new CommandException("Invalid region ID specified!");
|
||||
}
|
||||
throw new CommandException("A region with ID '" + id + "' doesn't exist.");
|
||||
}
|
||||
|
||||
ProtectedRegion region = mgr.getRegion(id);
|
||||
|
||||
if (player != null) {
|
||||
if (region.isOwner(localPlayer)) {
|
||||
plugin.checkPermission(sender, "worldguard.region.info.own");
|
||||
} else if (region.isMember(localPlayer)) {
|
||||
plugin.checkPermission(sender, "worldguard.region.info.member");
|
||||
} else {
|
||||
plugin.checkPermission(sender, "worldguard.region.info");
|
||||
}
|
||||
} else {
|
||||
plugin.checkPermission(sender, "worldguard.region.info");
|
||||
}
|
||||
|
||||
DefaultDomain owners = region.getOwners();
|
||||
DefaultDomain members = region.getMembers();
|
||||
|
||||
sender.sendMessage(ChatColor.YELLOW + "Region: " + id
|
||||
+ ChatColor.GRAY + " (type: " + region.getTypeName() + ")");
|
||||
if (!ProtectedRegion.isValidId(id)) {
|
||||
sender.sendMessage(ChatColor.RED + "This region has an invalid ID. "
|
||||
+ "Please ask the owner to delete it and recreate it.");
|
||||
}
|
||||
sender.sendMessage(ChatColor.BLUE + "Priority: " + region.getPriority());
|
||||
|
||||
StringBuilder s = new StringBuilder();
|
||||
|
||||
for (Flag<?> flag : DefaultFlag.getFlags()) {
|
||||
Object val = region.getFlag(flag);
|
||||
|
||||
if (val == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (s.length() > 0) {
|
||||
s.append(", ");
|
||||
}
|
||||
|
||||
s.append(flag.getName() + ": " + String.valueOf(val));
|
||||
}
|
||||
|
||||
sender.sendMessage(ChatColor.BLUE + "Flags: " + s.toString());
|
||||
sender.sendMessage(ChatColor.BLUE + "Parent: "
|
||||
+ (region.getParent() == null ? "(none)" : region.getParent().getId()));
|
||||
sender.sendMessage(ChatColor.LIGHT_PURPLE + "Owners: "
|
||||
+ owners.toUserFriendlyString());
|
||||
sender.sendMessage(ChatColor.LIGHT_PURPLE + "Members: "
|
||||
+ members.toUserFriendlyString());
|
||||
BlockVector min = region.getMinimumPoint();
|
||||
BlockVector max = region.getMaximumPoint();
|
||||
String c = "(" + min.getBlockX() + "," + min.getBlockY() + "," + min.getBlockZ() + ")";
|
||||
c += " (" +max.getBlockX() + "," + max.getBlockY() + "," + max.getBlockZ() + ")";
|
||||
sender.sendMessage(ChatColor.LIGHT_PURPLE + "Bounds: " + c);
|
||||
}
|
||||
|
||||
@Command(aliases = {"list"}, usage = "[.player] [page] [world]",
|
||||
desc = "Get a list of regions", max = 3)
|
||||
// @CommandPermissions({"worldguard.region.list"})
|
||||
public void list(CommandContext args, CommandSender sender) throws CommandException {
|
||||
|
||||
World world;
|
||||
int page = 0;
|
||||
int argl = 0;
|
||||
String name = "";
|
||||
boolean own = false;
|
||||
LocalPlayer localPlayer = null;
|
||||
|
||||
if (args.argsLength() > 0 && args.getString(0).startsWith(".")) {
|
||||
name = args.getString(0).substring(1).toLowerCase();
|
||||
argl = 1;
|
||||
|
||||
if (name.equals("me") || name.isEmpty() ||
|
||||
name.equals(plugin.checkPlayer(sender).getDisplayName().toLowerCase())) {
|
||||
plugin.checkPermission(sender, "worldguard.region.list.own");
|
||||
name = plugin.checkPlayer(sender).getDisplayName().toLowerCase();
|
||||
localPlayer = plugin.wrapPlayer(plugin.checkPlayer(sender));
|
||||
own = true;
|
||||
}
|
||||
}
|
||||
if (!own)
|
||||
plugin.checkPermission(sender, "worldguard.region.list");
|
||||
|
||||
if (args.argsLength() > 0 + argl) {
|
||||
page = Math.max(0, args.getInteger(0 + argl) - 1);
|
||||
}
|
||||
|
||||
if (args.argsLength() > 1 + argl) {
|
||||
world = plugin.matchWorld(sender, args.getString(1 + argl));
|
||||
} else {
|
||||
world = plugin.checkPlayer(sender).getWorld();
|
||||
}
|
||||
|
||||
int listSize = 10;
|
||||
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
|
||||
Map<String, ProtectedRegion> regions = mgr.getRegions();
|
||||
|
||||
int size = regions.size();
|
||||
|
||||
String[] regionIDList = new String[size];
|
||||
int index = 0;
|
||||
boolean show = false;
|
||||
String prefix = "";
|
||||
for (String id : regions.keySet()) {
|
||||
show = false;
|
||||
prefix = "";
|
||||
if (name.isEmpty()) {
|
||||
show = true;
|
||||
}
|
||||
else {
|
||||
if (own) {
|
||||
if (regions.get(id).isOwner(localPlayer)) {
|
||||
show = true;
|
||||
prefix += "+";
|
||||
}
|
||||
else if (regions.get(id).isMember(localPlayer)) {
|
||||
show = true;
|
||||
prefix += "-";
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (regions.get(id).getOwners().getPlayers().contains(name)) {
|
||||
show = true;
|
||||
prefix += "+";
|
||||
}
|
||||
if (regions.get(id).getMembers().getPlayers().contains(name)) {
|
||||
show = true;
|
||||
prefix += "-";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (show) {
|
||||
regionIDList[index] = prefix + " " + id;
|
||||
index++;
|
||||
}
|
||||
}
|
||||
if (!name.isEmpty())
|
||||
regionIDList = Arrays.copyOf(regionIDList, index);
|
||||
Arrays.sort(regionIDList);
|
||||
size = index;
|
||||
int pages = (int) Math.ceil(size / (float) listSize);
|
||||
|
||||
sender.sendMessage(ChatColor.RED
|
||||
+ (name.equals("") ? "Regions (page " : "Regions for " + name + " (page ")
|
||||
+ (page + 1) + " of " + pages + "):");
|
||||
|
||||
if (page < pages) {
|
||||
for (int i = page * listSize; i < page * listSize + listSize; i++) {
|
||||
if (i >= size) {
|
||||
break;
|
||||
}
|
||||
sender.sendMessage(ChatColor.YELLOW.toString() + (i + 1) +
|
||||
"." + regionIDList[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Command(aliases = {"flag", "f"}, usage = "<id> <flag> [value]",
|
||||
desc = "Set flags", min = 2)
|
||||
public void flag(CommandContext args, CommandSender sender) throws CommandException {
|
||||
|
||||
Player player = plugin.checkPlayer(sender);
|
||||
World world = player.getWorld();
|
||||
LocalPlayer localPlayer = plugin.wrapPlayer(player);
|
||||
|
||||
String id = args.getString(0);
|
||||
String flagName = args.getString(1);
|
||||
String value = null;
|
||||
|
||||
if (args.argsLength() >= 3) {
|
||||
value = args.getJoinedStrings(2);
|
||||
}
|
||||
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
|
||||
ProtectedRegion region = mgr.getRegion(id);
|
||||
|
||||
if (region == null) {
|
||||
if (id.equalsIgnoreCase("__global__")) {
|
||||
region = new GlobalProtectedRegion(id);
|
||||
mgr.addRegion(region);
|
||||
} else {
|
||||
throw new CommandException("Could not find a region by that ID.");
|
||||
}
|
||||
}
|
||||
|
||||
// @TODO deprecate "flag.[own./member./blank]"
|
||||
boolean hasPerm = false;
|
||||
if (region.isOwner(localPlayer)) {
|
||||
if (plugin.hasPermission(sender, "worldguard.region.flag.own." + id.toLowerCase())) hasPerm = true;
|
||||
else if (plugin.hasPermission(sender, "worldguard.region.flag.regions.own." + id.toLowerCase())) hasPerm = true;
|
||||
} else if (region.isMember(localPlayer)) {
|
||||
if (plugin.hasPermission(sender, "worldguard.region.flag.member." + id.toLowerCase())) hasPerm = true;
|
||||
else if (plugin.hasPermission(sender, "worldguard.region.flag.regions.member." + id.toLowerCase())) hasPerm = true;
|
||||
} else {
|
||||
if (plugin.hasPermission(sender, "worldguard.region.flag." + id.toLowerCase())) hasPerm = true;
|
||||
else if (plugin.hasPermission(sender, "worldguard.region.flag.regions." + id.toLowerCase())) hasPerm = true;
|
||||
}
|
||||
if (!hasPerm) throw new CommandPermissionsException();
|
||||
|
||||
Flag<?> foundFlag = null;
|
||||
|
||||
// Now time to find the flag!
|
||||
for (Flag<?> flag : DefaultFlag.getFlags()) {
|
||||
// Try to detect the flag
|
||||
if (flag.getName().replace("-", "").equalsIgnoreCase(flagName.replace("-", ""))) {
|
||||
foundFlag = flag;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundFlag == null) {
|
||||
StringBuilder list = new StringBuilder();
|
||||
|
||||
// Need to build a list
|
||||
for (Flag<?> flag : DefaultFlag.getFlags()) {
|
||||
if (list.length() > 0) {
|
||||
list.append(", ");
|
||||
}
|
||||
|
||||
// @TODO deprecate inconsistant "owner" permission
|
||||
if (region.isOwner(localPlayer)) {
|
||||
if (!plugin.hasPermission(sender, "worldguard.region.flag.flags."
|
||||
+ flag.getName() + ".owner." + id.toLowerCase())
|
||||
&& !plugin.hasPermission(sender, "worldguard.region.flag.flags."
|
||||
+ flag.getName() + ".own." + id.toLowerCase())) {
|
||||
continue;
|
||||
}
|
||||
} else if (region.isMember(localPlayer)) {
|
||||
if (!plugin.hasPermission(sender, "worldguard.region.flag.flags."
|
||||
+ flag.getName() + ".member." + id.toLowerCase())) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (!plugin.hasPermission(sender, "worldguard.region.flag.flags."
|
||||
+ flag.getName() + "." + id.toLowerCase())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
list.append(flag.getName());
|
||||
}
|
||||
|
||||
player.sendMessage(ChatColor.RED + "Unknown flag specified: " + flagName);
|
||||
player.sendMessage(ChatColor.RED + "Available flags: " + list);
|
||||
return;
|
||||
}
|
||||
|
||||
if (region.isOwner(localPlayer)) {
|
||||
plugin.checkPermission(sender, "worldguard.region.flag.flags."
|
||||
+ foundFlag.getName() + ".owner." + id.toLowerCase());
|
||||
} else if (region.isMember(localPlayer)) {
|
||||
plugin.checkPermission(sender, "worldguard.region.flag.flags."
|
||||
+ foundFlag.getName() + ".member." + id.toLowerCase());
|
||||
} else {
|
||||
plugin.checkPermission(sender, "worldguard.region.flag.flags."
|
||||
+ foundFlag.getName() + "." + id.toLowerCase());
|
||||
}
|
||||
|
||||
if (value != null) {
|
||||
try {
|
||||
setFlag(region, foundFlag, sender, value);
|
||||
} catch (InvalidFlagFormat e) {
|
||||
throw new CommandException(e.getMessage());
|
||||
}
|
||||
|
||||
sender.sendMessage(ChatColor.YELLOW
|
||||
+ "Region flag '" + foundFlag.getName() + "' set.");
|
||||
} else {
|
||||
// Clear the flag
|
||||
region.setFlag(foundFlag, null);
|
||||
|
||||
sender.sendMessage(ChatColor.YELLOW
|
||||
+ "Region flag '" + foundFlag.getName() + "' cleared.");
|
||||
}
|
||||
|
||||
try {
|
||||
mgr.save();
|
||||
} catch (ProtectionDatabaseException e) {
|
||||
throw new CommandException("Failed to write regions: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public <V> void setFlag(ProtectedRegion region,
|
||||
Flag<V> flag, CommandSender sender, String value)
|
||||
throws InvalidFlagFormat {
|
||||
region.setFlag(flag, flag.parseInput(plugin, sender, value));
|
||||
}
|
||||
|
||||
@Command(aliases = {"setpriority", "priority", "pri"}, usage = "<id> <priority>",
|
||||
desc = "Set the priority of a region", min = 2, max = 2)
|
||||
public void setPriority(CommandContext args, CommandSender sender) throws CommandException {
|
||||
Player player = plugin.checkPlayer(sender);
|
||||
World world = player.getWorld();
|
||||
LocalPlayer localPlayer = plugin.wrapPlayer(player);
|
||||
|
||||
String id = args.getString(0);
|
||||
int priority = args.getInteger(1);
|
||||
|
||||
if (id.equalsIgnoreCase("__global__")) {
|
||||
throw new CommandException("The region cannot be named __global__");
|
||||
}
|
||||
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
|
||||
ProtectedRegion region = mgr.getRegion(id);
|
||||
|
||||
if (region == null) {
|
||||
throw new CommandException("Could not find a region by that ID.");
|
||||
}
|
||||
|
||||
if (region.isOwner(localPlayer)) {
|
||||
plugin.checkPermission(sender, "worldguard.region.setpriority.own." + id.toLowerCase());
|
||||
} else if (region.isMember(localPlayer)) {
|
||||
plugin.checkPermission(sender, "worldguard.region.setpriority.member." + id.toLowerCase());
|
||||
} else {
|
||||
plugin.checkPermission(sender, "worldguard.region.setpriority." + id.toLowerCase());
|
||||
}
|
||||
|
||||
region.setPriority(priority);
|
||||
|
||||
sender.sendMessage(ChatColor.YELLOW
|
||||
+ "Priority of '" + region.getId() + "' set to "
|
||||
+ priority + ".");
|
||||
|
||||
try {
|
||||
mgr.save();
|
||||
} catch (ProtectionDatabaseException e) {
|
||||
throw new CommandException("Failed to write regions: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Command(aliases = {"setparent", "parent", "par"}, usage = "<id> [parent-id]",
|
||||
desc = "Set the parent of a region", min = 1, max = 2)
|
||||
public void setParent(CommandContext args, CommandSender sender) throws CommandException {
|
||||
Player player = plugin.checkPlayer(sender);
|
||||
World world = player.getWorld();
|
||||
LocalPlayer localPlayer = plugin.wrapPlayer(player);
|
||||
|
||||
String id = args.getString(0);
|
||||
|
||||
if (id.equalsIgnoreCase("__global__")) {
|
||||
throw new CommandException("The region cannot be named __global__");
|
||||
}
|
||||
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
|
||||
ProtectedRegion region = mgr.getRegion(id);
|
||||
|
||||
if (args.argsLength() == 1) {
|
||||
try {
|
||||
region.setParent(null);
|
||||
} catch (CircularInheritanceException e) {
|
||||
}
|
||||
|
||||
sender.sendMessage(ChatColor.YELLOW
|
||||
+ "Parent of '" + region.getId() + "' cleared.");
|
||||
} else {
|
||||
String parentId = args.getString(1);
|
||||
ProtectedRegion parent = mgr.getRegion(parentId);
|
||||
|
||||
if (region == null) {
|
||||
throw new CommandException("Could not find a target region by that ID.");
|
||||
}
|
||||
|
||||
if (parent == null) {
|
||||
throw new CommandException("Could not find the parent region by that ID.");
|
||||
}
|
||||
|
||||
if (region.isOwner(localPlayer)) {
|
||||
plugin.checkPermission(sender, "worldguard.region.setparent.own." + id.toLowerCase());
|
||||
} else if (region.isMember(localPlayer)) {
|
||||
plugin.checkPermission(sender, "worldguard.region.setparent.member." + id.toLowerCase());
|
||||
} else {
|
||||
plugin.checkPermission(sender, "worldguard.region.setparent." + id.toLowerCase());
|
||||
}
|
||||
|
||||
if (parent.isOwner(localPlayer)) {
|
||||
plugin.checkPermission(sender, "worldguard.region.setparent.own." + id.toLowerCase());
|
||||
} else if (parent.isMember(localPlayer)) {
|
||||
plugin.checkPermission(sender, "worldguard.region.setparent.member." + id.toLowerCase());
|
||||
} else {
|
||||
plugin.checkPermission(sender, "worldguard.region.setparent." + id.toLowerCase());
|
||||
}
|
||||
|
||||
try {
|
||||
region.setParent(parent);
|
||||
} catch (CircularInheritanceException e) {
|
||||
throw new CommandException("Circular inheritance detected!");
|
||||
}
|
||||
|
||||
sender.sendMessage(ChatColor.YELLOW
|
||||
+ "Parent of '" + region.getId() + "' set to '"
|
||||
+ parent.getId() + "'.");
|
||||
}
|
||||
|
||||
try {
|
||||
mgr.save();
|
||||
} catch (ProtectionDatabaseException e) {
|
||||
throw new CommandException("Failed to write regions: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Command(aliases = {"remove", "delete", "del", "rem"}, usage = "<id>",
|
||||
desc = "Remove a region", min = 1, max = 1)
|
||||
public void remove(CommandContext args, CommandSender sender) throws CommandException {
|
||||
|
||||
Player player = plugin.checkPlayer(sender);
|
||||
World world = player.getWorld();
|
||||
LocalPlayer localPlayer = plugin.wrapPlayer(player);
|
||||
|
||||
String id = args.getString(0);
|
||||
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
|
||||
ProtectedRegion region = mgr.getRegion(id);
|
||||
|
||||
if (region == null) {
|
||||
throw new CommandException("Could not find a region by that ID.");
|
||||
}
|
||||
|
||||
if (region.isOwner(localPlayer)) {
|
||||
plugin.checkPermission(sender, "worldguard.region.remove.own." + id.toLowerCase());
|
||||
} else if (region.isMember(localPlayer)) {
|
||||
plugin.checkPermission(sender, "worldguard.region.remove.member." + id.toLowerCase());
|
||||
} else {
|
||||
plugin.checkPermission(sender, "worldguard.region.remove." + id.toLowerCase());
|
||||
}
|
||||
|
||||
mgr.removeRegion(id);
|
||||
|
||||
sender.sendMessage(ChatColor.YELLOW
|
||||
+ "Region '" + id + "' removed.");
|
||||
|
||||
try {
|
||||
mgr.save();
|
||||
} catch (ProtectionDatabaseException e) {
|
||||
throw new CommandException("Failed to write regions: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Command(aliases = {"load", "reload"}, usage = "[world]",
|
||||
desc = "Reload regions from file", max = 1)
|
||||
public void load(CommandContext args, CommandSender sender) throws CommandException {
|
||||
|
||||
World world = null;
|
||||
|
||||
if (args.argsLength() > 0) {
|
||||
world = plugin.matchWorld(sender, args.getString(0));
|
||||
}
|
||||
|
||||
if (world != null) {
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
|
||||
|
||||
try {
|
||||
mgr.load();
|
||||
sender.sendMessage(ChatColor.YELLOW
|
||||
+ "Regions for '" + world.getName() + "' load.");
|
||||
} catch (ProtectionDatabaseException e) {
|
||||
throw new CommandException("Failed to read regions: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
} else {
|
||||
for (World w : plugin.getServer().getWorlds()) {
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(w);
|
||||
|
||||
try {
|
||||
mgr.load();
|
||||
} catch (ProtectionDatabaseException e) {
|
||||
throw new CommandException("Failed to read regions: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
sender.sendMessage(ChatColor.YELLOW
|
||||
+ "Region databases loaded.");
|
||||
}
|
||||
}
|
||||
|
||||
@Command(aliases = {"save", "write"}, usage = "[world]",
|
||||
desc = "Re-save regions to file", max = 1)
|
||||
public void save(CommandContext args, CommandSender sender) throws CommandException {
|
||||
|
||||
World world = null;
|
||||
|
||||
if (args.argsLength() > 0) {
|
||||
world = plugin.matchWorld(sender, args.getString(0));
|
||||
}
|
||||
|
||||
if (world != null) {
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
|
||||
|
||||
try {
|
||||
mgr.save();
|
||||
sender.sendMessage(ChatColor.YELLOW
|
||||
+ "Regions for '" + world.getName() + "' saved.");
|
||||
} catch (ProtectionDatabaseException e) {
|
||||
throw new CommandException("Failed to write regions: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
} else {
|
||||
for (World w : plugin.getServer().getWorlds()) {
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(w);
|
||||
|
||||
try {
|
||||
mgr.save();
|
||||
} catch (ProtectionDatabaseException e) {
|
||||
throw new CommandException("Failed to write regions: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
sender.sendMessage(ChatColor.YELLOW
|
||||
+ "Region databases saved.");
|
||||
}
|
||||
}
|
||||
|
||||
@Command(aliases = {"migratedb"}, usage = "<from> <to>",
|
||||
desc = "Migrate from one Protection Database to another.", min = 1)
|
||||
@CommandPermissions({"worldguard.region.migratedb"})
|
||||
public void migratedb(CommandContext args, CommandSender sender) throws CommandException {
|
||||
String from = args.getString(0).toLowerCase().trim();
|
||||
String to = args.getString(1).toLowerCase().trim();
|
||||
|
||||
if (from.equals(to)) {
|
||||
throw new CommandException("Will not migrate with common source and target.");
|
||||
}
|
||||
|
||||
Map<MigratorKey, Class<? extends AbstractDatabaseMigrator>> migrators = AbstractDatabaseMigrator.getMigrators();
|
||||
MigratorKey key = new MigratorKey(from,to);
|
||||
|
||||
if (!migrators.containsKey(key)) {
|
||||
throw new CommandException("No migrator found for that combination and direction.");
|
||||
}
|
||||
|
||||
long lastRequest = 10000000;
|
||||
if (this.migrateDBRequestDate != null) {
|
||||
lastRequest = new Date().getTime() - this.migrateDBRequestDate.getTime();
|
||||
}
|
||||
if (this.migrateDBRequest == null || lastRequest > 60000) {
|
||||
this.migrateDBRequest = key;
|
||||
this.migrateDBRequestDate = new Date();
|
||||
|
||||
throw new CommandException("This command is potentially dangerous.\n" +
|
||||
"Please ensure you have made a backup of your data, and then re-enter the command exactly to procede.");
|
||||
}
|
||||
|
||||
Class<? extends AbstractDatabaseMigrator> cls = migrators.get(key);
|
||||
|
||||
try {
|
||||
AbstractDatabaseMigrator migrator = cls.getConstructor(WorldGuardPlugin.class).newInstance(plugin);
|
||||
|
||||
migrator.migrate();
|
||||
} catch (IllegalArgumentException e) {
|
||||
} catch (SecurityException e) {
|
||||
} catch (InstantiationException e) {
|
||||
} catch (IllegalAccessException e) {
|
||||
} catch (InvocationTargetException e) {
|
||||
} catch (NoSuchMethodException e) {
|
||||
} catch (MigrationException e) {
|
||||
throw new CommandException("Error migrating database: " + e.getMessage());
|
||||
}
|
||||
|
||||
sender.sendMessage(ChatColor.YELLOW + "Regions have been migrated successfuly.\n" +
|
||||
"If you wish to use the destination format as your new backend, please update your config and reload WorldGuard.");
|
||||
}
|
||||
}
|
||||
@@ -1,213 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.bukkit.commands;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.domains.DefaultDomain;
|
||||
import com.sk89q.worldguard.protection.flags.DefaultFlag;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.databases.ProtectionDatabaseException;
|
||||
import com.sk89q.worldguard.util.RegionUtil;
|
||||
|
||||
// @TODO: A lot of code duplication here! Need to fix.
|
||||
|
||||
public class RegionMemberCommands {
|
||||
private final WorldGuardPlugin plugin;
|
||||
|
||||
public RegionMemberCommands(WorldGuardPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Command(aliases = {"addmember", "addmember"}, usage = "<id> <members...>",
|
||||
desc = "Add a member to a region", min = 2)
|
||||
public void addMember(CommandContext args, CommandSender sender) throws CommandException {
|
||||
|
||||
Player player = plugin.checkPlayer(sender);
|
||||
World world = player.getWorld();
|
||||
LocalPlayer localPlayer = plugin.wrapPlayer(player);
|
||||
|
||||
String id = args.getString(0);
|
||||
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
|
||||
ProtectedRegion region = mgr.getRegion(id);
|
||||
|
||||
if (region == null) {
|
||||
throw new CommandException("Could not find a region by that ID.");
|
||||
}
|
||||
|
||||
if (region.isOwner(localPlayer)) {
|
||||
plugin.checkPermission(sender, "worldguard.region.addmember.own." + id.toLowerCase());
|
||||
} else if (region.isMember(localPlayer)) {
|
||||
plugin.checkPermission(sender, "worldguard.region.addmember.member." + id.toLowerCase());
|
||||
} else {
|
||||
plugin.checkPermission(sender, "worldguard.region.addmember." + id.toLowerCase());
|
||||
}
|
||||
|
||||
RegionUtil.addToDomain(region.getMembers(), args.getPaddedSlice(2, 0), 0);
|
||||
|
||||
sender.sendMessage(ChatColor.YELLOW
|
||||
+ "Region '" + id + "' updated.");
|
||||
|
||||
try {
|
||||
mgr.save();
|
||||
} catch (ProtectionDatabaseException e) {
|
||||
throw new CommandException("Failed to write regions: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Command(aliases = {"addowner", "addowner"}, usage = "<id> <owners...>",
|
||||
desc = "Add an owner to a region", min = 2)
|
||||
public void addOwner(CommandContext args, CommandSender sender) throws CommandException {
|
||||
|
||||
Player player = plugin.checkPlayer(sender);
|
||||
World world = player.getWorld();
|
||||
LocalPlayer localPlayer = plugin.wrapPlayer(player);
|
||||
|
||||
String id = args.getString(0);
|
||||
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
|
||||
ProtectedRegion region = mgr.getRegion(id);
|
||||
|
||||
if (region == null) {
|
||||
throw new CommandException("Could not find a region by that ID.");
|
||||
}
|
||||
|
||||
Boolean flag = region.getFlag(DefaultFlag.BUYABLE);
|
||||
DefaultDomain owners = region.getOwners();
|
||||
if (flag != null && flag == true && owners != null && owners.size() == 0) {
|
||||
if (!plugin.hasPermission(player, "worldguard.region.unlimited")) {
|
||||
int maxRegionCount = plugin.getGlobalStateManager().get(world).getMaxRegionCount(player);
|
||||
if (maxRegionCount >= 0 && mgr.getRegionCountOfPlayer(localPlayer)
|
||||
>= maxRegionCount) {
|
||||
throw new CommandException("You already own the maximum allowed amount of regions.");
|
||||
}
|
||||
}
|
||||
plugin.checkPermission(sender, "worldguard.region.addowner.unclaimed." + id.toLowerCase());
|
||||
} else {
|
||||
if (region.isOwner(localPlayer)) {
|
||||
plugin.checkPermission(sender, "worldguard.region.addowner.own." + id.toLowerCase());
|
||||
} else if (region.isMember(localPlayer)) {
|
||||
plugin.checkPermission(sender, "worldguard.region.addowner.member." + id.toLowerCase());
|
||||
} else {
|
||||
plugin.checkPermission(sender, "worldguard.region.addowner." + id.toLowerCase());
|
||||
}
|
||||
}
|
||||
|
||||
RegionUtil.addToDomain(region.getOwners(), args.getPaddedSlice(2, 0), 0);
|
||||
|
||||
sender.sendMessage(ChatColor.YELLOW
|
||||
+ "Region '" + id + "' updated.");
|
||||
|
||||
try {
|
||||
mgr.save();
|
||||
} catch (ProtectionDatabaseException e) {
|
||||
throw new CommandException("Failed to write regions: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Command(aliases = {"removemember", "remmember", "removemem", "remmem"}, usage = "<id> <owners...>",
|
||||
desc = "Remove an owner to a region", min = 2)
|
||||
public void removeMember(CommandContext args, CommandSender sender) throws CommandException {
|
||||
|
||||
Player player = plugin.checkPlayer(sender);
|
||||
World world = player.getWorld();
|
||||
LocalPlayer localPlayer = plugin.wrapPlayer(player);
|
||||
|
||||
String id = args.getString(0);
|
||||
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
|
||||
ProtectedRegion region = mgr.getRegion(id);
|
||||
|
||||
if (region == null) {
|
||||
throw new CommandException("Could not find a region by that ID.");
|
||||
}
|
||||
|
||||
if (region.isOwner(localPlayer)) {
|
||||
plugin.checkPermission(sender, "worldguard.region.removemember.own." + id.toLowerCase());
|
||||
} else if (region.isMember(localPlayer)) {
|
||||
plugin.checkPermission(sender, "worldguard.region.removemember.member." + id.toLowerCase());
|
||||
} else {
|
||||
plugin.checkPermission(sender, "worldguard.region.removemember." + id.toLowerCase());
|
||||
}
|
||||
|
||||
RegionUtil.removeFromDomain(region.getMembers(), args.getPaddedSlice(2, 0), 0);
|
||||
|
||||
sender.sendMessage(ChatColor.YELLOW
|
||||
+ "Region '" + id + "' updated.");
|
||||
|
||||
try {
|
||||
mgr.save();
|
||||
} catch (ProtectionDatabaseException e) {
|
||||
throw new CommandException("Failed to write regions: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Command(aliases = {"removeowner", "remowner"}, usage = "<id> <owners...>",
|
||||
desc = "Remove an owner to a region", min = 2)
|
||||
public void removeOwner(CommandContext args,
|
||||
CommandSender sender) throws CommandException {
|
||||
|
||||
Player player = plugin.checkPlayer(sender);
|
||||
World world = player.getWorld();
|
||||
LocalPlayer localPlayer = plugin.wrapPlayer(player);
|
||||
|
||||
String id = args.getString(0);
|
||||
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
|
||||
ProtectedRegion region = mgr.getRegion(id);
|
||||
|
||||
if (region == null) {
|
||||
throw new CommandException("Could not find a region by that ID.");
|
||||
}
|
||||
|
||||
if (region.isOwner(localPlayer)) {
|
||||
plugin.checkPermission(sender, "worldguard.region.removeowner.own." + id.toLowerCase());
|
||||
} else if (region.isMember(localPlayer)) {
|
||||
plugin.checkPermission(sender, "worldguard.region.removeowner.member." + id.toLowerCase());
|
||||
} else {
|
||||
plugin.checkPermission(sender, "worldguard.region.removeowner." + id.toLowerCase());
|
||||
}
|
||||
|
||||
RegionUtil.removeFromDomain(region.getOwners(), args.getPaddedSlice(2, 0), 0);
|
||||
|
||||
sender.sendMessage(ChatColor.YELLOW
|
||||
+ "Region '" + id + "' updated.");
|
||||
|
||||
try {
|
||||
mgr.save();
|
||||
} catch (ProtectionDatabaseException e) {
|
||||
throw new CommandException("Failed to write regions: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.bukkit.commands;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||
import com.sk89q.worldguard.bukkit.BukkitUtil;
|
||||
import com.sk89q.worldguard.bukkit.ConfigurationManager;
|
||||
import com.sk89q.worldguard.bukkit.WorldConfiguration;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
|
||||
public class ToggleCommands {
|
||||
private final WorldGuardPlugin plugin;
|
||||
|
||||
public ToggleCommands(WorldGuardPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Command(aliases = {"stopfire"}, usage = "[<world>]",
|
||||
desc = "Disables all fire spread temporarily", max = 1)
|
||||
@CommandPermissions({"worldguard.fire-toggle.stop"})
|
||||
public void stopFire(CommandContext args, CommandSender sender) throws CommandException {
|
||||
|
||||
World world;
|
||||
|
||||
if (args.argsLength() == 0) {
|
||||
world = plugin.checkPlayer(sender).getWorld();
|
||||
} else {
|
||||
world = plugin.matchWorld(sender, args.getString(0));
|
||||
}
|
||||
|
||||
WorldConfiguration wcfg = plugin.getGlobalStateManager().get(world);
|
||||
|
||||
if (!wcfg.fireSpreadDisableToggle) {
|
||||
plugin.getServer().broadcastMessage(
|
||||
ChatColor.YELLOW
|
||||
+ "Fire spread has been globally disabled for '" + world.getName() + "' by "
|
||||
+ plugin.toName(sender) + ".");
|
||||
} else {
|
||||
sender.sendMessage(
|
||||
ChatColor.YELLOW
|
||||
+ "Fire spread was already globally disabled.");
|
||||
}
|
||||
|
||||
wcfg.fireSpreadDisableToggle = true;
|
||||
}
|
||||
|
||||
@Command(aliases = {"allowfire"}, usage = "[<world>]",
|
||||
desc = "Allows all fire spread temporarily", max = 1)
|
||||
@CommandPermissions({"worldguard.fire-toggle.stop"})
|
||||
public void allowFire(CommandContext args, CommandSender sender) throws CommandException {
|
||||
|
||||
World world;
|
||||
|
||||
if (args.argsLength() == 0) {
|
||||
world = plugin.checkPlayer(sender).getWorld();
|
||||
} else {
|
||||
world = plugin.matchWorld(sender, args.getString(0));
|
||||
}
|
||||
|
||||
WorldConfiguration wcfg = plugin.getGlobalStateManager().get(world);
|
||||
|
||||
if (wcfg.fireSpreadDisableToggle) {
|
||||
plugin.getServer().broadcastMessage(ChatColor.YELLOW
|
||||
+ "Fire spread has been globally for '" + world.getName() + "' re-enabled by "
|
||||
+ plugin.toName(sender) + ".");
|
||||
} else {
|
||||
sender.sendMessage(ChatColor.YELLOW
|
||||
+ "Fire spread was already globally enabled.");
|
||||
}
|
||||
|
||||
wcfg.fireSpreadDisableToggle = false;
|
||||
}
|
||||
|
||||
@Command(aliases = {"halt-activity", "stoplag", "haltactivity"},
|
||||
desc = "Attempts to cease as much activity in order to stop lag", flags = "c", max = 0)
|
||||
@CommandPermissions({"worldguard.halt-activity"})
|
||||
public void stopLag(CommandContext args, CommandSender sender) throws CommandException {
|
||||
|
||||
ConfigurationManager configManager = plugin.getGlobalStateManager();
|
||||
|
||||
configManager.activityHaltToggle = !args.hasFlag('c');
|
||||
|
||||
if (configManager.activityHaltToggle) {
|
||||
if (!(sender instanceof Player)) {
|
||||
sender.sendMessage(ChatColor.YELLOW
|
||||
+ "ALL intensive server activity halted.");
|
||||
}
|
||||
|
||||
plugin.getServer().broadcastMessage(ChatColor.YELLOW
|
||||
+ "ALL intensive server activity halted by "
|
||||
+ plugin.toName(sender) + ".");
|
||||
|
||||
for (World world : plugin.getServer().getWorlds()) {
|
||||
int removed = 0;
|
||||
|
||||
for (Entity entity : world.getEntities()) {
|
||||
if (BukkitUtil.isIntensiveEntity(entity)) {
|
||||
entity.remove();
|
||||
removed++;
|
||||
}
|
||||
}
|
||||
|
||||
if (removed > 10) {
|
||||
sender.sendMessage("" + removed + " entities (>10) auto-removed from "
|
||||
+ world.toString());
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (!(sender instanceof Player)) {
|
||||
sender.sendMessage(ChatColor.YELLOW
|
||||
+ "ALL intensive server activity no longer halted.");
|
||||
}
|
||||
|
||||
plugin.getServer().broadcastMessage(ChatColor.YELLOW
|
||||
+ "ALL intensive server activity is now allowed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.bukkit.commands;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||
import com.sk89q.worldguard.bukkit.LoggerToChatHandler;
|
||||
import com.sk89q.worldguard.bukkit.ReportWriter;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.util.PastebinPoster;
|
||||
import com.sk89q.worldguard.util.PastebinPoster.PasteCallback;
|
||||
|
||||
public class WorldGuardCommands {
|
||||
private final WorldGuardPlugin plugin;
|
||||
|
||||
public WorldGuardCommands(WorldGuardPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Command(aliases = {"version"}, desc = "Get the WorldGuard version", max = 0)
|
||||
public void version(CommandContext args, CommandSender sender) throws CommandException {
|
||||
sender.sendMessage(ChatColor.YELLOW
|
||||
+ "WorldGuard " + plugin.getDescription().getVersion());
|
||||
sender.sendMessage(ChatColor.YELLOW
|
||||
+ "http://www.sk89q.com");
|
||||
}
|
||||
|
||||
@Command(aliases = {"reload"}, desc = "Reload WorldGuard configuration", max = 0)
|
||||
@CommandPermissions({"worldguard.reload"})
|
||||
public void reload(CommandContext args, CommandSender sender) throws CommandException {
|
||||
|
||||
LoggerToChatHandler handler = null;
|
||||
Logger minecraftLogger = null;
|
||||
|
||||
if (sender instanceof Player) {
|
||||
handler = new LoggerToChatHandler(sender);
|
||||
handler.setLevel(Level.ALL);
|
||||
minecraftLogger = Logger.getLogger("Minecraft");
|
||||
minecraftLogger.addHandler(handler);
|
||||
}
|
||||
|
||||
try {
|
||||
plugin.getGlobalStateManager().unload();
|
||||
plugin.getGlobalRegionManager().unload();
|
||||
plugin.getGlobalStateManager().load();
|
||||
plugin.getGlobalRegionManager().preload();
|
||||
sender.sendMessage("WorldGuard configuration reloaded.");
|
||||
} catch (Throwable t) {
|
||||
sender.sendMessage("Error while reloading: "
|
||||
+ t.getMessage());
|
||||
} finally {
|
||||
if (minecraftLogger != null) {
|
||||
minecraftLogger.removeHandler(handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Command(aliases = {"report"}, desc = "Writes a report on WorldGuard", flags = "p", max = 0)
|
||||
@CommandPermissions({"worldguard.report"})
|
||||
public void report(CommandContext args, final CommandSender sender) throws CommandException {
|
||||
|
||||
File dest = new File(plugin.getDataFolder(), "report.txt");
|
||||
ReportWriter report = new ReportWriter(plugin);
|
||||
|
||||
try {
|
||||
report.write(dest);
|
||||
sender.sendMessage(ChatColor.YELLOW + "WorldGuard report written to "
|
||||
+ dest.getAbsolutePath());
|
||||
} catch (IOException e) {
|
||||
throw new CommandException("Failed to write report: " + e.getMessage());
|
||||
}
|
||||
|
||||
if (args.hasFlag('p')) {
|
||||
plugin.checkPermission(sender, "worldguard.report.pastebin");
|
||||
|
||||
sender.sendMessage(ChatColor.YELLOW + "Now uploading to Pastebin...");
|
||||
PastebinPoster.paste(report.toString(), new PasteCallback() {
|
||||
|
||||
public void handleSuccess(String url) {
|
||||
// Hope we don't have a thread safety issue here
|
||||
sender.sendMessage(ChatColor.YELLOW + "WorldGuard report (1 hour): " + url);
|
||||
}
|
||||
|
||||
public void handleError(String err) {
|
||||
// Hope we don't have a thread safety issue here
|
||||
sender.sendMessage(ChatColor.YELLOW + "WorldGuard report pastebin error: " + err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Command(aliases = {"flushstates", "clearstates"},
|
||||
usage = "[player]", desc = "Flush the state manager", max = 1)
|
||||
@CommandPermissions("worldguard.flushstates")
|
||||
public void flushStates(CommandContext args, CommandSender sender) throws CommandException {
|
||||
if (args.argsLength() == 0) {
|
||||
plugin.getFlagStateManager().forgetAll();
|
||||
sender.sendMessage("Cleared all states.");
|
||||
} else {
|
||||
Player player = plugin.getServer().getPlayer(args.getString(0));
|
||||
if (player != null) {
|
||||
plugin.getFlagStateManager().forget(player);
|
||||
sender.sendMessage("Cleared states for player \"" + player.getName() + "\".");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.chest;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* Interface for chest protection.
|
||||
*/
|
||||
public interface ChestProtection {
|
||||
|
||||
/**
|
||||
* Returns whether a block is protected.
|
||||
*
|
||||
* @param block
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
public boolean isProtected(Block block, Player player);
|
||||
|
||||
/**
|
||||
* Returns whether a location where a chest block is trying to be created
|
||||
* is protected.
|
||||
*
|
||||
* @param block
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
public boolean isProtectedPlacement(Block block, Player player);
|
||||
|
||||
/**
|
||||
* Returns whether an adjacent chest is protected.
|
||||
*
|
||||
* @param searchBlock
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
public boolean isAdjacentChestProtected(Block searchBlock, Player player);
|
||||
|
||||
/**
|
||||
* Returns whether a material is a chest.
|
||||
*
|
||||
* @param material
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean isChest(Material material);
|
||||
|
||||
/**
|
||||
* Returns whether a material is a chest.
|
||||
*
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
public boolean isChest(int type);
|
||||
|
||||
}
|
||||
@@ -1,162 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.chest;
|
||||
|
||||
import com.sk89q.worldedit.blocks.BlockID;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* Sign-based chest protection.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class SignChestProtection implements ChestProtection {
|
||||
|
||||
public boolean isProtected(Block block, Player player) {
|
||||
if (isChest(block.getTypeId())) {
|
||||
Block below = block.getRelative(0, -1, 0);
|
||||
return isProtectedSignAround(below, player);
|
||||
} else if (block.getTypeId() == BlockID.SIGN_POST) {
|
||||
return isProtectedSignAndChestBinary(block, player);
|
||||
} else {
|
||||
Block above = block.getRelative(0, 1, 0);
|
||||
Boolean res = isProtectedSign(above, player);
|
||||
if (res != null) return res;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isProtectedPlacement(Block block, Player player) {
|
||||
return isProtectedSignAround(block, player);
|
||||
}
|
||||
|
||||
private boolean isProtectedSignAround(Block searchBlock, Player player) {
|
||||
Block side;
|
||||
Boolean res;
|
||||
|
||||
side = searchBlock;
|
||||
res = isProtectedSign(side, player);
|
||||
if (res != null && res) return res;
|
||||
|
||||
side = searchBlock.getRelative(-1, 0, 0);
|
||||
res = isProtectedSignAndChest(side, player);
|
||||
if (res != null && res) return res;
|
||||
|
||||
side = searchBlock.getRelative(1, 0, 0);
|
||||
res = isProtectedSignAndChest(side, player);
|
||||
if (res != null && res) return res;
|
||||
|
||||
side = searchBlock.getRelative(0, 0, -1);
|
||||
res = isProtectedSignAndChest(side, player);
|
||||
if (res != null && res) return res;
|
||||
|
||||
side = searchBlock.getRelative(0, 0, 1);
|
||||
res = isProtectedSignAndChest(side, player);
|
||||
if (res != null && res) return res;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private Boolean isProtectedSign(Sign sign, Player player) {
|
||||
if (sign.getLine(0).equalsIgnoreCase("[Lock]")) {
|
||||
if (player == null) { // No player, no access
|
||||
return true;
|
||||
}
|
||||
|
||||
String name = player.getName();
|
||||
if (name.equalsIgnoreCase(sign.getLine(1).trim())
|
||||
|| name.equalsIgnoreCase(sign.getLine(2).trim())
|
||||
|| name.equalsIgnoreCase(sign.getLine(3).trim())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// No access!
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private Boolean isProtectedSign(Block block, Player player) {
|
||||
BlockState state = block.getState();
|
||||
if (state == null || !(state instanceof Sign)) {
|
||||
return null;
|
||||
}
|
||||
return isProtectedSign((Sign) state, player);
|
||||
}
|
||||
|
||||
private Boolean isProtectedSignAndChest(Block block, Player player) {
|
||||
if (!isChest(block.getRelative(0, 1, 0).getTypeId())) {
|
||||
return null;
|
||||
}
|
||||
return isProtectedSign(block, player);
|
||||
}
|
||||
|
||||
private boolean isProtectedSignAndChestBinary(Block block, Player player) {
|
||||
Boolean res = isProtectedSignAndChest(block, player);
|
||||
if (res == null || !res) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isAdjacentChestProtected(Block searchBlock, Player player) {
|
||||
Block side;
|
||||
Boolean res;
|
||||
|
||||
side = searchBlock;
|
||||
res = isProtected(side, player);
|
||||
if (res != null && res == true) return res;
|
||||
|
||||
side = searchBlock.getRelative(-1, 0, 0);
|
||||
res = isProtected(side, player);
|
||||
if (res != null && res == true) return res;
|
||||
|
||||
side = searchBlock.getRelative(1, 0, 0);
|
||||
res = isProtected(side, player);
|
||||
if (res != null && res == true) return res;
|
||||
|
||||
side = searchBlock.getRelative(0, 0, -1);
|
||||
res = isProtected(side, player);
|
||||
if (res != null && res == true) return res;
|
||||
|
||||
side = searchBlock.getRelative(0, 0, 1);
|
||||
res = isProtected(side, player);
|
||||
if (res != null && res == true) return res;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public boolean isChest(Material material) {
|
||||
return isChest(material.getId());
|
||||
}
|
||||
|
||||
public boolean isChest(int type) {
|
||||
return type == BlockID.CHEST
|
||||
|| type == BlockID.DISPENSER
|
||||
|| type == BlockID.FURNACE
|
||||
|| type == BlockID.BURNING_FURNACE;
|
||||
}
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.domains;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
|
||||
public class DefaultDomain implements Domain {
|
||||
private Set<String> groups;
|
||||
private Set<String> players;
|
||||
|
||||
public DefaultDomain() {
|
||||
this.groups = new LinkedHashSet<String>();
|
||||
this.players = new HashSet<String>();
|
||||
}
|
||||
|
||||
public void addPlayer(String name) {
|
||||
players.add(name.toLowerCase());
|
||||
}
|
||||
|
||||
public void addPlayer(LocalPlayer player) {
|
||||
players.add(player.getName().toLowerCase());
|
||||
}
|
||||
|
||||
public void removePlayer(String name) {
|
||||
players.remove(name.toLowerCase());
|
||||
}
|
||||
|
||||
public void removePlayer(LocalPlayer player) {
|
||||
players.remove(player.getName().toLowerCase());
|
||||
}
|
||||
|
||||
public void addGroup(String name) {
|
||||
groups.add(name.toLowerCase());
|
||||
}
|
||||
|
||||
public void removeGroup(String name) {
|
||||
groups.remove(name.toLowerCase());
|
||||
}
|
||||
|
||||
public Set<String> getGroups() {
|
||||
return groups;
|
||||
}
|
||||
|
||||
public Set<String> getPlayers() {
|
||||
return players;
|
||||
}
|
||||
|
||||
public boolean contains(LocalPlayer player) {
|
||||
if (players.contains(player.getName().toLowerCase())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (String group : groups) {
|
||||
if (player.hasGroup(group)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return groups.size() + players.size();
|
||||
}
|
||||
|
||||
public String toPlayersString() {
|
||||
StringBuilder str = new StringBuilder();
|
||||
List<String> output = new ArrayList<String>(players);
|
||||
Collections.sort(output, String.CASE_INSENSITIVE_ORDER);
|
||||
for (Iterator<String> it = output.iterator(); it.hasNext();) {
|
||||
str.append(it.next());
|
||||
if (it.hasNext()) {
|
||||
str.append(", ");
|
||||
}
|
||||
}
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
public String toGroupsString() {
|
||||
StringBuilder str = new StringBuilder();
|
||||
for (Iterator<String> it = groups.iterator(); it.hasNext(); ) {
|
||||
str.append("*");
|
||||
str.append(it.next());
|
||||
if (it.hasNext()) {
|
||||
str.append(", ");
|
||||
}
|
||||
}
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
public String toUserFriendlyString() {
|
||||
StringBuilder str = new StringBuilder();
|
||||
if (players.size() > 0) {
|
||||
str.append(toPlayersString());
|
||||
}
|
||||
|
||||
if (groups.size() > 0) {
|
||||
if (str.length() > 0) {
|
||||
str.append("; ");
|
||||
}
|
||||
|
||||
str.append(toGroupsString());
|
||||
}
|
||||
|
||||
return str.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package com.sk89q.worldguard.domains;
|
||||
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
|
||||
public interface Domain {
|
||||
/**
|
||||
* Returns true if a domain contains a player.
|
||||
*
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
public boolean contains(LocalPlayer player);
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.domains;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
|
||||
public class DomainCollection implements Domain {
|
||||
private Set<Domain> domains;
|
||||
|
||||
public DomainCollection() {
|
||||
domains = new LinkedHashSet<Domain>();
|
||||
}
|
||||
|
||||
public void add(Domain domain) {
|
||||
domains.add(domain);
|
||||
}
|
||||
|
||||
public void remove(Domain domain) {
|
||||
domains.remove(domain);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return domains.size();
|
||||
}
|
||||
|
||||
public boolean contains(LocalPlayer player) {
|
||||
for (Domain domain : domains) {
|
||||
if (domain.contains(player)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.domains;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
|
||||
public class GroupDomain implements Domain {
|
||||
private Set<String> groups;
|
||||
|
||||
public GroupDomain() {
|
||||
this.groups = new LinkedHashSet<String>();
|
||||
}
|
||||
|
||||
public GroupDomain(String[] groups) {
|
||||
this.groups = new LinkedHashSet<String>(Arrays.asList(groups));
|
||||
}
|
||||
|
||||
public void addGroup(String name) {
|
||||
groups.add(name);
|
||||
}
|
||||
|
||||
public boolean contains(LocalPlayer player) {
|
||||
for (String group : groups) {
|
||||
if (player.hasGroup(group)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return groups.size();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.domains;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
|
||||
public class PlayerDomain implements Domain {
|
||||
private Set<String> players;
|
||||
|
||||
public PlayerDomain() {
|
||||
this.players = new HashSet<String>();
|
||||
}
|
||||
|
||||
public PlayerDomain(String[] players) {
|
||||
this.players = new HashSet<String>();
|
||||
|
||||
for (String name : players) {
|
||||
this.players.add(name.toLowerCase());
|
||||
}
|
||||
}
|
||||
|
||||
public void addPlayer(String name) {
|
||||
players.add(name.toLowerCase());
|
||||
}
|
||||
|
||||
public boolean contains(LocalPlayer player) {
|
||||
return players.contains(player.getName().toLowerCase());
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return players.size();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,395 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.sk89q.worldguard.protection;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.protection.flags.DefaultFlag;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.flags.RegionGroupFlag;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag.State;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
|
||||
/**
|
||||
* Represents a set of regions for a particular point or area and the rules
|
||||
* that are represented by that set. An instance of this can be used to
|
||||
* query the value of a flag or check if a player can build in the respective
|
||||
* region or point. This object contains the list of applicable regions and so
|
||||
* the expensive search of regions that are in the desired area has already
|
||||
* been completed.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class ApplicableRegionSet implements Iterable<ProtectedRegion> {
|
||||
|
||||
private Collection<ProtectedRegion> applicable;
|
||||
private ProtectedRegion globalRegion;
|
||||
|
||||
/**
|
||||
* Construct the object.
|
||||
*
|
||||
* @param applicable
|
||||
* @param globalRegion
|
||||
*/
|
||||
public ApplicableRegionSet(Collection<ProtectedRegion> applicable,
|
||||
ProtectedRegion globalRegion) {
|
||||
this.applicable = applicable;
|
||||
this.globalRegion = globalRegion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a player can build in an area.
|
||||
*
|
||||
* @param player
|
||||
* @return build ability
|
||||
*/
|
||||
public boolean canBuild(LocalPlayer player) {
|
||||
return internalGetState(DefaultFlag.BUILD, player, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a player can use buttons and such in an area.
|
||||
*
|
||||
* @param player
|
||||
* @return able to use items
|
||||
*/
|
||||
public boolean canUse(LocalPlayer player) {
|
||||
return !allows(DefaultFlag.USE, player)
|
||||
&& !canBuild(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the state of a state flag. This cannot be used for the build flag.
|
||||
*
|
||||
* @param flag flag to check
|
||||
* @return whether it is allowed
|
||||
* @throws IllegalArgumentException if the build flag is given
|
||||
*/
|
||||
public boolean allows(StateFlag flag) {
|
||||
if (flag == DefaultFlag.BUILD) {
|
||||
throw new IllegalArgumentException("Can't use build flag with allows()");
|
||||
}
|
||||
return internalGetState(flag, null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the state of a state flag. This cannot be used for the build flag.
|
||||
*
|
||||
* @param flag flag to check
|
||||
* @param player player (used by some flags)
|
||||
* @return whether the state is allows for it
|
||||
* @throws IllegalArgumentException if the build flag is given
|
||||
*/
|
||||
public boolean allows(StateFlag flag, LocalPlayer player) {
|
||||
if (flag == DefaultFlag.BUILD) {
|
||||
throw new IllegalArgumentException("Can't use build flag with allows()");
|
||||
}
|
||||
return internalGetState(flag, null, flag.getGroupFlag(), player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether a player is an owner of all regions in this set.
|
||||
*
|
||||
* @param player player
|
||||
* @return whether the player is an owner of all regions
|
||||
*/
|
||||
public boolean isOwnerOfAll(LocalPlayer player) {
|
||||
for (ProtectedRegion region : applicable) {
|
||||
if (!region.isOwner(player)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether a player is an owner or member of all regions in
|
||||
* this set.
|
||||
*
|
||||
* @param player player
|
||||
* @return whether the player is a member of all regions
|
||||
*/
|
||||
public boolean isMemberOfAll(LocalPlayer player) {
|
||||
for (ProtectedRegion region : applicable) {
|
||||
if (!region.isMember(player)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a flag is permitted.
|
||||
*
|
||||
* @param flag flag to check
|
||||
* @param player null to not check owners and members
|
||||
* @param groupFlag group flag to check
|
||||
* @param groupPlayer player to use for the group flag check
|
||||
* @return
|
||||
*/
|
||||
private boolean internalGetState(StateFlag flag, LocalPlayer player,
|
||||
RegionGroupFlag groupFlag,
|
||||
LocalPlayer groupPlayer) {
|
||||
boolean found = false;
|
||||
boolean hasFlagDefined = false;
|
||||
boolean allowed = false; // Used for ALLOW override
|
||||
boolean def = flag.getDefault();
|
||||
|
||||
// Handle defaults
|
||||
if (globalRegion != null) {
|
||||
State globalState = globalRegion.getFlag(flag);
|
||||
|
||||
// The global region has this flag set
|
||||
if (globalState != null) {
|
||||
// Build flag is very special
|
||||
if (player != null && globalRegion.hasMembersOrOwners()) {
|
||||
def = globalRegion.isMember(player) && (globalState == State.ALLOW);
|
||||
} else {
|
||||
def = (globalState == State.ALLOW);
|
||||
}
|
||||
} else {
|
||||
// Build flag is very special
|
||||
if (player != null && globalRegion.hasMembersOrOwners()) {
|
||||
def = globalRegion.isMember(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The player argument is used if and only if the flag is the build
|
||||
// flag -- in which case, if there are any regions in this area, we
|
||||
// default to FALSE, otherwise true if there are no defined regions.
|
||||
// However, other flags are different -- if there are regions defined,
|
||||
// we default to the global region value.
|
||||
if (player == null) {
|
||||
allowed = def;
|
||||
}
|
||||
|
||||
int lastPriority = Integer.MIN_VALUE;
|
||||
|
||||
// The algorithm is as follows:
|
||||
// While iterating through the list of regions, if an entry disallows
|
||||
// the flag, then put it into the needsClear set. If an entry allows
|
||||
// the flag and it has a parent, then its parent is put into hasCleared.
|
||||
// In the situation that the child is reached before the parent, upon
|
||||
// the parent being reached, even if the parent disallows, because the
|
||||
// parent will be in hasCleared, permission will be allowed. In the
|
||||
// other case, where the parent is reached first, if it does not allow
|
||||
// permissions, it will be placed into needsClear. If a child of
|
||||
// the parent is reached later, the parent will be removed from
|
||||
// needsClear. At the end, if needsClear is not empty, that means that
|
||||
// permission should not be given. If a parent has multiple children
|
||||
// and one child does not allow permissions, then it will be placed into
|
||||
// needsClear just like as if was a parent.
|
||||
|
||||
Set<ProtectedRegion> needsClear = new HashSet<ProtectedRegion>();
|
||||
Set<ProtectedRegion> hasCleared = new HashSet<ProtectedRegion>();
|
||||
|
||||
Iterator<ProtectedRegion> it = applicable.iterator();
|
||||
|
||||
while (it.hasNext()) {
|
||||
ProtectedRegion region = it.next();
|
||||
|
||||
// Ignore lower priority regions
|
||||
if (hasFlagDefined && region.getPriority() < lastPriority) {
|
||||
break;
|
||||
}
|
||||
|
||||
lastPriority = region.getPriority();
|
||||
|
||||
// Ignore non-build regions
|
||||
if (player != null
|
||||
&& region.getFlag(DefaultFlag.PASSTHROUGH) == State.ALLOW) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check group permissions
|
||||
if (groupPlayer != null && groupFlag != null) {
|
||||
RegionGroupFlag.RegionGroup group = region.getFlag(groupFlag);
|
||||
if (group == null) {
|
||||
group = groupFlag.getDefault();
|
||||
}
|
||||
if (!RegionGroupFlag.isMember(region, group, groupPlayer)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
State v = region.getFlag(flag);
|
||||
|
||||
// Allow DENY to override everything
|
||||
if (v == State.DENY) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Forget about regions that allow it, although make sure the
|
||||
// default state is now to allow
|
||||
if (v == State.ALLOW) {
|
||||
allowed = true;
|
||||
found = true;
|
||||
hasFlagDefined = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// For the build flag, the flags are conditional and are based
|
||||
// on membership, so we have to check for parent-child
|
||||
// relationships
|
||||
if (player != null) {
|
||||
hasFlagDefined = true;
|
||||
|
||||
if (hasCleared.contains(region)) {
|
||||
// Already cleared, so do nothing
|
||||
} else {
|
||||
if (!region.isMember(player)) {
|
||||
needsClear.add(region);
|
||||
} else {
|
||||
// Need to clear all parents
|
||||
clearParents(needsClear, hasCleared, region);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
found = true;
|
||||
}
|
||||
|
||||
return found == false ? def :
|
||||
(allowed || (player != null && needsClear.size() == 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear a region's parents for isFlagAllowed().
|
||||
*
|
||||
* @param needsClear
|
||||
* @param hasCleared
|
||||
* @param region
|
||||
*/
|
||||
private void clearParents(Set<ProtectedRegion> needsClear,
|
||||
Set<ProtectedRegion> hasCleared, ProtectedRegion region) {
|
||||
ProtectedRegion parent = region.getParent();
|
||||
|
||||
while (parent != null) {
|
||||
if (!needsClear.remove(parent)) {
|
||||
hasCleared.add(parent);
|
||||
}
|
||||
|
||||
parent = parent.getParent();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of a flag. Do not use this for state flags
|
||||
* (use {@link #allows(StateFlag, LocalPlayer)} for that).
|
||||
*
|
||||
* @param flag flag to check
|
||||
* @return value of the flag
|
||||
* @throws IllegalArgumentException if a StateFlag is given
|
||||
*/
|
||||
public <T extends Flag<V>, V> V getFlag(T flag) {
|
||||
/*
|
||||
if (flag instanceof StateFlag) {
|
||||
throw new IllegalArgumentException("Cannot use StateFlag with getFlag()");
|
||||
}
|
||||
*/
|
||||
|
||||
int lastPriority = 0;
|
||||
boolean found = false;
|
||||
|
||||
Map<ProtectedRegion, V> needsClear = new HashMap<ProtectedRegion, V>();
|
||||
Set<ProtectedRegion> hasCleared = new HashSet<ProtectedRegion>();
|
||||
|
||||
Iterator<ProtectedRegion> it = applicable.iterator();
|
||||
|
||||
while (it.hasNext()) {
|
||||
ProtectedRegion region = it.next();
|
||||
|
||||
// Ignore lower priority regions
|
||||
if (found && region.getPriority() < lastPriority) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (hasCleared.contains(region)) {
|
||||
// Already cleared, so do nothing
|
||||
} else if (region.getFlag(flag) != null){
|
||||
clearParents(needsClear, hasCleared, region);
|
||||
|
||||
needsClear.put(region, region.getFlag(flag));
|
||||
|
||||
found = true;
|
||||
}
|
||||
|
||||
lastPriority = region.getPriority();
|
||||
}
|
||||
|
||||
try {
|
||||
return needsClear.values().iterator().next();
|
||||
} catch (NoSuchElementException e) {
|
||||
if (globalRegion != null) {
|
||||
V gFlag = globalRegion.getFlag(flag);
|
||||
if (gFlag != null) return gFlag;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear a region's parents for getFlag().
|
||||
*
|
||||
* @param needsClear
|
||||
* @param hasCleared
|
||||
* @param region
|
||||
*/
|
||||
private void clearParents(Map<ProtectedRegion, ?> needsClear,
|
||||
Set<ProtectedRegion> hasCleared, ProtectedRegion region) {
|
||||
ProtectedRegion parent = region.getParent();
|
||||
|
||||
while (parent != null) {
|
||||
if (needsClear.remove(parent) == null) {
|
||||
hasCleared.add(parent);
|
||||
}
|
||||
|
||||
parent = parent.getParent();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of regions that are included.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int size() {
|
||||
return applicable.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an iterator of affected regions.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Iterator<ProtectedRegion> iterator() {
|
||||
return applicable.iterator();
|
||||
}
|
||||
}
|
||||
@@ -1,317 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.sk89q.worldguard.protection;
|
||||
|
||||
import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.bukkit.BukkitUtil;
|
||||
import com.sk89q.worldguard.bukkit.ConfigurationManager;
|
||||
import com.sk89q.worldguard.bukkit.WorldConfiguration;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.protection.databases.ProtectionDatabaseException;
|
||||
import com.sk89q.worldguard.protection.databases.ProtectionDatabase;
|
||||
import com.sk89q.worldguard.protection.databases.YAMLDatabase;
|
||||
import com.sk89q.worldguard.protection.databases.MySQLDatabase;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
import com.sk89q.worldguard.protection.managers.FlatRegionManager;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
|
||||
/**
|
||||
* This class keeps track of region information for every world. It loads
|
||||
* world region information as needed.
|
||||
*
|
||||
* @author sk89q
|
||||
* @author Redecouverte
|
||||
*/
|
||||
public class GlobalRegionManager {
|
||||
|
||||
/**
|
||||
* Reference to the plugin.
|
||||
*/
|
||||
private WorldGuardPlugin plugin;
|
||||
|
||||
/**
|
||||
* Reference to the global configuration.
|
||||
*/
|
||||
private ConfigurationManager config;
|
||||
|
||||
/**
|
||||
* Map of managers per-world.
|
||||
*/
|
||||
private HashMap<String, RegionManager> managers;
|
||||
|
||||
/**
|
||||
* Stores the list of modification dates for the world files. This allows
|
||||
* WorldGuard to reload files as needed.
|
||||
*/
|
||||
private HashMap<String, Long> lastModified;
|
||||
|
||||
/**
|
||||
* Construct the object.
|
||||
*
|
||||
* @param plugin
|
||||
*/
|
||||
public GlobalRegionManager(WorldGuardPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
config = plugin.getGlobalStateManager();
|
||||
managers = new HashMap<String, RegionManager>();
|
||||
lastModified = new HashMap<String, Long>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unload region information.
|
||||
*/
|
||||
public void unload() {
|
||||
managers.clear();
|
||||
lastModified.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path for a world's regions file.
|
||||
*
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
protected File getPath(String name) {
|
||||
return new File(plugin.getDataFolder(),
|
||||
"worlds" + File.separator + name + File.separator + "regions.yml");
|
||||
}
|
||||
|
||||
/**
|
||||
* Unload region information for a world.
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
public void unload(String name) {
|
||||
RegionManager manager = managers.get(name);
|
||||
|
||||
if (manager != null) {
|
||||
managers.remove(name);
|
||||
lastModified.remove(name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unload all region information.
|
||||
*/
|
||||
public void unloadAll() {
|
||||
managers.clear();
|
||||
lastModified.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load region information for a world.
|
||||
*
|
||||
* @param world
|
||||
* @return
|
||||
*/
|
||||
public RegionManager load(World world) {
|
||||
String name = world.getName();
|
||||
ProtectionDatabase database = null;
|
||||
File file = null;
|
||||
|
||||
try {
|
||||
if (!config.useSqlDatabase) {
|
||||
file = getPath(name);
|
||||
database = new YAMLDatabase(file, plugin.getLogger());
|
||||
|
||||
// Store the last modification date so we can track changes
|
||||
lastModified.put(name, file.lastModified());
|
||||
} else {
|
||||
database = new MySQLDatabase(config, name, plugin.getLogger());
|
||||
}
|
||||
|
||||
// Create a manager
|
||||
RegionManager manager = new FlatRegionManager(database);
|
||||
|
||||
managers.put(name, manager);
|
||||
manager.load();
|
||||
|
||||
plugin.getLogger().info(manager.getRegions().size()
|
||||
+ " regions loaded for '" + name + "'");
|
||||
|
||||
return manager;
|
||||
} catch (ProtectionDatabaseException e) {
|
||||
String logStr = "Failed to load regions from ";
|
||||
if (config.useSqlDatabase) {
|
||||
logStr += "SQL Database <" + config.sqlDsn + "> ";
|
||||
} else {
|
||||
logStr += "file \"" + file + "\" ";
|
||||
}
|
||||
|
||||
plugin.getLogger().info(logStr + " : " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
plugin.getLogger().info("Error loading regions for world \""
|
||||
+ name + "\": " + e.toString() + "\n\t" + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// @TODO: THIS CREATES PROBLEMS!!one!!1!!eleven!!1!!!
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Preloads region managers for all worlds.
|
||||
*/
|
||||
public void preload() {
|
||||
// Load regions
|
||||
for (World world : plugin.getServer().getWorlds()) {
|
||||
load(world);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads the region information from file when region databases
|
||||
* have changed.
|
||||
*/
|
||||
public void reloadChanged() {
|
||||
if (config.useSqlDatabase) return;
|
||||
|
||||
for (String name : managers.keySet()) {
|
||||
File file = getPath(name);
|
||||
|
||||
Long oldDate = lastModified.get(name);
|
||||
|
||||
if (oldDate == null) {
|
||||
oldDate = 0L;
|
||||
}
|
||||
|
||||
try {
|
||||
if (file.lastModified() > oldDate) {
|
||||
World world = plugin.getServer().getWorld(name);
|
||||
|
||||
if (world != null) {
|
||||
load(world);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the region manager for a particular world.
|
||||
*
|
||||
* @param world
|
||||
* @return
|
||||
*/
|
||||
public RegionManager get(World world) {
|
||||
RegionManager manager = managers.get(world.getName());
|
||||
|
||||
if (manager == null) {
|
||||
manager = load(world);
|
||||
}
|
||||
|
||||
return manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the player can bypass.
|
||||
*
|
||||
* @param player
|
||||
* @param world
|
||||
* @return
|
||||
*/
|
||||
public boolean hasBypass(LocalPlayer player, World world) {
|
||||
return player.hasPermission("worldguard.region.bypass."
|
||||
+ world.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the player can bypass.
|
||||
*
|
||||
* @param player
|
||||
* @param world
|
||||
* @return
|
||||
*/
|
||||
public boolean hasBypass(Player player, World world) {
|
||||
return plugin.hasPermission(player, "worldguard.region.bypass."
|
||||
+ world.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a player has permission to build at a block.
|
||||
*
|
||||
* @param player
|
||||
* @param block
|
||||
* @return
|
||||
*/
|
||||
public boolean canBuild(Player player, Block block) {
|
||||
return canBuild(player, block.getLocation());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a player has permission to build at a location.
|
||||
*
|
||||
* @param player
|
||||
* @param loc
|
||||
* @return
|
||||
*/
|
||||
public boolean canBuild(Player player, Location loc) {
|
||||
World world = loc.getWorld();
|
||||
WorldConfiguration worldConfig = config.get(world);
|
||||
|
||||
if (!worldConfig.useRegions) {
|
||||
return true;
|
||||
}
|
||||
|
||||
LocalPlayer localPlayer = plugin.wrapPlayer(player);
|
||||
|
||||
if (!hasBypass(player, world)) {
|
||||
RegionManager mgr = get(world);
|
||||
|
||||
if (!mgr.getApplicableRegions(BukkitUtil.toVector(loc))
|
||||
.canBuild(localPlayer)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see whether a flag is allowed.
|
||||
*
|
||||
* @param flag
|
||||
* @param loc
|
||||
* @return
|
||||
*/
|
||||
public boolean allows(StateFlag flag, Location loc) {
|
||||
World world = loc.getWorld();
|
||||
WorldConfiguration worldConfig = config.get(world);
|
||||
|
||||
if (!worldConfig.useRegions) {
|
||||
return true;
|
||||
}
|
||||
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
|
||||
return mgr.getApplicableRegions(toVector(loc)).allows(flag);
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.protection;
|
||||
|
||||
public class UnsupportedIntersectionException extends Exception {
|
||||
private static final long serialVersionUID = 6423189392345575148L;
|
||||
}
|
||||
-46
@@ -1,46 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.protection.databases;
|
||||
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
|
||||
public abstract class AbstractProtectionDatabase implements ProtectionDatabase {
|
||||
|
||||
/**
|
||||
* Load the list of regions into a region manager.
|
||||
*
|
||||
* @throws ProtectionDatabaseException
|
||||
*/
|
||||
public void load(RegionManager manager) throws ProtectionDatabaseException {
|
||||
load();
|
||||
manager.setRegions(getRegions());
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the list of regions from a region manager.
|
||||
*
|
||||
* @throws ProtectionDatabaseException
|
||||
*/
|
||||
public void save(RegionManager manager) throws ProtectionDatabaseException {
|
||||
setRegions(manager.getRegions());
|
||||
save();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,352 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.protection.databases;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import au.com.bytecode.opencsv.CSVReader;
|
||||
|
||||
import com.sk89q.worldedit.BlockVector;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.domains.DefaultDomain;
|
||||
import com.sk89q.worldguard.protection.flags.DefaultFlag;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag.State;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion.CircularInheritanceException;
|
||||
import com.sk89q.worldguard.util.ArrayReader;
|
||||
|
||||
/**
|
||||
* Represents a protected area database that uses CSV files.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class CSVDatabase extends AbstractProtectionDatabase {
|
||||
private final Logger logger;
|
||||
|
||||
/**
|
||||
* References the CSV file.
|
||||
*/
|
||||
private final File file;
|
||||
/**
|
||||
* Holds the list of regions.
|
||||
*/
|
||||
private Map<String,ProtectedRegion> regions;
|
||||
|
||||
/**
|
||||
* Construct the database with a path to a file. No file is read or
|
||||
* written at this time.
|
||||
*
|
||||
* @param file
|
||||
*/
|
||||
public CSVDatabase(File file, Logger logger) {
|
||||
this.file = file;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the database.
|
||||
*/
|
||||
public void save() throws ProtectionDatabaseException {
|
||||
throw new UnsupportedOperationException("CSV format is no longer implemented");
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the database from file.
|
||||
*/
|
||||
public void load() throws ProtectionDatabaseException {
|
||||
Map<String,ProtectedRegion> regions =
|
||||
new HashMap<String,ProtectedRegion>();
|
||||
Map<ProtectedRegion,String> parentSets =
|
||||
new LinkedHashMap<ProtectedRegion, String>();
|
||||
|
||||
CSVReader reader = null;
|
||||
try {
|
||||
reader = new CSVReader(new FileReader(file));
|
||||
|
||||
String[] line;
|
||||
|
||||
while ((line = reader.readNext()) != null) {
|
||||
if (line.length < 2) {
|
||||
logger.warning("Invalid region definition: " + line);
|
||||
continue;
|
||||
}
|
||||
|
||||
String id = line[0].toLowerCase().replace(".", "");
|
||||
String type = line[1];
|
||||
ArrayReader<String> entries = new ArrayReader<String>(line);
|
||||
|
||||
if (type.equalsIgnoreCase("cuboid")) {
|
||||
if (line.length < 8) {
|
||||
logger.warning("Invalid region definition: " + line);
|
||||
continue;
|
||||
}
|
||||
|
||||
Vector pt1 = new Vector(
|
||||
Integer.parseInt(line[2]),
|
||||
Integer.parseInt(line[3]),
|
||||
Integer.parseInt(line[4]));
|
||||
Vector pt2 = new Vector(
|
||||
Integer.parseInt(line[5]),
|
||||
Integer.parseInt(line[6]),
|
||||
Integer.parseInt(line[7]));
|
||||
|
||||
BlockVector min = Vector.getMinimum(pt1, pt2).toBlockVector();
|
||||
BlockVector max = Vector.getMaximum(pt1, pt2).toBlockVector();
|
||||
|
||||
int priority = entries.get(8) == null ? 0 : Integer.parseInt(entries.get(8));
|
||||
String ownersData = entries.get(9);
|
||||
String flagsData = entries.get(10);
|
||||
//String enterMessage = nullEmptyString(entries.get(11));
|
||||
|
||||
ProtectedRegion region = new ProtectedCuboidRegion(id, min, max);
|
||||
region.setPriority(priority);
|
||||
parseFlags(region, flagsData);
|
||||
region.setOwners(this.parseDomains(ownersData));
|
||||
regions.put(id, region);
|
||||
} else if (type.equalsIgnoreCase("cuboid.2")) {
|
||||
Vector pt1 = new Vector(
|
||||
Integer.parseInt(line[2]),
|
||||
Integer.parseInt(line[3]),
|
||||
Integer.parseInt(line[4]));
|
||||
Vector pt2 = new Vector(
|
||||
Integer.parseInt(line[5]),
|
||||
Integer.parseInt(line[6]),
|
||||
Integer.parseInt(line[7]));
|
||||
|
||||
BlockVector min = Vector.getMinimum(pt1, pt2).toBlockVector();
|
||||
BlockVector max = Vector.getMaximum(pt1, pt2).toBlockVector();
|
||||
|
||||
int priority = entries.get(8) == null ? 0 : Integer.parseInt(entries.get(8));
|
||||
String parentId = entries.get(9);
|
||||
String ownersData = entries.get(10);
|
||||
String membersData = entries.get(11);
|
||||
String flagsData = entries.get(12);
|
||||
//String enterMessage = nullEmptyString(entries.get(13));
|
||||
//String leaveMessage = nullEmptyString(entries.get(14));
|
||||
|
||||
ProtectedRegion region = new ProtectedCuboidRegion(id, min, max);
|
||||
region.setPriority(priority);
|
||||
parseFlags(region, flagsData);
|
||||
region.setOwners(this.parseDomains(ownersData));
|
||||
region.setMembers(this.parseDomains(membersData));
|
||||
regions.put(id, region);
|
||||
|
||||
// Link children to parents later
|
||||
if (parentId.length() > 0) {
|
||||
parentSets.put(region, parentId);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new ProtectionDatabaseException(e);
|
||||
} finally {
|
||||
try {
|
||||
reader.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
for (Map.Entry<ProtectedRegion, String> entry : parentSets.entrySet()) {
|
||||
ProtectedRegion parent = regions.get(entry.getValue());
|
||||
if (parent != null) {
|
||||
try {
|
||||
entry.getKey().setParent(parent);
|
||||
} catch (CircularInheritanceException e) {
|
||||
logger.warning("Circular inheritance detect with '"
|
||||
+ entry.getValue() + "' detected as a parent");
|
||||
}
|
||||
} else {
|
||||
logger.warning("Unknown region parent: " + entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
this.regions = regions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to parse the specified domain in the CSV file.
|
||||
*
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
private DefaultDomain parseDomains(String data) {
|
||||
if (data == null) {
|
||||
return new DefaultDomain();
|
||||
}
|
||||
|
||||
DefaultDomain domain = new DefaultDomain();
|
||||
Pattern pattern = Pattern.compile("^([A-Za-z]):(.*)$");
|
||||
|
||||
String[] parts = data.split(",");
|
||||
|
||||
for (String part : parts) {
|
||||
if (part.trim().length() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Matcher matcher = pattern.matcher(part);
|
||||
|
||||
if (!matcher.matches()) {
|
||||
logger.warning("Invalid owner specification: " + part);
|
||||
continue;
|
||||
}
|
||||
|
||||
String type = matcher.group(1);
|
||||
String id = matcher.group(2);
|
||||
|
||||
if (type.equals("u")) {
|
||||
domain.addPlayer(id);
|
||||
} else if (type.equals("g")) {
|
||||
domain.addGroup(id);
|
||||
} else {
|
||||
logger.warning("Unknown owner specification: " + type);
|
||||
}
|
||||
}
|
||||
|
||||
return domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to parse the list of flags.
|
||||
*
|
||||
* @param data
|
||||
*/
|
||||
private void parseFlags(ProtectedRegion region, String data) {
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
State curState = State.ALLOW;
|
||||
|
||||
for (int i = 0; i < data.length(); i++) {
|
||||
char k = data.charAt(i);
|
||||
if (k == '+') {
|
||||
curState = State.ALLOW;
|
||||
} else if (k == '-') {
|
||||
curState = State.DENY;
|
||||
} else {
|
||||
String flagStr;
|
||||
if (k == '_') {
|
||||
if (i == data.length() - 1) {
|
||||
logger.warning("_ read ahead fail");
|
||||
break;
|
||||
}
|
||||
flagStr = "_" + data.charAt(i + 1);
|
||||
i++;
|
||||
|
||||
logger.warning("_? custom flags are no longer supported");
|
||||
continue;
|
||||
} else {
|
||||
flagStr = String.valueOf(k);
|
||||
}
|
||||
|
||||
StateFlag flag = DefaultFlag.getLegacyFlag(flagStr);
|
||||
if (flag != null) {
|
||||
region.setFlag(flag, curState);
|
||||
} else {
|
||||
logger.warning("Legacy flag '" + flagStr + "' is unsupported");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to write the list of domains.
|
||||
*
|
||||
* @param domain
|
||||
* @return
|
||||
*/
|
||||
/* private String writeDomains(DefaultDomain domain) {
|
||||
StringBuilder str = new StringBuilder();
|
||||
|
||||
for (String player : domain.getPlayers()) {
|
||||
str.append("u:" + player + ",");
|
||||
}
|
||||
|
||||
for (String group : domain.getGroups()) {
|
||||
str.append("g:" + group + ",");
|
||||
}
|
||||
|
||||
return str.length() > 0 ?
|
||||
str.toString().substring(0, str.length() - 1) : "";
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Helper method to prepend '+' or '-' in front of a flag according
|
||||
* to the flag's state.
|
||||
*
|
||||
* @param state
|
||||
* @param flag
|
||||
* @return
|
||||
*/
|
||||
/*
|
||||
private String writeFlag(State state, String flag) {
|
||||
if (state == State.ALLOW) {
|
||||
return "+" + flag;
|
||||
} else if (state == State.DENY) {
|
||||
return "-" + flag;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns a null if a string is null or empty.
|
||||
*
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
protected String nullEmptyString(String str) {
|
||||
if (str == null) {
|
||||
return null;
|
||||
} else if (str.length() == 0) {
|
||||
return null;
|
||||
} else {
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of protected regions.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Map<String,ProtectedRegion> getRegions() {
|
||||
return regions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of protected regions.
|
||||
*/
|
||||
public void setRegions(Map<String,ProtectedRegion> regions) {
|
||||
this.regions = regions;
|
||||
}
|
||||
}
|
||||
@@ -1,969 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* MySQL WordGuard Region Database
|
||||
* Copyright (C) 2011 Nicholas Steicke <http://narthollis.net>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.protection.databases;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.sql.PreparedStatement;
|
||||
|
||||
import com.sk89q.worldedit.BlockVector;
|
||||
import com.sk89q.worldedit.BlockVector2D;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.bukkit.ConfigurationManager;
|
||||
import com.sk89q.worldguard.domains.DefaultDomain;
|
||||
import com.sk89q.worldguard.protection.flags.DefaultFlag;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.regions.GlobalProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion.CircularInheritanceException;
|
||||
|
||||
public class MySQLDatabase extends AbstractProtectionDatabase {
|
||||
private final Logger logger;
|
||||
|
||||
private Map<String, ProtectedRegion> regions;
|
||||
|
||||
private Map<String, ProtectedRegion> cuboidRegions;
|
||||
private Map<String, ProtectedRegion> poly2dRegions;
|
||||
private Map<String, ProtectedRegion> globalRegions;
|
||||
private Map<ProtectedRegion, String> parentSets;
|
||||
|
||||
private final ConfigurationManager config;
|
||||
|
||||
private Connection conn;
|
||||
private String world;
|
||||
private int worldDbId = -1; // The database will never have an id of -1;
|
||||
|
||||
public MySQLDatabase(ConfigurationManager config, String world, Logger logger) throws ProtectionDatabaseException {
|
||||
this.config = config;
|
||||
this.world = world;
|
||||
this.logger = logger;
|
||||
|
||||
try {
|
||||
connect();
|
||||
|
||||
PreparedStatement worldStmt = conn.prepareStatement(
|
||||
"SELECT `id` FROM " +
|
||||
"`world` " +
|
||||
"WHERE `name` = ? LIMIT 0,1"
|
||||
);
|
||||
|
||||
worldStmt.setString(1, this.world);
|
||||
ResultSet worldResult = worldStmt.executeQuery();
|
||||
|
||||
if (worldResult.first()) {
|
||||
this.worldDbId = worldResult.getInt("id");
|
||||
} else {
|
||||
PreparedStatement insertWorldStatement = this.conn.prepareStatement(
|
||||
"INSERT INTO " +
|
||||
"`world` " +
|
||||
"(`id`, `name`) VALUES (null, ?)",
|
||||
Statement.RETURN_GENERATED_KEYS
|
||||
);
|
||||
|
||||
insertWorldStatement.setString(1, world);
|
||||
insertWorldStatement.execute();
|
||||
ResultSet generatedKeys = insertWorldStatement.getGeneratedKeys();
|
||||
if (generatedKeys.first()) {
|
||||
this.worldDbId = generatedKeys.getInt(1);
|
||||
}
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
logger.log(Level.SEVERE, ex.getMessage(), ex);
|
||||
// We havn't connected to the databases, or there was an error
|
||||
// initialising the world record, so there is no point continuing
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.worldDbId <= 0) {
|
||||
logger.log(Level.SEVERE, "Could not find or create the world");
|
||||
// There was an error initialising the world record, so there is
|
||||
// no point continuing
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void connect() throws SQLException {
|
||||
if (conn == null || conn.isClosed()) {
|
||||
conn = DriverManager.getConnection(config.sqlDsn, config.sqlUsername, config.sqlPassword);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadFlags(ProtectedRegion region) {
|
||||
// @TODO: Iterate _ONCE_
|
||||
try {
|
||||
PreparedStatement flagsStatement = this.conn.prepareStatement(
|
||||
"SELECT " +
|
||||
"`region_flag`.`flag`, " +
|
||||
"`region_flag`.`value` " +
|
||||
"FROM `region_flag` " +
|
||||
"WHERE `region_flag`.`region_id` = ? "
|
||||
);
|
||||
|
||||
flagsStatement.setString(1, region.getId().toLowerCase());
|
||||
ResultSet flagsResultSet = flagsStatement.executeQuery();
|
||||
|
||||
Map<String,Object> regionFlags = new HashMap<String,Object>();
|
||||
while (flagsResultSet.next()) {
|
||||
regionFlags.put(
|
||||
flagsResultSet.getString("flag"),
|
||||
flagsResultSet.getObject("value")
|
||||
);
|
||||
}
|
||||
|
||||
// @TODO: Make this better
|
||||
for (Flag<?> flag : DefaultFlag.getFlags()) {
|
||||
Object o = regionFlags.get(flag.getName());
|
||||
if (o != null) {
|
||||
setFlag(region, flag, o);
|
||||
}
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
logger.warning(
|
||||
"Unable to load flags for region "
|
||||
+ region.getId().toLowerCase() + ": " + ex.getMessage()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private <T> void setFlag(ProtectedRegion region, Flag<T> flag, Object rawValue) {
|
||||
T val = flag.unmarshal(rawValue);
|
||||
if (val == null) {
|
||||
logger.warning("Failed to parse flag '" + flag.getName()
|
||||
+ "' with value '" + rawValue.toString() + "'");
|
||||
return;
|
||||
}
|
||||
region.setFlag(flag, val);
|
||||
}
|
||||
|
||||
private void loadOwnersAndMembers(ProtectedRegion region) {
|
||||
DefaultDomain owners = new DefaultDomain();
|
||||
DefaultDomain members = new DefaultDomain();
|
||||
|
||||
try {
|
||||
PreparedStatement usersStatement = this.conn.prepareStatement(
|
||||
"SELECT " +
|
||||
"`user`.`name`, " +
|
||||
"`region_players`.`owner` " +
|
||||
"FROM `region_players` " +
|
||||
"LEFT JOIN `user` ON ( " +
|
||||
"`region_players`.`user_id` = " +
|
||||
"`user`.`id`) " +
|
||||
"WHERE `region_players`.`region_id` = ? "
|
||||
);
|
||||
|
||||
usersStatement.setString(1, region.getId().toLowerCase());
|
||||
ResultSet userSet = usersStatement.executeQuery();
|
||||
while(userSet.next()) {
|
||||
if (userSet.getBoolean("owner")) {
|
||||
owners.addPlayer(userSet.getString("name"));
|
||||
} else {
|
||||
members.addPlayer(userSet.getString("name"));
|
||||
}
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
logger.warning("Unable to load users for region " + region.getId().toLowerCase() + ": " + ex.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
PreparedStatement groupsStatement = this.conn.prepareStatement(
|
||||
"SELECT " +
|
||||
"`group`.`name`, " +
|
||||
"`region_groups`.`owner` " +
|
||||
"FROM `region_groups` " +
|
||||
"LEFT JOIN `group` ON ( " +
|
||||
"`region_groups`.`group_id` = " +
|
||||
"`group`.`id`) " +
|
||||
"WHERE `region_groups`.`region_id` = ? "
|
||||
);
|
||||
|
||||
groupsStatement.setString(1, region.getId().toLowerCase());
|
||||
ResultSet groupSet = groupsStatement.executeQuery();
|
||||
while(groupSet.next()) {
|
||||
if (groupSet.getBoolean("owner")) {
|
||||
owners.addGroup(groupSet.getString("name"));
|
||||
} else {
|
||||
members.addGroup(groupSet.getString("name"));
|
||||
}
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
logger.warning("Unable to load groups for region " + region.getId().toLowerCase() + ": " + ex.getMessage());
|
||||
}
|
||||
|
||||
region.setOwners(owners);
|
||||
region.setMembers(members);
|
||||
}
|
||||
|
||||
private void loadGlobal() {
|
||||
Map<String,ProtectedRegion> regions =
|
||||
new HashMap<String,ProtectedRegion>();
|
||||
|
||||
try {
|
||||
PreparedStatement globalRegionStatement = this.conn.prepareStatement(
|
||||
"SELECT " +
|
||||
"`region`.`id`, " +
|
||||
"`region`.`priority`, " +
|
||||
"`parent`.`id` AS `parent` " +
|
||||
"FROM `region` " +
|
||||
"LEFT JOIN `region` AS `parent` " +
|
||||
"ON (`region`.`parent` = `parent`.`id`) " +
|
||||
"WHERE `region`.`type` = 'global' " +
|
||||
"AND `region`.`world_id` = ? "
|
||||
);
|
||||
|
||||
globalRegionStatement.setInt(1, this.worldDbId);
|
||||
ResultSet globalResultSet = globalRegionStatement.executeQuery();
|
||||
|
||||
while (globalResultSet.next()) {
|
||||
ProtectedRegion region = new GlobalProtectedRegion(globalResultSet.getString("id"));
|
||||
|
||||
region.setPriority(globalResultSet.getInt("priority"));
|
||||
|
||||
this.loadFlags(region);
|
||||
this.loadOwnersAndMembers(region);
|
||||
|
||||
regions.put(globalResultSet.getString("id"), region);
|
||||
|
||||
String parentId = globalResultSet.getString("parent");
|
||||
if (parentId != null) {
|
||||
parentSets.put(region, parentId);
|
||||
}
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
logger.warning("Unable to load regions from sql database: " + ex.getMessage());
|
||||
Throwable t = ex.getCause();
|
||||
while (t != null) {
|
||||
logger.warning("\t\tCause: " + t.getMessage());
|
||||
t = t.getCause();
|
||||
}
|
||||
}
|
||||
|
||||
globalRegions = regions;
|
||||
}
|
||||
|
||||
private void loadCuboid() {
|
||||
Map<String,ProtectedRegion> regions =
|
||||
new HashMap<String,ProtectedRegion>();
|
||||
|
||||
try {
|
||||
PreparedStatement cuboidRegionStatement = this.conn.prepareStatement(
|
||||
"SELECT " +
|
||||
"`region_cuboid`.`min_z`, " +
|
||||
"`region_cuboid`.`min_y`, " +
|
||||
"`region_cuboid`.`min_x`, " +
|
||||
"`region_cuboid`.`max_z`, " +
|
||||
"`region_cuboid`.`max_y`, " +
|
||||
"`region_cuboid`.`max_x`, " +
|
||||
"`region`.`id`, " +
|
||||
"`region`.`priority`, " +
|
||||
"`parent`.`id` AS `parent` " +
|
||||
"FROM `region_cuboid` " +
|
||||
"LEFT JOIN `region` " +
|
||||
"ON (`region_cuboid`.`region_id` = `region`.`id`) " +
|
||||
"LEFT JOIN `region` AS `parent` " +
|
||||
"ON (`region`.`parent` = `parent`.`id`) " +
|
||||
"WHERE `region`.`world_id` = ? "
|
||||
);
|
||||
|
||||
cuboidRegionStatement.setInt(1, this.worldDbId);
|
||||
ResultSet cuboidResultSet = cuboidRegionStatement.executeQuery();
|
||||
|
||||
while (cuboidResultSet.next()) {
|
||||
Vector pt1 = new Vector(
|
||||
cuboidResultSet.getInt("min_x"),
|
||||
cuboidResultSet.getInt("min_y"),
|
||||
cuboidResultSet.getInt("min_z")
|
||||
);
|
||||
Vector pt2 = new Vector(
|
||||
cuboidResultSet.getInt("max_x"),
|
||||
cuboidResultSet.getInt("max_y"),
|
||||
cuboidResultSet.getInt("max_z")
|
||||
);
|
||||
|
||||
BlockVector min = Vector.getMinimum(pt1, pt2).toBlockVector();
|
||||
BlockVector max = Vector.getMaximum(pt1, pt2).toBlockVector();
|
||||
ProtectedRegion region = new ProtectedCuboidRegion(
|
||||
cuboidResultSet.getString("id"),
|
||||
min,
|
||||
max
|
||||
);
|
||||
|
||||
region.setPriority(cuboidResultSet.getInt("priority"));
|
||||
|
||||
this.loadFlags(region);
|
||||
this.loadOwnersAndMembers(region);
|
||||
|
||||
regions.put(cuboidResultSet.getString("id"), region);
|
||||
|
||||
String parentId = cuboidResultSet.getString("parent");
|
||||
if (parentId != null) {
|
||||
parentSets.put(region, parentId);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
logger.warning("Unable to load regions from sql database: " + ex.getMessage());
|
||||
Throwable t = ex.getCause();
|
||||
while (t != null) {
|
||||
logger.warning("\t\tCause: " + t.getMessage());
|
||||
t = t.getCause();
|
||||
}
|
||||
}
|
||||
|
||||
cuboidRegions = regions;
|
||||
}
|
||||
|
||||
private void loadPoly2d() {
|
||||
Map<String,ProtectedRegion> regions =
|
||||
new HashMap<String,ProtectedRegion>();
|
||||
|
||||
try {
|
||||
PreparedStatement poly2dRegionStatement = this.conn.prepareStatement(
|
||||
"SELECT " +
|
||||
"`region_poly2d`.`min_y`, " +
|
||||
"`region_poly2d`.`max_y`, " +
|
||||
"`region`.`id`, " +
|
||||
"`region`.`priority`, " +
|
||||
"`parent`.`id` AS `parent` " +
|
||||
"FROM `region_poly2d` " +
|
||||
"LEFT JOIN `region` " +
|
||||
"ON (`region_poly2d`.`region_id` = `region`.`id`) " +
|
||||
"LEFT JOIN `region` AS `parent` " +
|
||||
"ON (`region`.`parent` = `parent`.`id`) " +
|
||||
"WHERE `region`.`world_id` = ? "
|
||||
);
|
||||
|
||||
poly2dRegionStatement.setInt(1, this.worldDbId);
|
||||
ResultSet poly2dResultSet = poly2dRegionStatement.executeQuery();
|
||||
|
||||
PreparedStatement poly2dVectorStatement = this.conn.prepareStatement(
|
||||
"SELECT " +
|
||||
"`region_poly2d_point`.`x`, " +
|
||||
"`region_poly2d_point`.`z` " +
|
||||
"FROM `region_poly2d_point` " +
|
||||
"WHERE `region_poly2d_point`.`region_id` = ? "
|
||||
);
|
||||
|
||||
while (poly2dResultSet.next()) {
|
||||
String id = poly2dResultSet.getString("id");
|
||||
|
||||
Integer minY = poly2dResultSet.getInt("min_y");
|
||||
Integer maxY = poly2dResultSet.getInt("max_y");
|
||||
List<BlockVector2D> points = new ArrayList<BlockVector2D>();
|
||||
|
||||
poly2dVectorStatement.setString(1, id);
|
||||
ResultSet poly2dVectorResultSet = poly2dVectorStatement.executeQuery();
|
||||
|
||||
while(poly2dVectorResultSet.next()) {
|
||||
points.add(new BlockVector2D(
|
||||
poly2dVectorResultSet.getInt("x"),
|
||||
poly2dVectorResultSet.getInt("z")
|
||||
));
|
||||
}
|
||||
ProtectedRegion region = new ProtectedPolygonalRegion(id, points, minY, maxY);
|
||||
|
||||
region.setPriority(poly2dResultSet.getInt("priority"));
|
||||
|
||||
this.loadFlags(region);
|
||||
this.loadOwnersAndMembers(region);
|
||||
|
||||
regions.put(poly2dResultSet.getString("id"), region);
|
||||
|
||||
String parentId = poly2dResultSet.getString("parent");
|
||||
if (parentId != null) {
|
||||
parentSets.put(region, parentId);
|
||||
}
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
logger.warning("Unable to load regions from sql database: " + ex.getMessage());
|
||||
Throwable t = ex.getCause();
|
||||
while (t != null) {
|
||||
logger.warning("\t\tCause: " + t.getMessage());
|
||||
t = t.getCause();
|
||||
}
|
||||
}
|
||||
|
||||
poly2dRegions = regions;
|
||||
}
|
||||
|
||||
public void load() throws ProtectionDatabaseException {
|
||||
try {
|
||||
connect();
|
||||
} catch (SQLException ex) {
|
||||
throw new ProtectionDatabaseException(ex);
|
||||
}
|
||||
|
||||
parentSets = new HashMap<ProtectedRegion,String>();
|
||||
|
||||
// We load the cuboid regions first, as this is likely to be the
|
||||
// largest dataset. This should save time in regards to the putAll()s
|
||||
this.loadCuboid();
|
||||
Map<String,ProtectedRegion> regions = this.cuboidRegions;
|
||||
this.cuboidRegions = null;
|
||||
|
||||
this.loadPoly2d();
|
||||
regions.putAll(this.poly2dRegions);
|
||||
this.poly2dRegions = null;
|
||||
|
||||
this.loadGlobal();
|
||||
regions.putAll(this.globalRegions);
|
||||
this.globalRegions = null;
|
||||
|
||||
// Relink parents // Taken verbatim from YAMLDatabase
|
||||
for (Map.Entry<ProtectedRegion, String> entry : parentSets.entrySet()) {
|
||||
ProtectedRegion parent = regions.get(entry.getValue());
|
||||
if (parent != null) {
|
||||
try {
|
||||
entry.getKey().setParent(parent);
|
||||
} catch (CircularInheritanceException e) {
|
||||
logger.warning("Circular inheritance detect with '"
|
||||
+ entry.getValue() + "' detected as a parent");
|
||||
}
|
||||
} else {
|
||||
logger.warning("Unknown region parent: " + entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
this.regions = regions;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns the database id for the user
|
||||
* If it doesn't exits it adds the user and returns the id.
|
||||
*/
|
||||
private Map<String,Integer> getUserIds(String... usernames) {
|
||||
Map<String,Integer> users = new HashMap<String,Integer>();
|
||||
|
||||
if (usernames.length < 1) return users;
|
||||
|
||||
try {
|
||||
PreparedStatement findUsersStatement = this.conn.prepareStatement(
|
||||
String.format(
|
||||
"SELECT " +
|
||||
"`user`.`id`, " +
|
||||
"`user`.`name` " +
|
||||
"FROM `user` " +
|
||||
"WHERE `name` IN (%s)",
|
||||
RegionDBUtil.preparePlaceHolders(usernames.length)
|
||||
)
|
||||
);
|
||||
|
||||
RegionDBUtil.setValues(findUsersStatement, usernames);
|
||||
|
||||
ResultSet findUsersResults = findUsersStatement.executeQuery();
|
||||
|
||||
while(findUsersResults.next()) {
|
||||
users.put(findUsersResults.getString("name"), findUsersResults.getInt("id"));
|
||||
}
|
||||
|
||||
PreparedStatement insertUserStatement = this.conn.prepareStatement(
|
||||
"INSERT INTO " +
|
||||
"`user` ( " +
|
||||
"`id`, " +
|
||||
"`name`" +
|
||||
") VALUES (null, ?)",
|
||||
Statement.RETURN_GENERATED_KEYS
|
||||
);
|
||||
|
||||
for(int i=0, len=usernames.length; i<len; i++) {
|
||||
if (!users.containsKey(usernames[i])) {
|
||||
insertUserStatement.setString(1, usernames[i]);
|
||||
insertUserStatement.execute();
|
||||
ResultSet generatedKeys = insertUserStatement.getGeneratedKeys();
|
||||
if (generatedKeys.first()) {
|
||||
users.put(usernames[i], generatedKeys.getInt(1));
|
||||
} else {
|
||||
logger.warning("Could not get the database id for user " + usernames[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
logger.warning("Could not get the database id for the users " + usernames.toString() + "\n\t" + ex.getMessage());
|
||||
Throwable t = ex.getCause();
|
||||
while (t != null) {
|
||||
logger.warning(t.getMessage());
|
||||
t = t.getCause();
|
||||
}
|
||||
}
|
||||
|
||||
return users;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns the database id for the groups
|
||||
* If it doesn't exits it adds the group and returns the id.
|
||||
*/
|
||||
private Map<String,Integer> getGroupIds(String... groupnames) {
|
||||
Map<String,Integer> groups = new HashMap<String,Integer>();
|
||||
|
||||
if (groupnames.length < 1) return groups;
|
||||
|
||||
try {
|
||||
PreparedStatement findGroupsStatement = this.conn.prepareStatement(
|
||||
String.format(
|
||||
"SELECT " +
|
||||
"`group`.`id`, " +
|
||||
"`group`.`name` " +
|
||||
"FROM `group` " +
|
||||
"WHERE `name` IN (%s)",
|
||||
RegionDBUtil.preparePlaceHolders(groupnames.length)
|
||||
)
|
||||
);
|
||||
|
||||
RegionDBUtil.setValues(findGroupsStatement, groupnames);
|
||||
|
||||
ResultSet findGroupsResults = findGroupsStatement.executeQuery();
|
||||
|
||||
while(findGroupsResults.next()) {
|
||||
groups.put(findGroupsResults.getString("name"), findGroupsResults.getInt("id"));
|
||||
}
|
||||
|
||||
PreparedStatement insertGroupStatement = this.conn.prepareStatement(
|
||||
"INSERT INTO " +
|
||||
"`group` ( " +
|
||||
"`id`, " +
|
||||
"`name`" +
|
||||
") VALUES (null, ?)",
|
||||
Statement.RETURN_GENERATED_KEYS
|
||||
);
|
||||
|
||||
for(int i=0, len=groupnames.length; i<len; i++) {
|
||||
if (!groups.containsKey(groupnames[i])) {
|
||||
insertGroupStatement.setString(1, groupnames[i]);
|
||||
insertGroupStatement.execute();
|
||||
ResultSet generatedKeys = insertGroupStatement.getGeneratedKeys();
|
||||
if (generatedKeys.first()) {
|
||||
groups.put(groupnames[i], generatedKeys.getInt(1));
|
||||
} else {
|
||||
logger.warning("Could not get the database id for user " + groupnames[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
logger.warning("Could not get the database id for the groups " + groupnames.toString() + ex.getMessage());
|
||||
}
|
||||
|
||||
return groups;
|
||||
}
|
||||
|
||||
/*
|
||||
* As we don't get notified on the creation/removal of regions:
|
||||
* 1) We get a list of all of the in-database regions
|
||||
* 2) We iterate over all of the in-memory regions
|
||||
* 2a) If the region is in the database, we update the database and
|
||||
* remove the region from the in-database list
|
||||
* b) If the region is not in the database, we insert it
|
||||
* 3) We iterate over what remains of the in-database list and remove
|
||||
* them from the database
|
||||
*
|
||||
* TODO: Look at adding/removing/updating the database when the in
|
||||
* memory region is created/remove/updated
|
||||
*
|
||||
* @see com.sk89q.worldguard.protection.databases.ProtectionDatabase#save()
|
||||
*/
|
||||
public void save() throws ProtectionDatabaseException {
|
||||
try {
|
||||
connect();
|
||||
} catch (SQLException ex) {
|
||||
throw new ProtectionDatabaseException(ex);
|
||||
}
|
||||
|
||||
List<String> regionsInDatabase = new ArrayList<String>();
|
||||
|
||||
try {
|
||||
PreparedStatement getAllRegionsStatement = this.conn.prepareStatement(
|
||||
"SELECT `region`.`id` FROM " +
|
||||
"`region` " +
|
||||
"WHERE `world_id` = ? "
|
||||
);
|
||||
|
||||
getAllRegionsStatement.setInt(1, this.worldDbId);
|
||||
ResultSet getAllRegionsResult = getAllRegionsStatement.executeQuery();
|
||||
|
||||
while(getAllRegionsResult.next()) {
|
||||
regionsInDatabase.add(getAllRegionsResult.getString("id"));
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
logger.warning("Could not get region list for save comparison: " + ex.getMessage());
|
||||
}
|
||||
|
||||
for (Map.Entry<String, ProtectedRegion> entry : regions.entrySet()) {
|
||||
String name = entry.getKey();
|
||||
ProtectedRegion region = entry.getValue();
|
||||
|
||||
try {
|
||||
if (regionsInDatabase.contains(name)) {
|
||||
regionsInDatabase.remove(name);
|
||||
|
||||
if (region instanceof ProtectedCuboidRegion) {
|
||||
updateRegionCuboid( (ProtectedCuboidRegion) region );
|
||||
} else if (region instanceof ProtectedPolygonalRegion) {
|
||||
updateRegionPoly2D( (ProtectedPolygonalRegion) region );
|
||||
} else if (region instanceof GlobalProtectedRegion) {
|
||||
updateRegionGlobal( (GlobalProtectedRegion) region );
|
||||
} else {
|
||||
this.updateRegion(region, region.getClass().getCanonicalName());
|
||||
}
|
||||
} else {
|
||||
if (region instanceof ProtectedCuboidRegion) {
|
||||
insertRegionCuboid( (ProtectedCuboidRegion) region );
|
||||
} else if (region instanceof ProtectedPolygonalRegion) {
|
||||
insertRegionPoly2D( (ProtectedPolygonalRegion) region );
|
||||
} else if (region instanceof GlobalProtectedRegion) {
|
||||
insertRegionGlobal( (GlobalProtectedRegion) region );
|
||||
} else {
|
||||
this.insertRegion(region, region.getClass().getCanonicalName());
|
||||
}
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
logger.warning("Could not save region " + region.getId().toLowerCase() + ": " + ex.getMessage());
|
||||
throw new ProtectionDatabaseException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
for (Map.Entry<String, ProtectedRegion> entry : regions.entrySet()) {
|
||||
try {
|
||||
if (entry.getValue().getParent() == null) continue;
|
||||
|
||||
PreparedStatement setParentStatement = this.conn.prepareStatement(
|
||||
"UPDATE `region` SET " +
|
||||
"`parent` = ? " +
|
||||
"WHERE `id` = ? "
|
||||
);
|
||||
|
||||
setParentStatement.setString(1, entry.getValue().getParent().getId().toLowerCase());
|
||||
setParentStatement.setString(2, entry.getValue().getId().toLowerCase());
|
||||
|
||||
setParentStatement.execute();
|
||||
} catch (SQLException ex) {
|
||||
logger.warning("Could not save region parents " + entry.getValue().getId().toLowerCase() + ": " + ex.getMessage());
|
||||
throw new ProtectionDatabaseException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
for (String name : regionsInDatabase) {
|
||||
try {
|
||||
PreparedStatement removeRegion = this.conn.prepareStatement(
|
||||
"DELETE FROM `region` WHERE `id` = ? "
|
||||
);
|
||||
|
||||
removeRegion.setString(1, name);
|
||||
removeRegion.execute();
|
||||
} catch (SQLException ex) {
|
||||
logger.warning("Could not remove region from database " + name + ": " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void updateFlags(ProtectedRegion region) throws SQLException {
|
||||
PreparedStatement clearCurrentFlagStatement = this.conn.prepareStatement(
|
||||
"DELETE FROM `region_flag` " +
|
||||
"WHERE `region_id` = ? "
|
||||
);
|
||||
|
||||
clearCurrentFlagStatement.setString(1, region.getId().toLowerCase());
|
||||
clearCurrentFlagStatement.execute();
|
||||
|
||||
for (Map.Entry<Flag<?>, Object> entry : region.getFlags().entrySet()) {
|
||||
if (entry.getValue() == null) continue;
|
||||
|
||||
Object flag = marshalFlag(entry.getKey(), entry.getValue());
|
||||
|
||||
PreparedStatement insertFlagStatement = this.conn.prepareStatement(
|
||||
"INSERT INTO `region_flag` ( " +
|
||||
"`id`, " +
|
||||
"`region_id`, " +
|
||||
"`flag`, " +
|
||||
"`value` " +
|
||||
") VALUES (null, ?, ?, ?)"
|
||||
);
|
||||
|
||||
insertFlagStatement.setString(1, region.getId().toLowerCase());
|
||||
insertFlagStatement.setString(2, entry.getKey().getName());
|
||||
insertFlagStatement.setObject(3, flag);
|
||||
|
||||
insertFlagStatement.execute();
|
||||
}
|
||||
}
|
||||
|
||||
private void updatePlayerAndGroups(ProtectedRegion region, Boolean owners) throws SQLException {
|
||||
DefaultDomain domain;
|
||||
|
||||
if (owners) {
|
||||
domain = region.getOwners();
|
||||
} else {
|
||||
domain = region.getMembers();
|
||||
}
|
||||
|
||||
PreparedStatement deleteUsersForRegion = this.conn.prepareStatement(
|
||||
"DELETE FROM `region_players` " +
|
||||
"WHERE `region_id` = ? " +
|
||||
"AND `owner` = ?"
|
||||
);
|
||||
|
||||
deleteUsersForRegion.setString(1, region.getId().toLowerCase());
|
||||
deleteUsersForRegion.setBoolean(2, owners);
|
||||
deleteUsersForRegion.execute();
|
||||
|
||||
PreparedStatement insertUsersForRegion = this.conn.prepareStatement(
|
||||
"INSERT INTO `region_players` " +
|
||||
"(`region_id`, `user_id`, `owner`) VALUES (?, ?, ?)"
|
||||
);
|
||||
|
||||
Map<String,Integer> players = getUserIds(domain.getPlayers().toArray(new String[0]));
|
||||
|
||||
for (Integer player : players.values()) {
|
||||
insertUsersForRegion.setString(1, region.getId().toLowerCase());
|
||||
insertUsersForRegion.setInt(2, player);
|
||||
insertUsersForRegion.setBoolean(3, owners);
|
||||
|
||||
insertUsersForRegion.execute();
|
||||
}
|
||||
|
||||
PreparedStatement deleteGroupsForRegion = this.conn.prepareStatement(
|
||||
"DELETE FROM `region_groups` " +
|
||||
"WHERE `region_id` = ? " +
|
||||
"AND `owner` = ?"
|
||||
);
|
||||
|
||||
deleteGroupsForRegion.setString(1, region.getId().toLowerCase());
|
||||
deleteGroupsForRegion.setBoolean(2, owners);
|
||||
deleteGroupsForRegion.execute();
|
||||
|
||||
PreparedStatement insertGroupsForRegion = this.conn.prepareStatement(
|
||||
"INSERT INTO `region_groups` " +
|
||||
"(`region_id`, `group_id`, `owner`) VALUES (?, ?, ?)"
|
||||
);
|
||||
|
||||
Map<String,Integer> groups = getGroupIds(domain.getGroups().toArray(new String[0]));
|
||||
|
||||
for (Integer group : groups.values()) {
|
||||
insertGroupsForRegion.setString(1, region.getId().toLowerCase());
|
||||
insertGroupsForRegion.setInt(2, group);
|
||||
insertGroupsForRegion.setBoolean(3, owners);
|
||||
|
||||
insertGroupsForRegion.execute();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <V> Object marshalFlag(Flag<V> flag, Object val) {
|
||||
return flag.marshal( (V) val );
|
||||
}
|
||||
|
||||
private void insertRegion(ProtectedRegion region, String type) throws SQLException {
|
||||
PreparedStatement insertRegionStatement = this.conn.prepareStatement(
|
||||
"INSERT INTO `region` (" +
|
||||
"`id`, " +
|
||||
"`world_id`, " +
|
||||
"`type`, " +
|
||||
"`priority`, " +
|
||||
"`parent` " +
|
||||
") VALUES (?, " + this.worldDbId + ", ?, ?, null)"
|
||||
);
|
||||
|
||||
insertRegionStatement.setString(1, region.getId().toLowerCase());
|
||||
insertRegionStatement.setString(2, type);
|
||||
insertRegionStatement.setInt(3, region.getPriority());
|
||||
|
||||
insertRegionStatement.execute();
|
||||
|
||||
updateFlags(region);
|
||||
|
||||
updatePlayerAndGroups(region, false);
|
||||
updatePlayerAndGroups(region, true);
|
||||
}
|
||||
|
||||
private void insertRegionCuboid(ProtectedCuboidRegion region) throws SQLException {
|
||||
insertRegion(region, "cuboid");
|
||||
|
||||
PreparedStatement insertCuboidRegionStatement = this.conn.prepareStatement(
|
||||
"INSERT INTO `region_cuboid` (" +
|
||||
"`region_id`, " +
|
||||
"`min_z`, " +
|
||||
"`min_y`, " +
|
||||
"`min_x`, " +
|
||||
"`max_z`, " +
|
||||
"`max_y`, " +
|
||||
"`max_x` " +
|
||||
") VALUES (?, ?, ?, ?, ?, ?, ?)"
|
||||
);
|
||||
|
||||
BlockVector min = region.getMinimumPoint();
|
||||
BlockVector max = region.getMaximumPoint();
|
||||
|
||||
insertCuboidRegionStatement.setString(1, region.getId().toLowerCase());
|
||||
insertCuboidRegionStatement.setInt(2, min.getBlockZ());
|
||||
insertCuboidRegionStatement.setInt(3, min.getBlockY());
|
||||
insertCuboidRegionStatement.setInt(4, min.getBlockX());
|
||||
insertCuboidRegionStatement.setInt(5, max.getBlockZ());
|
||||
insertCuboidRegionStatement.setInt(6, max.getBlockY());
|
||||
insertCuboidRegionStatement.setInt(7, max.getBlockX());
|
||||
|
||||
insertCuboidRegionStatement.execute();
|
||||
}
|
||||
|
||||
private void insertRegionPoly2D(ProtectedPolygonalRegion region) throws SQLException {
|
||||
insertRegion(region, "poly2d");
|
||||
|
||||
PreparedStatement insertPoly2dRegionStatement = this.conn.prepareStatement(
|
||||
"INSERT INTO `region_poly2d` (" +
|
||||
"`region_id`, " +
|
||||
"`max_y`, " +
|
||||
"`min_y` " +
|
||||
") VALUES (?, ?, ?)"
|
||||
);
|
||||
|
||||
insertPoly2dRegionStatement.setString(1, region.getId().toLowerCase());
|
||||
insertPoly2dRegionStatement.setInt(2, region.getMaximumPoint().getBlockY());
|
||||
insertPoly2dRegionStatement.setInt(3, region.getMinimumPoint().getBlockY());
|
||||
|
||||
insertPoly2dRegionStatement.execute();
|
||||
|
||||
updatePoly2dPoints(region);
|
||||
}
|
||||
|
||||
private void updatePoly2dPoints(ProtectedPolygonalRegion region) throws SQLException {
|
||||
PreparedStatement clearPoly2dPointsForRegionStatement = this.conn.prepareStatement(
|
||||
"DELETE FROM `region_poly2d_point` " +
|
||||
"WHERE `region_id` = ? "
|
||||
);
|
||||
|
||||
clearPoly2dPointsForRegionStatement.setString(1, region.getId().toLowerCase());
|
||||
|
||||
clearPoly2dPointsForRegionStatement.execute();
|
||||
|
||||
PreparedStatement insertPoly2dPointStatement = this.conn.prepareStatement(
|
||||
"INSERT INTO `region_poly2d_point` (" +
|
||||
"`id`, " +
|
||||
"`region_id`, " +
|
||||
"`z`, " +
|
||||
"`x` " +
|
||||
") VALUES (null, ?, ?, ?)"
|
||||
);
|
||||
|
||||
for (BlockVector2D point : region.getPoints()) {
|
||||
insertPoly2dPointStatement.setString(1, region.getId().toLowerCase());
|
||||
insertPoly2dPointStatement.setInt(2, point.getBlockZ());
|
||||
insertPoly2dPointStatement.setInt(3, point.getBlockX());
|
||||
|
||||
insertPoly2dPointStatement.execute();
|
||||
}
|
||||
}
|
||||
|
||||
private void insertRegionGlobal(GlobalProtectedRegion region) throws SQLException {
|
||||
insertRegion(region, "global");
|
||||
}
|
||||
|
||||
private void updateRegion(ProtectedRegion region, String type) throws SQLException {
|
||||
PreparedStatement updateRegionStatement = this.conn.prepareStatement(
|
||||
"UPDATE `region` SET " +
|
||||
"`priority` = ? WHERE `id` = ? "
|
||||
);
|
||||
|
||||
updateRegionStatement.setInt(1, region.getPriority());
|
||||
updateRegionStatement.setString(2, region.getId().toLowerCase());
|
||||
|
||||
updateRegionStatement.execute();
|
||||
|
||||
updateFlags(region);
|
||||
|
||||
updatePlayerAndGroups(region, false);
|
||||
updatePlayerAndGroups(region, true);
|
||||
}
|
||||
|
||||
private void updateRegionCuboid(ProtectedCuboidRegion region) throws SQLException {
|
||||
updateRegion(region, "cuboid");
|
||||
|
||||
PreparedStatement updateCuboidRegionStatement = this.conn.prepareStatement(
|
||||
"UPDATE `region_cuboid` SET " +
|
||||
"`min_z` = ?, " +
|
||||
"`min_y` = ?, " +
|
||||
"`min_x` = ?, " +
|
||||
"`max_z` = ?, " +
|
||||
"`max_y` = ?, " +
|
||||
"`max_x` = ? " +
|
||||
"WHERE `region_id` = ? "
|
||||
);
|
||||
|
||||
BlockVector min = region.getMinimumPoint();
|
||||
BlockVector max = region.getMaximumPoint();
|
||||
|
||||
updateCuboidRegionStatement.setInt(1, min.getBlockZ());
|
||||
updateCuboidRegionStatement.setInt(2, min.getBlockY());
|
||||
updateCuboidRegionStatement.setInt(3, min.getBlockX());
|
||||
updateCuboidRegionStatement.setInt(4, max.getBlockZ());
|
||||
updateCuboidRegionStatement.setInt(5, max.getBlockY());
|
||||
updateCuboidRegionStatement.setInt(6, max.getBlockX());
|
||||
updateCuboidRegionStatement.setString(7, region.getId().toLowerCase());
|
||||
|
||||
updateCuboidRegionStatement.execute();
|
||||
}
|
||||
|
||||
private void updateRegionPoly2D(ProtectedPolygonalRegion region) throws SQLException {
|
||||
updateRegion(region, "poly2d");
|
||||
|
||||
PreparedStatement updatePoly2dRegionStatement = this.conn.prepareStatement(
|
||||
"UPDATE `region_poly2d` SET " +
|
||||
"`max_y` = ?, " +
|
||||
"`min_y` = ? " +
|
||||
"WHERE `region_id` = ? "
|
||||
);
|
||||
|
||||
updatePoly2dRegionStatement.setInt(1, region.getMaximumPoint().getBlockY());
|
||||
updatePoly2dRegionStatement.setInt(2, region.getMinimumPoint().getBlockY());
|
||||
updatePoly2dRegionStatement.setString(3, region.getId().toLowerCase());
|
||||
|
||||
updatePoly2dRegionStatement.execute();
|
||||
|
||||
updatePoly2dPoints(region);
|
||||
}
|
||||
|
||||
private void updateRegionGlobal(GlobalProtectedRegion region) throws SQLException {
|
||||
updateRegion(region, "global");
|
||||
}
|
||||
|
||||
public Map<String, ProtectedRegion> getRegions() {
|
||||
return regions;
|
||||
}
|
||||
|
||||
public void setRegions(Map<String, ProtectedRegion> regions) {
|
||||
this.regions = regions;
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.protection.databases;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
|
||||
/**
|
||||
* Represents a database to read and write lists of regions from and to.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public interface ProtectionDatabase {
|
||||
/**
|
||||
* Load the list of regions. The method should not modify the list returned
|
||||
* by getRegions() unless the load finishes successfully.
|
||||
*
|
||||
* @throws ProtectionDatabaseException
|
||||
*/
|
||||
public void load() throws ProtectionDatabaseException;
|
||||
/**
|
||||
* Save the list of regions.
|
||||
*
|
||||
* @throws ProtectionDatabaseException
|
||||
*/
|
||||
public void save() throws ProtectionDatabaseException;
|
||||
/**
|
||||
* Load the list of regions into a region manager.
|
||||
*
|
||||
* @param manager
|
||||
* @throws ProtectionDatabaseException
|
||||
*/
|
||||
public void load(RegionManager manager) throws ProtectionDatabaseException;
|
||||
/**
|
||||
* Save the list of regions from a region manager.
|
||||
*
|
||||
* @param manager
|
||||
* @throws ProtectionDatabaseException
|
||||
*/
|
||||
public void save(RegionManager manager) throws ProtectionDatabaseException;
|
||||
/**
|
||||
* Get a list of regions.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Map<String,ProtectedRegion> getRegions();
|
||||
/**
|
||||
* Set the list of regions.
|
||||
*
|
||||
* @param regions
|
||||
*/
|
||||
public void setRegions(Map<String,ProtectedRegion> regions);
|
||||
}
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard ProtectionDatabaseException
|
||||
* Copyright (C) 2011 Nicholas Steicke <http://narthollis.net>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.protection.databases;
|
||||
|
||||
import java.lang.Exception;
|
||||
|
||||
public class ProtectionDatabaseException extends Exception {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public ProtectionDatabaseException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ProtectionDatabaseException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ProtectionDatabaseException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public ProtectionDatabaseException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.protection.databases;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.sk89q.worldguard.domains.DefaultDomain;
|
||||
|
||||
/**
|
||||
* Various utility functions for parsing region databases.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class RegionDBUtil {
|
||||
private static Pattern groupPattern = Pattern.compile("^[gG]:(.+)$");
|
||||
|
||||
private RegionDBUtil() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a group/player DefaultDomain specification for areas.
|
||||
*
|
||||
* @param domain
|
||||
* @param split
|
||||
* @param startIndex
|
||||
*/
|
||||
public static void addToDomain(DefaultDomain domain, String[] split,
|
||||
int startIndex) {
|
||||
for (int i = startIndex; i < split.length; i++) {
|
||||
String s = split[i];
|
||||
Matcher m = groupPattern.matcher(s);
|
||||
if (m.matches()) {
|
||||
domain.addGroup(m.group(1));
|
||||
} else {
|
||||
domain.addPlayer(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a group/player DefaultDomain specification for areas.
|
||||
*
|
||||
* @param domain
|
||||
* @param split
|
||||
* @param startIndex
|
||||
*/
|
||||
public static void removeFromDomain(DefaultDomain domain, String[] split,
|
||||
int startIndex) {
|
||||
for (int i = startIndex; i < split.length; i++) {
|
||||
String s = split[i];
|
||||
Matcher m = groupPattern.matcher(s);
|
||||
if (m.matches()) {
|
||||
domain.removeGroup(m.group(1));
|
||||
} else {
|
||||
domain.removePlayer(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a group/player DefaultDomain specification for areas.
|
||||
*
|
||||
* @param split
|
||||
* @param startIndex
|
||||
* @return
|
||||
*/
|
||||
public static DefaultDomain parseDomainString(String[] split, int startIndex) {
|
||||
DefaultDomain domain = new DefaultDomain();
|
||||
|
||||
for (int i = startIndex; i < split.length; i++) {
|
||||
String s = split[i];
|
||||
Matcher m = groupPattern.matcher(s);
|
||||
if (m.matches()) {
|
||||
domain.addGroup(m.group(1));
|
||||
} else {
|
||||
domain.addPlayer(s);
|
||||
}
|
||||
}
|
||||
|
||||
return domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a comma separated list of PreparedStatement place holders
|
||||
*
|
||||
* @param length
|
||||
* @return
|
||||
*/
|
||||
public static String preparePlaceHolders(int length) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < length;) {
|
||||
builder.append("?");
|
||||
if (++i < length) {
|
||||
builder.append(",");
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all of the parsed values to the PreparedStatement
|
||||
*
|
||||
* @param preparedStatement
|
||||
* @param values
|
||||
* @throws SQLException
|
||||
*/
|
||||
public static void setValues(PreparedStatement preparedStatement, String... values) throws SQLException {
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
preparedStatement.setString(i + 1, values[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,308 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.protection.databases;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sk89q.util.yaml.YAMLFormat;
|
||||
import com.sk89q.util.yaml.YAMLNode;
|
||||
import com.sk89q.util.yaml.YAMLProcessor;
|
||||
import com.sk89q.worldedit.BlockVector;
|
||||
import com.sk89q.worldedit.BlockVector2D;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.domains.DefaultDomain;
|
||||
import com.sk89q.worldguard.protection.flags.DefaultFlag;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.regions.GlobalProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion.CircularInheritanceException;
|
||||
|
||||
public class YAMLDatabase extends AbstractProtectionDatabase {
|
||||
|
||||
private YAMLProcessor config;
|
||||
private Map<String, ProtectedRegion> regions;
|
||||
private final Logger logger;
|
||||
|
||||
public YAMLDatabase(File file, Logger logger) throws ProtectionDatabaseException, FileNotFoundException {
|
||||
this.logger = logger;
|
||||
if (!file.exists()) { // shouldn't be necessary, but check anyways
|
||||
try {
|
||||
file.createNewFile();
|
||||
} catch (IOException e) {
|
||||
throw new FileNotFoundException(file.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
config = new YAMLProcessor(file, false, YAMLFormat.COMPACT);
|
||||
}
|
||||
|
||||
public void load() throws ProtectionDatabaseException {
|
||||
try {
|
||||
config.load();
|
||||
} catch (IOException e) {
|
||||
throw new ProtectionDatabaseException(e);
|
||||
}
|
||||
|
||||
Map<String, YAMLNode> regionData = config.getNodes("regions");
|
||||
|
||||
// No regions are even configured
|
||||
if (regionData == null) {
|
||||
this.regions = new HashMap<String, ProtectedRegion>();
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String,ProtectedRegion> regions =
|
||||
new HashMap<String,ProtectedRegion>();
|
||||
Map<ProtectedRegion,String> parentSets =
|
||||
new LinkedHashMap<ProtectedRegion, String>();
|
||||
|
||||
for (Map.Entry<String, YAMLNode> entry : regionData.entrySet()) {
|
||||
String id = entry.getKey().toLowerCase().replace(".", "");
|
||||
YAMLNode node = entry.getValue();
|
||||
|
||||
String type = node.getString("type");
|
||||
ProtectedRegion region;
|
||||
|
||||
try {
|
||||
if (type == null) {
|
||||
logger.warning("Undefined region type for region '" + id + '"');
|
||||
continue;
|
||||
} else if (type.equals("cuboid")) {
|
||||
Vector pt1 = checkNonNull(node.getVector("min"));
|
||||
Vector pt2 = checkNonNull(node.getVector("max"));
|
||||
BlockVector min = Vector.getMinimum(pt1, pt2).toBlockVector();
|
||||
BlockVector max = Vector.getMaximum(pt1, pt2).toBlockVector();
|
||||
region = new ProtectedCuboidRegion(id, min, max);
|
||||
} else if (type.equals("poly2d")) {
|
||||
Integer minY = checkNonNull(node.getInt("min-y"));
|
||||
Integer maxY = checkNonNull(node.getInt("max-y"));
|
||||
List<BlockVector2D> points = node.getBlockVector2dList("points", null);
|
||||
region = new ProtectedPolygonalRegion(id, points, minY, maxY);
|
||||
} else if (type.equals("global")) {
|
||||
region = new GlobalProtectedRegion(id);
|
||||
} else {
|
||||
logger.warning("Unknown region type for region '" + id + '"');
|
||||
continue;
|
||||
}
|
||||
|
||||
Integer priority = checkNonNull(node.getInt("priority"));
|
||||
region.setPriority(priority);
|
||||
setFlags(region, node.getNode("flags"));
|
||||
region.setOwners(parseDomain(node.getNode("owners")));
|
||||
region.setMembers(parseDomain(node.getNode("members")));
|
||||
regions.put(id, region);
|
||||
|
||||
String parentId = node.getString("parent");
|
||||
if (parentId != null) {
|
||||
parentSets.put(region, parentId);
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
logger.warning("Missing data for region '" + id + '"');
|
||||
}
|
||||
}
|
||||
|
||||
// Relink parents
|
||||
for (Map.Entry<ProtectedRegion, String> entry : parentSets.entrySet()) {
|
||||
ProtectedRegion parent = regions.get(entry.getValue());
|
||||
if (parent != null) {
|
||||
try {
|
||||
entry.getKey().setParent(parent);
|
||||
} catch (CircularInheritanceException e) {
|
||||
logger.warning("Circular inheritance detect with '"
|
||||
+ entry.getValue() + "' detected as a parent");
|
||||
}
|
||||
} else {
|
||||
logger.warning("Unknown region parent: " + entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
this.regions = regions;
|
||||
}
|
||||
|
||||
private <V> V checkNonNull(V val) throws NullPointerException {
|
||||
if (val == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
private void setFlags(ProtectedRegion region, YAMLNode flagsData) {
|
||||
if (flagsData == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// @TODO: Make this better
|
||||
for (Flag<?> flag : DefaultFlag.getFlags()) {
|
||||
Object o = flagsData.getProperty(flag.getName());
|
||||
if (o != null) {
|
||||
setFlag(region, flag, o);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private <T> void setFlag(ProtectedRegion region, Flag<T> flag, Object rawValue) {
|
||||
T val = flag.unmarshal(rawValue);
|
||||
if (val == null) {
|
||||
logger.warning("Failed to parse flag '" + flag.getName()
|
||||
+ "' with value '" + rawValue.toString() + "'");
|
||||
return;
|
||||
}
|
||||
region.setFlag(flag, val);
|
||||
}
|
||||
|
||||
private DefaultDomain parseDomain(YAMLNode node) {
|
||||
if (node == null) {
|
||||
return new DefaultDomain();
|
||||
}
|
||||
|
||||
DefaultDomain domain = new DefaultDomain();
|
||||
|
||||
for (String name : node.getStringList("players", null)) {
|
||||
domain.addPlayer(name);
|
||||
}
|
||||
|
||||
for (String name : node.getStringList("groups", null)) {
|
||||
domain.addGroup(name);
|
||||
}
|
||||
|
||||
return domain;
|
||||
}
|
||||
|
||||
public void save() throws ProtectionDatabaseException {
|
||||
config.clear();
|
||||
|
||||
for (Map.Entry<String, ProtectedRegion> entry : regions.entrySet()) {
|
||||
ProtectedRegion region = entry.getValue();
|
||||
YAMLNode node = config.addNode("regions." + entry.getKey());
|
||||
|
||||
if (region instanceof ProtectedCuboidRegion) {
|
||||
ProtectedCuboidRegion cuboid = (ProtectedCuboidRegion) region;
|
||||
node.setProperty("type", "cuboid");
|
||||
node.setProperty("min", cuboid.getMinimumPoint());
|
||||
node.setProperty("max", cuboid.getMaximumPoint());
|
||||
} else if (region instanceof ProtectedPolygonalRegion) {
|
||||
ProtectedPolygonalRegion poly = (ProtectedPolygonalRegion) region;
|
||||
node.setProperty("type", "poly2d");
|
||||
node.setProperty("min-y", poly.getMinimumPoint().getBlockY());
|
||||
node.setProperty("max-y", poly.getMaximumPoint().getBlockY());
|
||||
|
||||
List<Map<String, Object>> points = new ArrayList<Map<String,Object>>();
|
||||
for (BlockVector2D point : poly.getPoints()) {
|
||||
Map<String, Object> data = new HashMap<String, Object>();
|
||||
data.put("x", point.getBlockX());
|
||||
data.put("z", point.getBlockZ());
|
||||
points.add(data);
|
||||
}
|
||||
|
||||
node.setProperty("points", points);
|
||||
} else if (region instanceof GlobalProtectedRegion) {
|
||||
node.setProperty("type", "global");
|
||||
} else {
|
||||
node.setProperty("type", region.getClass().getCanonicalName());
|
||||
}
|
||||
|
||||
node.setProperty("priority", region.getPriority());
|
||||
node.setProperty("flags", getFlagData(region));
|
||||
node.setProperty("owners", getDomainData(region.getOwners()));
|
||||
node.setProperty("members", getDomainData(region.getMembers()));
|
||||
ProtectedRegion parent = region.getParent();
|
||||
if (parent != null) {
|
||||
node.setProperty("parent", parent.getId());
|
||||
}
|
||||
}
|
||||
|
||||
config.setHeader("#\r\n" +
|
||||
"# WorldGuard regions file\r\n" +
|
||||
"#\r\n" +
|
||||
"# WARNING: THIS FILE IS AUTOMATICALLY GENERATED. If you modify this file by\r\n" +
|
||||
"# hand, be aware that A SINGLE MISTYPED CHARACTER CAN CORRUPT THE FILE. If\r\n" +
|
||||
"# WorldGuard is unable to parse the file, your regions will FAIL TO LOAD and\r\n" +
|
||||
"# the contents of this file will reset. Please use a YAML validator such as\r\n" +
|
||||
"# http://yaml-online-parser.appspot.com (for smaller files).\r\n" +
|
||||
"#\r\n" +
|
||||
"# REMEMBER TO KEEP PERIODICAL BACKUPS.\r\n" +
|
||||
"#");
|
||||
config.save();
|
||||
}
|
||||
|
||||
private Map<String, Object> getFlagData(ProtectedRegion region) {
|
||||
Map<String, Object> flagData = new HashMap<String, Object>();
|
||||
|
||||
for (Map.Entry<Flag<?>, Object> entry : region.getFlags().entrySet()) {
|
||||
Flag<?> flag = entry.getKey();
|
||||
addMarshalledFlag(flagData, flag, entry.getValue());
|
||||
}
|
||||
|
||||
return flagData;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <V> void addMarshalledFlag(Map<String, Object> flagData,
|
||||
Flag<V> flag, Object val) {
|
||||
if (val == null) {
|
||||
return;
|
||||
}
|
||||
flagData.put(flag.getName(), flag.marshal((V) val));
|
||||
}
|
||||
|
||||
private Map<String, Object> getDomainData(DefaultDomain domain) {
|
||||
Map<String, Object> domainData = new HashMap<String, Object>();
|
||||
|
||||
setDomainData(domainData, "players", domain.getPlayers());
|
||||
setDomainData(domainData, "groups", domain.getGroups());
|
||||
|
||||
return domainData;
|
||||
}
|
||||
|
||||
private void setDomainData(Map<String, Object> domainData,
|
||||
String key, Set<String> domain) {
|
||||
if (domain.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<String> list = new ArrayList<String>();
|
||||
|
||||
for (String str : domain) {
|
||||
list.add(str);
|
||||
}
|
||||
|
||||
domainData.put(key, list);
|
||||
}
|
||||
|
||||
public Map<String, ProtectedRegion> getRegions() {
|
||||
return regions;
|
||||
}
|
||||
|
||||
public void setRegions(Map<String, ProtectedRegion> regions) {
|
||||
this.regions = regions;
|
||||
}
|
||||
|
||||
}
|
||||
-62
@@ -1,62 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* MySQL WordGuard Region Database
|
||||
* Copyright (C) 2011 Nicholas Steicke <http://narthollis.net>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.protection.databases.migrators;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.sk89q.worldguard.protection.databases.ProtectionDatabase;
|
||||
import com.sk89q.worldguard.protection.databases.ProtectionDatabaseException;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
|
||||
public abstract class AbstractDatabaseMigrator implements DatabaseMigrator {
|
||||
|
||||
private static HashMap<MigratorKey, Class<? extends AbstractDatabaseMigrator>> migrators =
|
||||
new HashMap<MigratorKey, Class<? extends AbstractDatabaseMigrator>>();
|
||||
|
||||
public static Map<MigratorKey, Class<? extends AbstractDatabaseMigrator>> getMigrators() {
|
||||
if (!migrators.isEmpty()) return migrators;
|
||||
|
||||
AbstractDatabaseMigrator.migrators.put(new MigratorKey("mysql", "yaml"), MySQLToYAMLMigrator.class);
|
||||
AbstractDatabaseMigrator.migrators.put(new MigratorKey("yaml", "mysql"), YAMLToMySQLMigrator.class);
|
||||
|
||||
return migrators;
|
||||
}
|
||||
|
||||
protected abstract Set<String> getWorldsFromOld() throws MigrationException;
|
||||
|
||||
protected abstract Map<String, ProtectedRegion> getRegionsForWorldFromOld(String world) throws MigrationException;
|
||||
|
||||
protected abstract ProtectionDatabase getNewWorldStorage(String world) throws MigrationException;
|
||||
|
||||
public void migrate() throws MigrationException {
|
||||
for (String world : this.getWorldsFromOld()) {
|
||||
ProtectionDatabase database = this.getNewWorldStorage(world);
|
||||
database.setRegions(this.getRegionsForWorldFromOld(world));
|
||||
|
||||
try {
|
||||
database.save();
|
||||
} catch (ProtectionDatabaseException e) {
|
||||
throw new MigrationException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* MySQL WordGuard Region Database
|
||||
* Copyright (C) 2011 Nicholas Steicke <http://narthollis.net>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.protection.databases.migrators;
|
||||
|
||||
/**
|
||||
* Represents a method of converting from one database to another.
|
||||
*
|
||||
* @author Nicholas Steicke
|
||||
*/
|
||||
public interface DatabaseMigrator {
|
||||
|
||||
public void migrate() throws MigrationException;
|
||||
}
|
||||
|
||||
-40
@@ -1,40 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* MySQL WordGuard Region Database
|
||||
* Copyright (C) 2011 Nicholas Steicke <http://narthollis.net>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.protection.databases.migrators;
|
||||
|
||||
public class MigrationException extends Exception {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public MigrationException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public MigrationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public MigrationException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public MigrationException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* MySQL WordGuard Region Database
|
||||
* Copyright (C) 2011 Nicholas Steicke <http://narthollis.net>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.protection.databases.migrators;
|
||||
|
||||
public class MigratorKey {
|
||||
public final String from;
|
||||
public final String to;
|
||||
|
||||
public MigratorKey(String from, String to) {
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
MigratorKey other = (MigratorKey) o;
|
||||
|
||||
return other.from.equals(this.from) && other.to.equals(this.to);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int hash = 17;
|
||||
hash = hash * 31 + this.from.hashCode();
|
||||
hash = hash * 31 + this.to.hashCode();
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
-97
@@ -1,97 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* MySQL WordGuard Region Database
|
||||
* Copyright (C) 2011 Nicholas Steicke <http://narthollis.net>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.protection.databases.migrators;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.sk89q.worldguard.bukkit.ConfigurationManager;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.protection.databases.MySQLDatabase;
|
||||
import com.sk89q.worldguard.protection.databases.ProtectionDatabase;
|
||||
import com.sk89q.worldguard.protection.databases.ProtectionDatabaseException;
|
||||
import com.sk89q.worldguard.protection.databases.YAMLDatabase;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
|
||||
public class MySQLToYAMLMigrator extends AbstractDatabaseMigrator {
|
||||
|
||||
private WorldGuardPlugin plugin;
|
||||
private Set<String> worlds;
|
||||
|
||||
public MySQLToYAMLMigrator(WorldGuardPlugin plugin) throws MigrationException {
|
||||
this.plugin = plugin;
|
||||
this.worlds = new HashSet<String>();
|
||||
|
||||
ConfigurationManager config = plugin.getGlobalStateManager();
|
||||
|
||||
try {
|
||||
Connection conn = DriverManager.getConnection(config.sqlDsn, config.sqlUsername, config.sqlPassword);
|
||||
|
||||
ResultSet worlds = conn.prepareStatement("SELECT `name` FROM `world`;").executeQuery();
|
||||
|
||||
while(worlds.next()) {
|
||||
this.worlds.add(worlds.getString(1));
|
||||
}
|
||||
|
||||
conn.close();
|
||||
} catch (SQLException e) {
|
||||
throw new MigrationException((Exception) e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<String> getWorldsFromOld() {
|
||||
return this.worlds;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, ProtectedRegion> getRegionsForWorldFromOld(String world) throws MigrationException {
|
||||
ProtectionDatabase oldDatabase;
|
||||
try {
|
||||
oldDatabase = new MySQLDatabase(plugin.getGlobalStateManager(), world, plugin.getLogger());
|
||||
oldDatabase.load();
|
||||
} catch (ProtectionDatabaseException e) {
|
||||
throw new MigrationException((Exception) e);
|
||||
}
|
||||
|
||||
return oldDatabase.getRegions();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ProtectionDatabase getNewWorldStorage(String world) throws MigrationException {
|
||||
try {
|
||||
File file = new File(plugin.getDataFolder(),
|
||||
"worlds" + File.separator + world + File.separator + "regions.yml");
|
||||
|
||||
return new YAMLDatabase(file, plugin.getLogger());
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new MigrationException((Exception) e);
|
||||
} catch (ProtectionDatabaseException e) {
|
||||
throw new MigrationException((Exception) e);
|
||||
}
|
||||
}
|
||||
}
|
||||
-86
@@ -1,86 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* MySQL WordGuard Region Database
|
||||
* Copyright (C) 2011 Nicholas Steicke <http://narthollis.net>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldguard.protection.databases.migrators;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.protection.databases.MySQLDatabase;
|
||||
import com.sk89q.worldguard.protection.databases.ProtectionDatabase;
|
||||
import com.sk89q.worldguard.protection.databases.ProtectionDatabaseException;
|
||||
import com.sk89q.worldguard.protection.databases.YAMLDatabase;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
|
||||
public class YAMLToMySQLMigrator extends AbstractDatabaseMigrator {
|
||||
|
||||
private WorldGuardPlugin plugin;
|
||||
private HashMap<String,File> regionYamlFiles;
|
||||
|
||||
public YAMLToMySQLMigrator(WorldGuardPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
|
||||
this.regionYamlFiles = new HashMap<String,File>();
|
||||
|
||||
File files[] = new File(plugin.getDataFolder(), "worlds" + File.separator).listFiles();
|
||||
for (File item : files) {
|
||||
if (item.isDirectory()) {
|
||||
for (File subItem : item.listFiles()) {
|
||||
if (subItem.getName().equals("regions.yml")) {
|
||||
this.regionYamlFiles.put(item.getName(), subItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<String> getWorldsFromOld() {
|
||||
return this.regionYamlFiles.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, ProtectedRegion> getRegionsForWorldFromOld(String world) throws MigrationException {
|
||||
ProtectionDatabase oldDatabase;
|
||||
try {
|
||||
oldDatabase = new YAMLDatabase(this.regionYamlFiles.get(world), plugin.getLogger());
|
||||
oldDatabase.load();
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new MigrationException((Exception) e);
|
||||
} catch (ProtectionDatabaseException e) {
|
||||
throw new MigrationException((Exception) e);
|
||||
}
|
||||
|
||||
return oldDatabase.getRegions();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ProtectionDatabase getNewWorldStorage(String world) throws MigrationException {
|
||||
try {
|
||||
return new MySQLDatabase(plugin.getGlobalStateManager(), world, plugin.getLogger());
|
||||
} catch (ProtectionDatabaseException e) {
|
||||
throw new MigrationException((Exception) e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.sk89q.worldguard.protection.flags;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class CommandStringFlag extends Flag<String> {
|
||||
|
||||
public CommandStringFlag(String name, char legacyCode) {
|
||||
super(name, legacyCode);
|
||||
}
|
||||
|
||||
public CommandStringFlag(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parseInput(WorldGuardPlugin plugin, CommandSender sender,
|
||||
String input) throws InvalidFlagFormat {
|
||||
input = input.trim();
|
||||
if (!input.startsWith("/")) {
|
||||
input = "/" + input;
|
||||
}
|
||||
return input.toLowerCase();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String unmarshal(Object o) {
|
||||
if (o instanceof String) {
|
||||
return (String) o;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object marshal(String o) {
|
||||
return o;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldGuard
|
||||
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.sk89q.worldguard.protection.flags;
|
||||
|
||||
import org.bukkit.entity.CreatureType;
|
||||
|
||||
/**
|
||||
* Represents a creature type.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class CreatureTypeFlag extends EnumFlag<CreatureType> {
|
||||
|
||||
public CreatureTypeFlag(String name, char legacyCode) {
|
||||
super(name, legacyCode, CreatureType.class);
|
||||
}
|
||||
|
||||
public CreatureTypeFlag(String name) {
|
||||
super(name, CreatureType.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CreatureType detectValue(String input) {
|
||||
CreatureType lowMatch = null;
|
||||
|
||||
for (CreatureType type : CreatureType.values()) {
|
||||
if (type.name().equalsIgnoreCase(input.trim())) {
|
||||
return type;
|
||||
}
|
||||
|
||||
if (type.name().toLowerCase().startsWith(input.toLowerCase().trim())) {
|
||||
lowMatch = type;
|
||||
}
|
||||
}
|
||||
|
||||
return lowMatch;
|
||||
}
|
||||
}
|
||||
Loaded 100 of 463 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user