Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
120fff1fc4 | ||
|
|
f879bd5e3a | ||
|
|
01f9fd561d | ||
|
|
6802a7d747 | ||
|
|
b918b29014 | ||
|
|
4895a3313b | ||
|
|
59673c9e66 | ||
|
|
b126255be7 | ||
|
|
606c9f3fd8 | ||
|
|
aa306a8df7 | ||
|
|
b1256eedcf | ||
|
|
4454df341f | ||
|
|
5bcac17f1c | ||
|
|
875b9f326c | ||
|
|
a0d27c6f86 | ||
|
|
1d47d12189 | ||
|
|
67f78ae8b5 | ||
|
|
5948855da7 | ||
|
|
f6ec46cdf6 | ||
|
|
ebd2755eb2 | ||
|
|
78f5827d3d | ||
|
|
0829070c67 | ||
|
|
8b4332e842 | ||
|
|
f904c91443 | ||
|
|
944539453e | ||
|
|
5856b002df | ||
|
|
12f68bc227 | ||
|
|
de6e20d60a | ||
|
|
35e6ef5cd8 | ||
|
|
27251dda2e | ||
|
|
4bb967ab4a | ||
|
|
7c1f878610 | ||
|
|
e8c4c9b218 | ||
|
|
bc37d365ab | ||
|
|
d9ae1bbd9f | ||
|
|
e492b30178 | ||
|
|
920860c298 | ||
|
|
5f8a6e3423 | ||
|
|
3e7a5056d5 | ||
|
|
2ec6f04763 | ||
|
|
ecef9c9792 | ||
|
|
810501a508 | ||
|
|
6285a66d76 | ||
|
|
72e4922e8e | ||
|
|
c1f1885633 | ||
|
|
56e514a500 | ||
|
|
5ede100d56 | ||
|
|
f1456b8101 | ||
|
|
ef8eb76b16 | ||
|
|
b4f2188f72 | ||
|
|
38c30f5ecd | ||
|
|
94c794de6f | ||
|
|
fb535e620c | ||
|
|
5a42980d78 | ||
|
|
299d2a1f01 | ||
|
|
164ff5ea9a | ||
|
|
6c89ef908a | ||
|
|
3441ae11f2 | ||
|
|
c028331ef9 | ||
|
|
9343c300cd | ||
|
|
63693cc529 | ||
|
|
e6de06aae8 | ||
|
|
89ce7312d1 | ||
|
|
b884787377 | ||
|
|
a1427e7743 | ||
|
|
0c02190e19 | ||
|
|
1f7cce9535 | ||
|
|
9fea677b60 | ||
|
|
6b9a3aff58 | ||
|
|
b938271b4d | ||
|
|
297e06ba71 | ||
|
|
a521ab76a5 | ||
|
|
b1c8fc82c4 | ||
|
|
d4ba90c21d | ||
|
|
14dc868d45 | ||
|
|
61a60ecdd6 | ||
|
|
2b56247e21 | ||
|
|
e0066e6173 | ||
|
|
b5b92f91dc | ||
|
|
7b12510182 | ||
|
|
e2fc6a3ff0 | ||
|
|
5acd3a7f6c | ||
|
|
ce49ca0998 | ||
|
|
eacce487ed | ||
|
|
602b1d8a27 | ||
|
|
dec469caef | ||
|
|
4194b2ca86 | ||
|
|
17741822c1 | ||
|
|
3757056e46 | ||
|
|
0eb68ef864 | ||
|
|
3f77a9b721 | ||
|
|
321b3acf0a | ||
|
|
dfbbeeb473 | ||
|
|
31d3f2e7c6 | ||
|
|
40a66b9be4 | ||
|
|
049a1fb2ed | ||
|
|
3fc68af05f | ||
|
|
c3f0c8a7a1 | ||
|
|
cba1a95838 | ||
|
|
345f4a2e0e | ||
|
|
162d53b66e | ||
|
|
bed6782a00 | ||
|
|
d90b960597 | ||
|
|
3325feb1cb | ||
|
|
62d181eb81 | ||
|
|
1e24e9c128 | ||
|
|
cfffba25cf | ||
|
|
671b4fe2db | ||
|
|
5b300bc5d1 | ||
|
|
a5332c2166 | ||
|
|
141d5ccd25 | ||
|
|
c75b9c2328 | ||
|
|
0863db8cf0 | ||
|
|
53d6a272e6 | ||
|
|
71467a7ae7 | ||
|
|
56fa3458ab | ||
|
|
82e04ac4e5 | ||
|
|
564d4442fc | ||
|
|
df8fdd086b | ||
|
|
a31476251e | ||
|
|
360a655627 | ||
|
|
3b871b9c00 | ||
|
|
65834a2087 | ||
|
|
e9d85da691 | ||
|
|
cfa78af654 | ||
|
|
45d9119150 | ||
|
|
ea487eb6a4 | ||
|
|
4e295ea1eb | ||
|
|
32265414bd | ||
|
|
80e706e962 | ||
|
|
110838715b | ||
|
|
b90334c8a8 | ||
|
|
3ce0530d5f | ||
|
|
7eaa84d5b1 | ||
|
|
ad325dfedb | ||
|
|
5bb7eb6f01 | ||
|
|
342cfc0801 | ||
|
|
f5c6a9f507 | ||
|
|
e843ff372e | ||
|
|
ed27ffed65 | ||
|
|
7995ecd867 | ||
|
|
fcef6679c4 | ||
|
|
742b6a2e27 | ||
|
|
258fbc8870 | ||
|
|
0fa43ee287 | ||
|
|
fb39261dc7 | ||
|
|
7fce4bf53e | ||
|
|
13840cf61b | ||
|
|
e26f6b5e8d | ||
|
|
767c49f9fa | ||
|
|
c9178da608 | ||
|
|
855bc59a53 | ||
|
|
798c22e94b | ||
|
|
ea3be11294 | ||
|
|
335073b3b0 | ||
|
|
2b6ee344b7 | ||
|
|
8f55b82e2f | ||
|
|
ba9cd1f3e2 | ||
|
|
e0e7ae98e7 | ||
|
|
b05e439da9 | ||
|
|
fb5dbbdf58 | ||
|
|
9cb9dd0a58 | ||
|
|
276d42561e | ||
|
|
44b98165ba | ||
|
|
b5088340fd | ||
|
|
b7dd63ebd9 | ||
|
|
ba376a6326 | ||
|
|
87a43e8e8f | ||
|
|
b62ada53c3 | ||
|
|
4f3198b1bd | ||
|
|
c9f99e0903 | ||
|
|
3b4c58b721 | ||
|
|
6496bbd87f | ||
|
|
4ad8d362f7 | ||
|
|
d9aeb6afaa | ||
|
|
d971389746 | ||
|
|
233a2bdbe7 | ||
|
|
2277183330 | ||
|
|
b2cd3d31fd | ||
|
|
02f6b3be42 | ||
|
|
22e84321fc | ||
|
|
c472dc89ad | ||
|
|
b89d9d44b0 | ||
|
|
a2c21f8ceb | ||
|
|
e35596b0fa | ||
|
|
b95a7f063b | ||
|
|
e4bbd36d47 | ||
|
|
9790ab29a2 | ||
|
|
24cc2d3b36 | ||
|
|
12779699e3 | ||
|
|
2188690d20 | ||
|
|
7059fdfd9e | ||
|
|
9e1bde4b00 | ||
|
|
45790b60b0 | ||
|
|
c5f3a27d6b | ||
|
|
d9136aa407 | ||
|
|
183f48a998 | ||
|
|
3c5bc507a5 | ||
|
|
548dd0365c | ||
|
|
4591fc603f | ||
|
|
26946feecc | ||
|
|
dd14f3c469 | ||
|
|
69af41f1e5 | ||
|
|
474562455d | ||
|
|
c75d612541 | ||
|
|
8de6ce9868 | ||
|
|
97bde50708 | ||
|
|
b23e35cf26 | ||
|
|
b58e04707d | ||
|
|
846cf63268 | ||
|
|
4850bdefdf | ||
|
|
424b580eb9 | ||
|
|
7f8ad468ca | ||
|
|
e07e2bd7d1 | ||
|
|
7074963fb1 | ||
|
|
88acbe655d | ||
|
|
903ebc68a4 | ||
|
|
49bdccf020 | ||
|
|
ba3818884d | ||
|
|
64ce904ec1 | ||
|
|
8c5f7ef020 | ||
|
|
98426f6dcc | ||
|
|
f3ec873ac2 | ||
|
|
30961483e1 | ||
|
|
33e0750959 | ||
|
|
e59a07e232 | ||
|
|
3b05b9be11 | ||
|
|
943bbd9889 | ||
|
|
763cf8dbda | ||
|
|
5117518d8f | ||
|
|
936996da17 | ||
|
|
019a7e59b7 | ||
|
|
428a47f889 | ||
|
|
2be2cb19b2 | ||
|
|
66ee09d050 | ||
|
|
906dab28c1 | ||
|
|
6db8e1d842 | ||
|
|
a665e86096 | ||
|
|
b7481dbd2e | ||
|
|
b1e509c6f8 | ||
|
|
1f69622a34 | ||
|
|
215b2b5f75 | ||
|
|
1e8c91e92f | ||
|
|
19d447d67d | ||
|
|
925fa2ee1b | ||
|
|
1cedf0e9a0 | ||
|
|
ca8bb7f5f0 | ||
|
|
9e15a4a557 | ||
|
|
af5d0c4b0e | ||
|
|
08ab359534 | ||
|
|
28c44e0b2f | ||
|
|
7038f49a1a | ||
|
|
af25c15286 | ||
|
|
ffc5281d59 | ||
|
|
ad659cd32e | ||
|
|
afd3cbd311 | ||
|
|
a5a5f7e24a | ||
|
|
1e203b58c3 | ||
|
|
104b7c2cf2 | ||
|
|
355c89ecab | ||
|
|
1241e18f9c | ||
|
|
6566acf7eb | ||
|
|
4332ed92f2 | ||
|
|
2e7f96aab0 | ||
|
|
3cb9b90ef0 | ||
|
|
21a04cc8c8 | ||
|
|
dcc1b59627 | ||
|
|
e8fb3e6d24 | ||
|
|
93d084d5ba | ||
|
|
e45ecf9c86 | ||
|
|
beb10e22f2 | ||
|
|
64b12f8497 | ||
|
|
0821a08df2 | ||
|
|
50870a9b32 | ||
|
|
b823446e28 | ||
|
|
48b00874e5 | ||
|
|
deba6c79f3 | ||
|
|
c0be10ad94 | ||
|
|
5010d35ff3 | ||
|
|
42d26a1f4f | ||
|
|
92c25d2df4 | ||
|
|
5b5349fc34 | ||
|
|
cc6ac93b7a | ||
|
|
1b843b3586 | ||
|
|
3b9a426547 | ||
|
|
989ba0103d | ||
|
|
b584b996a3 | ||
|
|
896c7fc467 | ||
|
|
bd2393342f | ||
|
|
762b10cb17 | ||
|
|
9322eedb4e | ||
|
|
4e2a902b75 | ||
|
|
d3b8bd6f39 | ||
|
|
0fa64dad7f | ||
|
|
792e8663e6 | ||
|
|
4dc999b0d9 | ||
|
|
7c15c2de41 | ||
|
|
43137c3e53 | ||
|
|
521ecd438e | ||
|
|
949c6599b3 | ||
|
|
ea79efe693 | ||
|
|
b4a89462f8 | ||
|
|
70bd3d0e9a | ||
|
|
c33474e0f9 | ||
|
|
3d0ebe5c91 | ||
|
|
a9ab0702e0 | ||
|
|
9272741a3c | ||
|
|
2b72a99608 | ||
|
|
4c38e10fe1 | ||
|
|
7806b48d34 | ||
|
|
9803d6b731 | ||
|
|
649db3aca2 | ||
|
|
b75ab68e7a | ||
|
|
8ffc42d349 | ||
|
|
145c9750cd | ||
|
|
12647c3a6c | ||
|
|
056f8a57c7 | ||
|
|
94f0acf9f3 | ||
|
|
40bf65d56a | ||
|
|
726e3a5c20 | ||
|
|
d1cab0da7f | ||
|
|
ede4873c6a | ||
|
|
fd8c827bf1 | ||
|
|
20afbdf264 | ||
|
|
0dd92e5189 | ||
|
|
4b1ba5acb0 | ||
|
|
edc94594eb | ||
|
|
837efb75d1 | ||
|
|
252208a479 | ||
|
|
2641cb7d4f | ||
|
|
9c91f06c5d | ||
|
|
7fab4144ae | ||
|
|
81eb2cad1a | ||
|
|
eda7db7aca | ||
|
|
45a7653dcd | ||
|
|
36fef995e4 | ||
|
|
af2e862ca2 | ||
|
|
7f48ce06be | ||
|
|
1c5ae9ef67 | ||
|
|
3bf18c41bb | ||
|
|
7ab49f1909 | ||
|
|
44b5e5548d | ||
|
|
50ca9d129b | ||
|
|
7b725d655c | ||
|
|
3e9c7aa74b | ||
|
|
916ed2652e | ||
|
|
59a1726e8c | ||
|
|
20f91b5258 | ||
|
|
353ce7e825 | ||
|
|
94be4ab18e | ||
|
|
df7409607f | ||
|
|
79b937e8d2 | ||
|
|
83c6c9c743 | ||
|
|
6a2affc0f9 | ||
|
|
8ad713c183 | ||
|
|
f8fb746f64 | ||
|
|
c6b3507bf4 | ||
|
|
2dc95da6e0 | ||
|
|
8f9bfcf474 | ||
|
|
a8b54757e9 | ||
|
|
19cfd9edc6 | ||
|
|
03d0f962e5 | ||
|
|
0ff24627ca | ||
|
|
4d8cd430b7 | ||
|
|
30b0e5d0b1 | ||
|
|
cdf067bba8 | ||
|
|
e4d05e14ac | ||
|
|
82dc78523f | ||
|
|
676e744c02 | ||
|
|
0d80265ff2 | ||
|
|
442521a73c | ||
|
|
dcef083e30 | ||
|
|
162cd20f80 | ||
|
|
c74433422a | ||
|
|
f338650b24 | ||
|
|
65c0d77d3e | ||
|
|
09a150b6e9 | ||
|
|
06173a446a | ||
|
|
d6adea447e | ||
|
|
d042b785ed | ||
|
|
881846d301 | ||
|
|
2092cc43b3 | ||
|
|
dc637d0f2b | ||
|
|
987a20b33c | ||
|
|
dbf65f798f | ||
|
|
97aa259b2d | ||
|
|
770a108bad | ||
|
|
71aaa574b2 | ||
|
|
a02fe633e2 | ||
|
|
0669bab563 | ||
|
|
a258400443 | ||
|
|
d02c5057c6 | ||
|
|
a473f47235 | ||
|
|
7bedf6bb15 | ||
|
|
9d813290c6 | ||
|
|
05239bccb0 | ||
|
|
1d5c28f37f | ||
|
|
16fb6b4f9d | ||
|
|
97b09aab34 | ||
|
|
55210caceb | ||
|
|
8127e56603 | ||
|
|
e61b496ca4 | ||
|
|
3ed8eb76c2 | ||
|
|
a5c3b8a245 | ||
|
|
3f5d52f901 | ||
|
|
46e0607a26 | ||
|
|
23fa7a89ad | ||
|
|
dcd379bce7 | ||
|
|
40238a9d25 | ||
|
|
44db374e09 | ||
|
|
d960d543ff | ||
|
|
0a45292587 | ||
|
|
9b4a7c705b | ||
|
|
71a6d8ab44 | ||
|
|
91f9acb633 | ||
|
|
0e45dc5a3f | ||
|
|
3341574e02 | ||
|
|
881dc38a18 | ||
|
|
e54b201aa5 | ||
|
|
2d06a40127 | ||
|
|
f7e68798fa | ||
|
|
b9fe5d2afc | ||
|
|
5f12d99e73 | ||
|
|
933987ac0a | ||
|
|
3a10a0969a | ||
|
|
ba4907e67b | ||
|
|
99b37147d3 | ||
|
|
92a03ab7d6 | ||
|
|
68a0c67769 | ||
|
|
17e9105b9c | ||
|
|
5411a294e7 | ||
|
|
f821e277de | ||
|
|
18c2164049 | ||
|
|
c9688a9c58 | ||
|
|
cd599849b2 | ||
|
|
423f0199d0 | ||
|
|
40299eeea4 | ||
|
|
38077275bc | ||
|
|
23aa6dc743 | ||
|
|
b90fb6a2b0 | ||
|
|
17c8ed9ebc | ||
|
|
a091a32c26 | ||
|
|
23970a4e36 | ||
|
|
f61a9ab5cc | ||
|
|
4505bb6f4e | ||
|
|
bb836aea57 | ||
|
|
d584fba31c | ||
|
|
feacf3af7b | ||
|
|
8c428bb399 | ||
|
|
8edb6976fb | ||
|
|
edd2f460a0 | ||
|
|
8810647bb8 | ||
|
|
2204bd67a7 | ||
|
|
c9c747693d | ||
|
|
135d92303d | ||
|
|
c707434155 | ||
|
|
4b72805a69 | ||
|
|
d5a9b0c65f | ||
|
|
2015604fe2 | ||
|
|
96a290b153 | ||
|
|
912fcfe88a | ||
|
|
4dcf7489fa | ||
|
|
7f1552dff8 | ||
|
|
d2ca8bffc4 | ||
|
|
e15b01bac5 | ||
|
|
dcd3cb80b8 | ||
|
|
d0ddc7c271 | ||
|
|
2b55f3407c | ||
|
|
e84afb4808 | ||
|
|
10c47eff7e | ||
|
|
aee81f918e | ||
|
|
95b2d9419f | ||
|
|
feb9ce6633 | ||
|
|
43489ca087 | ||
|
|
ce1a15e6ea | ||
|
|
cc72d370ea | ||
|
|
d042185660 | ||
|
|
e78b639018 | ||
|
|
e8ea562b09 | ||
|
|
3b5a729ef3 | ||
|
|
ef7d487ec5 | ||
|
|
b379b8f022 | ||
|
|
a31378c2c8 | ||
|
|
0d2c2121bb | ||
|
|
21040b306a | ||
|
|
541b1dbc44 | ||
|
|
005ac41820 | ||
|
|
dd93772233 | ||
|
|
428fc7e5f6 | ||
|
|
5cf38cc885 | ||
|
|
2f6b51e811 | ||
|
|
2f12da6bc6 | ||
|
|
3985e157d9 | ||
|
|
3034eb5c12 | ||
|
|
f666f1baa9 | ||
|
|
3bbffa7b55 | ||
|
|
bc774e2596 | ||
|
|
65a0e5c188 | ||
|
|
772d2cb580 | ||
|
|
edc6825f83 | ||
|
|
7b2f9e0c86 | ||
|
|
0fa4fa1862 | ||
|
|
5be31ebb5c | ||
|
|
962394b2ba | ||
|
|
7cf7c5f44c | ||
|
|
5b494a09ec | ||
|
|
5cfac5da4a | ||
|
|
203004951b | ||
|
|
765d7402fa | ||
|
|
151b5fc561 | ||
|
|
b489da7fe4 | ||
|
|
786a0f6f2b | ||
|
|
e2a940e01b | ||
|
|
518c3be478 | ||
|
|
6f3eaac008 | ||
|
|
31633e9466 | ||
|
|
02913780ec | ||
|
|
f03a2263d8 | ||
|
|
a8cd832c28 | ||
|
|
abbced0530 | ||
|
|
200e07023f | ||
|
|
5fdd26b53f | ||
|
|
61896ea760 | ||
|
|
b43881c299 | ||
|
|
6046f4defc | ||
|
|
69ccb9f12b | ||
|
|
430f2f57e9 | ||
|
|
c3f0bbb41c | ||
|
|
7e481e6a9a | ||
|
|
627de1aebd | ||
|
|
194108336b | ||
|
|
eade612981 | ||
|
|
733163cc4c | ||
|
|
86a917ddd1 | ||
|
|
e8503aa0b9 | ||
|
|
01bf9e8406 | ||
|
|
0bdadf63b3 | ||
|
|
5b1c35bf06 | ||
|
|
c467acdfac | ||
|
|
22167a0a07 | ||
|
|
251647c7a2 | ||
|
|
80e9799579 | ||
|
|
95f49f34d0 | ||
|
|
b01b67f64c | ||
|
|
603fb5d2b8 | ||
|
|
22f7c347ab | ||
|
|
08229ed4f9 | ||
|
|
a942fd08f5 | ||
|
|
c96d534c26 | ||
|
|
789a9a9bb4 | ||
|
|
d2435a8026 | ||
|
|
36db436fa3 | ||
|
|
30d9978412 | ||
|
|
5db7f124ac | ||
|
|
c82ee055e7 | ||
|
|
cb1c1efc35 | ||
|
|
0037a4e83f | ||
|
|
c369b3c62a | ||
|
|
0934a12205 | ||
|
|
d19db5f86f | ||
|
|
5657ee6c90 | ||
|
|
41a71d6185 | ||
|
|
11592cd742 | ||
|
|
43d83d8855 | ||
|
|
d1cb628473 | ||
|
|
44fc802e8b | ||
|
|
bfa1734d23 | ||
|
|
66139dacac | ||
|
|
714c24445d | ||
|
|
79f55a02cb | ||
|
|
484fe22e9e | ||
|
|
119d8b1a81 | ||
|
|
953d1f0aed | ||
|
|
2e225a9452 | ||
|
|
960dc2cd48 | ||
|
|
345ac35649 | ||
|
|
802114c605 | ||
|
|
16bbd30209 | ||
|
|
0021e789bc | ||
|
|
41daebb629 | ||
|
|
b496e88557 | ||
|
|
7c0e10d058 | ||
|
|
1d72447096 | ||
|
|
01e93a642e | ||
|
|
696ae7c967 | ||
|
|
b28202f1cb | ||
|
|
601e15db5a | ||
|
|
f30b413b46 | ||
|
|
a9c4a81abe | ||
|
|
d619ed5798 | ||
|
|
e94a9bf68f | ||
|
|
257c12e727 | ||
|
|
8b3eaa70fb | ||
|
|
c96bb890b4 | ||
|
|
8192a1962a | ||
|
|
80df9c6aa4 | ||
|
|
8073089da4 | ||
|
|
23e7d4a8bb | ||
|
|
0e1e92df13 | ||
|
|
d13f0b9191 | ||
|
|
aa2bffbd00 | ||
|
|
a456d67528 | ||
|
|
95f074342c | ||
|
|
74016bf93e | ||
|
|
3f8bac582c | ||
|
|
6b57e58d63 | ||
|
|
19aa20537d | ||
|
|
cf31df35ec | ||
|
|
6d39ce7240 | ||
|
|
0f3c1b94d7 | ||
|
|
13cc6736e2 | ||
|
|
64629bd878 | ||
|
|
e42be555b1 | ||
|
|
c62c5f5cae | ||
|
|
313bdbd8bf | ||
|
|
765b606e18 | ||
|
|
c0be685846 | ||
|
|
133e4c2c78 | ||
|
|
b7e91ac6d0 | ||
|
|
79518e6503 | ||
|
|
2999f9d168 | ||
|
|
b4d8b2095d | ||
|
|
f7099f2093 | ||
|
|
8c51795b1a | ||
|
|
ba523ce3f3 | ||
|
|
e4af400acb | ||
|
|
ffa38f9fd1 | ||
|
|
84ccabdf34 | ||
|
|
c0b4d95082 | ||
|
|
f305b3a119 | ||
|
|
48ace4947b | ||
|
|
57acbebaf1 | ||
|
|
e15311178b | ||
|
|
7385be7eff | ||
|
|
9a29474132 | ||
|
|
881f050f0d | ||
|
|
339bf1a06d | ||
|
|
bc70678387 | ||
|
|
c3eef60672 | ||
|
|
eb78b390ca | ||
|
|
a0fc3472e4 | ||
|
|
915946317d | ||
|
|
d4c4a497c4 | ||
|
|
0286900829 | ||
|
|
cf7874f776 | ||
|
|
93c0295744 | ||
|
|
9bc3a25191 | ||
|
|
e95d7a8b6e | ||
|
|
1edc48b16f | ||
|
|
07c8abff54 | ||
|
|
afff62120e | ||
|
|
ff8c48e69e | ||
|
|
b9e84f7b4a | ||
|
|
924e6f3777 | ||
|
|
6d0d2ee538 | ||
|
|
8983d7bc84 | ||
|
|
fc81a7034e | ||
|
|
b7e5828c3f | ||
|
|
e543ac733f | ||
|
|
d09fcab7b3 | ||
|
|
70c6b26db5 | ||
|
|
1859fc5db2 | ||
|
|
47a4046d47 | ||
|
|
7b3a8402a1 | ||
|
|
84eb9343ce | ||
|
|
0a8dd85224 | ||
|
|
f8a63b372d | ||
|
|
8a731617e1 | ||
|
|
028ec89d26 | ||
|
|
9fd633cbe9 | ||
|
|
c1da391653 | ||
|
|
92edff6ffe | ||
|
|
d4a3e04622 | ||
|
|
2562502d26 | ||
|
|
e12fcdb1b8 | ||
|
|
a7aed1a278 | ||
|
|
e5dcb557dc | ||
|
|
447f192027 |
No files matched your search
@@ -0,0 +1,6 @@
|
||||
.classpath
|
||||
.project
|
||||
.settings
|
||||
target
|
||||
|
||||
.DS_Store
|
||||
+333
@@ -0,0 +1,333 @@
|
||||
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.
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
Installation
|
||||
------------
|
||||
|
||||
This plugin requires Hey0's server modification.
|
||||
|
||||
1. Create a "plugins" folder inside your "bin" folder.
|
||||
|
||||
2. Copy WorldProtect.jar into "plugins".
|
||||
|
||||
3. Add "WorldProtect" to the "plugins" line of your server.properties file.
|
||||
If it's not already there, add the line. The line should look like this:
|
||||
|
||||
plugins=WorldProtect
|
||||
|
||||
If you have multiple plugins, separate plugin names with commas.
|
||||
+39
-1
@@ -1,3 +1,7 @@
|
||||
----------------------------------------------------------------------------
|
||||
WorldGuard License
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
@@ -162,4 +166,38 @@ General Public License ever published by the Free Software Foundation.
|
||||
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.
|
||||
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
|
||||
SUCH DAMAGE.
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
<!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>
|
||||
@@ -0,0 +1,25 @@
|
||||
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.
|
||||
-110
@@ -1,110 +0,0 @@
|
||||
WorldProtect
|
||||
Copyright (c) 2010 sk89q <http://www.sk89q.com>
|
||||
Licensed under the GNU Lesser General Public License v3
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
WorldProtect has a number of features, any of which you can choose to
|
||||
use or not:
|
||||
|
||||
- Enforce only one session for a player on a server (can't login twice).
|
||||
- Block creeper explosions.
|
||||
- Block TNT explosions.
|
||||
- Block lighters from setting fires.
|
||||
- Block all fires.
|
||||
- Allow fire but prevent it from burning certain blocks.
|
||||
- Prevent lava from starting fires.
|
||||
- Restrict lava spreading to only some block types.
|
||||
- Simulate classic-esque water by letting water infinitely expand in
|
||||
area (only if there is a block underneath).
|
||||
- Simulate the sponge.
|
||||
- Block the use, destruction and/or placement of some items or block types.
|
||||
- Notify admins when a certain block type or item is used, destroyed,
|
||||
or place.
|
||||
- Log the use, destruction, and/or placement of some blocks/items.
|
||||
- Kick for the use, destruction, and/or placement of some blocks.
|
||||
|
||||
hMod is required as WorldProtect is a plugin for hMod.
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
A "worldprotect.properties" will be created the first the time that you load
|
||||
WorldProtect on your server. You can either restart your server or use
|
||||
/reloadplugin WorldProtect to reload the configuraton file after editing it.
|
||||
|
||||
- classic-water (def. false)
|
||||
Toggle use of classic water. Be foreward that your world may be
|
||||
flooded if you are not careful. If you have WorldEdit, you can use
|
||||
//drain in such an event, although that will drain the entire pool
|
||||
as well. This classic-esque water will only spread infinitely over
|
||||
ground, but if there are air blocks underneath, the water will not
|
||||
spread (preventing waterfalls from becoming tsunamis).
|
||||
|
||||
- simulate-sponge (def. false)
|
||||
Toggle simulation of the sponge. The sponge only prevents water
|
||||
from spreading. It will not take away existing water. Simulation of
|
||||
the sponge requires iterating over a 9x9x9 cuboid around the water
|
||||
block and the resource impact of this has not been quantified.
|
||||
|
||||
- enforce-single-session (def. true)
|
||||
Enforce single sessions. If the player is already found to be on
|
||||
the server when s/he logs in, the other player will be kicked with
|
||||
an informative message. The inventory will have been saved before
|
||||
the new session starts.
|
||||
|
||||
- blacklist-log-console (def. true)
|
||||
For log actions, print to console as well.
|
||||
|
||||
- blacklist-log-file (no default)
|
||||
File to log to. Log files are automatically rotated based on size, and
|
||||
you can use these patterns in the path:
|
||||
%t the system temporary directory
|
||||
%h the value of the "user.home" system property
|
||||
%g the generation number to distinguish rotated logs
|
||||
%u a unique number to resolve conflicts
|
||||
%% translates to a single percent sign "%"
|
||||
There is no way to put the date in the filename or rotate by date.
|
||||
|
||||
- blacklist-log-file-limit (def. 5242880)
|
||||
Size in bytes before the log file is rotated.
|
||||
|
||||
- blacklist-log-file-count (def. 10)
|
||||
Number of log files to keep in rotation at maximum.
|
||||
|
||||
- block-tnt (def. false)
|
||||
Block TNT explosions. TNT will still explode client-side but the blocks
|
||||
will be "restored" in a few seconds afterwards.
|
||||
|
||||
- block-lighter (def. false)
|
||||
Block flint and steel fires. Those with access to the commands
|
||||
/uselighter or /lighter can bypass this. /uselighter is not a real
|
||||
command; it is only used for permissions.
|
||||
|
||||
- block-creepers (def. false)
|
||||
Block creeper explosions. They will not explode client-side.
|
||||
|
||||
- disable-lava-fire (def. false)
|
||||
Prevent lava from starting fires.
|
||||
|
||||
- allowed-lava-spread-blocks (no default)
|
||||
List of block names/IDs to allow lava to spread to. Leave blank
|
||||
to disable this feature.
|
||||
|
||||
- disable-all-fire-spread (def. false)
|
||||
Disable all fire from spreading.
|
||||
|
||||
- disallowed-fire-spread-blocks (no default)
|
||||
List of block names/IDs to prevent fire from spreading to. Leave blank
|
||||
to disable this feature. Enabling disable-all-fire-spread will
|
||||
override this function.
|
||||
|
||||
- block-lag-fix (def. false)
|
||||
Attempts to fix block lag.
|
||||
|
||||
Blacklists
|
||||
----------
|
||||
|
||||
Edit the included worldprotect-blacklist.txt file and follow the
|
||||
instructions inside.
|
||||
@@ -0,0 +1,24 @@
|
||||
-- Blacklist table for MySQL.
|
||||
-- You must still configure WorldGuard to use your database.
|
||||
-- If you do not plan on using a database for logging blacklist events,
|
||||
-- you do not need to do anything with this file.
|
||||
|
||||
CREATE TABLE `blacklist_events` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`event` varchar(25) NOT NULL,
|
||||
`world` varchar(32) NOT NULL,
|
||||
`player` varchar(16) NOT NULL,
|
||||
`x` int(11) NOT NULL,
|
||||
`y` int(11) NOT NULL,
|
||||
`z` int(11) NOT NULL,
|
||||
`item` int(11) NOT NULL,
|
||||
`time` int(11) NOT NULL,
|
||||
`comment` varchar(255) NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
);
|
||||
|
||||
-- Required update if you have an older version of the table:
|
||||
|
||||
ALTER TABLE `blacklist_events` ADD `comment` VARCHAR( 255 ) NULL
|
||||
|
||||
ALTER TABLE `blacklist_events` ADD `world` VARCHAR( 32 ) NOT NULL
|
||||
@@ -1,2 +0,0 @@
|
||||
Manifest-Version: 1.0
|
||||
WorldProtect-Version: 1.1
|
||||
@@ -0,0 +1,192 @@
|
||||
<!--
|
||||
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.4</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 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/artifactory/repo</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<!-- Required component -->
|
||||
<dependency>
|
||||
<groupId>com.sk89q</groupId>
|
||||
<artifactId>worldedit</artifactId>
|
||||
<version>4.7</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Bukkit -->
|
||||
<dependency>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
<version>1.0.0-R1-SNAPSHOT</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>WorldEdit.jar 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.1</version>
|
||||
<configuration>
|
||||
<preparationGoals>assembly:assembly</preparationGoals>
|
||||
<goals>assembly:assembly</goals>
|
||||
</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,267 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldProtect
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import java.util.logging.Logger;
|
||||
import java.util.logging.Level;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class BlacklistEntry {
|
||||
/**
|
||||
* Used to prevent spamming.
|
||||
*/
|
||||
private static Map<String,Integer> lastAffected =
|
||||
new HashMap<String,Integer>();
|
||||
/**
|
||||
* Logger.
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger("WorldProtect.Blacklist");
|
||||
/**
|
||||
* List of groups to not affect.
|
||||
*/
|
||||
private Set<String> ignoreGroups;
|
||||
/**
|
||||
* List of actions to perform on destruction.
|
||||
*/
|
||||
private String[] destroyActions;
|
||||
/**
|
||||
* List of actions to perform on left click.
|
||||
*/
|
||||
private String[] leftClickActions;
|
||||
/**
|
||||
* List of actions to perform on right click.
|
||||
*/
|
||||
private String[] rightClickActions;
|
||||
|
||||
/**
|
||||
* @return the ignoreGroups
|
||||
*/
|
||||
public String[] getIgnoreGroups() {
|
||||
return ignoreGroups.toArray(new String[ignoreGroups.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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the destroyActions
|
||||
*/
|
||||
public String[] getDestroyActions() {
|
||||
return destroyActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param destroyActions the destroyActions to set
|
||||
*/
|
||||
public void setDestroyActions(String[] destroyActions) {
|
||||
this.destroyActions = destroyActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the leftClickActions
|
||||
*/
|
||||
public String[] getLeftClickActions() {
|
||||
return leftClickActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param leftClickActions the leftClickActions to set
|
||||
*/
|
||||
public void setLeftClickActions(String[] leftClickActions) {
|
||||
this.leftClickActions = leftClickActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the rightClickActions
|
||||
*/
|
||||
public String[] getRightClickActions() {
|
||||
return rightClickActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param rightClickActions the rightClickActions to set
|
||||
*/
|
||||
public void setRightClickActions(String[] rightClickActions) {
|
||||
this.rightClickActions = rightClickActions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this player should be ignored.
|
||||
*
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
public boolean shouldIgnore(Player player) {
|
||||
if (ignoreGroups == null) {
|
||||
return false;
|
||||
}
|
||||
for (String group : player.getGroups()) {
|
||||
if (ignoreGroups.contains(group.toLowerCase())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Announces a message to all administrators.
|
||||
*
|
||||
* @param str
|
||||
*/
|
||||
public void notifyAdmins(String str) {
|
||||
for (Player player : etc.getServer().getPlayerList()) {
|
||||
if (player.canUseCommand("/wprotectalerts")) {
|
||||
player.sendMessage(Colors.LightPurple + "WorldProtect: " + str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a message.
|
||||
*
|
||||
* @param message
|
||||
*/
|
||||
public void log(String message) {
|
||||
logger.log(Level.INFO, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on block destruction. Returns true to let the action pass
|
||||
* through.
|
||||
*
|
||||
* @param block
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
public boolean onDestroy(Block block, Player player) {
|
||||
if (destroyActions == null) {
|
||||
return true;
|
||||
}
|
||||
boolean ret = process(block.getType(), player, destroyActions);
|
||||
lastAffected.put(player.getName(), block.getType());
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on left click. Returns true to let the action pass through.
|
||||
*
|
||||
* @param item
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
public boolean onLeftClick(int item, Player player) {
|
||||
if (leftClickActions == null) {
|
||||
return true;
|
||||
}
|
||||
boolean ret = process(item, player, leftClickActions);
|
||||
lastAffected.put(player.getName(), item);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on right right. Returns true to let the action pass through.
|
||||
*
|
||||
* @param item
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
public boolean onRightClick(int item, Player player) {
|
||||
if (rightClickActions == null) {
|
||||
return true;
|
||||
}
|
||||
boolean ret = process(item, player, rightClickActions);
|
||||
lastAffected.put(player.getName(), item);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to handle the actions.
|
||||
*
|
||||
* @param id
|
||||
* @param player
|
||||
* @param actions
|
||||
* @return
|
||||
*/
|
||||
private boolean process(int id, Player player, String[] actions) {
|
||||
if (shouldIgnore(player)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
String name = player.getName();
|
||||
boolean repeating = lastAffected.containsKey(name)
|
||||
&& lastAffected.get(name) == id;
|
||||
|
||||
boolean ret = true;
|
||||
|
||||
for (String action : actions) {
|
||||
if (action.equalsIgnoreCase("deny")) {
|
||||
ret = false;
|
||||
} else if (action.equalsIgnoreCase("kick")) {
|
||||
player.kick("Performed disallowed action with "
|
||||
+ etc.getDataSource().getItem(id) + ".");
|
||||
} else if (!repeating) {
|
||||
if (action.equalsIgnoreCase("notify")) {
|
||||
notifyAdmins(player.getName() + " on destroy: "
|
||||
+ etc.getDataSource().getItem(id));
|
||||
} else if (action.equalsIgnoreCase("log")) {
|
||||
log(player.getName() + " on destroy: "
|
||||
+ etc.getDataSource().getItem(id));
|
||||
} else if (!repeating && action.equalsIgnoreCase("tell")) {
|
||||
player.sendMessage("Can't do that with "
|
||||
+ etc.getDataSource().getItem(id) + ".");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forget a player.
|
||||
*
|
||||
* @param player
|
||||
*/
|
||||
public static void forgetPlayer(Player player) {
|
||||
lastAffected.remove(player.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Forget all players.
|
||||
*
|
||||
* @param player
|
||||
*/
|
||||
public static void forgetAllPlayers() {
|
||||
lastAffected = new HashMap<String,Integer>();
|
||||
}
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldProtect
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import java.util.logging.Logger;
|
||||
import java.util.logging.Level;
|
||||
import java.util.jar.Manifest;
|
||||
import java.util.jar.Attributes;
|
||||
import java.net.URL;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* Entry point for the plugin for hey0's mod.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class WorldProtect extends Plugin {
|
||||
/**
|
||||
* Logger.
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger("Minecraft.WorldProtect");
|
||||
/**
|
||||
* Listener for the plugin system.
|
||||
*/
|
||||
private static final WorldProtectListener listener =
|
||||
new WorldProtectListener();
|
||||
|
||||
/**
|
||||
* Initializes the plugin.
|
||||
*/
|
||||
@Override
|
||||
public void initialize() {
|
||||
PluginLoader loader = etc.getLoader();
|
||||
|
||||
loader.addListener(PluginLoader.Hook.EXPLODE, listener, this,
|
||||
PluginListener.Priority.HIGH);
|
||||
loader.addListener(PluginLoader.Hook.IGNITE, listener, this,
|
||||
PluginListener.Priority.HIGH);
|
||||
loader.addListener(PluginLoader.Hook.FLOW, listener, this,
|
||||
PluginListener.Priority.HIGH);
|
||||
loader.addListener(PluginLoader.Hook.LOGINCHECK, listener, this,
|
||||
PluginListener.Priority.HIGH);
|
||||
loader.addListener(PluginLoader.Hook.BLOCK_CREATED, listener, this,
|
||||
PluginListener.Priority.HIGH);
|
||||
loader.addListener(PluginLoader.Hook.BLOCK_DESTROYED, listener, this,
|
||||
PluginListener.Priority.HIGH);
|
||||
loader.addListener(PluginLoader.Hook.DISCONNECT, listener, this,
|
||||
PluginListener.Priority.HIGH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the plugin.
|
||||
*/
|
||||
@Override
|
||||
public void enable() {
|
||||
listener.loadConfiguration();
|
||||
|
||||
logger.log(Level.INFO, "WorldProtect version " + getVersion() + " loaded");
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the plugin.
|
||||
*/
|
||||
@Override
|
||||
public void disable() {
|
||||
BlacklistEntry.forgetAllPlayers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the WorldProtect version.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private String getVersion() {
|
||||
try {
|
||||
String classContainer = WorldProtect.class.getProtectionDomain()
|
||||
.getCodeSource().getLocation().toString();
|
||||
URL manifestUrl = new URL("jar:" + classContainer + "!/META-INF/MANIFEST.MF");
|
||||
Manifest manifest = new Manifest(manifestUrl.openStream());
|
||||
Attributes attrib = manifest.getMainAttributes();
|
||||
String ver = (String)attrib.getValue("WorldProtect-Version");
|
||||
return ver != null ? ver : "(unavailable)";
|
||||
} catch (IOException e) {
|
||||
return "(unknown)";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,510 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldProtect
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
import java.util.logging.Logger;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Handler;
|
||||
import java.util.logging.ConsoleHandler;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
import java.io.*;
|
||||
import com.sk89q.worldprotect.*;
|
||||
import java.util.logging.FileHandler;
|
||||
|
||||
/**
|
||||
* Event listener for Hey0's server mod.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class WorldProtectListener extends PluginListener {
|
||||
/**
|
||||
* Logger.
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger("Minecraft.WorldProtect");
|
||||
/**
|
||||
* Properties file for CraftBook.
|
||||
*/
|
||||
private PropertiesFile properties = new PropertiesFile("worldprotect.properties");
|
||||
/**
|
||||
* Random number generator.
|
||||
*/
|
||||
private static Random rand = new Random();
|
||||
|
||||
private boolean enforceOneSession;
|
||||
private boolean blockCreepers;
|
||||
private boolean blockTNT;
|
||||
private boolean blockLighter;
|
||||
private boolean preventLavaFire;
|
||||
private boolean disableAllFire;
|
||||
private boolean simulateSponge;
|
||||
private boolean blockLagFix;
|
||||
private Set<Integer> fireNoSpreadBlocks;
|
||||
private Set<Integer> allowedLavaSpreadOver;
|
||||
private boolean classicWater;
|
||||
private Map<Integer,BlacklistEntry> blacklist;
|
||||
|
||||
/**
|
||||
* Convert a comma-delimited list to a set of integers.
|
||||
*
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
private static Set<Integer> toBlockIDSet(String str) {
|
||||
if (str.trim().length() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String[] items = str.split(",");
|
||||
Set<Integer> result = new HashSet<Integer>();
|
||||
|
||||
for (String item : items) {
|
||||
try {
|
||||
result.add(Integer.parseInt(item.trim()));
|
||||
} catch (NumberFormatException e) {
|
||||
int id = etc.getDataSource().getItem(item.trim());
|
||||
if (id != 0) {
|
||||
result.add(id);
|
||||
} else {
|
||||
logger.log(Level.WARNING, "WorldProtect: Unknown block name: "
|
||||
+ item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the configuration
|
||||
*/
|
||||
public void loadConfiguration() {
|
||||
properties.load();
|
||||
|
||||
enforceOneSession = properties.getBoolean("enforce-single-session", true);
|
||||
blockCreepers = properties.getBoolean("block-creepers", false);
|
||||
blockTNT = properties.getBoolean("block-tnt", false);
|
||||
blockLighter = properties.getBoolean("block-lighter", false);
|
||||
preventLavaFire = properties.getBoolean("disable-lava-fire", false);
|
||||
disableAllFire = properties.getBoolean("disable-all-fire-spread", false);
|
||||
fireNoSpreadBlocks = toBlockIDSet(properties.getString("disallowed-fire-spread-blocks", ""));
|
||||
allowedLavaSpreadOver = toBlockIDSet(properties.getString("allowed-lava-spread-blocks", ""));
|
||||
classicWater = properties.getBoolean("classic-water", false);
|
||||
simulateSponge = properties.getBoolean("simulate-sponge", false);
|
||||
blockLagFix = properties.getBoolean("block-lag-fix", false);
|
||||
|
||||
try {
|
||||
blacklist = loadBlacklist(new File("worldprotect-blacklist.txt"));
|
||||
} catch (FileNotFoundException e) {
|
||||
logger.log(Level.WARNING, "WorldProtect blacklist does not exist.");
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.WARNING, "Could not load WorldProtect blacklist: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
|
||||
Logger blacklistLogger = Logger.getLogger("WorldProtect.Blacklist");
|
||||
blacklistLogger.setUseParentHandlers(false);
|
||||
for (Handler handler : blacklistLogger.getHandlers()) {
|
||||
blacklistLogger.removeHandler(handler);
|
||||
}
|
||||
|
||||
// Blacklist log to console
|
||||
if (properties.getBoolean("blacklist-log-console", true)) {
|
||||
Handler handler = new ConsoleHandler();
|
||||
handler.setFormatter(new ConsoleLogFormat());
|
||||
blacklistLogger.addHandler(handler);
|
||||
}
|
||||
|
||||
// Blacklist log file
|
||||
String logFile = properties.getString("blacklist-log-file", "").trim();
|
||||
int limit = properties.getInt("blacklist-log-file-limit", 1024 * 1024 * 5);
|
||||
int count = properties.getInt("blacklist-log-file-count", 10);
|
||||
if (logFile.length() > 0) {
|
||||
try {
|
||||
Handler handler = new FileHandler(logFile, limit, count, true);
|
||||
handler.setFormatter(new SimpleLogFormat());
|
||||
blacklistLogger.addHandler(handler);
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.WARNING, "Could not open blacklist log file: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called during the early login process to check whether or not to kick the
|
||||
* player
|
||||
*
|
||||
* @param user
|
||||
* @return kick reason. null if you don't want to kick the player.
|
||||
*/
|
||||
public String onLoginChecks(String user) {
|
||||
if (enforceOneSession) {
|
||||
for (Player player : etc.getServer().getPlayerList()) {
|
||||
if (player.getName().equalsIgnoreCase(user)) {
|
||||
player.kick("Logged in from another location.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when someone presses right click. If they right clicked with a
|
||||
* block you can return true to cancel that. You can intercept this to add
|
||||
* your own right click actions to different item types (see itemInHand)
|
||||
*
|
||||
* @param player
|
||||
* @param blockPlaced
|
||||
* @param blockClicked
|
||||
* @param itemInHand
|
||||
* @return false if you want the action to go through
|
||||
*/
|
||||
public boolean onBlockCreate(Player player, Block blockPlaced, Block blockClicked,
|
||||
int itemInHand) {
|
||||
if (blacklist != null) {
|
||||
BlacklistEntry entry = blacklist.get(itemInHand);
|
||||
if (entry != null) {
|
||||
if (!entry.onRightClick(itemInHand, player)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a person left clicks a block.
|
||||
*
|
||||
* @param player
|
||||
* @param block
|
||||
* @return
|
||||
*/
|
||||
public boolean onBlockDestroy(Player player, Block block) {
|
||||
int type = block.getType();
|
||||
|
||||
if (blacklist != null) {
|
||||
BlacklistEntry entry = blacklist.get(player.getItemInHand());
|
||||
if (entry != null) {
|
||||
if (entry.onLeftClick(player.getItemInHand(), player)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
entry = blacklist.get(block.getType());
|
||||
if (entry != null) {
|
||||
if (!entry.onDestroy(block, player)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (blockLagFix
|
||||
&& type != 64 // Wooden door
|
||||
&& type != 71 // Iron door
|
||||
&& type != 77 // Stone button
|
||||
&& type != 69 // Lever
|
||||
&& type != 7 // Bedrock
|
||||
&& type != 51 // Fire
|
||||
&& type != 46 // TNT
|
||||
&& type != 59 // Crops
|
||||
&& type != 62 // Burning furnace
|
||||
&& type != 50 // Torch
|
||||
&& type != 75 // Redstone torch
|
||||
&& type != 76 // Redstone torch
|
||||
) {
|
||||
|
||||
if (block.getStatus() == 3) {
|
||||
int dropped = type;
|
||||
int count = 1;
|
||||
|
||||
if (type == 1) { dropped = 4; } // Stone
|
||||
else if (type == 2) { dropped = 3; } // Grass
|
||||
else if (type == 16) { dropped = 263; } // Coal ore
|
||||
else if (type == 18) { // Leaves
|
||||
if (rand.nextDouble() > 0.95) {
|
||||
dropped = 6;
|
||||
} else {
|
||||
dropped = 0;
|
||||
}
|
||||
}
|
||||
else if (type == 47) { dropped = 0; } // Bookshelves
|
||||
else if (type == 52) { dropped = 0; } // Mob spawner
|
||||
else if (type == 53) { dropped = 5; } // Wooden stairs
|
||||
else if (type == 55) { dropped = 5; } // Redstone wire
|
||||
else if (type == 56) { dropped = 264; } // Diamond ore
|
||||
else if (type == 60) { dropped = 3; } // Soil
|
||||
else if (type == 63) { dropped = 323; } // Sign post
|
||||
else if (type == 67) { dropped = 4; } // Cobblestone stairs
|
||||
else if (type == 68) { dropped = 323; } // Wall sign
|
||||
else if (type == 73) { dropped = 331; count = 4; } // Redstone ore
|
||||
else if (type == 74) { dropped = 331; count = 4; } // Glowing redstone ore
|
||||
else if (type == 75) { dropped = 76; count = 4; } // Redstone torch
|
||||
else if (type == 79) { dropped = 0; count = 4; } // Ice
|
||||
else if (type == 82) { dropped = 337; count = 4; } // Clay
|
||||
else if (type == 83) { dropped = 338; count = 4; } // Reed
|
||||
else if (type == 89) { dropped = 348; } // Lightstone
|
||||
|
||||
if (dropped > 0) {
|
||||
etc.getServer().setBlockAt(0, block.getX(), block.getY(), block.getZ());
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
etc.getServer().dropItem(block.getX(), block.getY(), block.getZ(),
|
||||
dropped, i);
|
||||
}
|
||||
|
||||
// Drop flint with gravel
|
||||
if (type == 13) {
|
||||
if (rand.nextDouble() > 0.95) {
|
||||
etc.getServer().dropItem(block.getX(), block.getY(), block.getZ(),
|
||||
318, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when either a lava block or a lighter tryes to light something on fire.
|
||||
* block status depends on the light source:
|
||||
* 1 = lava.
|
||||
* 2 = lighter (flint + steel).
|
||||
* 3 = spread (dynamic spreading of fire).
|
||||
* @param block
|
||||
* block that the fire wants to spawn in.
|
||||
*
|
||||
* @return true if you dont want the fire to ignite.
|
||||
*/
|
||||
public boolean onIgnite(Block block, Player player) {
|
||||
if (preventLavaFire && block.getStatus() == 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (blockLighter && block.getStatus() == 2) {
|
||||
return !player.canUseCommand("/uselighter")
|
||||
&& !player.canUseCommand("/lighter");
|
||||
}
|
||||
|
||||
if (disableAllFire && block.getStatus() == 3) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (fireNoSpreadBlocks != null && block.getStatus() == 3) {
|
||||
int x = block.getX();
|
||||
int y = block.getY();
|
||||
int z = block.getZ();
|
||||
if (fireNoSpreadBlocks.contains(etc.getServer().getBlockIdAt(x, y - 1, z))
|
||||
|| fireNoSpreadBlocks.contains(etc.getServer().getBlockIdAt(x + 1, y, z))
|
||||
|| fireNoSpreadBlocks.contains(etc.getServer().getBlockIdAt(x - 1, y, z))
|
||||
|| fireNoSpreadBlocks.contains(etc.getServer().getBlockIdAt(x, y, z - 1))
|
||||
|| fireNoSpreadBlocks.contains(etc.getServer().getBlockIdAt(x, y, z + 1))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when a dynamite block or a creeper is triggerd.
|
||||
* block status depends on explosive compound:
|
||||
* 1 = dynamite.
|
||||
* 2 = creeper.
|
||||
* @param block
|
||||
* dynamite block/creeper location block.
|
||||
*
|
||||
* @return true if you dont the block to explode.
|
||||
*/
|
||||
public boolean onExplode(Block block) {
|
||||
if (blockCreepers && block.getStatus() == 2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (blockTNT && block.getStatus() == 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when lava wants to flow to a certain block.
|
||||
* block status represents the type that wants to flow.
|
||||
* (10 & 11 for lava and 8 & 9 for water)
|
||||
*
|
||||
* @param block
|
||||
* the block beneath where the substance wants to flow to.
|
||||
*
|
||||
* for example:
|
||||
* lava want to flow to block x,y,z then the param block is the block x,y-1,z.
|
||||
*
|
||||
* @return true if you dont want the substance to flow.
|
||||
*/
|
||||
public boolean onFlow(Block block) {
|
||||
if (simulateSponge && (block.getStatus() == 8 || block.getStatus() == 9)) {
|
||||
int ox = block.getX();
|
||||
int oy = block.getY() + 1;
|
||||
int oz = block.getZ();
|
||||
|
||||
Server server = etc.getServer();
|
||||
|
||||
for (int x = -4; x <= 4; x++) {
|
||||
for (int y = -4; y <= 4; y++) {
|
||||
for (int z = -4; z <= 4; z++) {
|
||||
if (server.getBlockIdAt(ox + x, oy + y, oz + z) == 19) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (classicWater && (block.getStatus() == 8 || block.getStatus() == 9)) {
|
||||
int blockBelow = etc.getServer().getBlockIdAt(block.getX(), block.getY(), block.getZ());
|
||||
if (blockBelow != 0 && blockBelow != 8 && blockBelow != 9) {
|
||||
etc.getServer().setBlockAt(9, block.getX(), block.getY() + 1, block.getZ());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (allowedLavaSpreadOver != null && (block.getStatus() == 10 || block.getStatus() == 11)) {
|
||||
if (!allowedLavaSpreadOver.contains(block.getType())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on player disconnect
|
||||
*
|
||||
* @param player
|
||||
*/
|
||||
public void onDisconnect(Player player) {
|
||||
BlacklistEntry.forgetPlayer(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the blacklist.
|
||||
*
|
||||
* @param file
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public Map<Integer,BlacklistEntry> loadBlacklist(File file)
|
||||
throws IOException {
|
||||
FileReader input = null;
|
||||
Map<Integer,BlacklistEntry> blacklist = new HashMap<Integer,BlacklistEntry>();
|
||||
|
||||
try {
|
||||
input = new FileReader(file);
|
||||
BufferedReader buff = new BufferedReader(input);
|
||||
|
||||
String line;
|
||||
List<BlacklistEntry> entries = 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(",");
|
||||
entries = new ArrayList<BlacklistEntry>();
|
||||
|
||||
for (String item : items) {
|
||||
int id = 0;
|
||||
|
||||
try {
|
||||
id = Integer.parseInt(item.trim());
|
||||
} catch (NumberFormatException e) {
|
||||
id = etc.getDataSource().getItem(item.trim());
|
||||
if (id == 0) {
|
||||
logger.log(Level.WARNING, "WorldProtect: Unknown block name: "
|
||||
+ item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BlacklistEntry entry = new BlacklistEntry();
|
||||
blacklist.put(id, entry);
|
||||
entries.add(entry);
|
||||
}
|
||||
} else if (entries != 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 : entries) {
|
||||
if (parts[0].equalsIgnoreCase("ignore-groups")) {
|
||||
entry.setIgnoreGroups(parts[1].split(","));
|
||||
} else if(parts[0].equalsIgnoreCase("on-destroy")) {
|
||||
entry.setDestroyActions(parts[1].split(","));
|
||||
} else if(parts[0].equalsIgnoreCase("on-left")) {
|
||||
entry.setLeftClickActions(parts[1].split(","));
|
||||
} else if(parts[0].equalsIgnoreCase("on-right")) {
|
||||
entry.setRightClickActions(parts[1].split(","));
|
||||
} 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 + "'");
|
||||
}
|
||||
}
|
||||
|
||||
return blacklist.isEmpty() ? null : blacklist;
|
||||
} finally {
|
||||
try {
|
||||
if (input != null) {
|
||||
input.close();
|
||||
}
|
||||
} catch (IOException e2) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldProtect
|
||||
* 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.worldprotect;
|
||||
|
||||
import java.util.logging.Formatter;
|
||||
import java.util.logging.LogRecord;
|
||||
import java.util.logging.Level;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
/**
|
||||
* Used for formatting.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class ConsoleLogFormat extends Formatter {
|
||||
public String format(LogRecord record) {
|
||||
StringBuilder text = new StringBuilder();
|
||||
Level level = record.getLevel();
|
||||
|
||||
if (level == Level.FINEST) {
|
||||
text.append("[FINEST] ");
|
||||
} else if (level == Level.FINER) {
|
||||
text.append("[FINER] ");
|
||||
} else if (level == Level.FINE) {
|
||||
text.append("[FINE] ");
|
||||
} else if (level == Level.INFO) {
|
||||
text.append("[INFO] ");
|
||||
} else if (level == Level.WARNING) {
|
||||
text.append("[WARNING] ");
|
||||
} else if (level == Level.SEVERE) {
|
||||
text.append("[SEVERE] ");
|
||||
}
|
||||
|
||||
text.append(record.getMessage());
|
||||
text.append("\r\n");
|
||||
|
||||
Throwable t = record.getThrown();
|
||||
if (t != null) {
|
||||
StringWriter writer = new StringWriter();
|
||||
t.printStackTrace(new PrintWriter(writer));
|
||||
text.append(writer.toString());
|
||||
}
|
||||
|
||||
return text.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?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>
|
||||
@@ -0,0 +1,96 @@
|
||||
// $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();
|
||||
}
|
||||
}
|
||||
+35
-47
@@ -1,47 +1,35 @@
|
||||
// $Id$
|
||||
/*
|
||||
* WorldProtect
|
||||
* 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.worldprotect;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.logging.Formatter;
|
||||
import java.util.logging.LogRecord;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* Used for formatting.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class SimpleLogFormat extends Formatter {
|
||||
private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
public String format(LogRecord record) {
|
||||
StringBuilder text = new StringBuilder();
|
||||
Level level = record.getLevel();
|
||||
|
||||
text.append("[");
|
||||
text.append(dateFormat.format(new Date(record.getMillis())));
|
||||
text.append("] ");
|
||||
text.append(record.getMessage());
|
||||
text.append("\r\n");
|
||||
|
||||
return text.toString();
|
||||
}
|
||||
}
|
||||
// $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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,333 @@
|
||||
// $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 {
|
||||
/**
|
||||
* Logger.
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger("Minecraft.WorldGuard");
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
public Blacklist(Boolean useAsWhitelist) {
|
||||
this.useAsWhitelist = useAsWhitelist;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, "WorldGuard: 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 + "";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,425 @@
|
||||
// $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 + "";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
// $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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
// $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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
// $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();
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// $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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// $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";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// $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";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// $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";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// $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";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// $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";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// $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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// $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";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// $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";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
// $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();
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
// $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 {
|
||||
/**
|
||||
* Logger.
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger("Minecraft.WorldGuard");
|
||||
|
||||
|
||||
private String worldName;
|
||||
|
||||
public ConsoleLoggerHandler(String worldName)
|
||||
{
|
||||
this.worldName = worldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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, "WorldGuard: [" + 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, "WorldGuard: [" + 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, "WorldGuard: [" + 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, "WorldGuard: [" + 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, "WorldGuard: [" + 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, "WorldGuard: [" + 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, "WorldGuard: [" + worldName + "] " + event.getPlayer().getName()
|
||||
+ " tried to use " + getFriendlyItemName(evt.getType())
|
||||
+ (comment != null ? " (" + comment + ")" : ""));
|
||||
|
||||
// Unknown
|
||||
} else {
|
||||
logger.log(Level.INFO, "WorldGuard: [" + 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() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
// $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 {
|
||||
/**
|
||||
* Logger.
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger("Minecraft.WorldGuard");
|
||||
|
||||
/**
|
||||
* DSN.
|
||||
*/
|
||||
private String dsn;
|
||||
/**
|
||||
* Username.
|
||||
*/
|
||||
private String user;
|
||||
/**
|
||||
* Password.
|
||||
*/
|
||||
private String pass;
|
||||
/**
|
||||
* Table.
|
||||
*/
|
||||
private String table;
|
||||
/**
|
||||
* World name.
|
||||
*/
|
||||
private String worldName;
|
||||
/**
|
||||
* Database connection.
|
||||
*/
|
||||
private Connection conn;
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
this.dsn = dsn;
|
||||
this.user = user;
|
||||
this.pass = pass;
|
||||
this.table = table;
|
||||
this.worldName = worldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 name
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @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) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,330 @@
|
||||
// $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;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.sk89q.worldedit.Vector;
|
||||
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 FileLoggerHandler implements BlacklistLoggerHandler {
|
||||
/**
|
||||
* Logger.
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger("Minecraft.WorldGuard");
|
||||
/**
|
||||
* Regex for patterns in the path.
|
||||
*/
|
||||
private static Pattern pattern = Pattern.compile("%.");
|
||||
/**
|
||||
* Date format.
|
||||
*/
|
||||
private static SimpleDateFormat dateFormat =
|
||||
new SimpleDateFormat("yyyyy-MM-dd HH:mm:ss");
|
||||
|
||||
/**
|
||||
* Number of files to keep open at a time.
|
||||
*/
|
||||
private int cacheSize = 10;
|
||||
/**
|
||||
* Path pattern.
|
||||
*/
|
||||
private String pathPattern;
|
||||
/**
|
||||
* World name.
|
||||
*/
|
||||
private String worldName;
|
||||
/**
|
||||
* Cache of writers.
|
||||
*/
|
||||
private TreeMap<String,FileLoggerWriter> writers =
|
||||
new TreeMap<String,FileLoggerWriter>();
|
||||
|
||||
/**
|
||||
* Construct the object.
|
||||
*
|
||||
* @param pathPattern
|
||||
* @param worldName
|
||||
*/
|
||||
public FileLoggerHandler(String pathPattern, String worldName) {
|
||||
this.pathPattern = pathPattern;
|
||||
this.worldName = worldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the object.
|
||||
*
|
||||
* @param pathPattern
|
||||
* @param cacheSize
|
||||
* @param worldName
|
||||
*/
|
||||
public FileLoggerHandler(String pathPattern, int cacheSize, String worldName) {
|
||||
if (cacheSize < 1) {
|
||||
throw new IllegalArgumentException("Cache size cannot be less than 1");
|
||||
}
|
||||
this.pathPattern = pathPattern;
|
||||
this.cacheSize = cacheSize;
|
||||
this.worldName = worldName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the path.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private String buildPath(String playerName) {
|
||||
GregorianCalendar calendar = new GregorianCalendar();
|
||||
|
||||
Matcher m = pattern.matcher(pathPattern);
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
|
||||
// Pattern replacements
|
||||
while (m.find()) {
|
||||
String group = m.group();
|
||||
String rep = "?";
|
||||
|
||||
if (group.matches("%%")) {
|
||||
rep = "%";
|
||||
} else if (group.matches("%u")) {
|
||||
rep = playerName.toLowerCase().replaceAll("[^A-Za-z0-9_]", "_");
|
||||
if (rep.length() > 32) { // Actual max length is 16
|
||||
rep = rep.substring(0, 32);
|
||||
}
|
||||
|
||||
}else if (group.matches("%w")) {
|
||||
rep = worldName.toLowerCase().replaceAll("[^A-Za-z0-9_]", "_");
|
||||
if (rep.length() > 32) { // Actual max length is 16
|
||||
rep = rep.substring(0, 32);
|
||||
}
|
||||
|
||||
// Date and time
|
||||
} else if (group.matches("%Y")) {
|
||||
rep = String.valueOf(calendar.get(Calendar.YEAR));
|
||||
} else if (group.matches("%m")) {
|
||||
rep = String.format("%02d", calendar.get(Calendar.MONTH));
|
||||
} else if (group.matches("%d")) {
|
||||
rep = String.format("%02d", calendar.get(Calendar.DAY_OF_MONTH));
|
||||
} else if (group.matches("%W")) {
|
||||
rep = String.format("%02d", calendar.get(Calendar.WEEK_OF_YEAR));
|
||||
} else if (group.matches("%H")) {
|
||||
rep = String.format("%02d", calendar.get(Calendar.HOUR_OF_DAY));
|
||||
} else if (group.matches("%h")) {
|
||||
rep = String.format("%02d", calendar.get(Calendar.HOUR));
|
||||
} else if (group.matches("%i")) {
|
||||
rep = String.format("%02d", calendar.get(Calendar.MINUTE));
|
||||
} else if (group.matches("%s")) {
|
||||
rep = String.format("%02d", calendar.get(Calendar.SECOND));
|
||||
}
|
||||
|
||||
m.appendReplacement(buffer, rep);
|
||||
}
|
||||
|
||||
m.appendTail(buffer);
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a message.
|
||||
*
|
||||
* @param player
|
||||
* @param message
|
||||
*/
|
||||
private void log(LocalPlayer player, String message, String comment) {
|
||||
String path = buildPath(player.getName());
|
||||
try {
|
||||
String date = dateFormat.format(new Date());
|
||||
String line = "[" + date + "] " + player.getName() + ": " + message
|
||||
+ (comment != null ? " (" + comment + ")" : "") + "\r\n";
|
||||
|
||||
FileLoggerWriter writer = writers.get(path);
|
||||
|
||||
// Writer already exists!
|
||||
if (writer != null) {
|
||||
try {
|
||||
BufferedWriter out = writer.getWriter();
|
||||
out.write(line);
|
||||
out.flush();
|
||||
writer.updateLastUse();
|
||||
return;
|
||||
} catch (IOException e) {
|
||||
// Failed initial rewrite... let's re-open
|
||||
}
|
||||
}
|
||||
|
||||
// Make parent directory
|
||||
File file = new File(path);
|
||||
File parent = file.getParentFile();
|
||||
if (parent != null && !parent.exists()) {
|
||||
parent.mkdirs();
|
||||
}
|
||||
|
||||
FileWriter stream = new FileWriter(path, true);
|
||||
BufferedWriter out = new BufferedWriter(stream);
|
||||
out.write(line);
|
||||
out.flush();
|
||||
writer = new FileLoggerWriter(path, out);
|
||||
writers.put(path, writer);
|
||||
|
||||
// Check to make sure our cache doesn't get too big!
|
||||
if (writers.size() > cacheSize) {
|
||||
Iterator<Map.Entry<String,FileLoggerWriter>> it =
|
||||
writers.entrySet().iterator();
|
||||
|
||||
// Remove some entries
|
||||
for (; it.hasNext(); ) {
|
||||
Map.Entry<String,FileLoggerWriter> entry = it.next();
|
||||
try {
|
||||
entry.getValue().getWriter().close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
it.remove();
|
||||
|
||||
// Trimmed enough
|
||||
if (writers.size() <= cacheSize) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.WARNING, "Failed to log blacklist event to '"
|
||||
+ path + "': " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the coordinates in text form for the log.
|
||||
*
|
||||
* @param pos
|
||||
* @return
|
||||
*/
|
||||
private String getCoordinates(Vector pos) {
|
||||
return "@" + pos.getBlockX() + "," + pos.getBlockY() + "," + pos.getBlockZ();
|
||||
}
|
||||
|
||||
private void logEvent(BlacklistEvent event, String text, int id, Vector pos, String comment) {
|
||||
log(event.getPlayer(), "Tried to " + text + " " + getFriendlyItemName(id)
|
||||
+ " " + getCoordinates(pos), comment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log an event.
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
public void logEvent(BlacklistEvent event, String comment) {
|
||||
// Block break
|
||||
if (event instanceof BlockBreakBlacklistEvent) {
|
||||
BlockBreakBlacklistEvent evt = (BlockBreakBlacklistEvent)event;
|
||||
logEvent(event, "break", evt.getType(), evt.getPosition(), comment);
|
||||
|
||||
// Block place
|
||||
} else if (event instanceof BlockPlaceBlacklistEvent) {
|
||||
BlockPlaceBlacklistEvent evt = (BlockPlaceBlacklistEvent)event;
|
||||
logEvent(event, "place", evt.getType(), evt.getPosition(), comment);
|
||||
|
||||
// Block interact
|
||||
} else if (event instanceof BlockInteractBlacklistEvent) {
|
||||
BlockInteractBlacklistEvent evt = (BlockInteractBlacklistEvent)event;
|
||||
logEvent(event, "interact with", evt.getType(), evt.getPosition(), comment);
|
||||
|
||||
// Destroy with
|
||||
} else if (event instanceof DestroyWithBlacklistEvent) {
|
||||
DestroyWithBlacklistEvent evt = (DestroyWithBlacklistEvent)event;
|
||||
logEvent(event, "destroy with", evt.getType(), evt.getPosition(), comment);
|
||||
|
||||
// Acquire
|
||||
} else if (event instanceof ItemAcquireBlacklistEvent) {
|
||||
ItemAcquireBlacklistEvent evt = (ItemAcquireBlacklistEvent)event;
|
||||
logEvent(event, "acquire", evt.getType(), evt.getPosition(), comment);
|
||||
|
||||
// Drop
|
||||
} else if (event instanceof ItemDropBlacklistEvent) {
|
||||
ItemDropBlacklistEvent evt = (ItemDropBlacklistEvent)event;
|
||||
logEvent(event, "drop", evt.getType(), evt.getPosition(), comment);
|
||||
|
||||
// Use
|
||||
} else if (event instanceof ItemUseBlacklistEvent) {
|
||||
ItemUseBlacklistEvent evt = (ItemUseBlacklistEvent)event;
|
||||
logEvent(event, "use", evt.getType(), evt.getPosition(), comment);
|
||||
|
||||
// Unknown
|
||||
} else {
|
||||
log(event.getPlayer(), "Unknown event: "
|
||||
+ event.getClass().getCanonicalName(), comment);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 handles.
|
||||
*/
|
||||
public void close() {
|
||||
for (Map.Entry<String,FileLoggerWriter> entry : writers.entrySet()) {
|
||||
try {
|
||||
entry.getValue().getWriter().close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
writers.clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
// $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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// $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);
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void broadcastNotification(String msg) {
|
||||
plugin.broadcastNotification(msg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
// $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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
// $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 org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
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(Material.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).getType() == Material.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));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
// $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.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.config.Configuration;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* List of people with god mode.
|
||||
*/
|
||||
private Set<String> hasGodMode = new HashSet<String>();
|
||||
|
||||
/**
|
||||
* List of people who can breathe underwater.
|
||||
*/
|
||||
private Set<String> hasAmphibious = new HashSet<String>();
|
||||
|
||||
public boolean suppressTickSyncWarnings;
|
||||
public boolean useRegionsScheduler;
|
||||
public boolean activityHaltToggle = false;
|
||||
public boolean autoGodMode;
|
||||
public boolean usePlayerMove;
|
||||
|
||||
/**
|
||||
* 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");
|
||||
|
||||
Configuration config = plugin.getConfiguration();
|
||||
config.load();
|
||||
|
||||
suppressTickSyncWarnings = config.getBoolean(
|
||||
"suppress-tick-sync-warnings", false);
|
||||
useRegionsScheduler = config.getBoolean(
|
||||
"regions.use-scheduler", true);
|
||||
autoGodMode = config.getBoolean(
|
||||
"auto-invincible-permission", false);
|
||||
usePlayerMove = config.getBoolean(
|
||||
"use-player-move-event", true);
|
||||
|
||||
// Load configurations for each world
|
||||
for (World world : plugin.getServer().getWorlds()) {
|
||||
get(world);
|
||||
}
|
||||
|
||||
try {
|
||||
config.setHeader(CONFIG_HEADER);
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
|
||||
config.save();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
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
|
||||
*/
|
||||
public void enableGodMode(Player player) {
|
||||
hasGodMode.add(player.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable god mode for a player.
|
||||
*
|
||||
* @param player
|
||||
*/
|
||||
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) {
|
||||
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());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
// $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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
// $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.CSVDatabase;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
|
||||
/**
|
||||
* Utility methods for porting from legacy versions.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class LegacyWorldGuardMigration {
|
||||
/**
|
||||
* Logger for messages.
|
||||
*/
|
||||
protected static final Logger logger = Logger.getLogger("Minecraft.WorldGuard");
|
||||
|
||||
/**
|
||||
* 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()) {
|
||||
logger.warning("WorldGuard: 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 {
|
||||
logger.warning("WorldGuard: blacklist.txt has been converted " +
|
||||
"for the main world at " + newPath + "");
|
||||
logger.warning("WorldGuard: 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;
|
||||
|
||||
logger.info("WorldGuard: The regions database has changed in 4.x. "
|
||||
+ "Your old regions database will be converted to the new format "
|
||||
+ "and set as your primarily 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);
|
||||
db.load();
|
||||
|
||||
// Then save the new database
|
||||
mgr.setRegions(db.getRegions());
|
||||
mgr.save();
|
||||
|
||||
oldDatabase.renameTo(new File(plugin.getDataFolder(), "regions.txt.old"));
|
||||
|
||||
logger.info("WorldGuard: Regions database converted!");
|
||||
} catch (FileNotFoundException e) {
|
||||
} catch (IOException e) {
|
||||
logger.warning("WorldGuard: 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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
// $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());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
// $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.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 true;
|
||||
} else if (regionState == StateFlag.State.DENY) {
|
||||
return false;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,337 @@
|
||||
// $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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
// $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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,560 @@
|
||||
// $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 org.bukkit.block.Block;
|
||||
import org.bukkit.entity.CreatureType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.config.Configuration;
|
||||
|
||||
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 static final Logger logger = Logger
|
||||
.getLogger("Minecraft.WorldGuard");
|
||||
|
||||
private WorldGuardPlugin plugin;
|
||||
|
||||
private String worldName;
|
||||
private Configuration parentConfig;
|
||||
private Configuration 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 enforceOneSession;
|
||||
public boolean itemDurability;
|
||||
// public boolean classicWater;
|
||||
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 blockFireballExplosions;
|
||||
public boolean blockFireballBlockDamage;
|
||||
// public int loginProtection;
|
||||
// public int spawnProtection;
|
||||
// public boolean kickOnDeath;
|
||||
// public boolean exactRespawn;
|
||||
// public boolean teleportToHome;
|
||||
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
|
||||
* @param worldName
|
||||
*/
|
||||
public WorldConfiguration(WorldGuardPlugin plugin, String worldName) {
|
||||
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 = plugin.getConfiguration();
|
||||
|
||||
plugin.createDefaultConfiguration(configFile, "config_world.yml");
|
||||
plugin.createDefaultConfiguration(blacklistFile, "blacklist.txt");
|
||||
|
||||
config = new Configuration(this.configFile);
|
||||
loadConfiguration();
|
||||
|
||||
logger.info("WorldGuard: 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() {
|
||||
config.load();
|
||||
|
||||
opPermissions = getBoolean("op-permissions", true);
|
||||
|
||||
enforceOneSession = getBoolean("protection.enforce-single-session", 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);
|
||||
|
||||
// classicWater = getBoolean("simulation.classic-water", 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);
|
||||
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);
|
||||
|
||||
// loginProtection = getInt("spawn.login-protection", 3);
|
||||
// spawnProtection = getInt("spawn.spawn-protection", 0);
|
||||
// kickOnDeath = getBoolean("spawn.kick-on-death", false);
|
||||
// exactRespawn = getBoolean("spawn.exact-respawn", false);
|
||||
// teleportToHome = getBoolean("spawn.teleport-to-home-on-death", 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) {
|
||||
logger.warning("WorldGuard: 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;
|
||||
logger.log(Level.INFO, "WorldGuard: Blacklist loaded.");
|
||||
|
||||
BlacklistLogger blacklistLogger = blist.getLogger();
|
||||
|
||||
if (logDatabase) {
|
||||
blacklistLogger.addHandler(new DatabaseLoggerHandler(dsn, user, pass, table, worldName));
|
||||
}
|
||||
|
||||
if (logConsole) {
|
||||
blacklistLogger.addHandler(new ConsoleLoggerHandler(worldName));
|
||||
}
|
||||
|
||||
if (logFile) {
|
||||
FileLoggerHandler handler =
|
||||
new FileLoggerHandler(logFilePattern, logFileCacheSize, worldName);
|
||||
blacklistLogger.addHandler(handler);
|
||||
}
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
logger.log(Level.WARNING, "WorldGuard blacklist does not exist.");
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.WARNING, "Could not load WorldGuard blacklist: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
|
||||
// Print an overview of settings
|
||||
if (getBoolean("summary-on-start", true)) {
|
||||
logger.log(Level.INFO, enforceOneSession
|
||||
? "WorldGuard: (" + worldName + ") Single session is enforced."
|
||||
: "WorldGuard: (" + worldName + ") Single session is NOT ENFORCED.");
|
||||
logger.log(Level.INFO, blockTNTExplosions
|
||||
? "WorldGuard: (" + worldName + ") TNT ignition is blocked."
|
||||
: "WorldGuard: (" + worldName + ") TNT ignition is PERMITTED.");
|
||||
logger.log(Level.INFO, blockLighter
|
||||
? "WorldGuard: (" + worldName + ") Lighters are blocked."
|
||||
: "WorldGuard: (" + worldName + ") Lighters are PERMITTED.");
|
||||
logger.log(Level.INFO, preventLavaFire
|
||||
? "WorldGuard: (" + worldName + ") Lava fire is blocked."
|
||||
: "WorldGuard: (" + worldName + ") Lava fire is PERMITTED.");
|
||||
|
||||
if (disableFireSpread) {
|
||||
logger.log(Level.INFO, "WorldGuard: (" + worldName + ") All fire spread is disabled.");
|
||||
} else {
|
||||
if (disableFireSpreadBlocks.size() > 0) {
|
||||
logger.log(Level.INFO, "WorldGuard: (" + worldName
|
||||
+ ") Fire spread is limited to "
|
||||
+ disableFireSpreadBlocks.size() + " block types.");
|
||||
} else {
|
||||
logger.log(Level.INFO, "WorldGuard: (" + 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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,865 @@
|
||||
// $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.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.Event.Priority;
|
||||
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.BlockListener;
|
||||
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 org.bukkit.plugin.PluginManager;
|
||||
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.blocks.BlockType;
|
||||
import com.sk89q.worldedit.blocks.ItemType;
|
||||
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 extends BlockListener {
|
||||
/**
|
||||
* Logger for messages.
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger("Minecraft.WorldGuard");
|
||||
|
||||
private WorldGuardPlugin plugin;
|
||||
|
||||
/**
|
||||
* Construct the object.
|
||||
*
|
||||
* @param plugin
|
||||
*/
|
||||
public WorldGuardBlockListener(WorldGuardPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register events.
|
||||
*/
|
||||
public void registerEvents() {
|
||||
registerEvent("BLOCK_DAMAGE", Priority.High);
|
||||
registerEvent("BLOCK_BREAK", Priority.High);
|
||||
registerEvent("BLOCK_FROMTO", Priority.Normal);
|
||||
registerEvent("BLOCK_IGNITE", Priority.High);
|
||||
registerEvent("BLOCK_PHYSICS", Priority.Normal);
|
||||
registerEvent("BLOCK_PLACE", Priority.High);
|
||||
registerEvent("BLOCK_BURN", Priority.High);
|
||||
registerEvent("SIGN_CHANGE", Priority.High);
|
||||
registerEvent("REDSTONE_CHANGE", Priority.High);
|
||||
registerEvent("LEAVES_DECAY", Priority.High);
|
||||
registerEvent("BLOCK_FORM", Priority.High);
|
||||
registerEvent("BLOCK_SPREAD", Priority.High);
|
||||
registerEvent("BLOCK_FADE", Priority.High);
|
||||
registerEvent("BLOCK_PISTON_EXTEND", Priority.High);
|
||||
registerEvent("BLOCK_PISTON_RETRACT", Priority.High);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an event, but not failing if the event is not implemented.
|
||||
*
|
||||
* @param typeName
|
||||
* @param priority
|
||||
*/
|
||||
private void registerEvent(String typeName, Priority priority) {
|
||||
try {
|
||||
Event.Type type = Event.Type.valueOf(typeName);
|
||||
PluginManager pm = plugin.getServer().getPluginManager();
|
||||
pm.registerEvent(type, this, priority, plugin);
|
||||
} catch (IllegalArgumentException e) {
|
||||
logger.info("WorldGuard: Unable to register missing event type " + typeName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@Override
|
||||
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.getType() == Material.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.
|
||||
*/
|
||||
@Override
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
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.getType())) {
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
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().getType() != Material.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;
|
||||
}
|
||||
|
||||
Material below = event.getBlock().getRelative(0, -1, 0).getType();
|
||||
|
||||
if (below == Material.TNT || below == Material.SAND
|
||||
|| below == Material.GRAVEL || below == Material.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;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
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.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
Material type = event.getNewState().getType();
|
||||
|
||||
if (type == Material.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 == Material.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.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
Material fromType = event.getSource().getType();
|
||||
|
||||
if (fromType == Material.RED_MUSHROOM || fromType == Material.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 == Material.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.
|
||||
*/
|
||||
public void onBlockFade(BlockFadeEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigurationManager cfg = plugin.getGlobalStateManager();
|
||||
WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld());
|
||||
|
||||
Material type = event.getBlock().getType();
|
||||
|
||||
if (type == Material.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 == Material.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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,900 @@
|
||||
// $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 org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
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.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.Event;
|
||||
import org.bukkit.event.Event.Priority;
|
||||
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.EntityListener;
|
||||
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 org.bukkit.plugin.PluginManager;
|
||||
|
||||
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 extends EntityListener {
|
||||
/**
|
||||
* Logger for messages.
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger("Minecraft.WorldGuard");
|
||||
|
||||
private WorldGuardPlugin plugin;
|
||||
|
||||
/**
|
||||
* Construct the object;
|
||||
*
|
||||
* @param plugin
|
||||
*/
|
||||
public WorldGuardEntityListener(WorldGuardPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register events.
|
||||
*/
|
||||
public void registerEvents() {
|
||||
// PluginManager pm = plugin.getServer().getPluginManager();
|
||||
|
||||
registerEvent("ENTITY_DAMAGE", Priority.High);
|
||||
registerEvent("ENTITY_COMBUST", Priority.High);
|
||||
registerEvent("ENTITY_EXPLODE", Priority.High);
|
||||
registerEvent("EXPLOSION_PRIME", Priority.High);
|
||||
registerEvent("CREATURE_SPAWN", Priority.High);
|
||||
registerEvent("ENTITY_INTERACT", Priority.High);
|
||||
registerEvent("CREEPER_POWER", Priority.High);
|
||||
registerEvent("PIG_ZAP", Priority.High);
|
||||
registerEvent("PAINTING_BREAK", Priority.High);
|
||||
registerEvent("PAINTING_PLACE", Priority.High);
|
||||
registerEvent("ENTITY_REGAIN_HEALTH", Priority.High);
|
||||
registerEvent("ENDERMAN_PICKUP", Priority.High);
|
||||
registerEvent("ENDERMAN_PLACE", Priority.High);
|
||||
registerEvent("ENTITY_DEATH", Priority.High);
|
||||
registerEvent("FOOD_LEVEL_CHANGE", Priority.High);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an event, but not failing if the event is not implemented.
|
||||
*
|
||||
* @param typeName
|
||||
* @param priority
|
||||
*/
|
||||
private void registerEvent(String typeName, Priority priority) {
|
||||
try {
|
||||
Event.Type type = Event.Type.valueOf(typeName);
|
||||
PluginManager pm = plugin.getServer().getPluginManager();
|
||||
pm.registerEvent(type, this, priority, plugin);
|
||||
} catch (IllegalArgumentException e) {
|
||||
logger.info("WorldGuard: Unable to register missing event type " + typeName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an entity interacts with another object.
|
||||
*/
|
||||
@Override
|
||||
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.getType() == Material.SOIL) {
|
||||
if (entity instanceof Creature && wcfg.disableCreatureCropTrampling) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an entity dies.
|
||||
*/
|
||||
@Override
|
||||
public void onEntityDeath(EntityDeathEvent event) {
|
||||
WorldConfiguration wcfg = plugin.getGlobalStateManager().get(event.getEntity().getWorld());
|
||||
if (wcfg.disableExpDrops) {
|
||||
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);
|
||||
if (cfg.hasGodMode(player)) 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) {
|
||||
Vector pt = toVector(defender.getLocation());
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld());
|
||||
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
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().getType() == Material.PUMPKIN
|
||||
|| player.getInventory().getHelmet().getType() == Material.JACK_O_LANTERN)) {
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
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 LivingEntity) {
|
||||
if (wcfg.blockCreeperBlockDamage || 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.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (ent instanceof TNTPrimed) {
|
||||
if (wcfg.blockTNTBlockDamage || 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.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (ent instanceof Fireball) {
|
||||
if (wcfg.blockFireballBlockDamage || 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.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (wcfg.signChestProtection) {
|
||||
for (Block block : event.blockList()) {
|
||||
if (wcfg.isChestProtected(block)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on explosion prime
|
||||
*/
|
||||
@Override
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
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
@@ -0,0 +1,825 @@
|
||||
// $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.lang.reflect.InvocationTargetException;
|
||||
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 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.bukkit.migration.PermissionsResolverManager;
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.minecraft.util.commands.CommandPermissionsException;
|
||||
import com.sk89q.minecraft.util.commands.CommandUsageException;
|
||||
import com.sk89q.minecraft.util.commands.CommandsManager;
|
||||
import com.sk89q.minecraft.util.commands.MissingNestedCommandException;
|
||||
import com.sk89q.minecraft.util.commands.WrappedCommandException;
|
||||
import com.sk89q.minecraft.util.commands.Injector;
|
||||
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 {
|
||||
/**
|
||||
* Logger for messages.
|
||||
*/
|
||||
static final Logger logger = Logger.getLogger("Minecraft.WorldGuard");
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Processes queries for permissions information. The permissions manager
|
||||
* is from WorldEdit and it automatically handles looking up permissions
|
||||
* systems and picking the right one. WorldGuard just needs to call
|
||||
* the permission methods.
|
||||
*/
|
||||
private PermissionsResolverManager perms;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
};
|
||||
commands.setInjector(new Injector() {
|
||||
public Object getInstance(Class<?> cls) throws InvocationTargetException, IllegalAccessException, InstantiationException {
|
||||
try {
|
||||
return cls.getConstructor(WorldGuardPlugin.class).newInstance(plugin);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Register command classes
|
||||
commands.register(ToggleCommands.class);
|
||||
commands.register(ProtectionCommands.class);
|
||||
commands.register(GeneralCommands.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on plugin enable.
|
||||
*/
|
||||
public void onEnable() {
|
||||
// Need to create the plugins/WorldGuard folder
|
||||
getDataFolder().mkdirs();
|
||||
|
||||
// Set up permissions
|
||||
perms = new PermissionsResolverManager(this, getDescription().getName(), logger);
|
||||
perms.load();
|
||||
|
||||
// This must be done before configuration is laoded
|
||||
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();
|
||||
|
||||
// handle worlds separately to initialize already loaded worlds
|
||||
WorldGuardWorldListener worldListener = (new WorldGuardWorldListener(this));
|
||||
for (World world : getServer().getWorlds()) {
|
||||
worldListener.initWorld(world);
|
||||
}
|
||||
worldListener.registerEvents();
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
logger.info("WorldGuard " + this.getDescription().getVersion() + " enabled.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on plugin disable.
|
||||
*/
|
||||
public void onDisable() {
|
||||
globalRegionManager.unload();
|
||||
configuration.unload();
|
||||
this.getServer().getScheduler().cancelTasks(this);
|
||||
|
||||
logger.info("WorldGuard " + getDescription().getVersion() + " disabled.");
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 perms.inGroup(player.getName(), group);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the groups of a player.
|
||||
*
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
public String[] getGroups(Player player) {
|
||||
try {
|
||||
return perms.getGroups(player.getName());
|
||||
} 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 perms.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) {
|
||||
logger.severe(getDescription().getName() + ": 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);
|
||||
}
|
||||
|
||||
logger.info("WorldGuard: 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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
// $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.Event;
|
||||
import org.bukkit.event.vehicle.VehicleDestroyEvent;
|
||||
import org.bukkit.event.vehicle.VehicleListener;
|
||||
import org.bukkit.event.vehicle.VehicleMoveEvent;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
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 extends VehicleListener {
|
||||
|
||||
/**
|
||||
* Logger for messages.
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger("Minecraft.WorldGuard");
|
||||
|
||||
private WorldGuardPlugin plugin;
|
||||
|
||||
/**
|
||||
* Construct the object;
|
||||
*
|
||||
* @param plugin
|
||||
*/
|
||||
public WorldGuardVehicleListener(WorldGuardPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register events.
|
||||
*/
|
||||
public void registerEvents() {
|
||||
registerEvent("VEHICLE_MOVE", Event.Priority.Normal);
|
||||
registerEvent("VEHICLE_DESTROY", Event.Priority.Normal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an event, but not failing if the event is not implemented.
|
||||
*
|
||||
* @param typeName
|
||||
* @param priority
|
||||
*/
|
||||
private void registerEvent(String typeName, Event.Priority priority) {
|
||||
try {
|
||||
Event.Type type = Event.Type.valueOf(typeName);
|
||||
PluginManager pm = plugin.getServer().getPluginManager();
|
||||
pm.registerEvent(type, this, priority, plugin);
|
||||
} catch (IllegalArgumentException e) {
|
||||
logger.info("WorldGuard: Unable to register missing event type " + typeName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a vehicle is destroyed.
|
||||
*/
|
||||
@Override
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
// $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.Event;
|
||||
import org.bukkit.event.Event.Priority;
|
||||
import org.bukkit.event.weather.LightningStrikeEvent;
|
||||
import org.bukkit.event.weather.ThunderChangeEvent;
|
||||
import org.bukkit.event.weather.WeatherChangeEvent;
|
||||
import org.bukkit.event.weather.WeatherListener;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
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 extends WeatherListener {
|
||||
|
||||
/**
|
||||
* Logger for messages.
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger("Minecraft.WorldGuard");
|
||||
|
||||
/**
|
||||
* Plugin.
|
||||
*/
|
||||
private WorldGuardPlugin plugin;
|
||||
|
||||
/**
|
||||
* Construct the object;
|
||||
*
|
||||
* @param plugin
|
||||
*/
|
||||
public WorldGuardWeatherListener(WorldGuardPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public void registerEvents() {
|
||||
// PluginManager pm = plugin.getServer().getPluginManager();
|
||||
|
||||
registerEvent("LIGHTNING_STRIKE", Priority.High);
|
||||
registerEvent("THUNDER_CHANGE", Priority.High);
|
||||
registerEvent("WEATHER_CHANGE", Priority.High);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an event, but not failing if the event is not implemented.
|
||||
*
|
||||
* @param typeName
|
||||
* @param priority
|
||||
*/
|
||||
private void registerEvent(String typeName, Priority priority) {
|
||||
try {
|
||||
Event.Type type = Event.Type.valueOf(typeName);
|
||||
PluginManager pm = plugin.getServer().getPluginManager();
|
||||
pm.registerEvent(type, this, priority, plugin);
|
||||
} catch (IllegalArgumentException e) {
|
||||
logger.info("WorldGuard: Unable to register missing event type " + typeName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
// $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.Event;
|
||||
import org.bukkit.event.world.ChunkLoadEvent;
|
||||
import org.bukkit.event.world.WorldListener;
|
||||
import org.bukkit.event.world.WorldLoadEvent;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
public class WorldGuardWorldListener extends WorldListener {
|
||||
|
||||
/**
|
||||
* Logger for messages.
|
||||
*/
|
||||
private static final Logger logger = Logger.getLogger("Minecraft.WorldGuard");
|
||||
|
||||
private WorldGuardPlugin plugin;
|
||||
|
||||
/**
|
||||
* Construct the object;
|
||||
*
|
||||
* @param plugin
|
||||
*/
|
||||
public WorldGuardWorldListener(WorldGuardPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register events.
|
||||
*/
|
||||
public void registerEvents() {
|
||||
// PluginManager pm = plugin.getServer().getPluginManager();
|
||||
|
||||
registerEvent("CHUNK_LOAD", Event.Priority.Normal);
|
||||
registerEvent("WORLD_LOAD", Event.Priority.Normal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an event, but not failing if the event is not implemented.
|
||||
*
|
||||
* @param typeName
|
||||
* @param priority
|
||||
*/
|
||||
private void registerEvent(String typeName, Event.Priority priority) {
|
||||
try {
|
||||
Event.Type type = Event.Type.valueOf(typeName);
|
||||
PluginManager pm = plugin.getServer().getPluginManager();
|
||||
pm.registerEvent(type, this, priority, plugin);
|
||||
} catch (IllegalArgumentException e) {
|
||||
logger.info("WorldGuard: Unable to register missing event type " + typeName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a chunk is loaded.
|
||||
*/
|
||||
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) {
|
||||
logger.info("WG Halt-Act: " + removed + " entities (>50) auto-removed from "
|
||||
+ event.getChunk().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a world is loaded.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
// $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;
|
||||
}
|
||||
|
||||
@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.");
|
||||
}
|
||||
}
|
||||
|
||||
@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!");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
// $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"}, desc = "Region management commands")
|
||||
@NestedCommand({RegionCommands.class, RegionMemberCommands.class})
|
||||
public void region(CommandContext args, CommandSender sender) {}
|
||||
|
||||
@Command(aliases = {"worldguard"}, desc = "WorldGuard commands")
|
||||
@NestedCommand({WorldGuardCommands.class})
|
||||
public void worldGuard(CommandContext args, CommandSender sender) {}
|
||||
}
|
||||
@@ -0,0 +1,923 @@
|
||||
// $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.IOException;
|
||||
import java.util.Arrays;
|
||||
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.util.RegionUtil;
|
||||
|
||||
public class RegionCommands {
|
||||
private final WorldGuardPlugin plugin;
|
||||
|
||||
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 (IOException e) {
|
||||
throw new CommandException("Failed to write regions file: "
|
||||
+ 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 (IOException e) {
|
||||
throw new CommandException("Failed to write regions file: "
|
||||
+ 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 (IOException e) {
|
||||
throw new CommandException("Failed to write regions file: "
|
||||
+ 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 (IOException e) {
|
||||
throw new CommandException("Failed to write regions file: "
|
||||
+ 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 (IOException e) {
|
||||
throw new CommandException("Failed to write regions file: "
|
||||
+ 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 (IOException e) {
|
||||
throw new CommandException("Failed to write regions file: "
|
||||
+ 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 (IOException e) {
|
||||
throw new CommandException("Failed to write regions file: "
|
||||
+ 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 (IOException e) {
|
||||
throw new CommandException("Failed to read regions file: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
} else {
|
||||
for (World w : plugin.getServer().getWorlds()) {
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(w);
|
||||
|
||||
try {
|
||||
mgr.load();
|
||||
} catch (IOException e) {
|
||||
throw new CommandException("Failed to read regions file: "
|
||||
+ 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 (IOException e) {
|
||||
throw new CommandException("Failed to write regions file: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
} else {
|
||||
for (World w : plugin.getServer().getWorlds()) {
|
||||
RegionManager mgr = plugin.getGlobalRegionManager().get(w);
|
||||
|
||||
try {
|
||||
mgr.save();
|
||||
} catch (IOException e) {
|
||||
throw new CommandException("Failed to write regions file: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
sender.sendMessage(ChatColor.YELLOW
|
||||
+ "Region databases saved.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
// $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.IOException;
|
||||
|
||||
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.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 (IOException e) {
|
||||
throw new CommandException("Failed to write regions file: "
|
||||
+ 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 (IOException e) {
|
||||
throw new CommandException("Failed to write regions file: "
|
||||
+ 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 (IOException e) {
|
||||
throw new CommandException("Failed to write regions file: "
|
||||
+ 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 (IOException e) {
|
||||
throw new CommandException("Failed to write regions file: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
// $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"},
|
||||
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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
// $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() + "\".");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
// $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
|
||||
*/
|
||||
public boolean isChest(Material material);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
// $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.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.getType())) {
|
||||
Block below = block.getRelative(0, -1, 0);
|
||||
return isProtectedSignAround(below, player);
|
||||
} else if (block.getType() == Material.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 == true) return res;
|
||||
|
||||
side = searchBlock.getRelative(-1, 0, 0);
|
||||
res = isProtectedSignAndChest(side, player);
|
||||
if (res != null && res == true) return res;
|
||||
|
||||
side = searchBlock.getRelative(1, 0, 0);
|
||||
res = isProtectedSignAndChest(side, player);
|
||||
if (res != null && res == true) return res;
|
||||
|
||||
side = searchBlock.getRelative(0, 0, -1);
|
||||
res = isProtectedSignAndChest(side, player);
|
||||
if (res != null && res == true) return res;
|
||||
|
||||
side = searchBlock.getRelative(0, 0, 1);
|
||||
res = isProtectedSignAndChest(side, player);
|
||||
if (res != null && res == true) 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).getType())) {
|
||||
return null;
|
||||
}
|
||||
return isProtectedSign(block, player);
|
||||
}
|
||||
|
||||
private boolean isProtectedSignAndChestBinary(Block block, Player player) {
|
||||
Boolean res = isProtectedSignAndChest(block, player);
|
||||
if (res == null || res == false) {
|
||||
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;
|
||||
}
|
||||
|
||||
public boolean isChest(Material material) {
|
||||
return material == Material.CHEST
|
||||
|| material == Material.DISPENSER
|
||||
|| material == Material.FURNACE
|
||||
|| material == Material.BURNING_FURNACE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
// $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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
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);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
// $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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
// $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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
// $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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,395 @@
|
||||
// $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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,302 @@
|
||||
// $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.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
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.YAMLDatabase;
|
||||
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 {
|
||||
|
||||
private static final Logger logger = Logger.getLogger("Minecraft.WorldGuard");
|
||||
|
||||
/**
|
||||
* 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();
|
||||
File file = getPath(name);
|
||||
|
||||
try {
|
||||
// Create a manager
|
||||
RegionManager manager = new FlatRegionManager(new YAMLDatabase(file));
|
||||
managers.put(name, manager);
|
||||
manager.load();
|
||||
|
||||
logger.info("WorldGuard: " + manager.getRegions().size()
|
||||
+ " regions loaded for '" + name + "'");
|
||||
|
||||
// Store the last modification date so we can track changes
|
||||
lastModified.put(name, file.lastModified());
|
||||
|
||||
return manager;
|
||||
} catch (FileNotFoundException e) { // this should no longer happen hopefully
|
||||
logger.info("WorldGuard: Region file for world \""
|
||||
+ name + "\" missing or inaccessible.");
|
||||
} catch (IOException e) {
|
||||
logger.info("WorldGuard: Failed to load regions from file "
|
||||
+ file.getAbsolutePath() + " : " + e.getMessage());
|
||||
} catch (Exception e) {
|
||||
logger.info("WorldGuard: Error loading regions for world \""
|
||||
+ name + "\":" + e.getMessage());
|
||||
}
|
||||
|
||||
// @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() {
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// $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;
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
// $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.IOException;
|
||||
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
|
||||
public abstract class AbstractProtectionDatabase implements ProtectionDatabase {
|
||||
|
||||
/**
|
||||
* Load the list of regions into a region manager.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public void load(RegionManager manager) throws IOException {
|
||||
load();
|
||||
manager.setRegions(getRegions());
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the list of regions from a region manager.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public void save(RegionManager manager) throws IOException {
|
||||
setRegions(manager.getRegions());
|
||||
save();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,348 @@
|
||||
// $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 static Logger logger = Logger.getLogger("Minecraft.WorldGuard");
|
||||
|
||||
/**
|
||||
* References the CSV file.
|
||||
*/
|
||||
private 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) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the database.
|
||||
*/
|
||||
public void save() throws IOException {
|
||||
throw new UnsupportedOperationException("CSV format is no longer implemented");
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the database from file.
|
||||
*/
|
||||
public void load() throws IOException {
|
||||
Map<String,ProtectedRegion> regions =
|
||||
new HashMap<String,ProtectedRegion>();
|
||||
Map<ProtectedRegion,String> parentSets =
|
||||
new LinkedHashMap<ProtectedRegion, String>();
|
||||
|
||||
CSVReader reader = new CSVReader(new FileReader(file));
|
||||
|
||||
try {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
// $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.IOException;
|
||||
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 IOException
|
||||
*/
|
||||
public void load() throws IOException;
|
||||
/**
|
||||
* Save the list of regions.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public void save() throws IOException;
|
||||
/**
|
||||
* Load the list of regions into a region manager.
|
||||
*
|
||||
* @param manager
|
||||
* @throws IOException
|
||||
*/
|
||||
public void load(RegionManager manager) throws IOException;
|
||||
/**
|
||||
* Save the list of regions from a region manager.
|
||||
*
|
||||
* @param manager
|
||||
* @throws IOException
|
||||
*/
|
||||
public void save(RegionManager manager) throws IOException;
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
// $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.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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
// $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.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.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;
|
||||
import com.sk89q.worldguard.util.yaml.Configuration;
|
||||
import com.sk89q.worldguard.util.yaml.ConfigurationNode;
|
||||
|
||||
public class YAMLDatabase extends AbstractProtectionDatabase {
|
||||
|
||||
private static Logger logger = Logger.getLogger("Minecraft.WorldGuard");
|
||||
|
||||
private Configuration config;
|
||||
private Map<String, ProtectedRegion> regions;
|
||||
|
||||
public YAMLDatabase(File file) {
|
||||
if (!file.exists()) { // shouldn't be necessary, but check anyways
|
||||
try {
|
||||
file.createNewFile();
|
||||
} catch (IOException e) {}
|
||||
// if this is thrown, we can't do anything (caught elsewhere anyway)
|
||||
}
|
||||
config = new Configuration(file);
|
||||
}
|
||||
|
||||
public void load() throws IOException {
|
||||
config.load();
|
||||
|
||||
Map<String, ConfigurationNode> 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, ConfigurationNode> entry : regionData.entrySet()) {
|
||||
String id = entry.getKey().toLowerCase().replace(".", "");
|
||||
ConfigurationNode 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, ConfigurationNode 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(ConfigurationNode 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 IOException {
|
||||
config.clear();
|
||||
|
||||
for (Map.Entry<String, ProtectedRegion> entry : regions.entrySet()) {
|
||||
ProtectedRegion region = entry.getValue();
|
||||
ConfigurationNode 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
// $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 BooleanFlag extends Flag<Boolean> {
|
||||
|
||||
public BooleanFlag(String name, char legacyCode) {
|
||||
super(name, legacyCode);
|
||||
}
|
||||
|
||||
public BooleanFlag(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean parseInput(WorldGuardPlugin plugin, CommandSender sender,
|
||||
String input) throws InvalidFlagFormat {
|
||||
input = input.trim();
|
||||
|
||||
if (input.equalsIgnoreCase("true") || input.equalsIgnoreCase("yes")
|
||||
|| input.equalsIgnoreCase("on")
|
||||
|| input.equalsIgnoreCase("1")) {
|
||||
return true;
|
||||
} else if (input.equalsIgnoreCase("false") || input.equalsIgnoreCase("no")
|
||||
|| input.equalsIgnoreCase("off")
|
||||
|| input.equalsIgnoreCase("0")) {
|
||||
return false;
|
||||
} else {
|
||||
throw new InvalidFlagFormat("Not a yes/no value: " + input);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean unmarshal(Object o) {
|
||||
if (o instanceof Boolean) {
|
||||
return (Boolean) o;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object marshal(Boolean o) {
|
||||
return o;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
// $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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
// $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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
// $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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public final class DefaultFlag {
|
||||
|
||||
public static final StateFlag PASSTHROUGH = new StateFlag("passthrough", 'z', false);
|
||||
public static final StateFlag BUILD = new StateFlag("build", 'b', true);
|
||||
public static final StateFlag PVP = new StateFlag("pvp", 'p', true);
|
||||
public static final StateFlag MOB_DAMAGE = new StateFlag("mob-damage", 'm', true);
|
||||
public static final StateFlag MOB_SPAWNING = new StateFlag("mob-spawning", true);
|
||||
public static final StateFlag CREEPER_EXPLOSION = new StateFlag("creeper-explosion", 'c', true);
|
||||
public static final StateFlag GHAST_FIREBALL = new StateFlag("ghast-fireball", true);
|
||||
public static final StateFlag SLEEP = new StateFlag("sleep", true);
|
||||
public static final StateFlag TNT = new StateFlag("tnt", 't', true);
|
||||
public static final StateFlag LIGHTER = new StateFlag("lighter", 'l', true);
|
||||
public static final StateFlag FIRE_SPREAD = new StateFlag("fire-spread", 'f', true);
|
||||
public static final StateFlag LAVA_FIRE = new StateFlag("lava-fire", 'F', true);
|
||||
public static final StateFlag LIGHTNING = new StateFlag("lightning", true);
|
||||
public static final StateFlag CHEST_ACCESS = new StateFlag("chest-access", 'C', false);
|
||||
public static final StateFlag WATER_FLOW = new StateFlag("water-flow", true);
|
||||
public static final StateFlag LAVA_FLOW = new StateFlag("lava-flow", true);
|
||||
public static final StateFlag USE = new StateFlag("use", true);
|
||||
public static final StateFlag PLACE_VEHICLE = new StateFlag("vehicle-place", false);
|
||||
public static final StateFlag DESTROY_VEHICLE = new StateFlag("vehicle-destroy", false);
|
||||
public static final StateFlag PISTONS = new StateFlag("pistons", true);
|
||||
public static final StateFlag SNOW_FALL = new StateFlag("snow-fall", true);
|
||||
public static final StateFlag SNOW_MELT = new StateFlag("snow-melt", true);
|
||||
public static final StateFlag ICE_FORM = new StateFlag("ice-form", true);
|
||||
public static final StateFlag ICE_MELT = new StateFlag("ice-melt", true);
|
||||
public static final StateFlag MUSHROOMS = new StateFlag("mushroom-growth", true);
|
||||
public static final StateFlag LEAF_DECAY = new StateFlag("leaf-decay", true);
|
||||
public static final StateFlag GRASS_SPREAD = new StateFlag("grass-growth", true);
|
||||
public static final StateFlag ENDER_BUILD = new StateFlag("enderman-grief", true);
|
||||
public static final StateFlag INVINCIBILITY = new StateFlag("invincible", false);
|
||||
public static final StateFlag ENTRY = new StateFlag("entry", true);
|
||||
public static final RegionGroupFlag ENTRY_PERM = new RegionGroupFlag("entry-group", RegionGroupFlag.RegionGroup.NON_MEMBERS);
|
||||
public static final StateFlag EXIT = new StateFlag("exit", true);
|
||||
public static final RegionGroupFlag EXIT_PERM = new RegionGroupFlag("exit-group", RegionGroupFlag.RegionGroup.NON_MEMBERS);
|
||||
public static final StringFlag GREET_MESSAGE = new StringFlag("greeting");
|
||||
public static final StringFlag FAREWELL_MESSAGE = new StringFlag("farewell");
|
||||
public static final BooleanFlag NOTIFY_ENTER = new BooleanFlag("notify-enter");
|
||||
public static final BooleanFlag NOTIFY_LEAVE = new BooleanFlag("notify-leave");
|
||||
public static final SetFlag<CreatureType> DENY_SPAWN = new SetFlag<CreatureType>("deny-spawn", new CreatureTypeFlag(null));
|
||||
public static final IntegerFlag HEAL_DELAY = new IntegerFlag("heal-delay");
|
||||
public static final IntegerFlag HEAL_AMOUNT = new IntegerFlag("heal-amount");
|
||||
public static final IntegerFlag MIN_HEAL = new IntegerFlag("heal-min-health");
|
||||
public static final IntegerFlag MAX_HEAL = new IntegerFlag("heal-max-health");
|
||||
public static final IntegerFlag FEED_DELAY = new IntegerFlag("feed-delay");
|
||||
public static final IntegerFlag FEED_AMOUNT = new IntegerFlag("feed-amount");
|
||||
public static final IntegerFlag MIN_FOOD = new IntegerFlag("feed-min-hunger");
|
||||
public static final IntegerFlag MAX_FOOD = new IntegerFlag("feed-max-hunger");
|
||||
public static final VectorFlag TELE_LOC = new VectorFlag("teleport");
|
||||
public static final RegionGroupFlag TELE_PERM = new RegionGroupFlag("teleport-group", RegionGroupFlag.RegionGroup.MEMBERS);
|
||||
public static final VectorFlag SPAWN_LOC = new VectorFlag("spawn");
|
||||
public static final RegionGroupFlag SPAWN_PERM = new RegionGroupFlag("spawn-group", RegionGroupFlag.RegionGroup.MEMBERS);
|
||||
public static final BooleanFlag BUYABLE = new BooleanFlag("buyable");
|
||||
public static final DoubleFlag PRICE = new DoubleFlag("price");
|
||||
public static final SetFlag<String> BLOCKED_CMDS = new SetFlag<String>("blocked-cmds", new CommandStringFlag(null));
|
||||
public static final SetFlag<String> ALLOWED_CMDS = new SetFlag<String>("allowed-cmds", new CommandStringFlag(null));
|
||||
|
||||
public static final Flag<?>[] flagsList = new Flag<?>[] {
|
||||
PASSTHROUGH, BUILD, PVP, CHEST_ACCESS, PISTONS,
|
||||
TNT, LIGHTER, USE, PLACE_VEHICLE, DESTROY_VEHICLE, SLEEP,
|
||||
MOB_DAMAGE, MOB_SPAWNING, DENY_SPAWN, INVINCIBILITY,
|
||||
CREEPER_EXPLOSION, GHAST_FIREBALL, ENDER_BUILD,
|
||||
GREET_MESSAGE, FAREWELL_MESSAGE, NOTIFY_ENTER, NOTIFY_LEAVE,
|
||||
EXIT, EXIT_PERM, ENTRY, ENTRY_PERM,
|
||||
HEAL_AMOUNT, HEAL_DELAY, MIN_HEAL, MAX_HEAL,
|
||||
FEED_DELAY, FEED_AMOUNT, MIN_FOOD, MAX_FOOD,
|
||||
SNOW_FALL, SNOW_MELT, ICE_FORM, ICE_MELT,
|
||||
MUSHROOMS, LEAF_DECAY, GRASS_SPREAD,
|
||||
FIRE_SPREAD, LAVA_FIRE, LAVA_FLOW, WATER_FLOW,
|
||||
TELE_LOC, TELE_PERM, SPAWN_LOC, SPAWN_PERM,
|
||||
BLOCKED_CMDS, ALLOWED_CMDS, PRICE, BUYABLE,
|
||||
};
|
||||
|
||||
static {
|
||||
ENTRY.setGroupFlag(ENTRY_PERM);
|
||||
EXIT.setGroupFlag(EXIT_PERM);
|
||||
}
|
||||
|
||||
private DefaultFlag() {
|
||||
}
|
||||
|
||||
public static Flag<?>[] getFlags() {
|
||||
return flagsList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the legacy flag.
|
||||
*
|
||||
* @param flagString
|
||||
* @return null if not found
|
||||
*/
|
||||
public static StateFlag getLegacyFlag(String flagString) {
|
||||
for (Flag<?> flag : flagsList) {
|
||||
if (flag instanceof StateFlag && flagString.equals(String.valueOf(flag.getLegacyCode()))) {
|
||||
return (StateFlag) flag;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
// $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 DoubleFlag extends Flag<Double> {
|
||||
|
||||
public DoubleFlag(String name, char legacyCode) {
|
||||
super(name, legacyCode);
|
||||
}
|
||||
|
||||
public DoubleFlag(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double parseInput(WorldGuardPlugin plugin, CommandSender sender,
|
||||
String input) throws InvalidFlagFormat {
|
||||
input = input.trim();
|
||||
|
||||
try {
|
||||
return Double.parseDouble(input);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new InvalidFlagFormat("Not a number: " + input);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double unmarshal(Object o) {
|
||||
if (o instanceof Double) {
|
||||
return (Double) o;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object marshal(Double o) {
|
||||
return o;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
// $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 EnumFlag<T extends Enum<T>> extends Flag<T> {
|
||||
|
||||
private Class<T> enumClass;
|
||||
|
||||
public EnumFlag(String name, char legacyCode, Class<T> enumClass) {
|
||||
super(name, legacyCode);
|
||||
this.enumClass = enumClass;
|
||||
}
|
||||
|
||||
public EnumFlag(String name, Class<T> enumClass) {
|
||||
super(name);
|
||||
this.enumClass = enumClass;
|
||||
}
|
||||
|
||||
private T findValue(String input) throws IllegalArgumentException {
|
||||
try {
|
||||
return Enum.valueOf(enumClass, input);
|
||||
} catch (IllegalArgumentException e) {
|
||||
T val = detectValue(input);
|
||||
|
||||
if (val != null) {
|
||||
return val;
|
||||
}
|
||||
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fuzzy detect the value if the value is not found.
|
||||
*
|
||||
* @param input string input
|
||||
* @return value or null
|
||||
*/
|
||||
public T detectValue(String input) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T parseInput(WorldGuardPlugin plugin, CommandSender sender,
|
||||
String input) throws InvalidFlagFormat {
|
||||
try {
|
||||
return findValue(input);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new InvalidFlagFormat("Unknown value '" + input + "' in "
|
||||
+ enumClass.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public T unmarshal(Object o) {
|
||||
try {
|
||||
return Enum.valueOf(enumClass, String.valueOf(o));
|
||||
} catch (IllegalArgumentException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object marshal(T o) {
|
||||
return o.name();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// $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
|
||||
* @param <T>
|
||||
*/
|
||||
public abstract class Flag<T> {
|
||||
|
||||
private String name;
|
||||
private Character legacyCode;
|
||||
|
||||
public Flag(String name, char legacyCode) {
|
||||
this.name = name;
|
||||
this.legacyCode = legacyCode;
|
||||
}
|
||||
|
||||
public Flag(String name) {
|
||||
this.name = name;
|
||||
this.legacyCode = null;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Character getLegacyCode() {
|
||||
return legacyCode;
|
||||
}
|
||||
|
||||
public abstract T parseInput(WorldGuardPlugin plugin, CommandSender sender,
|
||||
String input) throws InvalidFlagFormat;
|
||||
|
||||
public abstract T unmarshal(Object o);
|
||||
|
||||
public abstract Object marshal(T o);
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
// $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 IntegerFlag extends Flag<Integer> {
|
||||
|
||||
public IntegerFlag(String name, char legacyCode) {
|
||||
super(name, legacyCode);
|
||||
}
|
||||
|
||||
public IntegerFlag(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer parseInput(WorldGuardPlugin plugin, CommandSender sender,
|
||||
String input) throws InvalidFlagFormat {
|
||||
input = input.trim();
|
||||
|
||||
try {
|
||||
return Integer.parseInt(input);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new InvalidFlagFormat("Not a number: " + input);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer unmarshal(Object o) {
|
||||
if (o instanceof Integer) {
|
||||
return (Integer) o;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object marshal(Integer o) {
|
||||
return o;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// $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;
|
||||
|
||||
public class InvalidFlagFormat extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 8101615074524004172L;
|
||||
|
||||
public InvalidFlagFormat(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
// $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.LocalPlayer;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class RegionGroupFlag extends Flag<RegionGroupFlag.RegionGroup> {
|
||||
|
||||
public static enum RegionGroup {
|
||||
MEMBERS,
|
||||
OWNERS,
|
||||
NON_MEMBERS,
|
||||
NON_OWNERS
|
||||
}
|
||||
|
||||
private RegionGroup def;
|
||||
|
||||
public RegionGroupFlag(String name, char legacyCode, RegionGroup def) {
|
||||
super(name, legacyCode);
|
||||
this.def = def;
|
||||
}
|
||||
|
||||
public RegionGroupFlag(String name, RegionGroup def) {
|
||||
super(name);
|
||||
this.def = def;
|
||||
}
|
||||
|
||||
public RegionGroup getDefault() {
|
||||
return def;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegionGroup parseInput(WorldGuardPlugin plugin, CommandSender sender,
|
||||
String input) throws InvalidFlagFormat {
|
||||
input = input.trim();
|
||||
|
||||
if (input.equalsIgnoreCase("members") || input.equalsIgnoreCase("member")) {
|
||||
return RegionGroup.MEMBERS;
|
||||
} else if (input.equalsIgnoreCase("owners") || input.equalsIgnoreCase("owner")) {
|
||||
return RegionGroup.OWNERS;
|
||||
} else if (input.equalsIgnoreCase("nonowners") || input.equalsIgnoreCase("nonowner")) {
|
||||
return RegionGroup.NON_OWNERS;
|
||||
} else if (input.equalsIgnoreCase("nonmembers") || input.equalsIgnoreCase("nonmember")) {
|
||||
return RegionGroup.NON_MEMBERS;
|
||||
} else if (input.equalsIgnoreCase("everyone") || input.equalsIgnoreCase("anyone")) {
|
||||
return null;
|
||||
} else {
|
||||
throw new InvalidFlagFormat("Expected [non]member/[non]owner/anyone but got '" + input + "'");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegionGroup unmarshal(Object o) {
|
||||
String str = o.toString();
|
||||
if (str.equalsIgnoreCase("members")) {
|
||||
return RegionGroup.MEMBERS;
|
||||
} else if (str.equalsIgnoreCase("owners")) {
|
||||
return RegionGroup.OWNERS;
|
||||
} else if (str.equalsIgnoreCase("nonmembers")) {
|
||||
return RegionGroup.NON_MEMBERS;
|
||||
} else if (str.equalsIgnoreCase("nonowners")) {
|
||||
return RegionGroup.NON_OWNERS;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object marshal(RegionGroup o) {
|
||||
if (o == RegionGroup.MEMBERS) {
|
||||
return "members";
|
||||
} else if (o == RegionGroup.OWNERS) {
|
||||
return "owners";
|
||||
} else if (o == RegionGroup.NON_MEMBERS) {
|
||||
return "nonmembers";
|
||||
} else if (o == RegionGroup.NON_OWNERS) {
|
||||
return "nonowners";
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isMember(ProtectedRegion region, RegionGroup group, LocalPlayer player) {
|
||||
if (group == RegionGroupFlag.RegionGroup.OWNERS) {
|
||||
if (region.isOwner(player)) {
|
||||
return true;
|
||||
}
|
||||
} else if (group == RegionGroupFlag.RegionGroup.MEMBERS) {
|
||||
if (region.isMember(player)) {
|
||||
return true;
|
||||
}
|
||||
} else if (group == RegionGroupFlag.RegionGroup.NON_OWNERS) {
|
||||
if (!region.isOwner(player)) {
|
||||
return true;
|
||||
}
|
||||
} else if (group == RegionGroupFlag.RegionGroup.NON_MEMBERS) {
|
||||
if (!region.isMember(player)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isMember(ApplicableRegionSet set,
|
||||
RegionGroup group, LocalPlayer player) {
|
||||
if (group == RegionGroupFlag.RegionGroup.OWNERS) {
|
||||
if (set.isOwnerOfAll(player)) {
|
||||
return true;
|
||||
}
|
||||
} else if (group == RegionGroupFlag.RegionGroup.MEMBERS) {
|
||||
if (set.isMemberOfAll(player)) {
|
||||
return true;
|
||||
}
|
||||
} else if (group == RegionGroupFlag.RegionGroup.NON_OWNERS) {
|
||||
if (!set.isOwnerOfAll(player)) {
|
||||
return true;
|
||||
}
|
||||
} else if (group == RegionGroupFlag.RegionGroup.NON_MEMBERS) {
|
||||
if (!set.isMemberOfAll(player)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
// $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 java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
|
||||
/**
|
||||
* Represents a flag that consists of a set.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class SetFlag<T> extends Flag<Set<T>> {
|
||||
|
||||
private Flag<T> subFlag;
|
||||
|
||||
public SetFlag(String name, char legacyCode, Flag<T> subFlag) {
|
||||
super(name, legacyCode);
|
||||
this.subFlag = subFlag;
|
||||
}
|
||||
|
||||
public SetFlag(String name, Flag<T> subFlag) {
|
||||
super(name);
|
||||
this.subFlag = subFlag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<T> parseInput(WorldGuardPlugin plugin, CommandSender sender,
|
||||
String input) throws InvalidFlagFormat {
|
||||
Set<T> items = new HashSet<T>();
|
||||
|
||||
for (String str : input.split(",")) {
|
||||
items.add(subFlag.parseInput(plugin, sender, str.trim()));
|
||||
}
|
||||
|
||||
return new HashSet<T>(items);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<T> unmarshal(Object o) {
|
||||
if (o instanceof Collection<?>) {
|
||||
Collection<?> collection = (Collection<?>) o;
|
||||
Set<T> items = new HashSet<T>();
|
||||
|
||||
for (Object sub : collection) {
|
||||
T item = subFlag.unmarshal(sub);
|
||||
if (item != null) {
|
||||
items.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object marshal(Set<T> o) {
|
||||
List<Object> list = new ArrayList<Object>();
|
||||
for (T item : o) {
|
||||
list.add(subFlag.marshal(item));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
// $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 StateFlag extends Flag<StateFlag.State> {
|
||||
|
||||
public enum State {
|
||||
ALLOW,
|
||||
DENY
|
||||
}
|
||||
|
||||
private boolean def;
|
||||
private RegionGroupFlag groupFlag;
|
||||
|
||||
public StateFlag(String name, char legacyCode, boolean def) {
|
||||
super(name, legacyCode);
|
||||
this.def = def;
|
||||
}
|
||||
|
||||
public StateFlag(String name, boolean def) {
|
||||
super(name);
|
||||
this.def = def;
|
||||
}
|
||||
|
||||
public boolean getDefault() {
|
||||
return def;
|
||||
}
|
||||
|
||||
public RegionGroupFlag getGroupFlag() {
|
||||
return groupFlag;
|
||||
}
|
||||
|
||||
public void setGroupFlag(RegionGroupFlag groupFlag) {
|
||||
this.groupFlag = groupFlag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public State parseInput(WorldGuardPlugin plugin, CommandSender sender,
|
||||
String input) throws InvalidFlagFormat {
|
||||
input = input.trim();
|
||||
|
||||
if (input.equalsIgnoreCase("allow")) {
|
||||
return State.ALLOW;
|
||||
} else if (input.equalsIgnoreCase("deny")) {
|
||||
return State.DENY;
|
||||
} else if (input.equalsIgnoreCase("none")) {
|
||||
return null;
|
||||
} else {
|
||||
throw new InvalidFlagFormat("Expected none/allow/deny but got '" + input + "'");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public State unmarshal(Object o) {
|
||||
String str = o.toString();
|
||||
if (str.equalsIgnoreCase("allow")) {
|
||||
return State.ALLOW;
|
||||
} else if (str.equalsIgnoreCase("deny")) {
|
||||
return State.DENY;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object marshal(State o) {
|
||||
if (o == State.ALLOW) {
|
||||
return "allow";
|
||||
} else if (o == State.DENY) {
|
||||
return "deny";
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// $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 StringFlag extends Flag<String> {
|
||||
|
||||
public StringFlag(String name, char legacyCode) {
|
||||
super(name, legacyCode);
|
||||
}
|
||||
|
||||
public StringFlag(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parseInput(WorldGuardPlugin plugin, CommandSender sender,
|
||||
String input) throws InvalidFlagFormat {
|
||||
return input;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String unmarshal(Object o) {
|
||||
if (o instanceof String) {
|
||||
return (String) o;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object marshal(String o) {
|
||||
return o;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
// $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 java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.bukkit.BukkitUtil;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class VectorFlag extends Flag<Vector> {
|
||||
|
||||
public VectorFlag(String name, char legacyCode) {
|
||||
super(name, legacyCode);
|
||||
}
|
||||
|
||||
public VectorFlag(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector parseInput(WorldGuardPlugin plugin, CommandSender sender,
|
||||
String input) throws InvalidFlagFormat {
|
||||
input = input.trim();
|
||||
|
||||
try {
|
||||
return BukkitUtil.toVector(plugin.checkPlayer(sender).getLocation());
|
||||
} catch (CommandException e) {
|
||||
throw new InvalidFlagFormat(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector unmarshal(Object o) {
|
||||
if (o instanceof Map<?, ?>) {
|
||||
Map<?, ?> map = (Map<?, ?>) o;
|
||||
|
||||
Object rawX = map.get("x");
|
||||
Object rawY = map.get("y");
|
||||
Object rawZ = map.get("z");
|
||||
|
||||
if (rawX == null || rawY == null || rawZ == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Vector(toNumber(rawX), toNumber(rawY), toNumber(rawZ));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object marshal(Vector o) {
|
||||
Map<String, Object> vec = new HashMap<String, Object>();
|
||||
vec.put("x", o.getX());
|
||||
vec.put("y", o.getY());
|
||||
vec.put("z", o.getZ());
|
||||
return vec;
|
||||
}
|
||||
|
||||
private double toNumber(Object o) {
|
||||
if (o instanceof Integer) {
|
||||
return (Integer) o;
|
||||
} else if (o instanceof Long) {
|
||||
return (Long) o;
|
||||
} else if (o instanceof Float) {
|
||||
return (Float) o;
|
||||
} else if (o instanceof Double) {
|
||||
return (Double) o;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
// $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.managers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.UnsupportedIntersectionException;
|
||||
import com.sk89q.worldguard.protection.databases.ProtectionDatabase;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
|
||||
/**
|
||||
* A very simple implementation of the region manager that uses a flat list
|
||||
* and iterates through the list to identify applicable regions. This method
|
||||
* is not very efficient.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class FlatRegionManager extends RegionManager {
|
||||
|
||||
/**
|
||||
* List of protected regions.
|
||||
*/
|
||||
private Map<String, ProtectedRegion> regions;
|
||||
|
||||
/**
|
||||
* Construct the manager.
|
||||
*
|
||||
* @param regionloader
|
||||
*/
|
||||
public FlatRegionManager(ProtectionDatabase regionloader) {
|
||||
super(regionloader);
|
||||
regions = new TreeMap<String, ProtectedRegion>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of protected regions.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Map<String, ProtectedRegion> getRegions() {
|
||||
return regions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a list of protected regions.
|
||||
*/
|
||||
@Override
|
||||
public void setRegions(Map<String, ProtectedRegion> regions) {
|
||||
this.regions = new TreeMap<String, ProtectedRegion>(regions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a region.
|
||||
*
|
||||
* @param region
|
||||
*/
|
||||
@Override
|
||||
public void addRegion(ProtectedRegion region) {
|
||||
regions.put(region.getId().toLowerCase(), region);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a region and its children.
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
@Override
|
||||
public void removeRegion(String id) {
|
||||
ProtectedRegion region = regions.get(id.toLowerCase());
|
||||
regions.remove(id.toLowerCase());
|
||||
|
||||
if (region != null) {
|
||||
List<String> removeRegions = new ArrayList<String>();
|
||||
Iterator<ProtectedRegion> iter = regions.values().iterator();
|
||||
while (iter.hasNext()) {
|
||||
ProtectedRegion curRegion = iter.next();
|
||||
if (curRegion.getParent() == region) {
|
||||
removeRegions.add(curRegion.getId().toLowerCase());
|
||||
}
|
||||
}
|
||||
|
||||
for (String remId : removeRegions) {
|
||||
removeRegion(remId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether a region exists by an ID.
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean hasRegion(String id) {
|
||||
return regions.containsKey(id.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a region by its ID.
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
@Override
|
||||
public ProtectedRegion getRegion(String id) {
|
||||
return regions.get(id.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an object for a point for rules to be applied with.
|
||||
*
|
||||
* @param pt
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ApplicableRegionSet getApplicableRegions(Vector pt) {
|
||||
TreeSet<ProtectedRegion> appRegions =
|
||||
new TreeSet<ProtectedRegion>();
|
||||
|
||||
for (ProtectedRegion region : regions.values()) {
|
||||
if (region.contains(pt)) {
|
||||
appRegions.add(region);
|
||||
|
||||
ProtectedRegion parent = region.getParent();
|
||||
|
||||
while (parent != null) {
|
||||
if (!appRegions.contains(parent)) {
|
||||
appRegions.add(region);
|
||||
}
|
||||
|
||||
parent = parent.getParent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new ApplicableRegionSet(appRegions, regions.get("__global__"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an object for a region for rules to be applied with.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/*@Override
|
||||
public ApplicableRegionSet getApplicableRegions(ProtectedRegion checkRegion) {
|
||||
|
||||
List<ProtectedRegion> appRegions = new ArrayList<ProtectedRegion>();
|
||||
appRegions.addAll(regions.values());
|
||||
|
||||
List<ProtectedRegion> intersectRegions;
|
||||
try {
|
||||
intersectRegions = checkRegion.getIntersectingRegions(appRegions);
|
||||
} catch (Exception e) {
|
||||
intersectRegions = new ArrayList<ProtectedRegion>();
|
||||
}
|
||||
|
||||
return new ApplicableRegionSet(intersectRegions, regions.get("__global__"));
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Get a list of region IDs that contain a point.
|
||||
*
|
||||
* @param pt
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<String> getApplicableRegionsIDs(Vector pt) {
|
||||
List<String> applicable = new ArrayList<String>();
|
||||
|
||||
for (Map.Entry<String, ProtectedRegion> entry : regions.entrySet()) {
|
||||
if (entry.getValue().contains(pt)) {
|
||||
applicable.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
return applicable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an object for a region for rules to be applied with.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ApplicableRegionSet getApplicableRegions(ProtectedRegion checkRegion) {
|
||||
|
||||
List<ProtectedRegion> appRegions = new ArrayList<ProtectedRegion>();
|
||||
appRegions.addAll(regions.values());
|
||||
|
||||
List<ProtectedRegion> intersectRegions;
|
||||
|
||||
try {
|
||||
intersectRegions = checkRegion.getIntersectingRegions(appRegions);
|
||||
} catch (Exception e) {
|
||||
intersectRegions = new ArrayList<ProtectedRegion>();
|
||||
}
|
||||
|
||||
return new ApplicableRegionSet(intersectRegions, regions.get("__global__"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the provided region overlaps with any other region that
|
||||
* is not owned by the player.
|
||||
*
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean overlapsUnownedRegion(ProtectedRegion checkRegion, LocalPlayer player) {
|
||||
List<ProtectedRegion> appRegions = new ArrayList<ProtectedRegion>();
|
||||
|
||||
for (ProtectedRegion other : regions.values()) {
|
||||
if (other.getOwners().contains(player)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
appRegions.add(other);
|
||||
}
|
||||
|
||||
List<ProtectedRegion> intersectRegions;
|
||||
try {
|
||||
intersectRegions = checkRegion.getIntersectingRegions(appRegions);
|
||||
} catch (UnsupportedIntersectionException e) {
|
||||
intersectRegions = new ArrayList<ProtectedRegion>();
|
||||
}
|
||||
|
||||
return intersectRegions.size() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of regions.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int size() {
|
||||
return regions.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRegionCountOfPlayer(LocalPlayer player) {
|
||||
int count = 0;
|
||||
|
||||
for (ProtectedRegion region : regions.values()) {
|
||||
if (region.getOwners().contains(player)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,264 @@
|
||||
// $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.managers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.khelekore.prtree.MBRConverter;
|
||||
import org.khelekore.prtree.PRTree;
|
||||
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.databases.ProtectionDatabase;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegionMBRConverter;
|
||||
|
||||
public class PRTreeRegionManager extends RegionManager {
|
||||
|
||||
private static final int BRANCH_FACTOR = 30;
|
||||
/**
|
||||
* List of protected regions.
|
||||
*/
|
||||
private Map<String, ProtectedRegion> regions;
|
||||
/**
|
||||
* Converter to get coordinates of the tree.
|
||||
*/
|
||||
private MBRConverter<ProtectedRegion> converter = new ProtectedRegionMBRConverter();
|
||||
/**
|
||||
* Priority R-tree.
|
||||
*/
|
||||
private PRTree<ProtectedRegion> tree;
|
||||
|
||||
/**
|
||||
* Construct the manager.
|
||||
*
|
||||
* @param regionloader
|
||||
* @throws IOException
|
||||
*/
|
||||
public PRTreeRegionManager(ProtectionDatabase regionloader) throws IOException {
|
||||
super(regionloader);
|
||||
regions = new TreeMap<String, ProtectedRegion>();
|
||||
tree = new PRTree<ProtectedRegion>(converter, BRANCH_FACTOR);
|
||||
this.load();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of protected regions.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Map<String, ProtectedRegion> getRegions() {
|
||||
return regions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a list of protected regions.
|
||||
*/
|
||||
@Override
|
||||
public void setRegions(Map<String, ProtectedRegion> regions) {
|
||||
this.regions = new TreeMap<String, ProtectedRegion>(regions);
|
||||
tree = new PRTree<ProtectedRegion>(converter, BRANCH_FACTOR);
|
||||
tree.load(regions.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a region.
|
||||
*
|
||||
* @param region
|
||||
*/
|
||||
@Override
|
||||
public void addRegion(ProtectedRegion region) {
|
||||
regions.put(region.getId().toLowerCase(), region);
|
||||
tree = new PRTree<ProtectedRegion>(converter, BRANCH_FACTOR);
|
||||
tree.load(regions.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether a region exists by an ID.
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean hasRegion(String id) {
|
||||
return regions.containsKey(id.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a region by its ID.
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
@Override
|
||||
public ProtectedRegion getRegion(String id) {
|
||||
return regions.get(id.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a region and its children.
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
@Override
|
||||
public void removeRegion(String id) {
|
||||
ProtectedRegion region = regions.get(id.toLowerCase());
|
||||
|
||||
regions.remove(id.toLowerCase());
|
||||
|
||||
if (region != null) {
|
||||
List<String> removeRegions = new ArrayList<String>();
|
||||
Iterator<ProtectedRegion> iter = regions.values().iterator();
|
||||
while (iter.hasNext()) {
|
||||
ProtectedRegion curRegion = iter.next();
|
||||
if (curRegion.getParent() == region) {
|
||||
removeRegions.add(curRegion.getId().toLowerCase());
|
||||
}
|
||||
}
|
||||
|
||||
for (String remId : removeRegions) {
|
||||
removeRegion(remId);
|
||||
}
|
||||
}
|
||||
|
||||
tree = new PRTree<ProtectedRegion>(converter, BRANCH_FACTOR);
|
||||
tree.load(regions.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an object for a point for rules to be applied with.
|
||||
*
|
||||
* @param pt
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ApplicableRegionSet getApplicableRegions(Vector pt) {
|
||||
List<ProtectedRegion> appRegions =
|
||||
new ArrayList<ProtectedRegion>();
|
||||
|
||||
int x = pt.getBlockX();
|
||||
int z = pt.getBlockZ();
|
||||
|
||||
for (ProtectedRegion region : tree.find(x, z, x, z)) {
|
||||
if (region.contains(pt)) {
|
||||
appRegions.add(region);
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(appRegions);
|
||||
|
||||
return new ApplicableRegionSet(appRegions, regions.get("__global__"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApplicableRegionSet getApplicableRegions(ProtectedRegion checkRegion) {
|
||||
List<ProtectedRegion> appRegions = new ArrayList<ProtectedRegion>();
|
||||
appRegions.addAll(regions.values());
|
||||
|
||||
List<ProtectedRegion> intersectRegions;
|
||||
try {
|
||||
intersectRegions = checkRegion.getIntersectingRegions(appRegions);
|
||||
} catch (Exception e) {
|
||||
intersectRegions = new ArrayList<ProtectedRegion>();
|
||||
}
|
||||
|
||||
return new ApplicableRegionSet(intersectRegions, regions.get("__global__"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of region IDs that contain a point.
|
||||
*
|
||||
* @param pt
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<String> getApplicableRegionsIDs(Vector pt) {
|
||||
List<String> applicable = new ArrayList<String>();
|
||||
|
||||
int x = pt.getBlockX();
|
||||
int z = pt.getBlockZ();
|
||||
|
||||
for (ProtectedRegion region : tree.find(x, z, x, z)) {
|
||||
if (region.contains(pt)) {
|
||||
applicable.add(region.getId());
|
||||
}
|
||||
}
|
||||
|
||||
return applicable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the provided region overlaps with any other region that
|
||||
* is not owned by the player.
|
||||
*
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean overlapsUnownedRegion(ProtectedRegion checkRegion, LocalPlayer player) {
|
||||
List<ProtectedRegion> appRegions = new ArrayList<ProtectedRegion>();
|
||||
|
||||
for (ProtectedRegion other : regions.values()) {
|
||||
if (other.getOwners().contains(player)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
appRegions.add(other);
|
||||
}
|
||||
|
||||
List<ProtectedRegion> intersectRegions;
|
||||
try {
|
||||
intersectRegions = checkRegion.getIntersectingRegions(appRegions);
|
||||
} catch (Exception e) {
|
||||
intersectRegions = new ArrayList<ProtectedRegion>();
|
||||
}
|
||||
|
||||
return intersectRegions.size() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of regions.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int size() {
|
||||
return regions.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRegionCountOfPlayer(LocalPlayer player) {
|
||||
int count = 0;
|
||||
|
||||
for (Map.Entry<String, ProtectedRegion> entry : regions.entrySet()) {
|
||||
if (entry.getValue().getOwners().contains(player)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
// $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.managers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||
import com.sk89q.worldguard.protection.databases.ProtectionDatabase;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
|
||||
/**
|
||||
* An abstract class for getting, setting, and looking up regions. The most
|
||||
* simple implementation uses a flat list and iterates through the entire list
|
||||
* to look for applicable regions, but a more complicated (and more efficient)
|
||||
* implementation may use space partitioning techniques.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public abstract class RegionManager {
|
||||
|
||||
protected ProtectionDatabase loader;
|
||||
|
||||
/**
|
||||
* Construct the object.
|
||||
*
|
||||
* @param loader
|
||||
*/
|
||||
public RegionManager(ProtectionDatabase loader) {
|
||||
this.loader = loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the list of regions. If the regions do not load properly, then
|
||||
* the existing list should be used (as stored previously).
|
||||
*
|
||||
* @throws IOException thrown on load error
|
||||
*/
|
||||
public void load() throws IOException {
|
||||
loader.load(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the list of regions.
|
||||
*
|
||||
* @throws IOException thrown on save eIf checking multiple flags for a single locationror
|
||||
*/
|
||||
public void save() throws IOException {
|
||||
loader.save(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a map of protected regions. Use one of the region manager methods
|
||||
* if possible if working with regions.
|
||||
*
|
||||
* @return map of regions, with keys being region IDs (lowercase)
|
||||
*/
|
||||
public abstract Map<String, ProtectedRegion> getRegions();
|
||||
|
||||
/**
|
||||
* Set a list of protected regions. Keys should be lowercase in the given
|
||||
* map fo regions.
|
||||
*
|
||||
* @param regions map of regions
|
||||
*/
|
||||
public abstract void setRegions(Map<String, ProtectedRegion> regions);
|
||||
|
||||
/**
|
||||
* Adds a region. If a region by the given name already exists, then
|
||||
* the existing region will be replaced.
|
||||
*
|
||||
* @param region region to add
|
||||
*/
|
||||
public abstract void addRegion(ProtectedRegion region);
|
||||
|
||||
/**
|
||||
* Return whether a region exists by an ID.
|
||||
*
|
||||
* @param id id of the region, can be mixed-case
|
||||
* @return whether the region exists
|
||||
*/
|
||||
public abstract boolean hasRegion(String id);
|
||||
|
||||
/**
|
||||
* Get a region by its ID.
|
||||
*
|
||||
* @param id id of the region, can be mixed-case
|
||||
* @return region or null if it doesn't exist
|
||||
*/
|
||||
public abstract ProtectedRegion getRegion(String id);
|
||||
|
||||
/**
|
||||
* Removes a region, including inheriting children.
|
||||
*
|
||||
* @param id id of the region, can be mixed-case
|
||||
*/
|
||||
public abstract void removeRegion(String id);
|
||||
|
||||
/**
|
||||
* Get an object for a point for rules to be applied with. Use this in order
|
||||
* to query for flag data or membership data for a given point.
|
||||
*
|
||||
* @param loc Bukkit location
|
||||
* @return applicable region set
|
||||
*/
|
||||
public ApplicableRegionSet getApplicableRegions(org.bukkit.Location loc) {
|
||||
return getApplicableRegions(com.sk89q.worldedit.bukkit.BukkitUtil.toVector(loc));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an object for a point for rules to be applied with. Use this in order
|
||||
* to query for flag data or membership data for a given point.
|
||||
*
|
||||
* @param pt point
|
||||
* @return applicable region set
|
||||
*/
|
||||
public abstract ApplicableRegionSet getApplicableRegions(Vector pt);
|
||||
|
||||
/**
|
||||
* Get an object for a point for rules to be applied with. This gets
|
||||
* a set for the given reason.
|
||||
*
|
||||
* @param region region
|
||||
* @return regino set
|
||||
*/
|
||||
public abstract ApplicableRegionSet getApplicableRegions(
|
||||
ProtectedRegion region);
|
||||
|
||||
/**
|
||||
* Get a list of region IDs that contain a point.
|
||||
*
|
||||
* @param pt point
|
||||
* @return list of region Ids
|
||||
*/
|
||||
public abstract List<String> getApplicableRegionsIDs(Vector pt);
|
||||
|
||||
/**
|
||||
* Returns true if the provided region overlaps with any other region that
|
||||
* is not owned by the player.
|
||||
*
|
||||
* @param region region to check
|
||||
* @param player player to check against
|
||||
* @return whether there is an overlap
|
||||
*/
|
||||
public abstract boolean overlapsUnownedRegion(ProtectedRegion region,
|
||||
LocalPlayer player);
|
||||
|
||||
/**
|
||||
* Get the number of regions.
|
||||
*
|
||||
* @return number of regions
|
||||
*/
|
||||
public abstract int size();
|
||||
|
||||
/**
|
||||
* Get the number of regions for a player.
|
||||
*
|
||||
* @param player player
|
||||
* @return name number of regions that a player owns
|
||||
*/
|
||||
public abstract int getRegionCountOfPlayer(LocalPlayer player);
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
// $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.regions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.sk89q.worldedit.BlockVector;
|
||||
import com.sk89q.worldedit.BlockVector2D;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.protection.UnsupportedIntersectionException;
|
||||
|
||||
public class GlobalProtectedRegion extends ProtectedRegion {
|
||||
|
||||
public GlobalProtectedRegion(String id) {
|
||||
super(id);
|
||||
min = new BlockVector(0, 0, 0);
|
||||
max = new BlockVector(0, 0, 0);
|
||||
}
|
||||
|
||||
public List<BlockVector2D> getPoints() {
|
||||
List<BlockVector2D> pts = new ArrayList<BlockVector2D>();
|
||||
pts.add(new BlockVector2D(min.getBlockX(),min.getBlockZ()));
|
||||
return pts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int volume() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Vector pt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeName() {
|
||||
return "global";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProtectedRegion> getIntersectingRegions(
|
||||
List<ProtectedRegion> regions)
|
||||
throws UnsupportedIntersectionException {
|
||||
return new ArrayList<ProtectedRegion>();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
// $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.regions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.sk89q.worldedit.BlockVector;
|
||||
import com.sk89q.worldedit.BlockVector2D;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.protection.UnsupportedIntersectionException;
|
||||
|
||||
/**
|
||||
* Represents a cuboid region that can be protected.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class ProtectedCuboidRegion extends ProtectedRegion {
|
||||
|
||||
/**
|
||||
* Construct a new instance of this cuboid region.
|
||||
*
|
||||
* @param id
|
||||
* @param pt1
|
||||
* @param pt2
|
||||
*/
|
||||
public ProtectedCuboidRegion(String id, BlockVector pt1, BlockVector pt2) {
|
||||
super(id);
|
||||
setMinMaxPoints(pt1, pt2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given any two points, sets the minimum and maximum points
|
||||
*
|
||||
* @param pt1
|
||||
* @param pt2
|
||||
*/
|
||||
private void setMinMaxPoints(BlockVector pt1, BlockVector pt2) {
|
||||
List<Vector> points = new ArrayList<Vector>();
|
||||
points.add(pt1);
|
||||
points.add(pt2);
|
||||
setMinMaxPoints(points);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the lower point of the cuboid.
|
||||
*
|
||||
* @param pt
|
||||
*/
|
||||
public void setMinimumPoint(BlockVector pt) {
|
||||
setMinMaxPoints(pt, max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the upper point of the cuboid.
|
||||
*
|
||||
* @param pt
|
||||
*/
|
||||
public void setMaximumPoint(BlockVector pt) {
|
||||
setMinMaxPoints(min, pt);
|
||||
}
|
||||
|
||||
public List<BlockVector2D> getPoints() {
|
||||
List<BlockVector2D> pts = new ArrayList<BlockVector2D>();
|
||||
int x1 = min.getBlockX();
|
||||
int x2 = max.getBlockX();
|
||||
int z1 = min.getBlockZ();
|
||||
int z2 = max.getBlockZ();
|
||||
|
||||
pts.add(new BlockVector2D(x1, z1));
|
||||
pts.add(new BlockVector2D(x2, z1));
|
||||
pts.add(new BlockVector2D(x1, z2));
|
||||
pts.add(new BlockVector2D(x2, z2));
|
||||
|
||||
return pts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a point is inside this region.
|
||||
*/
|
||||
@Override
|
||||
public boolean contains(Vector pt) {
|
||||
final double x = pt.getX();
|
||||
final double y = pt.getY();
|
||||
final double z = pt.getZ();
|
||||
return x >= min.getBlockX() && x < max.getBlockX()+1
|
||||
&& y >= min.getBlockY() && y < max.getBlockY()+1
|
||||
&& z >= min.getBlockZ() && z < max.getBlockZ()+1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
public boolean intersectsWith(ProtectedRegion region) throws UnsupportedIntersectionException {
|
||||
|
||||
if (region instanceof ProtectedCuboidRegion) {
|
||||
ProtectedCuboidRegion r1 = (ProtectedCuboidRegion) this;
|
||||
ProtectedCuboidRegion r2 = (ProtectedCuboidRegion) region;
|
||||
BlockVector min1 = r1.getMinimumPoint();
|
||||
BlockVector max1 = r1.getMaximumPoint();
|
||||
BlockVector min2 = r2.getMinimumPoint();
|
||||
BlockVector max2 = r2.getMaximumPoint();
|
||||
|
||||
return !(min1.getBlockX() > max2.getBlockX()
|
||||
|| min1.getBlockY() > max2.getBlockY()
|
||||
|| min1.getBlockZ() > max2.getBlockZ()
|
||||
|| max1.getBlockX() < min2.getBlockX()
|
||||
|| max1.getBlockY() < min2.getBlockY()
|
||||
|| max1.getBlockZ() < min2.getBlockZ());
|
||||
} else if (region instanceof ProtectedPolygonalRegion) {
|
||||
throw new UnsupportedIntersectionException();
|
||||
} else {
|
||||
throw new UnsupportedIntersectionException();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
@Override
|
||||
public List<ProtectedRegion> getIntersectingRegions(List<ProtectedRegion> regions) throws UnsupportedIntersectionException {
|
||||
List<ProtectedRegion> intersectingRegions = new ArrayList<ProtectedRegion>();
|
||||
|
||||
for (ProtectedRegion region : regions) {
|
||||
if (!intersectsBoundingBox(region)) continue;
|
||||
|
||||
// If both regions are Cuboids and their bounding boxes intersect, they intersect
|
||||
if (region instanceof ProtectedCuboidRegion) {
|
||||
intersectingRegions.add(region);
|
||||
continue;
|
||||
} else if (region instanceof ProtectedPolygonalRegion) {
|
||||
// If either region contains the points of the other,
|
||||
// or if any edges intersect, the regions intersect
|
||||
if (containsAny(region.getPoints())
|
||||
|| region.containsAny(getPoints())
|
||||
|| intersectsEdges(region)) {
|
||||
intersectingRegions.add(region);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
}
|
||||
return intersectingRegions;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the type of region as a user-friendly name.
|
||||
*
|
||||
* @return type of region
|
||||
*/
|
||||
@Override
|
||||
public String getTypeName() {
|
||||
return "cuboid";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of Blocks in this region
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int volume() {
|
||||
int xLength = max.getBlockX() - min.getBlockX() + 1;
|
||||
int yLength = max.getBlockY() - min.getBlockY() + 1;
|
||||
int zLength = max.getBlockZ() - min.getBlockZ() + 1;
|
||||
|
||||
int volume = xLength * yLength * zLength;
|
||||
return volume;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
// $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.regions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.sk89q.worldedit.BlockVector2D;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.protection.UnsupportedIntersectionException;
|
||||
|
||||
public class ProtectedPolygonalRegion extends ProtectedRegion {
|
||||
|
||||
protected List<BlockVector2D> points;
|
||||
protected int minY;
|
||||
protected int maxY;
|
||||
|
||||
public ProtectedPolygonalRegion(String id, List<BlockVector2D> points, int minY, int maxY) {
|
||||
super(id);
|
||||
this.points = points;
|
||||
setMinMaxPoints(points, minY, maxY);
|
||||
this.minY = min.getBlockY();
|
||||
this.maxY = max.getBlockY();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the min and max points from all the 2d points and the min/max Y values
|
||||
*
|
||||
* @param points2D
|
||||
* @param minY
|
||||
* @param maxY
|
||||
*/
|
||||
private void setMinMaxPoints(List<BlockVector2D> points2D, int minY, int maxY) {
|
||||
List<Vector> points = new ArrayList<Vector>();
|
||||
int y = minY;
|
||||
for (BlockVector2D point2D : points2D) {
|
||||
points.add(new Vector(point2D.getBlockX(), y, point2D.getBlockZ()));
|
||||
y = maxY;
|
||||
}
|
||||
setMinMaxPoints(points);
|
||||
}
|
||||
|
||||
public List<BlockVector2D> getPoints() {
|
||||
return points;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a point is inside this region.
|
||||
*/
|
||||
@Override
|
||||
public boolean contains(Vector pt) {
|
||||
int targetX = pt.getBlockX(); //wide
|
||||
int targetY = pt.getBlockY(); //height
|
||||
int targetZ = pt.getBlockZ(); //depth
|
||||
|
||||
if (targetY < minY || targetY > maxY) {
|
||||
return false;
|
||||
}
|
||||
//Quick and dirty check.
|
||||
if (targetX < min.getBlockX() || targetX > max.getBlockX() || targetZ < min.getBlockZ() || targetZ > max.getBlockZ()) {
|
||||
return false;
|
||||
}
|
||||
boolean inside = false;
|
||||
int npoints = points.size();
|
||||
int xNew, zNew;
|
||||
int xOld, zOld;
|
||||
int x1, z1;
|
||||
int x2, z2;
|
||||
long crossproduct;
|
||||
int i;
|
||||
|
||||
xOld = points.get(npoints - 1).getBlockX();
|
||||
zOld = points.get(npoints - 1).getBlockZ();
|
||||
|
||||
for (i = 0; i < npoints; i++) {
|
||||
xNew = points.get(i).getBlockX();
|
||||
zNew = points.get(i).getBlockZ();
|
||||
//Check for corner
|
||||
if (xNew == targetX && zNew == targetZ) {
|
||||
return true;
|
||||
}
|
||||
if (xNew > xOld) {
|
||||
x1 = xOld;
|
||||
x2 = xNew;
|
||||
z1 = zOld;
|
||||
z2 = zNew;
|
||||
} else {
|
||||
x1 = xNew;
|
||||
x2 = xOld;
|
||||
z1 = zNew;
|
||||
z2 = zOld;
|
||||
}
|
||||
if (x1 <= targetX && targetX <= x2) {
|
||||
crossproduct = ((long) targetZ - (long) z1) * (long) (x2 - x1)
|
||||
- ((long) z2 - (long) z1) * (long) (targetX - x1);
|
||||
if (crossproduct == 0) {
|
||||
if ((z1 <= targetZ) == (targetZ <= z2)) return true; // on edge
|
||||
} else if (crossproduct < 0 && (x1 != targetX)) {
|
||||
inside = !inside;
|
||||
}
|
||||
}
|
||||
xOld = xNew;
|
||||
zOld = zNew;
|
||||
}
|
||||
|
||||
return inside;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProtectedRegion> getIntersectingRegions(List<ProtectedRegion> regions) throws UnsupportedIntersectionException {
|
||||
List<ProtectedRegion> intersectingRegions = new ArrayList<ProtectedRegion>();
|
||||
|
||||
for (ProtectedRegion region : regions) {
|
||||
if (!intersectsBoundingBox(region)) continue;
|
||||
|
||||
if (region instanceof ProtectedPolygonalRegion || region instanceof ProtectedCuboidRegion) {
|
||||
// If either region contains the points of the other,
|
||||
// or if any edges intersect, the regions intersect
|
||||
if (containsAny(region.getPoints())
|
||||
|| region.containsAny(getPoints())
|
||||
|| intersectsEdges(region)) {
|
||||
intersectingRegions.add(region);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
}
|
||||
return intersectingRegions;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the type of region as a user-friendly name.
|
||||
*
|
||||
* @return type of region
|
||||
*/
|
||||
@Override
|
||||
public String getTypeName() {
|
||||
return "polygon";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of Blocks in this region
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int volume() {
|
||||
int volume = 0;
|
||||
// TODO: Fix this
|
||||
/*int numPoints = points.size();
|
||||
if (numPoints < 3) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
double area = 0;
|
||||
int xa, z1, z2;
|
||||
|
||||
for (int i = 0; i < numPoints; i++) {
|
||||
xa = points.get(i).getBlockX();
|
||||
//za = points.get(i).getBlockZ();
|
||||
|
||||
if (points.get(i + 1) == null) {
|
||||
z1 = points.get(0).getBlockZ();
|
||||
} else {
|
||||
z1 = points.get(i + 1).getBlockZ();
|
||||
}
|
||||
if (points.get(i - 1) == null) {
|
||||
z2 = points.get(numPoints - 1).getBlockZ();
|
||||
} else {
|
||||
z2 = points.get(i - 1).getBlockZ();
|
||||
}
|
||||
|
||||
area = area + (xa * (z1 - z2));
|
||||
}
|
||||
|
||||
xa = points.get(0).getBlockX();
|
||||
//za = points.get(0).getBlockZ();
|
||||
|
||||
area = area + (xa * (points.get(1).getBlockZ() - points.get(numPoints - 1).getBlockZ()));
|
||||
|
||||
volume = (Math.abs(maxY - minY) + 1) * (int) Math.ceil((Math.abs(area) / 2));*/
|
||||
|
||||
return volume;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,549 @@
|
||||
// $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.regions;
|
||||
|
||||
import java.awt.geom.Line2D;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.sk89q.worldedit.BlockVector;
|
||||
import com.sk89q.worldedit.BlockVector2D;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.domains.DefaultDomain;
|
||||
import com.sk89q.worldguard.protection.UnsupportedIntersectionException;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
|
||||
/**
|
||||
* Represents a region of any shape and size that can be protected.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public abstract class ProtectedRegion implements Comparable<ProtectedRegion> {
|
||||
|
||||
protected BlockVector min;
|
||||
protected BlockVector max;
|
||||
|
||||
private static final Pattern idPattern = Pattern.compile("^[A-Za-z0-9_,'\\-\\+/]{1,}$");
|
||||
|
||||
/**
|
||||
* Holds the region's ID.
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* Priority.
|
||||
*/
|
||||
private int priority = 0;
|
||||
|
||||
/**
|
||||
* Holds the curParent.
|
||||
*/
|
||||
private ProtectedRegion parent;
|
||||
|
||||
/**
|
||||
* List of owners.
|
||||
*/
|
||||
private DefaultDomain owners = new DefaultDomain();
|
||||
|
||||
/**
|
||||
* List of members.
|
||||
*/
|
||||
private DefaultDomain members = new DefaultDomain();
|
||||
|
||||
/**
|
||||
* List of flags.
|
||||
*/
|
||||
private Map<Flag<?>, Object> flags = new HashMap<Flag<?>, Object>();
|
||||
|
||||
/**
|
||||
* Construct a new instance of this region.
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
public ProtectedRegion(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the minimum and maximum points of the bounding box for a region
|
||||
*
|
||||
* @param points
|
||||
*/
|
||||
protected void setMinMaxPoints(List<Vector> points) {
|
||||
int minX = points.get(0).getBlockX();
|
||||
int minY = points.get(0).getBlockY();
|
||||
int minZ = points.get(0).getBlockZ();
|
||||
int maxX = minX;
|
||||
int maxY = minY;
|
||||
int maxZ = minZ;
|
||||
|
||||
for (Vector v : points) {
|
||||
int x = v.getBlockX();
|
||||
int y = v.getBlockY();
|
||||
int z = v.getBlockZ();
|
||||
|
||||
if (x < minX) minX = x;
|
||||
if (y < minY) minY = y;
|
||||
if (z < minZ) minZ = z;
|
||||
|
||||
if (x > maxX) maxX = x;
|
||||
if (y > maxY) maxY = y;
|
||||
if (z > maxZ) maxZ = z;
|
||||
}
|
||||
|
||||
min = new BlockVector(minX, minY, minZ);
|
||||
max = new BlockVector(maxX, maxY, maxZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the lower point of the cuboid.
|
||||
*
|
||||
* @return min point
|
||||
*/
|
||||
public BlockVector getMinimumPoint() {
|
||||
return min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the upper point of the cuboid.
|
||||
*
|
||||
* @return max point
|
||||
*/
|
||||
public BlockVector getMaximumPoint() {
|
||||
return max;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the priority
|
||||
*/
|
||||
public int getPriority() {
|
||||
return priority;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param priority the priority to setFlag
|
||||
*/
|
||||
public void setPriority(int priority) {
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the curParent
|
||||
*/
|
||||
public ProtectedRegion getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the curParent. This checks to make sure that it will not result
|
||||
* in circular inheritance.
|
||||
*
|
||||
* @param parent the curParent to setFlag
|
||||
* @throws CircularInheritanceException
|
||||
*/
|
||||
public void setParent(ProtectedRegion parent) throws CircularInheritanceException {
|
||||
if (parent == null) {
|
||||
this.parent = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (parent == this) {
|
||||
throw new CircularInheritanceException();
|
||||
}
|
||||
|
||||
ProtectedRegion p = parent.getParent();
|
||||
while (p != null) {
|
||||
if (p == this) {
|
||||
throw new CircularInheritanceException();
|
||||
}
|
||||
p = p.getParent();
|
||||
}
|
||||
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the owners
|
||||
*/
|
||||
public DefaultDomain getOwners() {
|
||||
|
||||
return owners;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param owners the owners to setFlag
|
||||
*/
|
||||
public void setOwners(DefaultDomain owners) {
|
||||
this.owners = owners;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the members
|
||||
*/
|
||||
public DefaultDomain getMembers() {
|
||||
return members;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param members the members to setFlag
|
||||
*/
|
||||
public void setMembers(DefaultDomain members) {
|
||||
this.members = members;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a region has members or owners.
|
||||
*
|
||||
* @return whether there are members or owners
|
||||
*/
|
||||
public boolean hasMembersOrOwners() {
|
||||
return owners.size() > 0 || members.size() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a player is an owner of region or any of its parents.
|
||||
*
|
||||
* @param player player to check
|
||||
* @return whether an owner
|
||||
*/
|
||||
public boolean isOwner(LocalPlayer player) {
|
||||
if (owners.contains(player)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ProtectedRegion curParent = getParent();
|
||||
while (curParent != null) {
|
||||
if (curParent.getOwners().contains(player)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
curParent = curParent.getParent();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a player is a member OR OWNER of the region
|
||||
* or any of its parents.
|
||||
*
|
||||
* @param player player to check
|
||||
* @return whether an owner or member
|
||||
*/
|
||||
public boolean isMember(LocalPlayer player) {
|
||||
if (owners.contains(player) || members.contains(player)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ProtectedRegion curParent = getParent();
|
||||
while (curParent != null) {
|
||||
if (curParent.getOwners().contains(player)
|
||||
|| curParent.getMembers().contains(player)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
curParent = curParent.getParent();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a player is a member of the region
|
||||
* or any of its parents.
|
||||
*
|
||||
* @param player player to check
|
||||
* @return whether an member
|
||||
*/
|
||||
public boolean isMemberOnly(LocalPlayer player) {
|
||||
if (members.contains(player)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ProtectedRegion curParent = getParent();
|
||||
while (curParent != null) {
|
||||
if (curParent.getMembers().contains(player)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
curParent = curParent.getParent();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a flag's value.
|
||||
*
|
||||
* @param <T>
|
||||
* @param <V>
|
||||
* @param flag
|
||||
* @return value or null if isn't defined
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Flag<V>, V> V getFlag(T flag) {
|
||||
Object obj = flags.get(flag);
|
||||
V val;
|
||||
if (obj != null) {
|
||||
val = (V) obj;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a flag's value.
|
||||
*
|
||||
* @param <T>
|
||||
* @param <V>
|
||||
* @param flag
|
||||
* @param val
|
||||
*/
|
||||
public <T extends Flag<V>, V> void setFlag(T flag, V val) {
|
||||
if (val == null) {
|
||||
flags.remove(flag);
|
||||
} else {
|
||||
flags.put(flag, val);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the map of flags.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Map<Flag<?>, Object> getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the map of flags.
|
||||
*
|
||||
* @param flags
|
||||
*/
|
||||
public void setFlags(Map<Flag<?>, Object> flags) {
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 2D points for this region
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public abstract List<BlockVector2D> getPoints();
|
||||
|
||||
/**
|
||||
* Get the number of blocks in this region
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public abstract int volume();
|
||||
|
||||
/**
|
||||
* Check to see if a point is inside this region.
|
||||
*
|
||||
* @param pt
|
||||
* @return
|
||||
*/
|
||||
public abstract boolean contains(Vector pt);
|
||||
|
||||
/**
|
||||
* Check to see if a point is inside this region.
|
||||
*
|
||||
* @param pt
|
||||
* @return
|
||||
*/
|
||||
public boolean contains(BlockVector2D pt) {
|
||||
return contains(new Vector(pt.getBlockX(), min.getBlockY(), pt.getBlockZ()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if a point is inside this region.
|
||||
*
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @return
|
||||
*/
|
||||
public boolean contains(int x, int y, int z) {
|
||||
return contains(new Vector(x, y, z));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if any of the 2D points are inside this region.
|
||||
*
|
||||
* @param pts
|
||||
* @return
|
||||
*/
|
||||
public boolean containsAny(List<BlockVector2D> pts) {
|
||||
for (BlockVector2D pt : pts) {
|
||||
if (contains(pt)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares to another region.
|
||||
*
|
||||
* @param other
|
||||
* @return
|
||||
*/
|
||||
public int compareTo(ProtectedRegion other) {
|
||||
if (id.equals(other.id)) {
|
||||
return 0;
|
||||
} else if (priority == other.priority) {
|
||||
return 1;
|
||||
} else if (priority > other.priority) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type of region as a user-friendly, lowercase name.
|
||||
*
|
||||
* @return type of region
|
||||
*/
|
||||
public abstract String getTypeName();
|
||||
|
||||
/**
|
||||
* Get a list of intersecting regions.
|
||||
*
|
||||
* @param regions
|
||||
* @return
|
||||
* @throws UnsupportedIntersectionException
|
||||
*/
|
||||
public abstract List<ProtectedRegion> getIntersectingRegions(
|
||||
List<ProtectedRegion> regions)
|
||||
throws UnsupportedIntersectionException;
|
||||
|
||||
/**
|
||||
* Checks if the bounding box of a region intersects with with the bounding
|
||||
* box of this region
|
||||
*
|
||||
* @param region
|
||||
*/
|
||||
protected boolean intersectsBoundingBox(ProtectedRegion region) {
|
||||
BlockVector rMaxPoint = region.getMaximumPoint();
|
||||
BlockVector min = getMinimumPoint();
|
||||
|
||||
if (rMaxPoint.getBlockX() < min.getBlockX()) return false;
|
||||
if (rMaxPoint.getBlockY() < min.getBlockY()) return false;
|
||||
if (rMaxPoint.getBlockZ() < min.getBlockZ()) return false;
|
||||
|
||||
BlockVector rMinPoint = region.getMinimumPoint();
|
||||
BlockVector max = getMaximumPoint();
|
||||
|
||||
if (rMinPoint.getBlockX() > max.getBlockX()) return false;
|
||||
if (rMinPoint.getBlockY() > max.getBlockY()) return false;
|
||||
if (rMinPoint.getBlockZ() > max.getBlockZ()) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares all edges of two regions to see if any of them intersect
|
||||
*
|
||||
* @param region
|
||||
* @return
|
||||
*/
|
||||
protected boolean intersectsEdges(ProtectedRegion region) {
|
||||
List<BlockVector2D> pts1 = getPoints();
|
||||
List<BlockVector2D> pts2 = region.getPoints();
|
||||
BlockVector2D lastPt1 = pts1.get(pts1.size() - 1);
|
||||
BlockVector2D lastPt2 = pts2.get(pts2.size() - 1);
|
||||
for (int i = 0; i < pts1.size(); i++ ) {
|
||||
for (int j = 0; j < pts2.size(); j++) {
|
||||
|
||||
Line2D line1 = new Line2D.Double(
|
||||
lastPt1.getBlockX(),
|
||||
lastPt1.getBlockZ(),
|
||||
pts1.get(i).getBlockX(),
|
||||
pts1.get(i).getBlockZ());
|
||||
|
||||
if (line1.intersectsLine(
|
||||
lastPt2.getBlockX(),
|
||||
lastPt2.getBlockZ(),
|
||||
pts2.get(j).getBlockX(),
|
||||
pts2.get(j).getBlockZ())) {
|
||||
return true;
|
||||
}
|
||||
lastPt2 = pts2.get(j);
|
||||
}
|
||||
lastPt1 = pts1.get(i);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the given ID is accurate.
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
public static boolean isValidId(String id) {
|
||||
return idPattern.matcher(id).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code.
|
||||
*/
|
||||
@Override
|
||||
public int hashCode(){
|
||||
return id.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this region has the same ID as another region.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof ProtectedRegion)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ProtectedRegion other = (ProtectedRegion) obj;
|
||||
return other.getId().equals(getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Thrown when setting a curParent would create a circular inheritance
|
||||
* situation.
|
||||
*
|
||||
*/
|
||||
public static class CircularInheritanceException extends Exception {
|
||||
private static final long serialVersionUID = 7479613488496776022L;
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
// $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.regions;
|
||||
|
||||
import org.khelekore.prtree.MBRConverter;
|
||||
|
||||
public class ProtectedRegionMBRConverter implements MBRConverter<ProtectedRegion> {
|
||||
public double getMinX(ProtectedRegion t) {
|
||||
return t.getMinimumPoint().getBlockX();
|
||||
}
|
||||
|
||||
public double getMinY(ProtectedRegion t) {
|
||||
return t.getMinimumPoint().getBlockZ();
|
||||
}
|
||||
|
||||
public double getMaxX(ProtectedRegion t) {
|
||||
return t.getMaximumPoint().getBlockX();
|
||||
}
|
||||
|
||||
public double getMaxY(ProtectedRegion t) {
|
||||
return t.getMaximumPoint().getBlockZ();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
// $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.util;
|
||||
|
||||
public class ArrayReader<T> {
|
||||
private T[] arr;
|
||||
|
||||
public ArrayReader(T[] arr) {
|
||||
this.arr = arr;
|
||||
}
|
||||
|
||||
public T get(int index) {
|
||||
if (arr.length > index) {
|
||||
return arr[index];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public T get(int index, T def) {
|
||||
if (arr.length > index) {
|
||||
return arr[index];
|
||||
} else {
|
||||
return def;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
// $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.util;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class LogListBlock {
|
||||
private LinkedHashMap <String, Object> items
|
||||
= new LinkedHashMap<String, Object>();
|
||||
private int maxKeyLength = 0;
|
||||
|
||||
private void updateKey(String key) {
|
||||
if (key.length() > maxKeyLength) {
|
||||
maxKeyLength = key.length();
|
||||
}
|
||||
}
|
||||
|
||||
public LogListBlock put(String key, String value) {
|
||||
updateKey(key);
|
||||
items.put(key, String.valueOf(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public LogListBlock put(String key, LogListBlock value) {
|
||||
updateKey(key);
|
||||
items.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LogListBlock put(String key, Object value) {
|
||||
put(key, String.valueOf(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public LogListBlock put(String key, String value, Object ... args) {
|
||||
put(key, String.format(value, args));
|
||||
return this;
|
||||
}
|
||||
|
||||
public LogListBlock put(String key, int value) {
|
||||
put(key, String.valueOf(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public LogListBlock put(String key, byte value) {
|
||||
put(key, String.valueOf(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public LogListBlock put(String key, double value) {
|
||||
put(key, String.valueOf(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public LogListBlock put(String key, float value) {
|
||||
put(key, String.valueOf(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public LogListBlock put(String key, short value) {
|
||||
put(key, String.valueOf(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public LogListBlock put(String key, long value) {
|
||||
put(key, String.valueOf(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public LogListBlock put(String key, boolean value) {
|
||||
put(key, String.valueOf(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public LogListBlock putChild(String key) {
|
||||
updateKey(key);
|
||||
LogListBlock block = new LogListBlock();
|
||||
items.put(key, block);
|
||||
return block;
|
||||
}
|
||||
|
||||
private String padKey(String key, int len) {
|
||||
return String.format("%-" + len + "s", key);
|
||||
}
|
||||
|
||||
protected String getOutput(String prefix) {
|
||||
StringBuilder out = new StringBuilder();
|
||||
for (Map.Entry<String, Object> entry : items.entrySet()) {
|
||||
Object val = entry.getValue();
|
||||
if (val instanceof LogListBlock) {
|
||||
out.append(prefix);
|
||||
out.append(padKey(entry.getKey(), maxKeyLength));
|
||||
out.append(":\r\n");
|
||||
out.append(((LogListBlock) val).getOutput(prefix + " "));
|
||||
} else {
|
||||
out.append(prefix);
|
||||
out.append(padKey(entry.getKey(), maxKeyLength));
|
||||
out.append(": ");
|
||||
out.append(val.toString());
|
||||
out.append("\r\n");
|
||||
}
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getOutput("");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
// $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.util;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
public class PastebinPoster {
|
||||
private static final int CONNECT_TIMEOUT = 5000;
|
||||
private static final int READ_TIMEOUT = 5000;
|
||||
|
||||
public static void paste(String code, PasteCallback callback) {
|
||||
PasteProcessor processor = new PasteProcessor(code, callback);
|
||||
Thread thread = new Thread(processor);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
public static interface PasteCallback {
|
||||
public void handleSuccess(String url);
|
||||
public void handleError(String err);
|
||||
}
|
||||
|
||||
private static class PasteProcessor implements Runnable {
|
||||
private String code;
|
||||
private PasteCallback callback;
|
||||
|
||||
public PasteProcessor(String code, PasteCallback callback) {
|
||||
this.code = code;
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
HttpURLConnection conn = null;
|
||||
OutputStream out = null;
|
||||
InputStream in = null;
|
||||
|
||||
try {
|
||||
URL url = new URL("http://pastebin.com/api/api_post.php");
|
||||
conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setConnectTimeout(CONNECT_TIMEOUT);
|
||||
conn.setReadTimeout(READ_TIMEOUT);
|
||||
conn.setRequestMethod("POST");
|
||||
conn.addRequestProperty("Content-type",
|
||||
"application/x-www-form-urlencoded");
|
||||
conn.setInstanceFollowRedirects(false);
|
||||
conn.setDoOutput(true);
|
||||
out = conn.getOutputStream();
|
||||
|
||||
out.write(("api_option=paste"
|
||||
+ "&api_dev_key=" + URLEncoder.encode("4867eae74c6990dbdef07c543cf8f805", "utf-8")
|
||||
+ "&api_paste_code=" + URLEncoder.encode(code, "utf-8")
|
||||
+ "&api_paste_private=" + URLEncoder.encode("0", "utf-8")
|
||||
+ "&api_paste_name=" + URLEncoder.encode("", "utf-8")
|
||||
+ "&api_paste_expire_date=" + URLEncoder.encode("1D", "utf-8")
|
||||
+ "&api_paste_format=" + URLEncoder.encode("text", "utf-8")
|
||||
+ "&api_user_key=" + URLEncoder.encode("", "utf-8")).getBytes());
|
||||
out.flush();
|
||||
out.close();
|
||||
|
||||
if (conn.getResponseCode() == 200) {//Get Response
|
||||
in = conn.getInputStream();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
|
||||
String line;
|
||||
StringBuffer response = new StringBuffer();
|
||||
while ((line = reader.readLine()) != null) {
|
||||
response.append(line);
|
||||
response.append("\r\n");
|
||||
}
|
||||
reader.close();
|
||||
|
||||
String result = response.toString().trim();
|
||||
|
||||
if (result.matches("^https?://.*")) {
|
||||
callback.handleSuccess(result.trim());
|
||||
} else {
|
||||
String err =result.trim();
|
||||
if (err.length() > 100) {
|
||||
err = err.substring(0, 100);
|
||||
}
|
||||
callback.handleError(err);
|
||||
}
|
||||
} else {
|
||||
callback.handleError("didn't get a 200 response code!");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
callback.handleError(e.getMessage());
|
||||
} finally {
|
||||
if (conn != null) {
|
||||
conn.disconnect();
|
||||
}
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
if (out != null) {
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Loaded 100 of 115 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user