Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
36117803fe
|
||
|
|
cb4fead942
|
||
|
|
60375ab964 | ||
|
|
3a94423501 | ||
|
|
4b62c83410 | ||
|
|
2ccfae5d87 | ||
|
|
7f444d0f1c | ||
|
|
46b3a3f14e | ||
|
|
9ddac66d62 | ||
|
|
dd7fa6f08a | ||
|
|
c2b4ceef1c | ||
|
|
b11136bed0 | ||
|
|
7664d40696 | ||
|
|
dcbc8f7407 | ||
|
|
752e9aeb19 | ||
|
|
7fc3f0cbc9 | ||
|
|
c3014e8092 | ||
|
|
7f5a5d8d54 | ||
|
|
27ff56f673 | ||
|
|
db49edaa88 | ||
|
|
b4e331fba3 | ||
|
|
563c184c0b | ||
|
|
6dd9ae0ec3 | ||
|
|
ac50b28659 | ||
|
|
65bf209705 | ||
|
|
6d57f9664e | ||
|
|
1408dee12e | ||
|
|
97f6cb5d68 | ||
|
|
4cd541e158 | ||
|
|
9a9793bb90 | ||
|
|
4005416de1 | ||
|
|
12c9972efd | ||
|
|
41acd5db94 | ||
|
|
337e5739c6 | ||
|
|
3ad5cff521 | ||
|
|
2457cdff71 | ||
|
|
7a9e8676d9 | ||
|
|
5f52fa53f4 | ||
|
|
1b1708aa69 | ||
|
|
fdc6cd9bdd | ||
|
|
1fb7c0ea42 | ||
|
|
8d75af5b46 | ||
|
|
4d0ad57695 | ||
|
|
4c8ab9ce32 | ||
|
|
34bc884a11 | ||
|
|
0ebde0b8db | ||
|
|
82301fd9f9 | ||
|
|
b0d87a94a8 | ||
|
|
a380d8bf35 | ||
|
|
ae8fb9a8db | ||
|
|
724fcd8395 | ||
|
|
cfbcf0975c | ||
|
|
32baaf620f | ||
|
|
06e3405bcc | ||
|
|
d2520eed6c | ||
|
|
24bd5b2618 | ||
|
|
f6b6a45fa8 | ||
|
|
b37bfe6334 | ||
|
|
1f8574fe26 | ||
|
|
7ee3b8a5fe | ||
|
|
cfb7e9e15b | ||
|
|
5d595869ee | ||
|
|
e154b62ef7 | ||
|
|
3d49982e56 | ||
|
|
a1bc66a717 | ||
|
|
c42f0ab912 | ||
|
|
22dd4ce266 | ||
|
|
2e66e1b926 | ||
|
|
ac28c94435 | ||
|
|
4acc809dd8 | ||
|
|
0ff5cd232f | ||
|
|
d49db3dfbe | ||
|
|
b36adb54fa | ||
|
|
91276ab5f6 | ||
|
|
3dd1d7506a | ||
|
|
00abe8588b | ||
|
|
9fba024e16 | ||
|
|
fe7a640e3d | ||
|
|
72c9689b6d | ||
|
|
cfd0dd1be7 | ||
|
|
cfdedfad15 | ||
|
|
32258bc1ef | ||
|
|
c2f297a125 | ||
|
|
036c225c2c | ||
|
|
bc10c6b94c | ||
|
|
211dd1e4f2 | ||
|
|
de500d9cd3 | ||
|
|
99d77b2f55 | ||
|
|
2ddafded74 | ||
|
|
876b66392f | ||
|
|
e59a27d09d | ||
|
|
0c4e9564bd | ||
|
|
9c7f60180b | ||
|
|
bbaa53f428 | ||
|
|
9f910d3027 | ||
|
|
2c3a324ec9 | ||
|
|
9ab902b9ce | ||
|
|
4c5a19fd60 | ||
|
|
342cfa4b03 | ||
|
|
6cf9314aaa | ||
|
|
967fe77753 | ||
|
|
6d6ebee2cc | ||
|
|
0e7bbfd0e2 | ||
|
|
3410f36c10 | ||
|
|
fe2bfda1b9 | ||
|
|
e106aacc47 | ||
|
|
e7aee8c99f | ||
|
|
c84265c1dd | ||
|
|
78b08ca164 | ||
|
|
54151515f4 | ||
|
|
fd1c252594 | ||
|
|
702349c762 | ||
|
|
1f6fb837de | ||
|
|
0284b80e44 | ||
|
|
6f99fe4ce8 | ||
|
|
1ac29de1bf | ||
|
|
2223094461 | ||
|
|
6279ae2477 | ||
|
|
5f90270cc8 | ||
|
|
885c7249a6 | ||
|
|
ffb8fd5767 | ||
|
|
c3717bc8b1 | ||
|
|
665c3816cd | ||
|
|
a586190e1f | ||
|
|
820d5138a9 | ||
|
|
39f240c1cb | ||
|
|
a8092d430a | ||
|
|
8173a69496 | ||
|
|
317afe064a | ||
|
|
7d3e6002f1 | ||
|
|
22a75203cf | ||
|
|
b63ba56f50 | ||
|
|
e0a20eff46 | ||
|
|
77d42f3367 | ||
|
|
09f3ad0384 | ||
|
|
0c2f0cdb96 | ||
|
|
13706a86e5 | ||
|
|
d121772f3c | ||
|
|
8b5234b2ad | ||
|
|
d659fd173e | ||
|
|
8e44e611d0 | ||
|
|
36c2c6183e | ||
|
|
06229ab9ae | ||
|
|
9df156703d | ||
|
|
7ab28b7126 | ||
|
|
f4fe7a4aa4 | ||
|
|
ea6f43f4e0 | ||
|
|
07304e0ad4 | ||
|
|
11bf0287f3 | ||
|
|
1bda7aae24 | ||
|
|
a919227b04 | ||
|
|
796f46dd44 | ||
|
|
3ebd6e627a | ||
|
|
53612fe24a | ||
|
|
cbcbba5678 | ||
|
|
962f7834c6 | ||
|
|
f724014efd | ||
|
|
84f39ca478 | ||
|
|
d06760e83f | ||
|
|
4e27c5b044 | ||
|
|
8480e1b28b | ||
|
|
f56afcf9a7 | ||
|
|
de6c56e1ba | ||
|
|
b37050b317 | ||
|
|
081a34c51b | ||
|
|
ff2ccf0478 | ||
|
|
34c6811295 | ||
|
|
4b50b67abf | ||
|
|
eee4be4ca0 | ||
|
|
f6d5e99a09 | ||
|
|
29c55e53af | ||
|
|
ac38cf143b | ||
|
|
1bd22f73e5 | ||
|
|
a256a10170 | ||
|
|
2e6f1b718a | ||
|
|
a30b833bfb | ||
|
|
4701803045 | ||
|
|
76385f3968 | ||
|
|
9283cb25e7 | ||
|
|
97dbe14127 | ||
|
|
da41f7cfc8 | ||
|
|
69e94ab3e1 | ||
|
|
4458533372 | ||
|
|
ad9251e332 | ||
|
|
ffeebfa4aa | ||
|
|
bc04bf866a | ||
|
|
3a2af01ad2 | ||
|
|
27d884ff31 | ||
|
|
c69b05501e | ||
|
|
6119cb77a8 | ||
|
|
01b0ca9817 | ||
|
|
7e188cadaf | ||
|
|
f12d16d686 | ||
|
|
441f53077b | ||
|
|
cb2b33b9e2 | ||
|
|
f50497b49a | ||
|
|
9fa699d22d | ||
|
|
d94034dc6e | ||
|
|
9b2f44dfaf | ||
|
|
a4f0d85cf7 | ||
|
|
4c21049e59 | ||
|
|
921aea4623 | ||
|
|
465ab57125 | ||
|
|
83be201d0f | ||
|
|
251dad766b | ||
|
|
880d839b52 | ||
|
|
197f986088 | ||
|
|
3925baef3c | ||
|
|
143b1f5d80 | ||
|
|
0461bf4ffc | ||
|
|
5e0809c448 | ||
|
|
b4c3fbeb19 | ||
|
|
44cedde712 | ||
|
|
ba31683d48 | ||
|
|
9780dcdb76 | ||
|
|
c3746996a1 | ||
|
|
58f986f0f7 | ||
|
|
0551558b8f | ||
|
|
3808edafca | ||
|
|
b85c85f4fd | ||
|
|
3956879fb8 | ||
|
|
4c8536faeb | ||
|
|
ef019df6fa | ||
|
|
415833c9b0 | ||
|
|
e844df3f26 | ||
|
|
2678ab40aa | ||
|
|
360725d4c5 | ||
|
|
2288d193fd | ||
|
|
16f8f15111 | ||
|
|
8bec54970b | ||
|
|
607b510bd1 | ||
|
|
71d174a90c | ||
|
|
45fb0d1ead | ||
|
|
f7cfb5d813 | ||
|
|
24598168bf | ||
|
|
7a5f4e317a | ||
|
|
bb8e6d391f | ||
|
|
14ce1934f1 | ||
|
|
a6f362523b | ||
|
|
6cbe823c23 | ||
|
|
5c3a7c3fce | ||
|
|
74399c49dc | ||
|
|
8dd6cd6a1f | ||
|
|
25fe2617dc | ||
|
|
6d4ea72e58 | ||
|
|
29ab1f35f2 | ||
|
|
adfb2a7c86 | ||
|
|
3f434737f8 | ||
|
|
097c8b7ce3 | ||
|
|
bfa229edbd | ||
|
|
de15485d64 | ||
|
|
b4c81b9359 | ||
|
|
ee61f49e63 | ||
|
|
4595c6b00c | ||
|
|
39b9b0e5a2 | ||
|
|
5c34d4fdee | ||
|
|
de4a1222e8 | ||
|
|
62d1ef6a61 | ||
|
|
c7cf0c073c | ||
|
|
6439684c70 | ||
|
|
eb7bbb0dad | ||
|
|
4b909dc85a | ||
|
|
66f1eef91f | ||
|
|
7beccd980b | ||
|
|
13cd8c0348 | ||
|
|
4408508625 | ||
|
|
65a3772b3a | ||
|
|
786dbef1c1 | ||
|
|
c7f1b6af2e | ||
|
|
c81b7b71cc | ||
|
|
159a95e75b | ||
|
|
385846605a | ||
|
|
789b16518c | ||
|
|
2af10d0bca | ||
|
|
5998db8df3 | ||
|
|
78133f3f00 | ||
|
|
10364ef2c9 | ||
|
|
210e738bec | ||
|
|
67dfb659ce | ||
|
|
1d60f62bcc | ||
|
|
fbb0f5c6a2 | ||
|
|
6c6d5b870e | ||
|
|
60ae8a8361 | ||
|
|
1d206d4dc7 | ||
|
|
4bb70ad57a | ||
|
|
2748d23cbf | ||
|
|
282bc50d3e | ||
|
|
40b6d23dd3 | ||
|
|
d236d26657 | ||
|
|
ac3b360c42 | ||
|
|
5eb572dfad | ||
|
|
f76db64995 | ||
|
|
37c0e2a024 | ||
|
|
06fa14bae4 | ||
|
|
1550a6c533 | ||
|
|
4229be161e | ||
|
|
7e7eb62e0a | ||
|
|
a7896ab1f9 | ||
|
|
3db3f55472 | ||
|
|
817c829bee | ||
|
|
1f5b008520 | ||
|
|
db1a0ec601 | ||
|
|
414995a8cd | ||
|
|
a9169367f6 | ||
|
|
ea8bde1fe1 | ||
|
|
12512c96a9 | ||
|
|
6ac5614982 | ||
|
|
694e01ce99 | ||
|
|
77e23811ed | ||
|
|
94fc06283c | ||
|
|
d9ed72b472 | ||
|
|
f8e88fb4bf | ||
|
|
e0aa2d392b | ||
|
|
1282c93fe4 | ||
|
|
bd4a143a0a | ||
|
|
f32efaa68e | ||
|
|
ce82285772 | ||
|
|
1d398287eb | ||
|
|
ed1f227608 | ||
|
|
81fb399932 | ||
|
|
db0758e949 | ||
|
|
3dabc3bc9c | ||
|
|
9f5c2c18c4 | ||
|
|
2f4ba89b17 | ||
|
|
fb93a3dc08 | ||
|
|
50dca0cc52 | ||
|
|
c3dbc9d8dd | ||
|
|
faaf125e13 | ||
|
|
ce7e1a5708 | ||
|
|
3ea42cc786 | ||
|
|
eb712ecf83 | ||
|
|
03f33b524c | ||
|
|
207b2a10de | ||
|
|
24ac8deb08 | ||
|
|
a4583a31ac | ||
|
|
71556f841f | ||
|
|
6a8c2dc99c | ||
|
|
b95a83eba2 | ||
|
|
66d92c1bba | ||
|
|
514a63b80a | ||
|
|
283297a51f | ||
|
|
bd411b5d01 | ||
|
|
bcc8d6e0d8 | ||
|
|
f63f1ba95d | ||
|
|
558c98a8cd | ||
|
|
f011540686 | ||
|
|
e9c7a13548 | ||
|
|
789c31445b | ||
|
|
b4f6fa191f | ||
|
|
a413c588bf | ||
|
|
1e58a75b25 | ||
|
|
309d127ec5 | ||
|
|
a22a2e5fd6 | ||
|
|
0876dac2d2 | ||
|
|
2df8bfad1d | ||
|
|
9d6be94f18 | ||
|
|
bf35fd05fc | ||
|
|
61339381d2 | ||
|
|
63f81fa37b | ||
|
|
c22f430f13 | ||
|
|
4353fc9f0b | ||
|
|
ca95932107 | ||
|
|
8c493c596c | ||
|
|
8445f021f6 | ||
|
|
b363f7ed37 | ||
|
|
389b00e89e | ||
|
|
a9f17f4861 | ||
|
|
6dc0500cdb | ||
|
|
de8370eb4b | ||
|
|
5bcfd7a2a1 | ||
|
|
b9f2203c7c | ||
|
|
ac5854ec0a | ||
|
|
da6987cb53 | ||
|
|
0022be942a | ||
|
|
94bc061c72 | ||
|
|
84aa4d7c69 | ||
|
|
32c0550e5f | ||
|
|
17c6548dd2 | ||
|
|
2d2eef848a | ||
|
|
c6d86dd427 | ||
|
|
ecd8e3aa8a | ||
|
|
7a6f1e981f | ||
|
|
85050fe395 | ||
|
|
24db266358 | ||
|
|
3563ff0f2d | ||
|
|
a18e7cfc20 | ||
|
|
f91b8a9982 | ||
|
|
c6c2fc0ffc | ||
|
|
01cc4a629d | ||
|
|
b5cb619399 | ||
|
|
dd55cb3def | ||
|
|
3516d143b8 | ||
|
|
73c1790e79 | ||
|
|
401879cdfe | ||
|
|
f610a5e2e9 | ||
|
|
6fd0cd0803 | ||
|
|
188007d6e1 | ||
|
|
9019b75248 | ||
|
|
71976a9216 | ||
|
|
f03d420e31 | ||
|
|
41a49d1071 | ||
|
|
331298a22c | ||
|
|
db7d9cc979 | ||
|
|
b8a8388573 | ||
|
|
62f6e9ba7c | ||
|
|
e24887ba45 | ||
|
|
7d70e27472 | ||
|
|
3d57a979f5 | ||
|
|
3eb02d6964 | ||
|
|
3c5bde4a07 | ||
|
|
c93fd06898 | ||
|
|
2ae384daa5 | ||
|
|
f2e6c9669c | ||
|
|
7267e3e6a0 | ||
|
|
ac7fdf5bc3 | ||
|
|
94837b3259 | ||
|
|
1244be40e1 | ||
|
|
284d56853c | ||
|
|
5368b1778a | ||
|
|
597dbfeb64 | ||
|
|
dc6e26ca7c | ||
|
|
9aad734635 | ||
|
|
de4c520045 | ||
|
|
377f754b88 | ||
|
|
934fedf39a | ||
|
|
be133208a2 | ||
|
|
b2c47c9c91 | ||
|
|
b31c630c1b | ||
|
|
0797335934 | ||
|
|
6d075c2a9a | ||
|
|
ef6109c206 | ||
|
|
05bba94e17 | ||
|
|
e7d667d481 | ||
|
|
e1fc49f955 | ||
|
|
0d7a01a81b | ||
|
|
15f8e49ed9 | ||
|
|
32c6ef23cd | ||
|
|
0eeb1ecd70 | ||
|
|
6c55a22921 | ||
|
|
0b3b212a67 | ||
|
|
68e729b823 | ||
|
|
ccc557dc8c | ||
|
|
f260377dcd | ||
|
|
ea2ca734a1 | ||
|
|
44be0bec3b | ||
|
|
4e12762b8f | ||
|
|
68bd84549d | ||
|
|
e57ee84836 | ||
|
|
7085a6b190 | ||
|
|
9cc5564e23 | ||
|
|
30f0cae65a | ||
|
|
360e980900 | ||
|
|
a4bf41bffd | ||
|
|
f340f5b51b | ||
|
|
aadf1daf6e | ||
|
|
75f27cbd6a | ||
|
|
8517624bd9 | ||
|
|
cc0a7205d5 | ||
|
|
8633b7e2de | ||
|
|
747757fa5e | ||
|
|
d8aac30c3a | ||
|
|
e8e9419758 | ||
|
|
a3e4fb4198 | ||
|
|
068ca78259 | ||
|
|
bbef35d793 | ||
|
|
056a6f91a4 | ||
|
|
84daea05b2 | ||
|
|
c63a32f44b | ||
|
|
196abfc5ce | ||
|
|
ffce4f26f2 | ||
|
|
9c9cd79a20 | ||
|
|
5790b920b3 | ||
|
|
ad38a56657 | ||
|
|
dc03eef9c6 | ||
|
|
266019b6ea | ||
|
|
4c7deca61b | ||
|
|
997366d5e2 | ||
|
|
1ed9ad4c9f | ||
|
|
ccee1db149 | ||
|
|
175c608c11 | ||
|
|
ea9a40a297 | ||
|
|
2f1266cdd0 | ||
|
|
e8672ddaa2 | ||
|
|
8cd71508f8 | ||
|
|
f9fafdd642 | ||
|
|
1c21dcaddd | ||
|
|
8174154394 | ||
|
|
ac1213336c | ||
|
|
c7d7c4557b | ||
|
|
ef7aa73031 | ||
|
|
1a60a76fd5 | ||
|
|
c421b96e3b | ||
|
|
1362bfcecb | ||
|
|
fcde435d90 | ||
|
|
2570fc90e7 | ||
|
|
a6eed677ce | ||
|
|
3d8378bcd7 | ||
|
|
e1ae515d23 | ||
|
|
eed4f0e1dd | ||
|
|
34d8e055de | ||
|
|
bc91301c11 | ||
|
|
e60994eb92 | ||
|
|
cf61a8a6e1 | ||
|
|
c7e981fc25 | ||
|
|
76d0f88dbd | ||
|
|
d789fcaf61 | ||
|
|
8b1450a334 | ||
|
|
beb782b50a | ||
|
|
b20d72860e | ||
|
|
82a5c04477 | ||
|
|
cfe6396267 | ||
|
|
0ae9c0ec13 | ||
|
|
8787f7277a | ||
|
|
105a7ddd56 | ||
|
|
436ae975c8 | ||
|
|
12c82f03c5 | ||
|
|
514fd6da1f | ||
|
|
c10dc68a1c | ||
|
|
076c8970b6 | ||
|
|
23ef2c7879 | ||
|
|
654c5feed2 | ||
|
|
d426d03eb2 | ||
|
|
ded6b69ebf | ||
|
|
393c25ce77 | ||
|
|
5a7bfc2921 | ||
|
|
9fa317a662 | ||
|
|
3fa20a2c69 | ||
|
|
f1f48fcfdb | ||
|
|
64a25bc980 | ||
|
|
c66be61fd2 | ||
|
|
b067ec1d36 | ||
|
|
cea6207662 | ||
|
|
b4da98a9a6 | ||
|
|
7467ae9f5f | ||
|
|
1d9313a2c1 | ||
|
|
7c58dbd96e | ||
|
|
aaaa05ea02 | ||
|
|
76d8076172 | ||
|
|
690a89d925 | ||
|
|
2cfd53cb89 | ||
|
|
f1ca524783 | ||
|
|
e9f1b723fd | ||
|
|
288ab56403 | ||
|
|
bc6d1a00db | ||
|
|
7b7c0bbda6 | ||
|
|
ba90b8ad6f | ||
|
|
a08c0a86a3 | ||
|
|
57ad385cee | ||
|
|
9c31d929a2 | ||
|
|
97f317b396 | ||
|
|
55da028e56 | ||
|
|
9fb8bc38b2 | ||
|
|
ccc686cc10 | ||
|
|
06e53921c0 | ||
|
|
79abdc3841 | ||
|
|
f8e7bf9d7b | ||
|
|
ae9811a198 | ||
|
|
faf4f490bf | ||
|
|
8d9e595082 | ||
|
|
8544c0b95b | ||
|
|
bf5dfb3c1a | ||
|
|
749787b9ff | ||
|
|
630ef694db | ||
|
|
793d763e25 | ||
|
|
cafe25101a | ||
|
|
4e99bef678 | ||
|
|
d29c41e805 | ||
|
|
bbd8b131e8 | ||
|
|
f3d5c4b66b | ||
|
|
ef60dad626 | ||
|
|
98537ac168 | ||
|
|
91d3e9756a | ||
|
|
98e62a0576 | ||
|
|
3a6860109b | ||
|
|
6180a5123c | ||
|
|
476b753baa | ||
|
|
32b9ab48c3 | ||
|
|
7788ca6e5e | ||
|
|
988213c981 | ||
|
|
a0c8dbdc22 | ||
|
|
65e0202312 | ||
|
|
1a47dd7c17 | ||
|
|
2117147d76 | ||
|
|
7cfd8d4412 | ||
|
|
3bd96e02ad | ||
|
|
d6a572b27c | ||
|
|
90f241b7fd | ||
|
|
f45b75f07a | ||
|
|
3d771d4b20 | ||
|
|
11ff1c6774 | ||
|
|
abdbec1134 | ||
|
|
e1b4be58ab | ||
|
|
9c80954773 | ||
|
|
17a911d50b | ||
|
|
df62ebdad4 | ||
|
|
5014abc21c | ||
|
|
01f856c3aa | ||
|
|
57a8aafbf4 | ||
|
|
53ef1def47 | ||
|
|
5288bd2aec | ||
|
|
1ea04e84b3 | ||
|
|
74bff29a05 | ||
|
|
d73a84a764 | ||
|
|
7048e775ef | ||
|
|
482ba146dc | ||
|
|
f02582705f | ||
|
|
ea132630c6 | ||
|
|
058342222a | ||
|
|
032d94a7c5 | ||
|
|
182da9da14 | ||
|
|
59cc67b73d | ||
|
|
21b74a06f4 | ||
|
|
5a03398bec | ||
|
|
fcd2757868 | ||
|
|
fdaa62c569 | ||
|
|
f092a1ecc7 | ||
|
|
40a9b0d0ee | ||
|
|
cf504c036b | ||
|
|
016f533a29 | ||
|
|
d7ebcdbd77 | ||
|
|
710d152bb3 | ||
|
|
016ce19b3c | ||
|
|
c7dd702849 | ||
|
|
99ada94f32 | ||
|
|
108d20098f | ||
|
|
e960471ee3 | ||
|
|
68a9f3ebfc | ||
|
|
6cd3088da4 | ||
|
|
069f40f2ca | ||
|
|
246aaf4b26 | ||
|
|
ff73fb0e08 | ||
|
|
c7fe3e2c0e | ||
|
|
4578cd9695 | ||
|
|
595f9a0e69 | ||
|
|
ee7662f96b | ||
|
|
93eeba64c0 | ||
|
|
975ae49594 | ||
|
|
58562fdb53 |
No files matched your search
@@ -0,0 +1 @@
|
||||
.gitea/CODEOWNERS linguist-detectable=false
|
||||
@@ -0,0 +1,3 @@
|
||||
# Pull requests request review from the eligible staff team(s).
|
||||
# One approval from either an Admin or Developer satisfies branch protection.
|
||||
* @trueog/Admins @trueog/Developers
|
||||
+81
-1
@@ -1,6 +1,86 @@
|
||||
# Maintenance Changelog
|
||||
This file contains update logs for this project. The top may contain a `Unreleased` section, gathering update logs for a future update during development.
|
||||
|
||||
---
|
||||
## 4.3.0 - September 17th 2024
|
||||
### Changed
|
||||
* Added alternative player count and player list hover message for when endtimers are running, similar to the existing ping messages setting. They are disabled by default and can be found in their `player-count-message` and `player-list-hover-message` config sections
|
||||
* All timer commands now accept durations like `2h30m`, `1h30m5s`, or `90s`. The default behavior without units will still be in minutes
|
||||
* The language defaults will *not* automatically update the command help messages
|
||||
* Slightly reorganized the configuration file (it will be automatically migrated on startup, but new sections will be slapped at the bottom of the file)
|
||||
* The `fallback` field now also accepts null values next to an empty array for disabling the feature
|
||||
* Updated language files from [Crowdin](https://crowdin.com/translate/maintenance)
|
||||
|
||||
### Fixed
|
||||
* Fixed the `/maintenance dump` command
|
||||
* Fixed the original player sample not being cleared in Velocity
|
||||
* Velocity: Fixed the console getting broadcasts twice
|
||||
* Velocity: Don't log legacy color codes to the console
|
||||
* Paper: Fixed the player count messages on Paper 1.21
|
||||
---
|
||||
## 4.2.1 - May 17th 2024
|
||||
### Changed
|
||||
* The proxied maintenance status is now also shown for forced hosts (thanks to alec-jensen)
|
||||
* Offline player fetching improvements (thanks to EpicPlayerA10)
|
||||
* Added the setting `fallback-to-offline-uuid` to use offline player uuids in maintenance whitelist commands (defaults to false)
|
||||
* Maintenance now skips the plugin remapping process on 1.20.5+ Paper servers
|
||||
* Small optimizations
|
||||
* Updated language files from [Crowdin](https://crowdin.com/translate/maintenance)
|
||||
* Massive thank you to all the contributors! These include: vortix22, xdalul, CodeZhangBorui, jesusskye, Doc94,
|
||||
Texider_, marvin2k0, leonard.bausenwein, pro.timeo.kerjean, meviper, troev5, Murka124, jhqwqmc, Pryzinho,
|
||||
raysetratyboy, Kolja07, and rikunightcore
|
||||
---
|
||||
## 4.2.0 - September 17th 2023
|
||||
### Changed
|
||||
* Velocity/Bungee: Added `commands-on-single-maintenance-enable` and `commands-on-single-maintenance-disable` config options to define commands to be executed after maintenance has been toggled on a proxied server
|
||||
* Commands inside the `all` list will be executed for any proxied server, but you can also define commands for specific servers by adding arrays with the server names as keys
|
||||
* You can use the placeholder `%SERVER%` in commands to be replaced with the server name
|
||||
* Start-, end-, and schedule timers for proxied servers now also include the server in the feedback message
|
||||
* Updated language files from [Crowdin](https://crowdin.com/translate/maintenance) (including new language files for Danish, Japanese, Korean, and Hungarian)
|
||||
---
|
||||
## 4.1.0 - April 17th 2023
|
||||
### Changed
|
||||
* Added config option `enable-playercounthovermessage` to be able to toggle the player count hover message
|
||||
* Removed platform specific command aliases (e.g. `maintenancevelocity`)
|
||||
* Translations
|
||||
* Moved translation editing to [Crowdin](https://crowdin.com/translate/maintenance)
|
||||
* Added Turkish translation file (thanks to Proomp)
|
||||
* Added Swedish translation file (thanks to Sup33r)
|
||||
* Added Ukrainian translation file (thanks to Mrlucke)
|
||||
* Added Japanese translation file (thanks to yu-solt)
|
||||
* Added bStats metrics to Velocity and Sponge modules
|
||||
|
||||
### Fixed
|
||||
* Fixed disabling the `enable-pingmessages` setting not working on Paper servers
|
||||
* Fixed variable replacement in messages with gradients
|
||||
* Fixed the message for cancelling proxied server timers not replacing the server argument
|
||||
* Setting `enable-pingmessages` to `false` no longer disables custom player and player hover messages
|
||||
---
|
||||
## 4.0.1 - April 17th 2022
|
||||
### Fixed
|
||||
* Fixed the config header sometimes breaking the config on upgrading/saving
|
||||
---
|
||||
## 4.0.0 - March 17th 2022
|
||||
### Changed
|
||||
* Added support for hex colors in messages and replaced the component parsing with adventure-minimessage
|
||||
* This means that section symbols (`§`) are no longer the intended/supported format
|
||||
* You can use the following page to edit and preview formatted text: https://webui.adventure.kyori.net/
|
||||
* You can find full documentation on the format (including normal colors and formatting, rgb, click/hover events, and more) here: https://docs.adventure.kyori.net/minimessage/format
|
||||
* Your config and language file will be updated to the new format automatically, you won't have to change anything manually!
|
||||
* Note that the player count and player count hover messages do not support rgb colors
|
||||
* Updated Sponge module to SpongeAPI v8 (Minecraft 1.15+)
|
||||
* Changed `%NEWLINE%` replacement to `<br>`
|
||||
* Changed `enable-timerspecific-messages` to default to `true` in newly generated config files
|
||||
* Added `prefix` entry in language file to use the placeholder `<prefix>` instead of copy-pasting the actual prefix every time
|
||||
* Added `singleServerMaintenanceListEntry` language string
|
||||
* Added Polish translations (thanks to Slasherss1)
|
||||
* Updated French translations (thanks to Aurelien30000)
|
||||
* Updated Spanish translations (thanks to Jaximo)
|
||||
* If you were using the MaintenanceAddon, you need to update it to [version 1.2.0](https://github.com/kennytv/MaintenanceAddon/releases/tag/1.2.0)
|
||||
### Fixed
|
||||
* Fixed missing language key warning for the scheduletimer command
|
||||
* Fixed typo in `singleServerMaintenanceListEmpty` default language string
|
||||
* Fixed typo in language key `whitelistEmpty` in the German language file (by Ceddix)
|
||||
---
|
||||
## 3.0.7 - August 17th 2021
|
||||
### Changed
|
||||
@@ -39,7 +119,7 @@ This file contains update logs for this project. The top may contain a `Unreleas
|
||||
* Bungee/Velocity: Added language fields to choose custom kickmessages for individual proxied servers
|
||||
* See [**HERE**](https://github.com/KennyTV/Maintenance/wiki/Configuration#language-file) for an example setting
|
||||
* Added Chinese language file (thanks to Spigot user yeban)
|
||||
* Added Italian language file (thanks to @TheViperShow)
|
||||
* Added Italian language file
|
||||
* Updated Russian language file (thanks to Spigot user En_0t_S)
|
||||
* Removed automated config migration from 2.x->3.0
|
||||
* See [**HERE**](https://github.com/KennyTV/Maintenance/wiki/Updates#updating-from-2x) on how to do that manually - virtually noone should be using such old versions anymore
|
||||
|
||||
@@ -8,7 +8,7 @@ about: Report a bug to have it fixed
|
||||
**How does the problem occur/what are the steps to reproduce it?**
|
||||
|
||||
## Error
|
||||
**Is there an error? Save it via https://pastebin.com/ and link paste the link.**
|
||||
**Is there an error? Save it via https://mclo.gs/ and link paste the link.**
|
||||
|
||||
## Server information
|
||||
**Type '/maintenance dump' and paste the given link here**
|
||||
@@ -0,0 +1,26 @@
|
||||
name: Build
|
||||
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: gradle/actions/wrapper-validation@v3
|
||||
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: 17
|
||||
distribution: 'temurin'
|
||||
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew build
|
||||
|
||||
- name: Upload a Build Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Maintenance Files
|
||||
path: build/libs
|
||||
@@ -1,36 +0,0 @@
|
||||
name: Build
|
||||
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2.3.4
|
||||
|
||||
- uses: actions/cache@v2.1.6
|
||||
with:
|
||||
path: ~/.m2/repository
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: ${{ runner.os }}-maven-
|
||||
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v2.1.0
|
||||
with:
|
||||
java-version: 11
|
||||
distribution: 'adopt'
|
||||
|
||||
- name: Build with Maven
|
||||
run: mvn -B package --file pom.xml
|
||||
|
||||
- name: Upload a Build Artifact
|
||||
uses: actions/upload-artifact@v2.2.4
|
||||
with:
|
||||
name: MaintenanceFiles
|
||||
path: |
|
||||
**/Maintenance.jar
|
||||
**/MaintenanceSpigot.jar
|
||||
**/MaintenanceBungee.jar
|
||||
**/MaintenanceVelocity.jar
|
||||
**/MaintenanceSponge.jar
|
||||
+4
-1
@@ -1,5 +1,8 @@
|
||||
.metadata
|
||||
build/
|
||||
.gradle
|
||||
bin/
|
||||
run/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
@@ -13,7 +16,6 @@ local.properties
|
||||
.externalToolBuilders/
|
||||
*.launch
|
||||
*.pydevproject
|
||||
*.jar
|
||||
.cproject
|
||||
.classpath
|
||||
.factorypath
|
||||
@@ -93,3 +95,4 @@ $RECYCLE.BIN/
|
||||
*.lnk
|
||||
!MaintenanceAPI.jar
|
||||
**/src/test/resources/
|
||||
!core/src/test/resources/dirty-config.yml
|
||||
@@ -1,7 +0,0 @@
|
||||
language: java
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
dist: trusty
|
||||
cache:
|
||||
directories:
|
||||
- '$HOME/.m2/repository'
|
||||
Binary file not shown.
@@ -1,11 +1,10 @@
|
||||
# Maintenance
|
||||
[](https://github.com/kennytv/Maintenance/releases)
|
||||

|
||||
[](https://github.com/kennytv/Maintenance/releases)
|
||||
[](https://crowdin.com/project/maintenance)
|
||||
[](https://discord.gg/vGCUzHq)
|
||||
[](https://twitter.com/kennytvn)
|
||||
|
||||
Maintenance is the most customizable free maintenance plugin for your Minecraft server you can find. It runs on Spigot, BungeeCord, Sponge, as well as Velocity.
|
||||
Maintenance is the most customizable free maintenance plugin for your Minecraft server you can find. It runs on Paper (also Spigot, but with limited functionality), BungeeCord, Sponge, as well as Velocity.
|
||||
|
||||
Its features include:
|
||||
* A custom motd as well as server icon, that will be shown during maintenance
|
||||
@@ -16,23 +15,25 @@ Its features include:
|
||||
* Features specifically for Bungee/Velocity
|
||||
* Only want to enable maintenance on a single server? You can also do so by using the `/maintenance <on/off> <servername>` command
|
||||
* Link multiple proxy instances through a MySQL database connection, so you don't have to change maintenance on each proxy by hand
|
||||
* Use PlaceholderAPI placeholders with the [**MaintenanceAddon**](https://github.com/kennytv/Maintenance/wiki/MaintenanceAddon) (only for Bungee)
|
||||
* Use PlaceholderAPI placeholders with the [**MaintenanceAddon**](https://hangar.papermc.io/kennytv/MaintenanceAddon) (for Velocity and Bungee)
|
||||
|
||||
A full list of commands, permissions and configuration options can be found in the wiki listed below.
|
||||
* [Hangar Downloads](https://hangar.papermc.io/kennytv/Maintenance)
|
||||
* [Wiki](https://github.com/kennytv/Maintenance/wiki) (configuration, permissions, API usage)
|
||||
* [Downloads](https://github.com/kennytv/Maintenance/releases) (GitHub)
|
||||
* [Changelogs](https://github.com/kennytv/Maintenance/blob/master/.github/CHANGELOG.md)
|
||||
* [Issue tracker/bug reports](https://github.com/kennytv/Maintenance/issues)
|
||||
* [Discord](https://discord.gg/vGCUzHq)
|
||||
* [PlaceholderAPI addon](https://github.com/kennytv/Maintenance/wiki/MaintenanceAddon)
|
||||
* [PlaceholderAPI addon](https://hangar.papermc.io/kennytv/MaintenanceAddon)
|
||||
|
||||
Other forum threads
|
||||
* [Spigot forums](https://www.spigotmc.org/resources/maintenance.40699/)
|
||||
* [Ore/Sponge Forums](https://ore.spongepowered.org/KennyTV/Maintenance)
|
||||
* [Velocity forums](https://forums.velocitypowered.com/t/maintenance/129)
|
||||
|
||||
## Localization
|
||||
The English base language file is localized using Crodwin. You can see and update translations here: https://crowdin.com/project/maintenance
|
||||
|
||||
Join [our Discord](https://discord.gg/vGCUzHq) if you want to get the proofreader or translator role on the project.
|
||||
Adding translations for languages not yet listed is always appreciated as well!
|
||||
|
||||
## Compiling
|
||||
To create a working jar yourself, simply clone the project and compile it with maven (by using `mvn clean package` in your IDE console).
|
||||
To create a working jar yourself, simply clone the project and compile it with Gradle (`gradlew build`).
|
||||
|
||||
## License
|
||||
This project is licensed under the [GNU General Public License v3](LICENSE.txt).
|
||||
@@ -0,0 +1,24 @@
|
||||
plugins {
|
||||
id("com.gradleup.shadow")
|
||||
}
|
||||
|
||||
// Shade and relocate adventure in an extra module, so that common/the rest can directly depend on a
|
||||
// relocated adventure without breaking native platform's adventure usage with project wide relocation
|
||||
tasks {
|
||||
shadowJar {
|
||||
relocate("net.kyori", "eu.kennytv.maintenance.lib.kyori")
|
||||
}
|
||||
build {
|
||||
dependsOn(shadowJar)
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(libs.bundles.adventure) {
|
||||
exclude("net.kyori", "adventure-api")
|
||||
exclude("net.kyori", "adventure-bom")
|
||||
exclude("com.google.code.gson", "gson")
|
||||
}
|
||||
}
|
||||
|
||||
publishShadowJar()
|
||||
@@ -0,0 +1,20 @@
|
||||
plugins {
|
||||
id("com.gradleup.shadow")
|
||||
}
|
||||
|
||||
tasks {
|
||||
shadowJar {
|
||||
relocate("net.kyori", "eu.kennytv.maintenance.lib.kyori")
|
||||
}
|
||||
build {
|
||||
dependsOn(shadowJar)
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(libs.adventurePlatformBukkit) {
|
||||
exclude("net.kyori", "adventure-api")
|
||||
}
|
||||
}
|
||||
|
||||
publishShadowJar()
|
||||
@@ -0,0 +1,20 @@
|
||||
plugins {
|
||||
id("com.gradleup.shadow")
|
||||
}
|
||||
|
||||
tasks {
|
||||
shadowJar {
|
||||
relocate("net.kyori", "eu.kennytv.maintenance.lib.kyori")
|
||||
}
|
||||
build {
|
||||
dependsOn(shadowJar)
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(libs.adventurePlatformBungee) {
|
||||
exclude("net.kyori", "adventure-api")
|
||||
}
|
||||
}
|
||||
|
||||
publishShadowJar()
|
||||
@@ -0,0 +1,14 @@
|
||||
plugins {
|
||||
id("maintenance.shadow-conventions")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(projects.maintenanceApi)
|
||||
compileOnly(projects.adventure.adventureApi) {
|
||||
targetConfiguration = "shadow"
|
||||
}
|
||||
}
|
||||
|
||||
java {
|
||||
withJavadocJar()
|
||||
}
|
||||
+1
-4
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -22,9 +22,6 @@ import eu.kennytv.maintenance.api.proxy.Server;
|
||||
|
||||
/**
|
||||
* Notification event fired when maintenance mode has been changed on a proxied server.
|
||||
*
|
||||
* @author kennytv
|
||||
* @since 3.0.1
|
||||
*/
|
||||
public final class ServerMaintenanceChangedEvent implements MaintenanceEvent {
|
||||
private final Server server;
|
||||
+10
-7
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -17,16 +17,12 @@
|
||||
*/
|
||||
package eu.kennytv.maintenance.api.proxy;
|
||||
|
||||
import eu.kennytv.maintenance.api.IMaintenance;
|
||||
import eu.kennytv.maintenance.api.Maintenance;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author kennytv
|
||||
* @since 3.0
|
||||
*/
|
||||
public interface IMaintenanceProxy extends IMaintenance {
|
||||
public interface MaintenanceProxy extends Maintenance {
|
||||
|
||||
/**
|
||||
* Enables/disables maintenance mode on a proxied server.
|
||||
@@ -63,6 +59,13 @@ public interface IMaintenanceProxy extends IMaintenance {
|
||||
@Nullable
|
||||
Server getServer(String server);
|
||||
|
||||
/**
|
||||
* Returns the currently registered proxied servers.
|
||||
*
|
||||
* @return set of proxied servers
|
||||
*/
|
||||
Set<String> getServers();
|
||||
|
||||
/**
|
||||
* @return immutable set with names of all proxied server that are currently under maintenance
|
||||
*/
|
||||
+6
-7
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -17,12 +17,11 @@
|
||||
*/
|
||||
package eu.kennytv.maintenance.api.proxy;
|
||||
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
|
||||
|
||||
/**
|
||||
* Wrapper for a proxied server.
|
||||
* Use {@link IMaintenanceProxy#getServer(String)} to get a server instance.
|
||||
*
|
||||
* @author kennytv
|
||||
* @since 3.0
|
||||
* Use {@link MaintenanceProxy#getServer(String)} to get a server instance.
|
||||
*/
|
||||
public interface Server {
|
||||
|
||||
@@ -39,9 +38,9 @@ public interface Server {
|
||||
/**
|
||||
* Sends a message to all players on the server.
|
||||
*
|
||||
* @param message message to be broadcasted
|
||||
* @param component message to be broadcasted
|
||||
*/
|
||||
void broadcast(String message);
|
||||
void broadcast(Component component);
|
||||
|
||||
/**
|
||||
* Returns whether the server is registered under the proxy.
|
||||
@@ -0,0 +1,11 @@
|
||||
plugins {
|
||||
id("maintenance.shadow-conventions")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnlyApi(libs.jetbrainsAnnotations)
|
||||
}
|
||||
|
||||
java {
|
||||
withJavadocJar()
|
||||
}
|
||||
+9
-13
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -17,13 +17,9 @@
|
||||
*/
|
||||
package eu.kennytv.maintenance.api;
|
||||
|
||||
import eu.kennytv.maintenance.api.event.manager.IEventManager;
|
||||
import eu.kennytv.maintenance.api.event.manager.EventManager;
|
||||
|
||||
/**
|
||||
* @author kennytv
|
||||
* @since 2.1
|
||||
*/
|
||||
public interface IMaintenance {
|
||||
public interface Maintenance {
|
||||
|
||||
/**
|
||||
* Enables/disables maintenance mode.
|
||||
@@ -53,18 +49,18 @@ public interface IMaintenance {
|
||||
String getVersion();
|
||||
|
||||
/**
|
||||
* Returns the {@link ISettings} instance, which gives further insight into settings set in the config files.
|
||||
* Returns the {@link Settings} instance, which gives further insight into settings set in the config files.
|
||||
*
|
||||
* @return {@link ISettings} instance
|
||||
* @return {@link Settings} instance
|
||||
*/
|
||||
ISettings getSettings();
|
||||
Settings getSettings();
|
||||
|
||||
/**
|
||||
* Returns the {@link IEventManager} instance to register listeners to maintenance events.
|
||||
* Returns the {@link EventManager} instance to register listeners to maintenance events.
|
||||
*
|
||||
* @return {@link IEventManager} instance
|
||||
* @return {@link EventManager} instance
|
||||
*/
|
||||
IEventManager getEventManager();
|
||||
EventManager getEventManager();
|
||||
|
||||
/**
|
||||
* @return true if debug mode is enabled, currently only implemented on Bungee
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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 eu.kennytv.maintenance.api;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Provider to get the maintenance api instance.
|
||||
*/
|
||||
public final class MaintenanceProvider {
|
||||
private static Maintenance maintenance;
|
||||
|
||||
private MaintenanceProvider() {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static void setMaintenance(final Maintenance maintenance) {
|
||||
if (MaintenanceProvider.maintenance != null) {
|
||||
throw new IllegalArgumentException("MaintenanceProvider is already set!");
|
||||
}
|
||||
MaintenanceProvider.maintenance = maintenance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maintenance api instance, or null if not loaded yet.
|
||||
*
|
||||
* @return maintenance api instance
|
||||
*/
|
||||
public static @Nullable Maintenance get() {
|
||||
return maintenance;
|
||||
}
|
||||
}
|
||||
+3
-7
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -20,11 +20,7 @@ package eu.kennytv.maintenance.api;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author kennytv
|
||||
* @since 2.1
|
||||
*/
|
||||
public interface ISettings {
|
||||
public interface Settings {
|
||||
|
||||
/**
|
||||
* Note that the value might need a few seconds to update, if you're on BungeeCord with MySQL enabled
|
||||
@@ -88,7 +84,7 @@ public interface ISettings {
|
||||
*
|
||||
* @param uuid uuid of the player to add
|
||||
* @param name of the player to add
|
||||
* @return true if adding the player was successful
|
||||
* @return true if adding the player was successful, false if already on the whitelist
|
||||
*/
|
||||
boolean addWhitelistedPlayer(UUID uuid, String name);
|
||||
|
||||
+1
-4
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -21,9 +21,6 @@ import eu.kennytv.maintenance.api.event.manager.MaintenanceEvent;
|
||||
|
||||
/**
|
||||
* Notification event fired when maintenance mode has been changed.
|
||||
*
|
||||
* @author kennytv
|
||||
* @since 3.0.1
|
||||
*/
|
||||
public final class MaintenanceChangedEvent implements MaintenanceEvent {
|
||||
private final boolean maintenance;
|
||||
+4
-6
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -17,17 +17,15 @@
|
||||
*/
|
||||
package eu.kennytv.maintenance.api.event;
|
||||
|
||||
import eu.kennytv.maintenance.api.IMaintenance;
|
||||
import eu.kennytv.maintenance.api.Maintenance;
|
||||
import eu.kennytv.maintenance.api.event.manager.MaintenanceEvent;
|
||||
import eu.kennytv.maintenance.api.proxy.IMaintenanceProxy;
|
||||
|
||||
/**
|
||||
* Notification event fired when Maintenance configuration is reloaded.
|
||||
*
|
||||
* @author kennytv
|
||||
* @see IMaintenance#isMaintenance() for the new maintenance status
|
||||
* @see IMaintenanceProxy#getMaintenanceServers() for the new list of servers under maintenance
|
||||
* @since 3.0.6
|
||||
* @see Maintenance#isMaintenance() for the new maintenance status
|
||||
* //@see MaintenanceProxy#getMaintenanceServers() for the new list of servers under maintenance
|
||||
*/
|
||||
public final class MaintenanceReloadedEvent implements MaintenanceEvent {
|
||||
}
|
||||
+1
-3
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -21,8 +21,6 @@ package eu.kennytv.maintenance.api.event.manager;
|
||||
* Abstract class representing a maintenance eventlistener.
|
||||
*
|
||||
* @param <T> event to be listened to
|
||||
* @author kennytv
|
||||
* @since 3.0.1
|
||||
*/
|
||||
public abstract class EventListener<T extends MaintenanceEvent> {
|
||||
|
||||
+2
-6
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -17,11 +17,7 @@
|
||||
*/
|
||||
package eu.kennytv.maintenance.api.event.manager;
|
||||
|
||||
/**
|
||||
* @author kennytv
|
||||
* @since 3.0.1
|
||||
*/
|
||||
public interface IEventManager {
|
||||
public interface EventManager {
|
||||
|
||||
/**
|
||||
* Registers an eventlistener for the given maintenance event.
|
||||
+1
-4
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -19,9 +19,6 @@ package eu.kennytv.maintenance.api.event.manager;
|
||||
|
||||
/**
|
||||
* Dummy interface representing a maintenance event.
|
||||
*
|
||||
* @author kennytv
|
||||
* @since 3.0.1
|
||||
*/
|
||||
public interface MaintenanceEvent {
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
plugins {
|
||||
`kotlin-dsl`
|
||||
}
|
||||
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// version must be manually kept in sync with the one in root project settings.gradle.kts
|
||||
implementation("com.gradleup.shadow", "shadow-gradle-plugin", "8.3.9")
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.plugins.JavaPluginExtension
|
||||
import org.gradle.api.publish.PublishingExtension
|
||||
import org.gradle.api.publish.maven.MavenPublication
|
||||
import org.gradle.jvm.toolchain.JavaLanguageVersion
|
||||
import org.gradle.kotlin.dsl.configure
|
||||
import org.gradle.kotlin.dsl.get
|
||||
import org.gradle.kotlin.dsl.named
|
||||
import java.io.ByteArrayOutputStream
|
||||
|
||||
fun Project.publishShadowJar() {
|
||||
configurePublication {
|
||||
artifact(tasks["shadowJar"])
|
||||
artifact(tasks["sourcesJar"])
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.publishJavaComponents() {
|
||||
configurePublication {
|
||||
from(components["java"])
|
||||
}
|
||||
}
|
||||
|
||||
private fun Project.configurePublication(configurer: MavenPublication.() -> Unit) {
|
||||
extensions.configure<PublishingExtension> {
|
||||
publications.named<MavenPublication>("mavenJava") {
|
||||
apply(configurer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.latestCommitHash(): String {
|
||||
return providers.exec {
|
||||
commandLine = listOf("git", "rev-parse", "--short", "HEAD")
|
||||
}.standardOutput.asBytes.get().toString(Charsets.UTF_8).trim()
|
||||
}
|
||||
|
||||
fun JavaPluginExtension.javaTarget(version: Int) {
|
||||
toolchain.languageVersion.set(JavaLanguageVersion.of(17))
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
plugins {
|
||||
`java-library`
|
||||
`maven-publish`
|
||||
signing
|
||||
}
|
||||
|
||||
tasks {
|
||||
// Variable replacements
|
||||
processResources {
|
||||
val ver = project.version.toString()
|
||||
val desc = project.description
|
||||
filesMatching(listOf("plugin.yml", "bungee.yml", "META-INF/sponge_plugins.json")) {
|
||||
expand("version" to ver, "description" to desc)
|
||||
}
|
||||
}
|
||||
javadoc {
|
||||
options.encoding = Charsets.UTF_8.name()
|
||||
(options as StandardJavadocDocletOptions).addStringOption("Xdoclint:none", "-quiet")
|
||||
}
|
||||
compileJava {
|
||||
options.encoding = Charsets.UTF_8.name()
|
||||
options.compilerArgs.addAll(listOf("-nowarn", "-Xlint:-unchecked", "-Xlint:-deprecation"))
|
||||
}
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
}
|
||||
|
||||
java {
|
||||
javaTarget(8)
|
||||
withSourcesJar()
|
||||
}
|
||||
|
||||
signing {
|
||||
useGpgCmd()
|
||||
sign(publishing.publications)
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications.create<MavenPublication>("mavenJava") {
|
||||
groupId = rootProject.group as String
|
||||
artifactId = project.name
|
||||
version = rootProject.version as String
|
||||
pom {
|
||||
name.set("Maintenance")
|
||||
description.set("Paper plugin to enable maintenance mode on your Minecraft server.")
|
||||
url.set("https://github.com/kennytv/Maintenance")
|
||||
licenses {
|
||||
license {
|
||||
name.set("GNU GPLv3")
|
||||
url.set("https://www.gnu.org/licenses/gpl-3.0.html")
|
||||
}
|
||||
}
|
||||
developers {
|
||||
developer {
|
||||
id.set("kennytv")
|
||||
name.set("Nassim Jahnke")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!name.startsWith("adventure")) {
|
||||
repositories.maven {
|
||||
name = "OSSRH"
|
||||
url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots/")
|
||||
credentials {
|
||||
username = System.getenv("OSSRH_USERNAME")
|
||||
password = System.getenv("OSSRH_PASSWORD")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,12 @@
|
||||
import java.util.*
|
||||
|
||||
plugins {
|
||||
id("maintenance.shadow-conventions")
|
||||
}
|
||||
|
||||
tasks {
|
||||
shadowJar {
|
||||
archiveFileName.set("Maintenance-${project.name.substringAfter("maintenance-").replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }}-${project.version}.jar")
|
||||
destinationDirectory.set(rootProject.layout.buildDirectory.dir("libs"))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import org.gradle.jvm.tasks.Jar
|
||||
import org.gradle.kotlin.dsl.named
|
||||
|
||||
plugins {
|
||||
id("maintenance.base-conventions")
|
||||
id("com.gradleup.shadow")
|
||||
}
|
||||
|
||||
tasks {
|
||||
named<Jar>("jar") {
|
||||
archiveClassifier.set("unshaded")
|
||||
from(project.rootProject.file("LICENSE.txt"))
|
||||
}
|
||||
val shadowJar = named<ShadowJar>("shadowJar") {
|
||||
archiveClassifier.set("")
|
||||
configureRelocations()
|
||||
}
|
||||
named("build") {
|
||||
dependsOn(shadowJar)
|
||||
}
|
||||
}
|
||||
|
||||
publishShadowJar()
|
||||
|
||||
fun ShadowJar.configureRelocations() {
|
||||
relocate("com.zaxxer.hikari", "eu.kennytv.maintenance.lib.hikari")
|
||||
relocate("org.bstats", "eu.kennytv.maintenance.lib.bstats")
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
plugins {
|
||||
id("maintenance.base-conventions")
|
||||
}
|
||||
|
||||
publishJavaComponents()
|
||||
@@ -0,0 +1,41 @@
|
||||
import org.gradle.api.plugins.JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME
|
||||
|
||||
plugins {
|
||||
base
|
||||
id("eclipse")
|
||||
id("maintenance.build-logic")
|
||||
}
|
||||
|
||||
allprojects {
|
||||
group = "eu.kennytv.maintenance"
|
||||
version = property("projectVersion") as String // from gradle.properties
|
||||
description = "Enable maintenance mode with a custom maintenance motd and icon."
|
||||
}
|
||||
|
||||
val platforms = setOf(
|
||||
projects.maintenancePaper,
|
||||
projects.maintenanceSponge,
|
||||
projects.maintenanceVelocity
|
||||
).map { it.path }
|
||||
|
||||
val special = setOf(
|
||||
projects.maintenance,
|
||||
projects.maintenanceApi,
|
||||
projects.maintenanceApiProxy,
|
||||
projects.adventure,
|
||||
projects.adventure.adventureApi,
|
||||
projects.adventure.adventurePlatformBukkit,
|
||||
).map { it.path }
|
||||
|
||||
subprojects {
|
||||
when (path) {
|
||||
in platforms -> plugins.apply("maintenance.platform-conventions")
|
||||
in special -> plugins.apply("maintenance.base-conventions")
|
||||
else -> plugins.apply("maintenance.standard-conventions")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
TEST_IMPLEMENTATION_CONFIGURATION_NAME(rootProject.libs.bundles.junit)
|
||||
TEST_IMPLEMENTATION_CONFIGURATION_NAME(rootProject.libs.snakeyaml)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
dependencies {
|
||||
api(projects.maintenanceApiProxy)
|
||||
api(projects.maintenanceCore)
|
||||
implementation(libs.hikariCP)
|
||||
compileOnly(libs.luckperms)
|
||||
compileOnly(libs.guava)
|
||||
compileOnly(libs.gson)
|
||||
}
|
||||
|
||||
java {
|
||||
withJavadocJar()
|
||||
}
|
||||
+93
-14
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -20,7 +20,7 @@ package eu.kennytv.maintenance.core.proxy;
|
||||
import com.google.common.io.CharStreams;
|
||||
import com.google.gson.JsonObject;
|
||||
import eu.kennytv.maintenance.api.event.proxy.ServerMaintenanceChangedEvent;
|
||||
import eu.kennytv.maintenance.api.proxy.IMaintenanceProxy;
|
||||
import eu.kennytv.maintenance.api.proxy.MaintenanceProxy;
|
||||
import eu.kennytv.maintenance.api.proxy.Server;
|
||||
import eu.kennytv.maintenance.core.MaintenancePlugin;
|
||||
import eu.kennytv.maintenance.core.proxy.command.MaintenanceProxyCommand;
|
||||
@@ -28,16 +28,17 @@ import eu.kennytv.maintenance.core.proxy.runnable.SingleMaintenanceRunnable;
|
||||
import eu.kennytv.maintenance.core.proxy.runnable.SingleMaintenanceScheduleRunnable;
|
||||
import eu.kennytv.maintenance.core.proxy.util.ProfileLookup;
|
||||
import eu.kennytv.maintenance.core.runnable.MaintenanceRunnableBase;
|
||||
import eu.kennytv.maintenance.core.util.RateLimitedException;
|
||||
import eu.kennytv.maintenance.core.util.SenderInfo;
|
||||
import eu.kennytv.maintenance.core.util.ServerType;
|
||||
import eu.kennytv.maintenance.core.util.Task;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@@ -45,13 +46,14 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.jetbrains.annotations.Blocking;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author kennytv
|
||||
* @since 3.0
|
||||
*/
|
||||
public abstract class MaintenanceProxyPlugin extends MaintenancePlugin implements IMaintenanceProxy {
|
||||
public abstract class MaintenanceProxyPlugin extends MaintenancePlugin implements MaintenanceProxy {
|
||||
private final Map<String, Task> serverTasks = new HashMap<>();
|
||||
protected SettingsProxy settingsProxy;
|
||||
|
||||
@@ -83,11 +85,23 @@ public abstract class MaintenanceProxyPlugin extends MaintenancePlugin implement
|
||||
@Override
|
||||
public boolean setMaintenanceToServer(final Server server, final boolean maintenance) {
|
||||
if (maintenance) {
|
||||
if (!settingsProxy.addMaintenanceServer(server.getName())) return false;
|
||||
} else {
|
||||
if (!settingsProxy.removeMaintenanceServer(server.getName())) return false;
|
||||
if (!settingsProxy.addMaintenanceServer(server.getName())) {
|
||||
return false;
|
||||
}
|
||||
} else if (!settingsProxy.removeMaintenanceServer(server.getName())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
serverActions(server, maintenance);
|
||||
|
||||
for (final String command : (maintenance ? settingsProxy.getCommandsOnMaintenanceEnable(server) : settingsProxy.getCommandsOnMaintenanceDisable(server))) {
|
||||
try {
|
||||
executeConsoleCommand(command.replace("%SERVER%", server.getName()));
|
||||
} catch (final Exception e) {
|
||||
getLogger().severe("Error while executing extra maintenance " + (maintenance ? "enable" : "disable") + " command: " + command);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -105,7 +119,7 @@ public abstract class MaintenanceProxyPlugin extends MaintenancePlugin implement
|
||||
}
|
||||
kickPlayers(server, fallback);
|
||||
} else {
|
||||
server.broadcast(settingsProxy.getMessage("singleMaintenanceDeactivated").replace("%SERVER%", server.getName()));
|
||||
server.broadcast(settingsProxy.getMessage("singleMaintenanceDeactivated", "%SERVER%", server.getName()));
|
||||
}
|
||||
|
||||
cancelSingleTask(server);
|
||||
@@ -131,15 +145,15 @@ public abstract class MaintenanceProxyPlugin extends MaintenancePlugin implement
|
||||
}
|
||||
}
|
||||
|
||||
public MaintenanceRunnableBase startSingleMaintenanceRunnable(final Server server, final long duration, final TimeUnit unit, final boolean enable) {
|
||||
final MaintenanceRunnableBase runnable = new SingleMaintenanceRunnable(this, settingsProxy, (int) unit.toSeconds(duration), enable, server);
|
||||
public MaintenanceRunnableBase startSingleMaintenanceRunnable(final Server server, final Duration duration, final boolean enable) {
|
||||
final MaintenanceRunnableBase runnable = new SingleMaintenanceRunnable(this, settingsProxy, (int) duration.getSeconds(), enable, server);
|
||||
serverTasks.put(server.getName(), runnable.getTask());
|
||||
return runnable;
|
||||
}
|
||||
|
||||
public MaintenanceRunnableBase scheduleSingleMaintenanceRunnable(final Server server, final long duration, final long maintenanceDuration, final TimeUnit unit) {
|
||||
public MaintenanceRunnableBase scheduleSingleMaintenanceRunnable(final Server server, final Duration enableIn, final Duration maintenanceDuration) {
|
||||
final MaintenanceRunnableBase runnable = new SingleMaintenanceScheduleRunnable(this, settingsProxy,
|
||||
(int) unit.toSeconds(duration), (int) unit.toSeconds(maintenanceDuration), server);
|
||||
(int) enableIn.getSeconds(), (int) maintenanceDuration.getSeconds(), server);
|
||||
serverTasks.put(server.getName(), runnable.getTask());
|
||||
return runnable;
|
||||
}
|
||||
@@ -175,9 +189,66 @@ public abstract class MaintenanceProxyPlugin extends MaintenancePlugin implement
|
||||
kickPlayersFromProxy();
|
||||
}
|
||||
|
||||
@Blocking
|
||||
@Nullable
|
||||
protected ProfileLookup doUUIDLookup(final String name) throws IOException {
|
||||
ProfileLookup profileLookup;
|
||||
try {
|
||||
profileLookup = doUUIDLookupMojangAPI(name);
|
||||
} catch (RateLimitedException e) {
|
||||
// Use fallback API if rate limit is reached
|
||||
profileLookup = doUUIDLookupAshconAPI(name);
|
||||
}
|
||||
|
||||
if (settingsProxy.isFallbackToOfflineUUID() && profileLookup == null) {
|
||||
// Use offline uuid
|
||||
return new ProfileLookup(UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(StandardCharsets.UTF_8)), name);
|
||||
}
|
||||
|
||||
return profileLookup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Official Mojang API
|
||||
*/
|
||||
@Nullable
|
||||
private ProfileLookup doUUIDLookupMojangAPI(final String name) throws IOException {
|
||||
final URL url = new URL("https://api.mojang.com/users/profiles/minecraft/" + name);
|
||||
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod("GET");
|
||||
|
||||
int status = connection.getResponseCode();
|
||||
if (status == 429) {
|
||||
throw new RateLimitedException();
|
||||
}
|
||||
if (status == 404) {
|
||||
// Return null if profile not found
|
||||
return null;
|
||||
}
|
||||
|
||||
try (final InputStream in = connection.getInputStream()) {
|
||||
final String output = CharStreams.toString(new InputStreamReader(in));
|
||||
final JsonObject json = GSON.fromJson(output, JsonObject.class);
|
||||
|
||||
final UUID uuid = fromStringUUIDWithoutDashes(json.getAsJsonPrimitive("id").getAsString());
|
||||
final String username = json.getAsJsonPrimitive("name").getAsString();
|
||||
return new ProfileLookup(uuid, username);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fallback API (Ashcon API)
|
||||
*/
|
||||
@Nullable
|
||||
private ProfileLookup doUUIDLookupAshconAPI(final String name) throws IOException {
|
||||
final URL url = new URL("https://api.ashcon.app/mojang/v2/user/" + name);
|
||||
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
|
||||
if (connection.getResponseCode() == 403) {
|
||||
// Return null if profile not found
|
||||
return null;
|
||||
}
|
||||
|
||||
try (final InputStream in = connection.getInputStream()) {
|
||||
final String output = CharStreams.toString(new InputStreamReader(in));
|
||||
final JsonObject json = GSON.fromJson(output, JsonObject.class);
|
||||
@@ -188,6 +259,14 @@ public abstract class MaintenanceProxyPlugin extends MaintenancePlugin implement
|
||||
}
|
||||
}
|
||||
|
||||
private UUID fromStringUUIDWithoutDashes(String undashedUUID) {
|
||||
return UUID.fromString(
|
||||
undashedUUID.substring(0, 8) + "-" + undashedUUID.substring(8, 12) + "-" +
|
||||
undashedUUID.substring(12, 16) + "-" + undashedUUID.substring(16, 20) + "-" +
|
||||
undashedUUID.substring(20, 32)
|
||||
);
|
||||
}
|
||||
|
||||
public SettingsProxy getSettingsProxy() {
|
||||
return settingsProxy;
|
||||
}
|
||||
+53
-11
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -21,13 +21,17 @@ import eu.kennytv.maintenance.api.proxy.Server;
|
||||
import eu.kennytv.maintenance.core.Settings;
|
||||
import eu.kennytv.maintenance.core.config.ConfigSection;
|
||||
import eu.kennytv.maintenance.core.proxy.mysql.MySQL;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public final class SettingsProxy extends Settings {
|
||||
@@ -35,7 +39,10 @@ public final class SettingsProxy extends Settings {
|
||||
private Set<String> maintenanceServers;
|
||||
private List<String> fallbackServers;
|
||||
private String waitingServer;
|
||||
private boolean fallbackToOfflineUUID;
|
||||
|
||||
private Map<String, List<String>> commandsOnMaintenanceEnable;
|
||||
private Map<String, List<String>> commandsOnMaintenanceDisable;
|
||||
private String mySQLTable;
|
||||
private String serverTable;
|
||||
private String maintenanceQuery;
|
||||
@@ -51,7 +58,7 @@ public final class SettingsProxy extends Settings {
|
||||
this.proxyPlugin = plugin;
|
||||
}
|
||||
|
||||
private void setupMySQL() throws Exception {
|
||||
private void setupMySQL() {
|
||||
plugin.getLogger().info("Trying to open database connection... (also, you can simply ignore the SLF4J soft-warning if it shows up)");
|
||||
final ConfigSection section = config.getSection("mysql");
|
||||
if (section == null) {
|
||||
@@ -91,12 +98,25 @@ public final class SettingsProxy extends Settings {
|
||||
}
|
||||
|
||||
final Object fallback = config.getObject("fallback");
|
||||
fallbackServers = fallback instanceof String ? Collections.singletonList((String) fallback) : config.getStringList("fallback");
|
||||
fallbackServers = fallback instanceof String ? Collections.singletonList((String) fallback) : config.getStringList("fallback", Collections.emptyList());
|
||||
|
||||
waitingServer = config.getString("waiting-server", "");
|
||||
if (waitingServer.isEmpty() || waitingServer.equalsIgnoreCase("none")) {
|
||||
waitingServer = null;
|
||||
}
|
||||
fallbackToOfflineUUID = config.getBoolean("fallback-to-offline-uuid", false);
|
||||
|
||||
commandsOnMaintenanceEnable = new HashMap<>();
|
||||
final ConfigSection enableCommandsSection = config.getSection("commands-on-single-maintenance-enable");
|
||||
for (final String key : enableCommandsSection.getKeys()) {
|
||||
commandsOnMaintenanceEnable.put(key.toLowerCase(Locale.ROOT), enableCommandsSection.getStringList(key));
|
||||
}
|
||||
|
||||
commandsOnMaintenanceDisable = new HashMap<>();
|
||||
final ConfigSection disableCommandsSection = config.getSection("commands-on-single-maintenance-disable");
|
||||
for (final String key : disableCommandsSection.getKeys()) {
|
||||
commandsOnMaintenanceDisable.put(key.toLowerCase(Locale.ROOT), disableCommandsSection.getStringList(key));
|
||||
}
|
||||
|
||||
if (hasMySQL()) {
|
||||
maintenance = loadMaintenance();
|
||||
@@ -149,21 +169,21 @@ public final class SettingsProxy extends Settings {
|
||||
return maintenanceServers.contains(serverName);
|
||||
}
|
||||
|
||||
public String getServerKickMessage(final String server) {
|
||||
String message = language.getString("singleMaintenanceKicks." + server);
|
||||
public Component getServerKickMessage(final String server) {
|
||||
String message = getLanguageStringOrNull("singleMaintenanceKicks." + server, "%SERVER%", server);
|
||||
if (message == null) {
|
||||
message = getMessage("singleMaintenanceKick");
|
||||
message = getLanguageString("singleMaintenanceKick", "%SERVER%", server);
|
||||
}
|
||||
return plugin.replacePingVariables(message).replace("%SERVER%", server);
|
||||
return parse(plugin.replacePingVariables(message));
|
||||
}
|
||||
|
||||
// Full = being kicked from the proxy, not just a proxied server
|
||||
public String getFullServerKickMessage(final String server) {
|
||||
String message = language.getString("singleMaintenanceKicksComplete." + server);
|
||||
public Component getFullServerKickMessage(final String server) {
|
||||
String message = getLanguageStringOrNull("singleMaintenanceKicksComplete." + server, "%SERVER%", server);
|
||||
if (message == null) {
|
||||
message = getMessage("singleMaintenanceKickComplete");
|
||||
message = getLanguageString("singleMaintenanceKickComplete", "%SERVER%", server);
|
||||
}
|
||||
return plugin.replacePingVariables(message).replace("%SERVER%", server);
|
||||
return parse(plugin.replacePingVariables(message));
|
||||
}
|
||||
|
||||
public boolean hasMySQL() {
|
||||
@@ -261,6 +281,28 @@ public final class SettingsProxy extends Settings {
|
||||
return waitingServer;
|
||||
}
|
||||
|
||||
public boolean isFallbackToOfflineUUID() {
|
||||
return fallbackToOfflineUUID;
|
||||
}
|
||||
|
||||
public List<String> getCommandsOnMaintenanceEnable(final Server server) {
|
||||
final List<String> enableCommands = commandsOnMaintenanceEnable.getOrDefault("all", new ArrayList<>());
|
||||
final List<String> serverEnableCommands = commandsOnMaintenanceEnable.get(server.getName().toLowerCase(Locale.ROOT));
|
||||
if (serverEnableCommands != null) {
|
||||
enableCommands.addAll(serverEnableCommands);
|
||||
}
|
||||
return enableCommands;
|
||||
}
|
||||
|
||||
public List<String> getCommandsOnMaintenanceDisable(final Server server) {
|
||||
final List<String> disableCommands = commandsOnMaintenanceDisable.getOrDefault("all", new ArrayList<>());
|
||||
final List<String> serverDisableCommands = commandsOnMaintenanceDisable.get(server.getName().toLowerCase(Locale.ROOT));
|
||||
if (serverDisableCommands != null) {
|
||||
disableCommands.addAll(serverDisableCommands);
|
||||
}
|
||||
return disableCommands;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
MySQL getMySQL() {
|
||||
return mySQL;
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -62,11 +62,11 @@ public abstract class MaintenanceProxyCommand extends MaintenanceCommand {
|
||||
public Server checkSingleTimerServerArg(final SenderInfo sender, final String serverName) {
|
||||
final Server server = plugin.getServer(serverName);
|
||||
if (server == null) {
|
||||
sender.sendMessage(settings.getMessage("serverNotFound"));
|
||||
sender.send(settings.getMessage("serverNotFound"));
|
||||
return null;
|
||||
}
|
||||
if (plugin.isServerTaskRunning(server)) {
|
||||
sender.sendMessage(settings.getMessage("singleTimerAlreadyRunning"));
|
||||
sender.send(settings.getMessage("singleTimerAlreadyRunning"));
|
||||
return null;
|
||||
}
|
||||
return server;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
+7
-7
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -41,28 +41,28 @@ public final class AbortSingleTimerCommand extends ProxyCommandInfo {
|
||||
if (args.length == 1) {
|
||||
if (checkPermission(sender, "timer")) return;
|
||||
if (!plugin.isTaskRunning()) {
|
||||
sender.sendMessage(getMessage("timerNotRunning"));
|
||||
sender.send(getMessage("timerNotRunning"));
|
||||
return;
|
||||
}
|
||||
|
||||
plugin.cancelTask();
|
||||
sender.sendMessage(getMessage("timerCancelled"));
|
||||
sender.send(getMessage("timerCancelled"));
|
||||
} else if (args.length == 2) {
|
||||
if (checkPermission(sender, "singleserver.timer")) return;
|
||||
final Server server = plugin.getServer(args[1]);
|
||||
if (server == null) {
|
||||
sender.sendMessage(getMessage("serverNotFound"));
|
||||
sender.send(getMessage("serverNotFound"));
|
||||
return;
|
||||
}
|
||||
if (!plugin.isServerTaskRunning(server)) {
|
||||
sender.sendMessage(getMessage("singleTimerNotRunning"));
|
||||
sender.send(getMessage("singleTimerNotRunning"));
|
||||
return;
|
||||
}
|
||||
|
||||
plugin.cancelSingleTask(server);
|
||||
sender.sendMessage(getMessage("singleTimerCancelled"));
|
||||
sender.send(getMessage("singleTimerCancelled", "%SERVER%", server.getName()));
|
||||
} else
|
||||
sender.sendMessage(getHelpMessage());
|
||||
sender.send(getHelpMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
+21
-14
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -22,10 +22,9 @@ import eu.kennytv.maintenance.core.proxy.MaintenanceProxyPlugin;
|
||||
import eu.kennytv.maintenance.core.proxy.command.ProxyCommandInfo;
|
||||
import eu.kennytv.maintenance.core.runnable.MaintenanceRunnableBase;
|
||||
import eu.kennytv.maintenance.core.util.SenderInfo;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public final class SingleEndtimerCommand extends ProxyCommandInfo {
|
||||
|
||||
@@ -42,35 +41,43 @@ public final class SingleEndtimerCommand extends ProxyCommandInfo {
|
||||
public void execute(final SenderInfo sender, final String[] args) {
|
||||
if (args.length == 2) {
|
||||
if (checkPermission(sender, "timer")) return;
|
||||
if (plugin.getCommandManager().checkTimerArgs(sender, args[1])) {
|
||||
sender.sendMessage(getHelpMessage());
|
||||
|
||||
final Duration duration = plugin.getCommandManager().parseDurationAndCheckTask(sender, args[1]);
|
||||
if (duration == null) {
|
||||
sender.send(getHelpMessage());
|
||||
return;
|
||||
}
|
||||
if (!plugin.isMaintenance()) {
|
||||
sender.sendMessage(getMessage("alreadyDisabled"));
|
||||
sender.send(getMessage("alreadyDisabled"));
|
||||
return;
|
||||
}
|
||||
|
||||
plugin.startMaintenanceRunnable(Integer.parseInt(args[1]), TimeUnit.MINUTES, false);
|
||||
sender.sendMessage(getMessage("endtimerStarted").replace("%TIME%", plugin.getRunnable().getTime()));
|
||||
plugin.startMaintenanceRunnable(duration, false);
|
||||
sender.send(getMessage("endtimerStarted", "%TIME%", plugin.getRunnable().getTime()));
|
||||
} else if (args.length == 3) {
|
||||
if (checkPermission(sender, "singleserver.timer")) return;
|
||||
if (plugin.getCommandManager().checkTimerArgs(sender, args[2], false)) {
|
||||
sender.sendMessage(getHelpMessage());
|
||||
|
||||
final Duration duration = plugin.getCommandManager().parseDurationAndCheckTask(sender, args[2], false);
|
||||
if (duration == null) {
|
||||
sender.send(getHelpMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
final Server server = plugin.getCommandManager().checkSingleTimerServerArg(sender, args[1]);
|
||||
if (server == null) return;
|
||||
if (!plugin.isMaintenance(server)) {
|
||||
sender.sendMessage(getMessage("singleServerAlreadyDisabled").replace("%SERVER%", server.getName()));
|
||||
sender.send(getMessage("singleServerAlreadyDisabled", "%SERVER%", server.getName()));
|
||||
return;
|
||||
}
|
||||
|
||||
final MaintenanceRunnableBase runnable = plugin.startSingleMaintenanceRunnable(server, Integer.parseInt(args[2]), TimeUnit.MINUTES, false);
|
||||
sender.sendMessage(getMessage("endtimerStarted").replace("%TIME%", runnable.getTime()));
|
||||
final MaintenanceRunnableBase runnable = plugin.startSingleMaintenanceRunnable(server, duration, false);
|
||||
sender.send(getMessage(
|
||||
"singleEndtimerStarted",
|
||||
"%TIME%", runnable.getTime(),
|
||||
"%SERVER%", server.getName()
|
||||
));
|
||||
} else {
|
||||
sender.sendMessage(getHelpMessage());
|
||||
sender.send(getHelpMessage());
|
||||
}
|
||||
}
|
||||
|
||||
+28
-16
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -22,10 +22,9 @@ import eu.kennytv.maintenance.core.proxy.MaintenanceProxyPlugin;
|
||||
import eu.kennytv.maintenance.core.proxy.command.ProxyCommandInfo;
|
||||
import eu.kennytv.maintenance.core.runnable.MaintenanceRunnableBase;
|
||||
import eu.kennytv.maintenance.core.util.SenderInfo;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public final class SingleScheduleTimerCommand extends ProxyCommandInfo {
|
||||
|
||||
@@ -42,37 +41,50 @@ public final class SingleScheduleTimerCommand extends ProxyCommandInfo {
|
||||
public void execute(final SenderInfo sender, final String[] args) {
|
||||
if (args.length == 3) {
|
||||
if (checkPermission(sender, "timer")) return;
|
||||
if (plugin.getCommandManager().checkTimerArgs(sender, args[1])
|
||||
|| plugin.getCommandManager().checkTimerArgs(sender, args[2], false)) {
|
||||
sender.sendMessage(getHelpMessage());
|
||||
|
||||
final Duration enableIn = plugin.getCommandManager().parseDurationAndCheckTask(sender, args[1]);
|
||||
final Duration duration = plugin.getCommandManager().parseDurationAndCheckTask(sender, args[2], false);
|
||||
if (enableIn == null || duration == null) {
|
||||
sender.send(getHelpMessage());
|
||||
return;
|
||||
}
|
||||
if (plugin.isMaintenance()) {
|
||||
sender.sendMessage(getMessage("alreadyEnabled"));
|
||||
sender.send(getMessage("alreadyEnabled"));
|
||||
return;
|
||||
}
|
||||
|
||||
plugin.scheduleMaintenanceRunnable(Integer.parseInt(args[1]), Integer.parseInt(args[2]), TimeUnit.MINUTES);
|
||||
sender.sendMessage(getMessage("starttimerStarted").replace("%TIME%", plugin.getRunnable().getTime()));
|
||||
plugin.scheduleMaintenanceRunnable(duration, enableIn);
|
||||
sender.send(getMessage(
|
||||
"scheduletimerStarted",
|
||||
"%TIME%", plugin.getRunnable().getTime(),
|
||||
"%DURATION%", plugin.getFormattedTime((int) duration.getSeconds())
|
||||
));
|
||||
} else if (args.length == 4) {
|
||||
if (checkPermission(sender, "singleserver.timer")) return;
|
||||
if (plugin.getCommandManager().checkTimerArgs(sender, args[2], false)
|
||||
|| plugin.getCommandManager().checkTimerArgs(sender, args[3], false)) {
|
||||
sender.sendMessage(getHelpMessage());
|
||||
|
||||
final Duration enableIn = plugin.getCommandManager().parseDurationAndCheckTask(sender, args[2], false);
|
||||
final Duration duration = plugin.getCommandManager().parseDurationAndCheckTask(sender, args[3], false);
|
||||
if (enableIn == null || duration == null) {
|
||||
sender.send(getHelpMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
final Server server = plugin.getCommandManager().checkSingleTimerServerArg(sender, args[1]);
|
||||
if (server == null) return;
|
||||
if (plugin.isMaintenance(server)) {
|
||||
sender.sendMessage(getMessage("singleServerAlreadyEnabled").replace("%SERVER%", server.getName()));
|
||||
sender.send(getMessage("singleServerAlreadyEnabled", "%SERVER%", server.getName()));
|
||||
return;
|
||||
}
|
||||
|
||||
final MaintenanceRunnableBase runnable = plugin.scheduleSingleMaintenanceRunnable(server, Integer.parseInt(args[2]), Integer.parseInt(args[3]), TimeUnit.MINUTES);
|
||||
sender.sendMessage(getMessage("starttimerStarted").replace("%TIME%", runnable.getTime()));
|
||||
final MaintenanceRunnableBase runnable = plugin.scheduleSingleMaintenanceRunnable(server, enableIn, duration);
|
||||
sender.send(getMessage(
|
||||
"singleScheduletimerStarted",
|
||||
"%TIME%", runnable.getTime(),
|
||||
"%DURATION%", plugin.getFormattedTime((int) duration.getSeconds()),
|
||||
"%SERVER%", server.getName()
|
||||
));
|
||||
} else {
|
||||
sender.sendMessage(getHelpMessage());
|
||||
sender.send(getHelpMessage());
|
||||
}
|
||||
}
|
||||
|
||||
+21
-14
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -22,10 +22,9 @@ import eu.kennytv.maintenance.core.proxy.MaintenanceProxyPlugin;
|
||||
import eu.kennytv.maintenance.core.proxy.command.ProxyCommandInfo;
|
||||
import eu.kennytv.maintenance.core.runnable.MaintenanceRunnableBase;
|
||||
import eu.kennytv.maintenance.core.util.SenderInfo;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public final class SingleStarttimerCommand extends ProxyCommandInfo {
|
||||
|
||||
@@ -42,35 +41,43 @@ public final class SingleStarttimerCommand extends ProxyCommandInfo {
|
||||
public void execute(final SenderInfo sender, final String[] args) {
|
||||
if (args.length == 2) {
|
||||
if (checkPermission(sender, "timer")) return;
|
||||
if (plugin.getCommandManager().checkTimerArgs(sender, args[1])) {
|
||||
sender.sendMessage(getHelpMessage());
|
||||
|
||||
final Duration duration = plugin.getCommandManager().parseDurationAndCheckTask(sender, args[1]);
|
||||
if (duration == null) {
|
||||
sender.send(getHelpMessage());
|
||||
return;
|
||||
}
|
||||
if (plugin.isMaintenance()) {
|
||||
sender.sendMessage(getMessage("alreadyEnabled"));
|
||||
sender.send(getMessage("alreadyEnabled"));
|
||||
return;
|
||||
}
|
||||
|
||||
plugin.startMaintenanceRunnable(Integer.parseInt(args[1]), TimeUnit.MINUTES, true);
|
||||
sender.sendMessage(getMessage("starttimerStarted").replace("%TIME%", plugin.getRunnable().getTime()));
|
||||
plugin.startMaintenanceRunnable(duration, true);
|
||||
sender.send(getMessage("starttimerStarted", "%TIME%", plugin.getRunnable().getTime()));
|
||||
} else if (args.length == 3) {
|
||||
if (checkPermission(sender, "singleserver.timer")) return;
|
||||
if (plugin.getCommandManager().checkTimerArgs(sender, args[2], false)) {
|
||||
sender.sendMessage(getHelpMessage());
|
||||
|
||||
final Duration duration = plugin.getCommandManager().parseDurationAndCheckTask(sender, args[2], false);
|
||||
if (duration == null) {
|
||||
sender.send(getHelpMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
final Server server = plugin.getCommandManager().checkSingleTimerServerArg(sender, args[1]);
|
||||
if (server == null) return;
|
||||
if (plugin.isMaintenance(server)) {
|
||||
sender.sendMessage(getMessage("singleServerAlreadyEnabled").replace("%SERVER%", server.getName()));
|
||||
sender.send(getMessage("singleServerAlreadyEnabled", "%SERVER%", server.getName()));
|
||||
return;
|
||||
}
|
||||
|
||||
final MaintenanceRunnableBase runnable = plugin.startSingleMaintenanceRunnable(server, Integer.parseInt(args[2]), TimeUnit.MINUTES, true);
|
||||
sender.sendMessage(getMessage("starttimerStarted").replace("%TIME%", runnable.getTime()));
|
||||
final MaintenanceRunnableBase runnable = plugin.startSingleMaintenanceRunnable(server, duration, true);
|
||||
sender.send(getMessage(
|
||||
"singleStarttimerStarted",
|
||||
"%TIME%", runnable.getTime(),
|
||||
"%SERVER%", server.getName()
|
||||
));
|
||||
} else {
|
||||
sender.sendMessage(getHelpMessage());
|
||||
sender.send(getHelpMessage());
|
||||
}
|
||||
}
|
||||
|
||||
+7
-7
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -43,7 +43,7 @@ public final class SingleToggleCommand extends ProxyCommandInfo {
|
||||
if (checkPermission(sender, "toggle")) return;
|
||||
final boolean maintenance = args[0].equalsIgnoreCase("on");
|
||||
if (maintenance == plugin.isMaintenance()) {
|
||||
sender.sendMessage(getMessage(maintenance ? "alreadyEnabled" : "alreadyDisabled"));
|
||||
sender.send(getMessage(maintenance ? "alreadyEnabled" : "alreadyDisabled"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -54,26 +54,26 @@ public final class SingleToggleCommand extends ProxyCommandInfo {
|
||||
Server server = plugin.getServer(args[1]);
|
||||
if (server == null) {
|
||||
if (maintenance) {
|
||||
sender.sendMessage(getMessage("serverNotFound"));
|
||||
sender.send(getMessage("serverNotFound"));
|
||||
return;
|
||||
}
|
||||
// Let servers be removed from the maintenance list, even if they don't exist on the proxy
|
||||
server = new DummyServer(args[1]);
|
||||
if (!plugin.isMaintenance(server)) {
|
||||
sender.sendMessage(getMessage("serverNotFound"));
|
||||
sender.send(getMessage("serverNotFound"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (plugin.setMaintenanceToServer(server, maintenance)) {
|
||||
if (!sender.isPlayer() || !server.getName().equals(plugin.getServerNameOf(sender))) {
|
||||
sender.sendMessage(getMessage(maintenance ? "singleMaintenanceActivated" : "singleMaintenanceDeactivated").replace("%SERVER%", server.getName()));
|
||||
sender.send(getMessage(maintenance ? "singleMaintenanceActivated" : "singleMaintenanceDeactivated", "%SERVER%", server.getName()));
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage(getMessage(maintenance ? "singleServerAlreadyEnabled" : "singleServerAlreadyDisabled").replace("%SERVER%", server.getName()));
|
||||
sender.send(getMessage(maintenance ? "singleServerAlreadyEnabled" : "singleServerAlreadyDisabled", "%SERVER%", server.getName()));
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage(getHelpMessage());
|
||||
sender.send(getHelpMessage());
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -30,13 +30,13 @@ public final class StatusCommand extends ProxyCommandInfo {
|
||||
@Override
|
||||
public void execute(final SenderInfo sender, final String[] args) {
|
||||
if (getSettings().getMaintenanceServers().isEmpty()) {
|
||||
sender.sendMessage(getMessage("singleServerMaintenanceListEmpty"));
|
||||
sender.send(getMessage("singleServerMaintenanceListEmpty"));
|
||||
return;
|
||||
}
|
||||
|
||||
sender.sendMessage(getMessage("singleServerMaintenanceList"));
|
||||
sender.send(getMessage("singleServerMaintenanceList"));
|
||||
for (final String server : getSettings().getMaintenanceServers()) {
|
||||
sender.sendMessage("§8- §b" + server);
|
||||
sender.send(getMessage("singleServerMaintenanceListEntry", "%SERVER%", server));
|
||||
}
|
||||
}
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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 eu.kennytv.maintenance.core.proxy.hook;
|
||||
|
||||
import eu.kennytv.maintenance.core.hook.LuckPermsHook;
|
||||
import eu.kennytv.maintenance.core.proxy.MaintenanceProxyPlugin;
|
||||
import net.luckperms.api.LuckPermsProvider;
|
||||
import net.luckperms.api.context.ContextCalculator;
|
||||
import net.luckperms.api.context.ContextConsumer;
|
||||
import net.luckperms.api.context.ContextSet;
|
||||
import net.luckperms.api.context.ImmutableContextSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public final class LuckPermsProxyHook {
|
||||
|
||||
public static <T> void register(final MaintenanceProxyPlugin plugin, final Function<T, String> function) {
|
||||
LuckPermsProvider.get().getContextManager().registerCalculator(new MaintenanceProxyCalculator<>(plugin, function));
|
||||
}
|
||||
|
||||
public static final class MaintenanceProxyCalculator<T> implements ContextCalculator<T> {
|
||||
|
||||
private static final String MAINTENANCE_ON_KEY = "is-maintenance-on-";
|
||||
private static final String ON_MAINTENANCE_SERVER_KEY = "on-maintenance-server";
|
||||
private final MaintenanceProxyPlugin maintenance;
|
||||
private final Function<T, String> playerServerFunction;
|
||||
|
||||
private MaintenanceProxyCalculator(final MaintenanceProxyPlugin plugin, final Function<T, String> playerServerFunction) {
|
||||
this.maintenance = plugin;
|
||||
this.playerServerFunction = playerServerFunction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calculate(@NotNull final T target, @NotNull final ContextConsumer consumer) {
|
||||
consumer.accept(LuckPermsHook.MaintenanceCalculator.MAINTENANCE_KEY, Boolean.toString(maintenance.isMaintenance()));
|
||||
/*for (final String serverName : maintenance.getServers()) {
|
||||
final Server server = maintenance.getServer(serverName);
|
||||
if (server != null) {
|
||||
consumer.accept(MAINTENANCE_ON_KEY + server, Boolean.toString(maintenance.isMaintenance(server)));
|
||||
}
|
||||
}*/
|
||||
final String server = playerServerFunction.apply(target);
|
||||
if (server != null) {
|
||||
final String value = Boolean.toString(maintenance.getSettingsProxy().isMaintenance(server));
|
||||
consumer.accept(MAINTENANCE_ON_KEY + server, value);
|
||||
consumer.accept(ON_MAINTENANCE_SERVER_KEY, value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContextSet estimatePotentialContexts() {
|
||||
final ImmutableContextSet.Builder builder = ImmutableContextSet.builder();
|
||||
for (final String serverName : maintenance.getServers()) {
|
||||
final String key = MAINTENANCE_ON_KEY + serverName;
|
||||
builder.add(key, "true").add(key, "false");
|
||||
}
|
||||
return builder.add(ON_MAINTENANCE_SERVER_KEY, "true").add(ON_MAINTENANCE_SERVER_KEY, "false")
|
||||
.add(LuckPermsHook.MaintenanceCalculator.MAINTENANCE_KEY, "true")
|
||||
.add(LuckPermsHook.MaintenanceCalculator.MAINTENANCE_KEY, "false").build();
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -60,11 +60,11 @@ public abstract class ProxyJoinListenerBase extends JoinListenerBase {
|
||||
// Player already is on the waiting server
|
||||
final String currentServer = plugin.getServerNameOf(sender);
|
||||
if (waitingServer.getName().equals(currentServer)) {
|
||||
sender.sendMessage(settings.getMessage("forceWaitingServer"));
|
||||
sender.send(settings.getMessage("forceWaitingServer"));
|
||||
return DENIED;
|
||||
}
|
||||
|
||||
sender.sendMessage(settings.getMessage("sentToWaitingServer"));
|
||||
sender.send(settings.getMessage("sentToWaitingServer"));
|
||||
return new ServerConnectResult(waitingServer);
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ public abstract class ProxyJoinListenerBase extends JoinListenerBase {
|
||||
}
|
||||
|
||||
if (normalServerConnect) {
|
||||
sender.sendMessage(settings.getServerKickMessage(target.getName()));
|
||||
sender.send(settings.getServerKickMessage(target.getName()));
|
||||
return DENIED;
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
+14
-9
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -17,11 +17,12 @@
|
||||
*/
|
||||
package eu.kennytv.maintenance.core.proxy.runnable;
|
||||
|
||||
import eu.kennytv.maintenance.api.proxy.IMaintenanceProxy;
|
||||
import eu.kennytv.maintenance.api.proxy.MaintenanceProxy;
|
||||
import eu.kennytv.maintenance.api.proxy.Server;
|
||||
import eu.kennytv.maintenance.core.MaintenancePlugin;
|
||||
import eu.kennytv.maintenance.core.Settings;
|
||||
import eu.kennytv.maintenance.core.runnable.MaintenanceRunnableBase;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
|
||||
|
||||
public class SingleMaintenanceRunnable extends MaintenanceRunnableBase {
|
||||
protected final Server server;
|
||||
@@ -32,22 +33,26 @@ public class SingleMaintenanceRunnable extends MaintenanceRunnableBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void broadcast(final String message) {
|
||||
server.broadcast(message);
|
||||
protected void broadcast(final Component component) {
|
||||
server.broadcast(component);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finish() {
|
||||
((IMaintenanceProxy) plugin).setMaintenanceToServer(server, enable);
|
||||
((MaintenanceProxy) plugin).setMaintenanceToServer(server, enable);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getStartMessage() {
|
||||
return settings.getMessage("singleStarttimerBroadcast").replace("%TIME%", getTime()).replace("%SERVER%", server.getName());
|
||||
protected Component getStartMessage() {
|
||||
return settings.getMessage("singleStarttimerBroadcast",
|
||||
"%TIME%", getTime(),
|
||||
"%SERVER%", server.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getEndMessage() {
|
||||
return settings.getMessage("singleEndtimerBroadcast").replace("%TIME%", getTime()).replace("%SERVER%", server.getName());
|
||||
protected Component getEndMessage() {
|
||||
return settings.getMessage("singleEndtimerBroadcast",
|
||||
"%TIME%", getTime(),
|
||||
"%SERVER%", server.getName());
|
||||
}
|
||||
}
|
||||
+10
-9
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -21,26 +21,27 @@ import eu.kennytv.maintenance.api.proxy.Server;
|
||||
import eu.kennytv.maintenance.core.MaintenancePlugin;
|
||||
import eu.kennytv.maintenance.core.Settings;
|
||||
import eu.kennytv.maintenance.core.proxy.MaintenanceProxyPlugin;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
|
||||
import java.time.Duration;
|
||||
|
||||
public final class SingleMaintenanceScheduleRunnable extends SingleMaintenanceRunnable {
|
||||
private final int maintenanceDuration;
|
||||
private final int maintenanceDurationSeconds;
|
||||
|
||||
public SingleMaintenanceScheduleRunnable(final MaintenancePlugin plugin, final Settings settings, final int seconds, final int maintenanceDuration, final Server server) {
|
||||
super(plugin, settings, seconds, true, server);
|
||||
this.maintenanceDuration = maintenanceDuration;
|
||||
this.maintenanceDurationSeconds = maintenanceDuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finish() {
|
||||
super.finish();
|
||||
((MaintenanceProxyPlugin) plugin).startSingleMaintenanceRunnable(server, maintenanceDuration, TimeUnit.SECONDS, false);
|
||||
((MaintenanceProxyPlugin) plugin).startSingleMaintenanceRunnable(server, Duration.ofSeconds(maintenanceDurationSeconds), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getStartMessage() {
|
||||
return settings.getMessage("singleScheduletimerBroadcast").replace("%SERVER%", server.getName())
|
||||
.replace("%TIME%", getTime()).replace("%DURATION%", plugin.getFormattedTime(maintenanceDuration));
|
||||
protected Component getStartMessage() {
|
||||
return settings.getMessage("singleScheduletimerBroadcast",
|
||||
"%SERVER%", server.getName(),
|
||||
"%TIME%", getTime(), "%DURATION%", plugin.getFormattedTime(maintenanceDurationSeconds));
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -18,6 +18,7 @@
|
||||
package eu.kennytv.maintenance.core.proxy.server;
|
||||
|
||||
import eu.kennytv.maintenance.api.proxy.Server;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
|
||||
|
||||
public final class DummyServer implements Server {
|
||||
private final String name;
|
||||
@@ -37,7 +38,7 @@ public final class DummyServer implements Server {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void broadcast(final String s) {
|
||||
public void broadcast(final Component component) {
|
||||
}
|
||||
|
||||
@Override
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
+4
-3
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -18,6 +18,7 @@
|
||||
package eu.kennytv.maintenance.core.proxy.util;
|
||||
|
||||
import eu.kennytv.maintenance.api.proxy.Server;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -36,7 +37,7 @@ public final class ProxyOfflineSenderInfo implements ProxySenderInfo {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect(final String message) {
|
||||
public void disconnect(final Component component) {
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -55,7 +56,7 @@ public final class ProxyOfflineSenderInfo implements ProxySenderInfo {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(final String message) {
|
||||
public void send(final Component component) {
|
||||
}
|
||||
|
||||
@Override
|
||||
+3
-2
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -19,10 +19,11 @@ package eu.kennytv.maintenance.core.proxy.util;
|
||||
|
||||
import eu.kennytv.maintenance.api.proxy.Server;
|
||||
import eu.kennytv.maintenance.core.util.SenderInfo;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
|
||||
|
||||
public interface ProxySenderInfo extends SenderInfo {
|
||||
|
||||
boolean canAccess(Server server);
|
||||
|
||||
void disconnect(String message);
|
||||
void disconnect(Component component);
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -0,0 +1,31 @@
|
||||
plugins {
|
||||
id("net.kyori.blossom")
|
||||
id("org.jetbrains.gradle.plugin.idea-ext")
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
blossom {
|
||||
javaSources {
|
||||
property("version", project.version.toString())
|
||||
property("impl_version", "git-Maintenance-${project.version}:${rootProject.latestCommitHash()}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(projects.maintenanceApi)
|
||||
api(projects.adventure.adventureApi) {
|
||||
targetConfiguration = "shadow"
|
||||
}
|
||||
compileOnly(libs.luckperms)
|
||||
compileOnly(libs.serverlistplus)
|
||||
compileOnly(libs.guava)
|
||||
compileOnly(libs.gson)
|
||||
compileOnly(libs.snakeyaml)
|
||||
}
|
||||
|
||||
java {
|
||||
withJavadocJar()
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2023 ViaVersion and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package eu.kennytv.maintenance.core.util;
|
||||
|
||||
public final class MaintenanceVersion {
|
||||
|
||||
public static final String VERSION = "{{ version }}";
|
||||
private static final String IMPLEMENTATION_VERSION = "{{ impl_version }}";
|
||||
|
||||
public static String getVersion() {
|
||||
return VERSION;
|
||||
}
|
||||
|
||||
public static String getImplementationVersion() {
|
||||
return IMPLEMENTATION_VERSION;
|
||||
}
|
||||
}
|
||||
+8
-9
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -15,18 +15,17 @@
|
||||
* 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 eu.kennytv.maintenance.api;
|
||||
package eu.kennytv.maintenance.core;
|
||||
|
||||
/**
|
||||
* @author kennytv
|
||||
* @since 2.2.2
|
||||
*/
|
||||
public interface IMaintenanceBase {
|
||||
import eu.kennytv.maintenance.api.Maintenance;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface MaintenanceBase {
|
||||
|
||||
/**
|
||||
* This method is used internally when getting the api instance.
|
||||
*
|
||||
* @return {@link IMaintenance} instance
|
||||
* @return {@link Maintenance} instance
|
||||
*/
|
||||
IMaintenance getApi();
|
||||
Maintenance getApi();
|
||||
}
|
||||
+92
-82
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -17,19 +17,18 @@
|
||||
*/
|
||||
package eu.kennytv.maintenance.core;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.io.CharStreams;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonObject;
|
||||
import eu.kennytv.maintenance.api.IMaintenance;
|
||||
import eu.kennytv.maintenance.api.Maintenance;
|
||||
import eu.kennytv.maintenance.api.MaintenanceProvider;
|
||||
import eu.kennytv.maintenance.api.event.MaintenanceChangedEvent;
|
||||
import eu.kennytv.maintenance.api.event.manager.IEventManager;
|
||||
import eu.kennytv.maintenance.api.event.manager.EventManager;
|
||||
import eu.kennytv.maintenance.core.command.MaintenanceCommand;
|
||||
import eu.kennytv.maintenance.core.dump.MaintenanceDump;
|
||||
import eu.kennytv.maintenance.core.dump.PluginDump;
|
||||
import eu.kennytv.maintenance.core.event.EventManager;
|
||||
import eu.kennytv.maintenance.core.hook.ServerListPlusHook;
|
||||
import eu.kennytv.maintenance.core.runnable.MaintenanceRunnable;
|
||||
import eu.kennytv.maintenance.core.runnable.MaintenanceScheduleRunnable;
|
||||
@@ -37,14 +36,12 @@ import eu.kennytv.maintenance.core.util.SenderInfo;
|
||||
import eu.kennytv.maintenance.core.util.ServerType;
|
||||
import eu.kennytv.maintenance.core.util.Task;
|
||||
import eu.kennytv.maintenance.core.util.Version;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.format.NamedTextColor;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
@@ -53,22 +50,31 @@ import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class MaintenancePlugin implements IMaintenance {
|
||||
public abstract class MaintenancePlugin implements Maintenance {
|
||||
public static final Gson GSON = new GsonBuilder().create();
|
||||
public static final String HANGAR_URL = "https://hangar.papermc.io/kennytv/Maintenance";
|
||||
private static final Pattern INT_PATTERN = Pattern.compile("[0-9]+");
|
||||
protected final EventManager eventManager;
|
||||
protected final Version version;
|
||||
protected Settings settings;
|
||||
protected ServerListPlusHook serverListPlusHook;
|
||||
protected MaintenanceRunnable runnable;
|
||||
protected MaintenanceCommand commandManager;
|
||||
private final String prefix;
|
||||
private final Component prefix;
|
||||
private final ServerType serverType;
|
||||
private Version newestVersion;
|
||||
private boolean debug;
|
||||
@@ -76,8 +82,14 @@ public abstract class MaintenancePlugin implements IMaintenance {
|
||||
protected MaintenancePlugin(final String version, final ServerType serverType) {
|
||||
this.version = new Version(version);
|
||||
this.serverType = serverType;
|
||||
this.prefix = "§8[§eMaintenance" + serverType + "§8] ";
|
||||
this.eventManager = new EventManager();
|
||||
this.prefix = Component.text()
|
||||
.append(Component.text().content("[").color(NamedTextColor.DARK_GRAY))
|
||||
.append(Component.text().content("Maintenance").color(NamedTextColor.YELLOW))
|
||||
.append(Component.text().content("]").color(NamedTextColor.DARK_GRAY))
|
||||
.append(Component.text(" "))
|
||||
.build();
|
||||
this.eventManager = new eu.kennytv.maintenance.core.event.EventManager();
|
||||
MaintenanceProvider.setMaintenance(this);
|
||||
}
|
||||
|
||||
public void disable() {
|
||||
@@ -94,8 +106,7 @@ public abstract class MaintenancePlugin implements IMaintenance {
|
||||
try {
|
||||
executeConsoleCommand(command);
|
||||
} catch (final Exception e) {
|
||||
getLogger().severe("Error while executing extra maintenance " + (maintenance ? "enable" : "disable") + " command: " + command);
|
||||
e.printStackTrace();
|
||||
getLogger().log(Level.SEVERE, "Error while executing extra maintenance " + (maintenance ? "enable" : "disable") + " command: " + command, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -120,28 +131,27 @@ public abstract class MaintenancePlugin implements IMaintenance {
|
||||
eventManager.callEvent(new MaintenanceChangedEvent(maintenance));
|
||||
}
|
||||
|
||||
public String replacePingVariables(String s) {
|
||||
if (s.contains("%TIMER%")) {
|
||||
s = s.replace("%TIMER%", getTimerMessage());
|
||||
public String replacePingVariables(String component) {
|
||||
if (component.contains("%TIMER%")) {
|
||||
component = component.replace("%TIMER%", getTimerMessage());
|
||||
}
|
||||
if (s.contains("%ONLINE%")) {
|
||||
s = s.replace("%ONLINE%", Integer.toString(getOnlinePlayers()));
|
||||
}
|
||||
if (s.contains("%MAX%")) {
|
||||
s = s.replace("%MAX%", Integer.toString(getMaxPlayers()));
|
||||
}
|
||||
return s;
|
||||
component = component.replace("%ONLINE%", String.valueOf(getOnlinePlayers()));
|
||||
component = component.replace("%MAX%", String.valueOf(getMaxPlayers()));
|
||||
return component;
|
||||
}
|
||||
|
||||
public String getTimerMessage() {
|
||||
if (!isTaskRunning()) return settings.getMessage("motdTimerNotRunning", "-");
|
||||
if (!isTaskRunning()) {
|
||||
return settings.getLanguageString("motdTimerNotRunning");
|
||||
}
|
||||
|
||||
final int preHours = runnable.getSecondsLeft() / 60;
|
||||
final int minutes = preHours % 60;
|
||||
final int seconds = runnable.getSecondsLeft() % 60;
|
||||
return settings.getMessage("motdTimer", "%HOURS%:%MINUTES%:%SECONDS%")
|
||||
.replace("%HOURS%", String.format("%02d", preHours / 60))
|
||||
.replace("%MINUTES%", String.format("%02d", minutes))
|
||||
.replace("%SECONDS%", String.format("%02d", seconds));
|
||||
return settings.getLanguageString("motdTimer",
|
||||
"%HOURS%", String.format("%02d", preHours / 60),
|
||||
"%MINUTES%", String.format("%02d", minutes),
|
||||
"%SECONDS%", String.format("%02d", seconds));
|
||||
}
|
||||
|
||||
public String getFormattedTime(final int timeSeconds) {
|
||||
@@ -161,25 +171,25 @@ public abstract class MaintenancePlugin implements IMaintenance {
|
||||
if (builder.length() != 0) {
|
||||
builder.append(' ');
|
||||
}
|
||||
builder.append(time).append(' ').append(settings.getMessage(time == 1 ? timeUnit : timeUnit + "s"));
|
||||
builder.append(time).append(' ').append(settings.language.getString(time == 1 ? timeUnit : timeUnit + "s"));
|
||||
}
|
||||
|
||||
public void startMaintenanceRunnable(final long duration, final TimeUnit unit, final boolean enable) {
|
||||
runnable = new MaintenanceRunnable(this, settings, (int) unit.toSeconds(duration), enable);
|
||||
public void startMaintenanceRunnable(final Duration duration, final boolean enable) {
|
||||
runnable = new MaintenanceRunnable(this, settings, (int) duration.getSeconds(), enable);
|
||||
// Save the endtimer to be able to continue it after a server stop
|
||||
if (settings.isSaveEndtimerOnStop() && !runnable.shouldEnable()) {
|
||||
settings.setSavedEndtimer(System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(runnable.getSecondsLeft()));
|
||||
}
|
||||
}
|
||||
|
||||
public void scheduleMaintenanceRunnable(final long duration, final int maintenanceDuration, final TimeUnit unit) {
|
||||
runnable = new MaintenanceScheduleRunnable(this, settings, (int) unit.toSeconds(duration), (int) unit.toSeconds(maintenanceDuration));
|
||||
public void scheduleMaintenanceRunnable(final Duration enableIn, final Duration maintenanceDuration) {
|
||||
runnable = new MaintenanceScheduleRunnable(this, settings, (int) enableIn.getSeconds(), (int) maintenanceDuration.getSeconds());
|
||||
}
|
||||
|
||||
public boolean updateAvailable() {
|
||||
try {
|
||||
checkNewestVersion();
|
||||
return version.compareTo(newestVersion) == -1;
|
||||
return version.compareTo(newestVersion) < 0;
|
||||
} catch (final Exception e) {
|
||||
return false;
|
||||
}
|
||||
@@ -199,7 +209,7 @@ public abstract class MaintenancePlugin implements IMaintenance {
|
||||
setMaintenance(false);
|
||||
settings.setSavedEndtimer(0);
|
||||
} else {
|
||||
startMaintenanceRunnable(settings.getSavedEndtimer() - current, TimeUnit.MILLISECONDS, false);
|
||||
startMaintenanceRunnable(Duration.ofMillis(settings.getSavedEndtimer() - current), false);
|
||||
getLogger().info("The timer has been continued - maintenance will be disabled in: " + getTimerMessage());
|
||||
}
|
||||
}
|
||||
@@ -210,44 +220,48 @@ public abstract class MaintenancePlugin implements IMaintenance {
|
||||
try {
|
||||
checkNewestVersion();
|
||||
} catch (final Exception e) {
|
||||
getLogger().warning("An error occured during update checking!");
|
||||
return;
|
||||
}
|
||||
|
||||
final int compare = version.compareTo(newestVersion);
|
||||
if (compare == -1) {
|
||||
getLogger().info("§cNewest version available: §aVersion " + newestVersion + "§c, you're on §a" + version);
|
||||
} else if (compare == 1) {
|
||||
if (compare < 0) {
|
||||
getLogger().warning("Newest version available: Version " + newestVersion + ", you're on " + version);
|
||||
} else if (compare > 0) {
|
||||
if (version.getTag().equalsIgnoreCase("snapshot")) {
|
||||
getLogger().info("§cYou're running a development version, please report bugs on the Discord server (https://discord.gg/vGCUzHq) or the GitHub issue tracker (https://github.com/kennytv/Maintenance/issues)");
|
||||
getLogger().info("You're running a development version, please report bugs on the Discord server (https://discord.gg/vGCUzHq) or the GitHub issue tracker (https://github.com/kennytv/Maintenance/issues)");
|
||||
} else {
|
||||
getLogger().info("§cYou're running a version, that doesn't exist! §cN§ai§dc§ee§5!");
|
||||
getLogger().info("You're running a version, that doesn't exist!");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean installUpdate() {
|
||||
// Ore sad :(
|
||||
Preconditions.checkArgument(serverType != ServerType.SPONGE);
|
||||
try {
|
||||
final String fileSuffix = serverType == ServerType.VELOCITY ? "Velocity" : "";
|
||||
final URLConnection conn = new URL("https://github.com/kennytv/Maintenance/releases/download/" + newestVersion + "/Maintenance" + fileSuffix + ".jar").openConnection();
|
||||
writeFile(new BufferedInputStream(conn.getInputStream()), new BufferedOutputStream(new FileOutputStream(getPluginFolder() + "Maintenance.tmp")));
|
||||
final File file = new File(getPluginFolder() + "Maintenance.tmp");
|
||||
final long newlength = file.length();
|
||||
if (newlength < 10000) {
|
||||
file.delete();
|
||||
return false;
|
||||
}
|
||||
public boolean installUpdate() throws Exception {
|
||||
// Sponge and Velocity need their own jar
|
||||
final String platformInfix = serverType == ServerType.VELOCITY ? "Velocity-" : serverType == ServerType.SPONGE ? "Sponge-" : "";
|
||||
final String fileName = "Maintenance-" + platformInfix + newestVersion + ".jar";
|
||||
final Path tempFilePath = Paths.get(getPluginFolder() + "Maintenance.tmp");
|
||||
final URLConnection connection = new URL("https://github.com/kennytv/Maintenance/releases/download/" + newestVersion + "/" + fileName).openConnection();
|
||||
try (final BufferedInputStream is = new BufferedInputStream(connection.getInputStream());
|
||||
final BufferedOutputStream os = new BufferedOutputStream(Files.newOutputStream(tempFilePath))) {
|
||||
writeFile(is, os);
|
||||
}
|
||||
|
||||
writeFile(new FileInputStream(file), new BufferedOutputStream(new FileOutputStream(getPluginFile())));
|
||||
final File file = tempFilePath.toFile();
|
||||
final long newlength = file.length();
|
||||
if (newlength < 10_000) {
|
||||
// Sanity check the file length
|
||||
file.delete();
|
||||
return true;
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
try (final InputStream is = Files.newInputStream(file.toPath());
|
||||
final BufferedOutputStream os = new BufferedOutputStream(Files.newOutputStream(getPluginFile().toPath()))) {
|
||||
writeFile(is, os);
|
||||
}
|
||||
|
||||
file.delete();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void writeFile(final InputStream is, final OutputStream os) throws IOException {
|
||||
@@ -256,13 +270,12 @@ public abstract class MaintenancePlugin implements IMaintenance {
|
||||
while ((chunkSize = is.read(chunk)) != -1) {
|
||||
os.write(chunk, 0, chunkSize);
|
||||
}
|
||||
is.close();
|
||||
os.close();
|
||||
}
|
||||
|
||||
private void checkNewestVersion() throws Exception {
|
||||
final HttpURLConnection c = (HttpURLConnection) new URL("https://api.spigotmc.org/legacy/update.php?resource=40699").openConnection();
|
||||
try (final BufferedReader reader = new BufferedReader(new InputStreamReader(c.getInputStream()))) {
|
||||
final URLConnection connection = new URL("https://hangar.papermc.io/api/v1/projects/Maintenance/latestrelease").openConnection();
|
||||
connection.setRequestProperty("User-Agent", "Maintenance/" + getVersion());
|
||||
try (final BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
|
||||
final String newVersionString = reader.readLine();
|
||||
final Version newVersion = new Version(newVersionString);
|
||||
if (!newVersion.equals(version)) {
|
||||
@@ -274,7 +287,7 @@ public abstract class MaintenancePlugin implements IMaintenance {
|
||||
public String pasteDump() {
|
||||
final MaintenanceDump dump = new MaintenanceDump(this, settings);
|
||||
try {
|
||||
final HttpURLConnection connection = (HttpURLConnection) new URL("https://hastebin.com/documents").openConnection();
|
||||
final HttpURLConnection connection = (HttpURLConnection) new URL("https://api.pastes.dev/post").openConnection();
|
||||
connection.setDoOutput(true);
|
||||
connection.setRequestMethod("POST");
|
||||
connection.setRequestProperty("User-Agent", "Maintenance/" + getVersion());
|
||||
@@ -285,7 +298,7 @@ public abstract class MaintenancePlugin implements IMaintenance {
|
||||
}
|
||||
|
||||
if (connection.getResponseCode() == 503) {
|
||||
getLogger().warning("Could not paste dump, hastebin.com down?");
|
||||
getLogger().warning("Could not paste dump, pastes.dev down?");
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -300,8 +313,7 @@ public abstract class MaintenancePlugin implements IMaintenance {
|
||||
return jsonOutput.get("key").getAsString();
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
getLogger().log(Level.WARNING, "Could not paste dump :(");
|
||||
e.printStackTrace();
|
||||
getLogger().log(Level.WARNING, "Could not paste dump :(", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -336,7 +348,7 @@ public abstract class MaintenancePlugin implements IMaintenance {
|
||||
try {
|
||||
uuid = UUID.fromString(s);
|
||||
} catch (final Exception e) {
|
||||
sender.sendMessage(settings.getMessage("invalidUuid"));
|
||||
sender.send(settings.getMessage("invalidUuid"));
|
||||
return null;
|
||||
}
|
||||
return uuid;
|
||||
@@ -349,7 +361,7 @@ public abstract class MaintenancePlugin implements IMaintenance {
|
||||
}
|
||||
|
||||
public boolean isNumeric(final String string) {
|
||||
return string.matches("[0-9]+");
|
||||
return INT_PATTERN.matcher(string).matches();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -368,7 +380,7 @@ public abstract class MaintenancePlugin implements IMaintenance {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IEventManager getEventManager() {
|
||||
public EventManager getEventManager() {
|
||||
return eventManager;
|
||||
}
|
||||
|
||||
@@ -400,7 +412,7 @@ public abstract class MaintenancePlugin implements IMaintenance {
|
||||
return newestVersion;
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
public Component prefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
@@ -428,28 +440,26 @@ public abstract class MaintenancePlugin implements IMaintenance {
|
||||
|
||||
protected abstract void executeConsoleCommand(String command);
|
||||
|
||||
public abstract void broadcast(String message);
|
||||
|
||||
public abstract void sendUpdateNotification(SenderInfo sender);
|
||||
public abstract void broadcast(Component component);
|
||||
|
||||
public abstract Task startMaintenanceRunnable(Runnable runnable);
|
||||
|
||||
/**
|
||||
* Returns offline sender info of a player.
|
||||
* Gets the offline sender info of a player.
|
||||
* This method may do a web lookup.
|
||||
*
|
||||
* @param name name of the player
|
||||
* @return sender info if found, else null
|
||||
*/
|
||||
@Nullable
|
||||
public abstract SenderInfo getOfflinePlayer(String name);
|
||||
public abstract CompletableFuture<@Nullable SenderInfo> getOfflinePlayer(String name);
|
||||
|
||||
@Nullable
|
||||
public abstract SenderInfo getOfflinePlayer(UUID uuid);
|
||||
public abstract CompletableFuture<@Nullable SenderInfo> getOfflinePlayer(UUID uuid);
|
||||
|
||||
public abstract File getDataFolder();
|
||||
|
||||
public abstract InputStream getResource(String name);
|
||||
@Nullable
|
||||
public InputStream getResource(final String name) {
|
||||
return this.getClass().getClassLoader().getResourceAsStream(name);
|
||||
}
|
||||
|
||||
public abstract Logger getLogger();
|
||||
|
||||
+224
-123
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -17,27 +17,34 @@
|
||||
*/
|
||||
package eu.kennytv.maintenance.core;
|
||||
|
||||
import eu.kennytv.maintenance.api.ISettings;
|
||||
import eu.kennytv.maintenance.api.event.MaintenanceReloadedEvent;
|
||||
import eu.kennytv.maintenance.core.config.Config;
|
||||
import eu.kennytv.maintenance.core.config.ConfigSection;
|
||||
import eu.kennytv.maintenance.core.util.ServerType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.TextComponent;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class Settings implements ISettings {
|
||||
private static final int CURRENT_CONFIG_VERSION = 5;
|
||||
public class Settings implements eu.kennytv.maintenance.api.Settings {
|
||||
public static final String NEW_LINE_REPLACEMENT = "<br>";
|
||||
private static final int CONFIG_VERSION = 9;
|
||||
private static final int LANGUAGE_VERSION = 2;
|
||||
private static final Random RANDOM = new Random();
|
||||
protected final MaintenancePlugin plugin;
|
||||
private final Map<UUID, String> whitelistedPlayers = new HashMap<>();
|
||||
@@ -48,11 +55,15 @@ public class Settings implements ISettings {
|
||||
private List<String> timerSpecificPingMessages;
|
||||
private List<String> commandsOnMaintenanceEnable;
|
||||
private List<String> commandsOnMaintenanceDisable;
|
||||
private String playerCountMessage;
|
||||
private String playerCountHoverMessage;
|
||||
private String legacyParsedPlayerCountMessage;
|
||||
private String legacyParsedTimerPlayerCountMessage;
|
||||
private List<String> legacyParsedPlayerCountHoverLines;
|
||||
private List<String> legacyParsedTimerPlayerCountHoverLines;
|
||||
private String prefixString;
|
||||
private String languageName;
|
||||
private boolean enablePingMessages;
|
||||
private boolean customPlayerCountMessage;
|
||||
private boolean customPlayerCountHoverMessage;
|
||||
private boolean customMaintenanceIcon;
|
||||
private boolean joinNotifications;
|
||||
private boolean updateChecks;
|
||||
@@ -87,8 +98,8 @@ public class Settings implements ISettings {
|
||||
config.resetAwesomeHeader();
|
||||
whitelist = new Config(new File(plugin.getDataFolder(), "WhitelistedPlayers.yml"));
|
||||
whitelist.load();
|
||||
} catch (final IOException e) {
|
||||
throw new RuntimeException("Unable to load Maintenance files!", e);
|
||||
} catch (final Exception e) {
|
||||
throw new RuntimeException("Unable to load Maintenance files - probably a malformed config file", e);
|
||||
}
|
||||
|
||||
loadSettings();
|
||||
@@ -98,32 +109,25 @@ public class Settings implements ISettings {
|
||||
language = new Config(new File(plugin.getDataFolder(), "language-" + languageName + ".yml"));
|
||||
language.load();
|
||||
} catch (final IOException e) {
|
||||
throw new RuntimeException("Unable to load Maintenance language file!", e);
|
||||
throw new RuntimeException("Unable to load Maintenance language file - probably a malformed file", e);
|
||||
}
|
||||
|
||||
updateLanguageFile();
|
||||
try {
|
||||
updateLanguageFile();
|
||||
} catch (final IOException e) {
|
||||
plugin.getLogger().log(Level.SEVERE, "Couldn't update language file", e);
|
||||
}
|
||||
|
||||
// Directly cache colored messages - this should not be saved!
|
||||
transformColoredMessages(language.getValues());
|
||||
prefixString = language.getString("prefix");
|
||||
|
||||
plugin.getEventManager().callEvent(new MaintenanceReloadedEvent());
|
||||
}
|
||||
|
||||
private void transformColoredMessages(final Map<String, Object> map) {
|
||||
for (final Map.Entry<String, Object> entry : map.entrySet()) {
|
||||
if (entry.getValue() instanceof Map) {
|
||||
transformColoredMessages((Map<String, Object>) entry.getValue());
|
||||
} else if (entry.getValue() instanceof String) {
|
||||
entry.setValue(getColoredString(replaceNewlineVar((String) entry.getValue())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void saveConfig() {
|
||||
try {
|
||||
config.save();
|
||||
} catch (final IOException e) {
|
||||
e.printStackTrace();
|
||||
plugin.getLogger().log(Level.SEVERE, "Couldn't save the config file!", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,7 +151,7 @@ public class Settings implements ISettings {
|
||||
try {
|
||||
whitelist.save();
|
||||
} catch (final IOException e) {
|
||||
e.printStackTrace();
|
||||
plugin.getLogger().log(Level.SEVERE, "Couldn't save the whitelisted players file!", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,23 +176,51 @@ public class Settings implements ISettings {
|
||||
private void loadSettings() {
|
||||
updateConfig();
|
||||
|
||||
enablePingMessages = config.getBoolean("enable-pingmessages", true);
|
||||
pingMessages = config.getStringList("pingmessages");
|
||||
if (config.getBoolean("enable-timerspecific-messages")) {
|
||||
timerSpecificPingMessages = config.getStringList("timerspecific-pingmessages");
|
||||
final ConfigSection pingMessageSection = config.getSection("ping-message");
|
||||
enablePingMessages = pingMessageSection.getBoolean("enabled", true);
|
||||
// Can't store this pre-parsed as components because gradients will break replacements
|
||||
pingMessages = loadPingMessages(pingMessageSection.getStringList("messages"));
|
||||
if (pingMessageSection.getBoolean("enable-timer-specific-messages")) {
|
||||
timerSpecificPingMessages = loadPingMessages(pingMessageSection.getStringList("timer-messages"));
|
||||
} else {
|
||||
timerSpecificPingMessages = null;
|
||||
}
|
||||
|
||||
maintenance = config.getBoolean("maintenance-enabled");
|
||||
commandsOnMaintenanceEnable = config.getStringList("commands-on-maintenance-enable");
|
||||
commandsOnMaintenanceDisable = config.getStringList("commands-on-maintenance-disable");
|
||||
customPlayerCountMessage = config.getBoolean("enable-playercountmessage");
|
||||
customMaintenanceIcon = config.getBoolean("custom-maintenance-icon");
|
||||
joinNotifications = config.getBoolean("send-join-notification");
|
||||
broadcastIntervals = new HashSet<>(config.getIntList("timer-broadcast-for-seconds"));
|
||||
|
||||
// Player count and player list hover messages are only accepted and rendered as legacy chat
|
||||
if (plugin.getServerType() != ServerType.SPONGE) {
|
||||
playerCountMessage = getColoredString(getConfigString("playercountmessage"));
|
||||
final ConfigSection playerCountMessageSection = config.getSection("player-count-message");
|
||||
customPlayerCountMessage = playerCountMessageSection.getBoolean("enabled");
|
||||
legacyParsedPlayerCountMessage = toLegacy(parse(getConfigMessage(playerCountMessageSection, "message")));
|
||||
if (playerCountMessageSection.getBoolean("enable-timer-specific-message")) {
|
||||
legacyParsedTimerPlayerCountMessage = toLegacy(parse(getConfigMessage(playerCountMessageSection, "timer-message")));
|
||||
} else {
|
||||
legacyParsedTimerPlayerCountMessage = null;
|
||||
}
|
||||
}
|
||||
playerCountHoverMessage = replaceNewlineVar(getColoredString(getConfigString("playercounthovermessage")));
|
||||
languageName = getConfigString("language").toLowerCase();
|
||||
|
||||
final ConfigSection listHoverMessageSection = config.getSection("player-list-hover-message");
|
||||
customPlayerCountHoverMessage = listHoverMessageSection.getBoolean("enabled");
|
||||
legacyParsedPlayerCountHoverLines = new ArrayList<>();
|
||||
for (final String line : listHoverMessageSection.getString("message").split("<br>")) {
|
||||
legacyParsedPlayerCountHoverLines.add(toLegacy(parse(line)));
|
||||
}
|
||||
if (listHoverMessageSection.getBoolean("enable-timer-specific-message")) {
|
||||
legacyParsedTimerPlayerCountHoverLines = new ArrayList<>();
|
||||
for (final String line : listHoverMessageSection.getString("timer-message").split("<br>")) {
|
||||
legacyParsedTimerPlayerCountHoverLines.add(toLegacy(parse(line)));
|
||||
}
|
||||
} else {
|
||||
legacyParsedTimerPlayerCountHoverLines = null;
|
||||
}
|
||||
|
||||
languageName = config.getString("language").toLowerCase();
|
||||
kickOnlinePlayers = config.getBoolean("kick-online-players", true);
|
||||
updateChecks = config.getBoolean("update-checks", true);
|
||||
debug = config.getBoolean("debug");
|
||||
@@ -204,9 +236,9 @@ public class Settings implements ISettings {
|
||||
whitelistedPlayers.clear();
|
||||
for (final Map.Entry<String, Object> entry : whitelist.getValues().entrySet()) {
|
||||
try {
|
||||
whitelistedPlayers.put(UUID.fromString(entry.getKey()), (String) entry.getValue());
|
||||
} catch (final Exception e) {
|
||||
plugin.getLogger().warning("invalid WhitelistedPlayers entry: " + entry.getKey());
|
||||
whitelistedPlayers.put(UUID.fromString(entry.getKey()), String.valueOf(entry.getValue()));
|
||||
} catch (final IllegalArgumentException e) {
|
||||
plugin.getLogger().warning("Invalid WhitelistedPlayers entry: " + entry.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,30 +247,50 @@ public class Settings implements ISettings {
|
||||
|
||||
private void updatePluginDirectory() {
|
||||
// All plugin identifiers were changed to 'Maintenance' ('maintenance' for Sponge and Velocity) in 3.0.5
|
||||
// Don't worry, this is only checked if no plugin folder is found
|
||||
String oldDirName = "Maintenance" + plugin.getServerType();
|
||||
if (plugin.getServerType() == ServerType.SPONGE || plugin.getServerType() == ServerType.VELOCITY) {
|
||||
oldDirName = oldDirName.toLowerCase();
|
||||
oldDirName = oldDirName.toLowerCase(Locale.ROOT);
|
||||
} else if (plugin.getServerType() == ServerType.SPIGOT) {
|
||||
oldDirName = "MaintenanceSpigot";
|
||||
}
|
||||
|
||||
final File oldDir = new File(plugin.getDataFolder().getParentFile(), oldDirName);
|
||||
if (!oldDir.exists()) return;
|
||||
if (!oldDir.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Files.move(oldDir.toPath(), plugin.getDataFolder().toPath());
|
||||
plugin.getLogger().info("Moved old " + oldDirName + " to new " + plugin.getDataFolder().getName() + " directory!");
|
||||
} catch (final IOException e) {
|
||||
plugin.getLogger().severe("Error while copying " + oldDirName + " to new " + plugin.getDataFolder().getName() + " directory!");
|
||||
e.printStackTrace();
|
||||
plugin.getLogger().log(Level.SEVERE, "Error while copying " + oldDirName + " to new " + plugin.getDataFolder().getName() + " directory!", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateConfig() {
|
||||
boolean changed = false;
|
||||
final int version = config.getInt("config-version");
|
||||
if (version != CONFIG_VERSION) {
|
||||
plugin.getLogger().info("Updating config to the latest version...");
|
||||
if (version < 6) {
|
||||
// Legacy text to MiniMessage
|
||||
config.getStringList("pingmessages").replaceAll(this::legacyToMinimessage);
|
||||
config.getStringList("timerspecific-pingmessages").replaceAll(this::legacyToMinimessage);
|
||||
config.set("playercounthovermessage", legacyToMinimessage(config.getString("playercounthovermessage")));
|
||||
config.set("playercountmessage", legacyToMinimessage(config.getString("playercountmessage")));
|
||||
}
|
||||
if (version < 9) {
|
||||
config.move("enable-pingmessages", "ping-message.enabled");
|
||||
config.move("pingmessages", "ping-message.messages");
|
||||
config.move("enable-timerspecific-messages", "ping-message.enable-timer-specific-messages");
|
||||
config.move("timerspecific-pingmessages", "ping-message.timer-messages");
|
||||
|
||||
config.move("enable-playercountmessage", "player-count-message.enabled");
|
||||
config.move("playercountmessage", "player-count-message.message");
|
||||
|
||||
config.move("enable-playercounthovermessage", "player-list-hover-message.enabled");
|
||||
config.move("playercounthovermessage", "player-list-hover-message.message");
|
||||
}
|
||||
|
||||
// Update config to latest version (config version included since 3.0.1)
|
||||
if (config.getInt("config-version") != CURRENT_CONFIG_VERSION) {
|
||||
plugin.getLogger().info("Updating config to latest version...");
|
||||
createFile("config-new.yml", "config.yml");
|
||||
final File file = new File(plugin.getDataFolder(), "config-new.yml");
|
||||
final Config tempConfig = new Config(file, unsupportedFields);
|
||||
@@ -248,115 +300,140 @@ public class Settings implements ISettings {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
config.addMissingFields(tempConfig.getValues(), tempConfig.getComments());
|
||||
config.set("config-version", CURRENT_CONFIG_VERSION);
|
||||
config.addMissingFields(tempConfig);
|
||||
config.replaceComments(tempConfig);
|
||||
config.set("config-version", CONFIG_VERSION);
|
||||
|
||||
file.delete();
|
||||
tempConfig.clear();
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
saveConfig();
|
||||
plugin.getLogger().info("Done! Updated config!");
|
||||
}
|
||||
}
|
||||
|
||||
private void updateLanguageFile() {
|
||||
final String filePrefix = "language-" + languageName;
|
||||
try {
|
||||
createFile(filePrefix + "-new.yml", filePrefix + ".yml");
|
||||
} catch (final NullPointerException e) {
|
||||
plugin.getLogger().info("Not checking for updated language strings, since there is no " + filePrefix + ".yml in the resource files (if your file is self translated and up to date, you can ignore this).");
|
||||
return;
|
||||
} catch (final Exception e) {
|
||||
plugin.getLogger().warning("Couldn't update language file, as the " + filePrefix + ".yml could not be loaded from the resource files!");
|
||||
e.printStackTrace();
|
||||
private void updateLanguageFile() throws IOException {
|
||||
final int version = language.getInt("language-version");
|
||||
if (version == LANGUAGE_VERSION) {
|
||||
return;
|
||||
}
|
||||
|
||||
plugin.getLogger().info("Updating language file to the latest version...");
|
||||
if (version < 1) {
|
||||
for (final Map.Entry<String, Object> entry : language.getValues().entrySet()) {
|
||||
if (!(entry.getValue() instanceof String)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String value = (String) entry.getValue();
|
||||
value = value.replace("&8[&eMaintenance&8] ", "<prefix>");
|
||||
value = legacyToMinimessage(value);
|
||||
value = value.replace("%NEWLINE%", NEW_LINE_REPLACEMENT);
|
||||
language.set(entry.getKey(), value);
|
||||
}
|
||||
}
|
||||
|
||||
final String filePrefix = "language-" + languageName;
|
||||
createFile(filePrefix + "-new.yml", filePrefix + ".yml");
|
||||
|
||||
final File file = new File(plugin.getDataFolder(), filePrefix + "-new.yml");
|
||||
final Config tempConfig = new Config(file);
|
||||
try {
|
||||
tempConfig.load();
|
||||
} catch (final IOException e) {
|
||||
e.printStackTrace();
|
||||
return;
|
||||
} finally {
|
||||
file.delete();
|
||||
}
|
||||
|
||||
final boolean updated = language.addMissingFields(tempConfig.getValues(), tempConfig.getComments());
|
||||
language.addMissingFields(tempConfig);
|
||||
language.replaceComments(tempConfig);
|
||||
tempConfig.clear();
|
||||
file.delete();
|
||||
if (updated) {
|
||||
try {
|
||||
language.save();
|
||||
plugin.getLogger().info("Updated language file!");
|
||||
} catch (final IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
language.set("language-version", LANGUAGE_VERSION);
|
||||
|
||||
language.save();
|
||||
plugin.getLogger().info("Updated language file!");
|
||||
}
|
||||
|
||||
private static final String ALL_CODES = "0123456789AaBbCcDdEeFfKkLlMmNnOoRr";
|
||||
|
||||
public String getColoredString(final String s) {
|
||||
// Method taken from Bungee
|
||||
final char[] b = s.toCharArray();
|
||||
for (int i = 0; i < b.length - 1; i++) {
|
||||
if (b[i] == '&' && ALL_CODES.indexOf(b[i + 1]) > -1) {
|
||||
b[i] = '§';
|
||||
b[i + 1] = Character.toLowerCase(b[i + 1]);
|
||||
}
|
||||
}
|
||||
return new String(b);
|
||||
private String legacyToMinimessage(final String s) {
|
||||
final TextComponent component = LegacyComponentSerializer.legacyAmpersand().deserialize(s);
|
||||
final String serialized = MiniMessage.miniMessage().serialize(component);
|
||||
//TODO hack to remove explicit closing until fixed in MM
|
||||
return serialized.replaceAll("</[a-z_]+>", "");
|
||||
}
|
||||
|
||||
public String getConfigString(final String path) {
|
||||
final String s = config.getString(path);
|
||||
private String getConfigMessage(final ConfigSection section, final String path) {
|
||||
final String s = section.getString(path);
|
||||
if (s == null) {
|
||||
plugin.getLogger().warning("The config is missing the following string: " + path);
|
||||
return "null";
|
||||
plugin.getLogger().warning("The config file is missing the following string: " + path);
|
||||
return path;
|
||||
}
|
||||
return s;
|
||||
return replaceNewlineVar(s);
|
||||
}
|
||||
|
||||
public String getMessage(final String path) {
|
||||
return getMessage(path, "null");
|
||||
public String getConfigMessage(final String path) {
|
||||
return getConfigMessage(config, path);
|
||||
}
|
||||
|
||||
public String getMessage(final String path, final String def) {
|
||||
final String s = language.getString(path);
|
||||
public String getLanguageString(final String path, final String... replacements) {
|
||||
String s = language.getString(path);
|
||||
if (s == null) {
|
||||
plugin.getLogger().warning("The language file is missing the following string: " + path);
|
||||
return def;
|
||||
return path;
|
||||
}
|
||||
return s;
|
||||
if (replacements.length != 0) {
|
||||
if (replacements.length % 2 != 0) {
|
||||
throw new IllegalArgumentException("Invalid replacement count: " + replacements.length);
|
||||
}
|
||||
|
||||
for (int i = 0; i < replacements.length; i += 2) {
|
||||
final String key = replacements[i];
|
||||
s = s.replace(key, replacements[i + 1]);
|
||||
}
|
||||
}
|
||||
return replaceNewlineVar(s).replace("<prefix>", prefixString);
|
||||
}
|
||||
|
||||
public String getRandomPingMessage() {
|
||||
public @Nullable String getLanguageStringOrNull(final String path, final String... replacements) {
|
||||
return language.contains(path) ? getLanguageString(path, replacements) : null;
|
||||
}
|
||||
|
||||
public Component getMessage(final String path, final String... replacements) {
|
||||
return parse(getLanguageString(path, replacements));
|
||||
}
|
||||
|
||||
// TODO Cache platform components if there are no replacements
|
||||
public Component getRandomPingMessage() {
|
||||
if (plugin.isTaskRunning() && !plugin.getRunnable().shouldEnable()
|
||||
&& hasTimerSpecificPingMessages() && !timerSpecificPingMessages.isEmpty()) {
|
||||
return getPingMessage(timerSpecificPingMessages);
|
||||
}
|
||||
return pingMessages.isEmpty() ? "" : getPingMessage(pingMessages);
|
||||
return pingMessages.isEmpty() ? Component.empty() : getPingMessage(pingMessages);
|
||||
}
|
||||
|
||||
private String getPingMessage(final List<String> list) {
|
||||
final String s = list.size() == 1 ? list.get(0) : list.get(RANDOM.nextInt(list.size()));
|
||||
return getColoredString(replaceNewlineVar(plugin.replacePingVariables(s)));
|
||||
private Component getPingMessage(final List<String> list) {
|
||||
final String component = list.size() == 1 ? list.get(0) : list.get(RANDOM.nextInt(list.size()));
|
||||
return parse(plugin.replacePingVariables(component));
|
||||
}
|
||||
|
||||
private List<String> loadPingMessages(final List<String> list) {
|
||||
final List<String> components = new ArrayList<>(list.size());
|
||||
for (final String s : list) {
|
||||
components.add(replaceNewlineVar(s));
|
||||
}
|
||||
return components;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeWhitelistedPlayer(final UUID uuid) {
|
||||
if (!whitelistedPlayers.containsKey(uuid)) return false;
|
||||
whitelistedPlayers.remove(uuid);
|
||||
if (whitelistedPlayers.remove(uuid) == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
whitelist.remove(uuid.toString());
|
||||
saveWhitelistedPlayers();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public boolean removeWhitelistedPlayer(final String name) {
|
||||
UUID uuid = null;
|
||||
@@ -367,7 +444,9 @@ public class Settings implements ISettings {
|
||||
}
|
||||
}
|
||||
|
||||
if (uuid == null) return false;
|
||||
if (uuid == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
whitelistedPlayers.remove(uuid);
|
||||
whitelist.remove(uuid.toString());
|
||||
@@ -377,11 +456,10 @@ public class Settings implements ISettings {
|
||||
|
||||
@Override
|
||||
public boolean addWhitelistedPlayer(final UUID uuid, final String name) {
|
||||
final boolean contains = !whitelistedPlayers.containsKey(uuid);
|
||||
whitelistedPlayers.put(uuid, name);
|
||||
final boolean added = whitelistedPlayers.put(uuid, name) == null;
|
||||
whitelist.set(uuid.toString(), name);
|
||||
saveWhitelistedPlayers();
|
||||
return contains;
|
||||
return added;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -444,7 +522,10 @@ public class Settings implements ISettings {
|
||||
}
|
||||
|
||||
public void setSavedEndtimer(final long millis) {
|
||||
if (savedEndtimer == millis) return;
|
||||
if (savedEndtimer == millis) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.savedEndtimer = millis;
|
||||
config.getSection("continue-endtimer-after-restart").set("end", millis);
|
||||
saveConfig();
|
||||
@@ -454,7 +535,6 @@ public class Settings implements ISettings {
|
||||
return config;
|
||||
}
|
||||
|
||||
// The ping messages still contain the %NEWLINE% (if they have 2 lines)
|
||||
public List<String> getPingMessages() {
|
||||
return pingMessages;
|
||||
}
|
||||
@@ -467,8 +547,7 @@ public class Settings implements ISettings {
|
||||
return commandsOnMaintenanceDisable;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public List<String> getTimerSpecificPingMessages() {
|
||||
public @Nullable List<String> getTimerSpecificPingMessages() {
|
||||
return timerSpecificPingMessages;
|
||||
}
|
||||
|
||||
@@ -476,16 +555,26 @@ public class Settings implements ISettings {
|
||||
return broadcastIntervals;
|
||||
}
|
||||
|
||||
public String getPlayerCountMessage() {
|
||||
return plugin.replacePingVariables(playerCountMessage);
|
||||
public String getLegacyParsedPlayerCountMessage() {
|
||||
final String message = timerDependent(legacyParsedPlayerCountMessage, legacyParsedTimerPlayerCountMessage);
|
||||
return plugin.replacePingVariables(message);
|
||||
}
|
||||
|
||||
public String getPlayerCountHoverMessage() {
|
||||
return plugin.replacePingVariables(playerCountHoverMessage);
|
||||
public String[] getLegacyParsedPlayerCountHoverLines() {
|
||||
final List<String> lines = timerDependent(legacyParsedPlayerCountHoverLines, legacyParsedTimerPlayerCountHoverLines);
|
||||
final String[] parsedLines = new String[lines.size()];
|
||||
for (int i = 0; i < lines.size(); i++) {
|
||||
parsedLines[i] = plugin.replacePingVariables(lines.get(i));
|
||||
}
|
||||
return parsedLines;
|
||||
}
|
||||
|
||||
public String getKickMessage() {
|
||||
return plugin.replacePingVariables(getMessage("kickmessage"));
|
||||
private <T> T timerDependent(final T normal, final @Nullable T timerSpecific) {
|
||||
return timerSpecific != null && plugin.isTaskRunning() && !plugin.getRunnable().shouldEnable() ? timerSpecific : normal;
|
||||
}
|
||||
|
||||
public Component getKickMessage() {
|
||||
return parse(plugin.replacePingVariables(getLanguageString("kickmessage")));
|
||||
}
|
||||
|
||||
public String getLanguage() {
|
||||
@@ -496,6 +585,18 @@ public class Settings implements ISettings {
|
||||
return customPlayerCountMessage;
|
||||
}
|
||||
|
||||
public boolean hasCustomPlayerCountHoverMessage() {
|
||||
return customPlayerCountHoverMessage;
|
||||
}
|
||||
|
||||
protected Component parse(final String s) {
|
||||
return MiniMessage.miniMessage().deserialize(s);
|
||||
}
|
||||
|
||||
protected String toLegacy(final Component component) {
|
||||
return LegacyComponentSerializer.legacySection().serialize(component);
|
||||
}
|
||||
|
||||
/*
|
||||
* Note on why this even exists: Yaml will force save all strings containing line breaks '\n' in this rather chunky format:
|
||||
* key: |-
|
||||
@@ -503,11 +604,11 @@ public class Settings implements ISettings {
|
||||
* Second line text.
|
||||
* ...
|
||||
*
|
||||
* This also happens to string lists, making those practically unreadable (in partciular the motd list), as well as confusing for most users in general.
|
||||
* Because of this, I replace %NEWLINE% manually, to spare users from these ugly breaks.
|
||||
* This also happens to string lists, making those practically unreadable (in particular the motd list), as well as confusing for most users in general.
|
||||
* Because of this, I replace <br> manually, to spare users from these ugly breaks (before I inevitably switch to a different configuration library).
|
||||
*/
|
||||
protected String replaceNewlineVar(final String s) {
|
||||
return s.replace("%NEWLINE%", "\n");
|
||||
return s.replace(NEW_LINE_REPLACEMENT, "\n");
|
||||
}
|
||||
|
||||
protected void loadExtraSettings() {
|
||||
+7
-6
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -20,6 +20,7 @@ package eu.kennytv.maintenance.core.command;
|
||||
import eu.kennytv.maintenance.core.MaintenancePlugin;
|
||||
import eu.kennytv.maintenance.core.Settings;
|
||||
import eu.kennytv.maintenance.core.util.SenderInfo;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -51,7 +52,7 @@ public abstract class CommandInfo {
|
||||
return visible;
|
||||
}
|
||||
|
||||
public String getHelpMessage() {
|
||||
public Component getHelpMessage() {
|
||||
return getMessage(helpMessageKey);
|
||||
}
|
||||
|
||||
@@ -63,7 +64,7 @@ public abstract class CommandInfo {
|
||||
|
||||
protected boolean checkPermission(final SenderInfo sender, final String permission) {
|
||||
if (!sender.hasMaintenancePermission(permission)) {
|
||||
sender.sendMessage(getMessage("noPermission"));
|
||||
sender.send(getMessage("noPermission"));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -71,14 +72,14 @@ public abstract class CommandInfo {
|
||||
|
||||
protected boolean checkArgs(final SenderInfo sender, final String[] args, final int length) {
|
||||
if (args.length != length) {
|
||||
sender.sendMessage(getHelpMessage());
|
||||
sender.send(getHelpMessage());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected String getMessage(final String s) {
|
||||
return plugin.getSettings().getMessage(s);
|
||||
protected Component getMessage(final String path, final String... replacements) {
|
||||
return plugin.getSettings().getMessage(path, replacements);
|
||||
}
|
||||
|
||||
protected Settings getSettings() {
|
||||
+37
-41
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -36,15 +36,19 @@ import eu.kennytv.maintenance.core.command.subcommand.WhitelistAddCommand;
|
||||
import eu.kennytv.maintenance.core.command.subcommand.WhitelistCommand;
|
||||
import eu.kennytv.maintenance.core.command.subcommand.WhitelistRemoveCommand;
|
||||
import eu.kennytv.maintenance.core.util.SenderInfo;
|
||||
import eu.kennytv.maintenance.core.util.ServerType;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class MaintenanceCommand {
|
||||
private static final long MAX_TASK_DURATION_SECONDS = TimeUnit.DAYS.toSeconds(28);
|
||||
protected final MaintenancePlugin plugin;
|
||||
protected final Settings settings;
|
||||
private final Map<String, CommandInfo> commandExecutors = new LinkedHashMap<>();
|
||||
@@ -85,7 +89,7 @@ public abstract class MaintenanceCommand {
|
||||
|
||||
public void execute(final SenderInfo sender, final String[] args) {
|
||||
if (!sender.hasMaintenancePermission("command")) {
|
||||
sender.sendMessage(settings.getMessage("noPermission"));
|
||||
sender.send(settings.getMessage("noPermission"));
|
||||
return;
|
||||
}
|
||||
if (args.length == 0) {
|
||||
@@ -99,7 +103,7 @@ public abstract class MaintenanceCommand {
|
||||
return;
|
||||
}
|
||||
if (!command.hasPermission(sender)) {
|
||||
sender.sendMessage(settings.getMessage("noPermission"));
|
||||
sender.send(settings.getMessage("noPermission"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -125,29 +129,41 @@ public abstract class MaintenanceCommand {
|
||||
return info != null && info.hasPermission(sender) ? info.getTabCompletion(sender, args) : Collections.emptyList();
|
||||
}
|
||||
|
||||
public boolean checkTimerArgs(final SenderInfo sender, final String time, final boolean taskCheck) {
|
||||
if (!plugin.isNumeric(time)) return true;
|
||||
if (taskCheck) {
|
||||
if (plugin.isTaskRunning()) {
|
||||
sender.sendMessage(settings.getMessage("timerAlreadyRunning"));
|
||||
return true;
|
||||
public @Nullable Duration parseDurationAndCheckTask(final SenderInfo sender, final String time, final boolean taskCheck) {
|
||||
final Duration duration;
|
||||
if (plugin.isNumeric(time)) {
|
||||
// Assume minutes by default as per old command behavior
|
||||
duration = Duration.ofMinutes(Integer.parseInt(time));
|
||||
} else {
|
||||
try {
|
||||
// Only accept hours, minutes, and seconds
|
||||
duration = Duration.parse("PT" + time.toUpperCase(Locale.ROOT));
|
||||
} catch (final DateTimeParseException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
final int minutes = Integer.parseInt(time);
|
||||
if (minutes > 40320) {
|
||||
sender.sendMessage(settings.getMessage("timerTooLong"));
|
||||
return true;
|
||||
if (taskCheck) {
|
||||
if (plugin.isTaskRunning()) {
|
||||
sender.send(settings.getMessage("timerAlreadyRunning"));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (minutes < 1) {
|
||||
sender.sendMessage("§8§o[kennytv whispers to you] §7§oThink about running a timer for a negative amount of minutes. Doesn't work §lthat §7§owell.");
|
||||
return true;
|
||||
|
||||
final long seconds = duration.getSeconds();
|
||||
if (seconds > MAX_TASK_DURATION_SECONDS) {
|
||||
sender.send(settings.getMessage("timerTooLong"));
|
||||
return null;
|
||||
}
|
||||
return false;
|
||||
if (seconds < 1) {
|
||||
sender.sendRich("<i><dark_gray>[kennytv whispers to you] <gray>Think about running a timer for a negative amount of minutes. Doesn't work <b>that</b> <gray>well.");
|
||||
return null;
|
||||
}
|
||||
return duration;
|
||||
}
|
||||
|
||||
public boolean checkTimerArgs(final SenderInfo sender, final String time) {
|
||||
return checkTimerArgs(sender, time, true);
|
||||
public @Nullable Duration parseDurationAndCheckTask(final SenderInfo sender, final String time) {
|
||||
return parseDurationAndCheckTask(sender, time, true);
|
||||
}
|
||||
|
||||
protected void addToggleAndTimerCommands() {
|
||||
@@ -159,24 +175,6 @@ public abstract class MaintenanceCommand {
|
||||
add(new AbortTimerCommand(plugin), "aborttimer", "abort");
|
||||
}
|
||||
|
||||
public void checkForUpdate(final SenderInfo sender) {
|
||||
if (plugin.updateAvailable()) {
|
||||
sender.sendMessage(plugin.getPrefix() + "§cNewest version available: §aVersion " + plugin.getNewestVersion() + "§c, you're on §a" + plugin.getVersion());
|
||||
// Ore sad :(
|
||||
if (plugin.getServerType() != ServerType.SPONGE) {
|
||||
sender.sendMessage(plugin.getPrefix() + "§c§lWARNING: §cYou will have to restart the server to prevent further issues and to complete the update! If you can't do that, don't update!");
|
||||
sendUpdateMessage(sender);
|
||||
} else {
|
||||
sender.sendMessage(plugin.getPrefix() + "§aDownload the latest version on the Ore plugin page: §bhttps://ore.spongepowered.org/KennyTV/Maintenance");
|
||||
}
|
||||
} else
|
||||
sender.sendMessage(plugin.getPrefix() + "§aYou already have the latest version of the plugin!");
|
||||
}
|
||||
|
||||
protected void sendUpdateMessage(final SenderInfo sender) {
|
||||
sender.sendMessage(plugin.getPrefix() + "§eUse §c§l/maintenance forceupdate §eto update!");
|
||||
}
|
||||
|
||||
public List<String> getServersCompletion(final String s) {
|
||||
return null;
|
||||
}
|
||||
@@ -189,8 +187,6 @@ public abstract class MaintenanceCommand {
|
||||
return null;
|
||||
}
|
||||
|
||||
public abstract void sendDumpMessage(final SenderInfo sender, final String url);
|
||||
|
||||
public List<CommandInfo> getCommands() {
|
||||
return commands;
|
||||
}
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -30,16 +30,16 @@ public final class AbortTimerCommand extends CommandInfo {
|
||||
@Override
|
||||
public void execute(final SenderInfo sender, final String[] args) {
|
||||
if (args.length != 1) {
|
||||
sender.sendMessage(getHelpMessage());
|
||||
sender.send(getHelpMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!plugin.isTaskRunning()) {
|
||||
sender.sendMessage(getMessage("timerNotRunning"));
|
||||
sender.send(getMessage("timerNotRunning"));
|
||||
return;
|
||||
}
|
||||
|
||||
plugin.cancelTask();
|
||||
sender.sendMessage(getMessage("timerCancelled"));
|
||||
sender.send(getMessage("timerCancelled"));
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -32,6 +32,6 @@ public final class DebugCommand extends CommandInfo {
|
||||
if (checkArgs(sender, args, 1)) return;
|
||||
|
||||
plugin.setDebug(!plugin.isDebug());
|
||||
sender.sendMessage("Debug mode is now " + (plugin.isDebug() ? "enabled" : "disabled"));
|
||||
sender.sendPrefixedRich("<gray>Debug mode is now " + (plugin.isDebug() ? "<green>enabled" : "<red>disabled"));
|
||||
}
|
||||
}
|
||||
+16
-8
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -20,7 +20,11 @@ package eu.kennytv.maintenance.core.command.subcommand;
|
||||
import eu.kennytv.maintenance.core.MaintenancePlugin;
|
||||
import eu.kennytv.maintenance.core.command.CommandInfo;
|
||||
import eu.kennytv.maintenance.core.util.SenderInfo;
|
||||
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.TextComponent;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.event.ClickEvent;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.event.HoverEvent;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.format.NamedTextColor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public final class DumpCommand extends CommandInfo {
|
||||
@@ -34,25 +38,29 @@ public final class DumpCommand extends CommandInfo {
|
||||
public void execute(final SenderInfo sender, final String[] args) {
|
||||
if (checkArgs(sender, args, 1)) return;
|
||||
if (System.currentTimeMillis() - lastDump < TimeUnit.MINUTES.toMillis(5)) {
|
||||
sender.sendMessage(plugin.getPrefix() + "§cYou can only create a dump every 5 minutes!");
|
||||
sender.sendPrefixedRich("<red>You can only create a dump every 5 minutes!");
|
||||
return;
|
||||
}
|
||||
|
||||
lastDump = System.currentTimeMillis();
|
||||
sender.sendMessage(plugin.getPrefix() + "§7The dump is being created, this might take a moment.");
|
||||
sender.sendPrefixedRich("<gray>The dump is being created, this might take a moment.");
|
||||
plugin.async(() -> {
|
||||
final String key = plugin.pasteDump();
|
||||
if (key == null) {
|
||||
if (sender.isPlayer()) {
|
||||
sender.sendMessage(plugin.getPrefix() + "§cCould not paste dump (see the console for details)");
|
||||
sender.sendPrefixedRich("<red>Could not paste dump (see the console for details)");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
final String url = "https://hastebin.com/" + key;
|
||||
sender.sendMessage(plugin.getPrefix() + "§c" + url);
|
||||
final String url = "https://pastes.dev/" + key;
|
||||
sender.sendPrefixedRich("<red><click:open_url:'" + url + "'>" + url + "</click>");
|
||||
if (sender.isPlayer()) {
|
||||
plugin.getCommandManager().sendDumpMessage(sender, url);
|
||||
final TextComponent text = Component.text().content("Click here to copy the link").color(NamedTextColor.GRAY)
|
||||
.clickEvent(ClickEvent.clickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, url))
|
||||
.hoverEvent(HoverEvent.showText(Component.text("Click here to copy the link to your clipboard").color(NamedTextColor.GREEN)))
|
||||
.build();
|
||||
sender.send(plugin.prefix().append(text));
|
||||
}
|
||||
});
|
||||
}
|
||||
+9
-7
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -21,7 +21,7 @@ import eu.kennytv.maintenance.core.MaintenancePlugin;
|
||||
import eu.kennytv.maintenance.core.command.CommandInfo;
|
||||
import eu.kennytv.maintenance.core.util.SenderInfo;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.time.Duration;
|
||||
|
||||
public final class EndtimerCommand extends CommandInfo {
|
||||
|
||||
@@ -32,16 +32,18 @@ public final class EndtimerCommand extends CommandInfo {
|
||||
@Override
|
||||
public void execute(final SenderInfo sender, final String[] args) {
|
||||
if (checkArgs(sender, args, 2)) return;
|
||||
if (plugin.getCommandManager().checkTimerArgs(sender, args[1])) {
|
||||
sender.sendMessage(getHelpMessage());
|
||||
|
||||
final Duration duration = plugin.getCommandManager().parseDurationAndCheckTask(sender, args[1]);
|
||||
if (duration == null) {
|
||||
sender.send(getHelpMessage());
|
||||
return;
|
||||
}
|
||||
if (!plugin.isMaintenance()) {
|
||||
sender.sendMessage(getMessage("alreadyDisabled"));
|
||||
sender.send(getMessage("alreadyDisabled"));
|
||||
return;
|
||||
}
|
||||
|
||||
plugin.startMaintenanceRunnable(Integer.parseInt(args[1]), TimeUnit.MINUTES, false);
|
||||
sender.sendMessage(getMessage("endtimerStarted").replace("%TIME%", plugin.getRunnable().getTime()));
|
||||
plugin.startMaintenanceRunnable(duration, false);
|
||||
sender.send(getMessage("endtimerStarted", "%TIME%", plugin.getRunnable().getTime()));
|
||||
}
|
||||
}
|
||||
+19
-17
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -21,7 +21,7 @@ import com.google.common.base.Preconditions;
|
||||
import eu.kennytv.maintenance.core.MaintenancePlugin;
|
||||
import eu.kennytv.maintenance.core.command.CommandInfo;
|
||||
import eu.kennytv.maintenance.core.util.SenderInfo;
|
||||
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -35,7 +35,7 @@ public final class HelpCommand extends CommandInfo {
|
||||
@Override
|
||||
public void execute(final SenderInfo sender, final String[] args) {
|
||||
if (args.length > 2) {
|
||||
sender.sendMessage(getHelpMessage());
|
||||
sender.send(getHelpMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public final class HelpCommand extends CommandInfo {
|
||||
}
|
||||
|
||||
if (!plugin.isNumeric(args[1])) {
|
||||
sender.sendMessage(getHelpMessage());
|
||||
sender.send(getHelpMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -59,35 +59,37 @@ public final class HelpCommand extends CommandInfo {
|
||||
|
||||
public void sendUsage(final SenderInfo sender, final int page) {
|
||||
Preconditions.checkArgument(page > 0);
|
||||
final List<String> commands = new ArrayList<>();
|
||||
final List<Component> commands = new ArrayList<>();
|
||||
for (final CommandInfo cmd : plugin.getCommandManager().getCommands()) {
|
||||
if (cmd.isVisible() && cmd.hasPermission(sender)) {
|
||||
commands.add(cmd.getHelpMessage());
|
||||
}
|
||||
}
|
||||
if ((page - 1) * COMMANDS_PER_PAGE >= commands.size()) {
|
||||
sender.sendMessage(getMessage("helpPageNotFound"));
|
||||
sender.send(getMessage("helpPageNotFound"));
|
||||
return;
|
||||
}
|
||||
|
||||
final List<String> filteredCommands = commands.subList((page - 1) * COMMANDS_PER_PAGE, Math.min(page * COMMANDS_PER_PAGE, commands.size()));
|
||||
final List<Component> filteredCommands = commands.subList((page - 1) * COMMANDS_PER_PAGE, Math.min(page * COMMANDS_PER_PAGE, commands.size()));
|
||||
|
||||
final String header = getMessage("helpHeader").replace("%NAME%", "Maintenance" + plugin.getServerType())
|
||||
.replace("%PAGE%", Integer.toString(page)).replace("%MAX%", Integer.toString((commands.size() + getDivide(commands.size())) / COMMANDS_PER_PAGE));
|
||||
sender.sendMessage("");
|
||||
sender.sendMessage(header);
|
||||
for (final String command : filteredCommands) {
|
||||
sender.sendMessage(command);
|
||||
final Component header = getMessage("helpHeader",
|
||||
"%NAME%", "Maintenance" + plugin.getServerType(),
|
||||
"%PAGE%", Integer.toString(page),
|
||||
"%MAX%", Integer.toString((commands.size() + getDivide(commands.size())) / COMMANDS_PER_PAGE));
|
||||
sender.send(Component.empty());
|
||||
sender.send(header);
|
||||
for (final Component command : filteredCommands) {
|
||||
sender.send(command);
|
||||
}
|
||||
|
||||
if (page * COMMANDS_PER_PAGE < commands.size()) {
|
||||
sender.sendMessage(getMessage("helpNextPage").replace("%PAGE%", Integer.toString(page + 1)));
|
||||
sender.send(getMessage("helpNextPage", "%PAGE%", Integer.toString(page + 1)));
|
||||
} else {
|
||||
sender.sendMessage("§8× §eVersion " + plugin.getVersion() + " §7by §bkennytv");
|
||||
sender.sendRich("<dark_gray>× <yellow>Version: " + plugin.getVersion() + " <gray>by <aqua>kennytv");
|
||||
}
|
||||
|
||||
sender.sendMessage(header);
|
||||
sender.sendMessage("");
|
||||
sender.send(header);
|
||||
sender.send(Component.empty());
|
||||
}
|
||||
|
||||
private int getDivide(final int size) {
|
||||
+11
-11
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -36,35 +36,35 @@ public final class MotdCommand extends CommandInfo {
|
||||
sendList(sender, getSettings().getPingMessages());
|
||||
} else if (args.length == 2 && args[1].equalsIgnoreCase("timer")) {
|
||||
if (!getSettings().hasTimerSpecificPingMessages()) {
|
||||
sender.sendMessage(getMessage("timerMotdDisabled"));
|
||||
sender.send(getMessage("timerMotdDisabled"));
|
||||
return;
|
||||
}
|
||||
|
||||
sendList(sender, getSettings().getTimerSpecificPingMessages());
|
||||
} else {
|
||||
sender.sendMessage(getHelpMessage());
|
||||
sender.send(getHelpMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void sendList(final SenderInfo sender, final List<String> list) {
|
||||
if (list == null || list.isEmpty()) {
|
||||
sender.sendMessage(getMessage("motdListEmpty"));
|
||||
sender.send(getMessage("motdListEmpty"));
|
||||
return;
|
||||
}
|
||||
|
||||
sender.sendMessage(getMessage("motdList"));
|
||||
sender.send(getMessage("motdList"));
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
sender.sendMessage("§b" + (i + 1) + "§8§m---------");
|
||||
for (final String motd : getSettings().getColoredString(list.get(i)).split("%NEWLINE%")) {
|
||||
sender.sendMessage(motd);
|
||||
}
|
||||
sender.sendRich("<aqua>" + (i + 1) + "<dark_gray><st>---------");
|
||||
sender.sendRich(list.get(i));
|
||||
}
|
||||
sender.sendMessage("§8§m----------");
|
||||
sender.sendRich("<dark_gray><st>----------");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabCompletion(final SenderInfo sender, final String[] args) {
|
||||
if (args.length != 2 || !getSettings().hasTimerSpecificPingMessages()) return Collections.emptyList();
|
||||
if (args.length != 2 || !getSettings().hasTimerSpecificPingMessages()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Collections.singletonList("timer");
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -31,6 +31,6 @@ public final class ReloadCommand extends CommandInfo {
|
||||
public void execute(final SenderInfo sender, final String[] args) {
|
||||
if (checkArgs(sender, args, 1)) return;
|
||||
getSettings().reloadConfigs();
|
||||
sender.sendMessage(getMessage("reload"));
|
||||
sender.send(getMessage("reload"));
|
||||
}
|
||||
}
|
||||
+14
-9
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -20,6 +20,7 @@ package eu.kennytv.maintenance.core.command.subcommand;
|
||||
import eu.kennytv.maintenance.core.MaintenancePlugin;
|
||||
import eu.kennytv.maintenance.core.Settings;
|
||||
import eu.kennytv.maintenance.core.command.CommandInfo;
|
||||
import eu.kennytv.maintenance.core.config.ConfigSection;
|
||||
import eu.kennytv.maintenance.core.util.SenderInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -37,7 +38,7 @@ public final class RemoveMotdCommand extends CommandInfo {
|
||||
boolean timerPingMessages = false;
|
||||
if (args.length == 3 && args[1].equalsIgnoreCase("timer")) {
|
||||
if (!getSettings().hasTimerSpecificPingMessages()) {
|
||||
sender.sendMessage(getMessage("timerMotdDisabled"));
|
||||
sender.send(getMessage("timerMotdDisabled"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -46,28 +47,32 @@ public final class RemoveMotdCommand extends CommandInfo {
|
||||
}
|
||||
if (checkArgs(sender, args, 2)) return;
|
||||
if (!plugin.isNumeric(args[1])) {
|
||||
sender.sendMessage(getHelpMessage());
|
||||
sender.send(getHelpMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
final Settings settings = getSettings();
|
||||
final List<String> pingMessages = timerPingMessages ? settings.getTimerSpecificPingMessages() : settings.getPingMessages();
|
||||
final ConfigSection section = settings.getConfig().getSection("ping-message");
|
||||
final List<String> pingMessages = section.getStringList(timerPingMessages ? "timer-messages" : "messages");
|
||||
if (pingMessages.size() < 2) {
|
||||
sender.sendMessage(getMessage("removeMotdError"));
|
||||
sender.send(getMessage("removeMotdError"));
|
||||
return;
|
||||
}
|
||||
|
||||
final int index = Integer.parseInt(args[1]);
|
||||
if (index == 0 || index > pingMessages.size()) {
|
||||
sender.sendMessage(getMessage("setMotdIndexError").replace("%MOTDS%", Integer.toString(pingMessages.size()))
|
||||
.replace("%NEWAMOUNT%", Integer.toString(pingMessages.size())));
|
||||
sender.send(getMessage("setMotdIndexError",
|
||||
"%MOTDS%", Integer.toString(pingMessages.size()),
|
||||
"%NEWAMOUNT%", Integer.toString(pingMessages.size())));
|
||||
return;
|
||||
}
|
||||
|
||||
final List<String> pingComponents = timerPingMessages ? settings.getTimerSpecificPingMessages() : settings.getPingMessages();
|
||||
pingComponents.remove(index - 1);
|
||||
pingMessages.remove(index - 1);
|
||||
settings.getConfig().set(timerPingMessages ? "timerspecific-pingmessages" : "pingmessages", pingMessages);
|
||||
section.set(timerPingMessages ? "timer-messages" : "messages", pingMessages);
|
||||
settings.saveConfig();
|
||||
sender.sendMessage(getMessage("removedMotd").replace("%INDEX%", args[1]));
|
||||
sender.send(getMessage("removedMotd", "%INDEX%", args[1]));
|
||||
}
|
||||
|
||||
@Override
|
||||
+14
-9
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -20,8 +20,7 @@ package eu.kennytv.maintenance.core.command.subcommand;
|
||||
import eu.kennytv.maintenance.core.MaintenancePlugin;
|
||||
import eu.kennytv.maintenance.core.command.CommandInfo;
|
||||
import eu.kennytv.maintenance.core.util.SenderInfo;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.time.Duration;
|
||||
|
||||
public final class ScheduleTimerCommand extends CommandInfo {
|
||||
|
||||
@@ -32,17 +31,23 @@ public final class ScheduleTimerCommand extends CommandInfo {
|
||||
@Override
|
||||
public void execute(final SenderInfo sender, final String[] args) {
|
||||
if (checkArgs(sender, args, 3)) return;
|
||||
if (plugin.getCommandManager().checkTimerArgs(sender, args[1])
|
||||
|| plugin.getCommandManager().checkTimerArgs(sender, args[2], false)) {
|
||||
sender.sendMessage(getHelpMessage());
|
||||
|
||||
final Duration enableIn = plugin.getCommandManager().parseDurationAndCheckTask(sender, args[1]);
|
||||
final Duration maintenanceDuration = plugin.getCommandManager().parseDurationAndCheckTask(sender, args[2], false);
|
||||
if (enableIn == null || maintenanceDuration == null) {
|
||||
sender.send(getHelpMessage());
|
||||
return;
|
||||
}
|
||||
if (plugin.isMaintenance()) {
|
||||
sender.sendMessage(getMessage("alreadyEnabled"));
|
||||
sender.send(getMessage("alreadyEnabled"));
|
||||
return;
|
||||
}
|
||||
|
||||
plugin.scheduleMaintenanceRunnable(Integer.parseInt(args[1]), Integer.parseInt(args[2]), TimeUnit.MINUTES);
|
||||
sender.sendMessage(getMessage("starttimerStarted").replace("%TIME%", plugin.getRunnable().getTime()));
|
||||
plugin.scheduleMaintenanceRunnable(enableIn, maintenanceDuration);
|
||||
sender.send(getMessage(
|
||||
"scheduletimerStarted",
|
||||
"%TIME%", plugin.getRunnable().getTime(),
|
||||
"%DURATION%", plugin.getFormattedTime((int) maintenanceDuration.getSeconds())
|
||||
));
|
||||
}
|
||||
}
|
||||
+29
-16
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -20,13 +20,15 @@ package eu.kennytv.maintenance.core.command.subcommand;
|
||||
import eu.kennytv.maintenance.core.MaintenancePlugin;
|
||||
import eu.kennytv.maintenance.core.Settings;
|
||||
import eu.kennytv.maintenance.core.command.CommandInfo;
|
||||
import eu.kennytv.maintenance.core.config.ConfigSection;
|
||||
import eu.kennytv.maintenance.core.util.SenderInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static eu.kennytv.maintenance.core.Settings.NEW_LINE_REPLACEMENT;
|
||||
|
||||
public final class SetMotdCommand extends CommandInfo {
|
||||
|
||||
public SetMotdCommand(final MaintenancePlugin plugin) {
|
||||
@@ -38,7 +40,7 @@ public final class SetMotdCommand extends CommandInfo {
|
||||
boolean timerPingMessages = false;
|
||||
if (args.length > 1 && args[1].equalsIgnoreCase("timer")) {
|
||||
if (!getSettings().hasTimerSpecificPingMessages()) {
|
||||
sender.sendMessage(getMessage("timerMotdDisabled"));
|
||||
sender.send(getMessage("timerMotdDisabled"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -47,27 +49,30 @@ public final class SetMotdCommand extends CommandInfo {
|
||||
timerPingMessages = true;
|
||||
}
|
||||
if (args.length < 4 || !plugin.isNumeric(args[1])) {
|
||||
sender.sendMessage(getHelpMessage());
|
||||
sender.send(getHelpMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
final Settings settings = getSettings();
|
||||
final List<String> pingMessages = timerPingMessages ? settings.getTimerSpecificPingMessages() : settings.getPingMessages();
|
||||
final List<String> pingComponents = timerPingMessages ? settings.getTimerSpecificPingMessages() : settings.getPingMessages();
|
||||
final ConfigSection section = settings.getConfig().getSection("ping-message");
|
||||
final List<String> pingMessages = section.getStringList(timerPingMessages ? "timer-messages" : "messages");
|
||||
final int index = Integer.parseInt(args[1]);
|
||||
if (index == 0 || index > pingMessages.size() + 1) {
|
||||
sender.sendMessage(getMessage("setMotdIndexError").replace("%MOTDS%", Integer.toString(pingMessages.size()))
|
||||
.replace("%NEWAMOUNT%", Integer.toString(pingMessages.size() + 1)));
|
||||
sender.send(getMessage("setMotdIndexError",
|
||||
"%MOTDS%", Integer.toString(pingMessages.size()),
|
||||
"%NEWAMOUNT%", Integer.toString(pingMessages.size() + 1)));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!plugin.isNumeric(args[2])) {
|
||||
sender.sendMessage(getMessage("setMotdLineError"));
|
||||
sender.send(getMessage("setMotdLineError"));
|
||||
return;
|
||||
}
|
||||
|
||||
final int line = Integer.parseInt(args[2]);
|
||||
if (line != 1 && line != 2) {
|
||||
sender.sendMessage(getMessage("setMotdLineError"));
|
||||
sender.send(getMessage("setMotdLineError"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -75,23 +80,31 @@ public final class SetMotdCommand extends CommandInfo {
|
||||
final String oldMessage = index > pingMessages.size() ? "" : pingMessages.get(index - 1);
|
||||
final String newMessage;
|
||||
if (line == 1) {
|
||||
newMessage = oldMessage.contains("%NEWLINE%") ?
|
||||
message + "%NEWLINE%" + oldMessage.split("%NEWLINE%", 2)[1] : message;
|
||||
newMessage = oldMessage.contains(NEW_LINE_REPLACEMENT) ?
|
||||
message + NEW_LINE_REPLACEMENT + oldMessage.split(NEW_LINE_REPLACEMENT, 2)[1] : message;
|
||||
} else {
|
||||
newMessage = oldMessage.contains("%NEWLINE%") ?
|
||||
oldMessage.split("%NEWLINE%", 2)[0] + "%NEWLINE%" + message : oldMessage + "%NEWLINE%" + message;
|
||||
newMessage = oldMessage.contains(NEW_LINE_REPLACEMENT) ?
|
||||
oldMessage.split(NEW_LINE_REPLACEMENT, 2)[0] + NEW_LINE_REPLACEMENT + message : oldMessage + NEW_LINE_REPLACEMENT + message;
|
||||
}
|
||||
|
||||
// Replace component in config and the cached list
|
||||
final String componentString = newMessage.replace(NEW_LINE_REPLACEMENT, "\n");
|
||||
if (index > pingMessages.size()) {
|
||||
pingMessages.add(newMessage);
|
||||
pingComponents.add(componentString);
|
||||
} else {
|
||||
pingMessages.set(index - 1, newMessage);
|
||||
pingComponents.set(index - 1, componentString);
|
||||
}
|
||||
|
||||
settings.getConfig().set(timerPingMessages ? "timerspecific-pingmessages" : "pingmessages", pingMessages);
|
||||
section.set(timerPingMessages ? "timer-messages" : "messages", pingMessages);
|
||||
settings.saveConfig();
|
||||
sender.sendMessage(settings.getMessage("setMotd").replace("%LINE%", args[2]).replace("%INDEX%", args[1])
|
||||
.replace("%MOTD%", "§f" + settings.getColoredString(message)));
|
||||
sender.send(settings.getMessage(
|
||||
"setMotd",
|
||||
"%LINE%", args[2],
|
||||
"%INDEX%", args[1],
|
||||
"%MOTD%", componentString
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
+9
-7
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -21,7 +21,7 @@ import eu.kennytv.maintenance.core.MaintenancePlugin;
|
||||
import eu.kennytv.maintenance.core.command.CommandInfo;
|
||||
import eu.kennytv.maintenance.core.util.SenderInfo;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.time.Duration;
|
||||
|
||||
public final class StarttimerCommand extends CommandInfo {
|
||||
|
||||
@@ -32,16 +32,18 @@ public final class StarttimerCommand extends CommandInfo {
|
||||
@Override
|
||||
public void execute(final SenderInfo sender, final String[] args) {
|
||||
if (checkArgs(sender, args, 2)) return;
|
||||
if (plugin.getCommandManager().checkTimerArgs(sender, args[1])) {
|
||||
sender.sendMessage(getHelpMessage());
|
||||
|
||||
final Duration duration = plugin.getCommandManager().parseDurationAndCheckTask(sender, args[1]);
|
||||
if (duration == null) {
|
||||
sender.send(getHelpMessage());
|
||||
return;
|
||||
}
|
||||
if (plugin.isMaintenance()) {
|
||||
sender.sendMessage(getMessage("alreadyEnabled"));
|
||||
sender.send(getMessage("alreadyEnabled"));
|
||||
return;
|
||||
}
|
||||
|
||||
plugin.startMaintenanceRunnable(Integer.parseInt(args[1]), TimeUnit.MINUTES, true);
|
||||
sender.sendMessage(getMessage("starttimerStarted").replace("%TIME%", plugin.getRunnable().getTime()));
|
||||
plugin.startMaintenanceRunnable(duration, true);
|
||||
sender.send(getMessage("starttimerStarted", "%TIME%", plugin.getRunnable().getTime()));
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -33,7 +33,7 @@ public final class ToggleCommand extends CommandInfo {
|
||||
|
||||
final boolean maintenance = args[0].equalsIgnoreCase("on");
|
||||
if (maintenance == plugin.isMaintenance()) {
|
||||
sender.sendMessage(getMessage(maintenance ? "alreadyEnabled" : "alreadyDisabled"));
|
||||
sender.send(getMessage(maintenance ? "alreadyEnabled" : "alreadyDisabled"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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 eu.kennytv.maintenance.core.command.subcommand;
|
||||
|
||||
import eu.kennytv.maintenance.core.MaintenancePlugin;
|
||||
import eu.kennytv.maintenance.core.command.CommandInfo;
|
||||
import eu.kennytv.maintenance.core.util.SenderInfo;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.event.ClickEvent;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.event.HoverEvent;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.format.NamedTextColor;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.minimessage.MiniMessage;
|
||||
|
||||
public final class UpdateCommand extends CommandInfo {
|
||||
|
||||
public UpdateCommand(final MaintenancePlugin plugin) {
|
||||
super(plugin, "update");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(final SenderInfo sender, final String[] args) {
|
||||
if (checkArgs(sender, args, 1)) return;
|
||||
if (args[0].equalsIgnoreCase("update")) {
|
||||
plugin.async(() -> checkForUpdate(sender));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!plugin.updateAvailable()) {
|
||||
sender.sendPrefixedRich("<green>You already have the latest version of the plugin!");
|
||||
return;
|
||||
}
|
||||
|
||||
sender.send(getMessage("updateDownloading"));
|
||||
try {
|
||||
if (plugin.installUpdate()) {
|
||||
sender.send(getMessage("updateFinished"));
|
||||
} else {
|
||||
sender.send(getMessage("updateFailed"));
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
sender.send(getMessage("updateFailed"));
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void checkForUpdate(final SenderInfo sender) {
|
||||
if (!plugin.updateAvailable()) {
|
||||
sender.sendPrefixedRich("<green>You already have the latest version of the plugin!");
|
||||
return;
|
||||
}
|
||||
|
||||
sender.sendPrefixedRich("<red>Newest version available: <green>Version " + plugin.getNewestVersion() + "<red>, you're on <green>" + plugin.getVersion());
|
||||
sender.sendPrefixedRich("<b><red>WARNING: <red>You will have to restart the server to prevent further issues and to complete the update! If you can't do that, don't update!");
|
||||
|
||||
sender.send(Component.text().append(MiniMessage.miniMessage().deserialize("<gold>× <dark_gray>[<green>Update<dark_gray>]"))
|
||||
.clickEvent(ClickEvent.runCommand("/maintenance forceupdate"))
|
||||
.hoverEvent(HoverEvent.showText(Component.text().content("Click here to update the plugin").color(NamedTextColor.GREEN)))
|
||||
.append(Component.text().content(", or manually run ").color(NamedTextColor.GRAY))
|
||||
.append(Component.text().content("/maintenance forceupdate").color(NamedTextColor.RED)).build());
|
||||
}
|
||||
}
|
||||
+32
-17
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -25,6 +25,7 @@ import eu.kennytv.maintenance.core.util.SenderInfo;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public final class WhitelistAddCommand extends CommandInfo {
|
||||
|
||||
@@ -45,7 +46,7 @@ public final class WhitelistAddCommand extends CommandInfo {
|
||||
}
|
||||
} else if (args.length == 3) {
|
||||
if (args[1].length() != 36) {
|
||||
sender.sendMessage(getHelpMessage());
|
||||
sender.send(getHelpMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -54,7 +55,7 @@ public final class WhitelistAddCommand extends CommandInfo {
|
||||
addPlayerToWhitelist(sender, new DummySenderInfo(uuid, args[2]));
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage(getHelpMessage());
|
||||
sender.send(getHelpMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,30 +65,44 @@ public final class WhitelistAddCommand extends CommandInfo {
|
||||
}
|
||||
|
||||
private void addPlayerToWhitelist(final SenderInfo sender, final String name) {
|
||||
final SenderInfo selected = plugin.getOfflinePlayer(name);
|
||||
if (selected == null) {
|
||||
sender.sendMessage(getMessage("playerNotOnline"));
|
||||
return;
|
||||
}
|
||||
plugin.getOfflinePlayer(name).whenComplete((selected, ex) -> {
|
||||
if (ex != null) {
|
||||
plugin.getLogger().log(Level.SEVERE, "Error while fetching offline player", ex);
|
||||
sender.send(getMessage("offlinePlayerFetchError"));
|
||||
return;
|
||||
}
|
||||
|
||||
addPlayerToWhitelist(sender, selected);
|
||||
if (selected == null) {
|
||||
sender.send(getMessage("playerNotOnline"));
|
||||
return;
|
||||
}
|
||||
|
||||
addPlayerToWhitelist(sender, selected);
|
||||
});
|
||||
}
|
||||
|
||||
private void addPlayerToWhitelist(final SenderInfo sender, final UUID uuid) {
|
||||
final SenderInfo selected = plugin.getOfflinePlayer(uuid);
|
||||
if (selected == null) {
|
||||
sender.sendMessage(getMessage("playerNotFoundUuid"));
|
||||
return;
|
||||
}
|
||||
plugin.getOfflinePlayer(uuid).whenComplete((selected, ex) -> {
|
||||
if (ex != null) {
|
||||
plugin.getLogger().log(Level.SEVERE, "Error while fetching offline player", ex);
|
||||
sender.send(getMessage("offlinePlayerFetchError"));
|
||||
return;
|
||||
}
|
||||
|
||||
addPlayerToWhitelist(sender, selected);
|
||||
if (selected == null) {
|
||||
sender.send(getMessage("playerNotFoundUuid"));
|
||||
return;
|
||||
}
|
||||
|
||||
addPlayerToWhitelist(sender, selected);
|
||||
});
|
||||
}
|
||||
|
||||
private void addPlayerToWhitelist(final SenderInfo sender, final SenderInfo selected) {
|
||||
if (getSettings().addWhitelistedPlayer(selected.getUuid(), selected.getName())) {
|
||||
sender.sendMessage(getMessage("whitelistAdded").replace("%PLAYER%", selected.getName()));
|
||||
sender.send(getMessage("whitelistAdded", "%PLAYER%", selected.getName()));
|
||||
} else {
|
||||
sender.sendMessage(getMessage("whitelistAlreadyAdded").replace("%PLAYER%", selected.getName()));
|
||||
sender.send(getMessage("whitelistAlreadyAdded", "%PLAYER%", selected.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
-6
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -20,6 +20,7 @@ package eu.kennytv.maintenance.core.command.subcommand;
|
||||
import eu.kennytv.maintenance.core.MaintenancePlugin;
|
||||
import eu.kennytv.maintenance.core.command.CommandInfo;
|
||||
import eu.kennytv.maintenance.core.util.SenderInfo;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
@@ -36,16 +37,17 @@ public final class WhitelistCommand extends CommandInfo {
|
||||
|
||||
final Map<UUID, String> players = getSettings().getWhitelistedPlayers();
|
||||
if (players.isEmpty()) {
|
||||
sender.sendMessage(getMessage("whitelistEmpty"));
|
||||
sender.send(getMessage("whitelistEmpty"));
|
||||
return;
|
||||
}
|
||||
|
||||
sender.sendMessage(getMessage("whitelistedPlayers"));
|
||||
final String format = getMessage("whitelistedPlayersFormat");
|
||||
sender.send(getMessage("whitelistedPlayers"));
|
||||
final Component format = getMessage("whitelistedPlayersFormat");
|
||||
for (final Map.Entry<UUID, String> entry : players.entrySet()) {
|
||||
sender.sendMessage(format.replace("%NAME%", entry.getValue()).replace("%UUID%", entry.getKey().toString()));
|
||||
sender.send(format.replaceText(builder -> builder.matchLiteral("%NAME%").replacement(entry.getValue()))
|
||||
.replaceText(builder -> builder.matchLiteral("%UUID%").replacement(entry.getKey().toString())));
|
||||
}
|
||||
|
||||
sender.sendMessage("");
|
||||
sender.send(Component.empty());
|
||||
}
|
||||
}
|
||||
+22
-19
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -50,8 +50,9 @@ public final class WhitelistRemoveCommand extends CommandInfo {
|
||||
if (args.length != 2) return Collections.emptyList();
|
||||
|
||||
final List<String> list = new ArrayList<>();
|
||||
String matchNameLowerCase = args[1].toLowerCase();
|
||||
for (final String name : getSettings().getWhitelistedPlayers().values()) {
|
||||
if (name.toLowerCase().startsWith(args[1])) {
|
||||
if (name.toLowerCase().startsWith(matchNameLowerCase)) {
|
||||
list.add(name);
|
||||
}
|
||||
}
|
||||
@@ -59,33 +60,35 @@ public final class WhitelistRemoveCommand extends CommandInfo {
|
||||
}
|
||||
|
||||
private void removePlayerFromWhitelist(final SenderInfo sender, final String name) {
|
||||
final SenderInfo selected = plugin.getOfflinePlayer(name);
|
||||
if (selected == null) {
|
||||
if (getSettings().removeWhitelistedPlayer(name)) {
|
||||
sender.sendMessage(getMessage("whitelistRemoved").replace("%PLAYER%", name));
|
||||
} else {
|
||||
sender.sendMessage(getMessage("whitelistNotFound"));
|
||||
plugin.getOfflinePlayer(name).whenComplete((selected, ex) -> {
|
||||
if (selected == null) {
|
||||
if (getSettings().removeWhitelistedPlayer(name)) {
|
||||
sender.send(getMessage("whitelistRemoved", "%PLAYER%", name));
|
||||
} else {
|
||||
sender.send(getMessage("whitelistNotFound"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
removePlayerFromWhitelist(sender, selected.getUuid(), selected.getName());
|
||||
removePlayerFromWhitelist(sender, selected.getUuid(), selected.getName());
|
||||
});
|
||||
}
|
||||
|
||||
private void removePlayerFromWhitelist(final SenderInfo sender, final UUID uuid) {
|
||||
final SenderInfo selected = plugin.getOfflinePlayer(uuid);
|
||||
if (selected == null) {
|
||||
removePlayerFromWhitelist(sender, uuid, uuid.toString());
|
||||
} else {
|
||||
removePlayerFromWhitelist(sender, selected.getUuid(), selected.getName());
|
||||
}
|
||||
plugin.getOfflinePlayer(uuid).whenComplete((selected, ex) -> {
|
||||
if (selected == null) {
|
||||
removePlayerFromWhitelist(sender, uuid, uuid.toString());
|
||||
} else {
|
||||
removePlayerFromWhitelist(sender, selected.getUuid(), selected.getName());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void removePlayerFromWhitelist(final SenderInfo sender, final UUID uuid, final String toReplace) {
|
||||
if (getSettings().removeWhitelistedPlayer(uuid)) {
|
||||
sender.sendMessage(getMessage("whitelistRemoved").replace("%PLAYER%", toReplace));
|
||||
sender.send(getMessage("whitelistRemoved", "%PLAYER%", toReplace));
|
||||
} else {
|
||||
sender.sendMessage(getMessage("whitelistNotFound"));
|
||||
sender.send(getMessage("whitelistNotFound"));
|
||||
}
|
||||
}
|
||||
}
|
||||
+18
-39
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -18,10 +18,6 @@
|
||||
package eu.kennytv.maintenance.core.config;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@@ -31,9 +27,12 @@ import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
/**
|
||||
* Further modified version of the SimpleConfig project of PSandro (https://github.com/PSandro/SimpleConfig).
|
||||
* Further modified version of the <a href="https://github.com/PSandro/SimpleConfig">SimpleConfig</a>SimpleConfig project of PSandro.
|
||||
*
|
||||
* @author PSandro on 26.01.19
|
||||
* @author kennytv
|
||||
@@ -41,16 +40,18 @@ import java.util.Set;
|
||||
public final class Config extends ConfigSection {
|
||||
|
||||
private static final String AWESOME_HEADER =
|
||||
"#######################################################################################################################\n" +
|
||||
"# __ __ _ _ _ _ __ _______ __ #\n" +
|
||||
"# | \\/ | __ _(_)_ __ | |_ ___ _ __ __ _ _ __ ___ ___ | |__ _ _ | |/ /___ _ __ _ __ _ |_ _\\ \\ / / #\n" +
|
||||
"# | |\\/| |/ _` | | '_ \\| __/ _ \\ '_ \\ / _` | '_ \\ / __/ _ \\ | '_ \\| | | | | ' // _ \\ '_ \\| '_ \\| | | || | \\ \\ / / #\n" +
|
||||
"# | | | | (_| | | | | | || __/ | | | (_| | | | | (_| __/ | |_) | |_| | | . \\ __/ | | | | | | |_| || | \\ V / #\n" +
|
||||
"# |_| |_|\\__,_|_|_| |_|\\__\\___|_| |_|\\__,_|_| |_|\\___\\___| |_.__/ \\__, | |_|\\_\\___|_| |_|_| |_|\\__, ||_| \\_/ #\n" +
|
||||
"# |___/ |___/ #\n" +
|
||||
"#######################################################################################################################\n" +
|
||||
"###################################################################################################################\n" +
|
||||
"# __ __ _ _ _ _ _ #\n" +
|
||||
"# | \\/ | __ _(_)_ __ | |_ ___ _ __ __ _ _ __ ___ ___ | |__ _ _ | | _____ _ __ _ __ _ _| |___ __ #\n" +
|
||||
"# | |\\/| |/ _` | | '_ \\| __/ _ \\ '_ \\ / _` | '_ \\ / __/ _ \\ | '_ \\| | | | | |/ / _ \\ '_ \\| '_ \\| | | | __\\ \\ / / #\n" +
|
||||
"# | | | | (_| | | | | | || __/ | | | (_| | | | | (_| __/ | |_) | |_| | | < __/ | | | | | | |_| | |_ \\ V / #\n" +
|
||||
"# |_| |_|\\__,_|_|_| |_|\\__\\___|_| |_|\\__,_|_| |_|\\___\\___| |_.__/ \\__, | |_|\\_\\___|_| |_|_| |_|\\__, |\\__| \\_/ #\n" +
|
||||
"# |___/ |___/ #\n" +
|
||||
"###################################################################################################################\n" +
|
||||
"# You can report bugs here: https://github.com/kennytv/Maintenance/issues\n" +
|
||||
"# If you need any other help/support, you can also join my Discord server: https://discord.gg/vGCUzHq\n";
|
||||
"# If you need any other help/support, you can also join my Discord server: https://discord.gg/vGCUzHq\n" +
|
||||
"# The config and language files use MiniMessage, NOT legacy text for input. Use https://webui.adventure.kyori.net/ to edit and preview the formatted text.\n" +
|
||||
"# For a full list of formats and fancy examples of MiniMessage, see https://docs.adventure.kyori.net/minimessage/format.html\n";
|
||||
private final Yaml yaml = createYaml();
|
||||
private final File file;
|
||||
private final Set<String> unsupportedFields;
|
||||
@@ -108,30 +109,8 @@ public final class Config extends ConfigSection {
|
||||
Files.write(file.toPath(), bytes);
|
||||
}
|
||||
|
||||
public boolean addMissingFields(final Map<String, Object> fields, final Map<String, String[]> comments) {
|
||||
// Note: Only scans for the first two levels
|
||||
boolean changed = false;
|
||||
for (final Map.Entry<String, Object> entry : fields.entrySet()) {
|
||||
final Object o = values.get(entry.getKey());
|
||||
if (o != null) {
|
||||
final Object o2 = entry.getValue();
|
||||
if (!(o instanceof Map) || !(o2 instanceof Map)) continue;
|
||||
|
||||
final Map<String, Object> deepMap = (Map<String, Object>) o2;
|
||||
for (final Map.Entry<String, Object> deepEntry : ((Map<String, Object>) o2).entrySet()) {
|
||||
if (deepMap.containsKey(deepEntry.getKey())) continue;
|
||||
deepMap.put(deepEntry.getKey(), deepEntry.getValue());
|
||||
changed = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
values.put(entry.getKey(), entry.getValue());
|
||||
changed = true;
|
||||
}
|
||||
|
||||
this.comments = new HashMap<>(comments);
|
||||
return changed;
|
||||
public void replaceComments(final Config fromConfig) {
|
||||
this.comments = new HashMap<>(fromConfig.comments);
|
||||
}
|
||||
|
||||
private static Yaml createYaml() {
|
||||
+58
-12
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -17,15 +17,15 @@
|
||||
*/
|
||||
package eu.kennytv.maintenance.core.config;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Further modified version of the SimpleConfig project of PSandro (https://github.com/PSandro/SimpleConfig).
|
||||
* Further modified version of the <a href="https://github.com/PSandro/SimpleConfig">SimpleConfig</a>SimpleConfig project of PSandro.
|
||||
*
|
||||
* @author kennytv
|
||||
*/
|
||||
@@ -63,15 +63,15 @@ public class ConfigSection {
|
||||
|
||||
@Nullable
|
||||
public Object getObject(final String key, final Object def) {
|
||||
int i1 = -1;
|
||||
int i2;
|
||||
int nextSeparatorIndex = -1;
|
||||
int sectionStartIndex;
|
||||
ConfigSection section = this;
|
||||
while ((i1 = key.indexOf('.', i2 = i1 + 1)) != -1) {
|
||||
section = section.getSection(key.substring(i2, i1));
|
||||
while ((nextSeparatorIndex = key.indexOf('.', sectionStartIndex = nextSeparatorIndex + 1)) != -1) {
|
||||
section = section.getSection(key.substring(sectionStartIndex, nextSeparatorIndex));
|
||||
if (section == null) return def;
|
||||
}
|
||||
|
||||
final String subKey = key.substring(i2);
|
||||
final String subKey = key.substring(sectionStartIndex);
|
||||
if (section == this) {
|
||||
final Object result = values.get(subKey);
|
||||
return result != null ? result : def;
|
||||
@@ -97,17 +97,41 @@ public class ConfigSection {
|
||||
return new ConfigSection(getRoot(), getFullKeyInPath(key), (Map<String, Object>) o);
|
||||
}
|
||||
|
||||
public ConfigSection getOrCreateSection(final String key) {
|
||||
final Object o = getObject(key);
|
||||
if (!(o instanceof Map)) {
|
||||
set(key, new LinkedHashMap<>());
|
||||
return getSection(key);
|
||||
}
|
||||
return new ConfigSection(getRoot(), getFullKeyInPath(key), (Map<String, Object>) o);
|
||||
}
|
||||
|
||||
public boolean contains(final String key) {
|
||||
return getObject(key) != null;
|
||||
}
|
||||
|
||||
public void set(final String key, @Nullable final Object value) {
|
||||
//TODO go deep if necessary
|
||||
int nextSeparatorIndex = -1;
|
||||
int sectionStartIndex;
|
||||
ConfigSection section = this;
|
||||
while ((nextSeparatorIndex = key.indexOf('.', sectionStartIndex = nextSeparatorIndex + 1)) != -1) {
|
||||
section = section.getOrCreateSection(key.substring(sectionStartIndex, nextSeparatorIndex));
|
||||
}
|
||||
|
||||
final String sectionKey = key.substring(sectionStartIndex);
|
||||
if (value == null) {
|
||||
values.remove(key);
|
||||
section.values.remove(sectionKey);
|
||||
getRoot().getComments().remove(getFullKeyInPath(key));
|
||||
} else {
|
||||
values.put(key, value);
|
||||
section.values.put(sectionKey, value);
|
||||
}
|
||||
}
|
||||
|
||||
public void move(final String key, final String toKey) {
|
||||
final Object o = getObject(key);
|
||||
if (o != null) {
|
||||
remove(key);
|
||||
set(toKey, o);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,6 +216,28 @@ public class ConfigSection {
|
||||
return list != null ? list : def;
|
||||
}
|
||||
|
||||
public boolean addMissingFields(final ConfigSection fromSection) {
|
||||
boolean changed = false;
|
||||
for (final Map.Entry<String, Object> entry : fromSection.values.entrySet()) {
|
||||
final String key = entry.getKey();
|
||||
final Object value = this.values.get(key);
|
||||
if (value != null) {
|
||||
// Go deeper for sections
|
||||
final Object newValue = entry.getValue();
|
||||
if (!(value instanceof Map) || !(newValue instanceof Map)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
changed |= this.getSection(key).addMissingFields(fromSection.getSection(key));
|
||||
} else {
|
||||
// Value is missing
|
||||
this.values.put(key, entry.getValue());
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return root config
|
||||
*/
|
||||
+7
-2
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -26,7 +26,7 @@ import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Further modified version of the SimpleConfig project of PSandro (https://github.com/PSandro/SimpleConfig).
|
||||
* Further modified version of the <a href="https://github.com/PSandro/SimpleConfig">SimpleConfig</a>SimpleConfig project of PSandro.
|
||||
*
|
||||
* @author PSandro on 26.01.19
|
||||
* @author kennytv
|
||||
@@ -146,6 +146,11 @@ public final class ConfigSerializer {
|
||||
multiLineValue = false;
|
||||
}
|
||||
|
||||
// YAML list items are values, not keys - skip without touching key/indent state
|
||||
if (line.length() > indent && line.charAt(indent) == '-') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if this is a level lower
|
||||
if (indents <= currentIndents) {
|
||||
final String[] array = key.split(PATH_SEPARATOR_QUOTED);
|
||||
+2
-1
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -25,6 +25,7 @@ import java.io.File;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@SuppressWarnings({"FieldCanBeLocal", "unused"})
|
||||
public final class MaintenanceDump {
|
||||
private final ServerDump general;
|
||||
private final Map<String, Object> configuration;
|
||||
+2
-1
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -19,6 +19,7 @@ package eu.kennytv.maintenance.core.dump;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings({"FieldCanBeLocal", "unused"})
|
||||
public final class PluginDump {
|
||||
private final String name;
|
||||
private final String version;
|
||||
+2
-1
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -19,6 +19,7 @@ package eu.kennytv.maintenance.core.dump;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings({"FieldCanBeLocal", "unused"})
|
||||
public final class ServerDump {
|
||||
private final String pluginVersion;
|
||||
private final String platform;
|
||||
+2
-3
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -18,7 +18,6 @@
|
||||
package eu.kennytv.maintenance.core.event;
|
||||
|
||||
import eu.kennytv.maintenance.api.event.manager.EventListener;
|
||||
import eu.kennytv.maintenance.api.event.manager.IEventManager;
|
||||
import eu.kennytv.maintenance.api.event.manager.MaintenanceEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -26,7 +25,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public final class EventManager implements IEventManager {
|
||||
public final class EventManager implements eu.kennytv.maintenance.api.event.manager.EventManager {
|
||||
private final Map<String, List<EventListener>> listeners = new HashMap<>();
|
||||
|
||||
@Override
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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 eu.kennytv.maintenance.core.hook;
|
||||
|
||||
import eu.kennytv.maintenance.api.Maintenance;
|
||||
import net.luckperms.api.LuckPermsProvider;
|
||||
import net.luckperms.api.context.ContextCalculator;
|
||||
import net.luckperms.api.context.ContextConsumer;
|
||||
import net.luckperms.api.context.ContextSet;
|
||||
import net.luckperms.api.context.ImmutableContextSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public final class LuckPermsHook {
|
||||
|
||||
public static <T> void register(final Maintenance maintenance) {
|
||||
LuckPermsProvider.get().getContextManager().registerCalculator(new MaintenanceCalculator<T>(maintenance));
|
||||
}
|
||||
|
||||
public static final class MaintenanceCalculator<T> implements ContextCalculator<T> {
|
||||
|
||||
public static final String MAINTENANCE_KEY = "is-maintenance";
|
||||
private final Maintenance maintenance;
|
||||
|
||||
private MaintenanceCalculator(final Maintenance maintenance) {
|
||||
this.maintenance = maintenance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void calculate(@NotNull final T target, @NotNull final ContextConsumer consumer) {
|
||||
consumer.accept(MAINTENANCE_KEY, Boolean.toString(maintenance.isMaintenance()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContextSet estimatePotentialContexts() {
|
||||
return ImmutableContextSet.builder().add(MAINTENANCE_KEY, "true").add(MAINTENANCE_KEY, "false").build();
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
+19
-4
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -21,6 +21,12 @@ import eu.kennytv.maintenance.core.MaintenancePlugin;
|
||||
import eu.kennytv.maintenance.core.Settings;
|
||||
import eu.kennytv.maintenance.core.util.SenderInfo;
|
||||
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.TextComponent;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.event.ClickEvent;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.event.HoverEvent;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.format.NamedTextColor;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.format.TextDecoration;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
@@ -60,11 +66,20 @@ public abstract class JoinListenerBase {
|
||||
if (!settings.hasUpdateChecks()) return;
|
||||
if (!sender.hasPermission("maintenance.admin") || notifiedPlayers.contains(sender.getUuid())) return;
|
||||
plugin.async(() -> {
|
||||
if (!plugin.updateAvailable()) return;
|
||||
if (!plugin.updateAvailable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
notifiedPlayers.add(sender.getUuid());
|
||||
sender.sendMessage(plugin.getPrefix() + "§cThere is a newer version available: §aVersion " + plugin.getNewestVersion() + "§c, you're on §a" + plugin.getVersion());
|
||||
plugin.sendUpdateNotification(sender);
|
||||
sender.sendPrefixedRich("<red>There is a newer version available: <green>Version " + plugin.getNewestVersion() + "<red>, you're on <green>" + plugin.getVersion());
|
||||
|
||||
final TextComponent text = Component.text().content("Download it at: ").color(NamedTextColor.RED)
|
||||
.append(Component.text().content(MaintenancePlugin.HANGAR_URL).color(NamedTextColor.GOLD))
|
||||
.append(Component.text().content(" (CLICK ME)").color(NamedTextColor.GRAY).decorate(TextDecoration.BOLD))
|
||||
.clickEvent(ClickEvent.clickEvent(ClickEvent.Action.OPEN_URL, MaintenancePlugin.HANGAR_URL))
|
||||
.hoverEvent(HoverEvent.showText(Component.text("Download the latest version").color(NamedTextColor.GREEN)))
|
||||
.build();
|
||||
sender.send(plugin.prefix().append(text));
|
||||
});
|
||||
}
|
||||
|
||||
+6
-5
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -19,6 +19,7 @@ package eu.kennytv.maintenance.core.runnable;
|
||||
|
||||
import eu.kennytv.maintenance.core.MaintenancePlugin;
|
||||
import eu.kennytv.maintenance.core.Settings;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
|
||||
|
||||
public class MaintenanceRunnable extends MaintenanceRunnableBase {
|
||||
|
||||
@@ -32,12 +33,12 @@ public class MaintenanceRunnable extends MaintenanceRunnableBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getStartMessage() {
|
||||
return settings.getMessage("starttimerBroadcast").replace("%TIME%", getTime());
|
||||
protected Component getStartMessage() {
|
||||
return settings.getMessage("starttimerBroadcast", "%TIME%", getTime());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getEndMessage() {
|
||||
return settings.getMessage("endtimerBroadcast").replace("%TIME%", getTime());
|
||||
protected Component getEndMessage() {
|
||||
return settings.getMessage("endtimerBroadcast", "%TIME%", getTime());
|
||||
}
|
||||
}
|
||||
+6
-5
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -20,12 +20,13 @@ package eu.kennytv.maintenance.core.runnable;
|
||||
import eu.kennytv.maintenance.core.MaintenancePlugin;
|
||||
import eu.kennytv.maintenance.core.Settings;
|
||||
import eu.kennytv.maintenance.core.util.Task;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
|
||||
|
||||
public abstract class MaintenanceRunnableBase implements Runnable {
|
||||
protected final MaintenancePlugin plugin;
|
||||
protected final Settings settings;
|
||||
protected final boolean enable;
|
||||
private final Task task;
|
||||
protected boolean enable;
|
||||
protected int seconds;
|
||||
|
||||
protected MaintenanceRunnableBase(final MaintenancePlugin plugin, final Settings settings, final int seconds, final boolean enable) {
|
||||
@@ -63,13 +64,13 @@ public abstract class MaintenanceRunnableBase implements Runnable {
|
||||
return task;
|
||||
}
|
||||
|
||||
protected void broadcast(final String message) {
|
||||
protected void broadcast(final Component message) {
|
||||
plugin.broadcast(message);
|
||||
}
|
||||
|
||||
protected abstract void finish();
|
||||
|
||||
protected abstract String getStartMessage();
|
||||
protected abstract Component getStartMessage();
|
||||
|
||||
protected abstract String getEndMessage();
|
||||
protected abstract Component getEndMessage();
|
||||
}
|
||||
+8
-7
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -19,8 +19,8 @@ package eu.kennytv.maintenance.core.runnable;
|
||||
|
||||
import eu.kennytv.maintenance.core.MaintenancePlugin;
|
||||
import eu.kennytv.maintenance.core.Settings;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
|
||||
import java.time.Duration;
|
||||
|
||||
public final class MaintenanceScheduleRunnable extends MaintenanceRunnable {
|
||||
private final int maintenanceDuration;
|
||||
@@ -35,12 +35,13 @@ public final class MaintenanceScheduleRunnable extends MaintenanceRunnable {
|
||||
super.finish();
|
||||
|
||||
// Start the timer to disable maintenance again
|
||||
plugin.startMaintenanceRunnable(maintenanceDuration, TimeUnit.SECONDS, false);
|
||||
plugin.startMaintenanceRunnable(Duration.ofSeconds(maintenanceDuration), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getStartMessage() {
|
||||
return settings.getMessage("scheduletimerBroadcast")
|
||||
.replace("%TIME%", getTime()).replace("%DURATION%", plugin.getFormattedTime(maintenanceDuration));
|
||||
protected Component getStartMessage() {
|
||||
return settings.getMessage("scheduletimerBroadcast",
|
||||
"%TIME%", getTime(),
|
||||
"%DURATION%", plugin.getFormattedTime(maintenanceDuration));
|
||||
}
|
||||
}
|
||||
+4
-2
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -17,6 +17,8 @@
|
||||
*/
|
||||
package eu.kennytv.maintenance.core.util;
|
||||
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public final class DummySenderInfo implements SenderInfo {
|
||||
@@ -44,7 +46,7 @@ public final class DummySenderInfo implements SenderInfo {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(final String message) {
|
||||
public void send(final Component component) {
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +1,9 @@
|
||||
package eu.kennytv.maintenance.core.util;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Exception thrown when an API rate limit is reached.
|
||||
*/
|
||||
public class RateLimitedException extends IOException {
|
||||
}
|
||||
+15
-2
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
@@ -17,6 +17,10 @@
|
||||
*/
|
||||
package eu.kennytv.maintenance.core.util;
|
||||
|
||||
import eu.kennytv.maintenance.api.MaintenanceProvider;
|
||||
import eu.kennytv.maintenance.core.MaintenancePlugin;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.Component;
|
||||
import eu.kennytv.maintenance.lib.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface SenderInfo {
|
||||
@@ -31,7 +35,16 @@ public interface SenderInfo {
|
||||
return permission == null || hasPermission("maintenance.admin") || hasPermission("maintenance." + permission);
|
||||
}
|
||||
|
||||
void sendMessage(String message);
|
||||
void send(Component component);
|
||||
|
||||
default void sendRich(final String message) {
|
||||
send(MiniMessage.miniMessage().deserialize(message));
|
||||
}
|
||||
|
||||
default void sendPrefixedRich(final String message) {
|
||||
final MaintenancePlugin maintenance = (MaintenancePlugin) MaintenanceProvider.get();
|
||||
send(maintenance.prefix().append(MiniMessage.miniMessage().deserialize(message)));
|
||||
}
|
||||
|
||||
boolean isPlayer();
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of Maintenance - https://github.com/kennytv/Maintenance
|
||||
* Copyright (C) 2018-2021 kennytv (https://github.com/kennytv)
|
||||
* Copyright (C) 2018-2024 kennytv (https://github.com/kennytv)
|
||||
*
|
||||
* 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
|
||||
File renamed without changes.
+76
-57
@@ -1,77 +1,107 @@
|
||||
#######################################################################################################################
|
||||
# __ __ _ _ _ _ __ _______ __ #
|
||||
# | \/ | __ _(_)_ __ | |_ ___ _ __ __ _ _ __ ___ ___ | |__ _ _ | |/ /___ _ __ _ __ _ |_ _\ \ / / #
|
||||
# | |\/| |/ _` | | '_ \| __/ _ \ '_ \ / _` | '_ \ / __/ _ \ | '_ \| | | | | ' // _ \ '_ \| '_ \| | | || | \ \ / / #
|
||||
# | | | | (_| | | | | | || __/ | | | (_| | | | | (_| __/ | |_) | |_| | | . \ __/ | | | | | | |_| || | \ V / #
|
||||
# |_| |_|\__,_|_|_| |_|\__\___|_| |_|\__,_|_| |_|\___\___| |_.__/ \__, | |_|\_\___|_| |_|_| |_|\__, ||_| \_/ #
|
||||
# |___/ |___/ #
|
||||
#######################################################################################################################
|
||||
###################################################################################################################
|
||||
# __ __ _ _ _ _ _ #
|
||||
# | \/ | __ _(_)_ __ | |_ ___ _ __ __ _ _ __ ___ ___ | |__ _ _ | | _____ _ __ _ __ _ _| |___ __ #
|
||||
# | |\/| |/ _` | | '_ \| __/ _ \ '_ \ / _` | '_ \ / __/ _ \ | '_ \| | | | | |/ / _ \ '_ \| '_ \| | | | __\ \ / / #
|
||||
# | | | | (_| | | | | | || __/ | | | (_| | | | | (_| __/ | |_) | |_| | | < __/ | | | | | | |_| | |_ \ V / #
|
||||
# |_| |_|\__,_|_|_| |_|\__\___|_| |_|\__,_|_| |_|\___\___| |_.__/ \__, | |_|\_\___|_| |_|_| |_|\__, |\__| \_/ #
|
||||
# |___/ |___/ #
|
||||
###################################################################################################################
|
||||
# You can report bugs here: https://github.com/kennytv/Maintenance/issues
|
||||
# If you need any other help/support, you can also join my Discord server: https://discord.gg/vGCUzHq
|
||||
# The config and language files use MiniMessage, NOT legacy text for input. Use https://webui.adventure.kyori.net/ to edit and preview the formatted text.
|
||||
# For a full list of formats and fancy examples of MiniMessage, see https://docs.adventure.kyori.net/minimessage/format.html
|
||||
|
||||
# Changes the language of command feedback/messages.
|
||||
# If you find missing translations or want to contribute, see https://crowdin.com/project/maintenance
|
||||
# Currently available are: en (English), de (German), fr (French), pt (Portuguese), es (Spanish), ru (Russian), zh (Chinese), it (Italian),
|
||||
# pl (Polish), tr (Turkish), sv (Swedish), uk (Ukrainian), ja (Japanese), da (Danish), ko (Korean), hu (Hungarian), vi (Vietnamese)
|
||||
language: en
|
||||
|
||||
# Enables maintenance mode.
|
||||
maintenance-enabled: false
|
||||
maintenance-enabled: true
|
||||
|
||||
# Enables maintenance on certain servers managed by your Bungee instance(s).
|
||||
# Enables maintenance on certain servers managed by your proxy instance(s).
|
||||
proxied-maintenance-servers:
|
||||
- SpigotServer1
|
||||
# - AnotherServer
|
||||
# - AServer
|
||||
|
||||
# If maintenance is enabled on a proxied server with players on it, they will be sent to the fallback server instead of being kicked off the network.
|
||||
# If the fallback server is not reachable/not set, they will just be kicked off the network.
|
||||
# This can also be set to an array to set multiple fallback servers, in case one server is not always reachable: 'fallback: [s1, s2, s3, ...]'
|
||||
fallback: lobby
|
||||
fallback: unreachable
|
||||
|
||||
# If maintenance is enabled globally, you can define a "waiting" lobby for players to be sent to instead of being kicked.
|
||||
# Leave this empty to disable.
|
||||
waiting-server: ""
|
||||
|
||||
# The message shown in the multiplayer server list motd when maintenance is enabled.
|
||||
# The message (MOTD) shown in the multiplayer server list motd when maintenance is enabled.
|
||||
# If you put in multiple entries, one of them will be chosen randomly on every ping.
|
||||
# If running an endtimer, the time left can be displayed by including '%TIMER%' in a pingmessage (also works in playercount(-hover) message).
|
||||
pingmessages:
|
||||
- "&cMaintenance mode!%NEWLINE%&6We will be back soon!"
|
||||
# - "Other entry"
|
||||
enable-pingmessages: true
|
||||
# If running an endtimer, the time left can be displayed by including '%TIMER%' in a ping message.
|
||||
ping-message:
|
||||
enabled: true
|
||||
messages:
|
||||
- "<bold><green>True<red>OG</bold> <yellow>Network</yellow> <aqua>》<red> Updating... </red><aqua>《 <gold>[1.8.0-1.21.11]<br><yellow>⚠ <dark_red>Maintenance in progress! <yellow>We'll be back <dark_aqua>soon™"
|
||||
# If set to true and an endtimer is currently running, a message from this pool will be chosen
|
||||
# instead of the ones above, so you can have different messages for when an endtimer is running/not running.
|
||||
enable-timer-specific-messages: true
|
||||
timer-messages:
|
||||
- "<bold><green>True<red>OG</bold> <yellow>Network</yellow> <aqua>》<red>Maintenance Mode</red><aqua>《 <gold>[1.8.0-1.21.11]<br><dark_red>Maintenance ends in <yellow>%TIMER% <gray>| <green>Thanks for waiting!"
|
||||
|
||||
# Any extra commands inside of the arrays will be executed when maintenance is enabled/disabled.
|
||||
# If enabled, the message below will be shown in the top right corner of the server in the server list, where the player count would normally be displayed.
|
||||
# You can use '%ONLINE%' and '%MAX%' if you want to include the player count in a custom message (e.g. "Maintenance %ONLINE%/%MAX%").
|
||||
# DOES NOT SUPPORT RGB!
|
||||
player-count-message:
|
||||
enabled: true
|
||||
message: "<dark_red>Maintenance"
|
||||
# If set to true and an endtimer is currently running, the timer message will be used instead of the normal one.
|
||||
enable-timer-specific-message: true
|
||||
timer-message: "<dark_red>Come back in: <yellow>%TIMER%"
|
||||
|
||||
# Is shown when you move your mouse above the text in the top right corner of the server in the server list, where the player count would normally be displayed.
|
||||
# DOES NOT SUPPORT RGB!
|
||||
player-list-hover-message:
|
||||
enabled: true
|
||||
message: "<red>Currently under<br><red>maintenance"
|
||||
# If set to true and an endtimer is currently running, the timer message will be used instead of the normal one.
|
||||
enable-timer-specific-message: true
|
||||
timer-message: "<red>Come back in:<br><red><yellow>%TIMER%"
|
||||
|
||||
# Any extra commands inside the arrays will be executed when maintenance is enabled/disabled.
|
||||
# Example: commands-on-maintenance-enable: ["say hello!", "stop"]
|
||||
commands-on-maintenance-enable: []
|
||||
commands-on-maintenance-disable: []
|
||||
|
||||
# If set to true and an endtimer is currently running, a pingmessage from this pool will be chosen
|
||||
# instead of the ones above, so you can have different messages for when an endtimer is running/not running.
|
||||
enable-timerspecific-messages: false
|
||||
timerspecific-pingmessages:
|
||||
- "&cMaintenance mode!%NEWLINE%&6We will be back in %TIMER%!"
|
||||
# - "Other entry"
|
||||
|
||||
# If set to true, the message below will be shown at the top right corner of the server in the serverlist, where the playercount would normally be displayed.
|
||||
# If set to false, the normal playercount will be shown.
|
||||
#
|
||||
# Alternatively you can use '%ONLINE%' and '%MAX%' if you want to include the playercount in a custom message (e.g. "&cMaintenance &7%ONLINE%&8/&7%MAX%").
|
||||
enable-playercountmessage: true
|
||||
playercountmessage: "&4Maintenance"
|
||||
|
||||
# Is shown when you move your mouse above the text at the top right corner of the server in the serverlist,
|
||||
# where the playercount would normally be displayed.
|
||||
playercounthovermessage: "&cCurrently under%NEWLINE%&cmaintenance"
|
||||
# Any extra commands inside the "all" array will be executed when maintenance is enabled/disabled on a proxied server.
|
||||
# You can also add commands for specific servers by adding a new array with the server name as key.
|
||||
# In the commands, you can use the %SERVER% placeholder to get the server name.
|
||||
# Example: coolserver: ["say hello", "othercommand %SERVER%"]
|
||||
commands-on-single-maintenance-enable:
|
||||
all: []
|
||||
commands-on-single-maintenance-disable:
|
||||
all: []
|
||||
|
||||
# If set to true, the server icon will be changed to the 'maintenance-icon.png' file in the plugin's folder during maintenance.
|
||||
custom-maintenance-icon: false
|
||||
|
||||
# If set to true, players with the 'maintenance.joinnotification' permission will receive a message,
|
||||
# that a player tried to join the server while maintenance is enabled.
|
||||
send-join-notification: false
|
||||
send-join-notification: true
|
||||
|
||||
# Set this to false if you do not want players to be kicked when you enable maintenance (new connections will still be blocked).
|
||||
# ... I don't know why you would want that, but you can disable it. :p
|
||||
kick-online-players: true
|
||||
|
||||
# Changes the language of command feedback/messages.
|
||||
# If you find missing translations or want to contribute a new language file, you are very welcome to message me on Spigot or my Discord server! :)
|
||||
# Currently available are: en (English), de (German), fr (French), pt (Portuguese), es (Spanish), ru (Russian), zh (Chinese), it (Italian)
|
||||
language: en
|
||||
# When fetched player does not exist then fallback to offline uuid. Only works on proxies like Velocity or BungeeCord
|
||||
fallback-to-offline-uuid: false
|
||||
|
||||
# If enabled and the server is restarted while running an endtimer, the timer will be continued after the restart.
|
||||
# If the timer ends while the server is offline, maintenance will be disabled as soon as the server starts again.
|
||||
continue-endtimer-after-restart:
|
||||
enabled: false
|
||||
# This value is set everytime an endtimer is started, cancelled or ended.
|
||||
# Do not manually change this value.
|
||||
end: 0
|
||||
|
||||
# If using the timer command: In what intervalls before enabling/disabling maintenance there will be a broadcast.
|
||||
timer-broadcast-for-seconds: [1200, 900, 600, 300, 120, 60, 30, 20, 10, 5, 4, 3, 2, 1]
|
||||
|
||||
# If you have 2 or more proxy instances, the database connection will make sure all proxies
|
||||
# have the same maintenance status, so you won't have to enable/disable it on every proxy by hand.
|
||||
@@ -91,21 +121,10 @@ mysql:
|
||||
# If you for some reason cannot establish SSL connections to your database, you may disable it here (not recommended).
|
||||
use-ssl: true
|
||||
|
||||
# If enabled and the server is restarted while running an endtimer, the timer will be continued after the restart.
|
||||
# If the timer ends while the server is offline, maintenance will be disabled as soon as the server starts again.
|
||||
continue-endtimer-after-restart:
|
||||
enabled: false
|
||||
# This value is set everytime an endtimer is started, cancelled or ended.
|
||||
# Do not manually change this value.
|
||||
end: 0
|
||||
|
||||
# If using the timer command: In what intervalls before enabling/disabling maintenance there will be a broadcast.
|
||||
timer-broadcast-for-seconds: [1200, 900, 600, 300, 120, 60, 30, 20, 10, 5, 4, 3, 2, 1]
|
||||
|
||||
# If disabled, you will no longer receive any messages if there is an update.
|
||||
# Not recommended to disable, as new versions generally tend to run better and with less bugs.
|
||||
# Not recommended to disable, as new versions generally tend to run better and with fewer bugs.
|
||||
# However, you can always check for updates manually using the '/maintenance update' command.
|
||||
update-checks: true
|
||||
update-checks: false
|
||||
|
||||
# Used for autoupdating the config, do not change this value.
|
||||
config-version: 5
|
||||
config-version: 9
|
||||
@@ -0,0 +1,104 @@
|
||||
#Maintenance Plugin by kennytv
|
||||
#You can use https://webui.adventure.kyori.net/ to edit and preview the formatted text
|
||||
#For a full list of formats and fancy examples, see https://docs.adventure.kyori.net/minimessage/format.html
|
||||
#Messages containing the placeholder "<prefix>" will have it replaced with the following string
|
||||
prefix: "<dark_gray>[<yellow>Maintenance<dark_gray>] "
|
||||
noPermission: "<red>Du har ikke tilladelse til at udføre denne kommando."
|
||||
kickmessage: "<red>Serveren er i øjeblikket under vedligeholdelse!<br>Prøv igen senere!"
|
||||
maintenanceActivated: "<prefix><gold>Vedligeholdelsestilstand er nu aktiveret."
|
||||
maintenanceDeactivated: "<prefix><gold>Vedligeholdelsestilstand er nu deaktiveret."
|
||||
alreadyEnabled: "<prefix><red>Vedligeholdelsestilstand er allerede aktiveret!"
|
||||
alreadyDisabled: "<prefix><red>Vedligeholdelsestilstand er allerede deaktiveret!"
|
||||
endtimerBroadcast: "<prefix><gray>Vedligeholdelsestilstand vil blive deaktiveret om <gold>%TIME%<gray>."
|
||||
endtimerStarted: "<prefix><green>Startet timer: <gray>Vedligeholdelsestilstand vil blive deaktiveret om <gold>%TIME%<gray>."
|
||||
starttimerBroadcast: "<prefix><gray>Vedligeholdelsestilstand vil blive aktiveret om <gold>%TIME%<gray>."
|
||||
starttimerStarted: "<prefix><green>Startet timer: <gray>Vedligeholdelsestilstand vil blive aktiveret om <gold>%TIME%<gray>."
|
||||
scheduletimerBroadcast: "<prefix><gray>Vedligeholdelsestilstand vil blive aktiveret om <gold>%TIME% <gray>og vil vare i <gold>%DURATION%<gray>."
|
||||
scheduletimerStarted: "<prefix><green>Startet timer: <gray>Vedligeholdelsestilstand vil blive aktiveret om <gold>%TIME% <gray>og vil vare i <gold>%DURATION%<gray>."
|
||||
timerAlreadyRunning: "<prefix><red>Der er allerede planlagt en timer!"
|
||||
timerNotRunning: "<prefix><red>Der er i øjeblikket ingen timer."
|
||||
timerCancelled: "<prefix><red>Den aktuelle timer er blevet deaktiveret."
|
||||
timerTooLong: "<prefix><red>Tallet skal være mindre end 40320 (28 days)!"
|
||||
timerMotdDisabled: "<prefix><red>Du skal angive 'enable-timerspecific-messages' i konfigurationsfilen til 'true', hvis du vil bruge/redigere tidsbestemte motds."
|
||||
motdTimer: "%HOURS%:%MINUTES%:%SECONDS%"
|
||||
motdTimerNotRunning: "-"
|
||||
joinNotification: "<prefix><yellow>%PLAYER% <red>prøvede at forbinde til serveren."
|
||||
motdList: "<prefix><gray>Liste over dine vedligeholdelses motds:"
|
||||
motdListEmpty: "<prefix><red>Du har ikke oprettet nogen vedligeholdelses motds!"
|
||||
reload: "<prefix><green>Genindlæs konfigurationsfilen, hvidlistede spillere, sprogfilen og vedligeholdelsesikonet."
|
||||
removedMotd: "<prefix><green>Slet motd nummer %INDEX%."
|
||||
removeMotdError: "<prefix><red>Du har kun én motd, så du kan ikke slette nogen!"
|
||||
setMotd: "<prefix><green>Angiv linje %LINE% af %INDEX%. vedligeholdelses motd til %MOTD%"
|
||||
setMotdIndexError: "<prefix><red>Du har %MOTDS% motds, så du skal angive et nummer mellem 1 og %NEWAMOUNT%."
|
||||
setMotdLineError: "<prefix><red>Det andet argument skal være linjenummer (1 or 2)!"
|
||||
updateDownloading: "<prefix><red><bold>Downloader opdatering..."
|
||||
updateFailed: "<prefix><dark_red><bold>Opdatering fejlede!"
|
||||
updateFinished: "<prefix><green><bold>Opdateringen lykkedes! For at forhindre problemer og for at fuldføre opdateringen skal du genstarte serveren!"
|
||||
whitelistedPlayers: "<prefix><gold>Hvidlistede spillere til vedligeholdelse:"
|
||||
whitelistedPlayersFormat: "<dark_gray>- <yellow>%NAME% <dark_gray>(<gray>%UUID%<dark_gray>)"
|
||||
whitelistAdded: "<prefix><green>Tilføj <aqua>%PLAYER% <green>til vedligeholdelseshvidlisten!"
|
||||
whitelistAlreadyAdded: "<prefix><aqua>%PLAYER% <red>findes allerede i vedligeholdelseshvidlisten!"
|
||||
whitelistRemoved: "<prefix><green>Fjern <aqua>%PLAYER% <green>fra vedligeholdelseshvidlisten!"
|
||||
whitelistNotFound: "<prefix><red>Denne spiller er ikke på vedligeholdelseshvidlisten!"
|
||||
whitelistEmpty: "<prefix><red>Vedligeholdelseshvidlisten er tom! Brug <yellow>/maintenance add <player/uuid> <red>til at tilføje spillere!"
|
||||
playerNotFound: "<prefix><red>Ingen spillere med dette navn har spillet på denne server før."
|
||||
playerNotFoundUuid: "<prefix><red>Ingen spiller med den uuid kunne findes."
|
||||
playerNotOnline: "<prefix><red>Der er ingen spiller online med det navn."
|
||||
offlinePlayerFetchError: "<prefix><red>There was an error while fetching offline player. Please try again later."
|
||||
invalidUuid: "<prefix><red>Ugyldigt uuid-format!"
|
||||
#Messages for the Bungee/Velocity part, you can ignore them if you use the plugin on Paper/Sponge
|
||||
sentToWaitingServer: "<prefix><red>Du er blevet sendt til en venteserver!"
|
||||
forceWaitingServer: "<prefix><red>Du kan ikke forlade venteserveren, mens vedligeholdelsetilstand er aktiveret!"
|
||||
serverNotFound: "<prefix><red>Ingen server med dette navn er registreret på proxyen!"
|
||||
singleTimerAlreadyRunning: "<prefix><red>Der er allerede planlagt en timer for den server!"
|
||||
singleTimerCancelled: "<prefix><red>Den aktuelle timer for serveren <yellow>%SERVER% <red>er deaktiveret."
|
||||
singleTimerNotRunning: "<prefix><red>Der er i øjeblikket ingen kørende timer for den server."
|
||||
singleEndtimerBroadcast: "<prefix><gray>Vedligeholdelsestilstand på server %SERVER% vil blive deaktiveret om <gold>%TIME%<gray>."
|
||||
singleEndtimerStarted: "<prefix><green>Startet timer: <gray>Vedligeholdelsestilstand på server %SERVER% vil blive deaktiveret om <gold>%TIME%<gray>."
|
||||
singleStarttimerBroadcast: "<prefix><gray>Vedligeholdelsestilstand på server %SERVER% vil blive aktiveret om <gold>%TIME%<gray>."
|
||||
singleStarttimerStarted: "<prefix><green>Startet timer: <gray>Vedligeholdelsestilstand på server %SERVER% vil blive aktiveret om <gold>%TIME%<gray>."
|
||||
singleScheduletimerBroadcast: "<prefix><gray>Vedligeholdelsestilstand på server %SERVER% vil blive aktiveret om <gold>%TIME% <gray>og vil vare i <gold>%DURATION%<gray>."
|
||||
singleScheduletimerStarted: "<prefix><green>Startet timer: <gray>Vedligeholdelsestilstand på server %SERVER% vil blive aktiveret om <gold>%TIME% <gray>og vil vare i <gold>%DURATION%<gray>."
|
||||
singleMaintenanceKick: "<prefix><red>Serveren %SERVER% er i øjeblikket under vedligeholdelse! Prøv igen senere!"
|
||||
singleMaintenanceKickComplete: "<red>Serveren %SERVER% er under vedligeholdelse!<br>Du kan prøve at forbinde igen for at gå ind på en anden server!"
|
||||
singleMaintenanceActivated: "<prefix><gold>Vedligeholdelsestilstand er nu aktiveret på serveren <yellow>%SERVER%<gold>."
|
||||
singleMaintenanceDeactivated: "<prefix><gold>Vedligeholdelsestilstand er nu deaktiveret på serveren <yellow>%SERVER%<gold>."
|
||||
singleServerAlreadyEnabled: "<prefix><red>Vedligeholdelsestilstand er allerede aktiveret på serveren <yellow>%SERVER%<red>!"
|
||||
singleServerAlreadyDisabled: "<prefix><red>Vedligeholdelsestilstand er allerede deaktiveret på serveren <yellow>%SERVER%<red>!"
|
||||
singleServerMaintenanceList: "<prefix><gray>Proxyservere, der har Vedligeholdelsestilstand aktiveret:"
|
||||
singleServerMaintenanceListEmpty: "<prefix><gray>Der er ingen proxy-servere, der er under vedligeholdelse."
|
||||
singleServerMaintenanceListEntry: "<dark_grey>- <aqua>%SERVER%"
|
||||
second: "sekund"
|
||||
seconds: "sekunder"
|
||||
minute: "minut"
|
||||
minutes: "minutter"
|
||||
hour: "time"
|
||||
hours: "timer"
|
||||
helpHeader: "<dark_gray>========[ <yellow>%NAME% <dark_gray>| <yellow>%PAGE%/%MAX% <dark_gray>]========"
|
||||
helpPageNotFound: "<prefix><red>Der er ingen side med det nummer!"
|
||||
helpNextPage: "<gray>Brug <aqua>/maintenance help %PAGE% <gray>for at komme til næste hjælpevindue."
|
||||
helpAbortTimer: "<gold>/maintenance aborttimer <gray>(Hvis timeren kører, vil den blive afbrudt)"
|
||||
helpEndtimer: "<gold>/maintenance endtimer <disable in> <gray>(After the given time, e.g. 1h5m, maintenance mode will be disabled)"
|
||||
helpStarttimer: "<gold>/maintenance starttimer <enable in> <gray>(After the given time, e.g. 1h5m, maintenance mode will be enabled)"
|
||||
helpScheduleTimer: "<gold>/maintenance scheduletimer <enable in> <maintenance duration> <gray>(After the given time, e.g. 1h5m, maintenance mode will be enabled)"
|
||||
helpDebug: "<gold>/maintenance debug <gray>(Aktiverer noget fejlretningslogning)"
|
||||
helpDump: "<gold>/maintenance dump <gray>(Dumper nogle serveroplysninger, brugt til fejlrapporter)"
|
||||
helpHelp: "<gold>/maintenance help [page] <gray>(Viser dette smukke hjælpevindue)"
|
||||
helpMotd: "<gold>/maintenance motd [timer] <gray>(Viser den aktuelle vedligeholdelses motds. Hvis 'timer' er angivet, bliver dennes motds vist)"
|
||||
helpRemoveMotd: "<gold>/maintenance removemotd [timer] <index> <gray>(Sletter en vedligeholdelses motd. Hvis 'timer' er angivet, vil en tidsspecifik pingbesked blive slettet)"
|
||||
helpSetMotd: "<gold>/maintenance setmotd [timer] <index> <1/2> <message> <gray>(Angiver en motd for vedligeholdelsestilstand. Hvis 'timer' er angivet, vil en tidsspecifik pingbesked blive angivet)"
|
||||
helpReload: "<gold>/maintenance reload <gray>(Genindlæser konfigurationsfilen, hvidlisten og serverikonet)"
|
||||
helpToggle: "<gold>/maintenance <on/off> <gray>(Aktiverer/deaktiverer vedligeholdelsestilstand)"
|
||||
helpUpdate: "<gold>/maintenance update <gray>(Downloader den nyeste version af plugin'et på din server)"
|
||||
helpWhitelist: "<gold>/maintenance whitelist <gray>(Viser alle hvidlistede spillere for vedligeholdelsestilstand)"
|
||||
helpWhitelistAdd: "<gold>/maintenance add <name/uuid> <gray>(Tilføjer spilleren til vedligeholdelseshvidlisten, så de kan forbinde til serveren, selvom vedligeholdelsestilstand er aktiveret)"
|
||||
helpWhitelistRemove: "<gold>/maintenance remove <name/uuid> <gray>(Sletter spilleren fra vedligeholdelseshvidlisten)"
|
||||
#Messages for the Bungee/Velocity part, you can ignore them if you use the plugin on Paper/Sponge
|
||||
helpAbortSingleTimer: "<gold>/maintenance aborttimer [server] <gray>(Hvis timeren kører, vil den blive afbrudt)"
|
||||
helpSingleEndtimer: "<gold>/maintenance endtimer [server] <disable in> <gray>(After the given time, e.g. 1h5m, maintenance mode will be disabled)"
|
||||
helpSingleStarttimer: "<gold>/maintenance starttimer [server] <enable in> <gray>(After the given time, e.g. 1h5m, maintenance mode will be enabled)"
|
||||
helpSingleScheduleTimer: "<gold>/maintenance scheduletimer [server] <enable in> <maintenance duration> <gray>(After the given time, e.g. 1h5m, maintenance mode will be enabled)"
|
||||
helpSingleToggle: "<gold>/maintenance <on/off> [server] <gray>(Aktiverer/deaktiverer vedligeholdelsestilstand)"
|
||||
helpStatus: "<gold>/maintenance status <gray>(Viser alle proxyservere, der har Vedligeholdelsestilstand aktiveret)"
|
||||
#Used for autoupdating the language file, do not change this value.
|
||||
language-version: 2
|
||||
Loaded 100 of 202 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user