Compare commits
940 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
09d3c06698 | ||
|
|
5048328e82 | ||
|
|
2e75ec023f | ||
|
|
f43274c03e | ||
|
|
86c98df5d2 | ||
|
|
d62b6af129 | ||
|
|
4ee2840a0a | ||
|
|
c52d117f12 | ||
|
|
e307aba414 | ||
|
|
5ea5a18fe8 | ||
|
|
9c1db4b48a | ||
|
|
b233c92ca1 | ||
|
|
1b1d2e61b9 | ||
|
|
2dc5b93133 | ||
|
|
880ddc22b5 | ||
|
|
d378f782b4 | ||
|
|
1f2d969a69 | ||
|
|
cac79a26af | ||
|
|
8b078f9058 | ||
|
|
d3a5d01f55 | ||
|
|
9a677d46a1 | ||
|
|
8116cbb385 | ||
|
|
b9affd0879 | ||
|
|
ec8657015c | ||
|
|
38a86e6d2d | ||
|
|
35376e43ca | ||
|
|
1c233ec297 | ||
|
|
967dec09ff | ||
|
|
85aa6ae8ae | ||
|
|
83aad38b09 | ||
|
|
b0fb784079 | ||
|
|
84948101f4 | ||
|
|
5dea70532c | ||
|
|
403adeb217 | ||
|
|
a81ed63c0f | ||
|
|
38da700168 | ||
|
|
4a085682dc | ||
|
|
cfed3ce31b | ||
|
|
4c62318338 | ||
|
|
7247cbb9f7 | ||
|
|
9ed7a7ae56 | ||
|
|
9a356ceecf | ||
|
|
e0ac7b1c66 | ||
|
|
82230d8156 | ||
|
|
cda55f20aa | ||
|
|
0df7a01fd8 | ||
|
|
b49668ddee | ||
|
|
f14b081f0b | ||
|
|
b51fbf4e13 | ||
|
|
e48b6fe702 | ||
|
|
984f944daf | ||
|
|
0575c8cf41 | ||
|
|
c181d18f5e | ||
|
|
2e0d9eb846 | ||
|
|
33d1009d6a | ||
|
|
b16d62fb75 | ||
|
|
e019d6370c | ||
|
|
581b73dbc7 | ||
|
|
25f7eafe32 | ||
|
|
ef22d564f3 | ||
|
|
787a053d98 | ||
|
|
f31dd2bea9 | ||
|
|
5c8086150a | ||
|
|
b838d1c52a | ||
|
|
0a712e6530 | ||
|
|
272e2e7904 | ||
|
|
98082398fc | ||
|
|
c66806ecf8 | ||
|
|
c97f5aa5a6 | ||
|
|
c1487898a9 | ||
|
|
907ced6d7d | ||
|
|
ac771207c3 | ||
|
|
8b031576aa | ||
|
|
2d1a0ee157 | ||
|
|
b9e2bf9429 | ||
|
|
a35923a117 | ||
|
|
d5e96bd6a6 | ||
|
|
2523b6c094 | ||
|
|
7b230fc679 | ||
|
|
68f467ab29 | ||
|
|
068b5a31b2 | ||
|
|
882b7c5965 | ||
|
|
7a0be5edf8 | ||
|
|
e94328935d | ||
|
|
604fed36a4 | ||
|
|
403622d205 | ||
|
|
1cd4d93f7f | ||
|
|
a83ef75bf9 | ||
|
|
b96e535aaa | ||
|
|
2e67272aea | ||
|
|
2c7767e77d | ||
|
|
c4a046ff24 | ||
|
|
57fa68c896 | ||
|
|
b64f024eb2 | ||
|
|
c7a4900aa3 | ||
|
|
491abd6238 | ||
|
|
d3646a9874 | ||
|
|
af0b475330 | ||
|
|
d35a499e31 | ||
|
|
c0f824450e | ||
|
|
5b1a8ef4ba | ||
|
|
5623a00f9b | ||
|
|
4926907b47 | ||
|
|
32f3d14682 | ||
|
|
152105017d | ||
|
|
be956f52b0 | ||
|
|
195158b18b | ||
|
|
36fa9ac96d | ||
|
|
42cfe1dc80 | ||
|
|
92a7d54664 | ||
|
|
f91b4e3752 | ||
|
|
a497e05e55 | ||
|
|
74d8fec6bd | ||
|
|
28287c7fbd | ||
|
|
744cf6d8c0 | ||
|
|
ecd4c002c8 | ||
|
|
b4e60b7db5 | ||
|
|
e862abe0b4 | ||
|
|
2d946646f0 | ||
|
|
5ab61e0cd3 | ||
|
|
81ef464dad | ||
|
|
0ae0ddc9cb | ||
|
|
3d00d48106 | ||
|
|
7e902cae66 | ||
|
|
f4e4433b16 | ||
|
|
d5c371004c | ||
|
|
e246473782 | ||
|
|
4afad7f7b0 | ||
|
|
a0b177bdd8 | ||
|
|
40b1fe8d68 | ||
|
|
9ee4afa1e9 | ||
|
|
1cf66b130c | ||
|
|
c3cfc82eb3 | ||
|
|
3afb634e58 | ||
|
|
d888d9754b | ||
|
|
4c228ca4fb | ||
|
|
6cf987586e | ||
|
|
46d9a69534 | ||
|
|
af8cc09fca | ||
|
|
452c8ccd42 | ||
|
|
054c780fd1 | ||
|
|
83261eee49 | ||
|
|
3fca78626a | ||
|
|
a2456c582d | ||
|
|
b987916328 | ||
|
|
23ef4ecb62 | ||
|
|
8b7a217796 | ||
|
|
74ebb0bec0 | ||
|
|
794c8890e5 | ||
|
|
013e566a85 | ||
|
|
5a4a8c2e7e | ||
|
|
0b068470ac | ||
|
|
f3cb7635c2 | ||
|
|
8e21a76118 | ||
|
|
1dad2381e5 | ||
|
|
9767811cb9 | ||
|
|
e6fb6d5ec6 | ||
|
|
1acc621f2e | ||
|
|
d9bab03e3b | ||
|
|
9baf5f58ae | ||
|
|
077d64dc68 | ||
|
|
b8d5886cad | ||
|
|
52119682f3 | ||
|
|
651e14a797 | ||
|
|
0ac62d6b63 | ||
|
|
0be6b721cf | ||
|
|
0e0e36476a | ||
|
|
a56b3b62b9 | ||
|
|
883f1c1edf | ||
|
|
bfc30a8703 | ||
|
|
37c39ab734 | ||
|
|
35c47a8745 | ||
|
|
fadf14a316 | ||
|
|
1388a5278f | ||
|
|
3bc6ad0f06 | ||
|
|
bb149811d4 | ||
|
|
350a2be0ed | ||
|
|
b73d72cec7 | ||
|
|
7afb8ee36d | ||
|
|
1241c33ba0 | ||
|
|
631609af74 | ||
|
|
fe8d865657 | ||
|
|
50d4e14333 | ||
|
|
666ab468a1 | ||
|
|
151fb08db8 | ||
|
|
cd9074203c | ||
|
|
38d77ff4ca | ||
|
|
3ccbbe9c20 | ||
|
|
358a3bcab3 | ||
|
|
ca088227c3 | ||
|
|
69fd180c9b | ||
|
|
38e6e02e1b | ||
|
|
a71b8657f1 | ||
|
|
850633e792 | ||
|
|
348b075ac5 | ||
|
|
ce18d3b597 | ||
|
|
9d66d9d9a1 | ||
|
|
5fe9389dda | ||
|
|
e25a28b2a5 | ||
|
|
cfd289939e | ||
|
|
d168be94b1 | ||
|
|
511717a8d6 | ||
|
|
18fb194ce6 | ||
|
|
e11d551071 | ||
|
|
020f14d82c | ||
|
|
acb5728e65 | ||
|
|
cc235cfc01 | ||
|
|
894dcd0a2f | ||
|
|
41c9231664 | ||
|
|
31deef2a62 | ||
|
|
3ba29f1147 | ||
|
|
e969f37405 | ||
|
|
b9a5f4445f | ||
|
|
6f87955898 | ||
|
|
d68af58df5 | ||
|
|
6e1eb88585 | ||
|
|
0798d94449 | ||
|
|
aa68a481ee | ||
|
|
6f5853746d | ||
|
|
416fbc0e3e | ||
|
|
407714c13f | ||
|
|
aa13ddf17e | ||
|
|
d9da5a706c | ||
|
|
80446de15b | ||
|
|
0647f88de5 | ||
|
|
38099198d6 | ||
|
|
6f2f1f1cf1 | ||
|
|
5e4d3f7135 | ||
|
|
327078d8dd | ||
|
|
1b7fabf238 | ||
|
|
66025a6a1c | ||
|
|
04f2c85722 | ||
|
|
7b5ceb520f | ||
|
|
f7dc184899 | ||
|
|
4300bf7d1e | ||
|
|
5412b484f8 | ||
|
|
af2f625224 | ||
|
|
d2a4f038d0 | ||
|
|
7e28dc0a41 | ||
|
|
b82948c87a | ||
|
|
39c68e8f87 | ||
|
|
5a24387f3d | ||
|
|
cd429bd7d7 | ||
|
|
a383a73b24 | ||
|
|
7baaa5233d | ||
|
|
b35035390e | ||
|
|
1b0a3bc09d | ||
|
|
3817f52158 | ||
|
|
663f149d74 | ||
|
|
3da8f00664 | ||
|
|
c24c75c8c0 | ||
|
|
c401adee86 | ||
|
|
1dd3e1fc0d | ||
|
|
1f53daf416 | ||
|
|
8105beeee0 | ||
|
|
8c9a20c035 | ||
|
|
c1d2effe7e | ||
|
|
2eda4b1335 | ||
|
|
ff72450d3f | ||
|
|
a654262196 | ||
|
|
fa705e4572 | ||
|
|
e687a06d6e | ||
|
|
08c43d25e7 | ||
|
|
48da25659d | ||
|
|
905c9e83ee | ||
|
|
54ddc9fd4d | ||
|
|
fe0bb12d53 | ||
|
|
e6da5f291e | ||
|
|
d674893312 | ||
|
|
9da9e8c20f | ||
|
|
33c309ee8e | ||
|
|
62c3261a00 | ||
|
|
c393392b85 | ||
|
|
fbf91d6393 | ||
|
|
8d30c4c99d | ||
|
|
721904335d | ||
|
|
d79f9725bd | ||
|
|
eb2decb93d | ||
|
|
d2192e3195 | ||
|
|
c01acfba77 | ||
|
|
a494add04c | ||
|
|
059047905f | ||
|
|
fa717c34ef | ||
|
|
e16287405b | ||
|
|
afdf80bf00 | ||
|
|
ec7943fe0a | ||
|
|
6493963d8a | ||
|
|
c48e11bd70 | ||
|
|
b4f6831e54 | ||
|
|
6348c88c6f | ||
|
|
5fb45d13da | ||
|
|
5710972288 | ||
|
|
63955511a8 | ||
|
|
9a7790c808 | ||
|
|
3abc78ff64 | ||
|
|
c4789b7db0 | ||
|
|
d7a4acc2f5 | ||
|
|
dd7751332f | ||
|
|
7b50453294 | ||
|
|
fa7c30df80 | ||
|
|
89053354e9 | ||
|
|
ead63ca763 | ||
|
|
0fa592383f | ||
|
|
7df3a5c6e0 | ||
|
|
c4a2256fff | ||
|
|
9b6b558002 | ||
|
|
94bf5fea57 | ||
|
|
252802dcbe | ||
|
|
8932a92049 | ||
|
|
679ef90091 | ||
|
|
ac9b0c42b7 | ||
|
|
14d885392c | ||
|
|
0c102a1823 | ||
|
|
4c968f012d | ||
|
|
ba71486151 | ||
|
|
e1269d6c86 | ||
|
|
438a665b74 | ||
|
|
247a5cde8f | ||
|
|
aa9ac65d02 | ||
|
|
ba983f7fb3 | ||
|
|
af268c4941 | ||
|
|
4c4b1602d9 | ||
|
|
8c69a164b8 | ||
|
|
df8583df57 | ||
|
|
09e68e7510 | ||
|
|
2c223ffc87 | ||
|
|
5571ba5d70 | ||
|
|
b77b1b9649 | ||
|
|
bf9b34eb57 | ||
|
|
215fd7e3f0 | ||
|
|
aca624c2d3 | ||
|
|
5826390251 | ||
|
|
a91a5c85ba | ||
|
|
156243a549 | ||
|
|
eceb236121 | ||
|
|
71b5433326 | ||
|
|
2c8314200f | ||
|
|
0b70ea61aa | ||
|
|
ac31e107ad | ||
|
|
b9230ef9c5 | ||
|
|
06e6765870 | ||
|
|
5ac579e878 | ||
|
|
a4d8009ce4 | ||
|
|
0df265881a | ||
|
|
5dbd58076a | ||
|
|
c3922de323 | ||
|
|
0f118f12bc | ||
|
|
edd3153acd | ||
|
|
748b9f33f7 | ||
|
|
230e36c55e | ||
|
|
0f7294972e | ||
|
|
d14f319eb4 | ||
|
|
0927760d76 | ||
|
|
91af12f575 | ||
|
|
5dbbe01b95 | ||
|
|
30b5abda19 | ||
|
|
a8e996fa26 | ||
|
|
3f83312454 | ||
|
|
0b1bd1c265 | ||
|
|
b747720f36 | ||
|
|
be34f28fd3 | ||
|
|
9843d84ac3 | ||
|
|
37de42f4a7 | ||
|
|
5595bc144f | ||
|
|
9b2e7bb3ca | ||
|
|
8b5ead7a13 | ||
|
|
0c6dd5466c | ||
|
|
41275509b2 | ||
|
|
4e8b1b47d1 | ||
|
|
d0e62e6434 | ||
|
|
2086fcb299 | ||
|
|
b3ea920b41 | ||
|
|
001fa6bcf2 | ||
|
|
3a31c5cb78 | ||
|
|
20b2a69b5e | ||
|
|
682717660f | ||
|
|
7b7bfb7306 | ||
|
|
09043c6aaf | ||
|
|
f711500d80 | ||
|
|
8d6aa7c801 | ||
|
|
04968cb437 | ||
|
|
048c539fff | ||
|
|
501d1bbbdd | ||
|
|
e4a6faa22a | ||
|
|
c3bdc90168 | ||
|
|
79ec3c8f95 | ||
|
|
e9e4caf989 | ||
|
|
0b1a3ced9e | ||
|
|
b55261a62f | ||
|
|
8c633c8943 | ||
|
|
8757217fb6 | ||
|
|
8f796e3940 | ||
|
|
bf1527a40f | ||
|
|
a65de95b16 | ||
|
|
fb8572313e | ||
|
|
2fc28777b7 | ||
|
|
ffd493fea9 | ||
|
|
b207cbf03e | ||
|
|
72239801d8 | ||
|
|
33ff83d102 | ||
|
|
031625e241 | ||
|
|
ec127dbeb1 | ||
|
|
5d80119fcd | ||
|
|
f6c972c9a2 | ||
|
|
a0b256c17d | ||
|
|
a66cae9a6b | ||
|
|
7f6122f8b8 | ||
|
|
ee7257208a | ||
|
|
87ea46a4dd | ||
|
|
d221a3f38a | ||
|
|
f62980606a | ||
|
|
c2ab9f5b85 | ||
|
|
2c925983a8 | ||
|
|
375e743124 | ||
|
|
78f76c8343 | ||
|
|
33e4743e89 | ||
|
|
b9b7104f6b | ||
|
|
a45f420069 | ||
|
|
a7d92f569f | ||
|
|
73f55735b4 | ||
|
|
a15c6b4855 | ||
|
|
48f7ffe089 | ||
|
|
c607338003 | ||
|
|
66a7a6d199 | ||
|
|
1d7bf239ea | ||
|
|
43a5db7711 | ||
|
|
0e56ea9503 | ||
|
|
d640d801e6 | ||
|
|
b5c70dedcb | ||
|
|
a8bcf0e14d | ||
|
|
0c13004040 | ||
|
|
cc05a3508b | ||
|
|
458030c575 | ||
|
|
3b4641c26c | ||
|
|
9b03af17b6 | ||
|
|
72b2be4933 | ||
|
|
2f0f717d44 | ||
|
|
e3bef564f2 | ||
|
|
319be0e043 | ||
|
|
431483da89 | ||
|
|
d07376245c | ||
|
|
2aa6ac2b63 | ||
|
|
03a362817c | ||
|
|
2dc972423a | ||
|
|
4b43d35bcc | ||
|
|
350ec10186 | ||
|
|
0104e48b72 | ||
|
|
a88f7aab30 | ||
|
|
e91ed337cc | ||
|
|
32d5b7697d | ||
|
|
c23d35d219 | ||
|
|
6b04b6c39b | ||
|
|
021d5b1f47 | ||
|
|
b0f14c6e4e | ||
|
|
cd3a0f52d5 | ||
|
|
cc5835423f | ||
|
|
155fc0592a | ||
|
|
a163c72e93 | ||
|
|
562f6a852d | ||
|
|
bfb88781af | ||
|
|
ff4656bbe7 | ||
|
|
c44b08e2e9 | ||
|
|
4d14b583ff | ||
|
|
892f0727e8 | ||
|
|
3635ecb8b4 | ||
|
|
dd2981b13e | ||
|
|
ff60343089 | ||
|
|
fb77c42bba | ||
|
|
a65b9ad49e | ||
|
|
0ed32c7ddd | ||
|
|
f1350783fc | ||
|
|
5ac2efd9c6 | ||
|
|
a7247acbb3 | ||
|
|
0b3663ee87 | ||
|
|
ba9b38dd0e | ||
|
|
62bb68ee94 | ||
|
|
e96c6fb7ef | ||
|
|
c04c101de5 | ||
|
|
5ab2c05821 | ||
|
|
9b9e0e4b9e | ||
|
|
c3ee5bbdc0 | ||
|
|
fb70ba6403 | ||
|
|
f605db479b | ||
|
|
175308ecf5 | ||
|
|
2adf2845fd | ||
|
|
0438c67f7d | ||
|
|
47d6928b9f | ||
|
|
deee5a1c39 | ||
|
|
c9492564e0 | ||
|
|
0c826a288e | ||
|
|
093ba4d68c | ||
|
|
1478aabb5e | ||
|
|
07ac8e41c5 | ||
|
|
f0dccbd594 | ||
|
|
26fdedd989 | ||
|
|
d342c73f24 | ||
|
|
0a52ef7219 | ||
|
|
6a69ec833f | ||
|
|
b540127651 | ||
|
|
8fa0f73a46 | ||
|
|
077a221c3f | ||
|
|
301a1c9ac5 | ||
|
|
0db15f96ae | ||
|
|
9b2ea05875 | ||
|
|
27d8ae03e1 | ||
|
|
15e22ea115 | ||
|
|
f398854c68 | ||
|
|
29446c08b6 | ||
|
|
3d44f8ffdc | ||
|
|
61afb24d33 | ||
|
|
e8b5660eda | ||
|
|
d4744838ee | ||
|
|
32f3e21ab7 | ||
|
|
e6d57f81da | ||
|
|
818bf91c93 | ||
|
|
ac2c2b324e | ||
|
|
cf9d07a856 | ||
|
|
860239fa2b | ||
|
|
69f0ede0c6 | ||
|
|
480f13a3ce | ||
|
|
b99335e5b2 | ||
|
|
e83eba9226 | ||
|
|
278a5a4096 | ||
|
|
1cfa247f8c | ||
|
|
a3b2777d16 | ||
|
|
3c9f6ea520 | ||
|
|
15d2452b19 | ||
|
|
f582474fb1 | ||
|
|
b1662676f1 | ||
|
|
23943f41ad | ||
|
|
3cd665a159 | ||
|
|
4074192c0b | ||
|
|
59cd5982ad | ||
|
|
b3893c38db | ||
|
|
a3d6426084 | ||
|
|
30a194c75d | ||
|
|
6431bcdeca | ||
|
|
0d1978cece | ||
|
|
e7e9e81e85 | ||
|
|
ba22201311 | ||
|
|
f799835dd0 | ||
|
|
6f3dcf04fe | ||
|
|
6b03c38e40 | ||
|
|
f756fbb43b | ||
|
|
f84702e3b2 | ||
|
|
9c750f50a2 | ||
|
|
dcca454bad | ||
|
|
ffef826c94 | ||
|
|
15e0a293eb | ||
|
|
11ed822845 | ||
|
|
1e4af86172 | ||
|
|
5f9dffc3c7 | ||
|
|
93e83efb57 | ||
|
|
0d9485ddec | ||
|
|
1248010566 | ||
|
|
d68fe7067c | ||
|
|
e16497618c | ||
|
|
4cfd419565 | ||
|
|
f52bdbc458 | ||
|
|
433dd7020c | ||
|
|
4fef2dd82a | ||
|
|
1e6fb502a6 | ||
|
|
b56ab1408e | ||
|
|
5dae844181 | ||
|
|
329b46c042 | ||
|
|
e2dd16cf1c | ||
|
|
dc244849a1 | ||
|
|
736de5b633 | ||
|
|
b31767ba4a | ||
|
|
ae06fcd807 | ||
|
|
7108ffbb31 | ||
|
|
7a6b6d7ce4 | ||
|
|
549a30b502 | ||
|
|
c64946173b | ||
|
|
5bca9dc41f | ||
|
|
5c830d7102 | ||
|
|
400c0d5b5d | ||
|
|
c53d5b2abf | ||
|
|
a842095fff | ||
|
|
c6e36fec2c | ||
|
|
fa7eeb5852 | ||
|
|
b6bfe3f3ef | ||
|
|
d6cfc8beae | ||
|
|
83c35ced32 | ||
|
|
b9bdb3167a | ||
|
|
dfec6c4c8b | ||
|
|
35838aa229 | ||
|
|
ee0df86f84 | ||
|
|
0650de95d6 | ||
|
|
279f1d0c07 | ||
|
|
5a8738e711 | ||
|
|
00b95461b6 | ||
|
|
a74f78bd73 | ||
|
|
9d35f4c3e6 | ||
|
|
325cd2d284 | ||
|
|
d4f0eb91ef | ||
|
|
5ab228d1d8 | ||
|
|
64e0f7e500 | ||
|
|
7998d4d666 | ||
|
|
2a91d34a65 | ||
|
|
ac717c7600 | ||
|
|
e13b91cb22 | ||
|
|
fdfca9da42 | ||
|
|
1556e15a1a | ||
|
|
7691dd93ad | ||
|
|
2c13acfd30 | ||
|
|
40f1fcbce2 | ||
|
|
456958d647 | ||
|
|
7c404db56b | ||
|
|
18cfd438b8 | ||
|
|
d5e27252cf | ||
|
|
3fe0f0143c | ||
|
|
61a71b9e73 | ||
|
|
e542dabd52 | ||
|
|
9cde086436 | ||
|
|
fe02939466 | ||
|
|
f1c2315055 | ||
|
|
9681c518fc | ||
|
|
762bb409d3 | ||
|
|
0394ba284b | ||
|
|
3e9dcdb53c | ||
|
|
ddfaf4105d | ||
|
|
5b1df7c42a | ||
|
|
7555bb0f97 | ||
|
|
ab96120911 | ||
|
|
7371a576d6 | ||
|
|
5d5ceb5902 | ||
|
|
125d02fecd | ||
|
|
8c98a214f8 | ||
|
|
2a3e8dcec1 | ||
|
|
a996d9039e | ||
|
|
cfba92bf14 | ||
|
|
41f408226e | ||
|
|
58cfa92136 | ||
|
|
f3309b76d1 | ||
|
|
04bfa1e721 | ||
|
|
dc894c6212 | ||
|
|
7c7025fdbb | ||
|
|
97a4eca0a7 | ||
|
|
5e4110b1b3 | ||
|
|
d1e3047445 | ||
|
|
c72515912d | ||
|
|
eb5a93dce2 | ||
|
|
7cb3b3b7ec | ||
|
|
c648d6a541 | ||
|
|
2d72e274e3 | ||
|
|
b73d00e169 | ||
|
|
5065623ab0 | ||
|
|
8698449e5d | ||
|
|
722e987b93 | ||
|
|
a00cbf4be3 | ||
|
|
f235c60bef | ||
|
|
a1d69cd25f | ||
|
|
f7504b99ca | ||
|
|
02669e2435 | ||
|
|
3d2fca277f | ||
|
|
3e6d10e203 | ||
|
|
f828857ce3 | ||
|
|
eeb9c8d5db | ||
|
|
6d38f411ba | ||
|
|
542ffd6b7b | ||
|
|
2a559fd240 | ||
|
|
51844cd291 | ||
|
|
ec9d6295fb | ||
|
|
19a80c2d26 | ||
|
|
12a358fbd0 | ||
|
|
0982505574 | ||
|
|
e3d71843ac | ||
|
|
364635cd06 | ||
|
|
d3844711bc | ||
|
|
81038dab80 | ||
|
|
514e25454d | ||
|
|
203f02029c | ||
|
|
eb20a80b37 | ||
|
|
c2dc51c728 | ||
|
|
c38ecfc16c | ||
|
|
105b116529 | ||
|
|
6a78ff88d3 | ||
|
|
dcc8dad4ea | ||
|
|
cee6984818 | ||
|
|
8a751cddd5 | ||
|
|
91d370d883 | ||
|
|
18854647bf | ||
|
|
97fd3a3b5d | ||
|
|
0f8ce0c6c3 | ||
|
|
9d43b743a2 | ||
|
|
e43b7bf205 | ||
|
|
9412fed9ad | ||
|
|
c7de89bebe | ||
|
|
cc02c126b5 | ||
|
|
aed0d288f7 | ||
|
|
b4a914314a | ||
|
|
f6ba24e46f | ||
|
|
745f7926a6 | ||
|
|
62c93465f2 | ||
|
|
0e733b6933 | ||
|
|
2e28647497 | ||
|
|
9b2b6992c7 | ||
|
|
81aa425616 | ||
|
|
e932fabe64 | ||
|
|
9901e8bc24 | ||
|
|
8c15cdf7cb | ||
|
|
fc453a9d7f | ||
|
|
a232294b11 | ||
|
|
8c829417a7 | ||
|
|
94ce9d6a6e | ||
|
|
a843369ebd | ||
|
|
8e3c942282 | ||
|
|
d2945539b3 | ||
|
|
0281e5e346 | ||
|
|
c76baeae1c | ||
|
|
d12c746630 | ||
|
|
3f9205d2df | ||
|
|
fbdd789dbe | ||
|
|
b521fe4a1f | ||
|
|
b24b127ad5 | ||
|
|
8a12d324e3 | ||
|
|
51975cbe40 | ||
|
|
f6e6394a74 | ||
|
|
466509c578 | ||
|
|
ee86fa7460 | ||
|
|
7f767cb222 | ||
|
|
c3499416f3 | ||
|
|
3bcffa0112 | ||
|
|
529399e486 | ||
|
|
0ce8dd5096 | ||
|
|
8b1227e6b7 | ||
|
|
a887aad9ac | ||
|
|
f5fc7f26b7 | ||
|
|
620bc01620 | ||
|
|
6362c9618d | ||
|
|
d053881549 | ||
|
|
3605ba4262 | ||
|
|
499a46898e | ||
|
|
49595c641c | ||
|
|
98fbceeb1d | ||
|
|
592f093566 | ||
|
|
63134f4d74 | ||
|
|
8b4a2517c0 | ||
|
|
a78b5fe712 | ||
|
|
68402d244b | ||
|
|
81225dafbc | ||
|
|
74bd22eb0c | ||
|
|
a6ab3a2a03 | ||
|
|
9ef5cedfd6 | ||
|
|
8f9b999e5a | ||
|
|
f9156209e7 | ||
|
|
77d0654a29 | ||
|
|
300eb64d89 | ||
|
|
ff01f83a09 | ||
|
|
c28eab1697 | ||
|
|
7a322e0bb8 | ||
|
|
731e177859 | ||
|
|
1beb2ef3da | ||
|
|
5047b0cdee | ||
|
|
5cc65c880a | ||
|
|
b73a6916cb | ||
|
|
134086f6a9 | ||
|
|
1993b2cd82 | ||
|
|
9291184534 | ||
|
|
6d502db694 | ||
|
|
f61b6acfa8 | ||
|
|
8360511c50 | ||
|
|
ee33de5ec8 | ||
|
|
a160f3abc9 | ||
|
|
b63f10f749 | ||
|
|
86002f50e6 | ||
|
|
c3e0c1fb64 | ||
|
|
b464590491 | ||
|
|
65f04ba70e | ||
|
|
a7a4b46821 | ||
|
|
07cd344123 | ||
|
|
30ead2ae4b | ||
|
|
9339192f88 | ||
|
|
6eb1ecc212 | ||
|
|
973484066a | ||
|
|
f177da8ef7 | ||
|
|
d1b50c3db4 | ||
|
|
fb7a3ec99d | ||
|
|
6caed4c23c | ||
|
|
f7c2e72c1e | ||
|
|
85b9fc36da | ||
|
|
5861f9fe6a | ||
|
|
b6ec478dd6 | ||
|
|
89061e6437 | ||
|
|
50cee40531 | ||
|
|
00ced0495d | ||
|
|
4e37f9f52a | ||
|
|
e57a0600f1 | ||
|
|
f4466059ac | ||
|
|
dd183b4031 | ||
|
|
5ef360e3fe | ||
|
|
ffe7680795 | ||
|
|
cbbb2f27e4 | ||
|
|
f3ba9d588e | ||
|
|
623fd68ccc | ||
|
|
5fec3b53d0 | ||
|
|
ffe2bb28ba | ||
|
|
651de80a01 | ||
|
|
4c586d1803 | ||
|
|
60a74258ec | ||
|
|
7d091f3cf4 | ||
|
|
34a0bff760 | ||
|
|
51abc00e51 | ||
|
|
3429d69f9d | ||
|
|
79b8dd73a5 | ||
|
|
fccf0d5bb8 | ||
|
|
e0e02f38b6 | ||
|
|
d1bc2f598f | ||
|
|
9d38d9b1a0 | ||
|
|
8b3f37b61e | ||
|
|
6fade3fb93 | ||
|
|
b7d1c6969e | ||
|
|
21ca434e72 | ||
|
|
d63d7dc5f8 | ||
|
|
f47eef7442 | ||
|
|
9631b087b3 | ||
|
|
d7b947ddad | ||
|
|
656f9ad03c | ||
|
|
0a4150d63e | ||
|
|
377d091ae2 | ||
|
|
bdf8a1bcc1 | ||
|
|
ee78fc1775 | ||
|
|
9ddb21220f | ||
|
|
47e336c1fe | ||
|
|
a2a736d909 | ||
|
|
9217147827 | ||
|
|
53736888a5 | ||
|
|
75004f08d0 | ||
|
|
51f61f61af | ||
|
|
e7ce84e7fc | ||
|
|
42992de312 | ||
|
|
45b3ebfbc2 | ||
|
|
3b3892e7d6 | ||
|
|
9060ea6bd3 | ||
|
|
49012dc6b2 | ||
|
|
9d73893cc8 | ||
|
|
4ce0b03852 | ||
|
|
8972f7cff4 | ||
|
|
d2223f83b8 | ||
|
|
b4d6b047af | ||
|
|
54d5757d0a | ||
|
|
ca8fb3117f | ||
|
|
bc0535e2f4 | ||
|
|
f9f59f1f96 | ||
|
|
f205146c75 | ||
|
|
0634a9cd9b | ||
|
|
3e396a97b0 | ||
|
|
9316636939 | ||
|
|
82fa8d7393 | ||
|
|
83abb8b728 | ||
|
|
feed418ccf | ||
|
|
a2868cbc4f | ||
|
|
43d134cbe3 | ||
|
|
e023c4e789 | ||
|
|
784d7dd273 | ||
|
|
d26561eaeb | ||
|
|
0666ac7b01 | ||
|
|
2caf5f0232 | ||
|
|
d706469ed8 | ||
|
|
5d4decafbe | ||
|
|
bb639328a3 | ||
|
|
ca0791f3af | ||
|
|
449c927c6c | ||
|
|
e95f1b4850 | ||
|
|
06513c89bc | ||
|
|
38d9185232 | ||
|
|
35738f59d9 | ||
|
|
66758b1992 | ||
|
|
c1cff8ca74 | ||
|
|
2dbf69a74e | ||
|
|
6c964baba7 | ||
|
|
4b77eb5d00 | ||
|
|
6e68929a5c | ||
|
|
fc263d9ce7 | ||
|
|
ab9716489b | ||
|
|
5c6202a8ee | ||
|
|
38c1eca590 | ||
|
|
a1a1b1afd7 | ||
|
|
51599c4044 | ||
|
|
9871efbadb | ||
|
|
6b9f22c7ec | ||
|
|
7c54e58ab7 | ||
|
|
024d9b281a | ||
|
|
6c5cd0ed1f | ||
|
|
719172c185 | ||
|
|
763bb52d06 | ||
|
|
d0d0c99505 | ||
|
|
16726215bb | ||
|
|
454b1f19f4 | ||
|
|
6286451991 | ||
|
|
b9881eb70b | ||
|
|
93f586a216 | ||
|
|
a0ac08b838 | ||
|
|
2c0b768774 | ||
|
|
21048f83d5 | ||
|
|
5b92dd5553 | ||
|
|
4851655110 | ||
|
|
64a6389ebf | ||
|
|
4860e3f8bf | ||
|
|
dfbf1b95f6 | ||
|
|
9af9a3570d | ||
|
|
16c237ce51 | ||
|
|
b44cb13d7a | ||
|
|
8c509b47d1 | ||
|
|
c4cba9c6a7 | ||
|
|
0809897303 | ||
|
|
82181ed74d | ||
|
|
85328c473b | ||
|
|
c9abc4ae00 | ||
|
|
5f23db98a8 | ||
|
|
f367abbdfa | ||
|
|
9377129554 | ||
|
|
f4409a6d92 | ||
|
|
c902485718 | ||
|
|
09db82a840 | ||
|
|
9b667fe383 | ||
|
|
00333f9a4e | ||
|
|
5472be631c | ||
|
|
68fa793354 | ||
|
|
111f5462fc | ||
|
|
62e282cc0e | ||
|
|
5aaa9720c8 | ||
|
|
9a2fb89e43 | ||
|
|
fc1a2af011 | ||
|
|
82e92ce777 | ||
|
|
9b317c2210 | ||
|
|
927f942236 | ||
|
|
75c3027e05 | ||
|
|
a2d408aea9 | ||
|
|
5386b7c23d | ||
|
|
a741f35139 | ||
|
|
1e25f35aac | ||
|
|
3042e49ddb | ||
|
|
6495a386a0 | ||
|
|
cee214cc98 | ||
|
|
41390d8ef4 | ||
|
|
c0f6cf225f | ||
|
|
16d0a4f690 | ||
|
|
8f600aec25 |
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,38 +0,0 @@
|
|||||||
---
|
|
||||||
name: Bug Report
|
|
||||||
about: Found a bug with PlaceholderAPI? Report it through this form!
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
[New placeholders/plugin]: https://github.com/PlaceholderAPI/PlaceholderAPI/issues/new?template=feature_request.md
|
|
||||||
[Request change]: https://github.com/PlaceholderAPI/PlaceholderAPI/issues/new?template=change_request.md
|
|
||||||
[Spigot page]: https://www.spigotmc.org/resources/6245/
|
|
||||||
[Jenkins page]: http://ci.extendedclip.com/job/PlaceholderAPI/
|
|
||||||
[issue]: https://github.com/PlaceholderAPI/PlaceholderAPI/issues
|
|
||||||
|
|
||||||
### Notes
|
|
||||||
This template is for **reporting a bug** and not for requesting changes to the wiki!
|
|
||||||
If you want your placeholders added or updated, use the [New placeholders/plugin] or [Request change] template.
|
|
||||||
|
|
||||||
Also make sure, that you use the latest version of PlaceholderAPI from either the [Spigot page] or the [Jenkins page] and that your
|
|
||||||
issue isn't already listed in the [issue] page.
|
|
||||||
|
|
||||||
### Issue
|
|
||||||
> What is the issue? Describe it like you would tell a friend.
|
|
||||||
<!-- Please type below this like -->
|
|
||||||
|
|
||||||
|
|
||||||
### Expected behaviour
|
|
||||||
> What should PlaceholderAPI do?
|
|
||||||
<!-- Please type below this like -->
|
|
||||||
|
|
||||||
|
|
||||||
### Actual behaviour
|
|
||||||
> What does PlaceholderAPI actually do?
|
|
||||||
<!-- Please type below this like -->
|
|
||||||
|
|
||||||
|
|
||||||
### How to reproduce
|
|
||||||
> What steps did you made, to get this bug?
|
|
||||||
<!-- Please type below this like -->
|
|
||||||
1.
|
|
||||||
36
.github/ISSUE_TEMPLATE/change_request.md
vendored
@@ -1,36 +0,0 @@
|
|||||||
---
|
|
||||||
name: Request change
|
|
||||||
about: Request a update/change of a wiki-page
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
[New placeholders/plugin]: https://github.com/PlaceholderAPI/PlaceholderAPI/issues/new?template=feature_request.md
|
|
||||||
[Bug report]: https://github.com/PlaceholderAPI/PlaceholderAPI/issues/new?template=bug_report.md
|
|
||||||
[issues]: https://github.com/PlaceholderAPI/PlaceholderAPI/issues
|
|
||||||
[wiki]: https://github.com/PlaceholderAPI/PlaceholderAPI/wiki
|
|
||||||
|
|
||||||
### Notes
|
|
||||||
This template is for **requesting changes to the wiki** and not for reporting bugs or requesting additions for the wiki!
|
|
||||||
If you want your placeholders added, use the [New placeholders/plugin] template.
|
|
||||||
For bug reports, use the [Bug report] template.
|
|
||||||
|
|
||||||
Also make sure, that your requested change isn't already made in the [wiki] or listed in the [issues] page.
|
|
||||||
|
|
||||||
### Type
|
|
||||||
> What kind of change is it? (Multiple selections possible)
|
|
||||||
<!-- Please select the right one, by changing the [ ] to [x] -->
|
|
||||||
|
|
||||||
- [ ] Placeholder(s) changed.
|
|
||||||
- [ ] New placeholder(s).
|
|
||||||
- [ ] Plugin no longer supports PlaceholderAPI and/or was deleted.
|
|
||||||
|
|
||||||
### Plugin
|
|
||||||
> What is the name of the plugin?
|
|
||||||
<!-- Please type below this line -->
|
|
||||||
|
|
||||||
|
|
||||||
### What is the new value?
|
|
||||||
> **Placeholder(s) changed**: Type what the old and the new placeholder(s) is/are.
|
|
||||||
> **New Placeholder(s)**: Type the new placeholder(s).
|
|
||||||
> **Plugin no longer supports PlaceholderAPI**: Leave this blank.
|
|
||||||
<!-- Please type below this line -->
|
|
||||||
35
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,35 +0,0 @@
|
|||||||
---
|
|
||||||
name: New placeholders/plugin
|
|
||||||
about: Do you have a plugin that supports and/or adds placeholders from/to PlaceholderAPI and that isn't on the wiki? Use this template!
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
[Request change]: https://github.com/PlaceholderAPI/PlaceholderAPI/issues/new?template=change_request.md
|
|
||||||
[Bug report]: https://github.com/PlaceholderAPI/PlaceholderAPI/issues/new?template=bug_report.md
|
|
||||||
[issues]: https://github.com/PlaceholderAPI/PlaceholderAPI/issues
|
|
||||||
[wiki]: https://github.com/PlaceholderAPI/PlaceholderAPI/wiki
|
|
||||||
|
|
||||||
### Notes
|
|
||||||
This template is for **requesting additions for the wiki** and not for reporting bugs or requesting changes for the wiki!
|
|
||||||
If you want changes to be made to the wiki, use the [Request change] template.
|
|
||||||
For bug reports, use the [Bug report] template.
|
|
||||||
|
|
||||||
Also make sure, that your requested placeholders/plugin isn't already added in the [wiki] or listed in the [issues] page.
|
|
||||||
|
|
||||||
### Type
|
|
||||||
> What kind of request is this? (Multiple selections possible)
|
|
||||||
<!-- Select the right option by replacing [ ] with [x] -->
|
|
||||||
<!-- For an update of an already listed plugin, use the "Request change" template -->
|
|
||||||
|
|
||||||
- [ ] New expansion providing placeholders.
|
|
||||||
- [ ] New plugin providing placeholders.
|
|
||||||
- [ ] New plugin supporting PlaceholderAPI.
|
|
||||||
|
|
||||||
### Plugin
|
|
||||||
> What is the name of the plugin/expansion?
|
|
||||||
> Provide also a link to it.
|
|
||||||
<!-- Please type below this line -->
|
|
||||||
|
|
||||||
### Placeholders/others
|
|
||||||
> What are the new placeholders/Any additional info?
|
|
||||||
<!-- Please type below this line -->
|
|
||||||
150
.gitignore
vendored
@@ -1,146 +1,6 @@
|
|||||||
### Eclipse ###
|
.idea/
|
||||||
|
.gradle/
|
||||||
.metadata
|
server/
|
||||||
bin/
|
|
||||||
tmp/
|
|
||||||
*.tmp
|
|
||||||
*.bak
|
|
||||||
*.swp
|
|
||||||
*~.nib
|
|
||||||
local.properties
|
|
||||||
.settings/
|
|
||||||
.loadpath
|
|
||||||
.recommenders
|
|
||||||
|
|
||||||
# External tool builders
|
|
||||||
.externalToolBuilders/
|
|
||||||
|
|
||||||
# Locally stored "Eclipse launch configurations"
|
|
||||||
*.launch
|
|
||||||
|
|
||||||
# PyDev specific (Python IDE for Eclipse)
|
|
||||||
*.pydevproject
|
|
||||||
|
|
||||||
# CDT-specific (C/C++ Development Tooling)
|
|
||||||
.cproject
|
|
||||||
|
|
||||||
# Java annotation processor (APT)
|
|
||||||
.factorypath
|
|
||||||
|
|
||||||
# PDT-specific (PHP Development Tools)
|
|
||||||
.buildpath
|
|
||||||
|
|
||||||
# sbteclipse plugin
|
|
||||||
.target
|
|
||||||
|
|
||||||
# Tern plugin
|
|
||||||
.tern-project
|
|
||||||
|
|
||||||
# TeXlipse plugin
|
|
||||||
.texlipse
|
|
||||||
|
|
||||||
# STS (Spring Tool Suite)
|
|
||||||
.springBeans
|
|
||||||
|
|
||||||
# Code Recommenders
|
|
||||||
.recommenders/
|
|
||||||
|
|
||||||
# Scala IDE specific (Scala & Java development for Eclipse)
|
|
||||||
.cache-main
|
|
||||||
.scala_dependencies
|
|
||||||
.worksheet
|
|
||||||
|
|
||||||
### Eclipse Patch ###
|
|
||||||
# Eclipse Core
|
|
||||||
.project
|
|
||||||
|
|
||||||
# JDT-specific (Eclipse Java Development Tools)
|
|
||||||
.classpath
|
|
||||||
|
|
||||||
### Intellij ###
|
|
||||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
|
|
||||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
|
||||||
|
|
||||||
# User-specific stuff:
|
|
||||||
.idea/**/workspace.xml
|
|
||||||
.idea/**/tasks.xml
|
|
||||||
.idea/dictionaries
|
|
||||||
|
|
||||||
# Sensitive or high-churn files:
|
|
||||||
.idea/**/dataSources/
|
|
||||||
.idea/**/dataSources.ids
|
|
||||||
.idea/**/dataSources.xml
|
|
||||||
.idea/**/dataSources.local.xml
|
|
||||||
.idea/**/sqlDataSources.xml
|
|
||||||
.idea/**/dynamic.xml
|
|
||||||
.idea/**/uiDesigner.xml
|
|
||||||
|
|
||||||
# Gradle:
|
|
||||||
.idea/**/gradle.xml
|
|
||||||
.idea/**/libraries
|
|
||||||
|
|
||||||
# CMake
|
|
||||||
cmake-build-debug/
|
|
||||||
|
|
||||||
# Mongo Explorer plugin:
|
|
||||||
.idea/**/mongoSettings.xml
|
|
||||||
|
|
||||||
## File-based project format:
|
|
||||||
*.iws
|
|
||||||
|
|
||||||
## Plugin-specific files:
|
|
||||||
|
|
||||||
# IntelliJ
|
|
||||||
/out/
|
|
||||||
|
|
||||||
# mpeltonen/sbt-idea plugin
|
|
||||||
.idea_modules/
|
|
||||||
|
|
||||||
# JIRA plugin
|
|
||||||
atlassian-ide-plugin.xml
|
|
||||||
|
|
||||||
# Cursive Clojure plugin
|
|
||||||
.idea/replstate.xml
|
|
||||||
|
|
||||||
# Ruby plugin and RubyMine
|
|
||||||
/.rakeTasks
|
|
||||||
|
|
||||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
|
||||||
com_crashlytics_export_strings.xml
|
|
||||||
crashlytics.properties
|
|
||||||
crashlytics-build.properties
|
|
||||||
fabric.properties
|
|
||||||
|
|
||||||
### Intellij Patch ###
|
|
||||||
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
|
|
||||||
|
|
||||||
*.iml
|
|
||||||
# modules.xml
|
|
||||||
# .idea/misc.xml
|
|
||||||
# *.ipr
|
|
||||||
|
|
||||||
# Sonarlint plugin
|
|
||||||
.idea/sonarlint
|
|
||||||
|
|
||||||
### Maven ###
|
|
||||||
target/
|
|
||||||
pom.xml.tag
|
|
||||||
pom.xml.releaseBackup
|
|
||||||
pom.xml.versionsBackup
|
|
||||||
pom.xml.next
|
|
||||||
release.properties
|
|
||||||
dependency-reduced-pom.xml
|
|
||||||
buildNumber.properties
|
|
||||||
.mvn/timing.properties
|
|
||||||
|
|
||||||
# Avoid ignoring Maven wrapper jar file (.jar files are usually ignored)
|
|
||||||
!/.mvn/wrapper/maven-wrapper.jar
|
|
||||||
|
|
||||||
### NetBeans ###
|
|
||||||
nbproject/private/
|
|
||||||
build/
|
build/
|
||||||
nbbuild/
|
out/
|
||||||
dist/
|
*.iml
|
||||||
nbdist/
|
|
||||||
.nb-gradle/
|
|
||||||
nbactions.xml
|
|
||||||
674
LICENSE
@@ -1,674 +0,0 @@
|
|||||||
GNU GENERAL PUBLIC LICENSE
|
|
||||||
Version 3, 29 June 2007
|
|
||||||
|
|
||||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
Preamble
|
|
||||||
|
|
||||||
The GNU General Public License is a free, copyleft license for
|
|
||||||
software and other kinds of works.
|
|
||||||
|
|
||||||
The licenses for most software and other practical works are designed
|
|
||||||
to take away your freedom to share and change the works. By contrast,
|
|
||||||
the GNU General Public License is intended to guarantee your freedom to
|
|
||||||
share and change all versions of a program--to make sure it remains free
|
|
||||||
software for all its users. We, the Free Software Foundation, use the
|
|
||||||
GNU General Public License for most of our software; it applies also to
|
|
||||||
any other work released this way by its authors. You can apply it to
|
|
||||||
your programs, too.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
|
||||||
have the freedom to distribute copies of free software (and charge for
|
|
||||||
them if you wish), that you receive source code or can get it if you
|
|
||||||
want it, that you can change the software or use pieces of it in new
|
|
||||||
free programs, and that you know you can do these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to prevent others from denying you
|
|
||||||
these rights or asking you to surrender the rights. Therefore, you have
|
|
||||||
certain responsibilities if you distribute copies of the software, or if
|
|
||||||
you modify it: responsibilities to respect the freedom of others.
|
|
||||||
|
|
||||||
For example, if you distribute copies of such a program, whether
|
|
||||||
gratis or for a fee, you must pass on to the recipients the same
|
|
||||||
freedoms that you received. You must make sure that they, too, receive
|
|
||||||
or can get the source code. And you must show them these terms so they
|
|
||||||
know their rights.
|
|
||||||
|
|
||||||
Developers that use the GNU GPL protect your rights with two steps:
|
|
||||||
(1) assert copyright on the software, and (2) offer you this License
|
|
||||||
giving you legal permission to copy, distribute and/or modify it.
|
|
||||||
|
|
||||||
For the developers' and authors' protection, the GPL clearly explains
|
|
||||||
that there is no warranty for this free software. For both users' and
|
|
||||||
authors' sake, the GPL requires that modified versions be marked as
|
|
||||||
changed, so that their problems will not be attributed erroneously to
|
|
||||||
authors of previous versions.
|
|
||||||
|
|
||||||
Some devices are designed to deny users access to install or run
|
|
||||||
modified versions of the software inside them, although the manufacturer
|
|
||||||
can do so. This is fundamentally incompatible with the aim of
|
|
||||||
protecting users' freedom to change the software. The systematic
|
|
||||||
pattern of such abuse occurs in the area of products for individuals to
|
|
||||||
use, which is precisely where it is most unacceptable. Therefore, we
|
|
||||||
have designed this version of the GPL to prohibit the practice for those
|
|
||||||
products. If such problems arise substantially in other domains, we
|
|
||||||
stand ready to extend this provision to those domains in future versions
|
|
||||||
of the GPL, as needed to protect the freedom of users.
|
|
||||||
|
|
||||||
Finally, every program is threatened constantly by software patents.
|
|
||||||
States should not allow patents to restrict development and use of
|
|
||||||
software on general-purpose computers, but in those that do, we wish to
|
|
||||||
avoid the special danger that patents applied to a free program could
|
|
||||||
make it effectively proprietary. To prevent this, the GPL assures that
|
|
||||||
patents cannot be used to render the program non-free.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow.
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
0. Definitions.
|
|
||||||
|
|
||||||
"This License" refers to version 3 of the GNU General Public License.
|
|
||||||
|
|
||||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
|
||||||
works, such as semiconductor masks.
|
|
||||||
|
|
||||||
"The Program" refers to any copyrightable work licensed under this
|
|
||||||
License. Each licensee is addressed as "you". "Licensees" and
|
|
||||||
"recipients" may be individuals or organizations.
|
|
||||||
|
|
||||||
To "modify" a work means to copy from or adapt all or part of the work
|
|
||||||
in a fashion requiring copyright permission, other than the making of an
|
|
||||||
exact copy. The resulting work is called a "modified version" of the
|
|
||||||
earlier work or a work "based on" the earlier work.
|
|
||||||
|
|
||||||
A "covered work" means either the unmodified Program or a work based
|
|
||||||
on the Program.
|
|
||||||
|
|
||||||
To "propagate" a work means to do anything with it that, without
|
|
||||||
permission, would make you directly or secondarily liable for
|
|
||||||
infringement under applicable copyright law, except executing it on a
|
|
||||||
computer or modifying a private copy. Propagation includes copying,
|
|
||||||
distribution (with or without modification), making available to the
|
|
||||||
public, and in some countries other activities as well.
|
|
||||||
|
|
||||||
To "convey" a work means any kind of propagation that enables other
|
|
||||||
parties to make or receive copies. Mere interaction with a user through
|
|
||||||
a computer network, with no transfer of a copy, is not conveying.
|
|
||||||
|
|
||||||
An interactive user interface displays "Appropriate Legal Notices"
|
|
||||||
to the extent that it includes a convenient and prominently visible
|
|
||||||
feature that (1) displays an appropriate copyright notice, and (2)
|
|
||||||
tells the user that there is no warranty for the work (except to the
|
|
||||||
extent that warranties are provided), that licensees may convey the
|
|
||||||
work under this License, and how to view a copy of this License. If
|
|
||||||
the interface presents a list of user commands or options, such as a
|
|
||||||
menu, a prominent item in the list meets this criterion.
|
|
||||||
|
|
||||||
1. Source Code.
|
|
||||||
|
|
||||||
The "source code" for a work means the preferred form of the work
|
|
||||||
for making modifications to it. "Object code" means any non-source
|
|
||||||
form of a work.
|
|
||||||
|
|
||||||
A "Standard Interface" means an interface that either is an official
|
|
||||||
standard defined by a recognized standards body, or, in the case of
|
|
||||||
interfaces specified for a particular programming language, one that
|
|
||||||
is widely used among developers working in that language.
|
|
||||||
|
|
||||||
The "System Libraries" of an executable work include anything, other
|
|
||||||
than the work as a whole, that (a) is included in the normal form of
|
|
||||||
packaging a Major Component, but which is not part of that Major
|
|
||||||
Component, and (b) serves only to enable use of the work with that
|
|
||||||
Major Component, or to implement a Standard Interface for which an
|
|
||||||
implementation is available to the public in source code form. A
|
|
||||||
"Major Component", in this context, means a major essential component
|
|
||||||
(kernel, window system, and so on) of the specific operating system
|
|
||||||
(if any) on which the executable work runs, or a compiler used to
|
|
||||||
produce the work, or an object code interpreter used to run it.
|
|
||||||
|
|
||||||
The "Corresponding Source" for a work in object code form means all
|
|
||||||
the source code needed to generate, install, and (for an executable
|
|
||||||
work) run the object code and to modify the work, including scripts to
|
|
||||||
control those activities. However, it does not include the work's
|
|
||||||
System Libraries, or general-purpose tools or generally available free
|
|
||||||
programs which are used unmodified in performing those activities but
|
|
||||||
which are not part of the work. For example, Corresponding Source
|
|
||||||
includes interface definition files associated with source files for
|
|
||||||
the work, and the source code for shared libraries and dynamically
|
|
||||||
linked subprograms that the work is specifically designed to require,
|
|
||||||
such as by intimate data communication or control flow between those
|
|
||||||
subprograms and other parts of the work.
|
|
||||||
|
|
||||||
The Corresponding Source need not include anything that users
|
|
||||||
can regenerate automatically from other parts of the Corresponding
|
|
||||||
Source.
|
|
||||||
|
|
||||||
The Corresponding Source for a work in source code form is that
|
|
||||||
same work.
|
|
||||||
|
|
||||||
2. Basic Permissions.
|
|
||||||
|
|
||||||
All rights granted under this License are granted for the term of
|
|
||||||
copyright on the Program, and are irrevocable provided the stated
|
|
||||||
conditions are met. This License explicitly affirms your unlimited
|
|
||||||
permission to run the unmodified Program. The output from running a
|
|
||||||
covered work is covered by this License only if the output, given its
|
|
||||||
content, constitutes a covered work. This License acknowledges your
|
|
||||||
rights of fair use or other equivalent, as provided by copyright law.
|
|
||||||
|
|
||||||
You may make, run and propagate covered works that you do not
|
|
||||||
convey, without conditions so long as your license otherwise remains
|
|
||||||
in force. You may convey covered works to others for the sole purpose
|
|
||||||
of having them make modifications exclusively for you, or provide you
|
|
||||||
with facilities for running those works, provided that you comply with
|
|
||||||
the terms of this License in conveying all material for which you do
|
|
||||||
not control copyright. Those thus making or running the covered works
|
|
||||||
for you must do so exclusively on your behalf, under your direction
|
|
||||||
and control, on terms that prohibit them from making any copies of
|
|
||||||
your copyrighted material outside their relationship with you.
|
|
||||||
|
|
||||||
Conveying under any other circumstances is permitted solely under
|
|
||||||
the conditions stated below. Sublicensing is not allowed; section 10
|
|
||||||
makes it unnecessary.
|
|
||||||
|
|
||||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
|
||||||
|
|
||||||
No covered work shall be deemed part of an effective technological
|
|
||||||
measure under any applicable law fulfilling obligations under article
|
|
||||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
|
||||||
similar laws prohibiting or restricting circumvention of such
|
|
||||||
measures.
|
|
||||||
|
|
||||||
When you convey a covered work, you waive any legal power to forbid
|
|
||||||
circumvention of technological measures to the extent such circumvention
|
|
||||||
is effected by exercising rights under this License with respect to
|
|
||||||
the covered work, and you disclaim any intention to limit operation or
|
|
||||||
modification of the work as a means of enforcing, against the work's
|
|
||||||
users, your or third parties' legal rights to forbid circumvention of
|
|
||||||
technological measures.
|
|
||||||
|
|
||||||
4. Conveying Verbatim Copies.
|
|
||||||
|
|
||||||
You may convey verbatim copies of the Program's source code as you
|
|
||||||
receive it, in any medium, provided that you conspicuously and
|
|
||||||
appropriately publish on each copy an appropriate copyright notice;
|
|
||||||
keep intact all notices stating that this License and any
|
|
||||||
non-permissive terms added in accord with section 7 apply to the code;
|
|
||||||
keep intact all notices of the absence of any warranty; and give all
|
|
||||||
recipients a copy of this License along with the Program.
|
|
||||||
|
|
||||||
You may charge any price or no price for each copy that you convey,
|
|
||||||
and you may offer support or warranty protection for a fee.
|
|
||||||
|
|
||||||
5. Conveying Modified Source Versions.
|
|
||||||
|
|
||||||
You may convey a work based on the Program, or the modifications to
|
|
||||||
produce it from the Program, in the form of source code under the
|
|
||||||
terms of section 4, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) The work must carry prominent notices stating that you modified
|
|
||||||
it, and giving a relevant date.
|
|
||||||
|
|
||||||
b) The work must carry prominent notices stating that it is
|
|
||||||
released under this License and any conditions added under section
|
|
||||||
7. This requirement modifies the requirement in section 4 to
|
|
||||||
"keep intact all notices".
|
|
||||||
|
|
||||||
c) You must license the entire work, as a whole, under this
|
|
||||||
License to anyone who comes into possession of a copy. This
|
|
||||||
License will therefore apply, along with any applicable section 7
|
|
||||||
additional terms, to the whole of the work, and all its parts,
|
|
||||||
regardless of how they are packaged. This License gives no
|
|
||||||
permission to license the work in any other way, but it does not
|
|
||||||
invalidate such permission if you have separately received it.
|
|
||||||
|
|
||||||
d) If the work has interactive user interfaces, each must display
|
|
||||||
Appropriate Legal Notices; however, if the Program has interactive
|
|
||||||
interfaces that do not display Appropriate Legal Notices, your
|
|
||||||
work need not make them do so.
|
|
||||||
|
|
||||||
A compilation of a covered work with other separate and independent
|
|
||||||
works, which are not by their nature extensions of the covered work,
|
|
||||||
and which are not combined with it such as to form a larger program,
|
|
||||||
in or on a volume of a storage or distribution medium, is called an
|
|
||||||
"aggregate" if the compilation and its resulting copyright are not
|
|
||||||
used to limit the access or legal rights of the compilation's users
|
|
||||||
beyond what the individual works permit. Inclusion of a covered work
|
|
||||||
in an aggregate does not cause this License to apply to the other
|
|
||||||
parts of the aggregate.
|
|
||||||
|
|
||||||
6. Conveying Non-Source Forms.
|
|
||||||
|
|
||||||
You may convey a covered work in object code form under the terms
|
|
||||||
of sections 4 and 5, provided that you also convey the
|
|
||||||
machine-readable Corresponding Source under the terms of this License,
|
|
||||||
in one of these ways:
|
|
||||||
|
|
||||||
a) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by the
|
|
||||||
Corresponding Source fixed on a durable physical medium
|
|
||||||
customarily used for software interchange.
|
|
||||||
|
|
||||||
b) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by a
|
|
||||||
written offer, valid for at least three years and valid for as
|
|
||||||
long as you offer spare parts or customer support for that product
|
|
||||||
model, to give anyone who possesses the object code either (1) a
|
|
||||||
copy of the Corresponding Source for all the software in the
|
|
||||||
product that is covered by this License, on a durable physical
|
|
||||||
medium customarily used for software interchange, for a price no
|
|
||||||
more than your reasonable cost of physically performing this
|
|
||||||
conveying of source, or (2) access to copy the
|
|
||||||
Corresponding Source from a network server at no charge.
|
|
||||||
|
|
||||||
c) Convey individual copies of the object code with a copy of the
|
|
||||||
written offer to provide the Corresponding Source. This
|
|
||||||
alternative is allowed only occasionally and noncommercially, and
|
|
||||||
only if you received the object code with such an offer, in accord
|
|
||||||
with subsection 6b.
|
|
||||||
|
|
||||||
d) Convey the object code by offering access from a designated
|
|
||||||
place (gratis or for a charge), and offer equivalent access to the
|
|
||||||
Corresponding Source in the same way through the same place at no
|
|
||||||
further charge. You need not require recipients to copy the
|
|
||||||
Corresponding Source along with the object code. If the place to
|
|
||||||
copy the object code is a network server, the Corresponding Source
|
|
||||||
may be on a different server (operated by you or a third party)
|
|
||||||
that supports equivalent copying facilities, provided you maintain
|
|
||||||
clear directions next to the object code saying where to find the
|
|
||||||
Corresponding Source. Regardless of what server hosts the
|
|
||||||
Corresponding Source, you remain obligated to ensure that it is
|
|
||||||
available for as long as needed to satisfy these requirements.
|
|
||||||
|
|
||||||
e) Convey the object code using peer-to-peer transmission, provided
|
|
||||||
you inform other peers where the object code and Corresponding
|
|
||||||
Source of the work are being offered to the general public at no
|
|
||||||
charge under subsection 6d.
|
|
||||||
|
|
||||||
A separable portion of the object code, whose source code is excluded
|
|
||||||
from the Corresponding Source as a System Library, need not be
|
|
||||||
included in conveying the object code work.
|
|
||||||
|
|
||||||
A "User Product" is either (1) a "consumer product", which means any
|
|
||||||
tangible personal property which is normally used for personal, family,
|
|
||||||
or household purposes, or (2) anything designed or sold for incorporation
|
|
||||||
into a dwelling. In determining whether a product is a consumer product,
|
|
||||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
|
||||||
product received by a particular user, "normally used" refers to a
|
|
||||||
typical or common use of that class of product, regardless of the status
|
|
||||||
of the particular user or of the way in which the particular user
|
|
||||||
actually uses, or expects or is expected to use, the product. A product
|
|
||||||
is a consumer product regardless of whether the product has substantial
|
|
||||||
commercial, industrial or non-consumer uses, unless such uses represent
|
|
||||||
the only significant mode of use of the product.
|
|
||||||
|
|
||||||
"Installation Information" for a User Product means any methods,
|
|
||||||
procedures, authorization keys, or other information required to install
|
|
||||||
and execute modified versions of a covered work in that User Product from
|
|
||||||
a modified version of its Corresponding Source. The information must
|
|
||||||
suffice to ensure that the continued functioning of the modified object
|
|
||||||
code is in no case prevented or interfered with solely because
|
|
||||||
modification has been made.
|
|
||||||
|
|
||||||
If you convey an object code work under this section in, or with, or
|
|
||||||
specifically for use in, a User Product, and the conveying occurs as
|
|
||||||
part of a transaction in which the right of possession and use of the
|
|
||||||
User Product is transferred to the recipient in perpetuity or for a
|
|
||||||
fixed term (regardless of how the transaction is characterized), the
|
|
||||||
Corresponding Source conveyed under this section must be accompanied
|
|
||||||
by the Installation Information. But this requirement does not apply
|
|
||||||
if neither you nor any third party retains the ability to install
|
|
||||||
modified object code on the User Product (for example, the work has
|
|
||||||
been installed in ROM).
|
|
||||||
|
|
||||||
The requirement to provide Installation Information does not include a
|
|
||||||
requirement to continue to provide support service, warranty, or updates
|
|
||||||
for a work that has been modified or installed by the recipient, or for
|
|
||||||
the User Product in which it has been modified or installed. Access to a
|
|
||||||
network may be denied when the modification itself materially and
|
|
||||||
adversely affects the operation of the network or violates the rules and
|
|
||||||
protocols for communication across the network.
|
|
||||||
|
|
||||||
Corresponding Source conveyed, and Installation Information provided,
|
|
||||||
in accord with this section must be in a format that is publicly
|
|
||||||
documented (and with an implementation available to the public in
|
|
||||||
source code form), and must require no special password or key for
|
|
||||||
unpacking, reading or copying.
|
|
||||||
|
|
||||||
7. Additional Terms.
|
|
||||||
|
|
||||||
"Additional permissions" are terms that supplement the terms of this
|
|
||||||
License by making exceptions from one or more of its conditions.
|
|
||||||
Additional permissions that are applicable to the entire Program shall
|
|
||||||
be treated as though they were included in this License, to the extent
|
|
||||||
that they are valid under applicable law. If additional permissions
|
|
||||||
apply only to part of the Program, that part may be used separately
|
|
||||||
under those permissions, but the entire Program remains governed by
|
|
||||||
this License without regard to the additional permissions.
|
|
||||||
|
|
||||||
When you convey a copy of a covered work, you may at your option
|
|
||||||
remove any additional permissions from that copy, or from any part of
|
|
||||||
it. (Additional permissions may be written to require their own
|
|
||||||
removal in certain cases when you modify the work.) You may place
|
|
||||||
additional permissions on material, added by you to a covered work,
|
|
||||||
for which you have or can give appropriate copyright permission.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, for material you
|
|
||||||
add to a covered work, you may (if authorized by the copyright holders of
|
|
||||||
that material) supplement the terms of this License with terms:
|
|
||||||
|
|
||||||
a) Disclaiming warranty or limiting liability differently from the
|
|
||||||
terms of sections 15 and 16 of this License; or
|
|
||||||
|
|
||||||
b) Requiring preservation of specified reasonable legal notices or
|
|
||||||
author attributions in that material or in the Appropriate Legal
|
|
||||||
Notices displayed by works containing it; or
|
|
||||||
|
|
||||||
c) Prohibiting misrepresentation of the origin of that material, or
|
|
||||||
requiring that modified versions of such material be marked in
|
|
||||||
reasonable ways as different from the original version; or
|
|
||||||
|
|
||||||
d) Limiting the use for publicity purposes of names of licensors or
|
|
||||||
authors of the material; or
|
|
||||||
|
|
||||||
e) Declining to grant rights under trademark law for use of some
|
|
||||||
trade names, trademarks, or service marks; or
|
|
||||||
|
|
||||||
f) Requiring indemnification of licensors and authors of that
|
|
||||||
material by anyone who conveys the material (or modified versions of
|
|
||||||
it) with contractual assumptions of liability to the recipient, for
|
|
||||||
any liability that these contractual assumptions directly impose on
|
|
||||||
those licensors and authors.
|
|
||||||
|
|
||||||
All other non-permissive additional terms are considered "further
|
|
||||||
restrictions" within the meaning of section 10. If the Program as you
|
|
||||||
received it, or any part of it, contains a notice stating that it is
|
|
||||||
governed by this License along with a term that is a further
|
|
||||||
restriction, you may remove that term. If a license document contains
|
|
||||||
a further restriction but permits relicensing or conveying under this
|
|
||||||
License, you may add to a covered work material governed by the terms
|
|
||||||
of that license document, provided that the further restriction does
|
|
||||||
not survive such relicensing or conveying.
|
|
||||||
|
|
||||||
If you add terms to a covered work in accord with this section, you
|
|
||||||
must place, in the relevant source files, a statement of the
|
|
||||||
additional terms that apply to those files, or a notice indicating
|
|
||||||
where to find the applicable terms.
|
|
||||||
|
|
||||||
Additional terms, permissive or non-permissive, may be stated in the
|
|
||||||
form of a separately written license, or stated as exceptions;
|
|
||||||
the above requirements apply either way.
|
|
||||||
|
|
||||||
8. Termination.
|
|
||||||
|
|
||||||
You may not propagate or modify a covered work except as expressly
|
|
||||||
provided under this License. Any attempt otherwise to propagate or
|
|
||||||
modify it is void, and will automatically terminate your rights under
|
|
||||||
this License (including any patent licenses granted under the third
|
|
||||||
paragraph of section 11).
|
|
||||||
|
|
||||||
However, if you cease all violation of this License, then your
|
|
||||||
license from a particular copyright holder is reinstated (a)
|
|
||||||
provisionally, unless and until the copyright holder explicitly and
|
|
||||||
finally terminates your license, and (b) permanently, if the copyright
|
|
||||||
holder fails to notify you of the violation by some reasonable means
|
|
||||||
prior to 60 days after the cessation.
|
|
||||||
|
|
||||||
Moreover, your license from a particular copyright holder is
|
|
||||||
reinstated permanently if the copyright holder notifies you of the
|
|
||||||
violation by some reasonable means, this is the first time you have
|
|
||||||
received notice of violation of this License (for any work) from that
|
|
||||||
copyright holder, and you cure the violation prior to 30 days after
|
|
||||||
your receipt of the notice.
|
|
||||||
|
|
||||||
Termination of your rights under this section does not terminate the
|
|
||||||
licenses of parties who have received copies or rights from you under
|
|
||||||
this License. If your rights have been terminated and not permanently
|
|
||||||
reinstated, you do not qualify to receive new licenses for the same
|
|
||||||
material under section 10.
|
|
||||||
|
|
||||||
9. Acceptance Not Required for Having Copies.
|
|
||||||
|
|
||||||
You are not required to accept this License in order to receive or
|
|
||||||
run a copy of the Program. Ancillary propagation of a covered work
|
|
||||||
occurring solely as a consequence of using peer-to-peer transmission
|
|
||||||
to receive a copy likewise does not require acceptance. However,
|
|
||||||
nothing other than this License grants you permission to propagate or
|
|
||||||
modify any covered work. These actions infringe copyright if you do
|
|
||||||
not accept this License. Therefore, by modifying or propagating a
|
|
||||||
covered work, you indicate your acceptance of this License to do so.
|
|
||||||
|
|
||||||
10. Automatic Licensing of Downstream Recipients.
|
|
||||||
|
|
||||||
Each time you convey a covered work, the recipient automatically
|
|
||||||
receives a license from the original licensors, to run, modify and
|
|
||||||
propagate that work, subject to this License. You are not responsible
|
|
||||||
for enforcing compliance by third parties with this License.
|
|
||||||
|
|
||||||
An "entity transaction" is a transaction transferring control of an
|
|
||||||
organization, or substantially all assets of one, or subdividing an
|
|
||||||
organization, or merging organizations. If propagation of a covered
|
|
||||||
work results from an entity transaction, each party to that
|
|
||||||
transaction who receives a copy of the work also receives whatever
|
|
||||||
licenses to the work the party's predecessor in interest had or could
|
|
||||||
give under the previous paragraph, plus a right to possession of the
|
|
||||||
Corresponding Source of the work from the predecessor in interest, if
|
|
||||||
the predecessor has it or can get it with reasonable efforts.
|
|
||||||
|
|
||||||
You may not impose any further restrictions on the exercise of the
|
|
||||||
rights granted or affirmed under this License. For example, you may
|
|
||||||
not impose a license fee, royalty, or other charge for exercise of
|
|
||||||
rights granted under this License, and you may not initiate litigation
|
|
||||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
|
||||||
any patent claim is infringed by making, using, selling, offering for
|
|
||||||
sale, or importing the Program or any portion of it.
|
|
||||||
|
|
||||||
11. Patents.
|
|
||||||
|
|
||||||
A "contributor" is a copyright holder who authorizes use under this
|
|
||||||
License of the Program or a work on which the Program is based. The
|
|
||||||
work thus licensed is called the contributor's "contributor version".
|
|
||||||
|
|
||||||
A contributor's "essential patent claims" are all patent claims
|
|
||||||
owned or controlled by the contributor, whether already acquired or
|
|
||||||
hereafter acquired, that would be infringed by some manner, permitted
|
|
||||||
by this License, of making, using, or selling its contributor version,
|
|
||||||
but do not include claims that would be infringed only as a
|
|
||||||
consequence of further modification of the contributor version. For
|
|
||||||
purposes of this definition, "control" includes the right to grant
|
|
||||||
patent sublicenses in a manner consistent with the requirements of
|
|
||||||
this License.
|
|
||||||
|
|
||||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
|
||||||
patent license under the contributor's essential patent claims, to
|
|
||||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
|
||||||
propagate the contents of its contributor version.
|
|
||||||
|
|
||||||
In the following three paragraphs, a "patent license" is any express
|
|
||||||
agreement or commitment, however denominated, not to enforce a patent
|
|
||||||
(such as an express permission to practice a patent or covenant not to
|
|
||||||
sue for patent infringement). To "grant" such a patent license to a
|
|
||||||
party means to make such an agreement or commitment not to enforce a
|
|
||||||
patent against the party.
|
|
||||||
|
|
||||||
If you convey a covered work, knowingly relying on a patent license,
|
|
||||||
and the Corresponding Source of the work is not available for anyone
|
|
||||||
to copy, free of charge and under the terms of this License, through a
|
|
||||||
publicly available network server or other readily accessible means,
|
|
||||||
then you must either (1) cause the Corresponding Source to be so
|
|
||||||
available, or (2) arrange to deprive yourself of the benefit of the
|
|
||||||
patent license for this particular work, or (3) arrange, in a manner
|
|
||||||
consistent with the requirements of this License, to extend the patent
|
|
||||||
license to downstream recipients. "Knowingly relying" means you have
|
|
||||||
actual knowledge that, but for the patent license, your conveying the
|
|
||||||
covered work in a country, or your recipient's use of the covered work
|
|
||||||
in a country, would infringe one or more identifiable patents in that
|
|
||||||
country that you have reason to believe are valid.
|
|
||||||
|
|
||||||
If, pursuant to or in connection with a single transaction or
|
|
||||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
|
||||||
covered work, and grant a patent license to some of the parties
|
|
||||||
receiving the covered work authorizing them to use, propagate, modify
|
|
||||||
or convey a specific copy of the covered work, then the patent license
|
|
||||||
you grant is automatically extended to all recipients of the covered
|
|
||||||
work and works based on it.
|
|
||||||
|
|
||||||
A patent license is "discriminatory" if it does not include within
|
|
||||||
the scope of its coverage, prohibits the exercise of, or is
|
|
||||||
conditioned on the non-exercise of one or more of the rights that are
|
|
||||||
specifically granted under this License. You may not convey a covered
|
|
||||||
work if you are a party to an arrangement with a third party that is
|
|
||||||
in the business of distributing software, under which you make payment
|
|
||||||
to the third party based on the extent of your activity of conveying
|
|
||||||
the work, and under which the third party grants, to any of the
|
|
||||||
parties who would receive the covered work from you, a discriminatory
|
|
||||||
patent license (a) in connection with copies of the covered work
|
|
||||||
conveyed by you (or copies made from those copies), or (b) primarily
|
|
||||||
for and in connection with specific products or compilations that
|
|
||||||
contain the covered work, unless you entered into that arrangement,
|
|
||||||
or that patent license was granted, prior to 28 March 2007.
|
|
||||||
|
|
||||||
Nothing in this License shall be construed as excluding or limiting
|
|
||||||
any implied license or other defenses to infringement that may
|
|
||||||
otherwise be available to you under applicable patent law.
|
|
||||||
|
|
||||||
12. No Surrender of Others' Freedom.
|
|
||||||
|
|
||||||
If conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot convey a
|
|
||||||
covered work so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you may
|
|
||||||
not convey it at all. For example, if you agree to terms that obligate you
|
|
||||||
to collect a royalty for further conveying from those to whom you convey
|
|
||||||
the Program, the only way you could satisfy both those terms and this
|
|
||||||
License would be to refrain entirely from conveying the Program.
|
|
||||||
|
|
||||||
13. Use with the GNU Affero General Public License.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, you have
|
|
||||||
permission to link or combine any covered work with a work licensed
|
|
||||||
under version 3 of the GNU Affero General Public License into a single
|
|
||||||
combined work, and to convey the resulting work. The terms of this
|
|
||||||
License will continue to apply to the part which is the covered work,
|
|
||||||
but the special requirements of the GNU Affero General Public License,
|
|
||||||
section 13, concerning interaction through a network will apply to the
|
|
||||||
combination as such.
|
|
||||||
|
|
||||||
14. Revised Versions of this License.
|
|
||||||
|
|
||||||
The Free Software Foundation may publish revised and/or new versions of
|
|
||||||
the GNU General Public License from time to time. Such new versions will
|
|
||||||
be similar in spirit to the present version, but may differ in detail to
|
|
||||||
address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the
|
|
||||||
Program specifies that a certain numbered version of the GNU General
|
|
||||||
Public License "or any later version" applies to it, you have the
|
|
||||||
option of following the terms and conditions either of that numbered
|
|
||||||
version or of any later version published by the Free Software
|
|
||||||
Foundation. If the Program does not specify a version number of the
|
|
||||||
GNU General Public License, you may choose any version ever published
|
|
||||||
by the Free Software Foundation.
|
|
||||||
|
|
||||||
If the Program specifies that a proxy can decide which future
|
|
||||||
versions of the GNU General Public License can be used, that proxy's
|
|
||||||
public statement of acceptance of a version permanently authorizes you
|
|
||||||
to choose that version for the Program.
|
|
||||||
|
|
||||||
Later license versions may give you additional or different
|
|
||||||
permissions. However, no additional obligations are imposed on any
|
|
||||||
author or copyright holder as a result of your choosing to follow a
|
|
||||||
later version.
|
|
||||||
|
|
||||||
15. Disclaimer of Warranty.
|
|
||||||
|
|
||||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
|
||||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
|
||||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
|
||||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
|
||||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
|
||||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
16. Limitation of Liability.
|
|
||||||
|
|
||||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
|
||||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
|
||||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
|
||||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
|
||||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
|
||||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
|
||||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
|
||||||
SUCH DAMAGES.
|
|
||||||
|
|
||||||
17. Interpretation of Sections 15 and 16.
|
|
||||||
|
|
||||||
If the disclaimer of warranty and limitation of liability provided
|
|
||||||
above cannot be given local legal effect according to their terms,
|
|
||||||
reviewing courts shall apply local law that most closely approximates
|
|
||||||
an absolute waiver of all civil liability in connection with the
|
|
||||||
Program, unless a warranty or assumption of liability accompanies a
|
|
||||||
copy of the Program in return for a fee.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
How to Apply These Terms to Your New Programs
|
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
|
||||||
possible use to the public, the best way to achieve this is to make it
|
|
||||||
free software which everyone can redistribute and change under these terms.
|
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest
|
|
||||||
to attach them to the start of each source file to most effectively
|
|
||||||
state the exclusion of warranty; and each file should have at least
|
|
||||||
the "copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
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/>.
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
If the program does terminal interaction, make it output a short
|
|
||||||
notice like this when it starts in an interactive mode:
|
|
||||||
|
|
||||||
<program> Copyright (C) <year> <name of author>
|
|
||||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
|
||||||
This is free software, and you are welcome to redistribute it
|
|
||||||
under certain conditions; type `show c' for details.
|
|
||||||
|
|
||||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
|
||||||
parts of the General Public License. Of course, your program's commands
|
|
||||||
might be different; for a GUI interface, you would use an "about box".
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or school,
|
|
||||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
|
||||||
For more information on this, and how to apply and follow the GNU GPL, see
|
|
||||||
<http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The GNU General Public License does not permit incorporating your program
|
|
||||||
into proprietary programs. If your program is a subroutine library, you
|
|
||||||
may consider it more useful to permit linking proprietary applications with
|
|
||||||
the library. If this is what you want to do, use the GNU Lesser General
|
|
||||||
Public License instead of this License. But first, please read
|
|
||||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
|
||||||
44
README.md
@@ -1,44 +0,0 @@
|
|||||||
[issues]: https://github.com/PlaceholderAPI/PlaceholderAPI/issues
|
|
||||||
[licenseImg]: https://img.shields.io/github/license/PlaceholderAPI/PlaceholderAPI.svg
|
|
||||||
[license]: https://github.com/PlaceholderAPI/PlaceholderAPI/blob/master/LICENSE
|
|
||||||
|
|
||||||
[releaseImg]: https://img.shields.io/github/release/PlaceholderAPI/PlaceholderAPI.svg?label=github%20release
|
|
||||||
[release]: https://github.com/PlaceholderAPI/PlaceholderAPI/releases/latest
|
|
||||||
|
|
||||||
[discord]: https://helpch.at/discord
|
|
||||||
[spigot]: https://www.spigotmc.org/resources/6245/
|
|
||||||
[Expansions cloud]: https://api.extendedclip.com/home
|
|
||||||
[placeholder list]: https://helpch.at/placeholders
|
|
||||||
[statistics]: https://bstats.org/plugin/bukkit/PlaceholderAPI
|
|
||||||
|
|
||||||
[ci]: http://ci.extendedclip.com/job/PlaceholderAPI/
|
|
||||||
[ciImg]: http://ci.extendedclip.com/buildStatus/icon?job=PlaceholderAPI
|
|
||||||
|
|
||||||
[APIversionImg]: https://img.shields.io/nexus/r/http/repo.extendedclip.com/me.clip/placeholderapi.svg?label=API-Version
|
|
||||||
[logo]: https://i.imgur.com/Ea4PURv.png
|
|
||||||
<!-- The stuff above isn't visible in the readme -->
|
|
||||||
|
|
||||||
[![logo]][spigot]
|
|
||||||
|
|
||||||
[![ciImg]][ci] [![releaseImg]][release] ![APIversionImg] [![licenseImg]][license]
|
|
||||||
|
|
||||||
# Information
|
|
||||||
[PlaceholderAPI][spigot] is a plugin for Spigot servers that allows server owners to display information from various plugins with a uniform format.
|
|
||||||
|
|
||||||
Support for specific plugins are provided either by the plugin itself or through expansions. The expansions may be downloaded in-game through the PAPI Expansion Cloud. There are currently over 100 expansions that support a wide variety of plugins, such as Essentials, Factions, LuckPerms, and Vault.
|
|
||||||
|
|
||||||
PlaceholderAPI has been downloaded over 100,000 times and has been used concurrently on over 10,000 servers, which makes it a must-have for a server of any type or scale.
|
|
||||||
|
|
||||||
<!-- TODO: Add contributing section -->
|
|
||||||
<!-- TODO: Add expansion creation section (possibly add to a wiki?) -->
|
|
||||||
|
|
||||||
## Support
|
|
||||||
- [Issue Tracker][issues]
|
|
||||||
- [Discord Support][discord]
|
|
||||||
|
|
||||||
## Quick Links
|
|
||||||
- [CI Server][ci]
|
|
||||||
- [Expansions cloud]
|
|
||||||
- [Placeholder List]
|
|
||||||
- [Spigot Page][spigot]
|
|
||||||
- [Plugin Statistics][statistics]
|
|
||||||
BIN
dark_mode/ABOUT.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
dark_mode/COMMANDS.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
dark_mode/CONFIG.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
dark_mode/GETTING_STARTED.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
dark_mode/HEADER.png
Normal file
|
After Width: | Height: | Size: 41 KiB |
BIN
dark_mode/PERMISSIONS.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
dark_mode/Placeholders.png
Normal file
|
After Width: | Height: | Size: 8.3 KiB |
BIN
dark_mode/Placeholders2.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
dark_mode/STEPS.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
dark_mode/eCloud.png
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
BIN
dark_mode/wiki.png
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
119
pom.xml
@@ -1,119 +0,0 @@
|
|||||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
|
|
||||||
<groupId>me.clip</groupId>
|
|
||||||
<artifactId>placeholderapi</artifactId>
|
|
||||||
|
|
||||||
<version>2.10.0</version>
|
|
||||||
<name>PlaceholderAPI</name>
|
|
||||||
<description>An awesome placeholder provider!</description>
|
|
||||||
<url>http://extendedclip.com</url>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<repositories>
|
|
||||||
<repository>
|
|
||||||
<id>spigot-repo</id>
|
|
||||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
|
||||||
</repository>
|
|
||||||
<repository>
|
|
||||||
<id>bstats-repo</id>
|
|
||||||
<url>http://repo.bstats.org/content/repositories/releases/</url>
|
|
||||||
</repository>
|
|
||||||
<repository>
|
|
||||||
<id>rayzr-repo</id>
|
|
||||||
<url>https://cdn.rawgit.com/Rayzr522/maven-repo/master/</url>
|
|
||||||
</repository>
|
|
||||||
</repositories>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.spigotmc</groupId>
|
|
||||||
<artifactId>spigot-api</artifactId>
|
|
||||||
<version>1.14-R0.1-SNAPSHOT</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.google.code.gson</groupId>
|
|
||||||
<artifactId>gson</artifactId>
|
|
||||||
<version>2.8.5</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.bstats</groupId>
|
|
||||||
<artifactId>bstats-bukkit</artifactId>
|
|
||||||
<version>1.2</version>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>me.rayzr522</groupId>
|
|
||||||
<artifactId>jsonmessage</artifactId>
|
|
||||||
<version>1.0.0</version>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<defaultGoal>clean package</defaultGoal>
|
|
||||||
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
|
||||||
<version>2.3.2</version>
|
|
||||||
<configuration>
|
|
||||||
<finalName>${project.name}-${project.version}</finalName>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<version>3.7.0</version>
|
|
||||||
<configuration>
|
|
||||||
<source>1.8</source>
|
|
||||||
<target>1.8</target>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
|
||||||
<version>3.1.0</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>shade</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<minimizeJar>false</minimizeJar>
|
|
||||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
|
||||||
<relocations>
|
|
||||||
<relocation>
|
|
||||||
<pattern>org.bstats</pattern>
|
|
||||||
<shadedPattern>me.clip.placeholderapi.metrics</shadedPattern>
|
|
||||||
</relocation>
|
|
||||||
<relocation>
|
|
||||||
<pattern>me.rayzr522</pattern>
|
|
||||||
<shadedPattern>me.clip.placeholderapi.util</shadedPattern>
|
|
||||||
</relocation>
|
|
||||||
<relocation>
|
|
||||||
<pattern>com.google.code.gson</pattern>
|
|
||||||
<shadedPattern>me.clip.placeholderapi.libs.gson</shadedPattern>
|
|
||||||
</relocation>
|
|
||||||
</relocations>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
<resources>
|
|
||||||
<resource>
|
|
||||||
<directory>src/main/resources</directory>
|
|
||||||
<filtering>true</filtering>
|
|
||||||
</resource>
|
|
||||||
</resources>
|
|
||||||
</build>
|
|
||||||
</project>
|
|
||||||
@@ -1,391 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* PlaceholderAPI
|
|
||||||
* Copyright (C) 2018 Ryan McCarthy
|
|
||||||
*
|
|
||||||
* 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 me.clip.placeholderapi;
|
|
||||||
|
|
||||||
import static me.clip.placeholderapi.util.Msg.color;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import me.clip.placeholderapi.events.ExpansionRegisterEvent;
|
|
||||||
import me.clip.placeholderapi.events.ExpansionUnregisterEvent;
|
|
||||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
|
||||||
import me.clip.placeholderapi.expansion.Relational;
|
|
||||||
import org.apache.commons.lang.Validate;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.OfflinePlayer;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.plugin.Plugin;
|
|
||||||
|
|
||||||
public class PlaceholderAPI {
|
|
||||||
|
|
||||||
private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile("[%]([^%]+)[%]");
|
|
||||||
private static final Pattern BRACKET_PLACEHOLDER_PATTERN = Pattern.compile("[{]([^{}]+)[}]");
|
|
||||||
private static final Pattern RELATIONAL_PLACEHOLDER_PATTERN = Pattern.compile("[%](rel_)([^%]+)[%]");
|
|
||||||
private static final Map<String, PlaceholderHook> placeholders = new HashMap<>();
|
|
||||||
|
|
||||||
private PlaceholderAPI() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* check if a specific placeholder identifier is currently registered
|
|
||||||
*
|
|
||||||
* @param identifier to check
|
|
||||||
* @return true if identifier is already registered
|
|
||||||
*/
|
|
||||||
public static boolean isRegistered(String identifier) {
|
|
||||||
return getRegisteredIdentifiers().stream().filter(id -> id.equalsIgnoreCase(identifier))
|
|
||||||
.findFirst().orElse(null) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a new placeholder hook
|
|
||||||
*
|
|
||||||
* @param identifier Identifier of the placeholder -> "%(identifier)_(args...)%
|
|
||||||
* @param placeholderHook implementing class that contains the onPlaceholderRequest method which
|
|
||||||
* is called when a value is needed for the specific placeholder
|
|
||||||
* @return true if the hook was successfully registered, false if there is already a hook
|
|
||||||
* registered for the specified identifier
|
|
||||||
*/
|
|
||||||
public static boolean registerPlaceholderHook(String identifier,
|
|
||||||
PlaceholderHook placeholderHook) {
|
|
||||||
Validate.notNull(identifier, "Identifier can not be null");
|
|
||||||
Validate.notNull(placeholderHook, "Placeholderhook can not be null");
|
|
||||||
if (isRegistered(identifier)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
placeholders.put(identifier.toLowerCase(), placeholderHook);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* unregister a placeholder hook by identifier
|
|
||||||
*
|
|
||||||
* @param identifier the identifier for the placeholder hook to unregister
|
|
||||||
* @return true if the placeholder hook was successfully unregistered, false if there was no
|
|
||||||
* placeholder hook registered for the identifier specified
|
|
||||||
*/
|
|
||||||
public static boolean unregisterPlaceholderHook(String identifier) {
|
|
||||||
Validate.notNull(identifier, "Identifier can not be null");
|
|
||||||
return placeholders.remove(identifier.toLowerCase()) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all registered placeholder identifiers
|
|
||||||
*
|
|
||||||
* @return all registered placeholder identifiers
|
|
||||||
*/
|
|
||||||
public static Set<String> getRegisteredIdentifiers() {
|
|
||||||
return ImmutableSet.copyOf(placeholders.keySet());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get map of registered placeholders
|
|
||||||
*
|
|
||||||
* @return copy of the internal placeholder map
|
|
||||||
*/
|
|
||||||
public static Map<String, PlaceholderHook> getPlaceholders() {
|
|
||||||
return ImmutableMap.copyOf(placeholders);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Set<PlaceholderExpansion> getExpansions() {
|
|
||||||
Set<PlaceholderExpansion> set = getPlaceholders().values().stream()
|
|
||||||
.filter(PlaceholderExpansion.class::isInstance).map(PlaceholderExpansion.class::cast)
|
|
||||||
.collect(Collectors.toCollection(HashSet::new));
|
|
||||||
return ImmutableSet.copyOf(set);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* check if a String contains any PlaceholderAPI placeholders
|
|
||||||
*
|
|
||||||
* @param text String to check
|
|
||||||
* @return true if String contains any registered placeholder identifiers, false otherwise
|
|
||||||
*/
|
|
||||||
public static boolean containsPlaceholders(String text) {
|
|
||||||
return text != null && PLACEHOLDER_PATTERN.matcher(text).find();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* check if a String contains any PlaceholderAPI bracket placeholders
|
|
||||||
*
|
|
||||||
* @param text String to check
|
|
||||||
* @return true if String contains any registered placeholder identifiers, false otherwise
|
|
||||||
*/
|
|
||||||
public static boolean containsBracketPlaceholders(String text) {
|
|
||||||
return text != null && BRACKET_PLACEHOLDER_PATTERN.matcher(text).find();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* set placeholders in the list<String> text provided placeholders are matched with the pattern
|
|
||||||
* {<placeholder>} when set with this method
|
|
||||||
*
|
|
||||||
* @param p Player to parse the placeholders for
|
|
||||||
* @param text text to set the placeholder values in
|
|
||||||
* @return modified list with all placeholders set to the corresponding values
|
|
||||||
*/
|
|
||||||
public static List<String> setBracketPlaceholders(OfflinePlayer p, List<String> text) {
|
|
||||||
return setPlaceholders(p, text, BRACKET_PLACEHOLDER_PATTERN);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* set placeholders in the list<String> text provided placeholders are matched with the pattern
|
|
||||||
* %(identifier)_(params)>% when set with this method
|
|
||||||
*
|
|
||||||
* @param p Player to parse the placeholders for
|
|
||||||
* @param text text to parse the placeholder values in
|
|
||||||
* @return modified list with all placeholders set to the corresponding values
|
|
||||||
*/
|
|
||||||
public static List<String> setPlaceholders(OfflinePlayer p, List<String> text) {
|
|
||||||
return setPlaceholders(p, text, PLACEHOLDER_PATTERN);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* set placeholders in the list<String> text provided placeholders are matched with the pattern
|
|
||||||
* %(identifier)_(params)>% when set with this method
|
|
||||||
*
|
|
||||||
* @param p Player to parse the placeholders for
|
|
||||||
* @param text text to parse the placeholder values in
|
|
||||||
* @return modified list with all placeholders set to the corresponding values
|
|
||||||
*/
|
|
||||||
public static List<String> setPlaceholders(OfflinePlayer p, List<String> text, Pattern pattern) {
|
|
||||||
if (text == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return text.stream().map(line -> setPlaceholders(p, line, pattern))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* set placeholders in the text specified placeholders are matched with the pattern
|
|
||||||
* {<placeholder>} when set with this method
|
|
||||||
*
|
|
||||||
* @param player Player to parse the placeholders for
|
|
||||||
* @param text text to parse the placeholder values to
|
|
||||||
* @return modified text with all placeholders set to the corresponding values
|
|
||||||
*/
|
|
||||||
public static String setBracketPlaceholders(OfflinePlayer player, String text) {
|
|
||||||
return setPlaceholders(player, text, BRACKET_PLACEHOLDER_PATTERN);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* set placeholders in the text specified placeholders are matched with the pattern
|
|
||||||
* %<(identifier)_(params)>% when set with this method
|
|
||||||
*
|
|
||||||
* @param player Player to parse the placeholders for
|
|
||||||
* @param text text to parse the placeholder values to
|
|
||||||
* @return text with all placeholders set to the corresponding values
|
|
||||||
*/
|
|
||||||
public static String setPlaceholders(OfflinePlayer player, String text) {
|
|
||||||
return setPlaceholders(player, text, PLACEHOLDER_PATTERN);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* set placeholders in the text specified placeholders are matched with the pattern
|
|
||||||
* %<(identifier)_(params)>% when set with this method
|
|
||||||
*
|
|
||||||
* @param player Player to parse the placeholders for
|
|
||||||
* @param text text to parse the placeholder values to
|
|
||||||
* @param placeholderPattern the pattern to match placeholders to. Capture group 1 must contain an
|
|
||||||
* underscore separating the identifier from the params
|
|
||||||
* @return text with all placeholders set to the corresponding values
|
|
||||||
*/
|
|
||||||
public static String setPlaceholders(OfflinePlayer player, String text,
|
|
||||||
Pattern placeholderPattern) {
|
|
||||||
if (text == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (placeholders.isEmpty()) {
|
|
||||||
return color(text);
|
|
||||||
}
|
|
||||||
Matcher m = placeholderPattern.matcher(text);
|
|
||||||
Map<String, PlaceholderHook> hooks = getPlaceholders();
|
|
||||||
while (m.find()) {
|
|
||||||
String format = m.group(1);
|
|
||||||
int index = format.indexOf("_");
|
|
||||||
if (index <= 0 || index >= format.length()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
String identifier = format.substring(0, index).toLowerCase();
|
|
||||||
String params = format.substring(index + 1);
|
|
||||||
if (hooks.containsKey(identifier)) {
|
|
||||||
String value = hooks.get(identifier).onRequest(player, params);
|
|
||||||
if (value != null) {
|
|
||||||
text = text.replaceAll(Pattern.quote(m.group()), Matcher.quoteReplacement(value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return color(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* set relational placeholders in the text specified placeholders are matched with the pattern
|
|
||||||
* %<rel_(identifier)_(params)>% when set with this method
|
|
||||||
*
|
|
||||||
* @param one Player to compare
|
|
||||||
* @param two Player to compare
|
|
||||||
* @param text text to parse the placeholder values to
|
|
||||||
* @return text with all relational placeholders set to the corresponding values
|
|
||||||
*/
|
|
||||||
public static List<String> setRelationalPlaceholders(Player one, Player two, List<String> text) {
|
|
||||||
if (text == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return text.stream().map(line -> setRelationalPlaceholders(one, two, line))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* set relational placeholders in the text specified placeholders are matched with the pattern
|
|
||||||
* %<rel_(identifier)_(params)>% when set with this method
|
|
||||||
*
|
|
||||||
* @param one Player to compare
|
|
||||||
* @param two Player to compare
|
|
||||||
* @param text text to parse the placeholder values to
|
|
||||||
* @return text with all relational placeholders set to the corresponding values
|
|
||||||
*/
|
|
||||||
public static String setRelationalPlaceholders(Player one, Player two, String text) {
|
|
||||||
if (text == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (placeholders.isEmpty()) {
|
|
||||||
return color(text);
|
|
||||||
}
|
|
||||||
Matcher m = RELATIONAL_PLACEHOLDER_PATTERN.matcher(text);
|
|
||||||
Map<String, PlaceholderHook> hooks = getPlaceholders();
|
|
||||||
while (m.find()) {
|
|
||||||
String format = m.group(2);
|
|
||||||
int index = format.indexOf("_");
|
|
||||||
if (index <= 0 || index >= format.length()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
String identifier = format.substring(0, index).toLowerCase();
|
|
||||||
String params = format.substring(index + 1);
|
|
||||||
if (hooks.containsKey(identifier)) {
|
|
||||||
if (!(hooks.get(identifier) instanceof Relational)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Relational rel = (Relational) hooks.get(identifier);
|
|
||||||
String value = rel.onPlaceholderRequest(one, two, params);
|
|
||||||
if (value != null) {
|
|
||||||
text = text.replaceAll(Pattern.quote(m.group()), Matcher.quoteReplacement(value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return color(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* unregister ALL placeholder hooks that are currently registered
|
|
||||||
*/
|
|
||||||
protected static void unregisterAll() {
|
|
||||||
unregisterAllProvidedExpansions();
|
|
||||||
placeholders.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* unregister all expansions provided by PlaceholderAPI
|
|
||||||
*/
|
|
||||||
public static void unregisterAllProvidedExpansions() {
|
|
||||||
if (placeholders.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
getPlaceholders().forEach((key, value) -> {
|
|
||||||
if (value instanceof PlaceholderExpansion) {
|
|
||||||
PlaceholderExpansion ex = (PlaceholderExpansion) value;
|
|
||||||
if (!ex.persist()) {
|
|
||||||
unregisterExpansion(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean registerExpansion(PlaceholderExpansion ex) {
|
|
||||||
if (registerPlaceholderHook(ex.getIdentifier(), ex)) {
|
|
||||||
Bukkit.getPluginManager().callEvent(new ExpansionRegisterEvent(ex));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean unregisterExpansion(PlaceholderExpansion ex) {
|
|
||||||
if (unregisterPlaceholderHook(ex.getIdentifier())) {
|
|
||||||
Bukkit.getPluginManager().callEvent(new ExpansionUnregisterEvent(ex));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Pattern getPlaceholderPattern() {
|
|
||||||
return PLACEHOLDER_PATTERN;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Pattern getBracketPlaceholderPattern() {
|
|
||||||
return BRACKET_PLACEHOLDER_PATTERN;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Pattern getRelationalPlaceholderPattern() {
|
|
||||||
return RELATIONAL_PLACEHOLDER_PATTERN;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public static Set<String> getRegisteredPlaceholderPlugins() {
|
|
||||||
return getRegisteredIdentifiers();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public static Set<String> getExternalPlaceholderPlugins() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public static boolean registerPlaceholderHook(Plugin plugin, PlaceholderHook placeholderHook) {
|
|
||||||
return plugin != null && registerPlaceholderHook(plugin.getName(), placeholderHook);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public static boolean unregisterPlaceholderHook(Plugin plugin) {
|
|
||||||
return plugin != null && unregisterPlaceholderHook(plugin.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String setPlaceholders(Player p, String text) {
|
|
||||||
return setPlaceholders((OfflinePlayer) p, text, PLACEHOLDER_PATTERN);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<String> setPlaceholders(Player p, List<String> text) {
|
|
||||||
return setPlaceholders((OfflinePlayer) p, text, PLACEHOLDER_PATTERN);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String setBracketPlaceholders(Player p, String text) {
|
|
||||||
return setPlaceholders((OfflinePlayer) p, text, BRACKET_PLACEHOLDER_PATTERN);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<String> setBracketPlaceholders(Player p, List<String> text) {
|
|
||||||
return setPlaceholders((OfflinePlayer) p, text, BRACKET_PLACEHOLDER_PATTERN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,260 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* PlaceholderAPI
|
|
||||||
* Copyright (C) 2018 Ryan McCarthy
|
|
||||||
*
|
|
||||||
* 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 me.clip.placeholderapi;
|
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import me.clip.placeholderapi.commands.PlaceholderAPICommands;
|
|
||||||
import me.clip.placeholderapi.configuration.PlaceholderAPIConfig;
|
|
||||||
import me.clip.placeholderapi.expansion.ExpansionManager;
|
|
||||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
|
||||||
import me.clip.placeholderapi.expansion.Version;
|
|
||||||
import me.clip.placeholderapi.expansion.cloud.ExpansionCloudManager;
|
|
||||||
import me.clip.placeholderapi.updatechecker.UpdateChecker;
|
|
||||||
import me.clip.placeholderapi.util.TimeUtil;
|
|
||||||
import org.bstats.bukkit.Metrics;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.ChatColor;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Yes I have a shit load of work to do...
|
|
||||||
*
|
|
||||||
* @author Ryan McCarthy
|
|
||||||
*/
|
|
||||||
public class PlaceholderAPIPlugin extends JavaPlugin {
|
|
||||||
|
|
||||||
private static PlaceholderAPIPlugin instance;
|
|
||||||
private static SimpleDateFormat dateFormat;
|
|
||||||
private static String booleanTrue;
|
|
||||||
private static String booleanFalse;
|
|
||||||
private static Version serverVersion;
|
|
||||||
private PlaceholderAPIConfig config;
|
|
||||||
private ExpansionManager expansionManager;
|
|
||||||
private ExpansionCloudManager expansionCloud;
|
|
||||||
private long startTime;
|
|
||||||
|
|
||||||
private static Version getVersion() {
|
|
||||||
String v = "unknown";
|
|
||||||
boolean spigot = false;
|
|
||||||
try {
|
|
||||||
v = Bukkit.getServer().getClass().getPackage().getName()
|
|
||||||
.split("\\.")[3];
|
|
||||||
} catch (ArrayIndexOutOfBoundsException ex) {
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Class.forName("org.spigotmc.SpigotConfig");
|
|
||||||
Class.forName("net.md_5.bungee.api.chat.BaseComponent");
|
|
||||||
spigot = true;
|
|
||||||
} catch (ExceptionInInitializerError | ClassNotFoundException exception) {
|
|
||||||
}
|
|
||||||
return new Version(v, spigot);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the static instance of the main class for PlaceholderAPI. This class is not the actual API
|
|
||||||
* class, this is the main class that extends JavaPlugin. For most API methods, use static methods
|
|
||||||
* available from the class: {@link PlaceholderAPI}
|
|
||||||
*
|
|
||||||
* @return PlaceholderAPIPlugin instance
|
|
||||||
*/
|
|
||||||
public static PlaceholderAPIPlugin getInstance() {
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the configurable {@linkplain SimpleDateFormat} object that is used to parse time for
|
|
||||||
* generic time based placeholders
|
|
||||||
*
|
|
||||||
* @return date format
|
|
||||||
*/
|
|
||||||
public static SimpleDateFormat getDateFormat() {
|
|
||||||
return dateFormat != null ? dateFormat : new SimpleDateFormat(
|
|
||||||
"MM/dd/yy HH:mm:ss");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the configurable {@linkplain String} value that should be returned when a boolean is true
|
|
||||||
*
|
|
||||||
* @return string value of true
|
|
||||||
*/
|
|
||||||
public static String booleanTrue() {
|
|
||||||
return booleanTrue != null ? booleanTrue : "true";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the configurable {@linkplain String} value that should be returned when a boolean is false
|
|
||||||
*
|
|
||||||
* @return string value of false
|
|
||||||
*/
|
|
||||||
public static String booleanFalse() {
|
|
||||||
return booleanFalse != null ? booleanFalse : "false";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Version getServerVersion() {
|
|
||||||
return serverVersion != null ? serverVersion : getVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoad() {
|
|
||||||
startTime = System.currentTimeMillis();
|
|
||||||
instance = this;
|
|
||||||
serverVersion = getVersion();
|
|
||||||
config = new PlaceholderAPIConfig(this);
|
|
||||||
expansionManager = new ExpansionManager(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnable() {
|
|
||||||
config.loadDefConfig();
|
|
||||||
setupOptions();
|
|
||||||
getCommand("placeholderapi").setExecutor(new PlaceholderAPICommands(this));
|
|
||||||
new PlaceholderListener(this);
|
|
||||||
getLogger().info("Placeholder expansion registration initializing...");
|
|
||||||
expansionManager.registerAllExpansions();
|
|
||||||
if (config.checkUpdates()) {
|
|
||||||
new UpdateChecker(this).fetch();
|
|
||||||
}
|
|
||||||
if (config.isCloudEnabled()) {
|
|
||||||
enableCloud();
|
|
||||||
}
|
|
||||||
setupMetrics();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDisable() {
|
|
||||||
disableCloud();
|
|
||||||
PlaceholderAPI.unregisterAll();
|
|
||||||
expansionManager.clean();
|
|
||||||
expansionManager = null;
|
|
||||||
Bukkit.getScheduler().cancelTasks(this);
|
|
||||||
serverVersion = null;
|
|
||||||
instance = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void reloadConf(CommandSender s) {
|
|
||||||
boolean cloudEnabled = this.expansionCloud != null;
|
|
||||||
expansionManager.clean();
|
|
||||||
PlaceholderAPI.unregisterAllProvidedExpansions();
|
|
||||||
reloadConfig();
|
|
||||||
setupOptions();
|
|
||||||
expansionManager.registerAllExpansions();
|
|
||||||
if (!config.isCloudEnabled()) {
|
|
||||||
disableCloud();
|
|
||||||
} else if (!cloudEnabled) {
|
|
||||||
enableCloud();
|
|
||||||
}
|
|
||||||
s.sendMessage(ChatColor.translateAlternateColorCodes('&',
|
|
||||||
PlaceholderAPI.getRegisteredIdentifiers().size()
|
|
||||||
+ " &aplaceholder hooks successfully registered!"));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupOptions() {
|
|
||||||
booleanTrue = config.booleanTrue();
|
|
||||||
if (booleanTrue == null) {
|
|
||||||
booleanTrue = "true";
|
|
||||||
}
|
|
||||||
booleanFalse = config.booleanFalse();
|
|
||||||
if (booleanFalse == null) {
|
|
||||||
booleanFalse = "false";
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
dateFormat = new SimpleDateFormat(config.dateFormat());
|
|
||||||
} catch (Exception e) {
|
|
||||||
dateFormat = new SimpleDateFormat("MM/dd/yy HH:mm:ss");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupMetrics() {
|
|
||||||
Metrics m = new Metrics(this);
|
|
||||||
m.addCustomChart(new Metrics.SimplePie("using_expansion_cloud",
|
|
||||||
() -> getExpansionCloud() != null ? "yes" : "no"));
|
|
||||||
|
|
||||||
m.addCustomChart(
|
|
||||||
new Metrics.SimplePie("using_spigot", () -> getServerVersion().isSpigot() ? "yes" : "no"));
|
|
||||||
|
|
||||||
m.addCustomChart(new Metrics.AdvancedPie("expansions_used", () -> {
|
|
||||||
Map<String, Integer> map = new HashMap<>();
|
|
||||||
Map<String, PlaceholderHook> p = PlaceholderAPI.getPlaceholders();
|
|
||||||
|
|
||||||
if (!p.isEmpty()) {
|
|
||||||
|
|
||||||
for (PlaceholderHook hook : p.values()) {
|
|
||||||
if (hook instanceof PlaceholderExpansion) {
|
|
||||||
PlaceholderExpansion ex = (PlaceholderExpansion) hook;
|
|
||||||
map.put(ex.getRequiredPlugin() == null ? ex.getIdentifier()
|
|
||||||
: ex.getRequiredPlugin(), 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
|
|
||||||
}));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void enableCloud() {
|
|
||||||
if (expansionCloud == null) {
|
|
||||||
expansionCloud = new ExpansionCloudManager(this);
|
|
||||||
expansionCloud.fetch(config.cloudAllowUnverifiedExpansions());
|
|
||||||
} else {
|
|
||||||
expansionCloud.clean();
|
|
||||||
expansionCloud.fetch(config.cloudAllowUnverifiedExpansions());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void disableCloud() {
|
|
||||||
if (expansionCloud != null) {
|
|
||||||
expansionCloud.clean();
|
|
||||||
expansionCloud = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtain the configuration class for PlaceholderAPI.
|
|
||||||
*
|
|
||||||
* @return PlaceholderAPIConfig instance
|
|
||||||
*/
|
|
||||||
public PlaceholderAPIConfig getPlaceholderAPIConfig() {
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExpansionManager getExpansionManager() {
|
|
||||||
return expansionManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExpansionCloudManager getExpansionCloud() {
|
|
||||||
return expansionCloud;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUptime() {
|
|
||||||
return TimeUtil
|
|
||||||
.getTime((int) TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() - startTime));
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getUptimeMillis() {
|
|
||||||
return (System.currentTimeMillis() - startTime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* PlaceholderAPI
|
|
||||||
* Copyright (C) 2018 Ryan McCarthy
|
|
||||||
*
|
|
||||||
* 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 me.clip.placeholderapi;
|
|
||||||
|
|
||||||
import org.bukkit.OfflinePlayer;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public abstract class PlaceholderHook {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* called when a placeholder value is requested from this hook
|
|
||||||
*
|
|
||||||
* @param p {@link OfflinePlayer} to request the placeholder value for, null if not needed for a
|
|
||||||
* player
|
|
||||||
* @param params String passed to the hook to determine what value to return
|
|
||||||
* @return value for the requested player and params
|
|
||||||
*/
|
|
||||||
public String onRequest(OfflinePlayer p, String params) {
|
|
||||||
if (p != null && p.isOnline()) {
|
|
||||||
return onPlaceholderRequest((Player) p, params);
|
|
||||||
}
|
|
||||||
return onPlaceholderRequest(null, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* called when a placeholder is requested from this hook
|
|
||||||
*
|
|
||||||
* @param p {@link Player} to request the placeholder value for, null if not needed for a player
|
|
||||||
* @param params String passed to the hook to determine what value to return
|
|
||||||
* @return value for the requested player and params
|
|
||||||
*/
|
|
||||||
public String onPlaceholderRequest(Player p, String params) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,157 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* PlaceholderAPI
|
|
||||||
* Copyright (C) 2018 Ryan McCarthy
|
|
||||||
*
|
|
||||||
* 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 me.clip.placeholderapi;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Set;
|
|
||||||
import me.clip.placeholderapi.events.ExpansionUnregisterEvent;
|
|
||||||
import me.clip.placeholderapi.expansion.Cacheable;
|
|
||||||
import me.clip.placeholderapi.expansion.Cleanable;
|
|
||||||
import me.clip.placeholderapi.expansion.ExpansionManager;
|
|
||||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
|
||||||
import me.clip.placeholderapi.expansion.Taskable;
|
|
||||||
import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
|
|
||||||
import me.clip.placeholderapi.external.EZPlaceholderHook;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.HandlerList;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.player.PlayerQuitEvent;
|
|
||||||
import org.bukkit.event.server.PluginDisableEvent;
|
|
||||||
import org.bukkit.event.server.PluginEnableEvent;
|
|
||||||
|
|
||||||
|
|
||||||
public class PlaceholderListener implements Listener {
|
|
||||||
|
|
||||||
private PlaceholderAPIPlugin plugin;
|
|
||||||
|
|
||||||
public PlaceholderListener(PlaceholderAPIPlugin instance) {
|
|
||||||
plugin = instance;
|
|
||||||
Bukkit.getPluginManager().registerEvents(this, instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onExpansionUnregister(ExpansionUnregisterEvent event) {
|
|
||||||
|
|
||||||
if (event.getExpansion() instanceof Listener) {
|
|
||||||
HandlerList.unregisterAll((Listener) event.getExpansion());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.getExpansion() instanceof Taskable) {
|
|
||||||
((Taskable) event.getExpansion()).stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.getExpansion() instanceof Cacheable) {
|
|
||||||
((Cacheable) event.getExpansion()).clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (plugin.getExpansionCloud() != null) {
|
|
||||||
|
|
||||||
CloudExpansion ex = plugin.getExpansionCloud()
|
|
||||||
.getCloudExpansion(event.getExpansion().getName());
|
|
||||||
|
|
||||||
if (ex != null) {
|
|
||||||
ex.setHasExpansion(false);
|
|
||||||
ex.setShouldUpdate(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onEnable(PluginEnableEvent event) {
|
|
||||||
ExpansionManager m = plugin.getExpansionManager();
|
|
||||||
PlaceholderExpansion e = m.getCachedExpansion(event.getPlugin().getName().toLowerCase());
|
|
||||||
if (e != null && e.canRegister()) {
|
|
||||||
if (e.isRegistered() || m.registerExpansion(e)) {
|
|
||||||
m.removeCachedExpansion(e.getRequiredPlugin());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGH)
|
|
||||||
public void onPluginUnload(PluginDisableEvent e) {
|
|
||||||
|
|
||||||
String n = e.getPlugin().getName();
|
|
||||||
|
|
||||||
if (n == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n.equals(plugin.getName())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, PlaceholderHook> hooks = PlaceholderAPI.getPlaceholders();
|
|
||||||
|
|
||||||
for (Entry<String, PlaceholderHook> hook : hooks.entrySet()) {
|
|
||||||
|
|
||||||
PlaceholderHook i = hook.getValue();
|
|
||||||
|
|
||||||
if (i instanceof EZPlaceholderHook) {
|
|
||||||
|
|
||||||
EZPlaceholderHook h = (EZPlaceholderHook) i;
|
|
||||||
|
|
||||||
if (h.getPluginName() == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (h.getPluginName().equalsIgnoreCase(n)) {
|
|
||||||
if (PlaceholderAPI.unregisterPlaceholderHook(hook.getKey())) {
|
|
||||||
plugin.getLogger()
|
|
||||||
.info("Unregistered placeholder hook for placeholder: " + h.getPlaceholderName());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (i instanceof PlaceholderExpansion) {
|
|
||||||
|
|
||||||
PlaceholderExpansion ex = (PlaceholderExpansion) i;
|
|
||||||
|
|
||||||
if (ex.getRequiredPlugin() == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ex.getRequiredPlugin().equalsIgnoreCase(n)) {
|
|
||||||
if (PlaceholderAPI.unregisterExpansion(ex)) {
|
|
||||||
plugin.getLogger().info("Unregistered placeholder expansion: " + ex.getIdentifier());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onQuit(PlayerQuitEvent e) {
|
|
||||||
|
|
||||||
Set<PlaceholderExpansion> expansions = PlaceholderAPI.getExpansions();
|
|
||||||
|
|
||||||
if (expansions.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (PlaceholderExpansion ex : expansions) {
|
|
||||||
if (ex instanceof Cleanable) {
|
|
||||||
((Cleanable) ex).cleanup(e.getPlayer());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,443 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* PlaceholderAPI
|
|
||||||
* Copyright (C) 2018 Ryan McCarthy
|
|
||||||
*
|
|
||||||
* 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 me.clip.placeholderapi.commands;
|
|
||||||
|
|
||||||
import static me.clip.placeholderapi.util.Msg.color;
|
|
||||||
import static me.clip.placeholderapi.util.Msg.msg;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPI;
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
|
||||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
|
||||||
import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
|
|
||||||
import me.rayzr522.jsonmessage.JSONMessage;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandExecutor;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class ExpansionCloudCommands implements CommandExecutor {
|
|
||||||
|
|
||||||
private PlaceholderAPIPlugin plugin;
|
|
||||||
|
|
||||||
public ExpansionCloudCommands(PlaceholderAPIPlugin instance) {
|
|
||||||
plugin = instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCommand(CommandSender s, Command c, String label, String[] args) {
|
|
||||||
|
|
||||||
if (args.length == 1) {
|
|
||||||
msg(s, "&bExpansion cloud commands",
|
|
||||||
" ",
|
|
||||||
"&b/papi ecloud status",
|
|
||||||
"&fView status of the ecloud",
|
|
||||||
"&b/papi ecloud list <all/author> (page)",
|
|
||||||
"&fList all/author specific available expansions",
|
|
||||||
"&b/papi ecloud info <expansion name>",
|
|
||||||
"&fView information about a specific expansion available on the cloud",
|
|
||||||
"&b/papi ecloud versioninfo <expansion name> <version>",
|
|
||||||
"&fView information about a specific version of an expansion",
|
|
||||||
"&b/papi ecloud placeholders <expansion name>",
|
|
||||||
"&fView placeholders for an expansion",
|
|
||||||
"&b/papi ecloud download <expansion name> (version)",
|
|
||||||
"&fDownload an expansion from the ecloud",
|
|
||||||
"&b/papi ecloud refresh",
|
|
||||||
"&fFetch the most up to date list of expansions available.",
|
|
||||||
"&b/papi ecloud clear",
|
|
||||||
"&fClear the expansion cloud cache.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args[1].equalsIgnoreCase("refresh") || args[1].equalsIgnoreCase("update") || args[1]
|
|
||||||
.equalsIgnoreCase("fetch")) {
|
|
||||||
msg(s, "&aRefresh task started. Use &f/papi ecloud list all &ain a few!!");
|
|
||||||
plugin.getExpansionCloud().clean();
|
|
||||||
plugin.getExpansionCloud().fetch(plugin.getPlaceholderAPIConfig().cloudAllowUnverifiedExpansions());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (plugin.getExpansionCloud().getCloudExpansions().isEmpty()) {
|
|
||||||
msg(s, "&7No cloud expansions are available at this time.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args[1].equalsIgnoreCase("clear")) {
|
|
||||||
plugin.getExpansionCloud().clean();
|
|
||||||
msg(s, "&aThe cache has been cleared!!");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args[1].equalsIgnoreCase("status")) {
|
|
||||||
|
|
||||||
msg(s, "&bThere are &f" + plugin.getExpansionCloud().getCloudExpansions().size()
|
|
||||||
+ " &bexpansions available on the cloud.",
|
|
||||||
"&7A total of &f" + plugin.getExpansionCloud().getCloudAuthorCount()
|
|
||||||
+ " &7authors have contributed to the expansion cloud.");
|
|
||||||
if (plugin.getExpansionCloud().getToUpdateCount() > 0) {
|
|
||||||
msg(s, "&eYou have &f" + plugin.getExpansionCloud().getToUpdateCount()
|
|
||||||
+ " &eexpansions installed that have updates available.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args[1].equalsIgnoreCase("info")) {
|
|
||||||
|
|
||||||
if (args.length < 3) {
|
|
||||||
msg(s, "&cAn expansion name must be specified!");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
CloudExpansion expansion = plugin.getExpansionCloud().getCloudExpansion(args[2]);
|
|
||||||
|
|
||||||
if (expansion == null) {
|
|
||||||
msg(s, "&cNo expansion found by the name: &f" + args[2]);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(s instanceof Player)) {
|
|
||||||
msg(s,
|
|
||||||
(expansion.shouldUpdate() ? "&e" : "") + expansion.getName() + " &8&m-- &r" + expansion
|
|
||||||
.getVersion().getUrl());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Player p = (Player) s;
|
|
||||||
|
|
||||||
msg(s, "&bExpansion&7: &f" + expansion.getName(),
|
|
||||||
"&bAuthor: &f" + expansion.getAuthor(),
|
|
||||||
"&bVerified: &f" + expansion.isVerified()
|
|
||||||
);
|
|
||||||
|
|
||||||
// latest version
|
|
||||||
JSONMessage latestVersion = JSONMessage
|
|
||||||
.create(color("&bLatest version: &f" + expansion.getLatestVersion()));
|
|
||||||
latestVersion.tooltip(color("&bReleased: &f" + expansion.getTimeSinceLastUpdate()
|
|
||||||
+ "\n&bUpdate information: &f" + expansion.getVersion().getReleaseNotes()
|
|
||||||
));
|
|
||||||
latestVersion.send(p);
|
|
||||||
|
|
||||||
// versions
|
|
||||||
JSONMessage versions = JSONMessage
|
|
||||||
.create(color("&bVersions available: &f" + expansion.getVersions().size()));
|
|
||||||
versions.tooltip(color(String.join("&b, &f", expansion.getAvailableVersions())));
|
|
||||||
versions.suggestCommand(
|
|
||||||
"/papi ecloud versioninfo " + expansion.getName() + " " + expansion.getLatestVersion());
|
|
||||||
versions.send(p);
|
|
||||||
|
|
||||||
// placeholders
|
|
||||||
if (expansion.getPlaceholders() != null) {
|
|
||||||
JSONMessage placeholders = JSONMessage
|
|
||||||
.create(color("&bPlaceholders: &f" + expansion.getPlaceholders().size()));
|
|
||||||
placeholders.tooltip(color(String.join("&b, &f", expansion.getPlaceholders())));
|
|
||||||
placeholders.suggestCommand("/papi ecloud placeholders " + expansion.getName());
|
|
||||||
placeholders.send(p);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args[1].equalsIgnoreCase("versioninfo")) {
|
|
||||||
|
|
||||||
if (args.length < 4) {
|
|
||||||
msg(s, "&cAn expansion name and version must be specified!");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
CloudExpansion expansion = plugin.getExpansionCloud().getCloudExpansion(args[2]);
|
|
||||||
|
|
||||||
if (expansion == null) {
|
|
||||||
msg(s, "&cNo expansion found by the name: &f" + args[2]);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
CloudExpansion.Version version = expansion.getVersion(args[3]);
|
|
||||||
|
|
||||||
if (version == null) {
|
|
||||||
msg(s, "&cThe version specified does not exist for expansion: &f" + expansion.getName());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg(s, "&bExpansion: " + (expansion.shouldUpdate() ? "&e" : "&f") + expansion.getName(),
|
|
||||||
"&bVersion: &f" + version.getVersion(),
|
|
||||||
"&bVersion info: &f" + version.getReleaseNotes());
|
|
||||||
|
|
||||||
if (!(s instanceof Player)) {
|
|
||||||
msg(s, "&bDownload url: " + version.getUrl());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Player p = (Player) s;
|
|
||||||
|
|
||||||
JSONMessage download = JSONMessage.create(color("&7Click to download this version"));
|
|
||||||
download.suggestCommand(
|
|
||||||
"/papi ecloud download " + expansion.getName() + " " + version.getVersion());
|
|
||||||
download.send(p);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args[1].equalsIgnoreCase("placeholders")) {
|
|
||||||
|
|
||||||
if (args.length < 3) {
|
|
||||||
msg(s, "&cAn expansion name must be specified!");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
CloudExpansion expansion = plugin.getExpansionCloud().getCloudExpansion(args[2]);
|
|
||||||
|
|
||||||
if (expansion == null) {
|
|
||||||
msg(s, "&cNo expansion found by the name: &f" + args[2]);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> placeholders = expansion.getPlaceholders();
|
|
||||||
|
|
||||||
if (placeholders == null) {
|
|
||||||
msg(s, "&cThe expansion: &f" + expansion.getName()
|
|
||||||
+ " &cdoes not have any placeholders listed.",
|
|
||||||
"&7You should contact &f" + expansion.getAuthor() + " &7and ask for them to be added.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(s instanceof Player)
|
|
||||||
|| plugin.getExpansionManager().getRegisteredExpansion(expansion.getName()) == null) {
|
|
||||||
msg(s, "&bPlaceholders: &f" + placeholders.size(),
|
|
||||||
String.join("&a, &f", placeholders));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Player p = (Player) s;
|
|
||||||
JSONMessage message = JSONMessage.create(color("&bPlaceholders: &f" + placeholders.size()));
|
|
||||||
message.then("\n");
|
|
||||||
|
|
||||||
for (int i = 0; i < placeholders.size(); i++) {
|
|
||||||
if (i == placeholders.size() - 1) {
|
|
||||||
message.then(placeholders.get(i));
|
|
||||||
} else {
|
|
||||||
message.then(color(placeholders.get(i) + "&b, &f"));
|
|
||||||
}
|
|
||||||
message.tooltip(PlaceholderAPI.setPlaceholders(p, placeholders.get(i)));
|
|
||||||
}
|
|
||||||
|
|
||||||
message.send(p);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args[1].equalsIgnoreCase("list")) {
|
|
||||||
|
|
||||||
int page = 1;
|
|
||||||
|
|
||||||
String author;
|
|
||||||
boolean installed = false;
|
|
||||||
|
|
||||||
if (args.length < 3) {
|
|
||||||
msg(s, "&cIncorrect usage! &7/papi ecloud list <all/author/installed> (page)");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
author = args[2];
|
|
||||||
|
|
||||||
if (author.equalsIgnoreCase("all")) {
|
|
||||||
author = null;
|
|
||||||
} else if (author.equalsIgnoreCase("installed")) {
|
|
||||||
author = null;
|
|
||||||
installed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.length >= 4) {
|
|
||||||
try {
|
|
||||||
page = Integer.parseInt(args[3]);
|
|
||||||
} catch (NumberFormatException ex) {
|
|
||||||
msg(s, "&cPage number must be an integer!");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (page < 1) {
|
|
||||||
msg(s, "&cPage must be greater than or equal to 1!");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int avail;
|
|
||||||
|
|
||||||
Map<Integer, CloudExpansion> ex;
|
|
||||||
|
|
||||||
if (installed) {
|
|
||||||
ex = plugin.getExpansionCloud().getAllInstalled();
|
|
||||||
} else if (author == null) {
|
|
||||||
ex = plugin.getExpansionCloud().getCloudExpansions();
|
|
||||||
} else {
|
|
||||||
ex = plugin.getExpansionCloud().getAllByAuthor(author);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ex == null || ex.isEmpty()) {
|
|
||||||
msg(s, "&cNo expansions available" + (author != null ? " for author &f" + author : ""));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
avail = plugin.getExpansionCloud().getPagesAvailable(ex, 10);
|
|
||||||
|
|
||||||
if (page > avail) {
|
|
||||||
msg(s, "&cThere " + ((avail == 1) ? " is only &f" + avail + " &cpage available!"
|
|
||||||
: "are only &f" + avail + " &cpages available!"));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg(s, "&bShowing expansions for&7: &f" + (author != null ? author
|
|
||||||
: (installed ? "all installed" : "all available")) + " &8&m--&r &bamount&7: &f" + ex
|
|
||||||
.size() + " &bpage&7: &f" + page + "&7/&f" + avail);
|
|
||||||
|
|
||||||
ex = plugin.getExpansionCloud().getPage(ex, page, 10);
|
|
||||||
|
|
||||||
if (ex == null) {
|
|
||||||
msg(s, "&cThere was a problem getting the requested page...");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg(s, "&aGreen = Expansions you have");
|
|
||||||
msg(s, "&6Gold = Expansions which need updated");
|
|
||||||
|
|
||||||
if (!(s instanceof Player)) {
|
|
||||||
Map<String, CloudExpansion> expansions = new HashMap<>();
|
|
||||||
for (CloudExpansion exp : ex.values()) {
|
|
||||||
if (exp == null || exp.getName() == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
expansions.put(exp.getName(), exp);
|
|
||||||
}
|
|
||||||
List<String> ce = expansions.keySet().stream().sorted().collect(Collectors.toList());
|
|
||||||
int i = 1;
|
|
||||||
for (String name : ce) {
|
|
||||||
if (expansions.get(name) == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
CloudExpansion expansion = expansions.get(name);
|
|
||||||
msg(s,
|
|
||||||
"&b" + i + "&7: " + (expansion.shouldUpdate() ? "&6"
|
|
||||||
: (expansion.hasExpansion() ? "&a" : "&7")) + expansion
|
|
||||||
.getName() + " &8&m-- &r" + expansion.getVersion().getUrl());
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Player p = (Player) s;
|
|
||||||
|
|
||||||
Map<String, CloudExpansion> expansions = new HashMap<>();
|
|
||||||
for (CloudExpansion exp : ex.values()) {
|
|
||||||
if (exp == null || exp.getName() == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
expansions.put(exp.getName(), exp);
|
|
||||||
}
|
|
||||||
List<String> ce = expansions.keySet().stream().sorted().collect(Collectors.toList());
|
|
||||||
int i = 1;
|
|
||||||
for (String name : ce) {
|
|
||||||
if (expansions.get(name) == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
CloudExpansion expansion = expansions.get(name);
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
if (expansion.shouldUpdate()) {
|
|
||||||
sb.append("&6Click to update to the latest version of this expansion\n\n");
|
|
||||||
} else if (!expansion.hasExpansion()) {
|
|
||||||
sb.append("&bClick to download this expansion\n\n");
|
|
||||||
} else {
|
|
||||||
sb.append("&aYou have the latest version of this expansion\n\n");
|
|
||||||
}
|
|
||||||
sb.append("&bAuthor&7: &f" + expansion.getAuthor() + "\n");
|
|
||||||
sb.append("&bVerified&7: &f" + expansion.isVerified() + "\n");
|
|
||||||
sb.append("&bLatest version&7: &f" + expansion.getVersion().getVersion() + "\n");
|
|
||||||
sb.append(
|
|
||||||
"&bLast updated&7: &f" + expansion.getTimeSinceLastUpdate() + " ago\n");
|
|
||||||
sb.append("\n" + expansion.getDescription());
|
|
||||||
|
|
||||||
String msg = color(
|
|
||||||
"&b" + (i + 1) + "&7: " + (expansion.shouldUpdate() ? "&6"
|
|
||||||
: (expansion.hasExpansion() ? "&a" : "")) + expansion.getName());
|
|
||||||
|
|
||||||
String hover = color(sb.toString());
|
|
||||||
|
|
||||||
JSONMessage line = JSONMessage.create(msg);
|
|
||||||
line.tooltip(hover);
|
|
||||||
if (expansion.shouldUpdate()) {
|
|
||||||
line.suggestCommand("/papi ecloud download " + expansion.getName());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
line.suggestCommand("/papi ecloud info " + expansion.getName());
|
|
||||||
}
|
|
||||||
line.send(p);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args[1].equalsIgnoreCase("download")) {
|
|
||||||
|
|
||||||
if (args.length < 3) {
|
|
||||||
msg(s, "&cAn expansion name must be specified!");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
CloudExpansion expansion = plugin.getExpansionCloud().getCloudExpansion(args[2]);
|
|
||||||
|
|
||||||
if (expansion == null) {
|
|
||||||
msg(s, "&cNo expansion found with the name: &f" + args[2]);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
PlaceholderExpansion loaded = plugin.getExpansionManager().getRegisteredExpansion(args[2]);
|
|
||||||
|
|
||||||
if (loaded != null && loaded.isRegistered()) {
|
|
||||||
PlaceholderAPI.unregisterPlaceholderHook(loaded.getIdentifier());
|
|
||||||
}
|
|
||||||
|
|
||||||
String version = expansion.getLatestVersion();
|
|
||||||
|
|
||||||
if (args.length == 4) {
|
|
||||||
version = args[3];
|
|
||||||
if (expansion.getVersion(version) == null) {
|
|
||||||
msg(s, "&cThe version you specified does not exist for &f" + expansion.getName());
|
|
||||||
msg(s, "&7Available versions: &f" + expansion.getVersions().size());
|
|
||||||
msg(s, String.join("&a, &f", expansion.getAvailableVersions()));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
msg(s, "&aDownload starting for expansion: &f" + expansion.getName() + " &aversion: &f"
|
|
||||||
+ version);
|
|
||||||
String player = ((s instanceof Player) ? s.getName() : null);
|
|
||||||
plugin.getExpansionCloud().downloadExpansion(player, expansion, version);
|
|
||||||
plugin.getExpansionCloud().clean();
|
|
||||||
plugin.getExpansionCloud().fetch(plugin.getPlaceholderAPIConfig().cloudAllowUnverifiedExpansions());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg(s, "&cIncorrect usage! &b/papi ecloud");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,289 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* PlaceholderAPI
|
|
||||||
* Copyright (C) 2018 Ryan McCarthy
|
|
||||||
*
|
|
||||||
* 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 me.clip.placeholderapi.commands;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPI;
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
|
||||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
|
||||||
import me.clip.placeholderapi.util.Msg;
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.OfflinePlayer;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandExecutor;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class PlaceholderAPICommands implements CommandExecutor {
|
|
||||||
|
|
||||||
private PlaceholderAPIPlugin plugin;
|
|
||||||
private CommandExecutor eCloud;
|
|
||||||
|
|
||||||
public PlaceholderAPICommands(PlaceholderAPIPlugin i) {
|
|
||||||
plugin = i;
|
|
||||||
eCloud = new ExpansionCloudCommands(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCommand(CommandSender s, Command c, String label, String[] args) {
|
|
||||||
if (args.length == 0) {
|
|
||||||
|
|
||||||
Msg.msg(s, "PlaceholderAPI &7version &b&o" + plugin.getDescription().getVersion(),
|
|
||||||
"&fCreated by&7: &bextended_clip",
|
|
||||||
"&fPapi commands: &b/papi help",
|
|
||||||
"&fEcloud commands: &b/papi ecloud");
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
|
|
||||||
if (args[0].equalsIgnoreCase("help")) {
|
|
||||||
|
|
||||||
Msg.msg(s, "PlaceholderAPI &aHelp &e(&f" + plugin.getDescription().getVersion() + "&e)",
|
|
||||||
"&b/papi",
|
|
||||||
"&fView plugin info/version info",
|
|
||||||
"&b/papi list",
|
|
||||||
"&fList all placeholder expansions that are currently active",
|
|
||||||
"&b/papi info <placeholder name>",
|
|
||||||
"&fView information for a specific expansion",
|
|
||||||
"&b/papi parse <(playername)/me> <...args>",
|
|
||||||
"&fParse a String with placeholders",
|
|
||||||
"&b/papi bcparse <(playername)/me> <...args>",
|
|
||||||
"&fParse a String with placeholders and broadcast the message",
|
|
||||||
"&b/papi parserel <player one> <player two> <...args>",
|
|
||||||
"&fParse a String with relational placeholders",
|
|
||||||
"&b/papi register <fileName>",
|
|
||||||
"&fRegister an expansion by the name of the file",
|
|
||||||
"&b/papi unregister <Expansion name>",
|
|
||||||
"&fUnregister an expansion by name",
|
|
||||||
"&b/papi reload",
|
|
||||||
"&fReload the config settings");
|
|
||||||
if (s.hasPermission("placeholderapi.ecloud")) {
|
|
||||||
if (plugin.getExpansionCloud() == null) {
|
|
||||||
Msg.msg(s, "&b/papi enablecloud",
|
|
||||||
"&fEnable the expansion cloud");
|
|
||||||
} else {
|
|
||||||
Msg.msg(s, "&b/papi disablecloud",
|
|
||||||
"&fDisable the expansion cloud",
|
|
||||||
"&b/papi ecloud",
|
|
||||||
"&fView ecloud command usage");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} else if (args[0].equalsIgnoreCase("ecloud")) {
|
|
||||||
|
|
||||||
if (!s.hasPermission("placeholderapi.ecloud")) {
|
|
||||||
Msg.msg(s, "&cYou don't have permission to do that!");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (plugin.getExpansionCloud() == null) {
|
|
||||||
Msg.msg(s, "&7The expansion cloud is not enabled!");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return eCloud.onCommand(s, c, label, args);
|
|
||||||
} else if (args[0].equalsIgnoreCase("enablecloud")) {
|
|
||||||
|
|
||||||
if (!s.hasPermission("placeholderapi.ecloud")) {
|
|
||||||
Msg.msg(s, "&cYou don't have permission to do that!");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (plugin.getExpansionCloud() != null) {
|
|
||||||
Msg.msg(s, "&7The cloud is already enabled!");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
plugin.enableCloud();
|
|
||||||
plugin.getPlaceholderAPIConfig().setCloudEnabled(true);
|
|
||||||
Msg.msg(s, "&aThe cloud has been enabled!");
|
|
||||||
return true;
|
|
||||||
} else if (args[0].equalsIgnoreCase("disablecloud")) {
|
|
||||||
|
|
||||||
if (!s.hasPermission("placeholderapi.ecloud")) {
|
|
||||||
Msg.msg(s, "&cYou don't have permission to do that!");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (plugin.getExpansionCloud() == null) {
|
|
||||||
Msg.msg(s, "&7The cloud is already disabled!");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
plugin.disableCloud();
|
|
||||||
plugin.getPlaceholderAPIConfig().setCloudEnabled(false);
|
|
||||||
Msg.msg(s, "&aThe cloud has been disabled!");
|
|
||||||
return true;
|
|
||||||
} else if (args.length > 1 && args[0].equalsIgnoreCase("info")) {
|
|
||||||
|
|
||||||
if (!s.hasPermission("placeholderapi.info")) {
|
|
||||||
Msg.msg(s, "&cYou don't have permission to do that!");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
PlaceholderExpansion ex = plugin.getExpansionManager().getRegisteredExpansion(args[1]);
|
|
||||||
if (ex == null) {
|
|
||||||
Msg.msg(s, "&cThere is no expansion loaded with the identifier: &f" + args[1]);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
Msg.msg(s, "&7Placeholder expansion info for: &f" + ex.getName());
|
|
||||||
Msg.msg(s, "&7Status: " + (ex.isRegistered() ? "&aRegistered" : "&cNot registered"));
|
|
||||||
if (ex.getAuthor() != null) {
|
|
||||||
Msg.msg(s, "&7Created by: &f" + ex.getAuthor());
|
|
||||||
}
|
|
||||||
if (ex.getVersion() != null) {
|
|
||||||
Msg.msg(s, "&7Version: &f" + ex.getVersion());
|
|
||||||
}
|
|
||||||
if (ex.getRequiredPlugin() != null) {
|
|
||||||
Msg.msg(s, "&7Requires plugin: &f" + ex.getRequiredPlugin());
|
|
||||||
}
|
|
||||||
if (ex.getPlaceholders() != null) {
|
|
||||||
Msg.msg(s, "&8&m-- &r&7Placeholders &8&m--");
|
|
||||||
for (String placeholder : ex.getPlaceholders()) {
|
|
||||||
Msg.msg(s, placeholder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} else if (args.length > 2 && args[0].equalsIgnoreCase("parse")
|
|
||||||
|| args.length > 2 && args[0].equalsIgnoreCase("bcparse")) {
|
|
||||||
|
|
||||||
if (!s.hasPermission("placeholderapi.parse")) {
|
|
||||||
Msg.msg(s, "&cYou don't have permission to do that!");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
OfflinePlayer pl = null;
|
|
||||||
if (args[1].equalsIgnoreCase("me")) {
|
|
||||||
if (s instanceof Player) {
|
|
||||||
pl = (Player) s;
|
|
||||||
} else {
|
|
||||||
Msg.msg(s, "&cThis command must target a player when used by console");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (Bukkit.getPlayer(args[1]) != null) {
|
|
||||||
pl = Bukkit.getPlayer(args[1]);
|
|
||||||
} else {
|
|
||||||
pl = Bukkit.getOfflinePlayer(args[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pl == null || !pl.hasPlayedBefore()) {
|
|
||||||
Msg.msg(s, "&cFailed to find player: &f" + args[1]);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
String parse = StringUtils.join(args, " ", 2, args.length);
|
|
||||||
if (args[0].equalsIgnoreCase("bcparse")) {
|
|
||||||
Msg.broadcast("&r" + PlaceholderAPI.setPlaceholders(pl, parse));
|
|
||||||
} else {
|
|
||||||
Msg.msg(s, "&r" + PlaceholderAPI.setPlaceholders(pl, parse));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} else if (args.length > 3 && args[0].equalsIgnoreCase("parserel")) {
|
|
||||||
|
|
||||||
if (!(s instanceof Player)) {
|
|
||||||
Msg.msg(s, "&cThis command can only be used in game!");
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
if (!s.hasPermission("placeholderapi.parse")) {
|
|
||||||
Msg.msg(s, "&cYou don't have permission to do that!");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Player one = Bukkit.getPlayer(args[1]);
|
|
||||||
if (one == null) {
|
|
||||||
Msg.msg(s, args[1] + " &cis not online!");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
Player two = Bukkit.getPlayer(args[2]);
|
|
||||||
if (two == null) {
|
|
||||||
Msg.msg(s, args[2] + " &cis not online!");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
String parse = StringUtils.join(args, " ", 3, args.length);
|
|
||||||
Msg.msg(s, "&r" + PlaceholderAPI.setRelationalPlaceholders(one, two, parse));
|
|
||||||
return true;
|
|
||||||
} else if (args[0].equalsIgnoreCase("reload")) {
|
|
||||||
|
|
||||||
if (s instanceof Player) {
|
|
||||||
if (!s.hasPermission("placeholderapi.reload")) {
|
|
||||||
Msg.msg(s, "&cYou don't have permission to do that!");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Msg.msg(s, "&fPlaceholder&7API &bconfiguration reloaded!");
|
|
||||||
plugin.reloadConf(s);
|
|
||||||
} else if (args[0].equalsIgnoreCase("list")) {
|
|
||||||
|
|
||||||
if (s instanceof Player) {
|
|
||||||
if (!s.hasPermission("placeholderapi.list")) {
|
|
||||||
Msg.msg(s, "&cYou don't have permission to do that!");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<String> registered = PlaceholderAPI.getRegisteredIdentifiers();
|
|
||||||
if (registered.isEmpty()) {
|
|
||||||
Msg.msg(s, "&7There are no placeholder hooks currently registered!");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
Msg.msg(s, registered.size() + " &7Placeholder hooks registered:");
|
|
||||||
Msg.msg(s, registered.stream().sorted().collect(Collectors.joining(", ")));
|
|
||||||
} else if (args.length > 1 && args[0].equalsIgnoreCase("register")) {
|
|
||||||
|
|
||||||
if (s instanceof Player) {
|
|
||||||
if (!s.hasPermission("placeholderapi.register")) {
|
|
||||||
Msg.msg(s, "&cYou don't have permission to do that!");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String fileName = args[1].replace(".jar", "");
|
|
||||||
PlaceholderExpansion ex = plugin.getExpansionManager().registerExpansion(fileName);
|
|
||||||
|
|
||||||
if (ex == null) {
|
|
||||||
Msg.msg(s, "&cFailed to register expansion from " + fileName);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Msg.msg(s, "&aSuccessfully registered expansion: &f" + ex.getName());
|
|
||||||
} else if (args.length > 1 && args[0].equalsIgnoreCase("unregister")) {
|
|
||||||
|
|
||||||
if (s instanceof Player) {
|
|
||||||
if (!s.hasPermission("placeholderapi.register")) {
|
|
||||||
Msg.msg(s, "&cYou don't have permission to do that!");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PlaceholderExpansion ex = plugin.getExpansionManager().getRegisteredExpansion(args[1]);
|
|
||||||
|
|
||||||
if (ex == null) {
|
|
||||||
Msg.msg(s, "&cFailed to find expansion: &f" + args[1]);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PlaceholderAPI.unregisterExpansion(ex)) {
|
|
||||||
Msg.msg(s, "&aSuccessfully unregistered expansion: &f" + ex.getName());
|
|
||||||
} else {
|
|
||||||
Msg.msg(s, "&cFailed to unregister expansion: &f" + ex.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
Msg.msg(s, "&cIncorrect usage! &7/papi help");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* PlaceholderAPI
|
|
||||||
* Copyright (C) 2018 Ryan McCarthy
|
|
||||||
*
|
|
||||||
* 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 me.clip.placeholderapi.configuration;
|
|
||||||
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
|
||||||
|
|
||||||
public class PlaceholderAPIConfig {
|
|
||||||
|
|
||||||
private PlaceholderAPIPlugin plugin;
|
|
||||||
|
|
||||||
public PlaceholderAPIConfig(PlaceholderAPIPlugin i) {
|
|
||||||
plugin = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void loadDefConfig() {
|
|
||||||
plugin.saveDefaultConfig();
|
|
||||||
plugin.reloadConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean checkUpdates() {
|
|
||||||
return plugin.getConfig().getBoolean("check_updates");
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean cloudAllowUnverifiedExpansions() {
|
|
||||||
return plugin.getConfig().getBoolean("cloud_allow_unverified_expansions");
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isCloudEnabled() {
|
|
||||||
return plugin.getConfig().getBoolean("cloud_enabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCloudEnabled(boolean b) {
|
|
||||||
plugin.getConfig().set("cloud_enabled", b);
|
|
||||||
plugin.reloadConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String booleanTrue() {
|
|
||||||
return plugin.getConfig().getString("boolean.true");
|
|
||||||
}
|
|
||||||
|
|
||||||
public String booleanFalse() {
|
|
||||||
return plugin.getConfig().getString("boolean.false");
|
|
||||||
}
|
|
||||||
|
|
||||||
public String dateFormat() {
|
|
||||||
return plugin.getConfig().getString("date_format");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* PlaceholderAPI
|
|
||||||
* Copyright (C) 2018 Ryan McCarthy
|
|
||||||
*
|
|
||||||
* 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 me.clip.placeholderapi.events;
|
|
||||||
|
|
||||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
|
||||||
import org.bukkit.event.Event;
|
|
||||||
import org.bukkit.event.HandlerList;
|
|
||||||
|
|
||||||
public class ExpansionRegisterEvent extends Event {
|
|
||||||
|
|
||||||
private static final HandlerList HANDLERS = new HandlerList();
|
|
||||||
private PlaceholderExpansion expansion;
|
|
||||||
|
|
||||||
public ExpansionRegisterEvent(PlaceholderExpansion expansion) {
|
|
||||||
this.expansion = expansion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HandlerList getHandlerList() {
|
|
||||||
return HANDLERS;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HandlerList getHandlers() {
|
|
||||||
return HANDLERS;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PlaceholderExpansion getExpansion() {
|
|
||||||
return expansion;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* PlaceholderAPI
|
|
||||||
* Copyright (C) 2018 Ryan McCarthy
|
|
||||||
*
|
|
||||||
* 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 me.clip.placeholderapi.events;
|
|
||||||
|
|
||||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
|
||||||
import org.bukkit.event.Event;
|
|
||||||
import org.bukkit.event.HandlerList;
|
|
||||||
|
|
||||||
public class ExpansionUnregisterEvent extends Event {
|
|
||||||
|
|
||||||
private static final HandlerList HANDLERS = new HandlerList();
|
|
||||||
private PlaceholderExpansion expansion;
|
|
||||||
|
|
||||||
public ExpansionUnregisterEvent(PlaceholderExpansion expansion) {
|
|
||||||
this.expansion = expansion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HandlerList getHandlerList() {
|
|
||||||
return HANDLERS;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HandlerList getHandlers() {
|
|
||||||
return HANDLERS;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PlaceholderExpansion getExpansion() {
|
|
||||||
return expansion;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* PlaceholderAPI
|
|
||||||
* Copyright (C) 2018 Ryan McCarthy
|
|
||||||
*
|
|
||||||
* 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 me.clip.placeholderapi.events;
|
|
||||||
|
|
||||||
import me.clip.placeholderapi.PlaceholderHook;
|
|
||||||
import org.bukkit.event.Event;
|
|
||||||
import org.bukkit.event.HandlerList;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public class PlaceholderHookUnloadEvent extends Event {
|
|
||||||
|
|
||||||
private static final HandlerList HANDLERS = new HandlerList();
|
|
||||||
private String plugin;
|
|
||||||
private PlaceholderHook hook;
|
|
||||||
|
|
||||||
public PlaceholderHookUnloadEvent(String plugin, PlaceholderHook placeholderHook) {
|
|
||||||
this.plugin = plugin;
|
|
||||||
this.hook = placeholderHook;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HandlerList getHandlerList() {
|
|
||||||
return HANDLERS;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HandlerList getHandlers() {
|
|
||||||
return HANDLERS;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getHookName() {
|
|
||||||
return plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PlaceholderHook getHook() {
|
|
||||||
return hook;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* PlaceholderAPI
|
|
||||||
* Copyright (C) 2018 Ryan McCarthy
|
|
||||||
*
|
|
||||||
* 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 me.clip.placeholderapi.expansion;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This interface allows a class which extends a {@link PlaceholderExpansion} to have the clear
|
|
||||||
* method called when the implementing expansion is unregistered from PlaceholderAPI. This is useful
|
|
||||||
* if we want to do things when the implementing hook is unregistered
|
|
||||||
*
|
|
||||||
* @author Ryan McCarthy
|
|
||||||
*/
|
|
||||||
public interface Cacheable {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the implementing class is unregistered from PlaceholderAPI
|
|
||||||
*/
|
|
||||||
void clear();
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* PlaceholderAPI
|
|
||||||
* Copyright (C) 2018 Ryan McCarthy
|
|
||||||
*
|
|
||||||
* 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 me.clip.placeholderapi.expansion;
|
|
||||||
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This interface allows a class which extends a {@link PlaceholderExpansion} to have the cleanup
|
|
||||||
* method called every time a player leaves the server. This is useful if we want to clean up after
|
|
||||||
* the player
|
|
||||||
*
|
|
||||||
* @author Ryan McCarthy
|
|
||||||
*/
|
|
||||||
public interface Cleanable {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when a player leaves the server
|
|
||||||
*
|
|
||||||
* @param p (@link Player} who left the server
|
|
||||||
*/
|
|
||||||
void cleanup(Player p);
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* PlaceholderAPI
|
|
||||||
* Copyright (C) 2018 Ryan McCarthy
|
|
||||||
*
|
|
||||||
* 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 me.clip.placeholderapi.expansion;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Any {@link PlaceholderExpansion} class which implements configurable will have any options listed
|
|
||||||
* in the getDefaults map automatically added to the PlaceholderAPI config.yml file
|
|
||||||
*
|
|
||||||
* @author Ryan McCarthy
|
|
||||||
*/
|
|
||||||
public interface Configurable {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method will be called before the implementing class is registered to obtain a map of
|
|
||||||
* configuration options that the implementing class needs These paths and values will be added to
|
|
||||||
* the PlaceholderAPI config.yml in the configuration section expansions.(placeholder
|
|
||||||
* identifier).(your key): (your value)
|
|
||||||
*
|
|
||||||
* @return Map of config path / values which need to be added / removed from the PlaceholderAPI
|
|
||||||
* config.yml file
|
|
||||||
*/
|
|
||||||
Map<String, Object> getDefaults();
|
|
||||||
}
|
|
||||||
@@ -1,201 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* PlaceholderAPI
|
|
||||||
* Copyright (C) 2018 Ryan McCarthy
|
|
||||||
*
|
|
||||||
* 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 me.clip.placeholderapi.expansion;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPI;
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
|
||||||
import me.clip.placeholderapi.PlaceholderHook;
|
|
||||||
import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
|
|
||||||
import me.clip.placeholderapi.util.FileUtil;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
|
|
||||||
public final class ExpansionManager {
|
|
||||||
|
|
||||||
private final Map<String, PlaceholderExpansion> cache = new HashMap<>();
|
|
||||||
private PlaceholderAPIPlugin plugin;
|
|
||||||
|
|
||||||
public ExpansionManager(PlaceholderAPIPlugin instance) {
|
|
||||||
plugin = instance;
|
|
||||||
File f = new File(PlaceholderAPIPlugin.getInstance().getDataFolder(), "expansions");
|
|
||||||
if (!f.exists()) {
|
|
||||||
f.mkdirs();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clean() {
|
|
||||||
cache.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public PlaceholderExpansion getCachedExpansion(String plugin) {
|
|
||||||
return cache.getOrDefault(plugin, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean removeCachedExpansion(String identifier) {
|
|
||||||
return cache.remove(identifier) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PlaceholderExpansion getRegisteredExpansion(String name) {
|
|
||||||
for (Entry<String, PlaceholderHook> hook : PlaceholderAPI.getPlaceholders().entrySet()) {
|
|
||||||
if (hook.getValue() instanceof PlaceholderExpansion) {
|
|
||||||
if (name.equalsIgnoreCase(hook.getKey())) {
|
|
||||||
return (PlaceholderExpansion) hook.getValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean registerExpansion(PlaceholderExpansion expansion) {
|
|
||||||
if (expansion == null || expansion.getIdentifier() == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (expansion instanceof Configurable) {
|
|
||||||
Map<String, Object> defaults = ((Configurable) expansion).getDefaults();
|
|
||||||
String pre = "expansions." + expansion.getIdentifier() + ".";
|
|
||||||
FileConfiguration cfg = plugin.getConfig();
|
|
||||||
boolean save = false;
|
|
||||||
for (Entry<String, Object> entries : defaults.entrySet()) {
|
|
||||||
if (entries.getKey() == null || entries.getKey().isEmpty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (entries.getValue() == null) {
|
|
||||||
if (cfg.contains(pre + entries.getKey())) {
|
|
||||||
save = true;
|
|
||||||
cfg.set(pre + entries.getKey(), null);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!cfg.contains(pre + entries.getKey())) {
|
|
||||||
save = true;
|
|
||||||
cfg.set(pre + entries.getKey(), entries.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (save) {
|
|
||||||
plugin.saveConfig();
|
|
||||||
plugin.reloadConfig();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (expansion instanceof VersionSpecific) {
|
|
||||||
VersionSpecific nms = (VersionSpecific) expansion;
|
|
||||||
if (!nms.isCompatibleWith(PlaceholderAPIPlugin.getServerVersion())) {
|
|
||||||
plugin.getLogger()
|
|
||||||
.info(
|
|
||||||
"Your server version is not compatible with expansion: " + expansion.getIdentifier()
|
|
||||||
+ " version: " + expansion.getVersion());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!expansion.canRegister()) {
|
|
||||||
if (expansion.getRequiredPlugin() != null) {
|
|
||||||
cache.put(expansion.getRequiredPlugin().toLowerCase(), expansion);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!expansion.register()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (expansion instanceof Listener) {
|
|
||||||
Listener l = (Listener) expansion;
|
|
||||||
Bukkit.getPluginManager().registerEvents(l, plugin);
|
|
||||||
}
|
|
||||||
plugin.getLogger().info("Successfully registered expansion: " + expansion.getIdentifier());
|
|
||||||
if (expansion instanceof Taskable) {
|
|
||||||
((Taskable) expansion).start();
|
|
||||||
}
|
|
||||||
if (plugin.getExpansionCloud() != null) {
|
|
||||||
CloudExpansion ce = plugin.getExpansionCloud().getCloudExpansion(expansion.getIdentifier());
|
|
||||||
if (ce != null) {
|
|
||||||
ce.setHasExpansion(true);
|
|
||||||
if (!ce.getLatestVersion().equals(expansion.getVersion())) {
|
|
||||||
ce.setShouldUpdate(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public PlaceholderExpansion registerExpansion(String fileName) {
|
|
||||||
List<Class<?>> subs = FileUtil.getClasses("expansions", fileName, PlaceholderExpansion.class);
|
|
||||||
if (subs == null || subs.isEmpty()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
// only register the first instance found as an expansion jar should only have 1 class
|
|
||||||
// extending PlaceholderExpansion
|
|
||||||
PlaceholderExpansion ex = createInstance(subs.get(0));
|
|
||||||
if (registerExpansion(ex)) {
|
|
||||||
return ex;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void registerAllExpansions() {
|
|
||||||
if (plugin == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
List<Class<?>> subs = FileUtil.getClasses("expansions", null, PlaceholderExpansion.class);
|
|
||||||
if (subs == null || subs.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (Class<?> klass : subs) {
|
|
||||||
PlaceholderExpansion ex = createInstance(klass);
|
|
||||||
if (ex != null) {
|
|
||||||
registerExpansion(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private PlaceholderExpansion createInstance(Class<?> klass) {
|
|
||||||
if (klass == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
PlaceholderExpansion ex = null;
|
|
||||||
if (!PlaceholderExpansion.class.isAssignableFrom(klass)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Constructor<?>[] c = klass.getConstructors();
|
|
||||||
if (c.length == 0) {
|
|
||||||
ex = (PlaceholderExpansion) klass.newInstance();
|
|
||||||
} else {
|
|
||||||
for (Constructor<?> con : c) {
|
|
||||||
if (con.getParameterTypes().length == 0) {
|
|
||||||
ex = (PlaceholderExpansion) klass.newInstance();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Throwable t) {
|
|
||||||
plugin.getLogger()
|
|
||||||
.severe("Failed to init placeholder expansion from class: " + klass.getName());
|
|
||||||
plugin.getLogger().severe(t.getMessage());
|
|
||||||
}
|
|
||||||
return ex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* PlaceholderAPI
|
|
||||||
* Copyright (C) 2018 Ryan McCarthy
|
|
||||||
*
|
|
||||||
* 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 me.clip.placeholderapi.expansion;
|
|
||||||
|
|
||||||
public enum NMSVersion {
|
|
||||||
|
|
||||||
UNKNOWN("unknown"),
|
|
||||||
SPIGOT_1_7_R1("v1_7_R1"),
|
|
||||||
SPIGOT_1_7_R2("v1_7_R2"),
|
|
||||||
SPIGOT_1_7_R3("v1_7_R3"),
|
|
||||||
SPIGOT_1_7_R4("v1_7_R4"),
|
|
||||||
SPIGOT_1_8_R1("v1_8_R1"),
|
|
||||||
SPIGOT_1_8_R2("v1_8_R2"),
|
|
||||||
SPIGOT_1_8_R3("v1_8_R3"),
|
|
||||||
SPIGOT_1_9_R1("v1_9_R1"),
|
|
||||||
SPIGOT_1_9_R2("v1_9_R2"),
|
|
||||||
SPIGOT_1_10_R1("v1_10_R1"),
|
|
||||||
SPIGOT_1_11_R1("v1_11_R1"),
|
|
||||||
SPIGOT_1_12_R1("v1_12_R1"),
|
|
||||||
SPIGOT_1_13_R1("v1_13_R1"),
|
|
||||||
SPIGOT_1_13_R2("v1_13_R2"),
|
|
||||||
SPIGOT_1_14_R1("v1_14_R1");
|
|
||||||
|
|
||||||
private String version;
|
|
||||||
|
|
||||||
NMSVersion(String version) {
|
|
||||||
this.version = version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static NMSVersion getVersion(String version) {
|
|
||||||
for (NMSVersion v : values()) {
|
|
||||||
if (v.getVersion().equalsIgnoreCase(version)) {
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NMSVersion.UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getVersion() {
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,199 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* PlaceholderAPI
|
|
||||||
* Copyright (C) 2018 Ryan McCarthy
|
|
||||||
*
|
|
||||||
* 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 me.clip.placeholderapi.expansion;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPI;
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
|
||||||
import me.clip.placeholderapi.PlaceholderHook;
|
|
||||||
import org.apache.commons.lang.Validate;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
|
||||||
|
|
||||||
public abstract class PlaceholderExpansion extends PlaceholderHook {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of this expansion
|
|
||||||
*
|
|
||||||
* @return {@link #getIdentifier()} by default, name of this expansion if specified
|
|
||||||
*/
|
|
||||||
public String getName() {
|
|
||||||
return getIdentifier();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The placeholder identifier of this expanion
|
|
||||||
*
|
|
||||||
* @return placeholder identifier that is associated with this expansion
|
|
||||||
*/
|
|
||||||
public abstract String getIdentifier();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The author of this expansion
|
|
||||||
*
|
|
||||||
* @return name of the author for this expansion
|
|
||||||
*/
|
|
||||||
public abstract String getAuthor();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The version of this expansion
|
|
||||||
*
|
|
||||||
* @return current version of this expansion
|
|
||||||
*/
|
|
||||||
public abstract String getVersion();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the plugin that this expansion hooks into. by default will return the deprecated
|
|
||||||
* {@link #getPlugin()} method
|
|
||||||
*
|
|
||||||
* @return plugin name that this expansion requires to function
|
|
||||||
*/
|
|
||||||
public String getRequiredPlugin() {
|
|
||||||
return getPlugin();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The placeholders associated with this expansion
|
|
||||||
*
|
|
||||||
* @return placeholder list that this expansion provides
|
|
||||||
*/
|
|
||||||
public List<String> getPlaceholders() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Expansions that do not use the ecloud and instead register from the dependency should set this
|
|
||||||
* to true to ensure that your placeholder expansion is not unregistered when the papi reload
|
|
||||||
* command is used
|
|
||||||
*
|
|
||||||
* @return if this expansion should persist through placeholder reloads
|
|
||||||
*/
|
|
||||||
public boolean persist() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if this placeholder identfier has already been registered
|
|
||||||
*
|
|
||||||
* @return true if the identifier for this expansion is already registered
|
|
||||||
*/
|
|
||||||
public boolean isRegistered() {
|
|
||||||
Validate.notNull(getIdentifier(), "Placeholder identifier can not be null!");
|
|
||||||
return PlaceholderAPI.getRegisteredIdentifiers().contains(getIdentifier());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If any requirements need to be checked before this expansion should register, you can check
|
|
||||||
* them here
|
|
||||||
*
|
|
||||||
* @return true if this hook meets all the requirements to register
|
|
||||||
*/
|
|
||||||
public boolean canRegister() {
|
|
||||||
return getRequiredPlugin() == null
|
|
||||||
|| Bukkit.getPluginManager().getPlugin(getRequiredPlugin()) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempt to register this PlaceholderExpansion
|
|
||||||
*
|
|
||||||
* @return true if this expansion is now registered with PlaceholderAPI
|
|
||||||
*/
|
|
||||||
public boolean register() {
|
|
||||||
Validate.notNull(getIdentifier(), "Placeholder identifier can not be null!");
|
|
||||||
return PlaceholderAPI.registerExpansion(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Quick getter for the {@link PlaceholderAPIPlugin} instance
|
|
||||||
*
|
|
||||||
* @return {@link PlaceholderAPIPlugin} instance
|
|
||||||
*/
|
|
||||||
public PlaceholderAPIPlugin getPlaceholderAPI() {
|
|
||||||
return PlaceholderAPIPlugin.getInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getString(String path, String def) {
|
|
||||||
return getPlaceholderAPI().getConfig()
|
|
||||||
.getString("expansions." + getIdentifier() + "." + path, def);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getInt(String path, int def) {
|
|
||||||
return getPlaceholderAPI().getConfig()
|
|
||||||
.getInt("expansions." + getIdentifier() + "." + path, def);
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getLong(String path, long def) {
|
|
||||||
return getPlaceholderAPI().getConfig()
|
|
||||||
.getLong("expansions." + getIdentifier() + "." + path, def);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getDouble(String path, double def) {
|
|
||||||
return getPlaceholderAPI().getConfig()
|
|
||||||
.getDouble("expansions." + getIdentifier() + "." + path, def);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getStringList(String path) {
|
|
||||||
return getPlaceholderAPI().getConfig()
|
|
||||||
.getStringList("expansions." + getIdentifier() + "." + path);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object get(String path, Object def) {
|
|
||||||
return getPlaceholderAPI().getConfig().get("expansions." + getIdentifier() + "." + path, def);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConfigurationSection getConfigSection(String path) {
|
|
||||||
return getPlaceholderAPI().getConfig()
|
|
||||||
.getConfigurationSection("expansions." + getIdentifier() + "." + path);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConfigurationSection getConfigSection() {
|
|
||||||
return getPlaceholderAPI().getConfig().getConfigurationSection("expansions." + getIdentifier());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean configurationContains(String path) {
|
|
||||||
return getPlaceholderAPI().getConfig().contains("expansions." + getIdentifier() + "." + path);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated As of versions greater than 2.8.7, use {@link #getRequiredPlugin()}
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public String getPlugin() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated As of versions greater than 2.8.7, use the expansion cloud to show a description
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public String getDescription() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated As of versions greater than 2.8.7, use the expansion cloud to display a link
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public String getLink() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* PlaceholderAPI
|
|
||||||
* Copyright (C) 2018 Ryan McCarthy
|
|
||||||
*
|
|
||||||
* 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 me.clip.placeholderapi.expansion;
|
|
||||||
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public interface Relational {
|
|
||||||
|
|
||||||
String onPlaceholderRequest(Player one, Player two, String identifier);
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* PlaceholderAPI
|
|
||||||
* Copyright (C) 2018 Ryan McCarthy
|
|
||||||
*
|
|
||||||
* 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 me.clip.placeholderapi.expansion;
|
|
||||||
|
|
||||||
|
|
||||||
public interface Taskable {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the implementing class has successfully been registered to the placeholder map
|
|
||||||
* Tasks that need to be performed when this expansion is registered should go here
|
|
||||||
*/
|
|
||||||
void start();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the implementing class has been unregistered from PlaceholderAPI Tasks that need to
|
|
||||||
* be performed when this expansion has unregistered should go here
|
|
||||||
*/
|
|
||||||
void stop();
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* PlaceholderAPI
|
|
||||||
* Copyright (C) 2018 Ryan McCarthy
|
|
||||||
*
|
|
||||||
* 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 me.clip.placeholderapi.expansion;
|
|
||||||
|
|
||||||
public final class Version {
|
|
||||||
|
|
||||||
private boolean isSpigot;
|
|
||||||
|
|
||||||
private String version;
|
|
||||||
|
|
||||||
public Version(String version, boolean isSpigot) {
|
|
||||||
this.version = version;
|
|
||||||
this.isSpigot = isSpigot;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getVersion() {
|
|
||||||
return version == null ? "unknown" : version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSpigot() {
|
|
||||||
return isSpigot;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean compareTo(String version) {
|
|
||||||
return getVersion().equalsIgnoreCase(version);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* PlaceholderAPI
|
|
||||||
* Copyright (C) 2018 Ryan McCarthy
|
|
||||||
*
|
|
||||||
* 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 me.clip.placeholderapi.expansion;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Placeholder expansions which use NMS code should be version specific. Implementing this class
|
|
||||||
* allows you to perform checks based on the version the server is running. The isCompatibleWith
|
|
||||||
* method will be passed the server version and allow you to return if your expansion is compatible
|
|
||||||
* with that version.
|
|
||||||
*
|
|
||||||
* @author Ryan McCarthy
|
|
||||||
*/
|
|
||||||
public interface VersionSpecific {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method is called before the expansion is attempted to be registered The server version
|
|
||||||
* will be passed to this method so you know what version the server is currently running.
|
|
||||||
*
|
|
||||||
* @return true if your expansion is compatible with the version the server is running.
|
|
||||||
*/
|
|
||||||
boolean isCompatibleWith(Version v);
|
|
||||||
}
|
|
||||||
@@ -1,202 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* PlaceholderAPI
|
|
||||||
* Copyright (C) 2018 Ryan McCarthy
|
|
||||||
*
|
|
||||||
* 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 me.clip.placeholderapi.expansion.cloud;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import me.clip.placeholderapi.util.TimeUtil;
|
|
||||||
|
|
||||||
|
|
||||||
public class CloudExpansion {
|
|
||||||
|
|
||||||
private String name,
|
|
||||||
author,
|
|
||||||
latest_version,
|
|
||||||
description,
|
|
||||||
source_url,
|
|
||||||
dependency_url;
|
|
||||||
|
|
||||||
private boolean hasExpansion,
|
|
||||||
shouldUpdate,
|
|
||||||
verified;
|
|
||||||
|
|
||||||
private long last_update,
|
|
||||||
ratings_count;
|
|
||||||
|
|
||||||
private double average_rating;
|
|
||||||
|
|
||||||
private List<String> placeholders;
|
|
||||||
|
|
||||||
private List<Version> versions;
|
|
||||||
|
|
||||||
public CloudExpansion() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTimeSinceLastUpdate() {
|
|
||||||
int time = (int) TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() - getLastUpdate());
|
|
||||||
return TimeUtil.getTime(time);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAuthor() {
|
|
||||||
return author;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAuthor(String author) {
|
|
||||||
this.author = author;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Version getVersion() {
|
|
||||||
return getLatestVersion() == null ? null : getVersion(getLatestVersion());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Version getVersion(String version) {
|
|
||||||
return versions == null ? null : versions.stream()
|
|
||||||
.filter(v -> v.getVersion().equals(version))
|
|
||||||
.findFirst()
|
|
||||||
.orElse(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getAvailableVersions() {
|
|
||||||
return versions.stream().map(Version::getVersion).collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLatestVersion() {
|
|
||||||
return latest_version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLatestVersion(String latest_version) {
|
|
||||||
this.latest_version = latest_version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDescription() {
|
|
||||||
return description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDescription(String description) {
|
|
||||||
this.description = description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSourceUrl() {
|
|
||||||
return source_url;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSourceUrl(String source_url) {
|
|
||||||
this.source_url = source_url;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDependencyUrl() {
|
|
||||||
return dependency_url;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDependencyUrl(String dependency_url) {
|
|
||||||
this.dependency_url = dependency_url;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasExpansion() {
|
|
||||||
return hasExpansion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHasExpansion(boolean hasExpansion) {
|
|
||||||
this.hasExpansion = hasExpansion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean shouldUpdate() {
|
|
||||||
return shouldUpdate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setShouldUpdate(boolean shouldUpdate) {
|
|
||||||
this.shouldUpdate = shouldUpdate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isVerified() {
|
|
||||||
return verified;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getLastUpdate() {
|
|
||||||
return last_update;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLastUpdate(long last_update) {
|
|
||||||
this.last_update = last_update;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getRatingsCount() {
|
|
||||||
return ratings_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getAverage_rating() {
|
|
||||||
return average_rating;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getPlaceholders() {
|
|
||||||
return placeholders;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPlaceholders(List<String> placeholders) {
|
|
||||||
this.placeholders = placeholders;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Version> getVersions() {
|
|
||||||
return versions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVersions(List<Version> versions) {
|
|
||||||
this.versions = versions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Version {
|
|
||||||
|
|
||||||
private String url, version, release_notes;
|
|
||||||
|
|
||||||
public String getUrl() {
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUrl(String url) {
|
|
||||||
this.url = url;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getVersion() {
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVersion(String version) {
|
|
||||||
this.version = version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getReleaseNotes() {
|
|
||||||
return release_notes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setReleaseNotes(String release_notes) {
|
|
||||||
this.release_notes = release_notes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,345 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* PlaceholderAPI
|
|
||||||
* Copyright (C) 2018 Ryan McCarthy
|
|
||||||
*
|
|
||||||
* 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 me.clip.placeholderapi.expansion.cloud;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLConnection;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.IntStream;
|
|
||||||
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPI;
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
|
||||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
|
||||||
import me.clip.placeholderapi.util.Msg;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
public class ExpansionCloudManager {
|
|
||||||
|
|
||||||
private static final String API_URL = "http://api.extendedclip.com/v2/";
|
|
||||||
private static final Gson GSON = new Gson();
|
|
||||||
|
|
||||||
|
|
||||||
private final PlaceholderAPIPlugin plugin;
|
|
||||||
private final File expansionsDir;
|
|
||||||
|
|
||||||
private final List<String> downloading = new ArrayList<>();
|
|
||||||
private final Map<Integer, CloudExpansion> remote = new TreeMap<>();
|
|
||||||
|
|
||||||
|
|
||||||
public ExpansionCloudManager(PlaceholderAPIPlugin plugin) {
|
|
||||||
this.plugin = plugin;
|
|
||||||
|
|
||||||
expansionsDir = new File(plugin.getDataFolder(), "expansions");
|
|
||||||
|
|
||||||
final boolean result = expansionsDir.mkdirs();
|
|
||||||
if (result) {
|
|
||||||
plugin.getLogger().info("Created Expansions Directory");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void clean() {
|
|
||||||
remote.clear();
|
|
||||||
downloading.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Map<Integer, CloudExpansion> getCloudExpansions() {
|
|
||||||
return remote;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CloudExpansion getCloudExpansion(String name) {
|
|
||||||
return remote.values()
|
|
||||||
.stream()
|
|
||||||
.filter(ex -> ex.getName().equalsIgnoreCase(name))
|
|
||||||
.findFirst()
|
|
||||||
.orElse(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public int getCloudAuthorCount() {
|
|
||||||
return remote.values()
|
|
||||||
.stream()
|
|
||||||
.collect(Collectors.groupingBy(CloudExpansion::getAuthor, Collectors.counting()))
|
|
||||||
.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getToUpdateCount() {
|
|
||||||
return ((int) PlaceholderAPI.getExpansions()
|
|
||||||
.stream()
|
|
||||||
.filter(ex -> getCloudExpansion(ex.getName()) != null && getCloudExpansion(ex.getName()).shouldUpdate())
|
|
||||||
.count());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Map<Integer, CloudExpansion> getAllByAuthor(String author) {
|
|
||||||
if (remote.isEmpty()) return new HashMap<>();
|
|
||||||
|
|
||||||
Map<Integer, CloudExpansion> byAuthor = new TreeMap<>();
|
|
||||||
|
|
||||||
for (CloudExpansion ex : remote.values()) {
|
|
||||||
if (!ex.getAuthor().equalsIgnoreCase(author)) continue;
|
|
||||||
|
|
||||||
byAuthor.put(byAuthor.size(), ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
return byAuthor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<Integer, CloudExpansion> getAllInstalled() {
|
|
||||||
if (remote.isEmpty()) return new HashMap<>();
|
|
||||||
|
|
||||||
Map<Integer, CloudExpansion> has = new TreeMap<>();
|
|
||||||
|
|
||||||
for (CloudExpansion ex : remote.values()) {
|
|
||||||
if (!ex.hasExpansion()) continue;
|
|
||||||
|
|
||||||
has.put(has.size(), ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
return has;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public int getPagesAvailable(Map<Integer, CloudExpansion> map, int amount) {
|
|
||||||
if (map == null) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int pages = map.size() > 0 ? 1 : 0;
|
|
||||||
if (pages == 0) {
|
|
||||||
return pages;
|
|
||||||
}
|
|
||||||
if (map.size() > amount) {
|
|
||||||
pages = map.size() / amount;
|
|
||||||
if (map.size() % amount > 0) {
|
|
||||||
pages++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return pages;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<Integer, CloudExpansion> getPage(Map<Integer, CloudExpansion> map, int page, int size) {
|
|
||||||
if (map == null || map.size() == 0 || page > getPagesAvailable(map, size)) {
|
|
||||||
return new HashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
int end = size * page;
|
|
||||||
int start = end - size;
|
|
||||||
|
|
||||||
Map<Integer, CloudExpansion> ex = new TreeMap<>();
|
|
||||||
IntStream.range(start, end).forEach(n -> ex.put(n, map.get(n)));
|
|
||||||
|
|
||||||
return ex;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void fetch(boolean allowUnverified) {
|
|
||||||
|
|
||||||
plugin.getLogger().info("Fetching available expansion information...");
|
|
||||||
|
|
||||||
plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> {
|
|
||||||
|
|
||||||
final String readJson = URLReader.read(API_URL);
|
|
||||||
final Map<String, CloudExpansion> data = GSON.fromJson(readJson, new TypeToken<Map<String, CloudExpansion>>() {
|
|
||||||
}.getType());
|
|
||||||
|
|
||||||
final List<CloudExpansion> unsorted = new ArrayList<>();
|
|
||||||
|
|
||||||
data.forEach((name, cexp) -> {
|
|
||||||
|
|
||||||
if ((allowUnverified || cexp.isVerified()) && cexp.getLatestVersion() != null && cexp.getVersion(cexp.getLatestVersion()) != null) {
|
|
||||||
cexp.setName(name);
|
|
||||||
|
|
||||||
PlaceholderExpansion ex = plugin.getExpansionManager().getRegisteredExpansion(cexp.getName());
|
|
||||||
|
|
||||||
if (ex != null && ex.isRegistered()) {
|
|
||||||
cexp.setHasExpansion(true);
|
|
||||||
if (!ex.getVersion().equals(cexp.getLatestVersion())) {
|
|
||||||
cexp.setShouldUpdate(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsorted.add(cexp);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
unsorted.sort(Comparator.comparing(CloudExpansion::getLastUpdate).reversed());
|
|
||||||
|
|
||||||
int count = 0;
|
|
||||||
for (CloudExpansion e : unsorted) {
|
|
||||||
remote.put(count++, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
plugin.getLogger().info(count + " placeholder expansions are available on the cloud.");
|
|
||||||
|
|
||||||
long updates = getToUpdateCount();
|
|
||||||
|
|
||||||
if (updates > 0) {
|
|
||||||
plugin.getLogger().info(updates + " installed expansions have updates available.");
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public boolean isDownloading(String expansion) {
|
|
||||||
return downloading.contains(expansion);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void download(URL url, String name) throws IOException {
|
|
||||||
|
|
||||||
InputStream is = null;
|
|
||||||
|
|
||||||
FileOutputStream fos = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
URLConnection urlConn = url.openConnection();
|
|
||||||
|
|
||||||
is = urlConn.getInputStream();
|
|
||||||
|
|
||||||
fos = new FileOutputStream(
|
|
||||||
expansionsDir.getAbsolutePath() + File.separator + "Expansion-" + name + ".jar");
|
|
||||||
|
|
||||||
byte[] buffer = new byte[is.available()];
|
|
||||||
|
|
||||||
int l;
|
|
||||||
|
|
||||||
while ((l = is.read(buffer)) > 0) {
|
|
||||||
fos.write(buffer, 0, l);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
if (is != null) {
|
|
||||||
is.close();
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
if (fos != null) {
|
|
||||||
fos.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void downloadExpansion(final String player, final CloudExpansion ex) {
|
|
||||||
downloadExpansion(player, ex, ex.getLatestVersion());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void downloadExpansion(final String player, final CloudExpansion ex, final String version) {
|
|
||||||
|
|
||||||
if (downloading.contains(ex.getName())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final CloudExpansion.Version ver = ex.getVersions()
|
|
||||||
.stream()
|
|
||||||
.filter(v -> v.getVersion().equals(version))
|
|
||||||
.findFirst()
|
|
||||||
.orElse(null);
|
|
||||||
|
|
||||||
if (ver == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
downloading.add(ex.getName());
|
|
||||||
|
|
||||||
plugin.getLogger().info("Attempting download of expansion: " + ex.getName() + (player != null ? " by user: " + player : "") + " from url: " + ver.getUrl());
|
|
||||||
|
|
||||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
download(new URL(ver.getUrl()), ex.getName());
|
|
||||||
|
|
||||||
plugin.getLogger().info("Download of expansion: " + ex.getName() + " complete!");
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
|
|
||||||
plugin.getLogger()
|
|
||||||
.warning("Failed to download expansion: " + ex.getName() + " from: " + ver.getUrl());
|
|
||||||
|
|
||||||
Bukkit.getScheduler().runTask(plugin, () -> {
|
|
||||||
|
|
||||||
downloading.remove(ex.getName());
|
|
||||||
|
|
||||||
if (player != null) {
|
|
||||||
Player p = Bukkit.getPlayer(player);
|
|
||||||
|
|
||||||
if (p != null) {
|
|
||||||
Msg.msg(p, "&cThere was a problem downloading expansion: &f" + ex.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Bukkit.getScheduler().runTask(plugin, () -> {
|
|
||||||
|
|
||||||
downloading.remove(ex.getName());
|
|
||||||
|
|
||||||
if (player != null) {
|
|
||||||
|
|
||||||
Player p = Bukkit.getPlayer(player);
|
|
||||||
|
|
||||||
if (p != null) {
|
|
||||||
Msg.msg(p, "&aExpansion &f" + ex.getName() + " &adownload complete!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static class URLReader {
|
|
||||||
|
|
||||||
static String read(String url) {
|
|
||||||
StringBuilder builder = new StringBuilder();
|
|
||||||
|
|
||||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(new URL(url).openStream()))) {
|
|
||||||
|
|
||||||
String inputLine;
|
|
||||||
while ((inputLine = reader.readLine()) != null) {
|
|
||||||
builder.append(inputLine);
|
|
||||||
}
|
|
||||||
} catch (Exception ex) {
|
|
||||||
builder.setLength(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* PlaceholderAPI
|
|
||||||
* Copyright (C) 2018 Ryan McCarthy
|
|
||||||
*
|
|
||||||
* 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 me.clip.placeholderapi.external;
|
|
||||||
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPI;
|
|
||||||
import me.clip.placeholderapi.PlaceholderHook;
|
|
||||||
import org.apache.commons.lang.Validate;
|
|
||||||
import org.bukkit.plugin.Plugin;
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public abstract class EZPlaceholderHook extends PlaceholderHook {
|
|
||||||
|
|
||||||
private String identifier;
|
|
||||||
|
|
||||||
private String plugin;
|
|
||||||
|
|
||||||
public EZPlaceholderHook(Plugin plugin, String identifier) {
|
|
||||||
Validate.notNull(plugin, "Plugin can not be null!");
|
|
||||||
Validate.notNull(identifier, "Placeholder name can not be null!");
|
|
||||||
this.identifier = identifier;
|
|
||||||
this.plugin = plugin.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isHooked() {
|
|
||||||
return PlaceholderAPI.getRegisteredPlaceholderPlugins().contains(identifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hook() {
|
|
||||||
return PlaceholderAPI.registerPlaceholderHook(identifier, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPlaceholderName() {
|
|
||||||
return identifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPluginName() {
|
|
||||||
return plugin;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
package me.clip.placeholderapi.updatechecker;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.net.URL;
|
|
||||||
import javax.net.ssl.HttpsURLConnection;
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
|
||||||
import me.clip.placeholderapi.util.Msg;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.player.PlayerJoinEvent;
|
|
||||||
|
|
||||||
public class UpdateChecker implements Listener {
|
|
||||||
|
|
||||||
private final int RESOURCE_ID = 6245;
|
|
||||||
private PlaceholderAPIPlugin plugin;
|
|
||||||
private String spigotVersion, pluginVersion;
|
|
||||||
private boolean updateAvailable;
|
|
||||||
|
|
||||||
public UpdateChecker(PlaceholderAPIPlugin i) {
|
|
||||||
plugin = i;
|
|
||||||
pluginVersion = i.getDescription().getVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasUpdateAvailable() {
|
|
||||||
return updateAvailable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSpigotVersion() {
|
|
||||||
return spigotVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fetch() {
|
|
||||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
|
|
||||||
try {
|
|
||||||
HttpsURLConnection con = (HttpsURLConnection) new URL(
|
|
||||||
"https://api.spigotmc.org/legacy/update.php?resource=" + RESOURCE_ID).openConnection();
|
|
||||||
con.setRequestMethod("GET");
|
|
||||||
spigotVersion = new BufferedReader(new InputStreamReader(con.getInputStream())).readLine();
|
|
||||||
} catch (Exception ex) {
|
|
||||||
plugin.getLogger().info("Failed to check for updates on spigot.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (spigotVersion == null || spigotVersion.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
updateAvailable = spigotIsNewer();
|
|
||||||
|
|
||||||
if (!updateAvailable) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Bukkit.getScheduler().runTask(plugin, () -> {
|
|
||||||
plugin.getLogger()
|
|
||||||
.info("An update for PlaceholderAPI (v" + getSpigotVersion() + ") is available at:");
|
|
||||||
plugin.getLogger()
|
|
||||||
.info("https://www.spigotmc.org/resources/placeholderapi." + RESOURCE_ID + "/");
|
|
||||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean spigotIsNewer() {
|
|
||||||
if (spigotVersion == null || spigotVersion.isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
String plV = toReadable(pluginVersion);
|
|
||||||
String spV = toReadable(spigotVersion);
|
|
||||||
return plV.compareTo(spV) < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String toReadable(String version) {
|
|
||||||
if (version.contains("-DEV-")) {
|
|
||||||
version = version.split("-DEV-")[0];
|
|
||||||
}
|
|
||||||
return version.replaceAll("\\.", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
|
||||||
public void onJoin(PlayerJoinEvent e) {
|
|
||||||
if (e.getPlayer().hasPermission("placeholderapi.updatenotify")) {
|
|
||||||
Msg.msg(e.getPlayer(),
|
|
||||||
"&bAn update for &fPlaceholder&7API &e(&fPlaceholder&7API &fv" + getSpigotVersion()
|
|
||||||
+ "&e)"
|
|
||||||
, "&bis available at &ehttps://www.spigotmc.org/resources/placeholderapi." + RESOURCE_ID
|
|
||||||
+ "/");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* PlaceholderAPI
|
|
||||||
* Copyright (C) 2018 Ryan McCarthy
|
|
||||||
*
|
|
||||||
* 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 me.clip.placeholderapi.util;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FilenameFilter;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLClassLoader;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.jar.JarEntry;
|
|
||||||
import java.util.jar.JarInputStream;
|
|
||||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
|
||||||
|
|
||||||
public class FileUtil {
|
|
||||||
|
|
||||||
public static List<Class<?>> getClasses(String folder, Class<?> type) {
|
|
||||||
return getClasses(folder, null, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<Class<?>> getClasses(String folder, String fileName, Class<?> type) {
|
|
||||||
List<Class<?>> list = new ArrayList<>();
|
|
||||||
try {
|
|
||||||
File f = new File(PlaceholderAPIPlugin.getInstance().getDataFolder(), folder);
|
|
||||||
if (!f.exists()) {
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
FilenameFilter fileNameFilter = (dir, name) -> {
|
|
||||||
if (fileName != null) {
|
|
||||||
return name.endsWith(".jar") && name.replace(".jar", "")
|
|
||||||
.equalsIgnoreCase(fileName.replace(".jar", ""));
|
|
||||||
}
|
|
||||||
return name.endsWith(".jar");
|
|
||||||
};
|
|
||||||
File[] jars = f.listFiles(fileNameFilter);
|
|
||||||
if (jars == null) {
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
for (File file : jars) {
|
|
||||||
list = gather(file.toURI().toURL(), list, type);
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
} catch (Throwable t) {
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<Class<?>> gather(URL jar, List<Class<?>> list, Class<?> clazz) {
|
|
||||||
if (list == null) {
|
|
||||||
list = new ArrayList<>();
|
|
||||||
}
|
|
||||||
try (URLClassLoader cl = new URLClassLoader(new URL[]{jar}, clazz.getClassLoader()); JarInputStream jis = new JarInputStream(jar.openStream())) {
|
|
||||||
while (true) {
|
|
||||||
JarEntry j = jis.getNextJarEntry();
|
|
||||||
if (j == null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
String name = j.getName();
|
|
||||||
if (name == null || name.isEmpty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (name.endsWith(".class")) {
|
|
||||||
name = name.replace("/", ".");
|
|
||||||
String cname = name.substring(0, name.lastIndexOf(".class"));
|
|
||||||
Class<?> c = cl.loadClass(cname);
|
|
||||||
if (clazz.isAssignableFrom(c)) {
|
|
||||||
list.add(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Throwable t) {
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* PlaceholderAPI
|
|
||||||
* Copyright (C) 2018 Ryan McCarthy
|
|
||||||
*
|
|
||||||
* 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 me.clip.placeholderapi.util;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.ChatColor;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
|
|
||||||
public class Msg {
|
|
||||||
|
|
||||||
public static void msg(CommandSender s, String... msg) {
|
|
||||||
Arrays.stream(msg).map(Msg::color).forEach(s::sendMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void broadcast(String... msg) {
|
|
||||||
Arrays.stream(msg).map(Msg::color).forEach(Bukkit::broadcastMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String color(String text) {
|
|
||||||
return ChatColor.translateAlternateColorCodes('&', text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* PlaceholderAPI
|
|
||||||
* Copyright (C) 2018 Ryan McCarthy
|
|
||||||
*
|
|
||||||
* 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 me.clip.placeholderapi.util;
|
|
||||||
|
|
||||||
public enum TimeFormat {
|
|
||||||
|
|
||||||
DAYS,
|
|
||||||
HOURS,
|
|
||||||
MINUTES,
|
|
||||||
SECONDS
|
|
||||||
}
|
|
||||||
@@ -1,162 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* PlaceholderAPI
|
|
||||||
* Copyright (C) 2018 Ryan McCarthy
|
|
||||||
*
|
|
||||||
* 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 me.clip.placeholderapi.util;
|
|
||||||
|
|
||||||
public class TimeUtil {
|
|
||||||
|
|
||||||
public static String getRemaining(int seconds, TimeFormat type) {
|
|
||||||
|
|
||||||
if (seconds < 60) {
|
|
||||||
switch (type) {
|
|
||||||
case DAYS:
|
|
||||||
return "0";
|
|
||||||
case HOURS:
|
|
||||||
return "0";
|
|
||||||
case MINUTES:
|
|
||||||
return "0";
|
|
||||||
case SECONDS:
|
|
||||||
return String.valueOf(seconds);
|
|
||||||
}
|
|
||||||
return String.valueOf(seconds);
|
|
||||||
}
|
|
||||||
|
|
||||||
int minutes = seconds / 60;
|
|
||||||
int s = 60 * minutes;
|
|
||||||
int secondsLeft = seconds - s;
|
|
||||||
if (minutes < 60) {
|
|
||||||
switch (type) {
|
|
||||||
case DAYS:
|
|
||||||
return "0";
|
|
||||||
case HOURS:
|
|
||||||
return "0";
|
|
||||||
case MINUTES:
|
|
||||||
return String.valueOf(minutes);
|
|
||||||
case SECONDS:
|
|
||||||
return String.valueOf(secondsLeft);
|
|
||||||
}
|
|
||||||
return String.valueOf(seconds);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (minutes < 1440) {
|
|
||||||
int hours = minutes / 60;
|
|
||||||
int inMins = 60 * hours;
|
|
||||||
int leftOver = minutes - inMins;
|
|
||||||
switch (type) {
|
|
||||||
case DAYS:
|
|
||||||
return "0";
|
|
||||||
case HOURS:
|
|
||||||
return String.valueOf(hours);
|
|
||||||
case MINUTES:
|
|
||||||
return String.valueOf(leftOver);
|
|
||||||
case SECONDS:
|
|
||||||
return String.valueOf(secondsLeft);
|
|
||||||
}
|
|
||||||
return String.valueOf(seconds);
|
|
||||||
}
|
|
||||||
|
|
||||||
int days = minutes / 1440;
|
|
||||||
int inMins = 1440 * days;
|
|
||||||
int leftOver = minutes - inMins;
|
|
||||||
|
|
||||||
if (leftOver < 60) {
|
|
||||||
switch (type) {
|
|
||||||
case DAYS:
|
|
||||||
return String.valueOf(days);
|
|
||||||
case HOURS:
|
|
||||||
return String.valueOf(0);
|
|
||||||
case MINUTES:
|
|
||||||
return String.valueOf(leftOver);
|
|
||||||
case SECONDS:
|
|
||||||
return String.valueOf(secondsLeft);
|
|
||||||
}
|
|
||||||
return String.valueOf(seconds);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
int hours = leftOver / 60;
|
|
||||||
int hoursInMins = 60 * hours;
|
|
||||||
int minsLeft = leftOver - hoursInMins;
|
|
||||||
switch (type) {
|
|
||||||
case DAYS:
|
|
||||||
return String.valueOf(days);
|
|
||||||
case HOURS:
|
|
||||||
return String.valueOf(hours);
|
|
||||||
case MINUTES:
|
|
||||||
return String.valueOf(minsLeft);
|
|
||||||
case SECONDS:
|
|
||||||
return String.valueOf(secondsLeft);
|
|
||||||
}
|
|
||||||
return String.valueOf(seconds);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getTime(int seconds) {
|
|
||||||
|
|
||||||
if (seconds < 60) {
|
|
||||||
return seconds + "s";
|
|
||||||
}
|
|
||||||
|
|
||||||
int minutes = seconds / 60;
|
|
||||||
int s = 60 * minutes;
|
|
||||||
int secondsLeft = seconds - s;
|
|
||||||
if (minutes < 60) {
|
|
||||||
if (secondsLeft > 0) {
|
|
||||||
return String.valueOf(minutes + "m " + secondsLeft + "s");
|
|
||||||
} else {
|
|
||||||
return String.valueOf(minutes + "m");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (minutes < 1440) {
|
|
||||||
String time;
|
|
||||||
int hours = minutes / 60;
|
|
||||||
time = hours + "h";
|
|
||||||
int inMins = 60 * hours;
|
|
||||||
int leftOver = minutes - inMins;
|
|
||||||
if (leftOver >= 1) {
|
|
||||||
time = time + " " + leftOver + "m";
|
|
||||||
}
|
|
||||||
if (secondsLeft > 0) {
|
|
||||||
time = time + " " + secondsLeft + "s";
|
|
||||||
}
|
|
||||||
return time;
|
|
||||||
}
|
|
||||||
|
|
||||||
String time;
|
|
||||||
int days = minutes / 1440;
|
|
||||||
time = days + "d";
|
|
||||||
int inMins = 1440 * days;
|
|
||||||
int leftOver = minutes - inMins;
|
|
||||||
if (leftOver >= 1) {
|
|
||||||
if (leftOver < 60) {
|
|
||||||
time = time + " " + leftOver + "m";
|
|
||||||
} else {
|
|
||||||
int hours = leftOver / 60;
|
|
||||||
time = time + " " + hours + "h";
|
|
||||||
int hoursInMins = 60 * hours;
|
|
||||||
int minsLeft = leftOver - hoursInMins;
|
|
||||||
time = time + " " + minsLeft + "m";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (secondsLeft > 0) {
|
|
||||||
time = time + " " + secondsLeft + "s";
|
|
||||||
}
|
|
||||||
return time;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
# PlaceholderAPI
|
|
||||||
# Version: ${project.version}
|
|
||||||
# Created by: extended_clip
|
|
||||||
# Contributors: https://github.com/PlaceholderAPI/PlaceholderAPI/graphs/contributors
|
|
||||||
# Issues: https://github.com/PlaceholderAPI/PlaceholderAPI/issues
|
|
||||||
# Expansions: https://api.extendedclip.com/all/
|
|
||||||
# Wiki: https://github.com/PlaceholderAPI/PlaceholderAPI/wiki
|
|
||||||
# Discord: https://helpch.at/discord
|
|
||||||
# No placeholders are provided with this plugin by default.
|
|
||||||
# Download placeholders: /papi ecloud
|
|
||||||
check_updates: true
|
|
||||||
cloud_enabled: true
|
|
||||||
cloud_allow_unverified_expansions: false
|
|
||||||
boolean:
|
|
||||||
'true': 'yes'
|
|
||||||
'false': 'no'
|
|
||||||
date_format: MM/dd/yy HH:mm:ss
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
name: ${project.name}
|
|
||||||
main: me.clip.placeholderapi.PlaceholderAPIPlugin
|
|
||||||
version: ${project.version}
|
|
||||||
author: [extended_clip]
|
|
||||||
description: ${project.description}
|
|
||||||
api-version: 1.13
|
|
||||||
load: STARTUP
|
|
||||||
permissions:
|
|
||||||
placeholderapi.*:
|
|
||||||
description: ability to use all commands
|
|
||||||
children:
|
|
||||||
placeholderapi.admin: true
|
|
||||||
placeholderapi.admin:
|
|
||||||
description: ability to use all commands
|
|
||||||
children:
|
|
||||||
placeholderapi.list: true
|
|
||||||
placeholderapi.reload: true
|
|
||||||
placeholderapi.ecloud: true
|
|
||||||
placeholderapi.parse: true
|
|
||||||
placeholderapi.register: true
|
|
||||||
placeholderapi.updatenotify: true
|
|
||||||
placeholderapi.list:
|
|
||||||
description: ability to use the list command
|
|
||||||
default: op
|
|
||||||
placeholderapi.reload:
|
|
||||||
description: ability to use the reload command
|
|
||||||
default: op
|
|
||||||
placeholderapi.parse:
|
|
||||||
description: ability to use parse command
|
|
||||||
default: op
|
|
||||||
placeholderapi.register:
|
|
||||||
description: ability to register or unregister placeholder expansions
|
|
||||||
default: op
|
|
||||||
placeholderapi.ecloud:
|
|
||||||
description: allows the usage of ecloud commands
|
|
||||||
default: op
|
|
||||||
placeholderapi.updatenotify:
|
|
||||||
description: notifies you when there is a PAPI update
|
|
||||||
default: op
|
|
||||||
commands:
|
|
||||||
placeholderapi:
|
|
||||||
description: PlaceholderAPI command
|
|
||||||
aliases: [clipsplaceholderapi, papi]
|
|
||||||