Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b3e8ad9164 | ||
|
|
c3501a831e | ||
|
|
9821cb1b16 | ||
|
|
bba1f2acf0 | ||
|
|
1afbff18ef | ||
|
|
56ec689841 | ||
|
|
3189501b78 | ||
|
|
1c23103517 | ||
|
|
06e1b90f29 | ||
|
|
acd79fc661 | ||
|
|
18bde6ee37 | ||
|
|
72f8052e58 | ||
|
|
0343be6915 | ||
|
|
000a034836 | ||
|
|
2d33447fc1 | ||
|
|
bcb76350a1 | ||
|
|
485f4fa070 | ||
|
|
b1e60f5f1b | ||
|
|
6c3479e739 | ||
|
|
4813cc3077 | ||
|
|
69c8cf8ffb | ||
|
|
510ff4e6a1 | ||
|
|
a6043c14cd | ||
|
|
1a4c34afcf | ||
|
|
2f9ec6f2aa | ||
|
|
bc2f6a423f | ||
|
|
0986b0982c | ||
|
|
9a24129e49 | ||
|
|
c8029bdbdf | ||
|
|
1129c17489 | ||
|
|
f313b5b617 | ||
|
|
765f92bfe5 | ||
|
|
edd71bf8ab | ||
|
|
7d96efc645 | ||
|
|
6cb2837d77 | ||
|
|
08a8268852 | ||
|
|
54b6d1c21c | ||
|
|
71341a9381 | ||
|
|
5eccc2e3cd | ||
|
|
0015682fe4 | ||
|
|
107892fb24 | ||
|
|
6371b77b94 | ||
|
|
03ba058a9b | ||
|
|
750c5ed9a7 | ||
|
|
14afb884ad | ||
|
|
ab788554bf | ||
|
|
b8c204b306 | ||
|
|
52f542774f | ||
|
|
e502f2c96d | ||
|
|
8d904ca010 | ||
|
|
9a6b0664e3 | ||
|
|
5f1472a18d | ||
|
|
9dff193c09 | ||
|
|
9b2c3320ee | ||
|
|
df9508ff3c | ||
|
|
414f561673 | ||
|
|
074edf1b48 | ||
|
|
a0a229fa29 | ||
|
|
ebdadf0774 | ||
|
|
5b09536dcf | ||
|
|
1ea548f05d | ||
|
|
b7bf993795 | ||
|
|
a709382d25 | ||
|
|
d36def89e1 | ||
|
|
074af0e282 | ||
|
|
b6358cf83c | ||
|
|
f53a6928f2 | ||
|
|
78bb5f171f | ||
|
|
28219a3993 | ||
|
|
cae5122d04 | ||
|
|
0070485d2e | ||
|
|
4b6b904361 | ||
|
|
7e03da66d4 | ||
|
|
b209eb3c8b | ||
|
|
be31c705b5 | ||
|
|
13ee674d96 | ||
|
|
d31310ace8 | ||
|
|
1afed864b1 | ||
|
|
95d56c970c | ||
|
|
2dcd832a29 | ||
|
|
f54bb7923b | ||
|
|
1b862d084b | ||
|
|
fc7a7396ef | ||
|
|
be6e086aac | ||
|
|
5e70b54f08 | ||
|
|
f3d8b47add | ||
|
|
d3cadaf90f | ||
|
|
83a49a686a | ||
|
|
a4920a2c74 | ||
|
|
37170a2180 | ||
|
|
c6c5b9430e | ||
|
|
338b8792a9 | ||
|
|
7163d38ddf | ||
|
|
b0fc931ecd | ||
|
|
0ec1116a9e | ||
|
|
e45c82ee87 | ||
|
|
cb4c4b2141 | ||
|
|
acfdbc5494 | ||
|
|
70d08dfc6f | ||
|
|
dfc4652da7 | ||
|
|
a2ac867269 | ||
|
|
9c61135a73 | ||
|
|
f7951e7ef9 | ||
|
|
d37509224d | ||
|
|
7d0b7288dc | ||
|
|
53d22dcff7 | ||
|
|
6060954f87 | ||
|
|
ff8a27d92a | ||
|
|
617abe2d8c | ||
|
|
93c84b1912 | ||
|
|
0b17b81b63 | ||
|
|
6a7a92a97b | ||
|
|
31f7bde35f | ||
|
|
da77c32a0d | ||
|
|
421453d25e | ||
|
|
fa4d44b929 | ||
|
|
7c8b56b3cb | ||
|
|
f6fec5b93b | ||
|
|
ea0f91136e | ||
|
|
cf7d49aec5 | ||
|
|
03733d274a | ||
|
|
2dd688fa0e | ||
|
|
8165e55514 | ||
|
|
e5464c8e4b | ||
|
|
f70b9a8322 | ||
|
|
c31f728a37 | ||
|
|
0a519379a1 | ||
|
|
2b50f6c713 | ||
|
|
be2ba2b1b9 | ||
|
|
5051e7ea48 | ||
|
|
a42aa4b202 | ||
|
|
3d22258321 | ||
|
|
8fe1648d6b | ||
|
|
49211240a3 | ||
|
|
89c503dd92 | ||
|
|
c326bb7b51 | ||
|
|
50024b0602 | ||
|
|
5503a338fa | ||
|
|
076c5e5265 | ||
|
|
01d534391d | ||
|
|
48f8412440 | ||
|
|
2c9ce50312 | ||
|
|
601a6eb808 | ||
|
|
647230a996 | ||
|
|
5047aaff0c | ||
|
|
a981adf7a3 | ||
|
|
a16a085f75 | ||
|
|
37f5948b0a | ||
|
|
7fa80e1759 | ||
|
|
e1464044a7 | ||
|
|
42167394e0 | ||
|
|
3ef1912267 | ||
|
|
3c20b79573 | ||
|
|
7171802b78 | ||
|
|
58e7455cd9 | ||
|
|
a613edcb42 | ||
|
|
5ce1e850c8 | ||
|
|
4f392ba361 | ||
|
|
61fb1c249c | ||
|
|
dae83d0e36 | ||
|
|
67c5e78e7b | ||
|
|
1ec2551fcc | ||
|
|
d4a299501a | ||
|
|
3fbeb3e902 | ||
|
|
7f2023176f | ||
|
|
3ddd289b49 | ||
|
|
f16ff65933 | ||
|
|
96485c444e | ||
|
|
b99b79f44a | ||
|
|
3ba2191829 | ||
|
|
26de3fe573 | ||
|
|
d59749fb03 | ||
|
|
a0195c59cc | ||
|
|
26b90b6d71 | ||
|
|
ed0db721dd | ||
|
|
b203db3ce5 | ||
|
|
e386f7cf45 | ||
|
|
c1c542cc5a | ||
|
|
642d427783 | ||
|
|
b2514a9e50 | ||
|
|
a942d3aad5 | ||
|
|
7a25645ed5 | ||
|
|
3c23bd41dd | ||
|
|
e5ba76e006 | ||
|
|
7a03feeccc | ||
|
|
67ef4700c7 | ||
|
|
790a9d0058 | ||
|
|
002ad95cad | ||
|
|
7ff42400c0 | ||
|
|
3df7f760a6 | ||
|
|
3a48e54e52 | ||
|
|
73eef1727a | ||
|
|
1ab0cd07af | ||
|
|
9df545483c | ||
|
|
3f93bb051d | ||
|
|
8bd982a412 | ||
|
|
7b200ad264 | ||
|
|
5d2a4e2ef3 | ||
|
|
d414106d5a | ||
|
|
d86ac64ac9 | ||
|
|
6761489ebf | ||
|
|
dd0ec0033a | ||
|
|
f91ddb2521 | ||
|
|
3ee94415a9 | ||
|
|
1a7ce908b8 | ||
|
|
d3fb7cd91b | ||
|
|
8b61d168f7 | ||
|
|
50cb30b4fc | ||
|
|
5b807a9f17 | ||
|
|
f671a4fa5c | ||
|
|
0b1c210f77 | ||
|
|
9220c5ae40 | ||
|
|
f391cc6185 | ||
|
|
b0fe7d9c6d | ||
|
|
3d39f0d304 | ||
|
|
42029770a2 | ||
|
|
cf00b9ee7c | ||
|
|
b0816b1ce6 | ||
|
|
67cce53b72 | ||
|
|
0c097d7467 | ||
|
|
70e142e4c4 | ||
|
|
9f104866b2 | ||
|
|
7ec9eb08d9 | ||
|
|
2ea3d60307 | ||
|
|
7595ca0c40 | ||
|
|
5a15d34d9e | ||
|
|
cc500e4681 | ||
|
|
4c7cf56655 | ||
|
|
f570e77325 | ||
|
|
9785878d87 | ||
|
|
6cd6c87127 | ||
|
|
8d7c7743b8 | ||
|
|
b9889d2c45 | ||
|
|
a58257bc38 | ||
|
|
7924dfeab2 | ||
|
|
989c0bf55f | ||
|
|
064c7a3cd0 | ||
|
|
e1b2702231 | ||
|
|
029f399a14 | ||
|
|
7588609c56 | ||
|
|
6513df10e7 | ||
|
|
d14a74f29e | ||
|
|
2f9c66eafb | ||
|
|
ad1707f0ee | ||
|
|
aa59ed112a | ||
|
|
7be8c9d8aa | ||
|
|
f408a5d4c6 | ||
|
|
5d8084986f | ||
|
|
5bd1ef882e | ||
|
|
6167c3b526 | ||
|
|
8188ae09f5 | ||
|
|
9c81ba368f | ||
|
|
39cb8fd554 | ||
|
|
623cdaf881 | ||
|
|
1ad559212e | ||
|
|
30e10bb645 | ||
|
|
df495f8131 | ||
|
|
529da10615 | ||
|
|
f2d6691af7 | ||
|
|
a8a1e9448e | ||
|
|
d58959fcca | ||
|
|
5fca206b8d | ||
|
|
67993364b4 | ||
|
|
25652eab15 | ||
|
|
f117239184 | ||
|
|
cc3dae127b | ||
|
|
137050be16 | ||
|
|
baf1b851c4 | ||
|
|
545ab2de79 | ||
|
|
38f845bb7e | ||
|
|
9f80553749 | ||
|
|
d7d4e58106 | ||
|
|
5293417900 | ||
|
|
9a59c40ce1 | ||
|
|
8a00e260f6 | ||
|
|
1285a0c6bf | ||
|
|
eb9d913cb6 | ||
|
|
a60340f330 | ||
|
|
796a42c981 | ||
|
|
63a81b939d | ||
|
|
a9e2544188 | ||
|
|
bea01bc794 | ||
|
|
3db74c79ab | ||
|
|
799c933d95 | ||
|
|
6b9e67f96b | ||
|
|
062d846c37 | ||
|
|
af3023562d | ||
|
|
92f4e3dd81 | ||
|
|
f7eb445d61 | ||
|
|
98b77278cd | ||
|
|
60461b9cff | ||
|
|
1394c70981 | ||
|
|
595b8c3b56 | ||
|
|
27cbd844f0 | ||
|
|
5c5c1ed402 | ||
|
|
245c7e8219 | ||
|
|
3079663ba9 | ||
|
|
25d54ae229 | ||
|
|
045c35243f | ||
|
|
5009ffbb5a | ||
|
|
47b43402f5 | ||
|
|
a5dbec5303 | ||
|
|
f3f82c4f1a | ||
|
|
653ca4b322 | ||
|
|
b57800c2e2 | ||
|
|
222c03aa67 | ||
|
|
d5ff2b5b63 | ||
|
|
0a95488146 | ||
|
|
93d21efd3d | ||
|
|
d71cd20a39 | ||
|
|
19201134a8 | ||
|
|
da2f153a43 | ||
|
|
d96b88b967 | ||
|
|
d33482e200 | ||
|
|
24ebb77860 | ||
|
|
e4bac5f81a | ||
|
|
4b9a15b003 | ||
|
|
32826467d3 | ||
|
|
886ac734f9 | ||
|
|
762c66ff42 | ||
|
|
53b8c2328e | ||
|
|
578c661730 | ||
|
|
a82bbc4e66 | ||
|
|
867cd4ee39 | ||
|
|
f7b841faf3 | ||
|
|
b80902ec10 | ||
|
|
90386cd0de | ||
|
|
e22bba0360 | ||
|
|
f82b52b017 | ||
|
|
2734b18d07 | ||
|
|
3a5a47aaa2 | ||
|
|
c7bc9aa43c | ||
|
|
c956f23def | ||
|
|
0f90efa05f | ||
|
|
e3821e1741 | ||
|
|
8bf9a910d5 | ||
|
|
83a6346a8d | ||
|
|
d9291e6457 | ||
|
|
2bd2fa3228 | ||
|
|
b03dfa9951 | ||
|
|
dd5cbb0e4c | ||
|
|
18034a334c | ||
|
|
17881b342a | ||
|
|
47e50d035f | ||
|
|
5af9f025d8 | ||
|
|
c12c43e79a | ||
|
|
9e4ed56384 | ||
|
|
8f08a32c5a | ||
|
|
fdb6137339 | ||
|
|
f173cf73d4 | ||
|
|
a91c72fb44 | ||
|
|
99abe3994c | ||
|
|
a0e3d70a3f | ||
|
|
ee7eaecdb3 | ||
|
|
a105c5cb11 | ||
|
|
4d30cc2309 | ||
|
|
ca78bf9851 | ||
|
|
d7027cc0e3 | ||
|
|
f8def524aa | ||
|
|
14532bfa9a | ||
|
|
721808d71d | ||
|
|
3c9c61056d | ||
|
|
19f7800173 | ||
|
|
df702736bf | ||
|
|
3737242226 | ||
|
|
ebff5e2f4d | ||
|
|
081781f223 | ||
|
|
c570f4a972 | ||
|
|
563c5f830d | ||
|
|
248fd92f6e | ||
|
|
757654aa9d | ||
|
|
e658304405 | ||
|
|
b5e5118450 | ||
|
|
95db675de5 | ||
|
|
cae6addf26 | ||
|
|
ed26971724 | ||
|
|
7cdcdfa3c9 | ||
|
|
8314f6c1db | ||
|
|
297fe0a538 | ||
|
|
b6592b38ad | ||
|
|
8ef0221d43 | ||
|
|
b1d6a49a82 | ||
|
|
0fcba4f4ec | ||
|
|
0ee6369884 | ||
|
|
b941a6a422 | ||
|
|
2d05d601a0 | ||
|
|
90f363a2be | ||
|
|
875b85b0fc | ||
|
|
29c1623aab | ||
|
|
a914bc349a | ||
|
|
88e20e2eb6 | ||
|
|
9d343a3f29 | ||
|
|
6b7f00ef76 | ||
|
|
c2a1d289e1 | ||
|
|
20ce8cc288 | ||
|
|
6eaeb5a201 | ||
|
|
f245bb8263 | ||
|
|
f746fda5a8 | ||
|
|
a7ab4153ef | ||
|
|
5057ac3d3d | ||
|
|
4b9d3e34ea | ||
|
|
7887e10bb6 | ||
|
|
ef88be547b | ||
|
|
dd73ba4f72 | ||
|
|
467adbd3ed | ||
|
|
2bf69c2df2 | ||
|
|
7ccc0eb488 | ||
|
|
97db997473 | ||
|
|
efbc246a72 | ||
|
|
9ce209ef42 | ||
|
|
df7ef32677 | ||
|
|
1a4945eecd | ||
|
|
e3e88d449d | ||
|
|
529f9a0e01 | ||
|
|
b5add583c9 | ||
|
|
c2d8b43eab | ||
|
|
6d823263ac | ||
|
|
a9b3640b69 | ||
|
|
17323c715d | ||
|
|
2420b8052e | ||
|
|
5c54e8a08d | ||
|
|
fa220a93eb | ||
|
|
7e164b40c7 | ||
|
|
323ceb9ced | ||
|
|
681a0dc0e4 | ||
|
|
7cbd20a038 | ||
|
|
3f5500c637 | ||
|
|
7513b0499d | ||
|
|
c4b447f7b6 | ||
|
|
177b0fbf33 | ||
|
|
7f5e53782b | ||
|
|
2184ef19ca | ||
|
|
712aa0dbf0 | ||
|
|
c33611d2d3 | ||
|
|
bf15415185 | ||
|
|
7a38e8ceb9 | ||
|
|
7f6c429a55 | ||
|
|
6eeecb271b | ||
|
|
109d5afcf5 | ||
|
|
116706c09f | ||
|
|
598b51a4bf | ||
|
|
b06b9c69ca | ||
|
|
704f946cf7 | ||
|
|
1ef9dc8de6 | ||
|
|
f9d10a9571 | ||
|
|
379c5791e6 | ||
|
|
8569f47627 | ||
|
|
555bbb550f | ||
|
|
4cf09f2e34 | ||
|
|
c9abd745c5 | ||
|
|
5d1b8dbb85 | ||
|
|
ebeb1905b3 | ||
|
|
605b217ba4 | ||
|
|
814bd9d85e | ||
|
|
8d16ebf6ae | ||
|
|
7f0af23f96 | ||
|
|
060370f356 | ||
|
|
ab384df279 | ||
|
|
9a0cc02b86 | ||
|
|
5fb86d8df3 | ||
|
|
c64c27331a | ||
|
|
cd2ca76236 | ||
|
|
9598e0e4f8 | ||
|
|
d29c2bdfb7 | ||
|
|
538b467fa6 | ||
|
|
7deca33374 | ||
|
|
c704813a6c | ||
|
|
86af7f054a | ||
|
|
a6932bb71f | ||
|
|
3384b6bc17 | ||
|
|
4bdb566fb5 | ||
|
|
5ad62a03ed | ||
|
|
280b6fae2a | ||
|
|
e07c994ddc | ||
|
|
5d974858fe | ||
|
|
5cb5992d44 | ||
|
|
fddbeda81e | ||
|
|
1c1ec10a0a | ||
|
|
cd9566fbc8 | ||
|
|
90b88f3cbf | ||
|
|
faf86b2439 | ||
|
|
5a1dadf476 | ||
|
|
6eabb17f67 | ||
|
|
4f72edeaee | ||
|
|
b0f3d04439 | ||
|
|
33a34fc149 | ||
|
|
679f573444 | ||
|
|
f35b931004 | ||
|
|
7ca50291e3 | ||
|
|
9c8a8e2e9c | ||
|
|
d45a370a4d | ||
|
|
d5907711e1 | ||
|
|
437463f1b4 | ||
|
|
d6b52bcc54 | ||
|
|
3738459fa6 | ||
|
|
be4d071250 | ||
|
|
91a2aa6781 | ||
|
|
ba08c3ad2f | ||
|
|
220c45b800 | ||
|
|
a42e724f50 | ||
|
|
1002ca4016 | ||
|
|
c1b11a55d5 | ||
|
|
a21a2079c6 | ||
|
|
07d219c77b | ||
|
|
b7b8bdc841 | ||
|
|
dd5c1bb1a4 | ||
|
|
5f46dcbab0 | ||
|
|
66b9bfbbd5 | ||
|
|
dfbe2e9739 | ||
|
|
3d10c56aac | ||
|
|
84624a4884 | ||
|
|
68ac978d45 | ||
|
|
8136eb15e1 | ||
|
|
2c95a1e71c | ||
|
|
c85d4224ad | ||
|
|
a74bee5bed | ||
|
|
9dae40f455 | ||
|
|
fe7a5a2ae5 | ||
|
|
44a3108982 | ||
|
|
c0beee9189 | ||
|
|
ea045e6c34 | ||
|
|
7c38a77f60 | ||
|
|
9174ad854c | ||
|
|
2960f2a3bb | ||
|
|
cfe073cd20 | ||
|
|
459871257e | ||
|
|
4bb4b96a10 | ||
|
|
68a18df969 | ||
|
|
8c921f427c | ||
|
|
90e1d7236e | ||
|
|
decb20d2d1 | ||
|
|
ff7cb4bbbe | ||
|
|
a68fca9dda | ||
|
|
944bfe2b06 | ||
|
|
762151f067 | ||
|
|
0327b66a1d | ||
|
|
2c95229cfc | ||
|
|
18fa4062e6 | ||
|
|
5c7520f552 | ||
|
|
875d2392b5 | ||
|
|
a68eac7cd2 | ||
|
|
42efec6e2b | ||
|
|
bcb953a45a | ||
|
|
bca5b43a2a | ||
|
|
da704539f0 | ||
|
|
bd9a1dda88 | ||
|
|
915258169e | ||
|
|
1b207251e8 | ||
|
|
b7a0829e76 | ||
|
|
48feee2bfc | ||
|
|
08e145f831 | ||
|
|
a44e28bbab | ||
|
|
21cad97f3f | ||
|
|
de97b5b15f | ||
|
|
1e8d04a07d | ||
|
|
a8a33a3a2b | ||
|
|
adafcda13d | ||
|
|
c478492227 | ||
|
|
07b11b4f4a | ||
|
|
beed8437a4 | ||
|
|
501adc503c | ||
|
|
907516eb71 | ||
|
|
9308fc7712 | ||
|
|
062d3759be | ||
|
|
c699baaa41 | ||
|
|
582e4a11d4 | ||
|
|
285744a274 | ||
|
|
faaa252fa8 | ||
|
|
b01fd89373 | ||
|
|
ed5702188c | ||
|
|
f9165a1b64 | ||
|
|
bd0ce3dd71 | ||
|
|
385a483a29 | ||
|
|
3b97f843cd | ||
|
|
3766da5a3a | ||
|
|
c3fa950a9f | ||
|
|
a114e56e06 | ||
|
|
04e60d95e4 | ||
|
|
000313ee9a | ||
|
|
dc54551d0c | ||
|
|
b3dc05e5ce | ||
|
|
3c57127a6c | ||
|
|
d16a760466 | ||
|
|
3761ebf8c7 | ||
|
|
a7d78f7f69 | ||
|
|
f59c0722e0 | ||
|
|
1735f48f23 | ||
|
|
a280c1ad39 | ||
|
|
ce4ae73f55 | ||
|
|
fd065fb7c5 | ||
|
|
5ad2511e17 | ||
|
|
8fe47391bf | ||
|
|
12279731ad | ||
|
|
a13c417352 | ||
|
|
a8d0a4dd14 | ||
|
|
f8b4a6e28a | ||
|
|
85e048f22a | ||
|
|
3257c79e69 | ||
|
|
ee54e153bf | ||
|
|
9ea6c34543 | ||
|
|
005c91eb4d | ||
|
|
806312e248 | ||
|
|
bd805bfdc4 | ||
|
|
98a8f7f072 | ||
|
|
28b7f6febc | ||
|
|
d2ad3aea44 | ||
|
|
3ffc55b539 | ||
|
|
96c58e7b1c | ||
|
|
c8171b3f43 | ||
|
|
857ae523cf | ||
|
|
232f2494e3 | ||
|
|
626eb14960 | ||
|
|
c131672870 | ||
|
|
10a2e6b959 | ||
|
|
a9c49d948a | ||
|
|
79a2304728 | ||
|
|
48edd01461 | ||
|
|
3adffdc438 | ||
|
|
655ef137c1 | ||
|
|
b11456d86b | ||
|
|
abb5e27358 | ||
|
|
42a7b5a1b2 | ||
|
|
7ba2630dd2 | ||
|
|
bbeabd20b8 | ||
|
|
7e323bc497 | ||
|
|
7e008226ec | ||
|
|
4e7c520abe | ||
|
|
dce64a0b34 | ||
|
|
aa9a1df1ab | ||
|
|
4537aaf339 | ||
|
|
44a4ffb26a | ||
|
|
9408946b36 | ||
|
|
cad6e7604d | ||
|
|
e452289603 | ||
|
|
0c95eaa1c3 | ||
|
|
c1cce6be9a | ||
|
|
0afcb893e3 | ||
|
|
c7050565b8 | ||
|
|
3c436c0259 | ||
|
|
8b6b3c77e4 | ||
|
|
5eb3771704 | ||
|
|
9fd4795cb3 | ||
|
|
23eadaeaee | ||
|
|
8ccba70788 | ||
|
|
91c2987cfe | ||
|
|
5b403da966 | ||
|
|
e6e7da89cc | ||
|
|
64e0b6c711 | ||
|
|
238c0e8d40 | ||
|
|
f35eb3054c | ||
|
|
ea25b559ed | ||
|
|
ad8e723005 | ||
|
|
4542e9511b | ||
|
|
c4b23b8c87 | ||
|
|
6f19d2d6d1 | ||
|
|
7cb4e1d00e | ||
|
|
28e8339a32 | ||
|
|
99ac42c168 | ||
|
|
8d97391bf3 | ||
|
|
2836184de3 | ||
|
|
196ff53927 | ||
|
|
aaba566b1e | ||
|
|
7191dcaa15 | ||
|
|
437b16ccd5 | ||
|
|
e4b0a99141 | ||
|
|
3e5300f03c | ||
|
|
abb09153f0 | ||
|
|
05437a3e70 | ||
|
|
c697704d04 | ||
|
|
bc09187dc1 | ||
|
|
fd53881221 | ||
|
|
2024614b68 | ||
|
|
3521f9ac36 | ||
|
|
d6973a301b | ||
|
|
ae7fcbc8ad | ||
|
|
b675018acf | ||
|
|
10984cbeb7 | ||
|
|
bae0cd5e3e | ||
|
|
e4750249e9 | ||
|
|
662bae45b7 | ||
|
|
c0e56c7c19 | ||
|
|
390653a9a6 | ||
|
|
0cd04381a4 | ||
|
|
dcefaa6b19 | ||
|
|
3063538ad0 | ||
|
|
604b694709 | ||
|
|
1c9309ac98 | ||
|
|
e7c89f28ba | ||
|
|
97a8f41e12 | ||
|
|
be5bf7961e | ||
|
|
318db58be1 | ||
|
|
0deed6e00d | ||
|
|
5ad9d51fb0 | ||
|
|
907b5e020c | ||
|
|
a8d13fadb3 | ||
|
|
0137105a6d | ||
|
|
5364d89ca8 | ||
|
|
744fa25349 | ||
|
|
3027490256 | ||
|
|
89dfcaf626 | ||
|
|
4fb0738c1a | ||
|
|
e8f4f7049b | ||
|
|
0087e382ed | ||
|
|
eb9e48ecdc | ||
|
|
34f8451ac5 | ||
|
|
894503d56b | ||
|
|
ee8c3d609f | ||
|
|
b2c1c24902 | ||
|
|
6e8ea8689b | ||
|
|
7fcb489f38 | ||
|
|
10b0a6fbb6 | ||
|
|
ecc1cce033 | ||
|
|
10d8ce86b3 | ||
|
|
b0fc69c308 | ||
|
|
5cc421cff9 | ||
|
|
ca1ba4f422 | ||
|
|
a2d9489ad5 | ||
|
|
232ee9b63b | ||
|
|
7861c76730 | ||
|
|
d7aa23681b | ||
|
|
b75016a186 | ||
|
|
6882b7074c | ||
|
|
83bca3c23f | ||
|
|
a075e31a4e | ||
|
|
bdd32688fa | ||
|
|
cb857d828f | ||
|
|
440d469fa2 | ||
|
|
82da5e5a60 | ||
|
|
a191d0de16 | ||
|
|
ae6cff5325 | ||
|
|
eb9520cdc3 | ||
|
|
f8f20097a9 | ||
|
|
cbb0f87676 | ||
|
|
a6e1488545 | ||
|
|
34c009e4e5 | ||
|
|
b67242c609 | ||
|
|
6e4516272b | ||
|
|
08383c9141 | ||
|
|
2e37175dc2 | ||
|
|
f25442337d | ||
|
|
56a34ec2f8 | ||
|
|
362962dfb3 | ||
|
|
77d572190e | ||
|
|
18f7459070 | ||
|
|
e71b08de3f | ||
|
|
e8f8473e1c | ||
|
|
1d0d032431 | ||
|
|
fac7dafca5 | ||
|
|
fbebf2d75e | ||
|
|
a51f347371 | ||
|
|
6cee137780 | ||
|
|
56b48a803a | ||
|
|
3318d682fd | ||
|
|
1fe3c337e1 | ||
|
|
2442520ef3 | ||
|
|
44183f19cd | ||
|
|
23b68a867c | ||
|
|
4d16dbf76f | ||
|
|
6911d061a7 | ||
|
|
ab9c0434e1 | ||
|
|
3b932bd6b3 | ||
|
|
256839765a | ||
|
|
46f9967dba | ||
|
|
d91d47a755 | ||
|
|
5a2c047e7a | ||
|
|
5ca8b0aef8 | ||
|
|
e249ea1f0a | ||
|
|
e1b06d3872 | ||
|
|
a4ed1644f3 | ||
|
|
ad12866bf4 | ||
|
|
b04acf98c7 | ||
|
|
6b58d86248 | ||
|
|
7f6069e76b | ||
|
|
04d5ae074a | ||
|
|
85067b2574 | ||
|
|
06340e593d | ||
|
|
a896961fc4 | ||
|
|
73a62b8123 | ||
|
|
6d8a763f4c | ||
|
|
61b5c90aa7 | ||
|
|
d7eff51805 | ||
|
|
da7a57026d | ||
|
|
643e3dc2da | ||
|
|
13086c7cac | ||
|
|
41b22e8951 | ||
|
|
d76e70b1f7 | ||
|
|
c7c5c79365 | ||
|
|
87eceb5264 | ||
|
|
7b29972af0 | ||
|
|
4258f52f86 | ||
|
|
c3a7abd5f2 | ||
|
|
a5f5472853 | ||
|
|
63fc733c88 | ||
|
|
b5944f66a7 | ||
|
|
c8a19a1d83 | ||
|
|
6ab525be7b | ||
|
|
fd1932cfd8 | ||
|
|
2eb9fe7e62 | ||
|
|
ac1943758d | ||
|
|
1f86c6ab21 | ||
|
|
44f8f5e66d | ||
|
|
0be8a56ba3 | ||
|
|
0b4d49d760 | ||
|
|
2bd266cd69 | ||
|
|
0380d80138 | ||
|
|
e297d825e3 | ||
|
|
53a639e7ae | ||
|
|
a23b6feb46 | ||
|
|
603fe9cbd8 | ||
|
|
17d61b51e9 | ||
|
|
8d85106ee8 | ||
|
|
0834610f8e | ||
|
|
2e289a1d18 | ||
|
|
b4418c02ca | ||
|
|
52b46a17cd | ||
|
|
05e056a28b | ||
|
|
7b1eefb115 | ||
|
|
d50ceaa172 | ||
|
|
34b0db57ae | ||
|
|
0c9de82e99 | ||
|
|
11ce8524ac | ||
|
|
4a8534c164 | ||
|
|
593b6fc3ac | ||
|
|
33315bc271 | ||
|
|
c3e406e95b | ||
|
|
dad71f1179 | ||
|
|
03382ea987 | ||
|
|
54eed43f94 | ||
|
|
404bc6725b | ||
|
|
1b7b3d1d28 | ||
|
|
d3662d226b | ||
|
|
d699000dc3 | ||
|
|
a18a1875d3 | ||
|
|
bf523c93d1 | ||
|
|
b58cbf85e5 | ||
|
|
e38bdffc84 | ||
|
|
89a01b3997 | ||
|
|
a4085c1a5a | ||
|
|
4fa57fd642 | ||
|
|
5f670a88a4 | ||
|
|
2cadde1187 | ||
|
|
bd7e36e38c | ||
|
|
4eb69eac66 | ||
|
|
8b5f6d1e67 | ||
|
|
3a4db0a675 | ||
|
|
b2352105e6 | ||
|
|
70cb461c32 | ||
|
|
f2628097ce | ||
|
|
49e85e2b8a | ||
|
|
d7353e01b0 | ||
|
|
6674423ea4 | ||
|
|
918ee46ecc | ||
|
|
e34c291bd6 | ||
|
|
6c39966fef | ||
|
|
32d6fd5386 | ||
|
|
f64d5446a4 | ||
|
|
ed17f1bb50 | ||
|
|
8c27ead19e | ||
|
|
247cc1ebe8 | ||
|
|
ea5ab1c2f5 | ||
|
|
1e53803353 | ||
|
|
6d1464d3f4 | ||
|
|
2d6defba11 | ||
|
|
658822166a | ||
|
|
4c6ee807a7 | ||
|
|
32b7d37861 | ||
|
|
afe767c6db | ||
|
|
b37430994d | ||
|
|
c51373dc9a | ||
|
|
421a5e8141 | ||
|
|
9fe19e763a | ||
|
|
6731ade5d9 | ||
|
|
cf3eb8b993 | ||
|
|
5333c38972 | ||
|
|
d9e057eb4f | ||
|
|
33cd80da7e | ||
|
|
8231b3aebe | ||
|
|
7fbbc5f4b8 | ||
|
|
91687339bf | ||
|
|
b3181d1429 | ||
|
|
3ef8aa9e7f | ||
|
|
1a7195386c | ||
|
|
77acdc1a17 | ||
|
|
aecf9fb9b1 | ||
|
|
c8d1304e7f | ||
|
|
796a508af0 | ||
|
|
6751acb6c4 | ||
|
|
475fb97730 | ||
|
|
acee33aae6 | ||
|
|
65f60098c8 | ||
|
|
19a75abaf3 | ||
|
|
fa36de2c78 | ||
|
|
0f49ce2f9d | ||
|
|
73b24657f5 | ||
|
|
e03db26530 | ||
|
|
3fd3777e8c | ||
|
|
7ad73cd476 | ||
|
|
c5e0fcae9a | ||
|
|
4ca25df410 | ||
|
|
56b5986fc5 | ||
|
|
05c1a31f00 | ||
|
|
e0b88b750d | ||
|
|
b0c2d6f71c | ||
|
|
4e28a10aaa | ||
|
|
49205f0361 | ||
|
|
47819180c4 | ||
|
|
be3fa19c0a | ||
|
|
32a2734082 | ||
|
|
b28b0c3018 | ||
|
|
ee5eb59e42 | ||
|
|
d3f4d8dd41 | ||
|
|
d44ecaabf7 | ||
|
|
d133ca4a0f | ||
|
|
f8df3239d5 | ||
|
|
f9d957a827 | ||
|
|
bef3e3d18f | ||
|
|
aca764c288 | ||
|
|
3c0282b04f | ||
|
|
d8c081b8d3 | ||
|
|
53ca96f158 | ||
|
|
f8895c7c78 | ||
|
|
12b45d95e0 | ||
|
|
1cdfeadd86 | ||
|
|
15fec93bf1 | ||
|
|
64d2de010d | ||
|
|
ad1cd2c993 | ||
|
|
687de97fcd | ||
|
|
9d0331e190 | ||
|
|
ca863ba8c6 | ||
|
|
b9a2279966 | ||
|
|
9a91250af7 | ||
|
|
05d01e70b7 | ||
|
|
6b313cb65e | ||
|
|
a4de84b6da | ||
|
|
31550bd010 | ||
|
|
5d63c359b3 | ||
|
|
8283816418 | ||
|
|
44be8b3791 | ||
|
|
f46a2bb618 | ||
|
|
96366aae42 | ||
|
|
fd8879b46d | ||
|
|
d962ef09ff | ||
|
|
b26d2ef906 | ||
|
|
0613886659 | ||
|
|
75d7ffb447 | ||
|
|
0b5c173945 | ||
|
|
f170aed1b9 | ||
|
|
1921b46a66 | ||
|
|
bccf90b093 | ||
|
|
deebc83f1e | ||
|
|
a319df630d | ||
|
|
ab5eb2c7ef | ||
|
|
3de06c269d | ||
|
|
876839348c | ||
|
|
755e8a007a | ||
|
|
6a2e1a8114 | ||
|
|
11b25151f7 | ||
|
|
35bb80d67a | ||
|
|
7859f5ebd6 | ||
|
|
f38d753341 | ||
|
|
d1007bbb38 | ||
|
|
0886fdabd3 | ||
|
|
891f8b143f | ||
|
|
7856716a3a | ||
|
|
4eb4b2c37f | ||
|
|
1be617c110 | ||
|
|
f1743e5912 | ||
|
|
102c1f99a7 | ||
|
|
ae3434cb89 | ||
|
|
63b743f85b | ||
|
|
73f6418db3 | ||
|
|
d9c25b1acc | ||
|
|
6c18fdb175 | ||
|
|
cd009388a4 | ||
|
|
d66c2f2f5d | ||
|
|
7534904737 | ||
|
|
bce3593110 | ||
|
|
9a92d180d0 | ||
|
|
a203c17e06 | ||
|
|
69b5134b5f | ||
|
|
8c543ee97f | ||
|
|
bafa6edd28 | ||
|
|
799567579b | ||
|
|
c10e61a165 | ||
|
|
a27e439c99 | ||
|
|
e224d9daa2 | ||
|
|
91d9f99c70 | ||
|
|
c57f0d90bb | ||
|
|
e9198e7946 | ||
|
|
25d1b08a6f | ||
|
|
50395da626 | ||
|
|
2d0209b221 | ||
|
|
44330c98b7 | ||
|
|
b7f72bf55d | ||
|
|
f6d7976eff | ||
|
|
f45a727396 | ||
|
|
d5f65eceb0 | ||
|
|
2285c453da | ||
|
|
193084927b | ||
|
|
1325d53950 | ||
|
|
fa1b56a7cf | ||
|
|
de11f1f90b | ||
|
|
9ba70424e8 | ||
|
|
c5ba5b4647 | ||
|
|
8e47497edb | ||
|
|
7f7dcffdf0 | ||
|
|
9d8a2a9680 | ||
|
|
880df7a482 | ||
|
|
a016eade01 | ||
|
|
b3167c450e | ||
|
|
6ea37c1f17 | ||
|
|
17c5849f33 | ||
|
|
7e8bd606fe | ||
|
|
51e4076084 | ||
|
|
ff0ec98a27 | ||
|
|
bbe4e5e7f5 | ||
|
|
47c25a0e5e | ||
|
|
553e56fe4c | ||
|
|
bea5d39ed5 | ||
|
|
f6932e09f7 | ||
|
|
44ca95bf85 | ||
|
|
5ba7c4ba2c | ||
|
|
605e63e1df | ||
|
|
bf34ea11bd | ||
|
|
7102214c9e | ||
|
|
e60447ecd2 | ||
|
|
77a57d2243 | ||
|
|
b129ef04f3 | ||
|
|
1f41893aab | ||
|
|
c8e8f39f9d | ||
|
|
4a79e23485 | ||
|
|
20654b0a77 | ||
|
|
8d77891f76 | ||
|
|
bea74661d1 | ||
|
|
6b7bf843a1 | ||
|
|
200ccfd092 | ||
|
|
67a0a47778 | ||
|
|
933e8cbaed | ||
|
|
daac2baf8e | ||
|
|
4a2bcf6fde | ||
|
|
cd7774f056 | ||
|
|
452fb4f990 | ||
|
|
1f72ddb8a1 | ||
|
|
9af078bb8c | ||
|
|
c88655a2a0 | ||
|
|
a27efd94c8 | ||
|
|
9a26ac380a | ||
|
|
240653c429 | ||
|
|
bac3a76d9a | ||
|
|
3a4aed0b34 | ||
|
|
7f5073476c | ||
|
|
1abc3ebea6 | ||
|
|
c21003e1b7 | ||
|
|
1fd0211725 | ||
|
|
1932c7af4f | ||
|
|
94422dab77 | ||
|
|
b10ca3ebcf | ||
|
|
aa2ff4b741 | ||
|
|
284a462936 | ||
|
|
858e0a5b21 | ||
|
|
eaa8e05373 | ||
|
|
3e3d338ed0 | ||
|
|
0c5f5c6e3f | ||
|
|
7c6118bd6f | ||
|
|
7fe99c98f0 | ||
|
|
d6c4c18d35 | ||
|
|
649676e811 | ||
|
|
98c0985657 | ||
|
|
43e93e74b1 | ||
|
|
ba7817170b | ||
|
|
88279906b5 | ||
|
|
134987cb20 | ||
|
|
7b880ae967 | ||
|
|
7e8e3fef61 | ||
|
|
c1147cb9f7 | ||
|
|
54b35ef075 | ||
|
|
fba0a59324 | ||
|
|
c5c7d36bd1 | ||
|
|
83ba55dda5 | ||
|
|
000fff210a | ||
|
|
8965b22f6d | ||
|
|
4023f2412d | ||
|
|
27d56caa48 | ||
|
|
0cc1146f0e | ||
|
|
8aa7b749ca | ||
|
|
55fad45a6c | ||
|
|
22cc12e7a9 | ||
|
|
2812b121ab | ||
|
|
ad3465f0d3 | ||
|
|
fc8b55dce7 | ||
|
|
62d67e9a38 | ||
|
|
079cd7210b | ||
|
|
b60c56f464 | ||
|
|
eb1571d3e4 | ||
|
|
9a13eb36b3 | ||
|
|
9ba5cc1f98 | ||
|
|
2778ec0d9d | ||
|
|
20b0954f8c | ||
|
|
69aa7be6c5 | ||
|
|
73dccbaf24 | ||
|
|
66d836739c | ||
|
|
ab1c44c4fb | ||
|
|
8549c22567 | ||
|
|
d0300de136 | ||
|
|
34c701e039 | ||
|
|
cf0bd6f021 | ||
|
|
3b14dd3b04 | ||
|
|
9a87adf51b | ||
|
|
ce65c7f583 | ||
|
|
82013d5737 | ||
|
|
14377ca354 | ||
|
|
75664961b8 | ||
|
|
c5969c303e | ||
|
|
f4b6b1795e | ||
|
|
b86950d0e7 | ||
|
|
3ef1ac06df | ||
|
|
4c07b6d28d | ||
|
|
7f77cbfd74 | ||
|
|
ca716a65d2 | ||
|
|
4be46cd51d | ||
|
|
bb2b8bc538 | ||
|
|
41ef4f6284 | ||
|
|
cfd3179cb8 | ||
|
|
1a3170c7db | ||
|
|
25463a929a | ||
|
|
408bd49120 | ||
|
|
3fc2d28b95 | ||
|
|
d9eff7bb5c | ||
|
|
4b1c291fca | ||
|
|
0b34b65f76 | ||
|
|
ccb5ceb9b3 | ||
|
|
9fac4f9de4 | ||
|
|
d84c4365c9 | ||
|
|
bec27e0fa6 | ||
|
|
437b02c961 | ||
|
|
e6922eae46 | ||
|
|
b92f4070d4 | ||
|
|
b9750be745 | ||
|
|
973b473100 | ||
|
|
b7606aece0 | ||
|
|
3f62730404 | ||
|
|
c58b28fd00 | ||
|
|
149b3c2e29 | ||
|
|
a412df00c4 | ||
|
|
aa067d4073 | ||
|
|
4c8917c6a0 | ||
|
|
78aefa936f | ||
|
|
2c18adf202 | ||
|
|
083f401ee5 | ||
|
|
6652a7fd83 | ||
|
|
d1b22b0f82 | ||
|
|
0fb08be6e9 | ||
|
|
2da9b99789 | ||
|
|
28bb60244f | ||
|
|
928cd9de94 | ||
|
|
0046fea684 | ||
|
|
864715af40 | ||
|
|
3684d3f9a2 | ||
|
|
69c52c48ab | ||
|
|
9cf5a66e2f | ||
|
|
ae73ef1a33 | ||
|
|
4e2ba4f810 | ||
|
|
aef88cd82f | ||
|
|
9cd40f3ec2 | ||
|
|
a368f0babc | ||
|
|
9565a47c22 | ||
|
|
0df089b3cb | ||
|
|
58efd6158f | ||
|
|
99bd1a52fb | ||
|
|
8ba1725eae | ||
|
|
0a2524fec8 | ||
|
|
162d6aa33a | ||
|
|
fdcdd0fe40 | ||
|
|
8532d388f8 | ||
|
|
ccc144556b | ||
|
|
0b7e438128 | ||
|
|
2f11268dcc | ||
|
|
81514e4192 | ||
|
|
7d5c59aa34 | ||
|
|
dc6d9367b0 | ||
|
|
6c609a6b23 | ||
|
|
b7a3c8568f | ||
|
|
80f84d4001 | ||
|
|
5cecfd14d9 | ||
|
|
8bfcc550f7 | ||
|
|
e40be243de | ||
|
|
033d3bcd4d | ||
|
|
449ec15309 | ||
|
|
8b0ccd81e2 | ||
|
|
a206fd7541 | ||
|
|
77472cb9f4 | ||
|
|
5372d4b8e7 | ||
|
|
0255f3c42f | ||
|
|
eb5c10d375 | ||
|
|
9f6766fb82 | ||
|
|
ab77eb98c0 | ||
|
|
85ab5d7741 | ||
|
|
6457ff315f | ||
|
|
c09a9c88b4 | ||
|
|
e8dc4c893f | ||
|
|
b61edb0d8e | ||
|
|
94b3b51602 | ||
|
|
5415a24f4e | ||
|
|
048ae2fcd0 | ||
|
|
3a4d425a1c | ||
|
|
0a8fc31be1 | ||
|
|
f6ae076731 | ||
|
|
76296d8d41 | ||
|
|
5024375466 | ||
|
|
527b5e6f99 | ||
|
|
17115460b7 | ||
|
|
84aaec6bff | ||
|
|
0a8f740a14 | ||
|
|
8bf230e057 | ||
|
|
1f51ee7233 | ||
|
|
4cd70ee711 | ||
|
|
3d1d73a81a | ||
|
|
ad4d142e94 | ||
|
|
0f77da15ff | ||
|
|
a05ea7c1ce | ||
|
|
8945fc27d7 | ||
|
|
ac91ecc5f6 | ||
|
|
925aaf345c | ||
|
|
2510751fdf | ||
|
|
83e94dbf4a | ||
|
|
41ab131a4d | ||
|
|
252c996abf | ||
|
|
acf5fc1ee4 | ||
|
|
c141d6efc7 | ||
|
|
3b48f11f7b | ||
|
|
9ec8e2daf7 | ||
|
|
4f84200a47 | ||
|
|
e4a99c4a3d | ||
|
|
75adf7c9d4 | ||
|
|
5fc693da22 | ||
|
|
12e2f8b35a | ||
|
|
1e7dbac34e | ||
|
|
e39876ae67 | ||
|
|
ff3bc9a0cd | ||
|
|
dfe1850b93 | ||
|
|
6f50fdc026 | ||
|
|
5c490be861 | ||
|
|
849c7b4fcf | ||
|
|
fd5bb94cb5 | ||
|
|
647bbbedb0 | ||
|
|
6cfb21f660 | ||
|
|
c709b019e1 | ||
|
|
faabe5afb2 | ||
|
|
798bf15155 | ||
|
|
543daa2628 | ||
|
|
3bdf81158a | ||
|
|
9b42094273 | ||
|
|
94f3fcba12 | ||
|
|
58b30341ee | ||
|
|
741e0f8fda | ||
|
|
d8885f9156 | ||
|
|
e9aa18fd6b | ||
|
|
7518f8b98b | ||
|
|
c9dab5402e | ||
|
|
e5169378fc | ||
|
|
ca23750c28 | ||
|
|
446fd84035 | ||
|
|
fc264d0b0f | ||
|
|
e9ad372039 | ||
|
|
b1e8efb00b | ||
|
|
73ee2498e8 | ||
|
|
6608877ef0 | ||
|
|
e9159cb2de | ||
|
|
a403c7424c | ||
|
|
de2abdcab0 | ||
|
|
088ce93701 | ||
|
|
b5a7c92c8d | ||
|
|
d4144264d5 | ||
|
|
b221530276 | ||
|
|
8476c83d62 | ||
|
|
9d624bc822 | ||
|
|
f15c841b99 | ||
|
|
019bccd24a | ||
|
|
584c0709e8 | ||
|
|
d577088b8c | ||
|
|
72f5d8addc | ||
|
|
6d959169fa | ||
|
|
076d05c103 | ||
|
|
1e91b21537 | ||
|
|
b64a0b065c | ||
|
|
faf7e5d25f | ||
|
|
fd37c6b040 | ||
|
|
bb4b5d3080 | ||
|
|
d27f17f74b | ||
|
|
3646fad197 | ||
|
|
34491967e2 | ||
|
|
3df70055b0 | ||
|
|
7c0c4ee74d | ||
|
|
ca415cc719 | ||
|
|
6c17615ecb | ||
|
|
9a1376dcb3 | ||
|
|
32161333dd | ||
|
|
a2f5120069 | ||
|
|
e067492cca | ||
|
|
1cdf2ed1ef | ||
|
|
dc90652853 | ||
|
|
459de30e9a | ||
|
|
4fe68c2c93 | ||
|
|
8b0eb9c9d0 | ||
|
|
a2fce6f4a5 | ||
|
|
78b9e5d833 | ||
|
|
4e2156bd2b | ||
|
|
fdc4d2c5d2 | ||
|
|
7a331bdb09 | ||
|
|
5f50b4522c | ||
|
|
2a630bbc7d | ||
|
|
df32569af6 | ||
|
|
361c36349b | ||
|
|
ddbbb14c72 | ||
|
|
a0899d4776 | ||
|
|
4c8761b17b | ||
|
|
7eb446d528 | ||
|
|
d0230af5c9 | ||
|
|
17564506b5 | ||
|
|
dfd18d64c2 | ||
|
|
c3eaf5a1b0 | ||
|
|
152ef7fe38 | ||
|
|
7ad59b7cb0 | ||
|
|
5d19697004 | ||
|
|
8f7c090a23 | ||
|
|
d39c59663a | ||
|
|
9232ea4fd6 | ||
|
|
cd9ff95226 | ||
|
|
54ad8606dc | ||
|
|
4e1ab821e1 | ||
|
|
3016e774ff | ||
|
|
666779b012 | ||
|
|
ba9198bd45 | ||
|
|
29460a310b | ||
|
|
3507c2016a | ||
|
|
6d996a93c8 | ||
|
|
7cd1563805 | ||
|
|
4ad51649cc | ||
|
|
17023d6afd | ||
|
|
ca85c9739a | ||
|
|
b83b7ee2bc | ||
|
|
c47d5dcba6 | ||
|
|
7335c8ea98 | ||
|
|
8d7ef29d3e | ||
|
|
31a1bf35d9 | ||
|
|
051df7401e | ||
|
|
e8cb0f561e | ||
|
|
24f0eb1a2e | ||
|
|
5f1fba0276 | ||
|
|
c88face33e | ||
|
|
c4eedca28b | ||
|
|
9ac3110d3e | ||
|
|
251f8bccaa | ||
|
|
84d3c0d3e8 | ||
|
|
074aa302bc | ||
|
|
638165aad5 | ||
|
|
65798d17ac | ||
|
|
aacce4f77b | ||
|
|
2153377c0e | ||
|
|
006fb177e6 | ||
|
|
cabc010582 | ||
|
|
ae693ed438 | ||
|
|
4c7b2bbb4e | ||
|
|
314af6d000 | ||
|
|
697e883649 | ||
|
|
f81892ea74 | ||
|
|
4e9a253cfa | ||
|
|
2c62cc37e7 | ||
|
|
2fe0ed2ca1 | ||
|
|
b5e7434c9a | ||
|
|
e3f71c26e7 | ||
|
|
7fda025c0d | ||
|
|
383cbe15a6 | ||
|
|
7cace1ee32 | ||
|
|
1be25079d4 | ||
|
|
16cc07c020 | ||
|
|
7d671c2908 | ||
|
|
df2d9ba3d8 | ||
|
|
ffa696b963 | ||
|
|
6f98e35dec | ||
|
|
39419f4ca3 | ||
|
|
e26b6d08e1 | ||
|
|
cb4fcde6f4 | ||
|
|
f12a210665 | ||
|
|
684c25dc2c | ||
|
|
b20dad57fe | ||
|
|
a41cbdde7f | ||
|
|
32ce40e19e | ||
|
|
fe71654f5b | ||
|
|
bef1f76e45 | ||
|
|
752f039411 | ||
|
|
047bbe0edb | ||
|
|
f022a57b23 | ||
|
|
235948a001 | ||
|
|
c650b5c0bb | ||
|
|
81f9f5ec60 | ||
|
|
870a9ba68f | ||
|
|
e334486e96 | ||
|
|
e9633c6522 | ||
|
|
2ea42eab62 | ||
|
|
06056de6bb | ||
|
|
067da7e1d9 | ||
|
|
8c02947c05 | ||
|
|
9d39bb2d62 | ||
|
|
6a4f2f6830 | ||
|
|
120b12feeb | ||
|
|
40853ae92b | ||
|
|
bb64329b07 | ||
|
|
5878c53aa4 | ||
|
|
f4d1c3fcf2 | ||
|
|
136adaebd5 | ||
|
|
188cc5019f | ||
|
|
e41f445e92 | ||
|
|
bd283910fc | ||
|
|
1e0113a58a | ||
|
|
8bf43648ce | ||
|
|
7d5451558d | ||
|
|
c61d5d480e | ||
|
|
960f8ddce7 | ||
|
|
dc758b767f | ||
|
|
3176d892dd | ||
|
|
495d162ef2 | ||
|
|
b61b52c57e | ||
|
|
f2f485731f | ||
|
|
1aad25776c | ||
|
|
07fa0f3e55 | ||
|
|
45105d8c6a | ||
|
|
613001a600 | ||
|
|
0ec5777f12 | ||
|
|
d066c2596b | ||
|
|
c0c1a6bbcf | ||
|
|
b7fde6390e | ||
|
|
feba8785d7 | ||
|
|
4a172a27ad | ||
|
|
ace9c2d9ec | ||
|
|
70e106eeab | ||
|
|
4d38ca1b3c | ||
|
|
576bee40fc | ||
|
|
0efb17af83 | ||
|
|
0228a2849d | ||
|
|
af53a96f67 | ||
|
|
7eab459195 | ||
|
|
5801cd1e0f | ||
|
|
6bb0f2145e | ||
|
|
15f67392dc | ||
|
|
6571c42c39 | ||
|
|
851fa4ca54 | ||
|
|
39dea80d9c | ||
|
|
c102ca7f15 | ||
|
|
9fe187c049 | ||
|
|
f56971e5ac | ||
|
|
fbaaa78b81 | ||
|
|
acb960bfdf | ||
|
|
0ada2496de | ||
|
|
b7ca30efe8 | ||
|
|
db57916af4 | ||
|
|
4f3074eca8 | ||
|
|
a6af99fdbc | ||
|
|
d6df48430b | ||
|
|
7a01376144 | ||
|
|
2fb9533575 | ||
|
|
66a4d7c2ee | ||
|
|
c66c277221 | ||
|
|
98a731e5df | ||
|
|
74cb0d5167 | ||
|
|
478812d648 | ||
|
|
e759fbb5db | ||
|
|
c24485b5f9 | ||
|
|
8eae83f218 | ||
|
|
09495695f2 | ||
|
|
14a86160d6 | ||
|
|
f59f178cec | ||
|
|
6498c010f8 | ||
|
|
909bbc43d0 | ||
|
|
ce326e24e6 | ||
|
|
4de081efda | ||
|
|
8848758578 | ||
|
|
326c6cb158 | ||
|
|
4e4b35b2e7 | ||
|
|
d7caf2ae3c | ||
|
|
700f0c293e | ||
|
|
00dedaa1ff | ||
|
|
34cba80fd8 | ||
|
|
172ac19585 | ||
|
|
05617a95b7 | ||
|
|
c46bdcf42b | ||
|
|
f739060ebb | ||
|
|
b9e4466ef0 | ||
|
|
be4af60ad1 | ||
|
|
721297bf21 | ||
|
|
9ff20f3fea | ||
|
|
566c9dbda0 | ||
|
|
ff5bb8acc6 | ||
|
|
195b89f24c | ||
|
|
012aac97ee | ||
|
|
ba70dae9ad | ||
|
|
c43e702ed9 | ||
|
|
9dfbe3b263 | ||
|
|
444eabcebf | ||
|
|
ede4fa5a5d | ||
|
|
cc4ae6eb80 | ||
|
|
0a37031418 | ||
|
|
bd9096ef6d | ||
|
|
246dc34835 | ||
|
|
f90029319e | ||
|
|
18dc323f7f | ||
|
|
a948503895 | ||
|
|
616c9474ce | ||
|
|
77dc403bb9 | ||
|
|
6fd1ee227f | ||
|
|
19eb478067 | ||
|
|
54540fb8ef | ||
|
|
5a74e129a4 | ||
|
|
12c21c9b0a | ||
|
|
61836895b0 | ||
|
|
5f36302057 | ||
|
|
1b9bf4b36e | ||
|
|
9b9cdf8b8f | ||
|
|
ab1a586b4c | ||
|
|
030a3fe4ac | ||
|
|
fd01b9a6d2 | ||
|
|
11be597d11 | ||
|
|
875e5d7252 | ||
|
|
e372a56827 | ||
|
|
471f1ae71d | ||
|
|
a27808ade1 | ||
|
|
2703e849cb | ||
|
|
d57ef2b303 | ||
|
|
5a7626f280 | ||
|
|
1c4e0051a0 | ||
|
|
b3d3921f6e | ||
|
|
976c418c9e | ||
|
|
b2669129f2 | ||
|
|
343e316e4c | ||
|
|
ce219e208c | ||
|
|
358267d6e3 | ||
|
|
786788aa23 | ||
|
|
49b20e37cb | ||
|
|
3f5362a857 | ||
|
|
c7c61df0b8 | ||
|
|
298835be42 | ||
|
|
4a51958da4 | ||
|
|
cff23db7d3 | ||
|
|
f70059b4b6 | ||
|
|
757d22da23 | ||
|
|
4bc4aa26a4 | ||
|
|
cbc0a12dd6 | ||
|
|
100a147a4a | ||
|
|
c405424500 | ||
|
|
23091d60ff | ||
|
|
f0968408b6 | ||
|
|
2bf2be071d | ||
|
|
c502e2cf7e | ||
|
|
2d8446b4e3 | ||
|
|
279162d720 | ||
|
|
a64c21da8b | ||
|
|
4d58c717cd | ||
|
|
634f92b5cd | ||
|
|
24c4af486c | ||
|
|
280fe1aed0 | ||
|
|
7cfa78557e | ||
|
|
f599583856 | ||
|
|
10688a7067 | ||
|
|
188419feb0 | ||
|
|
fd44e2e9bd | ||
|
|
e19d7e88bd | ||
|
|
2446577188 | ||
|
|
fef435b9fb | ||
|
|
1cb3b985a7 | ||
|
|
2292175e9a | ||
|
|
ef04346019 | ||
|
|
381ff1e5d3 | ||
|
|
079f8df6e0 | ||
|
|
56637f50bc | ||
|
|
914888dade | ||
|
|
8e20df57a9 | ||
|
|
7d5191fa2f | ||
|
|
08528a1745 | ||
|
|
a8e3d9ec95 | ||
|
|
e5dd9b61a4 | ||
|
|
6ee2d0574f | ||
|
|
91b5a8036c | ||
|
|
24ab0d8590 | ||
|
|
d8f55006ff | ||
|
|
0817d28b88 | ||
|
|
577c8b4eaf | ||
|
|
5b5f0dce24 | ||
|
|
a818b9a9d4 | ||
|
|
3160c076f0 | ||
|
|
6d0b28fac4 | ||
|
|
ce286cf322 | ||
|
|
7d001c61a8 | ||
|
|
a09e8b9f4d | ||
|
|
395d020411 | ||
|
|
ece4455130 | ||
|
|
cc64ffff98 | ||
|
|
dd332420e5 | ||
|
|
ce8ba6a5af | ||
|
|
21eb824395 | ||
|
|
246e5ca742 | ||
|
|
2bd03ad92c | ||
|
|
7971dc797b | ||
|
|
36c047bfa0 | ||
|
|
d7daab7e64 | ||
|
|
b925e91bbb | ||
|
|
3b1341f2b3 | ||
|
|
667ad0d059 | ||
|
|
da98722470 | ||
|
|
c92fcc9f9a | ||
|
|
8d66ce776c | ||
|
|
412202e105 | ||
|
|
35c9e4e268 | ||
|
|
81ea78e003 | ||
|
|
833698fe8a | ||
|
|
70964e9ba9 | ||
|
|
255a4d516e | ||
|
|
11d26c13b8 | ||
|
|
00b4396f86 | ||
|
|
1d5d0012e6 | ||
|
|
18c706ab8a | ||
|
|
6a65a35dee | ||
|
|
37aab2c759 | ||
|
|
18ad5da081 | ||
|
|
9f65e727c9 | ||
|
|
efa6e8ec31 | ||
|
|
a7df7715b1 | ||
|
|
a9831c842c | ||
|
|
439a5f90c1 | ||
|
|
a6491cf792 | ||
|
|
e1025afb54 | ||
|
|
a5dddf371d | ||
|
|
fe95bbf312 | ||
|
|
0bab4f62de | ||
|
|
981b5cf3bf | ||
|
|
89f47c6a6a | ||
|
|
9fd1687348 | ||
|
|
899eac0e7e | ||
|
|
efad8f41a1 | ||
|
|
ee81935a74 | ||
|
|
e3c4253c13 | ||
|
|
9d991cdd26 | ||
|
|
3fdbf5b062 | ||
|
|
40937acfa0 | ||
|
|
99e4ab22e3 | ||
|
|
8da0c4310c | ||
|
|
280da6b8e9 | ||
|
|
71ff8a773b | ||
|
|
e3c1b9bf64 | ||
|
|
a52552dcb4 | ||
|
|
e8039e158f | ||
|
|
c37ef71f72 | ||
|
|
0388f340cc | ||
|
|
5e437d26d9 | ||
|
|
c10c3547b9 | ||
|
|
528a8e5587 | ||
|
|
ea4487e33f | ||
|
|
c2578bd212 | ||
|
|
a1347dd669 | ||
|
|
3228ba65ae | ||
|
|
08b2d5b7e8 | ||
|
|
2b89dbce0e | ||
|
|
f256309487 | ||
|
|
462abb1ef9 | ||
|
|
a35408d14f | ||
|
|
81d4deaea7 | ||
|
|
9103f89aff | ||
|
|
8e4c2648a3 | ||
|
|
ad020ec329 | ||
|
|
df3be302af | ||
|
|
8e3b8cb572 | ||
|
|
ff1554556e | ||
|
|
b15c93c416 | ||
|
|
071b42c9e0 | ||
|
|
304f9b34fd | ||
|
|
c817a0e9cb | ||
|
|
744252d492 | ||
|
|
9186361a29 | ||
|
|
bf01c9ea0e | ||
|
|
bee260e2b4 | ||
|
|
21811991f1 | ||
|
|
a2809f8d5c | ||
|
|
95f2b597da | ||
|
|
fa348fbc23 | ||
|
|
d277701caa | ||
|
|
9b7f68a888 | ||
|
|
7e837ef9db | ||
|
|
eb78fe4bfc | ||
|
|
689f0fd5db | ||
|
|
32316cf3ab |
No files matched your search
@@ -0,0 +1,31 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a bug report so we can fix it
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug, provide any errors**
|
||||
A clear and concise description of what the bug is. If present, can you paste the error to https://paste.gg/?
|
||||
|
||||
**How can we reproduce it?**
|
||||
Steps to reproduce the behavior:
|
||||
1. Login on 1.12'
|
||||
2. Click on '....'
|
||||
3. The '....' is displayed wrong
|
||||
|
||||
**Expected behaviour**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**ViaVersion Dump**
|
||||
- Type /viaversion dump, and put the link here.
|
||||
|
||||
**Additional server info**
|
||||
Do you use a proxy (eg. BungeeCord)? What software do you use and what plugins?
|
||||
|
||||
**Checklist**
|
||||
- [ ] I have included a Viaversion dump
|
||||
- [ ] If applicable, I have included a paste (not a screenshot) of the error
|
||||
- [ ] I have tried a build from https://ci.viaversion.com/ and the issue still persists
|
||||
@@ -0,0 +1 @@
|
||||
blank_issues_enabled: false
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for ViaVersion
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Which versions is this for?**
|
||||
Does the feature apply to any specific versions? If so put them here.
|
||||
+7
-4
@@ -1,12 +1,15 @@
|
||||
sudo: false
|
||||
|
||||
language: java
|
||||
jdk: oraclejdk8
|
||||
jdk:
|
||||
- openjdk11
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- '$HOME/.m2/repository'
|
||||
- '$HOME/.m2/repository'
|
||||
|
||||
script:
|
||||
- mvn dependency:purge-local-repository -DactTransitively=false -DreResolve=false
|
||||
- mvn clean install -B -U
|
||||
- mvn dependency:purge-local-repository -DactTransitively=false -DreResolve=false
|
||||
- mvn clean install -B -U
|
||||
|
||||
install: true
|
||||
@@ -1,11 +0,0 @@
|
||||
### What is the output link of /viaversion dump?
|
||||
|
||||
|
||||
### Are you using any additional software like BungeeCord? If so, what software and version? (Please list your plugins as well)
|
||||
|
||||
|
||||
### How does this error happen? login? Using an item?
|
||||
|
||||
|
||||
### Is there an error in the console? Use pastebin.com. Is there a kick message?
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
License:
|
||||
--------
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016
|
||||
Copyright (c) 2020
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -21,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
SOFTWARE.
|
||||
@@ -1,20 +1,18 @@
|
||||
# ViaVersion 1.0.0 - Spigot, Sponge, BungeeCord
|
||||
[](https://travis-ci.org/MylesIsCool/ViaVersion)
|
||||
[](https://gitter.im/MylesIsCool/ViaVersion)
|
||||
|
||||
IRC: [#viaversion](http://irc.spi.gt/iris/?channels=viaversion) on irc.spi.gt for Support.
|
||||
# ViaVersion - Spigot, Sponge, BungeeCord, Velocity
|
||||
[](https://viaversion.com)
|
||||
[](https://travis-ci.com/ViaVersion/ViaVersion)
|
||||
[](https://viaversion.com/discord)
|
||||
|
||||
**Allows the connection of higher client versions to lower server versions**
|
||||
|
||||
Supported Versions:
|
||||
|
||||
[![Table] (http://i.imgur.com/SVVhFQ4.png)](http://i.imgur.com/SVVhFQ4.png)
|
||||

|
||||
|
||||
On Bukkit you may also use ProtocolSupport, but ensure you have the right build for your server version.
|
||||
On Paper you may also use ProtocolSupport, but ensure you have the right build for your server version.
|
||||
|
||||
**User Docs:** https://docs.viaversion.com/display/VIAVERSION/
|
||||
|
||||
**Contributor Chat:** https://gitter.im/MylesIsCool/ViaVersion
|
||||
|
||||
|
||||
|
||||
@@ -51,4 +49,4 @@ License:
|
||||
MIT License, see LICENSE for more details.
|
||||
|
||||
|
||||
Special thanks to all our [Contributors](https://github.com/MylesIsCool/ViaVersion/graphs/contributors)
|
||||
Special thanks to all our [Contributors](https://github.com/ViaVersion/ViaVersion/graphs/contributors)
|
||||
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>viaversion-parent</artifactId>
|
||||
<groupId>us.myles</groupId>
|
||||
<version>3.2.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>viaversion-bukkit-legacy</artifactId>
|
||||
|
||||
<properties>
|
||||
<bukkitVersion>1.8.8-R0.1-SNAPSHOT</bukkitVersion>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<targetPath>.</targetPath>
|
||||
<filtering>true</filtering>
|
||||
<directory>src/main/resources/</directory>
|
||||
<includes>
|
||||
<include>*</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<!-- Common Module -->
|
||||
<dependency>
|
||||
<groupId>us.myles</groupId>
|
||||
<artifactId>viaversion-common</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Bukkit API, http://www.spigotmc.org/ or http://bukkit.org/ -->
|
||||
<dependency>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
<version>${bukkitVersion}</version>
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>junit</artifactId>
|
||||
<groupId>junit</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>gson</artifactId>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>persistence-api</artifactId>
|
||||
<groupId>javax.persistence</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
+6
-7
@@ -1,21 +1,16 @@
|
||||
package us.myles.ViaVersion.bukkit.listeners;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import us.myles.ViaVersion.ViaVersionPlugin;
|
||||
import us.myles.ViaVersion.api.ViaListener;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.protocol.Protocol;
|
||||
|
||||
@Getter(AccessLevel.PROTECTED)
|
||||
public class ViaBukkitListener extends ViaListener implements Listener {
|
||||
private final Plugin plugin;
|
||||
|
||||
public ViaBukkitListener(ViaVersionPlugin plugin, Class<? extends Protocol> requiredPipeline) {
|
||||
public ViaBukkitListener(Plugin plugin, Class<? extends Protocol> requiredPipeline) {
|
||||
super(requiredPipeline);
|
||||
this.plugin = plugin;
|
||||
}
|
||||
@@ -26,7 +21,7 @@ public class ViaBukkitListener extends ViaListener implements Listener {
|
||||
* @param player Player object
|
||||
* @return The UserConnection
|
||||
*/
|
||||
protected UserConnection getUserConnection(@NonNull Player player) {
|
||||
protected UserConnection getUserConnection(Player player) {
|
||||
return getUserConnection(player.getUniqueId());
|
||||
}
|
||||
|
||||
@@ -50,4 +45,8 @@ public class ViaBukkitListener extends ViaListener implements Listener {
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
setRegistered(true);
|
||||
}
|
||||
|
||||
public Plugin getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
}
|
||||
+13
-18
@@ -9,17 +9,18 @@ import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.player.PlayerChangedWorldEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerItemBreakEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerRespawnEvent;
|
||||
import org.bukkit.inventory.CraftingInventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import us.myles.ViaVersion.ViaVersionPlugin;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.bukkit.listeners.ViaBukkitListener;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.ArmorType;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9To1_8;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -27,15 +28,14 @@ public class ArmorListener extends ViaBukkitListener {
|
||||
|
||||
private static final UUID ARMOR_ATTRIBUTE = UUID.fromString("2AD3F246-FEE1-4E67-B886-69FD380BB150");
|
||||
|
||||
public ArmorListener(ViaVersionPlugin plugin) {
|
||||
super(plugin, Protocol1_9TO1_8.class);
|
||||
public ArmorListener(Plugin plugin) {
|
||||
super(plugin, Protocol1_9To1_8.class);
|
||||
}
|
||||
|
||||
public void sendArmorUpdate(Player player) {
|
||||
// Ensure that the player is on our pipe
|
||||
if (!isOnPipe(player)) return;
|
||||
|
||||
|
||||
int armor = 0;
|
||||
for (ItemStack stack : player.getInventory().getArmorContents()) {
|
||||
armor += ArmorType.findById(stack.getTypeId()).getArmorPoints();
|
||||
@@ -52,7 +52,7 @@ public class ArmorListener extends ViaBukkitListener {
|
||||
wrapper.write(Type.DOUBLE, (double) armor); // the modifier value
|
||||
wrapper.write(Type.BYTE, (byte) 0);// the modifier operation, 0 is add number
|
||||
|
||||
wrapper.send(Protocol1_9TO1_8.class);
|
||||
wrapper.send(Protocol1_9To1_8.class);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -81,16 +81,16 @@ public class ArmorListener extends ViaBukkitListener {
|
||||
if (e.getAction() == Action.RIGHT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_BLOCK) {
|
||||
final Player player = e.getPlayer();
|
||||
// Due to odd bugs it's 3 ticks later
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(getPlugin(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
sendArmorUpdate(player);
|
||||
}
|
||||
}, 3L);
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(getPlugin(), () -> sendArmorUpdate(player), 3L);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onItemBreak(PlayerItemBreakEvent e) {
|
||||
sendDelayedArmorUpdate(e.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onJoin(PlayerJoinEvent e) {
|
||||
sendDelayedArmorUpdate(e.getPlayer());
|
||||
@@ -108,11 +108,6 @@ public class ArmorListener extends ViaBukkitListener {
|
||||
|
||||
public void sendDelayedArmorUpdate(final Player player) {
|
||||
if (!isOnPipe(player)) return; // Don't start a task if the player is not on the pipe
|
||||
Via.getPlatform().runSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
sendArmorUpdate(player);
|
||||
}
|
||||
});
|
||||
Via.getPlatform().runSync(() -> sendArmorUpdate(player));
|
||||
}
|
||||
}
|
||||
+7
-7
@@ -4,16 +4,16 @@ import org.bukkit.block.Block;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import us.myles.ViaVersion.ViaVersionPlugin;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import us.myles.ViaVersion.api.minecraft.Position;
|
||||
import us.myles.ViaVersion.bukkit.listeners.ViaBukkitListener;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9To1_8;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker1_9;
|
||||
|
||||
public class BlockListener extends ViaBukkitListener {
|
||||
|
||||
public BlockListener(ViaVersionPlugin plugin) {
|
||||
super(plugin, Protocol1_9TO1_8.class);
|
||||
public BlockListener(Plugin plugin) {
|
||||
super(plugin, Protocol1_9To1_8.class);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
@@ -21,8 +21,8 @@ public class BlockListener extends ViaBukkitListener {
|
||||
if (isOnPipe(e.getPlayer())) {
|
||||
Block b = e.getBlockPlaced();
|
||||
getUserConnection(e.getPlayer())
|
||||
.get(EntityTracker.class)
|
||||
.addBlockInteraction(new Position((long) b.getX(), (long) b.getY(), (long) b.getZ()));
|
||||
.get(EntityTracker1_9.class)
|
||||
.addBlockInteraction(new Position(b.getX(), (short) b.getY(), b.getZ()));
|
||||
}
|
||||
}
|
||||
}
|
||||
+20
-15
@@ -5,23 +5,24 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import us.myles.ViaVersion.ViaVersionPlugin;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.ViaVersion;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.bukkit.listeners.ViaBukkitListener;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9To1_8;
|
||||
|
||||
public class DeathListener extends ViaBukkitListener {
|
||||
public DeathListener(ViaVersionPlugin plugin) {
|
||||
super(plugin, Protocol1_9TO1_8.class);
|
||||
|
||||
public DeathListener(Plugin plugin) {
|
||||
super(plugin, Protocol1_9To1_8.class);
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||
public void onDeath(PlayerDeathEvent e) {
|
||||
Player p = e.getEntity();
|
||||
if (isOnPipe(p) && ViaVersion.getConfig().isShowNewDeathMessages() && checkGamerule(p.getWorld()) && e.getDeathMessage() != null)
|
||||
if (isOnPipe(p) && Via.getConfig().isShowNewDeathMessages() && checkGamerule(p.getWorld()) && e.getDeathMessage() != null)
|
||||
sendPacket(p, e.getDeathMessage());
|
||||
}
|
||||
|
||||
@@ -37,16 +38,20 @@ public class DeathListener extends ViaBukkitListener {
|
||||
Via.getPlatform().runSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
PacketWrapper wrapper = new PacketWrapper(0x2C, null, getUserConnection(p));
|
||||
try {
|
||||
wrapper.write(Type.VAR_INT, 2); // Event - Entity dead
|
||||
wrapper.write(Type.VAR_INT, p.getEntityId()); // Player ID
|
||||
wrapper.write(Type.INT, p.getEntityId()); // Entity ID
|
||||
Protocol1_9TO1_8.FIX_JSON.write(wrapper, msg); // Message
|
||||
// If online
|
||||
UserConnection userConnection = getUserConnection(p);
|
||||
if (userConnection != null) {
|
||||
PacketWrapper wrapper = new PacketWrapper(0x2C, null, userConnection);
|
||||
try {
|
||||
wrapper.write(Type.VAR_INT, 2); // Event - Entity dead
|
||||
wrapper.write(Type.VAR_INT, p.getEntityId()); // Player ID
|
||||
wrapper.write(Type.INT, p.getEntityId()); // Entity ID
|
||||
Protocol1_9To1_8.FIX_JSON.write(wrapper, msg); // Message
|
||||
|
||||
wrapper.send(Protocol1_9TO1_8.class);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
wrapper.send(Protocol1_9To1_8.class);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
+8
-9
@@ -8,18 +8,13 @@ import us.myles.ViaVersion.api.minecraft.item.Item;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class HandItemCache extends BukkitRunnable {
|
||||
public static boolean CACHE = false;
|
||||
private static ConcurrentHashMap<UUID, Item> handCache = new ConcurrentHashMap<>();
|
||||
|
||||
public static Item getHandItem(UUID player) {
|
||||
if (!handCache.containsKey(player))
|
||||
return null;
|
||||
return handCache.get(player);
|
||||
}
|
||||
private final Map<UUID, Item> handCache = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -35,8 +30,12 @@ public class HandItemCache extends BukkitRunnable {
|
||||
}
|
||||
}
|
||||
|
||||
public Item getHandItem(UUID player) {
|
||||
return handCache.get(player);
|
||||
}
|
||||
|
||||
public static Item convert(ItemStack itemInHand) {
|
||||
if (itemInHand == null) return new Item((short) 0, (byte) 0, (short) 0, null);
|
||||
return new Item((short) itemInHand.getTypeId(), (byte) itemInHand.getAmount(), itemInHand.getDurability(), null);
|
||||
if (itemInHand == null) return new Item(0, (byte) 0, (short) 0, null);
|
||||
return new Item(itemInHand.getTypeId(), (byte) itemInHand.getAmount(), itemInHand.getDurability(), null);
|
||||
}
|
||||
}
|
||||
+25
-9
@@ -4,15 +4,16 @@ import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import us.myles.ViaVersion.ViaVersionPlugin;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import us.myles.ViaVersion.bukkit.listeners.ViaBukkitListener;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9To1_8;
|
||||
|
||||
public class PaperPatch extends ViaBukkitListener {
|
||||
|
||||
public PaperPatch(ViaVersionPlugin plugin) {
|
||||
super(plugin, Protocol1_9TO1_8.class);
|
||||
public PaperPatch(Plugin plugin) {
|
||||
super(plugin, Protocol1_9To1_8.class);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -22,18 +23,19 @@ public class PaperPatch extends ViaBukkitListener {
|
||||
If there is a better fix then we'll replace this.
|
||||
*/
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
||||
public void onPlace(BlockPlaceEvent e) {
|
||||
if (isOnPipe(e.getPlayer())) {
|
||||
Location diff = e.getPlayer().getLocation().subtract(e.getBlock().getLocation().add(0.5D, 0, 0.5D));
|
||||
Location location = e.getPlayer().getLocation();
|
||||
Location diff = location.clone().subtract(e.getBlock().getLocation().add(0.5D, 0, 0.5D));
|
||||
Material block = e.getBlockPlaced().getType();
|
||||
if (!block.isSolid()) {
|
||||
if (isPlacable(block)) {
|
||||
return;
|
||||
}
|
||||
if (e.getPlayer().getLocation().getBlock().equals(e.getBlock())) {
|
||||
if (location.getBlock().equals(e.getBlock())) {
|
||||
e.setCancelled(true);
|
||||
} else {
|
||||
if (e.getPlayer().getLocation().getBlock().getRelative(BlockFace.UP).equals(e.getBlock())) {
|
||||
if (location.getBlock().getRelative(BlockFace.UP).equals(e.getBlock())) {
|
||||
e.setCancelled(true);
|
||||
} else {
|
||||
// Within radius of block
|
||||
@@ -55,4 +57,18 @@ public class PaperPatch extends ViaBukkitListener {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPlacable(Material material) {
|
||||
if (!material.isSolid()) return true;
|
||||
// signs and banners
|
||||
switch (material.getId()) {
|
||||
case 63:
|
||||
case 68:
|
||||
case 176:
|
||||
case 177:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package us.myles.ViaVersion.bukkit.providers;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.minecraft.Position;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.blockconnections.providers.BlockConnectionProvider;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class BukkitBlockConnectionProvider extends BlockConnectionProvider {
|
||||
private Chunk lastChunk;
|
||||
|
||||
@Override
|
||||
public int getWorldBlockData(UserConnection user, int bx, int by, int bz) {
|
||||
UUID uuid = user.getProtocolInfo().getUuid();
|
||||
Player player = Bukkit.getPlayer(uuid);
|
||||
if (player != null) {
|
||||
World world = player.getWorld();
|
||||
int x = bx >> 4;
|
||||
int z = bz >> 4;
|
||||
if (world.isChunkLoaded(x, z)) {
|
||||
Chunk c = getChunk(world, x, z);
|
||||
Block b = c.getBlock(bx, by, bz);
|
||||
return b.getTypeId() << 4 | b.getData();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Chunk getChunk(World world, int x, int z) {
|
||||
if (lastChunk != null && lastChunk.getX() == x && lastChunk.getZ() == z) {
|
||||
return lastChunk;
|
||||
}
|
||||
return lastChunk = world.getChunkAt(x, z);
|
||||
}
|
||||
}
|
||||
+15
-7
@@ -5,15 +5,15 @@
|
||||
<parent>
|
||||
<artifactId>viaversion-parent</artifactId>
|
||||
<groupId>us.myles</groupId>
|
||||
<version>1.0.0</version>
|
||||
<version>3.2.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>viaversion-bukkit</artifactId>
|
||||
|
||||
<properties>
|
||||
<!-- Change Bukkit Version HERE! -->
|
||||
<bukkitVersion>1.8.8-R0.1-SNAPSHOT</bukkitVersion>
|
||||
<!-- Change server version HERE! -->
|
||||
<serverVersion>1.16.1-R0.1-SNAPSHOT</serverVersion>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
@@ -40,9 +40,9 @@
|
||||
|
||||
<!-- Bukkit API, http://www.spigotmc.org/ or http://bukkit.org/ -->
|
||||
<dependency>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
<version>${bukkitVersion}</version>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>${serverVersion}</version>
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
<exclusions>
|
||||
@@ -60,5 +60,13 @@
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- Legacy Support -->
|
||||
<dependency>
|
||||
<groupId>us.myles</groupId>
|
||||
<artifactId>viaversion-bukkit-legacy</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
</project>
|
||||
@@ -1,7 +1,6 @@
|
||||
package us.myles.ViaVersion;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -9,15 +8,20 @@ import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.ViaAPI;
|
||||
import us.myles.ViaVersion.api.ViaVersion;
|
||||
import us.myles.ViaVersion.api.command.ViaCommandSender;
|
||||
import us.myles.ViaVersion.api.configuration.ConfigurationProvider;
|
||||
import us.myles.ViaVersion.api.data.MappingDataLoader;
|
||||
import us.myles.ViaVersion.api.platform.TaskId;
|
||||
import us.myles.ViaVersion.api.platform.ViaConnectionManager;
|
||||
import us.myles.ViaVersion.api.platform.ViaPlatform;
|
||||
import us.myles.ViaVersion.bukkit.classgenerator.ClassGenerator;
|
||||
import us.myles.ViaVersion.bukkit.commands.BukkitCommandHandler;
|
||||
import us.myles.ViaVersion.bukkit.commands.BukkitCommandSender;
|
||||
import us.myles.ViaVersion.bukkit.platform.*;
|
||||
import us.myles.ViaVersion.bukkit.platform.BukkitTaskId;
|
||||
import us.myles.ViaVersion.bukkit.platform.BukkitViaAPI;
|
||||
import us.myles.ViaVersion.bukkit.platform.BukkitViaConfig;
|
||||
import us.myles.ViaVersion.bukkit.platform.BukkitViaInjector;
|
||||
import us.myles.ViaVersion.bukkit.platform.BukkitViaLoader;
|
||||
import us.myles.ViaVersion.bukkit.util.NMSUtil;
|
||||
import us.myles.ViaVersion.dump.PluginInfo;
|
||||
import us.myles.ViaVersion.util.GsonUtil;
|
||||
@@ -26,21 +30,22 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform {
|
||||
|
||||
private BukkitCommandHandler commandHandler;
|
||||
private boolean compatSpigotBuild = false;
|
||||
public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform<Player> {
|
||||
private static ViaVersionPlugin instance;
|
||||
private final ViaConnectionManager connectionManager = new ViaConnectionManager();
|
||||
private final BukkitCommandHandler commandHandler;
|
||||
private final BukkitViaConfig conf;
|
||||
private final ViaAPI<Player> api = new BukkitViaAPI(this);
|
||||
private final List<Runnable> queuedTasks = new ArrayList<>();
|
||||
private final List<Runnable> asyncQueuedTasks = new ArrayList<>();
|
||||
private final boolean protocolSupport;
|
||||
private boolean compatSpigotBuild;
|
||||
private boolean spigot = true;
|
||||
private boolean lateBind = false;
|
||||
private boolean protocolSupport = false;
|
||||
@Getter
|
||||
private BukkitConfigAPI conf;
|
||||
@Getter
|
||||
private ViaAPI<Player> api = new BukkitViaAPI(this);
|
||||
private List<Runnable> queuedTasks = new ArrayList<>();
|
||||
private List<Runnable> asyncQueuedTasks = new ArrayList<>();
|
||||
private boolean lateBind;
|
||||
|
||||
public ViaVersionPlugin() {
|
||||
instance = this;
|
||||
|
||||
// Command handler
|
||||
commandHandler = new BukkitCommandHandler();
|
||||
// Init platform
|
||||
@@ -51,13 +56,10 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform {
|
||||
.loader(new BukkitViaLoader(this))
|
||||
.build());
|
||||
// Config magic
|
||||
conf = new BukkitConfigAPI();
|
||||
// For compatibility
|
||||
ViaVersion.setInstance(this);
|
||||
conf = new BukkitViaConfig();
|
||||
|
||||
// Check if we're using protocol support too
|
||||
protocolSupport = Bukkit.getPluginManager().getPlugin("ProtocolSupport") != null;
|
||||
|
||||
if (protocolSupport) {
|
||||
getLogger().info("Hooking into ProtocolSupport, to prevent issues!");
|
||||
try {
|
||||
@@ -79,11 +81,16 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform {
|
||||
|
||||
// Check if it's a spigot build with a protocol mod
|
||||
try {
|
||||
compatSpigotBuild = NMSUtil.nms("PacketEncoder").getDeclaredField("version") != null;
|
||||
NMSUtil.nms("PacketEncoder").getDeclaredField("version");
|
||||
compatSpigotBuild = true;
|
||||
} catch (Exception e) {
|
||||
compatSpigotBuild = false;
|
||||
}
|
||||
|
||||
if (getServer().getPluginManager().getPlugin("ViaBackwards") != null) {
|
||||
MappingDataLoader.enableMappingsCache();
|
||||
}
|
||||
|
||||
// Generate classes needed (only works if it's compat or ps)
|
||||
ClassGenerator.generate();
|
||||
lateBind = !BukkitViaInjector.isBinded();
|
||||
@@ -126,19 +133,6 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform {
|
||||
Via.getManager().destroy();
|
||||
}
|
||||
|
||||
public boolean isCompatSpigotBuild() {
|
||||
return compatSpigotBuild;
|
||||
}
|
||||
|
||||
|
||||
public boolean isSpigot() {
|
||||
return this.spigot;
|
||||
}
|
||||
|
||||
public boolean isProtocolSupport() {
|
||||
return protocolSupport;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPlatformName() {
|
||||
return Bukkit.getServer().getName();
|
||||
@@ -174,9 +168,14 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskId runSync(Runnable runnable, Long ticks) {
|
||||
return new BukkitTaskId(getServer().getScheduler().runTaskLater(this, runnable, ticks).getTaskId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskId runRepeatingSync(Runnable runnable, Long ticks) {
|
||||
return new BukkitTaskId(getServer().getScheduler().runTaskTimer(this, runnable, ticks, 0).getTaskId());
|
||||
return new BukkitTaskId(getServer().getScheduler().runTaskTimer(this, runnable, 0, ticks).getTaskId());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -232,7 +231,7 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform {
|
||||
if (Bukkit.getPluginManager().getPlugin("ProtocolLib") != null) {
|
||||
getLogger().severe("ViaVersion is already loaded, we're going to kick all the players... because otherwise we'll crash because of ProtocolLib.");
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
player.kickPlayer(ChatColor.translateAlternateColorCodes('&', getConf().getReloadDisconnectMsg()));
|
||||
player.kickPlayer(ChatColor.translateAlternateColorCodes('&', conf.getReloadDisconnectMsg()));
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -253,4 +252,40 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform {
|
||||
|
||||
return platformSpecific;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOldClientsAllowed() {
|
||||
return !protocolSupport; // Use protocolsupport for older clients
|
||||
}
|
||||
|
||||
@Override
|
||||
public BukkitViaConfig getConf() {
|
||||
return conf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViaAPI<Player> getApi() {
|
||||
return api;
|
||||
}
|
||||
|
||||
public boolean isCompatSpigotBuild() {
|
||||
return compatSpigotBuild;
|
||||
}
|
||||
|
||||
public boolean isSpigot() {
|
||||
return this.spigot;
|
||||
}
|
||||
|
||||
public boolean isProtocolSupport() {
|
||||
return protocolSupport;
|
||||
}
|
||||
|
||||
public static ViaVersionPlugin getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViaConnectionManager getConnectionManager() {
|
||||
return connectionManager;
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package us.myles.ViaVersion.api;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import us.myles.ViaVersion.ViaVersionPlugin;
|
||||
|
||||
@Deprecated
|
||||
public class ViaVersion {
|
||||
@Getter
|
||||
private static ViaVersionAPI instance;
|
||||
@Getter
|
||||
private static ViaVersionConfig config;
|
||||
|
||||
public static void setInstance(ViaVersionPlugin plugin) {
|
||||
Validate.isTrue(instance == null, "Instance is already set");
|
||||
ViaVersion.instance = (ViaVersionAPI) plugin.getApi();
|
||||
ViaVersion.config = plugin.getConf();
|
||||
}
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
package us.myles.ViaVersion.api;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import org.bukkit.entity.Player;
|
||||
import us.myles.ViaVersion.api.boss.BossBar;
|
||||
import us.myles.ViaVersion.api.boss.BossColor;
|
||||
import us.myles.ViaVersion.api.boss.BossStyle;
|
||||
import us.myles.ViaVersion.api.command.ViaVersionCommand;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
|
||||
|
||||
import java.util.SortedSet;
|
||||
import java.util.UUID;
|
||||
|
||||
@Deprecated
|
||||
public interface ViaVersionAPI extends ViaAPI<Player> {
|
||||
/**
|
||||
* Is the player connection modified by ViaVersion?
|
||||
*
|
||||
* @param player Bukkit player object
|
||||
* @return True if the client is modified (At the moment it also means version 1.9 and higher)
|
||||
* @deprecated As of 0.9.9, because all players are ported use {@link #getPlayerVersion(Player)}
|
||||
*/
|
||||
boolean isPorted(Player player);
|
||||
|
||||
/**
|
||||
* Get protocol number from a player
|
||||
* Will also retrieve version from ProtocolSupport if it's being used.
|
||||
*
|
||||
* @param player Bukkit player object
|
||||
* @return Protocol ID, For example (47=1.8-1.8.8, 107=1.9, 108=1.9.1)
|
||||
*/
|
||||
int getPlayerVersion(Player player);
|
||||
|
||||
/**
|
||||
* Get protocol number from a player
|
||||
*
|
||||
* @param uuid UUID of a player
|
||||
* @return Protocol ID, For example (47=1.8-1.8.8, 107=1.9, 108=1.9.1)
|
||||
*/
|
||||
int getPlayerVersion(UUID uuid);
|
||||
|
||||
/**
|
||||
* Is player using 1.9?
|
||||
*
|
||||
* @param playerUUID UUID of a player
|
||||
* @return True if the client is on 1.9
|
||||
* @deprecated As of 0.9.9, because all players are ported use {@link #getPlayerVersion(UUID)}
|
||||
*/
|
||||
@Deprecated
|
||||
boolean isPorted(UUID playerUUID);
|
||||
|
||||
/**
|
||||
* Get the version of the plugin
|
||||
*
|
||||
* @return Plugin version
|
||||
*/
|
||||
String getVersion();
|
||||
|
||||
/**
|
||||
* Send a raw packet to the player (Use new IDs)
|
||||
*
|
||||
* @param player The player to send packet
|
||||
* @param packet The packet, you need a VarInt ID then the packet contents.
|
||||
* @throws IllegalArgumentException If not on 1.9 throws IllegalArg
|
||||
*/
|
||||
void sendRawPacket(Player player, ByteBuf packet) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Send a raw packet to the player (Use new IDs)
|
||||
*
|
||||
* @param uuid The uuid from the player to send packet
|
||||
* @param packet The packet, you need a VarInt ID then the packet contents.
|
||||
* @throws IllegalArgumentException If not on 1.9 throws IllegalArg
|
||||
*/
|
||||
void sendRawPacket(UUID uuid, ByteBuf packet) throws IllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Create a new bossbar instance
|
||||
*
|
||||
* @param title The title
|
||||
* @param color The color
|
||||
* @param style The style
|
||||
* @return BossBar instance
|
||||
*/
|
||||
BossBar createBossBar(String title, BossColor color, BossStyle style);
|
||||
|
||||
/**
|
||||
* Create a new bossbar instance
|
||||
*
|
||||
* @param title The title
|
||||
* @param health Number between 0 and 1
|
||||
* @param color The color
|
||||
* @param style The style
|
||||
* @return BossBar instance
|
||||
*/
|
||||
BossBar createBossBar(String title, float health, BossColor color, BossStyle style);
|
||||
|
||||
/**
|
||||
* Get if global debug is enabled
|
||||
*
|
||||
* @return true if debug is enabled
|
||||
*/
|
||||
boolean isDebug();
|
||||
|
||||
/**
|
||||
* Get ViaVersions commands handler
|
||||
*
|
||||
* @return commands handler
|
||||
*/
|
||||
ViaVersionCommand getCommandHandler();
|
||||
|
||||
/**
|
||||
* Get if this version is a compatibility build for spigot.
|
||||
* Eg. 1.9.1 / 1.9.2 allow certain versions to connect
|
||||
*
|
||||
* @return True if it is
|
||||
*/
|
||||
boolean isCompatSpigotBuild();
|
||||
|
||||
/**
|
||||
* Get the supported protocol versions
|
||||
* This method removes any blocked protocol versions.
|
||||
*
|
||||
* @return a list of protocol versions
|
||||
* @see ProtocolRegistry#getSupportedVersions() for full list.
|
||||
*/
|
||||
SortedSet<Integer> getSupportedVersions();
|
||||
|
||||
/**
|
||||
* Gets if the server uses spigot
|
||||
* <p>
|
||||
* Note: Will only work after ViaVersion load
|
||||
*
|
||||
* @return True if spigot
|
||||
*/
|
||||
boolean isSpigot();
|
||||
|
||||
/**
|
||||
* Gets if protocol support is also being used.
|
||||
*
|
||||
* @return True if it is being used.
|
||||
*/
|
||||
boolean isProtocolSupport();
|
||||
}
|
||||
@@ -1,12 +1,10 @@
|
||||
package us.myles.ViaVersion.boss;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.bukkit.entity.Player;
|
||||
import us.myles.ViaVersion.api.boss.BossBar;
|
||||
import us.myles.ViaVersion.api.boss.BossColor;
|
||||
import us.myles.ViaVersion.api.boss.BossStyle;
|
||||
|
||||
@Getter
|
||||
public class ViaBossBar extends CommonBoss<Player> {
|
||||
|
||||
public ViaBossBar(String title, float health, BossColor color, BossStyle style) {
|
||||
|
||||
+128
-10
@@ -4,37 +4,56 @@ import javassist.*;
|
||||
import javassist.expr.ConstructorCall;
|
||||
import javassist.expr.ExprEditor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.EventException;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.EventExecutor;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import us.myles.ViaVersion.api.ViaVersion;
|
||||
import us.myles.ViaVersion.ViaVersionPlugin;
|
||||
import us.myles.ViaVersion.bukkit.handlers.BukkitDecodeHandler;
|
||||
import us.myles.ViaVersion.bukkit.handlers.BukkitEncodeHandler;
|
||||
import us.myles.ViaVersion.bukkit.util.NMSUtil;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
//TODO maybe clean this up a bit 👀
|
||||
public class ClassGenerator {
|
||||
private static HandlerConstructor constructor = new BasicHandlerConstructor();
|
||||
private static String psPackage = null;
|
||||
private static String psPackage;
|
||||
private static Class psConnectListener;
|
||||
|
||||
public static HandlerConstructor getConstructor() {
|
||||
return constructor;
|
||||
}
|
||||
|
||||
public static void generate() {
|
||||
if (ViaVersion.getInstance().isCompatSpigotBuild() || ViaVersion.getInstance().isProtocolSupport()) {
|
||||
if (ViaVersionPlugin.getInstance().isCompatSpigotBuild() || ViaVersionPlugin.getInstance().isProtocolSupport()) {
|
||||
try {
|
||||
ClassPool pool = ClassPool.getDefault();
|
||||
pool.insertClassPath(new LoaderClassPath(Bukkit.class.getClassLoader()));
|
||||
for (Plugin p : Bukkit.getPluginManager().getPlugins()) {
|
||||
pool.insertClassPath(new LoaderClassPath(p.getClass().getClassLoader()));
|
||||
}
|
||||
|
||||
if (ViaVersion.getInstance().isCompatSpigotBuild()) {
|
||||
if (ViaVersionPlugin.getInstance().isCompatSpigotBuild()) {
|
||||
Class decodeSuper = NMSUtil.nms("PacketDecoder");
|
||||
Class encodeSuper = NMSUtil.nms("PacketEncoder");
|
||||
// Generate the classes
|
||||
addSpigotCompatibility(pool, BukkitDecodeHandler.class, decodeSuper);
|
||||
addSpigotCompatibility(pool, BukkitEncodeHandler.class, encodeSuper);
|
||||
} else {
|
||||
Class decodeSuper = Class.forName(getPSPackage().equals("unknown") ? "protocolsupport.protocol.pipeline.common.PacketDecoder" : getPSPackage() + ".wrapped.WrappedDecoder");
|
||||
Class encodeSuper = Class.forName(getPSPackage().equals("unknown") ? "protocolsupport.protocol.pipeline.common.PacketEncoder" : getPSPackage() + ".wrapped.WrappedEncoder");
|
||||
// ProtocolSupport compatibility
|
||||
Class encodeSuper;
|
||||
Class decodeSuper;
|
||||
if (isMultiplatformPS()) {
|
||||
psConnectListener = makePSConnectListener(pool, shouldUseNewHandshakeVersionMethod());
|
||||
return;
|
||||
} else {
|
||||
String psPackage = getOldPSPackage();
|
||||
decodeSuper = Class.forName(psPackage.equals("unknown") ? "protocolsupport.protocol.pipeline.common.PacketDecoder" : psPackage + ".wrapped.WrappedDecoder");
|
||||
encodeSuper = Class.forName(psPackage.equals("unknown") ? "protocolsupport.protocol.pipeline.common.PacketEncoder" : psPackage + ".wrapped.WrappedEncoder");
|
||||
}
|
||||
// Generate the classes
|
||||
addPSCompatibility(pool, BukkitDecodeHandler.class, decodeSuper);
|
||||
addPSCompatibility(pool, BukkitEncodeHandler.class, encodeSuper);
|
||||
@@ -110,7 +129,7 @@ public class ClassGenerator {
|
||||
}
|
||||
|
||||
private static Class addPSCompatibility(ClassPool pool, Class input, Class superclass) {
|
||||
boolean newPS = getPSPackage().equals("unknown");
|
||||
boolean newPS = getOldPSPackage().equals("unknown");
|
||||
String newName = "us.myles.ViaVersion.classgenerator.generated." + input.getSimpleName();
|
||||
|
||||
try {
|
||||
@@ -121,8 +140,8 @@ public class ClassGenerator {
|
||||
|
||||
if (!newPS) {
|
||||
// Override setRealEncoder / setRealDecoder
|
||||
pool.importPackage(getPSPackage());
|
||||
pool.importPackage(getPSPackage() + ".wrapped");
|
||||
pool.importPackage(getOldPSPackage());
|
||||
pool.importPackage(getOldPSPackage() + ".wrapped");
|
||||
if (superclass.getName().endsWith("Decoder")) {
|
||||
// Decoder
|
||||
generated.addMethod(CtMethod.make("public void setRealDecoder(IPacketDecoder dec) {\n" +
|
||||
@@ -158,7 +177,87 @@ public class ClassGenerator {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getPSPackage() {
|
||||
private static Class makePSConnectListener(ClassPool pool, boolean newVersionMethod) {
|
||||
try {
|
||||
// Reference classes
|
||||
CtClass toExtend = pool.get("protocolsupport.api.Connection$PacketListener");
|
||||
CtClass connectListenerClazz = pool.makeClass("us.myles.ViaVersion.classgenerator.generated.ProtocolSupportConnectListener");
|
||||
connectListenerClazz.setSuperclass(toExtend);
|
||||
// Import packages
|
||||
pool.importPackage("java.util.Arrays");
|
||||
pool.importPackage("us.myles.ViaVersion.api.protocol.ProtocolRegistry");
|
||||
pool.importPackage("protocolsupport.api.ProtocolVersion");
|
||||
pool.importPackage("protocolsupport.api.ProtocolType");
|
||||
pool.importPackage("protocolsupport.api.Connection");
|
||||
pool.importPackage("protocolsupport.api.Connection.PacketListener");
|
||||
pool.importPackage("protocolsupport.api.Connection.PacketListener.PacketEvent");
|
||||
pool.importPackage("protocolsupport.protocol.ConnectionImpl");
|
||||
pool.importPackage(NMSUtil.nms("PacketHandshakingInSetProtocol").getName());
|
||||
// Add connection reference field
|
||||
connectListenerClazz.addField(CtField.make("private ConnectionImpl connection;", connectListenerClazz));
|
||||
// Bake constructor
|
||||
connectListenerClazz.addConstructor(CtNewConstructor.make(
|
||||
"public ProtocolSupportConnectListener (ConnectionImpl connection) {\n"
|
||||
+ " this.connection = connection;\n"
|
||||
+ "}", connectListenerClazz));
|
||||
// Add the listening method
|
||||
connectListenerClazz.addMethod(CtNewMethod.make(
|
||||
// On packet receive
|
||||
"public void onPacketReceiving(protocolsupport.api.Connection.PacketListener.PacketEvent event) {\n"
|
||||
// Check if we are getting handshake packet.
|
||||
+ " if (event.getPacket() instanceof PacketHandshakingInSetProtocol) {\n"
|
||||
// Get protocol version.
|
||||
+ " PacketHandshakingInSetProtocol packet = (PacketHandshakingInSetProtocol) event.getPacket();\n"
|
||||
+ (newVersionMethod ? (
|
||||
" int protoVersion = packet.getProtocolVersion();\n"
|
||||
) : (
|
||||
" int protoVersion = packet.b();\n"
|
||||
))
|
||||
// ViaVersion has at this point already spoofed the connectionversion. (Since it is higher up the pipeline)
|
||||
// If via has put the protoVersion to the server we can spoof ProtocolSupport's version.
|
||||
+ " if (connection.getVersion() == ProtocolVersion.MINECRAFT_FUTURE && protoVersion == us.myles.ViaVersion.api.protocol.ProtocolRegistry.SERVER_PROTOCOL) {\n"
|
||||
+ " connection.setVersion(ProtocolVersion.getLatest(ProtocolType.PC));\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
// Id version is not serverversion viaversion will not spoof. ProtocolSupport will handle the rest.
|
||||
// In any case, remove the packet listener and wrap up.
|
||||
+ " connection.removePacketListener(this);\n"
|
||||
+ "}", connectListenerClazz));
|
||||
return connectListenerClazz.toClass(HandlerConstructor.class.getClassLoader());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void registerPSConnectListener(ViaVersionPlugin plugin) {
|
||||
if (getPSConnectListener() != null) {
|
||||
try {
|
||||
Class<? extends Event> connectionOpenEvent = (Class<? extends Event>) Class.forName("protocolsupport.api.events.ConnectionOpenEvent");
|
||||
Bukkit.getPluginManager().registerEvent(connectionOpenEvent, new Listener() { }, EventPriority.HIGH, new EventExecutor() {
|
||||
@Override
|
||||
public void execute(Listener listener, Event event) throws EventException {
|
||||
try {
|
||||
Object connection = event.getClass().getMethod("getConnection").invoke(event);
|
||||
Object connectListener = getPSConnectListener().getConstructor(connection.getClass()).newInstance(connection);
|
||||
Method addConnectListener = connection.getClass().getMethod("addPacketListener", Class.forName("protocolsupport.api.Connection$PacketListener"));
|
||||
addConnectListener.invoke(connection, connectListener);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}, plugin);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Class getPSConnectListener() {
|
||||
return psConnectListener;
|
||||
}
|
||||
|
||||
public static String getOldPSPackage() {
|
||||
if (psPackage == null) {
|
||||
try {
|
||||
Class.forName("protocolsupport.protocol.core.IPacketDecoder");
|
||||
@@ -174,4 +273,23 @@ public class ClassGenerator {
|
||||
}
|
||||
return psPackage;
|
||||
}
|
||||
|
||||
public static boolean isMultiplatformPS() {
|
||||
try {
|
||||
Class.forName("protocolsupport.zplatform.impl.spigot.network.pipeline.SpigotPacketEncoder");
|
||||
return true;
|
||||
} catch (ClassNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean shouldUseNewHandshakeVersionMethod() {
|
||||
try {
|
||||
NMSUtil.nms("PacketHandshakingInSetProtocol").getMethod("getProtocolVersion");
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,15 +1,17 @@
|
||||
package us.myles.ViaVersion.bukkit.commands;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import us.myles.ViaVersion.api.command.ViaCommandSender;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class BukkitCommandSender implements ViaCommandSender {
|
||||
private CommandSender sender;
|
||||
private final CommandSender sender;
|
||||
|
||||
public BukkitCommandSender(CommandSender sender) {
|
||||
this.sender = sender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(String permission) {
|
||||
|
||||
@@ -3,19 +3,19 @@ package us.myles.ViaVersion.bukkit.handlers;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.ByteToMessageDecoder;
|
||||
import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.exception.CancelException;
|
||||
import us.myles.ViaVersion.packets.Direction;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.bukkit.util.NMSUtil;
|
||||
import us.myles.ViaVersion.exception.CancelCodecException;
|
||||
import us.myles.ViaVersion.exception.CancelDecoderException;
|
||||
import us.myles.ViaVersion.exception.InformativeException;
|
||||
import us.myles.ViaVersion.packets.State;
|
||||
import us.myles.ViaVersion.util.PipelineUtil;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.List;
|
||||
|
||||
public class BukkitDecodeHandler extends ByteToMessageDecoder {
|
||||
|
||||
private final ByteToMessageDecoder minecraftDecoder;
|
||||
private final UserConnection info;
|
||||
|
||||
@@ -26,64 +26,42 @@ public class BukkitDecodeHandler extends ByteToMessageDecoder {
|
||||
|
||||
@Override
|
||||
protected void decode(ChannelHandlerContext ctx, ByteBuf bytebuf, List<Object> list) throws Exception {
|
||||
// use transformers
|
||||
if (bytebuf.readableBytes() > 0) {
|
||||
// Ignore if pending disconnect
|
||||
if (info.isPendingDisconnect()) {
|
||||
return;
|
||||
}
|
||||
// Increment received
|
||||
boolean second = info.incrementReceived();
|
||||
// Check PPS
|
||||
if (second) {
|
||||
if (info.handlePPS())
|
||||
return;
|
||||
if (!info.checkIncomingPacket()) {
|
||||
bytebuf.clear(); // Don't accumulate
|
||||
throw CancelDecoderException.generate(null);
|
||||
}
|
||||
|
||||
ByteBuf transformedBuf = null;
|
||||
try {
|
||||
if (info.shouldTransformPacket()) {
|
||||
transformedBuf = ctx.alloc().buffer().writeBytes(bytebuf);
|
||||
info.transformIncoming(transformedBuf, CancelDecoderException::generate);
|
||||
}
|
||||
|
||||
if (info.isActive()) {
|
||||
// Handle ID
|
||||
int id = Type.VAR_INT.read(bytebuf);
|
||||
// Transform
|
||||
ByteBuf newPacket = ctx.alloc().buffer();
|
||||
try {
|
||||
if (id == PacketWrapper.PASSTHROUGH_ID) {
|
||||
newPacket.writeBytes(bytebuf);
|
||||
} else {
|
||||
PacketWrapper wrapper = new PacketWrapper(id, bytebuf, info);
|
||||
ProtocolInfo protInfo = info.get(ProtocolInfo.class);
|
||||
protInfo.getPipeline().transform(Direction.INCOMING, protInfo.getState(), wrapper);
|
||||
wrapper.writeToBuffer(newPacket);
|
||||
}
|
||||
|
||||
bytebuf.clear();
|
||||
bytebuf = newPacket;
|
||||
} catch (Exception e) {
|
||||
// Clear Buffer
|
||||
bytebuf.clear();
|
||||
// Release Packet, be free!
|
||||
newPacket.release();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
// call minecraft decoder
|
||||
try {
|
||||
list.addAll(PipelineUtil.callDecode(this.minecraftDecoder, ctx, bytebuf));
|
||||
list.addAll(PipelineUtil.callDecode(this.minecraftDecoder, ctx, transformedBuf == null ? bytebuf : transformedBuf));
|
||||
} catch (InvocationTargetException e) {
|
||||
if (e.getCause() instanceof Exception) {
|
||||
throw (Exception) e.getCause();
|
||||
} else if (e.getCause() instanceof Error) {
|
||||
throw (Error) e.getCause();
|
||||
}
|
||||
} finally {
|
||||
if (info.isActive()) {
|
||||
bytebuf.release();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (transformedBuf != null) {
|
||||
transformedBuf.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
if (PipelineUtil.containsCause(cause, CancelException.class)) return;
|
||||
if (PipelineUtil.containsCause(cause, CancelCodecException.class)) return; // ProtocolLib compat
|
||||
|
||||
super.exceptionCaught(ctx, cause);
|
||||
if (!NMSUtil.isDebugPropertySet() && PipelineUtil.containsCause(cause, InformativeException.class)
|
||||
&& (info.getProtocolInfo().getState() != State.HANDSHAKE || Via.getManager().isDebug())) {
|
||||
cause.printStackTrace(); // Print if CB doesn't already do it
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,22 +3,22 @@ package us.myles.ViaVersion.bukkit.handlers;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToByteEncoder;
|
||||
import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.bukkit.util.NMSUtil;
|
||||
import us.myles.ViaVersion.exception.CancelException;
|
||||
import us.myles.ViaVersion.exception.CancelCodecException;
|
||||
import us.myles.ViaVersion.exception.CancelEncoderException;
|
||||
import us.myles.ViaVersion.exception.InformativeException;
|
||||
import us.myles.ViaVersion.handlers.ChannelHandlerContextWrapper;
|
||||
import us.myles.ViaVersion.handlers.ViaHandler;
|
||||
import us.myles.ViaVersion.packets.Direction;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.packets.State;
|
||||
import us.myles.ViaVersion.util.PipelineUtil;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public class BukkitEncodeHandler extends MessageToByteEncoder implements ViaHandler {
|
||||
private static Field versionField = null;
|
||||
private static Field versionField;
|
||||
|
||||
static {
|
||||
try {
|
||||
@@ -37,7 +37,6 @@ public class BukkitEncodeHandler extends MessageToByteEncoder implements ViaHand
|
||||
this.minecraftEncoder = minecraftEncoder;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void encode(final ChannelHandlerContext ctx, Object o, final ByteBuf bytebuf) throws Exception {
|
||||
if (versionField != null) {
|
||||
@@ -51,6 +50,8 @@ public class BukkitEncodeHandler extends MessageToByteEncoder implements ViaHand
|
||||
} catch (InvocationTargetException e) {
|
||||
if (e.getCause() instanceof Exception) {
|
||||
throw (Exception) e.getCause();
|
||||
} else if (e.getCause() instanceof Error) {
|
||||
throw (Error) e.getCause();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -58,36 +59,21 @@ public class BukkitEncodeHandler extends MessageToByteEncoder implements ViaHand
|
||||
transform(bytebuf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transform(ByteBuf bytebuf) throws Exception {
|
||||
if (bytebuf.readableBytes() == 0) {
|
||||
return; // Someone Already Decoded It!
|
||||
}
|
||||
// Increment sent
|
||||
info.incrementSent();
|
||||
if (info.isActive()) {
|
||||
// Handle ID
|
||||
int id = Type.VAR_INT.read(bytebuf);
|
||||
// Transform
|
||||
ByteBuf oldPacket = bytebuf.copy();
|
||||
bytebuf.clear();
|
||||
|
||||
try {
|
||||
PacketWrapper wrapper = new PacketWrapper(id, oldPacket, info);
|
||||
ProtocolInfo protInfo = info.get(ProtocolInfo.class);
|
||||
protInfo.getPipeline().transform(Direction.OUTGOING, protInfo.getState(), wrapper);
|
||||
wrapper.writeToBuffer(bytebuf);
|
||||
} catch (Exception e) {
|
||||
bytebuf.clear();
|
||||
throw e;
|
||||
} finally {
|
||||
oldPacket.release();
|
||||
}
|
||||
}
|
||||
if (!info.checkOutgoingPacket()) throw CancelEncoderException.generate(null);
|
||||
if (!info.shouldTransformPacket()) return;
|
||||
info.transformOutgoing(bytebuf, CancelEncoderException::generate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
if (PipelineUtil.containsCause(cause, CancelException.class)) return;
|
||||
if (PipelineUtil.containsCause(cause, CancelCodecException.class)) return; // ProtocolLib compat
|
||||
|
||||
super.exceptionCaught(ctx, cause);
|
||||
if (!NMSUtil.isDebugPropertySet() && PipelineUtil.containsCause(cause, InformativeException.class)
|
||||
&& (info.getProtocolInfo().getState() != State.HANDSHAKE || Via.getManager().isDebug())) {
|
||||
cause.printStackTrace(); // Print if CB doesn't already do it
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ public class BukkitPacketHandler extends MessageToMessageEncoder {
|
||||
info.setLastPacket(o);
|
||||
/* This transformer is more for fixing issues which we find hard at packet level :) */
|
||||
if (info.isActive()) {
|
||||
if (info.get(ProtocolInfo.class).getPipeline().filter(o, list)) {
|
||||
if (info.getProtocolInfo().getPipeline().filter(o, list)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
package us.myles.ViaVersion.bukkit.listeners.multiversion;
|
||||
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.player.PlayerToggleSneakEvent;
|
||||
import us.myles.ViaVersion.ViaVersionPlugin;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
|
||||
import us.myles.ViaVersion.bukkit.listeners.ViaBukkitListener;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
|
||||
public class PlayerSneakListener extends ViaBukkitListener {
|
||||
private static final float STANDING_HEIGHT = 1.8F;
|
||||
private static final float HEIGHT_1_14 = 1.5F;
|
||||
private static final float HEIGHT_1_9 = 1.6F;
|
||||
private static final float DEFAULT_WIDTH = 0.6F;
|
||||
|
||||
private final boolean is1_9Fix;
|
||||
private final boolean is1_14Fix;
|
||||
private Map<Player, Boolean> sneaking; // true = 1.14+, else false
|
||||
private Set<UUID> sneakingUuids;
|
||||
private final Method getHandle;
|
||||
private Method setSize;
|
||||
|
||||
private boolean useCache;
|
||||
|
||||
public PlayerSneakListener(ViaVersionPlugin plugin, boolean is1_9Fix, boolean is1_14Fix) throws ReflectiveOperationException {
|
||||
super(plugin, null);
|
||||
this.is1_9Fix = is1_9Fix;
|
||||
this.is1_14Fix = is1_14Fix;
|
||||
|
||||
final String packageName = plugin.getServer().getClass().getPackage().getName();
|
||||
getHandle = Class.forName(packageName + ".entity.CraftPlayer").getMethod("getHandle");
|
||||
|
||||
final Class<?> entityPlayerClass = Class.forName(packageName
|
||||
.replace("org.bukkit.craftbukkit", "net.minecraft.server") + ".EntityPlayer");
|
||||
try {
|
||||
setSize = entityPlayerClass.getMethod("setSize", Float.TYPE, Float.TYPE);
|
||||
} catch (NoSuchMethodException e) {
|
||||
// Don't catch this one
|
||||
setSize = entityPlayerClass.getMethod("a", Float.TYPE, Float.TYPE);
|
||||
}
|
||||
|
||||
|
||||
// From 1.9 upwards the server hitbox is set in every entity tick, so we have to reset it everytime
|
||||
if (ProtocolRegistry.SERVER_PROTOCOL >= ProtocolVersion.v1_9.getVersion()) {
|
||||
sneaking = new WeakHashMap<>();
|
||||
useCache = true;
|
||||
plugin.getServer().getScheduler().runTaskTimer(plugin, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (Map.Entry<Player, Boolean> entry : sneaking.entrySet()) {
|
||||
setHeight(entry.getKey(), entry.getValue() ? HEIGHT_1_14 : HEIGHT_1_9);
|
||||
}
|
||||
}
|
||||
}, 1, 1);
|
||||
}
|
||||
|
||||
// Suffocation removal only required for 1.14+ clients.
|
||||
if (is1_14Fix) {
|
||||
sneakingUuids = new HashSet<>();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void playerToggleSneak(PlayerToggleSneakEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
UserConnection userConnection = getUserConnection(player);
|
||||
if (userConnection == null) return;
|
||||
ProtocolInfo info = userConnection.getProtocolInfo();
|
||||
if (info == null) return;
|
||||
|
||||
int protocolVersion = info.getProtocolVersion();
|
||||
if (is1_14Fix && protocolVersion >= ProtocolVersion.v1_14.getVersion()) {
|
||||
setHeight(player, event.isSneaking() ? HEIGHT_1_14 : STANDING_HEIGHT);
|
||||
if (event.isSneaking())
|
||||
sneakingUuids.add(player.getUniqueId());
|
||||
else
|
||||
sneakingUuids.remove(player.getUniqueId());
|
||||
|
||||
if (!useCache) return;
|
||||
if (event.isSneaking())
|
||||
sneaking.put(player, true);
|
||||
else
|
||||
sneaking.remove(player);
|
||||
} else if (is1_9Fix && protocolVersion >= ProtocolVersion.v1_9.getVersion()) {
|
||||
setHeight(player, event.isSneaking() ? HEIGHT_1_9 : STANDING_HEIGHT);
|
||||
if (!useCache) return;
|
||||
if (event.isSneaking())
|
||||
sneaking.put(player, false);
|
||||
else
|
||||
sneaking.remove(player);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void playerDamage(EntityDamageEvent event) {
|
||||
if (!is1_14Fix) return;
|
||||
if (event.getCause() != EntityDamageEvent.DamageCause.SUFFOCATION) return;
|
||||
if (event.getEntityType() != EntityType.PLAYER) return;
|
||||
|
||||
Player player = (Player) event.getEntity();
|
||||
if (!sneakingUuids.contains(player.getUniqueId())) return;
|
||||
|
||||
// Don't cancel when they should actually be suffocating; Essentially cancel when the head is in the top block only ever so slightly
|
||||
// ~0.041 should suffice, but gotta stay be safe
|
||||
double y = player.getEyeLocation().getY() + 0.045;
|
||||
y -= (int) y;
|
||||
if (y < 0.09) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void playerQuit(PlayerQuitEvent event) {
|
||||
if (sneaking != null)
|
||||
sneaking.remove(event.getPlayer());
|
||||
if (sneakingUuids != null)
|
||||
sneakingUuids.remove(event.getPlayer().getUniqueId());
|
||||
}
|
||||
|
||||
private void setHeight(Player player, float height) {
|
||||
try {
|
||||
setSize.invoke(getHandle.invoke(player), DEFAULT_WIDTH, height);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
package us.myles.ViaVersion.bukkit.listeners.protocol1_15to1_14_4;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.entity.EntityToggleGlideEvent;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import us.myles.ViaVersion.ViaVersionPlugin;
|
||||
import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
|
||||
import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_14;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.api.type.types.version.Types1_14;
|
||||
import us.myles.ViaVersion.bukkit.listeners.ViaBukkitListener;
|
||||
import us.myles.ViaVersion.protocols.protocol1_15to1_14_4.Protocol1_15To1_14_4;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class EntityToggleGlideListener extends ViaBukkitListener {
|
||||
|
||||
private boolean swimmingMethodExists;
|
||||
|
||||
public EntityToggleGlideListener(ViaVersionPlugin plugin) {
|
||||
super(plugin, Protocol1_15To1_14_4.class);
|
||||
try {
|
||||
Player.class.getMethod("isSwimming");
|
||||
swimmingMethodExists = true;
|
||||
} catch (NoSuchMethodException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void entityToggleGlide(EntityToggleGlideEvent event) {
|
||||
if (!(event.getEntity() instanceof Player)) return;
|
||||
|
||||
Player player = (Player) event.getEntity();
|
||||
if (!isOnPipe(player)) return;
|
||||
|
||||
// Cancelling can only be done by updating the player's metadata
|
||||
if (event.isGliding() && event.isCancelled()) {
|
||||
PacketWrapper packet = new PacketWrapper(0x44, null, getUserConnection(player));
|
||||
try {
|
||||
packet.write(Type.VAR_INT, player.getEntityId());
|
||||
|
||||
byte bitmask = 0;
|
||||
// Collect other metadata for the mitmask
|
||||
if (player.getFireTicks() > 0) {
|
||||
bitmask |= 0x01;
|
||||
}
|
||||
if (player.isSneaking()) {
|
||||
bitmask |= 0x02;
|
||||
}
|
||||
// 0x04 is unused
|
||||
if (player.isSprinting()) {
|
||||
bitmask |= 0x08;
|
||||
}
|
||||
if (swimmingMethodExists && player.isSwimming()) {
|
||||
bitmask |= 0x10;
|
||||
}
|
||||
if (player.hasPotionEffect(PotionEffectType.INVISIBILITY)) {
|
||||
bitmask |= 0x20;
|
||||
}
|
||||
if (player.isGlowing()) {
|
||||
bitmask |= 0x40;
|
||||
}
|
||||
|
||||
// leave 0x80 as 0 to stop gliding
|
||||
packet.write(Types1_14.METADATA_LIST, Arrays.asList(new Metadata(0, MetaType1_14.Byte, bitmask)));
|
||||
packet.send(Protocol1_15To1_14_4.class);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,179 +0,0 @@
|
||||
package us.myles.ViaVersion.bukkit.platform;
|
||||
|
||||
import us.myles.ViaVersion.ViaVersionPlugin;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.ViaVersionConfig;
|
||||
import us.myles.ViaVersion.util.Config;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class BukkitConfigAPI extends Config implements ViaVersionConfig {
|
||||
private static List<String> UNSUPPORTED = Arrays.asList("bungee-ping-interval", "bungee-ping-save", "bungee-servers");
|
||||
|
||||
public BukkitConfigAPI() {
|
||||
super(new File(((ViaVersionPlugin) Via.getPlatform()).getDataFolder(), "config.yml"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCheckForUpdates() {
|
||||
return getBoolean("checkforupdates", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPreventCollision() {
|
||||
return getBoolean("prevent-collision", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNewEffectIndicator() {
|
||||
return getBoolean("use-new-effect-indicator", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShowNewDeathMessages() {
|
||||
return getBoolean("use-new-deathmessages", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuppressMetadataErrors() {
|
||||
return getBoolean("suppress-metadata-errors", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShieldBlocking() {
|
||||
return getBoolean("shield-blocking", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHologramPatch() {
|
||||
return getBoolean("hologram-patch", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBossbarPatch() {
|
||||
return getBoolean("bossbar-patch", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBossbarAntiflicker() {
|
||||
return getBoolean("bossbar-anti-flicker", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUnknownEntitiesSuppressed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getHologramYOffset() {
|
||||
return getDouble("hologram-y", -0.96D);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBlockBreakPatch() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxPPS() {
|
||||
return getInt("max-pps", 800);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMaxPPSKickMessage() {
|
||||
return getString("max-pps-kick-msg", "Sending packets too fast? lag?");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTrackingPeriod() {
|
||||
return getInt("tracking-period", 6);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWarningPPS() {
|
||||
return getInt("tracking-warning-pps", 120);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxWarnings() {
|
||||
return getInt("tracking-max-warnings", 3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMaxWarningsKickMessage() {
|
||||
return getString("tracking-max-kick-msg", "You are sending too many packets, :(");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAntiXRay() {
|
||||
return getBoolean("anti-xray-patch", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSendSupportedVersions() {
|
||||
return getBoolean("send-supported-versions", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStimulatePlayerTick() {
|
||||
return getBoolean("simulate-pt", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemCache() {
|
||||
return getBoolean("item-cache", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNMSPlayerTicking() {
|
||||
return getBoolean("nms-player-ticking", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReplacePistons() {
|
||||
return getBoolean("replace-pistons", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPistonReplacementId() {
|
||||
return getInt("replacement-piston-id", 0);
|
||||
}
|
||||
|
||||
public boolean isAutoTeam() {
|
||||
// Collision has to be enabled first
|
||||
return isPreventCollision() && getBoolean("auto-team", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForceJsonTransform() {
|
||||
return getBoolean("force-json-transform", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Integer> getBlockedProtocols() {
|
||||
return getIntegerList("block-protocols");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBlockedDisconnectMsg() {
|
||||
return getString("block-disconnect-msg", "You are using an unsupported Minecraft version!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReloadDisconnectMsg() {
|
||||
return getString("reload-disconnect-msg", "Server reload, please rejoin!");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleConfig(Map<String, Object> config) {
|
||||
// Nothing currently
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getUnsupportedOptions() {
|
||||
return UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,16 @@
|
||||
package us.myles.ViaVersion.bukkit.platform;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import us.myles.ViaVersion.api.platform.TaskId;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public class BukkitTaskId implements TaskId {
|
||||
private Integer object;
|
||||
private final Integer object;
|
||||
|
||||
public BukkitTaskId(Integer object) {
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getObject() {
|
||||
return object;
|
||||
}
|
||||
}
|
||||
@@ -1,45 +1,41 @@
|
||||
package us.myles.ViaVersion.bukkit.platform;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import us.myles.ViaVersion.ViaVersionPlugin;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.ViaAPI;
|
||||
import us.myles.ViaVersion.api.ViaVersionAPI;
|
||||
import us.myles.ViaVersion.api.boss.BossBar;
|
||||
import us.myles.ViaVersion.api.boss.BossColor;
|
||||
import us.myles.ViaVersion.api.boss.BossStyle;
|
||||
import us.myles.ViaVersion.api.command.ViaVersionCommand;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
|
||||
import us.myles.ViaVersion.boss.ViaBossBar;
|
||||
import us.myles.ViaVersion.bukkit.util.ProtocolSupportUtil;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import java.util.UUID;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class BukkitViaAPI implements ViaAPI<Player>, ViaVersionAPI {
|
||||
private ViaVersionPlugin plugin;
|
||||
public class BukkitViaAPI implements ViaAPI<Player> {
|
||||
private final ViaVersionPlugin plugin;
|
||||
|
||||
@Override
|
||||
public int getPlayerVersion(@NonNull Player player) {
|
||||
if (!isPorted(player))
|
||||
return getExternalVersion(player);
|
||||
return getPortedPlayers().get(player.getUniqueId()).get(ProtocolInfo.class).getProtocolVersion();
|
||||
public BukkitViaAPI(ViaVersionPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPlayerVersion(@NonNull UUID uuid) {
|
||||
if (!isPorted(uuid))
|
||||
public int getPlayerVersion(Player player) {
|
||||
return getPlayerVersion(player.getUniqueId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPlayerVersion(UUID uuid) {
|
||||
if (!isInjected(uuid))
|
||||
return getExternalVersion(Bukkit.getPlayer(uuid));
|
||||
return getPortedPlayers().get(uuid).get(ProtocolInfo.class).getProtocolVersion();
|
||||
return Via.getManager().getConnection(uuid).getProtocolInfo().getProtocolVersion();
|
||||
}
|
||||
|
||||
private int getExternalVersion(Player player) {
|
||||
@@ -51,13 +47,8 @@ public class BukkitViaAPI implements ViaAPI<Player>, ViaVersionAPI {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPorted(Player player) {
|
||||
return isPorted(player.getUniqueId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPorted(UUID playerUUID) {
|
||||
return getPortedPlayers().containsKey(playerUUID);
|
||||
public boolean isInjected(UUID playerUUID) {
|
||||
return Via.getManager().isClientConnected(playerUUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -67,8 +58,8 @@ public class BukkitViaAPI implements ViaAPI<Player>, ViaVersionAPI {
|
||||
|
||||
@Override
|
||||
public void sendRawPacket(UUID uuid, ByteBuf packet) throws IllegalArgumentException {
|
||||
if (!isPorted(uuid)) throw new IllegalArgumentException("This player is not controlled by ViaVersion!");
|
||||
UserConnection ci = getPortedPlayers().get(uuid);
|
||||
if (!isInjected(uuid)) throw new IllegalArgumentException("This player is not controlled by ViaVersion!");
|
||||
UserConnection ci = Via.getManager().getConnection(uuid);
|
||||
ci.sendRawPacket(packet);
|
||||
}
|
||||
|
||||
@@ -78,25 +69,15 @@ public class BukkitViaAPI implements ViaAPI<Player>, ViaVersionAPI {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BossBar createBossBar(String title, BossColor color, BossStyle style) {
|
||||
public BossBar<Player> createBossBar(String title, BossColor color, BossStyle style) {
|
||||
return new ViaBossBar(title, 1F, color, style);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BossBar createBossBar(String title, float health, BossColor color, BossStyle style) {
|
||||
public BossBar<Player> createBossBar(String title, float health, BossColor color, BossStyle style) {
|
||||
return new ViaBossBar(title, health, color, style);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDebug() {
|
||||
return Via.getManager().isDebug();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViaVersionCommand getCommandHandler() {
|
||||
return Via.getManager().getCommandHandler();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SortedSet<Integer> getSupportedVersions() {
|
||||
SortedSet<Integer> outputSet = new TreeSet<>(ProtocolRegistry.getSupportedVersions());
|
||||
@@ -105,23 +86,23 @@ public class BukkitViaAPI implements ViaAPI<Player>, ViaVersionAPI {
|
||||
return outputSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Returns if this version is a compatibility build for spigot.
|
||||
* Eg. 1.9.1 / 1.9.2 allow certain versions to connect
|
||||
*
|
||||
* @return true if compat Spigot build
|
||||
*/
|
||||
public boolean isCompatSpigotBuild() {
|
||||
return plugin.isCompatSpigotBuild();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isSpigot() {
|
||||
return plugin.isSpigot();
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Returns if ProtocolSupport is also being used.
|
||||
*
|
||||
* @return true if ProtocolSupport is used
|
||||
*/
|
||||
public boolean isProtocolSupport() {
|
||||
return plugin.isProtocolSupport();
|
||||
}
|
||||
|
||||
public Map<UUID, UserConnection> getPortedPlayers() {
|
||||
return Via.getManager().getPortedPlayers();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package us.myles.ViaVersion.bukkit.platform;
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import us.myles.ViaVersion.AbstractViaConfig;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class BukkitViaConfig extends AbstractViaConfig {
|
||||
private static final List<String> UNSUPPORTED = Arrays.asList("bungee-ping-interval", "bungee-ping-save", "bungee-servers", "velocity-ping-interval", "velocity-ping-save", "velocity-servers");
|
||||
private boolean antiXRay;
|
||||
private boolean quickMoveActionFix;
|
||||
private boolean hitboxFix1_9;
|
||||
private boolean hitboxFix1_14;
|
||||
private String blockConnectionMethod;
|
||||
|
||||
public BukkitViaConfig() {
|
||||
super(new File(((Plugin) Via.getPlatform()).getDataFolder(), "config.yml"));
|
||||
reloadConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadFields() {
|
||||
super.loadFields();
|
||||
antiXRay = getBoolean("anti-xray-patch", true);
|
||||
quickMoveActionFix = getBoolean("quick-move-action-fix", false);
|
||||
hitboxFix1_9 = getBoolean("change-1_9-hitbox", false);
|
||||
hitboxFix1_14 = getBoolean("change-1_14-hitbox", false);
|
||||
blockConnectionMethod = getString("blockconnection-method", "packet");
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getDefaultConfigURL() {
|
||||
return BukkitViaConfig.class.getClassLoader().getResource("assets/viaversion/config.yml");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleConfig(Map<String, Object> config) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAntiXRay() {
|
||||
return antiXRay;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is1_12QuickMoveActionFix() {
|
||||
return quickMoveActionFix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is1_9HitboxFix() {
|
||||
return hitboxFix1_9;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is1_14HitboxFix() {
|
||||
return hitboxFix1_14;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBlockConnectionMethod() {
|
||||
return blockConnectionMethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getUnsupportedOptions() {
|
||||
return UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package us.myles.ViaVersion.bukkit.platform;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
@@ -17,11 +19,12 @@ import us.myles.ViaVersion.util.ReflectionUtil;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class BukkitViaInjector implements ViaInjector {
|
||||
private List<ChannelFuture> injectedFutures = new ArrayList<>();
|
||||
private List<Pair<Field, Object>> injectedLists = new ArrayList<>();
|
||||
private final List<ChannelFuture> injectedFutures = new ArrayList<>();
|
||||
private final List<Pair<Field, Object>> injectedLists = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void inject() throws Exception {
|
||||
@@ -32,19 +35,17 @@ public class BukkitViaInjector implements ViaInjector {
|
||||
}
|
||||
for (Field field : connection.getClass().getDeclaredFields()) {
|
||||
field.setAccessible(true);
|
||||
final Object value = field.get(connection);
|
||||
Object value = field.get(connection);
|
||||
if (value instanceof List) {
|
||||
// Inject the list
|
||||
List wrapper = new ListWrapper((List) value) {
|
||||
@Override
|
||||
public synchronized void handleAdd(Object o) {
|
||||
synchronized (this) {
|
||||
if (o instanceof ChannelFuture) {
|
||||
try {
|
||||
injectChannelFuture((ChannelFuture) o);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
public void handleAdd(Object o) {
|
||||
if (o instanceof ChannelFuture) {
|
||||
try {
|
||||
injectChannelFuture((ChannelFuture) o);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -232,25 +233,6 @@ public class BukkitViaInjector implements ViaInjector {
|
||||
return connection;
|
||||
}
|
||||
|
||||
public static void patchLists() throws Exception {
|
||||
Object connection = getServerConnection();
|
||||
if (connection == null) {
|
||||
Via.getPlatform().getLogger().warning("We failed to find the core component 'ServerConnection', please file an issue on our GitHub.");
|
||||
return;
|
||||
}
|
||||
for (Field field : connection.getClass().getDeclaredFields()) {
|
||||
field.setAccessible(true);
|
||||
final Object value = field.get(connection);
|
||||
if (value instanceof List) {
|
||||
if (!(value instanceof ConcurrentList)) {
|
||||
ConcurrentList list = new ConcurrentList();
|
||||
list.addAll((List) value);
|
||||
field.set(connection, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isBinded() {
|
||||
try {
|
||||
Object connection = getServerConnection();
|
||||
@@ -277,4 +259,84 @@ public class BukkitViaInjector implements ViaInjector {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject getDump() {
|
||||
JsonObject data = new JsonObject();
|
||||
|
||||
// Generate information about current injections
|
||||
JsonArray injectedChannelInitializers = new JsonArray();
|
||||
for (ChannelFuture cf : injectedFutures) {
|
||||
JsonObject info = new JsonObject();
|
||||
info.addProperty("futureClass", cf.getClass().getName());
|
||||
info.addProperty("channelClass", cf.channel().getClass().getName());
|
||||
|
||||
// Get information about the pipes for this channel future
|
||||
JsonArray pipeline = new JsonArray();
|
||||
for (String pipeName : cf.channel().pipeline().names()) {
|
||||
JsonObject pipe = new JsonObject();
|
||||
pipe.addProperty("name", pipeName);
|
||||
if (cf.channel().pipeline().get(pipeName) != null) {
|
||||
pipe.addProperty("class", cf.channel().pipeline().get(pipeName).getClass().getName());
|
||||
try {
|
||||
Object child = ReflectionUtil.get(cf.channel().pipeline().get(pipeName), "childHandler", ChannelInitializer.class);
|
||||
pipe.addProperty("childClass", child.getClass().getName());
|
||||
if (child instanceof BukkitChannelInitializer) {
|
||||
pipe.addProperty("oldInit", ((BukkitChannelInitializer) child).getOriginal().getClass().getName());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// Don't display
|
||||
}
|
||||
}
|
||||
// Add to the pipeline array
|
||||
pipeline.add(pipe);
|
||||
}
|
||||
info.add("pipeline", pipeline);
|
||||
|
||||
// Add to the list
|
||||
injectedChannelInitializers.add(info);
|
||||
}
|
||||
data.add("injectedChannelInitializers", injectedChannelInitializers);
|
||||
|
||||
// Generate information about lists we've injected into
|
||||
JsonObject wrappedLists = new JsonObject();
|
||||
JsonObject currentLists = new JsonObject();
|
||||
try {
|
||||
for (Pair<Field, Object> pair : injectedLists) {
|
||||
Object list = pair.getKey().get(pair.getValue());
|
||||
// Note down the current value (could be overridden by another plugin)
|
||||
currentLists.addProperty(pair.getKey().getName(), list.getClass().getName());
|
||||
// Also if it's not overridden we can display what's inside our list (possibly another plugin)
|
||||
if (list instanceof ListWrapper) {
|
||||
wrappedLists.addProperty(pair.getKey().getName(), ((ListWrapper) list).getOriginalList().getClass().getName());
|
||||
}
|
||||
}
|
||||
data.add("wrappedLists", wrappedLists);
|
||||
data.add("currentLists", currentLists);
|
||||
} catch (Exception e) {
|
||||
// Ignored, fields won't be present
|
||||
}
|
||||
|
||||
data.addProperty("binded", isBinded());
|
||||
return data;
|
||||
}
|
||||
|
||||
public static void patchLists() throws Exception {
|
||||
Object connection = getServerConnection();
|
||||
if (connection == null) {
|
||||
Via.getPlatform().getLogger().warning("We failed to find the core component 'ServerConnection', please file an issue on our GitHub.");
|
||||
return;
|
||||
}
|
||||
|
||||
for (Field field : connection.getClass().getDeclaredFields()) {
|
||||
field.setAccessible(true);
|
||||
Object value = field.get(connection);
|
||||
if (!(value instanceof List)) continue;
|
||||
if (value instanceof ConcurrentList) continue;
|
||||
|
||||
ConcurrentList list = new ConcurrentList();
|
||||
list.addAll((Collection) value);
|
||||
field.set(connection, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,81 +1,134 @@
|
||||
package us.myles.ViaVersion.bukkit.platform;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import us.myles.ViaVersion.ViaVersionPlugin;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.minecraft.item.Item;
|
||||
import us.myles.ViaVersion.api.platform.ViaPlatformLoader;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
|
||||
import us.myles.ViaVersion.bukkit.classgenerator.ClassGenerator;
|
||||
import us.myles.ViaVersion.bukkit.listeners.UpdateListener;
|
||||
import us.myles.ViaVersion.bukkit.listeners.protocol1_9to1_8.*;
|
||||
import us.myles.ViaVersion.bukkit.listeners.multiversion.PlayerSneakListener;
|
||||
import us.myles.ViaVersion.bukkit.listeners.protocol1_15to1_14_4.EntityToggleGlideListener;
|
||||
import us.myles.ViaVersion.bukkit.listeners.protocol1_9to1_8.ArmorListener;
|
||||
import us.myles.ViaVersion.bukkit.listeners.protocol1_9to1_8.BlockListener;
|
||||
import us.myles.ViaVersion.bukkit.listeners.protocol1_9to1_8.DeathListener;
|
||||
import us.myles.ViaVersion.bukkit.listeners.protocol1_9to1_8.HandItemCache;
|
||||
import us.myles.ViaVersion.bukkit.listeners.protocol1_9to1_8.PaperPatch;
|
||||
import us.myles.ViaVersion.bukkit.providers.BukkitBlockConnectionProvider;
|
||||
import us.myles.ViaVersion.bukkit.providers.BukkitInventoryQuickMoveProvider;
|
||||
import us.myles.ViaVersion.bukkit.providers.BukkitViaBulkChunkTranslator;
|
||||
import us.myles.ViaVersion.bukkit.providers.BukkitViaMovementTransmitter;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.protocols.protocol1_12to1_11_1.providers.InventoryQuickMoveProvider;
|
||||
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.blockconnections.ConnectionData;
|
||||
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.blockconnections.providers.BlockConnectionProvider;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.BulkChunkTranslatorProvider;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.HandItemProvider;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class BukkitViaLoader implements ViaPlatformLoader {
|
||||
private ViaVersionPlugin plugin;
|
||||
private final ViaVersionPlugin plugin;
|
||||
|
||||
private final Set<Listener> listeners = new HashSet<>();
|
||||
private final Set<BukkitTask> tasks = new HashSet<>();
|
||||
|
||||
private HandItemCache handItemCache;
|
||||
|
||||
public BukkitViaLoader(ViaVersionPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public void registerListener(Listener listener) {
|
||||
Bukkit.getPluginManager().registerEvents(storeListener(listener), plugin);
|
||||
}
|
||||
|
||||
public <T extends Listener> T storeListener(T listener) {
|
||||
listeners.add(listener);
|
||||
return listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
// Update Listener
|
||||
Bukkit.getPluginManager().registerEvents(new UpdateListener(), plugin);
|
||||
registerListener(new UpdateListener());
|
||||
|
||||
/* Base Protocol */
|
||||
final ViaVersionPlugin plugin = (ViaVersionPlugin) Bukkit.getPluginManager().getPlugin("ViaVersion");
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(new Listener() {
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerQuitEvent e) {
|
||||
Via.getManager().removePortedClient(e.getPlayer().getUniqueId());
|
||||
}
|
||||
}, plugin);
|
||||
// Add ProtocolSupport ConnectListener if necessary.
|
||||
ClassGenerator.registerPSConnectListener(plugin);
|
||||
|
||||
/* 1.9 client to 1.8 server */
|
||||
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_9.getVersion()) {
|
||||
storeListener(new ArmorListener(plugin)).register();
|
||||
storeListener(new DeathListener(plugin)).register();
|
||||
storeListener(new BlockListener(plugin)).register();
|
||||
|
||||
new ArmorListener(plugin).register();
|
||||
new DeathListener(plugin).register();
|
||||
new BlockListener(plugin).register();
|
||||
|
||||
if (Bukkit.getVersion().toLowerCase().contains("paper") || Bukkit.getVersion().toLowerCase().contains("taco")) {
|
||||
plugin.getLogger().info("Enabling PaperSpigot/TacoSpigot patch: Fixes block placement.");
|
||||
new PaperPatch(plugin).register();
|
||||
if (plugin.getConf().isItemCache()) {
|
||||
handItemCache = new HandItemCache();
|
||||
tasks.add(handItemCache.runTaskTimerAsynchronously(plugin, 2L, 2L)); // Updates player's items :)
|
||||
}
|
||||
}
|
||||
if (plugin.getConf().isItemCache()) {
|
||||
new HandItemCache().runTaskTimerAsynchronously(plugin, 2L, 2L); // Updates player's items :)
|
||||
HandItemCache.CACHE = true;
|
||||
|
||||
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_14.getVersion()) {
|
||||
boolean use1_9Fix = plugin.getConf().is1_9HitboxFix() && ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_9.getVersion();
|
||||
if (use1_9Fix || plugin.getConf().is1_14HitboxFix()) {
|
||||
try {
|
||||
storeListener(new PlayerSneakListener(plugin, use1_9Fix, plugin.getConf().is1_14HitboxFix())).register();
|
||||
} catch (ReflectiveOperationException e) {
|
||||
Via.getPlatform().getLogger().warning("Could not load hitbox fix - please report this on our GitHub");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_15.getVersion()) {
|
||||
try {
|
||||
Class.forName("org.bukkit.event.entity.EntityToggleGlideEvent");
|
||||
storeListener(new EntityToggleGlideListener(plugin)).register();
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
if ((Bukkit.getVersion().toLowerCase(Locale.ROOT).contains("paper")
|
||||
|| Bukkit.getVersion().toLowerCase(Locale.ROOT).contains("taco")
|
||||
|| Bukkit.getVersion().toLowerCase(Locale.ROOT).contains("torch"))
|
||||
&& ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_12.getVersion()) {
|
||||
plugin.getLogger().info("Enabling Paper/TacoSpigot/Torch patch: Fixes block placement.");
|
||||
storeListener(new PaperPatch(plugin)).register();
|
||||
}
|
||||
|
||||
/* Providers */
|
||||
Via.getManager().getProviders().use(BulkChunkTranslatorProvider.class, new BukkitViaBulkChunkTranslator());
|
||||
Via.getManager().getProviders().use(MovementTransmitterProvider.class, new BukkitViaMovementTransmitter());
|
||||
Via.getManager().getProviders().use(HandItemProvider.class, new HandItemProvider() {
|
||||
@Override
|
||||
public Item getHandItem(final UserConnection info) {
|
||||
if (HandItemCache.CACHE) {
|
||||
return HandItemCache.getHandItem(info.get(ProtocolInfo.class).getUuid());
|
||||
} else {
|
||||
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_9.getVersion()) {
|
||||
Via.getManager().getProviders().use(BulkChunkTranslatorProvider.class, new BukkitViaBulkChunkTranslator());
|
||||
Via.getManager().getProviders().use(MovementTransmitterProvider.class, new BukkitViaMovementTransmitter());
|
||||
|
||||
Via.getManager().getProviders().use(HandItemProvider.class, new HandItemProvider() {
|
||||
@Override
|
||||
public Item getHandItem(final UserConnection info) {
|
||||
if (handItemCache != null) {
|
||||
return handItemCache.getHandItem(info.getProtocolInfo().getUuid());
|
||||
}
|
||||
try {
|
||||
return Bukkit.getScheduler().callSyncMethod(Bukkit.getPluginManager().getPlugin("ViaVersion"), new Callable<Item>() {
|
||||
@Override
|
||||
public Item call() throws Exception {
|
||||
UUID playerUUID = info.get(ProtocolInfo.class).getUuid();
|
||||
if (Bukkit.getPlayer(playerUUID) != null) {
|
||||
return HandItemCache.convert(Bukkit.getPlayer(playerUUID).getItemInHand());
|
||||
}
|
||||
return null;
|
||||
return Bukkit.getScheduler().callSyncMethod(Bukkit.getPluginManager().getPlugin("ViaVersion"), () -> {
|
||||
UUID playerUUID = info.getProtocolInfo().getUuid();
|
||||
Player player = Bukkit.getPlayer(playerUUID);
|
||||
if (player != null) {
|
||||
return HandItemCache.convert(player.getItemInHand());
|
||||
}
|
||||
return null;
|
||||
}).get(10, TimeUnit.SECONDS);
|
||||
} catch (Exception e) {
|
||||
Via.getPlatform().getLogger().severe("Error fetching hand item: " + e.getClass().getName());
|
||||
@@ -84,8 +137,32 @@ public class BukkitViaLoader implements ViaPlatformLoader {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_12.getVersion()) {
|
||||
if (plugin.getConf().is1_12QuickMoveActionFix()) {
|
||||
Via.getManager().getProviders().use(InventoryQuickMoveProvider.class, new BukkitInventoryQuickMoveProvider());
|
||||
}
|
||||
}
|
||||
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_13.getVersion()) {
|
||||
if (Via.getConfig().getBlockConnectionMethod().equalsIgnoreCase("world")) {
|
||||
BukkitBlockConnectionProvider blockConnectionProvider = new BukkitBlockConnectionProvider();
|
||||
Via.getManager().getProviders().use(BlockConnectionProvider.class, blockConnectionProvider);
|
||||
ConnectionData.blockConnectionProvider = blockConnectionProvider;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unload() {
|
||||
for (Listener listener : listeners) {
|
||||
HandlerList.unregisterAll(listener);
|
||||
}
|
||||
listeners.clear();
|
||||
for (BukkitTask task : tasks) {
|
||||
task.cancel();
|
||||
}
|
||||
tasks.clear();
|
||||
}
|
||||
}
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
package us.myles.ViaVersion.bukkit.providers;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
|
||||
import us.myles.ViaVersion.bukkit.tasks.protocol1_12to1_11_1.BukkitInventoryUpdateTask;
|
||||
import us.myles.ViaVersion.bukkit.util.NMSUtil;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.protocols.protocol1_12to1_11_1.providers.InventoryQuickMoveProvider;
|
||||
import us.myles.ViaVersion.protocols.protocol1_12to1_11_1.storage.ItemTransaction;
|
||||
import us.myles.ViaVersion.util.ReflectionUtil;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class BukkitInventoryQuickMoveProvider extends InventoryQuickMoveProvider {
|
||||
|
||||
private final Map<UUID, BukkitInventoryUpdateTask> updateTasks = new ConcurrentHashMap<>();
|
||||
private final boolean supported;
|
||||
// packet class
|
||||
private Class<?> windowClickPacketClass;
|
||||
private Object clickTypeEnum;
|
||||
// Use for nms
|
||||
private Method nmsItemMethod;
|
||||
private Method craftPlayerHandle;
|
||||
private Field connection;
|
||||
private Method packetMethod;
|
||||
|
||||
public BukkitInventoryQuickMoveProvider() {
|
||||
this.supported = isSupported();
|
||||
setupReflection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean registerQuickMoveAction(short windowId, short slotId, short actionId, UserConnection userConnection) {
|
||||
if (!supported) {
|
||||
return false;
|
||||
}
|
||||
if (slotId < 0) { // clicked out of inv slot
|
||||
return false;
|
||||
}
|
||||
if (windowId == 0) {
|
||||
/**
|
||||
* windowId is always 0 for player inventory.
|
||||
* This has almost definitely something to do with the offhand slot.
|
||||
*/
|
||||
if (slotId >= 36 && slotId <= 44) {
|
||||
int protocolId = ProtocolRegistry.SERVER_PROTOCOL;
|
||||
// this seems to be working just fine.
|
||||
if (protocolId == ProtocolVersion.v1_8.getVersion()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
ProtocolInfo info = userConnection.getProtocolInfo();
|
||||
UUID uuid = info.getUuid();
|
||||
BukkitInventoryUpdateTask updateTask = updateTasks.get(uuid);
|
||||
final boolean registered = updateTask != null;
|
||||
if (!registered) {
|
||||
updateTask = new BukkitInventoryUpdateTask(this, uuid);
|
||||
updateTasks.put(uuid, updateTask);
|
||||
}
|
||||
// http://wiki.vg/index.php?title=Protocol&oldid=13223#Click_Window
|
||||
updateTask.addItem(windowId, slotId, actionId);
|
||||
if (!registered) {
|
||||
Via.getPlatform().runSync(updateTask, 5L);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public Object buildWindowClickPacket(Player p, ItemTransaction storage) {
|
||||
if (!supported) {
|
||||
return null;
|
||||
}
|
||||
InventoryView inv = p.getOpenInventory();
|
||||
short slotId = storage.getSlotId();
|
||||
Inventory tinv = inv.getTopInventory();
|
||||
InventoryType tinvtype = tinv == null ? null : tinv.getType(); // can this even be null?
|
||||
if (tinvtype != null) {
|
||||
int protocolId = ProtocolRegistry.SERVER_PROTOCOL;
|
||||
if (protocolId == ProtocolVersion.v1_8.getVersion()) {
|
||||
if (tinvtype == InventoryType.BREWING) {
|
||||
// 1.9 added the blaze powder slot to brewing stand fix for 1.8 servers
|
||||
if (slotId >= 5 && slotId <= 40) {
|
||||
slotId -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ItemStack itemstack = null;
|
||||
// must be after top inventory slot check
|
||||
if (slotId <= inv.countSlots()) {
|
||||
itemstack = inv.getItem(slotId);
|
||||
} else {
|
||||
// if not true we got too many slots (version inventory slot changes)?
|
||||
String cause = "Too many inventory slots: slotId: " + slotId + " invSlotCount: " + inv.countSlots()
|
||||
+ " invType: " + inv.getType() + " topInvType: " + tinvtype;
|
||||
Via.getPlatform().getLogger().severe("Failed to get an item to create a window click packet. Please report this issue to the ViaVersion Github: " + cause);
|
||||
}
|
||||
Object packet = null;
|
||||
try {
|
||||
packet = windowClickPacketClass.getDeclaredConstructor().newInstance();
|
||||
Object nmsItem = itemstack == null ? null : nmsItemMethod.invoke(null, itemstack);
|
||||
ReflectionUtil.set(packet, "a", (int) storage.getWindowId());
|
||||
ReflectionUtil.set(packet, "slot", (int) slotId);
|
||||
ReflectionUtil.set(packet, "button", 0); // shift + left mouse click
|
||||
ReflectionUtil.set(packet, "d", storage.getActionId());
|
||||
ReflectionUtil.set(packet, "item", nmsItem);
|
||||
int protocolId = ProtocolRegistry.SERVER_PROTOCOL;
|
||||
if (protocolId == ProtocolVersion.v1_8.getVersion()) {
|
||||
ReflectionUtil.set(packet, "shift", 1);
|
||||
} else if (protocolId >= ProtocolVersion.v1_9.getVersion()) { // 1.9+
|
||||
ReflectionUtil.set(packet, "shift", clickTypeEnum);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Via.getPlatform().getLogger().log(Level.SEVERE, "Failed to create a window click packet. Please report this issue to the ViaVersion Github: " + e.getMessage(), e);
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
|
||||
public boolean sendPacketToServer(Player p, Object packet) {
|
||||
if (packet == null) {
|
||||
// let the other packets pass through
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
Object entityPlayer = craftPlayerHandle.invoke(p);
|
||||
Object playerConnection = connection.get(entityPlayer);
|
||||
// send
|
||||
packetMethod.invoke(playerConnection, packet);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void onTaskExecuted(UUID uuid) {
|
||||
updateTasks.remove(uuid);
|
||||
}
|
||||
|
||||
private void setupReflection() {
|
||||
if (!supported) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this.windowClickPacketClass = NMSUtil.nms("PacketPlayInWindowClick");
|
||||
int protocolId = ProtocolRegistry.SERVER_PROTOCOL;
|
||||
if (protocolId >= ProtocolVersion.v1_9.getVersion()) {
|
||||
Class<?> eclassz = NMSUtil.nms("InventoryClickType");
|
||||
Object[] constants = eclassz.getEnumConstants();
|
||||
this.clickTypeEnum = constants[1]; // QUICK_MOVE
|
||||
}
|
||||
Class<?> craftItemStack = NMSUtil.obc("inventory.CraftItemStack");
|
||||
this.nmsItemMethod = craftItemStack.getDeclaredMethod("asNMSCopy", ItemStack.class);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Couldn't find required inventory classes", e);
|
||||
}
|
||||
try {
|
||||
this.craftPlayerHandle = NMSUtil.obc("entity.CraftPlayer").getDeclaredMethod("getHandle");
|
||||
} catch (NoSuchMethodException | ClassNotFoundException e) {
|
||||
throw new RuntimeException("Couldn't find CraftPlayer", e);
|
||||
}
|
||||
try {
|
||||
this.connection = NMSUtil.nms("EntityPlayer").getDeclaredField("playerConnection");
|
||||
} catch (NoSuchFieldException | ClassNotFoundException e) {
|
||||
throw new RuntimeException("Couldn't find Player Connection", e);
|
||||
}
|
||||
try {
|
||||
this.packetMethod = NMSUtil.nms("PlayerConnection").getDeclaredMethod("a", windowClickPacketClass);
|
||||
} catch (NoSuchMethodException | ClassNotFoundException e) {
|
||||
throw new RuntimeException("Couldn't find CraftPlayer", e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isSupported() {
|
||||
int protocolId = ProtocolRegistry.SERVER_PROTOCOL;
|
||||
if (protocolId >= ProtocolVersion.v1_8.getVersion() && protocolId <= ProtocolVersion.v1_11_1.getVersion()) {
|
||||
return true; // 1.8-1.11.2
|
||||
}
|
||||
// this is not needed on 1.12+ servers
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -81,7 +81,7 @@ public class BukkitViaMovementTransmitter extends MovementTransmitterProvider {
|
||||
@Override
|
||||
public void sendPlayer(UserConnection info) {
|
||||
if (USE_NMS) {
|
||||
Player player = Bukkit.getPlayer(info.get(ProtocolInfo.class).getUuid());
|
||||
Player player = Bukkit.getPlayer(info.getProtocolInfo().getUuid());
|
||||
if (player != null) {
|
||||
try {
|
||||
// Tick player
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package us.myles.ViaVersion.bukkit.tasks.protocol1_12to1_11_1;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import us.myles.ViaVersion.bukkit.providers.BukkitInventoryQuickMoveProvider;
|
||||
import us.myles.ViaVersion.protocols.protocol1_12to1_11_1.storage.ItemTransaction;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BukkitInventoryUpdateTask implements Runnable {
|
||||
|
||||
private final BukkitInventoryQuickMoveProvider provider;
|
||||
private final UUID uuid;
|
||||
private final List<ItemTransaction> items;
|
||||
|
||||
public BukkitInventoryUpdateTask(BukkitInventoryQuickMoveProvider provider, UUID uuid) {
|
||||
this.provider = provider;
|
||||
this.uuid = uuid;
|
||||
this.items = Collections.synchronizedList(new ArrayList<ItemTransaction>());
|
||||
}
|
||||
|
||||
public void addItem(short windowId, short slotId, short actionId) {
|
||||
ItemTransaction storage = new ItemTransaction(windowId, slotId, actionId);
|
||||
items.add(storage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Player p = Bukkit.getServer().getPlayer(uuid);
|
||||
if (p == null) {
|
||||
provider.onTaskExecuted(uuid);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
synchronized (items) {
|
||||
for (ItemTransaction storage : items) {
|
||||
Object packet = provider.buildWindowClickPacket(p, storage);
|
||||
boolean result = provider.sendPacketToServer(p, packet);
|
||||
if (!result) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
items.clear();
|
||||
}
|
||||
} finally {
|
||||
provider.onTaskExecuted(uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,19 @@ package us.myles.ViaVersion.bukkit.util;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
public class NMSUtil {
|
||||
private static String BASE = Bukkit.getServer().getClass().getPackage().getName();
|
||||
private static String NMS = BASE.replace("org.bukkit.craftbukkit", "net.minecraft.server");
|
||||
private static final String BASE = Bukkit.getServer().getClass().getPackage().getName();
|
||||
private static final String NMS = BASE.replace("org.bukkit.craftbukkit", "net.minecraft.server");
|
||||
private static final boolean DEBUG_PROPERTY = loadDebugProperty();
|
||||
|
||||
private static boolean loadDebugProperty() {
|
||||
try {
|
||||
Class<?> serverClass = nms("MinecraftServer");
|
||||
Object server = serverClass.getDeclaredMethod("getServer").invoke(null);
|
||||
return (boolean) serverClass.getMethod("isDebugging").invoke(server);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static Class<?> nms(String className) throws ClassNotFoundException {
|
||||
return Class.forName(NMS + "." + className);
|
||||
@@ -17,4 +28,11 @@ public class NMSUtil {
|
||||
public static String getVersion() {
|
||||
return BASE.substring(BASE.lastIndexOf('.') + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if debug=true is set in the server.properties (added by CB)
|
||||
*/
|
||||
public static boolean isDebugPropertySet() {
|
||||
return DEBUG_PROPERTY;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
name: ViaVersion
|
||||
main: us.myles.ViaVersion.ViaVersionPlugin
|
||||
authors: [_MylesC, Matsv]
|
||||
authors: [_MylesC, creeper123123321, Gerrygames, KennyTV, Matsv]
|
||||
version: ${project.version}
|
||||
description: ${project.description}
|
||||
load: postworld
|
||||
api-version: 1.13
|
||||
loadbefore: [ProtocolLib, ProxyPipe, SpigotLib, SkinRestorer]
|
||||
softdepend: [ProtocolSupport, PacketListenerApi]
|
||||
commands:
|
||||
|
||||
+4
-4
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>viaversion-parent</artifactId>
|
||||
<groupId>us.myles</groupId>
|
||||
<version>1.0.0</version>
|
||||
<version>3.2.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<dependency>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-api</artifactId>
|
||||
<version>1.10-SNAPSHOT</version>
|
||||
<version>1.15-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
<dependency>
|
||||
<groupId>us.myles</groupId>
|
||||
<artifactId>viaversion-common</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
</project>
|
||||
@@ -2,43 +2,60 @@ package us.myles.ViaVersion;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.event.PlayerDisconnectEvent;
|
||||
import net.md_5.bungee.api.plugin.Listener;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
import net.md_5.bungee.event.EventHandler;
|
||||
import net.md_5.bungee.protocol.ProtocolConstants;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.ViaAPI;
|
||||
import us.myles.ViaVersion.api.command.ViaCommandSender;
|
||||
import us.myles.ViaVersion.api.configuration.ConfigurationProvider;
|
||||
import us.myles.ViaVersion.api.data.MappingDataLoader;
|
||||
import us.myles.ViaVersion.api.platform.TaskId;
|
||||
import us.myles.ViaVersion.api.platform.ViaConnectionManager;
|
||||
import us.myles.ViaVersion.api.platform.ViaPlatform;
|
||||
import us.myles.ViaVersion.bungee.commands.BungeeCommand;
|
||||
import us.myles.ViaVersion.bungee.commands.BungeeCommandHandler;
|
||||
import us.myles.ViaVersion.bungee.commands.BungeeCommandSender;
|
||||
import us.myles.ViaVersion.bungee.platform.*;
|
||||
import us.myles.ViaVersion.bungee.platform.BungeeTaskId;
|
||||
import us.myles.ViaVersion.bungee.platform.BungeeViaAPI;
|
||||
import us.myles.ViaVersion.bungee.platform.BungeeViaConfig;
|
||||
import us.myles.ViaVersion.bungee.platform.BungeeViaInjector;
|
||||
import us.myles.ViaVersion.bungee.platform.BungeeViaLoader;
|
||||
import us.myles.ViaVersion.bungee.service.ProtocolDetectorService;
|
||||
import us.myles.ViaVersion.dump.PluginInfo;
|
||||
import us.myles.ViaVersion.util.GsonUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class BungeePlugin extends Plugin implements ViaPlatform, Listener {
|
||||
public class BungeePlugin extends Plugin implements ViaPlatform<ProxiedPlayer>, Listener {
|
||||
private final ViaConnectionManager connectionManager = new ViaConnectionManager();
|
||||
private BungeeViaAPI api;
|
||||
private BungeeConfigAPI config;
|
||||
private BungeeCommandHandler commandHandler;
|
||||
private BungeeViaConfig config;
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
try {
|
||||
ProtocolConstants.class.getField("MINECRAFT_1_16_3");
|
||||
} catch (NoSuchFieldException e) {
|
||||
getLogger().warning(" / \\");
|
||||
getLogger().warning(" / \\");
|
||||
getLogger().warning(" / | \\");
|
||||
getLogger().warning(" / | \\ BUNGEECORD IS OUTDATED");
|
||||
getLogger().warning(" / \\ VIAVERSION MAY NOT WORK AS INTENDED");
|
||||
getLogger().warning(" / o \\");
|
||||
getLogger().warning("/_____________\\");
|
||||
}
|
||||
|
||||
api = new BungeeViaAPI();
|
||||
config = new BungeeConfigAPI(getDataFolder());
|
||||
commandHandler = new BungeeCommandHandler();
|
||||
config = new BungeeViaConfig(getDataFolder());
|
||||
BungeeCommandHandler commandHandler = new BungeeCommandHandler();
|
||||
ProxyServer.getInstance().getPluginManager().registerCommand(this, new BungeeCommand(commandHandler));
|
||||
|
||||
// Init platform
|
||||
Via.init(ViaManager.builder()
|
||||
.platform(this)
|
||||
@@ -50,6 +67,10 @@ public class BungeePlugin extends Plugin implements ViaPlatform, Listener {
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
if (ProxyServer.getInstance().getPluginManager().getPlugin("ViaBackwards") != null) {
|
||||
MappingDataLoader.enableMappingsCache();
|
||||
}
|
||||
|
||||
// Inject
|
||||
Via.getManager().init();
|
||||
}
|
||||
@@ -64,6 +85,11 @@ public class BungeePlugin extends Plugin implements ViaPlatform, Listener {
|
||||
return getProxy().getVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProxy() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPluginVersion() {
|
||||
return getDescription().getVersion();
|
||||
@@ -79,6 +105,11 @@ public class BungeePlugin extends Plugin implements ViaPlatform, Listener {
|
||||
return runAsync(runnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskId runSync(Runnable runnable, Long ticks) {
|
||||
return new BungeeTaskId(getProxy().getScheduler().schedule(this, runnable, ticks * 50, TimeUnit.MILLISECONDS).getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskId runRepeatingSync(Runnable runnable, Long ticks) {
|
||||
return new BungeeTaskId(getProxy().getScheduler().schedule(this, runnable, 0, ticks * 50, TimeUnit.MILLISECONDS).getId());
|
||||
@@ -105,13 +136,14 @@ public class BungeePlugin extends Plugin implements ViaPlatform, Listener {
|
||||
|
||||
@Override
|
||||
public void sendMessage(UUID uuid, String message) {
|
||||
getProxy().getPlayer(uuid).sendMessage(TextComponent.fromLegacyText(message));
|
||||
getProxy().getPlayer(uuid).sendMessage(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean kickPlayer(UUID uuid, String message) {
|
||||
if (getProxy().getPlayer(uuid) != null) {
|
||||
getProxy().getPlayer(uuid).disconnect(TextComponent.fromLegacyText(message));
|
||||
ProxiedPlayer player = getProxy().getPlayer(uuid);
|
||||
if (player != null) {
|
||||
player.disconnect(message);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -123,12 +155,12 @@ public class BungeePlugin extends Plugin implements ViaPlatform, Listener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViaAPI getApi() {
|
||||
public ViaAPI<ProxiedPlayer> getApi() {
|
||||
return api;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BungeeConfigAPI getConf() {
|
||||
public BungeeViaConfig getConf() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@@ -148,15 +180,26 @@ public class BungeePlugin extends Plugin implements ViaPlatform, Listener {
|
||||
|
||||
List<PluginInfo> plugins = new ArrayList<>();
|
||||
for (Plugin p : ProxyServer.getInstance().getPluginManager().getPlugins())
|
||||
plugins.add(new PluginInfo(true, p.getDescription().getName(), p.getDescription().getVersion(), p.getDescription().getMain(), Arrays.asList(p.getDescription().getAuthor())));
|
||||
plugins.add(new PluginInfo(
|
||||
true,
|
||||
p.getDescription().getName(),
|
||||
p.getDescription().getVersion(),
|
||||
p.getDescription().getMain(),
|
||||
Collections.singletonList(p.getDescription().getAuthor())
|
||||
));
|
||||
|
||||
platformSpecific.add("plugins", GsonUtil.getGson().toJsonTree(plugins));
|
||||
platformSpecific.add("servers", GsonUtil.getGson().toJsonTree(ProtocolDetectorService.getDetectedIds()));
|
||||
return platformSpecific;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onQuit(PlayerDisconnectEvent e) {
|
||||
Via.getManager().removePortedClient(e.getPlayer().getUniqueId());
|
||||
@Override
|
||||
public boolean isOldClientsAllowed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViaConnectionManager getConnectionManager() {
|
||||
return connectionManager;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,17 @@
|
||||
package us.myles.ViaVersion.bungee.commands;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import us.myles.ViaVersion.api.command.ViaCommandSender;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class BungeeCommandSender implements ViaCommandSender {
|
||||
private CommandSender sender;
|
||||
private final CommandSender sender;
|
||||
|
||||
public BungeeCommandSender(CommandSender sender) {
|
||||
this.sender = sender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(String permission) {
|
||||
@@ -19,7 +20,7 @@ public class BungeeCommandSender implements ViaCommandSender {
|
||||
|
||||
@Override
|
||||
public void sendMessage(String msg) {
|
||||
sender.sendMessage(TextComponent.fromLegacyText(msg));
|
||||
sender.sendMessage(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -3,7 +3,7 @@ package us.myles.ViaVersion.bungee.commands.subs;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.command.ViaCommandSender;
|
||||
import us.myles.ViaVersion.api.command.ViaSubCommand;
|
||||
import us.myles.ViaVersion.bungee.platform.BungeeConfigAPI;
|
||||
import us.myles.ViaVersion.bungee.platform.BungeeViaConfig;
|
||||
import us.myles.ViaVersion.bungee.service.ProtocolDetectorService;
|
||||
|
||||
public class ProbeSubCmd extends ViaSubCommand {
|
||||
@@ -15,7 +15,7 @@ public class ProbeSubCmd extends ViaSubCommand {
|
||||
@Override
|
||||
public String description() {
|
||||
return "Forces ViaVersion to scan server protocol versions " +
|
||||
(((BungeeConfigAPI) Via.getConfig()).getBungeePingInterval() == -1 ?
|
||||
(((BungeeViaConfig) Via.getConfig()).getBungeePingInterval() == -1 ?
|
||||
"" : "(Also happens at an interval)");
|
||||
}
|
||||
|
||||
|
||||
+8
-4
@@ -2,14 +2,12 @@ package us.myles.ViaVersion.bungee.handlers;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolPipeline;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class BungeeChannelInitializer extends ChannelInitializer<SocketChannel> {
|
||||
|
||||
public class BungeeChannelInitializer extends ChannelInitializer<Channel> {
|
||||
private final ChannelInitializer<Channel> original;
|
||||
private Method method;
|
||||
|
||||
@@ -24,18 +22,24 @@ public class BungeeChannelInitializer extends ChannelInitializer<SocketChannel>
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initChannel(SocketChannel socketChannel) throws Exception {
|
||||
protected void initChannel(Channel socketChannel) throws Exception {
|
||||
UserConnection info = new UserConnection(socketChannel);
|
||||
// init protocol
|
||||
new ProtocolPipeline(info);
|
||||
// Add originals
|
||||
this.method.invoke(this.original, socketChannel);
|
||||
|
||||
if (socketChannel.pipeline().get("packet-encoder") == null) return; // Don't inject if no packet-encoder
|
||||
if (socketChannel.pipeline().get("packet-decoder") == null) return; // Don't inject if no packet-decoder
|
||||
// Add our transformers
|
||||
BungeeEncodeHandler encoder = new BungeeEncodeHandler(info);
|
||||
BungeeDecodeHandler decoder = new BungeeDecodeHandler(info);
|
||||
|
||||
socketChannel.pipeline().addBefore("packet-encoder", "via-encoder", encoder);
|
||||
socketChannel.pipeline().addBefore("packet-decoder", "via-decoder", decoder);
|
||||
}
|
||||
|
||||
public ChannelInitializer<Channel> getOriginal() {
|
||||
return original;
|
||||
}
|
||||
}
|
||||
@@ -4,19 +4,14 @@ import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToMessageDecoder;
|
||||
import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.exception.CancelException;
|
||||
import us.myles.ViaVersion.packets.Direction;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.util.PipelineUtil;
|
||||
import us.myles.ViaVersion.exception.CancelDecoderException;
|
||||
import us.myles.ViaVersion.exception.CancelCodecException;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ChannelHandler.Sharable
|
||||
public class BungeeDecodeHandler extends MessageToMessageDecoder<ByteBuf> {
|
||||
|
||||
private final UserConnection info;
|
||||
|
||||
public BungeeDecodeHandler(UserConnection info) {
|
||||
@@ -25,55 +20,24 @@ public class BungeeDecodeHandler extends MessageToMessageDecoder<ByteBuf> {
|
||||
|
||||
@Override
|
||||
protected void decode(final ChannelHandlerContext ctx, ByteBuf bytebuf, List<Object> out) throws Exception {
|
||||
// use transformers
|
||||
if (bytebuf.readableBytes() > 0) {
|
||||
// Ignore if pending disconnect
|
||||
if (info.isPendingDisconnect()) {
|
||||
return;
|
||||
}
|
||||
// Increment received
|
||||
boolean second = info.incrementReceived();
|
||||
// Check PPS
|
||||
if (second) {
|
||||
if (info.handlePPS())
|
||||
return;
|
||||
}
|
||||
if (!info.checkIncomingPacket()) throw CancelDecoderException.generate(null);
|
||||
if (!info.shouldTransformPacket()) {
|
||||
out.add(bytebuf.retain());
|
||||
return;
|
||||
}
|
||||
|
||||
if (info.isActive()) {
|
||||
// Handle ID
|
||||
int id = Type.VAR_INT.read(bytebuf);
|
||||
// Transform
|
||||
ByteBuf newPacket = ctx.alloc().buffer();
|
||||
try {
|
||||
if (id == PacketWrapper.PASSTHROUGH_ID) {
|
||||
newPacket.writeBytes(bytebuf);
|
||||
} else {
|
||||
PacketWrapper wrapper = new PacketWrapper(id, bytebuf, info);
|
||||
ProtocolInfo protInfo = info.get(ProtocolInfo.class);
|
||||
protInfo.getPipeline().transform(Direction.INCOMING, protInfo.getState(), wrapper);
|
||||
wrapper.writeToBuffer(newPacket);
|
||||
}
|
||||
|
||||
bytebuf.clear();
|
||||
bytebuf = newPacket;
|
||||
} catch (Exception e) {
|
||||
// Clear Buffer
|
||||
bytebuf.clear();
|
||||
// Release Packet, be free!
|
||||
newPacket.release();
|
||||
throw e;
|
||||
}
|
||||
} else {
|
||||
bytebuf.retain();
|
||||
}
|
||||
|
||||
out.add(bytebuf);
|
||||
ByteBuf transformedBuf = ctx.alloc().buffer().writeBytes(bytebuf);
|
||||
try {
|
||||
info.transformIncoming(transformedBuf, CancelDecoderException::generate);
|
||||
out.add(transformedBuf.retain());
|
||||
} finally {
|
||||
transformedBuf.release();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
if (PipelineUtil.containsCause(cause, CancelException.class)) return;
|
||||
if (cause instanceof CancelCodecException) return;
|
||||
super.exceptionCaught(ctx, cause);
|
||||
}
|
||||
}
|
||||
@@ -4,79 +4,81 @@ import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToMessageEncoder;
|
||||
import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.bungee.util.BungeePipelineUtil;
|
||||
import us.myles.ViaVersion.exception.CancelException;
|
||||
import us.myles.ViaVersion.packets.Direction;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.util.PipelineUtil;
|
||||
import us.myles.ViaVersion.exception.CancelEncoderException;
|
||||
import us.myles.ViaVersion.exception.CancelCodecException;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ChannelHandler.Sharable
|
||||
public class BungeeEncodeHandler extends MessageToMessageEncoder<ByteBuf> {
|
||||
private final UserConnection info;
|
||||
private boolean handledCompression = false;
|
||||
private boolean handledCompression;
|
||||
|
||||
public BungeeEncodeHandler(UserConnection info) {
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void encode(final ChannelHandlerContext ctx, ByteBuf bytebuf, List<Object> out) throws Exception {
|
||||
if (bytebuf.readableBytes() == 0) {
|
||||
throw new CancelException();
|
||||
if (!info.checkOutgoingPacket()) throw CancelEncoderException.generate(null);
|
||||
if (!info.shouldTransformPacket()) {
|
||||
out.add(bytebuf.retain());
|
||||
return;
|
||||
}
|
||||
|
||||
ByteBuf transformedBuf = ctx.alloc().buffer().writeBytes(bytebuf);
|
||||
try {
|
||||
boolean needsCompress = handleCompressionOrder(ctx, transformedBuf);
|
||||
info.transformOutgoing(transformedBuf, CancelEncoderException::generate);
|
||||
|
||||
if (needsCompress) {
|
||||
recompress(ctx, transformedBuf);
|
||||
}
|
||||
|
||||
out.add(transformedBuf.retain());
|
||||
} finally {
|
||||
transformedBuf.release();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean handleCompressionOrder(ChannelHandlerContext ctx, ByteBuf buf) {
|
||||
boolean needsCompress = false;
|
||||
if (!handledCompression) {
|
||||
if (ctx.pipeline().names().indexOf("compress") > ctx.pipeline().names().indexOf("via-encoder")) {
|
||||
// Need to decompress this packet due to bad order
|
||||
bytebuf = BungeePipelineUtil.decompress(ctx, bytebuf);
|
||||
ChannelHandler encoder = ctx.pipeline().get("via-decoder");
|
||||
ChannelHandler decoder = ctx.pipeline().get("via-encoder");
|
||||
ctx.pipeline().remove(encoder);
|
||||
ctx.pipeline().remove(decoder);
|
||||
ctx.pipeline().addAfter("decompress", "via-decoder", encoder);
|
||||
ctx.pipeline().addAfter("compress", "via-encoder", decoder);
|
||||
ByteBuf decompressed = BungeePipelineUtil.decompress(ctx, buf);
|
||||
try {
|
||||
buf.clear().writeBytes(decompressed);
|
||||
} finally {
|
||||
decompressed.release();
|
||||
}
|
||||
ChannelHandler dec = ctx.pipeline().get("via-decoder");
|
||||
ChannelHandler enc = ctx.pipeline().get("via-encoder");
|
||||
ctx.pipeline().remove(dec);
|
||||
ctx.pipeline().remove(enc);
|
||||
ctx.pipeline().addAfter("decompress", "via-decoder", dec);
|
||||
ctx.pipeline().addAfter("compress", "via-encoder", enc);
|
||||
needsCompress = true;
|
||||
handledCompression = true;
|
||||
}
|
||||
}
|
||||
// Increment sent
|
||||
info.incrementSent();
|
||||
return needsCompress;
|
||||
}
|
||||
|
||||
if (info.isActive()) {
|
||||
// Handle ID
|
||||
int id = Type.VAR_INT.read(bytebuf);
|
||||
// Transform
|
||||
ByteBuf oldPacket = bytebuf.copy();
|
||||
bytebuf.clear();
|
||||
|
||||
try {
|
||||
PacketWrapper wrapper = new PacketWrapper(id, oldPacket, info);
|
||||
ProtocolInfo protInfo = info.get(ProtocolInfo.class);
|
||||
protInfo.getPipeline().transform(Direction.OUTGOING, protInfo.getState(), wrapper);
|
||||
wrapper.writeToBuffer(bytebuf);
|
||||
} catch (Exception e) {
|
||||
bytebuf.clear();
|
||||
throw e;
|
||||
} finally {
|
||||
oldPacket.release();
|
||||
}
|
||||
private void recompress(ChannelHandlerContext ctx, ByteBuf buf) {
|
||||
ByteBuf compressed = BungeePipelineUtil.compress(ctx, buf);
|
||||
try {
|
||||
buf.clear().writeBytes(compressed);
|
||||
} finally {
|
||||
compressed.release();
|
||||
}
|
||||
|
||||
if (needsCompress) {
|
||||
bytebuf = BungeePipelineUtil.compress(ctx, bytebuf);
|
||||
}
|
||||
out.add(bytebuf.retain());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
if (PipelineUtil.containsCause(cause, CancelException.class)) return;
|
||||
if (cause instanceof CancelCodecException) return;
|
||||
super.exceptionCaught(ctx, cause);
|
||||
}
|
||||
}
|
||||
+150
-18
@@ -3,26 +3,43 @@ package us.myles.ViaVersion.bungee.handlers;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.event.ServerConnectEvent;
|
||||
import net.md_5.bungee.api.event.ServerConnectedEvent;
|
||||
import net.md_5.bungee.api.event.ServerSwitchEvent;
|
||||
import net.md_5.bungee.api.plugin.Listener;
|
||||
import net.md_5.bungee.api.score.Team;
|
||||
import net.md_5.bungee.event.EventHandler;
|
||||
import net.md_5.bungee.protocol.packet.PluginMessage;
|
||||
import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.Pair;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.data.ExternalJoinGameListener;
|
||||
import us.myles.ViaVersion.api.data.StoredObject;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.protocol.Protocol;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolPipeline;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.bungee.service.ProtocolDetectorService;
|
||||
import us.myles.ViaVersion.bungee.storage.BungeeStorage;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets.InventoryPackets;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9To1_8;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.EntityIdProvider;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker1_9;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class BungeeServerHandler implements Listener {
|
||||
private static Method getPendingConnection;
|
||||
private static Method getHandshake;
|
||||
private static Method getRelayMessages;
|
||||
private static Method setProtocol;
|
||||
private static Method getEntityMap = null;
|
||||
private static Method setVersion = null;
|
||||
@@ -31,8 +48,8 @@ public class BungeeServerHandler implements Listener {
|
||||
|
||||
static {
|
||||
try {
|
||||
getPendingConnection = Class.forName("net.md_5.bungee.UserConnection").getDeclaredMethod("getPendingConnection");
|
||||
getHandshake = Class.forName("net.md_5.bungee.connection.InitialHandler").getDeclaredMethod("getHandshake");
|
||||
getRelayMessages = Class.forName("net.md_5.bungee.connection.InitialHandler").getDeclaredMethod("getRelayMessages");
|
||||
setProtocol = Class.forName("net.md_5.bungee.protocol.packet.Handshake").getDeclaredMethod("setProtocolVersion", int.class);
|
||||
getEntityMap = Class.forName("net.md_5.bungee.entitymap.EntityMap").getDeclaredMethod("getEntityMap", int.class);
|
||||
setVersion = Class.forName("net.md_5.bungee.netty.ChannelWrapper").getDeclaredMethod("setVersion", int.class);
|
||||
@@ -46,27 +63,32 @@ public class BungeeServerHandler implements Listener {
|
||||
}
|
||||
|
||||
// Set the handshake version every time someone connects to any server
|
||||
@EventHandler
|
||||
public void onServerConnect(ServerConnectEvent e) throws NoSuchFieldException, IllegalAccessException {
|
||||
@EventHandler(priority = 120)
|
||||
public void onServerConnect(ServerConnectEvent e) {
|
||||
if (e.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
UserConnection user = Via.getManager().getConnection(e.getPlayer().getUniqueId());
|
||||
if (user == null) return;
|
||||
if (!user.has(BungeeStorage.class)) {
|
||||
user.put(new BungeeStorage(user, e.getPlayer()));
|
||||
}
|
||||
|
||||
int protocolId = ProtocolDetectorService.getProtocolId(e.getTarget().getName());
|
||||
List<Pair<Integer, Protocol>> protocols = ProtocolRegistry.getProtocolPath(user.get(ProtocolInfo.class).getProtocolVersion(), protocolId);
|
||||
List<Pair<Integer, Protocol>> protocols = ProtocolRegistry.getProtocolPath(user.getProtocolInfo().getProtocolVersion(), protocolId);
|
||||
|
||||
// Check if ViaVersion can support that version
|
||||
try {
|
||||
Object pendingConnection = getPendingConnection.invoke(e.getPlayer());
|
||||
Object handshake = getHandshake.invoke(pendingConnection);
|
||||
setProtocol.invoke(handshake, protocols == null ? user.get(ProtocolInfo.class).getProtocolVersion() : protocolId);
|
||||
} catch (InvocationTargetException e1) {
|
||||
//Object pendingConnection = getPendingConnection.invoke(e.getPlayer());
|
||||
Object handshake = getHandshake.invoke(e.getPlayer().getPendingConnection());
|
||||
setProtocol.invoke(handshake, protocols == null ? user.getProtocolInfo().getProtocolVersion() : protocolId);
|
||||
} catch (InvocationTargetException | IllegalAccessException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@EventHandler(priority = -120)
|
||||
public void onServerConnected(ServerConnectedEvent e) {
|
||||
try {
|
||||
checkServerChange(e, Via.getManager().getConnection(e.getPlayer().getUniqueId()));
|
||||
@@ -75,25 +97,71 @@ public class BungeeServerHandler implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = -120)
|
||||
public void onServerSwitch(ServerSwitchEvent e) {
|
||||
// Update entity id
|
||||
UserConnection userConnection = Via.getManager().getConnection(e.getPlayer().getUniqueId());
|
||||
if (userConnection == null) return;
|
||||
int playerId;
|
||||
try {
|
||||
playerId = Via.getManager().getProviders().get(EntityIdProvider.class).getEntityId(userConnection);
|
||||
} catch (Exception ex) {
|
||||
return; // Ignored
|
||||
}
|
||||
for (StoredObject storedObject : userConnection.getStoredObjects().values()) {
|
||||
if (storedObject instanceof ExternalJoinGameListener) {
|
||||
((ExternalJoinGameListener) storedObject).onExternalJoinGame(playerId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void checkServerChange(ServerConnectedEvent e, UserConnection user) throws Exception {
|
||||
if (user == null) return;
|
||||
// Auto-team handling
|
||||
// Handle server/version change
|
||||
if (user.has(BungeeStorage.class)) {
|
||||
BungeeStorage storage = user.get(BungeeStorage.class);
|
||||
ProxiedPlayer player = storage.getPlayer();
|
||||
|
||||
if (e.getServer() != null) {
|
||||
if (!e.getServer().getInfo().getName().equals(storage.getCurrentServer())) {
|
||||
// Clear auto-team
|
||||
EntityTracker1_9 oldEntityTracker = user.get(EntityTracker1_9.class);
|
||||
if (oldEntityTracker != null) {
|
||||
if (oldEntityTracker.isAutoTeam() && oldEntityTracker.isTeamExists()) {
|
||||
oldEntityTracker.sendTeamPacket(false, true);
|
||||
}
|
||||
}
|
||||
|
||||
String serverName = e.getServer().getInfo().getName();
|
||||
|
||||
storage.setCurrentServer(serverName);
|
||||
|
||||
int protocolId = ProtocolDetectorService.getProtocolId(serverName);
|
||||
|
||||
UserConnection viaConnection = Via.getManager().getConnection(player.getUniqueId());
|
||||
ProtocolInfo info = viaConnection.get(ProtocolInfo.class);
|
||||
if (protocolId <= ProtocolVersion.v1_8.getVersion()) { // 1.8 doesn't have BossBar packet
|
||||
if (storage.getBossbar() != null) {
|
||||
// TODO: Verify whether this packet needs to be sent when 1.8 -> 1.9 protocol isn't present in the pipeline
|
||||
// This ensures we can encode it properly as only the 1.9 protocol is currently implemented.
|
||||
if (user.getProtocolInfo().getPipeline().contains(Protocol1_9To1_8.class)) {
|
||||
for (UUID uuid : storage.getBossbar()) {
|
||||
PacketWrapper wrapper = new PacketWrapper(0x0C, null, user);
|
||||
wrapper.write(Type.UUID, uuid);
|
||||
wrapper.write(Type.VAR_INT, 1); // remove
|
||||
wrapper.send(Protocol1_9To1_8.class, true, true);
|
||||
}
|
||||
}
|
||||
storage.getBossbar().clear();
|
||||
}
|
||||
}
|
||||
|
||||
ProtocolInfo info = user.getProtocolInfo();
|
||||
int previousServerProtocol = info.getServerProtocolVersion();
|
||||
|
||||
// Refresh the pipes
|
||||
List<Pair<Integer, Protocol>> protocols = ProtocolRegistry.getProtocolPath(info.getProtocolVersion(), protocolId);
|
||||
ProtocolPipeline pipeline = viaConnection.get(ProtocolInfo.class).getPipeline();
|
||||
viaConnection.clearStoredObjects();
|
||||
ProtocolPipeline pipeline = user.getProtocolInfo().getPipeline();
|
||||
user.clearStoredObjects();
|
||||
pipeline.cleanPipes();
|
||||
if (protocols == null) {
|
||||
// TODO Check Bungee Supported Protocols? *shrugs*
|
||||
@@ -104,14 +172,78 @@ public class BungeeServerHandler implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
viaConnection.put(info);
|
||||
viaConnection.put(storage);
|
||||
info.setServerProtocolVersion(protocolId);
|
||||
// Add version-specific base Protocol
|
||||
pipeline.add(ProtocolRegistry.getBaseProtocol(protocolId));
|
||||
|
||||
viaConnection.setActive(protocols != null);
|
||||
// Workaround 1.13 server change
|
||||
Object relayMessages = getRelayMessages.invoke(e.getPlayer().getPendingConnection());
|
||||
for (Object message : (List) relayMessages) {
|
||||
PluginMessage plMsg = (PluginMessage) message;
|
||||
String channel = plMsg.getTag();
|
||||
int id1_13 = ProtocolVersion.v1_13.getVersion();
|
||||
if (previousServerProtocol != -1) {
|
||||
String oldChannel = channel;
|
||||
if (previousServerProtocol < id1_13 && protocolId >= id1_13) {
|
||||
channel = InventoryPackets.getNewPluginChannelId(channel);
|
||||
if (channel == null) {
|
||||
throw new RuntimeException(oldChannel + " found in relayMessages");
|
||||
}
|
||||
if (channel.equals("minecraft:register")) {
|
||||
plMsg.setData(Arrays.stream(new String(plMsg.getData(), StandardCharsets.UTF_8).split("\0"))
|
||||
.map(InventoryPackets::getNewPluginChannelId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.joining("\0")).getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
} else if (previousServerProtocol >= id1_13 && protocolId < id1_13) {
|
||||
channel = InventoryPackets.getOldPluginChannelId(channel);
|
||||
if (channel == null) {
|
||||
throw new RuntimeException(oldChannel + " found in relayMessages");
|
||||
}
|
||||
if (channel.equals("REGISTER")) {
|
||||
plMsg.setData(Arrays.stream(new String(plMsg.getData(), StandardCharsets.UTF_8).split("\0"))
|
||||
.map(InventoryPackets::getOldPluginChannelId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.joining("\0")).getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
}
|
||||
plMsg.setTag(channel);
|
||||
}
|
||||
|
||||
user.put(info);
|
||||
user.put(storage);
|
||||
|
||||
user.setActive(protocols != null);
|
||||
|
||||
// Init all protocols TODO check if this can get moved up to the previous for loop, and doesn't require the pipeline to already exist.
|
||||
for (Protocol protocol : pipeline.pipes()) {
|
||||
protocol.init(viaConnection);
|
||||
protocol.init(user);
|
||||
}
|
||||
|
||||
EntityTracker1_9 newTracker = user.get(EntityTracker1_9.class);
|
||||
if (newTracker != null) {
|
||||
if (Via.getConfig().isAutoTeam()) {
|
||||
String currentTeam = null;
|
||||
for (Team team : player.getScoreboard().getTeams()) {
|
||||
if (team.getPlayers().contains(info.getUsername())) {
|
||||
currentTeam = team.getName();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Reinitialize auto-team
|
||||
newTracker.setAutoTeam(true);
|
||||
if (currentTeam == null) {
|
||||
// Send auto-team as it was cleared above
|
||||
newTracker.sendTeamPacket(true, true);
|
||||
newTracker.setCurrentTeam("viaversion");
|
||||
} else {
|
||||
// Auto-team will be sent when bungee send remove packet
|
||||
newTracker.setAutoTeam(Via.getConfig().isAutoTeam());
|
||||
newTracker.setCurrentTeam(currentTeam);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Object wrapper = channelWrapper.get(player);
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package us.myles.ViaVersion.bungee.listeners;
|
||||
|
||||
import net.md_5.bungee.api.event.ServerConnectedEvent;
|
||||
import net.md_5.bungee.api.plugin.Listener;
|
||||
import net.md_5.bungee.event.EventHandler;
|
||||
import net.md_5.bungee.event.EventPriority;
|
||||
import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
|
||||
import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_9;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.api.type.types.version.Types1_9;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9To1_8;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker1_9;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
/*
|
||||
* This patches https://github.com/ViaVersion/ViaVersion/issues/555
|
||||
*/
|
||||
public class ElytraPatch implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onServerConnected(ServerConnectedEvent event) {
|
||||
UserConnection user = Via.getManager().getConnection(event.getPlayer().getUniqueId());
|
||||
if (user == null) return;
|
||||
|
||||
try {
|
||||
if (user.getProtocolInfo().getPipeline().contains(Protocol1_9To1_8.class)) {
|
||||
int entityId = user.get(EntityTracker1_9.class).getProvidedEntityId();
|
||||
|
||||
PacketWrapper wrapper = new PacketWrapper(0x39, null, user);
|
||||
|
||||
wrapper.write(Type.VAR_INT, entityId);
|
||||
wrapper.write(Types1_9.METADATA_LIST, Collections.singletonList(new Metadata(0, MetaType1_9.Byte, (byte) 0)));
|
||||
|
||||
wrapper.send(Protocol1_9To1_8.class);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,232 +0,0 @@
|
||||
package us.myles.ViaVersion.bungee.platform;
|
||||
|
||||
import us.myles.ViaVersion.api.ViaVersionConfig;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
|
||||
import us.myles.ViaVersion.bungee.providers.BungeeVersionProvider;
|
||||
import us.myles.ViaVersion.util.Config;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
public class BungeeConfigAPI extends Config implements ViaVersionConfig {
|
||||
private static List<String> UNSUPPORTED = Arrays.asList("nms-player-ticking", "item-cache", "anti-xray-patch");
|
||||
|
||||
public BungeeConfigAPI(File configFile) {
|
||||
super(new File(configFile, "config.yml"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleConfig(Map<String, Object> config) {
|
||||
// Parse servers
|
||||
Map<String, Object> servers;
|
||||
if (!(config.get("bungee-servers") instanceof Map)) {
|
||||
servers = new HashMap<>();
|
||||
} else {
|
||||
servers = (Map) config.get("bungee-servers");
|
||||
}
|
||||
// Convert any bad Protocol Ids
|
||||
for (Map.Entry<String, Object> entry : new HashSet<>(servers.entrySet())) {
|
||||
if (!(entry.getValue() instanceof Integer)) {
|
||||
if (entry.getValue() instanceof String) {
|
||||
ProtocolVersion found = ProtocolVersion.getClosest((String) entry.getValue());
|
||||
if (found != null) {
|
||||
servers.put(entry.getKey(), found.getId());
|
||||
} else {
|
||||
servers.remove(entry.getKey()); // Remove!
|
||||
}
|
||||
} else {
|
||||
servers.remove(entry.getKey()); // Remove!
|
||||
}
|
||||
}
|
||||
}
|
||||
// Ensure default exists
|
||||
if (!servers.containsKey("default")) {
|
||||
servers.put("default", BungeeVersionProvider.getLowestSupportedVersion());
|
||||
}
|
||||
// Put back
|
||||
config.put("bungee-servers", servers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getUnsupportedOptions() {
|
||||
return UNSUPPORTED;
|
||||
}
|
||||
|
||||
public boolean isCheckForUpdates() {
|
||||
return getBoolean("checkforupdates", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPreventCollision() {
|
||||
return getBoolean("prevent-collision", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNewEffectIndicator() {
|
||||
return getBoolean("use-new-effect-indicator", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShowNewDeathMessages() {
|
||||
return getBoolean("use-new-deathmessages", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuppressMetadataErrors() {
|
||||
return getBoolean("suppress-metadata-errors", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShieldBlocking() {
|
||||
return getBoolean("shield-blocking", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHologramPatch() {
|
||||
return getBoolean("hologram-patch", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBossbarPatch() {
|
||||
return getBoolean("bossbar-patch", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBossbarAntiflicker() {
|
||||
return getBoolean("bossbar-anti-flicker", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUnknownEntitiesSuppressed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getHologramYOffset() {
|
||||
return getDouble("hologram-y", -0.96D);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBlockBreakPatch() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxPPS() {
|
||||
return getInt("max-pps", 800);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMaxPPSKickMessage() {
|
||||
return getString("max-pps-kick-msg", "Sending packets too fast? lag?");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTrackingPeriod() {
|
||||
return getInt("tracking-period", 6);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWarningPPS() {
|
||||
return getInt("tracking-warning-pps", 120);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxWarnings() {
|
||||
return getInt("tracking-max-warnings", 3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMaxWarningsKickMessage() {
|
||||
return getString("tracking-max-kick-msg", "You are sending too many packets, :(");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAntiXRay() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSendSupportedVersions() {
|
||||
return getBoolean("send-supported-versions", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStimulatePlayerTick() {
|
||||
return getBoolean("simulate-pt", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemCache() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNMSPlayerTicking() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReplacePistons() {
|
||||
return getBoolean("replace-pistons", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPistonReplacementId() {
|
||||
return getInt("replacement-piston-id", 0);
|
||||
}
|
||||
|
||||
public boolean isAutoTeam() {
|
||||
// Collision has to be enabled first
|
||||
return isPreventCollision() && getBoolean("auto-team", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForceJsonTransform() {
|
||||
return getBoolean("force-json-transform", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Integer> getBlockedProtocols() {
|
||||
return getIntegerList("block-protocols");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBlockedDisconnectMsg() {
|
||||
return getString("block-disconnect-msg", "You are using an unsupported Minecraft version!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReloadDisconnectMsg() {
|
||||
return getString("reload-disconnect-msg", "Server reload, please rejoin!");
|
||||
}
|
||||
|
||||
/**
|
||||
* What is the interval for checking servers via ping
|
||||
* -1 for disabled
|
||||
*
|
||||
* @return Ping interval in seconds
|
||||
*/
|
||||
public int getBungeePingInterval() {
|
||||
return getInt("bungee-ping-interval", 60);
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the bungee ping be saved to the config on change.
|
||||
*
|
||||
* @return True if it should save
|
||||
*/
|
||||
public boolean isBungeePingSave() {
|
||||
return getBoolean("bungee-ping-save", true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the listed server protocols in the config.
|
||||
* default will be listed as default.
|
||||
*
|
||||
* @return Map of String, Integer
|
||||
*/
|
||||
public Map<String, Integer> getBungeeServerProtocols() {
|
||||
return get("bungee-servers", Map.class, new HashMap<>());
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,16 @@
|
||||
package us.myles.ViaVersion.bungee.platform;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import us.myles.ViaVersion.api.platform.TaskId;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public class BungeeTaskId implements TaskId {
|
||||
private Integer object;
|
||||
private final Integer object;
|
||||
|
||||
public BungeeTaskId(Integer object) {
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getObject() {
|
||||
return object;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package us.myles.ViaVersion.bungee.platform;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.NonNull;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
@@ -14,29 +14,29 @@ import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
|
||||
import us.myles.ViaVersion.bungee.service.ProtocolDetectorService;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BungeeViaAPI implements ViaAPI<ProxiedPlayer> {
|
||||
|
||||
@Override
|
||||
public int getPlayerVersion(@NonNull ProxiedPlayer player) {
|
||||
if (!isPorted(player.getUniqueId()))
|
||||
return ProtocolRegistry.SERVER_PROTOCOL;
|
||||
return getPortedPlayers().get(player.getUniqueId()).get(ProtocolInfo.class).getProtocolVersion();
|
||||
public int getPlayerVersion(ProxiedPlayer player) {
|
||||
UserConnection conn = Via.getManager().getConnection(player.getUniqueId());
|
||||
if (conn == null) {
|
||||
return player.getPendingConnection().getVersion();
|
||||
}
|
||||
return conn.getProtocolInfo().getProtocolVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPlayerVersion(@NonNull UUID uuid) {
|
||||
if (!isPorted(uuid))
|
||||
return ProtocolRegistry.SERVER_PROTOCOL;
|
||||
return getPortedPlayers().get(uuid).get(ProtocolInfo.class).getProtocolVersion();
|
||||
public int getPlayerVersion(UUID uuid) {
|
||||
return getPlayerVersion(ProxyServer.getInstance().getPlayer(uuid));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPorted(UUID playerUUID) {
|
||||
return getPortedPlayers().containsKey(playerUUID);
|
||||
public boolean isInjected(UUID playerUUID) {
|
||||
return Via.getManager().isClientConnected(playerUUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -46,8 +46,10 @@ public class BungeeViaAPI implements ViaAPI<ProxiedPlayer> {
|
||||
|
||||
@Override
|
||||
public void sendRawPacket(UUID uuid, ByteBuf packet) throws IllegalArgumentException {
|
||||
if (!isPorted(uuid)) throw new IllegalArgumentException("This player is not controlled by ViaVersion!");
|
||||
UserConnection ci = getPortedPlayers().get(uuid);
|
||||
if (!isInjected(uuid)) {
|
||||
throw new IllegalArgumentException("This player is not controlled by ViaVersion!");
|
||||
}
|
||||
UserConnection ci = Via.getManager().getConnection(uuid);
|
||||
ci.sendRawPacket(packet);
|
||||
}
|
||||
|
||||
@@ -74,10 +76,6 @@ public class BungeeViaAPI implements ViaAPI<ProxiedPlayer> {
|
||||
return outputSet;
|
||||
}
|
||||
|
||||
public Map<UUID, UserConnection> getPortedPlayers() {
|
||||
return Via.getManager().getPortedPlayers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces ViaVersion to probe a server
|
||||
*
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
package us.myles.ViaVersion.bungee.platform;
|
||||
|
||||
import us.myles.ViaVersion.AbstractViaConfig;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
|
||||
import us.myles.ViaVersion.bungee.providers.BungeeVersionProvider;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
|
||||
public class BungeeViaConfig extends AbstractViaConfig {
|
||||
private static final List<String> UNSUPPORTED = Arrays.asList("nms-player-ticking", "item-cache", "anti-xray-patch", "quick-move-action-fix", "velocity-ping-interval", "velocity-ping-save", "velocity-servers", "blockconnection-method", "change-1_9-hitbox", "change-1_14-hitbox");
|
||||
private int bungeePingInterval;
|
||||
private boolean bungeePingSave;
|
||||
private Map<String, Integer> bungeeServerProtocols;
|
||||
|
||||
public BungeeViaConfig(File configFile) {
|
||||
super(new File(configFile, "config.yml"));
|
||||
reloadConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadFields() {
|
||||
super.loadFields();
|
||||
bungeePingInterval = getInt("bungee-ping-interval", 60);
|
||||
bungeePingSave = getBoolean("bungee-ping-save", true);
|
||||
bungeeServerProtocols = get("bungee-servers", Map.class, new HashMap<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getDefaultConfigURL() {
|
||||
return BungeeViaConfig.class.getClassLoader().getResource("assets/viaversion/config.yml");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleConfig(Map<String, Object> config) {
|
||||
// Parse servers
|
||||
Map<String, Object> servers;
|
||||
if (!(config.get("bungee-servers") instanceof Map)) {
|
||||
servers = new HashMap<>();
|
||||
} else {
|
||||
servers = (Map) config.get("bungee-servers");
|
||||
}
|
||||
// Convert any bad Protocol Ids
|
||||
for (Map.Entry<String, Object> entry : new HashSet<>(servers.entrySet())) {
|
||||
if (!(entry.getValue() instanceof Integer)) {
|
||||
if (entry.getValue() instanceof String) {
|
||||
ProtocolVersion found = ProtocolVersion.getClosest((String) entry.getValue());
|
||||
if (found != null) {
|
||||
servers.put(entry.getKey(), found.getVersion());
|
||||
} else {
|
||||
servers.remove(entry.getKey()); // Remove!
|
||||
}
|
||||
} else {
|
||||
servers.remove(entry.getKey()); // Remove!
|
||||
}
|
||||
}
|
||||
}
|
||||
// Ensure default exists
|
||||
if (!servers.containsKey("default")) {
|
||||
servers.put("default", BungeeVersionProvider.getLowestSupportedVersion());
|
||||
}
|
||||
// Put back
|
||||
config.put("bungee-servers", servers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getUnsupportedOptions() {
|
||||
return UNSUPPORTED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemCache() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNMSPlayerTicking() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* What is the interval for checking servers via ping
|
||||
* -1 for disabled
|
||||
*
|
||||
* @return Ping interval in seconds
|
||||
*/
|
||||
public int getBungeePingInterval() {
|
||||
return bungeePingInterval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the bungee ping be saved to the config on change.
|
||||
*
|
||||
* @return True if it should save
|
||||
*/
|
||||
public boolean isBungeePingSave() {
|
||||
return bungeePingSave;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the listed server protocols in the config.
|
||||
* default will be listed as default.
|
||||
*
|
||||
* @return Map of String, Integer
|
||||
*/
|
||||
public Map<String, Integer> getBungeeServerProtocols() {
|
||||
return bungeeServerProtocols;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package us.myles.ViaVersion.bungee.platform;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
@@ -8,28 +9,43 @@ import us.myles.ViaVersion.bungee.handlers.BungeeChannelInitializer;
|
||||
import us.myles.ViaVersion.util.ReflectionUtil;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.List;
|
||||
|
||||
public class BungeeViaInjector implements ViaInjector {
|
||||
|
||||
@Override
|
||||
public void inject() throws Exception {
|
||||
try {
|
||||
try {
|
||||
Class<?> pipelineUtils = Class.forName("net.md_5.bungee.netty.PipelineUtils");
|
||||
Field field = pipelineUtils.getDeclaredField("SERVER_CHILD");
|
||||
field.setAccessible(true);
|
||||
|
||||
Class<?> pipelineUtils = Class.forName("net.md_5.bungee.netty.PipelineUtils");
|
||||
Field field = pipelineUtils.getDeclaredField("SERVER_CHILD");
|
||||
field.setAccessible(true);
|
||||
// Remove any final stuff
|
||||
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
||||
modifiersField.setAccessible(true);
|
||||
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
|
||||
|
||||
BungeeChannelInitializer newInit = new BungeeChannelInitializer((ChannelInitializer<Channel>) field.get(null));
|
||||
field.set(null, newInit);
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new Exception("Unable to find core component 'childHandler', please check your plugins. issue: ");
|
||||
// Remove the final modifier (unless removed by a fork)
|
||||
int modifiers = field.getModifiers();
|
||||
if (Modifier.isFinal(modifiers)) {
|
||||
try {
|
||||
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
||||
modifiersField.setAccessible(true);
|
||||
modifiersField.setInt(field, modifiers & ~Modifier.FINAL);
|
||||
} catch (NoSuchFieldException e) {
|
||||
// Java 12 compatibility *this is fine*
|
||||
Method getDeclaredFields0 = Class.class.getDeclaredMethod("getDeclaredFields0", boolean.class);
|
||||
getDeclaredFields0.setAccessible(true);
|
||||
Field[] fields = (Field[]) getDeclaredFields0.invoke(Field.class, false);
|
||||
for (Field classField : fields) {
|
||||
if ("modifiers".equals(classField.getName())) {
|
||||
classField.setAccessible(true);
|
||||
classField.set(field, modifiers & ~Modifier.FINAL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BungeeChannelInitializer newInit = new BungeeChannelInitializer((ChannelInitializer<Channel>) field.get(null));
|
||||
field.set(null, newInit);
|
||||
} catch (Exception e) {
|
||||
Via.getPlatform().getLogger().severe("Unable to inject ViaVersion, please post these details on our GitHub and ensure you're using a compatible server version.");
|
||||
throw e;
|
||||
@@ -56,4 +72,26 @@ public class BungeeViaInjector implements ViaInjector {
|
||||
public String getDecoderName() {
|
||||
return "via-decoder";
|
||||
}
|
||||
|
||||
private ChannelInitializer<Channel> getChannelInitializer() throws Exception {
|
||||
Class<?> pipelineUtils = Class.forName("net.md_5.bungee.netty.PipelineUtils");
|
||||
Field field = pipelineUtils.getDeclaredField("SERVER_CHILD");
|
||||
field.setAccessible(true);
|
||||
return (ChannelInitializer<Channel>) field.get(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject getDump() {
|
||||
JsonObject data = new JsonObject();
|
||||
try {
|
||||
ChannelInitializer<Channel> initializer = getChannelInitializer();
|
||||
data.addProperty("currentInitializer", initializer.getClass().getName());
|
||||
if (initializer instanceof BungeeChannelInitializer) {
|
||||
data.addProperty("originalInitializer", ((BungeeChannelInitializer) initializer).getOriginal().getClass().getName());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// Ignored, not printed in the dump
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@@ -1,39 +1,83 @@
|
||||
package us.myles.ViaVersion.bungee.platform;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.plugin.Listener;
|
||||
import net.md_5.bungee.api.scheduler.ScheduledTask;
|
||||
import us.myles.ViaVersion.BungeePlugin;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.platform.ViaPlatformLoader;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
|
||||
import us.myles.ViaVersion.bungee.handlers.BungeeServerHandler;
|
||||
import us.myles.ViaVersion.bungee.listeners.ElytraPatch;
|
||||
import us.myles.ViaVersion.bungee.listeners.UpdateListener;
|
||||
import us.myles.ViaVersion.bungee.providers.BungeeEntityIdProvider;
|
||||
import us.myles.ViaVersion.bungee.providers.BungeeMovementTransmitter;
|
||||
import us.myles.ViaVersion.bungee.providers.BungeeVersionProvider;
|
||||
import us.myles.ViaVersion.bungee.providers.*;
|
||||
import us.myles.ViaVersion.bungee.service.ProtocolDetectorService;
|
||||
import us.myles.ViaVersion.protocols.base.VersionProvider;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.BossBarProvider;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.EntityIdProvider;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.MainHandProvider;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class BungeeViaLoader implements ViaPlatformLoader {
|
||||
private BungeePlugin plugin;
|
||||
private final BungeePlugin plugin;
|
||||
|
||||
private final Set<Listener> listeners = new HashSet<>();
|
||||
private final Set<ScheduledTask> tasks = new HashSet<>();
|
||||
|
||||
public BungeeViaLoader(BungeePlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
private void registerListener(Listener listener) {
|
||||
listeners.add(listener);
|
||||
ProxyServer.getInstance().getPluginManager().registerListener(plugin, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
// Listeners
|
||||
ProxyServer.getInstance().getPluginManager().registerListener(plugin, plugin);
|
||||
ProxyServer.getInstance().getPluginManager().registerListener(plugin, new UpdateListener());
|
||||
ProxyServer.getInstance().getPluginManager().registerListener(plugin, new BungeeServerHandler());
|
||||
registerListener(plugin);
|
||||
registerListener(new UpdateListener());
|
||||
registerListener(new BungeeServerHandler());
|
||||
|
||||
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_9.getVersion()) {
|
||||
registerListener(new ElytraPatch());
|
||||
}
|
||||
|
||||
// Providers
|
||||
Via.getManager().getProviders().use(MovementTransmitterProvider.class, new BungeeMovementTransmitter());
|
||||
Via.getManager().getProviders().use(VersionProvider.class, new BungeeVersionProvider());
|
||||
Via.getManager().getProviders().use(EntityIdProvider.class, new BungeeEntityIdProvider());
|
||||
|
||||
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_9.getVersion()) {
|
||||
Via.getManager().getProviders().use(MovementTransmitterProvider.class, new BungeeMovementTransmitter());
|
||||
Via.getManager().getProviders().use(BossBarProvider.class, new BungeeBossBarProvider());
|
||||
Via.getManager().getProviders().use(MainHandProvider.class, new BungeeMainHandProvider());
|
||||
}
|
||||
|
||||
if (plugin.getConf().getBungeePingInterval() > 0) {
|
||||
plugin.getProxy().getScheduler().schedule(plugin, new ProtocolDetectorService(plugin), 0, plugin.getConf().getBungeePingInterval(), TimeUnit.SECONDS);
|
||||
tasks.add(plugin.getProxy().getScheduler().schedule(
|
||||
plugin,
|
||||
new ProtocolDetectorService(plugin),
|
||||
0, plugin.getConf().getBungeePingInterval(),
|
||||
TimeUnit.SECONDS
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unload() {
|
||||
for (Listener listener : listeners) {
|
||||
ProxyServer.getInstance().getPluginManager().unregisterListener(listener);
|
||||
}
|
||||
listeners.clear();
|
||||
for (ScheduledTask task : tasks) {
|
||||
task.cancel();
|
||||
}
|
||||
tasks.clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package us.myles.ViaVersion.bungee.providers;
|
||||
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.bungee.storage.BungeeStorage;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.BossBarProvider;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class BungeeBossBarProvider extends BossBarProvider {
|
||||
@Override
|
||||
public void handleAdd(UserConnection user, UUID barUUID) {
|
||||
if (user.has(BungeeStorage.class)) {
|
||||
BungeeStorage storage = user.get(BungeeStorage.class);
|
||||
// Check if bossbars are supported by bungee, static maybe
|
||||
if (storage.getBossbar() != null) {
|
||||
storage.getBossbar().add(barUUID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleRemove(UserConnection user, UUID barUUID) {
|
||||
if (user.has(BungeeStorage.class)) {
|
||||
BungeeStorage storage = user.get(BungeeStorage.class);
|
||||
if (storage.getBossbar() != null) {
|
||||
storage.getBossbar().remove(barUUID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package us.myles.ViaVersion.bungee.providers;
|
||||
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.MainHandProvider;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/*
|
||||
This solves the wrong mainhand issue when you join with BungeeCord on a 1.8 server, and switch to a 1.9 or higher.
|
||||
*/
|
||||
public class BungeeMainHandProvider extends MainHandProvider {
|
||||
private static Method getSettings = null;
|
||||
private static Method setMainHand = null;
|
||||
|
||||
static {
|
||||
try {
|
||||
getSettings = Class.forName("net.md_5.bungee.UserConnection").getDeclaredMethod("getSettings");
|
||||
setMainHand = Class.forName("net.md_5.bungee.protocol.packet.ClientSettings").getDeclaredMethod("setMainHand", int.class);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMainHand(UserConnection user, int hand) {
|
||||
ProtocolInfo info = user.getProtocolInfo();
|
||||
if (info == null || info.getUuid() == null) return;
|
||||
ProxiedPlayer player = ProxyServer.getInstance().getPlayer(info.getUuid());
|
||||
if (player == null) return;
|
||||
try {
|
||||
Object settings = getSettings.invoke(player);
|
||||
if (settings != null) {
|
||||
setMainHand.invoke(settings, hand);
|
||||
}
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -5,6 +5,7 @@ import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.packets.State;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9To1_8;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.MovementTracker;
|
||||
|
||||
@@ -20,11 +21,11 @@ public class BungeeMovementTransmitter extends MovementTransmitterProvider {
|
||||
}
|
||||
|
||||
public void sendPlayer(UserConnection userConnection) {
|
||||
if (userConnection.get(ProtocolInfo.class).getState() == State.PLAY) {
|
||||
if (userConnection.getProtocolInfo().getState() == State.PLAY) {
|
||||
PacketWrapper wrapper = new PacketWrapper(0x03, null, userConnection);
|
||||
wrapper.write(Type.BOOLEAN, userConnection.get(MovementTracker.class).isGround());
|
||||
try {
|
||||
wrapper.sendToServer();
|
||||
wrapper.sendToServer(Protocol1_9To1_8.class);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
+14
-6
@@ -4,10 +4,13 @@ import com.google.common.collect.Lists;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.protocols.base.VersionProvider;
|
||||
import us.myles.ViaVersion.util.ReflectionUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class BungeeVersionProvider extends VersionProvider {
|
||||
@@ -28,21 +31,26 @@ public class BungeeVersionProvider extends VersionProvider {
|
||||
return super.getServerProtocol(user);
|
||||
// TODO Have one constant list forever until restart? (Might limit plugins if they change this)
|
||||
List<Integer> list = ReflectionUtil.getStatic(ref, "SUPPORTED_VERSION_IDS", List.class);
|
||||
List<Integer> sorted = new ArrayList<>(list);
|
||||
Collections.sort(sorted);
|
||||
|
||||
ProtocolInfo info = user.get(ProtocolInfo.class);
|
||||
ProtocolInfo info = user.getProtocolInfo();
|
||||
|
||||
// Bungee supports it
|
||||
if (list.contains(info.getProtocolVersion()))
|
||||
if (sorted.contains(info.getProtocolVersion()))
|
||||
return info.getProtocolVersion();
|
||||
|
||||
// Older than bungee supports, get the lowest version
|
||||
if (info.getProtocolVersion() < list.get(0)) {
|
||||
if (info.getProtocolVersion() < sorted.get(0)) {
|
||||
return getLowestSupportedVersion();
|
||||
}
|
||||
|
||||
// Loop through all protocols to get the closest protocol id that bungee supports
|
||||
for (Integer protocol : Lists.reverse(list)) {
|
||||
if (info.getProtocolVersion() > protocol)
|
||||
// Loop through all protocols to get the closest protocol id that bungee supports (and that viaversion does too)
|
||||
|
||||
// TODO: This needs a better fix, i.e checking ProtocolRegistry to see if it would work.
|
||||
// This is more of a workaround for snapshot support by bungee.
|
||||
for (Integer protocol : Lists.reverse(sorted)) {
|
||||
if (info.getProtocolVersion() > protocol && ProtocolVersion.isRegistered(protocol))
|
||||
return protocol;
|
||||
}
|
||||
|
||||
|
||||
+33
-21
@@ -1,12 +1,11 @@
|
||||
package us.myles.ViaVersion.bungee.service;
|
||||
|
||||
import lombok.Getter;
|
||||
import net.md_5.bungee.api.Callback;
|
||||
import net.md_5.bungee.api.ServerPing;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import us.myles.ViaVersion.BungeePlugin;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.bungee.platform.BungeeConfigAPI;
|
||||
import us.myles.ViaVersion.bungee.platform.BungeeViaConfig;
|
||||
import us.myles.ViaVersion.bungee.providers.BungeeVersionProvider;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -15,9 +14,8 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class ProtocolDetectorService implements Runnable {
|
||||
private static final Map<String, Integer> detectedProtocolIds = new ConcurrentHashMap<>();
|
||||
private BungeePlugin plugin;
|
||||
@Getter
|
||||
private static ProtocolDetectorService instance;
|
||||
private final BungeePlugin plugin;
|
||||
|
||||
public ProtocolDetectorService(BungeePlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
@@ -26,17 +24,20 @@ public class ProtocolDetectorService implements Runnable {
|
||||
|
||||
public static Integer getProtocolId(String serverName) {
|
||||
// Step 1. Check Config
|
||||
Map<String, Integer> servers = ((BungeeConfigAPI) Via.getConfig()).getBungeeServerProtocols();
|
||||
if (servers.containsKey(serverName)) {
|
||||
return servers.get(serverName);
|
||||
Map<String, Integer> servers = ((BungeeViaConfig) Via.getConfig()).getBungeeServerProtocols();
|
||||
Integer protocol = servers.get(serverName);
|
||||
if (protocol != null) {
|
||||
return protocol;
|
||||
}
|
||||
// Step 2. Check Detected
|
||||
if (detectedProtocolIds.containsKey(serverName)) {
|
||||
return detectedProtocolIds.get(serverName);
|
||||
Integer detectedProtocol = detectedProtocolIds.get(serverName);
|
||||
if (detectedProtocol != null) {
|
||||
return detectedProtocol;
|
||||
}
|
||||
// Step 3. Use Default
|
||||
if (servers.containsKey("default")) {
|
||||
return servers.get("default");
|
||||
Integer defaultProtocol = servers.get("default");
|
||||
if (defaultProtocol != null) {
|
||||
return defaultProtocol;
|
||||
}
|
||||
// Step 4: Use bungee lowest supported... *cries*
|
||||
return BungeeVersionProvider.getLowestSupportedVersion();
|
||||
@@ -54,19 +55,23 @@ public class ProtocolDetectorService implements Runnable {
|
||||
serverInfo.ping(new Callback<ServerPing>() {
|
||||
@Override
|
||||
public void done(ServerPing serverPing, Throwable throwable) {
|
||||
if (throwable == null) {
|
||||
detectedProtocolIds.put(key, serverPing.getVersion().getProtocol());
|
||||
if (((BungeeConfigAPI) Via.getConfig()).isBungeePingSave()) {
|
||||
Map<String, Integer> servers = ((BungeeConfigAPI) Via.getConfig()).getBungeeServerProtocols();
|
||||
if (servers.containsKey(key)) {
|
||||
if (servers.get(key) == serverPing.getVersion().getProtocol()) {
|
||||
if (throwable == null && serverPing != null && serverPing.getVersion() != null) {
|
||||
// Ensure protocol is positive, some services will return -1
|
||||
if (serverPing.getVersion().getProtocol() > 0) {
|
||||
detectedProtocolIds.put(key, serverPing.getVersion().getProtocol());
|
||||
if (((BungeeViaConfig) Via.getConfig()).isBungeePingSave()) {
|
||||
Map<String, Integer> servers = ((BungeeViaConfig) Via.getConfig()).getBungeeServerProtocols();
|
||||
Integer protocol = servers.get(key);
|
||||
if (protocol != null && protocol == serverPing.getVersion().getProtocol()) {
|
||||
return;
|
||||
}
|
||||
// Ensure we're the only ones writing to the config
|
||||
synchronized (Via.getPlatform().getConfigurationProvider()) {
|
||||
servers.put(key, serverPing.getVersion().getProtocol());
|
||||
}
|
||||
// Save
|
||||
Via.getPlatform().getConfigurationProvider().saveConfig();
|
||||
}
|
||||
// Save Server
|
||||
servers.put(key, serverPing.getVersion().getProtocol());
|
||||
// Save
|
||||
Via.getPlatform().getConfigurationProvider().saveConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,4 +82,11 @@ public class ProtocolDetectorService implements Runnable {
|
||||
return new HashMap<>(detectedProtocolIds);
|
||||
}
|
||||
|
||||
public static ProtocolDetectorService getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public BungeePlugin getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,79 @@
|
||||
package us.myles.ViaVersion.bungee.storage;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import us.myles.ViaVersion.api.data.StoredObject;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BungeeStorage extends StoredObject {
|
||||
private ProxiedPlayer player;
|
||||
private static Field bossField;
|
||||
|
||||
static {
|
||||
try {
|
||||
Class<?> user = Class.forName("net.md_5.bungee.UserConnection");
|
||||
bossField = user.getDeclaredField("sentBossBars");
|
||||
bossField.setAccessible(true);
|
||||
} catch (ClassNotFoundException e) {
|
||||
// Not supported *shrug* probably modified
|
||||
} catch (NoSuchFieldException e) {
|
||||
// Not supported, old version probably
|
||||
}
|
||||
}
|
||||
|
||||
private final ProxiedPlayer player;
|
||||
private String currentServer;
|
||||
private Set<UUID> bossbar;
|
||||
|
||||
public BungeeStorage(UserConnection user, ProxiedPlayer player) {
|
||||
super(user);
|
||||
this.player = player;
|
||||
this.currentServer = "";
|
||||
|
||||
// Get bossbar list if it's supported
|
||||
if (bossField != null) {
|
||||
try {
|
||||
bossbar = (Set<UUID>) bossField.get(player);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ProxiedPlayer getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public String getCurrentServer() {
|
||||
return currentServer;
|
||||
}
|
||||
|
||||
public void setCurrentServer(String currentServer) {
|
||||
this.currentServer = currentServer;
|
||||
}
|
||||
|
||||
public Set<UUID> getBossbar() {
|
||||
return bossbar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
BungeeStorage that = (BungeeStorage) o;
|
||||
if (!Objects.equals(player, that.player)) return false;
|
||||
if (!Objects.equals(currentServer, that.currentServer)) return false;
|
||||
return Objects.equals(bossbar, that.bossbar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = player != null ? player.hashCode() : 0;
|
||||
result = 31 * result + (currentServer != null ? currentServer.hashCode() : 0);
|
||||
result = 31 * result + (bossbar != null ? bossbar.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToByteEncoder;
|
||||
import io.netty.handler.codec.MessageToMessageDecoder;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: ViaVersion
|
||||
main: us.myles.ViaVersion.BungeePlugin
|
||||
description: ${project.description}
|
||||
author: _MylesC, Matsv
|
||||
author: _MylesC, creeper123123321, Gerrygames, KennyTV, Matsv
|
||||
version: ${project.version}
|
||||
+3
-3
@@ -3,9 +3,9 @@ machine:
|
||||
version: oraclejdk8
|
||||
general:
|
||||
artifacts:
|
||||
- "target/*.jar"
|
||||
- "target/*.jar"
|
||||
test:
|
||||
override:
|
||||
- mvn clean install -B
|
||||
- mvn clean install -B
|
||||
post:
|
||||
- cp ./target/*.jar $CIRCLE_ARTIFACTS
|
||||
- cp ./target/*.jar $CIRCLE_ARTIFACTS
|
||||
+7
-8
@@ -5,20 +5,19 @@
|
||||
<parent>
|
||||
<artifactId>viaversion-parent</artifactId>
|
||||
<groupId>us.myles</groupId>
|
||||
<version>1.0.0</version>
|
||||
<version>3.2.0</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>viaversion-common</artifactId>
|
||||
<dependencies>
|
||||
<!-- Snake YAML -->
|
||||
|
||||
<!-- FastUtil for performance increases -->
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
<version>1.18-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
<groupId>it.unimi.dsi</groupId>
|
||||
<artifactId>fastutil</artifactId>
|
||||
<version>8.3.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
</project>
|
||||
@@ -0,0 +1,379 @@
|
||||
package us.myles.ViaVersion;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import us.myles.ViaVersion.api.ViaVersionConfig;
|
||||
import us.myles.ViaVersion.util.Config;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public abstract class AbstractViaConfig extends Config implements ViaVersionConfig {
|
||||
|
||||
private boolean checkForUpdates;
|
||||
private boolean preventCollision;
|
||||
private boolean useNewEffectIndicator;
|
||||
private boolean useNewDeathmessages;
|
||||
private boolean suppressMetadataErrors;
|
||||
private boolean shieldBlocking;
|
||||
private boolean hologramPatch;
|
||||
private boolean pistonAnimationPatch;
|
||||
private boolean bossbarPatch;
|
||||
private boolean bossbarAntiFlicker;
|
||||
private double hologramOffset;
|
||||
private int maxPPS;
|
||||
private String maxPPSKickMessage;
|
||||
private int trackingPeriod;
|
||||
private int warningPPS;
|
||||
private int maxPPSWarnings;
|
||||
private String maxPPSWarningsKickMessage;
|
||||
private boolean sendSupportedVersions;
|
||||
private boolean simulatePlayerTick;
|
||||
private boolean itemCache;
|
||||
private boolean nmsPlayerTicking;
|
||||
private boolean replacePistons;
|
||||
private int pistonReplacementId;
|
||||
private boolean autoTeam;
|
||||
private boolean forceJsonTransform;
|
||||
private boolean nbtArrayFix;
|
||||
private IntSet blockedProtocols;
|
||||
private String blockedDisconnectMessage;
|
||||
private String reloadDisconnectMessage;
|
||||
private boolean suppressConversionWarnings;
|
||||
private boolean disable1_13TabComplete;
|
||||
private boolean minimizeCooldown;
|
||||
private boolean teamColourFix;
|
||||
private boolean serversideBlockConnections;
|
||||
private boolean reduceBlockStorageMemory;
|
||||
private boolean flowerStemWhenBlockAbove;
|
||||
private boolean vineClimbFix;
|
||||
private boolean snowCollisionFix;
|
||||
private boolean infestedBlocksFix;
|
||||
private int tabCompleteDelay;
|
||||
private boolean truncate1_14Books;
|
||||
private boolean leftHandedHandling;
|
||||
private boolean fullBlockLightFix;
|
||||
private boolean healthNaNFix;
|
||||
private boolean instantRespawn;
|
||||
private boolean ignoreLongChannelNames;
|
||||
|
||||
protected AbstractViaConfig(File configFile) {
|
||||
super(configFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadConfig() {
|
||||
super.reloadConfig();
|
||||
loadFields();
|
||||
}
|
||||
|
||||
protected void loadFields() {
|
||||
checkForUpdates = getBoolean("checkforupdates", true);
|
||||
preventCollision = getBoolean("prevent-collision", true);
|
||||
useNewEffectIndicator = getBoolean("use-new-effect-indicator", true);
|
||||
useNewDeathmessages = getBoolean("use-new-deathmessages", true);
|
||||
suppressMetadataErrors = getBoolean("suppress-metadata-errors", false);
|
||||
shieldBlocking = getBoolean("shield-blocking", true);
|
||||
hologramPatch = getBoolean("hologram-patch", false);
|
||||
pistonAnimationPatch = getBoolean("piston-animation-patch", false);
|
||||
bossbarPatch = getBoolean("bossbar-patch", true);
|
||||
bossbarAntiFlicker = getBoolean("bossbar-anti-flicker", false);
|
||||
hologramOffset = getDouble("hologram-y", -0.96D);
|
||||
maxPPS = getInt("max-pps", 800);
|
||||
maxPPSKickMessage = getString("max-pps-kick-msg", "Sending packets too fast? lag?");
|
||||
trackingPeriod = getInt("tracking-period", 6);
|
||||
warningPPS = getInt("tracking-warning-pps", 120);
|
||||
maxPPSWarnings = getInt("tracking-max-warnings", 3);
|
||||
maxPPSWarningsKickMessage = getString("tracking-max-kick-msg", "You are sending too many packets, :(");
|
||||
sendSupportedVersions = getBoolean("send-supported-versions", false);
|
||||
simulatePlayerTick = getBoolean("simulate-pt", true);
|
||||
itemCache = getBoolean("item-cache", true);
|
||||
nmsPlayerTicking = getBoolean("nms-player-ticking", true);
|
||||
replacePistons = getBoolean("replace-pistons", false);
|
||||
pistonReplacementId = getInt("replacement-piston-id", 0);
|
||||
autoTeam = getBoolean("auto-team", true);
|
||||
forceJsonTransform = getBoolean("force-json-transform", false);
|
||||
nbtArrayFix = getBoolean("chat-nbt-fix", true);
|
||||
blockedProtocols = new IntOpenHashSet(getIntegerList("block-protocols"));
|
||||
blockedDisconnectMessage = getString("block-disconnect-msg", "You are using an unsupported Minecraft version!");
|
||||
reloadDisconnectMessage = getString("reload-disconnect-msg", "Server reload, please rejoin!");
|
||||
minimizeCooldown = getBoolean("minimize-cooldown", true);
|
||||
teamColourFix = getBoolean("team-colour-fix", true);
|
||||
suppressConversionWarnings = getBoolean("suppress-conversion-warnings", false);
|
||||
disable1_13TabComplete = getBoolean("disable-1_13-auto-complete", false);
|
||||
serversideBlockConnections = getBoolean("serverside-blockconnections", true);
|
||||
reduceBlockStorageMemory = getBoolean("reduce-blockstorage-memory", false);
|
||||
flowerStemWhenBlockAbove = getBoolean("flowerstem-when-block-above", false);
|
||||
vineClimbFix = getBoolean("vine-climb-fix", false);
|
||||
snowCollisionFix = getBoolean("fix-low-snow-collision", false);
|
||||
infestedBlocksFix = getBoolean("fix-infested-block-breaking", true);
|
||||
tabCompleteDelay = getInt("1_13-tab-complete-delay", 0);
|
||||
truncate1_14Books = getBoolean("truncate-1_14-books", false);
|
||||
leftHandedHandling = getBoolean("left-handed-handling", true);
|
||||
fullBlockLightFix = getBoolean("fix-non-full-blocklight", false);
|
||||
healthNaNFix = getBoolean("fix-1_14-health-nan", true);
|
||||
instantRespawn = getBoolean("use-1_15-instant-respawn", false);
|
||||
ignoreLongChannelNames = getBoolean("ignore-long-1_16-channel-names", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCheckForUpdates() {
|
||||
return checkForUpdates;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCheckForUpdates(boolean checkForUpdates) {
|
||||
this.checkForUpdates = checkForUpdates;
|
||||
set("checkforupdates", checkForUpdates);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPreventCollision() {
|
||||
return preventCollision;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNewEffectIndicator() {
|
||||
return useNewEffectIndicator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShowNewDeathMessages() {
|
||||
return useNewDeathmessages;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuppressMetadataErrors() {
|
||||
return suppressMetadataErrors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShieldBlocking() {
|
||||
return shieldBlocking;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHologramPatch() {
|
||||
return hologramPatch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPistonAnimationPatch() {
|
||||
return pistonAnimationPatch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBossbarPatch() {
|
||||
return bossbarPatch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBossbarAntiflicker() {
|
||||
return bossbarAntiFlicker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getHologramYOffset() {
|
||||
return hologramOffset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxPPS() {
|
||||
return maxPPS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMaxPPSKickMessage() {
|
||||
return maxPPSKickMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTrackingPeriod() {
|
||||
return trackingPeriod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWarningPPS() {
|
||||
return warningPPS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxWarnings() {
|
||||
return maxPPSWarnings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMaxWarningsKickMessage() {
|
||||
return maxPPSWarningsKickMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAntiXRay() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSendSupportedVersions() {
|
||||
return sendSupportedVersions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSimulatePlayerTick() {
|
||||
return simulatePlayerTick;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemCache() {
|
||||
return itemCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNMSPlayerTicking() {
|
||||
return nmsPlayerTicking;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReplacePistons() {
|
||||
return replacePistons;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPistonReplacementId() {
|
||||
return pistonReplacementId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoTeam() {
|
||||
// Collision has to be enabled first
|
||||
return preventCollision && autoTeam;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isForceJsonTransform() {
|
||||
return forceJsonTransform;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is1_12NBTArrayFix() {
|
||||
return nbtArrayFix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is1_12QuickMoveActionFix() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IntSet getBlockedProtocols() {
|
||||
return blockedProtocols;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBlockedDisconnectMsg() {
|
||||
return blockedDisconnectMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReloadDisconnectMsg() {
|
||||
return reloadDisconnectMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMinimizeCooldown() {
|
||||
return minimizeCooldown;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is1_13TeamColourFix() {
|
||||
return teamColourFix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuppressConversionWarnings() {
|
||||
return suppressConversionWarnings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDisable1_13AutoComplete() {
|
||||
return disable1_13TabComplete;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isServersideBlockConnections() {
|
||||
return serversideBlockConnections;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBlockConnectionMethod() {
|
||||
return "packet";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReduceBlockStorageMemory() {
|
||||
return reduceBlockStorageMemory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStemWhenBlockAbove() {
|
||||
return flowerStemWhenBlockAbove;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVineClimbFix() {
|
||||
return vineClimbFix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSnowCollisionFix() {
|
||||
return snowCollisionFix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInfestedBlocksFix() {
|
||||
return infestedBlocksFix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int get1_13TabCompleteDelay() {
|
||||
return tabCompleteDelay;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTruncate1_14Books() {
|
||||
return truncate1_14Books;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLeftHandedHandling() {
|
||||
return leftHandedHandling;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is1_9HitboxFix() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is1_14HitboxFix() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNonFullBlockLightFix() {
|
||||
return fullBlockLightFix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is1_14HealthNaNFix() {
|
||||
return healthNaNFix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is1_15InstantRespawn() {
|
||||
return instantRespawn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIgnoreLong1_16ChannelNames() {
|
||||
return ignoreLongChannelNames;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
package us.myles.ViaVersion;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.platform.TaskId;
|
||||
import us.myles.ViaVersion.api.platform.ViaConnectionManager;
|
||||
import us.myles.ViaVersion.api.platform.ViaInjector;
|
||||
import us.myles.ViaVersion.api.platform.ViaPlatform;
|
||||
import us.myles.ViaVersion.api.platform.ViaPlatformLoader;
|
||||
@@ -11,74 +12,94 @@ import us.myles.ViaVersion.api.platform.providers.ViaProviders;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
|
||||
import us.myles.ViaVersion.commands.ViaCommandHandler;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.TabCompleteThread;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.ViaIdleThread;
|
||||
import us.myles.ViaVersion.update.UpdateUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@Getter
|
||||
public class ViaManager {
|
||||
private final Map<UUID, UserConnection> portedPlayers = new ConcurrentHashMap<>();
|
||||
private ViaPlatform platform;
|
||||
private ViaProviders providers = new ViaProviders();
|
||||
@Setter
|
||||
private boolean debug = false;
|
||||
private final ViaPlatform<?> platform;
|
||||
private final ViaProviders providers = new ViaProviders();
|
||||
// Internals
|
||||
private ViaInjector injector;
|
||||
private ViaCommandHandler commandHandler;
|
||||
private ViaPlatformLoader loader;
|
||||
private final ViaInjector injector;
|
||||
private final ViaCommandHandler commandHandler;
|
||||
private final ViaPlatformLoader loader;
|
||||
private final Set<String> subPlatforms = new HashSet<>();
|
||||
private List<Runnable> enableListeners = new ArrayList<>();
|
||||
private TaskId mappingLoadingTask;
|
||||
private boolean debug;
|
||||
|
||||
@Builder
|
||||
public ViaManager(ViaPlatform platform, ViaInjector injector, ViaCommandHandler commandHandler, ViaPlatformLoader loader) {
|
||||
public ViaManager(ViaPlatform<?> platform, ViaInjector injector, ViaCommandHandler commandHandler, ViaPlatformLoader loader) {
|
||||
this.platform = platform;
|
||||
this.injector = injector;
|
||||
this.commandHandler = commandHandler;
|
||||
this.loader = loader;
|
||||
}
|
||||
|
||||
public static ViaManagerBuilder builder() {
|
||||
return new ViaManagerBuilder();
|
||||
}
|
||||
|
||||
public void init() {
|
||||
if (System.getProperty("ViaVersion") != null) {
|
||||
// Reload?
|
||||
platform.onReload();
|
||||
}
|
||||
// Check for updates
|
||||
if (platform.getConf().isCheckForUpdates())
|
||||
if (platform.getConf().isCheckForUpdates()) {
|
||||
UpdateUtil.sendUpdateMessage();
|
||||
}
|
||||
|
||||
// Force class load
|
||||
ProtocolRegistry.init();
|
||||
|
||||
// Inject
|
||||
try {
|
||||
injector.inject();
|
||||
} catch (Exception e) {
|
||||
getPlatform().getLogger().severe("ViaVersion failed to inject:");
|
||||
platform.getLogger().severe("ViaVersion failed to inject:");
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
// Mark as injected
|
||||
System.setProperty("ViaVersion", getPlatform().getPluginVersion());
|
||||
// If successful
|
||||
platform.runSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
onServerLoaded();
|
||||
}
|
||||
});
|
||||
|
||||
// Mark as injected
|
||||
System.setProperty("ViaVersion", platform.getPluginVersion());
|
||||
|
||||
for (Runnable listener : enableListeners) {
|
||||
listener.run();
|
||||
}
|
||||
enableListeners = null;
|
||||
|
||||
// If successful
|
||||
platform.runSync(this::onServerLoaded);
|
||||
}
|
||||
|
||||
public void onServerLoaded() {
|
||||
// Load Server Protocol
|
||||
try {
|
||||
ProtocolRegistry.SERVER_PROTOCOL = injector.getServerProtocolVersion();
|
||||
ProtocolRegistry.SERVER_PROTOCOL = ProtocolVersion.getProtocol(injector.getServerProtocolVersion()).getVersion();
|
||||
} catch (Exception e) {
|
||||
getPlatform().getLogger().severe("ViaVersion failed to get the server protocol!");
|
||||
platform.getLogger().severe("ViaVersion failed to get the server protocol!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
// Check if there are any pipes to this version
|
||||
if (ProtocolRegistry.SERVER_PROTOCOL != -1) {
|
||||
getPlatform().getLogger().info("ViaVersion detected server version: " + ProtocolVersion.getProtocol(ProtocolRegistry.SERVER_PROTOCOL));
|
||||
if (!ProtocolRegistry.isWorkingPipe()) {
|
||||
getPlatform().getLogger().warning("ViaVersion does not have any compatible versions for this server version, please read our resource page carefully.");
|
||||
platform.getLogger().info("ViaVersion detected server version: " + ProtocolVersion.getProtocol(ProtocolRegistry.SERVER_PROTOCOL));
|
||||
if (!ProtocolRegistry.isWorkingPipe() && !platform.isProxy()) {
|
||||
platform.getLogger().warning("ViaVersion does not have any compatible versions for this server version!");
|
||||
platform.getLogger().warning("Please remember that ViaVersion only adds support for versions newer than the server version.");
|
||||
platform.getLogger().warning("If you need support for older versions you may need to use one or more ViaVersion addons too.");
|
||||
platform.getLogger().warning("In that case please read the ViaVersion resource page carefully or use https://jo0001.github.io/ViaSetup");
|
||||
platform.getLogger().warning("and if you're still unsure, feel free to join our Discord-Server for further assistance.");
|
||||
} else if (ProtocolRegistry.SERVER_PROTOCOL == ProtocolVersion.v1_8.getVersion() && !platform.isProxy()) {
|
||||
platform.getLogger().warning("This version of Minecraft is over half a decade old and support for it will be fully dropped eventually. "
|
||||
+ "Please upgrade to a newer version to avoid encountering bugs and stability issues that have long been fixed.");
|
||||
}
|
||||
}
|
||||
// Load Listeners / Tasks
|
||||
@@ -86,6 +107,23 @@ public class ViaManager {
|
||||
|
||||
// Load Platform
|
||||
loader.load();
|
||||
// Common tasks
|
||||
mappingLoadingTask = Via.getPlatform().runRepeatingSync(() -> {
|
||||
if (ProtocolRegistry.checkForMappingCompletion()) {
|
||||
platform.cancelTask(mappingLoadingTask);
|
||||
mappingLoadingTask = null;
|
||||
}
|
||||
}, 10L);
|
||||
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_9.getVersion()) {
|
||||
if (Via.getConfig().isSimulatePlayerTick()) {
|
||||
Via.getPlatform().runRepeatingSync(new ViaIdleThread(), 1L);
|
||||
}
|
||||
}
|
||||
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_13.getVersion()) {
|
||||
if (Via.getConfig().get1_13TabCompleteDelay() > 0) {
|
||||
Via.getPlatform().runRepeatingSync(new TabCompleteThread(), 1L);
|
||||
}
|
||||
}
|
||||
|
||||
// Refresh Versions
|
||||
ProtocolRegistry.refreshVersions();
|
||||
@@ -93,25 +131,132 @@ public class ViaManager {
|
||||
|
||||
public void destroy() {
|
||||
// Uninject
|
||||
getPlatform().getLogger().info("ViaVersion is disabling, if this is a reload and you experience issues consider rebooting.");
|
||||
platform.getLogger().info("ViaVersion is disabling, if this is a reload and you experience issues consider rebooting.");
|
||||
try {
|
||||
injector.uninject();
|
||||
} catch (Exception e) {
|
||||
getPlatform().getLogger().severe("ViaVersion failed to uninject:");
|
||||
platform.getLogger().severe("ViaVersion failed to uninject:");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// Unload
|
||||
loader.unload();
|
||||
}
|
||||
|
||||
public void addPortedClient(UserConnection info) {
|
||||
portedPlayers.put(info.get(ProtocolInfo.class).getUuid(), info);
|
||||
public Set<UserConnection> getConnections() {
|
||||
return platform.getConnectionManager().getConnections();
|
||||
}
|
||||
|
||||
public void removePortedClient(UUID clientID) {
|
||||
portedPlayers.remove(clientID);
|
||||
/**
|
||||
* @deprecated use getConnectedClients()
|
||||
*/
|
||||
@Deprecated
|
||||
public Map<UUID, UserConnection> getPortedPlayers() {
|
||||
return getConnectedClients();
|
||||
}
|
||||
|
||||
public Map<UUID, UserConnection> getConnectedClients() {
|
||||
return platform.getConnectionManager().getConnectedClients();
|
||||
}
|
||||
|
||||
public UUID getConnectedClientId(UserConnection conn) {
|
||||
return platform.getConnectionManager().getConnectedClientId(conn);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ViaConnectionManager#isClientConnected(UUID)
|
||||
*/
|
||||
public boolean isClientConnected(UUID player) {
|
||||
return platform.getConnectionManager().isClientConnected(player);
|
||||
}
|
||||
|
||||
public void handleLoginSuccess(UserConnection info) {
|
||||
platform.getConnectionManager().onLoginSuccess(info);
|
||||
}
|
||||
|
||||
public ViaPlatform<?> getPlatform() {
|
||||
return platform;
|
||||
}
|
||||
|
||||
public ViaProviders getProviders() {
|
||||
return providers;
|
||||
}
|
||||
|
||||
public boolean isDebug() {
|
||||
return debug;
|
||||
}
|
||||
|
||||
public void setDebug(boolean debug) {
|
||||
this.debug = debug;
|
||||
}
|
||||
|
||||
public ViaInjector getInjector() {
|
||||
return injector;
|
||||
}
|
||||
|
||||
public ViaCommandHandler getCommandHandler() {
|
||||
return commandHandler;
|
||||
}
|
||||
|
||||
public ViaPlatformLoader getLoader() {
|
||||
return loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a mutable set of self-added subplatform version strings.
|
||||
* This set is expanded by the subplatform itself (e.g. ViaBackwards), and may not contain all running ones.
|
||||
*
|
||||
* @return mutable set of subplatform versions
|
||||
*/
|
||||
public Set<String> getSubPlatforms() {
|
||||
return subPlatforms;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ViaConnectionManager#getConnectedClient(UUID)
|
||||
*/
|
||||
@Nullable
|
||||
public UserConnection getConnection(UUID playerUUID) {
|
||||
return portedPlayers.get(playerUUID);
|
||||
return platform.getConnectionManager().getConnectedClient(playerUUID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a runnable to be executed when ViaVersion has finished its init before the full server load.
|
||||
*
|
||||
* @param runnable runnable to be executed
|
||||
*/
|
||||
public void addEnableListener(Runnable runnable) {
|
||||
enableListeners.add(runnable);
|
||||
}
|
||||
|
||||
public static final class ViaManagerBuilder {
|
||||
private ViaPlatform<?> platform;
|
||||
private ViaInjector injector;
|
||||
private ViaCommandHandler commandHandler;
|
||||
private ViaPlatformLoader loader;
|
||||
|
||||
public ViaManagerBuilder platform(ViaPlatform<?> platform) {
|
||||
this.platform = platform;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ViaManagerBuilder injector(ViaInjector injector) {
|
||||
this.injector = injector;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ViaManagerBuilder loader(ViaPlatformLoader loader) {
|
||||
this.loader = loader;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ViaManagerBuilder commandHandler(ViaCommandHandler commandHandler) {
|
||||
this.commandHandler = commandHandler;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ViaManager build() {
|
||||
return new ViaManager(platform, injector, commandHandler, loader);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,34 +2,31 @@ package us.myles.ViaVersion.api;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.protocol.Protocol;
|
||||
import us.myles.ViaVersion.api.remapper.ValueCreator;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.api.type.TypeConverter;
|
||||
import us.myles.ViaVersion.exception.CancelException;
|
||||
import us.myles.ViaVersion.exception.InformativeException;
|
||||
import us.myles.ViaVersion.packets.Direction;
|
||||
import us.myles.ViaVersion.packets.State;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.util.PipelineUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
public class PacketWrapper {
|
||||
public static final int PASSTHROUGH_ID = 1000;
|
||||
private static final Protocol[] PROTOCOL_ARRAY = new Protocol[0];
|
||||
|
||||
private final ByteBuf inputBuffer;
|
||||
private final UserConnection userConnection;
|
||||
private boolean send = true;
|
||||
@Setter
|
||||
@Getter
|
||||
private int id = -1;
|
||||
private final LinkedList<Pair<Type, Object>> readableObjects = new LinkedList<>();
|
||||
private final List<Pair<Type, Object>> packetValues = new ArrayList<>();
|
||||
@@ -47,7 +44,7 @@ public class PacketWrapper {
|
||||
* @param <T> The return type of the type you wish to get.
|
||||
* @param index The index of the part (relative to the type)
|
||||
* @return The requested type or throws ArrayIndexOutOfBounds
|
||||
* @throws Exception If it fails to find it, an exception will be thrown.
|
||||
* @throws InformativeException If it fails to find it, an exception will be thrown.
|
||||
*/
|
||||
public <T> T get(Type<T> type, int index) throws Exception {
|
||||
int currentIndex = 0;
|
||||
@@ -112,7 +109,7 @@ public class PacketWrapper {
|
||||
* @param <T> The return type of the type you wish to set.
|
||||
* @param index The index of the part (relative to the type)
|
||||
* @param value The value of the part you wish to set it to.
|
||||
* @throws Exception If it fails to set it, an exception will be thrown.
|
||||
* @throws InformativeException If it fails to set it, an exception will be thrown.
|
||||
*/
|
||||
public <T> void set(Type<T> type, int index, T value) throws Exception {
|
||||
int currentIndex = 0;
|
||||
@@ -135,7 +132,7 @@ public class PacketWrapper {
|
||||
* @param type The type you wish to read
|
||||
* @param <T> The return type of the type you wish to read.
|
||||
* @return The requested type
|
||||
* @throws Exception If it fails to read
|
||||
* @throws InformativeException If it fails to read
|
||||
*/
|
||||
public <T> T read(Type<T> type) throws Exception {
|
||||
if (type == Type.NOTHING) return null;
|
||||
@@ -149,10 +146,11 @@ public class PacketWrapper {
|
||||
}
|
||||
} else {
|
||||
Pair<Type, Object> read = readableObjects.poll();
|
||||
if (read.getKey().equals(type) || (type.getBaseClass().equals(read.getKey().getBaseClass()) && type.getOutputClass().equals(read.getKey().getOutputClass()))) {
|
||||
Type rtype = read.getKey();
|
||||
if (rtype.equals(type) || (type.getBaseClass().equals(rtype.getBaseClass()) && type.getOutputClass().equals(rtype.getOutputClass()))) {
|
||||
return (T) read.getValue();
|
||||
} else {
|
||||
if (type == Type.NOTHING) {
|
||||
if (rtype == Type.NOTHING) {
|
||||
return read(type); // retry
|
||||
} else {
|
||||
Exception e = new IOException("Unable to read type " + type.getTypeName() + ", found " + read.getKey().getTypeName());
|
||||
@@ -216,13 +214,13 @@ public class PacketWrapper {
|
||||
* Write the current output to a buffer.
|
||||
*
|
||||
* @param buffer The buffer to write to.
|
||||
* @throws Exception Throws an exception if it fails to write a value.
|
||||
* @throws InformativeException Throws an exception if it fails to write a value.
|
||||
*/
|
||||
public void writeToBuffer(ByteBuf buffer) throws Exception {
|
||||
if (id != -1) {
|
||||
Type.VAR_INT.write(buffer, id);
|
||||
Type.VAR_INT.writePrimitive(buffer, id);
|
||||
}
|
||||
if (readableObjects.size() > 0) {
|
||||
if (!readableObjects.isEmpty()) {
|
||||
packetValues.addAll(readableObjects);
|
||||
readableObjects.clear();
|
||||
}
|
||||
@@ -254,8 +252,9 @@ public class PacketWrapper {
|
||||
* Clear the input buffer / readable objects
|
||||
*/
|
||||
public void clearInputBuffer() {
|
||||
if (inputBuffer != null)
|
||||
if (inputBuffer != null) {
|
||||
inputBuffer.clear();
|
||||
}
|
||||
readableObjects.clear(); // :(
|
||||
}
|
||||
|
||||
@@ -278,47 +277,73 @@ public class PacketWrapper {
|
||||
* Be careful not to send packets twice.
|
||||
* (Sends it after current)
|
||||
*
|
||||
* @param packetProtocol - The protocol version of the packet.
|
||||
* @param skipCurrentPipeline - Skip the current pipeline
|
||||
* @param packetProtocol The protocol version of the packet.
|
||||
* @param skipCurrentPipeline Skip the current pipeline
|
||||
* @throws Exception if it fails to write
|
||||
*/
|
||||
public void send(Class<? extends Protocol> packetProtocol, boolean skipCurrentPipeline) throws Exception {
|
||||
send(packetProtocol, skipCurrentPipeline, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send this packet to the associated user.
|
||||
* Be careful not to send packets twice.
|
||||
* (Sends it after current)
|
||||
*
|
||||
* @param packetProtocol The protocol version of the packet.
|
||||
* @param skipCurrentPipeline Skip the current pipeline
|
||||
* @param currentThread Run in the same thread
|
||||
* @throws Exception if it fails to write
|
||||
*/
|
||||
public void send(Class<? extends Protocol> packetProtocol, boolean skipCurrentPipeline, boolean currentThread) throws Exception {
|
||||
if (!isCancelled()) {
|
||||
ByteBuf output = constructPacket(packetProtocol, skipCurrentPipeline);
|
||||
user().sendRawPacket(output);
|
||||
try {
|
||||
ByteBuf output = constructPacket(packetProtocol, skipCurrentPipeline, Direction.OUTGOING);
|
||||
user().sendRawPacket(output, currentThread);
|
||||
} catch (Exception e) {
|
||||
if (!PipelineUtil.containsCause(e, CancelException.class)) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Let the packet go through the protocol pipes and write it to ByteBuf
|
||||
*
|
||||
* @param packetProtocol - The protocol version of the packet.
|
||||
* @param skipCurrentPipeline - Skip the current pipeline
|
||||
* @param packetProtocol The protocol version of the packet.
|
||||
* @param skipCurrentPipeline Skip the current pipeline
|
||||
* @return Packet buffer
|
||||
* @throws Exception if it fails to write
|
||||
*/
|
||||
private ByteBuf constructPacket(Class<? extends Protocol> packetProtocol, boolean skipCurrentPipeline) throws Exception {
|
||||
// Apply current pipeline
|
||||
List<Protocol> protocols = new ArrayList<>(user().get(ProtocolInfo.class).getPipeline().pipes());
|
||||
// Other way if outgoing
|
||||
Collections.reverse(protocols);
|
||||
int index = 0;
|
||||
for (int i = 0; i < protocols.size(); i++) {
|
||||
if (protocols.get(i).getClass().equals(packetProtocol)) {
|
||||
index = skipCurrentPipeline ? (i + 1) : (i);
|
||||
private ByteBuf constructPacket(Class<? extends Protocol> packetProtocol, boolean skipCurrentPipeline, Direction direction) throws Exception {
|
||||
// Apply current pipeline - for outgoing protocol, the collection will be reversed in the apply method
|
||||
Protocol[] protocols = user().getProtocolInfo().getPipeline().pipes().toArray(PROTOCOL_ARRAY);
|
||||
boolean reverse = direction == Direction.OUTGOING;
|
||||
int index = -1;
|
||||
for (int i = 0; i < protocols.length; i++) {
|
||||
if (protocols[i].getClass() == packetProtocol) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index == -1) {
|
||||
// The given protocol is not in the pipeline
|
||||
throw new NoSuchElementException(packetProtocol.getCanonicalName());
|
||||
}
|
||||
|
||||
if (skipCurrentPipeline) {
|
||||
index = reverse ? index - 1 : index + 1;
|
||||
}
|
||||
|
||||
// Reset reader before we start
|
||||
resetReader();
|
||||
|
||||
// Apply other protocols
|
||||
apply(Direction.OUTGOING, user().get(ProtocolInfo.class).getState(), index, protocols);
|
||||
// Send
|
||||
ByteBuf output = inputBuffer == null ? Unpooled.buffer() : inputBuffer.alloc().buffer();
|
||||
apply(direction, user().getProtocolInfo().getState(), index, protocols, reverse);
|
||||
ByteBuf output = inputBuffer == null ? user().getChannel().alloc().buffer() : inputBuffer.alloc().buffer();
|
||||
writeToBuffer(output);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
@@ -327,7 +352,7 @@ public class PacketWrapper {
|
||||
* Be careful not to send packets twice.
|
||||
* (Sends it after current)
|
||||
*
|
||||
* @param packetProtocol - The protocol version of the packet.
|
||||
* @param packetProtocol The protocol version of the packet.
|
||||
* @throws Exception if it fails to write
|
||||
*/
|
||||
public void send(Class<? extends Protocol> packetProtocol) throws Exception {
|
||||
@@ -340,13 +365,13 @@ public class PacketWrapper {
|
||||
* (Sends it after current)
|
||||
* Also returns the packets ChannelFuture
|
||||
*
|
||||
* @param packetProtocol - The protocol version of the packet.
|
||||
* @param packetProtocol The protocol version of the packet.
|
||||
* @return The packets ChannelFuture
|
||||
* @throws Exception if it fails to write
|
||||
*/
|
||||
public ChannelFuture sendFuture(Class<? extends Protocol> packetProtocol) throws Exception {
|
||||
if (!isCancelled()) {
|
||||
ByteBuf output = constructPacket(packetProtocol, true);
|
||||
ByteBuf output = constructPacket(packetProtocol, true, Direction.OUTGOING);
|
||||
return user().sendRawPacketFuture(output);
|
||||
}
|
||||
return user().getChannel().newFailedFuture(new Exception("Cancelled packet"));
|
||||
@@ -364,7 +389,7 @@ public class PacketWrapper {
|
||||
public void send() throws Exception {
|
||||
if (!isCancelled()) {
|
||||
// Send
|
||||
ByteBuf output = inputBuffer == null ? Unpooled.buffer() : inputBuffer.alloc().buffer();
|
||||
ByteBuf output = inputBuffer == null ? user().getChannel().alloc().buffer() : inputBuffer.alloc().buffer();
|
||||
writeToBuffer(output);
|
||||
user().sendRawPacket(output);
|
||||
}
|
||||
@@ -395,22 +420,41 @@ public class PacketWrapper {
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a pipeline from an index to the wrapper
|
||||
* Applies a pipeline from an index to the wrapper.
|
||||
*
|
||||
* @param direction The direction
|
||||
* @param state The state
|
||||
* @param index The index to start from
|
||||
* @param pipeline The pipeline
|
||||
* @param direction protocol direction
|
||||
* @param state protocol state
|
||||
* @param index index to start from, will be reversed depending on the reverse parameter
|
||||
* @param pipeline protocol pipeline
|
||||
* @param reverse whether the array should be looped in reverse, will also reverse the given index
|
||||
* @return The current packetwrapper
|
||||
* @throws Exception If it fails to transform a packet, exception will be thrown
|
||||
*/
|
||||
public PacketWrapper apply(Direction direction, State state, int index, List<Protocol> pipeline) throws Exception {
|
||||
for (int i = index; i < pipeline.size(); i++) { // Copy to prevent from removal.
|
||||
pipeline.get(i).transform(direction, state, this);
|
||||
// Reset the reader for the packetWrapper (So it can be recycled across packets)
|
||||
resetReader();
|
||||
}
|
||||
public PacketWrapper apply(Direction direction, State state, int index, List<Protocol> pipeline, boolean reverse) throws Exception {
|
||||
Protocol[] array = pipeline.toArray(PROTOCOL_ARRAY);
|
||||
return apply(direction, state, reverse ? array.length - 1 : index, array, reverse); // Copy to prevent from removal
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #apply(Direction, State, int, List, boolean)
|
||||
*/
|
||||
public PacketWrapper apply(Direction direction, State state, int index, List<Protocol> pipeline) throws Exception {
|
||||
return apply(direction, state, index, pipeline.toArray(PROTOCOL_ARRAY), false);
|
||||
}
|
||||
|
||||
private PacketWrapper apply(Direction direction, State state, int index, Protocol[] pipeline, boolean reverse) throws Exception {
|
||||
// Reset the reader after every transformation for the packetWrapper, so it can be recycled across packets
|
||||
if (reverse) {
|
||||
for (int i = index; i >= 0; i--) {
|
||||
pipeline[i].transform(direction, state, this);
|
||||
resetReader();
|
||||
}
|
||||
} else {
|
||||
for (int i = index; i < pipeline.length; i++) {
|
||||
pipeline[i].transform(direction, state, this);
|
||||
resetReader();
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -457,15 +501,53 @@ public class PacketWrapper {
|
||||
*
|
||||
* @throws Exception If it failed to write
|
||||
*/
|
||||
@Deprecated
|
||||
public void sendToServer() throws Exception {
|
||||
if (!isCancelled()) {
|
||||
ByteBuf output = inputBuffer == null ? Unpooled.buffer() : inputBuffer.alloc().buffer();
|
||||
ByteBuf output = inputBuffer == null ? user().getChannel().alloc().buffer() : inputBuffer.alloc().buffer();
|
||||
writeToBuffer(output);
|
||||
|
||||
user().getChannel().pipeline().context(Via.getManager().getInjector().getDecoderName()).fireChannelRead(output);
|
||||
user().sendRawPacketToServer(output, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send this packet to the server.
|
||||
*
|
||||
* @param packetProtocol The protocol version of the packet.
|
||||
* @param skipCurrentPipeline Skip the current pipeline
|
||||
* @param currentThread Run in the same thread
|
||||
* @throws Exception if it fails to write
|
||||
*/
|
||||
public void sendToServer(Class<? extends Protocol> packetProtocol, boolean skipCurrentPipeline, boolean currentThread) throws Exception {
|
||||
if (!isCancelled()) {
|
||||
try {
|
||||
ByteBuf output = constructPacket(packetProtocol, skipCurrentPipeline, Direction.INCOMING);
|
||||
user().sendRawPacketToServer(output, currentThread);
|
||||
} catch (Exception e) {
|
||||
if (!PipelineUtil.containsCause(e, CancelException.class)) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void sendToServer(Class<? extends Protocol> packetProtocol, boolean skipCurrentPipeline) throws Exception {
|
||||
sendToServer(packetProtocol, skipCurrentPipeline, false);
|
||||
}
|
||||
|
||||
public void sendToServer(Class<? extends Protocol> packetProtocol) throws Exception {
|
||||
sendToServer(packetProtocol, true);
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PacketWrapper{" +
|
||||
|
||||
@@ -1,23 +1,48 @@
|
||||
package us.myles.ViaVersion.api;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@EqualsAndHashCode
|
||||
public class Pair<X, Y> {
|
||||
private X key;
|
||||
private final X key;
|
||||
private Y value;
|
||||
|
||||
public Pair(X key, Y value) {
|
||||
public Pair(@Nullable X key, @Nullable Y value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public X getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public Y getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(@Nullable Y value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Pair{" + key + ", " + value + '}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Pair<?, ?> pair = (Pair<?, ?>) o;
|
||||
if (!Objects.equals(key, pair.key)) return false;
|
||||
return Objects.equals(value, pair.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = key != null ? key.hashCode() : 0;
|
||||
result = 31 * result + (value != null ? value.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package us.myles.ViaVersion.api;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class Triple<A, B, C> {
|
||||
private final A first;
|
||||
private final B second;
|
||||
private final C third;
|
||||
|
||||
public Triple(@Nullable A first, @Nullable B second, @Nullable C third) {
|
||||
this.first = first;
|
||||
this.second = second;
|
||||
this.third = third;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public A getFirst() {
|
||||
return first;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public B getSecond() {
|
||||
return second;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public C getThird() {
|
||||
return third;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Triple{" + first + ", " + second + ", " + third + '}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Triple<?, ?, ?> triple = (Triple<?, ?, ?>) o;
|
||||
if (!Objects.equals(first, triple.first)) return false;
|
||||
if (!Objects.equals(second, triple.second)) return false;
|
||||
return Objects.equals(third, triple.third);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = first != null ? first.hashCode() : 0;
|
||||
result = 31 * result + (second != null ? second.hashCode() : 0);
|
||||
result = 31 * result + (third != null ? third.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,11 @@
|
||||
package us.myles.ViaVersion.api;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import lombok.Getter;
|
||||
import us.myles.ViaVersion.ViaManager;
|
||||
import us.myles.ViaVersion.api.platform.ViaPlatform;
|
||||
|
||||
public class Via {
|
||||
@Getter
|
||||
private static ViaPlatform platform;
|
||||
@Getter
|
||||
private static ViaManager manager;
|
||||
|
||||
/**
|
||||
@@ -42,4 +39,12 @@ public class Via {
|
||||
Preconditions.checkArgument(platform != null, "ViaVersion has not loaded the Platform");
|
||||
return Via.platform.getConf();
|
||||
}
|
||||
|
||||
public static ViaPlatform getPlatform() {
|
||||
return platform;
|
||||
}
|
||||
|
||||
public static ViaManager getManager() {
|
||||
return manager;
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import java.util.UUID;
|
||||
* @param <T> The player type for the specific platform, for bukkit it's {@code ViaAPI<Player>}
|
||||
*/
|
||||
public interface ViaAPI<T> {
|
||||
|
||||
/**
|
||||
* Get protocol number from a player
|
||||
* Will also retrieve version from ProtocolSupport if it's being used.
|
||||
@@ -33,14 +34,25 @@ public interface ViaAPI<T> {
|
||||
int getPlayerVersion(UUID uuid);
|
||||
|
||||
/**
|
||||
* Is player using 1.9?
|
||||
* Returns if the player is ported by Via.
|
||||
*
|
||||
* @param playerUUID UUID of a player
|
||||
* @return True if the client is on 1.9
|
||||
* @deprecated As of 0.9.9, because all players are ported use {@link #getPlayerVersion(UUID)}
|
||||
* @return true if Via has a cached userconnection for this player
|
||||
* @deprecated use {@link #isInjected(UUID)}
|
||||
* @see #isInjected(UUID)
|
||||
*/
|
||||
@Deprecated
|
||||
boolean isPorted(UUID playerUUID);
|
||||
default boolean isPorted(UUID playerUUID) {
|
||||
return isInjected(playerUUID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if Via injected into this player connection
|
||||
*
|
||||
* @param playerUUID UUID of a player
|
||||
* @return true if Via has a cached UserConnection for this player
|
||||
*/
|
||||
boolean isInjected(UUID playerUUID);
|
||||
|
||||
/**
|
||||
* Get the version of the plugin
|
||||
@@ -54,18 +66,18 @@ public interface ViaAPI<T> {
|
||||
*
|
||||
* @param player Platform player object, eg. Bukkit this is Player
|
||||
* @param packet The packet, you need a VarInt ID then the packet contents.
|
||||
* @throws IllegalArgumentException If not on 1.9 throws IllegalArg
|
||||
* @throws IllegalArgumentException if the player is not injected by Via
|
||||
*/
|
||||
void sendRawPacket(T player, ByteBuf packet) throws IllegalArgumentException;
|
||||
void sendRawPacket(T player, ByteBuf packet);
|
||||
|
||||
/**
|
||||
* Send a raw packet to the player (Use new IDs)
|
||||
*
|
||||
* @param uuid The uuid from the player to send packet
|
||||
* @param packet The packet, you need a VarInt ID then the packet contents.
|
||||
* @throws IllegalArgumentException If not on 1.9 throws IllegalArg
|
||||
* @throws IllegalArgumentException if the player is not injected by Via
|
||||
*/
|
||||
void sendRawPacket(UUID uuid, ByteBuf packet) throws IllegalArgumentException;
|
||||
void sendRawPacket(UUID uuid, ByteBuf packet);
|
||||
|
||||
/**
|
||||
* Create a new bossbar instance
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
package us.myles.ViaVersion.api;
|
||||
|
||||
import lombok.*;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.protocol.Protocol;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Getter(AccessLevel.PROTECTED)
|
||||
@Setter(AccessLevel.PROTECTED)
|
||||
@RequiredArgsConstructor
|
||||
public abstract class ViaListener {
|
||||
private final Class<? extends Protocol> requiredPipeline;
|
||||
private boolean registered = false;
|
||||
private boolean registered;
|
||||
|
||||
public ViaListener(Class<? extends Protocol> requiredPipeline) {
|
||||
this.requiredPipeline = requiredPipeline;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the UserConnection from an UUID
|
||||
@@ -20,7 +21,8 @@ public abstract class ViaListener {
|
||||
* @param uuid UUID object
|
||||
* @return The UserConnection
|
||||
*/
|
||||
protected UserConnection getUserConnection(@NonNull UUID uuid) {
|
||||
@Nullable
|
||||
protected UserConnection getUserConnection(UUID uuid) {
|
||||
return Via.getManager().getConnection(uuid);
|
||||
}
|
||||
|
||||
@@ -33,11 +35,23 @@ public abstract class ViaListener {
|
||||
protected boolean isOnPipe(UUID uuid) {
|
||||
UserConnection userConnection = getUserConnection(uuid);
|
||||
return userConnection != null &&
|
||||
userConnection.get(ProtocolInfo.class).getPipeline().contains(requiredPipeline);
|
||||
(requiredPipeline == null || userConnection.getProtocolInfo().getPipeline().contains(requiredPipeline));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the event
|
||||
*/
|
||||
public abstract void register();
|
||||
|
||||
protected Class<? extends Protocol> getRequiredPipeline() {
|
||||
return requiredPipeline;
|
||||
}
|
||||
|
||||
protected boolean isRegistered() {
|
||||
return registered;
|
||||
}
|
||||
|
||||
protected void setRegistered(boolean registered) {
|
||||
this.registered = registered;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package us.myles.ViaVersion.api;
|
||||
|
||||
import java.util.List;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
|
||||
public interface ViaVersionConfig {
|
||||
|
||||
@@ -11,6 +11,14 @@ public interface ViaVersionConfig {
|
||||
*/
|
||||
boolean isCheckForUpdates();
|
||||
|
||||
/**
|
||||
* Sets whether to check for updates. This updates the internally cached value
|
||||
* as well as the config, but does not save the config to disk.
|
||||
*
|
||||
* @param checkForUpdates true to check for updates on server start and joins
|
||||
*/
|
||||
void setCheckForUpdates(boolean checkForUpdates);
|
||||
|
||||
/**
|
||||
* Get if collision preventing for players is enabled
|
||||
*
|
||||
@@ -53,6 +61,13 @@ public interface ViaVersionConfig {
|
||||
*/
|
||||
boolean isHologramPatch();
|
||||
|
||||
/**
|
||||
* Get if the 1.11 piston animation patch is enabled
|
||||
*
|
||||
* @return true if the piston patch is enabled.
|
||||
*/
|
||||
boolean isPistonAnimationPatch();
|
||||
|
||||
/**
|
||||
* Get if boss bars are fixed for 1.9 & 1.10 clients
|
||||
*
|
||||
@@ -68,14 +83,6 @@ public interface ViaVersionConfig {
|
||||
*/
|
||||
boolean isBossbarAntiflicker();
|
||||
|
||||
/**
|
||||
* Get if unknown entity errors will be suppressed
|
||||
*
|
||||
* @return true if boss bar patching is enabled
|
||||
*/
|
||||
@Deprecated
|
||||
boolean isUnknownEntitiesSuppressed();
|
||||
|
||||
/**
|
||||
* Get the vertical offset armor stands are being moved with when the hologram patch is enabled
|
||||
*
|
||||
@@ -90,14 +97,6 @@ public interface ViaVersionConfig {
|
||||
*/
|
||||
boolean isAutoTeam();
|
||||
|
||||
/**
|
||||
* Get if our block break patch is enabled to prevent weird ghost glitches.
|
||||
*
|
||||
* @return true if it is enabled.
|
||||
*/
|
||||
@Deprecated
|
||||
boolean isBlockBreakPatch();
|
||||
|
||||
/**
|
||||
* Get the maximum number of packets a client can send per second.
|
||||
*
|
||||
@@ -159,7 +158,7 @@ public interface ViaVersionConfig {
|
||||
*
|
||||
* @return if true, enabled
|
||||
*/
|
||||
boolean isStimulatePlayerTick();
|
||||
boolean isSimulatePlayerTick();
|
||||
|
||||
/**
|
||||
* Use the item cache to prevent high resource usage
|
||||
@@ -178,7 +177,7 @@ public interface ViaVersionConfig {
|
||||
/**
|
||||
* Replace extended pistons on 1.10 chunk loading.
|
||||
*
|
||||
* @return True if to replace them
|
||||
* @return true if to replace them
|
||||
*/
|
||||
boolean isReplacePistons();
|
||||
|
||||
@@ -192,16 +191,37 @@ public interface ViaVersionConfig {
|
||||
/**
|
||||
* Force json transform
|
||||
*
|
||||
* @return True if enabled
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean isForceJsonTransform();
|
||||
|
||||
/**
|
||||
* Should we fix nbt array's in json chat messages for 1.12 clients
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean is1_12NBTArrayFix();
|
||||
|
||||
/**
|
||||
* Should we make team colours based on the last colour in team prefix
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean is1_13TeamColourFix();
|
||||
|
||||
/**
|
||||
* Should we fix shift quick move action for 1.12 clients
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean is1_12QuickMoveActionFix();
|
||||
|
||||
/**
|
||||
* Get the blocked protocols
|
||||
*
|
||||
* @return An Integer list
|
||||
*/
|
||||
List<Integer> getBlockedProtocols();
|
||||
IntSet getBlockedProtocols();
|
||||
|
||||
/**
|
||||
* Get the custom disconnect message
|
||||
@@ -217,4 +237,133 @@ public interface ViaVersionConfig {
|
||||
* @return Disconnect message
|
||||
*/
|
||||
String getReloadDisconnectMsg();
|
||||
|
||||
/**
|
||||
* Should we hide errors that occur when trying to convert block and item data over versions?
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean isSuppressConversionWarnings();
|
||||
|
||||
/**
|
||||
* Should we disable the 1.13 auto-complete feature to stop spam kicks? (for any server lower than 1.13)
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean isDisable1_13AutoComplete();
|
||||
|
||||
/**
|
||||
* Tries to minimize cooldown animation.
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean isMinimizeCooldown();
|
||||
|
||||
/**
|
||||
* Enable the serverside blockconnections for 1.13+ clients
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean isServersideBlockConnections();
|
||||
|
||||
/**
|
||||
* Get the type of block-connection provider which should be used
|
||||
*
|
||||
* @return String world for world-level or packet for packet-level
|
||||
*/
|
||||
String getBlockConnectionMethod();
|
||||
|
||||
/**
|
||||
* When activated, only the most important blocks are saved in the BlockStorage.
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean isReduceBlockStorageMemory();
|
||||
|
||||
/**
|
||||
* When activated with serverside-blockconnections, flower parts with blocks above will be sent as stems.
|
||||
* Useful for lobbyservers where users can't build and those stems are used decoratively.
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean isStemWhenBlockAbove();
|
||||
|
||||
/**
|
||||
* Vines not connected to any blocks will be mapped to air for 1.13+ clients to prevent them from climbing up.
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean isVineClimbFix();
|
||||
|
||||
/**
|
||||
* When activated, the 1-layer snow will be sent as 2-layer snow to 1.13+ clients to have collision.
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean isSnowCollisionFix();
|
||||
|
||||
/**
|
||||
* When activated, infested blocks will be mapped to their normal stone variants for 1.13+ clients.
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean isInfestedBlocksFix();
|
||||
|
||||
/**
|
||||
* When greater than 0, enables tab complete request delaying by x ticks
|
||||
*
|
||||
* @return the delay in ticks
|
||||
*/
|
||||
int get1_13TabCompleteDelay();
|
||||
|
||||
/**
|
||||
* When activated, edited books with more than 50 pages will be shortened to 50.
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean isTruncate1_14Books();
|
||||
|
||||
/**
|
||||
* Handles left handed info by using unused bit 7 on Client Settings packet
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean isLeftHandedHandling();
|
||||
|
||||
/**
|
||||
* Fixes velocity bugs due to different hitbox for 1.9-1.13 clients on 1.8 servers.
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean is1_9HitboxFix();
|
||||
|
||||
/**
|
||||
* Fixes velocity bugs due to different hitbox for 1.14+ clients on sub 1.14 servers.
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean is1_14HitboxFix();
|
||||
|
||||
/**
|
||||
* Fixes non full blocks having 0 light for 1.14+ clients on sub 1.14 servers.
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean isNonFullBlockLightFix();
|
||||
|
||||
boolean is1_14HealthNaNFix();
|
||||
|
||||
/**
|
||||
* Should 1.15 clients respawn instantly / without showing the death screen.
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean is1_15InstantRespawn();
|
||||
|
||||
/**
|
||||
* Ignores incoming plugin channel messages of 1.16+ clients with channel names longer than 32 charatcers.
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean isIgnoreLong1_16ChannelNames();
|
||||
}
|
||||
@@ -1,11 +1,13 @@
|
||||
package us.myles.ViaVersion.api.boss;
|
||||
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class BossBar<T> {
|
||||
|
||||
/**
|
||||
* Get the current title
|
||||
*
|
||||
@@ -79,13 +81,21 @@ public abstract class BossBar<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the bossbar to a player (uuid)
|
||||
* Show the bossbar to a player (uuid). This only works for frontend connections. Use #addConnection(UserConnection) for other types.
|
||||
*
|
||||
* @param player uuid of the player
|
||||
* @return The BossBar object
|
||||
*/
|
||||
public abstract BossBar addPlayer(UUID player);
|
||||
|
||||
/**
|
||||
* Show the bossbar to a player connection.
|
||||
*
|
||||
* @param conn UserConnection of the connection
|
||||
* @return The BossBar object
|
||||
*/
|
||||
public abstract BossBar addConnection(UserConnection conn);
|
||||
|
||||
/**
|
||||
* add multiple players
|
||||
*
|
||||
@@ -111,13 +121,21 @@ public abstract class BossBar<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the bossbar from a player
|
||||
* Removes the bossbar from a player. This only works for frontend connections. For others types, use #removeConnection(UserConnection)
|
||||
*
|
||||
* @param uuid The platers YYUD
|
||||
* @param uuid The players UUID
|
||||
* @return The BossBar object
|
||||
*/
|
||||
public abstract BossBar removePlayer(UUID uuid);
|
||||
|
||||
/**
|
||||
* Removes the bossbar from a player connection.
|
||||
*
|
||||
* @param conn The UserConnection
|
||||
* @return The BossBar object
|
||||
*/
|
||||
public abstract BossBar removeConnection(UserConnection conn);
|
||||
|
||||
/**
|
||||
* Add flags
|
||||
*
|
||||
@@ -141,12 +159,19 @@ public abstract class BossBar<T> {
|
||||
public abstract boolean hasFlag(BossFlag flag);
|
||||
|
||||
/**
|
||||
* Get players
|
||||
* Get players. Only returns UUIDs which are front-end. For all connections, use #getConnections()
|
||||
*
|
||||
* @return UUIDS from players (sorry I lied)
|
||||
*/
|
||||
public abstract Set<UUID> getPlayers();
|
||||
|
||||
/**
|
||||
* Get UserConnections.
|
||||
*
|
||||
* @return UserConnection from players
|
||||
*/
|
||||
public abstract Set<UserConnection> getConnections();
|
||||
|
||||
/**
|
||||
* Show the bossbar to everyone (In the getPlayer set)
|
||||
*
|
||||
@@ -167,4 +192,11 @@ public abstract class BossBar<T> {
|
||||
* @return visibility changable with show() and hide()
|
||||
*/
|
||||
public abstract boolean isVisible();
|
||||
|
||||
/**
|
||||
* Get the UUID of this bossbar
|
||||
*
|
||||
* @return Unique Id for this bossbar
|
||||
*/
|
||||
public abstract UUID getId();
|
||||
}
|
||||
@@ -1,11 +1,7 @@
|
||||
package us.myles.ViaVersion.api.boss;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
public enum BossColor {
|
||||
|
||||
PINK(0),
|
||||
BLUE(1),
|
||||
RED(2),
|
||||
@@ -15,4 +11,12 @@ public enum BossColor {
|
||||
WHITE(6);
|
||||
|
||||
private final int id;
|
||||
|
||||
BossColor(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,17 @@
|
||||
package us.myles.ViaVersion.api.boss;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
public enum BossFlag {
|
||||
|
||||
DARKEN_SKY(1),
|
||||
PLAY_BOSS_MUSIC(2);
|
||||
|
||||
private final int id;
|
||||
|
||||
BossFlag(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,7 @@
|
||||
package us.myles.ViaVersion.api.boss;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
public enum BossStyle {
|
||||
|
||||
SOLID(0),
|
||||
SEGMENTED_6(1),
|
||||
SEGMENTED_10(2),
|
||||
@@ -13,4 +9,12 @@ public enum BossStyle {
|
||||
SEGMENTED_20(4);
|
||||
|
||||
private final int id;
|
||||
|
||||
BossStyle(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package us.myles.ViaVersion.api.command;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ViaVersionCommand {
|
||||
@@ -25,6 +27,7 @@ public interface ViaVersionCommand {
|
||||
* @param name subcommand name
|
||||
* @return ViaSubCommand instance
|
||||
*/
|
||||
@Nullable
|
||||
ViaSubCommand getSubCommand(String name);
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package us.myles.ViaVersion.api.data;
|
||||
|
||||
public interface ExternalJoinGameListener {
|
||||
|
||||
void onExternalJoinGame(int playerEntityId);
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
package us.myles.ViaVersion.api.data;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.util.Int2IntBiMap;
|
||||
|
||||
public class MappingData {
|
||||
protected final String oldVersion;
|
||||
protected final String newVersion;
|
||||
protected final boolean hasDiffFile;
|
||||
protected Int2IntBiMap itemMappings;
|
||||
protected ParticleMappings particleMappings;
|
||||
protected Mappings blockMappings;
|
||||
protected Mappings blockStateMappings;
|
||||
protected Mappings soundMappings;
|
||||
protected Mappings statisticsMappings;
|
||||
protected boolean loadItems = true;
|
||||
|
||||
public MappingData(String oldVersion, String newVersion) {
|
||||
this(oldVersion, newVersion, false);
|
||||
}
|
||||
|
||||
public MappingData(String oldVersion, String newVersion, boolean hasDiffFile) {
|
||||
this.oldVersion = oldVersion;
|
||||
this.newVersion = newVersion;
|
||||
this.hasDiffFile = hasDiffFile;
|
||||
}
|
||||
|
||||
public void load() {
|
||||
Via.getPlatform().getLogger().info("Loading " + oldVersion + " -> " + newVersion + " mappings...");
|
||||
JsonObject diffmapping = hasDiffFile ? loadDiffFile() : null;
|
||||
JsonObject oldMappings = MappingDataLoader.loadData("mapping-" + oldVersion + ".json", true);
|
||||
JsonObject newMappings = MappingDataLoader.loadData("mapping-" + newVersion + ".json", true);
|
||||
|
||||
blockMappings = loadFromObject(oldMappings, newMappings, diffmapping, "blocks");
|
||||
blockStateMappings = loadFromObject(oldMappings, newMappings, diffmapping, "blockstates");
|
||||
soundMappings = loadFromArray(oldMappings, newMappings, diffmapping, "sounds");
|
||||
statisticsMappings = loadFromArray(oldMappings, newMappings, diffmapping, "statistics");
|
||||
|
||||
Mappings particles = loadFromArray(oldMappings, newMappings, diffmapping, "particles");
|
||||
if (particles != null) {
|
||||
particleMappings = new ParticleMappings(oldMappings.getAsJsonArray("particles"), particles);
|
||||
}
|
||||
|
||||
if (loadItems && newMappings.has("items")) {
|
||||
itemMappings = new Int2IntBiMap();
|
||||
itemMappings.defaultReturnValue(-1);
|
||||
MappingDataLoader.mapIdentifiers(itemMappings, oldMappings.getAsJsonObject("items"), newMappings.getAsJsonObject("items"),
|
||||
diffmapping != null ? diffmapping.getAsJsonObject("items") : null);
|
||||
}
|
||||
|
||||
loadExtras(oldMappings, newMappings, diffmapping);
|
||||
}
|
||||
|
||||
public int getNewBlockStateId(int id) {
|
||||
return checkValidity(id, blockStateMappings.getNewId(id), "blockstate");
|
||||
}
|
||||
|
||||
public int getNewBlockId(int id) {
|
||||
return checkValidity(id, blockMappings.getNewId(id), "block");
|
||||
}
|
||||
|
||||
public int getNewItemId(int id) {
|
||||
return checkValidity(id, itemMappings.get(id), "item");
|
||||
}
|
||||
|
||||
public int getOldItemId(int id) {
|
||||
int oldId = itemMappings.inverse().get(id);
|
||||
// Remap new items to stone
|
||||
return oldId != -1 ? oldId : 1;
|
||||
}
|
||||
|
||||
public int getNewParticleId(int id) {
|
||||
return checkValidity(id, particleMappings.getMappings().getNewId(id), "particles");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Int2IntBiMap getItemMappings() {
|
||||
return itemMappings;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ParticleMappings getParticleMappings() {
|
||||
return particleMappings;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Mappings getBlockMappings() {
|
||||
return blockMappings;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Mappings getBlockStateMappings() {
|
||||
return blockStateMappings;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Mappings getSoundMappings() {
|
||||
return soundMappings;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Mappings getStatisticsMappings() {
|
||||
return statisticsMappings;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected Mappings loadFromArray(JsonObject oldMappings, JsonObject newMappings, @Nullable JsonObject diffMappings, String key) {
|
||||
if (!oldMappings.has(key) || !newMappings.has(key)) return null;
|
||||
|
||||
JsonObject diff = diffMappings != null ? diffMappings.getAsJsonObject(key) : null;
|
||||
return new Mappings(oldMappings.getAsJsonArray(key), newMappings.getAsJsonArray(key), diff);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected Mappings loadFromObject(JsonObject oldMappings, JsonObject newMappings, @Nullable JsonObject diffMappings, String key) {
|
||||
if (!oldMappings.has(key) || !newMappings.has(key)) return null;
|
||||
|
||||
JsonObject diff = diffMappings != null ? diffMappings.getAsJsonObject(key) : null;
|
||||
return new Mappings(oldMappings.getAsJsonObject(key), newMappings.getAsJsonObject(key), diff);
|
||||
}
|
||||
|
||||
protected JsonObject loadDiffFile() {
|
||||
return MappingDataLoader.loadData("mappingdiff-" + oldVersion + "to" + newVersion + ".json");
|
||||
}
|
||||
|
||||
protected int checkValidity(int id, int mappedId, String type) {
|
||||
if (mappedId == -1) {
|
||||
Via.getPlatform().getLogger().warning(String.format("Missing %s %s for %s %s %d", newVersion, type, oldVersion, type, id));
|
||||
return 0;
|
||||
}
|
||||
return mappedId;
|
||||
}
|
||||
|
||||
/**
|
||||
* To be overridden.
|
||||
*
|
||||
* @param oldMappings old mappings
|
||||
* @param newMappings new mappings
|
||||
* @param diffMappings diff mappings if present
|
||||
*/
|
||||
protected void loadExtras(JsonObject oldMappings, JsonObject newMappings, @Nullable JsonObject diffMappings) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
package us.myles.ViaVersion.api.data;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonIOException;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.util.GsonUtil;
|
||||
import us.myles.ViaVersion.util.Int2IntBiMap;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class MappingDataLoader {
|
||||
|
||||
private static final Map<String, JsonObject> MAPPINGS_CACHE = new ConcurrentHashMap<>();
|
||||
private static boolean cacheJsonMappings;
|
||||
|
||||
/**
|
||||
* Returns true if a selected number of mappings should be cached.
|
||||
* If enabled, cleanup should be done after the cache is no longer needed.
|
||||
*
|
||||
* @return true if mappings should be cached
|
||||
*/
|
||||
public static boolean isCacheJsonMappings() {
|
||||
return cacheJsonMappings;
|
||||
}
|
||||
|
||||
public static void enableMappingsCache() {
|
||||
cacheJsonMappings = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cached mappings. Cleared after Via has been fully loaded.
|
||||
*
|
||||
* @see #isCacheJsonMappings()
|
||||
*/
|
||||
public static Map<String, JsonObject> getMappingsCache() {
|
||||
return MAPPINGS_CACHE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the file from the plugin folder if present, else from the bundled resources.
|
||||
*/
|
||||
@Nullable
|
||||
public static JsonObject loadFromDataDir(String name) {
|
||||
File file = new File(Via.getPlatform().getDataFolder(), name);
|
||||
if (!file.exists()) return loadData(name);
|
||||
|
||||
// Load the file from the platform's directory if present
|
||||
try (FileReader reader = new FileReader(file)) {
|
||||
return GsonUtil.getGson().fromJson(reader, JsonObject.class);
|
||||
} catch (JsonSyntaxException e) {
|
||||
// Users might mess up the format, so let's catch the syntax error
|
||||
Via.getPlatform().getLogger().warning(name + " is badly formatted!");
|
||||
e.printStackTrace();
|
||||
} catch (IOException | JsonIOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the file from the bundled resources. Uses the cache if enabled.
|
||||
*/
|
||||
@Nullable
|
||||
public static JsonObject loadData(String name) {
|
||||
return loadData(name, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the file from the bundled resources. Uses the cache if enabled.
|
||||
*
|
||||
* @param cacheIfEnabled whether loaded files should be cached
|
||||
*/
|
||||
@Nullable
|
||||
public static JsonObject loadData(String name, boolean cacheIfEnabled) {
|
||||
if (cacheJsonMappings) {
|
||||
JsonObject cached = MAPPINGS_CACHE.get(name);
|
||||
if (cached != null) {
|
||||
return cached;
|
||||
}
|
||||
}
|
||||
|
||||
InputStream stream = getResource(name);
|
||||
if (stream == null) return null;
|
||||
|
||||
InputStreamReader reader = new InputStreamReader(stream);
|
||||
try {
|
||||
JsonObject object = GsonUtil.getGson().fromJson(reader, JsonObject.class);
|
||||
if (cacheIfEnabled && cacheJsonMappings) {
|
||||
MAPPINGS_CACHE.put(name, object);
|
||||
}
|
||||
return object;
|
||||
} finally {
|
||||
try {
|
||||
reader.close();
|
||||
} catch (IOException ignored) {
|
||||
// Ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void mapIdentifiers(Int2IntBiMap output, JsonObject oldIdentifiers, JsonObject newIdentifiers, @Nullable JsonObject diffIdentifiers) {
|
||||
Object2IntMap<String> newIdentifierMap = MappingDataLoader.indexedObjectToMap(newIdentifiers);
|
||||
for (Map.Entry<String, JsonElement> entry : oldIdentifiers.entrySet()) {
|
||||
int value = mapIdentifierEntry(entry, newIdentifierMap, diffIdentifiers);
|
||||
if (value != -1) {
|
||||
output.put(Integer.parseInt(entry.getKey()), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void mapIdentifiers(short[] output, JsonObject oldIdentifiers, JsonObject newIdentifiers) {
|
||||
MappingDataLoader.mapIdentifiers(output, oldIdentifiers, newIdentifiers, null);
|
||||
}
|
||||
|
||||
public static void mapIdentifiers(short[] output, JsonObject oldIdentifiers, JsonObject newIdentifiers, @Nullable JsonObject diffIdentifiers) {
|
||||
Object2IntMap newIdentifierMap = MappingDataLoader.indexedObjectToMap(newIdentifiers);
|
||||
for (Map.Entry<String, JsonElement> entry : oldIdentifiers.entrySet()) {
|
||||
int value = mapIdentifierEntry(entry, newIdentifierMap, diffIdentifiers);
|
||||
if (value != -1) {
|
||||
output[Integer.parseInt(entry.getKey())] = (short) value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static int mapIdentifierEntry(Map.Entry<String, JsonElement> entry, Object2IntMap newIdentifierMap, @Nullable JsonObject diffIdentifiers) {
|
||||
int value = newIdentifierMap.getInt(entry.getValue().getAsString());
|
||||
if (value == -1) {
|
||||
// Search in diff mappings
|
||||
if (diffIdentifiers != null) {
|
||||
JsonElement diffElement = diffIdentifiers.get(entry.getKey());
|
||||
if (diffElement != null) {
|
||||
value = newIdentifierMap.getInt(diffElement.getAsString());
|
||||
}
|
||||
}
|
||||
if (value == -1) {
|
||||
if (!Via.getConfig().isSuppressConversionWarnings() || Via.getManager().isDebug()) {
|
||||
Via.getPlatform().getLogger().warning("No key for " + entry.getValue() + " :( ");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static void mapIdentifiers(short[] output, JsonArray oldIdentifiers, JsonArray newIdentifiers, boolean warnOnMissing) {
|
||||
mapIdentifiers(output, oldIdentifiers, newIdentifiers, null, warnOnMissing);
|
||||
}
|
||||
|
||||
public static void mapIdentifiers(short[] output, JsonArray oldIdentifiers, JsonArray newIdentifiers, @Nullable JsonObject diffIdentifiers, boolean warnOnMissing) {
|
||||
Object2IntMap<String> newIdentifierMap = MappingDataLoader.arrayToMap(newIdentifiers);
|
||||
for (int i = 0; i < oldIdentifiers.size(); i++) {
|
||||
JsonElement oldIdentifier = oldIdentifiers.get(i);
|
||||
int mappedId = newIdentifierMap.getInt(oldIdentifier.getAsString());
|
||||
if (mappedId == -1) {
|
||||
// Search in diff mappings
|
||||
if (diffIdentifiers != null) {
|
||||
JsonElement diffElement = diffIdentifiers.get(oldIdentifier.getAsString());
|
||||
if (diffElement != null) {
|
||||
String mappedName = diffElement.getAsString();
|
||||
if (mappedName.isEmpty()) continue; // "empty" remaps
|
||||
|
||||
mappedId = newIdentifierMap.getInt(mappedName);
|
||||
}
|
||||
}
|
||||
if (mappedId == -1) {
|
||||
if (warnOnMissing && !Via.getConfig().isSuppressConversionWarnings() || Via.getManager().isDebug()) {
|
||||
Via.getPlatform().getLogger().warning("No key for " + oldIdentifier + " :( ");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
output[i] = (short) mappedId;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param object json object
|
||||
* @return map with indexes hashed by their id value
|
||||
*/
|
||||
public static Object2IntMap<String> indexedObjectToMap(JsonObject object) {
|
||||
Object2IntMap<String> map = new Object2IntOpenHashMap<>(object.size(), 1F);
|
||||
map.defaultReturnValue(-1);
|
||||
for (Map.Entry<String, JsonElement> entry : object.entrySet()) {
|
||||
map.put(entry.getValue().getAsString(), Integer.parseInt(entry.getKey()));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array json array
|
||||
* @return map with indexes hashed by their id value
|
||||
*/
|
||||
public static Object2IntMap<String> arrayToMap(JsonArray array) {
|
||||
Object2IntMap<String> map = new Object2IntOpenHashMap<>(array.size(), 1F);
|
||||
map.defaultReturnValue(-1);
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
map.put(array.get(i).getAsString(), i);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static InputStream getResource(String name) {
|
||||
return MappingDataLoader.class.getClassLoader().getResourceAsStream("assets/viaversion/data/" + name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package us.myles.ViaVersion.api.data;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class Mappings {
|
||||
protected final short[] oldToNew;
|
||||
|
||||
public Mappings(short[] oldToNew) {
|
||||
this.oldToNew = oldToNew;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps old identifiers to the new ones.
|
||||
* If an old value cannot be found in the new mappings, the diffmapping will be checked for the given entry.
|
||||
*
|
||||
* @param size set size of the underlying short array
|
||||
* @param oldMapping mappings to map from
|
||||
* @param newMapping mappings to map to
|
||||
* @param diffMapping extra mappings that will be used/scanned when an entry cannot be found
|
||||
*/
|
||||
public Mappings(int size, JsonObject oldMapping, JsonObject newMapping, @Nullable JsonObject diffMapping) {
|
||||
oldToNew = new short[size];
|
||||
Arrays.fill(oldToNew, (short) -1);
|
||||
MappingDataLoader.mapIdentifiers(oldToNew, oldMapping, newMapping, diffMapping);
|
||||
}
|
||||
|
||||
public Mappings(JsonObject oldMapping, JsonObject newMapping, @Nullable JsonObject diffMapping) {
|
||||
this(oldMapping.entrySet().size(), oldMapping, newMapping, diffMapping);
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps old identifiers to the new ones.
|
||||
*
|
||||
* @param size set size of the underlying short array
|
||||
* @param oldMapping mappings to map from
|
||||
* @param newMapping mappings to map to
|
||||
*/
|
||||
public Mappings(int size, JsonObject oldMapping, JsonObject newMapping) {
|
||||
oldToNew = new short[size];
|
||||
Arrays.fill(oldToNew, (short) -1);
|
||||
MappingDataLoader.mapIdentifiers(oldToNew, oldMapping, newMapping);
|
||||
}
|
||||
|
||||
public Mappings(JsonObject oldMapping, JsonObject newMapping) {
|
||||
this(oldMapping.entrySet().size(), oldMapping, newMapping);
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps old identifiers to the new ones.
|
||||
*
|
||||
* @param size set size of the underlying short array
|
||||
* @param oldMapping mappings to map from
|
||||
* @param newMapping mappings to map to
|
||||
* @param diffMapping extra mappings that will be used/scanned when an entry cannot be found
|
||||
* @param warnOnMissing should "No key for x" be printed if there is no matching identifier
|
||||
*/
|
||||
public Mappings(int size, JsonArray oldMapping, JsonArray newMapping, JsonObject diffMapping, boolean warnOnMissing) {
|
||||
oldToNew = new short[size];
|
||||
Arrays.fill(oldToNew, (short) -1);
|
||||
MappingDataLoader.mapIdentifiers(oldToNew, oldMapping, newMapping, diffMapping, warnOnMissing);
|
||||
}
|
||||
|
||||
public Mappings(int size, JsonArray oldMapping, JsonArray newMapping, boolean warnOnMissing) {
|
||||
this(size, oldMapping, newMapping, null, warnOnMissing);
|
||||
}
|
||||
|
||||
public Mappings(JsonArray oldMapping, JsonArray newMapping, boolean warnOnMissing) {
|
||||
this(oldMapping.size(), oldMapping, newMapping, warnOnMissing);
|
||||
}
|
||||
|
||||
public Mappings(int size, JsonArray oldMapping, JsonArray newMapping) {
|
||||
this(size, oldMapping, newMapping, true);
|
||||
}
|
||||
|
||||
public Mappings(JsonArray oldMapping, JsonArray newMapping, JsonObject diffMapping) {
|
||||
this(oldMapping.size(), oldMapping, newMapping, diffMapping, true);
|
||||
}
|
||||
|
||||
public Mappings(JsonArray oldMapping, JsonArray newMapping) {
|
||||
this(oldMapping.size(), oldMapping, newMapping, true);
|
||||
}
|
||||
|
||||
public int getNewId(int old) {
|
||||
return old >= 0 && old < oldToNew.length ? oldToNew[old] : -1;
|
||||
}
|
||||
|
||||
public short[] getOldToNew() {
|
||||
return oldToNew;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package us.myles.ViaVersion.api.data;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
|
||||
public class ParticleMappings {
|
||||
private final Mappings mappings;
|
||||
private final int blockId;
|
||||
private final int fallingDustId;
|
||||
private final int itemId;
|
||||
|
||||
public ParticleMappings(JsonArray oldMappings, Mappings mappings) {
|
||||
this.mappings = mappings;
|
||||
|
||||
Object2IntMap<String> map = MappingDataLoader.arrayToMap(oldMappings);
|
||||
blockId = map.getInt("block");
|
||||
fallingDustId = map.getInt("falling_dust");
|
||||
itemId = map.getInt("item");
|
||||
}
|
||||
|
||||
public Mappings getMappings() {
|
||||
return mappings;
|
||||
}
|
||||
|
||||
public int getBlockId() {
|
||||
return blockId;
|
||||
}
|
||||
|
||||
public int getFallingDustId() {
|
||||
return fallingDustId;
|
||||
}
|
||||
|
||||
public int getItemId() {
|
||||
return itemId;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
package us.myles.ViaVersion.api.data;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public class StoredObject {
|
||||
private UserConnection user;
|
||||
private final UserConnection user;
|
||||
|
||||
public StoredObject(UserConnection user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public UserConnection getUser() {
|
||||
return user;
|
||||
}
|
||||
}
|
||||
@@ -1,54 +1,79 @@
|
||||
package us.myles.ViaVersion.api.data;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import lombok.Data;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.ViaVersionConfig;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.exception.CancelException;
|
||||
import us.myles.ViaVersion.exception.InformativeException;
|
||||
import us.myles.ViaVersion.packets.Direction;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.util.PipelineUtil;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.function.Function;
|
||||
|
||||
@Data
|
||||
public class UserConnection {
|
||||
private final SocketChannel channel;
|
||||
private static final AtomicLong IDS = new AtomicLong();
|
||||
private final long id = IDS.incrementAndGet();
|
||||
private final Channel channel;
|
||||
private final boolean clientSide;
|
||||
Map<Class, StoredObject> storedObjects = new ConcurrentHashMap<>();
|
||||
private ProtocolInfo protocolInfo;
|
||||
private boolean active = true;
|
||||
private boolean pendingDisconnect = false;
|
||||
private boolean pendingDisconnect;
|
||||
private Object lastPacket;
|
||||
private long sentPackets = 0L;
|
||||
private long receivedPackets = 0L;
|
||||
private long sentPackets;
|
||||
private long receivedPackets;
|
||||
// Used for tracking pps
|
||||
private long startTime = 0L;
|
||||
private long intervalPackets = 0L;
|
||||
private long startTime;
|
||||
private long intervalPackets;
|
||||
private long packetsPerSecond = -1L;
|
||||
// Used for handling warnings (over time)
|
||||
private int secondsObserved = 0;
|
||||
private int warnings = 0;
|
||||
private int secondsObserved;
|
||||
private int warnings;
|
||||
|
||||
|
||||
public UserConnection(SocketChannel socketChannel) {
|
||||
this.channel = socketChannel;
|
||||
/**
|
||||
* Creates an UserConnection. When it's a client-side connection, some method behaviors are modified.
|
||||
*
|
||||
* @param channel netty channel.
|
||||
* @param clientSide true if it's a client-side connection
|
||||
*/
|
||||
public UserConnection(@Nullable Channel channel, boolean clientSide) {
|
||||
this.channel = channel;
|
||||
this.clientSide = clientSide;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an object from the storage
|
||||
* @param channel
|
||||
* @see #UserConnection(Channel, boolean)
|
||||
*/
|
||||
public UserConnection(@Nullable Channel channel) {
|
||||
this(channel, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an object from the storage.
|
||||
*
|
||||
* @param objectClass The class of the object to get
|
||||
* @param <T> The type of the class you want to get.
|
||||
* @return The requested object
|
||||
*/
|
||||
@Nullable
|
||||
public <T extends StoredObject> T get(Class<T> objectClass) {
|
||||
return (T) storedObjects.get(objectClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the storage has an object
|
||||
* Check if the storage has an object.
|
||||
*
|
||||
* @param objectClass The object class to check
|
||||
* @return True if the object is in the storage
|
||||
@@ -58,7 +83,7 @@ public class UserConnection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Put an object into the stored objects based on class
|
||||
* Put an object into the stored objects based on class.
|
||||
*
|
||||
* @param object The object to store.
|
||||
*/
|
||||
@@ -67,7 +92,7 @@ public class UserConnection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all the stored objects
|
||||
* Clear all the stored objects.
|
||||
* Used for bungee when switching servers.
|
||||
*/
|
||||
public void clearStoredObjects() {
|
||||
@@ -75,60 +100,80 @@ public class UserConnection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a raw packet to the player
|
||||
* Send a raw packet to the player.
|
||||
*
|
||||
* @param packet The raw packet to send
|
||||
* @param currentThread Should it run in the same thread
|
||||
*/
|
||||
public void sendRawPacket(final ByteBuf packet, boolean currentThread) {
|
||||
final ChannelHandler handler = channel.pipeline().get(Via.getManager().getInjector().getEncoderName());
|
||||
if (currentThread) {
|
||||
channel.pipeline().context(handler).writeAndFlush(packet);
|
||||
Runnable act;
|
||||
if (clientSide) {
|
||||
// We'll just assume that Via decoder isn't wrapping the original decoder
|
||||
act = () -> getChannel().pipeline()
|
||||
.context(Via.getManager().getInjector().getDecoderName()).fireChannelRead(packet);
|
||||
} else {
|
||||
channel.eventLoop().submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
channel.pipeline().context(handler).writeAndFlush(packet);
|
||||
}
|
||||
});
|
||||
act = () -> channel.pipeline().context(Via.getManager().getInjector().getEncoderName()).writeAndFlush(packet);
|
||||
}
|
||||
if (currentThread) {
|
||||
act.run();
|
||||
} else {
|
||||
try {
|
||||
channel.eventLoop().submit(act);
|
||||
} catch (Throwable e) {
|
||||
packet.release(); // Couldn't schedule
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a raw packet to the player with returning the future
|
||||
* Send a raw packet to the player with returning the future.
|
||||
*
|
||||
* @param packet The raw packet to send
|
||||
* @return ChannelFuture of the packet being sent
|
||||
*/
|
||||
public ChannelFuture sendRawPacketFuture(final ByteBuf packet) {
|
||||
final ChannelHandler handler = channel.pipeline().get(Via.getManager().getInjector().getEncoderName());
|
||||
return channel.pipeline().context(handler).writeAndFlush(packet);
|
||||
if (clientSide) {
|
||||
return sendRawPacketFutureClientSide(packet);
|
||||
} else {
|
||||
return sendRawPacketFutureServerSide(packet);
|
||||
}
|
||||
}
|
||||
|
||||
private ChannelFuture sendRawPacketFutureServerSide(final ByteBuf packet) {
|
||||
return channel.pipeline().context(Via.getManager().getInjector().getEncoderName()).writeAndFlush(packet);
|
||||
}
|
||||
|
||||
private ChannelFuture sendRawPacketFutureClientSide(final ByteBuf packet) {
|
||||
// Assume that decoder isn't wrapping
|
||||
getChannel().pipeline().context(Via.getManager().getInjector().getDecoderName()).fireChannelRead(packet);
|
||||
return getChannel().newSucceededFuture();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a raw packet to the player (netty thread)
|
||||
* Send a raw packet to the player (netty thread).
|
||||
*
|
||||
* @param packet The packet to send
|
||||
*/
|
||||
public void sendRawPacket(final ByteBuf packet) {
|
||||
public void sendRawPacket(ByteBuf packet) {
|
||||
sendRawPacket(packet, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for incrementing the number of packets sent to the client
|
||||
* Used for incrementing the number of packets sent to the client.
|
||||
*/
|
||||
public void incrementSent() {
|
||||
this.sentPackets++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for incrementing the number of packets received from the client
|
||||
* Used for incrementing the number of packets received from the client.
|
||||
*
|
||||
* @return True if the interval has reset
|
||||
* @return true if the interval has reset and can now be checked for the packets sent
|
||||
*/
|
||||
public boolean incrementReceived() {
|
||||
// handle stats
|
||||
Long diff = System.currentTimeMillis() - startTime;
|
||||
long diff = System.currentTimeMillis() - startTime;
|
||||
if (diff >= 1000) {
|
||||
packetsPerSecond = intervalPackets;
|
||||
startTime = System.currentTimeMillis();
|
||||
@@ -142,30 +187,38 @@ public class UserConnection {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean handlePPS() {
|
||||
/**
|
||||
* Checks for packet flood with the packets sent in the last second.
|
||||
* ALWAYS check for {@link #incrementReceived()} before using this method.
|
||||
*
|
||||
* @return true if the packet should be cancelled
|
||||
* @see #incrementReceived()
|
||||
*/
|
||||
public boolean exceedsMaxPPS() {
|
||||
if (clientSide) return false; // Don't apply PPS limiting for client-side
|
||||
ViaVersionConfig conf = Via.getConfig();
|
||||
// Max PPS Checker
|
||||
if (conf.getMaxPPS() > 0) {
|
||||
if (getPacketsPerSecond() >= conf.getMaxPPS()) {
|
||||
disconnect(conf.getMaxPPSKickMessage().replace("%pps", ((Long) getPacketsPerSecond()).intValue() + ""));
|
||||
if (packetsPerSecond >= conf.getMaxPPS()) {
|
||||
disconnect(conf.getMaxPPSKickMessage().replace("%pps", Long.toString(packetsPerSecond)));
|
||||
return true; // don't send current packet
|
||||
}
|
||||
}
|
||||
|
||||
// Tracking PPS Checker
|
||||
if (conf.getMaxWarnings() > 0 && conf.getTrackingPeriod() > 0) {
|
||||
if (getSecondsObserved() > conf.getTrackingPeriod()) {
|
||||
if (secondsObserved > conf.getTrackingPeriod()) {
|
||||
// Reset
|
||||
setWarnings(0);
|
||||
setSecondsObserved(1);
|
||||
warnings = 0;
|
||||
secondsObserved = 1;
|
||||
} else {
|
||||
setSecondsObserved(getSecondsObserved() + 1);
|
||||
if (getPacketsPerSecond() >= conf.getWarningPPS()) {
|
||||
setWarnings(getWarnings() + 1);
|
||||
secondsObserved++;
|
||||
if (packetsPerSecond >= conf.getWarningPPS()) {
|
||||
warnings++;
|
||||
}
|
||||
|
||||
if (getWarnings() >= conf.getMaxWarnings()) {
|
||||
disconnect(conf.getMaxWarningsKickMessage().replace("%pps", ((Long) getPacketsPerSecond()).intValue() + ""));
|
||||
if (warnings >= conf.getMaxWarnings()) {
|
||||
disconnect(conf.getMaxWarningsKickMessage().replace("%pps", Long.toString(packetsPerSecond)));
|
||||
return true; // don't send current packet
|
||||
}
|
||||
}
|
||||
@@ -174,25 +227,320 @@ public class UserConnection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect a connection
|
||||
* Disconnect a connection.
|
||||
*
|
||||
* @param reason The reason to use, not used if player is not active.
|
||||
*/
|
||||
public void disconnect(final String reason) {
|
||||
if (!getChannel().isOpen()) return;
|
||||
if (pendingDisconnect) return;
|
||||
public void disconnect(String reason) {
|
||||
if (!channel.isOpen() || pendingDisconnect) return;
|
||||
|
||||
pendingDisconnect = true;
|
||||
if (get(ProtocolInfo.class).getUuid() != null) {
|
||||
final UUID uuid = get(ProtocolInfo.class).getUuid();
|
||||
Via.getPlatform().runSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!Via.getPlatform().kickPlayer(uuid, ChatColor.translateAlternateColorCodes('&', reason))) {
|
||||
getChannel().close(); // =)
|
||||
}
|
||||
Via.getPlatform().runSync(() -> {
|
||||
if (!Via.getPlatform().disconnect(this, ChatColor.translateAlternateColorCodes('&', reason))) {
|
||||
channel.close(); // =)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a raw packet to the server.
|
||||
*
|
||||
* @param packet Raw packet to be sent
|
||||
* @param currentThread If {@code true} executes immediately, {@code false} submits a task to EventLoop
|
||||
*/
|
||||
public void sendRawPacketToServer(final ByteBuf packet, boolean currentThread) {
|
||||
if (clientSide) {
|
||||
sendRawPacketToServerClientSide(packet, currentThread);
|
||||
} else {
|
||||
sendRawPacketToServerServerSide(packet, currentThread);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendRawPacketToServerServerSide(final ByteBuf packet, boolean currentThread) {
|
||||
final ByteBuf buf = packet.alloc().buffer();
|
||||
try {
|
||||
// We'll use passing through because there are some encoder wrappers
|
||||
ChannelHandlerContext context = PipelineUtil
|
||||
.getPreviousContext(Via.getManager().getInjector().getDecoderName(), channel.pipeline());
|
||||
try {
|
||||
Type.VAR_INT.writePrimitive(buf, PacketWrapper.PASSTHROUGH_ID);
|
||||
} catch (Exception e) {
|
||||
// Should not happen
|
||||
Via.getPlatform().getLogger().warning("Type.VAR_INT.write thrown an exception: " + e);
|
||||
}
|
||||
buf.writeBytes(packet);
|
||||
Runnable act = () -> {
|
||||
if (context != null) {
|
||||
context.fireChannelRead(buf);
|
||||
} else {
|
||||
channel.pipeline().fireChannelRead(buf);
|
||||
}
|
||||
});
|
||||
};
|
||||
if (currentThread) {
|
||||
act.run();
|
||||
} else {
|
||||
try {
|
||||
channel.eventLoop().submit(act);
|
||||
} catch (Throwable t) {
|
||||
// Couldn't schedule
|
||||
buf.release();
|
||||
throw t;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
packet.release();
|
||||
}
|
||||
}
|
||||
|
||||
private void sendRawPacketToServerClientSide(final ByteBuf packet, boolean currentThread) {
|
||||
Runnable act = () -> getChannel().pipeline()
|
||||
.context(Via.getManager().getInjector().getEncoderName()).writeAndFlush(packet);
|
||||
if (currentThread) {
|
||||
act.run();
|
||||
} else {
|
||||
try {
|
||||
getChannel().eventLoop().submit(act);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
packet.release(); // Couldn't schedule
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a raw packet to the server. It will submit a task to EventLoop.
|
||||
*
|
||||
* @param packet Raw packet to be sent
|
||||
*/
|
||||
public void sendRawPacketToServer(ByteBuf packet) {
|
||||
sendRawPacketToServer(packet, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Monitors incoming packets
|
||||
*
|
||||
* @return false if this packet should be cancelled
|
||||
*/
|
||||
public boolean checkIncomingPacket() {
|
||||
if (clientSide) {
|
||||
return checkClientBound();
|
||||
} else {
|
||||
return checkServerBound();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkClientBound() {
|
||||
incrementSent();
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean checkServerBound() {
|
||||
// Ignore if pending disconnect
|
||||
if (pendingDisconnect) return false;
|
||||
// Increment received + Check PPS
|
||||
return !incrementReceived() || !exceedsMaxPPS();
|
||||
}
|
||||
|
||||
/**
|
||||
* Monitors outgoing packets
|
||||
*
|
||||
* @return false if this packet should be cancelled
|
||||
*/
|
||||
public boolean checkOutgoingPacket() {
|
||||
if (clientSide) {
|
||||
return checkServerBound();
|
||||
} else {
|
||||
return checkClientBound();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if packets needs transforming.
|
||||
*
|
||||
* @return if packets should be passed through
|
||||
*/
|
||||
public boolean shouldTransformPacket() {
|
||||
return active;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the outgoing packet contained in ByteBuf. When clientSide is true, this packet is considered
|
||||
* serverbound.
|
||||
*
|
||||
* @param buf ByteBuf with packet id and packet contents
|
||||
* @param cancelSupplier Function called with original CancelException for generating the Exception used when
|
||||
* packet is cancelled
|
||||
* @throws CancelException if the packet should be cancelled
|
||||
* @throws InformativeException if packet transforming failed
|
||||
* @throws Exception if any other processing outside of transforming fails
|
||||
*/
|
||||
public void transformOutgoing(ByteBuf buf, Function<Throwable, Exception> cancelSupplier) throws Exception {
|
||||
if (!buf.isReadable()) return;
|
||||
transform(buf, clientSide ? Direction.INCOMING : Direction.OUTGOING, cancelSupplier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms the incoming packet contained in ByteBuf. When clientSide is true, this packet is considered
|
||||
* clientbound
|
||||
*
|
||||
* @param buf ByteBuf with packet id and packet contents
|
||||
* @param cancelSupplier Function called with original CancelException for generating the Exception used when
|
||||
* packet is cancelled
|
||||
* @throws CancelException if the packet should be cancelled
|
||||
* @throws InformativeException if packet transforming failed
|
||||
* @throws Exception if any other processing outside of transforming fails
|
||||
*/
|
||||
public void transformIncoming(ByteBuf buf, Function<Throwable, Exception> cancelSupplier) throws Exception {
|
||||
if (!buf.isReadable()) return;
|
||||
transform(buf, clientSide ? Direction.OUTGOING : Direction.INCOMING, cancelSupplier);
|
||||
}
|
||||
|
||||
private void transform(ByteBuf buf, Direction direction, Function<Throwable, Exception> cancelSupplier) throws Exception {
|
||||
int id = Type.VAR_INT.readPrimitive(buf);
|
||||
if (id == PacketWrapper.PASSTHROUGH_ID) return;
|
||||
|
||||
PacketWrapper wrapper = new PacketWrapper(id, buf, this);
|
||||
try {
|
||||
protocolInfo.getPipeline().transform(direction, protocolInfo.getState(), wrapper);
|
||||
} catch (CancelException ex) {
|
||||
throw cancelSupplier.apply(ex);
|
||||
}
|
||||
|
||||
ByteBuf transformed = buf.alloc().buffer();
|
||||
try {
|
||||
wrapper.writeToBuffer(transformed);
|
||||
buf.clear().writeBytes(transformed);
|
||||
} finally {
|
||||
transformed.release();
|
||||
}
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Channel getChannel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ProtocolInfo getProtocolInfo() {
|
||||
return protocolInfo;
|
||||
}
|
||||
|
||||
public void setProtocolInfo(@Nullable ProtocolInfo protocolInfo) {
|
||||
this.protocolInfo = protocolInfo;
|
||||
if (protocolInfo != null) {
|
||||
storedObjects.put(ProtocolInfo.class, protocolInfo);
|
||||
} else {
|
||||
storedObjects.remove(ProtocolInfo.class);
|
||||
}
|
||||
}
|
||||
|
||||
public Map<Class, StoredObject> getStoredObjects() {
|
||||
return storedObjects;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
public void setActive(boolean active) {
|
||||
this.active = active;
|
||||
}
|
||||
|
||||
public boolean isPendingDisconnect() {
|
||||
return pendingDisconnect;
|
||||
}
|
||||
|
||||
public void setPendingDisconnect(boolean pendingDisconnect) {
|
||||
this.pendingDisconnect = pendingDisconnect;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Object getLastPacket() {
|
||||
return lastPacket;
|
||||
}
|
||||
|
||||
public void setLastPacket(@Nullable Object lastPacket) {
|
||||
this.lastPacket = lastPacket;
|
||||
}
|
||||
|
||||
public long getSentPackets() {
|
||||
return sentPackets;
|
||||
}
|
||||
|
||||
public void setSentPackets(long sentPackets) {
|
||||
this.sentPackets = sentPackets;
|
||||
}
|
||||
|
||||
public long getReceivedPackets() {
|
||||
return receivedPackets;
|
||||
}
|
||||
|
||||
public void setReceivedPackets(long receivedPackets) {
|
||||
this.receivedPackets = receivedPackets;
|
||||
}
|
||||
|
||||
public long getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public void setStartTime(long startTime) {
|
||||
this.startTime = startTime;
|
||||
}
|
||||
|
||||
public long getIntervalPackets() {
|
||||
return intervalPackets;
|
||||
}
|
||||
|
||||
public void setIntervalPackets(long intervalPackets) {
|
||||
this.intervalPackets = intervalPackets;
|
||||
}
|
||||
|
||||
public long getPacketsPerSecond() {
|
||||
return packetsPerSecond;
|
||||
}
|
||||
|
||||
public void setPacketsPerSecond(long packetsPerSecond) {
|
||||
this.packetsPerSecond = packetsPerSecond;
|
||||
}
|
||||
|
||||
public int getSecondsObserved() {
|
||||
return secondsObserved;
|
||||
}
|
||||
|
||||
public void setSecondsObserved(int secondsObserved) {
|
||||
this.secondsObserved = secondsObserved;
|
||||
}
|
||||
|
||||
public int getWarnings() {
|
||||
return warnings;
|
||||
}
|
||||
|
||||
public void setWarnings(int warnings) {
|
||||
this.warnings = warnings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
UserConnection that = (UserConnection) o;
|
||||
return id == that.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Long.hashCode(id);
|
||||
}
|
||||
|
||||
public boolean isClientSide() {
|
||||
return clientSide;
|
||||
}
|
||||
|
||||
public boolean shouldApplyBlockProtocol() {
|
||||
return !clientSide; // Don't apply protocol blocking on client-side
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
package us.myles.ViaVersion.api.entities;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
// 1.10 Entity / Object ids
|
||||
public class Entity1_10Types {
|
||||
|
||||
@@ -12,42 +13,40 @@ public class Entity1_10Types {
|
||||
Optional<EntityType> type;
|
||||
|
||||
if (isObject)
|
||||
type = ObjectTypes.getPCEntity(typeID);
|
||||
type = ObjectType.getPCEntity(typeID);
|
||||
else
|
||||
type = EntityType.findById(typeID);
|
||||
|
||||
if (!type.isPresent()) {
|
||||
Via.getPlatform().getLogger().severe("Could not find type id " + typeID + " isObject=" + isObject);
|
||||
Via.getPlatform().getLogger().severe("Could not find 1.10 type id " + typeID + " isObject=" + isObject);
|
||||
return EntityType.ENTITY; // Fall back to the basic ENTITY
|
||||
}
|
||||
|
||||
return type.get();
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum EntityType {
|
||||
public enum EntityType implements us.myles.ViaVersion.api.entities.EntityType {
|
||||
ENTITY(-1),
|
||||
DROPPED_ITEM(1, EntityType.ENTITY),
|
||||
EXPERIENCE_ORB(2, EntityType.ENTITY),
|
||||
LEASH_HITCH(8, EntityType.ENTITY), // Actually entity hanging but it doesn't make a lot of difference for metadata
|
||||
PAINTING(9, EntityType.ENTITY), // Actually entity hanging but it doesn't make a lot of difference for metadata
|
||||
ARROW(10, EntityType.ENTITY),
|
||||
SNOWBALL(11, EntityType.ENTITY), // Actually EntityProjectile
|
||||
FIREBALL(12, EntityType.ENTITY),
|
||||
SMALL_FIREBALL(13, EntityType.ENTITY),
|
||||
ENDER_PEARL(14, EntityType.ENTITY), // Actually EntityProjectile
|
||||
ENDER_SIGNAL(15, EntityType.ENTITY),
|
||||
THROWN_EXP_BOTTLE(17, EntityType.ENTITY),
|
||||
ITEM_FRAME(18, EntityType.ENTITY), // Actually EntityHanging
|
||||
WITHER_SKULL(19, EntityType.ENTITY),
|
||||
PRIMED_TNT(20, EntityType.ENTITY),
|
||||
FALLING_BLOCK(21, EntityType.ENTITY),
|
||||
FIREWORK(22, EntityType.ENTITY),
|
||||
TIPPED_ARROW(23, EntityType.ARROW),
|
||||
SPECTRAL_ARROW(24, EntityType.ARROW),
|
||||
SHULKER_BULLET(25, EntityType.ENTITY),
|
||||
DRAGON_FIREBALL(26, EntityType.FIREBALL),
|
||||
DROPPED_ITEM(1, ENTITY),
|
||||
EXPERIENCE_ORB(2, ENTITY),
|
||||
LEASH_HITCH(8, ENTITY), // Actually entity hanging but it doesn't make a lot of difference for metadata
|
||||
PAINTING(9, ENTITY), // Actually entity hanging but it doesn't make a lot of difference for metadata
|
||||
ARROW(10, ENTITY),
|
||||
SNOWBALL(11, ENTITY), // Actually EntityProjectile
|
||||
FIREBALL(12, ENTITY),
|
||||
SMALL_FIREBALL(13, ENTITY),
|
||||
ENDER_PEARL(14, ENTITY), // Actually EntityProjectile
|
||||
ENDER_SIGNAL(15, ENTITY),
|
||||
THROWN_EXP_BOTTLE(17, ENTITY),
|
||||
ITEM_FRAME(18, ENTITY), // Actually EntityHanging
|
||||
WITHER_SKULL(19, ENTITY),
|
||||
PRIMED_TNT(20, ENTITY),
|
||||
FALLING_BLOCK(21, ENTITY),
|
||||
FIREWORK(22, ENTITY),
|
||||
TIPPED_ARROW(23, ARROW),
|
||||
SPECTRAL_ARROW(24, ARROW),
|
||||
SHULKER_BULLET(25, ENTITY),
|
||||
DRAGON_FIREBALL(26, FIREBALL),
|
||||
|
||||
ENTITY_LIVING(-1, ENTITY),
|
||||
ENTITY_INSENTIENT(-1, ENTITY_LIVING),
|
||||
@@ -55,7 +54,7 @@ public class Entity1_10Types {
|
||||
ENTITY_TAMEABLE_ANIMAL(-1, ENTITY_AGEABLE),
|
||||
ENTITY_HUMAN(-1, ENTITY_LIVING),
|
||||
|
||||
ARMOR_STAND(30, EntityType.ENTITY_LIVING),
|
||||
ARMOR_STAND(30, ENTITY_LIVING),
|
||||
|
||||
// Vehicles
|
||||
MINECART_ABSTRACT(-1, ENTITY),
|
||||
@@ -88,7 +87,7 @@ public class Entity1_10Types {
|
||||
ENDERMITE(67, ENTITY_INSENTIENT),
|
||||
GUARDIAN(68, ENTITY_INSENTIENT),
|
||||
IRON_GOLEM(99, ENTITY_INSENTIENT), // moved up to avoid illegal forward references
|
||||
SHULKER(69, EntityType.IRON_GOLEM),
|
||||
SHULKER(69, IRON_GOLEM),
|
||||
PIG(90, ENTITY_AGEABLE),
|
||||
SHEEP(91, ENTITY_AGEABLE),
|
||||
COW(92, ENTITY_AGEABLE),
|
||||
@@ -96,7 +95,7 @@ public class Entity1_10Types {
|
||||
SQUID(94, ENTITY_INSENTIENT),
|
||||
WOLF(95, ENTITY_TAMEABLE_ANIMAL),
|
||||
MUSHROOM_COW(96, COW),
|
||||
SNOWMAN(97, EntityType.IRON_GOLEM),
|
||||
SNOWMAN(97, IRON_GOLEM),
|
||||
OCELOT(98, ENTITY_TAMEABLE_ANIMAL),
|
||||
HORSE(100, ENTITY_AGEABLE),
|
||||
RABBIT(101, ENTITY_AGEABLE),
|
||||
@@ -113,6 +112,8 @@ public class Entity1_10Types {
|
||||
PLAYER(-1, ENTITY_HUMAN),
|
||||
COMPLEX_PART(-1, ENTITY);
|
||||
|
||||
private static final Map<Integer, EntityType> TYPES = new HashMap<>();
|
||||
|
||||
private final int id;
|
||||
private final EntityType parent;
|
||||
|
||||
@@ -121,25 +122,39 @@ public class Entity1_10Types {
|
||||
this.parent = null;
|
||||
}
|
||||
|
||||
EntityType(int id, EntityType parent) {
|
||||
this.id = id;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
static {
|
||||
for (EntityType type : EntityType.values()) {
|
||||
TYPES.put(type.id, type);
|
||||
}
|
||||
}
|
||||
|
||||
public static Optional<EntityType> findById(int id) {
|
||||
if (id == -1) // Check if this is called
|
||||
return Optional.absent();
|
||||
return Optional.empty();
|
||||
return Optional.ofNullable(TYPES.get(id));
|
||||
}
|
||||
|
||||
for (EntityType ent : EntityType.values())
|
||||
if (ent.getId() == id)
|
||||
return Optional.of(ent);
|
||||
@Override
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
return Optional.absent();
|
||||
@Override
|
||||
public EntityType getParent() {
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum ObjectTypes {
|
||||
public enum ObjectType implements us.myles.ViaVersion.api.entities.ObjectType {
|
||||
BOAT(1, EntityType.BOAT),
|
||||
ITEM(2, EntityType.DROPPED_ITEM),
|
||||
AREA_EFFECT_CLOUD(3, EntityType.AREA_EFFECT_CLOUD),
|
||||
MINECART(10, EntityType.MINECART_ABSTRACT),
|
||||
MINECART(10, EntityType.MINECART_RIDEABLE),
|
||||
TNT_PRIMED(50, EntityType.PRIMED_TNT),
|
||||
ENDER_CRYSTAL(51, EntityType.ENDER_CRYSTAL),
|
||||
TIPPED_ARROW(60, EntityType.TIPPED_ARROW),
|
||||
@@ -162,26 +177,44 @@ public class Entity1_10Types {
|
||||
SPECTRAL_ARROW(91, EntityType.SPECTRAL_ARROW),
|
||||
DRAGON_FIREBALL(93, EntityType.DRAGON_FIREBALL);
|
||||
|
||||
private static final Map<Integer, ObjectType> TYPES = new HashMap<>();
|
||||
|
||||
private final int id;
|
||||
private final EntityType type;
|
||||
|
||||
public static Optional<ObjectTypes> findById(int id) {
|
||||
static {
|
||||
for (ObjectType type : ObjectType.values()) {
|
||||
TYPES.put(type.id, type);
|
||||
}
|
||||
}
|
||||
|
||||
ObjectType(int id, EntityType type) {
|
||||
this.id = id;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public static Optional<ObjectType> findById(int id) {
|
||||
if (id == -1)
|
||||
return Optional.absent();
|
||||
|
||||
for (ObjectTypes ent : ObjectTypes.values())
|
||||
if (ent.getId() == id)
|
||||
return Optional.of(ent);
|
||||
|
||||
return Optional.absent();
|
||||
return Optional.empty();
|
||||
return Optional.ofNullable(TYPES.get(id));
|
||||
}
|
||||
|
||||
public static Optional<EntityType> getPCEntity(int id) {
|
||||
Optional<ObjectTypes> output = findById(id);
|
||||
Optional<ObjectType> output = findById(id);
|
||||
|
||||
if (!output.isPresent())
|
||||
return Optional.absent();
|
||||
return Optional.of(output.get().getType());
|
||||
return Optional.empty();
|
||||
return Optional.of(output.get().type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +1,31 @@
|
||||
package us.myles.ViaVersion.api.entities;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
// 1.11 Entity / Object ids TODO maybe in the future instead of copying it, some api.
|
||||
public class Entity1_11Types {
|
||||
|
||||
public static EntityType getTypeFromId(int typeID, boolean isObject) {
|
||||
Optional<EntityType> type;
|
||||
|
||||
if (isObject)
|
||||
type = ObjectTypes.getPCEntity(typeID);
|
||||
type = ObjectType.getPCEntity(typeID);
|
||||
else
|
||||
type = EntityType.findById(typeID);
|
||||
|
||||
if (!type.isPresent()) {
|
||||
Via.getPlatform().getLogger().severe("Could not find type id " + typeID + " isObject=" + isObject);
|
||||
Via.getPlatform().getLogger().severe("Could not find 1.11 type id " + typeID + " isObject=" + isObject);
|
||||
return EntityType.ENTITY; // Fall back to the basic ENTITY
|
||||
}
|
||||
|
||||
return type.get();
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum EntityType {
|
||||
public enum EntityType implements us.myles.ViaVersion.api.entities.EntityType {
|
||||
ENTITY(-1),
|
||||
DROPPED_ITEM(1, ENTITY),
|
||||
EXPERIENCE_ORB(2, ENTITY),
|
||||
@@ -43,7 +43,6 @@ public class Entity1_11Types {
|
||||
PRIMED_TNT(20, ENTITY),
|
||||
FALLING_BLOCK(21, ENTITY),
|
||||
FIREWORK(22, ENTITY),
|
||||
TIPPED_ARROW(23, ARROW),
|
||||
SPECTRAL_ARROW(24, ARROW),
|
||||
SHULKER_BULLET(25, ENTITY),
|
||||
DRAGON_FIREBALL(26, FIREBALL),
|
||||
@@ -101,10 +100,10 @@ public class Entity1_11Types {
|
||||
ENDERMITE(67, ENTITY_INSENTIENT),
|
||||
|
||||
GUARDIAN(68, ENTITY_INSENTIENT),
|
||||
ELDER_GUARDIAN(4, EntityType.GUARDIAN), // Moved down to avoid illegal forward reference
|
||||
ELDER_GUARDIAN(4, GUARDIAN), // Moved down to avoid illegal forward reference
|
||||
|
||||
IRON_GOLEM(99, ENTITY_INSENTIENT), // moved up to avoid illegal forward references
|
||||
SHULKER(69, EntityType.IRON_GOLEM),
|
||||
SHULKER(69, IRON_GOLEM),
|
||||
PIG(90, ENTITY_AGEABLE),
|
||||
SHEEP(91, ENTITY_AGEABLE),
|
||||
COW(92, ENTITY_AGEABLE),
|
||||
@@ -112,7 +111,7 @@ public class Entity1_11Types {
|
||||
SQUID(94, ENTITY_INSENTIENT),
|
||||
WOLF(95, ENTITY_TAMEABLE_ANIMAL),
|
||||
MUSHROOM_COW(96, COW),
|
||||
SNOWMAN(97, EntityType.IRON_GOLEM),
|
||||
SNOWMAN(97, IRON_GOLEM),
|
||||
OCELOT(98, ENTITY_TAMEABLE_ANIMAL),
|
||||
|
||||
ABSTRACT_HORSE(-1, ENTITY_AGEABLE),
|
||||
@@ -141,6 +140,8 @@ public class Entity1_11Types {
|
||||
COMPLEX_PART(-1, ENTITY),
|
||||
LIAMA_SPIT(-1, ENTITY);
|
||||
|
||||
private static final Map<Integer, EntityType> TYPES = new HashMap<>();
|
||||
|
||||
private final int id;
|
||||
private final EntityType parent;
|
||||
|
||||
@@ -149,52 +150,42 @@ public class Entity1_11Types {
|
||||
this.parent = null;
|
||||
}
|
||||
|
||||
EntityType(int id, EntityType parent) {
|
||||
this.id = id;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
static {
|
||||
for (EntityType type : EntityType.values()) {
|
||||
TYPES.put(type.id, type);
|
||||
}
|
||||
}
|
||||
|
||||
public static Optional<EntityType> findById(int id) {
|
||||
if (id == -1) // Check if this is called
|
||||
return Optional.absent();
|
||||
|
||||
for (EntityType ent : EntityType.values())
|
||||
if (ent.getId() == id)
|
||||
return Optional.of(ent);
|
||||
|
||||
return Optional.absent();
|
||||
}
|
||||
|
||||
public boolean is(EntityType... types) {
|
||||
for (EntityType type : types)
|
||||
if (is(type))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean is(EntityType type) {
|
||||
return this == type;
|
||||
}
|
||||
|
||||
public boolean isOrHasParent(EntityType type) {
|
||||
EntityType parent = this;
|
||||
|
||||
do {
|
||||
if (parent.equals(type))
|
||||
return true;
|
||||
|
||||
parent = parent.getParent();
|
||||
} while (parent != null);
|
||||
|
||||
return false;
|
||||
return Optional.empty();
|
||||
return Optional.ofNullable(TYPES.get(id));
|
||||
}
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
public enum ObjectTypes {
|
||||
public enum ObjectType implements us.myles.ViaVersion.api.entities.ObjectType {
|
||||
BOAT(1, EntityType.BOAT),
|
||||
ITEM(2, EntityType.DROPPED_ITEM),
|
||||
AREA_EFFECT_CLOUD(3, EntityType.AREA_EFFECT_CLOUD),
|
||||
MINECART(10, EntityType.MINECART_ABSTRACT),
|
||||
MINECART(10, EntityType.MINECART_RIDEABLE),
|
||||
TNT_PRIMED(50, EntityType.PRIMED_TNT),
|
||||
ENDER_CRYSTAL(51, EntityType.ENDER_CRYSTAL),
|
||||
TIPPED_ARROW(60, EntityType.TIPPED_ARROW),
|
||||
TIPPED_ARROW(60, EntityType.ARROW),
|
||||
SNOWBALL(61, EntityType.SNOWBALL),
|
||||
EGG(62, EntityType.EGG),
|
||||
FIREBALL(63, EntityType.FIREBALL),
|
||||
@@ -211,31 +202,49 @@ public class Entity1_11Types {
|
||||
FIREWORK(76, EntityType.FIREWORK),
|
||||
LEASH(77, EntityType.LEASH_HITCH),
|
||||
ARMOR_STAND(78, EntityType.ARMOR_STAND),
|
||||
EVOCATION_FANGS(39, EntityType.EVOCATION_FANGS),
|
||||
EVOCATION_FANGS(79, EntityType.EVOCATION_FANGS),
|
||||
FISHIHNG_HOOK(90, EntityType.FISHING_HOOK),
|
||||
SPECTRAL_ARROW(91, EntityType.SPECTRAL_ARROW),
|
||||
DRAGON_FIREBALL(93, EntityType.DRAGON_FIREBALL);
|
||||
|
||||
private static final Map<Integer, ObjectType> TYPES = new HashMap<>();
|
||||
|
||||
private final int id;
|
||||
private final EntityType type;
|
||||
|
||||
public static Optional<ObjectTypes> findById(int id) {
|
||||
static {
|
||||
for (ObjectType type : ObjectType.values()) {
|
||||
TYPES.put(type.id, type);
|
||||
}
|
||||
}
|
||||
|
||||
ObjectType(int id, EntityType type) {
|
||||
this.id = id;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public static Optional<ObjectType> findById(int id) {
|
||||
if (id == -1)
|
||||
return Optional.absent();
|
||||
|
||||
for (ObjectTypes ent : ObjectTypes.values())
|
||||
if (ent.getId() == id)
|
||||
return Optional.of(ent);
|
||||
|
||||
return Optional.absent();
|
||||
return Optional.empty();
|
||||
return Optional.ofNullable(TYPES.get(id));
|
||||
}
|
||||
|
||||
public static Optional<EntityType> getPCEntity(int id) {
|
||||
Optional<ObjectTypes> output = findById(id);
|
||||
Optional<ObjectType> output = findById(id);
|
||||
|
||||
if (!output.isPresent())
|
||||
return Optional.absent();
|
||||
return Optional.of(output.get().getType());
|
||||
return Optional.empty();
|
||||
return Optional.of(output.get().type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Matsv
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package us.myles.ViaVersion.api.entities;
|
||||
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
// 1.12 Entity / Object taken from https://github.com/Matsv/ViaBackwards/blob/master/core/src/main/java/nl/matsv/viabackwards/api/entities/types/EntityType1_12.java
|
||||
public class Entity1_12Types {
|
||||
|
||||
public static EntityType getTypeFromId(int typeID, boolean isObject) {
|
||||
Optional<EntityType> type;
|
||||
|
||||
if (isObject)
|
||||
type = ObjectType.getPCEntity(typeID);
|
||||
else
|
||||
type = EntityType.findById(typeID);
|
||||
|
||||
if (!type.isPresent()) {
|
||||
Via.getPlatform().getLogger().severe("Could not find 1.12 type id " + typeID + " isObject=" + isObject);
|
||||
return EntityType.ENTITY; // Fall back to the basic ENTITY
|
||||
}
|
||||
|
||||
return type.get();
|
||||
}
|
||||
|
||||
public enum EntityType implements us.myles.ViaVersion.api.entities.EntityType {
|
||||
ENTITY(-1),
|
||||
DROPPED_ITEM(1, ENTITY),
|
||||
EXPERIENCE_ORB(2, ENTITY),
|
||||
LEASH_HITCH(8, ENTITY), // Actually entity hanging but it doesn't make a lot of difference for metadata
|
||||
PAINTING(9, ENTITY), // Actually entity hanging but it doesn't make a lot of difference for metadata
|
||||
ARROW(10, ENTITY),
|
||||
SNOWBALL(11, ENTITY), // Actually EntityProjectile
|
||||
FIREBALL(12, ENTITY),
|
||||
SMALL_FIREBALL(13, ENTITY),
|
||||
ENDER_PEARL(14, ENTITY), // Actually EntityProjectile
|
||||
ENDER_SIGNAL(15, ENTITY),
|
||||
THROWN_EXP_BOTTLE(17, ENTITY),
|
||||
ITEM_FRAME(18, ENTITY), // Actually EntityHanging
|
||||
WITHER_SKULL(19, ENTITY),
|
||||
PRIMED_TNT(20, ENTITY),
|
||||
FALLING_BLOCK(21, ENTITY),
|
||||
FIREWORK(22, ENTITY),
|
||||
SPECTRAL_ARROW(24, ARROW),
|
||||
SHULKER_BULLET(25, ENTITY),
|
||||
DRAGON_FIREBALL(26, FIREBALL),
|
||||
EVOCATION_FANGS(33, ENTITY),
|
||||
|
||||
|
||||
ENTITY_LIVING(-1, ENTITY),
|
||||
ENTITY_INSENTIENT(-1, ENTITY_LIVING),
|
||||
ENTITY_AGEABLE(-1, ENTITY_INSENTIENT),
|
||||
ENTITY_TAMEABLE_ANIMAL(-1, ENTITY_AGEABLE),
|
||||
ENTITY_HUMAN(-1, ENTITY_LIVING),
|
||||
|
||||
ARMOR_STAND(30, ENTITY_LIVING),
|
||||
ENTITY_ILLAGER_ABSTRACT(-1, ENTITY_INSENTIENT),
|
||||
EVOCATION_ILLAGER(34, ENTITY_ILLAGER_ABSTRACT),
|
||||
VEX(35, ENTITY_INSENTIENT),
|
||||
VINDICATION_ILLAGER(36, ENTITY_ILLAGER_ABSTRACT),
|
||||
ILLUSION_ILLAGER(37, EVOCATION_ILLAGER),
|
||||
|
||||
// Vehicles
|
||||
MINECART_ABSTRACT(-1, ENTITY),
|
||||
MINECART_COMMAND(40, MINECART_ABSTRACT),
|
||||
BOAT(41, ENTITY),
|
||||
MINECART_RIDEABLE(42, MINECART_ABSTRACT),
|
||||
MINECART_CHEST(43, MINECART_ABSTRACT),
|
||||
MINECART_FURNACE(44, MINECART_ABSTRACT),
|
||||
MINECART_TNT(45, MINECART_ABSTRACT),
|
||||
MINECART_HOPPER(46, MINECART_ABSTRACT),
|
||||
MINECART_MOB_SPAWNER(47, MINECART_ABSTRACT),
|
||||
|
||||
CREEPER(50, ENTITY_INSENTIENT),
|
||||
|
||||
ABSTRACT_SKELETON(-1, ENTITY_INSENTIENT),
|
||||
SKELETON(51, ABSTRACT_SKELETON),
|
||||
WITHER_SKELETON(5, ABSTRACT_SKELETON),
|
||||
STRAY(6, ABSTRACT_SKELETON),
|
||||
|
||||
SPIDER(52, ENTITY_INSENTIENT),
|
||||
GIANT(53, ENTITY_INSENTIENT),
|
||||
|
||||
ZOMBIE(54, ENTITY_INSENTIENT),
|
||||
HUSK(23, ZOMBIE),
|
||||
ZOMBIE_VILLAGER(27, ZOMBIE),
|
||||
|
||||
SLIME(55, ENTITY_INSENTIENT),
|
||||
GHAST(56, ENTITY_INSENTIENT),
|
||||
PIG_ZOMBIE(57, ZOMBIE),
|
||||
ENDERMAN(58, ENTITY_INSENTIENT),
|
||||
CAVE_SPIDER(59, SPIDER),
|
||||
SILVERFISH(60, ENTITY_INSENTIENT),
|
||||
BLAZE(61, ENTITY_INSENTIENT),
|
||||
MAGMA_CUBE(62, SLIME),
|
||||
ENDER_DRAGON(63, ENTITY_INSENTIENT),
|
||||
WITHER(64, ENTITY_INSENTIENT),
|
||||
BAT(65, ENTITY_INSENTIENT),
|
||||
WITCH(66, ENTITY_INSENTIENT),
|
||||
ENDERMITE(67, ENTITY_INSENTIENT),
|
||||
|
||||
GUARDIAN(68, ENTITY_INSENTIENT),
|
||||
ELDER_GUARDIAN(4, GUARDIAN), // Moved down to avoid illegal forward reference
|
||||
|
||||
IRON_GOLEM(99, ENTITY_INSENTIENT), // moved up to avoid illegal forward references
|
||||
SHULKER(69, IRON_GOLEM),
|
||||
PIG(90, ENTITY_AGEABLE),
|
||||
SHEEP(91, ENTITY_AGEABLE),
|
||||
COW(92, ENTITY_AGEABLE),
|
||||
CHICKEN(93, ENTITY_AGEABLE),
|
||||
SQUID(94, ENTITY_INSENTIENT),
|
||||
WOLF(95, ENTITY_TAMEABLE_ANIMAL),
|
||||
MUSHROOM_COW(96, COW),
|
||||
SNOWMAN(97, IRON_GOLEM),
|
||||
OCELOT(98, ENTITY_TAMEABLE_ANIMAL),
|
||||
PARROT(105, ENTITY_TAMEABLE_ANIMAL),
|
||||
|
||||
ABSTRACT_HORSE(-1, ENTITY_AGEABLE),
|
||||
HORSE(100, ABSTRACT_HORSE),
|
||||
SKELETON_HORSE(28, ABSTRACT_HORSE),
|
||||
ZOMBIE_HORSE(29, ABSTRACT_HORSE),
|
||||
|
||||
CHESTED_HORSE(-1, ABSTRACT_HORSE),
|
||||
DONKEY(31, CHESTED_HORSE),
|
||||
MULE(32, CHESTED_HORSE),
|
||||
LIAMA(103, CHESTED_HORSE),
|
||||
|
||||
|
||||
RABBIT(101, ENTITY_AGEABLE),
|
||||
POLAR_BEAR(102, ENTITY_AGEABLE),
|
||||
VILLAGER(120, ENTITY_AGEABLE),
|
||||
ENDER_CRYSTAL(200, ENTITY),
|
||||
SPLASH_POTION(-1, ENTITY),
|
||||
LINGERING_POTION(-1, SPLASH_POTION),
|
||||
AREA_EFFECT_CLOUD(-1, ENTITY),
|
||||
EGG(-1, ENTITY),
|
||||
FISHING_HOOK(-1, ENTITY),
|
||||
LIGHTNING(-1, ENTITY),
|
||||
WEATHER(-1, ENTITY),
|
||||
PLAYER(-1, ENTITY_HUMAN),
|
||||
COMPLEX_PART(-1, ENTITY),
|
||||
LIAMA_SPIT(-1, ENTITY);
|
||||
|
||||
private static final Map<Integer, EntityType> TYPES = new HashMap<>();
|
||||
|
||||
private final int id;
|
||||
private final EntityType parent;
|
||||
|
||||
EntityType(int id) {
|
||||
this.id = id;
|
||||
this.parent = null;
|
||||
}
|
||||
|
||||
EntityType(int id, EntityType parent) {
|
||||
this.id = id;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
static {
|
||||
for (EntityType type : EntityType.values()) {
|
||||
TYPES.put(type.id, type);
|
||||
}
|
||||
}
|
||||
|
||||
public static Optional<EntityType> findById(int id) {
|
||||
if (id == -1) // Check if this is called
|
||||
return Optional.empty();
|
||||
return Optional.ofNullable(TYPES.get(id));
|
||||
}
|
||||
}
|
||||
|
||||
public enum ObjectType implements us.myles.ViaVersion.api.entities.ObjectType {
|
||||
BOAT(1, EntityType.BOAT),
|
||||
ITEM(2, EntityType.DROPPED_ITEM),
|
||||
AREA_EFFECT_CLOUD(3, EntityType.AREA_EFFECT_CLOUD),
|
||||
MINECART(10, EntityType.MINECART_RIDEABLE),
|
||||
TNT_PRIMED(50, EntityType.PRIMED_TNT),
|
||||
ENDER_CRYSTAL(51, EntityType.ENDER_CRYSTAL),
|
||||
TIPPED_ARROW(60, EntityType.ARROW),
|
||||
SNOWBALL(61, EntityType.SNOWBALL),
|
||||
EGG(62, EntityType.EGG),
|
||||
FIREBALL(63, EntityType.FIREBALL),
|
||||
SMALL_FIREBALL(64, EntityType.SMALL_FIREBALL),
|
||||
ENDER_PEARL(65, EntityType.ENDER_PEARL),
|
||||
WITHER_SKULL(66, EntityType.WITHER_SKULL),
|
||||
SHULKER_BULLET(67, EntityType.SHULKER_BULLET),
|
||||
LIAMA_SPIT(68, EntityType.LIAMA_SPIT),
|
||||
FALLING_BLOCK(70, EntityType.FALLING_BLOCK),
|
||||
ITEM_FRAME(71, EntityType.ITEM_FRAME),
|
||||
ENDER_SIGNAL(72, EntityType.ENDER_SIGNAL),
|
||||
POTION(73, EntityType.SPLASH_POTION),
|
||||
THROWN_EXP_BOTTLE(75, EntityType.THROWN_EXP_BOTTLE),
|
||||
FIREWORK(76, EntityType.FIREWORK),
|
||||
LEASH(77, EntityType.LEASH_HITCH),
|
||||
ARMOR_STAND(78, EntityType.ARMOR_STAND),
|
||||
EVOCATION_FANGS(79, EntityType.EVOCATION_FANGS),
|
||||
FISHIHNG_HOOK(90, EntityType.FISHING_HOOK),
|
||||
SPECTRAL_ARROW(91, EntityType.SPECTRAL_ARROW),
|
||||
DRAGON_FIREBALL(93, EntityType.DRAGON_FIREBALL);
|
||||
|
||||
private static final Map<Integer, ObjectType> TYPES = new HashMap<>();
|
||||
|
||||
private final int id;
|
||||
private final EntityType type;
|
||||
|
||||
static {
|
||||
for (ObjectType type : ObjectType.values()) {
|
||||
TYPES.put(type.id, type);
|
||||
}
|
||||
}
|
||||
|
||||
ObjectType(int id, EntityType type) {
|
||||
this.id = id;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public static Optional<ObjectType> findById(int id) {
|
||||
if (id == -1)
|
||||
return Optional.empty();
|
||||
return Optional.ofNullable(TYPES.get(id));
|
||||
}
|
||||
|
||||
public static Optional<EntityType> getPCEntity(int id) {
|
||||
Optional<ObjectType> output = findById(id);
|
||||
|
||||
if (!output.isPresent())
|
||||
return Optional.empty();
|
||||
return Optional.of(output.get().type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
package us.myles.ViaVersion.api.entities;
|
||||
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
// TODO auto generate 18w11a with PAaaS
|
||||
public class Entity1_13Types {
|
||||
|
||||
public static EntityType getTypeFromId(int typeID, boolean isObject) {
|
||||
Optional<EntityType> type;
|
||||
|
||||
if (isObject)
|
||||
type = ObjectType.getPCEntity(typeID);
|
||||
else
|
||||
type = EntityType.findById(typeID);
|
||||
|
||||
if (!type.isPresent()) {
|
||||
Via.getPlatform().getLogger().severe("Could not find 1.13 type id " + typeID + " isObject=" + isObject);
|
||||
return EntityType.ENTITY; // Fall back to the basic ENTITY
|
||||
}
|
||||
|
||||
return type.get();
|
||||
}
|
||||
|
||||
public enum EntityType implements us.myles.ViaVersion.api.entities.EntityType {
|
||||
// Auto generated
|
||||
|
||||
ENTITY(-1), // abm
|
||||
|
||||
AREA_EFFECT_CLOUD(0, ENTITY), // abk
|
||||
END_CRYSTAL(16, ENTITY), // aho
|
||||
EVOKER_FANGS(20, ENTITY), // ala
|
||||
EXPERIENCE_ORB(22, ENTITY), // abs
|
||||
EYE_OF_ENDER(23, ENTITY), // alb
|
||||
FALLING_BLOCK(24, ENTITY), // aix
|
||||
FIREWORK_ROCKET(25, ENTITY), // alc
|
||||
ITEM(32, ENTITY), // aiy
|
||||
LLAMA_SPIT(37, ENTITY), // ale
|
||||
TNT(55, ENTITY), // aiz
|
||||
SHULKER_BULLET(60, ENTITY), // alh
|
||||
FISHING_BOBBER(93, ENTITY), // ais
|
||||
|
||||
LIVINGENTITY(-1, ENTITY), // abv
|
||||
ARMOR_STAND(1, LIVINGENTITY), // ail
|
||||
PLAYER(92, LIVINGENTITY), // aks
|
||||
|
||||
ABSTRACT_INSENTIENT(-1, LIVINGENTITY), // abw
|
||||
ENDER_DRAGON(17, ABSTRACT_INSENTIENT), // ahp
|
||||
|
||||
ABSTRACT_CREATURE(-1, ABSTRACT_INSENTIENT), // acd
|
||||
|
||||
ABSTRACT_AGEABLE(-1, ABSTRACT_CREATURE), // abj
|
||||
VILLAGER(79, ABSTRACT_AGEABLE), // akn
|
||||
|
||||
// Animals
|
||||
ABSTRACT_ANIMAL(-1, ABSTRACT_AGEABLE), // agd
|
||||
CHICKEN(7, ABSTRACT_ANIMAL), // age
|
||||
COW(9, ABSTRACT_ANIMAL), // agg
|
||||
MOOSHROOM(47, COW), // agi
|
||||
PIG(51, ABSTRACT_ANIMAL), // agl
|
||||
POLAR_BEAR(54, ABSTRACT_ANIMAL), // agm
|
||||
RABBIT(56, ABSTRACT_ANIMAL), // ago
|
||||
SHEEP(58, ABSTRACT_ANIMAL), // agq
|
||||
TURTLE(73, ABSTRACT_ANIMAL), // agv
|
||||
|
||||
ABSTRACT_TAMEABLE_ANIMAL(-1, ABSTRACT_ANIMAL), // acg
|
||||
OCELOT(48, ABSTRACT_TAMEABLE_ANIMAL), // agj
|
||||
WOLF(86, ABSTRACT_TAMEABLE_ANIMAL), // agy
|
||||
|
||||
ABSTRACT_PARROT(-1, ABSTRACT_TAMEABLE_ANIMAL), // agr
|
||||
PARROT(50, ABSTRACT_PARROT), // agk
|
||||
|
||||
// Horses
|
||||
ABSTRACT_HORSE(-1, ABSTRACT_ANIMAL), // aha
|
||||
CHESTED_HORSE(-1, ABSTRACT_HORSE), // agz
|
||||
DONKEY(11, CHESTED_HORSE), // ahb
|
||||
MULE(46, CHESTED_HORSE), // ahf
|
||||
LLAMA(36, CHESTED_HORSE), // ahe
|
||||
HORSE(29, ABSTRACT_HORSE), // ahc
|
||||
SKELETON_HORSE(63, ABSTRACT_HORSE), // ahg
|
||||
ZOMBIE_HORSE(88, ABSTRACT_HORSE), // ahi
|
||||
|
||||
// Golem
|
||||
ABSTRACT_GOLEM(-1, ABSTRACT_CREATURE), // agc
|
||||
SNOW_GOLEM(66, ABSTRACT_GOLEM), // ags
|
||||
IRON_GOLEM(80, ABSTRACT_GOLEM), // agw
|
||||
SHULKER(59, ABSTRACT_GOLEM), // ajx
|
||||
|
||||
// Fish
|
||||
ABSTRACT_FISHES(-1, ABSTRACT_CREATURE), // agb
|
||||
COD(8, ABSTRACT_FISHES), // agf
|
||||
PUFFERFISH(52, ABSTRACT_FISHES), // agn
|
||||
SALMON(57, ABSTRACT_FISHES), // agp
|
||||
TROPICAL_FISH(72, ABSTRACT_FISHES), // agu
|
||||
|
||||
// Monsters
|
||||
ABSTRACT_MONSTER(-1, ABSTRACT_CREATURE), // ajs
|
||||
BLAZE(4, ABSTRACT_MONSTER), // ajd
|
||||
CREEPER(10, ABSTRACT_MONSTER), // ajf
|
||||
ENDERMITE(19, ABSTRACT_MONSTER), // ajj
|
||||
ENDERMAN(18, ABSTRACT_MONSTER), // aji
|
||||
GIANT(27, ABSTRACT_MONSTER), // ajn
|
||||
SILVERFISH(61, ABSTRACT_MONSTER), // ajy
|
||||
VEX(78, ABSTRACT_MONSTER), // ake
|
||||
WITCH(82, ABSTRACT_MONSTER), // akg
|
||||
WITHER(83, ABSTRACT_MONSTER), // aij
|
||||
|
||||
// Illagers
|
||||
ABSTRACT_ILLAGER_BASE(-1, ABSTRACT_MONSTER), // ajb
|
||||
ABSTRACT_EVO_ILLU_ILLAGER(-1, ABSTRACT_ILLAGER_BASE), // akb
|
||||
EVOKER(21, ABSTRACT_EVO_ILLU_ILLAGER), // ajl
|
||||
ILLUSIONER(31, ABSTRACT_EVO_ILLU_ILLAGER), // ajq
|
||||
VINDICATOR(81, ABSTRACT_ILLAGER_BASE), // akf
|
||||
|
||||
// Skeletons
|
||||
ABSTRACT_SKELETON(-1, ABSTRACT_MONSTER), // ajc
|
||||
SKELETON(62, ABSTRACT_SKELETON), // ajz
|
||||
STRAY(71, ABSTRACT_SKELETON), // akd
|
||||
WITHER_SKELETON(84, ABSTRACT_SKELETON), // akh
|
||||
|
||||
// Guardians
|
||||
GUARDIAN(28, ABSTRACT_MONSTER), // ajo
|
||||
ELDER_GUARDIAN(15, GUARDIAN), // ajh
|
||||
|
||||
// Spiders
|
||||
SPIDER(69, ABSTRACT_MONSTER), // akc
|
||||
CAVE_SPIDER(6, SPIDER), // aje
|
||||
|
||||
// Zombies - META CHECKED
|
||||
ZOMBIE(87, ABSTRACT_MONSTER), // aki
|
||||
DROWNED(14, ZOMBIE), // ajg
|
||||
HUSK(30, ZOMBIE), // ajp
|
||||
ZOMBIE_PIGMAN(53, ZOMBIE), // aju
|
||||
ZOMBIE_VILLAGER(89, ZOMBIE), // akj
|
||||
|
||||
// Flying entities
|
||||
ABSTRACT_FLYING(-1, ABSTRACT_INSENTIENT), // abt
|
||||
GHAST(26, ABSTRACT_FLYING), // ajm
|
||||
PHANTOM(90, ABSTRACT_FLYING), // ajt
|
||||
|
||||
ABSTRACT_AMBIENT(-1, ABSTRACT_INSENTIENT), // afy
|
||||
BAT(3, ABSTRACT_AMBIENT), // afz
|
||||
|
||||
ABSTRACT_WATERMOB(-1, ABSTRACT_INSENTIENT), // agx
|
||||
SQUID(70, ABSTRACT_WATERMOB), // agt
|
||||
DOLPHIN(12, ABSTRACT_WATERMOB),
|
||||
|
||||
// Slimes
|
||||
SLIME(64, ABSTRACT_INSENTIENT), // aka
|
||||
MAGMA_CUBE(38, SLIME), // ajr
|
||||
|
||||
// Hangable objects
|
||||
ABSTRACT_HANGING(-1, ENTITY), // aim
|
||||
LEASH_KNOT(35, ABSTRACT_HANGING), // aio
|
||||
ITEM_FRAME(33, ABSTRACT_HANGING), // ain
|
||||
PAINTING(49, ABSTRACT_HANGING), // aiq
|
||||
|
||||
ABSTRACT_LIGHTNING(-1, ENTITY), // aiu
|
||||
LIGHTNING_BOLT(91, ABSTRACT_LIGHTNING), // aiv
|
||||
|
||||
// Arrows
|
||||
ABSTRACT_ARROW(-1, ENTITY), // akw
|
||||
ARROW(2, ABSTRACT_ARROW), // aky
|
||||
SPECTRAL_ARROW(68, ABSTRACT_ARROW), // alk
|
||||
TRIDENT(94, ABSTRACT_ARROW), // alq
|
||||
|
||||
// Fireballs
|
||||
ABSTRACT_FIREBALL(-1, ENTITY), // akx
|
||||
DRAGON_FIREBALL(13, ABSTRACT_FIREBALL), // akz
|
||||
FIREBALL(34, ABSTRACT_FIREBALL), // ald
|
||||
SMALL_FIREBALL(65, ABSTRACT_FIREBALL), // ali
|
||||
WITHER_SKULL(85, ABSTRACT_FIREBALL), // alr
|
||||
|
||||
// Projectiles
|
||||
PROJECTILE_ABSTRACT(-1, ENTITY), // all
|
||||
SNOWBALL(67, PROJECTILE_ABSTRACT), // alj
|
||||
ENDER_PEARL(75, PROJECTILE_ABSTRACT), // aln
|
||||
EGG(74, PROJECTILE_ABSTRACT), // alm
|
||||
POTION(77, PROJECTILE_ABSTRACT), // alp
|
||||
EXPERIENCE_BOTTLE(76, PROJECTILE_ABSTRACT), // alo
|
||||
|
||||
// Vehicles
|
||||
MINECART_ABSTRACT(-1, ENTITY), // alt
|
||||
CHESTED_MINECART_ABSTRACT(-1, MINECART_ABSTRACT), // alu
|
||||
CHEST_MINECART(40, CHESTED_MINECART_ABSTRACT), // alx
|
||||
HOPPER_MINECART(43, CHESTED_MINECART_ABSTRACT), // ama
|
||||
MINECART(39, MINECART_ABSTRACT), // alw
|
||||
FURNACE_MINECART(42, MINECART_ABSTRACT), // alz
|
||||
COMMAND_BLOCK_MINECART(41, MINECART_ABSTRACT), // aly
|
||||
TNT_MINECART(45, MINECART_ABSTRACT), // amc
|
||||
SPAWNER_MINECART(44, MINECART_ABSTRACT), // amb
|
||||
BOAT(5, ENTITY); // alv
|
||||
|
||||
private static final Map<Integer, EntityType> TYPES = new HashMap<>();
|
||||
|
||||
private final int id;
|
||||
private final EntityType parent;
|
||||
|
||||
EntityType(int id) {
|
||||
this.id = id;
|
||||
this.parent = null;
|
||||
}
|
||||
|
||||
EntityType(int id, EntityType parent) {
|
||||
this.id = id;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
static {
|
||||
for (EntityType type : EntityType.values()) {
|
||||
TYPES.put(type.id, type);
|
||||
}
|
||||
}
|
||||
|
||||
public static Optional<EntityType> findById(int id) {
|
||||
if (id == -1) // Check if this is called
|
||||
return Optional.empty();
|
||||
return Optional.ofNullable(TYPES.get(id));
|
||||
}
|
||||
}
|
||||
|
||||
public enum ObjectType implements us.myles.ViaVersion.api.entities.ObjectType {
|
||||
BOAT(1, EntityType.BOAT),
|
||||
ITEM(2, EntityType.ITEM),
|
||||
AREA_EFFECT_CLOUD(3, EntityType.AREA_EFFECT_CLOUD),
|
||||
MINECART(10, EntityType.MINECART),
|
||||
TNT_PRIMED(50, EntityType.TNT),
|
||||
ENDER_CRYSTAL(51, EntityType.END_CRYSTAL),
|
||||
TIPPED_ARROW(60, EntityType.ARROW),
|
||||
SNOWBALL(61, EntityType.SNOWBALL),
|
||||
EGG(62, EntityType.EGG),
|
||||
FIREBALL(63, EntityType.FIREBALL),
|
||||
SMALL_FIREBALL(64, EntityType.SMALL_FIREBALL),
|
||||
ENDER_PEARL(65, EntityType.ENDER_PEARL),
|
||||
WITHER_SKULL(66, EntityType.WITHER_SKULL),
|
||||
SHULKER_BULLET(67, EntityType.SHULKER_BULLET),
|
||||
LLAMA_SPIT(68, EntityType.LLAMA_SPIT),
|
||||
FALLING_BLOCK(70, EntityType.FALLING_BLOCK),
|
||||
ITEM_FRAME(71, EntityType.ITEM_FRAME),
|
||||
EYE_OF_ENDER(72, EntityType.EYE_OF_ENDER),
|
||||
POTION(73, EntityType.POTION),
|
||||
EXPERIENCE_BOTTLE(75, EntityType.EXPERIENCE_BOTTLE),
|
||||
FIREWORK_ROCKET(76, EntityType.FIREWORK_ROCKET),
|
||||
LEASH(77, EntityType.LEASH_KNOT),
|
||||
ARMOR_STAND(78, EntityType.ARMOR_STAND),
|
||||
EVOKER_FANGS(79, EntityType.EVOKER_FANGS),
|
||||
FISHIHNG_HOOK(90, EntityType.FISHING_BOBBER),
|
||||
SPECTRAL_ARROW(91, EntityType.SPECTRAL_ARROW),
|
||||
DRAGON_FIREBALL(93, EntityType.DRAGON_FIREBALL),
|
||||
TRIDENT(94, EntityType.TRIDENT);
|
||||
|
||||
private static final Map<Integer, ObjectType> TYPES = new HashMap<>();
|
||||
|
||||
private final int id;
|
||||
private final EntityType type;
|
||||
|
||||
static {
|
||||
for (ObjectType type : ObjectType.values()) {
|
||||
TYPES.put(type.id, type);
|
||||
}
|
||||
}
|
||||
|
||||
ObjectType(int id, EntityType type) {
|
||||
this.id = id;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public static Optional<ObjectType> findById(int id) {
|
||||
if (id == -1)
|
||||
return Optional.empty();
|
||||
return Optional.ofNullable(TYPES.get(id));
|
||||
}
|
||||
|
||||
public static Optional<EntityType> getPCEntity(int id) {
|
||||
Optional<ObjectType> output = findById(id);
|
||||
if (!output.isPresent())
|
||||
return Optional.empty();
|
||||
return Optional.of(output.get().type);
|
||||
}
|
||||
|
||||
public static Optional<ObjectType> fromEntityType(EntityType type) {
|
||||
for (ObjectType ent : ObjectType.values())
|
||||
if (ent.type == type)
|
||||
return Optional.of(ent);
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
package us.myles.ViaVersion.api.entities;
|
||||
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
public class Entity1_14Types {
|
||||
|
||||
public static EntityType getTypeFromId(int typeID) {
|
||||
Optional<EntityType> type = EntityType.findById(typeID);
|
||||
|
||||
if (!type.isPresent()) {
|
||||
Via.getPlatform().getLogger().severe("Could not find 1.14 type id " + typeID);
|
||||
return EntityType.ENTITY; // Fall back to the basic ENTITY
|
||||
}
|
||||
|
||||
return type.get();
|
||||
}
|
||||
|
||||
public enum EntityType implements us.myles.ViaVersion.api.entities.EntityType {
|
||||
// Auto generated
|
||||
|
||||
ENTITY(-1),
|
||||
|
||||
AREA_EFFECT_CLOUD(0, ENTITY),
|
||||
END_CRYSTAL(17, ENTITY),
|
||||
EVOKER_FANGS(21, ENTITY),
|
||||
EXPERIENCE_ORB(23, ENTITY),
|
||||
EYE_OF_ENDER(24, ENTITY),
|
||||
FALLING_BLOCK(25, ENTITY),
|
||||
FIREWORK_ROCKET(26, ENTITY),
|
||||
ITEM(34, ENTITY),
|
||||
LLAMA_SPIT(39, ENTITY),
|
||||
TNT(58, ENTITY),
|
||||
SHULKER_BULLET(63, ENTITY),
|
||||
FISHING_BOBBER(101, ENTITY),
|
||||
|
||||
LIVINGENTITY(-1, ENTITY),
|
||||
ARMOR_STAND(1, LIVINGENTITY),
|
||||
PLAYER(100, LIVINGENTITY),
|
||||
|
||||
ABSTRACT_INSENTIENT(-1, LIVINGENTITY),
|
||||
ENDER_DRAGON(18, ABSTRACT_INSENTIENT),
|
||||
|
||||
ABSTRACT_CREATURE(-1, ABSTRACT_INSENTIENT),
|
||||
|
||||
ABSTRACT_AGEABLE(-1, ABSTRACT_CREATURE),
|
||||
VILLAGER(84, ABSTRACT_AGEABLE),
|
||||
WANDERING_TRADER(88, ABSTRACT_AGEABLE),
|
||||
|
||||
// Animals
|
||||
ABSTRACT_ANIMAL(-1, ABSTRACT_AGEABLE),
|
||||
DOLPHIN(13, ABSTRACT_INSENTIENT),
|
||||
CHICKEN(8, ABSTRACT_ANIMAL),
|
||||
COW(10, ABSTRACT_ANIMAL),
|
||||
MOOSHROOM(49, COW),
|
||||
PANDA(52, ABSTRACT_INSENTIENT),
|
||||
PIG(54, ABSTRACT_ANIMAL),
|
||||
POLAR_BEAR(57, ABSTRACT_ANIMAL),
|
||||
RABBIT(59, ABSTRACT_ANIMAL),
|
||||
SHEEP(61, ABSTRACT_ANIMAL),
|
||||
TURTLE(77, ABSTRACT_ANIMAL),
|
||||
FOX(27, ABSTRACT_ANIMAL),
|
||||
|
||||
ABSTRACT_TAMEABLE_ANIMAL(-1, ABSTRACT_ANIMAL),
|
||||
CAT(6, ABSTRACT_TAMEABLE_ANIMAL),
|
||||
OCELOT(50, ABSTRACT_TAMEABLE_ANIMAL),
|
||||
WOLF(93, ABSTRACT_TAMEABLE_ANIMAL),
|
||||
|
||||
ABSTRACT_PARROT(-1, ABSTRACT_TAMEABLE_ANIMAL),
|
||||
PARROT(53, ABSTRACT_PARROT),
|
||||
|
||||
// Horses
|
||||
ABSTRACT_HORSE(-1, ABSTRACT_ANIMAL),
|
||||
CHESTED_HORSE(-1, ABSTRACT_HORSE),
|
||||
DONKEY(12, CHESTED_HORSE),
|
||||
MULE(48, CHESTED_HORSE),
|
||||
LLAMA(38, CHESTED_HORSE),
|
||||
TRADER_LLAMA(75, CHESTED_HORSE),
|
||||
HORSE(31, ABSTRACT_HORSE),
|
||||
SKELETON_HORSE(66, ABSTRACT_HORSE),
|
||||
ZOMBIE_HORSE(95, ABSTRACT_HORSE),
|
||||
|
||||
// Golem
|
||||
ABSTRACT_GOLEM(-1, ABSTRACT_CREATURE),
|
||||
SNOW_GOLEM(69, ABSTRACT_GOLEM),
|
||||
IRON_GOLEM(85, ABSTRACT_GOLEM),
|
||||
SHULKER(62, ABSTRACT_GOLEM),
|
||||
|
||||
// Fish
|
||||
ABSTRACT_FISHES(-1, ABSTRACT_CREATURE),
|
||||
COD(9, ABSTRACT_FISHES),
|
||||
PUFFERFISH(55, ABSTRACT_FISHES),
|
||||
SALMON(60, ABSTRACT_FISHES),
|
||||
TROPICAL_FISH(76, ABSTRACT_FISHES),
|
||||
|
||||
// Monsters
|
||||
ABSTRACT_MONSTER(-1, ABSTRACT_CREATURE),
|
||||
BLAZE(4, ABSTRACT_MONSTER),
|
||||
CREEPER(11, ABSTRACT_MONSTER),
|
||||
ENDERMITE(20, ABSTRACT_MONSTER),
|
||||
ENDERMAN(19, ABSTRACT_MONSTER),
|
||||
GIANT(29, ABSTRACT_MONSTER),
|
||||
SILVERFISH(64, ABSTRACT_MONSTER),
|
||||
VEX(83, ABSTRACT_MONSTER),
|
||||
WITCH(89, ABSTRACT_MONSTER),
|
||||
WITHER(90, ABSTRACT_MONSTER),
|
||||
RAVAGER(98, ABSTRACT_MONSTER),
|
||||
|
||||
// Illagers
|
||||
ABSTRACT_ILLAGER_BASE(-1, ABSTRACT_MONSTER),
|
||||
ABSTRACT_EVO_ILLU_ILLAGER(-1, ABSTRACT_ILLAGER_BASE),
|
||||
EVOKER(22, ABSTRACT_EVO_ILLU_ILLAGER),
|
||||
ILLUSIONER(33, ABSTRACT_EVO_ILLU_ILLAGER),
|
||||
VINDICATOR(86, ABSTRACT_ILLAGER_BASE),
|
||||
PILLAGER(87, ABSTRACT_ILLAGER_BASE),
|
||||
|
||||
// Skeletons
|
||||
ABSTRACT_SKELETON(-1, ABSTRACT_MONSTER),
|
||||
SKELETON(65, ABSTRACT_SKELETON),
|
||||
STRAY(74, ABSTRACT_SKELETON),
|
||||
WITHER_SKELETON(91, ABSTRACT_SKELETON),
|
||||
|
||||
// Guardians
|
||||
GUARDIAN(30, ABSTRACT_MONSTER),
|
||||
ELDER_GUARDIAN(16, GUARDIAN),
|
||||
|
||||
// Spiders
|
||||
SPIDER(72, ABSTRACT_MONSTER),
|
||||
CAVE_SPIDER(7, SPIDER),
|
||||
|
||||
// Zombies - META CHECKED
|
||||
ZOMBIE(94, ABSTRACT_MONSTER),
|
||||
DROWNED(15, ZOMBIE),
|
||||
HUSK(32, ZOMBIE),
|
||||
ZOMBIE_PIGMAN(56, ZOMBIE),
|
||||
ZOMBIE_VILLAGER(96, ZOMBIE),
|
||||
|
||||
// Flying entities
|
||||
ABSTRACT_FLYING(-1, ABSTRACT_INSENTIENT),
|
||||
GHAST(28, ABSTRACT_FLYING),
|
||||
PHANTOM(97, ABSTRACT_FLYING),
|
||||
|
||||
ABSTRACT_AMBIENT(-1, ABSTRACT_INSENTIENT),
|
||||
BAT(3, ABSTRACT_AMBIENT),
|
||||
|
||||
ABSTRACT_WATERMOB(-1, ABSTRACT_INSENTIENT),
|
||||
SQUID(73, ABSTRACT_WATERMOB),
|
||||
|
||||
// Slimes
|
||||
SLIME(67, ABSTRACT_INSENTIENT),
|
||||
MAGMA_CUBE(40, SLIME),
|
||||
|
||||
// Hangable objects
|
||||
ABSTRACT_HANGING(-1, ENTITY),
|
||||
LEASH_KNOT(37, ABSTRACT_HANGING),
|
||||
ITEM_FRAME(35, ABSTRACT_HANGING),
|
||||
PAINTING(51, ABSTRACT_HANGING),
|
||||
|
||||
ABSTRACT_LIGHTNING(-1, ENTITY),
|
||||
LIGHTNING_BOLT(99, ABSTRACT_LIGHTNING),
|
||||
|
||||
// Arrows
|
||||
ABSTRACT_ARROW(-1, ENTITY),
|
||||
ARROW(2, ABSTRACT_ARROW),
|
||||
SPECTRAL_ARROW(71, ABSTRACT_ARROW),
|
||||
TRIDENT(82, ABSTRACT_ARROW),
|
||||
|
||||
// Fireballs
|
||||
ABSTRACT_FIREBALL(-1, ENTITY),
|
||||
DRAGON_FIREBALL(14, ABSTRACT_FIREBALL),
|
||||
FIREBALL(36, ABSTRACT_FIREBALL),
|
||||
SMALL_FIREBALL(68, ABSTRACT_FIREBALL),
|
||||
WITHER_SKULL(92, ABSTRACT_FIREBALL),
|
||||
|
||||
// Projectiles
|
||||
PROJECTILE_ABSTRACT(-1, ENTITY),
|
||||
SNOWBALL(70, PROJECTILE_ABSTRACT),
|
||||
ENDER_PEARL(79, PROJECTILE_ABSTRACT),
|
||||
EGG(78, PROJECTILE_ABSTRACT),
|
||||
POTION(81, PROJECTILE_ABSTRACT),
|
||||
EXPERIENCE_BOTTLE(80, PROJECTILE_ABSTRACT),
|
||||
|
||||
// Vehicles
|
||||
MINECART_ABSTRACT(-1, ENTITY),
|
||||
CHESTED_MINECART_ABSTRACT(-1, MINECART_ABSTRACT),
|
||||
CHEST_MINECART(42, CHESTED_MINECART_ABSTRACT),
|
||||
HOPPER_MINECART(45, CHESTED_MINECART_ABSTRACT),
|
||||
MINECART(41, MINECART_ABSTRACT),
|
||||
FURNACE_MINECART(44, MINECART_ABSTRACT),
|
||||
COMMAND_BLOCK_MINECART(43, MINECART_ABSTRACT),
|
||||
TNT_MINECART(47, MINECART_ABSTRACT),
|
||||
SPAWNER_MINECART(46, MINECART_ABSTRACT),
|
||||
BOAT(5, ENTITY),
|
||||
;
|
||||
|
||||
private static final Map<Integer, EntityType> TYPES = new HashMap<>();
|
||||
|
||||
private final int id;
|
||||
private final EntityType parent;
|
||||
|
||||
EntityType(int id) {
|
||||
this.id = id;
|
||||
this.parent = null;
|
||||
}
|
||||
|
||||
EntityType(int id, EntityType parent) {
|
||||
this.id = id;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
static {
|
||||
for (EntityType type : EntityType.values()) {
|
||||
TYPES.put(type.id, type);
|
||||
}
|
||||
}
|
||||
|
||||
public static Optional<EntityType> findById(int id) {
|
||||
if (id == -1)
|
||||
return Optional.empty();
|
||||
return Optional.ofNullable(TYPES.get(id));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
package us.myles.ViaVersion.api.entities;
|
||||
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
public class Entity1_15Types {
|
||||
|
||||
public static EntityType getTypeFromId(int typeID) {
|
||||
Optional<EntityType> type = EntityType.findById(typeID);
|
||||
|
||||
if (!type.isPresent()) {
|
||||
Via.getPlatform().getLogger().severe("Could not find 1.15 type id " + typeID);
|
||||
return EntityType.ENTITY; // Fall back to the basic ENTITY
|
||||
}
|
||||
|
||||
return type.get();
|
||||
}
|
||||
|
||||
public enum EntityType implements us.myles.ViaVersion.api.entities.EntityType {
|
||||
ENTITY(-1),
|
||||
|
||||
AREA_EFFECT_CLOUD(0, ENTITY),
|
||||
END_CRYSTAL(18, ENTITY),
|
||||
EVOKER_FANGS(22, ENTITY),
|
||||
EXPERIENCE_ORB(24, ENTITY),
|
||||
EYE_OF_ENDER(25, ENTITY),
|
||||
FALLING_BLOCK(26, ENTITY),
|
||||
FIREWORK_ROCKET(27, ENTITY),
|
||||
ITEM(35, ENTITY),
|
||||
LLAMA_SPIT(40, ENTITY),
|
||||
TNT(59, ENTITY),
|
||||
SHULKER_BULLET(64, ENTITY),
|
||||
FISHING_BOBBER(102, ENTITY),
|
||||
|
||||
LIVINGENTITY(-1, ENTITY),
|
||||
ARMOR_STAND(1, LIVINGENTITY),
|
||||
PLAYER(101, LIVINGENTITY),
|
||||
|
||||
ABSTRACT_INSENTIENT(-1, LIVINGENTITY),
|
||||
ENDER_DRAGON(19, ABSTRACT_INSENTIENT),
|
||||
|
||||
BEE(4, ABSTRACT_INSENTIENT),
|
||||
|
||||
ABSTRACT_CREATURE(-1, ABSTRACT_INSENTIENT),
|
||||
|
||||
ABSTRACT_AGEABLE(-1, ABSTRACT_CREATURE),
|
||||
VILLAGER(85, ABSTRACT_AGEABLE),
|
||||
WANDERING_TRADER(89, ABSTRACT_AGEABLE),
|
||||
|
||||
// Animals
|
||||
ABSTRACT_ANIMAL(-1, ABSTRACT_AGEABLE),
|
||||
DOLPHIN(14, ABSTRACT_INSENTIENT),
|
||||
CHICKEN(9, ABSTRACT_ANIMAL),
|
||||
COW(11, ABSTRACT_ANIMAL),
|
||||
MOOSHROOM(50, COW),
|
||||
PANDA(53, ABSTRACT_INSENTIENT),
|
||||
PIG(55, ABSTRACT_ANIMAL),
|
||||
POLAR_BEAR(58, ABSTRACT_ANIMAL),
|
||||
RABBIT(60, ABSTRACT_ANIMAL),
|
||||
SHEEP(62, ABSTRACT_ANIMAL),
|
||||
TURTLE(78, ABSTRACT_ANIMAL),
|
||||
FOX(28, ABSTRACT_ANIMAL),
|
||||
|
||||
ABSTRACT_TAMEABLE_ANIMAL(-1, ABSTRACT_ANIMAL),
|
||||
CAT(7, ABSTRACT_TAMEABLE_ANIMAL),
|
||||
OCELOT(51, ABSTRACT_TAMEABLE_ANIMAL),
|
||||
WOLF(94, ABSTRACT_TAMEABLE_ANIMAL),
|
||||
|
||||
ABSTRACT_PARROT(-1, ABSTRACT_TAMEABLE_ANIMAL),
|
||||
PARROT(54, ABSTRACT_PARROT),
|
||||
|
||||
// Horses
|
||||
ABSTRACT_HORSE(-1, ABSTRACT_ANIMAL),
|
||||
CHESTED_HORSE(-1, ABSTRACT_HORSE),
|
||||
DONKEY(13, CHESTED_HORSE),
|
||||
MULE(49, CHESTED_HORSE),
|
||||
LLAMA(39, CHESTED_HORSE),
|
||||
TRADER_LLAMA(76, CHESTED_HORSE),
|
||||
HORSE(32, ABSTRACT_HORSE),
|
||||
SKELETON_HORSE(67, ABSTRACT_HORSE),
|
||||
ZOMBIE_HORSE(96, ABSTRACT_HORSE),
|
||||
|
||||
// Golem
|
||||
ABSTRACT_GOLEM(-1, ABSTRACT_CREATURE),
|
||||
SNOW_GOLEM(70, ABSTRACT_GOLEM),
|
||||
IRON_GOLEM(86, ABSTRACT_GOLEM),
|
||||
SHULKER(63, ABSTRACT_GOLEM),
|
||||
|
||||
// Fish
|
||||
ABSTRACT_FISHES(-1, ABSTRACT_CREATURE),
|
||||
COD(10, ABSTRACT_FISHES),
|
||||
PUFFERFISH(56, ABSTRACT_FISHES),
|
||||
SALMON(61, ABSTRACT_FISHES),
|
||||
TROPICAL_FISH(77, ABSTRACT_FISHES),
|
||||
|
||||
// Monsters
|
||||
ABSTRACT_MONSTER(-1, ABSTRACT_CREATURE),
|
||||
BLAZE(5, ABSTRACT_MONSTER),
|
||||
CREEPER(12, ABSTRACT_MONSTER),
|
||||
ENDERMITE(21, ABSTRACT_MONSTER),
|
||||
ENDERMAN(20, ABSTRACT_MONSTER),
|
||||
GIANT(30, ABSTRACT_MONSTER),
|
||||
SILVERFISH(65, ABSTRACT_MONSTER),
|
||||
VEX(84, ABSTRACT_MONSTER),
|
||||
WITCH(90, ABSTRACT_MONSTER),
|
||||
WITHER(91, ABSTRACT_MONSTER),
|
||||
RAVAGER(99, ABSTRACT_MONSTER),
|
||||
|
||||
// Illagers
|
||||
ABSTRACT_ILLAGER_BASE(-1, ABSTRACT_MONSTER),
|
||||
ABSTRACT_EVO_ILLU_ILLAGER(-1, ABSTRACT_ILLAGER_BASE),
|
||||
EVOKER(23, ABSTRACT_EVO_ILLU_ILLAGER),
|
||||
ILLUSIONER(34, ABSTRACT_EVO_ILLU_ILLAGER),
|
||||
VINDICATOR(87, ABSTRACT_ILLAGER_BASE),
|
||||
PILLAGER(88, ABSTRACT_ILLAGER_BASE),
|
||||
|
||||
// Skeletons
|
||||
ABSTRACT_SKELETON(-1, ABSTRACT_MONSTER),
|
||||
SKELETON(66, ABSTRACT_SKELETON),
|
||||
STRAY(75, ABSTRACT_SKELETON),
|
||||
WITHER_SKELETON(92, ABSTRACT_SKELETON),
|
||||
|
||||
// Guardians
|
||||
GUARDIAN(31, ABSTRACT_MONSTER),
|
||||
ELDER_GUARDIAN(17, GUARDIAN),
|
||||
|
||||
// Spiders
|
||||
SPIDER(73, ABSTRACT_MONSTER),
|
||||
CAVE_SPIDER(8, SPIDER),
|
||||
|
||||
// Zombies
|
||||
ZOMBIE(95, ABSTRACT_MONSTER),
|
||||
DROWNED(16, ZOMBIE),
|
||||
HUSK(33, ZOMBIE),
|
||||
ZOMBIE_PIGMAN(57, ZOMBIE),
|
||||
ZOMBIE_VILLAGER(97, ZOMBIE),
|
||||
|
||||
// Flying entities
|
||||
ABSTRACT_FLYING(-1, ABSTRACT_INSENTIENT),
|
||||
GHAST(29, ABSTRACT_FLYING),
|
||||
PHANTOM(98, ABSTRACT_FLYING),
|
||||
|
||||
ABSTRACT_AMBIENT(-1, ABSTRACT_INSENTIENT),
|
||||
BAT(3, ABSTRACT_AMBIENT),
|
||||
|
||||
ABSTRACT_WATERMOB(-1, ABSTRACT_INSENTIENT),
|
||||
SQUID(74, ABSTRACT_WATERMOB),
|
||||
|
||||
// Slimes
|
||||
SLIME(68, ABSTRACT_INSENTIENT),
|
||||
MAGMA_CUBE(41, SLIME),
|
||||
|
||||
// Hangable objects
|
||||
ABSTRACT_HANGING(-1, ENTITY),
|
||||
LEASH_KNOT(38, ABSTRACT_HANGING),
|
||||
ITEM_FRAME(36, ABSTRACT_HANGING),
|
||||
PAINTING(52, ABSTRACT_HANGING),
|
||||
|
||||
ABSTRACT_LIGHTNING(-1, ENTITY),
|
||||
LIGHTNING_BOLT(100, ABSTRACT_LIGHTNING),
|
||||
|
||||
// Arrows
|
||||
ABSTRACT_ARROW(-1, ENTITY),
|
||||
ARROW(2, ABSTRACT_ARROW),
|
||||
SPECTRAL_ARROW(72, ABSTRACT_ARROW),
|
||||
TRIDENT(83, ABSTRACT_ARROW),
|
||||
|
||||
// Fireballs
|
||||
ABSTRACT_FIREBALL(-1, ENTITY),
|
||||
DRAGON_FIREBALL(15, ABSTRACT_FIREBALL),
|
||||
FIREBALL(37, ABSTRACT_FIREBALL),
|
||||
SMALL_FIREBALL(69, ABSTRACT_FIREBALL),
|
||||
WITHER_SKULL(93, ABSTRACT_FIREBALL),
|
||||
|
||||
// Projectiles
|
||||
PROJECTILE_ABSTRACT(-1, ENTITY),
|
||||
SNOWBALL(71, PROJECTILE_ABSTRACT),
|
||||
ENDER_PEARL(80, PROJECTILE_ABSTRACT),
|
||||
EGG(79, PROJECTILE_ABSTRACT),
|
||||
POTION(82, PROJECTILE_ABSTRACT),
|
||||
EXPERIENCE_BOTTLE(81, PROJECTILE_ABSTRACT),
|
||||
|
||||
// Vehicles
|
||||
MINECART_ABSTRACT(-1, ENTITY),
|
||||
CHESTED_MINECART_ABSTRACT(-1, MINECART_ABSTRACT),
|
||||
CHEST_MINECART(43, CHESTED_MINECART_ABSTRACT),
|
||||
HOPPER_MINECART(46, CHESTED_MINECART_ABSTRACT),
|
||||
MINECART(42, MINECART_ABSTRACT),
|
||||
FURNACE_MINECART(45, MINECART_ABSTRACT),
|
||||
COMMAND_BLOCK_MINECART(44, MINECART_ABSTRACT),
|
||||
TNT_MINECART(48, MINECART_ABSTRACT),
|
||||
SPAWNER_MINECART(47, MINECART_ABSTRACT),
|
||||
BOAT(6, ENTITY);
|
||||
|
||||
private static final Map<Integer, EntityType> TYPES = new HashMap<>();
|
||||
|
||||
private final int id;
|
||||
private final EntityType parent;
|
||||
|
||||
EntityType(int id) {
|
||||
this.id = id;
|
||||
this.parent = null;
|
||||
}
|
||||
|
||||
EntityType(int id, EntityType parent) {
|
||||
this.id = id;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
static {
|
||||
for (EntityType type : EntityType.values()) {
|
||||
TYPES.put(type.id, type);
|
||||
}
|
||||
}
|
||||
|
||||
public static Optional<EntityType> findById(int id) {
|
||||
if (id == -1)
|
||||
return Optional.empty();
|
||||
return Optional.ofNullable(TYPES.get(id));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
package us.myles.ViaVersion.api.entities;
|
||||
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
public class Entity1_16Types {
|
||||
|
||||
public static EntityType getTypeFromId(int typeID) {
|
||||
Optional<EntityType> type = EntityType.findById(typeID);
|
||||
|
||||
if (!type.isPresent()) {
|
||||
Via.getPlatform().getLogger().severe("Could not find 1.16 type id " + typeID);
|
||||
return EntityType.ENTITY; // Fall back to the basic ENTITY
|
||||
}
|
||||
|
||||
return type.get();
|
||||
}
|
||||
|
||||
public enum EntityType implements us.myles.ViaVersion.api.entities.EntityType {
|
||||
ENTITY(-1),
|
||||
|
||||
AREA_EFFECT_CLOUD(0, ENTITY),
|
||||
END_CRYSTAL(18, ENTITY),
|
||||
EVOKER_FANGS(23, ENTITY),
|
||||
EXPERIENCE_ORB(24, ENTITY),
|
||||
EYE_OF_ENDER(25, ENTITY),
|
||||
FALLING_BLOCK(26, ENTITY),
|
||||
FIREWORK_ROCKET(27, ENTITY),
|
||||
ITEM(37, ENTITY),
|
||||
LLAMA_SPIT(43, ENTITY),
|
||||
TNT(63, ENTITY),
|
||||
SHULKER_BULLET(70, ENTITY),
|
||||
FISHING_BOBBER(106, ENTITY),
|
||||
|
||||
LIVINGENTITY(-1, ENTITY),
|
||||
ARMOR_STAND(1, LIVINGENTITY),
|
||||
PLAYER(105, LIVINGENTITY),
|
||||
|
||||
ABSTRACT_INSENTIENT(-1, LIVINGENTITY),
|
||||
ENDER_DRAGON(19, ABSTRACT_INSENTIENT),
|
||||
|
||||
BEE(4, ABSTRACT_INSENTIENT),
|
||||
|
||||
ABSTRACT_CREATURE(-1, ABSTRACT_INSENTIENT),
|
||||
|
||||
ABSTRACT_AGEABLE(-1, ABSTRACT_CREATURE),
|
||||
VILLAGER(92, ABSTRACT_AGEABLE),
|
||||
WANDERING_TRADER(94, ABSTRACT_AGEABLE),
|
||||
|
||||
// Animals
|
||||
ABSTRACT_ANIMAL(-1, ABSTRACT_AGEABLE),
|
||||
DOLPHIN(13, ABSTRACT_INSENTIENT),
|
||||
CHICKEN(9, ABSTRACT_ANIMAL),
|
||||
COW(11, ABSTRACT_ANIMAL),
|
||||
MOOSHROOM(53, COW),
|
||||
PANDA(56, ABSTRACT_INSENTIENT),
|
||||
PIG(59, ABSTRACT_ANIMAL),
|
||||
POLAR_BEAR(62, ABSTRACT_ANIMAL),
|
||||
RABBIT(65, ABSTRACT_ANIMAL),
|
||||
SHEEP(68, ABSTRACT_ANIMAL),
|
||||
TURTLE(90, ABSTRACT_ANIMAL),
|
||||
FOX(28, ABSTRACT_ANIMAL),
|
||||
|
||||
ABSTRACT_TAMEABLE_ANIMAL(-1, ABSTRACT_ANIMAL),
|
||||
CAT(7, ABSTRACT_TAMEABLE_ANIMAL),
|
||||
OCELOT(54, ABSTRACT_TAMEABLE_ANIMAL),
|
||||
WOLF(99, ABSTRACT_TAMEABLE_ANIMAL),
|
||||
|
||||
ABSTRACT_PARROT(-1, ABSTRACT_TAMEABLE_ANIMAL),
|
||||
PARROT(57, ABSTRACT_PARROT),
|
||||
|
||||
// Horses
|
||||
ABSTRACT_HORSE(-1, ABSTRACT_ANIMAL),
|
||||
CHESTED_HORSE(-1, ABSTRACT_HORSE),
|
||||
DONKEY(14, CHESTED_HORSE),
|
||||
MULE(52, CHESTED_HORSE),
|
||||
LLAMA(42, CHESTED_HORSE),
|
||||
TRADER_LLAMA(88, CHESTED_HORSE),
|
||||
HORSE(33, ABSTRACT_HORSE),
|
||||
SKELETON_HORSE(73, ABSTRACT_HORSE),
|
||||
ZOMBIE_HORSE(102, ABSTRACT_HORSE),
|
||||
|
||||
// Golem
|
||||
ABSTRACT_GOLEM(-1, ABSTRACT_CREATURE),
|
||||
SNOW_GOLEM(76, ABSTRACT_GOLEM),
|
||||
IRON_GOLEM(36, ABSTRACT_GOLEM),
|
||||
SHULKER(69, ABSTRACT_GOLEM),
|
||||
|
||||
// Fish
|
||||
ABSTRACT_FISHES(-1, ABSTRACT_CREATURE),
|
||||
COD(10, ABSTRACT_FISHES),
|
||||
PUFFERFISH(64, ABSTRACT_FISHES),
|
||||
SALMON(67, ABSTRACT_FISHES),
|
||||
TROPICAL_FISH(89, ABSTRACT_FISHES),
|
||||
|
||||
// Monsters
|
||||
ABSTRACT_MONSTER(-1, ABSTRACT_CREATURE),
|
||||
BLAZE(5, ABSTRACT_MONSTER),
|
||||
CREEPER(12, ABSTRACT_MONSTER),
|
||||
ENDERMITE(21, ABSTRACT_MONSTER),
|
||||
ENDERMAN(20, ABSTRACT_MONSTER),
|
||||
GIANT(30, ABSTRACT_MONSTER),
|
||||
SILVERFISH(71, ABSTRACT_MONSTER),
|
||||
VEX(91, ABSTRACT_MONSTER),
|
||||
WITCH(95, ABSTRACT_MONSTER),
|
||||
WITHER(96, ABSTRACT_MONSTER),
|
||||
RAVAGER(66, ABSTRACT_MONSTER),
|
||||
PIGLIN(60, ABSTRACT_MONSTER),
|
||||
|
||||
HOGLIN(32, ABSTRACT_ANIMAL),
|
||||
STRIDER(82, ABSTRACT_ANIMAL),
|
||||
ZOGLIN(100, ABSTRACT_MONSTER),
|
||||
|
||||
// Illagers
|
||||
ABSTRACT_ILLAGER_BASE(-1, ABSTRACT_MONSTER),
|
||||
ABSTRACT_EVO_ILLU_ILLAGER(-1, ABSTRACT_ILLAGER_BASE),
|
||||
EVOKER(22, ABSTRACT_EVO_ILLU_ILLAGER),
|
||||
ILLUSIONER(35, ABSTRACT_EVO_ILLU_ILLAGER),
|
||||
VINDICATOR(93, ABSTRACT_ILLAGER_BASE),
|
||||
PILLAGER(61, ABSTRACT_ILLAGER_BASE),
|
||||
|
||||
// Skeletons
|
||||
ABSTRACT_SKELETON(-1, ABSTRACT_MONSTER),
|
||||
SKELETON(72, ABSTRACT_SKELETON),
|
||||
STRAY(81, ABSTRACT_SKELETON),
|
||||
WITHER_SKELETON(97, ABSTRACT_SKELETON),
|
||||
|
||||
// Guardians
|
||||
GUARDIAN(31, ABSTRACT_MONSTER),
|
||||
ELDER_GUARDIAN(17, GUARDIAN),
|
||||
|
||||
// Spiders
|
||||
SPIDER(79, ABSTRACT_MONSTER),
|
||||
CAVE_SPIDER(8, SPIDER),
|
||||
|
||||
// Zombies
|
||||
ZOMBIE(101, ABSTRACT_MONSTER),
|
||||
DROWNED(16, ZOMBIE),
|
||||
HUSK(34, ZOMBIE),
|
||||
ZOMBIFIED_PIGLIN(104, ZOMBIE),
|
||||
ZOMBIE_VILLAGER(103, ZOMBIE),
|
||||
|
||||
// Flying entities
|
||||
ABSTRACT_FLYING(-1, ABSTRACT_INSENTIENT),
|
||||
GHAST(29, ABSTRACT_FLYING),
|
||||
PHANTOM(58, ABSTRACT_FLYING),
|
||||
|
||||
ABSTRACT_AMBIENT(-1, ABSTRACT_INSENTIENT),
|
||||
BAT(3, ABSTRACT_AMBIENT),
|
||||
|
||||
ABSTRACT_WATERMOB(-1, ABSTRACT_INSENTIENT),
|
||||
SQUID(80, ABSTRACT_WATERMOB),
|
||||
|
||||
// Slimes
|
||||
SLIME(74, ABSTRACT_INSENTIENT),
|
||||
MAGMA_CUBE(44, SLIME),
|
||||
|
||||
// Hangable objects
|
||||
ABSTRACT_HANGING(-1, ENTITY),
|
||||
LEASH_KNOT(40, ABSTRACT_HANGING),
|
||||
ITEM_FRAME(38, ABSTRACT_HANGING),
|
||||
PAINTING(55, ABSTRACT_HANGING),
|
||||
|
||||
ABSTRACT_LIGHTNING(-1, ENTITY),
|
||||
LIGHTNING_BOLT(41, ABSTRACT_LIGHTNING),
|
||||
|
||||
// Arrows
|
||||
ABSTRACT_ARROW(-1, ENTITY),
|
||||
ARROW(2, ABSTRACT_ARROW),
|
||||
SPECTRAL_ARROW(78, ABSTRACT_ARROW),
|
||||
TRIDENT(87, ABSTRACT_ARROW),
|
||||
|
||||
// Fireballs
|
||||
ABSTRACT_FIREBALL(-1, ENTITY),
|
||||
DRAGON_FIREBALL(15, ABSTRACT_FIREBALL),
|
||||
FIREBALL(39, ABSTRACT_FIREBALL),
|
||||
SMALL_FIREBALL(75, ABSTRACT_FIREBALL),
|
||||
WITHER_SKULL(98, ABSTRACT_FIREBALL),
|
||||
|
||||
// Projectiles
|
||||
PROJECTILE_ABSTRACT(-1, ENTITY),
|
||||
SNOWBALL(77, PROJECTILE_ABSTRACT),
|
||||
ENDER_PEARL(84, PROJECTILE_ABSTRACT),
|
||||
EGG(83, PROJECTILE_ABSTRACT),
|
||||
POTION(86, PROJECTILE_ABSTRACT),
|
||||
EXPERIENCE_BOTTLE(85, PROJECTILE_ABSTRACT),
|
||||
|
||||
// Vehicles
|
||||
MINECART_ABSTRACT(-1, ENTITY),
|
||||
CHESTED_MINECART_ABSTRACT(-1, MINECART_ABSTRACT),
|
||||
CHEST_MINECART(46, CHESTED_MINECART_ABSTRACT),
|
||||
HOPPER_MINECART(49, CHESTED_MINECART_ABSTRACT),
|
||||
MINECART(45, MINECART_ABSTRACT),
|
||||
FURNACE_MINECART(48, MINECART_ABSTRACT),
|
||||
COMMAND_BLOCK_MINECART(47, MINECART_ABSTRACT),
|
||||
TNT_MINECART(51, MINECART_ABSTRACT),
|
||||
SPAWNER_MINECART(50, MINECART_ABSTRACT),
|
||||
BOAT(6, ENTITY);
|
||||
|
||||
private static final Map<Integer, EntityType> TYPES = new HashMap<>();
|
||||
|
||||
private final int id;
|
||||
private final EntityType parent;
|
||||
|
||||
EntityType(int id) {
|
||||
this.id = id;
|
||||
this.parent = null;
|
||||
}
|
||||
|
||||
EntityType(int id, EntityType parent) {
|
||||
this.id = id;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
static {
|
||||
for (EntityType type : EntityType.values()) {
|
||||
TYPES.put(type.id, type);
|
||||
}
|
||||
}
|
||||
|
||||
public static Optional<EntityType> findById(int id) {
|
||||
if (id == -1)
|
||||
return Optional.empty();
|
||||
return Optional.ofNullable(TYPES.get(id));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
package us.myles.ViaVersion.api.entities;
|
||||
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
public class Entity1_16_2Types {
|
||||
|
||||
public static EntityType getTypeFromId(int typeID) {
|
||||
Optional<EntityType> type = EntityType.findById(typeID);
|
||||
if (!type.isPresent()) {
|
||||
Via.getPlatform().getLogger().severe("Could not find 1.16.2 type id " + typeID);
|
||||
return EntityType.ENTITY; // Fall back to the basic ENTITY
|
||||
}
|
||||
return type.get();
|
||||
}
|
||||
|
||||
public enum EntityType implements us.myles.ViaVersion.api.entities.EntityType {
|
||||
ENTITY(-1),
|
||||
|
||||
AREA_EFFECT_CLOUD(0, ENTITY),
|
||||
END_CRYSTAL(18, ENTITY),
|
||||
EVOKER_FANGS(23, ENTITY),
|
||||
EXPERIENCE_ORB(24, ENTITY),
|
||||
EYE_OF_ENDER(25, ENTITY),
|
||||
FALLING_BLOCK(26, ENTITY),
|
||||
FIREWORK_ROCKET(27, ENTITY),
|
||||
ITEM(37, ENTITY),
|
||||
LLAMA_SPIT(43, ENTITY),
|
||||
TNT(64, ENTITY),
|
||||
SHULKER_BULLET(71, ENTITY),
|
||||
FISHING_BOBBER(107, ENTITY),
|
||||
|
||||
LIVINGENTITY(-1, ENTITY),
|
||||
ARMOR_STAND(1, LIVINGENTITY),
|
||||
PLAYER(106, LIVINGENTITY),
|
||||
|
||||
ABSTRACT_INSENTIENT(-1, LIVINGENTITY),
|
||||
ENDER_DRAGON(19, ABSTRACT_INSENTIENT),
|
||||
|
||||
BEE(4, ABSTRACT_INSENTIENT),
|
||||
|
||||
ABSTRACT_CREATURE(-1, ABSTRACT_INSENTIENT),
|
||||
|
||||
ABSTRACT_AGEABLE(-1, ABSTRACT_CREATURE),
|
||||
VILLAGER(93, ABSTRACT_AGEABLE),
|
||||
WANDERING_TRADER(95, ABSTRACT_AGEABLE),
|
||||
|
||||
// Animals
|
||||
ABSTRACT_ANIMAL(-1, ABSTRACT_AGEABLE),
|
||||
DOLPHIN(13, ABSTRACT_INSENTIENT),
|
||||
CHICKEN(9, ABSTRACT_ANIMAL),
|
||||
COW(11, ABSTRACT_ANIMAL),
|
||||
MOOSHROOM(53, COW),
|
||||
PANDA(56, ABSTRACT_INSENTIENT),
|
||||
PIG(59, ABSTRACT_ANIMAL),
|
||||
POLAR_BEAR(63, ABSTRACT_ANIMAL),
|
||||
RABBIT(66, ABSTRACT_ANIMAL),
|
||||
SHEEP(69, ABSTRACT_ANIMAL),
|
||||
TURTLE(91, ABSTRACT_ANIMAL),
|
||||
FOX(28, ABSTRACT_ANIMAL),
|
||||
|
||||
ABSTRACT_TAMEABLE_ANIMAL(-1, ABSTRACT_ANIMAL),
|
||||
CAT(7, ABSTRACT_TAMEABLE_ANIMAL),
|
||||
OCELOT(54, ABSTRACT_TAMEABLE_ANIMAL),
|
||||
WOLF(100, ABSTRACT_TAMEABLE_ANIMAL),
|
||||
|
||||
ABSTRACT_PARROT(-1, ABSTRACT_TAMEABLE_ANIMAL),
|
||||
PARROT(57, ABSTRACT_PARROT),
|
||||
|
||||
// Horses
|
||||
ABSTRACT_HORSE(-1, ABSTRACT_ANIMAL),
|
||||
CHESTED_HORSE(-1, ABSTRACT_HORSE),
|
||||
DONKEY(14, CHESTED_HORSE),
|
||||
MULE(52, CHESTED_HORSE),
|
||||
LLAMA(42, CHESTED_HORSE),
|
||||
TRADER_LLAMA(89, CHESTED_HORSE),
|
||||
HORSE(33, ABSTRACT_HORSE),
|
||||
SKELETON_HORSE(74, ABSTRACT_HORSE),
|
||||
ZOMBIE_HORSE(103, ABSTRACT_HORSE),
|
||||
|
||||
// Golem
|
||||
ABSTRACT_GOLEM(-1, ABSTRACT_CREATURE),
|
||||
SNOW_GOLEM(77, ABSTRACT_GOLEM),
|
||||
IRON_GOLEM(36, ABSTRACT_GOLEM),
|
||||
SHULKER(70, ABSTRACT_GOLEM),
|
||||
|
||||
// Fish
|
||||
ABSTRACT_FISHES(-1, ABSTRACT_CREATURE),
|
||||
COD(10, ABSTRACT_FISHES),
|
||||
PUFFERFISH(65, ABSTRACT_FISHES),
|
||||
SALMON(68, ABSTRACT_FISHES),
|
||||
TROPICAL_FISH(90, ABSTRACT_FISHES),
|
||||
|
||||
// Monsters
|
||||
ABSTRACT_MONSTER(-1, ABSTRACT_CREATURE),
|
||||
BLAZE(5, ABSTRACT_MONSTER),
|
||||
CREEPER(12, ABSTRACT_MONSTER),
|
||||
ENDERMITE(21, ABSTRACT_MONSTER),
|
||||
ENDERMAN(20, ABSTRACT_MONSTER),
|
||||
GIANT(30, ABSTRACT_MONSTER),
|
||||
SILVERFISH(72, ABSTRACT_MONSTER),
|
||||
VEX(92, ABSTRACT_MONSTER),
|
||||
WITCH(96, ABSTRACT_MONSTER),
|
||||
WITHER(97, ABSTRACT_MONSTER),
|
||||
RAVAGER(67, ABSTRACT_MONSTER),
|
||||
|
||||
ABSTRACT_PIGLIN(-1, ABSTRACT_MONSTER),
|
||||
|
||||
PIGLIN(60, ABSTRACT_PIGLIN),
|
||||
PIGLIN_BRUTE(61, ABSTRACT_PIGLIN),
|
||||
|
||||
HOGLIN(32, ABSTRACT_ANIMAL),
|
||||
STRIDER(83, ABSTRACT_ANIMAL),
|
||||
ZOGLIN(101, ABSTRACT_MONSTER),
|
||||
|
||||
// Illagers
|
||||
ABSTRACT_ILLAGER_BASE(-1, ABSTRACT_MONSTER),
|
||||
ABSTRACT_EVO_ILLU_ILLAGER(-1, ABSTRACT_ILLAGER_BASE),
|
||||
EVOKER(22, ABSTRACT_EVO_ILLU_ILLAGER),
|
||||
ILLUSIONER(35, ABSTRACT_EVO_ILLU_ILLAGER),
|
||||
VINDICATOR(94, ABSTRACT_ILLAGER_BASE),
|
||||
PILLAGER(62, ABSTRACT_ILLAGER_BASE),
|
||||
|
||||
// Skeletons
|
||||
ABSTRACT_SKELETON(-1, ABSTRACT_MONSTER),
|
||||
SKELETON(73, ABSTRACT_SKELETON),
|
||||
STRAY(82, ABSTRACT_SKELETON),
|
||||
WITHER_SKELETON(98, ABSTRACT_SKELETON),
|
||||
|
||||
// Guardians
|
||||
GUARDIAN(31, ABSTRACT_MONSTER),
|
||||
ELDER_GUARDIAN(17, GUARDIAN),
|
||||
|
||||
// Spiders
|
||||
SPIDER(80, ABSTRACT_MONSTER),
|
||||
CAVE_SPIDER(8, SPIDER),
|
||||
|
||||
// Zombies
|
||||
ZOMBIE(102, ABSTRACT_MONSTER),
|
||||
DROWNED(16, ZOMBIE),
|
||||
HUSK(34, ZOMBIE),
|
||||
ZOMBIFIED_PIGLIN(105, ZOMBIE),
|
||||
ZOMBIE_VILLAGER(104, ZOMBIE),
|
||||
|
||||
// Flying entities
|
||||
ABSTRACT_FLYING(-1, ABSTRACT_INSENTIENT),
|
||||
GHAST(29, ABSTRACT_FLYING),
|
||||
PHANTOM(58, ABSTRACT_FLYING),
|
||||
|
||||
ABSTRACT_AMBIENT(-1, ABSTRACT_INSENTIENT),
|
||||
BAT(3, ABSTRACT_AMBIENT),
|
||||
|
||||
ABSTRACT_WATERMOB(-1, ABSTRACT_INSENTIENT),
|
||||
SQUID(81, ABSTRACT_WATERMOB),
|
||||
|
||||
// Slimes
|
||||
SLIME(75, ABSTRACT_INSENTIENT),
|
||||
MAGMA_CUBE(44, SLIME),
|
||||
|
||||
// Hangable objects
|
||||
ABSTRACT_HANGING(-1, ENTITY),
|
||||
LEASH_KNOT(40, ABSTRACT_HANGING),
|
||||
ITEM_FRAME(38, ABSTRACT_HANGING),
|
||||
PAINTING(55, ABSTRACT_HANGING),
|
||||
|
||||
ABSTRACT_LIGHTNING(-1, ENTITY),
|
||||
LIGHTNING_BOLT(41, ABSTRACT_LIGHTNING),
|
||||
|
||||
// Arrows
|
||||
ABSTRACT_ARROW(-1, ENTITY),
|
||||
ARROW(2, ABSTRACT_ARROW),
|
||||
SPECTRAL_ARROW(79, ABSTRACT_ARROW),
|
||||
TRIDENT(88, ABSTRACT_ARROW),
|
||||
|
||||
// Fireballs
|
||||
ABSTRACT_FIREBALL(-1, ENTITY),
|
||||
DRAGON_FIREBALL(15, ABSTRACT_FIREBALL),
|
||||
FIREBALL(39, ABSTRACT_FIREBALL),
|
||||
SMALL_FIREBALL(76, ABSTRACT_FIREBALL),
|
||||
WITHER_SKULL(99, ABSTRACT_FIREBALL),
|
||||
|
||||
// Projectiles
|
||||
PROJECTILE_ABSTRACT(-1, ENTITY),
|
||||
SNOWBALL(78, PROJECTILE_ABSTRACT),
|
||||
ENDER_PEARL(85, PROJECTILE_ABSTRACT),
|
||||
EGG(84, PROJECTILE_ABSTRACT),
|
||||
POTION(87, PROJECTILE_ABSTRACT),
|
||||
EXPERIENCE_BOTTLE(86, PROJECTILE_ABSTRACT),
|
||||
|
||||
// Vehicles
|
||||
MINECART_ABSTRACT(-1, ENTITY),
|
||||
CHESTED_MINECART_ABSTRACT(-1, MINECART_ABSTRACT),
|
||||
CHEST_MINECART(46, CHESTED_MINECART_ABSTRACT),
|
||||
HOPPER_MINECART(49, CHESTED_MINECART_ABSTRACT),
|
||||
MINECART(45, MINECART_ABSTRACT),
|
||||
FURNACE_MINECART(48, MINECART_ABSTRACT),
|
||||
COMMAND_BLOCK_MINECART(47, MINECART_ABSTRACT),
|
||||
TNT_MINECART(51, MINECART_ABSTRACT),
|
||||
SPAWNER_MINECART(50, MINECART_ABSTRACT),
|
||||
BOAT(6, ENTITY);
|
||||
|
||||
private static final Map<Integer, EntityType> TYPES = new HashMap<>();
|
||||
|
||||
private final int id;
|
||||
private final EntityType parent;
|
||||
|
||||
EntityType(int id) {
|
||||
this.id = id;
|
||||
this.parent = null;
|
||||
}
|
||||
|
||||
EntityType(int id, EntityType parent) {
|
||||
this.id = id;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
static {
|
||||
for (EntityType type : EntityType.values()) {
|
||||
TYPES.put(type.id, type);
|
||||
}
|
||||
}
|
||||
|
||||
public static Optional<EntityType> findById(int id) {
|
||||
if (id == -1)
|
||||
return Optional.empty();
|
||||
return Optional.ofNullable(TYPES.get(id));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package us.myles.ViaVersion.api.entities;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface EntityType {
|
||||
|
||||
int getId();
|
||||
|
||||
@Nullable
|
||||
EntityType getParent();
|
||||
|
||||
String name();
|
||||
|
||||
default boolean is(EntityType... types) {
|
||||
for (EntityType type : types)
|
||||
if (is(type))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean is(EntityType type) {
|
||||
return this == type;
|
||||
}
|
||||
|
||||
default boolean isOrHasParent(EntityType type) {
|
||||
EntityType parent = this;
|
||||
|
||||
do {
|
||||
if (parent.equals(type))
|
||||
return true;
|
||||
|
||||
parent = parent.getParent();
|
||||
} while (parent != null);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package us.myles.ViaVersion.api.entities;
|
||||
|
||||
public interface ObjectType {
|
||||
|
||||
int getId();
|
||||
|
||||
EntityType getType();
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package us.myles.ViaVersion.api.minecraft;
|
||||
|
||||
public interface BlockChangeRecord {
|
||||
|
||||
/**
|
||||
* @return relative x coordinate within the chunk section
|
||||
*/
|
||||
byte getSectionX();
|
||||
|
||||
/**
|
||||
* @return relative y coordinate within the chunk section
|
||||
*/
|
||||
byte getSectionY();
|
||||
|
||||
/**
|
||||
* @return relative z coordinate within the chunk section
|
||||
*/
|
||||
byte getSectionZ();
|
||||
|
||||
/**
|
||||
* @param chunkSectionY chunk section
|
||||
* @return absolute y coordinate
|
||||
*/
|
||||
short getY(int chunkSectionY);
|
||||
|
||||
/**
|
||||
* @return absolute y coordinate
|
||||
* @deprecated 1.16+ stores the relative y coordinate
|
||||
*/
|
||||
@Deprecated
|
||||
default short getY() {
|
||||
return getY(-1);
|
||||
}
|
||||
|
||||
int getBlockId();
|
||||
|
||||
void setBlockId(int blockId);
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package us.myles.ViaVersion.api.minecraft;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
public class BlockChangeRecord1_16_2 implements BlockChangeRecord {
|
||||
private final byte sectionX;
|
||||
private final byte sectionY;
|
||||
private final byte sectionZ;
|
||||
private int blockId;
|
||||
|
||||
public BlockChangeRecord1_16_2(byte sectionX, byte sectionY, byte sectionZ, int blockId) {
|
||||
this.sectionX = sectionX;
|
||||
this.sectionY = sectionY;
|
||||
this.sectionZ = sectionZ;
|
||||
this.blockId = blockId;
|
||||
}
|
||||
|
||||
public BlockChangeRecord1_16_2(int sectionX, int sectionY, int sectionZ, int blockId) {
|
||||
this((byte) sectionX, (byte) sectionY, (byte) sectionZ, blockId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getSectionX() {
|
||||
return sectionX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getSectionY() {
|
||||
return sectionY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getSectionZ() {
|
||||
return sectionZ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public short getY(int chunkSectionY) {
|
||||
Preconditions.checkArgument(chunkSectionY >= 0 && chunkSectionY < 16, "Invalid chunkSectionY: " + chunkSectionY);
|
||||
return (short) ((chunkSectionY << 4) + sectionY);
|
||||
}
|
||||
|
||||
public int getBlockId() {
|
||||
return blockId;
|
||||
}
|
||||
|
||||
public void setBlockId(int blockId) {
|
||||
this.blockId = blockId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package us.myles.ViaVersion.api.minecraft;
|
||||
|
||||
public class BlockChangeRecord1_8 implements BlockChangeRecord {
|
||||
private final byte sectionX;
|
||||
private final short y;
|
||||
private final byte sectionZ;
|
||||
private int blockId;
|
||||
|
||||
public BlockChangeRecord1_8(byte sectionX, short y, byte sectionZ, int blockId) {
|
||||
this.sectionX = sectionX;
|
||||
this.y = y;
|
||||
this.sectionZ = sectionZ;
|
||||
this.blockId = blockId;
|
||||
}
|
||||
|
||||
public BlockChangeRecord1_8(int sectionX, int y, int sectionZ, int blockId) {
|
||||
this((byte) sectionX, (short) y, (byte) sectionZ, blockId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return x coordinate within the chunk section
|
||||
*/
|
||||
public byte getSectionX() {
|
||||
return sectionX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getSectionY() {
|
||||
return (byte) (y & 0xF);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return y coordinate
|
||||
*/
|
||||
@Override
|
||||
public short getY(int chunkSectionY) {
|
||||
return y;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return z coordinate within the chunk section
|
||||
*/
|
||||
public byte getSectionZ() {
|
||||
return sectionZ;
|
||||
}
|
||||
|
||||
public int getBlockId() {
|
||||
return blockId;
|
||||
}
|
||||
|
||||
public void setBlockId(int blockId) {
|
||||
this.blockId = blockId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package us.myles.ViaVersion.api.minecraft;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public enum BlockFace {
|
||||
NORTH((byte) 0, (byte) 0, (byte) -1, EnumAxis.Z),
|
||||
SOUTH((byte) 0, (byte) 0, (byte) 1, EnumAxis.Z),
|
||||
EAST((byte) 1, (byte) 0, (byte) 0, EnumAxis.X),
|
||||
WEST((byte) -1, (byte) 0, (byte) 0, EnumAxis.X),
|
||||
TOP((byte) 0, (byte) 1, (byte) 0, EnumAxis.Y),
|
||||
BOTTOM((byte) 0, (byte) -1, (byte) 0, EnumAxis.Y);
|
||||
|
||||
private static final Map<BlockFace, BlockFace> opposites = new HashMap<>();
|
||||
|
||||
static {
|
||||
opposites.put(BlockFace.NORTH, BlockFace.SOUTH);
|
||||
opposites.put(BlockFace.SOUTH, BlockFace.NORTH);
|
||||
opposites.put(BlockFace.EAST, BlockFace.WEST);
|
||||
opposites.put(BlockFace.WEST, BlockFace.EAST);
|
||||
opposites.put(BlockFace.TOP, BlockFace.BOTTOM);
|
||||
opposites.put(BlockFace.BOTTOM, BlockFace.TOP);
|
||||
}
|
||||
|
||||
private final byte modX;
|
||||
private final byte modY;
|
||||
private final byte modZ;
|
||||
private final EnumAxis axis;
|
||||
|
||||
BlockFace(byte modX, byte modY, byte modZ, EnumAxis axis) {
|
||||
this.modX = modX;
|
||||
this.modY = modY;
|
||||
this.modZ = modZ;
|
||||
this.axis = axis;
|
||||
}
|
||||
|
||||
public BlockFace opposite() {
|
||||
return opposites.get(this);
|
||||
}
|
||||
|
||||
public byte getModX() {
|
||||
return modX;
|
||||
}
|
||||
|
||||
public byte getModY() {
|
||||
return modY;
|
||||
}
|
||||
|
||||
public byte getModZ() {
|
||||
return modZ;
|
||||
}
|
||||
|
||||
public EnumAxis getAxis() {
|
||||
return axis;
|
||||
}
|
||||
|
||||
public enum EnumAxis {
|
||||
X, Y, Z
|
||||
}
|
||||
}
|
||||
@@ -1,21 +1,12 @@
|
||||
package us.myles.ViaVersion.api.minecraft;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public enum Environment {
|
||||
|
||||
NORMAL(0),
|
||||
NETHER(-1),
|
||||
END(1);
|
||||
|
||||
private final int id;
|
||||
private static final Map<Integer, Environment> lookup = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (Environment env : values()) {
|
||||
lookup.put(env.getId(), env);
|
||||
}
|
||||
}
|
||||
|
||||
Environment(int id) {
|
||||
this.id = id;
|
||||
@@ -25,8 +16,15 @@ public enum Environment {
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
public static Environment getEnvironmentById(int id) {
|
||||
return lookup.get(id);
|
||||
switch (id) {
|
||||
default:
|
||||
case -1:
|
||||
return NETHER;
|
||||
case 0:
|
||||
return NORMAL;
|
||||
case 1:
|
||||
return END;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,25 @@
|
||||
package us.myles.ViaVersion.api.minecraft;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class EulerAngle {
|
||||
private float x;
|
||||
private float y;
|
||||
private float z;
|
||||
private final float x;
|
||||
private final float y;
|
||||
private final float z;
|
||||
|
||||
public EulerAngle(final float x, final float y, final float z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public float getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public float getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public float getZ() {
|
||||
return z;
|
||||
}
|
||||
}
|
||||
Loaded 100 of 531 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user