mirror of
https://github.com/EssentialsX/Essentials.git
synced 2026-11-05 09:10:17 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f2dde4154c | ||
|
|
12c2a4f2b5 | ||
|
|
ee7c1b1cf1 | ||
|
|
422f25af8b | ||
|
|
728c746200 | ||
|
|
6dfa18ca53 | ||
|
|
a394760677 | ||
|
|
5f48cdef13 | ||
|
|
c56a9e6741 | ||
|
|
5b20f30350 | ||
|
|
037577162b | ||
|
|
908189a233 | ||
|
|
c938767b2d | ||
|
|
b135fcf086 | ||
|
|
09dc49aacb | ||
|
|
f4b6197a49 | ||
|
|
4a53cfe7ac | ||
|
|
2bba577567 | ||
|
|
6e674c73e0 | ||
|
|
a60f3c067f | ||
|
|
6816eb4e18 | ||
|
|
9c5536b2e6 | ||
|
|
ff80338350 | ||
|
|
8d856dd6db | ||
|
|
96c6c951e8 | ||
|
|
0931b21f6d | ||
|
|
9147d1036d | ||
|
|
a7f602e2ad | ||
|
|
0c81980ead | ||
|
|
2d5794f68d | ||
|
|
6b80e0b113 | ||
|
|
18f9af898e | ||
|
|
d04c933abe | ||
|
|
b916488de2 | ||
|
|
c6066bd2d8 | ||
|
|
3af931740b | ||
|
|
1c5a7e9ffb | ||
|
|
ea5cdc097d | ||
|
|
d891268143 | ||
|
|
4bd1b3c09f | ||
|
|
c4f10d9c1d | ||
|
|
e12f1b5022 | ||
|
|
31732cec95 | ||
|
|
f104b6ec15 | ||
|
|
695546420f | ||
|
|
997fb1800e | ||
|
|
3984bddd9d | ||
|
|
d92ce8bdfe | ||
|
|
3348bd9129 | ||
|
|
1a5526867c | ||
|
|
c5253bc5e2 | ||
|
|
29a2a865c5 | ||
|
|
c3b994808f | ||
|
|
bc2da98703 | ||
|
|
cbb012853c | ||
|
|
4bf4bd432a | ||
|
|
83d0e0d9a0 | ||
|
|
2f5c24d114 | ||
|
|
88c8ccd29b | ||
|
|
94edbcfeb1 | ||
|
|
d5822e9a41 | ||
|
|
debf09437e | ||
|
|
a9e5f079a9 | ||
|
|
f00c2dcf92 | ||
|
|
63cbf7e2da | ||
|
|
19837f9309 | ||
|
|
4b8b770c30 | ||
|
|
ddc258ed11 | ||
|
|
d23796dade | ||
|
|
41f5cc3175 | ||
|
|
c6fe160b47 | ||
|
|
5c46bea2ca | ||
|
|
a9585bb525 | ||
|
|
bb88a6a749 | ||
|
|
739600eb05 | ||
|
|
5f98d3fac5 | ||
|
|
84326cf13e | ||
|
|
685084219e | ||
|
|
c4e62ae22b | ||
|
|
05ce11f657 | ||
|
|
bcb0fb5825 | ||
|
|
91f4493fe0 | ||
|
|
d53ff36a2a | ||
|
|
98917d97c8 | ||
|
|
7e1d18fee4 | ||
|
|
0b7e7801d0 | ||
|
|
840035944a | ||
|
|
20a7d1c7ee | ||
|
|
253185bd0e | ||
|
|
dae519494e | ||
|
|
dc27af78bf | ||
|
|
41861a8551 | ||
|
|
9b629e42d8 | ||
|
|
7794634d37 | ||
|
|
d091d6902c | ||
|
|
c45c741210 | ||
|
|
e35c65b976 | ||
|
|
0983167740 | ||
|
|
1509cf8978 | ||
|
|
c0082ee734 | ||
|
|
db2ec1b436 | ||
|
|
7a1e50d10f | ||
|
|
b6ba1768a1 | ||
|
|
c38dd997d2 | ||
|
|
f8ca1bae5d | ||
|
|
3c60bcf2de | ||
|
|
3f857e3183 | ||
|
|
668c9634ca | ||
|
|
51c49b0de6 | ||
|
|
5723dac6ba | ||
|
|
680d3230ea | ||
|
|
8f679de352 | ||
|
|
86d435eee1 | ||
|
|
e4cf965bae | ||
|
|
78c846a0a8 | ||
|
|
c466c9c370 | ||
|
|
6994005a5f | ||
|
|
e43f06bfa6 | ||
|
|
9601687190 | ||
|
|
2ed94f1048 | ||
|
|
70045c30f3 | ||
|
|
ce88c0e1e4 | ||
|
|
494e82e581 | ||
|
|
edd15132fd | ||
|
|
add664441e | ||
|
|
58b0fb089f | ||
|
|
90e4845627 | ||
|
|
43f4d306be | ||
|
|
cb7d9baf7a | ||
|
|
f3aea5e6ec | ||
|
|
a7a1fcd98c | ||
|
|
ef8bcc8bc4 | ||
|
|
b3692d18b0 | ||
|
|
a7b2b675d5 | ||
|
|
7d7a8e47ac | ||
|
|
f0da17b75c | ||
|
|
d86b471402 | ||
|
|
767508fb87 | ||
|
|
c85d772e1b | ||
|
|
fde6524e46 | ||
|
|
b2886969f0 | ||
|
|
19ca5186e4 | ||
|
|
b86a34c909 | ||
|
|
d145fbc5cc | ||
|
|
3ca960e31b | ||
|
|
8bbaf7da68 | ||
|
|
14c2ab5ddd | ||
|
|
6f20a789f9 | ||
|
|
4bee15956a | ||
|
|
e4c179f5ed | ||
|
|
4811eb1558 | ||
|
|
69850d82c8 | ||
|
|
df88a89c14 | ||
|
|
c746a1ce17 | ||
|
|
ecdaed7d11 | ||
|
|
c062651821 | ||
|
|
3692740762 | ||
|
|
1179caab88 | ||
|
|
35b1a284f3 | ||
|
|
36432c65e9 | ||
|
|
871e718f63 | ||
|
|
42293596f3 | ||
|
|
ac8a13f039 | ||
|
|
d56ecaacdc | ||
|
|
14fbfe360e | ||
|
|
5334a3fd34 | ||
|
|
2fa9c6486e | ||
|
|
c221e96122 | ||
|
|
26c016fea2 | ||
|
|
b6a08ec712 | ||
|
|
9179c6c1e2 | ||
|
|
3f9aceb922 | ||
|
|
3da8efae49 | ||
|
|
b84207f955 | ||
|
|
f57de40668 | ||
|
|
e95df57642 | ||
|
|
aaddb2af1f | ||
|
|
082950cc18 | ||
|
|
90828965df | ||
|
|
17e026f9aa | ||
|
|
f1d7e50dc0 | ||
|
|
e2cb7b2102 | ||
|
|
28578a5d8a | ||
|
|
0d8e90b8da | ||
|
|
1556b911b2 | ||
|
|
eed73e3157 | ||
|
|
c020526b1e | ||
|
|
cca98e817f | ||
|
|
46a8a7d04c | ||
|
|
d4ddc87d81 | ||
|
|
b473460ffc | ||
|
|
db027bced3 | ||
|
|
12cc0b99f9 | ||
|
|
15cac529c5 | ||
|
|
feed2d6a45 | ||
|
|
b516db669c | ||
|
|
3bc58264ea | ||
|
|
0a0416ae38 | ||
|
|
d244956b4b | ||
|
|
37e3730e9d | ||
|
|
48532a0ae6 | ||
|
|
0b6b0f9c61 | ||
|
|
435ac80ff9 | ||
|
|
a098055fc9 | ||
|
|
cba5063b33 | ||
|
|
3787b80286 | ||
|
|
2858bd3784 | ||
|
|
ff58d8e443 | ||
|
|
5e178943a0 | ||
|
|
33ca3b2981 | ||
|
|
8c8c85d753 | ||
|
|
6535edf4e0 | ||
|
|
7e25570344 | ||
|
|
409210ccde | ||
|
|
555a62c582 | ||
|
|
36a070be4c | ||
|
|
d903e40a53 | ||
|
|
d78729f343 | ||
|
|
a55289196b | ||
|
|
3505b47d8f | ||
|
|
11836e6662 | ||
|
|
4ce38bde36 | ||
|
|
711f701d62 | ||
|
|
94c509b1e2 | ||
|
|
5c08a0e72c | ||
|
|
9c451271e0 | ||
|
|
55db6c2476 | ||
|
|
0861427bf3 | ||
|
|
9d3bf337e1 | ||
|
|
4e4eb35240 | ||
|
|
e7e3f58c8f | ||
|
|
c18830ce75 | ||
|
|
3f36a52685 | ||
|
|
64eb39a417 | ||
|
|
736ecae5ff | ||
|
|
6bd4a6a037 | ||
|
|
4271938c3a | ||
|
|
e1441c1d33 | ||
|
|
9bd35a2cd2 | ||
|
|
d4e194fbf7 | ||
|
|
003d556f3d | ||
|
|
1da3b3f08e | ||
|
|
f08c176b68 | ||
|
|
780aadedf2 | ||
|
|
3fe279e229 | ||
|
|
c43af5d3d9 | ||
|
|
65b80200bd | ||
|
|
6e5a41a880 | ||
|
|
fa87c74b56 | ||
|
|
8142da608c | ||
|
|
eacc748b09 | ||
|
|
def41802b8 | ||
|
|
38dcdff659 | ||
|
|
bd9540cea3 | ||
|
|
0d71fe65f6 | ||
|
|
54c70581a2 | ||
|
|
3abddd6f84 | ||
|
|
8e712bc827 | ||
|
|
2018149395 | ||
|
|
ecea17195a | ||
|
|
a28d0823b2 | ||
|
|
6e6561a267 | ||
|
|
8b1db22a53 | ||
|
|
3d09ea386b | ||
|
|
300daea4f9 | ||
|
|
7653da0e4f | ||
|
|
19b4da07b9 | ||
|
|
ff9f93fba4 | ||
|
|
fed26071ac | ||
|
|
a4fbfbef02 | ||
|
|
347751a826 | ||
|
|
fbb3a9a0a4 | ||
|
|
f8f1facf43 | ||
|
|
0d6441d0b6 | ||
|
|
a009b2f9b5 | ||
|
|
7852aedabd | ||
|
|
b2d7d1b4cb | ||
|
|
ec50b28f4b | ||
|
|
4ed36d9bbe | ||
|
|
887772a428 | ||
|
|
e9169b890d | ||
|
|
b716c04d96 | ||
|
|
2d3cbc9783 | ||
|
|
23a497abf6 | ||
|
|
d00b90cd61 | ||
|
|
f4fe8808a4 | ||
|
|
02193b0523 | ||
|
|
c9310ea429 | ||
|
|
c76e4239bb | ||
|
|
8a8d45c91e | ||
|
|
071f99560e | ||
|
|
8b23c2c4cd | ||
|
|
0d640d1215 | ||
|
|
b4d63857ce | ||
|
|
4976484d91 | ||
|
|
16627d10b6 | ||
|
|
83ca7d2574 | ||
|
|
956afc0382 | ||
|
|
312ff110ec | ||
|
|
214d07c468 | ||
|
|
2c68d1b866 | ||
|
|
5171215817 | ||
|
|
195148a2a2 | ||
|
|
edf664e19a | ||
|
|
0668e4c48a | ||
|
|
d75787726c | ||
|
|
1e0d7fb0a3 | ||
|
|
454698bf98 | ||
|
|
bfeb0ef2ad | ||
|
|
1cf2b11f1e | ||
|
|
0ce4029483 | ||
|
|
504e82e9fd | ||
|
|
eca6a9f247 | ||
|
|
94d4385d41 | ||
|
|
c41bb0ec42 | ||
|
|
00b71cafc9 | ||
|
|
3cd69dabe9 | ||
|
|
10fa3b5a31 | ||
|
|
b43790e9d2 | ||
|
|
ee5f4b9b42 | ||
|
|
e5db842dd6 | ||
|
|
657a11b1f4 | ||
|
|
0ef1e23c69 | ||
|
|
141512f2f7 | ||
|
|
671983724a | ||
|
|
81571fc014 | ||
|
|
f806409d80 | ||
|
|
f3c347424b | ||
|
|
8cbd9b7935 | ||
|
|
158d273dbe | ||
|
|
1258d2f0a1 | ||
|
|
36422ab22b | ||
|
|
191cea7fb3 | ||
|
|
f8cc0e41d1 | ||
|
|
f29f9e1aba | ||
|
|
34fdcf8f6f | ||
|
|
adef08af3e | ||
|
|
1301e8fc99 | ||
|
|
eee1c0628b | ||
|
|
9ce839c9d8 | ||
|
|
401fc4d2eb | ||
|
|
4e7f1377bf | ||
|
|
fccf796eeb | ||
|
|
500edb7860 | ||
|
|
cb168b0c8a | ||
|
|
74131f816c | ||
|
|
f1ef21eb0d | ||
|
|
79406613c1 | ||
|
|
89c1e3b60d | ||
|
|
224634d8d2 | ||
|
|
e42d37e86d | ||
|
|
191c9e9302 | ||
|
|
a482ddf0f6 | ||
|
|
7245e84f00 | ||
|
|
e287600c34 | ||
|
|
817585a9a6 | ||
|
|
eae8bc05c9 | ||
|
|
026d279556 | ||
|
|
8177893e28 | ||
|
|
70de83827d | ||
|
|
5af9536db1 | ||
|
|
cb7b2dabf5 | ||
|
|
01987a0374 | ||
|
|
5528b5b92c | ||
|
|
1838354b70 | ||
|
|
1f1edd9b23 | ||
|
|
2b7a4364b1 | ||
|
|
2f45d3edf3 | ||
|
|
a20d20574e | ||
|
|
d78832498e | ||
|
|
e2c6170eba | ||
|
|
6864af762c | ||
|
|
a8daa2160f | ||
|
|
b84aaa1dab | ||
|
|
c6de77130f | ||
|
|
02ba924f33 | ||
|
|
318df64e54 | ||
|
|
cb45867de8 | ||
|
|
c4ca0e51e2 | ||
|
|
7bb12fd33c | ||
|
|
001213ee2c | ||
|
|
f320705216 | ||
|
|
d4ed77fdc6 | ||
|
|
ef1202923e | ||
|
|
e1e98f5048 | ||
|
|
5bb3cc88e5 | ||
|
|
43eff69a2f | ||
|
|
450da59057 | ||
|
|
dda4d58a23 | ||
|
|
f5d5ed9844 | ||
|
|
2342d53dba | ||
|
|
005d83c6fe | ||
|
|
8c4fb3fefb | ||
|
|
b0fa0d1ec8 | ||
|
|
2ce5797d5e | ||
|
|
c2617e5a1d | ||
|
|
3f73e31d9e | ||
|
|
84a48adbdd | ||
|
|
63c29a318e | ||
|
|
69748fd72e | ||
|
|
35278c6e90 | ||
|
|
088fc35435 | ||
|
|
4baad6b89c | ||
|
|
9a23f806fe | ||
|
|
82b466db0b | ||
|
|
a6edf04a60 | ||
|
|
3ba675a899 | ||
|
|
1fed7a9a3a | ||
|
|
80fb91b6d7 | ||
|
|
5b0c2a4131 | ||
|
|
bb43e8f7b6 | ||
|
|
4d9a10147a | ||
|
|
ea4f5cf919 | ||
|
|
295bc9f76d | ||
|
|
327806d9a1 | ||
|
|
80e7558fc0 | ||
|
|
9cda59511e | ||
|
|
c12a031918 | ||
|
|
a4f580e319 | ||
|
|
583bf88207 | ||
|
|
a5f8e83e03 | ||
|
|
e2f17f11d3 | ||
|
|
4f8c040d06 | ||
|
|
af1d068022 | ||
|
|
1bd8d1c85c | ||
|
|
d7fc859d14 | ||
|
|
ac953cd114 | ||
|
|
6e6dd041d5 | ||
|
|
9b3c8a9df2 | ||
|
|
234a481b0d | ||
|
|
89b3c9233e | ||
|
|
5d61a43fe1 | ||
|
|
29d5ccf751 | ||
|
|
fde0665593 | ||
|
|
29541b0995 | ||
|
|
05f31c5ddf | ||
|
|
f89840545d | ||
|
|
18534f8576 | ||
|
|
1382a05dc8 | ||
|
|
1671d4839c | ||
|
|
4d2fbd04c5 | ||
|
|
dc6b9b89cd | ||
|
|
76f36aa895 | ||
|
|
fa835e9c64 | ||
|
|
c8dc874a56 | ||
|
|
b3a6307052 | ||
|
|
3ca0181b79 | ||
|
|
98557dcecf | ||
|
|
3351092c79 | ||
|
|
68cd509d41 | ||
|
|
5fa65b42ae | ||
|
|
bdae259a1d | ||
|
|
fea86ea70e | ||
|
|
1133770aeb | ||
|
|
2c462106bc | ||
|
|
bd1e624c91 | ||
|
|
6875fa4c7e | ||
|
|
def5f2155d | ||
|
|
73d2457fea | ||
|
|
bc52ca856e | ||
|
|
18ccea320a | ||
|
|
f6cb9ff470 | ||
|
|
14c6c2a055 | ||
|
|
68d0aa9688 | ||
|
|
1ef4e15a4d | ||
|
|
d35b4b9128 | ||
|
|
6995be7dbd | ||
|
|
f9de6763d3 | ||
|
|
dfce971565 | ||
|
|
97e3f32d7f | ||
|
|
c86e1a5973 | ||
|
|
ab545dc44c | ||
|
|
11cd57e8fb | ||
|
|
b7c18d0785 | ||
|
|
9aec89f381 | ||
|
|
e34984513d | ||
|
|
cedd42f411 | ||
|
|
c9b75aabb2 | ||
|
|
41ae12ed3d | ||
|
|
dba35f043d | ||
|
|
8046b8594a | ||
|
|
6c64aaefec | ||
|
|
07fa87dc6a | ||
|
|
b58c98bea0 | ||
|
|
08e553bd1a | ||
|
|
e35fb82bc2 | ||
|
|
a92ca63ca9 | ||
|
|
cbfad7b320 | ||
|
|
c16987fb87 | ||
|
|
477f5a7841 | ||
|
|
6f149224d1 | ||
|
|
1a6ad2fdb0 | ||
|
|
76e511a774 | ||
|
|
9681933ec2 | ||
|
|
711bfed557 | ||
|
|
016a1b3421 | ||
|
|
01b9ec4a42 | ||
|
|
9b729dd091 | ||
|
|
0a73be2082 | ||
|
|
c668879070 | ||
|
|
c4d318b7d0 | ||
|
|
e7d9dbfbcf | ||
|
|
1be3daf0b5 | ||
|
|
8f86849aec | ||
|
|
0b4ee9e73e | ||
|
|
65f88834ba | ||
|
|
024c56efdd | ||
|
|
9c487b0aac | ||
|
|
d743f928ad | ||
|
|
07e2fe3af1 | ||
|
|
9f384c71f3 | ||
|
|
7a5aea0bcf | ||
|
|
b6c9bc1439 | ||
|
|
b7f38517ef | ||
|
|
60f54ee37d | ||
|
|
adf1273bf9 | ||
|
|
3c79e9e59d | ||
|
|
1ab1b5713e | ||
|
|
edf2f295d1 | ||
|
|
c043416b11 | ||
|
|
4a471f0a93 | ||
|
|
04a1d8197f | ||
|
|
d9bf099c3d | ||
|
|
d2f2140be9 | ||
|
|
04f88e460b | ||
|
|
d64f73e719 | ||
|
|
2ab4dcbc11 | ||
|
|
846043e9a0 | ||
|
|
ea57e4ae01 | ||
|
|
6aa5e5cc4a | ||
|
|
3e5bd4cf09 | ||
|
|
3d096c1f31 | ||
|
|
b5b6bce758 | ||
|
|
46ed8e954f | ||
|
|
cfca2f7550 | ||
|
|
a09df9bf3a | ||
|
|
dc2462c277 | ||
|
|
25c7ebcf39 | ||
|
|
baab65d776 | ||
|
|
9e2b906048 | ||
|
|
9f3c2683ae | ||
|
|
9e01a1a427 | ||
|
|
db729241c9 | ||
|
|
d5d8c80d74 | ||
|
|
4c48ccb422 | ||
|
|
53e7c83254 | ||
|
|
fdef1062f0 | ||
|
|
b9f8fc2e11 | ||
|
|
db410fb3e7 | ||
|
|
500dadc760 | ||
|
|
7d61953753 | ||
|
|
5b9b76d5e7 | ||
|
|
b9804d8980 | ||
|
|
b960ee365a | ||
|
|
302f0acbaa | ||
|
|
8f5b97b9d2 | ||
|
|
6371cf7517 | ||
|
|
e53520aef6 | ||
|
|
d59fd71ba5 | ||
|
|
4b967a749b | ||
|
|
8f88a8dcb3 | ||
|
|
a58ba406eb | ||
|
|
a93ca9b7bc | ||
|
|
02e6b5f1b3 | ||
|
|
63dd5f3f64 | ||
|
|
a3a50e9cd5 | ||
|
|
8e3c1aaa96 | ||
|
|
8b71437264 | ||
|
|
61d0ed3f01 | ||
|
|
fc2b7b63a2 | ||
|
|
96590a3389 | ||
|
|
a043de3e44 | ||
|
|
81d3900ef6 | ||
|
|
fd136384a1 | ||
|
|
dd5fe117b5 | ||
|
|
e9d29f789f | ||
|
|
1bc1f646fd | ||
|
|
8ad55cb634 | ||
|
|
b19dec120a | ||
|
|
283c088b21 | ||
|
|
d5ffed09b4 | ||
|
|
b7eec09307 | ||
|
|
23f0f98af3 | ||
|
|
6bbdbc89a6 | ||
|
|
12c8623666 | ||
|
|
2bd6ebd2b1 | ||
|
|
40fb496052 | ||
|
|
b72d822f94 | ||
|
|
6d92ac9af6 | ||
|
|
47f27a8016 | ||
|
|
849d095e9a | ||
|
|
923f240aa1 | ||
|
|
8655ff2de3 | ||
|
|
6f61010cf9 | ||
|
|
5082badca4 | ||
|
|
307bd2a35f | ||
|
|
a11552f497 | ||
|
|
8556caaeb4 | ||
|
|
7c09012b3d | ||
|
|
eb596caa00 | ||
|
|
ab4501aa4c | ||
|
|
4b766d373d | ||
|
|
e3574edc5d | ||
|
|
dcb69ddc73 | ||
|
|
1d6ad297a4 | ||
|
|
85a5e517c9 | ||
|
|
b08d380643 | ||
|
|
ad98fc4121 | ||
|
|
810689c037 | ||
|
|
c007700c59 | ||
|
|
8cc3f6626b | ||
|
|
a3b8a4adc9 | ||
|
|
8f817c089b | ||
|
|
ed4e7794c3 | ||
|
|
6f732d410e | ||
|
|
6c8da20883 | ||
|
|
c7d9ce7f7f | ||
|
|
4e7f639076 | ||
|
|
b2c3b3a99f | ||
|
|
77338d66dc | ||
|
|
e2130df596 | ||
|
|
2bbe6d6069 | ||
|
|
c8b8e505f3 | ||
|
|
89743f9900 | ||
|
|
dbc0562fb0 | ||
|
|
76f4dff14c | ||
|
|
baa2a2f24f | ||
|
|
2ca02911b3 | ||
|
|
cf48237049 | ||
|
|
adfe2c1975 | ||
|
|
a782043798 | ||
|
|
90c4a2f53c | ||
|
|
338b371e4c | ||
|
|
347179373d | ||
|
|
3bb45b80b1 | ||
|
|
e3ec0f3b9b | ||
|
|
f20572b30c | ||
|
|
2124cce603 | ||
|
|
ebf60c1e70 | ||
|
|
c31b6c3683 | ||
|
|
ffc83343fe | ||
|
|
2554acd304 | ||
|
|
98239114ad | ||
|
|
c10b39c1c7 | ||
|
|
20e11465e4 | ||
|
|
46e1b95b33 | ||
|
|
279d6f16e1 | ||
|
|
a747eccaa3 | ||
|
|
0bafbc3184 | ||
|
|
8069370b8c | ||
|
|
46f4b92ff7 | ||
|
|
d92f5ce71c | ||
|
|
2314bf8bd4 | ||
|
|
7808b21496 | ||
|
|
18ef412211 | ||
|
|
0678328253 | ||
|
|
5503e1e14c | ||
|
|
9e89cfa4ed | ||
|
|
13f454a022 | ||
|
|
129650dade | ||
|
|
6fa5b80c0a | ||
|
|
04dfcd0965 | ||
|
|
2e818ac709 | ||
|
|
32ef61197f | ||
|
|
fa06cd8253 | ||
|
|
5020983af5 | ||
|
|
f4496b6977 | ||
|
|
a1719d651e | ||
|
|
e7be2b68a3 | ||
|
|
552dcb56a1 | ||
|
|
e158a65603 | ||
|
|
b694e8aaa2 | ||
|
|
a2e09121ba | ||
|
|
4ce7dfa8f0 | ||
|
|
1c4ce7b4bd | ||
|
|
8a04c1e232 | ||
|
|
6e5d378324 | ||
|
|
8e1f3617fd | ||
|
|
2549ed830f | ||
|
|
0ebd64d314 | ||
|
|
843ecb4a42 | ||
|
|
a1a0d34940 | ||
|
|
15bb978dab | ||
|
|
6a7cf39548 | ||
|
|
8ccb70d07d | ||
|
|
45461a93b0 | ||
|
|
b3a54a78bc | ||
|
|
a4182b5ff9 | ||
|
|
215dcde4b9 | ||
|
|
67b2a9a4f4 | ||
|
|
3b51b23ac2 | ||
|
|
e0f19f8121 | ||
|
|
e720fb528a | ||
|
|
518a5454c6 | ||
|
|
2d9c846084 | ||
|
|
59e30f05fc | ||
|
|
0f1085a02d | ||
|
|
882699919e | ||
|
|
f6a70a542e | ||
|
|
785b1fe937 | ||
|
|
bae909ba10 | ||
|
|
dbb9757a9f | ||
|
|
deaeb46ce9 | ||
|
|
219012bc35 | ||
|
|
5f9eb22d23 | ||
|
|
2c33fb6834 | ||
|
|
8bcef6022b | ||
|
|
93d36779f0 | ||
|
|
2502f5e6f2 | ||
|
|
95f2852cf3 | ||
|
|
ff9f712d65 | ||
|
|
60c4e75a1c | ||
|
|
ccf7c48bf1 | ||
|
|
65d81eb31e | ||
|
|
b97eb12dfc | ||
|
|
d2724d77df | ||
|
|
119b21ac67 |
No files matched your search
@@ -0,0 +1,183 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE module PUBLIC "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
|
||||
"https://checkstyle.org/dtds/configuration_1_3.dtd">
|
||||
|
||||
<!-- based on https://github.com/KyoriPowered/adventure/blob/master/.checkstyle/checkstyle.xml -->
|
||||
|
||||
<module name="Checker">
|
||||
<property name="charset" value="UTF-8"/>
|
||||
<property name="fileExtensions" value="java, properties, xml"/>
|
||||
<property name="severity" value="error"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_filefilters.html#BeforeExecutionExclusionFileFilter -->
|
||||
<module name="BeforeExecutionExclusionFileFilter">
|
||||
<property name="fileNamePattern" value="module\-info\.java$"/>
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_whitespace.html#FileTabCharacter -->
|
||||
<module name="FileTabCharacter">
|
||||
<property name="eachLine" value="true"/>
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_misc.html#NewlineAtEndOfFile -->
|
||||
<module name="NewlineAtEndOfFile"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_filters.html#SuppressionFilter -->
|
||||
<module name="SuppressionFilter">
|
||||
<property name="file" value="${configDirectory}/suppressions.xml"/>
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_filters.html#SuppressWithPlainTextCommentFilter -->
|
||||
<module name="SuppressWithPlainTextCommentFilter"/>
|
||||
|
||||
<module name="TreeWalker">
|
||||
<!-- https://checkstyle.org/config_misc.html#ArrayTypeStyle -->
|
||||
<module name="ArrayTypeStyle"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_imports.html#AvoidStarImport -->
|
||||
<module name="AvoidStarImport"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_misc.html#AvoidEscapedUnicodeCharacters -->
|
||||
<module name="AvoidEscapedUnicodeCharacters">
|
||||
<property name="allowByTailComment" value="true"/>
|
||||
<property name="allowEscapesForControlCharacters" value="true"/>
|
||||
<property name="allowNonPrintableEscapes" value="true"/>
|
||||
<property name="severity" value="info"/>
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_misc.html#CommentsIndentation -->
|
||||
<module name="CommentsIndentation"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_whitespace.html#EmptyForInitializerPad -->
|
||||
<module name="EmptyForInitializerPad"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_whitespace.html#EmptyForIteratorPad -->
|
||||
<module name="EmptyForIteratorPad"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_whitespace.html#EmptyLineSeparator -->
|
||||
<module name="EmptyLineSeparator">
|
||||
<property name="allowMultipleEmptyLines" value="false"/>
|
||||
<property name="allowMultipleEmptyLinesInsideClassMembers" value="false"/>
|
||||
<property name="allowNoEmptyLineBetweenFields" value="true"/>
|
||||
<property name="tokens"
|
||||
value="CLASS_DEF, CTOR_DEF, ENUM_DEF, IMPORT, INSTANCE_INIT, INTERFACE_DEF, METHOD_DEF, STATIC_IMPORT, STATIC_INIT, VARIABLE_DEF"/> <!-- remove PACKAGE_DEF, temporarily remove COMPACT_CTOR_DEF, RECORD_DEF -->
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_coding.html#FallThrough -->
|
||||
<module name="FallThrough">
|
||||
<property name="checkLastCaseGroup" value="true"/>
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_design.html#FinalClass -->
|
||||
<module name="FinalClass"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_coding.html#FinalLocalVariable -->
|
||||
<module name="FinalLocalVariable"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_whitespace.html#GenericWhitespace -->
|
||||
<module name="GenericWhitespace"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_design.html#HideUtilityClassConstructor -->
|
||||
<module name="HideUtilityClassConstructor"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_imports.html#IllegalImport -->
|
||||
<module name="IllegalImport">
|
||||
<property name="illegalPkgs" value="sun, jdk, com.sun"/>
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_coding.html#IllegalTokenText -->
|
||||
<module name="IllegalTokenText">
|
||||
<property name="format"
|
||||
value="\\u00(09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)|134)"/>
|
||||
<property name="message"
|
||||
value="Consider using special escape sequence instead of octal value or Unicode escaped value."/>
|
||||
<property name="tokens" value="CHAR_LITERAL, STRING_LITERAL"/>
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_misc.html#Indentation -->
|
||||
<module name="Indentation"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_blocks.html#LeftCurly -->
|
||||
<module name="LeftCurly"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_naming.html#MethodName -->
|
||||
<module name="MethodName">
|
||||
<property name="format" value="^[_]?[a-z][a-zA-Z0-9]*$"/>
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_whitespace.html#MethodParamPad -->
|
||||
<module name="MethodParamPad"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_javadoc.html#MissingJavadocMethod -->
|
||||
<module name="MissingJavadocMethod">
|
||||
<property name="allowMissingPropertyJavadoc" value="true"/>
|
||||
<property name="tokens" value="METHOD_DEF, ANNOTATION_FIELD_DEF"/> <!-- remove CTOR_DEF, COMPACT_CTOR_DEF -->
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_javadoc.html#MissingJavadocType -->
|
||||
<module name="MissingJavadocType"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_coding.html#NoFinalizer -->
|
||||
<module name="NoFinalizer"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_whitespace.html#NoLineWrap -->
|
||||
<module name="NoLineWrap"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_whitespace.html#NoWhitespaceAfter -->
|
||||
<module name="NoWhitespaceAfter">
|
||||
<property name="allowLineBreaks" value="false"/>
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_whitespace.html#NoWhitespaceBefore -->
|
||||
<module name="NoWhitespaceBefore">
|
||||
<property name="allowLineBreaks" value="true"/>
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_coding.html#OneStatementPerLine -->
|
||||
<module name="OneStatementPerLine"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_misc.html#OuterTypeFilename -->
|
||||
<module name="OuterTypeFilename"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_imports.html#RedundantImport -->
|
||||
<module name="RedundantImport"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_modifier.html#RedundantModifier -->
|
||||
<module name="RedundantModifier">
|
||||
<property name="tokens"
|
||||
value="ANNOTATION_FIELD_DEF, CLASS_DEF, CTOR_DEF, ENUM_DEF, INTERFACE_DEF, VARIABLE_DEF"/> <!-- remove METHOD_DEF and RESOURCE -->
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_coding.html#RequireThis -->
|
||||
<module name="RequireThis"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_blocks.html#RightCurly -->
|
||||
<module name="RightCurly">
|
||||
<property name="id" value="RightCurlyAlone"/>
|
||||
<property name="option" value="alone"/>
|
||||
<property name="tokens"
|
||||
value="ANNOTATION_DEF, CLASS_DEF, CTOR_DEF, ENUM_DEF, INSTANCE_INIT, LITERAL_FOR, LITERAL_WHILE, METHOD_DEF, STATIC_INIT"/>
|
||||
</module>
|
||||
<module name="RightCurly">
|
||||
<property name="id" value="RightCurlySame"/>
|
||||
<property name="option" value="same"/>
|
||||
<property name="tokens"
|
||||
value="LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY, LITERAL_IF, LITERAL_TRY"/> <!-- add LITERAL_DO -->
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_whitespace.html#SingleSpaceSeparator -->
|
||||
<module name="SingleSpaceSeparator">
|
||||
<property name="validateComments" value="true"/>
|
||||
</module>
|
||||
|
||||
<!-- https://checkstyle.org/config_whitespace.html#TypecastParenPad -->
|
||||
<module name="TypecastParenPad"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_coding.html#UnnecessaryParentheses -->
|
||||
<module name="UnnecessaryParentheses"/>
|
||||
|
||||
<!-- https://checkstyle.org/config_imports.html#UnusedImports -->
|
||||
<module name="UnusedImports"/>
|
||||
|
||||
</module>
|
||||
</module>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE suppressions PUBLIC "-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN" "http://checkstyle.org/dtds/suppressions_1_2.dtd">
|
||||
<suppressions>
|
||||
<suppress files=".*[\\/]test[\\/]java[\\/].*" checks="RequireExplicitVisibilityModifier"/>
|
||||
<!-- TODO: don't suppress I-prefixed API interfaces under com.earth2me.essentials -->
|
||||
<suppress files="(com[\\/]earth2me[\\/]essentials[\\/]|net[\\/]ess3[\\/]|net[\\/]essentialsx[\\/])(?:[^\\/]+$|(?!api)[^\\/]+[\\/])" checks="MissingJavadoc(Method|Type)"/>
|
||||
</suppressions>
|
||||
+3
-3
@@ -1,10 +1,10 @@
|
||||
# Currently used
|
||||
patreon: EssentialsX
|
||||
ko_fi: essentialsx
|
||||
github: EssentialsX
|
||||
open_collective: EssentialsX
|
||||
|
||||
# Currently not used
|
||||
#github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
#open_collective: # Replace with a single Open Collective username
|
||||
#ko_fi: # Replace with a single Ko-fi username
|
||||
#tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
#community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
#liberapay: # Replace with a single Liberapay username
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: View common issues
|
||||
url: https://github.com/EssentialsX/Essentials/issues/3956
|
||||
about: Check the list of known common issues to see if it solves your problem.
|
||||
- name: Check past help requests
|
||||
url: https://github.com/EssentialsX/Essentials/discussions/categories/q-a
|
||||
about: Visit the Q&A forum to search for previous help requests.
|
||||
- name: Check past feature suggestions
|
||||
url: https://github.com/EssentialsX/Essentials/discussions/categories/ideas-and-feature-suggestions
|
||||
about: Visit the Feature Suggestions forum to view and discuss existing feature suggestions.
|
||||
- name: Create help request
|
||||
url: https://github.com/EssentialsX/Essentials/discussions/new?category=q-a
|
||||
about: Create a support ticket to get help from developers.
|
||||
- name: Suggest a feature
|
||||
url: https://github.com/EssentialsX/Essentials/discussions/new?category=ideas-and-feature-suggestions
|
||||
about: Suggest new features for EssentialsX!
|
||||
- name: Get help from the community on Discord
|
||||
url: https://discord.gg/casfFyh
|
||||
about: Join the MOSS Discord for community-powered EssentialsX support!
|
||||
@@ -1,45 +0,0 @@
|
||||
---
|
||||
name: Help!
|
||||
about: Encountered a problem with EssentialsX? Not sure how to fix it?
|
||||
|
||||
---
|
||||
|
||||
<!-- EssentialsX help guide
|
||||
|
||||
Don't write inside the arrows as they will be hidden when you post your issue.
|
||||
|
||||
Want faster support? Come join our Discord server to get help sooner:
|
||||
https://discord.gg/F7gexAQ
|
||||
|
||||
If you're happy to wait (or you were sent here from Discord), read on:
|
||||
|
||||
1. Fill out the template.
|
||||
This will help us understand what problem you've encountered and help us
|
||||
find a solution.
|
||||
|
||||
2. Check the Common Issues page.
|
||||
Read through the wiki page to see if you've encountered a regular issue:
|
||||
https://essentialsx.github.io/#/Common-Issues
|
||||
|
||||
3. Delete this line and all above lines before posting your issue! -->
|
||||
|
||||
### Information
|
||||
|
||||
Full output of `/ess version`:
|
||||
|
||||
<!-- Replace this with the command output -->
|
||||
|
||||
**Server log:** <!-- Upload `logs/latest.log` to https://gist.github.com/ -->
|
||||
|
||||
**EssentialsX config** <!-- Upload `plugins/Essentials/config.yml` to https://gist.github.com/ -->
|
||||
|
||||
### Help request
|
||||
|
||||
**Problem**
|
||||
<!-- What problem did you encounter? -->
|
||||
|
||||
**What I have tried**
|
||||
<!-- What have you tried so far? -->
|
||||
|
||||
**Screenshots**
|
||||
<!-- If relevant, include any screenshots here. -->
|
||||
@@ -1,58 +0,0 @@
|
||||
---
|
||||
name: Report a bug
|
||||
about: Report an EssentialsX bug. Only use this if you're 100% sure there's something wrong with EssentialsX - otherwise, try "Help!".
|
||||
|
||||
---
|
||||
|
||||
<!-- EssentialsX bug reporting guide
|
||||
|
||||
Don't put anything inside this block, as it won't be included in the issue.
|
||||
|
||||
If you are reporting a bug, please follow the following steps:
|
||||
|
||||
1. Fill out the template in full.
|
||||
Run the commands in the console. Don't just put "latest" as a version,
|
||||
or we will ignore it.
|
||||
|
||||
2. When linking files, do not attach them to the post!
|
||||
Copy and paste any logs into https://gist.github.com/, then paste a
|
||||
link to them in the relevant parts of the template. Avoid using
|
||||
Hastebin or Pastebin, as this makes providing support more difficult.
|
||||
**DO NOT drag files into this box!**
|
||||
|
||||
3. If you are reporting a performance issue, please include a link to a
|
||||
Timings and/or profiler report.
|
||||
|
||||
4. If you are reporting a bug with commands or something else in-game,
|
||||
please include screenshots to help us diagnose the problem.
|
||||
|
||||
5. Make sure not to write between the arrows, as anything there will be
|
||||
hidden.
|
||||
|
||||
6. Delete this line and all above lines before posting your issue! -->
|
||||
|
||||
### Information
|
||||
|
||||
**Full output of `/ess version`**:
|
||||
|
||||
```
|
||||
<!-- Run the command in your console, and copy and paste the whole output here -->
|
||||
```
|
||||
|
||||
**Server log**: <!-- Upload `logs/latest.log` to https://gist.github.com/, replace this with link -->
|
||||
|
||||
**EssentialsX config**: <!-- Upload `plugins/Essentials/config.yml` to https://gist.github.com/, replace this with link -->
|
||||
|
||||
### Details
|
||||
|
||||
**Description**
|
||||
<!-- Replace this with a brief summary of the bug. -->
|
||||
|
||||
**Steps to reproduce**
|
||||
<!-- Replace this with exactly what you did to cause the bug. -->
|
||||
|
||||
**Expected behavior**
|
||||
<!-- Replace this with what you expected to happen. -->
|
||||
|
||||
**Screenshots**
|
||||
<!-- Replace this with screenshots, if necessary. -->
|
||||
@@ -0,0 +1,79 @@
|
||||
name: Report bug
|
||||
description: Report a bug in EssentialsX.
|
||||
labels: 'bug: unconfirmed'
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to report an EssentialsX bug! Fill out the form below to provide us with info to help fix the bug.
|
||||
Only use this if you're 100% sure you've found a bug and can reproduce it. If you're looking for general help with EssentialsX, try the Q&A forum or MOSS Discord server.
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Type of bug
|
||||
description: What type of bug is this? Choose all that apply.
|
||||
multiple: true
|
||||
options:
|
||||
- Performance issue or memory leak
|
||||
- Data loss
|
||||
- Exploit
|
||||
- Compatibility issue
|
||||
- Error in console
|
||||
- Other unexpected behaviour
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
label: "`/ess dump all` output"
|
||||
description: Run `/ess dump all` in the console, then copy and paste the link from the output of the command into this box. (If this command doesn't work, you should [update EssentialsX](https://essentialsx.net/downloads.html) and try again.)
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: Error log (if applicable)
|
||||
description: If you are reporting a console error, upload any relevant log excerpts to either https://paste.gg or https://gist.github.com, save and the paste the link in this box. If you included those files in the same paste as your startup log, paste the same link here.
|
||||
placeholder: "Example: https://paste.gg/p/anonymous/109dd6a10a734a3aa430d5a351ea5210"
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Bug description
|
||||
description: Describe roughly what the bug is here.
|
||||
placeholder: |
|
||||
Example: "When running /nuke after putting everyone into adventure mode, there aren't any explosions..."
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Provide an example of how to trigger the bug.
|
||||
placeholder: |
|
||||
Example:
|
||||
1. Have at least 3 people online
|
||||
2. Run `/gma *` to put everyone into adventure mode
|
||||
3. Run `/nuke`
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Expected behaviour
|
||||
description: Explain what you should expect to happen.
|
||||
placeholder: |
|
||||
Example: "Everything should explode!"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Actual behaviour
|
||||
description: Explain what actually happens.
|
||||
placeholder: |
|
||||
Example: "Everything doesn't explode :("
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
In the text box below, you can attach any relevant screenshots, files and links to Timings/spark profiler reports.
|
||||
You can also include a link to a heapdump if necessary, but please make sure you don't include any private player data in the heapdump.
|
||||
If you suspect this issue is related to a prior issue/PR/commit, please mention it here.
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
---
|
||||
name: Request a feature
|
||||
about: Suggest a feature you want to see in EssentialsX!
|
||||
|
||||
---
|
||||
|
||||
<!-- EssentialsX feature request guide
|
||||
|
||||
Fill out the template. Don't write inside the arrows as they will be hidden
|
||||
when you post your issue.
|
||||
|
||||
Not sure if your feature fits in EssentialsX? Feel free to ask on our Discord
|
||||
server: https://discord.gg/F7gexAQ
|
||||
|
||||
If you have a feature suggestion for EssentialsX, read the following tips:
|
||||
|
||||
1. Fill out the template.
|
||||
This will help us understand what you're requesting and why you want us
|
||||
to add it.
|
||||
|
||||
2. Keep it simple.
|
||||
Make sure it's easy to understand what you're requesting. A good way is
|
||||
to keep it to one request per GitHub issue, as we can then easily track
|
||||
feature requests.
|
||||
|
||||
3. Check whether it has already been asked or added.
|
||||
You can search the issue tracker to see if your feature has already been
|
||||
requested at https://github.com/EssentialsX/Essentials/issues. You can
|
||||
also check the wiki at https://essentialsx.github.io/ to see if the
|
||||
feature was recently added.
|
||||
|
||||
4. Ask yourself: "Does this belong in EssentialsX?"
|
||||
There are lots of features that we reject because most servers won't
|
||||
need or use them. If your feature is very specific or already exists in
|
||||
another plugin, it might not be a good fit for EssentialsX.
|
||||
|
||||
5. Delete this line and all above lines before posting your issue! -->
|
||||
|
||||
### Feature request
|
||||
|
||||
**Feature description**
|
||||
<!-- What feature are you suggesting? -->
|
||||
|
||||
**How the feature is useful**
|
||||
<!-- How is the feature useful to players, server owners and/or developers? -->
|
||||
@@ -0,0 +1,94 @@
|
||||
<!--
|
||||
|
||||
EssentialsX bug fix submission guide
|
||||
====================================
|
||||
|
||||
NOTE: Failure to fill out this template properly may result in your PR being
|
||||
delayed or ignored without warning.
|
||||
|
||||
NOTE: Don't type between any arrows in the template, as this text will be
|
||||
hidden. This includes this header block and any other explanation text
|
||||
blocks.
|
||||
|
||||
Want to discuss your PR before submitting it? Join the EssentialsX Development
|
||||
server: https://discord.gg/CUN7qVb
|
||||
|
||||
|
||||
EssentialsX is GPL
|
||||
------------------
|
||||
|
||||
By contributing to EssentialsX, you agree to license your code under the
|
||||
GNU General Public License version 3, which can be found at the link below:
|
||||
https://github.com/EssentialsX/Essentials/blob/2.x/LICENSE
|
||||
|
||||
|
||||
Instructions
|
||||
------------
|
||||
|
||||
If you are submitting a bug fix, please follow the following steps:
|
||||
|
||||
1. Fill out the template in full.
|
||||
This includes providing screenshots and a link to the original bug
|
||||
report. If there isn't an existing bug report, we recommend opening a new
|
||||
detailed bug report BEFORE opening your PR to fix it, else your PR may be
|
||||
delayed or rejected without warning.
|
||||
|
||||
You can open a new bug report by following this link:
|
||||
https://github.com/EssentialsX/Essentials/issues/new/choose
|
||||
|
||||
2. When linking logs or config files, do not attach them to the post!
|
||||
Copy and paste any logs into https://gist.github.com/, then paste a
|
||||
link to them in the relevant parts of the template. Do not use Hastebin
|
||||
or Pastebin, as this can cause issues with future reviews.
|
||||
|
||||
DO NOT drag logs directly into this text box, as we cannot read these!
|
||||
|
||||
3. If you are fixing a performance issue, please include a link to a
|
||||
Timings and/or profiler report, both before and after your PR.
|
||||
|
||||
4. If you are fixing a visual bug, such as in commands, please include
|
||||
screenshots so that we can more easily review the proposed fix.
|
||||
(You can drag screenshots into the bottom of the editor.)
|
||||
|
||||
-->
|
||||
|
||||
### Information
|
||||
|
||||
<!--
|
||||
Replace #nnnn with the number of the original issue. If this PR fixes
|
||||
multiple issues, you should repeat the phrase "fixes #nnnn" for each issue.
|
||||
-->
|
||||
|
||||
This PR fixes #nnnn.
|
||||
|
||||
### Details
|
||||
|
||||
**Proposed fix:**
|
||||
<!-- Type a description of your proposed fix below this line. -->
|
||||
|
||||
|
||||
**Environments tested:**
|
||||
|
||||
<!-- Type the OS you have used below. -->
|
||||
OS:
|
||||
|
||||
<!-- Type the JDK version (from java -version) you have used below. -->
|
||||
Java version:
|
||||
|
||||
<!--
|
||||
Put an "x" inside the boxes for the server software you have tested this
|
||||
bug fix on. If this feature does not apply to a server, strike through the server software using ~~strikethrough~~. If you have tested on other
|
||||
environments, add a new line with relevant details.
|
||||
-->
|
||||
- [ ] Most recent Paper version (1.XX.Y, git-Paper-BUILD)
|
||||
- [ ] CraftBukkit/Spigot/Paper 1.12.2
|
||||
- [ ] CraftBukkit 1.8.8
|
||||
|
||||
|
||||
**Demonstration:**
|
||||
<!--
|
||||
Below this block, include screenshots/log snippets from before and after as
|
||||
necessary. If you have created or used a test case plugin, please link to a
|
||||
download of the plugin, source code and exact version used where possible.
|
||||
-->
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: MOSS Discord Server
|
||||
url: https://discord.gg/casfFyh
|
||||
about: Need help with using EssentialsX? Join the MOSS Discord server for help.
|
||||
- name: EssentialsX Development Discord Server
|
||||
url: https://discord.gg/CUN7qVb
|
||||
about: Got questions or want to discuss changes before opening your PR? Join the EssentialsX Development Discord server. (Need help? Join MOSS instead.)
|
||||
@@ -0,0 +1,93 @@
|
||||
<!--
|
||||
|
||||
EssentialsX feature submission guide
|
||||
====================================
|
||||
|
||||
NOTE: Failure to fill out this template properly may result in your PR being
|
||||
delayed or ignored without warning.
|
||||
|
||||
NOTE: Don't type between any arrows in the template, as this text will be
|
||||
hidden. This includes this header block and any other explanation text
|
||||
blocks.
|
||||
|
||||
Want to discuss your PR before submitting it? Join the EssentialsX Development
|
||||
server: https://discord.gg/CUN7qVb
|
||||
|
||||
|
||||
EssentialsX is GPL
|
||||
------------------
|
||||
|
||||
By contributing to EssentialsX, you agree to license your code under the
|
||||
GNU General Public License version 3, which can be found at the link below:
|
||||
https://github.com/EssentialsX/Essentials/blob/2.x/LICENSE
|
||||
|
||||
|
||||
Instructions
|
||||
------------
|
||||
|
||||
If you are submitting a new feature, please follow the following steps:
|
||||
|
||||
1. Fill out the template in full.
|
||||
This includes providing screenshots and a link to the original feature
|
||||
request. If there isn't an existing feature request, we strongly
|
||||
recommend opening a new feature request BEFORE opening your PR to
|
||||
implement it, as this allows us to review whether we're likely to accept
|
||||
your feature in advance, and also allows us to discuss possible
|
||||
implementations for the feature. If there is no associated feature
|
||||
request, your PR may be delayed or rejected without warning.
|
||||
|
||||
You can open a new feature request by following this link:
|
||||
https://github.com/EssentialsX/Essentials/issues/new/choose
|
||||
|
||||
2. If you are fixing a performance issue, please use the "Bug fix" PR template
|
||||
instead. The "bug fix" template is better suited to performance issues.
|
||||
|
||||
3. Include a demonstration.
|
||||
If you are adding commands, please provide screenshots and/or a video
|
||||
demonstration of the feature. Similarly, if you are adding a new API,
|
||||
please include a link to example code that takes advantage of your
|
||||
proposed API. This will aid us in reviewing PRs and speed up the process
|
||||
significantly.
|
||||
|
||||
-->
|
||||
|
||||
### Information
|
||||
|
||||
<!--
|
||||
Replace #nnnn with the number of the original issue. If this PR implements
|
||||
features from multiple issues, you should repeat the phrase "closes #nnnn"
|
||||
for each issue.
|
||||
-->
|
||||
|
||||
This PR closes #nnnn.
|
||||
|
||||
### Details
|
||||
|
||||
**Proposed feature:**
|
||||
<!-- Type a description of your proposed feature below this line. -->
|
||||
|
||||
|
||||
**Environments tested:**
|
||||
|
||||
<!-- Type the OS you have used below. -->
|
||||
OS:
|
||||
|
||||
<!-- Type the JDK version (from java -version) you have used below. -->
|
||||
Java version:
|
||||
|
||||
<!--
|
||||
Put an "x" inside the boxes for the server software you have tested this
|
||||
bug fix on. If this feature does not apply to a server, strike through the server software using ~~strikethrough~~. If you have tested on other
|
||||
environments, add a new line with relevant details.
|
||||
-->
|
||||
- [ ] Most recent Paper version (1.XX.Y, git-Paper-BUILD)
|
||||
- [ ] CraftBukkit/Spigot/Paper 1.12.2
|
||||
- [ ] CraftBukkit 1.8.8
|
||||
|
||||
|
||||
**Demonstration:**
|
||||
<!--
|
||||
Below this block, include screenshots/log snippets from before and after as
|
||||
necessary. If you have created or used a test case plugin, please link to a
|
||||
download of the plugin, source code and exact version used where possible.
|
||||
-->
|
||||
@@ -0,0 +1,10 @@
|
||||
You need to select a pull request template!
|
||||
|
||||
If you're adding a new feature, copy and paste the following parameter at the end of the URL:
|
||||
?template=new-feature.md
|
||||
|
||||
If you're fixing a bug, copy and paste the following parameter at the end of the URL:
|
||||
?template=bug-fix.md
|
||||
|
||||
For more information about contributing to EssentialsX, see CONTRIBUTING.md:
|
||||
https://github.com/EssentialsX/Essentials/blob/2.x/CONTRIBUTING.md
|
||||
@@ -0,0 +1,75 @@
|
||||
name: Build EssentialsX
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 2.x
|
||||
- dev/*
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build and upload
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout Git repo
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Restore Gradle cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.gradle/caches
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
|
||||
- name: Set up JDK 16
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: 16
|
||||
|
||||
- name: Validate Gradle Wrapper
|
||||
uses: gradle/wrapper-validation-action@v1
|
||||
|
||||
- name: Build with Gradle
|
||||
run: |
|
||||
chmod +x gradlew
|
||||
./gradlew build --stacktrace
|
||||
|
||||
- name: Archive plugin jars on GitHub
|
||||
uses: actions/upload-artifact@master
|
||||
with:
|
||||
name: EssentialsX plugin jars
|
||||
path: jars/
|
||||
|
||||
- name: Deploy to Maven repo
|
||||
if: ${{ success() && github.event_name == 'push' && github.repository == 'EssentialsX/Essentials' && github.ref == 'refs/heads/2.x' }}
|
||||
env:
|
||||
ORG_GRADLE_PROJECT_essxUsername: ${{ secrets.ESSENTIALSX_DEPLOY_USERNAME }}
|
||||
ORG_GRADLE_PROJECT_essxPassword: ${{ secrets.ESSENTIALSX_DEPLOY_PASSWORD }}
|
||||
run: |
|
||||
./gradlew publish
|
||||
|
||||
- name: Prepare Javadocs
|
||||
if: ${{ success() && github.event_name == 'push' && github.repository == 'EssentialsX/Essentials' && github.ref == 'refs/heads/2.x' }}
|
||||
run: |
|
||||
mv Essentials/build/docs/javadoc/ javadocs/
|
||||
cp -r EssentialsAntiBuild/build/docs/javadoc/ javadocs/EssentialsAntiBuild/
|
||||
cp -r EssentialsChat/build/docs/javadoc/ javadocs/EssentialsChat/
|
||||
cp -r EssentialsDiscord/build/docs/javadoc/ javadocs/EssentialsDiscord/
|
||||
cp -r EssentialsGeoIP/build/docs/javadoc/ javadocs/EssentialsGeoIP/
|
||||
cp -r EssentialsProtect/build/docs/javadoc/ javadocs/EssentialsProtect/
|
||||
cp -r EssentialsSpawn/build/docs/javadoc/ javadocs/EssentialsSpawn/
|
||||
cp -r EssentialsXMPP/build/docs/javadoc/ javadocs/EssentialsXMPP/
|
||||
|
||||
- name: Deploy Javadocs
|
||||
if: ${{ success() && github.event_name == 'push' && github.repository == 'EssentialsX/Essentials' && github.ref == 'refs/heads/2.x' }}
|
||||
uses: netlify/actions/cli@master
|
||||
with:
|
||||
args: deploy --dir=javadocs/ --prod --message="GitHubActionsDeploy"
|
||||
env:
|
||||
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_JD_AUTH_TOKEN }}
|
||||
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_JD_2X_SITE_ID }}
|
||||
@@ -0,0 +1,51 @@
|
||||
name: Build Pull Request
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- mc/* # MC version updates
|
||||
- pr/* # PR rebases
|
||||
pull_request:
|
||||
branches:
|
||||
- 2.x
|
||||
- mc/*
|
||||
- dev/*
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build and upload
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout Git repo
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Restore Gradle cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.gradle/caches
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
|
||||
- name: Set up JDK 16
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: 16
|
||||
|
||||
- name: Validate Gradle Wrapper
|
||||
uses: gradle/wrapper-validation-action@v1
|
||||
|
||||
- name: Build with Gradle
|
||||
run: |
|
||||
chmod +x gradlew
|
||||
./gradlew build --stacktrace
|
||||
|
||||
- name: Archive plugin jars on GitHub
|
||||
uses: actions/upload-artifact@master
|
||||
with:
|
||||
name: EssentialsX plugin jars
|
||||
path: jars/
|
||||
+13
-3
@@ -1,11 +1,14 @@
|
||||
# IDE files
|
||||
# Other IDE files
|
||||
*.classpath
|
||||
*.project
|
||||
*.settings/
|
||||
.idea/
|
||||
.idea/*
|
||||
*.iml
|
||||
.DS_Store
|
||||
|
||||
# Checkstyle-IDEA config
|
||||
!.idea/checkstyle-idea.xml
|
||||
|
||||
# Essentials files
|
||||
/Essentials/userdata
|
||||
/Essentials/config.yml
|
||||
@@ -14,5 +17,12 @@
|
||||
/Essentials/usermap.csv
|
||||
|
||||
# Build files
|
||||
.gradle/
|
||||
/jars/
|
||||
out/
|
||||
build/
|
||||
target/
|
||||
jars/
|
||||
*.class
|
||||
|
||||
# Run directory
|
||||
/run/
|
||||
Generated
+19
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CheckStyle-IDEA">
|
||||
<option name="configuration">
|
||||
<map>
|
||||
<entry key="active-configuration" value="PROJECT_RELATIVE:$PROJECT_DIR$/.checkstyle/checkstyle.xml:EssentialsX" />
|
||||
<entry key="checkstyle-version" value="8.36.2" />
|
||||
<entry key="copy-libs" value="true" />
|
||||
<entry key="location-0" value="BUNDLED:(bundled):Sun Checks" />
|
||||
<entry key="location-1" value="BUNDLED:(bundled):Google Checks" />
|
||||
<entry key="location-2" value="PROJECT_RELATIVE:$PROJECT_DIR$/.checkstyle/checkstyle.xml:EssentialsX" />
|
||||
<entry key="property-2.configDirectory" value=".checkstyle/" />
|
||||
<entry key="scan-before-checkin" value="true" />
|
||||
<entry key="scanscope" value="JavaOnly" />
|
||||
<entry key="suppress-errors" value="false" />
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
language: java
|
||||
|
||||
jdk:
|
||||
- openjdk8
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- .buildtools
|
||||
- $HOME/.m2
|
||||
|
||||
before_install:
|
||||
- chmod +x scripts/buildtools.sh
|
||||
- scripts/buildtools.sh
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
# Contributing to EssentialsX
|
||||
|
||||
*By contributing to EssentialsX, you agree to license your changes under the [GNU General Public License version 3](https://github.com/EssentialsX/Essentials/blob/2.x/LICENSE).*
|
||||
|
||||
## Submitting code changes to EssentialsX
|
||||
|
||||
If you're interested in submitting new code to EssentialsX, we accept changes via GitHub pull requests.
|
||||
|
||||
### Adding features
|
||||
|
||||
In general, we will only consider PRs for features if they have already been discussed with the team through
|
||||
GitHub issues and discussions. Check the list of
|
||||
["open to PR" issues](https://github.com/EssentialsX/Essentials/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22status%3A+open+to+PR%22)
|
||||
and [feature request discussions](https://github.com/EssentialsX/Essentials/discussions/categories/ideas-and-feature-suggestions)
|
||||
before you start working on your changes. If you don't see your desired feature listed,
|
||||
[open a feature request](https://github.com/EssentialsX/Essentials/issues/new/choose) and wait for a response, otherwise
|
||||
you may end up wasting your time on a feature that we aren't in a position to accept.
|
||||
|
||||
#### Keep it focused
|
||||
|
||||
Please try to keep feature PRs focused around one feature. Your PR should ideally contain
|
||||
one feature, or a few closely-linked features. If you submit several unrelated features
|
||||
in one PR, the PR will not be accepted.
|
||||
|
||||
### Fixing bugs
|
||||
|
||||
If you're opening a PR to fix a bug, please ensure a bug report has been filed - search the
|
||||
[issue tracker](https://github.com/EssentialsX/Essentials/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22bug%3A+confirmed%22%2C%22bug%3A+unconfirmed%22%2C%22bug%3A+upstream%22)
|
||||
for an existing report, and if you can't find a bug report,
|
||||
[create one](https://github.com/EssentialsX/Essentials/issues/new/choose) before you submit your PR.
|
||||
|
||||
#### Unconfirmed bugs
|
||||
|
||||
You may find a bug report with the label `bug: unconfirmed`. This means the EssentialsX team hasn't had the time
|
||||
to review the bug report yet or hasn't been able to confirm
|
||||
whether the reported issue is actually a bug in EssentialsX. You can help us by following the steps in the report and
|
||||
posting whether you are able to replicate this issue, ideally on the latest versions of EssentialsX and Paper. This will
|
||||
help us confirm issues and prioritise PRs accordingly.
|
||||
|
||||
#### Upstream bugs
|
||||
|
||||
You may also find bug reports with the `bug: upstream` label. This label means the issue is caused by a bug in *another
|
||||
project*, not EssentialsX. This includes bugs in CraftBukkit/Spigot and bugs in other plugins. It may be appropriate to
|
||||
mitigate an issue in EssentialsX, but please check with us in the [EssentialsX Development Discord server](https://discord.gg/CUN7qVb) before you submit a PR.
|
||||
|
||||
### Making your changes
|
||||
|
||||
You'll need the following to make your changes to EssentialsX:
|
||||
|
||||
* A GitHub account
|
||||
* [`git`](https://git-scm.com/downloads): the Git command-line tool, used to track and save your changes
|
||||
* [`gh`](https://cli.github.com/): the GitHub command-line tool, used to submit your changes to EssentialsX
|
||||
* Your IDE of choice - we recommend [IntelliJ IDEA Community Edition](https://www.jetbrains.com/idea/download)
|
||||
|
||||
If you're already familiar with Git, you can skip this next section.
|
||||
|
||||
You'll need to clone the EssentialsX repository
|
||||
(`gh repo clone EssentialsX/Essentials`), then create a new branch for your work
|
||||
(`cd Essentials` then `git switch -c my-cool-pr`).
|
||||
|
||||
You can then make changes using your IDE of choice. Follow the instructions in `README.md` to build and test your
|
||||
changes.
|
||||
|
||||
Once you've finished, you should commit your changes (`git commit -am "My cool commit name!"`).
|
||||
|
||||
### Submitting your PR
|
||||
|
||||
*Even if you're already familiar with GitHub, you will need to follow these steps in order to submit a PR to
|
||||
EssentialsX. This ensures we have the information we need to test and review your changes.*
|
||||
|
||||
Next, you'll need to fork EssentialsX on GitHub and push your changes to a branch on that fork. We strongly recommend
|
||||
using the `gh` command-line tool for this:
|
||||
|
||||
* In your terminal, run `gh pr create`.
|
||||
* Select either the bug fix or feature template, depending on what your PR is for.
|
||||
* If you get asked `Where should we push the '...' branch?`, select `Create a fork of EssentialsX/Essentials`.
|
||||
* For the title, choose a title that describes what your PR does. For example, `Add more ducks to /spawnmob`.
|
||||
* For the body, press E. You will then need to fill in the PR template in your text editor.
|
||||
- Follow the instructions in the template and fill out the sections as required.
|
||||
- This step is important! Without it, we won't know why you've made your changes or how to test them.
|
||||
* Save the file in your text editor and close it, then return to the terminal.
|
||||
* Select `Submit` to open your PR.
|
||||
|
||||
If you follow these steps correctly, GitHub will create a fork (if necessary) and then open a PR with your changes. You
|
||||
can now sit back while we review your changes. If we need to ask questions or request further changes to your code,
|
||||
we will review your PR and post a comment on GitHub. You can respond to our reviews and comments on the GitHub website,
|
||||
and you can push new changes using `git commit` and `git push`.
|
||||
|
||||
|
||||
## Submitting community translations to EssentialsX
|
||||
|
||||
EssentialsX relies on community translations for its messages in other languages. You can help translate EssentialsX on
|
||||
[Crowdin](https://translate.essentialsx.net/). You'll need a Crowdin account to translate and improve messages.
|
||||
|
||||
If your language isn't listed or doesn't have an active proofreader, please let us know on Discord (see below).
|
||||
|
||||
|
||||
## Discussing EssentialsX contributions
|
||||
|
||||
Want to discuss something before opening a PR or translating messages? Join the
|
||||
[EssentialsX Development Discord server](https://discord.gg/CUN7qVb). Note that this server is **not for end-users** -
|
||||
if you need support with EssentialsX, you should join [MOSS](https://discord.gg/casfFyh) instead.
|
||||
@@ -0,0 +1,58 @@
|
||||
plugins {
|
||||
id("essentials.shadow-module")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly('com.github.milkbowl:VaultAPI:1.7') {
|
||||
exclude group: "org.bukkit", module: "bukkit"
|
||||
}
|
||||
compileOnly 'net.luckperms:api:5.0'
|
||||
|
||||
api 'io.papermc:paperlib:1.0.6'
|
||||
|
||||
api 'org.bstats:bstats-bukkit:2.2.1'
|
||||
|
||||
implementation 'org.spongepowered:configurate-yaml:4.1.2'
|
||||
implementation 'org.checkerframework:checker-qual:3.14.0'
|
||||
|
||||
// Providers
|
||||
api project(':providers:BaseProviders')
|
||||
api project(':providers:PaperProvider')
|
||||
api(project(':providers:NMSReflectionProvider')) {
|
||||
exclude group: "org.bukkit", module: "bukkit"
|
||||
}
|
||||
api(project(':providers:1_8Provider')) {
|
||||
exclude group: "org.spigotmc", module: "spigot"
|
||||
}
|
||||
api(project(':providers:1_12Provider')) {
|
||||
exclude group: "org.bukkit", module: "bukkit"
|
||||
}
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
dependencies {
|
||||
include (dependency('io.papermc:paperlib'))
|
||||
include (dependency('org.bstats:bstats-bukkit'))
|
||||
include (dependency('org.bstats:bstats-base'))
|
||||
include (dependency('org.spongepowered:configurate-yaml'))
|
||||
include (dependency('org.spongepowered:configurate-core'))
|
||||
include (dependency('org.yaml:snakeyaml'))
|
||||
include (dependency('io.leangen.geantyref:geantyref'))
|
||||
include (dependency('org.checkerframework:checker-qual'))
|
||||
include (project(':providers:BaseProviders'))
|
||||
include (project(':providers:PaperProvider'))
|
||||
include (project(':providers:NMSReflectionProvider'))
|
||||
include (project(':providers:1_8Provider'))
|
||||
include (project(':providers:1_12Provider'))
|
||||
}
|
||||
relocate 'io.papermc.lib', 'com.earth2me.essentials.paperlib'
|
||||
relocate 'org.bstats', 'com.earth2me.essentials.libs.bstats'
|
||||
relocate 'org.spongepowered.configurate', 'com.earth2me.essentials.libs.configurate'
|
||||
relocate 'org.yaml.snakeyaml', 'com.earth2me.essentials.libs.snakeyaml'
|
||||
relocate 'io.leangen.geantyref', 'com.earth2me.essentials.libs.geantyref'
|
||||
relocate 'org.checkerframework', 'com.earth2me.essentials.libs.checkerframework'
|
||||
|
||||
minimize {
|
||||
include(dependency('org.checkerframework:checker-qual'))
|
||||
}
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
<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>
|
||||
|
||||
<parent>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>EssentialsXParent</artifactId>
|
||||
<version>2.17.1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>EssentialsX</artifactId>
|
||||
|
||||
<build>
|
||||
<finalName>EssentialsX-${full.version}</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.0</version>
|
||||
<configuration>
|
||||
<showDeprecation>false</showDeprecation>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.2.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>io.papermc.lib</pattern>
|
||||
<shadedPattern>com.earth2me.essentials.paperlib</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>net.milkbowl.vault</groupId>
|
||||
<artifactId>VaultAPI</artifactId>
|
||||
<version>1.7</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.papermc</groupId>
|
||||
<artifactId>paperlib</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>NMSProvider</artifactId>
|
||||
<version>2.17.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>UpdatedMetaProvider</artifactId>
|
||||
<version>2.17.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>1_8_R1Provider</artifactId>
|
||||
<version>2.17.1</version>
|
||||
<scope>compile</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>craftbukkit</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>1_8_R2Provider</artifactId>
|
||||
<version>2.17.1</version>
|
||||
<scope>compile</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>craftbukkit</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>LegacyProvider</artifactId>
|
||||
<version>2.17.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>ReflectionProvider</artifactId>
|
||||
<version>2.17.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>FlattenedProvider</artifactId>
|
||||
<version>2.17.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -1,113 +0,0 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import net.ess3.api.IEssentials;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.command.PluginCommandYamlParser;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
||||
public class AlternativeCommandsHandler {
|
||||
private static final Logger LOGGER = Logger.getLogger("Essentials");
|
||||
private final transient Map<String, List<PluginCommand>> altcommands = new HashMap<>();
|
||||
private final transient Map<String, String> disabledList = new HashMap<>();
|
||||
private final transient IEssentials ess;
|
||||
|
||||
public AlternativeCommandsHandler(final IEssentials ess) {
|
||||
this.ess = ess;
|
||||
for (Plugin plugin : ess.getServer().getPluginManager().getPlugins()) {
|
||||
if (plugin.isEnabled()) {
|
||||
addPlugin(plugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final void addPlugin(final Plugin plugin) {
|
||||
if (plugin.getDescription().getMain().contains("com.earth2me.essentials")) {
|
||||
return;
|
||||
}
|
||||
final List<Command> commands = PluginCommandYamlParser.parse(plugin);
|
||||
final String pluginName = plugin.getDescription().getName().toLowerCase(Locale.ENGLISH);
|
||||
|
||||
for (Command command : commands) {
|
||||
final PluginCommand pc = (PluginCommand) command;
|
||||
final List<String> labels = new ArrayList<>(pc.getAliases());
|
||||
labels.add(pc.getName());
|
||||
|
||||
PluginCommand reg = ess.getServer().getPluginCommand(pluginName + ":" + pc.getName().toLowerCase(Locale.ENGLISH));
|
||||
if (reg == null) {
|
||||
reg = ess.getServer().getPluginCommand(pc.getName().toLowerCase(Locale.ENGLISH));
|
||||
}
|
||||
if (reg == null || !reg.getPlugin().equals(plugin)) {
|
||||
continue;
|
||||
}
|
||||
for (String label : labels) {
|
||||
List<PluginCommand> plugincommands = altcommands.get(label.toLowerCase(Locale.ENGLISH));
|
||||
if (plugincommands == null) {
|
||||
plugincommands = new ArrayList<>();
|
||||
altcommands.put(label.toLowerCase(Locale.ENGLISH), plugincommands);
|
||||
}
|
||||
boolean found = false;
|
||||
for (PluginCommand pc2 : plugincommands) {
|
||||
if (pc2.getPlugin().equals(plugin)) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
plugincommands.add(reg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removePlugin(final Plugin plugin) {
|
||||
final Iterator<Map.Entry<String, List<PluginCommand>>> iterator = altcommands.entrySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final Map.Entry<String, List<PluginCommand>> entry = iterator.next();
|
||||
final Iterator<PluginCommand> pcIterator = entry.getValue().iterator();
|
||||
while (pcIterator.hasNext()) {
|
||||
final PluginCommand pc = pcIterator.next();
|
||||
if (pc.getPlugin() == null || pc.getPlugin().equals(plugin)) {
|
||||
pcIterator.remove();
|
||||
}
|
||||
}
|
||||
if (entry.getValue().isEmpty()) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public PluginCommand getAlternative(final String label) {
|
||||
final List<PluginCommand> commands = altcommands.get(label);
|
||||
if (commands == null || commands.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
if (commands.size() == 1) {
|
||||
return commands.get(0);
|
||||
}
|
||||
// return the first command that is not an alias
|
||||
for (PluginCommand command : commands) {
|
||||
if (command.getName().equalsIgnoreCase(label)) {
|
||||
return command;
|
||||
}
|
||||
}
|
||||
// return the first alias
|
||||
return commands.get(0);
|
||||
}
|
||||
|
||||
public void executed(final String label, final PluginCommand pc) {
|
||||
final String altString = pc.getPlugin().getName() + ":" + pc.getLabel();
|
||||
if (ess.getSettings().isDebug()) {
|
||||
LOGGER.log(Level.INFO, "Essentials: Alternative command " + label + " found, using " + altString);
|
||||
}
|
||||
disabledList.put(label, altString);
|
||||
}
|
||||
|
||||
public Map<String, String> disabledCommands() {
|
||||
return disabledList;
|
||||
}
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import net.ess3.api.IEssentials;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Backup implements Runnable {
|
||||
private static final Logger LOGGER = Logger.getLogger("Essentials");
|
||||
private transient final Server server;
|
||||
private transient final IEssentials ess;
|
||||
private transient boolean running = false;
|
||||
private transient int taskId = -1;
|
||||
private transient boolean active = false;
|
||||
|
||||
public Backup(final IEssentials ess) {
|
||||
this.ess = ess;
|
||||
server = ess.getServer();
|
||||
if (!ess.getOnlinePlayers().isEmpty()) {
|
||||
ess.runTaskAsynchronously(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
startTask();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void onPlayerJoin() {
|
||||
startTask();
|
||||
}
|
||||
|
||||
public synchronized void stopTask() {
|
||||
running = false;
|
||||
if (taskId != -1) {
|
||||
server.getScheduler().cancelTask(taskId);
|
||||
}
|
||||
taskId = -1;
|
||||
}
|
||||
|
||||
private synchronized void startTask() {
|
||||
if (!running) {
|
||||
final long interval = ess.getSettings().getBackupInterval() * 1200; // minutes -> ticks
|
||||
if (interval < 1200) {
|
||||
return;
|
||||
}
|
||||
taskId = ess.scheduleSyncRepeatingTask(this, interval, interval);
|
||||
running = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (active) {
|
||||
return;
|
||||
}
|
||||
active = true;
|
||||
final String command = ess.getSettings().getBackupCommand();
|
||||
if (command == null || "".equals(command)) {
|
||||
return;
|
||||
}
|
||||
if ("save-all".equalsIgnoreCase(command)) {
|
||||
final CommandSender cs = server.getConsoleSender();
|
||||
server.dispatchCommand(cs, "save-all");
|
||||
active = false;
|
||||
return;
|
||||
}
|
||||
LOGGER.log(Level.INFO, tl("backupStarted"));
|
||||
final CommandSender cs = server.getConsoleSender();
|
||||
server.dispatchCommand(cs, "save-all");
|
||||
server.dispatchCommand(cs, "save-off");
|
||||
|
||||
ess.runTaskAsynchronously(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
final ProcessBuilder childBuilder = new ProcessBuilder(command);
|
||||
childBuilder.redirectErrorStream(true);
|
||||
childBuilder.directory(ess.getDataFolder().getParentFile().getParentFile());
|
||||
final Process child = childBuilder.start();
|
||||
ess.runTaskAsynchronously(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
final BufferedReader reader = new BufferedReader(new InputStreamReader(child.getInputStream()));
|
||||
try {
|
||||
String line;
|
||||
do {
|
||||
line = reader.readLine();
|
||||
if (line != null) {
|
||||
LOGGER.log(Level.INFO, line);
|
||||
}
|
||||
} while (line != null);
|
||||
} finally {
|
||||
reader.close();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
});
|
||||
child.waitFor();
|
||||
} catch (InterruptedException ex) {
|
||||
LOGGER.log(Level.SEVERE, null, ex);
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, null, ex);
|
||||
} finally {
|
||||
class BackupEnableSaveTask implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
server.dispatchCommand(cs, "save-on");
|
||||
if (ess.getOnlinePlayers().isEmpty()) {
|
||||
stopTask();
|
||||
}
|
||||
active = false;
|
||||
LOGGER.log(Level.INFO, tl("backupFinished"));
|
||||
}
|
||||
}
|
||||
ess.scheduleSyncDelayedTask(new BackupEnableSaveTask());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,964 +0,0 @@
|
||||
/*
|
||||
* Essentials - a bukkit plugin
|
||||
* Copyright (C) 2011 Essentials Team
|
||||
*
|
||||
* 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.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.commands.*;
|
||||
import com.earth2me.essentials.items.AbstractItemDb;
|
||||
import com.earth2me.essentials.items.FlatItemDb;
|
||||
import com.earth2me.essentials.items.LegacyItemDb;
|
||||
import com.earth2me.essentials.metrics.Metrics;
|
||||
import com.earth2me.essentials.perm.PermissionsHandler;
|
||||
import com.earth2me.essentials.register.payment.Methods;
|
||||
import com.earth2me.essentials.signs.SignBlockListener;
|
||||
import com.earth2me.essentials.signs.SignEntityListener;
|
||||
import com.earth2me.essentials.signs.SignPlayerListener;
|
||||
import com.earth2me.essentials.textreader.IText;
|
||||
import com.earth2me.essentials.textreader.KeywordReplacer;
|
||||
import com.earth2me.essentials.textreader.SimpleTextInput;
|
||||
import com.earth2me.essentials.utils.DateUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.Iterables;
|
||||
import net.ess3.api.*;
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.api.ISettings;
|
||||
import net.ess3.nms.PotionMetaProvider;
|
||||
import net.ess3.nms.SpawnEggProvider;
|
||||
import net.ess3.nms.SpawnerProvider;
|
||||
import net.ess3.nms.flattened.FlatSpawnEggProvider;
|
||||
import net.ess3.nms.legacy.LegacyPotionMetaProvider;
|
||||
import net.ess3.nms.legacy.LegacySpawnEggProvider;
|
||||
import net.ess3.nms.legacy.LegacySpawnerProvider;
|
||||
import net.ess3.nms.refl.ReflSpawnEggProvider;
|
||||
import net.ess3.nms.updatedmeta.BasePotionDataProvider;
|
||||
import net.ess3.nms.updatedmeta.BlockMetaSpawnerProvider;
|
||||
import net.ess3.nms.v1_8_R1.v1_8_R1SpawnerProvider;
|
||||
import net.ess3.nms.v1_8_R2.v1_8_R2SpawnerProvider;
|
||||
import net.ess3.providers.ProviderFactory;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.command.*;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.world.WorldLoadEvent;
|
||||
import org.bukkit.event.world.WorldUnloadEvent;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
import org.bukkit.plugin.InvalidDescriptionException;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.plugin.java.JavaPluginLoader;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import org.yaml.snakeyaml.error.YAMLException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||
private static final Logger LOGGER = Logger.getLogger("Essentials");
|
||||
private transient ISettings settings;
|
||||
private final transient TNTExplodeListener tntListener = new TNTExplodeListener(this);
|
||||
private transient Jails jails;
|
||||
private transient Warps warps;
|
||||
private transient Worth worth;
|
||||
private transient List<IConf> confList;
|
||||
private transient Backup backup;
|
||||
private transient AbstractItemDb itemDb;
|
||||
private transient final Methods paymentMethod = new Methods();
|
||||
private transient PermissionsHandler permissionsHandler;
|
||||
private transient AlternativeCommandsHandler alternativeCommandsHandler;
|
||||
private transient UserMap userMap;
|
||||
private transient ExecuteTimer execTimer;
|
||||
private transient I18n i18n;
|
||||
private transient Metrics metrics;
|
||||
private transient EssentialsTimer timer;
|
||||
private final transient Set<String> vanishedPlayers = new LinkedHashSet<>();
|
||||
private transient Method oldGetOnlinePlayers;
|
||||
private transient SpawnerProvider spawnerProvider;
|
||||
private transient SpawnEggProvider spawnEggProvider;
|
||||
private transient PotionMetaProvider potionMetaProvider;
|
||||
private transient Kits kits;
|
||||
|
||||
public Essentials() {
|
||||
}
|
||||
|
||||
public Essentials(final Server server) {
|
||||
super(new JavaPluginLoader(server), new PluginDescriptionFile("Essentials", "", "com.earth2me.essentials.Essentials"), null, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void forceLoadClasses() {
|
||||
try {
|
||||
Class.forName(OfflinePlayer.class.getName());
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ISettings getSettings() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
public void setupForTesting(final Server server) throws IOException, InvalidDescriptionException {
|
||||
final File dataFolder = File.createTempFile("essentialstest", "");
|
||||
if (!dataFolder.delete()) {
|
||||
throw new IOException();
|
||||
}
|
||||
if (!dataFolder.mkdir()) {
|
||||
throw new IOException();
|
||||
}
|
||||
i18n = new I18n(this);
|
||||
i18n.onEnable();
|
||||
i18n.updateLocale("en");
|
||||
Console.setInstance(this);
|
||||
|
||||
LOGGER.log(Level.INFO, tl("usingTempFolderForTesting"));
|
||||
LOGGER.log(Level.INFO, dataFolder.toString());
|
||||
settings = new Settings(this);
|
||||
userMap = new UserMap(this);
|
||||
permissionsHandler = new PermissionsHandler(this, false);
|
||||
Economy.setEss(this);
|
||||
confList = new ArrayList<>();
|
||||
jails = new Jails(this);
|
||||
registerListeners(server.getPluginManager());
|
||||
kits = new Kits(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
try {
|
||||
if (LOGGER != this.getLogger()) {
|
||||
LOGGER.setParent(this.getLogger());
|
||||
}
|
||||
execTimer = new ExecuteTimer();
|
||||
execTimer.start();
|
||||
i18n = new I18n(this);
|
||||
i18n.onEnable();
|
||||
execTimer.mark("I18n1");
|
||||
|
||||
Console.setInstance(this);
|
||||
|
||||
if (!VersionUtil.isServerSupported()) {
|
||||
getLogger().severe(tl("serverUnsupported"));
|
||||
}
|
||||
|
||||
final PluginManager pm = getServer().getPluginManager();
|
||||
for (Plugin plugin : pm.getPlugins()) {
|
||||
if (plugin.getDescription().getName().startsWith("Essentials") && !plugin.getDescription().getVersion().equals(this.getDescription().getVersion()) && !plugin.getDescription().getName().equals("EssentialsAntiCheat")) {
|
||||
getLogger().warning(tl("versionMismatch", plugin.getDescription().getName()));
|
||||
}
|
||||
}
|
||||
|
||||
for (Method method : Server.class.getDeclaredMethods()) {
|
||||
if (method.getName().endsWith("getOnlinePlayers") && method.getReturnType() == Player[].class) {
|
||||
oldGetOnlinePlayers = method;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
forceLoadClasses();
|
||||
|
||||
try {
|
||||
final EssentialsUpgrade upgrade = new EssentialsUpgrade(this);
|
||||
upgrade.beforeSettings();
|
||||
execTimer.mark("Upgrade");
|
||||
|
||||
confList = new ArrayList<>();
|
||||
settings = new Settings(this);
|
||||
confList.add(settings);
|
||||
execTimer.mark("Settings");
|
||||
|
||||
userMap = new UserMap(this);
|
||||
confList.add(userMap);
|
||||
execTimer.mark("Init(Usermap)");
|
||||
|
||||
kits = new Kits(this);
|
||||
confList.add(kits);
|
||||
upgrade.convertKits();
|
||||
execTimer.mark("Kits");
|
||||
|
||||
upgrade.afterSettings();
|
||||
execTimer.mark("Upgrade2");
|
||||
|
||||
warps = new Warps(getServer(), this.getDataFolder());
|
||||
confList.add(warps);
|
||||
execTimer.mark("Init(Spawn/Warp)");
|
||||
|
||||
worth = new Worth(this.getDataFolder());
|
||||
confList.add(worth);
|
||||
itemDb = getItemDbFromConfig();
|
||||
confList.add(itemDb);
|
||||
execTimer.mark("Init(Worth/ItemDB)");
|
||||
|
||||
jails = new Jails(this);
|
||||
confList.add(jails);
|
||||
execTimer.mark("Init(Jails)");
|
||||
|
||||
spawnerProvider = new ProviderFactory<>(getLogger(),
|
||||
Arrays.asList(
|
||||
BlockMetaSpawnerProvider.class,
|
||||
v1_8_R2SpawnerProvider.class,
|
||||
v1_8_R1SpawnerProvider.class,
|
||||
LegacySpawnerProvider.class
|
||||
), "mob spawner").getProvider();
|
||||
spawnEggProvider = new ProviderFactory<>(getLogger(),
|
||||
Arrays.asList(
|
||||
FlatSpawnEggProvider.class,
|
||||
ReflSpawnEggProvider.class,
|
||||
LegacySpawnEggProvider.class
|
||||
), "spawn egg").getProvider();
|
||||
potionMetaProvider = new ProviderFactory<>(getLogger(),
|
||||
Arrays.asList(
|
||||
BasePotionDataProvider.class,
|
||||
LegacyPotionMetaProvider.class
|
||||
), "potion meta").getProvider();
|
||||
execTimer.mark("Init(Providers)");
|
||||
reload();
|
||||
|
||||
// The item spawn blacklist is loaded with all other settings, before the item
|
||||
// DB, but it depends on the item DB, so we need to reload it again here:
|
||||
((Settings) settings)._lateLoadItemSpawnBlacklist();
|
||||
} catch (YAMLException exception) {
|
||||
if (pm.getPlugin("EssentialsUpdate") != null) {
|
||||
LOGGER.log(Level.SEVERE, tl("essentialsHelp2"));
|
||||
} else {
|
||||
LOGGER.log(Level.SEVERE, tl("essentialsHelp1"));
|
||||
}
|
||||
handleCrash(exception);
|
||||
return;
|
||||
}
|
||||
backup = new Backup(this);
|
||||
permissionsHandler = new PermissionsHandler(this, settings.useBukkitPermissions());
|
||||
alternativeCommandsHandler = new AlternativeCommandsHandler(this);
|
||||
|
||||
timer = new EssentialsTimer(this);
|
||||
scheduleSyncRepeatingTask(timer, 1000, 50);
|
||||
|
||||
Economy.setEss(this);
|
||||
execTimer.mark("RegHandler");
|
||||
|
||||
for (World w : Bukkit.getWorlds())
|
||||
addDefaultBackPermissionsToWorld(w);
|
||||
|
||||
metrics = new Metrics(this);
|
||||
if (metrics.isEnabled()) {
|
||||
getLogger().info("Starting Metrics. Opt-out using the global bStats config.");
|
||||
} else {
|
||||
getLogger().info("Metrics disabled per bStats config.");
|
||||
}
|
||||
|
||||
final String timeroutput = execTimer.end();
|
||||
if (getSettings().isDebug()) {
|
||||
LOGGER.log(Level.INFO, "Essentials load {0}", timeroutput);
|
||||
}
|
||||
} catch (NumberFormatException ex) {
|
||||
handleCrash(ex);
|
||||
} catch (Error ex) {
|
||||
handleCrash(ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveConfig() {
|
||||
// We don't use any of the bukkit config writing, as this breaks our config file formatting.
|
||||
}
|
||||
|
||||
private void registerListeners(PluginManager pm) {
|
||||
HandlerList.unregisterAll(this);
|
||||
|
||||
if (getSettings().isDebug()) {
|
||||
LOGGER.log(Level.INFO, "Registering Listeners");
|
||||
}
|
||||
|
||||
final EssentialsPluginListener pluginListener = new EssentialsPluginListener(this);
|
||||
pm.registerEvents(pluginListener, this);
|
||||
confList.add(pluginListener);
|
||||
|
||||
final EssentialsPlayerListener playerListener = new EssentialsPlayerListener(this);
|
||||
playerListener.registerEvents();
|
||||
|
||||
final EssentialsBlockListener blockListener = new EssentialsBlockListener(this);
|
||||
pm.registerEvents(blockListener, this);
|
||||
|
||||
final SignBlockListener signBlockListener = new SignBlockListener(this);
|
||||
pm.registerEvents(signBlockListener, this);
|
||||
|
||||
final SignPlayerListener signPlayerListener = new SignPlayerListener(this);
|
||||
pm.registerEvents(signPlayerListener, this);
|
||||
|
||||
final SignEntityListener signEntityListener = new SignEntityListener(this);
|
||||
pm.registerEvents(signEntityListener, this);
|
||||
|
||||
final EssentialsEntityListener entityListener = new EssentialsEntityListener(this);
|
||||
pm.registerEvents(entityListener, this);
|
||||
|
||||
final EssentialsWorldListener worldListener = new EssentialsWorldListener(this);
|
||||
pm.registerEvents(worldListener, this);
|
||||
|
||||
final EssentialsServerListener serverListener = new EssentialsServerListener(this);
|
||||
pm.registerEvents(serverListener, this);
|
||||
|
||||
pm.registerEvents(tntListener, this);
|
||||
|
||||
jails.resetListener();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
for (User user : getOnlineUsers()) {
|
||||
if (user.isVanished()) {
|
||||
user.setVanished(false);
|
||||
user.sendMessage(tl("unvanishedReload"));
|
||||
}
|
||||
user.stopTransaction();
|
||||
}
|
||||
cleanupOpenInventories();
|
||||
if (i18n != null) {
|
||||
i18n.onDisable();
|
||||
}
|
||||
if (backup != null) {
|
||||
backup.stopTask();
|
||||
}
|
||||
Economy.setEss(null);
|
||||
Trade.closeLog();
|
||||
getUserMap().getUUIDMap().shutdown();
|
||||
|
||||
HandlerList.unregisterAll(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
Trade.closeLog();
|
||||
|
||||
for (IConf iConf : confList) {
|
||||
iConf.reloadConfig();
|
||||
execTimer.mark("Reload(" + iConf.getClass().getSimpleName() + ")");
|
||||
}
|
||||
|
||||
i18n.updateLocale(settings.getLocale());
|
||||
|
||||
final PluginManager pm = getServer().getPluginManager();
|
||||
registerListeners(pm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender sender, Command command, String commandLabel, String[] args) {
|
||||
return onTabCompleteEssentials(sender, command, commandLabel, args, Essentials.class.getClassLoader(),
|
||||
"com.earth2me.essentials.commands.Command", "essentials.", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabCompleteEssentials(final CommandSender cSender, final Command command, final String commandLabel, final String[] args,
|
||||
final ClassLoader classLoader, final String commandPath, final String permissionPrefix,
|
||||
final IEssentialsModule module) {
|
||||
if (!getSettings().isCommandOverridden(command.getName()) && (!commandLabel.startsWith("e") || commandLabel.equalsIgnoreCase(command.getName()))) {
|
||||
final PluginCommand pc = alternativeCommandsHandler.getAlternative(commandLabel);
|
||||
if (pc != null) {
|
||||
try {
|
||||
TabCompleter completer = pc.getTabCompleter();
|
||||
if (completer != null) {
|
||||
return completer.onTabComplete(cSender, command, commandLabel, args);
|
||||
}
|
||||
} catch (final Exception ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// Note: The tab completer is always a player, even when tab-completing in a command block
|
||||
User user = null;
|
||||
if (cSender instanceof Player) {
|
||||
user = getUser((Player) cSender);
|
||||
}
|
||||
|
||||
CommandSource sender = new CommandSource(cSender);
|
||||
|
||||
// Check for disabled commands
|
||||
if (getSettings().isCommandDisabled(commandLabel)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
IEssentialsCommand cmd;
|
||||
try {
|
||||
cmd = (IEssentialsCommand) classLoader.loadClass(commandPath + command.getName()).newInstance();
|
||||
cmd.setEssentials(this);
|
||||
cmd.setEssentialsModule(module);
|
||||
} catch (Exception ex) {
|
||||
sender.sendMessage(tl("commandNotLoaded", commandLabel));
|
||||
LOGGER.log(Level.SEVERE, tl("commandNotLoaded", commandLabel), ex);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// Check authorization
|
||||
if (user != null && !user.isAuthorized(cmd, permissionPrefix)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
if (user != null && user.isJailed() && !user.isAuthorized(cmd, "essentials.jail.allow.")) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// Run the command
|
||||
try {
|
||||
if (user == null) {
|
||||
return cmd.tabComplete(getServer(), sender, commandLabel, command, args);
|
||||
} else {
|
||||
return cmd.tabComplete(getServer(), user, commandLabel, command, args);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
showError(sender, ex, commandLabel);
|
||||
// Tab completion shouldn't fail
|
||||
LOGGER.log(Level.SEVERE, tl("commandFailed", commandLabel), ex);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
LOGGER.log(Level.SEVERE, tl("commandFailed", commandLabel), ex);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(final CommandSender sender, final Command command, final String commandLabel, final String[] args) {
|
||||
return onCommandEssentials(sender, command, commandLabel, args, Essentials.class.getClassLoader(), "com.earth2me.essentials.commands.Command", "essentials.", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommandEssentials(final CommandSender cSender, final Command command, final String commandLabel, final String[] args, final ClassLoader classLoader, final String commandPath, final String permissionPrefix, final IEssentialsModule module) {
|
||||
// Allow plugins to override the command via onCommand
|
||||
if (!getSettings().isCommandOverridden(command.getName()) && (!commandLabel.startsWith("e") || commandLabel.equalsIgnoreCase(command.getName()))) {
|
||||
final PluginCommand pc = alternativeCommandsHandler.getAlternative(commandLabel);
|
||||
if (pc != null) {
|
||||
alternativeCommandsHandler.executed(commandLabel, pc);
|
||||
try {
|
||||
return pc.execute(cSender, commandLabel, args);
|
||||
} catch (final Exception ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
cSender.sendMessage(tl("internalError"));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
User user = null;
|
||||
Block bSenderBlock = null;
|
||||
if (cSender instanceof Player) {
|
||||
user = getUser((Player) cSender);
|
||||
} else if (cSender instanceof BlockCommandSender) {
|
||||
BlockCommandSender bsender = (BlockCommandSender) cSender;
|
||||
bSenderBlock = bsender.getBlock();
|
||||
}
|
||||
|
||||
if (bSenderBlock != null) {
|
||||
Bukkit.getLogger().log(Level.INFO, "CommandBlock at {0},{1},{2} issued server command: /{3} {4}", new Object[]{bSenderBlock.getX(), bSenderBlock.getY(), bSenderBlock.getZ(), commandLabel, EssentialsCommand.getFinalArg(args, 0)});
|
||||
} else if (user == null) {
|
||||
Bukkit.getLogger().log(Level.INFO, "{0} issued server command: /{1} {2}", new Object[]{cSender.getName(), commandLabel, EssentialsCommand.getFinalArg(args, 0)});
|
||||
}
|
||||
|
||||
CommandSource sender = new CommandSource(cSender);
|
||||
|
||||
// New mail notification
|
||||
if (user != null && !getSettings().isCommandDisabled("mail") && !command.getName().equals("mail") && user.isAuthorized("essentials.mail")) {
|
||||
user.notifyOfMail();
|
||||
}
|
||||
|
||||
//Print version even if admin command is not available #easteregg
|
||||
if (commandLabel.equalsIgnoreCase("essversion")) {
|
||||
sender.sendMessage("This server is running Essentials " + getDescription().getVersion());
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check for disabled commands
|
||||
if (getSettings().isCommandDisabled(commandLabel)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
IEssentialsCommand cmd;
|
||||
try {
|
||||
cmd = (IEssentialsCommand) classLoader.loadClass(commandPath + command.getName()).newInstance();
|
||||
cmd.setEssentials(this);
|
||||
cmd.setEssentialsModule(module);
|
||||
} catch (Exception ex) {
|
||||
sender.sendMessage(tl("commandNotLoaded", commandLabel));
|
||||
LOGGER.log(Level.SEVERE, tl("commandNotLoaded", commandLabel), ex);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check authorization
|
||||
if (user != null && !user.isAuthorized(cmd, permissionPrefix)) {
|
||||
LOGGER.log(Level.INFO, tl("deniedAccessCommand", user.getName()));
|
||||
user.sendMessage(tl("noAccessCommand"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (user != null && user.isJailed() && !user.isAuthorized(cmd, "essentials.jail.allow.")) {
|
||||
if (user.getJailTimeout() > 0) {
|
||||
user.sendMessage(tl("playerJailedFor", user.getName(), DateUtil.formatDateDiff(user.getJailTimeout())));
|
||||
} else {
|
||||
user.sendMessage(tl("jailMessage"));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Run the command
|
||||
try {
|
||||
if (user == null) {
|
||||
cmd.run(getServer(), sender, commandLabel, command, args);
|
||||
} else {
|
||||
cmd.run(getServer(), user, commandLabel, command, args);
|
||||
}
|
||||
return true;
|
||||
} catch (NoChargeException ex) {
|
||||
return true;
|
||||
} catch (QuietAbortException ex) {
|
||||
return true;
|
||||
} catch (NotEnoughArgumentsException ex) {
|
||||
sender.sendMessage(command.getDescription());
|
||||
sender.sendMessage(command.getUsage().replaceAll("<command>", commandLabel));
|
||||
if (!ex.getMessage().isEmpty()) {
|
||||
sender.sendMessage(ex.getMessage());
|
||||
}
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
showError(sender, ex, commandLabel);
|
||||
if (settings.isDebug()) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
LOGGER.log(Level.SEVERE, tl("commandFailed", commandLabel), ex);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void cleanupOpenInventories() {
|
||||
for (User user : getOnlineUsers()) {
|
||||
if (user.isRecipeSee()) {
|
||||
user.getBase().getOpenInventory().getTopInventory().clear();
|
||||
user.getBase().getOpenInventory().close();
|
||||
user.setRecipeSee(false);
|
||||
}
|
||||
if (user.isInvSee() || user.isEnderSee()) {
|
||||
user.getBase().getOpenInventory().close();
|
||||
user.setInvSee(false);
|
||||
user.setEnderSee(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showError(final CommandSource sender, final Throwable exception, final String commandLabel) {
|
||||
sender.sendMessage(tl("errorWithMessage", exception.getMessage()));
|
||||
if (getSettings().isDebug()) {
|
||||
LOGGER.log(Level.INFO, tl("errorCallingCommand", commandLabel), exception);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BukkitScheduler getScheduler() {
|
||||
return this.getServer().getScheduler();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJails getJails() {
|
||||
return jails;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Warps getWarps() {
|
||||
return warps;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Worth getWorth() {
|
||||
return worth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Backup getBackup() {
|
||||
return backup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Kits getKits() {
|
||||
return kits;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Metrics getMetrics() {
|
||||
return metrics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMetrics(Metrics metrics) {
|
||||
this.metrics = metrics;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public User getUser(final Object base) {
|
||||
if (base instanceof Player) {
|
||||
return getUser((Player) base);
|
||||
}
|
||||
if (base instanceof org.bukkit.OfflinePlayer) {
|
||||
return getUser(((org.bukkit.OfflinePlayer) base).getUniqueId());
|
||||
}
|
||||
if (base instanceof UUID) {
|
||||
return getUser((UUID) base);
|
||||
}
|
||||
if (base instanceof String) {
|
||||
return getOfflineUser((String) base);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//This will return null if there is not a match.
|
||||
@Override
|
||||
public User getUser(final String base) {
|
||||
return getOfflineUser(base);
|
||||
}
|
||||
|
||||
//This will return null if there is not a match.
|
||||
@Override
|
||||
public User getUser(final UUID base) {
|
||||
return userMap.getUser(base);
|
||||
}
|
||||
|
||||
//This will return null if there is not a match.
|
||||
@Override
|
||||
public User getOfflineUser(final String name) {
|
||||
final User user = userMap.getUser(name);
|
||||
if (user != null && user.getBase() instanceof OfflinePlayer) {
|
||||
//This code should attempt to use the last known name of a user, if Bukkit returns name as null.
|
||||
final String lastName = user.getLastAccountName();
|
||||
if (lastName != null) {
|
||||
((OfflinePlayer) user.getBase()).setName(lastName);
|
||||
} else {
|
||||
((OfflinePlayer) user.getBase()).setName(name);
|
||||
}
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
//This will create a new user if there is not a match.
|
||||
@Override
|
||||
public User getUser(final Player base) {
|
||||
if (base == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (userMap == null) {
|
||||
LOGGER.log(Level.WARNING, "Essentials userMap not initialized");
|
||||
return null;
|
||||
}
|
||||
|
||||
User user = userMap.getUser(base.getUniqueId());
|
||||
|
||||
if (user == null) {
|
||||
if (getSettings().isDebug()) {
|
||||
LOGGER.log(Level.INFO, "Constructing new userfile from base player {0}", base.getName());
|
||||
}
|
||||
user = new User(base, this);
|
||||
} else {
|
||||
user.update(base);
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
private void handleCrash(Throwable exception) {
|
||||
final PluginManager pm = getServer().getPluginManager();
|
||||
LOGGER.log(Level.SEVERE, exception.toString());
|
||||
exception.printStackTrace();
|
||||
pm.registerEvents(new Listener() {
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onPlayerJoin(final PlayerJoinEvent event) {
|
||||
event.getPlayer().sendMessage("Essentials failed to load, read the log file.");
|
||||
}
|
||||
}, this);
|
||||
for (Player player : getOnlinePlayers()) {
|
||||
player.sendMessage("Essentials failed to load, read the log file.");
|
||||
}
|
||||
this.setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public World getWorld(final String name) {
|
||||
if (name.matches("[0-9]+")) {
|
||||
final int worldId = Integer.parseInt(name);
|
||||
if (worldId < getServer().getWorlds().size()) {
|
||||
return getServer().getWorlds().get(worldId);
|
||||
}
|
||||
}
|
||||
return getServer().getWorld(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addReloadListener(final IConf listener) {
|
||||
confList.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Methods getPaymentMethod() {
|
||||
return paymentMethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int broadcastMessage(final String message) {
|
||||
return broadcastMessage(null, null, message, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int broadcastMessage(final IUser sender, final String message) {
|
||||
return broadcastMessage(sender, null, message, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int broadcastMessage(final String permission, final String message) {
|
||||
return broadcastMessage(null, permission, message, false);
|
||||
}
|
||||
|
||||
private int broadcastMessage(final IUser sender, final String permission, final String message, final boolean keywords) {
|
||||
if (sender != null && sender.isHidden()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
IText broadcast = new SimpleTextInput(message);
|
||||
|
||||
final Collection<Player> players = getOnlinePlayers();
|
||||
|
||||
for (Player player : players) {
|
||||
final User user = getUser(player);
|
||||
if ((permission == null && (sender == null || !user.isIgnoredPlayer(sender))) || (permission != null && user.isAuthorized(permission))) {
|
||||
if (keywords) {
|
||||
broadcast = new KeywordReplacer(broadcast, new CommandSource(player), this, false);
|
||||
}
|
||||
for (String messageText : broadcast.getLines()) {
|
||||
user.sendMessage(messageText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return players.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BukkitTask runTaskAsynchronously(final Runnable run) {
|
||||
return this.getScheduler().runTaskAsynchronously(this, run);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BukkitTask runTaskLaterAsynchronously(final Runnable run, final long delay) {
|
||||
return this.getScheduler().runTaskLaterAsynchronously(this, run, delay);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BukkitTask runTaskTimerAsynchronously(final Runnable run, final long delay, final long period) {
|
||||
return this.getScheduler().runTaskTimerAsynchronously(this, run, delay, period);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int scheduleSyncDelayedTask(final Runnable run) {
|
||||
return this.getScheduler().scheduleSyncDelayedTask(this, run);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int scheduleSyncDelayedTask(final Runnable run, final long delay) {
|
||||
return this.getScheduler().scheduleSyncDelayedTask(this, run, delay);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int scheduleSyncRepeatingTask(final Runnable run, final long delay, final long period) {
|
||||
return this.getScheduler().scheduleSyncRepeatingTask(this, run, delay, period);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TNTExplodeListener getTNTListener() {
|
||||
return tntListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PermissionsHandler getPermissionsHandler() {
|
||||
return permissionsHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AlternativeCommandsHandler getAlternativeCommandsHandler() {
|
||||
return alternativeCommandsHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IItemDb getItemDb() {
|
||||
return itemDb;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserMap getUserMap() {
|
||||
return userMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public I18n getI18n() {
|
||||
return i18n;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EssentialsTimer getTimer() {
|
||||
return timer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getVanishedPlayers() {
|
||||
return Collections.unmodifiableList(new ArrayList<>(vanishedPlayers));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getVanishedPlayersNew() {
|
||||
return vanishedPlayers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Player> getOnlinePlayers() {
|
||||
try {
|
||||
return (Collection<Player>) getServer().getOnlinePlayers(); // Needed for sanity here, the Bukkit API is a bit broken in the sense it only allows subclasses of Player to this list
|
||||
} catch (NoSuchMethodError ex) {
|
||||
try {
|
||||
return Arrays.asList((Player[]) oldGetOnlinePlayers.invoke(getServer()));
|
||||
} catch (InvocationTargetException ex1) {
|
||||
throw Throwables.propagate(ex.getCause());
|
||||
} catch (IllegalAccessException ex1) {
|
||||
throw new RuntimeException("Error invoking oldGetOnlinePlayers", ex1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<User> getOnlineUsers() {
|
||||
return Iterables.transform(getOnlinePlayers(), new Function<Player, User>() {
|
||||
|
||||
@Override
|
||||
public User apply(Player player) {
|
||||
return getUser(player);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpawnerProvider getSpawnerProvider() {
|
||||
return spawnerProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpawnEggProvider getSpawnEggProvider() {
|
||||
return spawnEggProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PotionMetaProvider getPotionMetaProvider() {
|
||||
return potionMetaProvider;
|
||||
}
|
||||
|
||||
private static void addDefaultBackPermissionsToWorld(World w) {
|
||||
String permName = "essentials.back.into." + w.getName();
|
||||
|
||||
Permission p = Bukkit.getPluginManager().getPermission(permName);
|
||||
if (p == null) {
|
||||
p = new Permission(permName,
|
||||
"Allows access to /back when the destination location is within world " + w.getName(),
|
||||
PermissionDefault.TRUE);
|
||||
Bukkit.getPluginManager().addPermission(p);
|
||||
}
|
||||
}
|
||||
|
||||
private static class EssentialsWorldListener implements Listener, Runnable {
|
||||
private transient final IEssentials ess;
|
||||
|
||||
public EssentialsWorldListener(final IEssentials ess) {
|
||||
this.ess = ess;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onWorldLoad(final WorldLoadEvent event) {
|
||||
addDefaultBackPermissionsToWorld(event.getWorld());
|
||||
|
||||
ess.getJails().onReload();
|
||||
ess.getWarps().reloadConfig();
|
||||
for (IConf iConf : ((Essentials) ess).confList) {
|
||||
if (iConf instanceof IEssentialsModule) {
|
||||
iConf.reloadConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onWorldUnload(final WorldUnloadEvent event) {
|
||||
ess.getJails().onReload();
|
||||
ess.getWarps().reloadConfig();
|
||||
for (IConf iConf : ((Essentials) ess).confList) {
|
||||
if (iConf instanceof IEssentialsModule) {
|
||||
iConf.reloadConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
ess.reload();
|
||||
}
|
||||
}
|
||||
|
||||
private AbstractItemDb getItemDbFromConfig() {
|
||||
final String setting = settings.getItemDbType();
|
||||
|
||||
if (setting.equalsIgnoreCase("json")) {
|
||||
return new FlatItemDb(this);
|
||||
} else if (setting.equalsIgnoreCase("csv")) {
|
||||
return new LegacyItemDb(this);
|
||||
} else {
|
||||
VersionUtil.BukkitVersion version = VersionUtil.getServerBukkitVersion();
|
||||
|
||||
if (version.isHigherThanOrEqualTo(VersionUtil.v1_13_0_R01)) {
|
||||
return new FlatItemDb(this);
|
||||
} else {
|
||||
return new LegacyItemDb(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,661 +0,0 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
import net.ess3.api.InvalidWorldException;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.io.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.CharsetDecoder;
|
||||
import java.nio.charset.CoderResult;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class EssentialsConf extends YamlConfiguration {
|
||||
protected static final Logger LOGGER = Logger.getLogger("Essentials");
|
||||
protected final File configFile;
|
||||
protected String templateName = null;
|
||||
protected static final Charset UTF8 = Charset.forName("UTF-8");
|
||||
private Class<?> resourceClass = EssentialsConf.class;
|
||||
private static final ExecutorService EXECUTOR_SERVICE = Executors.newSingleThreadExecutor();
|
||||
private final AtomicInteger pendingDiskWrites = new AtomicInteger(0);
|
||||
private final AtomicBoolean transaction = new AtomicBoolean(false);
|
||||
|
||||
public EssentialsConf(final File configFile) {
|
||||
super();
|
||||
this.configFile = configFile.getAbsoluteFile();
|
||||
}
|
||||
|
||||
private final byte[] bytebuffer = new byte[1024];
|
||||
|
||||
public synchronized void load() {
|
||||
if (pendingDiskWrites.get() != 0) {
|
||||
LOGGER.log(Level.INFO, "File {0} not read, because it''s not yet written to disk.", configFile);
|
||||
return;
|
||||
}
|
||||
if (!configFile.getParentFile().exists()) {
|
||||
if (!configFile.getParentFile().mkdirs()) {
|
||||
LOGGER.log(Level.SEVERE, tl("failedToCreateConfig", configFile.toString()));
|
||||
}
|
||||
}
|
||||
// This will delete files where the first character is 0. In most cases they are broken.
|
||||
if (configFile.exists() && configFile.length() != 0) {
|
||||
try {
|
||||
final InputStream input = new FileInputStream(configFile);
|
||||
try {
|
||||
if (input.read() == 0) {
|
||||
input.close();
|
||||
configFile.delete();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, null, ex);
|
||||
} finally {
|
||||
try {
|
||||
input.close();
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
LOGGER.log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
if (!configFile.exists()) {
|
||||
if (legacyFileExists()) {
|
||||
convertLegacyFile();
|
||||
} else if (altFileExists()) {
|
||||
convertAltFile();
|
||||
} else if (templateName != null) {
|
||||
LOGGER.log(Level.INFO, tl("creatingConfigFromTemplate", configFile.toString()));
|
||||
createFromTemplate();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
try (FileInputStream inputStream = new FileInputStream(configFile)) {
|
||||
long startSize = configFile.length();
|
||||
if (startSize > Integer.MAX_VALUE) {
|
||||
throw new InvalidConfigurationException("File too big");
|
||||
}
|
||||
ByteBuffer buffer = ByteBuffer.allocate((int) startSize);
|
||||
int length;
|
||||
while ((length = inputStream.read(bytebuffer)) != -1) {
|
||||
if (length > buffer.remaining()) {
|
||||
ByteBuffer resize = ByteBuffer.allocate(buffer.capacity() + length - buffer.remaining());
|
||||
int resizePosition = buffer.position();
|
||||
buffer.rewind();
|
||||
resize.put(buffer);
|
||||
resize.position(resizePosition);
|
||||
buffer = resize;
|
||||
}
|
||||
buffer.put(bytebuffer, 0, length);
|
||||
}
|
||||
buffer.rewind();
|
||||
final CharBuffer data = CharBuffer.allocate(buffer.capacity());
|
||||
CharsetDecoder decoder = UTF8.newDecoder();
|
||||
CoderResult result = decoder.decode(buffer, data, true);
|
||||
if (result.isError()) {
|
||||
buffer.rewind();
|
||||
data.clear();
|
||||
LOGGER.log(Level.INFO, "File " + configFile.getAbsolutePath() + " is not utf-8 encoded, trying " + Charset.defaultCharset().displayName());
|
||||
decoder = Charset.defaultCharset().newDecoder();
|
||||
result = decoder.decode(buffer, data, true);
|
||||
if (result.isError()) {
|
||||
throw new InvalidConfigurationException("Invalid Characters in file " + configFile.getAbsolutePath());
|
||||
} else {
|
||||
decoder.flush(data);
|
||||
}
|
||||
} else {
|
||||
decoder.flush(data);
|
||||
}
|
||||
final int end = data.position();
|
||||
data.rewind();
|
||||
super.loadFromString(data.subSequence(0, end).toString());
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, ex.getMessage(), ex);
|
||||
} catch (InvalidConfigurationException ex) {
|
||||
File broken = new File(configFile.getAbsolutePath() + ".broken." + System.currentTimeMillis());
|
||||
configFile.renameTo(broken);
|
||||
LOGGER.log(Level.SEVERE, "The file " + configFile.toString() + " is broken, it has been renamed to " + broken.toString(), ex.getCause());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean legacyFileExists() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void convertLegacyFile() {
|
||||
LOGGER.log(Level.SEVERE, "Unable to import legacy config file.");
|
||||
}
|
||||
|
||||
public boolean altFileExists() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void convertAltFile() {
|
||||
LOGGER.log(Level.SEVERE, "Unable to import alt config file.");
|
||||
}
|
||||
|
||||
private void createFromTemplate() {
|
||||
InputStream istr = null;
|
||||
OutputStream ostr = null;
|
||||
try {
|
||||
istr = resourceClass.getResourceAsStream(templateName);
|
||||
if (istr == null) {
|
||||
LOGGER.log(Level.SEVERE, tl("couldNotFindTemplate", templateName));
|
||||
return;
|
||||
}
|
||||
ostr = new FileOutputStream(configFile);
|
||||
byte[] buffer = new byte[1024];
|
||||
int length = 0;
|
||||
length = istr.read(buffer);
|
||||
while (length > 0) {
|
||||
ostr.write(buffer, 0, length);
|
||||
length = istr.read(buffer);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, tl("failedToWriteConfig", configFile.toString()), ex);
|
||||
} finally {
|
||||
try {
|
||||
if (istr != null) {
|
||||
istr.close();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(EssentialsConf.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
try {
|
||||
if (ostr != null) {
|
||||
ostr.close();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, tl("failedToCloseConfig", configFile.toString()), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setTemplateName(final String templateName) {
|
||||
this.templateName = templateName;
|
||||
}
|
||||
|
||||
public File getFile() {
|
||||
return configFile;
|
||||
}
|
||||
|
||||
public void setTemplateName(final String templateName, final Class<?> resClass) {
|
||||
this.templateName = templateName;
|
||||
this.resourceClass = resClass;
|
||||
}
|
||||
|
||||
public void startTransaction() {
|
||||
transaction.set(true);
|
||||
}
|
||||
|
||||
public void stopTransaction() {
|
||||
transaction.set(false);
|
||||
save();
|
||||
}
|
||||
|
||||
public void save() {
|
||||
try {
|
||||
save(configFile);
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void saveWithError() throws IOException {
|
||||
save(configFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void save(final File file) throws IOException {
|
||||
if (!transaction.get()) {
|
||||
delayedSave(file);
|
||||
}
|
||||
}
|
||||
|
||||
//This may be aborted if there are stagnant requests sitting in queue.
|
||||
//This needs fixed to discard outstanding save requests.
|
||||
public synchronized void forceSave() {
|
||||
try {
|
||||
Future<?> future = delayedSave(configFile);
|
||||
if (future != null) {
|
||||
future.get();
|
||||
}
|
||||
} catch (InterruptedException | ExecutionException ex) {
|
||||
LOGGER.log(Level.SEVERE, ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void cleanup() {
|
||||
forceSave();
|
||||
}
|
||||
|
||||
private Future<?> delayedSave(final File file) {
|
||||
if (file == null) {
|
||||
throw new IllegalArgumentException("File cannot be null");
|
||||
}
|
||||
|
||||
final String data = saveToString();
|
||||
|
||||
if (data.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
pendingDiskWrites.incrementAndGet();
|
||||
|
||||
return EXECUTOR_SERVICE.submit(new WriteRunner(configFile, data, pendingDiskWrites));
|
||||
}
|
||||
|
||||
|
||||
private static class WriteRunner implements Runnable {
|
||||
private final File configFile;
|
||||
private final String data;
|
||||
private final AtomicInteger pendingDiskWrites;
|
||||
|
||||
private WriteRunner(final File configFile, final String data, final AtomicInteger pendingDiskWrites) {
|
||||
this.configFile = configFile;
|
||||
this.data = data;
|
||||
this.pendingDiskWrites = pendingDiskWrites;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
//long startTime = System.nanoTime();
|
||||
synchronized (configFile) {
|
||||
if (pendingDiskWrites.get() > 1) {
|
||||
// Writes can be skipped, because they are stored in a queue (in the executor).
|
||||
// Only the last is actually written.
|
||||
pendingDiskWrites.decrementAndGet();
|
||||
//LOGGER.log(Level.INFO, configFile + " skipped writing in " + (System.nanoTime() - startTime) + " nsec.");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Files.createParentDirs(configFile);
|
||||
|
||||
if (!configFile.exists()) {
|
||||
try {
|
||||
LOGGER.log(Level.INFO, tl("creatingEmptyConfig", configFile.toString()));
|
||||
if (!configFile.createNewFile()) {
|
||||
LOGGER.log(Level.SEVERE, tl("failedToCreateConfig", configFile.toString()));
|
||||
return;
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
LOGGER.log(Level.SEVERE, tl("failedToCreateConfig", configFile.toString()), ex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try (FileOutputStream fos = new FileOutputStream(configFile)) {
|
||||
try (OutputStreamWriter writer = new OutputStreamWriter(fos, UTF8)) {
|
||||
writer.write(data);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOGGER.log(Level.SEVERE, e.getMessage(), e);
|
||||
} finally {
|
||||
//LOGGER.log(Level.INFO, configFile + " written to disk in " + (System.nanoTime() - startTime) + " nsec.");
|
||||
pendingDiskWrites.decrementAndGet();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasProperty(final String path) {
|
||||
return isSet(path);
|
||||
}
|
||||
|
||||
public Location getLocation(final String path, final Server server) throws InvalidWorldException {
|
||||
final String worldString = (path == null ? "" : path + ".") + "world";
|
||||
final String worldName = getString(worldString);
|
||||
if (worldName == null || worldName.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
final World world = server.getWorld(worldName);
|
||||
if (world == null) {
|
||||
throw new InvalidWorldException(worldName);
|
||||
}
|
||||
return new Location(world, getDouble((path == null ? "" : path + ".") + "x", 0), getDouble((path == null ? "" : path + ".") + "y", 0), getDouble((path == null ? "" : path + ".") + "z", 0), (float) getDouble((path == null ? "" : path + ".") + "yaw", 0), (float) getDouble((path == null ? "" : path + ".") + "pitch", 0));
|
||||
}
|
||||
|
||||
public void setProperty(final String path, final Location loc) {
|
||||
set((path == null ? "" : path + ".") + "world", loc.getWorld().getName());
|
||||
set((path == null ? "" : path + ".") + "x", loc.getX());
|
||||
set((path == null ? "" : path + ".") + "y", loc.getY());
|
||||
set((path == null ? "" : path + ".") + "z", loc.getZ());
|
||||
set((path == null ? "" : path + ".") + "yaw", loc.getYaw());
|
||||
set((path == null ? "" : path + ".") + "pitch", loc.getPitch());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getItemStack(final String path) {
|
||||
final ItemStack stack = new ItemStack(Material.valueOf(getString(path + ".type", "AIR")), getInt(path + ".amount", 1), (short) getInt(path + ".damage", 0));
|
||||
final ConfigurationSection enchants = getConfigurationSection(path + ".enchant");
|
||||
if (enchants != null) {
|
||||
for (String enchant : enchants.getKeys(false)) {
|
||||
final Enchantment enchantment = Enchantment.getByName(enchant.toUpperCase(Locale.ENGLISH));
|
||||
if (enchantment == null) {
|
||||
continue;
|
||||
}
|
||||
final int level = getInt(path + ".enchant." + enchant, enchantment.getStartLevel());
|
||||
stack.addUnsafeEnchantment(enchantment, level);
|
||||
}
|
||||
}
|
||||
return stack;
|
||||
/*
|
||||
* ,
|
||||
* (byte)getInt(path + ".data", 0)
|
||||
*/
|
||||
}
|
||||
|
||||
public void setProperty(final String path, final ItemStack stack) {
|
||||
final Map<String, Object> map = new HashMap<>();
|
||||
map.put("type", stack.getType().toString());
|
||||
map.put("amount", stack.getAmount());
|
||||
map.put("damage", stack.getDurability());
|
||||
Map<Enchantment, Integer> enchantments = stack.getEnchantments();
|
||||
if (!enchantments.isEmpty()) {
|
||||
Map<String, Integer> enchant = new HashMap<>();
|
||||
for (Map.Entry<Enchantment, Integer> entry : enchantments.entrySet()) {
|
||||
enchant.put(entry.getKey().getName().toLowerCase(Locale.ENGLISH), entry.getValue());
|
||||
}
|
||||
map.put("enchant", enchant);
|
||||
}
|
||||
// getData().getData() is broken
|
||||
//map.put("data", stack.getDurability());
|
||||
set(path, map);
|
||||
}
|
||||
|
||||
public void setProperty(String path, List object) {
|
||||
set(path, new ArrayList(object));
|
||||
}
|
||||
|
||||
public void setProperty(String path, Map object) {
|
||||
set(path, new LinkedHashMap(object));
|
||||
}
|
||||
|
||||
public Object getProperty(String path) {
|
||||
return get(path);
|
||||
}
|
||||
|
||||
public void setProperty(final String path, final BigDecimal bigDecimal) {
|
||||
set(path, bigDecimal.toString());
|
||||
}
|
||||
|
||||
public void setProperty(String path, Object object) {
|
||||
set(path, object);
|
||||
}
|
||||
|
||||
public void removeProperty(String path) {
|
||||
set(path, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Object get(String path) {
|
||||
return super.get(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Object get(String path, Object def) {
|
||||
return super.get(path, def);
|
||||
}
|
||||
|
||||
public synchronized BigDecimal getBigDecimal(final String path, final BigDecimal def) {
|
||||
final String input = super.getString(path);
|
||||
return toBigDecimal(input, def);
|
||||
}
|
||||
|
||||
public static BigDecimal toBigDecimal(final String input, final BigDecimal def) {
|
||||
if (input == null || input.isEmpty()) {
|
||||
return def;
|
||||
} else {
|
||||
try {
|
||||
return new BigDecimal(input, MathContext.DECIMAL128);
|
||||
} catch (NumberFormatException e) {
|
||||
return def;
|
||||
} catch (ArithmeticException e) {
|
||||
return def;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean getBoolean(String path) {
|
||||
return super.getBoolean(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean getBoolean(String path, boolean def) {
|
||||
return super.getBoolean(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<Boolean> getBooleanList(String path) {
|
||||
return super.getBooleanList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<Byte> getByteList(String path) {
|
||||
return super.getByteList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<Character> getCharacterList(String path) {
|
||||
return super.getCharacterList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized ConfigurationSection getConfigurationSection(String path) {
|
||||
return super.getConfigurationSection(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized double getDouble(String path) {
|
||||
return super.getDouble(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized double getDouble(final String path, final double def) {
|
||||
return super.getDouble(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<Double> getDoubleList(String path) {
|
||||
return super.getDoubleList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<Float> getFloatList(String path) {
|
||||
return super.getFloatList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int getInt(String path) {
|
||||
return super.getInt(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int getInt(String path, int def) {
|
||||
return super.getInt(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<Integer> getIntegerList(String path) {
|
||||
return super.getIntegerList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized ItemStack getItemStack(String path, ItemStack def) {
|
||||
return super.getItemStack(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Set<String> getKeys(boolean deep) {
|
||||
return super.getKeys(deep);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<?> getList(String path) {
|
||||
return super.getList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<?> getList(String path, List<?> def) {
|
||||
return super.getList(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized long getLong(String path) {
|
||||
return super.getLong(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized long getLong(final String path, final long def) {
|
||||
return super.getLong(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<Long> getLongList(String path) {
|
||||
return super.getLongList(path);
|
||||
}
|
||||
|
||||
public synchronized Map<String, Object> getMap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<Map<?, ?>> getMapList(String path) {
|
||||
return super.getMapList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized OfflinePlayer getOfflinePlayer(String path) {
|
||||
return super.getOfflinePlayer(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized OfflinePlayer getOfflinePlayer(String path, OfflinePlayer def) {
|
||||
return super.getOfflinePlayer(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<Short> getShortList(String path) {
|
||||
return super.getShortList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized String getString(String path) {
|
||||
return super.getString(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized String getString(String path, String def) {
|
||||
return super.getString(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<String> getStringList(String path) {
|
||||
return super.getStringList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Map<String, Object> getValues(boolean deep) {
|
||||
return super.getValues(deep);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Vector getVector(String path) {
|
||||
return super.getVector(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Vector getVector(String path, Vector def) {
|
||||
return super.getVector(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isBoolean(String path) {
|
||||
return super.isBoolean(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isConfigurationSection(String path) {
|
||||
return super.isConfigurationSection(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isDouble(String path) {
|
||||
return super.isDouble(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isInt(String path) {
|
||||
return super.isInt(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isItemStack(String path) {
|
||||
return super.isItemStack(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isList(String path) {
|
||||
return super.isList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isLong(String path) {
|
||||
return super.isLong(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isOfflinePlayer(String path) {
|
||||
return super.isOfflinePlayer(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isSet(String path) {
|
||||
return super.isSet(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isString(String path) {
|
||||
return super.isString(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isVector(String path) {
|
||||
return super.isVector(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void set(String path, Object value) {
|
||||
super.set(path, value);
|
||||
}
|
||||
}
|
||||
@@ -1,722 +0,0 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.craftbukkit.BanLookup;
|
||||
import com.earth2me.essentials.craftbukkit.FakeWorld;
|
||||
import com.earth2me.essentials.settings.Spawns;
|
||||
import com.earth2me.essentials.storage.YamlStorageWriter;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.collect.Maps;
|
||||
import net.ess3.api.IEssentials;
|
||||
import org.bukkit.BanList;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
|
||||
import java.io.*;
|
||||
import java.math.BigInteger;
|
||||
import java.security.DigestInputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class EssentialsUpgrade {
|
||||
private final static Logger LOGGER = Logger.getLogger("Essentials");
|
||||
private final transient IEssentials ess;
|
||||
private final transient EssentialsConf doneFile;
|
||||
|
||||
EssentialsUpgrade(final IEssentials essentials) {
|
||||
ess = essentials;
|
||||
if (!ess.getDataFolder().exists()) {
|
||||
ess.getDataFolder().mkdirs();
|
||||
}
|
||||
doneFile = new EssentialsConf(new File(ess.getDataFolder(), "upgrades-done.yml"));
|
||||
doneFile.load();
|
||||
}
|
||||
|
||||
public void convertKits() {
|
||||
Kits kits = ess.getKits();
|
||||
EssentialsConf config = kits.getConfig();
|
||||
if (doneFile.getBoolean("kitsyml", false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOGGER.info("Attempting to convert old kits in config.yml to new kits.yml");
|
||||
|
||||
ConfigurationSection section = ess.getSettings().getKitSection();
|
||||
if (section == null) {
|
||||
LOGGER.info("No kits found to migrate.");
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, Object> legacyKits = ess.getSettings().getKitSection().getValues(true);
|
||||
|
||||
for (Map.Entry<String, Object> entry : legacyKits.entrySet()) {
|
||||
LOGGER.info("Converting " + entry.getKey());
|
||||
config.set("kits." + entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
config.save();
|
||||
doneFile.setProperty("kitsyml", true);
|
||||
doneFile.save();
|
||||
LOGGER.info("Done converting kits.");
|
||||
}
|
||||
|
||||
private void moveMotdRulesToFile(String name) {
|
||||
if (doneFile.getBoolean("move" + name + "ToFile", false)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
final File file = new File(ess.getDataFolder(), name + ".txt");
|
||||
if (file.exists()) {
|
||||
return;
|
||||
}
|
||||
final File configFile = new File(ess.getDataFolder(), "config.yml");
|
||||
if (!configFile.exists()) {
|
||||
return;
|
||||
}
|
||||
final EssentialsConf conf = new EssentialsConf(configFile);
|
||||
conf.load();
|
||||
List<String> lines = conf.getStringList(name);
|
||||
if (lines != null && !lines.isEmpty()) {
|
||||
if (!file.createNewFile()) {
|
||||
throw new IOException("Failed to create file " + file);
|
||||
}
|
||||
PrintWriter writer = new PrintWriter(file);
|
||||
|
||||
for (String line : lines) {
|
||||
writer.println(line);
|
||||
}
|
||||
writer.close();
|
||||
}
|
||||
doneFile.setProperty("move" + name + "ToFile", true);
|
||||
doneFile.save();
|
||||
} catch (IOException e) {
|
||||
LOGGER.log(Level.SEVERE, tl("upgradingFilesError"), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeLinesFromConfig(File file, String regex, String info) throws Exception {
|
||||
boolean needUpdate = false;
|
||||
final BufferedReader bReader = new BufferedReader(new FileReader(file));
|
||||
final File tempFile = File.createTempFile("essentialsupgrade", ".tmp.yml", ess.getDataFolder());
|
||||
final BufferedWriter bWriter = new BufferedWriter(new FileWriter(tempFile));
|
||||
do {
|
||||
final String line = bReader.readLine();
|
||||
if (line == null) {
|
||||
break;
|
||||
}
|
||||
if (line.matches(regex)) {
|
||||
if (!needUpdate && info != null) {
|
||||
bWriter.write(info, 0, info.length());
|
||||
bWriter.newLine();
|
||||
}
|
||||
needUpdate = true;
|
||||
} else {
|
||||
if (line.endsWith("\r\n")) {
|
||||
bWriter.write(line, 0, line.length() - 2);
|
||||
} else if (line.endsWith("\r") || line.endsWith("\n")) {
|
||||
bWriter.write(line, 0, line.length() - 1);
|
||||
} else {
|
||||
bWriter.write(line, 0, line.length());
|
||||
}
|
||||
bWriter.newLine();
|
||||
}
|
||||
} while (true);
|
||||
bReader.close();
|
||||
bWriter.close();
|
||||
if (needUpdate) {
|
||||
if (!file.renameTo(new File(file.getParentFile(), file.getName().concat("." + System.currentTimeMillis() + ".upgradebackup")))) {
|
||||
throw new Exception(tl("configFileMoveError"));
|
||||
}
|
||||
if (!tempFile.renameTo(file)) {
|
||||
throw new Exception(tl("configFileRenameError"));
|
||||
}
|
||||
} else {
|
||||
tempFile.delete();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateUsersPowerToolsFormat() {
|
||||
if (doneFile.getBoolean("updateUsersPowerToolsFormat", false)) {
|
||||
return;
|
||||
}
|
||||
final File userdataFolder = new File(ess.getDataFolder(), "userdata");
|
||||
if (!userdataFolder.exists() || !userdataFolder.isDirectory()) {
|
||||
return;
|
||||
}
|
||||
final File[] userFiles = userdataFolder.listFiles();
|
||||
|
||||
for (File file : userFiles) {
|
||||
if (!file.isFile() || !file.getName().endsWith(".yml")) {
|
||||
continue;
|
||||
}
|
||||
final EssentialsConf config = new EssentialsConf(file);
|
||||
try {
|
||||
config.load();
|
||||
if (config.hasProperty("powertools")) {
|
||||
@SuppressWarnings("unchecked") final Map<String, Object> powertools = config.getConfigurationSection("powertools").getValues(false);
|
||||
if (powertools == null) {
|
||||
continue;
|
||||
}
|
||||
for (Map.Entry<String, Object> entry : powertools.entrySet()) {
|
||||
if (entry.getValue() instanceof String) {
|
||||
List<String> temp = new ArrayList<>();
|
||||
temp.add((String) entry.getValue());
|
||||
powertools.put(entry.getKey(), temp);
|
||||
}
|
||||
}
|
||||
config.forceSave();
|
||||
}
|
||||
} catch (RuntimeException ex) {
|
||||
LOGGER.log(Level.INFO, "File: " + file.toString());
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
doneFile.setProperty("updateUsersPowerToolsFormat", true);
|
||||
doneFile.save();
|
||||
}
|
||||
|
||||
private void updateUsersHomesFormat() {
|
||||
if (doneFile.getBoolean("updateUsersHomesFormat", false)) {
|
||||
return;
|
||||
}
|
||||
final File userdataFolder = new File(ess.getDataFolder(), "userdata");
|
||||
if (!userdataFolder.exists() || !userdataFolder.isDirectory()) {
|
||||
return;
|
||||
}
|
||||
final File[] userFiles = userdataFolder.listFiles();
|
||||
|
||||
for (File file : userFiles) {
|
||||
if (!file.isFile() || !file.getName().endsWith(".yml")) {
|
||||
continue;
|
||||
}
|
||||
final EssentialsConf config = new EssentialsConf(file);
|
||||
try {
|
||||
|
||||
config.load();
|
||||
if (config.hasProperty("home") && config.hasProperty("home.default")) {
|
||||
@SuppressWarnings("unchecked") final String defworld = (String) config.getProperty("home.default");
|
||||
final Location defloc = getFakeLocation(config, "home.worlds." + defworld);
|
||||
if (defloc != null) {
|
||||
config.setProperty("homes.home", defloc);
|
||||
}
|
||||
|
||||
Set<String> worlds = config.getConfigurationSection("home.worlds").getKeys(false);
|
||||
Location loc;
|
||||
String worldName;
|
||||
|
||||
if (worlds == null) {
|
||||
continue;
|
||||
}
|
||||
for (String world : worlds) {
|
||||
if (defworld.equalsIgnoreCase(world)) {
|
||||
continue;
|
||||
}
|
||||
loc = getFakeLocation(config, "home.worlds." + world);
|
||||
if (loc == null) {
|
||||
continue;
|
||||
}
|
||||
worldName = loc.getWorld().getName().toLowerCase(Locale.ENGLISH);
|
||||
if (worldName != null && !worldName.isEmpty()) {
|
||||
config.setProperty("homes." + worldName, loc);
|
||||
}
|
||||
}
|
||||
config.removeProperty("home");
|
||||
config.forceSave();
|
||||
}
|
||||
|
||||
} catch (RuntimeException ex) {
|
||||
LOGGER.log(Level.INFO, "File: " + file.toString());
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
doneFile.setProperty("updateUsersHomesFormat", true);
|
||||
doneFile.save();
|
||||
}
|
||||
|
||||
private void sanitizeAllUserFilenames() {
|
||||
if (doneFile.getBoolean("sanitizeAllUserFilenames", false)) {
|
||||
return;
|
||||
}
|
||||
final File usersFolder = new File(ess.getDataFolder(), "userdata");
|
||||
if (!usersFolder.exists()) {
|
||||
return;
|
||||
}
|
||||
final File[] listOfFiles = usersFolder.listFiles();
|
||||
for (File listOfFile : listOfFiles) {
|
||||
final String filename = listOfFile.getName();
|
||||
if (!listOfFile.isFile() || !filename.endsWith(".yml")) {
|
||||
continue;
|
||||
}
|
||||
final String sanitizedFilename = StringUtil.sanitizeFileName(filename.substring(0, filename.length() - 4)) + ".yml";
|
||||
if (sanitizedFilename.equals(filename)) {
|
||||
continue;
|
||||
}
|
||||
final File tmpFile = new File(listOfFile.getParentFile(), sanitizedFilename + ".tmp");
|
||||
final File newFile = new File(listOfFile.getParentFile(), sanitizedFilename);
|
||||
if (!listOfFile.renameTo(tmpFile)) {
|
||||
LOGGER.log(Level.WARNING, tl("userdataMoveError", filename, sanitizedFilename));
|
||||
continue;
|
||||
}
|
||||
if (newFile.exists()) {
|
||||
LOGGER.log(Level.WARNING, tl("duplicatedUserdata", filename, sanitizedFilename));
|
||||
continue;
|
||||
}
|
||||
if (!tmpFile.renameTo(newFile)) {
|
||||
LOGGER.log(Level.WARNING, tl("userdataMoveBackError", sanitizedFilename, sanitizedFilename));
|
||||
}
|
||||
}
|
||||
doneFile.setProperty("sanitizeAllUserFilenames", true);
|
||||
doneFile.save();
|
||||
}
|
||||
|
||||
private World getFakeWorld(final String name) {
|
||||
final File bukkitDirectory = ess.getDataFolder().getParentFile().getParentFile();
|
||||
final File worldDirectory = new File(bukkitDirectory, name);
|
||||
if (worldDirectory.exists() && worldDirectory.isDirectory()) {
|
||||
return new FakeWorld(worldDirectory.getName(), World.Environment.NORMAL);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Location getFakeLocation(EssentialsConf config, String path) {
|
||||
String worldName = config.getString((path != null ? path + "." : "") + "world");
|
||||
if (worldName == null || worldName.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
World world = getFakeWorld(worldName);
|
||||
if (world == null) {
|
||||
return null;
|
||||
}
|
||||
return new Location(world, config.getDouble((path != null ? path + "." : "") + "x", 0), config.getDouble((path != null ? path + "." : "") + "y", 0), config.getDouble((path != null ? path + "." : "") + "z", 0), (float) config.getDouble((path != null ? path + "." : "") + "yaw", 0), (float) config.getDouble((path != null ? path + "." : "") + "pitch", 0));
|
||||
}
|
||||
|
||||
private void deleteOldItemsCsv() {
|
||||
if (doneFile.getBoolean("deleteOldItemsCsv", false)) {
|
||||
return;
|
||||
}
|
||||
final File file = new File(ess.getDataFolder(), "items.csv");
|
||||
if (file.exists()) {
|
||||
try {
|
||||
final Set<BigInteger> oldconfigs = new HashSet<>();
|
||||
oldconfigs.add(new BigInteger("66ec40b09ac167079f558d1099e39f10", 16)); // sep 1
|
||||
oldconfigs.add(new BigInteger("34284de1ead43b0bee2aae85e75c041d", 16)); // crlf
|
||||
oldconfigs.add(new BigInteger("c33bc9b8ee003861611bbc2f48eb6f4f", 16)); // jul 24
|
||||
oldconfigs.add(new BigInteger("6ff17925430735129fc2a02f830c1daa", 16)); // crlf
|
||||
|
||||
MessageDigest digest = ManagedFile.getDigest();
|
||||
final BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
|
||||
final byte[] buffer = new byte[1024];
|
||||
try (DigestInputStream dis = new DigestInputStream(bis, digest)) {
|
||||
while (dis.read(buffer) != -1) {
|
||||
}
|
||||
}
|
||||
|
||||
BigInteger hash = new BigInteger(1, digest.digest());
|
||||
if (oldconfigs.contains(hash) && !file.delete()) {
|
||||
throw new IOException("Could not delete file " + file.toString());
|
||||
}
|
||||
doneFile.setProperty("deleteOldItemsCsv", true);
|
||||
doneFile.save();
|
||||
} catch (IOException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSpawnsToNewSpawnsConfig() {
|
||||
if (doneFile.getBoolean("updateSpawnsToNewSpawnsConfig", false)) {
|
||||
return;
|
||||
}
|
||||
final File configFile = new File(ess.getDataFolder(), "spawn.yml");
|
||||
if (configFile.exists()) {
|
||||
|
||||
final EssentialsConf config = new EssentialsConf(configFile);
|
||||
try {
|
||||
config.load();
|
||||
if (!config.hasProperty("spawns")) {
|
||||
final Spawns spawns = new Spawns();
|
||||
Set<String> keys = config.getKeys(false);
|
||||
for (String group : keys) {
|
||||
Location loc = getFakeLocation(config, group);
|
||||
spawns.getSpawns().put(group.toLowerCase(Locale.ENGLISH), loc);
|
||||
}
|
||||
if (!configFile.renameTo(new File(ess.getDataFolder(), "spawn.yml.old"))) {
|
||||
throw new Exception(tl("fileRenameError", "spawn.yml"));
|
||||
}
|
||||
try (PrintWriter writer = new PrintWriter(configFile)) {
|
||||
new YamlStorageWriter(writer).save(spawns);
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
doneFile.setProperty("updateSpawnsToNewSpawnsConfig", true);
|
||||
doneFile.save();
|
||||
}
|
||||
|
||||
private void updateJailsToNewJailsConfig() {
|
||||
if (doneFile.getBoolean("updateJailsToNewJailsConfig", false)) {
|
||||
return;
|
||||
}
|
||||
final File configFile = new File(ess.getDataFolder(), "jail.yml");
|
||||
if (configFile.exists()) {
|
||||
|
||||
final EssentialsConf config = new EssentialsConf(configFile);
|
||||
try {
|
||||
config.load();
|
||||
if (!config.hasProperty("jails")) {
|
||||
final com.earth2me.essentials.settings.Jails jails = new com.earth2me.essentials.settings.Jails();
|
||||
Set<String> keys = config.getKeys(false);
|
||||
for (String jailName : keys) {
|
||||
Location loc = getFakeLocation(config, jailName);
|
||||
jails.getJails().put(jailName.toLowerCase(Locale.ENGLISH), loc);
|
||||
}
|
||||
if (!configFile.renameTo(new File(ess.getDataFolder(), "jail.yml.old"))) {
|
||||
throw new Exception(tl("fileRenameError", "jail.yml"));
|
||||
}
|
||||
try (PrintWriter writer = new PrintWriter(configFile)) {
|
||||
new YamlStorageWriter(writer).save(jails);
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
doneFile.setProperty("updateJailsToNewJailsConfig", true);
|
||||
doneFile.save();
|
||||
}
|
||||
|
||||
private void warnMetrics() {
|
||||
if (doneFile.getBoolean("warnMetrics", false)) {
|
||||
return;
|
||||
}
|
||||
doneFile.setProperty("warnMetrics", true);
|
||||
doneFile.save();
|
||||
}
|
||||
|
||||
private void uuidFileChange() {
|
||||
if (doneFile.getBoolean("uuidFileChange", false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Boolean ignoreUFCache = doneFile.getBoolean("ignore-userfiles-cache", false);
|
||||
|
||||
final File userdir = new File(ess.getDataFolder(), "userdata");
|
||||
if (!userdir.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int countFiles = 0;
|
||||
int countReqFiles = 0;
|
||||
for (String string : userdir.list()) {
|
||||
if (!string.endsWith(".yml") || string.length() < 5) {
|
||||
continue;
|
||||
}
|
||||
|
||||
countFiles++;
|
||||
|
||||
final String name = string.substring(0, string.length() - 4);
|
||||
UUID uuid = null;
|
||||
|
||||
try {
|
||||
uuid = UUID.fromString(name);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
countReqFiles++;
|
||||
}
|
||||
|
||||
if (countFiles > 100) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (countReqFiles < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
ess.getLogger().info("#### Starting Essentials UUID userdata conversion in a few seconds. ####");
|
||||
ess.getLogger().info("We recommend you take a backup of your server before upgrading from the old username system.");
|
||||
|
||||
try {
|
||||
Thread.sleep(15000);
|
||||
} catch (InterruptedException ex) {
|
||||
// NOOP
|
||||
}
|
||||
|
||||
uuidFileConvert(ess, ignoreUFCache);
|
||||
|
||||
doneFile.setProperty("uuidFileChange", true);
|
||||
doneFile.save();
|
||||
}
|
||||
|
||||
public static void uuidFileConvert(IEssentials ess, Boolean ignoreUFCache) {
|
||||
ess.getLogger().info("Starting Essentials UUID userdata conversion");
|
||||
|
||||
final File userdir = new File(ess.getDataFolder(), "userdata");
|
||||
if (!userdir.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int countFiles = 0;
|
||||
int countFails = 0;
|
||||
int countEssCache = 0;
|
||||
int countBukkit = 0;
|
||||
|
||||
ess.getLogger().info("Found " + userdir.list().length + " files to convert...");
|
||||
|
||||
for (String string : userdir.list()) {
|
||||
if (!string.endsWith(".yml") || string.length() < 5) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final int showProgress = countFiles % 250;
|
||||
|
||||
if (showProgress == 0) {
|
||||
ess.getUserMap().getUUIDMap().forceWriteUUIDMap();
|
||||
ess.getLogger().info("Converted " + countFiles + "/" + userdir.list().length);
|
||||
}
|
||||
|
||||
countFiles++;
|
||||
|
||||
String name = string.substring(0, string.length() - 4);
|
||||
EssentialsUserConf config;
|
||||
UUID uuid = null;
|
||||
try {
|
||||
uuid = UUID.fromString(name);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
File file = new File(userdir, string);
|
||||
EssentialsConf conf = new EssentialsConf(file);
|
||||
conf.load();
|
||||
conf.setProperty("lastAccountName", name);
|
||||
conf.save();
|
||||
|
||||
String uuidConf = ignoreUFCache ? "force-uuid" : "uuid";
|
||||
|
||||
String uuidString = conf.getString(uuidConf, null);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
try {
|
||||
uuid = UUID.fromString(uuidString);
|
||||
countEssCache++;
|
||||
break;
|
||||
} catch (Exception ex2) {
|
||||
if (conf.getBoolean("npc", false)) {
|
||||
uuid = UUID.nameUUIDFromBytes(("NPC:" + name).getBytes(Charsets.UTF_8));
|
||||
break;
|
||||
}
|
||||
|
||||
org.bukkit.OfflinePlayer player = ess.getServer().getOfflinePlayer(name);
|
||||
uuid = player.getUniqueId();
|
||||
}
|
||||
|
||||
if (uuid != null) {
|
||||
countBukkit++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (uuid != null) {
|
||||
conf.forceSave();
|
||||
config = new EssentialsUserConf(name, uuid, new File(userdir, uuid + ".yml"));
|
||||
config.convertLegacyFile();
|
||||
ess.getUserMap().trackUUID(uuid, name, false);
|
||||
continue;
|
||||
}
|
||||
countFails++;
|
||||
}
|
||||
}
|
||||
ess.getUserMap().getUUIDMap().forceWriteUUIDMap();
|
||||
|
||||
ess.getLogger().info("Converted " + countFiles + "/" + countFiles + ". Conversion complete.");
|
||||
ess.getLogger().info("Converted via cache: " + countEssCache + " :: Converted via lookup: " + countBukkit + " :: Failed to convert: " + countFails);
|
||||
ess.getLogger().info("To rerun the conversion type /essentials uuidconvert");
|
||||
}
|
||||
|
||||
public void banFormatChange() {
|
||||
if (doneFile.getBoolean("banFormatChange", false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ess.getLogger().info("Starting Essentials ban format conversion");
|
||||
|
||||
final File userdir = new File(ess.getDataFolder(), "userdata");
|
||||
if (!userdir.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int countFiles = 0;
|
||||
|
||||
ess.getLogger().info("Found " + userdir.list().length + " files to convert...");
|
||||
|
||||
for (String string : userdir.list()) {
|
||||
if (!string.endsWith(".yml") || string.length() < 5) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final int showProgress = countFiles % 250;
|
||||
|
||||
if (showProgress == 0) {
|
||||
ess.getLogger().info("Converted " + countFiles + "/" + userdir.list().length);
|
||||
}
|
||||
|
||||
countFiles++;
|
||||
final File pFile = new File(userdir, string);
|
||||
final EssentialsConf conf = new EssentialsConf(pFile);
|
||||
conf.load();
|
||||
|
||||
String banReason;
|
||||
Long banTimeout;
|
||||
|
||||
try {
|
||||
banReason = conf.getConfigurationSection("ban").getString("reason");
|
||||
} catch (NullPointerException n) {
|
||||
banReason = null;
|
||||
}
|
||||
|
||||
final String playerName = conf.getString("lastAccountName");
|
||||
if (playerName != null && playerName.length() > 1 && banReason != null && banReason.length() > 1) {
|
||||
try {
|
||||
if (conf.getConfigurationSection("ban").contains("timeout")) {
|
||||
banTimeout = Long.parseLong(conf.getConfigurationSection("ban").getString("timeout"));
|
||||
} else {
|
||||
banTimeout = 0L;
|
||||
}
|
||||
} catch (NumberFormatException n) {
|
||||
banTimeout = 0L;
|
||||
}
|
||||
|
||||
if (BanLookup.isBanned(ess, playerName)) {
|
||||
updateBan(playerName, banReason, banTimeout);
|
||||
}
|
||||
}
|
||||
conf.removeProperty("ban");
|
||||
conf.save();
|
||||
}
|
||||
|
||||
doneFile.setProperty("banFormatChange", true);
|
||||
doneFile.save();
|
||||
ess.getLogger().info("Ban format update complete.");
|
||||
}
|
||||
|
||||
private void updateBan(String playerName, String banReason, Long banTimeout) {
|
||||
if (banTimeout == 0) {
|
||||
Bukkit.getBanList(BanList.Type.NAME).addBan(playerName, banReason, null, Console.NAME);
|
||||
} else {
|
||||
Bukkit.getBanList(BanList.Type.NAME).addBan(playerName, banReason, new Date(banTimeout), Console.NAME);
|
||||
}
|
||||
}
|
||||
|
||||
private static final FileFilter YML_FILTER = new FileFilter() {
|
||||
@Override
|
||||
public boolean accept(File pathname) {
|
||||
return pathname.isFile() && pathname.getName().endsWith(".yml");
|
||||
}
|
||||
};
|
||||
|
||||
private static final String PATTERN_CONFIG_UUID_REGEX = "(?mi)^uuid:\\s*([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\\s*$";
|
||||
private static final Pattern PATTERN_CONFIG_UUID = Pattern.compile(PATTERN_CONFIG_UUID_REGEX);
|
||||
|
||||
private static final String PATTERN_CONFIG_NAME_REGEX = "(?mi)^lastAccountName:\\s*[\"\']?(\\w+)[\"\']?\\s*$";
|
||||
private static final Pattern PATTERN_CONFIG_NAME = Pattern.compile(PATTERN_CONFIG_NAME_REGEX);
|
||||
|
||||
private void repairUserMap() {
|
||||
if (doneFile.getBoolean("userMapRepaired", false)) {
|
||||
return;
|
||||
}
|
||||
ess.getLogger().info("Starting usermap repair");
|
||||
|
||||
File userdataFolder = new File(ess.getDataFolder(), "userdata");
|
||||
if (!userdataFolder.isDirectory()) {
|
||||
ess.getLogger().warning("Missing userdata folder, aborting");
|
||||
return;
|
||||
}
|
||||
File[] files = userdataFolder.listFiles(YML_FILTER);
|
||||
|
||||
final DecimalFormat format = new DecimalFormat("#0.00");
|
||||
final Map<String, UUID> names = Maps.newHashMap();
|
||||
|
||||
for (int index = 0; index < files.length; index++) {
|
||||
final File file = files[index];
|
||||
try {
|
||||
UUID uuid = null;
|
||||
final String filename = file.getName();
|
||||
final String configData = new String(java.nio.file.Files.readAllBytes(file.toPath()), Charsets.UTF_8);
|
||||
|
||||
if (filename.length() > 36) {
|
||||
try {
|
||||
// ".yml" ending has 4 chars...
|
||||
uuid = UUID.fromString(filename.substring(0, filename.length() - 4));
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
final Matcher uuidMatcher = PATTERN_CONFIG_UUID.matcher(configData);
|
||||
if (uuidMatcher.find()) {
|
||||
try {
|
||||
uuid = UUID.fromString(uuidMatcher.group(1));
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
if (uuid == null) {
|
||||
// Don't import
|
||||
continue;
|
||||
}
|
||||
|
||||
final Matcher nameMatcher = PATTERN_CONFIG_NAME.matcher(configData);
|
||||
if (nameMatcher.find()) {
|
||||
final String username = nameMatcher.group(1);
|
||||
if (username != null && username.length() > 0) {
|
||||
names.put(StringUtil.safeString(username), uuid);
|
||||
}
|
||||
}
|
||||
|
||||
if (index % 1000 == 0) {
|
||||
ess.getLogger().info("Reading: " + format.format((100d * (double) index) / files.length)
|
||||
+ "%");
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
ess.getLogger().log(Level.SEVERE, "Error while reading file: ", e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ess.getUserMap().getNames().putAll(names);
|
||||
ess.getUserMap().reloadConfig();
|
||||
|
||||
doneFile.setProperty("userMapRepaired", true);
|
||||
doneFile.save();
|
||||
ess.getLogger().info("Completed usermap repair.");
|
||||
}
|
||||
|
||||
public void beforeSettings() {
|
||||
if (!ess.getDataFolder().exists()) {
|
||||
ess.getDataFolder().mkdirs();
|
||||
}
|
||||
moveMotdRulesToFile("motd");
|
||||
moveMotdRulesToFile("rules");
|
||||
}
|
||||
|
||||
public void afterSettings() {
|
||||
sanitizeAllUserFilenames();
|
||||
updateUsersPowerToolsFormat();
|
||||
updateUsersHomesFormat();
|
||||
deleteOldItemsCsv();
|
||||
updateSpawnsToNewSpawnsConfig();
|
||||
updateJailsToNewJailsConfig();
|
||||
uuidFileChange();
|
||||
banFormatChange();
|
||||
warnMetrics();
|
||||
repairUserMap();
|
||||
}
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.api.IItemDb;
|
||||
import com.earth2me.essentials.api.IJails;
|
||||
import com.earth2me.essentials.api.IWarps;
|
||||
import com.earth2me.essentials.metrics.Metrics;
|
||||
import com.earth2me.essentials.perm.PermissionsHandler;
|
||||
import com.earth2me.essentials.register.payment.Methods;
|
||||
import net.ess3.nms.SpawnerProvider;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface IEssentials extends Plugin {
|
||||
void addReloadListener(IConf listener);
|
||||
|
||||
void reload();
|
||||
|
||||
List<String> onTabCompleteEssentials(CommandSender sender, Command command, String commandLabel, String[] args, ClassLoader classLoader, String commandPath, String permissionPrefix, IEssentialsModule module);
|
||||
|
||||
boolean onCommandEssentials(CommandSender sender, Command command, String commandLabel, String[] args, ClassLoader classLoader, String commandPath, String permissionPrefix, IEssentialsModule module);
|
||||
|
||||
@Deprecated
|
||||
User getUser(Object base);
|
||||
|
||||
User getUser(UUID base);
|
||||
|
||||
User getUser(String base);
|
||||
|
||||
User getUser(Player base);
|
||||
|
||||
I18n getI18n();
|
||||
|
||||
User getOfflineUser(String name);
|
||||
|
||||
World getWorld(String name);
|
||||
|
||||
int broadcastMessage(String message);
|
||||
|
||||
int broadcastMessage(IUser sender, String message);
|
||||
|
||||
int broadcastMessage(String permission, String message);
|
||||
|
||||
ISettings getSettings();
|
||||
|
||||
BukkitScheduler getScheduler();
|
||||
|
||||
IJails getJails();
|
||||
|
||||
IWarps getWarps();
|
||||
|
||||
Worth getWorth();
|
||||
|
||||
Backup getBackup();
|
||||
|
||||
Kits getKits();
|
||||
|
||||
Methods getPaymentMethod();
|
||||
|
||||
BukkitTask runTaskAsynchronously(Runnable run);
|
||||
|
||||
BukkitTask runTaskLaterAsynchronously(Runnable run, long delay);
|
||||
|
||||
BukkitTask runTaskTimerAsynchronously(Runnable run, long delay, long period);
|
||||
|
||||
int scheduleSyncDelayedTask(Runnable run);
|
||||
|
||||
int scheduleSyncDelayedTask(Runnable run, long delay);
|
||||
|
||||
int scheduleSyncRepeatingTask(Runnable run, long delay, long period);
|
||||
|
||||
TNTExplodeListener getTNTListener();
|
||||
|
||||
PermissionsHandler getPermissionsHandler();
|
||||
|
||||
AlternativeCommandsHandler getAlternativeCommandsHandler();
|
||||
|
||||
void showError(CommandSource sender, Throwable exception, String commandLabel);
|
||||
|
||||
IItemDb getItemDb();
|
||||
|
||||
UserMap getUserMap();
|
||||
|
||||
Metrics getMetrics();
|
||||
|
||||
void setMetrics(Metrics metrics);
|
||||
|
||||
EssentialsTimer getTimer();
|
||||
|
||||
@Deprecated
|
||||
List<String> getVanishedPlayers();
|
||||
|
||||
Collection<Player> getOnlinePlayers();
|
||||
|
||||
Iterable<User> getOnlineUsers();
|
||||
|
||||
SpawnerProvider getSpawnerProvider();
|
||||
}
|
||||
@@ -1,194 +0,0 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.commands.IEssentialsCommand;
|
||||
import net.ess3.api.ITeleport;
|
||||
import net.ess3.api.MaxMoneyException;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
public interface IUser {
|
||||
boolean isAuthorized(String node);
|
||||
|
||||
boolean isAuthorized(IEssentialsCommand cmd);
|
||||
|
||||
boolean isAuthorized(IEssentialsCommand cmd, String permissionPrefix);
|
||||
|
||||
boolean isPermissionSet(String node);
|
||||
|
||||
void healCooldown() throws Exception;
|
||||
|
||||
void giveMoney(BigDecimal value) throws MaxMoneyException;
|
||||
|
||||
void giveMoney(final BigDecimal value, final CommandSource initiator) throws MaxMoneyException;
|
||||
|
||||
void payUser(final User reciever, final BigDecimal value) throws Exception;
|
||||
|
||||
void takeMoney(BigDecimal value);
|
||||
|
||||
void takeMoney(final BigDecimal value, final CommandSource initiator);
|
||||
|
||||
boolean canAfford(BigDecimal value);
|
||||
|
||||
Boolean canSpawnItem(final Material material);
|
||||
|
||||
void setLastLocation();
|
||||
|
||||
void setLogoutLocation();
|
||||
|
||||
void requestTeleport(final User player, final boolean here);
|
||||
|
||||
/**
|
||||
* Returns whether this user has an outstanding teleport request to deal with.
|
||||
*
|
||||
* @return whether there is a teleport request
|
||||
*/
|
||||
boolean hasOutstandingTeleportRequest();
|
||||
|
||||
ITeleport getTeleport();
|
||||
|
||||
BigDecimal getMoney();
|
||||
|
||||
void setMoney(final BigDecimal value) throws MaxMoneyException;
|
||||
|
||||
void setAfk(final boolean set);
|
||||
|
||||
/**
|
||||
* 'Hidden' Represents when a player is hidden from others. This status includes when the player is hidden via other
|
||||
* supported plugins. Use isVanished() if you want to check if a user is vanished by Essentials.
|
||||
*
|
||||
* @return If the user is hidden or not
|
||||
*
|
||||
* @see isVanished
|
||||
*/
|
||||
boolean isHidden();
|
||||
|
||||
void setHidden(boolean vanish);
|
||||
|
||||
boolean isGodModeEnabled();
|
||||
|
||||
String getGroup();
|
||||
|
||||
boolean inGroup(final String group);
|
||||
|
||||
boolean canBuild();
|
||||
|
||||
long getTeleportRequestTime();
|
||||
|
||||
void enableInvulnerabilityAfterTeleport();
|
||||
|
||||
void resetInvulnerabilityAfterTeleport();
|
||||
|
||||
boolean hasInvulnerabilityAfterTeleport();
|
||||
|
||||
/**
|
||||
* 'Vanished' Represents when a player is hidden from others by Essentials. This status does NOT include when the
|
||||
* player is hidden via other plugins. Use isHidden() if you want to check if a user is vanished by any supported
|
||||
* plugin.
|
||||
*
|
||||
* @return If the user is vanished or not
|
||||
*
|
||||
* @see isHidden
|
||||
*/
|
||||
boolean isVanished();
|
||||
|
||||
void setVanished(boolean vanish);
|
||||
|
||||
boolean isIgnoreExempt();
|
||||
|
||||
void sendMessage(String message);
|
||||
|
||||
/*
|
||||
* UserData
|
||||
*/
|
||||
Location getHome(String name) throws Exception;
|
||||
|
||||
Location getHome(Location loc) throws Exception;
|
||||
|
||||
List<String> getHomes();
|
||||
|
||||
void setHome(String name, Location loc);
|
||||
|
||||
void delHome(String name) throws Exception;
|
||||
|
||||
boolean hasHome();
|
||||
|
||||
Location getLastLocation();
|
||||
|
||||
Location getLogoutLocation();
|
||||
|
||||
long getLastTeleportTimestamp();
|
||||
|
||||
void setLastTeleportTimestamp(long time);
|
||||
|
||||
String getJail();
|
||||
|
||||
void setJail(String jail);
|
||||
|
||||
List<String> getMails();
|
||||
|
||||
void addMail(String mail);
|
||||
|
||||
boolean isAfk();
|
||||
|
||||
void setIgnoreMsg(boolean ignoreMsg);
|
||||
|
||||
boolean isIgnoreMsg();
|
||||
|
||||
void setConfigProperty(String node, Object object);
|
||||
|
||||
Set<String> getConfigKeys();
|
||||
|
||||
Map<String, Object> getConfigMap();
|
||||
|
||||
Map<String, Object> getConfigMap(String node);
|
||||
|
||||
Map<Pattern, Long> getCommandCooldowns();
|
||||
|
||||
Date getCommandCooldownExpiry(String label);
|
||||
|
||||
void addCommandCooldown(Pattern pattern, Date expiresAt, boolean save);
|
||||
|
||||
boolean clearCommandCooldown(Pattern pattern);
|
||||
|
||||
/*
|
||||
* PlayerExtension
|
||||
*/
|
||||
Player getBase();
|
||||
|
||||
CommandSource getSource();
|
||||
|
||||
String getName();
|
||||
|
||||
String getAfkMessage();
|
||||
|
||||
void setAfkMessage(final String message);
|
||||
|
||||
long getAfkSince();
|
||||
|
||||
boolean isAcceptingPay();
|
||||
|
||||
void setAcceptingPay(boolean acceptingPay);
|
||||
|
||||
boolean isPromptingPayConfirm();
|
||||
|
||||
void setPromptingPayConfirm(boolean prompt);
|
||||
|
||||
boolean isPromptingClearConfirm();
|
||||
|
||||
void setPromptingClearConfirm(boolean prompt);
|
||||
|
||||
boolean isLastMessageReplyRecipient();
|
||||
|
||||
void setLastMessageReplyRecipient(boolean enabled);
|
||||
|
||||
Map<User, BigDecimal> getConfirmingPayments();
|
||||
}
|
||||
@@ -1,264 +0,0 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.storage.AsyncStorageObjectHolder;
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.api.IUser;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockDamageEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerRespawnEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Jails extends AsyncStorageObjectHolder<com.earth2me.essentials.settings.Jails> implements net.ess3.api.IJails {
|
||||
private static final transient Logger LOGGER = Bukkit.getLogger();
|
||||
private static transient boolean enabled = false;
|
||||
|
||||
public Jails(final IEssentials ess) {
|
||||
super(ess, com.earth2me.essentials.settings.Jails.class);
|
||||
reloadConfig();
|
||||
}
|
||||
|
||||
private void registerListeners() {
|
||||
enabled = true;
|
||||
final PluginManager pluginManager = ess.getServer().getPluginManager();
|
||||
final JailListener blockListener = new JailListener();
|
||||
pluginManager.registerEvents(blockListener, ess);
|
||||
if (ess.getSettings().isDebug()) {
|
||||
LOGGER.log(Level.INFO, "Registering Jail listener");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getStorageFile() {
|
||||
return new File(ess.getDataFolder(), "jail.yml");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishRead() {
|
||||
checkRegister();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishWrite() {
|
||||
checkRegister();
|
||||
}
|
||||
|
||||
public void resetListener() {
|
||||
enabled = false;
|
||||
checkRegister();
|
||||
}
|
||||
|
||||
private void checkRegister() {
|
||||
if (enabled == false && getCount() > 0) {
|
||||
registerListeners();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getJail(final String jailName) throws Exception {
|
||||
acquireReadLock();
|
||||
try {
|
||||
if (getData().getJails() == null || jailName == null || !getData().getJails().containsKey(jailName.toLowerCase(Locale.ENGLISH))) {
|
||||
throw new Exception(tl("jailNotExist"));
|
||||
}
|
||||
Location loc = getData().getJails().get(jailName.toLowerCase(Locale.ENGLISH));
|
||||
if (loc == null || loc.getWorld() == null) {
|
||||
throw new Exception(tl("jailNotExist"));
|
||||
}
|
||||
return loc;
|
||||
} finally {
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getList() throws Exception {
|
||||
acquireReadLock();
|
||||
try {
|
||||
if (getData().getJails() == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return new ArrayList<String>(getData().getJails().keySet());
|
||||
} finally {
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeJail(final String jail) throws Exception {
|
||||
acquireWriteLock();
|
||||
try {
|
||||
if (getData().getJails() == null) {
|
||||
return;
|
||||
}
|
||||
getData().getJails().remove(jail.toLowerCase(Locale.ENGLISH));
|
||||
} finally {
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendToJail(final IUser user, final String jail) throws Exception {
|
||||
acquireReadLock();
|
||||
try {
|
||||
if (user.getBase().isOnline()) {
|
||||
Location loc = getJail(jail);
|
||||
user.getTeleport().now(loc, false, TeleportCause.COMMAND);
|
||||
}
|
||||
user.setJail(jail);
|
||||
} finally {
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setJail(final String jailName, final Location loc) throws Exception {
|
||||
acquireWriteLock();
|
||||
try {
|
||||
if (getData().getJails() == null) {
|
||||
getData().setJails(new HashMap<String, Location>());
|
||||
}
|
||||
getData().getJails().put(jailName.toLowerCase(Locale.ENGLISH), loc);
|
||||
} finally {
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
try {
|
||||
return getList().size();
|
||||
} catch (Exception ex) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class JailListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onJailBlockBreak(final BlockBreakEvent event) {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
if (user.isJailed()) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onJailBlockPlace(final BlockPlaceEvent event) {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
if (user.isJailed()) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onJailBlockDamage(final BlockDamageEvent event) {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
if (user.isJailed()) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onJailEntityDamageByEntity(final EntityDamageByEntityEvent event) {
|
||||
if (event.getCause() != DamageCause.ENTITY_ATTACK || event.getEntity().getType() != EntityType.PLAYER) {
|
||||
return;
|
||||
}
|
||||
final Entity damager = event.getDamager();
|
||||
if (damager.getType() == EntityType.PLAYER) {
|
||||
final User user = ess.getUser((Player) damager);
|
||||
if (user != null && user.isJailed()) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onJailPlayerInteract(final PlayerInteractEvent event) {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
if (user.isJailed()) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onJailPlayerRespawn(final PlayerRespawnEvent event) {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
if (!user.isJailed() || user.getJail() == null || user.getJail().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
event.setRespawnLocation(getJail(user.getJail()));
|
||||
} catch (Exception ex) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
LOGGER.log(Level.INFO, tl("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()), ex);
|
||||
} else {
|
||||
LOGGER.log(Level.INFO, tl("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onJailPlayerTeleport(final PlayerTeleportEvent event) {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
if (!user.isJailed() || user.getJail() == null || user.getJail().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
event.setTo(getJail(user.getJail()));
|
||||
} catch (Exception ex) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
LOGGER.log(Level.INFO, tl("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()), ex);
|
||||
} else {
|
||||
LOGGER.log(Level.INFO, tl("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()));
|
||||
}
|
||||
}
|
||||
user.sendMessage(tl("jailMessage"));
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onJailPlayerJoin(final PlayerJoinEvent event) {
|
||||
final User user = ess.getUser(event.getPlayer());
|
||||
final long currentTime = System.currentTimeMillis();
|
||||
user.checkJailTimeout(currentTime);
|
||||
if (!user.isJailed() || user.getJail() == null || user.getJail().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
sendToJail(user, user.getJail());
|
||||
} catch (Exception ex) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
LOGGER.log(Level.INFO, tl("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()), ex);
|
||||
} else {
|
||||
LOGGER.log(Level.INFO, tl("returnPlayerToJailError", user.getName(), ex.getLocalizedMessage()));
|
||||
}
|
||||
}
|
||||
user.sendMessage(tl("jailMessage"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,214 +0,0 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.Trade.OverflowType;
|
||||
import com.earth2me.essentials.commands.NoChargeException;
|
||||
import com.earth2me.essentials.craftbukkit.InventoryWorkaround;
|
||||
import com.earth2me.essentials.textreader.IText;
|
||||
import com.earth2me.essentials.textreader.KeywordReplacer;
|
||||
import com.earth2me.essentials.textreader.SimpleTextInput;
|
||||
import com.earth2me.essentials.utils.DateUtil;
|
||||
import net.ess3.api.IEssentials;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Kit {
|
||||
final IEssentials ess;
|
||||
final String kitName;
|
||||
final Map<String, Object> kit;
|
||||
final Trade charge;
|
||||
|
||||
public Kit(final String kitName, final IEssentials ess) throws Exception {
|
||||
this.kitName = kitName;
|
||||
this.ess = ess;
|
||||
this.kit = ess.getKits().getKit(kitName);
|
||||
this.charge = new Trade("kit-" + kitName, new Trade("kit-kit", ess), ess);
|
||||
|
||||
if (kit == null) {
|
||||
throw new Exception(tl("kitNotFound"));
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return kitName;
|
||||
}
|
||||
|
||||
public void checkPerms(final User user) throws Exception {
|
||||
if (!user.isAuthorized("essentials.kits." + kitName)) {
|
||||
throw new Exception(tl("noKitPermission", "essentials.kits." + kitName));
|
||||
}
|
||||
}
|
||||
|
||||
public void checkDelay(final User user) throws Exception {
|
||||
long nextUse = getNextUse(user);
|
||||
|
||||
if (nextUse == 0L) {
|
||||
return;
|
||||
} else if (nextUse < 0L) {
|
||||
user.sendMessage(tl("kitOnce"));
|
||||
throw new NoChargeException();
|
||||
} else {
|
||||
user.sendMessage(tl("kitTimed", DateUtil.formatDateDiff(nextUse)));
|
||||
throw new NoChargeException();
|
||||
}
|
||||
}
|
||||
|
||||
public void checkAffordable(final User user) throws Exception {
|
||||
charge.isAffordableFor(user);
|
||||
}
|
||||
|
||||
public void setTime(final User user) throws Exception {
|
||||
final Calendar time = new GregorianCalendar();
|
||||
user.setKitTimestamp(kitName, time.getTimeInMillis());
|
||||
}
|
||||
|
||||
public void chargeUser(final User user) throws Exception {
|
||||
charge.charge(user);
|
||||
}
|
||||
|
||||
public long getNextUse(final User user) throws Exception {
|
||||
if (user.isAuthorized("essentials.kit.exemptdelay")) {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
final Calendar time = new GregorianCalendar();
|
||||
|
||||
double delay = 0;
|
||||
try {
|
||||
// Make sure delay is valid
|
||||
delay = kit.containsKey("delay") ? ((Number) kit.get("delay")).doubleValue() : 0.0d;
|
||||
} catch (Exception e) {
|
||||
throw new Exception(tl("kitError2"));
|
||||
}
|
||||
|
||||
// When was the last kit used?
|
||||
final long lastTime = user.getKitTimestamp(kitName);
|
||||
|
||||
// When can be use the kit again?
|
||||
final Calendar delayTime = new GregorianCalendar();
|
||||
delayTime.setTimeInMillis(lastTime);
|
||||
delayTime.add(Calendar.SECOND, (int) delay);
|
||||
delayTime.add(Calendar.MILLISECOND, (int) ((delay * 1000.0) % 1000.0));
|
||||
|
||||
if (lastTime == 0L || lastTime > time.getTimeInMillis()) {
|
||||
// If we have no record of kit use, or its corrupted, give them benefit of the doubt.
|
||||
return 0L;
|
||||
} else if (delay < 0d) {
|
||||
// If the kit has a negative kit time, it can only be used once.
|
||||
return -1;
|
||||
} else if (delayTime.before(time)) {
|
||||
// If the kit was used in the past, but outside the delay time, it can be used.
|
||||
return 0L;
|
||||
} else {
|
||||
// If the kit has been used recently, return the next time it can be used.
|
||||
return delayTime.getTimeInMillis();
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public List<String> getItems(final User user) throws Exception {
|
||||
return getItems();
|
||||
}
|
||||
|
||||
public List<String> getItems() throws Exception {
|
||||
if (kit == null) {
|
||||
throw new Exception(tl("kitNotFound"));
|
||||
}
|
||||
try {
|
||||
final List<String> itemList = new ArrayList<String>();
|
||||
final Object kitItems = kit.get("items");
|
||||
if (kitItems instanceof List) {
|
||||
for (Object item : (List) kitItems) {
|
||||
if (item instanceof String) {
|
||||
itemList.add(item.toString());
|
||||
continue;
|
||||
}
|
||||
throw new Exception("Invalid kit item: " + item.toString());
|
||||
}
|
||||
return itemList;
|
||||
}
|
||||
throw new Exception("Invalid item list");
|
||||
} catch (Exception e) {
|
||||
ess.getLogger().log(Level.WARNING, "Error parsing kit " + kitName + ": " + e.getMessage());
|
||||
throw new Exception(tl("kitError2"), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void expandItems(final User user) throws Exception {
|
||||
expandItems(user, getItems(user));
|
||||
}
|
||||
|
||||
public void expandItems(final User user, final List<String> items) throws Exception {
|
||||
try {
|
||||
IText input = new SimpleTextInput(items);
|
||||
IText output = new KeywordReplacer(input, user.getSource(), ess, true, true);
|
||||
|
||||
boolean spew = false;
|
||||
final boolean allowUnsafe = ess.getSettings().allowUnsafeEnchantments();
|
||||
for (String kitItem : output.getLines()) {
|
||||
if (kitItem.startsWith(ess.getSettings().getCurrencySymbol())) {
|
||||
BigDecimal value = new BigDecimal(kitItem.substring(ess.getSettings().getCurrencySymbol().length()).trim());
|
||||
Trade t = new Trade(value, ess);
|
||||
t.pay(user, OverflowType.DROP);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (kitItem.startsWith("/")) {
|
||||
String command = kitItem.substring(1);
|
||||
String name = user.getName();
|
||||
command = command.replace("{player}", name);
|
||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command);
|
||||
continue;
|
||||
}
|
||||
|
||||
final String[] parts = kitItem.split(" +");
|
||||
final ItemStack parseStack = ess.getItemDb().get(parts[0], parts.length > 1 ? Integer.parseInt(parts[1]) : 1);
|
||||
|
||||
if (parseStack.getType() == Material.AIR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final MetaItemStack metaStack = new MetaItemStack(parseStack);
|
||||
|
||||
if (parts.length > 2) {
|
||||
// We pass a null sender here because kits should not do perm checks
|
||||
metaStack.parseStringMeta(null, allowUnsafe, parts, 2, ess);
|
||||
}
|
||||
|
||||
final Map<Integer, ItemStack> overfilled;
|
||||
final boolean allowOversizedStacks = user.isAuthorized("essentials.oversizedstacks");
|
||||
if (allowOversizedStacks) {
|
||||
overfilled = InventoryWorkaround.addOversizedItems(user.getBase().getInventory(), ess.getSettings().getOversizedStackSize(), metaStack.getItemStack());
|
||||
} else {
|
||||
overfilled = InventoryWorkaround.addItems(user.getBase().getInventory(), metaStack.getItemStack());
|
||||
}
|
||||
for (ItemStack itemStack : overfilled.values()) {
|
||||
int spillAmount = itemStack.getAmount();
|
||||
if (!allowOversizedStacks) {
|
||||
itemStack.setAmount(spillAmount < itemStack.getMaxStackSize() ? spillAmount : itemStack.getMaxStackSize());
|
||||
}
|
||||
while (spillAmount > 0) {
|
||||
user.getWorld().dropItemNaturally(user.getLocation(), itemStack);
|
||||
spillAmount -= itemStack.getAmount();
|
||||
}
|
||||
spew = true;
|
||||
}
|
||||
}
|
||||
user.getBase().updateInventory();
|
||||
if (spew) {
|
||||
user.sendMessage(tl("kitInvFull"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
user.getBase().updateInventory();
|
||||
ess.getLogger().log(Level.WARNING, e.getMessage());
|
||||
throw new Exception(tl("kitError2"), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.MemoryConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.earth2me.essentials.I18n.capitalCase;
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class Kits implements IConf {
|
||||
|
||||
private final EssentialsConf config;
|
||||
private ConfigurationSection kits;
|
||||
|
||||
public Kits(final IEssentials essentials) {
|
||||
config = new EssentialsConf(new File(essentials.getDataFolder(), "kits.yml"));
|
||||
config.setTemplateName("/kits.yml");
|
||||
|
||||
reloadConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadConfig() {
|
||||
config.load();
|
||||
kits = _getKits();
|
||||
}
|
||||
|
||||
private ConfigurationSection _getKits() {
|
||||
if (config.isConfigurationSection("kits")) {
|
||||
final ConfigurationSection section = config.getConfigurationSection("kits");
|
||||
final ConfigurationSection newSection = new MemoryConfiguration();
|
||||
for (String kitItem : section.getKeys(false)) {
|
||||
if (section.isConfigurationSection(kitItem)) {
|
||||
newSection.set(kitItem.toLowerCase(Locale.ENGLISH), section.getConfigurationSection(kitItem));
|
||||
}
|
||||
}
|
||||
return newSection;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public EssentialsConf getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public ConfigurationSection getKits() {
|
||||
return kits;
|
||||
}
|
||||
|
||||
public Map<String, Object> getKit(String name) {
|
||||
name = name.replace('.', '_').replace('/', '_');
|
||||
if (getKits() != null) {
|
||||
final ConfigurationSection kits = getKits();
|
||||
// For some reason, YAML doesn't sees keys as always lowercase even if they aren't defined like that.
|
||||
// Workaround is to toLowercase when getting from the config, but showing normally elsewhere.
|
||||
// ODDLY ENOUGH when you get the configuration section for ALL kits, it will return the proper
|
||||
// case of each kit. But when you check for each kit's configuration section, it won't return the kit
|
||||
// you just found if you don't toLowercase it.
|
||||
if (kits.isConfigurationSection(name.toLowerCase())) {
|
||||
return kits.getConfigurationSection(name.toLowerCase()).getValues(true);
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addKit(String name, List<String> lines, long delay) {
|
||||
// Will overwrite but w/e
|
||||
config.set("kits." + name + ".delay", delay);
|
||||
config.set("kits." + name + ".items", lines);
|
||||
kits = _getKits();
|
||||
config.save();
|
||||
}
|
||||
|
||||
public String listKits(final net.ess3.api.IEssentials ess, final User user) throws Exception {
|
||||
try {
|
||||
final ConfigurationSection kits = config.getConfigurationSection("kits");
|
||||
final StringBuilder list = new StringBuilder();
|
||||
for (String kitItem : kits.getKeys(false)) {
|
||||
if (user == null) {
|
||||
list.append(" ").append(capitalCase(kitItem));
|
||||
} else if (user.isAuthorized("essentials.kits." + kitItem.toLowerCase(Locale.ENGLISH))) {
|
||||
String cost = "";
|
||||
String name = capitalCase(kitItem);
|
||||
BigDecimal costPrice = new Trade("kit-" + kitItem.toLowerCase(Locale.ENGLISH), ess).getCommandCost(user);
|
||||
if (costPrice.signum() > 0) {
|
||||
cost = tl("kitCost", NumberUtil.displayCurrency(costPrice, ess));
|
||||
}
|
||||
|
||||
Kit kit = new Kit(kitItem, ess);
|
||||
double nextUse = kit.getNextUse(user);
|
||||
if (nextUse == -1 && ess.getSettings().isSkippingUsedOneTimeKitsFromKitList()) {
|
||||
continue;
|
||||
} else if (nextUse != 0) {
|
||||
name = tl("kitDelay", name);
|
||||
}
|
||||
|
||||
list.append(" ").append(name).append(cost);
|
||||
}
|
||||
}
|
||||
return list.toString().trim();
|
||||
} catch (Exception ex) {
|
||||
throw new Exception(tl("kitError"), ex);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,224 +0,0 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.utils.EnumUtil;
|
||||
import net.ess3.nms.refl.ReflUtil;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Ocelot;
|
||||
import org.bukkit.entity.Villager;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static com.earth2me.essentials.utils.EnumUtil.getEntityType;
|
||||
|
||||
public class MobCompat {
|
||||
|
||||
// Constants for mobs added in later versions
|
||||
public static final EntityType LLAMA = getEntityType("LLAMA");
|
||||
public static final EntityType PARROT = getEntityType("PARROT");
|
||||
public static final EntityType TROPICAL_FISH = getEntityType("TROPICAL_FISH");
|
||||
public static final EntityType PANDA = getEntityType("PANDA");
|
||||
public static final EntityType TRADER_LLAMA = getEntityType("TRADER_LLAMA");
|
||||
|
||||
// Constants for mobs that have changed since earlier versions
|
||||
public static final EntityType CAT = getEntityType("CAT", "OCELOT");
|
||||
|
||||
public enum CatType {
|
||||
// These are (loosely) Mojang names for the cats
|
||||
SIAMESE("SIAMESE", "SIAMESE_CAT"),
|
||||
WHITE("WHITE", "SIAMESE_CAT"),
|
||||
RED("RED", "RED_CAT"),
|
||||
TABBY("TABBY", "RED_CAT"),
|
||||
TUXEDO("BLACK", "BLACK_CAT"),
|
||||
BRITISH_SHORTHAIR("BRITISH_SHORTHAIR", "SIAMESE_CAT"),
|
||||
CALICO("CALICO", "RED_CAT"),
|
||||
PERSIAN("PERSIAN", "RED_CAT"),
|
||||
RAGDOLL("RAGDOLL", "SIAMESE_CAT"),
|
||||
JELLIE("JELLIE", "SIAMESE_CAT"),
|
||||
BLACK("ALL_BLACK", "BLACK_CAT"),
|
||||
;
|
||||
|
||||
private final String catTypeName;
|
||||
private final String ocelotTypeName;
|
||||
|
||||
CatType(final String catTypeName, final String ocelotTypeName) {
|
||||
this.catTypeName = catTypeName;
|
||||
this.ocelotTypeName = ocelotTypeName;
|
||||
}
|
||||
}
|
||||
|
||||
public enum VillagerProfession {
|
||||
// These are 1.14+ villager professions mapped to their respective pre-V&P profession and career
|
||||
NONE("FARMER", "FARMER", "NONE"),
|
||||
ARMORER("BLACKSMITH", "ARMORER"),
|
||||
BUTCHER("FARMER", "BUTCHER"),
|
||||
CARTOGRAPHER("LIBRARIAN", "CARTOGRAPHER"),
|
||||
CLERIC("PRIEST", "CLERIC"),
|
||||
FARMER("FARMER", "FARMER"),
|
||||
FISHERMAN("FARMER", "FISHERMAN"),
|
||||
FLETCHER("FARMER", "FLETCHER"),
|
||||
LEATHERWORKER("BUTCHER", "LEATHERWORKER"),
|
||||
LIBRARIAN("LIBRARIAN", "LIBRARIAN"),
|
||||
MASON(null, null, "MASON"),
|
||||
NITWIT("NITWIT", "NITWIT"),
|
||||
SHEPHERD("FARMER", "SHEPHERD"),
|
||||
TOOLSMITH("BLACKSMITH", "TOOL_SMITH", "TOOLSMITH"),
|
||||
WEAPONSMITH("BLACKSMITH", "WEAPON_SMITH", "WEAPONSMITH")
|
||||
;
|
||||
|
||||
private String oldProfession;
|
||||
private String oldCareer;
|
||||
private String newProfession;
|
||||
|
||||
VillagerProfession(final String oldProfession, final String career) {
|
||||
this.oldProfession = oldProfession;
|
||||
this.oldCareer = career;
|
||||
this.newProfession = career;
|
||||
}
|
||||
|
||||
VillagerProfession(final String oldProfession, final String oldCareer, final String newProfession) {
|
||||
this.oldProfession = oldProfession;
|
||||
this.oldCareer = oldCareer;
|
||||
this.newProfession = newProfession;
|
||||
}
|
||||
|
||||
private Villager.Profession asEnum() {
|
||||
return EnumUtil.valueOf(Villager.Profession.class, newProfession, oldProfession);
|
||||
}
|
||||
}
|
||||
|
||||
// Older cats are Ocelots, whereas 1.14+ cats are Cats
|
||||
private static Class catClass = ReflUtil.getClassCached("org.bukkit.entity.Cat");
|
||||
private static Class catTypeClass = ReflUtil.getClassCached("org.bukkit.entity.Cat.Type");
|
||||
private static Method catSetTypeMethod = (catClass == null || catTypeClass == null) ? null : ReflUtil.getMethodCached(catClass, "setCatType", catTypeClass);
|
||||
|
||||
private static boolean isNewCat() {
|
||||
return (catClass != null && catTypeClass != null && catSetTypeMethod != null);
|
||||
}
|
||||
|
||||
public static void setCatType(final Entity entity, final CatType type) {
|
||||
if (isNewCat()) {
|
||||
try {
|
||||
catSetTypeMethod.invoke(entity, EnumUtil.valueOf(catTypeClass, type.catTypeName));
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
((Ocelot) entity).setCatType(Ocelot.Type.valueOf(type.ocelotTypeName));
|
||||
}
|
||||
}
|
||||
|
||||
// Older villagers have professions and careers, 1.14+ villagers only have professions
|
||||
private static Class villagerCareerClass = ReflUtil.getClassCached("org.bukkit.entity.Villager.Career");
|
||||
private static Method villagerSetCareerMethod = (villagerCareerClass == null) ? null : ReflUtil.getMethodCached(Villager.class, "setCareer", villagerCareerClass);
|
||||
|
||||
private static boolean isCareerVillager() {
|
||||
return (villagerCareerClass != null && villagerSetCareerMethod != null);
|
||||
}
|
||||
|
||||
public static void setVillagerProfession(final Entity entity, final VillagerProfession profession) {
|
||||
if (!isCareerVillager()) {
|
||||
((Villager) entity).setProfession(profession.asEnum());
|
||||
} else {
|
||||
((Villager) entity).setProfession(profession.asEnum());
|
||||
try {
|
||||
villagerSetCareerMethod.invoke(entity, EnumUtil.valueOf(villagerCareerClass, profession.oldCareer));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only 1.14+ villagers have biome variants
|
||||
public static void setVillagerType(final Entity entity, final String type) {
|
||||
Class typeEnum = ReflUtil.getClassCached("org.bukkit.entity.Villager.Type");
|
||||
if (typeEnum == null) return;
|
||||
|
||||
Method villagerSetTypeMethod = ReflUtil.getMethodCached(Villager.class, "setVillagerType", typeEnum);
|
||||
try {
|
||||
villagerSetTypeMethod.invoke(entity, EnumUtil.valueOf(typeEnum, type));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Llamas only exist in 1.11+
|
||||
public static void setLlamaColor(final Entity entity, final String color) {
|
||||
Class llamaClass = ReflUtil.getClassCached("org.bukkit.entity.Llama");
|
||||
if (llamaClass == null) return;
|
||||
|
||||
Class colorEnum = ReflUtil.getClassCached("org.bukkit.entity.Llama.Color");
|
||||
Method setVariantMethod = ReflUtil.getMethodCached(llamaClass, "setColor");
|
||||
|
||||
try {
|
||||
setVariantMethod.invoke(entity, EnumUtil.valueOf(colorEnum, color));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Parrots only exist in 1.12+
|
||||
public static void setParrotVariant(final Entity entity, final String variant) {
|
||||
Class parrotClass = ReflUtil.getClassCached("org.bukkit.entity.Parrot");
|
||||
if (parrotClass == null) return;
|
||||
|
||||
Class variantEnum = ReflUtil.getClassCached("org.bukkit.entity.Parrot.Variant");
|
||||
Method setVariantMethod = ReflUtil.getMethodCached(parrotClass, "setVariant");
|
||||
try {
|
||||
setVariantMethod.invoke(entity, EnumUtil.valueOf(variantEnum, variant));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Tropical fish only exist in 1.13+
|
||||
public static void setTropicalFishPattern(final Entity entity, final String pattern) {
|
||||
Class tropicalFishClass = ReflUtil.getClassCached("org.bukkit.entity.TropicalFish");
|
||||
if (tropicalFishClass == null) return;
|
||||
|
||||
Class patternEnum = ReflUtil.getClassCached("org.bukkit.entity.TropicalFish.Pattern");
|
||||
Method setPatternMethod = ReflUtil.getMethodCached(tropicalFishClass, "setPattern");
|
||||
try {
|
||||
setPatternMethod.invoke(entity, EnumUtil.valueOf(patternEnum, pattern));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Mushroom cow variant API only exists in 1.14+
|
||||
public static void setMooshroomVariant(final Entity entity, final String variant) {
|
||||
Class mushroomCowClass = ReflUtil.getClassCached("org.bukkit.entity.MushroomCow");
|
||||
Class variantEnum = ReflUtil.getClassCached("org.bukkit.entity.MushroomCow.Variant");
|
||||
if (mushroomCowClass == null || variantEnum == null) return;
|
||||
|
||||
Method setVariantMethod = ReflUtil.getMethodCached(mushroomCowClass, "setVariant");
|
||||
try {
|
||||
setVariantMethod.invoke(entity, EnumUtil.valueOf(variantEnum, variant));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Pandas only exists in 1.14+
|
||||
public static void setPandaGene(final Entity entity, final String gene, final boolean mainGene) {
|
||||
Class pandaClass = ReflUtil.getClassCached("org.bukkit.entity.Panda");
|
||||
if (pandaClass == null) return;
|
||||
|
||||
Class geneEnum = ReflUtil.getClassCached("org.bukkit.entity.Panda.Gene");
|
||||
Method setGeneMethod;
|
||||
|
||||
if (mainGene) {
|
||||
setGeneMethod = ReflUtil.getMethodCached(pandaClass, "setMainGene");
|
||||
} else {
|
||||
setGeneMethod = ReflUtil.getMethodCached(pandaClass, "setHiddenGene");
|
||||
}
|
||||
|
||||
try {
|
||||
setGeneMethod.invoke(entity, EnumUtil.valueOf(geneEnum, gene));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.utils.FormatUtil;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class PlayerList {
|
||||
// Cosmetic list formatting
|
||||
public static String listUsers(final IEssentials ess, final List<User> users, final String seperator) {
|
||||
final StringBuilder groupString = new StringBuilder();
|
||||
Collections.sort(users);
|
||||
boolean needComma = false;
|
||||
for (User user : users) {
|
||||
if (needComma) {
|
||||
groupString.append(seperator);
|
||||
}
|
||||
needComma = true;
|
||||
if (user.isAfk()) {
|
||||
groupString.append(tl("listAfkTag"));
|
||||
}
|
||||
if (user.isHidden()) {
|
||||
groupString.append(tl("listHiddenTag"));
|
||||
}
|
||||
user.setDisplayNick();
|
||||
groupString.append(user.getDisplayName());
|
||||
groupString.append("\u00a7f");
|
||||
}
|
||||
return groupString.toString();
|
||||
}
|
||||
|
||||
// Produce a user summary: There are 5 out of maximum 10 players online.
|
||||
public static String listSummary(final IEssentials ess, final User user, final boolean showHidden) {
|
||||
Server server = ess.getServer();
|
||||
int playerHidden = 0;
|
||||
int hiddenCount = 0;
|
||||
for (User onlinePlayer : ess.getOnlineUsers()) {
|
||||
if (onlinePlayer.isHidden() || (user != null && !user.getBase().canSee(onlinePlayer.getBase()))) {
|
||||
playerHidden++;
|
||||
if (showHidden || user.getBase().canSee(onlinePlayer.getBase())) {
|
||||
hiddenCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
String online;
|
||||
if (hiddenCount > 0) {
|
||||
online = tl("listAmountHidden", ess.getOnlinePlayers().size() - playerHidden, hiddenCount, server.getMaxPlayers());
|
||||
} else {
|
||||
online = tl("listAmount", ess.getOnlinePlayers().size() - playerHidden, server.getMaxPlayers());
|
||||
}
|
||||
return online;
|
||||
}
|
||||
|
||||
// Build the basic player list, divided by groups.
|
||||
public static Map<String, List<User>> getPlayerLists(final IEssentials ess, final User sender, final boolean showHidden) {
|
||||
Server server = ess.getServer();
|
||||
final Map<String, List<User>> playerList = new HashMap<String, List<User>>();
|
||||
for (User onlineUser : ess.getOnlineUsers()) {
|
||||
if ((sender == null && !showHidden && onlineUser.isHidden()) || (sender != null && !showHidden && !sender.getBase().canSee(onlineUser.getBase()))) {
|
||||
continue;
|
||||
}
|
||||
final String group = FormatUtil.stripFormat(FormatUtil.stripEssentialsFormat(onlineUser.getGroup().toLowerCase()));
|
||||
List<User> list = playerList.get(group);
|
||||
if (list == null) {
|
||||
list = new ArrayList<User>();
|
||||
playerList.put(group, list);
|
||||
}
|
||||
list.add(onlineUser);
|
||||
}
|
||||
return playerList;
|
||||
}
|
||||
|
||||
// Handle the merging of groups
|
||||
public static List<User> getMergedList(final IEssentials ess, final Map<String, List<User>> playerList, final String groupName) {
|
||||
final Set<String> configGroups = ess.getSettings().getListGroupConfig().keySet();
|
||||
final List<User> users = new ArrayList<User>();
|
||||
for (String configGroup : configGroups) {
|
||||
if (configGroup.equalsIgnoreCase(groupName)) {
|
||||
String[] groupValues = ess.getSettings().getListGroupConfig().get(configGroup).toString().trim().split(" ");
|
||||
for (String groupValue : groupValues) {
|
||||
groupValue = groupValue.toLowerCase(Locale.ENGLISH);
|
||||
if (groupValue == null || groupValue.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
List<User> u = playerList.get(groupValue.trim());
|
||||
if (u == null || u.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
playerList.remove(groupValue);
|
||||
users.addAll(u);
|
||||
}
|
||||
}
|
||||
}
|
||||
return users;
|
||||
}
|
||||
|
||||
// Output a playerlist of just a single group, /list <groupname>
|
||||
public static String listGroupUsers(final IEssentials ess, final Map<String, List<User>> playerList, final String groupName) throws Exception {
|
||||
final List<User> users = getMergedList(ess, playerList, groupName);
|
||||
final List<User> groupUsers = playerList.get(groupName);
|
||||
if (groupUsers != null && !groupUsers.isEmpty()) {
|
||||
users.addAll(groupUsers);
|
||||
}
|
||||
if (users == null || users.isEmpty()) {
|
||||
throw new Exception(tl("groupDoesNotExist"));
|
||||
}
|
||||
final StringBuilder displayGroupName = new StringBuilder();
|
||||
displayGroupName.append(Character.toTitleCase(groupName.charAt(0)));
|
||||
displayGroupName.append(groupName.substring(1));
|
||||
return outputFormat(displayGroupName.toString(), listUsers(ess, users, ", "));
|
||||
}
|
||||
|
||||
// Build the output string
|
||||
public static String outputFormat(final String group, final String message) {
|
||||
final StringBuilder outputString = new StringBuilder();
|
||||
outputString.append(tl("listGroupTag", FormatUtil.replaceFormat(group)));
|
||||
outputString.append(message);
|
||||
return outputString.toString();
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,167 +0,0 @@
|
||||
package com.earth2me.essentials;
|
||||
|
||||
import com.earth2me.essentials.commands.WarpNotFoundException;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
import net.ess3.api.InvalidNameException;
|
||||
import net.ess3.api.InvalidWorldException;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Warps implements IConf, net.ess3.api.IWarps {
|
||||
private static final Logger logger = Logger.getLogger("Essentials");
|
||||
private final Map<StringIgnoreCase, EssentialsConf> warpPoints = new HashMap<StringIgnoreCase, EssentialsConf>();
|
||||
private final File warpsFolder;
|
||||
private final Server server;
|
||||
|
||||
public Warps(Server server, File dataFolder) {
|
||||
this.server = server;
|
||||
warpsFolder = new File(dataFolder, "warps");
|
||||
if (!warpsFolder.exists()) {
|
||||
warpsFolder.mkdirs();
|
||||
}
|
||||
reloadConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return warpPoints.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getList() {
|
||||
final List<String> keys = new ArrayList<String>();
|
||||
for (StringIgnoreCase stringIgnoreCase : warpPoints.keySet()) {
|
||||
keys.add(stringIgnoreCase.getString());
|
||||
}
|
||||
Collections.sort(keys, String.CASE_INSENSITIVE_ORDER);
|
||||
return keys;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getWarp(String warp) throws WarpNotFoundException, InvalidWorldException {
|
||||
EssentialsConf conf = warpPoints.get(new StringIgnoreCase(warp));
|
||||
if (conf == null) {
|
||||
throw new WarpNotFoundException();
|
||||
}
|
||||
return conf.getLocation(null, server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWarp(String name, Location loc) throws Exception {
|
||||
setWarp(null, name, loc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWarp(IUser user, String name, Location loc) throws Exception {
|
||||
String filename = StringUtil.sanitizeFileName(name);
|
||||
EssentialsConf conf = warpPoints.get(new StringIgnoreCase(name));
|
||||
if (conf == null) {
|
||||
File confFile = new File(warpsFolder, filename + ".yml");
|
||||
if (confFile.exists()) {
|
||||
throw new Exception(tl("similarWarpExist"));
|
||||
}
|
||||
conf = new EssentialsConf(confFile);
|
||||
warpPoints.put(new StringIgnoreCase(name), conf);
|
||||
}
|
||||
conf.setProperty(null, loc);
|
||||
conf.setProperty("name", name);
|
||||
if (user != null) conf.setProperty("lastowner", user.getBase().getUniqueId().toString());
|
||||
try {
|
||||
conf.saveWithError();
|
||||
} catch (IOException ex) {
|
||||
throw new IOException(tl("invalidWarpName"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getLastOwner(String warp) throws WarpNotFoundException {
|
||||
EssentialsConf conf = warpPoints.get(new StringIgnoreCase(warp));
|
||||
if (conf == null) {
|
||||
throw new WarpNotFoundException();
|
||||
}
|
||||
UUID uuid = null;
|
||||
try {
|
||||
uuid = UUID.fromString(conf.getString("lastowner"));
|
||||
}
|
||||
catch (Exception ex) {}
|
||||
return uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeWarp(String name) throws Exception {
|
||||
EssentialsConf conf = warpPoints.get(new StringIgnoreCase(name));
|
||||
if (conf == null) {
|
||||
throw new Exception(tl("warpNotExist"));
|
||||
}
|
||||
if (!conf.getFile().delete()) {
|
||||
throw new Exception(tl("warpDeleteError"));
|
||||
}
|
||||
warpPoints.remove(new StringIgnoreCase(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void reloadConfig() {
|
||||
warpPoints.clear();
|
||||
File[] listOfFiles = warpsFolder.listFiles();
|
||||
if (listOfFiles.length >= 1) {
|
||||
for (int i = 0; i < listOfFiles.length; i++) {
|
||||
String filename = listOfFiles[i].getName();
|
||||
if (listOfFiles[i].isFile() && filename.endsWith(".yml")) {
|
||||
try {
|
||||
EssentialsConf conf = new EssentialsConf(listOfFiles[i]);
|
||||
conf.load();
|
||||
String name = conf.getString("name");
|
||||
if (name != null) {
|
||||
warpPoints.put(new StringIgnoreCase(name), conf);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.WARNING, tl("loadWarpError", filename), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//This is here for future 3.x api support. Not implemented here becasue storage is handled differently
|
||||
@Override
|
||||
public File getWarpFile(String name) throws InvalidNameException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return getList().size();
|
||||
}
|
||||
|
||||
private static class StringIgnoreCase {
|
||||
private final String string;
|
||||
|
||||
public StringIgnoreCase(String string) {
|
||||
this.string = string;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getString().toLowerCase(Locale.ENGLISH).hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof StringIgnoreCase) {
|
||||
return getString().equalsIgnoreCase(((StringIgnoreCase) o).getString());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getString() {
|
||||
return string;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,427 +0,0 @@
|
||||
package com.earth2me.essentials.api;
|
||||
|
||||
import com.earth2me.essentials.EssentialsUserConf;
|
||||
import com.earth2me.essentials.Trade;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
import com.google.common.base.Charsets;
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.api.MaxMoneyException;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.File;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
||||
/**
|
||||
* You should use Vault instead of directly using this class.
|
||||
*/
|
||||
public class Economy {
|
||||
public Economy() {
|
||||
}
|
||||
|
||||
private static final Logger logger = Logger.getLogger("Essentials");
|
||||
private static IEssentials ess;
|
||||
private static final String noCallBeforeLoad = "Essentials API is called before Essentials is loaded.";
|
||||
public static final MathContext MATH_CONTEXT = MathContext.DECIMAL128;
|
||||
|
||||
/**
|
||||
* @param aEss the ess to set
|
||||
*/
|
||||
public static void setEss(IEssentials aEss) {
|
||||
ess = aEss;
|
||||
}
|
||||
|
||||
private static void createNPCFile(String name) {
|
||||
File folder = new File(ess.getDataFolder(), "userdata");
|
||||
name = StringUtil.safeString(name);
|
||||
if (!folder.exists()) {
|
||||
folder.mkdirs();
|
||||
}
|
||||
UUID npcUUID = UUID.nameUUIDFromBytes(("NPC:" + name).getBytes(Charsets.UTF_8));
|
||||
EssentialsUserConf npcConfig = new EssentialsUserConf(name, npcUUID, new File(folder, npcUUID.toString() + ".yml"));
|
||||
npcConfig.load();
|
||||
npcConfig.setProperty("npc", true);
|
||||
npcConfig.setProperty("lastAccountName", name);
|
||||
npcConfig.setProperty("money", ess.getSettings().getStartingBalance());
|
||||
npcConfig.forceSave();
|
||||
ess.getUserMap().trackUUID(npcUUID, name, false);
|
||||
}
|
||||
|
||||
private static void deleteNPC(String name) {
|
||||
User user = ess.getUser(name);
|
||||
user.reset();
|
||||
}
|
||||
|
||||
private static User getUserByName(String name) {
|
||||
if (ess == null) {
|
||||
throw new RuntimeException(noCallBeforeLoad);
|
||||
}
|
||||
if (name == null) {
|
||||
throw new RuntimeException("Economy username cannot be null");
|
||||
}
|
||||
|
||||
User user = ess.getUser(name);
|
||||
if (user == null) {
|
||||
/*
|
||||
Attempt lookup using UUID - this prevents balance resets when accessing economy
|
||||
via Vault during player join.
|
||||
See: https://github.com/EssentialsX/Essentials/issues/2400
|
||||
*/
|
||||
Player player = ess.getServer().getPlayerExact(name);
|
||||
if (player != null) {
|
||||
user = ess.getUser(player.getUniqueId());
|
||||
if (user != null) {
|
||||
logger.info(String.format("[Economy] Found player %s by UUID %s but not by their actual name - they may have changed their username", name, player.getUniqueId().toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the balance of a user
|
||||
*
|
||||
* @param name Name of the user
|
||||
*
|
||||
* @return balance
|
||||
*
|
||||
* @throws UserDoesNotExistException
|
||||
*/
|
||||
@Deprecated
|
||||
public static double getMoney(String name) throws UserDoesNotExistException {
|
||||
BigDecimal exactAmount = getMoneyExact(name);
|
||||
double amount = exactAmount.doubleValue();
|
||||
if (new BigDecimal(amount).compareTo(exactAmount) > 0) {
|
||||
// closest double is bigger than the exact amount
|
||||
// -> get the previous double value to not return more money than the user has
|
||||
amount = Math.nextAfter(amount, Double.NEGATIVE_INFINITY);
|
||||
}
|
||||
return amount;
|
||||
}
|
||||
|
||||
public static BigDecimal getMoneyExact(String name) throws UserDoesNotExistException {
|
||||
User user = getUserByName(name);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(name);
|
||||
}
|
||||
return user.getMoney();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the balance of a user
|
||||
*
|
||||
* @param name Name of the user
|
||||
* @param balance The balance you want to set
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that name does not exists
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
*/
|
||||
@Deprecated
|
||||
public static void setMoney(String name, double balance) throws UserDoesNotExistException, NoLoanPermittedException {
|
||||
try {
|
||||
setMoney(name, BigDecimal.valueOf(balance));
|
||||
} catch (ArithmeticException e) {
|
||||
logger.log(Level.WARNING, "Failed to set balance of " + name + " to " + balance + ": " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setMoney(String name, BigDecimal balance) throws UserDoesNotExistException, NoLoanPermittedException {
|
||||
User user = getUserByName(name);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(name);
|
||||
}
|
||||
if (balance.compareTo(ess.getSettings().getMinMoney()) < 0) {
|
||||
throw new NoLoanPermittedException();
|
||||
}
|
||||
if (balance.signum() < 0 && !user.isAuthorized("essentials.eco.loan")) {
|
||||
throw new NoLoanPermittedException();
|
||||
}
|
||||
try {
|
||||
user.setMoney(balance);
|
||||
} catch (MaxMoneyException ex) {
|
||||
//TODO: Update API to show max balance errors
|
||||
}
|
||||
Trade.log("API", "Set", "API", name, new Trade(balance, ess), null, null, null, ess);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds money to the balance of a user
|
||||
*
|
||||
* @param name Name of the user
|
||||
* @param amount The money you want to add
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that name does not exists
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
*/
|
||||
@Deprecated
|
||||
public static void add(String name, double amount) throws UserDoesNotExistException, NoLoanPermittedException {
|
||||
try {
|
||||
add(name, BigDecimal.valueOf(amount));
|
||||
} catch (ArithmeticException e) {
|
||||
logger.log(Level.WARNING, "Failed to add " + amount + " to balance of " + name + ": " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void add(String name, BigDecimal amount) throws UserDoesNotExistException, NoLoanPermittedException, ArithmeticException {
|
||||
BigDecimal result = getMoneyExact(name).add(amount, MATH_CONTEXT);
|
||||
setMoney(name, result);
|
||||
Trade.log("API", "Add", "API", name, new Trade(amount, ess), null, null, null, ess);
|
||||
}
|
||||
|
||||
/**
|
||||
* Substracts money from the balance of a user
|
||||
*
|
||||
* @param name Name of the user
|
||||
* @param amount The money you want to substract
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that name does not exists
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
*/
|
||||
@Deprecated
|
||||
public static void subtract(String name, double amount) throws UserDoesNotExistException, NoLoanPermittedException {
|
||||
try {
|
||||
substract(name, BigDecimal.valueOf(amount));
|
||||
} catch (ArithmeticException e) {
|
||||
logger.log(Level.WARNING, "Failed to substract " + amount + " of balance of " + name + ": " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void substract(String name, BigDecimal amount) throws UserDoesNotExistException, NoLoanPermittedException, ArithmeticException {
|
||||
BigDecimal result = getMoneyExact(name).subtract(amount, MATH_CONTEXT);
|
||||
setMoney(name, result);
|
||||
Trade.log("API", "Subtract", "API", name, new Trade(amount, ess), null, null, null, ess);
|
||||
}
|
||||
|
||||
/**
|
||||
* Divides the balance of a user by a value
|
||||
*
|
||||
* @param name Name of the user
|
||||
* @param amount The balance is divided by this value
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that name does not exists
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
*/
|
||||
@Deprecated
|
||||
public static void divide(String name, double amount) throws UserDoesNotExistException, NoLoanPermittedException {
|
||||
try {
|
||||
divide(name, BigDecimal.valueOf(amount));
|
||||
} catch (ArithmeticException e) {
|
||||
logger.log(Level.WARNING, "Failed to divide balance of " + name + " by " + amount + ": " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void divide(String name, BigDecimal amount) throws UserDoesNotExistException, NoLoanPermittedException, ArithmeticException {
|
||||
BigDecimal result = getMoneyExact(name).divide(amount, MATH_CONTEXT);
|
||||
setMoney(name, result);
|
||||
Trade.log("API", "Divide", "API", name, new Trade(amount, ess), null, null, null, ess);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies the balance of a user by a value
|
||||
*
|
||||
* @param name Name of the user
|
||||
* @param amount The balance is multiplied by this value
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that name does not exists
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
*/
|
||||
@Deprecated
|
||||
public static void multiply(String name, double amount) throws UserDoesNotExistException, NoLoanPermittedException {
|
||||
try {
|
||||
multiply(name, BigDecimal.valueOf(amount));
|
||||
} catch (ArithmeticException e) {
|
||||
logger.log(Level.WARNING, "Failed to multiply balance of " + name + " by " + amount + ": " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void multiply(String name, BigDecimal amount) throws UserDoesNotExistException, NoLoanPermittedException, ArithmeticException {
|
||||
BigDecimal result = getMoneyExact(name).multiply(amount, MATH_CONTEXT);
|
||||
setMoney(name, result);
|
||||
Trade.log("API", "Multiply", "API", name, new Trade(amount, ess), null, null, null, ess);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the balance of a user to the starting balance
|
||||
*
|
||||
* @param name Name of the user
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that name does not exists
|
||||
* @throws NoLoanPermittedException If the user is not allowed to have a negative balance
|
||||
*/
|
||||
public static void resetBalance(String name) throws UserDoesNotExistException, NoLoanPermittedException {
|
||||
if (ess == null) {
|
||||
throw new RuntimeException(noCallBeforeLoad);
|
||||
}
|
||||
setMoney(name, ess.getSettings().getStartingBalance());
|
||||
Trade.log("API", "Reset", "API", name, new Trade(BigDecimal.ZERO, ess), null, null, null, ess);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name Name of the user
|
||||
* @param amount The amount of money the user should have
|
||||
*
|
||||
* @return true, if the user has more or an equal amount of money
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that name does not exists
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean hasEnough(String name, double amount) throws UserDoesNotExistException {
|
||||
try {
|
||||
return hasEnough(name, BigDecimal.valueOf(amount));
|
||||
} catch (ArithmeticException e) {
|
||||
logger.log(Level.WARNING, "Failed to compare balance of " + name + " with " + amount + ": " + e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean hasEnough(String name, BigDecimal amount) throws UserDoesNotExistException, ArithmeticException {
|
||||
return amount.compareTo(getMoneyExact(name)) <= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name Name of the user
|
||||
* @param amount The amount of money the user should have
|
||||
*
|
||||
* @return true, if the user has more money
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that name does not exists
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean hasMore(String name, double amount) throws UserDoesNotExistException {
|
||||
try {
|
||||
return hasMore(name, BigDecimal.valueOf(amount));
|
||||
} catch (ArithmeticException e) {
|
||||
logger.log(Level.WARNING, "Failed to compare balance of " + name + " with " + amount + ": " + e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean hasMore(String name, BigDecimal amount) throws UserDoesNotExistException, ArithmeticException {
|
||||
return amount.compareTo(getMoneyExact(name)) < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name Name of the user
|
||||
* @param amount The amount of money the user should not have
|
||||
*
|
||||
* @return true, if the user has less money
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that name does not exists
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean hasLess(String name, double amount) throws UserDoesNotExistException {
|
||||
try {
|
||||
return hasLess(name, BigDecimal.valueOf(amount));
|
||||
} catch (ArithmeticException e) {
|
||||
logger.log(Level.WARNING, "Failed to compare balance of " + name + " with " + amount + ": " + e.getMessage(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean hasLess(String name, BigDecimal amount) throws UserDoesNotExistException, ArithmeticException {
|
||||
return amount.compareTo(getMoneyExact(name)) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the user has a negative balance
|
||||
*
|
||||
* @param name Name of the user
|
||||
*
|
||||
* @return true, if the user has a negative balance
|
||||
*
|
||||
* @throws UserDoesNotExistException If a user by that name does not exists
|
||||
*/
|
||||
public static boolean isNegative(String name) throws UserDoesNotExistException {
|
||||
return getMoneyExact(name).signum() < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the amount of money like all other Essentials functions. Example: $100000 or $12345.67
|
||||
*
|
||||
* @param amount The amount of money
|
||||
*
|
||||
* @return Formatted money
|
||||
*/
|
||||
@Deprecated
|
||||
public static String format(double amount) {
|
||||
try {
|
||||
return format(BigDecimal.valueOf(amount));
|
||||
} catch (NumberFormatException e) {
|
||||
logger.log(Level.WARNING, "Failed to display " + amount + ": " + e.getMessage(), e);
|
||||
return "NaN";
|
||||
}
|
||||
}
|
||||
|
||||
public static String format(BigDecimal amount) {
|
||||
if (ess == null) {
|
||||
throw new RuntimeException(noCallBeforeLoad);
|
||||
}
|
||||
return NumberUtil.displayCurrency(amount, ess);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a player exists to avoid the UserDoesNotExistException
|
||||
*
|
||||
* @param name Name of the user
|
||||
*
|
||||
* @return true, if the user exists
|
||||
*/
|
||||
public static boolean playerExists(String name) {
|
||||
return getUserByName(name) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a player is a npc
|
||||
*
|
||||
* @param name Name of the player
|
||||
*
|
||||
* @return true, if it's a npc
|
||||
*
|
||||
* @throws UserDoesNotExistException
|
||||
*/
|
||||
public static boolean isNPC(String name) throws UserDoesNotExistException {
|
||||
User user = getUserByName(name);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(name);
|
||||
}
|
||||
return user.isNPC();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates dummy files for a npc, if there is no player yet with that name.
|
||||
*
|
||||
* @param name Name of the player
|
||||
*
|
||||
* @return true, if a new npc was created
|
||||
*/
|
||||
public static boolean createNPC(String name) {
|
||||
User user = getUserByName(name);
|
||||
if (user == null) {
|
||||
createNPCFile(name);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a user, if it is marked as npc.
|
||||
*
|
||||
* @param name Name of the player
|
||||
*
|
||||
* @throws UserDoesNotExistException
|
||||
*/
|
||||
public static void removeNPC(String name) throws UserDoesNotExistException {
|
||||
User user = getUserByName(name);
|
||||
if (user == null) {
|
||||
throw new UserDoesNotExistException(name);
|
||||
}
|
||||
deleteNPC(name);
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package com.earth2me.essentials.api;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
|
||||
public interface II18n {
|
||||
/**
|
||||
* Gets the current locale setting
|
||||
*
|
||||
* @return the current locale, if not set it will return the default locale
|
||||
*/
|
||||
Locale getCurrentLocale();
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
package com.earth2me.essentials.api;
|
||||
|
||||
|
||||
public interface IReload {
|
||||
void onReload();
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package com.earth2me.essentials.api;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class UserDoesNotExistException extends Exception {
|
||||
public UserDoesNotExistException(String name) {
|
||||
super(tl("userDoesNotExist", name));
|
||||
}
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandafk extends EssentialsCommand {
|
||||
public Commandafk() {
|
||||
super("afk");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(Server server, User user, String commandLabel, String[] args) throws Exception {
|
||||
if (args.length > 0 && user.isAuthorized("essentials.afk.others")) {
|
||||
User afkUser = user; // if no player found, but message specified, set command executor to target user
|
||||
String message;
|
||||
try {
|
||||
afkUser = getPlayer(server, user, args, 0);
|
||||
message = args.length > 1 ? getFinalArg(args, 1) : null;
|
||||
} catch (PlayerNotFoundException e) {
|
||||
// If only one arg is passed, assume the command executor is targeting another player.
|
||||
if (args.length == 1) {
|
||||
throw e;
|
||||
}
|
||||
message = getFinalArg(args, 0);
|
||||
}
|
||||
toggleAfk(user, afkUser, message);
|
||||
} else {
|
||||
String message = args.length > 0 ? getFinalArg(args, 0) : null;
|
||||
toggleAfk(user, user, message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(Server server, CommandSource sender, String commandLabel, String[] args) throws Exception {
|
||||
if (args.length > 0) {
|
||||
User afkUser = getPlayer(server, args, 0, true, false);
|
||||
String message = args.length > 1 ? getFinalArg(args, 1) : null;
|
||||
toggleAfk(null, afkUser, message);
|
||||
} else {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
}
|
||||
|
||||
private void toggleAfk(User sender, User user, String message) throws Exception {
|
||||
if (message != null && sender != null) {
|
||||
if (sender.isMuted()) {
|
||||
throw new Exception(sender.hasMuteReason() ? tl("voiceSilencedReason", sender.getMuteReason()) : tl("voiceSilenced"));
|
||||
}
|
||||
if (!sender.isAuthorized("essentials.afk.message")) {
|
||||
throw new Exception(tl("noPermToAFKMessage"));
|
||||
}
|
||||
}
|
||||
user.setDisplayNick();
|
||||
String msg = "";
|
||||
if (!user.toggleAfk()) {
|
||||
//user.sendMessage(_("markedAsNotAway"));
|
||||
if (!user.isHidden()) {
|
||||
msg = tl("userIsNotAway", user.getDisplayName());
|
||||
}
|
||||
user.updateActivity(false);
|
||||
} else {
|
||||
//user.sendMessage(_("markedAsAway"));
|
||||
if (!user.isHidden()) {
|
||||
if (message != null) {
|
||||
msg = tl("userIsAwayWithMessage", user.getDisplayName(), message);
|
||||
} else {
|
||||
msg = tl("userIsAway", user.getDisplayName());
|
||||
}
|
||||
}
|
||||
user.setAfkMessage(message);
|
||||
}
|
||||
if (!msg.isEmpty()) {
|
||||
ess.broadcastMessage(user, msg);
|
||||
}
|
||||
user.setDisplayNick(); // Set this again after toggling
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, User user, String commandLabel, String[] args) {
|
||||
if (args.length == 1 && user.isAuthorized("essentials.afk.others")) {
|
||||
return getPlayers(server, user);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, CommandSource sender, String commandLabel, String[] args) {
|
||||
if (args.length == 1) {
|
||||
return getPlayers(server, sender);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,180 +0,0 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.textreader.SimpleTextInput;
|
||||
import com.earth2me.essentials.textreader.TextPager;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.text.DateFormat;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandbalancetop extends EssentialsCommand {
|
||||
public Commandbalancetop() {
|
||||
super("balancetop");
|
||||
}
|
||||
|
||||
private static final int CACHETIME = 2 * 60 * 1000;
|
||||
public static final int MINUSERS = 50;
|
||||
private static final SimpleTextInput cache = new SimpleTextInput();
|
||||
private static long cacheage = 0;
|
||||
private static final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
|
||||
@Override
|
||||
protected void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
int page = 0;
|
||||
boolean force = false;
|
||||
if (args.length > 0) {
|
||||
try {
|
||||
page = Integer.parseInt(args[0]);
|
||||
} catch (NumberFormatException ex) {
|
||||
if (args[0].equalsIgnoreCase("force") && (!sender.isPlayer() || ess.getUser(sender.getPlayer()).isAuthorized("essentials.balancetop.force"))) {
|
||||
force = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!force && lock.readLock().tryLock()) {
|
||||
try {
|
||||
if (cacheage > System.currentTimeMillis() - CACHETIME) {
|
||||
outputCache(sender, commandLabel, page);
|
||||
return;
|
||||
}
|
||||
if (ess.getUserMap().getUniqueUsers() > MINUSERS) {
|
||||
sender.sendMessage(tl("orderBalances", ess.getUserMap().getUniqueUsers()));
|
||||
}
|
||||
} finally {
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
ess.runTaskAsynchronously(new Viewer(sender, commandLabel, page, force));
|
||||
} else {
|
||||
if (ess.getUserMap().getUniqueUsers() > MINUSERS) {
|
||||
sender.sendMessage(tl("orderBalances", ess.getUserMap().getUniqueUsers()));
|
||||
}
|
||||
ess.runTaskAsynchronously(new Viewer(sender, commandLabel, page, force));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void outputCache(final CommandSource sender, String command, int page) {
|
||||
final Calendar cal = Calendar.getInstance();
|
||||
cal.setTimeInMillis(cacheage);
|
||||
final DateFormat format = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
|
||||
sender.sendMessage(tl("balanceTop", format.format(cal.getTime())));
|
||||
new TextPager(cache).showPage(Integer.toString(page), null, "balancetop", sender);
|
||||
}
|
||||
|
||||
|
||||
private class Calculator implements Runnable {
|
||||
private final transient Viewer viewer;
|
||||
private final boolean force;
|
||||
|
||||
public Calculator(final Viewer viewer, final boolean force) {
|
||||
this.viewer = viewer;
|
||||
this.force = force;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
lock.writeLock().lock();
|
||||
try {
|
||||
if (force || cacheage <= System.currentTimeMillis() - CACHETIME) {
|
||||
cache.getLines().clear();
|
||||
final Map<String, BigDecimal> balances = new HashMap<String, BigDecimal>();
|
||||
BigDecimal totalMoney = BigDecimal.ZERO;
|
||||
if (ess.getSettings().isEcoDisabled()) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().info("Internal economy functions disabled, aborting baltop.");
|
||||
}
|
||||
} else {
|
||||
for (UUID u : ess.getUserMap().getAllUniqueUsers()) {
|
||||
final User user = ess.getUserMap().getUser(u);
|
||||
if (user != null) {
|
||||
if (!ess.getSettings().isNpcsInBalanceRanking() && user.isNPC()) {
|
||||
// Don't list NPCs in output
|
||||
continue;
|
||||
}
|
||||
if (!user.isAuthorized("essentials.balancetop.exclude")) {
|
||||
final BigDecimal userMoney = user.getMoney();
|
||||
user.updateMoneyCache(userMoney);
|
||||
totalMoney = totalMoney.add(userMoney);
|
||||
final String name = user.isHidden() ? user.getName() : user.getDisplayName();
|
||||
balances.put(name, userMoney);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final List<Map.Entry<String, BigDecimal>> sortedEntries = new ArrayList<Map.Entry<String, BigDecimal>>(balances.entrySet());
|
||||
Collections.sort(sortedEntries, new Comparator<Map.Entry<String, BigDecimal>>() {
|
||||
@Override
|
||||
public int compare(final Entry<String, BigDecimal> entry1, final Entry<String, BigDecimal> entry2) {
|
||||
return entry2.getValue().compareTo(entry1.getValue());
|
||||
}
|
||||
});
|
||||
|
||||
cache.getLines().add(tl("serverTotal", NumberUtil.displayCurrency(totalMoney, ess)));
|
||||
int pos = 1;
|
||||
for (Map.Entry<String, BigDecimal> entry : sortedEntries) {
|
||||
cache.getLines().add(pos + ". " + entry.getKey() + ", " + NumberUtil.displayCurrency(entry.getValue(), ess));
|
||||
pos++;
|
||||
}
|
||||
cacheage = System.currentTimeMillis();
|
||||
}
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
ess.runTaskAsynchronously(viewer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class Viewer implements Runnable {
|
||||
private final transient CommandSource sender;
|
||||
private final transient int page;
|
||||
private final transient boolean force;
|
||||
private final transient String commandLabel;
|
||||
|
||||
public Viewer(final CommandSource sender, final String commandLabel, final int page, final boolean force) {
|
||||
this.sender = sender;
|
||||
this.page = page;
|
||||
this.force = force;
|
||||
this.commandLabel = commandLabel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
lock.readLock().lock();
|
||||
try {
|
||||
if (!force && cacheage > System.currentTimeMillis() - CACHETIME) {
|
||||
outputCache(sender, commandLabel, page);
|
||||
return;
|
||||
}
|
||||
} finally {
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
ess.runTaskAsynchronously(new Calculator(new Viewer(sender, commandLabel, page, false), force));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, CommandSource sender, String commandLabel, String[] args) {
|
||||
if (args.length == 1) {
|
||||
List<String> options = Lists.newArrayList("1");
|
||||
if (!sender.isPlayer() || ess.getUser(sender.getPlayer()).isAuthorized("essentials.balancetop.force")) {
|
||||
options.add("force");
|
||||
}
|
||||
return options;
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.io.CharStreams;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.DateUtil;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.MemoryConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConstructor;
|
||||
import org.bukkit.configuration.file.YamlRepresenter;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.DumperOptions.FlowStyle;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.representer.Representer;
|
||||
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public class Commandcreatekit extends EssentialsCommand {
|
||||
|
||||
private static final String PASTE_URL = "https://hastebin.com/";
|
||||
private static final String PASTE_UPLOAD_URL = PASTE_URL + "documents";
|
||||
private static final Gson GSON = new Gson();
|
||||
|
||||
private final ExecutorService executorService = Executors.newSingleThreadExecutor();
|
||||
private final DumperOptions yamlOptions = new DumperOptions();
|
||||
private final Representer yamlRepresenter = new YamlRepresenter();
|
||||
private final YamlConstructor yamlConstructor = new YamlConstructor();
|
||||
|
||||
public Commandcreatekit() {
|
||||
super("createkit");
|
||||
yamlOptions.setDefaultFlowStyle(FlowStyle.BLOCK);
|
||||
yamlRepresenter.setDefaultFlowStyle(FlowStyle.BLOCK);
|
||||
}
|
||||
|
||||
// /createkit <name> <delay>
|
||||
@Override
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length != 2) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
// Command handler will auto fail if this fails.
|
||||
long delay = Long.valueOf(args[1]);
|
||||
String kitname = args[0];
|
||||
ItemStack[] items = user.getBase().getInventory().getContents();
|
||||
List<String> list = new ArrayList<>();
|
||||
for (ItemStack is : items) {
|
||||
if (is != null && is.getType() != null && is.getType() != Material.AIR) {
|
||||
String serialized = ess.getItemDb().serialize(is);
|
||||
list.add(serialized);
|
||||
}
|
||||
}
|
||||
// Some users might want to directly write to config knowing the consequences. *shrug*
|
||||
if (!ess.getSettings().isPastebinCreateKit()) {
|
||||
ess.getKits().addKit(kitname, list, delay);
|
||||
user.sendMessage(tl("createdKit", kitname, list.size(), delay));
|
||||
} else {
|
||||
ConfigurationSection config = new MemoryConfiguration();
|
||||
config.set("kits." + kitname + ".delay", delay);
|
||||
config.set("kits." + kitname + ".items", list);
|
||||
|
||||
final Yaml yaml = new Yaml(yamlConstructor, yamlRepresenter, yamlOptions);
|
||||
String fileContents = "# Copy the kit code below into the kits section in your config.yml file\n";
|
||||
fileContents += yaml.dump(config.getValues(false));
|
||||
|
||||
uploadPaste(user.getSource(), kitname, delay, fileContents);
|
||||
}
|
||||
}
|
||||
|
||||
private void uploadPaste(final CommandSource sender, final String kitName, final long delay, final String contents) {
|
||||
executorService.submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
HttpURLConnection connection = (HttpURLConnection) new URL(PASTE_UPLOAD_URL).openConnection();
|
||||
connection.setRequestMethod("POST");
|
||||
connection.setDoInput(true);
|
||||
connection.setDoOutput(true);
|
||||
connection.setRequestProperty("User-Agent", "EssentialsX plugin");
|
||||
try (OutputStream os = connection.getOutputStream()) {
|
||||
os.write(contents.getBytes(Charsets.UTF_8));
|
||||
}
|
||||
// Error
|
||||
if (connection.getResponseCode() >= 400) {
|
||||
sender.sendMessage(tl("createKitFailed", kitName));
|
||||
String message = CharStreams.toString(new InputStreamReader(connection.getErrorStream(), Charsets.UTF_8));
|
||||
ess.getLogger().severe("Error creating kit: " + message);
|
||||
return;
|
||||
}
|
||||
|
||||
// Read URL
|
||||
JsonObject object = GSON.fromJson(new InputStreamReader(connection.getInputStream(), Charsets.UTF_8), JsonObject.class);
|
||||
String pasteUrl = PASTE_URL + object.get("key").getAsString();
|
||||
connection.disconnect();
|
||||
|
||||
String separator = tl("createKitSeparator");
|
||||
String delayFormat = "0";
|
||||
if (delay > 0) {
|
||||
delayFormat = DateUtil.formatDateDiff(System.currentTimeMillis() + (delay * 1000));
|
||||
}
|
||||
sender.sendMessage(separator);
|
||||
sender.sendMessage(tl("createKitSuccess", kitName, delayFormat, pasteUrl));
|
||||
sender.sendMessage(separator);
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().info(sender.getSender().getName() + " created a kit: " + pasteUrl);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
sender.sendMessage(tl("createKitFailed", kitName));
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commanddelwarp extends EssentialsCommand {
|
||||
public Commanddelwarp() {
|
||||
super("delwarp");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length < 1) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
ess.getWarps().removeWarp(args[0]);
|
||||
sender.sendMessage(tl("deleteWarp", args[0]));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
return new ArrayList<>(ess.getWarps().getList());
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.ChargeException;
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import net.ess3.api.MaxMoneyException;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandeco extends EssentialsLoopCommand {
|
||||
Commandeco.EcoCommands cmd;
|
||||
BigDecimal amount;
|
||||
|
||||
public Commandeco() {
|
||||
super("eco");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length < 2) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
BigDecimal startingBalance = ess.getSettings().getStartingBalance();
|
||||
|
||||
try {
|
||||
cmd = Commandeco.EcoCommands.valueOf(args[0].toUpperCase(Locale.ENGLISH));
|
||||
amount = (cmd == Commandeco.EcoCommands.RESET) ? startingBalance : new BigDecimal(args[2].replaceAll("[^0-9\\.]", ""));
|
||||
} catch (Exception ex) {
|
||||
throw new NotEnoughArgumentsException(ex);
|
||||
}
|
||||
|
||||
loopOfflinePlayers(server, sender, false, true, args[1], args);
|
||||
|
||||
if (cmd == Commandeco.EcoCommands.RESET || cmd == Commandeco.EcoCommands.SET) {
|
||||
if (args[1].contentEquals("**")) {
|
||||
server.broadcastMessage(tl("resetBalAll", NumberUtil.displayCurrency(amount, ess)));
|
||||
} else if (args[1].contentEquals("*")) {
|
||||
server.broadcastMessage(tl("resetBal", NumberUtil.displayCurrency(amount, ess)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updatePlayer(final Server server, final CommandSource sender, final User player, final String[] args) throws NotEnoughArgumentsException, ChargeException, MaxMoneyException {
|
||||
switch (cmd) {
|
||||
case GIVE:
|
||||
player.giveMoney(amount, sender);
|
||||
break;
|
||||
|
||||
case TAKE:
|
||||
take(amount, player, sender);
|
||||
break;
|
||||
|
||||
case RESET:
|
||||
case SET:
|
||||
set(amount, player, sender);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void take(BigDecimal amount, final User player, final CommandSource sender) throws ChargeException {
|
||||
BigDecimal money = player.getMoney();
|
||||
BigDecimal minBalance = ess.getSettings().getMinMoney();
|
||||
if (money.subtract(amount).compareTo(minBalance) >= 0) {
|
||||
player.takeMoney(amount, sender);
|
||||
} else if (sender == null) {
|
||||
try {
|
||||
player.setMoney(minBalance);
|
||||
} catch (MaxMoneyException ex) {
|
||||
// Take shouldn't be able to throw a max money exception
|
||||
}
|
||||
player.sendMessage(tl("takenFromAccount", NumberUtil.displayCurrency(player.getMoney(), ess)));
|
||||
} else {
|
||||
throw new ChargeException(tl("insufficientFunds"));
|
||||
}
|
||||
}
|
||||
|
||||
private void set(BigDecimal amount, final User player, final CommandSource sender) throws MaxMoneyException {
|
||||
BigDecimal minBalance = ess.getSettings().getMinMoney();
|
||||
BigDecimal maxBalance = ess.getSettings().getMaxMoney();
|
||||
boolean underMinimum = (amount.compareTo(minBalance) < 0);
|
||||
boolean aboveMax = (amount.compareTo(maxBalance) > 0);
|
||||
player.setMoney(underMinimum ? minBalance : aboveMax ? maxBalance : amount);
|
||||
player.sendMessage(tl("setBal", NumberUtil.displayCurrency(player.getMoney(), ess)));
|
||||
if (sender != null) {
|
||||
sender.sendMessage(tl("setBalOthers", player.getDisplayName(), NumberUtil.displayCurrency(player.getMoney(), ess)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private enum EcoCommands {
|
||||
GIVE, TAKE, SET, RESET
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, final CommandSource sender, String commandLabel, String[] args) {
|
||||
if (args.length == 1) {
|
||||
List<String> options = Lists.newArrayList();
|
||||
for (EcoCommands command : EcoCommands.values()) {
|
||||
options.add(command.name().toLowerCase(Locale.ENGLISH));
|
||||
}
|
||||
return options;
|
||||
} else if (args.length == 2) {
|
||||
return getPlayers(server, sender);
|
||||
} else if (args.length == 3 && !args[0].equalsIgnoreCase(EcoCommands.RESET.name())) {
|
||||
if (args[0].equalsIgnoreCase(EcoCommands.SET.name())) {
|
||||
return Lists.newArrayList("0", ess.getSettings().getStartingBalance().toString());
|
||||
} else {
|
||||
return Lists.newArrayList("1", "10", "100", "1000");
|
||||
}
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,415 +0,0 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.EssentialsUpgrade;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.UserMap;
|
||||
import com.earth2me.essentials.utils.*;
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
// This command has 4 undocumented behaviours #EasterEgg
|
||||
public class Commandessentials extends EssentialsCommand {
|
||||
|
||||
private final Sound NOTE_HARP = EnumUtil.valueOf(Sound.class, "BLOCK_NOTE_BLOCK_HARP", "BLOCK_NOTE_HARP", "NOTE_PIANO");
|
||||
|
||||
public Commandessentials() {
|
||||
super("essentials");
|
||||
}
|
||||
|
||||
private transient int taskid;
|
||||
private final transient Map<Player, Block> noteBlocks = new HashMap<Player, Block>();
|
||||
|
||||
private final List<String> versionPlugins = Arrays.asList(
|
||||
"Vault",
|
||||
"LuckPerms",
|
||||
"PermissionsEx",
|
||||
"GroupManager"
|
||||
);
|
||||
|
||||
private final List<String> officialPlugins = Arrays.asList(
|
||||
"EssentialsAntiBuild",
|
||||
"EssentialsChat",
|
||||
"EssentialsGeoIP",
|
||||
"EssentialsProtect",
|
||||
"EssentialsSpawn",
|
||||
"EssentialsXMPP"
|
||||
);
|
||||
|
||||
private final List<String> warnPlugins = Arrays.asList(
|
||||
"PermissionsEx",
|
||||
"GroupManager"
|
||||
);
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length == 0) {
|
||||
run_disabled(server, sender, commandLabel, args);
|
||||
} else if (args[0].equalsIgnoreCase("debug")) {
|
||||
run_debug(server, sender, commandLabel, args);
|
||||
} else if (args[0].equalsIgnoreCase("nya")) {
|
||||
run_nya(server, sender, commandLabel, args);
|
||||
} else if (args[0].equalsIgnoreCase("moo")) {
|
||||
run_moo(server, sender, commandLabel, args);
|
||||
} else if (args[0].equalsIgnoreCase("reset")) {
|
||||
run_reset(server, sender, commandLabel, args);
|
||||
} else if (args[0].equalsIgnoreCase("cleanup")) {
|
||||
run_cleanup(server, sender, commandLabel, args);
|
||||
} else if (args[0].equalsIgnoreCase("uuidconvert")) {
|
||||
run_uuidconvert(server, sender, commandLabel, args);
|
||||
} else if (args[0].equalsIgnoreCase("uuidtest")) {
|
||||
run_uuidtest(server, sender, commandLabel, args);
|
||||
} else if (args[0].equalsIgnoreCase("version")) {
|
||||
run_version(server, sender, commandLabel, args);
|
||||
} else {
|
||||
run_reload(server, sender, commandLabel, args);
|
||||
}
|
||||
}
|
||||
|
||||
//If you do not supply an argument this command will list 'overridden' commands.
|
||||
private void run_disabled(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
sender.sendMessage("/<command> <reload/debug>");
|
||||
|
||||
final StringBuilder disabledCommands = new StringBuilder();
|
||||
for (Map.Entry<String, String> entry : ess.getAlternativeCommandsHandler().disabledCommands().entrySet()) {
|
||||
if (disabledCommands.length() > 0) {
|
||||
disabledCommands.append(", ");
|
||||
}
|
||||
disabledCommands.append(entry.getKey()).append(" => ").append(entry.getValue());
|
||||
}
|
||||
if (disabledCommands.length() > 0) {
|
||||
sender.sendMessage(tl("blockList"));
|
||||
sender.sendMessage(disabledCommands.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private void run_reset(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length < 2) {
|
||||
throw new Exception("/<command> reset <player>");
|
||||
}
|
||||
final User user = getPlayer(server, args, 1, true, true);
|
||||
user.reset();
|
||||
sender.sendMessage("Reset Essentials userdata for player: " + user.getDisplayName());
|
||||
}
|
||||
|
||||
private void run_debug(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
ess.getSettings().setDebug(!ess.getSettings().isDebug());
|
||||
sender.sendMessage("Essentials " + ess.getDescription().getVersion() + " debug mode " + (ess.getSettings().isDebug() ? "enabled" : "disabled"));
|
||||
}
|
||||
|
||||
private void run_reload(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
ess.reload();
|
||||
sender.sendMessage(tl("essentialsReload", ess.getDescription().getVersion()));
|
||||
}
|
||||
|
||||
private void run_nya(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
final Map<String, Float> noteMap = new HashMap<String, Float>();
|
||||
noteMap.put("1F#", 0.5f);
|
||||
noteMap.put("1G", 0.53f);
|
||||
noteMap.put("1G#", 0.56f);
|
||||
noteMap.put("1A", 0.6f);
|
||||
noteMap.put("1A#", 0.63f);
|
||||
noteMap.put("1B", 0.67f);
|
||||
noteMap.put("1C", 0.7f);
|
||||
noteMap.put("1C#", 0.76f);
|
||||
noteMap.put("1D", 0.8f);
|
||||
noteMap.put("1D#", 0.84f);
|
||||
noteMap.put("1E", 0.9f);
|
||||
noteMap.put("1F", 0.94f);
|
||||
noteMap.put("2F#", 1.0f);
|
||||
noteMap.put("2G", 1.06f);
|
||||
noteMap.put("2G#", 1.12f);
|
||||
noteMap.put("2A", 1.18f);
|
||||
noteMap.put("2A#", 1.26f);
|
||||
noteMap.put("2B", 1.34f);
|
||||
noteMap.put("2C", 1.42f);
|
||||
noteMap.put("2C#", 1.5f);
|
||||
noteMap.put("2D", 1.6f);
|
||||
noteMap.put("2D#", 1.68f);
|
||||
noteMap.put("2E", 1.78f);
|
||||
noteMap.put("2F", 1.88f);
|
||||
final String tuneStr = "1D#,1E,2F#,,2A#,1E,1D#,1E,2F#,2B,2D#,2E,2D#,2A#,2B,,2F#,,1D#,1E,2F#,2B,2C#,2A#,2B,2C#,2E,2D#,2E,2C#,,2F#,,2G#,,1D,1D#,,1C#,1D,1C#,1B,,1B,,1C#,,1D,,1D,1C#,1B,1C#,1D#,2F#,2G#,1D#,2F#,1C#,1D#,1B,1C#,1B,1D#,,2F#,,2G#,1D#,2F#,1C#,1D#,1B,1D,1D#,1D,1C#,1B,1C#,1D,,1B,1C#,1D#,2F#,1C#,1D,1C#,1B,1C#,,1B,,1C#,,2F#,,2G#,,1D,1D#,,1C#,1D,1C#,1B,,1B,,1C#,,1D,,1D,1C#,1B,1C#,1D#,2F#,2G#,1D#,2F#,1C#,1D#,1B,1C#,1B,1D#,,2F#,,2G#,1D#,2F#,1C#,1D#,1B,1D,1D#,1D,1C#,1B,1C#,1D,,1B,1C#,1D#,2F#,1C#,1D,1C#,1B,1C#,,1B,,1B,,1B,,1F#,1G#,1B,,1F#,1G#,1B,1C#,1D#,1B,1E,1D#,1E,2F#,1B,,1B,,1F#,1G#,1B,1E,1D#,1C#,1B,,,,1F#,1B,,1F#,1G#,1B,,1F#,1G#,1B,1B,1C#,1D#,1B,1F#,1G#,1F#,1B,,1B,1A#,1B,1F#,1G#,1B,1E,1D#,1E,2F#,1B,,1A#,,1B,,1F#,1G#,1B,,1F#,1G#,1B,1C#,1D#,1B,1E,1D#,1E,2F#,1B,,1B,,1F#,1G#,1B,1F#,1E,1D#,1C#,1B,,,,1F#,1B,,1F#,1G#,1B,,1F#,1G#,1B,1B,1C#,1D#,1B,1F#,1G#,1F#,1B,,1B,1A#,1B,1F#,1G#,1B,1E,1D#,1E,2F#,1B,,1A#,,1B,,1F#,1G#,1B,,1F#,1G#,1B,1C#,1D#,1B,1E,1D#,1E,2F#,1B,,1B,,1F#,1G#,1B,1F#,1E,1D#,1C#,1B,,,,1F#,1B,,1F#,1G#,1B,,1F#,1G#,1B,1B,1C#,1D#,1B,1F#,1G#,1F#,1B,,1B,1A#,1B,1F#,1G#,1B,1E,1D#,1E,2F#,1B,,1A#,,1B,,1F#,1G#,1B,,1F#,1G#,1B,1C#,1D#,1B,1E,1D#,1E,2F#,1B,,1B,,1F#,1G#,1B,1F#,1E,1D#,1C#,1B,,,,1F#,1B,,1F#,1G#,1B,,1F#,1G#,1B,1B,1C#,1D#,1B,1F#,1G#,1F#,1B,,1B,1A#,1B,1F#,1G#,1B,1E,1D#,1E,2F#,1B,,1A#,,1B,,1F#,1G#,1B,,1F#,1G#,1B,1C#,1D#,1B,1E,1D#,1E,2F#,1B,,1B,,1F#,1G#,1B,1F#,1E,1D#,1C#,1B,,,,1F#,1B,,1F#,1G#,1B,,1F#,1G#,1B,1B,1C#,1D#,1B,1F#,1G#,1F#,1B,,1B,1A#,1B,1F#,1G#,1B,1E,1D#,1E,2F#,1B,,1B,,";
|
||||
final String[] tune = tuneStr.split(",");
|
||||
taskid = ess.scheduleSyncRepeatingTask(new Runnable() {
|
||||
int i = 0;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
final String note = tune[i];
|
||||
i++;
|
||||
if (i >= tune.length) {
|
||||
Commandessentials.this.stopTune();
|
||||
}
|
||||
if (note == null || note.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Player onlinePlayer : ess.getOnlinePlayers()) {
|
||||
onlinePlayer.playSound(onlinePlayer.getLocation(), NOTE_HARP, 1, noteMap.get(note));
|
||||
}
|
||||
}
|
||||
}, 20, 2);
|
||||
}
|
||||
|
||||
private void stopTune() {
|
||||
ess.getScheduler().cancelTask(taskid);
|
||||
for (Block block : noteBlocks.values()) {
|
||||
if (block.getType() == Material.NOTE_BLOCK) {
|
||||
block.setType(Material.AIR);
|
||||
}
|
||||
}
|
||||
noteBlocks.clear();
|
||||
}
|
||||
|
||||
private final String[] consoleMoo = new String[]{" (__)", " (oo)", " /------\\/", " / | ||", " * /\\---/\\", " ~~ ~~", "....\"Have you mooed today?\"..."};
|
||||
private final String[] playerMoo = new String[]{" (__)", " (oo)", " /------\\/", " / | | |", " * /\\---/\\", " ~~ ~~", "....\"Have you mooed today?\"..."};
|
||||
|
||||
private void run_moo(final Server server, final CommandSource sender, final String command, final String args[]) {
|
||||
Sound moo = EnumUtil.valueOf(Sound.class, "COW_IDLE", "ENTITY_COW_MILK");
|
||||
|
||||
if (args.length == 2 && args[1].equals("moo")) {
|
||||
for (String s : consoleMoo) {
|
||||
logger.info(s);
|
||||
}
|
||||
for (Player player : ess.getOnlinePlayers()) {
|
||||
player.sendMessage(playerMoo);
|
||||
player.playSound(player.getLocation(), moo, 1, 1.0f);
|
||||
}
|
||||
} else {
|
||||
if (sender.isPlayer()) {
|
||||
sender.getSender().sendMessage(playerMoo);
|
||||
final Player player = sender.getPlayer();
|
||||
player.playSound(player.getLocation(), moo, 1, 1.0f);
|
||||
|
||||
} else {
|
||||
sender.getSender().sendMessage(consoleMoo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void run_cleanup(final Server server, final CommandSource sender, final String command, final String args[]) throws Exception {
|
||||
if (args.length < 2 || !NumberUtil.isInt(args[1])) {
|
||||
sender.sendMessage("This sub-command will delete users who havent logged in in the last <days> days.");
|
||||
sender.sendMessage("Optional parameters define the minium amount required to prevent deletion.");
|
||||
sender.sendMessage("Unless you define larger default values, this command wil ignore people who have more than 0 money/homes.");
|
||||
throw new Exception("/<command> cleanup <days> [money] [homes]");
|
||||
}
|
||||
sender.sendMessage(tl("cleaning"));
|
||||
|
||||
final long daysArg = Long.parseLong(args[1]);
|
||||
final double moneyArg = args.length >= 3 ? FloatUtil.parseDouble(args[2].replaceAll("[^0-9\\.]", "")) : 0;
|
||||
final int homesArg = args.length >= 4 && NumberUtil.isInt(args[3]) ? Integer.parseInt(args[3]) : 0;
|
||||
final UserMap userMap = ess.getUserMap();
|
||||
|
||||
ess.runTaskAsynchronously(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Long currTime = System.currentTimeMillis();
|
||||
for (UUID u : userMap.getAllUniqueUsers()) {
|
||||
final User user = ess.getUserMap().getUser(u);
|
||||
if (user == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
long lastLog = user.getLastLogout();
|
||||
if (lastLog == 0) {
|
||||
lastLog = user.getLastLogin();
|
||||
}
|
||||
if (lastLog == 0) {
|
||||
user.setLastLogin(currTime);
|
||||
}
|
||||
|
||||
if (user.isNPC()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
long timeDiff = currTime - lastLog;
|
||||
long milliDays = daysArg * 24L * 60L * 60L * 1000L;
|
||||
int homeCount = user.getHomes().size();
|
||||
double moneyCount = user.getMoney().doubleValue();
|
||||
|
||||
if ((lastLog == 0) || (timeDiff < milliDays) || (homeCount > homesArg) || (moneyCount > moneyArg)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().info("Deleting user: " + user.getName() + " Money: " + moneyCount + " Homes: " + homeCount + " Last seen: " + DateUtil.formatDateDiff(lastLog));
|
||||
}
|
||||
|
||||
user.reset();
|
||||
}
|
||||
sender.sendMessage(tl("cleaned"));
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void run_uuidconvert(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
sender.sendMessage("Starting Essentials UUID userdata conversion, this may lag the server.");
|
||||
|
||||
Boolean ignoreUFCache = (args.length > 2 && args[1].toLowerCase(Locale.ENGLISH).contains("ignore"));
|
||||
EssentialsUpgrade.uuidFileConvert(ess, ignoreUFCache);
|
||||
|
||||
sender.sendMessage("UUID conversion complete, check your server log for more information.");
|
||||
}
|
||||
|
||||
private void run_uuidtest(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length < 2) {
|
||||
throw new Exception("/<command> uuidtest <name>");
|
||||
}
|
||||
String name = args[1];
|
||||
sender.sendMessage("Looking up UUID for " + name);
|
||||
|
||||
UUID onlineUUID = null;
|
||||
|
||||
for (Player player : ess.getOnlinePlayers()) {
|
||||
if (player.getName().equalsIgnoreCase(name)) {
|
||||
onlineUUID = player.getUniqueId();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
UUID essUUID = ess.getUserMap().getUser(name).getConfigUUID();
|
||||
|
||||
org.bukkit.OfflinePlayer player = ess.getServer().getOfflinePlayer(name);
|
||||
UUID bukkituuid = player.getUniqueId();
|
||||
sender.sendMessage("Bukkit Lookup: " + bukkituuid.toString());
|
||||
|
||||
if (onlineUUID != null && onlineUUID != bukkituuid) {
|
||||
sender.sendMessage("Online player: " + onlineUUID.toString());
|
||||
}
|
||||
|
||||
if (essUUID != null && essUUID != bukkituuid) {
|
||||
sender.sendMessage("Essentials config: " + essUUID.toString());
|
||||
}
|
||||
|
||||
UUID npcuuid = UUID.nameUUIDFromBytes(("NPC:" + name).getBytes(Charsets.UTF_8));
|
||||
sender.sendMessage("NPC UUID: " + npcuuid.toString());
|
||||
|
||||
UUID offlineuuid = UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(Charsets.UTF_8));
|
||||
sender.sendMessage("Offline Mode UUID: " + offlineuuid.toString());
|
||||
}
|
||||
|
||||
private void run_version(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
if (sender.isPlayer() && !ess.getUser(sender.getPlayer()).isAuthorized("essentials.version")) return;
|
||||
|
||||
boolean isMismatched = false;
|
||||
boolean isVaultInstalled = false;
|
||||
boolean isUnsupported = false;
|
||||
final boolean isServerSupported = VersionUtil.isServerSupported();
|
||||
final PluginManager pm = server.getPluginManager();
|
||||
final String essVer = pm.getPlugin("Essentials").getDescription().getVersion();
|
||||
|
||||
sender.sendMessage(tl(isServerSupported ? "versionOutputFine" : "versionOutputWarn", "Server", server.getBukkitVersion() + " " + server.getVersion()));
|
||||
sender.sendMessage(tl("versionOutputFine", "EssentialsX", essVer));
|
||||
|
||||
for (Plugin plugin : pm.getPlugins()) {
|
||||
final PluginDescriptionFile desc = plugin.getDescription();
|
||||
String name = desc.getName();
|
||||
String version = desc.getVersion();
|
||||
|
||||
if (name.startsWith("Essentials") && !name.equalsIgnoreCase("Essentials")) {
|
||||
if (officialPlugins.contains(name)) {
|
||||
name = name.replace("Essentials", "EssentialsX");
|
||||
|
||||
if (!version.equalsIgnoreCase(essVer)) {
|
||||
isMismatched = true;
|
||||
sender.sendMessage(tl("versionOutputWarn", name, version));
|
||||
} else {
|
||||
sender.sendMessage(tl("versionOutputFine", name, version));
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage(tl("versionOutputUnsupported", name, version));
|
||||
isUnsupported = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (versionPlugins.contains(name)) {
|
||||
if (warnPlugins.contains(name)) {
|
||||
sender.sendMessage(tl("versionOutputUnsupported", name, version));
|
||||
isUnsupported = true;
|
||||
} else {
|
||||
sender.sendMessage(tl("versionOutputFine", name, version));
|
||||
}
|
||||
}
|
||||
|
||||
if (name.equals("Vault")) isVaultInstalled = true;
|
||||
}
|
||||
|
||||
if (isMismatched) {
|
||||
sender.sendMessage(tl("versionMismatchAll"));
|
||||
}
|
||||
|
||||
if (!isVaultInstalled) {
|
||||
sender.sendMessage(tl("versionOutputVaultMissing"));
|
||||
}
|
||||
|
||||
if (isUnsupported) {
|
||||
sender.sendMessage(tl("versionOutputUnsupportedPlugins"));
|
||||
}
|
||||
|
||||
if (!VersionUtil.isServerSupported()) {
|
||||
sender.sendMessage(tl("serverUnsupported"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
List<String> options = Lists.newArrayList();
|
||||
options.add("reload");
|
||||
options.add("debug");
|
||||
//options.add("nya");
|
||||
//options.add("moo");
|
||||
options.add("reset");
|
||||
options.add("cleanup");
|
||||
//options.add("uuidconvert");
|
||||
//options.add("uuidtest");
|
||||
options.add("version");
|
||||
return options;
|
||||
} else if (args[0].equalsIgnoreCase("debug")) {
|
||||
// No args
|
||||
} else if (args[0].equalsIgnoreCase("nya")) {
|
||||
// No args
|
||||
} else if (args[0].equalsIgnoreCase("moo")) {
|
||||
if (args.length == 2) {
|
||||
return Lists.newArrayList("moo");
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("reset")) {
|
||||
if (args.length == 2) {
|
||||
return getPlayers(server, sender);
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("cleanup")) {
|
||||
if (args.length == 2) {
|
||||
return COMMON_DURATIONS;
|
||||
} else if (args.length == 3 || args.length == 4) {
|
||||
return Lists.newArrayList("-1", "0");
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("uuidconvert")) {
|
||||
if (args.length == 2) {
|
||||
return Lists.newArrayList("ignoreUFCache");
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("uuidtest")) {
|
||||
if (args.length == 2) {
|
||||
return getPlayers(server, sender);
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("version")) {
|
||||
// No args
|
||||
} else {
|
||||
// No args
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
@@ -1,223 +0,0 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.craftbukkit.SetExpFix;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandexp extends EssentialsCommand {
|
||||
public Commandexp() {
|
||||
super("exp");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length == 0) {
|
||||
showExp(user.getSource(), user);
|
||||
} else if (args.length > 1 && args[0].equalsIgnoreCase("set") && user.isAuthorized("essentials.exp.set")) {
|
||||
if (args.length == 3 && user.isAuthorized("essentials.exp.set.others")) {
|
||||
expMatch(server, user.getSource(), args[1], args[2], false);
|
||||
} else {
|
||||
setExp(user.getSource(), user, args[1], false);
|
||||
}
|
||||
} else if (args.length > 1 && args[0].equalsIgnoreCase("give") && user.isAuthorized("essentials.exp.give")) {
|
||||
if (args.length == 3 && user.isAuthorized("essentials.exp.give.others")) {
|
||||
expMatch(server, user.getSource(), args[1], args[2], true);
|
||||
} else {
|
||||
setExp(user.getSource(), user, args[1], true);
|
||||
}
|
||||
} else if (args.length > 1 && args[0].equalsIgnoreCase("take") && user.isAuthorized("essentials.exp.take")) {
|
||||
if (args.length == 3 && user.isAuthorized("essentials.exp.take.others")) {
|
||||
expMatch(server, user.getSource(), args[1], "-" + args[2], true);
|
||||
} else {
|
||||
setExp(user.getSource(), user, "-" + args[1], true);
|
||||
}
|
||||
} else if (args.length < 3 && args[0].equalsIgnoreCase("reset") && user.isAuthorized("essentials.exp.reset")) {
|
||||
if (args.length == 2 && user.isAuthorized("essentials.exp.reset.others")) {
|
||||
expMatch(server, user.getSource(), args[1], "0", false);
|
||||
} else {
|
||||
setExp(user.getSource(), user, "0", false);
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("show")) {
|
||||
if (args.length >= 2 && user.isAuthorized("essentials.exp.others")) {
|
||||
String match = args[1].trim();
|
||||
showMatch(server, user.getSource(), match);
|
||||
} else {
|
||||
showExp(user.getSource(), user);
|
||||
}
|
||||
} else {
|
||||
if (args.length >= 1 && NumberUtil.isInt(args[0].toLowerCase(Locale.ENGLISH).replace("l", "")) && user.isAuthorized("essentials.exp.give")) {
|
||||
if (args.length >= 2 && user.isAuthorized("essentials.exp.give.others")) {
|
||||
expMatch(server, user.getSource(), args[1], args[0], true);
|
||||
} else {
|
||||
setExp(user.getSource(), user, args[0], true);
|
||||
}
|
||||
} else if (args.length >= 1 && user.isAuthorized("essentials.exp.others")) {
|
||||
String match = args[0].trim();
|
||||
showMatch(server, user.getSource(), match);
|
||||
} else {
|
||||
showExp(user.getSource(), user);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length < 1) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
} else if (args.length > 2 && args[0].equalsIgnoreCase("set")) {
|
||||
expMatch(server, sender, args[1], args[2], false);
|
||||
} else if (args.length > 2 && args[0].equalsIgnoreCase("give")) {
|
||||
expMatch(server, sender, args[1], args[2], true);
|
||||
} else {
|
||||
String match = args[0].trim();
|
||||
if (args.length >= 2 && NumberUtil.isInt(args[0].toLowerCase(Locale.ENGLISH).replace("l", ""))) {
|
||||
match = args[1].trim();
|
||||
expMatch(server, sender, match, args[0], true);
|
||||
} else if (args.length == 1) {
|
||||
match = args[0].trim();
|
||||
}
|
||||
showMatch(server, sender, match);
|
||||
}
|
||||
}
|
||||
|
||||
private void showMatch(final Server server, final CommandSource sender, final String match) throws PlayerNotFoundException {
|
||||
boolean skipHidden = sender.isPlayer() && !ess.getUser(sender.getPlayer()).canInteractVanished();
|
||||
boolean foundUser = false;
|
||||
final List<Player> matchedPlayers = server.matchPlayer(match);
|
||||
for (Player matchPlayer : matchedPlayers) {
|
||||
final User player = ess.getUser(matchPlayer);
|
||||
if (skipHidden && player.isHidden(sender.getPlayer()) && !sender.getPlayer().canSee(matchPlayer)) {
|
||||
continue;
|
||||
}
|
||||
foundUser = true;
|
||||
showExp(sender, player);
|
||||
}
|
||||
if (!foundUser) {
|
||||
throw new PlayerNotFoundException();
|
||||
}
|
||||
}
|
||||
|
||||
private void expMatch(final Server server, final CommandSource sender, final String match, String amount, final boolean give) throws NotEnoughArgumentsException, PlayerNotFoundException {
|
||||
boolean skipHidden = sender.isPlayer() && !ess.getUser(sender.getPlayer()).canInteractVanished();
|
||||
boolean foundUser = false;
|
||||
final List<Player> matchedPlayers = server.matchPlayer(match);
|
||||
for (Player matchPlayer : matchedPlayers) {
|
||||
final User player = ess.getUser(matchPlayer);
|
||||
if (skipHidden && player.isHidden(sender.getPlayer()) && !sender.getPlayer().canSee(matchPlayer)) {
|
||||
continue;
|
||||
}
|
||||
foundUser = true;
|
||||
setExp(sender, player, amount, give);
|
||||
}
|
||||
if (!foundUser) {
|
||||
throw new PlayerNotFoundException();
|
||||
}
|
||||
}
|
||||
|
||||
private void showExp(final CommandSource sender, final User target) {
|
||||
sender.sendMessage(tl("exp", target.getDisplayName(), SetExpFix.getTotalExperience(target.getBase()), target.getBase().getLevel(), SetExpFix.getExpUntilNextLevel(target.getBase())));
|
||||
}
|
||||
|
||||
//TODO: Limit who can give negative exp?
|
||||
private void setExp(final CommandSource sender, final User target, String strAmount, final boolean give) throws NotEnoughArgumentsException {
|
||||
long amount;
|
||||
strAmount = strAmount.toLowerCase(Locale.ENGLISH);
|
||||
if (strAmount.contains("l")) {
|
||||
strAmount = strAmount.replaceAll("l", "");
|
||||
int neededLevel = Integer.parseInt(strAmount);
|
||||
if (give) {
|
||||
neededLevel += target.getBase().getLevel();
|
||||
}
|
||||
amount = (long) SetExpFix.getExpToLevel(neededLevel);
|
||||
SetExpFix.setTotalExperience(target.getBase(), 0);
|
||||
} else {
|
||||
amount = Long.parseLong(strAmount);
|
||||
if (amount > Integer.MAX_VALUE || amount < Integer.MIN_VALUE) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
}
|
||||
|
||||
if (give) {
|
||||
amount += SetExpFix.getTotalExperience(target.getBase());
|
||||
}
|
||||
if (amount > Integer.MAX_VALUE) {
|
||||
amount = (long) Integer.MAX_VALUE;
|
||||
}
|
||||
if (amount < 0l) {
|
||||
amount = 0l;
|
||||
}
|
||||
SetExpFix.setTotalExperience(target.getBase(), (int) amount);
|
||||
sender.sendMessage(tl("expSet", target.getDisplayName(), amount));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
List<String> options = Lists.newArrayList("show");
|
||||
if (user.isAuthorized("essentials.exp.set")) {
|
||||
options.add("set");
|
||||
}
|
||||
if (user.isAuthorized("essentials.exp.give")) {
|
||||
options.add("give");
|
||||
}
|
||||
if (user.isAuthorized("essentials.exp.take")) {
|
||||
options.add("take");
|
||||
}
|
||||
if (user.isAuthorized("essentials.exp.reset")) {
|
||||
options.add("reset");
|
||||
}
|
||||
return options;
|
||||
} else if (args.length == 2) {
|
||||
if ((args[0].equalsIgnoreCase("set") && user.isAuthorized("essentials.exp.set")) || (args[0].equalsIgnoreCase("give") && user.isAuthorized("essentials.exp.give"))) {
|
||||
String levellessArg = args[1].toLowerCase(Locale.ENGLISH).replace("l", "");
|
||||
if (NumberUtil.isInt(levellessArg)) {
|
||||
return Lists.newArrayList(levellessArg, args[1] + "l");
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("show") && user.isAuthorized("essentials.exp.others")) {
|
||||
return getPlayers(server, user);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
} else if (args.length == 3 && (args[0].equalsIgnoreCase("set") && user.isAuthorized("essentials.exp.set.others")) || (args[0].equalsIgnoreCase("give") && user.isAuthorized("essentials.exp.give.others"))) {
|
||||
return getPlayers(server, user);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
// TODO: This seems somewhat buggy, both setting and showing - right now, ignoring that
|
||||
return Lists.newArrayList("set", "give", "show", "take", "reset");
|
||||
} else if (args.length == 2) {
|
||||
if (args[0].equalsIgnoreCase("set") || args[0].equalsIgnoreCase("give")) {
|
||||
String levellessArg = args[1].toLowerCase(Locale.ENGLISH).replace("l", "");
|
||||
if (NumberUtil.isInt(levellessArg)) {
|
||||
return Lists.newArrayList(levellessArg, args[1] + "l");
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
} else { // even without 'show'
|
||||
return getPlayers(server, sender);
|
||||
}
|
||||
} else if (args.length == 3 && (args[0].equalsIgnoreCase("set") || args[0].equalsIgnoreCase("give"))) {
|
||||
return getPlayers(server, sender);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.User;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class Commandfireball extends EssentialsCommand {
|
||||
public Commandfireball() {
|
||||
super("fireball");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
Class<? extends Entity> type = Fireball.class;
|
||||
Projectile projectile;
|
||||
int speed = 2;
|
||||
if (args.length > 0) {
|
||||
if (args[0].equalsIgnoreCase("small")) {
|
||||
type = SmallFireball.class;
|
||||
} else if (args[0].equalsIgnoreCase("arrow")) {
|
||||
type = Arrow.class;
|
||||
} else if (args[0].equalsIgnoreCase("skull")) {
|
||||
type = WitherSkull.class;
|
||||
} else if (args[0].equalsIgnoreCase("egg")) {
|
||||
type = Egg.class;
|
||||
} else if (args[0].equalsIgnoreCase("snowball")) {
|
||||
type = Snowball.class;
|
||||
} else if (args[0].equalsIgnoreCase("expbottle")) {
|
||||
type = ThrownExpBottle.class;
|
||||
} else if (args[0].equalsIgnoreCase("large")) {
|
||||
type = LargeFireball.class;
|
||||
} else if (args[0].equalsIgnoreCase("splashpotion")) {
|
||||
type = SplashPotion.class;
|
||||
} else if (args[0].equalsIgnoreCase("lingeringpotion")) {
|
||||
type = LingeringPotion.class;
|
||||
}
|
||||
}
|
||||
final Vector direction = user.getBase().getEyeLocation().getDirection().multiply(speed);
|
||||
projectile = (Projectile) user.getWorld().spawn(user.getBase().getEyeLocation().add(direction.getX(), direction.getY(), direction.getZ()), type);
|
||||
projectile.setShooter(user.getBase());
|
||||
projectile.setVelocity(direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
return Lists.newArrayList("small", "arrow", "skull", "egg", "snowball", "expbottle", "large", "splashpotion", "lingeringpotion");
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,178 +0,0 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.MetaItemStack;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.MaterialUtil;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.FireworkEffect;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Firework;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.FireworkMeta;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
//This command has quite a complicated syntax, in theory it has 4 seperate syntaxes which are all variable:
|
||||
//
|
||||
//1: /firework clear - This clears all of the effects on a firework stack
|
||||
//
|
||||
//2: /firework power <int> - This changes the base power of a firework
|
||||
//
|
||||
//3: /firework fire - This 'fires' a copy of the firework held.
|
||||
//3: /firework fire <int> - This 'fires' a number of copies of the firework held.
|
||||
//3: /firework fire <other> - This 'fires' a copy of the firework held, in the direction you are looking, #easteregg
|
||||
//
|
||||
//4: /firework [meta] - This will add an effect to the firework stack held
|
||||
//4: /firework color:<color> - The minimum you need to set an effect is 'color'
|
||||
//4: Full Syntax: color:<color[,color,..]> [fade:<color[,color,..]>] [shape:<shape>] [effect:<effect[,effect]>]
|
||||
//4: Possible Shapes: star, ball, large, creeper, burst
|
||||
//4: Possible Effects trail, twinkle
|
||||
|
||||
public class Commandfirework extends EssentialsCommand {
|
||||
|
||||
public Commandfirework() {
|
||||
super("firework");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
final ItemStack stack = user.getItemInHand();
|
||||
if (MaterialUtil.isFirework(stack.getType())) {
|
||||
if (args.length > 0) {
|
||||
if (args[0].equalsIgnoreCase("clear")) {
|
||||
FireworkMeta fmeta = (FireworkMeta) stack.getItemMeta();
|
||||
fmeta.clearEffects();
|
||||
stack.setItemMeta(fmeta);
|
||||
user.sendMessage(tl("fireworkEffectsCleared"));
|
||||
} else if (args.length > 1 && (args[0].equalsIgnoreCase("power") || (args[0].equalsIgnoreCase("p")))) {
|
||||
FireworkMeta fmeta = (FireworkMeta) stack.getItemMeta();
|
||||
try {
|
||||
int power = Integer.parseInt(args[1]);
|
||||
fmeta.setPower(power > 3 ? 4 : power);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new Exception(tl("invalidFireworkFormat", args[1], args[0]));
|
||||
}
|
||||
stack.setItemMeta(fmeta);
|
||||
} else if ((args[0].equalsIgnoreCase("fire") || (args[0].equalsIgnoreCase("f"))) && user.isAuthorized("essentials.firework.fire")) {
|
||||
int amount = 1;
|
||||
boolean direction = false;
|
||||
if (args.length > 1) {
|
||||
if (NumberUtil.isInt(args[1])) {
|
||||
final int serverLimit = ess.getSettings().getSpawnMobLimit();
|
||||
amount = Integer.parseInt(args[1]);
|
||||
if (amount > serverLimit) {
|
||||
amount = serverLimit;
|
||||
user.sendMessage(tl("mobSpawnLimit"));
|
||||
}
|
||||
} else {
|
||||
direction = true;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < amount; i++) {
|
||||
Firework firework = (Firework) user.getWorld().spawnEntity(user.getLocation(), EntityType.FIREWORK);
|
||||
FireworkMeta fmeta = (FireworkMeta) stack.getItemMeta();
|
||||
if (direction) {
|
||||
final Vector vector = user.getBase().getEyeLocation().getDirection().multiply(0.070);
|
||||
if (fmeta.getPower() > 1) {
|
||||
fmeta.setPower(1);
|
||||
}
|
||||
firework.setVelocity(vector);
|
||||
}
|
||||
firework.setFireworkMeta(fmeta);
|
||||
}
|
||||
} else {
|
||||
final MetaItemStack mStack = new MetaItemStack(stack);
|
||||
for (String arg : args) {
|
||||
try {
|
||||
mStack.addFireworkMeta(user.getSource(), true, arg, ess);
|
||||
} catch (Exception e) {
|
||||
user.sendMessage(tl("fireworkSyntax"));
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
if (mStack.isValidFirework()) {
|
||||
FireworkMeta fmeta = (FireworkMeta) mStack.getItemStack().getItemMeta();
|
||||
FireworkEffect effect = mStack.getFireworkBuilder().build();
|
||||
if (fmeta.getEffects().size() > 0 && !user.isAuthorized("essentials.firework.multiple")) {
|
||||
throw new Exception(tl("multipleCharges"));
|
||||
}
|
||||
fmeta.addEffect(effect);
|
||||
stack.setItemMeta(fmeta);
|
||||
} else {
|
||||
user.sendMessage(tl("fireworkSyntax"));
|
||||
throw new Exception(tl("fireworkColor"));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
} else {
|
||||
throw new Exception(tl("holdFirework"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, User user, String commandLabel, String[] args) {
|
||||
// Note: this enforces an order of color fade shape effect, which the actual command doesn't have. But that's fine.
|
||||
if (args.length == 1) {
|
||||
List<String> options = Lists.newArrayList();
|
||||
if (args[0].startsWith("color:")) {
|
||||
String prefix;
|
||||
if (args[0].contains(",")) {
|
||||
prefix = args[0].substring(0, args[0].lastIndexOf(',') + 1);
|
||||
} else {
|
||||
prefix = "color:";
|
||||
}
|
||||
for (DyeColor color : DyeColor.values()) {
|
||||
options.add(prefix + color.name().toLowerCase() + ",");
|
||||
}
|
||||
return options;
|
||||
}
|
||||
options.add("clear");
|
||||
options.add("power");
|
||||
options.add("color:");
|
||||
if (user.isAuthorized("essentials.firework.fire")) {
|
||||
options.add("fire");
|
||||
}
|
||||
return options;
|
||||
} else if (args.length == 2) {
|
||||
if (args[0].equals("power")) {
|
||||
return Lists.newArrayList("1", "2", "3", "4");
|
||||
} else if (args[0].equals("fire")) {
|
||||
return Lists.newArrayList("1");
|
||||
} else if (args[0].startsWith("color:")) {
|
||||
List<String> options = Lists.newArrayList();
|
||||
if (!args[1].startsWith("fade:")) {
|
||||
args[1] = "fade:";
|
||||
}
|
||||
String prefix;
|
||||
if (args[1].contains(",")) {
|
||||
prefix = args[1].substring(0, args[1].lastIndexOf(',') + 1);
|
||||
} else {
|
||||
prefix = "fade:";
|
||||
}
|
||||
for (DyeColor color : DyeColor.values()) {
|
||||
options.add(prefix + color.name().toLowerCase() + ",");
|
||||
}
|
||||
return options;
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
} else if (args.length == 3 && args[0].startsWith("color:")) {
|
||||
return Lists.newArrayList("shape:star", "shape:ball", "shape:large", "shape:creeper", "shape:burst");
|
||||
} else if (args.length == 4 && args[0].startsWith("color:")) {
|
||||
return Lists.newArrayList("effect:trail", "effect:twinkle", "effect:trail,twinkle", "effect:twinkle,trail");
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.craftbukkit.InventoryWorkaround;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandhat extends EssentialsCommand {
|
||||
public Commandhat() {
|
||||
super("hat");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length > 0 && (args[0].contains("rem") || args[0].contains("off") || args[0].equalsIgnoreCase("0"))) {
|
||||
final PlayerInventory inv = user.getBase().getInventory();
|
||||
final ItemStack head = inv.getHelmet();
|
||||
if (head == null || head.getType() == Material.AIR) {
|
||||
user.sendMessage(tl("hatEmpty"));
|
||||
} else {
|
||||
final ItemStack air = new ItemStack(Material.AIR);
|
||||
inv.setHelmet(air);
|
||||
InventoryWorkaround.addItems(user.getBase().getInventory(), head);
|
||||
user.sendMessage(tl("hatRemoved"));
|
||||
}
|
||||
} else {
|
||||
final ItemStack hand = user.getItemInHand();
|
||||
if (hand != null && hand.getType() != Material.AIR) {
|
||||
if (hand.getType().getMaxDurability() == 0) {
|
||||
final PlayerInventory inv = user.getBase().getInventory();
|
||||
final ItemStack head = inv.getHelmet();
|
||||
inv.setHelmet(hand);
|
||||
inv.setItemInHand(head);
|
||||
user.sendMessage(tl("hatPlaced"));
|
||||
} else {
|
||||
user.sendMessage(tl("hatArmor"));
|
||||
}
|
||||
} else {
|
||||
user.sendMessage(tl("hatFail"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
return Lists.newArrayList("remove", "wear"); // "wear" isn't real
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,100 +0,0 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.entity.EntityRegainHealthEvent;
|
||||
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandheal extends EssentialsLoopCommand {
|
||||
public Commandheal() {
|
||||
super("heal");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
if (!user.isAuthorized("essentials.heal.cooldown.bypass")) {
|
||||
user.healCooldown();
|
||||
}
|
||||
|
||||
if (args.length > 0 && user.isAuthorized("essentials.heal.others")) {
|
||||
loopOnlinePlayers(server, user.getSource(), true, true, args[0], null);
|
||||
return;
|
||||
}
|
||||
|
||||
healPlayer(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length < 1) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
loopOnlinePlayers(server, sender, true, true, args[0], null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updatePlayer(final Server server, final CommandSource sender, final User player, final String[] args) throws PlayerExemptException {
|
||||
try {
|
||||
healPlayer(player);
|
||||
sender.sendMessage(tl("healOther", player.getDisplayName()));
|
||||
} catch (QuietAbortException e) {
|
||||
//Handle Quietly
|
||||
}
|
||||
}
|
||||
|
||||
private void healPlayer(final User user) throws PlayerExemptException, QuietAbortException {
|
||||
final Player player = user.getBase();
|
||||
|
||||
if (player.getHealth() == 0) {
|
||||
throw new PlayerExemptException(tl("healDead"));
|
||||
}
|
||||
|
||||
final double amount = player.getMaxHealth() - player.getHealth();
|
||||
final EntityRegainHealthEvent erhe = new EntityRegainHealthEvent(player, amount, RegainReason.CUSTOM);
|
||||
ess.getServer().getPluginManager().callEvent(erhe);
|
||||
if (erhe.isCancelled()) {
|
||||
throw new QuietAbortException();
|
||||
}
|
||||
|
||||
double newAmount = player.getHealth() + erhe.getAmount();
|
||||
if (newAmount > player.getMaxHealth()) {
|
||||
newAmount = player.getMaxHealth();
|
||||
}
|
||||
|
||||
player.setHealth(newAmount);
|
||||
player.setFoodLevel(20);
|
||||
player.setFireTicks(0);
|
||||
user.sendMessage(tl("heal"));
|
||||
for (PotionEffect effect : player.getActivePotionEffects()) {
|
||||
player.removePotionEffect(effect.getType());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, User user, String commandLabel, String[] args) {
|
||||
if (args.length == 1 && user.isAuthorized("essentials.heal.others")) {
|
||||
return getPlayers(server, user);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, CommandSource sender, String commandLabel, String[] args) {
|
||||
if (args.length == 1) {
|
||||
return getPlayers(server, sender);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.textreader.*;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandhelp extends EssentialsCommand {
|
||||
public Commandhelp() {
|
||||
super("help");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
IText output;
|
||||
String pageStr = args.length > 0 ? args[0] : null;
|
||||
String chapterPageStr = args.length > 1 ? args[1] : null;
|
||||
String command = commandLabel;
|
||||
final IText input = new TextInput(user.getSource(), "help", false, ess);
|
||||
|
||||
if (input.getLines().isEmpty()) {
|
||||
if (NumberUtil.isInt(pageStr) || pageStr == null) {
|
||||
output = new HelpInput(user, "", ess);
|
||||
} else {
|
||||
if (pageStr.length() > 26) {
|
||||
pageStr = pageStr.substring(0, 25);
|
||||
}
|
||||
output = new HelpInput(user, pageStr.toLowerCase(Locale.ENGLISH), ess);
|
||||
command = command.concat(" ").concat(pageStr);
|
||||
pageStr = chapterPageStr;
|
||||
}
|
||||
chapterPageStr = null;
|
||||
} else {
|
||||
user.setDisplayNick();
|
||||
output = new KeywordReplacer(input, user.getSource(), ess);
|
||||
}
|
||||
final TextPager pager = new TextPager(output);
|
||||
pager.showPage(pageStr, chapterPageStr, command, user.getSource());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
sender.sendMessage(tl("helpConsole"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, CommandSource sender, String commandLabel, String[] args) {
|
||||
if (args.length == 1) {
|
||||
return getCommands(server);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.Trade;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandhome extends EssentialsCommand {
|
||||
public Commandhome() {
|
||||
super("home");
|
||||
}
|
||||
|
||||
// This method contains an undocumented translation parameters #EasterEgg
|
||||
@Override
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
final Trade charge = new Trade(this.getName(), ess);
|
||||
User player = user;
|
||||
String homeName = "";
|
||||
String[] nameParts;
|
||||
if (args.length > 0) {
|
||||
nameParts = args[0].split(":");
|
||||
if (nameParts[0].length() == args[0].length() || !user.isAuthorized("essentials.home.others")) {
|
||||
homeName = nameParts[0];
|
||||
} else {
|
||||
player = getPlayer(server, nameParts, 0, true, true);
|
||||
if (nameParts.length > 1) {
|
||||
homeName = nameParts[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
if ("bed".equalsIgnoreCase(homeName) && user.isAuthorized("essentials.home.bed")) {
|
||||
final Location bed = player.getBase().getBedSpawnLocation();
|
||||
if (bed != null) {
|
||||
user.getTeleport().teleport(bed, charge, TeleportCause.COMMAND);
|
||||
throw new NoChargeException();
|
||||
} else {
|
||||
throw new Exception(tl("bedMissing"));
|
||||
}
|
||||
}
|
||||
goHome(user, player, homeName.toLowerCase(Locale.ENGLISH), charge);
|
||||
} catch (NotEnoughArgumentsException e) {
|
||||
Location bed = player.getBase().getBedSpawnLocation();
|
||||
final List<String> homes = player.getHomes();
|
||||
if (homes.isEmpty() && player.equals(user)) {
|
||||
user.getTeleport().respawn(charge, TeleportCause.COMMAND);
|
||||
} else if (homes.isEmpty()) {
|
||||
throw new Exception(tl("noHomeSetPlayer"));
|
||||
} else if (homes.size() == 1 && player.equals(user)) {
|
||||
goHome(user, player, homes.get(0), charge);
|
||||
} else {
|
||||
final int count = homes.size();
|
||||
if (user.isAuthorized("essentials.home.bed")) {
|
||||
if (bed != null) {
|
||||
homes.add(tl("bed"));
|
||||
} else {
|
||||
homes.add(tl("bedNull"));
|
||||
}
|
||||
}
|
||||
user.sendMessage(tl("homes", StringUtil.joinList(homes), count, getHomeLimit(player)));
|
||||
}
|
||||
}
|
||||
throw new NoChargeException();
|
||||
}
|
||||
|
||||
private String getHomeLimit(final User player) {
|
||||
if (!player.getBase().isOnline()) {
|
||||
return "?";
|
||||
}
|
||||
if (player.isAuthorized("essentials.sethome.multiple.unlimited")) {
|
||||
return "*";
|
||||
}
|
||||
return Integer.toString(ess.getSettings().getHomeLimit(player));
|
||||
}
|
||||
|
||||
private void goHome(final User user, final User player, final String home, final Trade charge) throws Exception {
|
||||
if (home.length() < 1) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
final Location loc = player.getHome(home);
|
||||
if (loc == null) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
if (user.getWorld() != loc.getWorld() && ess.getSettings().isWorldHomePermissions() && !user.isAuthorized("essentials.worlds." + loc.getWorld().getName())) {
|
||||
throw new Exception(tl("noPerm", "essentials.worlds." + loc.getWorld().getName()));
|
||||
}
|
||||
user.getTeleport().teleport(loc, charge, TeleportCause.COMMAND);
|
||||
user.sendMessage(tl("teleportHome", home));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
|
||||
boolean canVisitOthers = user.isAuthorized("essentials.home.others");
|
||||
|
||||
if (args.length == 1) {
|
||||
if (canVisitOthers) {
|
||||
return getPlayers(server, user);
|
||||
} else {
|
||||
List<String> homes = user.getHomes();
|
||||
if (user.isAuthorized("essentials.home.bed")) {
|
||||
homes.add("bed");
|
||||
}
|
||||
return homes;
|
||||
}
|
||||
} else if (args.length == 2 && canVisitOthers) {
|
||||
try {
|
||||
User otherUser = getPlayer(server, args, 0, true, true);
|
||||
List<String> homes = otherUser.getHomes();
|
||||
if (user.isAuthorized("essentials.home.bed")) {
|
||||
homes.add("bed");
|
||||
}
|
||||
return homes;
|
||||
} catch (Exception ex) {
|
||||
// No such user
|
||||
return Collections.emptyList();
|
||||
}
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.User;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandignore extends EssentialsCommand {
|
||||
public Commandignore() {
|
||||
super("ignore");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length < 1) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String s : user._getIgnoredPlayers()) {
|
||||
sb.append(s).append(" ");
|
||||
}
|
||||
String ignoredList = sb.toString().trim();
|
||||
user.sendMessage(ignoredList.length() > 0 ? tl("ignoredList", ignoredList) : tl("noIgnored"));
|
||||
} else {
|
||||
User player;
|
||||
try {
|
||||
player = getPlayer(server, args, 0, true, true);
|
||||
} catch (PlayerNotFoundException ex) {
|
||||
player = ess.getOfflineUser(args[0]);
|
||||
}
|
||||
if (player == null) {
|
||||
throw new PlayerNotFoundException();
|
||||
}
|
||||
if (player.isIgnoreExempt()) {
|
||||
user.sendMessage(tl("ignoreExempt"));
|
||||
} else if (user.isIgnoredPlayer(player)) {
|
||||
user.setIgnoredPlayer(player, false);
|
||||
user.sendMessage(tl("unignorePlayer", player.getName()));
|
||||
} else {
|
||||
user.setIgnoredPlayer(player, true);
|
||||
user.sendMessage(tl("ignorePlayer", player.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, User user, String commandLabel, String[] args) {
|
||||
if (args.length == 1) {
|
||||
return getPlayers(server, user);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.I18n;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.FormatUtil;
|
||||
|
||||
import com.earth2me.essentials.utils.MaterialUtil;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class Commanditemname extends EssentialsCommand {
|
||||
|
||||
public Commanditemname() {
|
||||
super("itemname");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run(Server server, User user, String commandLabel, String[] args) throws Exception {
|
||||
ItemStack item = user.getBase().getItemInHand();
|
||||
if (item.getType().name().contains("AIR")) {
|
||||
user.sendMessage(tl("itemnameInvalidItem", item.getType().toString().toLowerCase(Locale.ENGLISH).replace('_', ' ')));
|
||||
return;
|
||||
}
|
||||
|
||||
String name = FormatUtil.formatString(user, "essentials.itemname", getFinalArg(args, 0)).trim();
|
||||
if (name.isEmpty()) name = null;
|
||||
|
||||
ItemMeta im = item.getItemMeta();
|
||||
im.setDisplayName(name);
|
||||
item.setItemMeta(im);
|
||||
user.sendMessage(name == null ? tl("itemnameClear") : tl("itemnameSuccess", name));
|
||||
}
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.PlayerList;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.FormatUtil;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandlist extends EssentialsCommand {
|
||||
public Commandlist() {
|
||||
super("list");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
boolean showHidden = true;
|
||||
User user = null;
|
||||
if (sender.isPlayer()) {
|
||||
user = ess.getUser(sender.getPlayer());
|
||||
showHidden = user.isAuthorized("essentials.list.hidden") || user.canInteractVanished();
|
||||
}
|
||||
sender.sendMessage(PlayerList.listSummary(ess, user, showHidden));
|
||||
final Map<String, List<User>> playerList = PlayerList.getPlayerLists(ess, user, showHidden);
|
||||
|
||||
if (args.length > 0) {
|
||||
sender.sendMessage(PlayerList.listGroupUsers(ess, playerList, args[0].toLowerCase()));
|
||||
} else {
|
||||
sendGroupedList(sender, commandLabel, playerList);
|
||||
}
|
||||
}
|
||||
|
||||
// Output the standard /list output, when no group is specified
|
||||
private void sendGroupedList(CommandSource sender, String commandLabel, Map<String, List<User>> playerList) {
|
||||
final Set<String> configGroups = ess.getSettings().getListGroupConfig().keySet();
|
||||
final List<String> asterisk = new ArrayList<>();
|
||||
|
||||
// Loop through the custom defined groups and display them
|
||||
for (String oConfigGroup : configGroups) {
|
||||
String groupValue = ess.getSettings().getListGroupConfig().get(oConfigGroup).toString().trim();
|
||||
String configGroup = oConfigGroup.toLowerCase();
|
||||
|
||||
// If the group value is an asterisk, then skip it, and handle it later
|
||||
if (groupValue.equals("*")) {
|
||||
asterisk.add(oConfigGroup);
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the group value is hidden, we don't need to display it
|
||||
if (groupValue.equalsIgnoreCase("hidden")) {
|
||||
playerList.remove(configGroup);
|
||||
continue;
|
||||
}
|
||||
|
||||
List<User> outputUserList = new ArrayList<>();
|
||||
final List<User> matchedList = playerList.get(configGroup);
|
||||
|
||||
// If the group value is an int, then we might need to truncate it
|
||||
if (NumberUtil.isInt(groupValue)) {
|
||||
if (matchedList != null && !matchedList.isEmpty()) {
|
||||
playerList.remove(configGroup);
|
||||
outputUserList.addAll(matchedList);
|
||||
int limit = Integer.parseInt(groupValue);
|
||||
if (matchedList.size() > limit) {
|
||||
sender.sendMessage(PlayerList.outputFormat(oConfigGroup, tl("groupNumber", matchedList.size(), commandLabel, FormatUtil.stripFormat(configGroup))));
|
||||
} else {
|
||||
sender.sendMessage(PlayerList.outputFormat(oConfigGroup, PlayerList.listUsers(ess, outputUserList, ", ")));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
outputUserList = PlayerList.getMergedList(ess, playerList, configGroup);
|
||||
|
||||
// If we have no users, than we don't need to continue parsing this group
|
||||
if (outputUserList == null || outputUserList.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
sender.sendMessage(PlayerList.outputFormat(oConfigGroup, PlayerList.listUsers(ess, outputUserList, ", ")));
|
||||
}
|
||||
|
||||
Set<String> var = playerList.keySet();
|
||||
String[] onlineGroups = var.toArray(new String[var.size()]);
|
||||
Arrays.sort(onlineGroups, String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
// If we have an asterisk group, then merge all remaining groups
|
||||
if (!asterisk.isEmpty()) {
|
||||
List<User> asteriskUsers = new ArrayList<>();
|
||||
for (String onlineGroup : onlineGroups) {
|
||||
asteriskUsers.addAll(playerList.get(onlineGroup));
|
||||
}
|
||||
for (String key : asterisk) {
|
||||
playerList.put(key, asteriskUsers);
|
||||
}
|
||||
onlineGroups = asterisk.toArray(new String[asterisk.size()]);
|
||||
}
|
||||
|
||||
// If we have any groups remaining after the custom groups loop through and display them
|
||||
for (String onlineGroup : onlineGroups) {
|
||||
List<User> users = playerList.get(onlineGroup);
|
||||
String groupName = asterisk.isEmpty() ? users.get(0).getGroup() : onlineGroup;
|
||||
|
||||
if (ess.getPermissionsHandler().getName().equals("ConfigPermissions")) {
|
||||
groupName = tl("connectedPlayers");
|
||||
}
|
||||
if (users == null || users.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
sender.sendMessage(PlayerList.outputFormat(groupName, PlayerList.listUsers(ess, users, ", ")));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
return getGroups();
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,196 +0,0 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.textreader.IText;
|
||||
import com.earth2me.essentials.textreader.SimpleTextInput;
|
||||
import com.earth2me.essentials.textreader.TextPager;
|
||||
import com.earth2me.essentials.utils.FormatUtil;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandmail extends EssentialsCommand {
|
||||
private static int mailsPerMinute = 0;
|
||||
private static long timestamp = 0;
|
||||
|
||||
public Commandmail() {
|
||||
super("mail");
|
||||
}
|
||||
|
||||
//TODO: Tidy this up / TL these errors.
|
||||
@Override
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length >= 1 && "read".equalsIgnoreCase(args[0])) {
|
||||
final List<String> mail = user.getMails();
|
||||
if (mail.isEmpty()) {
|
||||
user.sendMessage(tl("noMail"));
|
||||
throw new NoChargeException();
|
||||
}
|
||||
|
||||
IText input = new SimpleTextInput(mail);
|
||||
final TextPager pager = new TextPager(input);
|
||||
pager.showPage(args.length > 1 ? args[1] : null, null, commandLabel + " " + args[0], user.getSource());
|
||||
|
||||
user.sendMessage(tl("mailClear"));
|
||||
return;
|
||||
}
|
||||
if (args.length >= 3 && "send".equalsIgnoreCase(args[0])) {
|
||||
if (!user.isAuthorized("essentials.mail.send")) {
|
||||
throw new Exception(tl("noPerm", "essentials.mail.send"));
|
||||
}
|
||||
|
||||
if (user.isMuted()) {
|
||||
throw new Exception(user.hasMuteReason() ? tl("voiceSilencedReason", user.getMuteReason()) : tl("voiceSilenced"));
|
||||
}
|
||||
|
||||
User u = getPlayer(server, args[1], true, true);
|
||||
if (u == null) {
|
||||
throw new Exception(tl("playerNeverOnServer", args[1]));
|
||||
}
|
||||
|
||||
String mail = tl("mailFormat", user.getName(), FormatUtil.formatMessage(user, "essentials.mail", StringUtil.sanitizeString(FormatUtil.stripFormat(getFinalArg(args, 2)))));
|
||||
if (mail.length() > 1000) {
|
||||
throw new Exception(tl("mailTooLong"));
|
||||
}
|
||||
|
||||
if (!u.isIgnoredPlayer(user)) {
|
||||
if (Math.abs(System.currentTimeMillis() - timestamp) > 60000) {
|
||||
timestamp = System.currentTimeMillis();
|
||||
mailsPerMinute = 0;
|
||||
}
|
||||
mailsPerMinute++;
|
||||
if (mailsPerMinute > ess.getSettings().getMailsPerMinute()) {
|
||||
throw new Exception(tl("mailDelay", ess.getSettings().getMailsPerMinute()));
|
||||
}
|
||||
u.addMail(tl("mailMessage", mail));
|
||||
}
|
||||
|
||||
user.sendMessage(tl("mailSentTo", u.getDisplayName(), u.getName()));
|
||||
user.sendMessage(mail);
|
||||
return;
|
||||
}
|
||||
if (args.length > 1 && "sendall".equalsIgnoreCase(args[0])) {
|
||||
if (!user.isAuthorized("essentials.mail.sendall")) {
|
||||
throw new Exception(tl("noPerm", "essentials.mail.sendall"));
|
||||
}
|
||||
ess.runTaskAsynchronously(new SendAll(tl("mailFormat", user.getName(),
|
||||
FormatUtil.formatMessage(user, "essentials.mail", StringUtil.sanitizeString(FormatUtil.stripFormat(getFinalArg(args, 1)))))));
|
||||
user.sendMessage(tl("mailSent"));
|
||||
return;
|
||||
}
|
||||
if (args.length >= 1 && "clear".equalsIgnoreCase(args[0])) {
|
||||
if (user.getMails() == null || user.getMails().isEmpty()) {
|
||||
user.sendMessage(tl("noMail"));
|
||||
throw new NoChargeException();
|
||||
}
|
||||
|
||||
user.setMails(null);
|
||||
user.sendMessage(tl("mailCleared"));
|
||||
return;
|
||||
}
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run(Server server, CommandSource sender, String commandLabel, String[] args) throws Exception {
|
||||
if (args.length >= 1 && "read".equalsIgnoreCase(args[0])) {
|
||||
throw new Exception(tl("onlyPlayers", commandLabel + " read"));
|
||||
} else if (args.length >= 1 && "clear".equalsIgnoreCase(args[0])) {
|
||||
throw new Exception(tl("onlyPlayers", commandLabel + " clear"));
|
||||
} else if (args.length >= 3 && "send".equalsIgnoreCase(args[0])) {
|
||||
User u = getPlayer(server, args[1], true, true);
|
||||
if (u == null) {
|
||||
throw new Exception(tl("playerNeverOnServer", args[1]));
|
||||
}
|
||||
u.addMail(tl("mailFormat", "Server", FormatUtil.replaceFormat(getFinalArg(args, 2))));
|
||||
sender.sendMessage(tl("mailSent"));
|
||||
return;
|
||||
} else if (args.length >= 2 && "sendall".equalsIgnoreCase(args[0])) {
|
||||
ess.runTaskAsynchronously(new SendAll(tl("mailFormat", "Server", FormatUtil.replaceFormat(getFinalArg(args, 1)))));
|
||||
sender.sendMessage(tl("mailSent"));
|
||||
return;
|
||||
} else if (args.length >= 2) {
|
||||
//allow sending from console without "send" argument, since it's the only thing the console can do
|
||||
User u = getPlayer(server, args[0], true, true);
|
||||
if (u == null) {
|
||||
throw new Exception(tl("playerNeverOnServer", args[0]));
|
||||
}
|
||||
u.addMail(tl("mailFormat", "Server", FormatUtil.replaceFormat(getFinalArg(args, 1))));
|
||||
sender.sendMessage(tl("mailSent"));
|
||||
return;
|
||||
}
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
|
||||
private class SendAll implements Runnable {
|
||||
String message;
|
||||
|
||||
public SendAll(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for (UUID userid : ess.getUserMap().getAllUniqueUsers()) {
|
||||
User user = ess.getUserMap().getUser(userid);
|
||||
if (user != null) {
|
||||
user.addMail(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final User user, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
List<String> options = Lists.newArrayList("read", "clear");
|
||||
if (user.isAuthorized("essentials.mail.send")) {
|
||||
options.add("send");
|
||||
}
|
||||
if (user.isAuthorized("essentials.mail.sendall")) {
|
||||
options.add("sendall");
|
||||
}
|
||||
return options;
|
||||
} else if (args.length == 2 && args[0].equalsIgnoreCase("send") && user.isAuthorized("essentials.mail.send")) {
|
||||
return getPlayers(server, user);
|
||||
} else if (args.length == 2 && args[0].equalsIgnoreCase("read")) {
|
||||
final List<String> mail = user.getMails();
|
||||
int pages = mail.size() / 9 + (mail.size() % 9 > 0 ? 1 : 0);
|
||||
if (pages == 0) {
|
||||
return Lists.newArrayList("0");
|
||||
} else {
|
||||
List<String> options = Lists.newArrayList("1");
|
||||
if (pages > 1) {
|
||||
options.add(String.valueOf(pages));
|
||||
}
|
||||
return options;
|
||||
}
|
||||
} else if ((args.length > 2 && args[0].equalsIgnoreCase("send") && user.isAuthorized("essentials.mail.send")) || (args.length > 1 && args[0].equalsIgnoreCase("sendall") && user.isAuthorized("essentials.mail.sendall"))) {
|
||||
return null; // Use vanilla handler
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
return Lists.newArrayList("send", "sendall");
|
||||
} else if (args.length == 2 && args[0].equalsIgnoreCase("send")) {
|
||||
return getPlayers(server, sender);
|
||||
} else if ((args.length > 2 && args[0].equalsIgnoreCase("send")) || (args.length > 1 && args[0].equalsIgnoreCase("sendall"))) {
|
||||
return null; // Use vanilla handler
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.User;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandmore extends EssentialsCommand {
|
||||
public Commandmore() {
|
||||
super("more");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
final ItemStack stack = user.getItemInHand();
|
||||
if (stack == null) {
|
||||
throw new Exception(tl("cantSpawnItem", "Air"));
|
||||
}
|
||||
|
||||
if (stack.getAmount() >= ((user.isAuthorized("essentials.oversizedstacks")) ? ess.getSettings().getOversizedStackSize() : stack.getMaxStackSize())) {
|
||||
throw new Exception(tl("fullStack"));
|
||||
}
|
||||
final String itemname = stack.getType().toString().toLowerCase(Locale.ENGLISH).replace("_", "");
|
||||
if (!user.canSpawnItem(stack.getType())) {
|
||||
throw new Exception(tl("cantSpawnItem", itemname));
|
||||
}
|
||||
if (user.isAuthorized("essentials.oversizedstacks")) {
|
||||
stack.setAmount(ess.getSettings().getOversizedStackSize());
|
||||
} else {
|
||||
stack.setAmount(stack.getMaxStackSize());
|
||||
}
|
||||
user.getBase().updateInventory();
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.Console;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.messaging.IMessageRecipient;
|
||||
import com.earth2me.essentials.utils.FormatUtil;
|
||||
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Commandmsg extends EssentialsLoopCommand {
|
||||
|
||||
public Commandmsg() {
|
||||
super("msg");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(Server server, CommandSource sender, String commandLabel, String[] args) throws Exception {
|
||||
if (args.length < 2 || args[0].trim().length() < 2 || args[1].trim().isEmpty()) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
String message = getFinalArg(args, 1);
|
||||
boolean canWildcard;
|
||||
if (sender.isPlayer()) {
|
||||
User user = ess.getUser(sender.getPlayer());
|
||||
if (user.isMuted()) {
|
||||
throw new Exception(user.hasMuteReason() ? tl("voiceSilencedReason", user.getMuteReason()) : tl("voiceSilenced"));
|
||||
}
|
||||
message = FormatUtil.formatMessage(user, "essentials.msg", message);
|
||||
canWildcard = user.isAuthorized("essentials.msg.multiple");
|
||||
} else {
|
||||
message = FormatUtil.replaceFormat(message);
|
||||
canWildcard = true;
|
||||
}
|
||||
|
||||
// Sending messages to console
|
||||
if (args[0].equalsIgnoreCase(Console.NAME)) {
|
||||
IMessageRecipient messageSender = sender.isPlayer() ? ess.getUser(sender.getPlayer()) : Console.getInstance();
|
||||
messageSender.sendMessage(Console.getInstance(), message);
|
||||
return;
|
||||
}
|
||||
|
||||
loopOnlinePlayers(server, sender, canWildcard, canWildcard, args[0], new String[]{message});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updatePlayer(final Server server, final CommandSource sender, final User messageReceiver, final String[] args) {
|
||||
IMessageRecipient messageSender = sender.isPlayer() ? ess.getUser(sender.getPlayer()) : Console.getInstance();
|
||||
messageSender.sendMessage(messageReceiver, args[0]); // args[0] is the message.
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, CommandSource sender, String commandLabel, String[] args) {
|
||||
if (args.length == 1) {
|
||||
return getPlayers(server, sender);
|
||||
} else {
|
||||
return null; // It's a chat message, use the default chat handler
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.ChargeException;
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.Trade;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import net.ess3.api.MaxMoneyException;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandpay extends EssentialsLoopCommand {
|
||||
BigDecimal amount;
|
||||
boolean informToConfirm;
|
||||
|
||||
public Commandpay() {
|
||||
super("pay");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
informToConfirm = false;
|
||||
if (args.length < 2) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
if (args[1].contains("-")) {
|
||||
throw new Exception(tl("payMustBePositive"));
|
||||
}
|
||||
|
||||
String stringAmount = args[1].replaceAll("[^0-9\\.]", "");
|
||||
|
||||
if (stringAmount.length() < 1) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
amount = new BigDecimal(stringAmount);
|
||||
if (amount.compareTo(ess.getSettings().getMinimumPayAmount()) < 0) { // Check if amount is less than minimum-pay-amount
|
||||
throw new Exception(tl("minimumPayAmount", NumberUtil.displayCurrencyExactly(ess.getSettings().getMinimumPayAmount(), ess)));
|
||||
}
|
||||
loopOnlinePlayers(server, user.getSource(), false, user.isAuthorized("essentials.pay.multiple"), args[0], args);
|
||||
if (informToConfirm) {
|
||||
String cmd = "/" + commandLabel + " " + StringUtil.joinList(" ", (Object[]) args);
|
||||
user.sendMessage(tl("confirmPayment", NumberUtil.displayCurrency(amount, ess), cmd));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updatePlayer(final Server server, final CommandSource sender, final User player, final String[] args) throws ChargeException {
|
||||
User user = ess.getUser(sender.getPlayer());
|
||||
try {
|
||||
if (!player.isAcceptingPay()) {
|
||||
sender.sendMessage(tl("notAcceptingPay", player.getDisplayName()));
|
||||
return;
|
||||
}
|
||||
if (user.isPromptingPayConfirm() && !amount.equals(user.getConfirmingPayments().get(player))) { // checks if exists and if command needs to be repeated.
|
||||
// Used to reset confirmations and inform to confirm when a new pay command has been inserted.
|
||||
if (!informToConfirm) {
|
||||
// User hasnt been asked to confirm payment to this player, reset all confirmed payments and ask to confirm again.
|
||||
// Clear previous confirmations to ensure that a new confirmation message is brought up.
|
||||
user.getConfirmingPayments().clear();
|
||||
this.informToConfirm = true;
|
||||
}
|
||||
user.getConfirmingPayments().put(player, amount);
|
||||
return;
|
||||
}
|
||||
user.payUser(player, amount);
|
||||
user.getConfirmingPayments().remove(player);
|
||||
Trade.log("Command", "Pay", "Player", user.getName(), new Trade(amount, ess), player.getName(), new Trade(amount, ess), user.getLocation(), ess);
|
||||
} catch (MaxMoneyException ex) {
|
||||
sender.sendMessage(tl("maxMoney"));
|
||||
try {
|
||||
user.setMoney(user.getMoney().add(amount));
|
||||
} catch (MaxMoneyException ignored) {
|
||||
// this should never happen
|
||||
}
|
||||
} catch (Exception e) {
|
||||
sender.sendMessage(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, CommandSource sender, String commandLabel, String[] args) {
|
||||
if (args.length == 1) {
|
||||
return getPlayers(server, sender);
|
||||
} else if (args.length == 2) {
|
||||
return Lists.newArrayList(ess.getSettings().getMinimumPayAmount().toString());
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
import com.earth2me.essentials.I18n;
|
||||
import com.earth2me.essentials.User;
|
||||
|
||||
import org.bukkit.Server;
|
||||
|
||||
public class Commandpaytoggle extends EssentialsCommand {
|
||||
|
||||
public Commandpaytoggle() {
|
||||
super("paytoggle");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(Server server, User user, String commandLabel, String[] args) throws Exception {
|
||||
boolean acceptingPay = !user.isAcceptingPay();
|
||||
if (commandLabel.contains("payon")) {
|
||||
acceptingPay = true;
|
||||
} else if (commandLabel.contains("payoff")) {
|
||||
acceptingPay = false;
|
||||
}
|
||||
user.setAcceptingPay(acceptingPay);
|
||||
if (acceptingPay) {
|
||||
user.sendMessage(tl("payToggleOn"));
|
||||
} else {
|
||||
user.sendMessage(tl("payToggleOff"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,209 +0,0 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.DescParseTickFormat;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandptime extends EssentialsCommand {
|
||||
private static final Set<String> getAliases = new HashSet<>();
|
||||
|
||||
static {
|
||||
getAliases.add("get");
|
||||
getAliases.add("list");
|
||||
getAliases.add("show");
|
||||
getAliases.add("display");
|
||||
}
|
||||
|
||||
public Commandptime() {
|
||||
super("ptime");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
// Which Players(s) / Users(s) are we interested in?
|
||||
String userSelector = null;
|
||||
if (args.length == 2) {
|
||||
userSelector = args[1];
|
||||
}
|
||||
Set<User> users = getUsers(server, sender, userSelector);
|
||||
|
||||
// If no arguments we are reading the time
|
||||
if (args.length == 0) {
|
||||
getUsersTime(sender, users);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sender.isPlayer()) {
|
||||
User user = ess.getUser(sender.getPlayer());
|
||||
if (user != null && (!users.contains(user) || users.size() > 1) && !user.isAuthorized("essentials.ptime.others")) {
|
||||
user.sendMessage(tl("pTimeOthersPermission"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Long ticks;
|
||||
// Parse the target time int ticks from args[0]
|
||||
String timeParam = args[0];
|
||||
boolean relative = true;
|
||||
if (timeParam.startsWith("@")) {
|
||||
relative = false;
|
||||
timeParam = timeParam.substring(1);
|
||||
}
|
||||
|
||||
if (getAliases.contains(timeParam)) {
|
||||
getUsersTime(sender, users);
|
||||
return;
|
||||
} else if (DescParseTickFormat.meansReset(timeParam)) {
|
||||
ticks = null;
|
||||
} else {
|
||||
try {
|
||||
ticks = DescParseTickFormat.parse(timeParam);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new NotEnoughArgumentsException(e);
|
||||
}
|
||||
}
|
||||
|
||||
setUsersTime(sender, users, ticks, relative);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to get the time and inform
|
||||
*/
|
||||
private void getUsersTime(final CommandSource sender, final Collection<User> users) {
|
||||
if (users.size() > 1) {
|
||||
sender.sendMessage(tl("pTimePlayers"));
|
||||
}
|
||||
|
||||
for (User user : users) {
|
||||
if (user.getBase().getPlayerTimeOffset() == 0) {
|
||||
sender.sendMessage(tl("pTimeNormal", user.getName()));
|
||||
} else {
|
||||
String time = DescParseTickFormat.format(user.getBase().getPlayerTime());
|
||||
if (!user.getBase().isPlayerTimeRelative()) {
|
||||
sender.sendMessage(tl("pTimeCurrentFixed", user.getName(), time));
|
||||
} else {
|
||||
sender.sendMessage(tl("pTimeCurrent", user.getName(), time));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to set the time and inform of the change
|
||||
*/
|
||||
private void setUsersTime(final CommandSource sender, final Collection<User> users, final Long ticks, Boolean relative) {
|
||||
// Update the time
|
||||
if (ticks == null) {
|
||||
// Reset
|
||||
for (User user : users) {
|
||||
user.getBase().resetPlayerTime();
|
||||
}
|
||||
} else {
|
||||
// Set
|
||||
for (User user : users) {
|
||||
final World world = user.getWorld();
|
||||
long time = user.getBase().getPlayerTime();
|
||||
time -= time % 24000;
|
||||
time += 24000 + ticks;
|
||||
if (relative) {
|
||||
time -= world.getTime();
|
||||
}
|
||||
user.getBase().setPlayerTime(time, relative);
|
||||
}
|
||||
}
|
||||
|
||||
final StringBuilder msg = new StringBuilder();
|
||||
for (User user : users) {
|
||||
if (msg.length() > 0) {
|
||||
msg.append(", ");
|
||||
}
|
||||
|
||||
msg.append(user.getName());
|
||||
}
|
||||
|
||||
// Inform the sender of the change
|
||||
if (ticks == null) {
|
||||
sender.sendMessage(tl("pTimeReset", msg.toString()));
|
||||
} else {
|
||||
String time = DescParseTickFormat.format(ticks);
|
||||
if (!relative) {
|
||||
sender.sendMessage(tl("pTimeSetFixed", time, msg.toString()));
|
||||
} else {
|
||||
sender.sendMessage(tl("pTimeSet", time, msg.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to parse an argument of the type "users(s) selector"
|
||||
*/
|
||||
private Set<User> getUsers(final Server server, final CommandSource sender, final String selector) throws Exception {
|
||||
final Set<User> users = new TreeSet<>(new UserNameComparator());
|
||||
// If there is no selector we want the sender itself. Or all users if sender isn't a user.
|
||||
if (selector == null) {
|
||||
if (sender.isPlayer()) {
|
||||
final User user = ess.getUser(sender.getPlayer());
|
||||
users.add(user);
|
||||
} else {
|
||||
for (User user : ess.getOnlineUsers()) {
|
||||
users.add(user);
|
||||
}
|
||||
}
|
||||
return users;
|
||||
}
|
||||
|
||||
// Try to find the user with name = selector
|
||||
User user = null;
|
||||
final List<Player> matchedPlayers = server.matchPlayer(selector);
|
||||
if (!matchedPlayers.isEmpty()) {
|
||||
user = ess.getUser(matchedPlayers.get(0));
|
||||
}
|
||||
|
||||
if (user != null) {
|
||||
users.add(user);
|
||||
}
|
||||
// If that fails, Is the argument something like "*" or "all"?
|
||||
else if (selector.equalsIgnoreCase("*") || selector.equalsIgnoreCase("all")) {
|
||||
for (User u : ess.getOnlineUsers()) {
|
||||
users.add(u);
|
||||
}
|
||||
}
|
||||
// We failed to understand the world target...
|
||||
else {
|
||||
throw new PlayerNotFoundException();
|
||||
}
|
||||
|
||||
return users;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, CommandSource sender, String commandLabel, String[] args) {
|
||||
final User user = ess.getUser(sender.getPlayer());
|
||||
|
||||
if (args.length == 1) {
|
||||
return Lists.newArrayList("get", "reset", "sunrise", "day", "morning", "noon", "afternoon", "sunset", "night", "midnight");
|
||||
} else if (args.length == 2 && (getAliases.contains(args[0]) || user == null || user.isAuthorized("essentials.ptime.others"))) {
|
||||
return getPlayers(server, sender);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class UserNameComparator implements Comparator<User> {
|
||||
@Override
|
||||
public int compare(User a, User b) {
|
||||
return a.getName().compareTo(b.getName());
|
||||
}
|
||||
}
|
||||
@@ -1,166 +0,0 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.WeatherType;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandpweather extends EssentialsCommand {
|
||||
public static final Set<String> getAliases = new HashSet<>();
|
||||
public static final Map<String, WeatherType> weatherAliases = new HashMap<>();
|
||||
|
||||
static {
|
||||
getAliases.add("get");
|
||||
getAliases.add("list");
|
||||
getAliases.add("show");
|
||||
getAliases.add("display");
|
||||
weatherAliases.put("sun", WeatherType.CLEAR);
|
||||
weatherAliases.put("clear", WeatherType.CLEAR);
|
||||
weatherAliases.put("storm", WeatherType.DOWNFALL);
|
||||
weatherAliases.put("thunder", WeatherType.DOWNFALL);
|
||||
}
|
||||
|
||||
public Commandpweather() {
|
||||
super("pweather");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
// Which Players(s) / Users(s) are we interested in?
|
||||
String userSelector = null;
|
||||
if (args.length == 2) {
|
||||
userSelector = args[1];
|
||||
}
|
||||
Set<User> users = getUsers(server, sender, userSelector);
|
||||
|
||||
if (args.length == 0) {
|
||||
getUsersWeather(sender, users);
|
||||
return;
|
||||
}
|
||||
|
||||
if (getAliases.contains(args[0])) {
|
||||
getUsersWeather(sender, users);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sender.isPlayer()) {
|
||||
User user = ess.getUser(sender.getPlayer());
|
||||
if (user != null && (!users.contains(user) || users.size() > 1) && !user.isAuthorized("essentials.pweather.others")) {
|
||||
user.sendMessage(tl("pWeatherOthersPermission"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
setUsersWeather(sender, users, args[0].toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to get the time and inform
|
||||
*/
|
||||
private void getUsersWeather(final CommandSource sender, final Collection<User> users) {
|
||||
if (users.size() > 1) {
|
||||
sender.sendMessage(tl("pWeatherPlayers"));
|
||||
}
|
||||
|
||||
for (User user : users) {
|
||||
if (user.getBase().getPlayerWeather() == null) {
|
||||
sender.sendMessage(tl("pWeatherNormal", user.getName()));
|
||||
} else {
|
||||
sender.sendMessage(tl("pWeatherCurrent", user.getName(), user.getBase().getPlayerWeather().toString().toLowerCase(Locale.ENGLISH)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to set the time and inform of the change
|
||||
*/
|
||||
private void setUsersWeather(final CommandSource sender, final Collection<User> users, final String weatherType) throws Exception {
|
||||
|
||||
final StringBuilder msg = new StringBuilder();
|
||||
for (User user : users) {
|
||||
if (msg.length() > 0) {
|
||||
msg.append(", ");
|
||||
}
|
||||
|
||||
msg.append(user.getName());
|
||||
}
|
||||
|
||||
if (weatherType.equalsIgnoreCase("reset")) {
|
||||
for (User user : users) {
|
||||
user.getBase().resetPlayerWeather();
|
||||
}
|
||||
|
||||
sender.sendMessage(tl("pWeatherReset", msg));
|
||||
} else {
|
||||
if (!weatherAliases.containsKey(weatherType)) {
|
||||
throw new NotEnoughArgumentsException(tl("pWeatherInvalidAlias"));
|
||||
}
|
||||
|
||||
for (User user : users) {
|
||||
user.getBase().setPlayerWeather(weatherAliases.get(weatherType));
|
||||
}
|
||||
sender.sendMessage(tl("pWeatherSet", weatherType, msg.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to parse an argument of the type "users(s) selector"
|
||||
*/
|
||||
private Set<User> getUsers(final Server server, final CommandSource sender, final String selector) throws Exception {
|
||||
final Set<User> users = new TreeSet<>(new UserNameComparator());
|
||||
// If there is no selector we want the sender itself. Or all users if sender isn't a user.
|
||||
if (selector == null) {
|
||||
if (sender.isPlayer()) {
|
||||
final User user = ess.getUser(sender.getPlayer());
|
||||
users.add(user);
|
||||
} else {
|
||||
for (User user : ess.getOnlineUsers()) {
|
||||
users.add(user);
|
||||
}
|
||||
}
|
||||
return users;
|
||||
}
|
||||
|
||||
// Try to find the user with name = selector
|
||||
User user = null;
|
||||
final List<Player> matchedPlayers = server.matchPlayer(selector);
|
||||
if (!matchedPlayers.isEmpty()) {
|
||||
user = ess.getUser(matchedPlayers.get(0));
|
||||
}
|
||||
|
||||
if (user != null) {
|
||||
users.add(user);
|
||||
}
|
||||
// If that fails, Is the argument something like "*" or "all"?
|
||||
else if (selector.equalsIgnoreCase("*") || selector.equalsIgnoreCase("all")) {
|
||||
for (User u : ess.getOnlineUsers()) {
|
||||
users.add(u);
|
||||
}
|
||||
}
|
||||
// We failed to understand the world target...
|
||||
else {
|
||||
throw new PlayerNotFoundException();
|
||||
}
|
||||
|
||||
return users;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, User user, String commandLabel, String[] args) {
|
||||
if (args.length == 1) {
|
||||
return Lists.newArrayList("get", "reset", "storm", "sun");
|
||||
} else if (args.length == 2 && (getAliases.contains(args[0]) || user == null || user.isAuthorized("essentials.pweather.others"))) {
|
||||
return getPlayers(server, user);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,239 +0,0 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.UserMap;
|
||||
import com.earth2me.essentials.craftbukkit.BanLookup;
|
||||
import com.earth2me.essentials.utils.DateUtil;
|
||||
import com.earth2me.essentials.utils.FormatUtil;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
import org.bukkit.BanEntry;
|
||||
import org.bukkit.BanList;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.Collections;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandseen extends EssentialsCommand {
|
||||
public Commandseen() {
|
||||
super("seen");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
seen(server, sender, commandLabel, args, true, true, true, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
seen(server, user.getSource(), commandLabel, args, user.isAuthorized("essentials.seen.banreason"), user.isAuthorized("essentials.seen.ip"), user.isAuthorized("essentials.seen.location"), user.isAuthorized("essentials.seen.ipsearch"));
|
||||
}
|
||||
|
||||
protected void seen(final Server server, final CommandSource sender, final String commandLabel, final String[] args,
|
||||
final boolean showBan, final boolean showIp, final boolean showLocation, final boolean ipLookup) throws Exception {
|
||||
if (args.length < 1) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
User player;
|
||||
// Check by uuid, if it fails check by name.
|
||||
try {
|
||||
UUID uuid = UUID.fromString(args[0]);
|
||||
player = ess.getUser(uuid);
|
||||
}catch (IllegalArgumentException ignored) { // Thrown if invalid UUID from string, check by name.
|
||||
player = ess.getOfflineUser(args[0]);
|
||||
}
|
||||
|
||||
if (player == null) {
|
||||
if (ipLookup && FormatUtil.validIP(args[0])) {
|
||||
seenIP(server, sender, args[0]);
|
||||
return;
|
||||
} else if (ess.getServer().getBanList(BanList.Type.IP).isBanned(args[0])) {
|
||||
sender.sendMessage(tl("isIpBanned", args[0]));
|
||||
return;
|
||||
} else if (BanLookup.isBanned(ess, args[0])) {
|
||||
sender.sendMessage(tl("whoisBanned", showBan ? BanLookup.getBanEntry(ess, args[0]).getReason() : tl("true")));
|
||||
return;
|
||||
}
|
||||
ess.getScheduler().runTaskAsynchronously(ess, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
User userFromBukkit = ess.getUserMap().getUserFromBukkit(args[0]);
|
||||
try {
|
||||
if (userFromBukkit != null) {
|
||||
showUserSeen(userFromBukkit);
|
||||
} else {
|
||||
showUserSeen(getPlayer(server, sender, args, 0));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
ess.showError(sender, e, commandLabel);
|
||||
}
|
||||
}
|
||||
|
||||
private void showUserSeen(User user) throws Exception {
|
||||
if (user == null) {
|
||||
throw new PlayerNotFoundException();
|
||||
}
|
||||
showSeenMessage(server, sender, user, showBan, showIp, showLocation);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
showSeenMessage(server, sender, player, showBan, showIp, showLocation);
|
||||
}
|
||||
}
|
||||
|
||||
private void showSeenMessage(Server server, CommandSource sender, User player, boolean showBan, boolean showIp, boolean showLocation) throws Exception {
|
||||
if (player.getBase().isOnline() && canInteractWith(sender, player)) {
|
||||
seenOnline(server, sender, player, showBan, showIp, showLocation);
|
||||
} else {
|
||||
seenOffline(server, sender, player, showBan, showIp, showLocation);
|
||||
}
|
||||
}
|
||||
|
||||
private void seenOnline(final Server server, final CommandSource sender, final User user, final boolean showBan, final boolean showIp, final boolean showLocation) throws Exception {
|
||||
|
||||
user.setDisplayNick();
|
||||
sender.sendMessage(tl("seenOnline", user.getDisplayName(), DateUtil.formatDateDiff(user.getLastLogin())));
|
||||
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().info("UUID: " + user.getBase().getUniqueId().toString());
|
||||
}
|
||||
|
||||
List<String> history = ess.getUserMap().getUserHistory(user.getBase().getUniqueId());
|
||||
if (history != null && history.size() > 1) {
|
||||
sender.sendMessage(tl("seenAccounts", StringUtil.joinListSkip(", ", user.getName(), history)));
|
||||
}
|
||||
|
||||
if (user.isAfk()) {
|
||||
sender.sendMessage(tl("whoisAFK", tl("true")));
|
||||
}
|
||||
if (user.isJailed()) {
|
||||
sender.sendMessage(tl("whoisJail", (user.getJailTimeout() > 0 ? DateUtil.formatDateDiff(user.getJailTimeout()) : tl("true"))));
|
||||
}
|
||||
if (user.isMuted()) {
|
||||
long muteTimeout = user.getMuteTimeout();
|
||||
if (!user.hasMuteReason()) {
|
||||
sender.sendMessage(tl("whoisMuted", (muteTimeout > 0 ? DateUtil.formatDateDiff(muteTimeout) : tl("true"))));
|
||||
} else {
|
||||
sender.sendMessage(tl("whoisMutedReason", (muteTimeout > 0 ? DateUtil.formatDateDiff(muteTimeout) : tl("true")), user.getMuteReason()));
|
||||
}
|
||||
}
|
||||
final String location = user.getGeoLocation();
|
||||
if (location != null && (!(sender.isPlayer()) || ess.getUser(sender.getPlayer()).isAuthorized("essentials.geoip.show"))) {
|
||||
sender.sendMessage(tl("whoisGeoLocation", location));
|
||||
}
|
||||
if (showIp) {
|
||||
sender.sendMessage(tl("whoisIPAddress", user.getBase().getAddress().getAddress().toString()));
|
||||
}
|
||||
}
|
||||
|
||||
private void seenOffline(final Server server, final CommandSource sender, User user, final boolean showBan, final boolean showIp, final boolean showLocation) throws Exception {
|
||||
user.setDisplayNick();
|
||||
if (user.getLastLogout() > 0) {
|
||||
sender.sendMessage(tl("seenOffline", user.getName(), DateUtil.formatDateDiff(user.getLastLogout())));
|
||||
} else {
|
||||
sender.sendMessage(tl("userUnknown", user.getName()));
|
||||
}
|
||||
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().info("UUID: " + user.getBase().getUniqueId().toString());
|
||||
}
|
||||
|
||||
List<String> history = ess.getUserMap().getUserHistory(user.getBase().getUniqueId());
|
||||
if (history != null && history.size() > 1) {
|
||||
sender.sendMessage(tl("seenAccounts", StringUtil.joinListSkip(", ", user.getName(), history)));
|
||||
}
|
||||
|
||||
if (BanLookup.isBanned(ess, user)) {
|
||||
final BanEntry banEntry = BanLookup.getBanEntry(ess, user.getName());
|
||||
final String reason = showBan ? banEntry.getReason() : tl("true");
|
||||
sender.sendMessage(tl("whoisBanned", reason));
|
||||
if (banEntry.getExpiration() != null) {
|
||||
Date expiry = banEntry.getExpiration();
|
||||
String expireString = tl("now");
|
||||
if (expiry.after(new Date())) {
|
||||
expireString = DateUtil.formatDateDiff(expiry.getTime());
|
||||
}
|
||||
sender.sendMessage(tl("whoisTempBanned", expireString));
|
||||
}
|
||||
}
|
||||
|
||||
if (user.isMuted()) {
|
||||
long muteTimeout = user.getMuteTimeout();
|
||||
if (!user.hasMuteReason()) {
|
||||
sender.sendMessage(tl("whoisMuted", (muteTimeout > 0 ? DateUtil.formatDateDiff(muteTimeout) : tl("true"))));
|
||||
} else {
|
||||
sender.sendMessage(tl("whoisMutedReason", (muteTimeout > 0 ? DateUtil.formatDateDiff(muteTimeout) : tl("true")), user.getMuteReason()));
|
||||
}
|
||||
}
|
||||
|
||||
final String location = user.getGeoLocation();
|
||||
if (location != null && (!(sender.isPlayer()) || ess.getUser(sender.getPlayer()).isAuthorized("essentials.geoip.show"))) {
|
||||
sender.sendMessage(tl("whoisGeoLocation", location));
|
||||
}
|
||||
if (showIp) {
|
||||
if (!user.getLastLoginAddress().isEmpty()) {
|
||||
sender.sendMessage(tl("whoisIPAddress", user.getLastLoginAddress()));
|
||||
}
|
||||
}
|
||||
if (showLocation) {
|
||||
final Location loc = user.getLogoutLocation();
|
||||
if (loc != null) {
|
||||
sender.sendMessage(tl("whoisLocation", loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void seenIP(final Server server, final CommandSource sender, final String ipAddress) throws Exception {
|
||||
final UserMap userMap = ess.getUserMap();
|
||||
|
||||
if (ess.getServer().getBanList(BanList.Type.IP).isBanned(ipAddress)) {
|
||||
sender.sendMessage(tl("isIpBanned", ipAddress));
|
||||
}
|
||||
|
||||
sender.sendMessage(tl("runningPlayerMatch", ipAddress));
|
||||
|
||||
ess.runTaskAsynchronously(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final List<String> matches = new ArrayList<>();
|
||||
for (final UUID u : userMap.getAllUniqueUsers()) {
|
||||
final User user = ess.getUserMap().getUser(u);
|
||||
if (user == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final String uIPAddress = user.getLastLoginAddress();
|
||||
|
||||
if (!uIPAddress.isEmpty() && uIPAddress.equalsIgnoreCase(ipAddress)) {
|
||||
matches.add(user.getName());
|
||||
}
|
||||
}
|
||||
|
||||
if (matches.size() > 0) {
|
||||
sender.sendMessage(tl("matchingIPAddress"));
|
||||
sender.sendMessage(StringUtil.joinList(matches));
|
||||
} else {
|
||||
sender.sendMessage(tl("noMatchingPlayers"));
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, CommandSource sender, String commandLabel, String[] args) {
|
||||
if (args.length == 1) {
|
||||
return getPlayers(server, sender);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.api.IWarps;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.earth2me.essentials.utils.StringUtil;
|
||||
import net.ess3.api.InvalidWorldException;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandsetwarp extends EssentialsCommand {
|
||||
public Commandsetwarp() {
|
||||
super("setwarp");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length < 1) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
if (NumberUtil.isInt(args[0]) || args[0].isEmpty()) {
|
||||
throw new NoSuchFieldException(tl("invalidWarpName"));
|
||||
}
|
||||
|
||||
final Location loc = user.getLocation();
|
||||
final IWarps warps = ess.getWarps();
|
||||
Location warpLoc = null;
|
||||
|
||||
try {
|
||||
warpLoc = warps.getWarp(args[0]);
|
||||
} catch (WarpNotFoundException | InvalidWorldException ex) {
|
||||
}
|
||||
|
||||
if (warpLoc == null || user.isAuthorized("essentials.warp.overwrite." + StringUtil.safeString(args[0]))) {
|
||||
warps.setWarp(user, args[0], loc);
|
||||
} else {
|
||||
throw new Exception(tl("warpOverwrite"));
|
||||
}
|
||||
user.sendMessage(tl("warpSet", args[0]));
|
||||
}
|
||||
}
|
||||
@@ -1,203 +0,0 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.DescParseTickFormat;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandtime extends EssentialsCommand {
|
||||
public Commandtime() {
|
||||
super("time");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
boolean add = false;
|
||||
final List<String> argList = new ArrayList<>(Arrays.asList(args));
|
||||
if (argList.remove("set") && !argList.isEmpty() && NumberUtil.isInt(argList.get(0))) {
|
||||
argList.set(0, argList.get(0) + "t");
|
||||
}
|
||||
if (argList.remove("add") && !argList.isEmpty() && NumberUtil.isInt(argList.get(0))) {
|
||||
add = true;
|
||||
argList.set(0, argList.get(0) + "t");
|
||||
}
|
||||
final String[] validArgs = argList.toArray(new String[argList.size()]);
|
||||
|
||||
// Which World(s) are we interested in?
|
||||
String worldSelector = null;
|
||||
if (validArgs.length == 2) {
|
||||
worldSelector = validArgs[1];
|
||||
}
|
||||
final Set<World> worlds = getWorlds(server, sender, worldSelector);
|
||||
final String setTime;
|
||||
|
||||
// If no arguments we are reading the time
|
||||
if (validArgs.length == 0) {
|
||||
if (commandLabel.equalsIgnoreCase("day") || commandLabel.equalsIgnoreCase("eday")) {
|
||||
setTime = "day";
|
||||
} else if (commandLabel.equalsIgnoreCase("night") || commandLabel.equalsIgnoreCase("enight")) {
|
||||
setTime = "night";
|
||||
} else {
|
||||
getWorldsTime(sender, worlds);
|
||||
throw new NoChargeException();
|
||||
}
|
||||
} else {
|
||||
setTime = validArgs[0];
|
||||
}
|
||||
|
||||
final User user = ess.getUser(sender.getPlayer());
|
||||
if (user != null && !user.isAuthorized("essentials.time.set")) {
|
||||
throw new Exception(tl("timeSetPermission"));
|
||||
}
|
||||
|
||||
// Parse the target time int ticks from args[0]
|
||||
long ticks;
|
||||
try {
|
||||
ticks = DescParseTickFormat.parse(setTime);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new NotEnoughArgumentsException(e);
|
||||
}
|
||||
|
||||
setWorldsTime(sender, worlds, ticks, add);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to get the time and inform
|
||||
*/
|
||||
private void getWorldsTime(final CommandSource sender, final Collection<World> worlds) {
|
||||
if (worlds.size() == 1) {
|
||||
final Iterator<World> iter = worlds.iterator();
|
||||
sender.sendMessage(DescParseTickFormat.format(iter.next().getTime()));
|
||||
return;
|
||||
}
|
||||
|
||||
for (World world : worlds) {
|
||||
sender.sendMessage(tl("timeWorldCurrent", world.getName(), DescParseTickFormat.format(world.getTime())));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to set the time and inform of the change
|
||||
*/
|
||||
private void setWorldsTime(final CommandSource sender, final Collection<World> worlds, final long ticks, final boolean add) throws Exception {
|
||||
User user = ess.getUser(sender.getPlayer());
|
||||
for (World world : worlds) {
|
||||
if (!canUpdateWorld(user, world)) {
|
||||
throw new Exception(tl("timeSetWorldPermission", user.getWorld().getName()));
|
||||
}
|
||||
}
|
||||
|
||||
// Update the time
|
||||
for (World world : worlds) {
|
||||
long time = world.getTime();
|
||||
if (!add) {
|
||||
time -= time % 24000;
|
||||
}
|
||||
world.setTime(time + (add ? 0 : 24000) + ticks);
|
||||
}
|
||||
|
||||
final StringBuilder output = new StringBuilder();
|
||||
for (World world : worlds) {
|
||||
if (output.length() > 0) {
|
||||
output.append(", ");
|
||||
}
|
||||
|
||||
output.append(world.getName());
|
||||
}
|
||||
|
||||
sender.sendMessage(tl("timeWorldSet", DescParseTickFormat.format(ticks), output.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to parse an argument of the type "world(s) selector"
|
||||
*/
|
||||
private Set<World> getWorlds(final Server server, final CommandSource sender, final String selector) throws Exception {
|
||||
final Set<World> worlds = new TreeSet<>(new WorldNameComparator());
|
||||
|
||||
// If there is no selector we want the world the user is currently in. Or all worlds if it isn't a user.
|
||||
if (selector == null) {
|
||||
if (sender.isPlayer()) {
|
||||
|
||||
final User user = ess.getUser(sender.getPlayer());
|
||||
worlds.add(user.getWorld());
|
||||
} else {
|
||||
worlds.addAll(server.getWorlds());
|
||||
}
|
||||
return worlds;
|
||||
}
|
||||
|
||||
// Try to find the world with name = selector
|
||||
final World world = server.getWorld(selector);
|
||||
if (world != null) {
|
||||
worlds.add(world);
|
||||
}
|
||||
// If that fails, Is the argument something like "*" or "all"?
|
||||
else if (selector.equalsIgnoreCase("*") || selector.equalsIgnoreCase("all")) {
|
||||
worlds.addAll(server.getWorlds());
|
||||
}
|
||||
// We failed to understand the world target...
|
||||
else {
|
||||
throw new Exception(tl("invalidWorld"));
|
||||
}
|
||||
|
||||
return worlds;
|
||||
}
|
||||
|
||||
private boolean canUpdateAll(User user) {
|
||||
return !ess.getSettings().isWorldTimePermissions() // First check if per world permissions are enabled, if not, return true.
|
||||
|| user == null || user.isAuthorized("essentials.time.world.all");
|
||||
}
|
||||
|
||||
private boolean canUpdateWorld(User user, World world) {
|
||||
return canUpdateAll(user) || user.isAuthorized("essentials.time.world." + normalizeWorldName(world));
|
||||
}
|
||||
|
||||
private String normalizeWorldName(World world) {
|
||||
return world.getName().toLowerCase().replaceAll("\\s+", "_");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(Server server, CommandSource sender, String commandLabel, String[] args) {
|
||||
final User user = ess.getUser(sender.getPlayer());
|
||||
|
||||
if (args.length == 1) {
|
||||
if (user == null || user.isAuthorized("essentials.time.set")) {
|
||||
return Lists.newArrayList("set", "add");
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
} else if (args.length == 2 && args[0].equalsIgnoreCase("set")) {
|
||||
return Lists.newArrayList("sunrise", "day", "morning", "noon", "afternoon", "sunset", "night", "midnight");
|
||||
// TODO: handle tab completion for add
|
||||
} else if (args.length == 3 && (args[0].equalsIgnoreCase("set") || args[0].equalsIgnoreCase("add"))) {
|
||||
List<String> worlds = Lists.newArrayList();
|
||||
for (World world : server.getWorlds()) {
|
||||
if (user == null || user.isAuthorized("essentials.time.world." + normalizeWorldName(world))) {
|
||||
worlds.add(world.getName());
|
||||
}
|
||||
}
|
||||
if (user == null || user.isAuthorized("essentials.time.world.all")) {
|
||||
worlds.add("*");
|
||||
}
|
||||
return worlds;
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class WorldNameComparator implements Comparator<World> {
|
||||
@Override
|
||||
public int compare(final World a, final World b) {
|
||||
return a.getName().compareTo(b.getName());
|
||||
}
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.DateUtil;
|
||||
import net.ess3.api.events.JailStatusChangeEvent;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandtogglejail extends EssentialsCommand {
|
||||
public Commandtogglejail() {
|
||||
super("togglejail");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final CommandSource sender, final String commandLabel, final String[] args) throws Exception {
|
||||
if (args.length < 1) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
|
||||
final User player = getPlayer(server, args, 0, true, true);
|
||||
|
||||
if (args.length >= 2 && !player.isJailed()) {
|
||||
if (!player.getBase().isOnline()) {
|
||||
if (sender.isPlayer() && !ess.getUser(sender.getPlayer()).isAuthorized("essentials.togglejail.offline")) {
|
||||
sender.sendMessage(tl("mayNotJailOffline"));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (player.isAuthorized("essentials.jail.exempt")) {
|
||||
sender.sendMessage(tl("mayNotJail"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
final User controller = sender.isPlayer() ? ess.getUser(sender.getPlayer()) : null;
|
||||
final JailStatusChangeEvent event = new JailStatusChangeEvent(player, controller, true);
|
||||
ess.getServer().getPluginManager().callEvent(event);
|
||||
|
||||
if (!event.isCancelled()) {
|
||||
if (player.getBase().isOnline()) {
|
||||
ess.getJails().sendToJail(player, args[1]);
|
||||
} else {
|
||||
// Check if jail exists
|
||||
ess.getJails().getJail(args[1]);
|
||||
}
|
||||
player.setJailed(true);
|
||||
player.sendMessage(tl("userJailed"));
|
||||
player.setJail(null);
|
||||
player.setJail(args[1]);
|
||||
long timeDiff = 0;
|
||||
if (args.length > 2) {
|
||||
final String time = getFinalArg(args, 2);
|
||||
timeDiff = DateUtil.parseDateDiff(time, true);
|
||||
player.setJailTimeout(timeDiff);
|
||||
}
|
||||
sender.sendMessage((timeDiff > 0 ? tl("playerJailedFor", player.getName(), DateUtil.formatDateDiff(timeDiff)) : tl("playerJailed", player.getName())));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.length >= 2 && player.isJailed() && !args[1].equalsIgnoreCase(player.getJail())) {
|
||||
sender.sendMessage(tl("jailAlreadyIncarcerated", player.getJail()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.length >= 2 && player.isJailed() && args[1].equalsIgnoreCase(player.getJail())) {
|
||||
final String time = getFinalArg(args, 2);
|
||||
final long timeDiff = DateUtil.parseDateDiff(time, true);
|
||||
player.setJailTimeout(timeDiff);
|
||||
sender.sendMessage(tl("jailSentenceExtended", DateUtil.formatDateDiff(timeDiff)));
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.length == 1 || (args.length == 2 && args[1].equalsIgnoreCase(player.getJail()))) {
|
||||
if (!player.isJailed()) {
|
||||
throw new NotEnoughArgumentsException();
|
||||
}
|
||||
final User controller = sender.isPlayer() ? ess.getUser(sender.getPlayer()) : null;
|
||||
final JailStatusChangeEvent event = new JailStatusChangeEvent(player, controller, false);
|
||||
ess.getServer().getPluginManager().callEvent(event);
|
||||
|
||||
if (!event.isCancelled()) {
|
||||
player.setJailed(false);
|
||||
player.setJailTimeout(0);
|
||||
player.sendMessage(tl("jailReleasedPlayerNotify"));
|
||||
player.setJail(null);
|
||||
if (player.getBase().isOnline()) {
|
||||
player.getTeleport().back();
|
||||
}
|
||||
sender.sendMessage(tl("jailReleased", player.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getTabCompleteOptions(final Server server, final CommandSource sender, final String commandLabel, final String[] args) {
|
||||
if (args.length == 1) {
|
||||
return getPlayers(server, sender);
|
||||
} else if (args.length == 2) {
|
||||
try {
|
||||
return new ArrayList<>(ess.getJails().getList());
|
||||
} catch (Exception e) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
} else {
|
||||
return COMMON_DATE_DIFFS;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.Teleport;
|
||||
import com.earth2me.essentials.Trade;
|
||||
import com.earth2me.essentials.User;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandtpaccept extends EssentialsCommand {
|
||||
public Commandtpaccept() {
|
||||
super("tpaccept");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
final User requester;
|
||||
try {
|
||||
requester = ess.getUser(user.getTeleportRequest());
|
||||
} catch (Exception ex) {
|
||||
throw new Exception(tl("noPendingRequest"));
|
||||
}
|
||||
|
||||
if (!requester.getBase().isOnline()) {
|
||||
throw new Exception(tl("noPendingRequest"));
|
||||
}
|
||||
|
||||
if (user.isTpRequestHere() && ((!requester.isAuthorized("essentials.tpahere") && !requester.isAuthorized("essentials.tpaall")) || (user.getWorld() != requester.getWorld() && ess.getSettings().isWorldTeleportPermissions() && !user.isAuthorized("essentials.worlds." + user.getWorld().getName())))) {
|
||||
throw new Exception(tl("noPendingRequest"));
|
||||
}
|
||||
|
||||
if (!user.isTpRequestHere() && (!requester.isAuthorized("essentials.tpa") || (user.getWorld() != requester.getWorld() && ess.getSettings().isWorldTeleportPermissions() && !user.isAuthorized("essentials.worlds." + requester.getWorld().getName())))) {
|
||||
throw new Exception(tl("noPendingRequest"));
|
||||
}
|
||||
|
||||
if (args.length > 0 && !requester.getName().contains(args[0])) {
|
||||
throw new Exception(tl("noPendingRequest"));
|
||||
}
|
||||
|
||||
if (!user.hasOutstandingTeleportRequest()) {
|
||||
user.requestTeleport(null, false);
|
||||
throw new Exception(tl("requestTimedOut"));
|
||||
}
|
||||
|
||||
final Trade charge = new Trade(this.getName(), ess);
|
||||
user.sendMessage(tl("requestAccepted"));
|
||||
requester.sendMessage(tl("requestAcceptedFrom", user.getDisplayName()));
|
||||
|
||||
try {
|
||||
if (user.isTpRequestHere()) {
|
||||
final Location loc = user.getTpRequestLocation();
|
||||
Teleport teleport = requester.getTeleport();
|
||||
teleport.setTpType(Teleport.TeleportType.TPA);
|
||||
teleport.teleportPlayer(user, user.getTpRequestLocation(), charge, TeleportCause.COMMAND);
|
||||
requester.sendMessage(tl("teleporting", loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
|
||||
} else {
|
||||
Teleport teleport = requester.getTeleport();
|
||||
teleport.setTpType(Teleport.TeleportType.TPA);
|
||||
teleport.teleport(user.getBase(), charge, TeleportCause.COMMAND);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
user.sendMessage(tl("pendingTeleportCancelled"));
|
||||
ess.showError(requester.getSource(), ex, commandLabel);
|
||||
}
|
||||
user.requestTeleport(null, false);
|
||||
throw new NoChargeException();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import com.earth2me.essentials.User;
|
||||
import org.bukkit.Server;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class Commandtpdeny extends EssentialsCommand {
|
||||
public Commandtpdeny() {
|
||||
super("tpdeny");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final Server server, final User user, final String commandLabel, final String[] args) throws Exception {
|
||||
if (user.getTeleportRequest() == null) {
|
||||
throw new Exception(tl("noPendingRequest"));
|
||||
}
|
||||
final User player = ess.getUser(user.getTeleportRequest());
|
||||
if (player == null) {
|
||||
throw new Exception(tl("noPendingRequest"));
|
||||
}
|
||||
|
||||
user.sendMessage(tl("requestDenied"));
|
||||
player.sendMessage(tl("requestDeniedFrom", user.getDisplayName()));
|
||||
user.requestTeleport(null, false);
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package com.earth2me.essentials.craftbukkit;
|
||||
|
||||
import com.earth2me.essentials.User;
|
||||
import net.ess3.api.IEssentials;
|
||||
import org.bukkit.BanEntry;
|
||||
import org.bukkit.BanList;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
public class BanLookup {
|
||||
public static Boolean isBanned(IEssentials ess, User user) {
|
||||
return isBanned(ess, user.getName());
|
||||
}
|
||||
|
||||
public static Boolean isBanned(IEssentials ess, String name) {
|
||||
return getBanEntry(ess, name) != null;
|
||||
}
|
||||
|
||||
public static BanEntry getBanEntry(IEssentials ess, String name) {
|
||||
Set<BanEntry> benteries = ess.getServer().getBanList(BanList.Type.NAME).getBanEntries();
|
||||
for (BanEntry banEnt : benteries) {
|
||||
if (banEnt.getTarget().equals(name)) {
|
||||
return banEnt;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,314 +0,0 @@
|
||||
package com.earth2me.essentials.items;
|
||||
|
||||
import com.earth2me.essentials.IConf;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.utils.MaterialUtil;
|
||||
import com.earth2me.essentials.utils.VersionUtil;
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.api.PluginKey;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.block.Banner;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.*;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.potion.Potion;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
public abstract class AbstractItemDb implements IConf, net.ess3.api.IItemDb {
|
||||
|
||||
protected final IEssentials ess;
|
||||
protected boolean ready = false;
|
||||
|
||||
private Map<PluginKey, ItemResolver> resolverMap = new HashMap<>();
|
||||
|
||||
AbstractItemDb(IEssentials ess) {
|
||||
this.ess = ess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerResolver(Plugin plugin, String name, ItemResolver resolver) throws Exception {
|
||||
PluginKey key = PluginKey.fromKey(plugin, name);
|
||||
if (resolverMap.containsKey(key)) {
|
||||
throw new Exception("Tried to add a duplicate resolver with name " + key.toString());
|
||||
}
|
||||
|
||||
resolverMap.put(key, resolver);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterResolver(Plugin plugin, String name) throws Exception {
|
||||
PluginKey key = PluginKey.fromKey(plugin, name);
|
||||
if (!resolverMap.containsKey(key)) {
|
||||
throw new Exception("Tried to remove nonexistent resolver with name " + key.toString());
|
||||
}
|
||||
|
||||
resolverMap.remove(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isResolverPresent(Plugin plugin, String name) {
|
||||
return resolverMap.containsKey(PluginKey.fromKey(plugin, name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<PluginKey, ItemResolver> getResolvers() {
|
||||
return new HashMap<>(resolverMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<PluginKey, ItemResolver> getResolvers(Plugin plugin) {
|
||||
Map<PluginKey, ItemResolver> matchingResolvers = new HashMap<>();
|
||||
for (PluginKey key : resolverMap.keySet()) {
|
||||
if (key.getPlugin().equals(plugin)) {
|
||||
matchingResolvers.put(key, resolverMap.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
return matchingResolvers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemResolver getResolver(Plugin plugin, String name) {
|
||||
return resolverMap.get(PluginKey.fromKey(plugin, name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack get(String id) throws Exception {
|
||||
return get(id, true);
|
||||
}
|
||||
|
||||
ItemStack tryResolvers(String id) {
|
||||
for (PluginKey key : resolverMap.keySet()) {
|
||||
if (ess.getSettings().isDebug()) {
|
||||
ess.getLogger().info(String.format("Trying resolver '%s' for item '%s'...", key, id));
|
||||
}
|
||||
|
||||
Function<String, ItemStack> resolver = resolverMap.get(key);
|
||||
ItemStack stack = resolver.apply(id);
|
||||
|
||||
if (stack != null) {
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
Collection<String> getResolverNames() {
|
||||
return resolverMap.values().stream()
|
||||
.map(ItemResolver::getNames)
|
||||
.flatMap(Collection::stream)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemStack> getMatching(User user, String[] args) throws Exception {
|
||||
List<ItemStack> is = new ArrayList<>();
|
||||
|
||||
if (args.length < 1) {
|
||||
is.add(user.getItemInHand().clone());
|
||||
} else if (args[0].equalsIgnoreCase("hand")) {
|
||||
is.add(user.getItemInHand().clone());
|
||||
} else if (args[0].equalsIgnoreCase("inventory") || args[0].equalsIgnoreCase("invent") || args[0].equalsIgnoreCase("all")) {
|
||||
for (ItemStack stack : user.getBase().getInventory().getContents()) {
|
||||
if (stack == null || stack.getType() == Material.AIR) {
|
||||
continue;
|
||||
}
|
||||
is.add(stack.clone());
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("blocks")) {
|
||||
for (ItemStack stack : user.getBase().getInventory().getContents()) {
|
||||
if (stack == null || stack.getType() == Material.AIR) {
|
||||
continue;
|
||||
}
|
||||
is.add(stack.clone());
|
||||
}
|
||||
} else {
|
||||
is.add(get(args[0]));
|
||||
}
|
||||
|
||||
if (is.isEmpty() || is.get(0).getType() == Material.AIR) {
|
||||
throw new Exception(tl("itemSellAir"));
|
||||
}
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String serialize(ItemStack is) {
|
||||
String mat = name(is);
|
||||
if (VersionUtil.getServerBukkitVersion().isLowerThanOrEqualTo(VersionUtil.v1_12_2_R01) && is.getData().getData() != 0) {
|
||||
mat = mat + ":" + is.getData().getData();
|
||||
}
|
||||
int quantity = is.getAmount();
|
||||
StringBuilder sb = new StringBuilder(); // Add space AFTER you add something. We can trim at end.
|
||||
sb.append(mat).append(" ").append(quantity).append(" ");
|
||||
|
||||
// ItemMeta applies to anything.
|
||||
if (is.hasItemMeta()) {
|
||||
ItemMeta meta = is.getItemMeta();
|
||||
if (meta.hasDisplayName()) {
|
||||
sb.append("name:").append(meta.getDisplayName().replaceAll(" ", "_")).append(" ");
|
||||
}
|
||||
|
||||
if (meta.hasLore()) {
|
||||
sb.append("lore:");
|
||||
boolean first = true;
|
||||
for (String s : meta.getLore()) {
|
||||
// Add | before the line if it's not the first one. Easy but weird way
|
||||
// to do this since we need each line separated by |
|
||||
if (!first) {
|
||||
sb.append("|");
|
||||
}
|
||||
first = false;
|
||||
sb.append(s.replaceAll(" ", "_"));
|
||||
}
|
||||
sb.append(" ");
|
||||
}
|
||||
|
||||
if (meta.hasEnchants()) {
|
||||
for (Enchantment e : meta.getEnchants().keySet()) {
|
||||
sb.append(e.getName().toLowerCase()).append(":").append(meta.getEnchantLevel(e)).append(" ");
|
||||
}
|
||||
}
|
||||
|
||||
Set<ItemFlag> flags = meta.getItemFlags();
|
||||
if (flags != null && !flags.isEmpty()) {
|
||||
sb.append("itemflags:");
|
||||
boolean first = true;
|
||||
for (ItemFlag flag : flags) {
|
||||
if (!first) {
|
||||
sb.append(",");
|
||||
}
|
||||
sb.append(flag.name());
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final Material material = is.getType();
|
||||
|
||||
switch (material) {
|
||||
case WRITTEN_BOOK:
|
||||
// Everything from http://wiki.ess3.net/wiki/Item_Meta#Books in that order.
|
||||
// Interesting as I didn't see a way to do pages or chapters.
|
||||
BookMeta bookMeta = (BookMeta) is.getItemMeta();
|
||||
if (bookMeta.hasTitle()) {
|
||||
sb.append("title:").append(bookMeta.getTitle()).append(" ");
|
||||
}
|
||||
if (bookMeta.hasAuthor()) {
|
||||
sb.append("author:").append(bookMeta.getAuthor()).append(" ");
|
||||
}
|
||||
// Only other thing it could have is lore but that's done up there ^^^
|
||||
break;
|
||||
case ENCHANTED_BOOK:
|
||||
EnchantmentStorageMeta enchantmentStorageMeta = (EnchantmentStorageMeta) is.getItemMeta();
|
||||
for (Enchantment e : enchantmentStorageMeta.getStoredEnchants().keySet()) {
|
||||
sb.append(e.getName().toLowerCase()).append(":").append(enchantmentStorageMeta.getStoredEnchantLevel(e)).append(" ");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (MaterialUtil.isFirework(material)) {
|
||||
// Everything from http://wiki.ess3.net/wiki/Item_Meta#Fireworks in that order.
|
||||
FireworkMeta fireworkMeta = (FireworkMeta) is.getItemMeta();
|
||||
if (fireworkMeta.hasEffects()) {
|
||||
for (FireworkEffect effect : fireworkMeta.getEffects()) {
|
||||
if (effect.getColors() != null && !effect.getColors().isEmpty()) {
|
||||
sb.append("color:");
|
||||
boolean first = true;
|
||||
for (Color c : effect.getColors()) {
|
||||
if (!first) {
|
||||
sb.append(","); // same thing as above.
|
||||
}
|
||||
sb.append(c.toString());
|
||||
first = false;
|
||||
}
|
||||
sb.append(" ");
|
||||
}
|
||||
|
||||
sb.append("shape:").append(effect.getType().name()).append(" ");
|
||||
if (effect.getFadeColors() != null && !effect.getFadeColors().isEmpty()) {
|
||||
sb.append("fade:");
|
||||
boolean first = true;
|
||||
for (Color c : effect.getFadeColors()) {
|
||||
if (!first) {
|
||||
sb.append(","); // same thing as above.
|
||||
}
|
||||
sb.append(c.toString());
|
||||
first = false;
|
||||
}
|
||||
sb.append(" ");
|
||||
}
|
||||
}
|
||||
sb.append("power:").append(fireworkMeta.getPower()).append(" ");
|
||||
}
|
||||
} else if (MaterialUtil.isPotion(material)) {
|
||||
Potion potion = Potion.fromItemStack(is);
|
||||
for (PotionEffect e : potion.getEffects()) {
|
||||
// long but needs to be effect:speed power:2 duration:120 in that order.
|
||||
sb.append("splash:").append(potion.isSplash()).append(" ").append("effect:").append(e.getType().getName().toLowerCase()).append(" ").append("power:").append(e.getAmplifier()).append(" ").append("duration:").append(e.getDuration() / 20).append(" ");
|
||||
}
|
||||
} else if (MaterialUtil.isPlayerHead(material, is.getData().getData())) {
|
||||
// item stack with meta
|
||||
SkullMeta skullMeta = (SkullMeta) is.getItemMeta();
|
||||
if (skullMeta != null && skullMeta.hasOwner()) {
|
||||
sb.append("player:").append(skullMeta.getOwner()).append(" ");
|
||||
}
|
||||
} else if (MaterialUtil.isBanner(material)) {
|
||||
if (material.toString().contains("SHIELD")) {
|
||||
// Hacky fix for accessing Shield meta - https://github.com/drtshock/Essentials/pull/745#issuecomment-234843795
|
||||
BlockStateMeta shieldMeta = (BlockStateMeta) is.getItemMeta();
|
||||
Banner shieldBannerMeta = (Banner) shieldMeta.getBlockState();
|
||||
DyeColor baseDyeColor = shieldBannerMeta.getBaseColor();
|
||||
if (baseDyeColor != null) {
|
||||
int basecolor = baseDyeColor.getColor().asRGB();
|
||||
sb.append("basecolor:").append(basecolor).append(" ");
|
||||
}
|
||||
for (org.bukkit.block.banner.Pattern p : shieldBannerMeta.getPatterns()) {
|
||||
String type = p.getPattern().getIdentifier();
|
||||
int color = p.getColor().getColor().asRGB();
|
||||
sb.append(type).append(",").append(color).append(" ");
|
||||
}
|
||||
} else {
|
||||
BannerMeta bannerMeta = (BannerMeta) is.getItemMeta();
|
||||
if (bannerMeta != null) {
|
||||
DyeColor baseDyeColor = bannerMeta.getBaseColor();
|
||||
if (baseDyeColor == null) {
|
||||
baseDyeColor = MaterialUtil.getColorOf(material);
|
||||
}
|
||||
if (baseDyeColor != null) {
|
||||
int basecolor = baseDyeColor
|
||||
.getColor()
|
||||
.asRGB();
|
||||
sb.append("basecolor:").append(basecolor).append(" ");
|
||||
}
|
||||
for (org.bukkit.block.banner.Pattern p : bannerMeta.getPatterns()) {
|
||||
String type = p.getPattern().getIdentifier();
|
||||
int color = p.getColor().getColor().asRGB();
|
||||
sb.append(type).append(",").append(color).append(" ");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (MaterialUtil.isLeatherArmor(material)) {
|
||||
LeatherArmorMeta leatherArmorMeta = (LeatherArmorMeta) is.getItemMeta();
|
||||
int rgb = leatherArmorMeta.getColor().asRGB();
|
||||
sb.append("color:").append(rgb).append(" ");
|
||||
}
|
||||
|
||||
return sb.toString().trim().replaceAll("§", "&");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReady() {
|
||||
return ready;
|
||||
}
|
||||
}
|
||||
@@ -1,715 +0,0 @@
|
||||
package com.earth2me.essentials.metrics;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.logging.Level;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
/**
|
||||
* bStats collects some data for plugin authors.
|
||||
* <p>
|
||||
* Check out https://bStats.org/ to learn more about bStats!
|
||||
*/
|
||||
@SuppressWarnings({"WeakerAccess", "unused"})
|
||||
public class Metrics {
|
||||
|
||||
static {
|
||||
// You can use the property to disable the check in your test environment
|
||||
if (System.getProperty("bstats.relocatecheck") == null || !System.getProperty("bstats.relocatecheck").equals("false")) {
|
||||
// Maven's Relocate is clever and changes strings, too. So we have to use this little "trick" ... :D
|
||||
final String defaultPackage = new String(
|
||||
new byte[]{'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'k', 'k', 'i', 't'});
|
||||
final String examplePackage = new String(new byte[]{'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
|
||||
// We want to make sure nobody just copy & pastes the example and use the wrong package names
|
||||
if (Metrics.class.getPackage().getName().equals(defaultPackage) || Metrics.class.getPackage().getName().equals(examplePackage)) {
|
||||
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The version of this bStats class
|
||||
public static final int B_STATS_VERSION = 1;
|
||||
|
||||
// The url to which the data is sent
|
||||
private static final String URL = "https://bStats.org/submitData/bukkit";
|
||||
|
||||
// Is bStats enabled on this server?
|
||||
private boolean enabled;
|
||||
|
||||
// Should failed requests be logged?
|
||||
private static boolean logFailedRequests;
|
||||
|
||||
// Should the sent data be logged?
|
||||
private static boolean logSentData;
|
||||
|
||||
// Should the response text be logged?
|
||||
private static boolean logResponseStatusText;
|
||||
|
||||
// The uuid of the server
|
||||
private static String serverUUID;
|
||||
|
||||
// The plugin
|
||||
private final Plugin plugin;
|
||||
|
||||
// A list with all custom charts
|
||||
private final List<CustomChart> charts = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param plugin The plugin which stats should be submitted.
|
||||
*/
|
||||
public Metrics(Plugin plugin) {
|
||||
if (plugin == null) {
|
||||
throw new IllegalArgumentException("Plugin cannot be null!");
|
||||
}
|
||||
this.plugin = plugin;
|
||||
|
||||
// Get the config file
|
||||
File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
|
||||
File configFile = new File(bStatsFolder, "config.yml");
|
||||
YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
|
||||
|
||||
// Check if the config file exists
|
||||
if (!config.isSet("serverUuid")) {
|
||||
|
||||
// Add default values
|
||||
config.addDefault("enabled", true);
|
||||
// Every server gets it's unique random id.
|
||||
config.addDefault("serverUuid", UUID.randomUUID().toString());
|
||||
// Should failed request be logged?
|
||||
config.addDefault("logFailedRequests", false);
|
||||
// Should the sent data be logged?
|
||||
config.addDefault("logSentData", false);
|
||||
// Should the response text be logged?
|
||||
config.addDefault("logResponseStatusText", false);
|
||||
|
||||
// Inform the server owners about bStats
|
||||
config.options().header(
|
||||
"bStats collects some data for plugin authors like how many servers are using their plugins.\n" +
|
||||
"To honor their work, you should not disable it.\n" +
|
||||
"This has nearly no effect on the server performance!\n" +
|
||||
"Check out https://bStats.org/ to learn more :)"
|
||||
).copyDefaults(true);
|
||||
try {
|
||||
config.save(configFile);
|
||||
} catch (IOException ignored) { }
|
||||
}
|
||||
|
||||
// Load the data
|
||||
enabled = config.getBoolean("enabled", true);
|
||||
serverUUID = config.getString("serverUuid");
|
||||
logFailedRequests = config.getBoolean("logFailedRequests", false);
|
||||
logSentData = config.getBoolean("logSentData", false);
|
||||
logResponseStatusText = config.getBoolean("logResponseStatusText", false);
|
||||
|
||||
if (enabled) {
|
||||
boolean found = false;
|
||||
// Search for all other bStats Metrics classes to see if we are the first one
|
||||
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
|
||||
try {
|
||||
service.getField("B_STATS_VERSION"); // Our identifier :)
|
||||
found = true; // We aren't the first
|
||||
break;
|
||||
} catch (NoSuchFieldException ignored) { }
|
||||
}
|
||||
// Register our service
|
||||
Bukkit.getServicesManager().register(Metrics.class, this, plugin, ServicePriority.Normal);
|
||||
if (!found) {
|
||||
// We are the first!
|
||||
startSubmitting();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if bStats is enabled.
|
||||
*
|
||||
* @return Whether bStats is enabled or not.
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a custom chart.
|
||||
*
|
||||
* @param chart The chart to add.
|
||||
*/
|
||||
public void addCustomChart(CustomChart chart) {
|
||||
if (chart == null) {
|
||||
throw new IllegalArgumentException("Chart cannot be null!");
|
||||
}
|
||||
charts.add(chart);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the Scheduler which submits our data every 30 minutes.
|
||||
*/
|
||||
private void startSubmitting() {
|
||||
final Timer timer = new Timer(true); // We use a timer cause the Bukkit scheduler is affected by server lags
|
||||
timer.scheduleAtFixedRate(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!plugin.isEnabled()) { // Plugin was disabled
|
||||
timer.cancel();
|
||||
return;
|
||||
}
|
||||
// Nevertheless we want our code to run in the Bukkit main thread, so we have to use the Bukkit scheduler
|
||||
// Don't be afraid! The connection to the bStats server is still async, only the stats collection is sync ;)
|
||||
Bukkit.getScheduler().runTask(plugin, () -> submitData());
|
||||
}
|
||||
}, 1000 * 60 * 5, 1000 * 60 * 30);
|
||||
// Submit the data every 30 minutes, first time after 5 minutes to give other plugins enough time to start
|
||||
// WARNING: Changing the frequency has no effect but your plugin WILL be blocked/deleted!
|
||||
// WARNING: Just don't do it!
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the plugin specific data.
|
||||
* This method is called using Reflection.
|
||||
*
|
||||
* @return The plugin specific data.
|
||||
*/
|
||||
public JsonObject getPluginData() {
|
||||
JsonObject data = new JsonObject();
|
||||
|
||||
String pluginName = plugin.getDescription().getName().replace("Essentials", "EssentialsX");
|
||||
String pluginVersion = plugin.getDescription().getVersion();
|
||||
|
||||
data.addProperty("pluginName", pluginName); // Append the name of the plugin
|
||||
data.addProperty("pluginVersion", pluginVersion); // Append the version of the plugin
|
||||
JsonArray customCharts = new JsonArray();
|
||||
for (CustomChart customChart : charts) {
|
||||
// Add the data of the custom charts
|
||||
JsonObject chart = customChart.getRequestJsonObject();
|
||||
if (chart == null) { // If the chart is null, we skip it
|
||||
continue;
|
||||
}
|
||||
customCharts.add(chart);
|
||||
}
|
||||
data.add("customCharts", customCharts);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the server specific data.
|
||||
*
|
||||
* @return The server specific data.
|
||||
*/
|
||||
private JsonObject getServerData() {
|
||||
// Minecraft specific data
|
||||
int playerAmount;
|
||||
try {
|
||||
// Around MC 1.8 the return type was changed to a collection from an array,
|
||||
// This fixes java.lang.NoSuchMethodError: org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection;
|
||||
Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers");
|
||||
playerAmount = onlinePlayersMethod.getReturnType().equals(Collection.class)
|
||||
? ((Collection<?>) onlinePlayersMethod.invoke(Bukkit.getServer())).size()
|
||||
: ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length;
|
||||
} catch (Exception e) {
|
||||
playerAmount = Bukkit.getOnlinePlayers().size(); // Just use the new method if the Reflection failed
|
||||
}
|
||||
int onlineMode = Bukkit.getOnlineMode() ? 1 : 0;
|
||||
String bukkitVersion = Bukkit.getVersion();
|
||||
String bukkitName = Bukkit.getName();
|
||||
|
||||
// OS/Java specific data
|
||||
String javaVersion = System.getProperty("java.version");
|
||||
String osName = System.getProperty("os.name");
|
||||
String osArch = System.getProperty("os.arch");
|
||||
String osVersion = System.getProperty("os.version");
|
||||
int coreCount = Runtime.getRuntime().availableProcessors();
|
||||
|
||||
JsonObject data = new JsonObject();
|
||||
|
||||
data.addProperty("serverUUID", serverUUID);
|
||||
|
||||
data.addProperty("playerAmount", playerAmount);
|
||||
data.addProperty("onlineMode", onlineMode);
|
||||
data.addProperty("bukkitVersion", bukkitVersion);
|
||||
data.addProperty("bukkitName", bukkitName);
|
||||
|
||||
data.addProperty("javaVersion", javaVersion);
|
||||
data.addProperty("osName", osName);
|
||||
data.addProperty("osArch", osArch);
|
||||
data.addProperty("osVersion", osVersion);
|
||||
data.addProperty("coreCount", coreCount);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects the data and sends it afterwards.
|
||||
*/
|
||||
private void submitData() {
|
||||
final JsonObject data = getServerData();
|
||||
|
||||
JsonArray pluginData = new JsonArray();
|
||||
// Search for all other bStats Metrics classes to get their plugin data
|
||||
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
|
||||
try {
|
||||
service.getField("B_STATS_VERSION"); // Our identifier :)
|
||||
|
||||
for (RegisteredServiceProvider<?> provider : Bukkit.getServicesManager().getRegistrations(service)) {
|
||||
try {
|
||||
Object plugin = provider.getService().getMethod("getPluginData").invoke(provider.getProvider());
|
||||
if (plugin instanceof JsonObject) {
|
||||
pluginData.add((JsonObject) plugin);
|
||||
} else { // old bstats version compatibility
|
||||
try {
|
||||
Class<?> jsonObjectJsonSimple = Class.forName("org.json.simple.JSONObject");
|
||||
if (plugin.getClass().isAssignableFrom(jsonObjectJsonSimple)) {
|
||||
Method jsonStringGetter = jsonObjectJsonSimple.getDeclaredMethod("toJSONString");
|
||||
jsonStringGetter.setAccessible(true);
|
||||
String jsonString = (String) jsonStringGetter.invoke(plugin);
|
||||
JsonObject object = new JsonParser().parse(jsonString).getAsJsonObject();
|
||||
pluginData.add(object);
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
// minecraft version 1.14+
|
||||
if (logFailedRequests) {
|
||||
this.plugin.getLogger().log(Level.SEVERE, "Encountered unexpected exception", e);
|
||||
}
|
||||
continue; // continue looping since we cannot do any other thing.
|
||||
}
|
||||
}
|
||||
} catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { }
|
||||
}
|
||||
} catch (NoSuchFieldException ignored) { }
|
||||
}
|
||||
|
||||
data.add("plugins", pluginData);
|
||||
|
||||
// Create a new thread for the connection to the bStats server
|
||||
new Thread(() -> {
|
||||
try {
|
||||
// Send the data
|
||||
sendData(plugin, data);
|
||||
} catch (Exception e) {
|
||||
// Something went wrong! :(
|
||||
if (logFailedRequests) {
|
||||
plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " + plugin.getName(), e);
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the data to the bStats server.
|
||||
*
|
||||
* @param plugin Any plugin. It's just used to get a logger instance.
|
||||
* @param data The data to send.
|
||||
* @throws Exception If the request failed.
|
||||
*/
|
||||
private static void sendData(Plugin plugin, JsonObject data) throws Exception {
|
||||
if (data == null) {
|
||||
throw new IllegalArgumentException("Data cannot be null!");
|
||||
}
|
||||
if (Bukkit.isPrimaryThread()) {
|
||||
throw new IllegalAccessException("This method must not be called from the main thread!");
|
||||
}
|
||||
if (logSentData) {
|
||||
plugin.getLogger().info("Sending data to bStats: " + data.toString());
|
||||
}
|
||||
HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection();
|
||||
|
||||
// Compress the data to save bandwidth
|
||||
byte[] compressedData = compress(data.toString());
|
||||
|
||||
// Add headers
|
||||
connection.setRequestMethod("POST");
|
||||
connection.addRequestProperty("Accept", "application/json");
|
||||
connection.addRequestProperty("Connection", "close");
|
||||
connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request
|
||||
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
|
||||
connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format
|
||||
connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION);
|
||||
|
||||
// Send data
|
||||
connection.setDoOutput(true);
|
||||
DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
|
||||
outputStream.write(compressedData);
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
|
||||
InputStream inputStream = connection.getInputStream();
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
String line;
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
builder.append(line);
|
||||
}
|
||||
bufferedReader.close();
|
||||
if (logResponseStatusText) {
|
||||
plugin.getLogger().info("Sent data to bStats and received response: " + builder.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gzips the given String.
|
||||
*
|
||||
* @param str The string to gzip.
|
||||
* @return The gzipped String.
|
||||
* @throws IOException If the compression failed.
|
||||
*/
|
||||
private static byte[] compress(final String str) throws IOException {
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
GZIPOutputStream gzip = new GZIPOutputStream(outputStream);
|
||||
gzip.write(str.getBytes(StandardCharsets.UTF_8));
|
||||
gzip.close();
|
||||
return outputStream.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom chart.
|
||||
*/
|
||||
public static abstract class CustomChart {
|
||||
|
||||
// The id of the chart
|
||||
final String chartId;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
*/
|
||||
CustomChart(String chartId) {
|
||||
if (chartId == null || chartId.isEmpty()) {
|
||||
throw new IllegalArgumentException("ChartId cannot be null or empty!");
|
||||
}
|
||||
this.chartId = chartId;
|
||||
}
|
||||
|
||||
private JsonObject getRequestJsonObject() {
|
||||
JsonObject chart = new JsonObject();
|
||||
chart.addProperty("chartId", chartId);
|
||||
try {
|
||||
JsonObject data = getChartData();
|
||||
if (data == null) {
|
||||
// If the data is null we don't send the chart.
|
||||
return null;
|
||||
}
|
||||
chart.add("data", data);
|
||||
} catch (Throwable t) {
|
||||
if (logFailedRequests) {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Failed to get data for custom chart with id " + chartId, t);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return chart;
|
||||
}
|
||||
|
||||
protected abstract JsonObject getChartData() throws Exception;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom simple pie.
|
||||
*/
|
||||
public static class SimplePie extends CustomChart {
|
||||
|
||||
private final Callable<String> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SimplePie(String chartId, Callable<String> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObject getChartData() throws Exception {
|
||||
JsonObject data = new JsonObject();
|
||||
String value = callable.call();
|
||||
if (value == null || value.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.addProperty("value", value);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom advanced pie.
|
||||
*/
|
||||
public static class AdvancedPie extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Integer>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public AdvancedPie(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObject getChartData() throws Exception {
|
||||
JsonObject data = new JsonObject();
|
||||
JsonObject values = new JsonObject();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
if (entry.getValue() == 0) {
|
||||
continue; // Skip this invalid
|
||||
}
|
||||
allSkipped = false;
|
||||
values.addProperty(entry.getKey(), entry.getValue());
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.add("values", values);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom drilldown pie.
|
||||
*/
|
||||
public static class DrilldownPie extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Map<String, Integer>>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public DrilldownPie(String chartId, Callable<Map<String, Map<String, Integer>>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject getChartData() throws Exception {
|
||||
JsonObject data = new JsonObject();
|
||||
JsonObject values = new JsonObject();
|
||||
Map<String, Map<String, Integer>> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean reallyAllSkipped = true;
|
||||
for (Map.Entry<String, Map<String, Integer>> entryValues : map.entrySet()) {
|
||||
JsonObject value = new JsonObject();
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> valueEntry : map.get(entryValues.getKey()).entrySet()) {
|
||||
value.addProperty(valueEntry.getKey(), valueEntry.getValue());
|
||||
allSkipped = false;
|
||||
}
|
||||
if (!allSkipped) {
|
||||
reallyAllSkipped = false;
|
||||
values.add(entryValues.getKey(), value);
|
||||
}
|
||||
}
|
||||
if (reallyAllSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.add("values", values);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom single line chart.
|
||||
*/
|
||||
public static class SingleLineChart extends CustomChart {
|
||||
|
||||
private final Callable<Integer> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SingleLineChart(String chartId, Callable<Integer> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObject getChartData() throws Exception {
|
||||
JsonObject data = new JsonObject();
|
||||
int value = callable.call();
|
||||
if (value == 0) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.addProperty("value", value);
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom multi line chart.
|
||||
*/
|
||||
public static class MultiLineChart extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Integer>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public MultiLineChart(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObject getChartData() throws Exception {
|
||||
JsonObject data = new JsonObject();
|
||||
JsonObject values = new JsonObject();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
if (entry.getValue() == 0) {
|
||||
continue; // Skip this invalid
|
||||
}
|
||||
allSkipped = false;
|
||||
values.addProperty(entry.getKey(), entry.getValue());
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.add("values", values);
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom simple bar chart.
|
||||
*/
|
||||
public static class SimpleBarChart extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, Integer>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public SimpleBarChart(String chartId, Callable<Map<String, Integer>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObject getChartData() throws Exception {
|
||||
JsonObject data = new JsonObject();
|
||||
JsonObject values = new JsonObject();
|
||||
Map<String, Integer> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
for (Map.Entry<String, Integer> entry : map.entrySet()) {
|
||||
JsonArray categoryValues = new JsonArray();
|
||||
categoryValues.add(entry.getValue());
|
||||
values.add(entry.getKey(), categoryValues);
|
||||
}
|
||||
data.add("values", values);
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a custom advanced bar chart.
|
||||
*/
|
||||
public static class AdvancedBarChart extends CustomChart {
|
||||
|
||||
private final Callable<Map<String, int[]>> callable;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param chartId The id of the chart.
|
||||
* @param callable The callable which is used to request the chart data.
|
||||
*/
|
||||
public AdvancedBarChart(String chartId, Callable<Map<String, int[]>> callable) {
|
||||
super(chartId);
|
||||
this.callable = callable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonObject getChartData() throws Exception {
|
||||
JsonObject data = new JsonObject();
|
||||
JsonObject values = new JsonObject();
|
||||
Map<String, int[]> map = callable.call();
|
||||
if (map == null || map.isEmpty()) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
boolean allSkipped = true;
|
||||
for (Map.Entry<String, int[]> entry : map.entrySet()) {
|
||||
if (entry.getValue().length == 0) {
|
||||
continue; // Skip this invalid
|
||||
}
|
||||
allSkipped = false;
|
||||
JsonArray categoryValues = new JsonArray();
|
||||
for (int categoryValue : entry.getValue()) {
|
||||
categoryValues.add(categoryValue);
|
||||
}
|
||||
values.add(entry.getKey(), categoryValues);
|
||||
}
|
||||
if (allSkipped) {
|
||||
// Null = skip the chart
|
||||
return null;
|
||||
}
|
||||
data.add("values", values);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package com.earth2me.essentials.perm.impl;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class PermissionsExHandler extends AbstractVaultHandler {
|
||||
@Override
|
||||
public boolean canBuild(final Player base, final String group) {
|
||||
return base != null && chat.getPlayerInfoBoolean(base.getWorld().getName(), base, "build", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryProvider() {
|
||||
return super.canLoad() && Bukkit.getPluginManager().getPlugin("PermissionsEx") != null;
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
package com.earth2me.essentials.perm.impl;
|
||||
|
||||
import com.earth2me.essentials.perm.IPermissionsHandler;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class SuperpermsHandler implements IPermissionsHandler {
|
||||
@Override
|
||||
public String getGroup(final Player base) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getGroups(final Player base) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBuild(final Player base, final String group) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inGroup(final Player base, final String group) {
|
||||
return hasPermission(base, "group." + group);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(final Player base, String node) {
|
||||
String permCheck = node;
|
||||
int index;
|
||||
while (true) {
|
||||
if (base.isPermissionSet(permCheck)) {
|
||||
return base.hasPermission(permCheck);
|
||||
}
|
||||
|
||||
index = node.lastIndexOf('.');
|
||||
if (index < 1) {
|
||||
return base.hasPermission("*");
|
||||
}
|
||||
|
||||
node = node.substring(0, index);
|
||||
permCheck = node + ".*";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPermissionSet(final Player base, final String node) {
|
||||
return base.isPermissionSet(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrefix(final Player base) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSuffix(final Player base) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryProvider() {
|
||||
return getEnabledPermsPlugin() != null;
|
||||
}
|
||||
|
||||
public String getEnabledPermsPlugin() {
|
||||
String enabledPermsPlugin = null;
|
||||
List<String> specialCasePlugins = Arrays.asList("PermissionsEx", "GroupManager",
|
||||
"SimplyPerms", "Privileges", "bPermissions", "zPermissions", "PermissionsBukkit",
|
||||
"DroxPerms", "xPerms", "LuckPerms");
|
||||
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
|
||||
if (specialCasePlugins.contains(plugin.getName())) {
|
||||
enabledPermsPlugin = plugin.getName();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return enabledPermsPlugin;
|
||||
}
|
||||
}
|
||||
@@ -1,222 +0,0 @@
|
||||
package com.earth2me.essentials.register.payment;
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
|
||||
/**
|
||||
* Interface to be implemented by a payment method.
|
||||
* Copyright (C) 2011
|
||||
* AOL license <http://aol.nexua.org>
|
||||
*
|
||||
* @author Nijikokun <nijikokun@shortmail.com> (@nijikokun)
|
||||
*/
|
||||
public interface Method {
|
||||
/**
|
||||
* Encodes the Plugin into an Object disguised as the Plugin. If you want the original Plugin Class you must cast it
|
||||
* to the correct Plugin, to do so you have to verify the name and or version then cast.
|
||||
* <p/>
|
||||
* <pre>
|
||||
* if(method.getName().equalsIgnoreCase("iConomy"))
|
||||
* iConomy plugin = ((iConomy)method.getPlugin());</pre>
|
||||
*
|
||||
* @return <code>Object</code>
|
||||
*
|
||||
* @see #getName()
|
||||
* @see #getVersion()
|
||||
*/
|
||||
Object getPlugin();
|
||||
|
||||
/**
|
||||
* Returns the actual name of this method.
|
||||
*
|
||||
* @return <code>String</code> Plugin name.
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Returns the reported name of this method.
|
||||
*
|
||||
* @return <code>String</code> Plugin name.
|
||||
*/
|
||||
String getLongName();
|
||||
|
||||
/**
|
||||
* Returns the actual version of this method.
|
||||
*
|
||||
* @return <code>String</code> Plugin version.
|
||||
*/
|
||||
String getVersion();
|
||||
|
||||
/**
|
||||
* Returns the amount of decimal places that get stored NOTE: it will return -1 if there is no rounding
|
||||
*
|
||||
* @return <code>int</code> for each decimal place
|
||||
*/
|
||||
int fractionalDigits();
|
||||
|
||||
/**
|
||||
* Formats amounts into this payment methods style of currency display.
|
||||
*
|
||||
* @param amount Double
|
||||
*
|
||||
* @return <code>String</code> - Formatted Currency Display.
|
||||
*/
|
||||
String format(double amount);
|
||||
|
||||
/**
|
||||
* Allows the verification of bank API existence in this payment method.
|
||||
*
|
||||
* @return <code>boolean</code>
|
||||
*/
|
||||
boolean hasBanks();
|
||||
|
||||
/**
|
||||
* Determines the existence of a bank via name.
|
||||
*
|
||||
* @param bank Bank name
|
||||
*
|
||||
* @return <code>boolean</code>
|
||||
*
|
||||
* @see #hasBanks
|
||||
*/
|
||||
boolean hasBank(String bank);
|
||||
|
||||
/**
|
||||
* Determines the existence of an account via name.
|
||||
*
|
||||
* @param name Account name
|
||||
*
|
||||
* @return <code>boolean</code>
|
||||
*/
|
||||
boolean hasAccount(String name);
|
||||
|
||||
/**
|
||||
* Check to see if an account <code>name</code> is tied to a <code>bank</code>.
|
||||
*
|
||||
* @param bank Bank name
|
||||
* @param name Account name
|
||||
*
|
||||
* @return <code>boolean</code>
|
||||
*/
|
||||
boolean hasBankAccount(String bank, String name);
|
||||
|
||||
/**
|
||||
* Forces an account creation
|
||||
*
|
||||
* @param name Account name
|
||||
*
|
||||
* @return <code>boolean</code>
|
||||
*/
|
||||
boolean createAccount(String name);
|
||||
|
||||
/**
|
||||
* Forces an account creation
|
||||
*
|
||||
* @param name Account name
|
||||
* @param balance Initial account balance
|
||||
*
|
||||
* @return <code>boolean</code>
|
||||
*/
|
||||
boolean createAccount(String name, Double balance);
|
||||
|
||||
/**
|
||||
* Returns a <code>MethodAccount</code> class for an account <code>name</code>.
|
||||
*
|
||||
* @param name Account name
|
||||
*
|
||||
* @return <code>MethodAccount</code> <em>or</em> <code>Null</code>
|
||||
*/
|
||||
MethodAccount getAccount(String name);
|
||||
|
||||
/**
|
||||
* Returns a <code>MethodBankAccount</code> class for an account <code>name</code>.
|
||||
*
|
||||
* @param bank Bank name
|
||||
* @param name Account name
|
||||
*
|
||||
* @return <code>MethodBankAccount</code> <em>or</em> <code>Null</code>
|
||||
*/
|
||||
MethodBankAccount getBankAccount(String bank, String name);
|
||||
|
||||
/**
|
||||
* Checks to verify the compatibility between this Method and a plugin. Internal usage only, for the most part.
|
||||
*
|
||||
* @param plugin Plugin
|
||||
*
|
||||
* @return <code>boolean</code>
|
||||
*/
|
||||
boolean isCompatible(Plugin plugin);
|
||||
|
||||
/**
|
||||
* Set Plugin data.
|
||||
*
|
||||
* @param plugin Plugin
|
||||
*/
|
||||
void setPlugin(Plugin plugin);
|
||||
|
||||
|
||||
/**
|
||||
* Contains Calculator and Balance functions for Accounts.
|
||||
*/
|
||||
interface MethodAccount {
|
||||
double balance();
|
||||
|
||||
boolean set(double amount);
|
||||
|
||||
boolean add(double amount);
|
||||
|
||||
boolean subtract(double amount);
|
||||
|
||||
boolean multiply(double amount);
|
||||
|
||||
boolean divide(double amount);
|
||||
|
||||
boolean hasEnough(double amount);
|
||||
|
||||
boolean hasOver(double amount);
|
||||
|
||||
boolean hasUnder(double amount);
|
||||
|
||||
boolean isNegative();
|
||||
|
||||
boolean remove();
|
||||
|
||||
@Override
|
||||
String toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Contains Calculator and Balance functions for Bank Accounts.
|
||||
*/
|
||||
interface MethodBankAccount {
|
||||
double balance();
|
||||
|
||||
String getBankName();
|
||||
|
||||
int getBankId();
|
||||
|
||||
boolean set(double amount);
|
||||
|
||||
boolean add(double amount);
|
||||
|
||||
boolean subtract(double amount);
|
||||
|
||||
boolean multiply(double amount);
|
||||
|
||||
boolean divide(double amount);
|
||||
|
||||
boolean hasEnough(double amount);
|
||||
|
||||
boolean hasOver(double amount);
|
||||
|
||||
boolean hasUnder(double amount);
|
||||
|
||||
boolean isNegative();
|
||||
|
||||
boolean remove();
|
||||
|
||||
@Override
|
||||
String toString();
|
||||
}
|
||||
}
|
||||
@@ -1,245 +0,0 @@
|
||||
package com.earth2me.essentials.register.payment;
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
/**
|
||||
* The <code>Methods</code> initializes Methods that utilize the Method interface based on a "first come, first served"
|
||||
* basis.
|
||||
* <p/>
|
||||
* Allowing you to check whether a payment method exists or not.
|
||||
* <p/>
|
||||
* Methods also allows you to set a preferred method of payment before it captures payment plugins in the initialization
|
||||
* process.
|
||||
* <p/>
|
||||
* in
|
||||
* <code>bukkit.yml</code>: <blockquote><pre>
|
||||
* economy:
|
||||
* preferred: "iConomy"
|
||||
* </pre></blockquote>
|
||||
*
|
||||
* @author Nijikokun <nijikokun@shortmail.com> (@nijikokun) @copyright: Copyright (C) 2011 @license: AOL license
|
||||
* <http://aol.nexua.org>
|
||||
*/
|
||||
public class Methods {
|
||||
private static String version = null;
|
||||
private static boolean self = false;
|
||||
private static Method Method = null;
|
||||
private static String preferred = "";
|
||||
private static final Set<Method> Methods = new HashSet<>();
|
||||
private static final Set<String> Dependencies = new HashSet<>();
|
||||
private static final Set<Method> Attachables = new HashSet<>();
|
||||
|
||||
static {
|
||||
_init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement all methods along with their respective name & class.
|
||||
*/
|
||||
private static void _init() {
|
||||
addMethod("Vault", new com.earth2me.essentials.register.payment.methods.VaultEco());
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by the plugin to setup version
|
||||
*
|
||||
* @param v version
|
||||
*/
|
||||
public static void setVersion(String v) {
|
||||
version = v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use to reset methods during disable
|
||||
*/
|
||||
public static void reset() {
|
||||
version = null;
|
||||
self = false;
|
||||
Method = null;
|
||||
preferred = "";
|
||||
Attachables.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Use to get version of Register plugin
|
||||
*
|
||||
* @return version
|
||||
*/
|
||||
public static String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of payment method names that have been loaded through the <code>_init</code> method.
|
||||
*
|
||||
* @return <code>Set<String></code> - Array of payment methods that are loaded.
|
||||
*
|
||||
* @see #setMethod(PluginManager)
|
||||
*/
|
||||
public static Set<String> getDependencies() {
|
||||
return Dependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interprets Plugin class data to verify whether it is compatible with an existing payment method to use for
|
||||
* payments and other various economic activity.
|
||||
*
|
||||
* @param plugin Plugin data from bukkit, Internal Class file.
|
||||
*
|
||||
* @return Method <em>or</em> Null
|
||||
*/
|
||||
public static Method createMethod(Plugin plugin) {
|
||||
for (Method method : Methods) {
|
||||
if (method.isCompatible(plugin)) {
|
||||
method.setPlugin(plugin);
|
||||
return method;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void addMethod(String name, Method method) {
|
||||
Dependencies.add(name);
|
||||
Methods.add(method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies if Register has set a payment method for usage yet.
|
||||
*
|
||||
* @return <code>boolean</code>
|
||||
*
|
||||
* @see #setMethod(PluginManager)
|
||||
* @see #checkDisabled(Plugin)
|
||||
*/
|
||||
public static boolean hasMethod() {
|
||||
return (Method != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks Plugin Class against a multitude of checks to verify it's usability as a payment method.
|
||||
*
|
||||
* @param manager the plugin manager for the server
|
||||
*
|
||||
* @return <code>boolean</code> True on success, False on failure.
|
||||
*/
|
||||
public static boolean setMethod(PluginManager manager) {
|
||||
if (hasMethod()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (self) {
|
||||
self = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
boolean match = false;
|
||||
Plugin plugin;
|
||||
|
||||
for (String name : getDependencies()) {
|
||||
if (hasMethod()) {
|
||||
break;
|
||||
}
|
||||
|
||||
plugin = manager.getPlugin(name);
|
||||
if (plugin == null || !plugin.isEnabled()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Method current = createMethod(plugin);
|
||||
if (current == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (preferred.isEmpty()) {
|
||||
Method = current;
|
||||
} else {
|
||||
Attachables.add(current);
|
||||
}
|
||||
}
|
||||
|
||||
if (!preferred.isEmpty()) {
|
||||
do {
|
||||
if (hasMethod()) {
|
||||
match = true;
|
||||
} else {
|
||||
for (Method attached : Attachables) {
|
||||
if (attached == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (hasMethod()) {
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (preferred.isEmpty()) {
|
||||
Method = attached;
|
||||
}
|
||||
|
||||
if (count == 0) {
|
||||
if (preferred.equalsIgnoreCase(attached.getName())) {
|
||||
Method = attached;
|
||||
} else {
|
||||
Method = attached;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
} while (!match);
|
||||
}
|
||||
|
||||
return hasMethod();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the preferred economy
|
||||
*
|
||||
* @return <code>boolean</code>
|
||||
*/
|
||||
public static boolean setPreferred(String check) {
|
||||
if (getDependencies().contains(check)) {
|
||||
preferred = check;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grab the existing and initialized (hopefully) Method Class.
|
||||
*
|
||||
* @return <code>Method</code> <em>or</em> <code>Null</code>
|
||||
*/
|
||||
public static Method getMethod() {
|
||||
return Method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify is a plugin is disabled, only does this if we there is an existing payment method initialized in
|
||||
* Register.
|
||||
*
|
||||
* @param method Plugin data from bukkit, Internal Class file.
|
||||
*
|
||||
* @return <code>boolean</code>
|
||||
*/
|
||||
public static boolean checkDisabled(Plugin method) {
|
||||
if (!hasMethod()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Method.isCompatible(method)) {
|
||||
Method = null;
|
||||
}
|
||||
|
||||
return (Method == null);
|
||||
}
|
||||
}
|
||||
@@ -1,282 +0,0 @@
|
||||
package com.earth2me.essentials.register.payment.methods;
|
||||
|
||||
import com.earth2me.essentials.register.payment.Method;
|
||||
import net.milkbowl.vault.economy.Economy;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
|
||||
|
||||
public class VaultEco implements Method {
|
||||
private Plugin vault;
|
||||
private Economy economy;
|
||||
|
||||
@Override
|
||||
public Plugin getPlugin() {
|
||||
return this.vault;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createAccount(String name, Double amount) {
|
||||
if (hasAccount(name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.vault.getDescription().getName();
|
||||
}
|
||||
|
||||
public String getEconomy() {
|
||||
return economy == null ? "NoEco" : economy.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLongName() {
|
||||
return getName().concat(" - Economy: ").concat(getEconomy());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return this.vault.getDescription().getVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int fractionalDigits() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String format(double amount) {
|
||||
return this.economy.format(amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasBanks() {
|
||||
return this.economy.hasBankSupport();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasBank(String bank) {
|
||||
return this.economy.getBanks().contains(bank);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAccount(String name) {
|
||||
return this.economy.hasAccount(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasBankAccount(String bank, String name) {
|
||||
return this.economy.isBankOwner(bank, name).transactionSuccess() || this.economy.isBankMember(bank, name).transactionSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createAccount(String name) {
|
||||
return this.economy.createBank(name, "").transactionSuccess();
|
||||
}
|
||||
|
||||
public boolean createAccount(String name, double balance) {
|
||||
if (!this.economy.createBank(name, "").transactionSuccess()) {
|
||||
return false;
|
||||
}
|
||||
return this.economy.bankDeposit(name, balance).transactionSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodAccount getAccount(String name) {
|
||||
if (!hasAccount(name)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new VaultAccount(name, this.economy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodBankAccount getBankAccount(String bank, String name) {
|
||||
if (!hasBankAccount(bank, name)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new VaultBankAccount(bank, economy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompatible(Plugin plugin) {
|
||||
try {
|
||||
RegisteredServiceProvider<Economy> ecoPlugin = plugin.getServer().getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class);
|
||||
return plugin.getName().equals("Vault") && ecoPlugin != null && !ecoPlugin.getProvider().getName().equals("Essentials Economy");
|
||||
} catch (LinkageError | Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlugin(Plugin plugin) {
|
||||
this.vault = plugin;
|
||||
RegisteredServiceProvider<Economy> economyProvider = this.vault.getServer().getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class);
|
||||
if (economyProvider != null) {
|
||||
this.economy = economyProvider.getProvider();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class VaultAccount implements MethodAccount {
|
||||
private final String name;
|
||||
private final Economy economy;
|
||||
|
||||
VaultAccount(String name, Economy economy) {
|
||||
this.name = name;
|
||||
this.economy = economy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double balance() {
|
||||
return this.economy.getBalance(this.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean set(double amount) {
|
||||
if (!this.economy.withdrawPlayer(this.name, this.balance()).transactionSuccess()) {
|
||||
return false;
|
||||
}
|
||||
if (amount == 0) {
|
||||
return true;
|
||||
}
|
||||
return this.economy.depositPlayer(this.name, amount).transactionSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(double amount) {
|
||||
return this.economy.depositPlayer(this.name, amount).transactionSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean subtract(double amount) {
|
||||
return this.economy.withdrawPlayer(this.name, amount).transactionSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean multiply(double amount) {
|
||||
double balance = this.balance();
|
||||
return this.set(balance * amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean divide(double amount) {
|
||||
double balance = this.balance();
|
||||
return this.set(balance / amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasEnough(double amount) {
|
||||
return (this.balance() >= amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasOver(double amount) {
|
||||
return (this.balance() > amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasUnder(double amount) {
|
||||
return (this.balance() < amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNegative() {
|
||||
return (this.balance() < 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove() {
|
||||
return this.set(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class VaultBankAccount implements MethodBankAccount {
|
||||
private final String bank;
|
||||
private final Economy economy;
|
||||
|
||||
public VaultBankAccount(String bank, Economy economy) {
|
||||
this.bank = bank;
|
||||
this.economy = economy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBankName() {
|
||||
return this.bank;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBankId() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double balance() {
|
||||
return this.economy.bankBalance(this.bank).balance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean set(double amount) {
|
||||
if (!this.economy.bankWithdraw(this.bank, this.balance()).transactionSuccess()) {
|
||||
return false;
|
||||
}
|
||||
if (amount == 0) {
|
||||
return true;
|
||||
}
|
||||
return this.economy.bankDeposit(this.bank, amount).transactionSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(double amount) {
|
||||
return this.economy.bankDeposit(this.bank, amount).transactionSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean subtract(double amount) {
|
||||
return this.economy.bankWithdraw(this.bank, amount).transactionSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean multiply(double amount) {
|
||||
double balance = this.balance();
|
||||
return this.set(balance * amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean divide(double amount) {
|
||||
double balance = this.balance();
|
||||
return this.set(balance / amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasEnough(double amount) {
|
||||
return (this.balance() >= amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasOver(double amount) {
|
||||
return (this.balance() > amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasUnder(double amount) {
|
||||
return (this.balance() < amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNegative() {
|
||||
return (this.balance() < 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove() {
|
||||
return this.set(0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
package com.earth2me.essentials.settings;
|
||||
|
||||
import com.earth2me.essentials.storage.MapValueType;
|
||||
import com.earth2me.essentials.storage.StorageObject;
|
||||
import org.bukkit.Location;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
public class Jails implements StorageObject {
|
||||
@MapValueType(Location.class)
|
||||
private Map<String, Location> jails = new HashMap<>();
|
||||
|
||||
public Map<String, Location> getJails() {
|
||||
return jails;
|
||||
}
|
||||
|
||||
public void setJails(Map<String, Location> jails) {
|
||||
this.jails = jails;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Jails jails1 = (Jails) o;
|
||||
return Objects.equals(jails, jails1.jails);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(jails);
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
package com.earth2me.essentials.settings;
|
||||
|
||||
import com.earth2me.essentials.storage.MapValueType;
|
||||
import com.earth2me.essentials.storage.StorageObject;
|
||||
import org.bukkit.Location;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class Spawns implements StorageObject {
|
||||
@MapValueType(Location.class)
|
||||
private Map<String, Location> spawns = new HashMap<>();
|
||||
|
||||
public Map<String, Location> getSpawns() {
|
||||
return spawns;
|
||||
}
|
||||
|
||||
public void setSpawns(Map<String, Location> spawns) {
|
||||
this.spawns = spawns;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Spawns spawns1 = (Spawns) o;
|
||||
return Objects.equals(spawns, spawns1.spawns);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(spawns);
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package com.earth2me.essentials.signs;
|
||||
|
||||
import com.earth2me.essentials.User;
|
||||
import net.ess3.api.IEssentials;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class SignMail extends EssentialsSign {
|
||||
public SignMail() {
|
||||
super("Mail");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onSignInteract(final ISign sign, final User player, final String username, final IEssentials ess) throws SignException {
|
||||
final List<String> mail = player.getMails();
|
||||
if (mail.isEmpty()) {
|
||||
player.sendMessage(tl("noNewMail"));
|
||||
return false;
|
||||
}
|
||||
for (String s : mail) {
|
||||
player.sendMessage(s);
|
||||
}
|
||||
player.sendMessage(tl("markMailAsRead"));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
package com.earth2me.essentials.storage;
|
||||
|
||||
import net.ess3.api.IEssentials;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
|
||||
|
||||
public abstract class AbstractDelayedYamlFileReader<T extends StorageObject> implements Runnable {
|
||||
private final transient File file;
|
||||
private final transient Class<T> clazz;
|
||||
protected final transient IEssentials plugin;
|
||||
|
||||
public AbstractDelayedYamlFileReader(final IEssentials ess, final File file, final Class<T> clazz) {
|
||||
this.file = file;
|
||||
this.clazz = clazz;
|
||||
this.plugin = ess;
|
||||
ess.runTaskAsynchronously(this);
|
||||
}
|
||||
|
||||
public abstract void onStart();
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
onStart();
|
||||
try {
|
||||
final FileReader reader = new FileReader(file);
|
||||
try {
|
||||
final T object = new YamlStorageReader(reader, plugin).load(clazz);
|
||||
onSuccess(object);
|
||||
} finally {
|
||||
try {
|
||||
reader.close();
|
||||
} catch (IOException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "File can't be closed: " + file.toString(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (FileNotFoundException ex) {
|
||||
onException();
|
||||
if (plugin.getSettings() == null || plugin.getSettings().isDebug()) {
|
||||
Bukkit.getLogger().log(Level.INFO, "File not found: " + file.toString());
|
||||
}
|
||||
} catch (ObjectLoadException ex) {
|
||||
onException();
|
||||
Bukkit.getLogger().log(Level.SEVERE, "File broken: " + file.toString(), ex.getCause());
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void onSuccess(T object);
|
||||
|
||||
public abstract void onException();
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package com.earth2me.essentials.storage;
|
||||
|
||||
import net.ess3.api.IEssentials;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.logging.Level;
|
||||
|
||||
|
||||
public abstract class AbstractDelayedYamlFileWriter implements Runnable {
|
||||
private final transient File file;
|
||||
|
||||
public AbstractDelayedYamlFileWriter(IEssentials ess, File file) {
|
||||
this.file = file;
|
||||
ess.runTaskAsynchronously(this);
|
||||
}
|
||||
|
||||
public abstract StorageObject getObject();
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
PrintWriter pw = null;
|
||||
try {
|
||||
final StorageObject object = getObject();
|
||||
final File folder = file.getParentFile();
|
||||
if (!folder.exists()) {
|
||||
folder.mkdirs();
|
||||
}
|
||||
pw = new PrintWriter(file);
|
||||
new YamlStorageWriter(pw).save(object);
|
||||
} catch (FileNotFoundException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, file.toString(), ex);
|
||||
} finally {
|
||||
onFinish();
|
||||
if (pw != null) {
|
||||
pw.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public abstract void onFinish();
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
package com.earth2me.essentials.storage;
|
||||
|
||||
import com.earth2me.essentials.IConf;
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.api.IReload;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.logging.Level;
|
||||
|
||||
|
||||
public abstract class AsyncStorageObjectHolder<T extends StorageObject> implements IConf, IStorageObjectHolder<T>, IReload {
|
||||
private transient T data;
|
||||
private final transient ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
|
||||
private final transient Class<T> clazz;
|
||||
protected final transient IEssentials ess;
|
||||
|
||||
public AsyncStorageObjectHolder(final IEssentials ess, final Class<T> clazz) {
|
||||
this.ess = ess;
|
||||
this.clazz = clazz;
|
||||
try {
|
||||
this.data = clazz.newInstance();
|
||||
} catch (IllegalAccessException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
} catch (InstantiationException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acquireReadLock() {
|
||||
rwl.readLock().lock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acquireWriteLock() {
|
||||
while (rwl.getReadHoldCount() > 0) {
|
||||
rwl.readLock().unlock();
|
||||
}
|
||||
rwl.writeLock().lock();
|
||||
rwl.readLock().lock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
unlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unlock() {
|
||||
if (rwl.isWriteLockedByCurrentThread()) {
|
||||
rwl.writeLock().unlock();
|
||||
new StorageObjectDataWriter();
|
||||
}
|
||||
while (rwl.getReadHoldCount() > 0) {
|
||||
rwl.readLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadConfig() {
|
||||
new StorageObjectDataReader();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReload() {
|
||||
new StorageObjectDataReader();
|
||||
}
|
||||
|
||||
public abstract void finishRead();
|
||||
|
||||
public abstract void finishWrite();
|
||||
|
||||
public abstract File getStorageFile();
|
||||
|
||||
|
||||
private class StorageObjectDataWriter extends AbstractDelayedYamlFileWriter {
|
||||
StorageObjectDataWriter() {
|
||||
super(ess, getStorageFile());
|
||||
}
|
||||
|
||||
@Override
|
||||
public StorageObject getObject() {
|
||||
acquireReadLock();
|
||||
return getData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinish() {
|
||||
unlock();
|
||||
finishWrite();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class StorageObjectDataReader extends AbstractDelayedYamlFileReader<T> {
|
||||
StorageObjectDataReader() {
|
||||
super(ess, getStorageFile(), clazz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
rwl.writeLock().lock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(final T object) {
|
||||
if (object != null) {
|
||||
data = object;
|
||||
}
|
||||
rwl.writeLock().unlock();
|
||||
finishRead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException() {
|
||||
if (data == null) {
|
||||
try {
|
||||
data = clazz.newInstance();
|
||||
} catch (IllegalAccessException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
} catch (InstantiationException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
rwl.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,217 +0,0 @@
|
||||
package com.earth2me.essentials.storage;
|
||||
|
||||
import com.earth2me.essentials.Enchantments;
|
||||
import com.earth2me.essentials.utils.NumberUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.material.MaterialData;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.yaml.snakeyaml.constructor.BaseConstructor;
|
||||
import org.yaml.snakeyaml.constructor.CustomClassLoaderConstructor;
|
||||
import org.yaml.snakeyaml.introspector.PropertyUtils;
|
||||
import org.yaml.snakeyaml.nodes.*;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Locale;
|
||||
|
||||
|
||||
public class BukkitConstructor extends CustomClassLoaderConstructor {
|
||||
private final transient Plugin plugin;
|
||||
|
||||
public BukkitConstructor(final Class clazz, final Plugin plugin) {
|
||||
super(clazz, plugin.getClass().getClassLoader());
|
||||
this.plugin = plugin;
|
||||
yamlClassConstructors.put(NodeId.scalar, new ConstructBukkitScalar());
|
||||
yamlClassConstructors.put(NodeId.mapping, new ConstructBukkitMapping());
|
||||
|
||||
PropertyUtils propertyUtils = getPropertyUtils();
|
||||
propertyUtils.setSkipMissingProperties(true);
|
||||
setPropertyUtils(propertyUtils);
|
||||
}
|
||||
|
||||
private Method constructScalarMethod = null;
|
||||
|
||||
protected String constructScalarRefl(ScalarNode scalarNode) {
|
||||
try {
|
||||
if (constructScalarMethod == null) {
|
||||
constructScalarMethod = BaseConstructor.class.getDeclaredMethod("constructScalar", ScalarNode.class);
|
||||
}
|
||||
return (String) constructScalarMethod.invoke(this, scalarNode);
|
||||
} catch (NoSuchMethodException
|
||||
| SecurityException
|
||||
| IllegalAccessException
|
||||
| IllegalArgumentException
|
||||
| InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private class ConstructBukkitScalar extends ConstructScalar {
|
||||
|
||||
@Override
|
||||
public Object construct(final Node node) {
|
||||
if (node.getType().equals(Material.class)) {
|
||||
final String val = constructScalarRefl((ScalarNode) node);
|
||||
return Material.matchMaterial(val);
|
||||
}
|
||||
|
||||
if (node.getType().equals(MaterialData.class)) {
|
||||
final String val = constructScalarRefl((ScalarNode) node);
|
||||
if (val.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
final String[] split = val.split("[:+',;.]", 2);
|
||||
if (split.length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Material mat = Material.matchMaterial(split[0]);
|
||||
|
||||
if (mat == null) {
|
||||
return null;
|
||||
}
|
||||
byte data = 0;
|
||||
if (split.length == 2 && NumberUtil.isInt(split[1])) {
|
||||
data = Byte.parseByte(split[1]);
|
||||
}
|
||||
return new MaterialData(mat, data);
|
||||
}
|
||||
if (node.getType().equals(ItemStack.class)) {
|
||||
final String val = constructScalarRefl((ScalarNode) node);
|
||||
if (val.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
final String[] split1 = val.split("\\W");
|
||||
if (split1.length == 0) {
|
||||
return null;
|
||||
}
|
||||
final String[] split2 = split1[0].split("[:+',;.]", 2);
|
||||
if (split2.length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Material mat = Material.matchMaterial(split2[0]);
|
||||
|
||||
if (mat == null) {
|
||||
return null;
|
||||
}
|
||||
short data = 0;
|
||||
if (split2.length == 2 && NumberUtil.isInt(split2[1])) {
|
||||
data = Short.parseShort(split2[1]);
|
||||
}
|
||||
int size = mat.getMaxStackSize();
|
||||
if (split1.length > 1 && NumberUtil.isInt(split1[1])) {
|
||||
size = Integer.parseInt(split1[1]);
|
||||
}
|
||||
final ItemStack stack = new ItemStack(mat, size, data);
|
||||
if (split1.length > 2) {
|
||||
for (int i = 2; i < split1.length; i++) {
|
||||
final String[] split3 = split1[0].split("[:+',;.]", 2);
|
||||
if (split3.length < 1) {
|
||||
continue;
|
||||
}
|
||||
Enchantment enchantment = Enchantments.getByName(split3[0]);
|
||||
if (enchantment == null) {
|
||||
continue;
|
||||
}
|
||||
int level = enchantment.getStartLevel();
|
||||
if (split3.length == 2 && NumberUtil.isInt(split3[1])) {
|
||||
level = Integer.parseInt(split3[1]);
|
||||
}
|
||||
if (level < enchantment.getStartLevel()) {
|
||||
level = enchantment.getStartLevel();
|
||||
}
|
||||
if (level > enchantment.getMaxLevel()) {
|
||||
level = enchantment.getMaxLevel();
|
||||
}
|
||||
stack.addUnsafeEnchantment(enchantment, level);
|
||||
}
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
if (node.getType().equals(EnchantmentLevel.class)) {
|
||||
final String val = constructScalarRefl((ScalarNode) node);
|
||||
if (val.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
final String[] split = val.split("[:+',;.]", 2);
|
||||
if (split.length == 0) {
|
||||
return null;
|
||||
}
|
||||
Enchantment enchant = Enchantments.getByName(split[0]);
|
||||
if (enchant == null) {
|
||||
return null;
|
||||
}
|
||||
int level = enchant.getStartLevel();
|
||||
if (split.length == 2 && NumberUtil.isInt(split[1])) {
|
||||
level = Integer.parseInt(split[1]);
|
||||
}
|
||||
if (level < enchant.getStartLevel()) {
|
||||
level = enchant.getStartLevel();
|
||||
}
|
||||
if (level > enchant.getMaxLevel()) {
|
||||
level = enchant.getMaxLevel();
|
||||
}
|
||||
return new EnchantmentLevel(enchant, level);
|
||||
}
|
||||
return super.construct(node);
|
||||
}
|
||||
}
|
||||
|
||||
private class ConstructBukkitMapping extends ConstructMapping {
|
||||
|
||||
@Override
|
||||
public Object construct(final Node node) {
|
||||
if (node.getType().equals(Location.class)) {
|
||||
//TODO: NPE checks
|
||||
final MappingNode mnode = (MappingNode) node;
|
||||
String worldName = "";
|
||||
double x = 0, y = 0, z = 0;
|
||||
float yaw = 0, pitch = 0;
|
||||
if (mnode.getValue().size() < 4) {
|
||||
return null;
|
||||
}
|
||||
for (NodeTuple nodeTuple : mnode.getValue()) {
|
||||
final String key = constructScalarRefl((ScalarNode) nodeTuple.getKeyNode());
|
||||
final ScalarNode snode = (ScalarNode) nodeTuple.getValueNode();
|
||||
if (key.equalsIgnoreCase("world")) {
|
||||
worldName = constructScalarRefl(snode);
|
||||
}
|
||||
if (key.equalsIgnoreCase("x")) {
|
||||
x = Double.parseDouble(constructScalarRefl(snode));
|
||||
}
|
||||
if (key.equalsIgnoreCase("y")) {
|
||||
y = Double.parseDouble(constructScalarRefl(snode));
|
||||
}
|
||||
if (key.equalsIgnoreCase("z")) {
|
||||
z = Double.parseDouble(constructScalarRefl(snode));
|
||||
}
|
||||
if (key.equalsIgnoreCase("yaw")) {
|
||||
yaw = Float.parseFloat(constructScalarRefl(snode));
|
||||
}
|
||||
if (key.equalsIgnoreCase("pitch")) {
|
||||
pitch = Float.parseFloat(constructScalarRefl(snode));
|
||||
}
|
||||
}
|
||||
if (worldName == null || worldName.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
final World world = Bukkit.getWorld(worldName);
|
||||
if (world == null) {
|
||||
return null;
|
||||
}
|
||||
return new Location(world, x, y, z, yaw, pitch);
|
||||
}
|
||||
return super.construct(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package com.earth2me.essentials.storage;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
|
||||
@Target(ElementType.FIELD) @Documented @Retention(RetentionPolicy.RUNTIME) public @interface Comment {
|
||||
String[] value() default "";
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
package com.earth2me.essentials.storage;
|
||||
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
|
||||
import java.util.Map.Entry;
|
||||
|
||||
|
||||
public class EnchantmentLevel implements Entry<Enchantment, Integer> {
|
||||
private Enchantment enchantment;
|
||||
private int level;
|
||||
|
||||
public EnchantmentLevel(final Enchantment enchantment, final int level) {
|
||||
this.enchantment = enchantment;
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public Enchantment getEnchantment() {
|
||||
return enchantment;
|
||||
}
|
||||
|
||||
public void setEnchantment(final Enchantment enchantment) {
|
||||
this.enchantment = enchantment;
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public void setLevel(final int level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enchantment getKey() {
|
||||
return enchantment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getValue() {
|
||||
return level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer setValue(final Integer v) {
|
||||
int t = level;
|
||||
level = v;
|
||||
return t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return enchantment.hashCode() ^ level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (obj instanceof Entry) {
|
||||
final Entry entry = (Entry) obj;
|
||||
if (entry.getKey() instanceof Enchantment && entry.getValue() instanceof Integer) {
|
||||
final Enchantment enchant = (Enchantment) entry.getKey();
|
||||
final Integer lvl = (Integer) entry.getValue();
|
||||
return this.enchantment.equals(enchant) && this.level == lvl.intValue();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package com.earth2me.essentials.storage;
|
||||
|
||||
|
||||
public interface IStorageObjectHolder<T extends StorageObject> {
|
||||
T getData();
|
||||
|
||||
void acquireReadLock();
|
||||
|
||||
void acquireWriteLock();
|
||||
|
||||
void close();
|
||||
|
||||
void unlock();
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
package com.earth2me.essentials.storage;
|
||||
|
||||
|
||||
public interface IStorageReader {
|
||||
<T extends StorageObject> T load(final Class<? extends T> clazz) throws ObjectLoadException;
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
package com.earth2me.essentials.storage;
|
||||
|
||||
|
||||
public interface IStorageWriter {
|
||||
void save(final StorageObject object);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package com.earth2me.essentials.storage;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
|
||||
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface ListType {
|
||||
Class value() default String.class;
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package com.earth2me.essentials.storage;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
|
||||
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface MapKeyType {
|
||||
Class value() default String.class;
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package com.earth2me.essentials.storage;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
|
||||
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface MapValueType {
|
||||
Class value() default String.class;
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package com.earth2me.essentials.storage;
|
||||
|
||||
|
||||
public class ObjectLoadException extends Exception {
|
||||
public ObjectLoadException(Throwable thrwbl) {
|
||||
super(thrwbl);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
package com.earth2me.essentials.storage;
|
||||
|
||||
|
||||
public interface StorageObject {
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
package com.earth2me.essentials.storage;
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.yaml.snakeyaml.TypeDescription;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.constructor.Constructor;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
|
||||
public class YamlStorageReader implements IStorageReader {
|
||||
private transient static final Map<Class, Yaml> PREPARED_YAMLS = Collections.synchronizedMap(new HashMap<Class, Yaml>());
|
||||
private transient static final Map<Class, ReentrantLock> LOCKS = new HashMap<Class, ReentrantLock>();
|
||||
private transient final Reader reader;
|
||||
private transient final Plugin plugin;
|
||||
|
||||
public YamlStorageReader(final Reader reader, final Plugin plugin) {
|
||||
this.reader = reader;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends StorageObject> T load(final Class<? extends T> clazz) throws ObjectLoadException {
|
||||
Yaml yaml = PREPARED_YAMLS.get(clazz);
|
||||
if (yaml == null) {
|
||||
yaml = new Yaml(prepareConstructor(clazz));
|
||||
PREPARED_YAMLS.put(clazz, yaml);
|
||||
}
|
||||
ReentrantLock lock;
|
||||
synchronized (LOCKS) {
|
||||
lock = LOCKS.get(clazz);
|
||||
if (lock == null) {
|
||||
lock = new ReentrantLock();
|
||||
}
|
||||
}
|
||||
lock.lock();
|
||||
try {
|
||||
T object = (T) yaml.load(reader);
|
||||
if (object == null) {
|
||||
object = clazz.newInstance();
|
||||
}
|
||||
return object;
|
||||
} catch (IllegalAccessException ex) {
|
||||
throw new ObjectLoadException(ex);
|
||||
} catch (InstantiationException ex) {
|
||||
throw new ObjectLoadException(ex);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private Constructor prepareConstructor(final Class<?> clazz) {
|
||||
final Constructor constructor = new BukkitConstructor(clazz, plugin);
|
||||
final Set<Class> classes = new HashSet<Class>();
|
||||
|
||||
prepareConstructor(constructor, classes, clazz);
|
||||
return constructor;
|
||||
}
|
||||
|
||||
private void prepareConstructor(final Constructor constructor, final Set<Class> classes, final Class clazz) {
|
||||
classes.add(clazz);
|
||||
final TypeDescription description = new TypeDescription(clazz);
|
||||
for (Field field : clazz.getDeclaredFields()) {
|
||||
prepareList(field, description, classes, constructor);
|
||||
prepareMap(field, description, classes, constructor);
|
||||
if (StorageObject.class.isAssignableFrom(field.getType()) && !classes.contains(field.getType())) {
|
||||
prepareConstructor(constructor, classes, field.getType());
|
||||
}
|
||||
}
|
||||
constructor.addTypeDescription(description);
|
||||
}
|
||||
|
||||
private void prepareList(final Field field, final TypeDescription description, final Set<Class> classes, final Constructor constructor) {
|
||||
final ListType listType = field.getAnnotation(ListType.class);
|
||||
if (listType != null) {
|
||||
description.putListPropertyType(field.getName(), listType.value());
|
||||
if (StorageObject.class.isAssignableFrom(listType.value()) && !classes.contains(listType.value())) {
|
||||
prepareConstructor(constructor, classes, listType.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void prepareMap(final Field field, final TypeDescription description, final Set<Class> classes, final Constructor constructor) {
|
||||
final MapValueType mapType = field.getAnnotation(MapValueType.class);
|
||||
if (mapType != null) {
|
||||
final MapKeyType mapKeyType = field.getAnnotation(MapKeyType.class);
|
||||
description.putMapPropertyType(field.getName(), mapKeyType == null ? String.class : mapKeyType.value(), mapType.value());
|
||||
if (StorageObject.class.isAssignableFrom(mapType.value()) && !classes.contains(mapType.value())) {
|
||||
prepareConstructor(constructor, classes, mapType.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,257 +0,0 @@
|
||||
package com.earth2me.essentials.storage;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.material.MaterialData;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
public class YamlStorageWriter implements IStorageWriter {
|
||||
private transient static final Pattern NON_WORD_PATTERN = Pattern.compile("\\W");
|
||||
private transient static final Yaml YAML = new Yaml();
|
||||
private transient final PrintWriter writer;
|
||||
|
||||
public YamlStorageWriter(final PrintWriter writer) {
|
||||
this.writer = writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(final StorageObject object) {
|
||||
try {
|
||||
writeToFile(object, 0, object.getClass());
|
||||
} catch (IllegalArgumentException ex) {
|
||||
Logger.getLogger(YamlStorageWriter.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} catch (IllegalAccessException ex) {
|
||||
Logger.getLogger(YamlStorageWriter.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeToFile(final Object object, final int depth, final Class clazz) throws IllegalAccessException {
|
||||
for (Field field : clazz.getDeclaredFields()) {
|
||||
final int modifier = field.getModifiers();
|
||||
if (Modifier.isPrivate(modifier) && !Modifier.isTransient(modifier) && !Modifier.isStatic(modifier)) {
|
||||
field.setAccessible(true);
|
||||
|
||||
final Object data = field.get(object);
|
||||
if (writeKey(field, depth, data)) {
|
||||
continue;
|
||||
}
|
||||
if (data instanceof StorageObject) {
|
||||
writer.println();
|
||||
writeToFile(data, depth + 1, data.getClass());
|
||||
} else if (data instanceof Map) {
|
||||
writeMap((Map<Object, Object>) data, depth + 1);
|
||||
} else if (data instanceof Collection) {
|
||||
writeCollection((Collection<Object>) data, depth + 1);
|
||||
} else if (data instanceof Location) {
|
||||
writeLocation((Location) data, depth + 1);
|
||||
} else {
|
||||
writeScalar(data);
|
||||
writer.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean writeKey(final Field field, final int depth, final Object data) {
|
||||
final boolean commentPresent = writeComment(field, depth);
|
||||
if (data == null && !commentPresent) {
|
||||
return true;
|
||||
}
|
||||
writeIndention(depth);
|
||||
if (data == null && commentPresent) {
|
||||
writer.print('#');
|
||||
}
|
||||
final String name = field.getName();
|
||||
writer.print(name);
|
||||
writer.print(": ");
|
||||
if (data == null && commentPresent) {
|
||||
writer.println();
|
||||
writer.println();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean writeComment(final Field field, final int depth) {
|
||||
final boolean commentPresent = field.isAnnotationPresent(Comment.class);
|
||||
if (commentPresent) {
|
||||
final Comment comments = field.getAnnotation(Comment.class);
|
||||
for (String comment : comments.value()) {
|
||||
final String trimmed = comment.trim();
|
||||
if (trimmed.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
writeIndention(depth);
|
||||
writer.print("# ");
|
||||
writer.print(trimmed);
|
||||
writer.println();
|
||||
}
|
||||
}
|
||||
return commentPresent;
|
||||
}
|
||||
|
||||
private void writeCollection(final Collection<Object> data, final int depth) throws IllegalAccessException {
|
||||
writer.println();
|
||||
if (data.isEmpty()) {
|
||||
writer.println();
|
||||
}
|
||||
for (Object entry : data) {
|
||||
if (entry != null) {
|
||||
writeIndention(depth);
|
||||
writer.print("- ");
|
||||
if (entry instanceof StorageObject) {
|
||||
writer.println();
|
||||
writeToFile(entry, depth + 1, entry.getClass());
|
||||
} else if (entry instanceof Location) {
|
||||
writeLocation((Location) entry, depth + 1);
|
||||
} else {
|
||||
writeScalar(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
writer.println();
|
||||
}
|
||||
|
||||
private void writeMap(final Map<Object, Object> data, final int depth) throws IllegalArgumentException, IllegalAccessException {
|
||||
writer.println();
|
||||
if (data.isEmpty()) {
|
||||
writer.println();
|
||||
}
|
||||
for (Entry<Object, Object> entry : data.entrySet()) {
|
||||
final Object value = entry.getValue();
|
||||
if (value != null) {
|
||||
writeIndention(depth);
|
||||
writeKey(entry.getKey());
|
||||
writer.print(": ");
|
||||
if (value instanceof StorageObject) {
|
||||
writer.println();
|
||||
writeToFile(value, depth + 1, value.getClass());
|
||||
} else if (value instanceof Collection) {
|
||||
writeCollection((Collection<Object>) value, depth + 1);
|
||||
} else if (value instanceof Location) {
|
||||
writeLocation((Location) value, depth + 1);
|
||||
} else {
|
||||
writeScalar(value);
|
||||
writer.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void writeIndention(final int depth) {
|
||||
for (int i = 0; i < depth; i++) {
|
||||
writer.print(" ");
|
||||
}
|
||||
}
|
||||
|
||||
private void writeScalar(final Object data) {
|
||||
if (data instanceof String || data instanceof Boolean || data instanceof Number) {
|
||||
synchronized (YAML) {
|
||||
YAML.dumpAll(Collections.singletonList(data).iterator(), writer);
|
||||
}
|
||||
} else if (data instanceof Material) {
|
||||
writeMaterial(data);
|
||||
writer.println();
|
||||
} else if (data instanceof MaterialData) {
|
||||
writeMaterialData(data);
|
||||
writer.println();
|
||||
} else if (data instanceof ItemStack) {
|
||||
writeItemStack(data);
|
||||
writer.println();
|
||||
} else if (data instanceof EnchantmentLevel) {
|
||||
writeEnchantmentLevel(data);
|
||||
writer.println();
|
||||
} else {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
private void writeKey(final Object data) {
|
||||
if (data instanceof String || data instanceof Boolean || data instanceof Number) {
|
||||
String output = data.toString();
|
||||
if (NON_WORD_PATTERN.matcher(output).find()) {
|
||||
writer.print('"');
|
||||
writer.print(output.replace("\"", "\\\""));
|
||||
writer.print('"');
|
||||
} else {
|
||||
writer.print(output);
|
||||
}
|
||||
} else if (data instanceof Material) {
|
||||
writeMaterial(data);
|
||||
} else if (data instanceof MaterialData) {
|
||||
writeMaterialData(data);
|
||||
} else if (data instanceof EnchantmentLevel) {
|
||||
writeEnchantmentLevel(data);
|
||||
} else {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
private void writeMaterial(final Object data) {
|
||||
writer.print(data.toString().toLowerCase(Locale.ENGLISH));
|
||||
}
|
||||
|
||||
private void writeMaterialData(final Object data) {
|
||||
final MaterialData matData = (MaterialData) data;
|
||||
writeMaterial(matData.getItemType());
|
||||
if (matData.getData() > 0) {
|
||||
writer.print(':');
|
||||
writer.print(matData.getData());
|
||||
}
|
||||
}
|
||||
|
||||
private void writeItemStack(final Object data) {
|
||||
final ItemStack itemStack = (ItemStack) data;
|
||||
writeMaterialData(itemStack.getData());
|
||||
writer.print(' ');
|
||||
writer.print(itemStack.getAmount());
|
||||
for (Entry<Enchantment, Integer> entry : itemStack.getEnchantments().entrySet()) {
|
||||
writer.print(' ');
|
||||
writeEnchantmentLevel(entry);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeEnchantmentLevel(Object data) {
|
||||
final Entry<Enchantment, Integer> enchLevel = (Entry<Enchantment, Integer>) data;
|
||||
writer.print(enchLevel.getKey().getName().toLowerCase(Locale.ENGLISH));
|
||||
writer.print(':');
|
||||
writer.print(enchLevel.getValue());
|
||||
}
|
||||
|
||||
private void writeLocation(final Location entry, final int depth) {
|
||||
writer.println();
|
||||
writeIndention(depth);
|
||||
writer.print("world: ");
|
||||
writeScalar(entry.getWorld().getName());
|
||||
writeIndention(depth);
|
||||
writer.print("x: ");
|
||||
writeScalar(entry.getX());
|
||||
writeIndention(depth);
|
||||
writer.print("y: ");
|
||||
writeScalar(entry.getY());
|
||||
writeIndention(depth);
|
||||
writer.print("z: ");
|
||||
writeScalar(entry.getZ());
|
||||
writeIndention(depth);
|
||||
writer.print("yaw: ");
|
||||
writeScalar(entry.getYaw());
|
||||
writeIndention(depth);
|
||||
writer.print("pitch: ");
|
||||
writeScalar(entry.getPitch());
|
||||
}
|
||||
}
|
||||
@@ -1,179 +0,0 @@
|
||||
package com.earth2me.essentials.utils;
|
||||
|
||||
import net.ess3.api.IUser;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
public class FormatUtil {
|
||||
private static final Set<ChatColor> COLORS = EnumSet.of(ChatColor.BLACK, ChatColor.DARK_BLUE, ChatColor.DARK_GREEN, ChatColor.DARK_AQUA, ChatColor.DARK_RED, ChatColor.DARK_PURPLE, ChatColor.GOLD, ChatColor.GRAY, ChatColor.DARK_GRAY, ChatColor.BLUE, ChatColor.GREEN, ChatColor.AQUA, ChatColor.RED, ChatColor.LIGHT_PURPLE, ChatColor.YELLOW, ChatColor.WHITE);
|
||||
private static final Set<ChatColor> FORMATS = EnumSet.of(ChatColor.BOLD, ChatColor.STRIKETHROUGH, ChatColor.UNDERLINE, ChatColor.ITALIC, ChatColor.RESET);
|
||||
private static final Set<ChatColor> MAGIC = EnumSet.of(ChatColor.MAGIC);
|
||||
|
||||
//Vanilla patterns used to strip existing formats
|
||||
private static final Pattern STRIP_ALL_PATTERN = Pattern.compile("\u00a7+([0-9a-fk-orA-FK-OR])");
|
||||
//Essentials '&' convention colour codes
|
||||
private static final Pattern REPLACE_ALL_PATTERN = Pattern.compile("(&)?&([0-9a-fk-orA-FK-OR])");
|
||||
//Used to prepare xmpp output
|
||||
private static final Pattern LOGCOLOR_PATTERN = Pattern.compile("\\x1B\\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]");
|
||||
private static final Pattern URL_PATTERN = Pattern.compile("((?:(?:https?)://)?[\\w-_\\.]{2,})\\.([a-zA-Z]{2,3}(?:/\\S+)?)");
|
||||
public static final Pattern IPPATTERN = Pattern.compile("^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$");
|
||||
|
||||
//This method is used to simply strip the native minecraft colour codes
|
||||
public static String stripFormat(final String input) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
return ChatColor.stripColor(input);
|
||||
}
|
||||
|
||||
//This method is used to simply strip the & convention colour codes
|
||||
public static String stripEssentialsFormat(final String input) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
return stripColor(input, REPLACE_ALL_PATTERN);
|
||||
}
|
||||
|
||||
//This is the general permission sensitive message format function, checks for urls.
|
||||
public static String formatMessage(final IUser user, final String permBase, final String input) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
String message = formatString(user, permBase, input);
|
||||
if (!user.isAuthorized(permBase + ".url")) {
|
||||
message = FormatUtil.blockURL(message);
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
//This method is used to simply replace the ess colour codes with minecraft ones, ie &c
|
||||
public static String replaceFormat(final String input) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
return replaceColor(input, EnumSet.allOf(ChatColor.class));
|
||||
}
|
||||
|
||||
static String replaceColor(final String input, final Set<ChatColor> supported) {
|
||||
StringBuffer builder = new StringBuffer();
|
||||
Matcher matcher = REPLACE_ALL_PATTERN.matcher(input);
|
||||
searchLoop: while (matcher.find()) {
|
||||
boolean isEscaped = (matcher.group(1) != null);
|
||||
if (!isEscaped) {
|
||||
char code = matcher.group(2).toLowerCase(Locale.ROOT).charAt(0);
|
||||
for (ChatColor color : supported) {
|
||||
if (color.getChar() == code) {
|
||||
matcher.appendReplacement(builder, "\u00a7$2");
|
||||
continue searchLoop;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Don't change & to section sign (or replace two &'s with one)
|
||||
matcher.appendReplacement(builder, "&$2");
|
||||
}
|
||||
matcher.appendTail(builder);
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
static String stripColor(final String input, final Set<ChatColor> strip) {
|
||||
StringBuffer builder = new StringBuffer();
|
||||
Matcher matcher = STRIP_ALL_PATTERN.matcher(input);
|
||||
searchLoop: while (matcher.find()) {
|
||||
char code = matcher.group(1).toLowerCase(Locale.ROOT).charAt(0);
|
||||
for (ChatColor color : strip) {
|
||||
if (color.getChar() == code) {
|
||||
matcher.appendReplacement(builder, "");
|
||||
continue searchLoop;
|
||||
}
|
||||
}
|
||||
// Don't replace
|
||||
matcher.appendReplacement(builder, "$0");
|
||||
}
|
||||
matcher.appendTail(builder);
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
//This is the general permission sensitive message format function, does not touch urls.
|
||||
public static String formatString(final IUser user, final String permBase, String message) {
|
||||
if (message == null) {
|
||||
return null;
|
||||
}
|
||||
EnumSet<ChatColor> supported = EnumSet.noneOf(ChatColor.class);
|
||||
if (user.isAuthorized(permBase + ".color")) {
|
||||
supported.addAll(COLORS);
|
||||
}
|
||||
if (user.isAuthorized(permBase + ".format")) {
|
||||
supported.addAll(FORMATS);
|
||||
}
|
||||
if (user.isAuthorized(permBase + ".magic")) {
|
||||
supported.addAll(MAGIC);
|
||||
}
|
||||
for (ChatColor chatColor : ChatColor.values()) {
|
||||
String colorName = chatColor.name();
|
||||
if (chatColor == ChatColor.MAGIC) {
|
||||
// Bukkit's name doesn't match with vanilla's
|
||||
colorName = "obfuscated";
|
||||
}
|
||||
|
||||
final String node = permBase + "." + colorName.toLowerCase(Locale.ROOT);
|
||||
// Only handle individual colors that are explicitly added or removed.
|
||||
if (!user.isPermissionSet(node)) {
|
||||
continue;
|
||||
}
|
||||
if (user.isAuthorized(node)) {
|
||||
supported.add(chatColor);
|
||||
} else {
|
||||
supported.remove(chatColor);
|
||||
}
|
||||
}
|
||||
EnumSet<ChatColor> strip = EnumSet.complementOf(supported);
|
||||
|
||||
if (!supported.isEmpty()) {
|
||||
message = replaceColor(message, supported);
|
||||
}
|
||||
if (!strip.isEmpty()) {
|
||||
message = stripColor(message, strip);
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
public static String stripLogColorFormat(final String input) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
return stripColor(input, LOGCOLOR_PATTERN);
|
||||
}
|
||||
|
||||
static String stripColor(final String input, final Pattern pattern) {
|
||||
return pattern.matcher(input).replaceAll("");
|
||||
}
|
||||
|
||||
public static String lastCode(final String input) {
|
||||
int pos = input.lastIndexOf('\u00a7');
|
||||
if (pos == -1 || (pos + 1) == input.length()) {
|
||||
return "";
|
||||
}
|
||||
return input.substring(pos, pos + 2);
|
||||
}
|
||||
|
||||
static String blockURL(final String input) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
String text = URL_PATTERN.matcher(input).replaceAll("$1 $2");
|
||||
while (URL_PATTERN.matcher(text).find()) {
|
||||
text = URL_PATTERN.matcher(text).replaceAll("$1 $2");
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
public static boolean validIP(String ipAddress) {
|
||||
return IPPATTERN.matcher(ipAddress).matches();
|
||||
}
|
||||
}
|
||||
@@ -1,241 +0,0 @@
|
||||
package com.earth2me.essentials.utils;
|
||||
|
||||
import com.earth2me.essentials.IEssentials;
|
||||
import net.ess3.api.IUser;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static com.earth2me.essentials.I18n.tl;
|
||||
|
||||
|
||||
public class LocationUtil {
|
||||
// Water types used for TRANSPARENT_MATERIALS and is-water-safe config option
|
||||
private static final Set<Material> WATER_TYPES =
|
||||
EnumUtil.getAllMatching(Material.class, "WATER", "FLOWING_WATER");
|
||||
|
||||
// The player can stand inside these materials
|
||||
private static final Set<Material> HOLLOW_MATERIALS = new HashSet<>();
|
||||
private static final Set<Material> TRANSPARENT_MATERIALS = new HashSet<>();
|
||||
|
||||
static {
|
||||
// Materials from Material.isTransparent()
|
||||
for (Material mat : Material.values()) {
|
||||
if (mat.isTransparent()) {
|
||||
HOLLOW_MATERIALS.add(mat);
|
||||
}
|
||||
}
|
||||
|
||||
TRANSPARENT_MATERIALS.addAll(HOLLOW_MATERIALS);
|
||||
TRANSPARENT_MATERIALS.addAll(WATER_TYPES);
|
||||
}
|
||||
|
||||
public static void setIsWaterSafe(boolean isWaterSafe) {
|
||||
if (isWaterSafe) {
|
||||
HOLLOW_MATERIALS.addAll(WATER_TYPES);
|
||||
} else {
|
||||
HOLLOW_MATERIALS.removeAll(WATER_TYPES);
|
||||
}
|
||||
}
|
||||
|
||||
public static final int RADIUS = 3;
|
||||
public static final Vector3D[] VOLUME;
|
||||
|
||||
public static ItemStack convertBlockToItem(final Block block) {
|
||||
return new ItemStack(block.getType(), 1);
|
||||
}
|
||||
|
||||
|
||||
public static class Vector3D {
|
||||
public int x;
|
||||
public int y;
|
||||
public int z;
|
||||
|
||||
Vector3D(int x, int y, int z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
List<Vector3D> pos = new ArrayList<>();
|
||||
for (int x = -RADIUS; x <= RADIUS; x++) {
|
||||
for (int y = -RADIUS; y <= RADIUS; y++) {
|
||||
for (int z = -RADIUS; z <= RADIUS; z++) {
|
||||
pos.add(new Vector3D(x, y, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
pos.sort(Comparator.comparingInt(a -> (a.x * a.x + a.y * a.y + a.z * a.z)));
|
||||
VOLUME = pos.toArray(new Vector3D[0]);
|
||||
}
|
||||
|
||||
public static Location getTarget(final LivingEntity entity) throws Exception {
|
||||
Block block = null;
|
||||
try {
|
||||
block = entity.getTargetBlock(TRANSPARENT_MATERIALS, 300);
|
||||
} catch (NoSuchMethodError ignored) {} // failing now :(
|
||||
if (block == null) {
|
||||
throw new Exception("Not targeting a block");
|
||||
}
|
||||
return block.getLocation();
|
||||
}
|
||||
|
||||
public static boolean isBlockAboveAir(final World world, final int x, final int y, final int z) {
|
||||
return y > world.getMaxHeight() || HOLLOW_MATERIALS.contains(world.getBlockAt(x, y - 1, z).getType());
|
||||
}
|
||||
|
||||
public static boolean isBlockUnsafeForUser(final IUser user, final World world, final int x, final int y, final int z) {
|
||||
if (user.getBase().isOnline() && world.equals(user.getBase().getWorld()) && (user.getBase().getGameMode() == GameMode.CREATIVE || user.getBase().getGameMode() == GameMode.SPECTATOR || user.isGodModeEnabled()) && user.getBase().getAllowFlight()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isBlockDamaging(world, x, y, z)) {
|
||||
return true;
|
||||
}
|
||||
return isBlockAboveAir(world, x, y, z);
|
||||
}
|
||||
|
||||
public static boolean isBlockUnsafe(final World world, final int x, final int y, final int z) {
|
||||
return isBlockDamaging(world, x, y, z) || isBlockAboveAir(world, x, y, z);
|
||||
}
|
||||
|
||||
public static boolean isBlockDamaging(final World world, final int x, final int y, final int z) {
|
||||
final Block below = world.getBlockAt(x, y - 1, z);
|
||||
|
||||
switch (below.getType()) {
|
||||
case LAVA:
|
||||
case FIRE:
|
||||
return true;
|
||||
}
|
||||
|
||||
if (MaterialUtil.isBed(below.getType())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
if (below.getType() == Material.valueOf("FLOWING_LAVA")) {
|
||||
return true;
|
||||
}
|
||||
} catch (Exception ignored) {} // 1.13 LAVA uses Levelled
|
||||
|
||||
Material PORTAL = EnumUtil.getMaterial("NETHER_PORTAL", "PORTAL");
|
||||
|
||||
if (world.getBlockAt(x, y, z).getType() == PORTAL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (!HOLLOW_MATERIALS.contains(world.getBlockAt(x, y, z).getType())) || (!HOLLOW_MATERIALS.contains(world.getBlockAt(x, y + 1, z).getType()));
|
||||
}
|
||||
|
||||
// Not needed if using getSafeDestination(loc)
|
||||
public static Location getRoundedDestination(final Location loc) {
|
||||
final World world = loc.getWorld();
|
||||
int x = loc.getBlockX();
|
||||
int y = (int) Math.round(loc.getY());
|
||||
int z = loc.getBlockZ();
|
||||
return new Location(world, x + 0.5, y, z + 0.5, loc.getYaw(), loc.getPitch());
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #getSafeDestination(IEssentials, IUser, Location)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static Location getSafeDestination(final IUser user, final Location loc) throws Exception {
|
||||
return getSafeDestination(null, user, loc);
|
||||
}
|
||||
|
||||
public static Location getSafeDestination(final IEssentials ess, final IUser user, final Location loc) throws Exception {
|
||||
if (user.getBase().isOnline() && loc.getWorld().equals(user.getBase().getWorld()) && (user.getBase().getGameMode() == GameMode.CREATIVE || user.isGodModeEnabled()) && user.getBase().getAllowFlight()) {
|
||||
if (shouldFly(loc)) {
|
||||
user.getBase().setFlying(true);
|
||||
}
|
||||
// ess can be null if old deprecated method is calling it.
|
||||
if (ess == null || ess.getSettings().isTeleportToCenterLocation()) {
|
||||
return getRoundedDestination(loc);
|
||||
} else {
|
||||
return loc;
|
||||
}
|
||||
}
|
||||
return getSafeDestination(loc);
|
||||
}
|
||||
|
||||
public static Location getSafeDestination(final Location loc) throws Exception {
|
||||
if (loc == null || loc.getWorld() == null) {
|
||||
throw new Exception(tl("destinationNotSet"));
|
||||
}
|
||||
final World world = loc.getWorld();
|
||||
int x = loc.getBlockX();
|
||||
int y = (int) Math.round(loc.getY());
|
||||
int z = loc.getBlockZ();
|
||||
final int origX = x;
|
||||
final int origY = y;
|
||||
final int origZ = z;
|
||||
while (isBlockAboveAir(world, x, y, z)) {
|
||||
y -= 1;
|
||||
if (y < 0) {
|
||||
y = origY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isBlockUnsafe(world, x, y, z)) {
|
||||
x = Math.round(loc.getX()) == origX ? x - 1 : x + 1;
|
||||
z = Math.round(loc.getZ()) == origZ ? z - 1 : z + 1;
|
||||
}
|
||||
int i = 0;
|
||||
while (isBlockUnsafe(world, x, y, z)) {
|
||||
i++;
|
||||
if (i >= VOLUME.length) {
|
||||
x = origX;
|
||||
y = origY + RADIUS;
|
||||
z = origZ;
|
||||
break;
|
||||
}
|
||||
x = origX + VOLUME[i].x;
|
||||
y = origY + VOLUME[i].y;
|
||||
z = origZ + VOLUME[i].z;
|
||||
}
|
||||
while (isBlockUnsafe(world, x, y, z)) {
|
||||
y += 1;
|
||||
if (y >= world.getMaxHeight()) {
|
||||
x += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (isBlockUnsafe(world, x, y, z)) {
|
||||
y -= 1;
|
||||
if (y <= 1) {
|
||||
x += 1;
|
||||
y = world.getHighestBlockYAt(x, z);
|
||||
if (x - 48 > loc.getBlockX()) {
|
||||
throw new Exception(tl("holeInFloor"));
|
||||
}
|
||||
}
|
||||
}
|
||||
return new Location(world, x + 0.5, y, z + 0.5, loc.getYaw(), loc.getPitch());
|
||||
}
|
||||
|
||||
public static boolean shouldFly(Location loc) {
|
||||
final World world = loc.getWorld();
|
||||
final int x = loc.getBlockX();
|
||||
int y = (int) Math.round(loc.getY());
|
||||
final int z = loc.getBlockZ();
|
||||
int count = 0;
|
||||
while (LocationUtil.isBlockUnsafe(world, x, y, z) && y > -1) {
|
||||
y--;
|
||||
count++;
|
||||
if (count > 2) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return y < 0;
|
||||
}
|
||||
}
|
||||
@@ -1,153 +0,0 @@
|
||||
package com.earth2me.essentials.utils;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.material.MaterialData;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public class MaterialUtil {
|
||||
|
||||
|
||||
private static final Set<Material> BEDS;
|
||||
private static final Set<Material> BANNERS;
|
||||
private static final Set<Material> FIREWORKS;
|
||||
private static final Set<Material> LEGACY_SKULLS;
|
||||
private static final Set<Material> LEATHER_ARMOR;
|
||||
private static final Set<Material> MOB_HEADS;
|
||||
// includes TIPPED_ARROW which also has potion effects
|
||||
private static final Set<Material> PLAYER_HEADS;
|
||||
private static final Set<Material> POTIONS;
|
||||
private static final Set<Material> SIGN_POSTS;
|
||||
private static final Set<Material> WALL_SIGNS;
|
||||
|
||||
public static final Material SPAWNER = EnumUtil.getMaterial("MOB_SPAWNER", "SPAWNER");
|
||||
|
||||
static {
|
||||
|
||||
BEDS = EnumUtil.getAllMatching(Material.class, "BED", "WHITE_BED", "ORANGE_BED",
|
||||
"MAGENTA_BED", "LIGHT_BLUE_BED", "YELLOW_BED", "LIME_BED", "PINK_BED", "GRAY_BED",
|
||||
"LIGHT_GRAY_BED", "CYAN_BED", "PURPLE_BED", "BLUE_BED", "BROWN_BED", "GREEN_BED",
|
||||
"RED_BED", "BLACK_BED");
|
||||
|
||||
BANNERS = EnumUtil.getAllMatching(Material.class, "BANNER", "WHITE_BANNER",
|
||||
"ORANGE_BANNER", "MAGENTA_BANNER", "LIGHT_BLUE_BANNER", "YELLOW_BANNER", "LIME_BANNER",
|
||||
"PINK_BANNER","GRAY_BANNER","LIGHT_GRAY_BANNER", "CYAN_BANNER", "PURPLE_BANNER",
|
||||
"BLUE_BANNER", "BROWN_BANNER", "GREEN_BANNER", "RED_BANNER", "BLACK_BANNER", "SHIELD");
|
||||
|
||||
FIREWORKS = EnumUtil.getAllMatching(Material.class, "FIREWORK", "FIREWORK_ROCKET",
|
||||
"FIREWORK_CHARGE", "FIREWORK_STAR");
|
||||
|
||||
LEATHER_ARMOR = EnumUtil.getAllMatching(Material.class, "LEATHER_HELMET",
|
||||
"LEATHER_CHESTPLATE", "LEATHER_LEGGINGS", "LEATHER_BOOTS");
|
||||
|
||||
LEGACY_SKULLS = EnumUtil.getAllMatching(Material.class,"SKULL", "SKULL_ITEM");
|
||||
|
||||
MOB_HEADS = EnumUtil.getAllMatching(Material.class, "SKELETON_SKULL",
|
||||
"SKELETON_WALL_SKULL", "WITHER_SKELETON_SKULL", "WITHER_SKELETON_WALL_SKULL",
|
||||
"CREEPER_HEAD", "CREEPER_WALL_HEAD", "ZOMBIE_HEAD", "ZOMBIE_WALL_HEAD", "DRAGON_HEAD"
|
||||
, "DRAGON_WALL_HEAD");
|
||||
|
||||
PLAYER_HEADS = EnumUtil.getAllMatching(Material.class, "PLAYER_HEAD", "PLAYER_WALL_HEAD");
|
||||
|
||||
POTIONS = EnumUtil.getAllMatching(Material.class, "POTION", "SPLASH_POTION",
|
||||
"LINGERING_POTION", "TIPPED_ARROW");
|
||||
|
||||
SIGN_POSTS = EnumUtil.getAllMatching(Material.class, "SIGN", "SIGN_POST",
|
||||
"ACACIA_SIGN", "BIRCH_SIGN",
|
||||
"DARK_OAK_SIGN", "JUNGLE_SIGN",
|
||||
"OAK_SIGN", "SPRUCE_SIGN");
|
||||
|
||||
WALL_SIGNS = EnumUtil.getAllMatching(Material.class, "WALL_SIGN",
|
||||
"ACACIA_WALL_SIGN", "BIRCH_WALL_SIGN", "DARK_OAK_WALL_SIGN", "JUNGLE_WALL_SIGN",
|
||||
"OAK_WALL_SIGN", "SPRUCE_WALL_SIGN");
|
||||
}
|
||||
|
||||
public static boolean isBed(Material material) {
|
||||
return BEDS.contains(material);
|
||||
}
|
||||
|
||||
public static boolean isBanner(Material material) {
|
||||
return BANNERS.contains(material);
|
||||
}
|
||||
|
||||
public static boolean isFirework(Material material) {
|
||||
return FIREWORKS.contains(material);
|
||||
}
|
||||
|
||||
public static boolean isLeatherArmor(Material material) {
|
||||
return LEATHER_ARMOR.contains(material);
|
||||
}
|
||||
|
||||
public static boolean isMobHead(Material material, int durability) {
|
||||
if (MOB_HEADS.contains(material)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return LEGACY_SKULLS.contains(material) && (durability < 0 || durability != 3);
|
||||
}
|
||||
|
||||
public static boolean isPlayerHead(Material material, int durability) {
|
||||
if (PLAYER_HEADS.contains(material)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return LEGACY_SKULLS.contains(material) && durability == 3;
|
||||
}
|
||||
|
||||
public static boolean isPotion(Material material) {
|
||||
return POTIONS.contains(material);
|
||||
}
|
||||
|
||||
public static boolean isSignPost(Material material) {
|
||||
return SIGN_POSTS.contains(material);
|
||||
}
|
||||
|
||||
public static boolean isWallSign(Material material) {
|
||||
return WALL_SIGNS.contains(material);
|
||||
}
|
||||
|
||||
public static boolean isSign(Material material) {
|
||||
return isSignPost(material) || isWallSign(material);
|
||||
}
|
||||
|
||||
public static boolean isSkull(Material material) {
|
||||
return isPlayerHead(material, -1) || isMobHead(material, -1);
|
||||
}
|
||||
|
||||
public static Material convertFromLegacy(int id, byte damage) {
|
||||
for (Material material : EnumSet.allOf(Material.class)) {
|
||||
if (material.getId() == id) {
|
||||
try {
|
||||
return Bukkit.getUnsafe().fromLegacy(new MaterialData(material, damage));
|
||||
} catch (NoSuchMethodError error) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
Method getMaterialFromId = Material.class.getDeclaredMethod("getMaterial", int.class);
|
||||
return (Material) getMaterialFromId.invoke(null, id);
|
||||
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) {}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static DyeColor getColorOf(Material material) {
|
||||
for (DyeColor color : DyeColor.values()) {
|
||||
if (material.toString().contains(color.name())) {
|
||||
return color;
|
||||
}
|
||||
}
|
||||
|
||||
return DyeColor.WHITE;
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
package com.earth2me.essentials.utils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
public class StringUtil {
|
||||
private static final Pattern INVALIDFILECHARS = Pattern.compile("[^a-z0-9-]");
|
||||
private static final Pattern STRICTINVALIDCHARS = Pattern.compile("[^a-z0-9]");
|
||||
private static final Pattern INVALIDCHARS = Pattern.compile("[^\t\n\r\u0020-\u007E\u0085\u00A0-\uD7FF\uE000-\uFFFC]");
|
||||
|
||||
//Used to clean file names before saving to disk
|
||||
public static String sanitizeFileName(final String name) {
|
||||
return INVALIDFILECHARS.matcher(name.toLowerCase(Locale.ENGLISH)).replaceAll("_");
|
||||
}
|
||||
|
||||
//Used to clean strings/names before saving as filenames/permissions
|
||||
public static String safeString(final String string) {
|
||||
return STRICTINVALIDCHARS.matcher(string.toLowerCase(Locale.ENGLISH)).replaceAll("_");
|
||||
}
|
||||
|
||||
//Less restrictive string sanitizing, when not used as perm or filename
|
||||
public static String sanitizeString(final String string) {
|
||||
return INVALIDCHARS.matcher(string).replaceAll("");
|
||||
}
|
||||
|
||||
public static String joinList(Object... list) {
|
||||
return joinList(", ", list);
|
||||
}
|
||||
|
||||
public static String joinList(String seperator, Object... list) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
for (Object each : list) {
|
||||
if (buf.length() > 0) {
|
||||
buf.append(seperator);
|
||||
}
|
||||
|
||||
if (each instanceof Collection) {
|
||||
buf.append(joinList(seperator, ((Collection) each).toArray()));
|
||||
} else {
|
||||
try {
|
||||
buf.append(each.toString());
|
||||
} catch (Exception e) {
|
||||
buf.append(each.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public static String joinListSkip(String seperator, String skip, Object... list) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
for (Object each : list) {
|
||||
if (each.toString().equalsIgnoreCase(skip)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (buf.length() > 0) {
|
||||
buf.append(seperator);
|
||||
}
|
||||
|
||||
if (each instanceof Collection) {
|
||||
buf.append(joinListSkip(seperator, skip, ((Collection) each).toArray()));
|
||||
} else {
|
||||
try {
|
||||
buf.append(each.toString());
|
||||
} catch (Exception e) {
|
||||
buf.append(each.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
private StringUtil() {
|
||||
}
|
||||
}
|
||||
@@ -1,184 +0,0 @@
|
||||
package com.earth2me.essentials.utils;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class VersionUtil {
|
||||
|
||||
public static final BukkitVersion v1_8_8_R01 = BukkitVersion.fromString("1.8.8-R0.1-SNAPSHOT");
|
||||
public static final BukkitVersion v1_9_R01 = BukkitVersion.fromString("1.9-R0.1-SNAPSHOT");
|
||||
public static final BukkitVersion v1_9_4_R01 = BukkitVersion.fromString("1.9.4-R0.1-SNAPSHOT");
|
||||
public static final BukkitVersion v1_10_2_R01 = BukkitVersion.fromString("1.10.2-R0.1-SNAPSHOT");
|
||||
public static final BukkitVersion v1_11_2_R01 = BukkitVersion.fromString("1.11.2-R0.1-SNAPSHOT");
|
||||
public static final BukkitVersion v1_12_0_R01 = BukkitVersion.fromString("1.12.0-R0.1-SNAPSHOT");
|
||||
public static final BukkitVersion v1_12_2_R01 = BukkitVersion.fromString("1.12.2-R0.1-SNAPSHOT");
|
||||
public static final BukkitVersion v1_13_0_R01 = BukkitVersion.fromString("1.13.0-R0.1-SNAPSHOT");
|
||||
public static final BukkitVersion v1_13_2_R01 = BukkitVersion.fromString("1.13.2-R0.1-SNAPSHOT");
|
||||
public static final BukkitVersion v1_14_R01 = BukkitVersion.fromString("1.14-R0.1-SNAPSHOT");
|
||||
public static final BukkitVersion v1_14_1_R01 = BukkitVersion.fromString("1.14.1-R0.1-SNAPSHOT");
|
||||
public static final BukkitVersion v1_14_2_R01 = BukkitVersion.fromString("1.14.2-R0.1-SNAPSHOT");
|
||||
public static final BukkitVersion v1_14_3_R01 = BukkitVersion.fromString("1.14.3-R0.1-SNAPSHOT");
|
||||
public static final BukkitVersion v1_14_4_R01 = BukkitVersion.fromString("1.14.4-R0.1-SNAPSHOT");
|
||||
|
||||
private static final Set<BukkitVersion> supportedVersions = ImmutableSet.of(v1_8_8_R01, v1_9_4_R01, v1_10_2_R01, v1_11_2_R01, v1_12_2_R01, v1_13_2_R01, v1_14_4_R01);
|
||||
|
||||
private static BukkitVersion serverVersion = null;
|
||||
|
||||
public static BukkitVersion getServerBukkitVersion() {
|
||||
if (serverVersion == null) {
|
||||
serverVersion = BukkitVersion.fromString(Bukkit.getServer().getBukkitVersion());
|
||||
}
|
||||
return serverVersion;
|
||||
}
|
||||
|
||||
public static boolean isServerSupported() {
|
||||
return supportedVersions.contains(getServerBukkitVersion());
|
||||
}
|
||||
|
||||
public static class BukkitVersion implements Comparable<BukkitVersion> {
|
||||
private static final Pattern VERSION_PATTERN = Pattern.compile("^(\\d+)\\.(\\d+)\\.?([0-9]*)?(?:-pre(\\d))?(?:-?R?([\\d.]+))?(?:-SNAPSHOT)?");
|
||||
|
||||
private final int major;
|
||||
private final int minor;
|
||||
private final int prerelease;
|
||||
private final int patch;
|
||||
private final double revision;
|
||||
|
||||
public static BukkitVersion fromString(String string) {
|
||||
Preconditions.checkNotNull(string, "string cannot be null.");
|
||||
Matcher matcher = VERSION_PATTERN.matcher(string);
|
||||
if (!matcher.matches()) {
|
||||
if (!Bukkit.getName().equals("Essentials Fake Server")) {
|
||||
throw new IllegalArgumentException(string + " is not in valid version format. e.g. 1.8.8-R0.1");
|
||||
}
|
||||
matcher = VERSION_PATTERN.matcher(v1_14_R01.toString());
|
||||
Preconditions.checkArgument(matcher.matches(), string + " is not in valid version format. e.g. 1.8.8-R0.1");
|
||||
}
|
||||
|
||||
return from(matcher.group(1), matcher.group(2), matcher.group(3), matcher.groupCount() < 5 ? "" : matcher.group(5), matcher.group(4));
|
||||
}
|
||||
|
||||
private static BukkitVersion from(String major, String minor, String patch, String revision, String prerelease) {
|
||||
if (patch == null || patch.isEmpty()) patch = "0";
|
||||
if (revision == null || revision.isEmpty()) revision = "0";
|
||||
if (prerelease == null || prerelease.isEmpty()) prerelease = "-1";
|
||||
return new BukkitVersion(Integer.parseInt(major),
|
||||
Integer.parseInt(minor),
|
||||
Integer.parseInt(patch),
|
||||
Double.parseDouble(revision),
|
||||
Integer.parseInt(prerelease));
|
||||
}
|
||||
|
||||
private BukkitVersion(int major, int minor, int patch, double revision, int prerelease) {
|
||||
this.major = major;
|
||||
this.minor = minor;
|
||||
this.patch = patch;
|
||||
this.revision = revision;
|
||||
this.prerelease = prerelease;
|
||||
}
|
||||
|
||||
public boolean isHigherThan(BukkitVersion o) {
|
||||
return compareTo(o) > 0;
|
||||
}
|
||||
|
||||
public boolean isHigherThanOrEqualTo(BukkitVersion o) {
|
||||
return compareTo(o) >= 0;
|
||||
}
|
||||
|
||||
public boolean isLowerThan(BukkitVersion o) {
|
||||
return compareTo(o) < 0;
|
||||
}
|
||||
|
||||
public boolean isLowerThanOrEqualTo(BukkitVersion o) {
|
||||
return compareTo(o) <= 0;
|
||||
}
|
||||
|
||||
public int getMajor() {
|
||||
return major;
|
||||
}
|
||||
|
||||
public int getMinor() {
|
||||
return minor;
|
||||
}
|
||||
|
||||
public int getPatch() {
|
||||
return patch;
|
||||
}
|
||||
|
||||
public double getRevision() {
|
||||
return revision;
|
||||
}
|
||||
|
||||
public int getPrerelease() {
|
||||
return prerelease;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
BukkitVersion that = (BukkitVersion) o;
|
||||
return major == that.major &&
|
||||
minor == that.minor &&
|
||||
patch == that.patch &&
|
||||
revision == that.revision &&
|
||||
prerelease == that.prerelease;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(major, minor, patch, revision, prerelease);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder(major + "." + minor);
|
||||
if (patch != 0) {
|
||||
sb.append(".").append(patch);
|
||||
}
|
||||
if (prerelease != -1) {
|
||||
sb.append("-pre").append(prerelease);
|
||||
}
|
||||
return sb.append("-R").append(revision).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(BukkitVersion o) {
|
||||
if (major < o.major) {
|
||||
return -1;
|
||||
} else if (major > o.major) {
|
||||
return 1;
|
||||
} else { // equal major
|
||||
if (minor < o.minor) {
|
||||
return -1;
|
||||
} else if (minor > o.minor) {
|
||||
return 1;
|
||||
} else { // equal minor
|
||||
if (patch < o.patch) {
|
||||
return -1;
|
||||
} else if (patch > o.patch) {
|
||||
return 1;
|
||||
} else { // equal patch
|
||||
if (prerelease < o.prerelease) {
|
||||
return -1;
|
||||
} else if (prerelease > o.prerelease) {
|
||||
return 1;
|
||||
} else { // equal prerelease
|
||||
return Double.compare(revision, o.revision);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
Loaded 100 of 814 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user