Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ab8faf358c | ||
|
|
243ce3c5dd | ||
|
|
d4762195f9 | ||
|
|
121e1615b6 | ||
|
|
350d33ae6f | ||
|
|
d4f7bced86 | ||
|
|
8037e659a8 | ||
|
|
28c7849252 | ||
|
|
cb277bf16a | ||
|
|
0612e1e188 | ||
|
|
7a9f83129e | ||
|
|
a17e5f13a7 | ||
|
|
02a565bf39 | ||
|
|
f1d7d5ac81 | ||
|
|
a1663f5a03 | ||
|
|
909492cfae | ||
|
|
a3b4cc21f5 | ||
|
|
402ebd729e | ||
|
|
349b5dc110 | ||
|
|
c778cc3368 | ||
|
|
26e5aab84e | ||
|
|
79da4e1bc4 | ||
|
|
51b550ca5e | ||
|
|
2877b74c42 | ||
|
|
c67d1a86c5 | ||
|
|
5cf9b34fd2 | ||
|
|
99acbe4960 | ||
|
|
2bf64b6107 | ||
|
|
4e86af8754 | ||
|
|
6bf639f18a | ||
|
|
9a7bb17459 | ||
|
|
6b84c683ee | ||
|
|
dc015dc457 | ||
|
|
fd7bc84cd5 | ||
|
|
9fd5b3b912 | ||
|
|
a2d259af58 | ||
|
|
6cc21a6d98 | ||
|
|
e105770dde | ||
|
|
68b7ee51dc | ||
|
|
a4a375f411 | ||
|
|
ae6b3d18a4 | ||
|
|
8763b0e77f | ||
|
|
2440b64981 | ||
|
|
ebe73587fe | ||
|
|
5b87ac4f61 | ||
|
|
d9a3f33199 | ||
|
|
9f44834514 | ||
|
|
314d4a2813 | ||
|
|
97fee0c898 | ||
|
|
bdc96a88cd | ||
|
|
af1691e6e5 | ||
|
|
e4058f7f15 | ||
|
|
7f0c922e10 | ||
|
|
453793eb60 | ||
|
|
015e7a4647 | ||
|
|
45c0c580f7 | ||
|
|
1c12a868c8 | ||
|
|
a3f22320d5 | ||
|
|
f4bb1dd8fc | ||
|
|
5203b3a376 | ||
|
|
fe66d743a9 | ||
|
|
1d1cf84c60 | ||
|
|
1c81aab994 | ||
|
|
52559f6fc8 | ||
|
|
06cc25bf23 | ||
|
|
86cf0d51ed | ||
|
|
5fbb052d6f | ||
|
|
b7021fcd1f | ||
|
|
64db7f13c6 | ||
|
|
20c9fdf634 | ||
|
|
a71035a157 | ||
|
|
b0002102e3 | ||
|
|
a3e65cfcbe | ||
|
|
edd9c5ce3d | ||
|
|
e918e6b10a | ||
|
|
f6c309fd18 | ||
|
|
322a99dbc4 | ||
|
|
6793dee0bc | ||
|
|
d33751dbb0 | ||
|
|
fa67de16a1 | ||
|
|
57fc21f411 | ||
|
|
9999ee3b4a | ||
|
|
4a90cadeb1 | ||
|
|
048903f33f | ||
|
|
3fa5eaf2a3 | ||
|
|
93bd6d5ac9 | ||
|
|
aa5535615c | ||
|
|
9ccd85178d | ||
|
|
14fd279c06 | ||
|
|
6df845324b | ||
|
|
c3f233ca61 | ||
|
|
ed4f018b34 | ||
|
|
ef4bc1c02e | ||
|
|
ca725b68a5 | ||
|
|
40f7463e93 | ||
|
|
7778768c30 | ||
|
|
6a6be44ab2 | ||
|
|
fe67c23ad4 | ||
|
|
c09348d4f7 | ||
|
|
e04cd2108f | ||
|
|
39f0dee9f1 | ||
|
|
9b9ae8d36c | ||
|
|
fc934195de | ||
|
|
6c4db8029b | ||
|
|
c4ce7b7a87 | ||
|
|
b751c63625 | ||
|
|
31ac149b42 | ||
|
|
2f45e9e469 | ||
|
|
7b152ff264 | ||
|
|
e9eb441a1c | ||
|
|
55c1093783 | ||
|
|
963ec4e978 | ||
|
|
26c30f46e7 | ||
|
|
c2cdafb17f | ||
|
|
22060a9889 | ||
|
|
e1a54099a4 | ||
|
|
3fa6a0f69a | ||
|
|
676cb6c3ce | ||
|
|
a3063f0bcb | ||
|
|
c1520401b6 | ||
|
|
d988d0c684 | ||
|
|
e2283d6f4e | ||
|
|
ea56cfde04 | ||
|
|
16733e587e | ||
|
|
b247807f0f | ||
|
|
679aea8181 | ||
|
|
f0d499a008 | ||
|
|
b5320f2ae7 | ||
|
|
0fd0821a93 | ||
|
|
c7c1b9da17 | ||
|
|
d67d307788 | ||
|
|
c057f18914 | ||
|
|
7a5b425dbb | ||
|
|
9b22739977 | ||
|
|
12e0869e0a | ||
|
|
0039ab8704 | ||
|
|
7da389db14 | ||
|
|
1f85797768 | ||
|
|
3c55703718 | ||
|
|
e3734c2d94 | ||
|
|
afc571e331 | ||
|
|
4549d07a6c | ||
|
|
acc220729b | ||
|
|
b27f64c3b1 | ||
|
|
1f7a09a561 | ||
|
|
f0b15c3f94 | ||
|
|
cc03d3029d | ||
|
|
ef2d24c5ff | ||
|
|
6a69d1bcb4 | ||
|
|
ea1e11d690 | ||
|
|
65b51fa6f5 | ||
|
|
dae31cedf6 | ||
|
|
6179f997c9 | ||
|
|
8cb083c29a | ||
|
|
7dd2434ea9 | ||
|
|
66ca952a1d | ||
|
|
d6fef1180f | ||
|
|
32451165ba | ||
|
|
2c806b2d4e | ||
|
|
a8dadfdfff | ||
|
|
4524b4289c | ||
|
|
67010e8f11 | ||
|
|
245ee7699a | ||
|
|
25dfb3c5b9 | ||
|
|
52709f279b | ||
|
|
13d6437638 | ||
|
|
7a3505070e | ||
|
|
7d79603d08 | ||
|
|
7890a8ae97 | ||
|
|
c73e149f43 | ||
|
|
2f72766aac | ||
|
|
43d915d09c | ||
|
|
3444b07f6a | ||
|
|
3cfb1c5b3e | ||
|
|
150736b170 | ||
|
|
1f325a36d6 | ||
|
|
bdc8f6ef82 | ||
|
|
d365e4b949 | ||
|
|
4f4a3ba87b | ||
|
|
7ceeaa5f3f | ||
|
|
6f968275c1 | ||
|
|
245b7a0d2a | ||
|
|
13b1007c1c | ||
|
|
c164908aac | ||
|
|
1dd28f124a | ||
|
|
149483ef21 | ||
|
|
0a689564ce | ||
|
|
facc6bc074 | ||
|
|
41224c9faf | ||
|
|
14548f5679 | ||
|
|
d31d0b2487 | ||
|
|
1366872acb | ||
|
|
40fcd23d87 | ||
|
|
ba7d09ee91 | ||
|
|
b0fa4eb3b7 | ||
|
|
a8bf163355 | ||
|
|
f81730c689 | ||
|
|
a830fe8b63 | ||
|
|
05c116271e | ||
|
|
a08f89813e | ||
|
|
87fa35dea0 | ||
|
|
4ed644313a | ||
|
|
9fdd1615bd | ||
|
|
4ab220f189 | ||
|
|
adef187685 | ||
|
|
0e5a443e9b | ||
|
|
4961ad6e8d | ||
|
|
e056f1ca0a | ||
|
|
9d43fd7a35 | ||
|
|
45bafb37fe | ||
|
|
3554f3c6ac | ||
|
|
10d4cf4a9d | ||
|
|
7a1621aa37 | ||
|
|
22a5e67c69 | ||
|
|
8737ba218a | ||
|
|
98e0a35f0c | ||
|
|
21500f3cab | ||
|
|
750d87937a | ||
|
|
f78ffc9a5c | ||
|
|
48b789d268 | ||
|
|
a765347cba | ||
|
|
21fe4c920d | ||
|
|
d35505b83a | ||
|
|
930d1370ce | ||
|
|
4f01b9b2d6 | ||
|
|
79ae548463 | ||
|
|
08120db4b4 | ||
|
|
11d2d979cc | ||
|
|
3822609afe | ||
|
|
dd057ca20f | ||
|
|
42403c9f51 | ||
|
|
9eb6b11fe0 | ||
|
|
8c02988330 | ||
|
|
fd7223a259 | ||
|
|
b22560852f | ||
|
|
3498720e8c | ||
|
|
457aed221b | ||
|
|
d6fb68d8e7 | ||
|
|
0e6c15eb8b | ||
|
|
485124bfef | ||
|
|
3517d1fd00 | ||
|
|
7d80f08e1c | ||
|
|
ff0af88299 | ||
|
|
ba08959d39 | ||
|
|
050aab96f7 | ||
|
|
afcdfae5a1 | ||
|
|
8908cce24f | ||
|
|
31447cb6cf | ||
|
|
884ab800f5 | ||
|
|
6e87103114 | ||
|
|
c3b8c213d3 | ||
|
|
33f50a0eb9 | ||
|
|
3f309bc92d | ||
|
|
8315b8d335 | ||
|
|
902c99aca2 | ||
|
|
f4fc20a1c8 | ||
|
|
0690c45558 | ||
|
|
699fd9ac02 | ||
|
|
b01db5ca2a | ||
|
|
4fdc9c67ad | ||
|
|
395ed0d58e | ||
|
|
bcad08260c | ||
|
|
06be6d52b2 | ||
|
|
7ec896b8b0 | ||
|
|
2717a94db5 | ||
|
|
2ea20e3d19 | ||
|
|
94d939ba67 | ||
|
|
620af0aec0 | ||
|
|
2299d82b92 | ||
|
|
25dbe61f64 | ||
|
|
ecd183156a | ||
|
|
3f0cb7e799 | ||
|
|
3400877958 | ||
|
|
7b209c9733 | ||
|
|
dfd490afc8 | ||
|
|
b5a2c0ac29 | ||
|
|
c43dd6425a | ||
|
|
8b643ae238 | ||
|
|
b07461340e | ||
|
|
4cec8fe549 | ||
|
|
55ea059640 | ||
|
|
5429e80f66 | ||
|
|
16c71fad14 | ||
|
|
d27a97c322 | ||
|
|
59ccfa89db | ||
|
|
b6f25939be | ||
|
|
d19406edf4 | ||
|
|
0702ff3716 | ||
|
|
4577c5a948 | ||
|
|
d073f716f9 | ||
|
|
5051c31bea | ||
|
|
eb2d91745a | ||
|
|
9d40bc506e | ||
|
|
0fa3be1ce2 | ||
|
|
acecdb57f4 | ||
|
|
33d3a72d4d | ||
|
|
2ce1fc1e79 | ||
|
|
63b9e27ebf | ||
|
|
8093481f08 | ||
|
|
629871fcb5 | ||
|
|
d2d9135c45 | ||
|
|
bf5c3e90b3 | ||
|
|
d100fd54de | ||
|
|
c8137956f1 | ||
|
|
e7739bac22 | ||
|
|
5c9cfcb25d | ||
|
|
4364d7a646 | ||
|
|
0ba826f578 | ||
|
|
92564a3a09 | ||
|
|
3e21b7d384 | ||
|
|
b934d7361d | ||
|
|
172cfceed7 | ||
|
|
4047bafc6a | ||
|
|
27de28476e | ||
|
|
e5dfb84a53 | ||
|
|
2b3c77b6b8 | ||
|
|
16294ccc63 | ||
|
|
9ae2cd0538 | ||
|
|
30492a7b1f | ||
|
|
ecce9d8c4e | ||
|
|
448f7be2ae | ||
|
|
4e3c45bc7e | ||
|
|
ccd3fd4b7b | ||
|
|
5003d578c7 | ||
|
|
881a66740f | ||
|
|
c9ae98814c | ||
|
|
ee2c562c9e | ||
|
|
cbd38ea581 | ||
|
|
983b27d071 | ||
|
|
b2a827e97b | ||
|
|
a709e5f746 | ||
|
|
c1f482dd35 | ||
|
|
269ca7ad43 | ||
|
|
594f8cdc6e | ||
|
|
187041bd47 | ||
|
|
68eb537b66 | ||
|
|
b18884a5b3 | ||
|
|
061d1c25e8 | ||
|
|
b1a881bfab | ||
|
|
e68dbe4155 | ||
|
|
60e33ef0a3 | ||
|
|
eac72687cb | ||
|
|
d205d83f61 | ||
|
|
61969bf9df | ||
|
|
ed9ff0c5da | ||
|
|
371ec62571 | ||
|
|
4eaf000dea | ||
|
|
97ca0007fc | ||
|
|
ece10d66c1 | ||
|
|
420a658b0a | ||
|
|
48fbb745e0 | ||
|
|
24d78ef500 | ||
|
|
a1123cdf67 | ||
|
|
cd3d3b17b1 | ||
|
|
1f2de8a566 | ||
|
|
74f4d65356 | ||
|
|
2be8692661 | ||
|
|
5021eebd55 | ||
|
|
124e59ba70 | ||
|
|
301adfb28f | ||
|
|
8d80725cf7 | ||
|
|
7aa429988b | ||
|
|
1cbd15e797 | ||
|
|
802c707902 | ||
|
|
17d5e3f711 | ||
|
|
7a342a8c21 | ||
|
|
a4e9a2cd06 | ||
|
|
4abc4a7403 | ||
|
|
2a364895cf | ||
|
|
ff56e81136 | ||
|
|
371fcff23a | ||
|
|
abe5b9f75a | ||
|
|
2c36b5ad9f | ||
|
|
0436b8cb6a | ||
|
|
2fb967ec04 | ||
|
|
aafc45d70d | ||
|
|
3e25fa641c | ||
|
|
3f3c6ba2e1 | ||
|
|
3175ef85c4 | ||
|
|
e876b1c95f | ||
|
|
be2094a21f | ||
|
|
95fdebfb08 | ||
|
|
5662c7ea9c | ||
|
|
b8587a2487 | ||
|
|
1411fd09b9 | ||
|
|
604a48e2dd | ||
|
|
f091ab69bc | ||
|
|
e22db21f72 | ||
|
|
24000fd837 | ||
|
|
87275458bb | ||
|
|
faac9cd83d | ||
|
|
887a9fa959 | ||
|
|
d716309e34 | ||
|
|
92603a382b | ||
|
|
88c788f654 | ||
|
|
bdb429a0b4 | ||
|
|
0c2e09bc7b | ||
|
|
131a66220f | ||
|
|
7e2c6726e0 | ||
|
|
882e7b57f9 | ||
|
|
990a19585f | ||
|
|
c2f7c92ed4 | ||
|
|
08b420ffb4 | ||
|
|
d9a821e44e | ||
|
|
2e39d61d53 | ||
|
|
bb9bd91970 | ||
|
|
a789d9ec83 | ||
|
|
524cf896c3 | ||
|
|
5190d71bc8 | ||
|
|
29dd1cdc03 | ||
|
|
cbe517e994 | ||
|
|
5175ed9733 | ||
|
|
26ddcfde2a | ||
|
|
e17eb7987f | ||
|
|
6cc2ac81df | ||
|
|
12d16144c0 | ||
|
|
f4fc034d51 | ||
|
|
42c6df480c | ||
|
|
c591335dd4 | ||
|
|
d93e01cca1 | ||
|
|
b666a1a62c | ||
|
|
fcdac76ba9 | ||
|
|
3e33d38518 | ||
|
|
46dd4be1d3 | ||
|
|
809517f04b | ||
|
|
f53e73ed9a | ||
|
|
a7e1852af4 | ||
|
|
95ac9d8633 | ||
|
|
8034de3ec3 | ||
|
|
ee6aac43d4 | ||
|
|
2fef51f3d4 | ||
|
|
f27ead56c7 | ||
|
|
317853fd8e | ||
|
|
db8a4184f8 | ||
|
|
95543c7033 | ||
|
|
306f1598e0 | ||
|
|
5a26451880 | ||
|
|
9384187f06 | ||
|
|
5e414bae58 | ||
|
|
990dfc279f | ||
|
|
27ec0876cb | ||
|
|
c3853614c5 | ||
|
|
67855eda8a | ||
|
|
e2ed78e81d | ||
|
|
80ae2de524 | ||
|
|
af3c440526 | ||
|
|
8bac60f2db | ||
|
|
6d0d1df82e | ||
|
|
44eba1fbdc | ||
|
|
7ca7eaa346 | ||
|
|
fb93dde220 | ||
|
|
4f9f58f76f | ||
|
|
4c2ee57f8d | ||
|
|
345db7d3f6 | ||
|
|
ab6df11274 | ||
|
|
71ed30e2a9 | ||
|
|
cbfccafce7 | ||
|
|
2888afa999 | ||
|
|
9c4d7cb933 | ||
|
|
baec4bdd00 | ||
|
|
a00ae8f52c | ||
|
|
b973820c59 | ||
|
|
5fbf597d20 | ||
|
|
cc8bb89ee5 | ||
|
|
1f0792f854 | ||
|
|
6b7ebc2162 | ||
|
|
596a961b05 | ||
|
|
9586d8da29 | ||
|
|
8391c11a7f | ||
|
|
51de60ab4f | ||
|
|
5d14703492 | ||
|
|
d3968b15db | ||
|
|
990cc38b67 | ||
|
|
df0d135a72 | ||
|
|
18ac4937b6 | ||
|
|
531cef241a | ||
|
|
e5353800e7 | ||
|
|
21dfaceb22 | ||
|
|
c13454a255 | ||
|
|
4f4f5f0578 | ||
|
|
02544cd0f5 | ||
|
|
3ed09a3834 | ||
|
|
28749faa44 | ||
|
|
2dbbdcc5d4 | ||
|
|
291266c4bd | ||
|
|
411693611a | ||
|
|
98c36ff39f | ||
|
|
1e69b33d4f | ||
|
|
ae2c6cdc4b | ||
|
|
3104885fb5 | ||
|
|
081868571b | ||
|
|
6a3b18aff9 | ||
|
|
c4caba57bd | ||
|
|
c9f3eb32aa | ||
|
|
1dad678f98 | ||
|
|
4f579f59c3 | ||
|
|
3352f25ede | ||
|
|
0378141ac4 | ||
|
|
9dbb877455 | ||
|
|
ee382176c5 | ||
|
|
b3d9c1f10f | ||
|
|
a51ce059e5 | ||
|
|
126bf406ce | ||
|
|
b476d51910 | ||
|
|
02e9f7f901 | ||
|
|
0cf411c4de | ||
|
|
37e2317a5f | ||
|
|
415550b354 | ||
|
|
3b5099f940 | ||
|
|
34605f3d72 | ||
|
|
8e5eab8bd1 | ||
|
|
8cde415712 | ||
|
|
c5189d2788 | ||
|
|
e550924b38 | ||
|
|
27d7495f65 | ||
|
|
7477483f15 | ||
|
|
7e064f453a | ||
|
|
f7e58de863 | ||
|
|
7a135fe0f5 | ||
|
|
8336f1c0ab | ||
|
|
2648f8538d | ||
|
|
6893216ed2 | ||
|
|
b6f944ad57 | ||
|
|
969f032607 | ||
|
|
daed712bf7 | ||
|
|
835952a7d2 | ||
|
|
d272f8d19e | ||
|
|
8cb8ad7388 | ||
|
|
6793fcb928 | ||
|
|
86ea24d3ee | ||
|
|
69f9c4f500 | ||
|
|
3d869f7dfc | ||
|
|
92d716d78e | ||
|
|
8a7f086fdf | ||
|
|
58f6a77287 | ||
|
|
04110da6f1 | ||
|
|
81e5a50b8a | ||
|
|
dfb6787322 | ||
|
|
6b03502307 | ||
|
|
499d2eea6c | ||
|
|
fdf1942553 | ||
|
|
9e9b9abb14 | ||
|
|
92397b2e4a | ||
|
|
154b789b48 | ||
|
|
0cee676a69 | ||
|
|
387f4661e8 | ||
|
|
c261e1d467 | ||
|
|
b43a76e682 | ||
|
|
6efb6f59b1 | ||
|
|
9f27a49358 | ||
|
|
5001b21e7a | ||
|
|
24446c61e0 | ||
|
|
d03ed48409 | ||
|
|
840153bc98 | ||
|
|
f3ee112a4e | ||
|
|
1634eed6e7 | ||
|
|
6e7dbf13e3 | ||
|
|
d60c661d3d | ||
|
|
cd0f1bb241 | ||
|
|
dd46140147 | ||
|
|
337d35f1d8 | ||
|
|
6ad2d61dd3 | ||
|
|
1d6e737611 | ||
|
|
a3739319af | ||
|
|
5513c0f14b | ||
|
|
6869ac594f | ||
|
|
1bad630ec1 | ||
|
|
ba21fa9a8b | ||
|
|
7d01583cea | ||
|
|
01e161d37e | ||
|
|
90968ca195 | ||
|
|
3e1cffee7e | ||
|
|
d6564e6263 | ||
|
|
24b7b97c09 | ||
|
|
bf0448ab15 | ||
|
|
6c3b66ef84 | ||
|
|
507281fd18 | ||
|
|
c46c536ea9 | ||
|
|
fb15ac5742 | ||
|
|
427a305b61 | ||
|
|
ded4f5103f | ||
|
|
004c1aadab | ||
|
|
2f0ffb163c | ||
|
|
be03ffe93f | ||
|
|
b943f195f3 | ||
|
|
31e7fba37d | ||
|
|
14c75f19fb | ||
|
|
3fef6fa51c | ||
|
|
b6c62bb055 | ||
|
|
c3edd14b90 | ||
|
|
7014999f65 | ||
|
|
d3b32b4e22 | ||
|
|
b94a86e5fa | ||
|
|
9038fd149a | ||
|
|
65cf7c0b92 | ||
|
|
c1d2c6c049 | ||
|
|
b2a9b6a98c | ||
|
|
1cf80df77a | ||
|
|
2606094a40 | ||
|
|
ddf014b852 | ||
|
|
be2f392c91 | ||
|
|
91c370327b | ||
|
|
6dfdfc8363 | ||
|
|
e09c596020 | ||
|
|
5bf7dba140 | ||
|
|
7d74474fde | ||
|
|
14195de83e | ||
|
|
8e16c5564d | ||
|
|
803a50542c | ||
|
|
150acb64c3 | ||
|
|
009f0a7c13 | ||
|
|
db99d1f187 | ||
|
|
6514b84adf | ||
|
|
e40dfe35b8 | ||
|
|
fee0ff6e26 | ||
|
|
9ed447164a | ||
|
|
6102208f45 | ||
|
|
ec31fb0cbb | ||
|
|
c4660b4821 | ||
|
|
978be6bbcc | ||
|
|
ee8b1e9458 | ||
|
|
4fdd047026 | ||
|
|
5c22920393 | ||
|
|
8a18947fd2 | ||
|
|
bbb3e47a50 | ||
|
|
e903aa52e3 | ||
|
|
9ff8cf30b4 | ||
|
|
8092bbdb3b | ||
|
|
bff9ef2f6b | ||
|
|
cc1bd65841 | ||
|
|
8a84b1fc15 | ||
|
|
09ab2ff82b | ||
|
|
a59a8e116c | ||
|
|
9adfa831bf | ||
|
|
3a4daec265 | ||
|
|
de87ca203e | ||
|
|
9957cb3de9 | ||
|
|
2ac60d7055 | ||
|
|
3015f40531 | ||
|
|
f4e5dab1d8 | ||
|
|
2792dd4c78 | ||
|
|
b4d45f0fba | ||
|
|
3443a482b3 | ||
|
|
d89af56959 | ||
|
|
80d7c4a5a9 | ||
|
|
810b205cfa | ||
|
|
0c452ab842 | ||
|
|
be414fceb6 | ||
|
|
95099e9763 | ||
|
|
f806773cbe | ||
|
|
9af8bab57f | ||
|
|
20c5d9f28a | ||
|
|
cbe474dafa | ||
|
|
af90c6534b | ||
|
|
4130fcf172 | ||
|
|
e321a169c2 | ||
|
|
54d4614600 | ||
|
|
8fc10e8f62 | ||
|
|
e770a1c9ee | ||
|
|
c999f3a810 | ||
|
|
8e070aac9a | ||
|
|
faecd9dd9c | ||
|
|
e40d8c875f | ||
|
|
10765058f8 | ||
|
|
c71d6da310 | ||
|
|
4ec106e36f | ||
|
|
66a7ef3ffa | ||
|
|
3d858013e6 | ||
|
|
3c15e5409f | ||
|
|
206d484f27 | ||
|
|
e2949ade16 | ||
|
|
896ed7ff07 | ||
|
|
4ca682704a | ||
|
|
2275091e76 | ||
|
|
dd71d9ae69 | ||
|
|
b2d3aee10e | ||
|
|
1891307753 | ||
|
|
399d831d04 | ||
|
|
29ad41f42f | ||
|
|
bab19e14bd | ||
|
|
286ea801d8 | ||
|
|
6320cc314e | ||
|
|
cb094f1af3 | ||
|
|
d00d138a21 | ||
|
|
8b86b3e48b | ||
|
|
3232c69a5a | ||
|
|
4ee24812f4 | ||
|
|
a2139718a5 | ||
|
|
57e536b8b2 | ||
|
|
ab0e4030c3 | ||
|
|
89fe7f43a7 | ||
|
|
fffb4e08b8 | ||
|
|
1b071e6564 | ||
|
|
efb1b1e1eb | ||
|
|
60421a6727 | ||
|
|
7f7107a79a | ||
|
|
94827892cc | ||
|
|
78d0d674b5 | ||
|
|
ed681fadd1 | ||
|
|
35de72c331 | ||
|
|
018d611b2b | ||
|
|
852d34cdcf | ||
|
|
d4fead85b8 | ||
|
|
a8bbc97d00 | ||
|
|
94d77e94da | ||
|
|
b1e2a746e3 | ||
|
|
1b8e23dcf5 | ||
|
|
ecd87f2fc6 | ||
|
|
22453a2fac | ||
|
|
80c1413811 | ||
|
|
0fcd8d57c0 | ||
|
|
750d8813f3 | ||
|
|
ca546a9e59 | ||
|
|
29fd80865c | ||
|
|
ab253a0976 | ||
|
|
5545de8886 | ||
|
|
637aecbf4b | ||
|
|
aaf6d41766 | ||
|
|
f814d0ecf8 | ||
|
|
f20e8432b1 | ||
|
|
0e558e4baf | ||
|
|
5eb7d5b3fc | ||
|
|
87c2ca3c07 | ||
|
|
1f1b1aabd1 | ||
|
|
4a5382b14c | ||
|
|
c2b006ddab | ||
|
|
e4b60d55f3 | ||
|
|
4521ce8037 | ||
|
|
73490b8ff6 | ||
|
|
0549c8e486 | ||
|
|
af7c0d346f | ||
|
|
9a5da1bc9a | ||
|
|
96a601da74 | ||
|
|
f29626311c | ||
|
|
ea0b9a497e | ||
|
|
b11e76494e | ||
|
|
cb3a62cf71 | ||
|
|
992d4855e7 | ||
|
|
a684b56dc3 | ||
|
|
e6c86a7e4f | ||
|
|
73e34d8f0b | ||
|
|
d006974e7b | ||
|
|
0742f24973 | ||
|
|
76bde2568b | ||
|
|
40bd7d60d4 | ||
|
|
6d7718428a | ||
|
|
92229a90e9 | ||
|
|
7dd6fbd9af | ||
|
|
2fa285ddde | ||
|
|
8962c80495 | ||
|
|
2dccce47bf | ||
|
|
6231e8c7d4 | ||
|
|
5ba3080d00 | ||
|
|
a110c549be | ||
|
|
021460ba08 | ||
|
|
74d14166d5 | ||
|
|
f24add4246 | ||
|
|
acf631a54f | ||
|
|
a6b4087454 | ||
|
|
f392495474 | ||
|
|
b8fdd74f96 | ||
|
|
9dba5d40ca | ||
|
|
78c7709add | ||
|
|
7a0908faaf | ||
|
|
0624b1766f | ||
|
|
651de583b6 | ||
|
|
c29847af02 | ||
|
|
87c8147514 | ||
|
|
57778b5eb3 | ||
|
|
f2d136af0a | ||
|
|
22d568f30e | ||
|
|
49a81fa4f7 | ||
|
|
57f9a8fe3a | ||
|
|
94c731afbf | ||
|
|
98304cb41e | ||
|
|
70d68d7860 | ||
|
|
5502c4a434 | ||
|
|
f424b9bd66 | ||
|
|
c8d0733935 | ||
|
|
c2ba3304f7 | ||
|
|
510bf9301c | ||
|
|
8a64746b18 | ||
|
|
feab6ba0bd | ||
|
|
f11a5dd31c | ||
|
|
5a3a4f6507 | ||
|
|
e2865ce4be | ||
|
|
f53f182090 | ||
|
|
2ec7771a8a | ||
|
|
75320ef583 | ||
|
|
40fa932d33 | ||
|
|
1355ca6bdd | ||
|
|
5639c2b85e | ||
|
|
baa8837987 | ||
|
|
38f2783149 | ||
|
|
43a5e2c590 | ||
|
|
9a124b8e68 | ||
|
|
02b9e9260f | ||
|
|
d109e9dd54 | ||
|
|
2ea24250a0 | ||
|
|
39d555f3ec | ||
|
|
6e09ec2e2b | ||
|
|
f91de06044 | ||
|
|
63e3563a1a | ||
|
|
655d97c73a | ||
|
|
a7c8f21d31 | ||
|
|
f23ff3d421 | ||
|
|
766f0c0a32 | ||
|
|
e13d52a518 | ||
|
|
329b8adefa | ||
|
|
5bb90aa0de | ||
|
|
a7949eb096 | ||
|
|
a4288ca29c | ||
|
|
9b1e92b555 | ||
|
|
104615edb5 | ||
|
|
9f54ca6843 | ||
|
|
46919017e1 | ||
|
|
0a1ce38c7e | ||
|
|
f60d5230c3 | ||
|
|
8034f5dc89 | ||
|
|
265ade55d0 | ||
|
|
cffcbaf596 | ||
|
|
4dc90a2920 | ||
|
|
e5b5845ebf | ||
|
|
b5f6a7f6b8 | ||
|
|
f916addda3 | ||
|
|
d275fb8d8b | ||
|
|
3ce8971215 | ||
|
|
5866e4ede1 | ||
|
|
a47040e18a | ||
|
|
631b41d9d0 | ||
|
|
8b9cf0c283 | ||
|
|
e7afd771f8 | ||
|
|
98446b5afc | ||
|
|
0fbfca81a1 | ||
|
|
33f1eab93b | ||
|
|
38fcccd7c9 | ||
|
|
053768ccfa | ||
|
|
d11a0406cb | ||
|
|
5966ca1355 | ||
|
|
72944a00c0 | ||
|
|
671c935134 | ||
|
|
c931974779 | ||
|
|
5e6d0bffde | ||
|
|
c08719acc7 | ||
|
|
e76b00c880 | ||
|
|
b30d56ed0b | ||
|
|
211b85a51b | ||
|
|
f895ff0e0a | ||
|
|
3726f6629a | ||
|
|
33aae65e35 | ||
|
|
6f0f6eaa24 | ||
|
|
d6ee3b356e | ||
|
|
2d495b7570 | ||
|
|
5a8acfdffd | ||
|
|
1938f9f3bf | ||
|
|
672b8e47fd | ||
|
|
846d0a893e | ||
|
|
fb45b5b35a | ||
|
|
1205020451 | ||
|
|
3ed2735d0e | ||
|
|
5b3d6ae7a2 | ||
|
|
e3d9638b47 | ||
|
|
9ec6118159 | ||
|
|
7b800a9015 | ||
|
|
ba0feb31f0 | ||
|
|
36b73752f7 | ||
|
|
6f0586ce23 | ||
|
|
59159d47a0 | ||
|
|
23c0fc9bff | ||
|
|
c34690197d | ||
|
|
c98425cb99 | ||
|
|
55f4280ccb | ||
|
|
b9299dfa96 | ||
|
|
b1fb30163c | ||
|
|
50b8776aa9 | ||
|
|
d47b450307 | ||
|
|
1f41447a02 | ||
|
|
af251d03b8 | ||
|
|
1445057145 | ||
|
|
a306ac26b9 | ||
|
|
df6a334a00 | ||
|
|
c43ea28f59 | ||
|
|
596f1b57ce | ||
|
|
386238aae8 | ||
|
|
e7dcb4c96e | ||
|
|
6049e37d87 | ||
|
|
a41e747da7 | ||
|
|
c4c61dff3c | ||
|
|
84b85c8f00 | ||
|
|
f9b3786c16 | ||
|
|
d2350ad383 | ||
|
|
f6c554da02 | ||
|
|
721532ee44 | ||
|
|
7ff8c40402 | ||
|
|
df6d7fa741 | ||
|
|
c936c9da31 | ||
|
|
3a5aa401f0 | ||
|
|
9c5263bf20 | ||
|
|
28cb480ac3 | ||
|
|
838426e1bf | ||
|
|
d486863a64 | ||
|
|
cd98e8488b | ||
|
|
a7c6f88a11 | ||
|
|
c15b88e77f | ||
|
|
1a2d39d68f | ||
|
|
fe8ca640cc | ||
|
|
26eee81455 | ||
|
|
8c63a7c7b6 | ||
|
|
d221869491 | ||
|
|
539b814a5a | ||
|
|
d0da1d710b | ||
|
|
2771959dd8 | ||
|
|
aa17d098c4 | ||
|
|
7a1f432652 | ||
|
|
bca60bfa19 | ||
|
|
94e2dc0378 | ||
|
|
e8bdd02838 | ||
|
|
b962876dfd | ||
|
|
f0135204e3 | ||
|
|
5bedb44e11 | ||
|
|
4e3ada1bd8 | ||
|
|
38d68418dc | ||
|
|
5f8efaaf0f | ||
|
|
9b8de173e4 | ||
|
|
de4594fbdc | ||
|
|
5eae00ef0b | ||
|
|
3c418473d8 | ||
|
|
1e919053c6 | ||
|
|
30ff648bad | ||
|
|
6c5d9beb76 | ||
|
|
3e828ea9ee | ||
|
|
4ef8b381d7 | ||
|
|
24838cd7d9 | ||
|
|
e17b877b5f | ||
|
|
8b85bc8d4d | ||
|
|
fca9ad22fe | ||
|
|
667652bfb8 | ||
|
|
2da42185e8 | ||
|
|
fd1b918956 | ||
|
|
828013bf77 | ||
|
|
6e30fb393a | ||
|
|
cbfca6c5fa | ||
|
|
945ca46491 | ||
|
|
f7d5252bf0 | ||
|
|
a624a76427 | ||
|
|
39f9ed008c | ||
|
|
a0096b3032 | ||
|
|
ae1a0258fe | ||
|
|
f863ad026f | ||
|
|
abea90564f | ||
|
|
3bdd110864 | ||
|
|
b2e47f48a5 | ||
|
|
513de88321 | ||
|
|
5a49cf2687 | ||
|
|
65fba0b83d | ||
|
|
5272557f58 | ||
|
|
51abf38d3f | ||
|
|
33abe17a2b | ||
|
|
593015dd0b | ||
|
|
aaf00bf167 | ||
|
|
d72c8df72c |
No files matched your search
+1
-3
@@ -1,5 +1,3 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: retrooper
|
||||
custom: ['https://paypal.me/retrooperdev']
|
||||
github: [retrooper]
|
||||
@@ -8,48 +8,57 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up JDK 8
|
||||
uses: actions/setup-java@v3
|
||||
- name: Validate gradle wrapper
|
||||
uses: gradle/actions/wrapper-validation@v3
|
||||
|
||||
- name: Set up JDK 21
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: '8'
|
||||
java-version: '21'
|
||||
distribution: 'adopt'
|
||||
cache: 'gradle'
|
||||
server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
|
||||
settings-path: ${{ github.workspace }} # location for the settings.xml file
|
||||
|
||||
- name: Build with Gradle
|
||||
run: chmod +x gradlew && ./gradlew shadowJar
|
||||
run: chmod +x gradlew && ./gradlew build
|
||||
|
||||
- name: Upload build artifacts api
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: api-build
|
||||
path: api/build/libs
|
||||
|
||||
- name: Upload build artifacts spigot
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: spigot-build
|
||||
path: spigot/build/libs
|
||||
|
||||
- name: Upload build artifacts netty-common
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: netty-common-build
|
||||
path: netty-common/build/libs
|
||||
|
||||
- name: Upload build artifacts bungeecord
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: bungeecord-build
|
||||
path: bungeecord/build/libs
|
||||
|
||||
- name: Upload build artifacts velocity
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: velocity-build
|
||||
path: velocity/build/libs
|
||||
path: velocity/build/libs
|
||||
|
||||
- name: Upload build artifacts fabric
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: fabric-build
|
||||
path: fabric/build/libs
|
||||
@@ -1,30 +1,43 @@
|
||||
# packetevents
|
||||
<!--suppress HtmlDeprecatedAttribute -->
|
||||
<div align="center">
|
||||
<h2><i>packetevents</i></h2>
|
||||
<a href="https://github.com/retrooper/packetevents/actions"><img src="https://img.shields.io/github/actions/workflow/status/retrooper/packetevents/gradle-publish.yml?style=for-the-badge&logo=github"></a>
|
||||
<a href="https://discord.gg/DVHxPPxHZc"><img src="https://img.shields.io/discord/721686193061888071?color=5562e9&logo=discord&logoColor=white&style=for-the-badge"></a>
|
||||
<img src="https://img.shields.io/github/license/retrooper/packetevents?style=for-the-badge&logo=github">
|
||||
<a href="https://bstats.org/plugin/bukkit/packetevents/11327"><img src="https://img.shields.io/bstats/servers/11327?style=for-the-badge"></a>
|
||||
<a href="https://github.com/retrooper/packetevents/releases"><img src="https://img.shields.io/github/downloads/retrooper/packetevents/total.svg?style=for-the-badge&logo=github"></a>
|
||||
</div>
|
||||
PacketEvents is emerging as a strong contender in the realm of Minecraft packet processing libraries. Designed to simplify packet manipulation while delivering high performance, this powerful tool aims to demystify the complexities of projects utilizing packets. Imbued with versatility, PacketEvents supports various platforms such as Spigot, BungeeCord, Velocity, and Fabric.
|
||||
|
||||
[](https://github.com/retrooper/packetevents/blob/2.0/LICENSE) [](https://github.com/retrooper/packetevents/actions) [](https://discord.gg/prqzNg9tRU)
|
||||
<h3>Resources</h3>
|
||||
|
||||
PacketEvents is a fast and efficient multi-platform packet processing library. Our packet wrappers are easy to use with multi-version support. With our API you can write code that runs on Spigot, BungeeCord, Velocity, and Fabric! Switch to PacketEvents today by joining \
|
||||
our [Discord Server](https://discord.me/packetevents) for help.
|
||||
- [Read documentation](https://docs.packetevents.com/)
|
||||
- [Getting Started](https://docs.packetevents.com/getting-started)
|
||||
- [JavaDocs](javadocs.packetevents.com)
|
||||
- [Releases](https://github.com/retrooper/packetevents/releases/)
|
||||
- [GitHub](https://github.com/retrooper/packetevents/releases/)
|
||||
- [Modrinth](https://modrinth.com/plugin/packetevents)
|
||||
- [SpigotMC](https://www.spigotmc.org/resources/packetevents-api.80279/)
|
||||
- [Development Builds](https://ci.codemc.io/job/retrooper/job/packetevents)
|
||||
- [Statistics](https://bstats.org/plugin/bukkit/packetevents/11327)
|
||||
|
||||
### Links
|
||||
* [Find release builds on Modrinth](https://modrinth.com/plugin/packetevents)
|
||||
* [Find development builds on Jenkins](https://ci.codemc.io/job/retrooper/job/packetevents)
|
||||
* [View documentation on our JavaDocs Page](https://packetevents.github.io/javadocs)
|
||||
<h3>Sponsors</h3>
|
||||
|
||||
### Setup
|
||||
[How to Setup PacketEvents](https://github.com/retrooper/packetevents/wiki/Depending-on-pre%E2%80%90built-PacketEvents)
|
||||
<i>Thanks to the following sponsors for supporting this project:</i>
|
||||
|
||||
### Sponsorships
|
||||
[](https://www.ej-technologies.com/products/jprofiler/overview.html)
|
||||
<a href="https://pebblehost.com"><img src="https://pebblehost.com/src/img/logos/main-old.png" width=150><br>
|
||||
|
||||
### Statistics
|
||||
PacketEvents optionally collects statistics using [bStats](https://bstats.org/)\
|
||||
Check out our [bStats page](https://bstats.org/plugin/bukkit/packetevents/11327)
|
||||
<a href="https://www.ej-technologies.com"><img src="https://www.ej-technologies.com/images/product_banners/jprofiler_small.png"><br>
|
||||
|
||||
### Credit to these projects
|
||||
[wiki.vg/Protocol](https://wiki.vg/Protocol)\
|
||||
[netty](https://github.com/netty/netty)\
|
||||
[gson](https://github.com/google/gson)\
|
||||
[adventure](https://github.com/KyoriPowered/adventure)\
|
||||
<a href="https://github.com/radstevee"><img src="https://github.com/radstevee.png" width="50px" alt="radstevee"/></a><br>
|
||||
|
||||
<h3>Credits</h3>
|
||||
|
||||
<i>Here are some projects that we are heavily inspired by, thus we have integrated</i>\
|
||||
<i>small portions of their code into our work.</i>
|
||||
|
||||
[Protocol Documentation for the Minecraft Java Edition](https://wiki.vg/Protocol)\
|
||||
[ViaVersion](https://github.com/ViaVersion/ViaVersion)\
|
||||
[ProtocolSupport](https://github.com/ProtocolSupport/ProtocolSupport)\
|
||||
[adventure](https://github.com/KyoriPowered/adventure)\
|
||||
[MCProtocolLib](https://github.com/GeyserMC/MCProtocolLib/)
|
||||
@@ -1,3 +0,0 @@
|
||||
dependencies {
|
||||
compileOnly(adventureDependencies)
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
import com.github.retrooper.compression.strategy.JsonArrayCompressionStrategy
|
||||
import com.github.retrooper.compression.strategy.JsonObjectCompressionStrategy
|
||||
import com.github.retrooper.compression.strategy.JsonToNbtStrategy
|
||||
import com.github.retrooper.excludeAdventure
|
||||
|
||||
plugins {
|
||||
packetevents.`shadow-conventions`
|
||||
packetevents.`library-conventions`
|
||||
`mapping-compression`
|
||||
`pe-version`
|
||||
}
|
||||
|
||||
// papermc repo + disableAutoTargetJvm needed for mockbukkit
|
||||
repositories {
|
||||
maven("https://repo.papermc.io/repository/maven-public/")
|
||||
}
|
||||
|
||||
java {
|
||||
withJavadocJar()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnlyApi(libs.bundles.adventure)
|
||||
compileOnlyApi(libs.bundles.adventure.serializers)
|
||||
implementation(libs.adventure.api)
|
||||
api(project(":patch:adventure-text-serializer-gson", "shadow")) {
|
||||
excludeAdventure()
|
||||
}
|
||||
api(libs.adventure.text.serializer.legacy) {
|
||||
excludeAdventure()
|
||||
}
|
||||
compileOnly(libs.gson)
|
||||
|
||||
testImplementation(libs.bundles.adventure)
|
||||
testImplementation(project(":patch:adventure-text-serializer-gson"))
|
||||
testImplementation(libs.adventure.text.serializer.legacy)
|
||||
testImplementation(project(":netty-common"))
|
||||
testImplementation(testlibs.mockbukkit)
|
||||
testImplementation(testlibs.slf4j)
|
||||
testImplementation(testlibs.bundles.junit)
|
||||
}
|
||||
|
||||
mappingCompression {
|
||||
mappingDirectory = rootDir.resolve("mappings")
|
||||
outDirectory = project.layout.buildDirectory.dir("mappings/generated/assets/mappings")
|
||||
|
||||
with<JsonToNbtStrategy> {
|
||||
compress("block/legacy_block_mappings.json")
|
||||
compress("block/modern_block_mappings.json")
|
||||
|
||||
compress("enchantment/enchantment_type_data.json")
|
||||
|
||||
compress("stats/statistics.json")
|
||||
|
||||
compress("world/biome_data.json")
|
||||
}
|
||||
|
||||
with<JsonArrayCompressionStrategy> {
|
||||
compress("attribute/attribute_mappings.json")
|
||||
|
||||
compress("block/block_entity_type_mappings.json")
|
||||
compress("block/block_type_mappings.json")
|
||||
|
||||
compress("chat/chat_type_mappings.json")
|
||||
|
||||
compress("command/argument_parser_mappings.json")
|
||||
|
||||
compress("damage/damagetype_mappings.json")
|
||||
|
||||
compress("enchantment/effect_component_type.json")
|
||||
|
||||
compress("entity/entity_data_type_mappings.json")
|
||||
compress("entity/painting_mappings.json")
|
||||
compress("entity/wolf_variant_mappings.json")
|
||||
|
||||
compress("item/item_armor_material_mappings.json")
|
||||
compress("item/item_banner_pattern_mappings.json")
|
||||
compress("item/item_component_mappings.json")
|
||||
compress("item/item_instrument_mappings.json")
|
||||
compress("item/item_jukebox_song_mappings.json")
|
||||
compress("item/item_map_decoration_type_mappings.json")
|
||||
compress("item/item_potion_mappings.json")
|
||||
compress("item/item_trim_material_mappings.json")
|
||||
compress("item/item_trim_pattern_mappings.json")
|
||||
compress("item/recipe_serializer_mappings.json")
|
||||
|
||||
compress("particle/particle_type_mappings.json")
|
||||
|
||||
compress("sound/sound_mappings.json")
|
||||
|
||||
compress("world/biome_mappings.json")
|
||||
compress("world/world_position_source_mappings.json")
|
||||
}
|
||||
|
||||
with<JsonObjectCompressionStrategy> {
|
||||
compress("enchantment/enchantment_type_mappings.json")
|
||||
|
||||
compress("entity/entity_effect_mappings.json")
|
||||
compress("entity/entity_type_mappings.json")
|
||||
compress("entity/legacy_entity_type_mappings.json")
|
||||
|
||||
compress("item/item_type_mappings.json")
|
||||
|
||||
compress("world/dimension_type_mappings.json")
|
||||
}
|
||||
}
|
||||
|
||||
tasks {
|
||||
javadoc {
|
||||
setDestinationDir(file("${project.layout.buildDirectory.asFile.get()}/docs/javadoc"))
|
||||
options {
|
||||
(this as CoreJavadocOptions).addBooleanOption("Xdoclint:none", true)
|
||||
}
|
||||
mustRunAfter(generateVersionsFile)
|
||||
}
|
||||
|
||||
sourcesJar {
|
||||
mustRunAfter(generateVersionsFile)
|
||||
}
|
||||
|
||||
withType<JavaCompile> {
|
||||
dependsOn(generateVersionsFile)
|
||||
}
|
||||
|
||||
processResources {
|
||||
dependsOn(compressMappings)
|
||||
from(project.layout.buildDirectory.dir("mappings/generated").get())
|
||||
}
|
||||
|
||||
generateVersionsFile {
|
||||
packageName = "com.github.retrooper.packetevents.util"
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
exclude {
|
||||
val path = it.path
|
||||
path.startsWith("net/kyori") && !path.startsWith("net/kyori/adventure/text/serializer") && !path.startsWith("net/kyori/option")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
named<MavenPublication>("shadow") {
|
||||
artifact(tasks["javadocJar"])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,10 +18,13 @@
|
||||
|
||||
package com.github.retrooper.packetevents;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
public final class PacketEvents {
|
||||
private static PacketEventsAPI<?> API;
|
||||
|
||||
//Put these variable names anywhere else, they are really only for the injectors
|
||||
@ApiStatus.Internal
|
||||
public static String IDENTIFIER, ENCODER_NAME, DECODER_NAME, CONNECTION_HANDLER_NAME, SERVER_CHANNEL_HANDLER_NAME,
|
||||
TIMEOUT_HANDLER_NAME;
|
||||
|
||||
|
||||
@@ -27,33 +27,34 @@ import com.github.retrooper.packetevents.netty.NettyManager;
|
||||
import com.github.retrooper.packetevents.settings.PacketEventsSettings;
|
||||
import com.github.retrooper.packetevents.util.LogManager;
|
||||
import com.github.retrooper.packetevents.util.PEVersion;
|
||||
//Note: The PEVersions class is generated. Refer to PEVersionTask.kt
|
||||
import com.github.retrooper.packetevents.util.PEVersions;
|
||||
import com.github.retrooper.packetevents.util.updatechecker.UpdateChecker;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public abstract class PacketEventsAPI<T> {
|
||||
private static final EventManager EVENT_MANAGER = new EventManager();
|
||||
private static final PacketEventsSettings SETTINGS = new PacketEventsSettings();
|
||||
private static final UpdateChecker UPDATE_CHECKER = new UpdateChecker();
|
||||
private final Logger LOGGER = Logger.getLogger(PacketEventsAPI.class.getName());
|
||||
private static final LogManager LOG_MANAGER = new LogManager();
|
||||
//TODO UPDATE
|
||||
private static final PEVersion VERSION = new PEVersion(2, 1, 0);
|
||||
|
||||
private final EventManager eventManager = new EventManager();
|
||||
private final PacketEventsSettings settings = new PacketEventsSettings();
|
||||
private final UpdateChecker updateChecker = new UpdateChecker();
|
||||
private final LogManager logManager = new LogManager();
|
||||
private static final Logger LOGGER = Logger.getLogger(PacketEventsAPI.class.getName());
|
||||
|
||||
public EventManager getEventManager() {
|
||||
return EVENT_MANAGER;
|
||||
return eventManager;
|
||||
}
|
||||
|
||||
public PacketEventsSettings getSettings() {
|
||||
return SETTINGS;
|
||||
return settings;
|
||||
}
|
||||
|
||||
public UpdateChecker getUpdateChecker() {
|
||||
return UPDATE_CHECKER;
|
||||
return updateChecker;
|
||||
}
|
||||
|
||||
public PEVersion getVersion() {
|
||||
return VERSION;
|
||||
//Note: The PEVersions class is generated by the auto-version task. Refer to PEVersionTask.kt
|
||||
return PEVersions.CURRENT;
|
||||
}
|
||||
|
||||
public Logger getLogger() {
|
||||
@@ -61,7 +62,7 @@ public abstract class PacketEventsAPI<T> {
|
||||
}
|
||||
|
||||
public LogManager getLogManager() {
|
||||
return LOG_MANAGER;
|
||||
return logManager;
|
||||
}
|
||||
|
||||
public abstract void load();
|
||||
@@ -74,6 +75,8 @@ public abstract class PacketEventsAPI<T> {
|
||||
|
||||
public abstract void terminate();
|
||||
|
||||
public abstract boolean isTerminated();
|
||||
|
||||
public abstract T getPlugin();
|
||||
|
||||
public abstract ServerManager getServerManager();
|
||||
|
||||
@@ -22,13 +22,37 @@ import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.exception.InvalidHandshakeException;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* Class for event managing. Implements both, internal and API methods.
|
||||
*
|
||||
* @apiNote It is highly recommended to register the event listeners at server start-up,
|
||||
* without frequent modifications during runtime, since this class needs to recalculate all of
|
||||
* its event listeners during any modifications. In other words, it assumes that reads (events fired)
|
||||
* greatly outnumber writes (listeners modifications). If your case requires frequent listener modifications,
|
||||
* open a pull request on GitHub and describe your case.
|
||||
*
|
||||
* @author retrooper
|
||||
* @author ShadowOfHeaven (optimization)
|
||||
*
|
||||
*/
|
||||
|
||||
public class EventManager {
|
||||
private final Map<Byte, Set<PacketListenerCommon>> listenersMap = new ConcurrentHashMap<>();
|
||||
|
||||
//Using a ConcurrentHashMap is faster and more secure here, compared to Collections.synchronizedMap(new EnumMap<>(PacketListenerPriority.class))
|
||||
//This is mainly due to:
|
||||
//1. On each modification Collections.synchronizedMap synchronizes the whole Map object, while ConcurrentHashMap only it's internal, currently modified Node
|
||||
//2. ConcurrentHashMap won't fail in a multi-thread environment, while Collections.synchronizedMap is said to have a lot of potential problems,
|
||||
//being a generalized method for synchronization
|
||||
private final Map<PacketListenerPriority, Set<PacketListenerCommon>> listenersMap = new ConcurrentHashMap<>();
|
||||
//Since reads greatly outnumber writes, create an array for the best possible iteration time
|
||||
//Updated as a whole on writes, no index modifications are allowed
|
||||
private volatile PacketListenerCommon[] listeners = new PacketListenerCommon[0];
|
||||
|
||||
|
||||
/**
|
||||
* Call the PacketEvent.
|
||||
@@ -43,32 +67,43 @@ public class EventManager {
|
||||
callEvent(event, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Call the PacketEvent.
|
||||
* This method processes the event on all the registered dynamic packet event listeners.
|
||||
* The {@link PacketListenerPriority#LOWEST} prioritized listeners will be processing first,
|
||||
* the {@link PacketListenerPriority#MONITOR} will be processing last and can
|
||||
* be the final decider whether the event has been cancelled or not.
|
||||
*
|
||||
* @param event {@link PacketEvent}
|
||||
* @param postCallListenerAction The action to be ran after all the listeners have finished processing
|
||||
*/
|
||||
public void callEvent(PacketEvent event, @Nullable Runnable postCallListenerAction) {
|
||||
for (byte priority = PacketListenerPriority.LOWEST.getId(); priority <= PacketListenerPriority.MONITOR.getId(); priority++) {
|
||||
Set<PacketListenerCommon> listeners = listenersMap.get(priority);
|
||||
if (listeners != null) {
|
||||
for (PacketListenerCommon listener : listeners) {
|
||||
try {
|
||||
event.call(listener);
|
||||
} catch (Exception t) {
|
||||
// ignore handshake exceptions
|
||||
if (t.getClass() != InvalidHandshakeException.class) {
|
||||
PacketEvents.getAPI().getLogger().log(Level.WARNING, "PacketEvents caught an unhandled exception while calling your listener.", t);
|
||||
}
|
||||
}
|
||||
if (postCallListenerAction != null) {
|
||||
postCallListenerAction.run();
|
||||
}
|
||||
for (PacketListenerCommon listener : listeners) {
|
||||
try {
|
||||
event.call(listener);
|
||||
} catch (Exception t) {
|
||||
// ignore handshake exceptions
|
||||
if (t.getClass() != InvalidHandshakeException.class) {
|
||||
PacketEvents.getAPI().getLogger().log(Level.WARNING, "PacketEvents caught an unhandled exception while calling your listener.", t);
|
||||
}
|
||||
}
|
||||
if (postCallListenerAction != null) {
|
||||
postCallListenerAction.run();
|
||||
}
|
||||
}
|
||||
// For performance reasons, we don't want to re-encode the packet if it's not needed.
|
||||
if (event instanceof ProtocolPacketEvent && !((ProtocolPacketEvent<?>) event).needsReEncode()) {
|
||||
((ProtocolPacketEvent<?>) event).setLastUsedWrapper(null);
|
||||
if (event instanceof ProtocolPacketEvent && !((ProtocolPacketEvent) event).needsReEncode()) {
|
||||
((ProtocolPacketEvent) event).setLastUsedWrapper(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the dynamic packet event listener.
|
||||
*
|
||||
* @param listener {@link PacketListenerCommon}
|
||||
* @param priority {@link PacketListenerPriority}
|
||||
*/
|
||||
public PacketListenerCommon registerListener(PacketListener listener, PacketListenerPriority priority) {
|
||||
PacketListenerCommon packetListenerAbstract = listener.asAbstract(priority);
|
||||
return registerListener(packetListenerAbstract);
|
||||
@@ -80,13 +115,8 @@ public class EventManager {
|
||||
* @param listener {@link PacketListenerCommon}
|
||||
*/
|
||||
public PacketListenerCommon registerListener(PacketListenerCommon listener) {
|
||||
byte priority = listener.getPriority().getId();
|
||||
Set<PacketListenerCommon> listenerSet = listenersMap.get(priority);
|
||||
if (listenerSet == null) {
|
||||
listenerSet = ConcurrentHashMap.newKeySet();
|
||||
}
|
||||
listenerSet.add(listener);
|
||||
listenersMap.put(priority, listenerSet);
|
||||
this.registerListenerNoRecalculation(listener);
|
||||
this.recalculateListeners();
|
||||
return listener;
|
||||
}
|
||||
|
||||
@@ -97,21 +127,22 @@ public class EventManager {
|
||||
*/
|
||||
public PacketListenerCommon[] registerListeners(PacketListenerCommon... listeners) {
|
||||
for (PacketListenerCommon listener : listeners) {
|
||||
registerListener(listener);
|
||||
this.registerListenerNoRecalculation(listener);
|
||||
}
|
||||
this.recalculateListeners();
|
||||
return listeners;
|
||||
}
|
||||
|
||||
public void unregisterListener(PacketListenerCommon listener) {
|
||||
Set<PacketListenerCommon> listenerSet = listenersMap.get(listener.getPriority().getId());
|
||||
if (listenerSet == null) return;
|
||||
listenerSet.remove(listener);
|
||||
if (this.unregisterListenerNoRecalculation(listener)) this.recalculateListeners();
|
||||
}
|
||||
|
||||
public void unregisterListeners(PacketListenerCommon... listeners) {
|
||||
boolean modified = false;
|
||||
for (PacketListenerCommon listener : listeners) {
|
||||
unregisterListener(listener);
|
||||
modified |= this.unregisterListenerNoRecalculation(listener);//OR - at least one of these needs to be true to return true, meaning the boolean will permanently stay true if once set so
|
||||
}
|
||||
if (modified) this.recalculateListeners();
|
||||
}
|
||||
|
||||
|
||||
@@ -119,6 +150,36 @@ public class EventManager {
|
||||
* Unregister all dynamic packet event listeners.
|
||||
*/
|
||||
public void unregisterAllListeners() {
|
||||
listenersMap.clear();
|
||||
this.listenersMap.clear();
|
||||
synchronized (this) {//like booky10 said, the synchronization is necessary here
|
||||
this.listeners = new PacketListenerCommon[0];
|
||||
}
|
||||
}
|
||||
|
||||
//Needs to be synchronized in order to avoid race conditions (for example where the 'listeners' variable
|
||||
//is overridden by its non-up-to-date value, simply because it finished a bit later than the most recent update)
|
||||
private void recalculateListeners() {
|
||||
synchronized (this) {
|
||||
List<PacketListenerCommon> list = new ArrayList<>();
|
||||
//adds from LOWEST to MONITOR, so in the correct order
|
||||
for (PacketListenerPriority priority : PacketListenerPriority.values()) {
|
||||
Set<PacketListenerCommon> set = this.listenersMap.get(priority);
|
||||
if (set != null) list.addAll(set);
|
||||
}
|
||||
this.listeners = list.toArray(new PacketListenerCommon[0]);
|
||||
}
|
||||
}
|
||||
|
||||
//Internal registration methods, specifically separated for lesser overhead when registering an array of Listeners
|
||||
|
||||
private void registerListenerNoRecalculation(PacketListenerCommon listener) {
|
||||
Set<PacketListenerCommon> listenerSet = this.listenersMap.computeIfAbsent(listener.getPriority(), p -> new CopyOnWriteArraySet<>());
|
||||
listenerSet.add(listener);
|
||||
}
|
||||
|
||||
//Returns true if the listener was removed, so a modification occurred
|
||||
private boolean unregisterListenerNoRecalculation(PacketListenerCommon listener) {
|
||||
Set<PacketListenerCommon> listenerSet = this.listenersMap.get(listener.getPriority());
|
||||
return listenerSet != null && listenerSet.remove(listener);
|
||||
}
|
||||
}
|
||||
+9
-7
@@ -30,8 +30,7 @@ package com.github.retrooper.packetevents.event;
|
||||
*/
|
||||
public enum PacketListenerPriority {
|
||||
/**
|
||||
* Listener is of very low importance.
|
||||
* This listener will be ran first.
|
||||
* This listener will be run first and has little say in the outcome of events.
|
||||
*/
|
||||
LOWEST,
|
||||
|
||||
@@ -41,8 +40,11 @@ public enum PacketListenerPriority {
|
||||
LOW,
|
||||
|
||||
/**
|
||||
* Default listener priority.
|
||||
* Listener is neither important nor unimportant and may run normally.
|
||||
* The normal listener priority.
|
||||
* If possible, always pick this.
|
||||
* It allows other projects to easily overturn your decisions.
|
||||
* Moreover, it is pretty bold to assume that your project should
|
||||
* always have the final say.
|
||||
*/
|
||||
NORMAL,
|
||||
|
||||
@@ -52,13 +54,13 @@ public enum PacketListenerPriority {
|
||||
HIGH,
|
||||
|
||||
/**
|
||||
* Listener is of critical importance and wants to decide the cancellation of an event.
|
||||
* Listener is of critical importance. Use this to decide the final state of packets.
|
||||
*/
|
||||
HIGHEST,
|
||||
|
||||
/**
|
||||
* Listener is purely trying to decide the cancellation of an event.
|
||||
* This listener should be ran last.
|
||||
* Only use this priority if you want to perform logic based on the outcome of an event.
|
||||
* Please do not modify packets in this stage.
|
||||
*/
|
||||
MONITOR;
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
package com.github.retrooper.packetevents.event;
|
||||
|
||||
import com.github.retrooper.packetevents.event.simple.*;
|
||||
import com.github.retrooper.packetevents.exception.PacketProcessException;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.netty.buffer.ByteBufHelper;
|
||||
@@ -26,7 +25,7 @@ import com.github.retrooper.packetevents.protocol.PacketSide;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketTypeCommon;
|
||||
import com.github.retrooper.packetevents.protocol.player.User;
|
||||
|
||||
public class PacketReceiveEvent extends ProtocolPacketEvent<Object> {
|
||||
public class PacketReceiveEvent extends ProtocolPacketEvent {
|
||||
protected PacketReceiveEvent(Object channel, User user, Object player, Object rawByteBuf,
|
||||
boolean autoProtocolTranslation) throws PacketProcessException {
|
||||
super(PacketSide.CLIENT, channel, user, player, rawByteBuf, autoProtocolTranslation);
|
||||
|
||||
@@ -29,7 +29,7 @@ import com.github.retrooper.packetevents.protocol.player.User;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class PacketSendEvent extends ProtocolPacketEvent<Object> {
|
||||
public class PacketSendEvent extends ProtocolPacketEvent {
|
||||
private List<Runnable> tasksAfterSend = null;
|
||||
|
||||
protected PacketSendEvent(Object channel, User user, Object player, Object rawByteBuf,
|
||||
|
||||
@@ -24,11 +24,11 @@ package com.github.retrooper.packetevents.event;
|
||||
* @author retrooper
|
||||
* @since 1.6.9
|
||||
*/
|
||||
public interface PlayerEvent<T> {
|
||||
public interface PlayerEvent {
|
||||
/**
|
||||
* Associated player.
|
||||
*
|
||||
* @return Player.
|
||||
*/
|
||||
T getPlayer();
|
||||
<T> T getPlayer();
|
||||
}
|
||||
@@ -39,11 +39,11 @@ import java.net.InetSocketAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class ProtocolPacketEvent<T> extends PacketEvent implements PlayerEvent<T>, CancellableEvent, UserEvent {
|
||||
public abstract class ProtocolPacketEvent extends PacketEvent implements PlayerEvent, CancellableEvent, UserEvent {
|
||||
private final Object channel;
|
||||
private final ConnectionState connectionState;
|
||||
private final User user;
|
||||
private final T player;
|
||||
private final Object player;
|
||||
private Object byteBuf;
|
||||
private final int packetID;
|
||||
private final PacketTypeCommon packetType;
|
||||
@@ -55,7 +55,7 @@ public abstract class ProtocolPacketEvent<T> extends PacketEvent implements Play
|
||||
private boolean needsReEncode = PacketEvents.getAPI().getSettings().reEncodeByDefault();
|
||||
|
||||
public ProtocolPacketEvent(PacketSide packetSide, Object channel,
|
||||
User user, T player, Object byteBuf,
|
||||
User user, Object player, Object byteBuf,
|
||||
boolean autoProtocolTranslation) throws PacketProcessException {
|
||||
this.channel = channel;
|
||||
this.user = user;
|
||||
@@ -92,7 +92,7 @@ public abstract class ProtocolPacketEvent<T> extends PacketEvent implements Play
|
||||
}
|
||||
|
||||
public ProtocolPacketEvent(int packetID, PacketTypeCommon packetType, ServerVersion serverVersion, Object channel,
|
||||
User user, T player, Object byteBuf) {
|
||||
User user, Object player, Object byteBuf) {
|
||||
this.channel = channel;
|
||||
this.user = user;
|
||||
this.player = player;
|
||||
@@ -133,8 +133,8 @@ public abstract class ProtocolPacketEvent<T> extends PacketEvent implements Play
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getPlayer() {
|
||||
return player;
|
||||
public <T> T getPlayer() {
|
||||
return (T) player;
|
||||
}
|
||||
|
||||
public ConnectionState getConnectionState() {
|
||||
@@ -213,7 +213,7 @@ public abstract class ProtocolPacketEvent<T> extends PacketEvent implements Play
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProtocolPacketEvent<?> clone() {
|
||||
public ProtocolPacketEvent clone() {
|
||||
return this instanceof PacketReceiveEvent ? ((PacketReceiveEvent) this).clone()
|
||||
: ((PacketSendEvent) this).clone();
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ package com.github.retrooper.packetevents.event;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.player.User;
|
||||
|
||||
public class UserLoginEvent extends PacketEvent implements CallableEvent, UserEvent, PlayerEvent<Object> {
|
||||
public class UserLoginEvent extends PacketEvent implements CallableEvent, UserEvent, PlayerEvent {
|
||||
private final User user;
|
||||
private final Object player;
|
||||
|
||||
@@ -35,8 +35,8 @@ public class UserLoginEvent extends PacketEvent implements CallableEvent, UserEv
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPlayer() {
|
||||
return player;
|
||||
public <T> T getPlayer() {
|
||||
return (T) player;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+18
-43
@@ -26,12 +26,11 @@ import com.github.retrooper.packetevents.event.PacketSendEvent;
|
||||
import com.github.retrooper.packetevents.manager.protocol.ProtocolManager;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.ConnectionState;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTList;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.player.User;
|
||||
import com.github.retrooper.packetevents.protocol.player.UserProfile;
|
||||
import com.github.retrooper.packetevents.util.mappings.SynchronizedRegistriesHandler;
|
||||
import com.github.retrooper.packetevents.wrapper.configuration.server.WrapperConfigServerRegistryData;
|
||||
import com.github.retrooper.packetevents.wrapper.handshaking.client.WrapperHandshakingClientHandshake;
|
||||
import com.github.retrooper.packetevents.wrapper.login.server.WrapperLoginServerLoginSuccess;
|
||||
@@ -83,61 +82,37 @@ public class InternalPacketListener extends PacketListenerAbstract {
|
||||
}
|
||||
}
|
||||
|
||||
// The server sends dimension information in configuration phase >= 1.20.2
|
||||
// The server sends dimension information in configuration phase, since 1.20.2
|
||||
else if (event.getPacketType() == PacketType.Configuration.Server.REGISTRY_DATA) {
|
||||
WrapperConfigServerRegistryData registryData = new WrapperConfigServerRegistryData(event);
|
||||
WrapperConfigServerRegistryData packet = new WrapperConfigServerRegistryData(event);
|
||||
|
||||
// Store world data
|
||||
NBTCompound registryDataTag = registryData.getRegistryData();
|
||||
if (registryDataTag != null) {
|
||||
NBTList<NBTCompound> list = registryDataTag
|
||||
.getCompoundTagOrNull("minecraft:dimension_type")
|
||||
.getCompoundListTagOrNull("value");
|
||||
user.setWorldNBT(list);
|
||||
if (packet.getElements() != null) { // 1.20.2 to 1.20.5
|
||||
SynchronizedRegistriesHandler.handleRegistry(user, packet.getServerVersion().toClientVersion(),
|
||||
packet.getRegistryKey(), packet.getElements());
|
||||
}
|
||||
if (packet.getRegistryData() != null) { // since 1.20.5
|
||||
SynchronizedRegistriesHandler.handleLegacyRegistries(user, packet.getServerVersion()
|
||||
.toClientVersion(), packet.getRegistryData());
|
||||
}
|
||||
}
|
||||
|
||||
// The server sends dimension information in login packet for >= 1.17 and < 1.20.2
|
||||
// The server sends registry info in login packet for 1.16 to 1.20.1
|
||||
else if (event.getPacketType() == PacketType.Play.Server.JOIN_GAME) {
|
||||
WrapperPlayServerJoinGame joinGame = new WrapperPlayServerJoinGame(event);
|
||||
user.setEntityId(joinGame.getEntityId());
|
||||
user.setDimension(joinGame.getDimension());
|
||||
if (event.getServerVersion().isOlderThanOrEquals(ServerVersion.V_1_16_5)) {
|
||||
return; // Fixed world height, no tags are sent to the client
|
||||
|
||||
if (joinGame.getDimensionCodec() != null) { // 1.16 to 1.20.1
|
||||
SynchronizedRegistriesHandler.handleLegacyRegistries(user, joinGame.getServerVersion().toClientVersion(),
|
||||
joinGame.getDimensionCodec());
|
||||
}
|
||||
|
||||
// Store world data
|
||||
NBTCompound dimensionCodec = joinGame.getDimensionCodec();
|
||||
if (dimensionCodec != null) {
|
||||
NBTList<NBTCompound> list = dimensionCodec
|
||||
.getCompoundTagOrNull("minecraft:dimension_type")
|
||||
.getCompoundListTagOrNull("value");
|
||||
user.setWorldNBT(list);
|
||||
}
|
||||
|
||||
// Update world height
|
||||
NBTCompound dimension = user.getWorldNBT(joinGame.getDimension().getDimensionName());
|
||||
if (dimension != null) {
|
||||
NBTCompound worldNBT = dimension.getCompoundTagOrNull("element");
|
||||
user.setMinWorldHeight(worldNBT.getNumberTagOrNull("min_y").getAsInt());
|
||||
user.setTotalWorldHeight(worldNBT.getNumberTagOrNull("height").getAsInt());
|
||||
}
|
||||
user.setDimensionType(joinGame.getDimensionType());
|
||||
}
|
||||
|
||||
// Respawn is used to switch dimensions
|
||||
else if (event.getPacketType() == PacketType.Play.Server.RESPAWN) {
|
||||
WrapperPlayServerRespawn respawn = new WrapperPlayServerRespawn(event);
|
||||
user.setDimension(respawn.getDimension());
|
||||
if (event.getServerVersion().isOlderThanOrEquals(ServerVersion.V_1_16_5)) {
|
||||
return; // Fixed world height, no tags are sent to the client
|
||||
}
|
||||
|
||||
NBTCompound dimension = user.getWorldNBT(respawn.getDimension().getDimensionName());
|
||||
if (dimension != null) {
|
||||
NBTCompound worldNBT = dimension.getCompoundTagOrNull("element"); // This is 1.17+, it always sends the world name
|
||||
user.setMinWorldHeight(worldNBT.getNumberTagOrNull("min_y").getAsInt());
|
||||
user.setTotalWorldHeight(worldNBT.getNumberTagOrNull("height").getAsInt());
|
||||
}
|
||||
WrapperPlayServerRespawn packet = new WrapperPlayServerRespawn(event);
|
||||
user.setDimensionType(packet.getDimensionType());
|
||||
} else if (event.getPacketType() == PacketType.Play.Server.CONFIGURATION_START) {
|
||||
user.setEncoderState(ConnectionState.CONFIGURATION);
|
||||
} else if (event.getPacketType() == PacketType.Configuration.Server.CONFIGURATION_END) {
|
||||
|
||||
+7
-4
@@ -104,10 +104,13 @@ public interface ProtocolManager {
|
||||
PacketWrapper<?>[] wrappers = PacketTransformationUtil.transform(wrapper);
|
||||
Object[] buffers = new Object[wrappers.length];
|
||||
for (int i = 0; i < wrappers.length; i++) {
|
||||
wrappers[i].prepareForSend(channel, outgoing);
|
||||
buffers[i] = wrappers[i].buffer;
|
||||
// Fix race condition when sending packets to multiple people (due to when the buffer is freed)
|
||||
wrappers[i].buffer = null;
|
||||
PacketWrapper<?> wrappper = wrappers[i];
|
||||
synchronized (wrappper.bufferLock) {
|
||||
wrappper.prepareForSend(channel, outgoing);
|
||||
buffers[i] = wrappper.buffer;
|
||||
// Fix race condition when sending packets to multiple people (due to when the buffer is freed)
|
||||
wrappper.buffer = null;
|
||||
}
|
||||
}
|
||||
return buffers;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
|
||||
package com.github.retrooper.packetevents.manager.server;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.player.User;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface ServerManager {
|
||||
/**
|
||||
* Get the server version.
|
||||
@@ -34,4 +38,20 @@ public interface ServerManager {
|
||||
default SystemOS getOS() {
|
||||
return SystemOS.getOS();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a platform-specific network-synchronized-registries cache key.
|
||||
* <p>
|
||||
* This tells packetevents, if a registry should be cached or read again. On
|
||||
* backend servers with global registries, this may be a constant value. On
|
||||
* proxy servers with per-server registries, this may be a value which depends
|
||||
* on the current server the {@link User} is on.
|
||||
*
|
||||
* @param user the {@link User} for which the registry gets read
|
||||
* @param version the version the packet is for
|
||||
* @return some value or null for no caching at all
|
||||
*/
|
||||
default @Nullable Object getRegistryCacheKey(User user, ClientVersion version) {
|
||||
return null; // no caching
|
||||
}
|
||||
}
|
||||
+4
-2
@@ -47,8 +47,10 @@ public enum ServerVersion {
|
||||
V_1_18(757), V_1_18_1(757), V_1_18_2(758),
|
||||
//1.19.1 and 1.19.2 have the same protocol version
|
||||
V_1_19(759), V_1_19_1(760), V_1_19_2(760), V_1_19_3(761), V_1_19_4(762),
|
||||
//1.20 and 1.20.1 have the same protocol version
|
||||
V_1_20(763), V_1_20_1(763), V_1_20_2(764),
|
||||
//1.20 and 1.20.1 have the same protocol version. 1.20.3 and 1.20.4 have the same protocol version. 1.20.5 and 1.20.6 have the same protocol version
|
||||
V_1_20(763), V_1_20_1(763), V_1_20_2(764), V_1_20_3(765), V_1_20_4(765), V_1_20_5(766), V_1_20_6(766),
|
||||
//1.21 and 1.21.1 have the same protocol version
|
||||
V_1_21(767), V_1_21_1(767),
|
||||
//TODO UPDATE Add server version constant
|
||||
ERROR(-1, true);
|
||||
|
||||
|
||||
+3
@@ -24,8 +24,11 @@ public interface ByteBufAllocationOperator {
|
||||
Object copiedBuffer(byte[] bytes);
|
||||
|
||||
Object buffer();
|
||||
Object buffer(int initialCapacity);
|
||||
|
||||
Object directBuffer();
|
||||
Object directBuffer(int initialCapacity);
|
||||
|
||||
Object compositeBuffer();
|
||||
Object compositeBuffer(int maxNumComponents);
|
||||
}
|
||||
@@ -103,6 +103,14 @@ public class ByteBufHelper {
|
||||
PacketEvents.getAPI().getNettyManager().getByteBufOperator().writeShort(buffer, value);
|
||||
}
|
||||
|
||||
public static int readMedium(Object buffer) {
|
||||
return PacketEvents.getAPI().getNettyManager().getByteBufOperator().readMedium(buffer);
|
||||
}
|
||||
|
||||
public static void writeMedium(Object buffer, int value) {
|
||||
PacketEvents.getAPI().getNettyManager().getByteBufOperator().writeMedium(buffer, value);
|
||||
}
|
||||
|
||||
public static int readInt(Object buffer) {
|
||||
return PacketEvents.getAPI().getNettyManager().getByteBufOperator().readInt(buffer);
|
||||
}
|
||||
|
||||
+18
-8
@@ -18,6 +18,8 @@
|
||||
|
||||
package com.github.retrooper.packetevents.netty.buffer;
|
||||
|
||||
import com.github.retrooper.packetevents.exception.PacketProcessException;
|
||||
|
||||
import java.io.*;
|
||||
//TODO give netty credit
|
||||
public class ByteBufInputStream extends InputStream implements DataInput {
|
||||
@@ -40,27 +42,27 @@ public class ByteBufInputStream extends InputStream implements DataInput {
|
||||
this(buffer, ByteBufHelper.readableBytes(buffer), releaseOnClose);
|
||||
}
|
||||
|
||||
public ByteBufInputStream(Object buffer, int length, boolean releaseOnClose) {
|
||||
public ByteBufInputStream(Object buffer, int maxLength, boolean releaseOnClose) {
|
||||
this.lineBuf = new StringBuilder();
|
||||
if (buffer == null) {
|
||||
throw new NullPointerException("buffer");
|
||||
} else if (length < 0) {
|
||||
} else if (maxLength < 0) {
|
||||
if (releaseOnClose) {
|
||||
ByteBufHelper.release(buffer);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("length: " + length);
|
||||
} else if (length > ByteBufHelper.readableBytes(buffer)) {
|
||||
throw new IllegalArgumentException("maxLength: " + maxLength);
|
||||
} else if (ByteBufHelper.readableBytes(buffer) > maxLength) {
|
||||
if (releaseOnClose) {
|
||||
ByteBufHelper.release(buffer);
|
||||
}
|
||||
|
||||
throw new IndexOutOfBoundsException("Too many bytes to be read - Needs " + length + ", maximum is " + ByteBufHelper.readableBytes(buffer));
|
||||
throw new IndexOutOfBoundsException("Too many bytes to be read - Found " + ByteBufHelper.readableBytes(buffer) + ", maximum is " + maxLength);
|
||||
} else {
|
||||
this.releaseOnClose = releaseOnClose;
|
||||
this.buffer = buffer;
|
||||
this.startIndex = ByteBufHelper.readerIndex(buffer);
|
||||
this.endIndex = this.startIndex + length;
|
||||
this.endIndex = this.startIndex + ByteBufHelper.readableBytes(buffer);
|
||||
ByteBufHelper.markReaderIndex(buffer);
|
||||
}
|
||||
}
|
||||
@@ -204,7 +206,8 @@ public class ByteBufInputStream extends InputStream implements DataInput {
|
||||
}
|
||||
|
||||
public String readUTF() throws IOException {
|
||||
return DataInputStream.readUTF(this);
|
||||
String text = DataInputStream.readUTF(this);
|
||||
return text;
|
||||
}
|
||||
|
||||
public int readUnsignedByte() throws IOException {
|
||||
@@ -225,7 +228,14 @@ public class ByteBufInputStream extends InputStream implements DataInput {
|
||||
if (fieldSize < 0) {
|
||||
throw new IndexOutOfBoundsException("fieldSize cannot be a negative number");
|
||||
} else if (fieldSize > this.available()) {
|
||||
throw new EOFException("fieldSize is too long! Length is " + fieldSize + ", but maximum is " + this.available());
|
||||
int value = this.available();
|
||||
String msg = "fieldSize is too long! Length is " + fieldSize + ", but maximum is " + value;
|
||||
if (value == 0) {
|
||||
throw new PacketProcessException(msg);
|
||||
}
|
||||
else {
|
||||
throw new EOFException(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,12 +35,14 @@ public interface ByteBufOperator {
|
||||
|
||||
byte readByte(Object buffer);
|
||||
short readShort(Object buffer);
|
||||
int readMedium(Object buffer);
|
||||
int readInt(Object buffer);
|
||||
long readUnsignedInt(Object buffer);
|
||||
long readLong(Object buffer);
|
||||
|
||||
void writeByte(Object buffer, int value);
|
||||
void writeShort(Object buffer, int value);
|
||||
void writeMedium(Object buffer, int value);
|
||||
void writeInt(Object buffer, int value);
|
||||
void writeLong(Object buffer, long value);
|
||||
|
||||
|
||||
+12
@@ -40,4 +40,16 @@ public class UnpooledByteBufAllocationHelper {
|
||||
public static Object compositeBuffer() {
|
||||
return PacketEvents.getAPI().getNettyManager().getByteBufAllocationOperator().compositeBuffer();
|
||||
}
|
||||
|
||||
public static Object buffer(int initialCapacity) {
|
||||
return PacketEvents.getAPI().getNettyManager().getByteBufAllocationOperator().buffer(initialCapacity);
|
||||
}
|
||||
|
||||
public static Object directBuffer(int initialCapacity) {
|
||||
return PacketEvents.getAPI().getNettyManager().getByteBufAllocationOperator().directBuffer(initialCapacity);
|
||||
}
|
||||
|
||||
public static Object compositeBuffer(int maxNumComponents) {
|
||||
return PacketEvents.getAPI().getNettyManager().getByteBufAllocationOperator().compositeBuffer(maxNumComponents);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2023 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.attribute;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
|
||||
|
||||
public interface Attribute extends MappedEntity {
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.attribute;
|
||||
|
||||
public enum AttributeOperation {
|
||||
ADDITION,
|
||||
MULTIPLY_BASE,
|
||||
MULTIPLY_TOTAL,
|
||||
}
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2023 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.attribute;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.mappings.MappingHelper;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilder;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class Attributes {
|
||||
|
||||
private static final Map<String, Attribute> ATTRIBUTE_MAP = new HashMap<>();
|
||||
private static final Map<Byte, Map<Integer, Attribute>> ATTRIBUTE_ID_MAP = new HashMap<>();
|
||||
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("attribute/attribute_mappings");
|
||||
|
||||
public static Attribute define(String key) {
|
||||
TypesBuilderData data = TYPES_BUILDER.define(key);
|
||||
Attribute attribute = new Attribute() {
|
||||
@Override
|
||||
public ResourceLocation getName() {
|
||||
return data.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId(ClientVersion version) {
|
||||
return MappingHelper.getId(version, TYPES_BUILDER, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof Attribute) {
|
||||
return this.getName().equals(((Attribute) obj).getName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
MappingHelper.registerMapping(TYPES_BUILDER, ATTRIBUTE_MAP, ATTRIBUTE_ID_MAP, attribute);
|
||||
return attribute;
|
||||
}
|
||||
|
||||
// with minecraft:key
|
||||
public static Attribute getByName(String name) {
|
||||
return ATTRIBUTE_MAP.get(name);
|
||||
}
|
||||
|
||||
public static Attribute getById(ClientVersion version, int id) {
|
||||
int index = TYPES_BUILDER.getDataIndex(version);
|
||||
Map<Integer, Attribute> idMap = ATTRIBUTE_ID_MAP.get((byte) index);
|
||||
return idMap.get(id);
|
||||
}
|
||||
|
||||
public static final Attribute GENERIC_ARMOR = define("generic.armor");
|
||||
public static final Attribute GENERIC_ARMOR_TOUGHNESS = define("generic.armor_toughness");
|
||||
public static final Attribute GENERIC_ATTACK_DAMAGE = define("generic.attack_damage");
|
||||
public static final Attribute GENERIC_ATTACK_KNOCKBACK = define("generic.attack_knockback");
|
||||
public static final Attribute GENERIC_ATTACK_SPEED = define("generic.attack_speed");
|
||||
public static final Attribute GENERIC_FLYING_SPEED = define("generic.flying_speed");
|
||||
public static final Attribute GENERIC_FOLLOW_RANGE = define("generic.follow_range");
|
||||
@ApiStatus.Obsolete // renamed in 1.20.5
|
||||
public static final Attribute HORSE_JUMP_STRENGTH = define("horse.jump_strength");
|
||||
public static final Attribute GENERIC_KNOCKBACK_RESISTANCE = define("generic.knockback_resistance");
|
||||
public static final Attribute GENERIC_LUCK = define("generic.luck");
|
||||
public static final Attribute GENERIC_MAX_HEALTH = define("generic.max_health");
|
||||
public static final Attribute GENERIC_MOVEMENT_SPEED = define("generic.movement_speed");
|
||||
public static final Attribute ZOMBIE_SPAWN_REINFORCEMENTS = define("zombie.spawn_reinforcements");
|
||||
|
||||
// Added in 1.20.2
|
||||
public static final Attribute GENERIC_MAX_ABSORPTION = define("generic.max_absorption");
|
||||
|
||||
// Added in 1.20.5
|
||||
public static final Attribute PLAYER_BLOCK_BREAK_SPEED = define("player.block_break_speed");
|
||||
public static final Attribute PLAYER_BLOCK_INTERACTION_RANGE = define("player.block_interaction_range");
|
||||
public static final Attribute PLAYER_ENTITY_INTERACTION_RANGE = define("player.entity_interaction_range");
|
||||
public static final Attribute GENERIC_FALL_DAMAGE_MULTIPLIER = define("generic.fall_damage_multiplier");
|
||||
public static final Attribute GENERIC_GRAVITY = define("generic.gravity");
|
||||
public static final Attribute GENERIC_JUMP_STRENGTH = define("generic.jump_strength");
|
||||
public static final Attribute GENERIC_SAFE_FALL_DISTANCE = define("generic.safe_fall_distance");
|
||||
public static final Attribute GENERIC_SCALE = define("generic.scale");
|
||||
public static final Attribute GENERIC_STEP_HEIGHT = define("generic.step_height");
|
||||
|
||||
// Added in 1.21
|
||||
public static final Attribute GENERIC_BURNING_TIME = define("generic.burning_time");
|
||||
public static final Attribute GENERIC_EXPLOSION_KNOCKBACK_RESISTANCE = define("generic.explosion_knockback_resistance");
|
||||
public static final Attribute PLAYER_MINING_EFFICIENCY = define("player.mining_efficiency");
|
||||
public static final Attribute GENERIC_MOVEMENT_EFFICIENCY = define("generic.movement_efficiency");
|
||||
public static final Attribute GENERIC_OXYGEN_BONUS = define("generic.oxygen_bonus");
|
||||
public static final Attribute PLAYER_SNEAKING_SPEED = define("player.sneaking_speed");
|
||||
public static final Attribute PLAYER_SUBMERGED_MINING_SPEED = define("player.submerged_mining_speed");
|
||||
public static final Attribute PLAYER_SWEEPING_DAMAGE_RATIO = define("player.sweeping_damage_ratio");
|
||||
public static final Attribute GENERIC_WATER_MOVEMENT_EFFICIENCY = define("generic.water_movement_efficiency");
|
||||
|
||||
static {
|
||||
TYPES_BUILDER.unloadFileMappings();
|
||||
}
|
||||
}
|
||||
@@ -18,8 +18,149 @@
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.chat;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.chat.message.ChatMessage_v1_19_1;
|
||||
import com.github.retrooper.packetevents.protocol.mapper.CopyableEntity;
|
||||
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBT;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.util.Index;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.UnknownNullability;
|
||||
|
||||
public interface ChatType extends MappedEntity {
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.github.retrooper.packetevents.util.adventure.AdventureIndexUtil.indexValueOrThrow;
|
||||
|
||||
public interface ChatType extends MappedEntity, CopyableEntity<ChatType> {
|
||||
|
||||
@UnknownNullability("only nullable for 1.19")
|
||||
ChatTypeDecoration getChatDecoration();
|
||||
|
||||
@ApiStatus.Obsolete(since = "1.19.1")
|
||||
@Nullable ChatTypeDecoration getOverlayDecoration();
|
||||
|
||||
@UnknownNullability("only nullable for 1.19")
|
||||
ChatTypeDecoration getNarrationDecoration();
|
||||
|
||||
@ApiStatus.Obsolete(since = "1.19.1")
|
||||
@Nullable NarrationPriority getNarrationPriority();
|
||||
|
||||
static ChatType readDirect(PacketWrapper<?> wrapper) {
|
||||
ChatTypeDecoration chatDecoration = ChatTypeDecoration.read(wrapper);
|
||||
ChatTypeDecoration narrationDecoration = ChatTypeDecoration.read(wrapper);
|
||||
return new StaticChatType(chatDecoration, narrationDecoration);
|
||||
}
|
||||
|
||||
static void writeDirect(PacketWrapper<?> wrapper, ChatType chatType) {
|
||||
ChatTypeDecoration.write(wrapper, chatType.getChatDecoration());
|
||||
ChatTypeDecoration.write(wrapper, chatType.getNarrationDecoration());
|
||||
}
|
||||
|
||||
static ChatType decode(NBT nbt, ClientVersion version, @Nullable TypesBuilderData data) {
|
||||
// everything is nullable in 1.19, even the chat format!
|
||||
NBTCompound compound = (NBTCompound) nbt;
|
||||
NBTCompound chatTag = compound.getCompoundTagOrNull("chat");
|
||||
NBTCompound narrationTag = compound.getCompoundTagOrNull("narration");
|
||||
|
||||
ChatTypeDecoration overlay = null;
|
||||
NarrationPriority narrationPriority = null;
|
||||
if (version.isOlderThan(ClientVersion.V_1_19_1)) {
|
||||
NBTCompound overlayTag = compound.getCompoundTagOrNull("overlay");
|
||||
if (overlayTag != null) {
|
||||
// why is this nullable? why is this wrapped? There is no reason to wrap this...
|
||||
overlayTag = overlayTag.getCompoundTagOrNull("description");
|
||||
if (overlayTag != null) {
|
||||
overlay = ChatTypeDecoration.decode(overlayTag, version);
|
||||
}
|
||||
}
|
||||
if (chatTag != null) {
|
||||
chatTag = chatTag.getCompoundTagOrNull("description");
|
||||
}
|
||||
if (narrationTag != null) {
|
||||
// the priority is the ONLY value which isn't nullable!
|
||||
narrationPriority = indexValueOrThrow(NarrationPriority.ID_INDEX,
|
||||
narrationTag.getStringTagValueOrThrow("priority"));
|
||||
narrationTag = narrationTag.getCompoundTagOrNull("description");
|
||||
}
|
||||
} else {
|
||||
// ensure this isn't null in everything but 1.19
|
||||
Objects.requireNonNull(chatTag, "NBT chat does not exist");
|
||||
Objects.requireNonNull(narrationTag, "NBT narration does not exist");
|
||||
}
|
||||
|
||||
ChatTypeDecoration chat = chatTag == null ? null : ChatTypeDecoration.decode(chatTag, version);
|
||||
ChatTypeDecoration narration = narrationTag == null ? null : ChatTypeDecoration.decode(narrationTag, version);
|
||||
return new StaticChatType(data, chat, overlay, narration, narrationPriority);
|
||||
}
|
||||
|
||||
static NBT encode(ChatType chatType, ClientVersion version) {
|
||||
NBTCompound compound = new NBTCompound();
|
||||
NBT chatTag = chatType.getChatDecoration() == null ? null :
|
||||
ChatTypeDecoration.encode(chatType.getChatDecoration(), version);
|
||||
NBT narrationTag = chatType.getNarrationDecoration() == null ? null :
|
||||
ChatTypeDecoration.encode(chatType.getNarrationDecoration(), version);
|
||||
|
||||
if (version.isOlderThan(ClientVersion.V_1_19_1)) {
|
||||
ChatTypeDecoration overlayDeco = chatType.getOverlayDecoration();
|
||||
if (overlayDeco != null) {
|
||||
NBTCompound overlayCompound = new NBTCompound();
|
||||
overlayCompound.setTag("description",
|
||||
ChatTypeDecoration.encode(overlayDeco, version));
|
||||
compound.setTag("overlay", overlayCompound);
|
||||
}
|
||||
if (narrationTag != null) {
|
||||
NBTCompound narrationCompound = new NBTCompound();
|
||||
narrationCompound.setTag("description", narrationTag);
|
||||
if (chatType.getNarrationPriority() != null) {
|
||||
narrationCompound.setTag("priority", new NBTString(chatType.getNarrationPriority().getId()));
|
||||
}
|
||||
narrationTag = narrationCompound;
|
||||
}
|
||||
if (chatTag != null) {
|
||||
NBTCompound chatCompound = new NBTCompound();
|
||||
chatCompound.setTag("description", chatTag);
|
||||
chatTag = chatCompound;
|
||||
}
|
||||
}
|
||||
|
||||
if (chatTag != null) {
|
||||
compound.setTag("chat", chatTag);
|
||||
}
|
||||
if (narrationTag != null) {
|
||||
compound.setTag("narration", narrationTag);
|
||||
}
|
||||
return compound;
|
||||
}
|
||||
|
||||
class Bound extends ChatMessage_v1_19_1.ChatTypeBoundNetwork {
|
||||
public Bound(ChatType type, Component name, @Nullable Component targetName) {
|
||||
super(type, name, targetName);
|
||||
}
|
||||
}
|
||||
|
||||
@ApiStatus.Obsolete(since = "1.19.1")
|
||||
enum NarrationPriority {
|
||||
|
||||
CHAT("chat"),
|
||||
SYSTEM("system");
|
||||
|
||||
public static final Index<String, NarrationPriority> ID_INDEX = Index.create(
|
||||
NarrationPriority.class, NarrationPriority::getId);
|
||||
|
||||
private final String id;
|
||||
|
||||
NarrationPriority(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.chat;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBT;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTList;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.util.adventure.AdventureSerializer;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.ComponentLike;
|
||||
import net.kyori.adventure.text.format.Style;
|
||||
import net.kyori.adventure.util.Index;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import static com.github.retrooper.packetevents.protocol.chat.ChatTypeDecoration.Parameter.CONTENT;
|
||||
import static com.github.retrooper.packetevents.protocol.chat.ChatTypeDecoration.Parameter.SENDER;
|
||||
import static com.github.retrooper.packetevents.protocol.chat.ChatTypeDecoration.Parameter.TARGET;
|
||||
import static com.github.retrooper.packetevents.util.adventure.AdventureIndexUtil.indexValueOrThrow;
|
||||
import static java.util.Arrays.asList;
|
||||
import static net.kyori.adventure.text.format.NamedTextColor.GRAY;
|
||||
import static net.kyori.adventure.text.format.Style.empty;
|
||||
import static net.kyori.adventure.text.format.Style.style;
|
||||
import static net.kyori.adventure.text.format.TextDecoration.ITALIC;
|
||||
|
||||
public class ChatTypeDecoration {
|
||||
|
||||
private final String translationKey;
|
||||
private final List<Parameter> parameters;
|
||||
private final Style style;
|
||||
|
||||
public ChatTypeDecoration(String translationKey, List<Parameter> parameters, Style style) {
|
||||
this.translationKey = translationKey;
|
||||
this.parameters = Collections.unmodifiableList(new ArrayList<>(parameters));
|
||||
this.style = style;
|
||||
}
|
||||
|
||||
public static ChatTypeDecoration read(PacketWrapper<?> wrapper) {
|
||||
String translationKey = wrapper.readString();
|
||||
List<Parameter> parameters = wrapper.readList(ew -> ew.readEnum(Parameter.values()));
|
||||
Style style = wrapper.readStyle();
|
||||
return new ChatTypeDecoration(translationKey, parameters, style);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, ChatTypeDecoration decoration) {
|
||||
wrapper.writeString(decoration.translationKey);
|
||||
wrapper.writeList(decoration.parameters, PacketWrapper::writeEnum);
|
||||
wrapper.writeStyle(decoration.style);
|
||||
}
|
||||
|
||||
public static ChatTypeDecoration decode(NBT nbt, ClientVersion version) {
|
||||
NBTCompound compound = (NBTCompound) nbt;
|
||||
String translationKey = compound.getStringTagValueOrThrow("translation_key");
|
||||
NBT paramsTag = compound.getTagOrThrow("parameters");
|
||||
List<Parameter> params;
|
||||
if (paramsTag instanceof NBTList<?>) {
|
||||
params = new ArrayList<>();
|
||||
NBTList<?> paramsTagList = (NBTList<?>) paramsTag;
|
||||
for (NBT paramTag : paramsTagList.getTags()) {
|
||||
String paramId = ((NBTString) paramTag).getValue();
|
||||
params.add(indexValueOrThrow(Parameter.ID_INDEX, paramId));
|
||||
}
|
||||
} else {
|
||||
String paramId = ((NBTString) paramsTag).getValue();
|
||||
params = Collections.singletonList(indexValueOrThrow(Parameter.ID_INDEX, paramId));
|
||||
}
|
||||
NBTCompound styleTag = compound.getCompoundTagOrNull("style");
|
||||
Style style = styleTag == null ? empty() :
|
||||
AdventureSerializer.getNBTSerializer().deserializeStyle(styleTag);
|
||||
return new ChatTypeDecoration(translationKey, params, style);
|
||||
}
|
||||
|
||||
public static NBT encode(ChatTypeDecoration decoration, ClientVersion version) {
|
||||
NBTList<NBTString> paramsTag = NBTList.createStringList();
|
||||
for (Parameter param : decoration.parameters) {
|
||||
paramsTag.addTag(new NBTString(param.getId()));
|
||||
}
|
||||
|
||||
NBTCompound compound = new NBTCompound();
|
||||
compound.setTag("translation_key", new NBTString(decoration.translationKey));
|
||||
compound.setTag("parameters", paramsTag);
|
||||
if (!decoration.style.isEmpty()) {
|
||||
compound.setTag("style", AdventureSerializer.getNBTSerializer()
|
||||
.serializeStyle(decoration.style));
|
||||
}
|
||||
return compound;
|
||||
}
|
||||
|
||||
public static ChatTypeDecoration withSender(String translationKey) {
|
||||
return new ChatTypeDecoration(translationKey, asList(SENDER, CONTENT), empty());
|
||||
}
|
||||
|
||||
public static ChatTypeDecoration incomingDirectMessage(String translationKey) {
|
||||
return new ChatTypeDecoration(translationKey, asList(SENDER, CONTENT),
|
||||
style(GRAY, ITALIC));
|
||||
}
|
||||
|
||||
public static ChatTypeDecoration outgoingDirectMessage(String translationKey) {
|
||||
return new ChatTypeDecoration(translationKey, asList(TARGET, CONTENT),
|
||||
style(GRAY, ITALIC));
|
||||
}
|
||||
|
||||
public static ChatTypeDecoration teamMessage(String translationKey) {
|
||||
return new ChatTypeDecoration(translationKey, asList(TARGET, SENDER, CONTENT), empty());
|
||||
}
|
||||
|
||||
public Component decorate(Component component, ChatType.Bound chatType) {
|
||||
ComponentLike[] components = new ComponentLike[this.parameters.size()];
|
||||
for (int i = 0; i < components.length; i++) {
|
||||
Parameter parameter = this.parameters.get(i);
|
||||
components[i] = parameter.selector.apply(component, chatType);
|
||||
}
|
||||
return Component.translatable(this.translationKey, null, this.style, components);
|
||||
}
|
||||
|
||||
public String getTranslationKey() {
|
||||
return this.translationKey;
|
||||
}
|
||||
|
||||
public List<Parameter> getParameters() {
|
||||
return this.parameters;
|
||||
}
|
||||
|
||||
public Style getStyle() {
|
||||
return this.style;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof ChatTypeDecoration)) return false;
|
||||
ChatTypeDecoration that = (ChatTypeDecoration) obj;
|
||||
if (!this.translationKey.equals(that.translationKey)) return false;
|
||||
if (!this.parameters.equals(that.parameters)) return false;
|
||||
return this.style.equals(that.style);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.translationKey, this.parameters, this.style);
|
||||
}
|
||||
|
||||
public enum Parameter {
|
||||
|
||||
SENDER("sender", (component, type) -> type.getName()),
|
||||
TARGET("target", (component, type) -> type.getTargetName() != null
|
||||
? type.getTargetName() : Component.empty()),
|
||||
CONTENT("content", (component, type) -> component);
|
||||
|
||||
public static final Index<String, Parameter> ID_INDEX = Index.create(
|
||||
Parameter.class, Parameter::getId);
|
||||
|
||||
private final String id;
|
||||
private final BiFunction<Component, ChatType.Bound, Component> selector;
|
||||
|
||||
Parameter(String id, BiFunction<Component, ChatType.Bound, Component> selector) {
|
||||
this.id = id;
|
||||
this.selector = selector;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static @Nullable Parameter valueByName(String id) {
|
||||
return ID_INDEX.value(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,68 +19,68 @@
|
||||
package com.github.retrooper.packetevents.protocol.chat;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.TypesBuilder;
|
||||
import com.github.retrooper.packetevents.util.TypesBuilderData;
|
||||
import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
|
||||
public class ChatTypes {
|
||||
private static final Map<String, ChatType> CHAT_TYPE_MAP = new HashMap<>();
|
||||
//Key - mappings version, value - map with chat type ids and chat types
|
||||
private static final Map<Byte, Map<Integer, ChatType>> CHAT_TYPE_ID_MAP = new HashMap<>();
|
||||
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("chat/chat_type_mappings",
|
||||
ClientVersion.V_1_18_2,
|
||||
ClientVersion.V_1_19,
|
||||
ClientVersion.V_1_19_1);
|
||||
import static com.github.retrooper.packetevents.protocol.chat.ChatTypeDecoration.incomingDirectMessage;
|
||||
import static com.github.retrooper.packetevents.protocol.chat.ChatTypeDecoration.outgoingDirectMessage;
|
||||
import static com.github.retrooper.packetevents.protocol.chat.ChatTypeDecoration.teamMessage;
|
||||
import static com.github.retrooper.packetevents.protocol.chat.ChatTypeDecoration.withSender;
|
||||
|
||||
static {
|
||||
TYPES_BUILDER.unloadFileMappings();
|
||||
public final class ChatTypes {
|
||||
|
||||
private static final VersionedRegistry<ChatType> REGISTRY = new VersionedRegistry<>(
|
||||
"chat_type", "chat/chat_type_mappings");
|
||||
|
||||
private ChatTypes() {
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static ChatType define(String key) {
|
||||
TypesBuilderData data = TYPES_BUILDER.define(key);
|
||||
ChatType chatType = new ChatType() {
|
||||
private final int[] ids = data.getData();
|
||||
|
||||
@Override
|
||||
public ResourceLocation getName() {
|
||||
return data.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId(ClientVersion version) {
|
||||
int index = TYPES_BUILDER.getDataIndex(version);
|
||||
return ids[index];
|
||||
}
|
||||
};
|
||||
CHAT_TYPE_MAP.put(chatType.getName().toString(), chatType);
|
||||
for (ClientVersion version : TYPES_BUILDER.getVersions()) {
|
||||
int index = TYPES_BUILDER.getDataIndex(version);
|
||||
Map<Integer, ChatType> typeIdMap = CHAT_TYPE_ID_MAP.computeIfAbsent((byte) index, k -> new HashMap<>());
|
||||
typeIdMap.put(chatType.getId(version), chatType);
|
||||
}
|
||||
return chatType;
|
||||
return define(key, withSender("chat.type.text"));
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static ChatType define(String key, ChatTypeDecoration chatDeco) {
|
||||
return define(key, chatDeco, withSender("chat.type.text.narrate"));
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static ChatType define(String key, ChatTypeDecoration chatDeco, ChatTypeDecoration narrationDeco) {
|
||||
return REGISTRY.define(key, data ->
|
||||
new StaticChatType(data, chatDeco, narrationDeco));
|
||||
}
|
||||
|
||||
public static VersionedRegistry<ChatType> getRegistry() {
|
||||
return REGISTRY;
|
||||
}
|
||||
|
||||
//with minecraft:key
|
||||
public static ChatType getByName(String name) {
|
||||
return CHAT_TYPE_MAP.get(name);
|
||||
return REGISTRY.getByName(name);
|
||||
}
|
||||
|
||||
public static ChatType getById(ClientVersion version, int id) {
|
||||
int index = TYPES_BUILDER.getDataIndex(version);
|
||||
return CHAT_TYPE_ID_MAP.get((byte) index).get(id);
|
||||
return REGISTRY.getById(version, id);
|
||||
}
|
||||
|
||||
public static final ChatType CHAT = define("chat");
|
||||
public static final ChatType SAY_COMMAND = define("say_command");
|
||||
public static final ChatType MSG_COMMAND_INCOMING = define("msg_command_incoming");
|
||||
public static final ChatType MSG_COMMAND_OUTGOING = define("msg_command_outgoing");
|
||||
public static final ChatType TEAM_MSG_COMMAND_INCOMING = define("team_msg_command_incoming");
|
||||
public static final ChatType TEAM_MSG_COMMAND_OUTGOING = define("team_msg_command_outgoing");
|
||||
public static final ChatType EMOTE_COMMAND = define("emote_command");
|
||||
public static final ChatType SAY_COMMAND = define("say_command",
|
||||
withSender("chat.type.announcement"));
|
||||
public static final ChatType MSG_COMMAND_INCOMING = define("msg_command_incoming",
|
||||
incomingDirectMessage("commands.message.display.incoming"));
|
||||
public static final ChatType MSG_COMMAND_OUTGOING = define("msg_command_outgoing",
|
||||
outgoingDirectMessage("commands.message.display.outgoing"));
|
||||
public static final ChatType TEAM_MSG_COMMAND_INCOMING = define("team_msg_command_incoming",
|
||||
teamMessage("chat.type.team.text"));
|
||||
public static final ChatType TEAM_MSG_COMMAND_OUTGOING = define("team_msg_command_outgoing",
|
||||
teamMessage("chat.type.team.sent"));
|
||||
public static final ChatType EMOTE_COMMAND = define("emote_command",
|
||||
withSender("chat.type.emote"),
|
||||
withSender("chat.type.emote"));
|
||||
|
||||
// added by CraftBukkit for a few versions
|
||||
public static final ChatType RAW = define("raw");
|
||||
|
||||
@Deprecated
|
||||
@@ -91,4 +91,17 @@ public class ChatTypes {
|
||||
public static final ChatType MSG_COMMAND = define("msg_command");
|
||||
@Deprecated
|
||||
public static final ChatType TEAM_MSG_COMMAND = define("team_msg_command");
|
||||
|
||||
/**
|
||||
* Returns an immutable view of the chat types.
|
||||
*
|
||||
* @return Chat Types
|
||||
*/
|
||||
public static Collection<ChatType> values() {
|
||||
return REGISTRY.getEntries();
|
||||
}
|
||||
|
||||
static {
|
||||
REGISTRY.unloadMappings();
|
||||
}
|
||||
}
|
||||
@@ -16,9 +16,10 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.chat;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.protocol.chat.Parsers.Parser;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -26,20 +27,33 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class Node {
|
||||
|
||||
private byte flags;
|
||||
private List<Integer> children;
|
||||
private Optional<Integer> redirectNodeIndex;
|
||||
private int redirectNodeIndex;
|
||||
private Optional<String> name;
|
||||
private Optional<Integer> parserID;
|
||||
private Optional<Parser> parser;
|
||||
private Optional<List<Object>> properties;
|
||||
private Optional<ResourceLocation> suggestionsType;
|
||||
|
||||
public Node(byte flags, List<Integer> children, @Nullable Integer redirectNodeIndex, @Nullable String name, @Nullable Integer parserID, @Nullable List<Object> properties, @Nullable ResourceLocation suggestionsType) {
|
||||
public Node(
|
||||
byte flags, List<Integer> children, int redirectNodeIndex, @Nullable String name,
|
||||
@Nullable Integer parserID, @Nullable List<Object> properties, @Nullable ResourceLocation suggestionsType
|
||||
) {
|
||||
this(flags, children, redirectNodeIndex, name, parserID == null ? null : Parsers.getById(
|
||||
PacketEvents.getAPI().getServerManager().getVersion().toClientVersion(), parserID),
|
||||
properties, suggestionsType);
|
||||
}
|
||||
|
||||
public Node(
|
||||
byte flags, List<Integer> children, int redirectNodeIndex, @Nullable String name, @Nullable Parser parser,
|
||||
@Nullable List<Object> properties, @Nullable ResourceLocation suggestionsType
|
||||
) {
|
||||
this.flags = flags;
|
||||
this.children = children;
|
||||
this.redirectNodeIndex = Optional.ofNullable(redirectNodeIndex);
|
||||
this.redirectNodeIndex = redirectNodeIndex;
|
||||
this.name = Optional.ofNullable(name);
|
||||
this.parserID = Optional.ofNullable(parserID);
|
||||
this.parser = Optional.ofNullable(parser);
|
||||
this.properties = Optional.ofNullable(properties);
|
||||
this.suggestionsType = Optional.ofNullable(suggestionsType);
|
||||
}
|
||||
@@ -60,11 +74,11 @@ public class Node {
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
public Optional<Integer> getRedirectNodeIndex() {
|
||||
public int getRedirectNodeIndex() {
|
||||
return redirectNodeIndex;
|
||||
}
|
||||
|
||||
public void setRedirectNodeIndex(Optional<Integer> redirectNodeIndex) {
|
||||
public void setRedirectNodeIndex(int redirectNodeIndex) {
|
||||
this.redirectNodeIndex = redirectNodeIndex;
|
||||
}
|
||||
|
||||
@@ -76,12 +90,22 @@ public class Node {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Optional<Parser> getParser() {
|
||||
return this.parser;
|
||||
}
|
||||
|
||||
public void setParser(Optional<Parser> parser) {
|
||||
this.parser = parser;
|
||||
}
|
||||
|
||||
public Optional<Integer> getParserID() {
|
||||
return parserID;
|
||||
return this.parser.map(parser -> parser.getId(PacketEvents.getAPI()
|
||||
.getServerManager().getVersion().toClientVersion()));
|
||||
}
|
||||
|
||||
public void setParserID(Optional<Integer> parserID) {
|
||||
this.parserID = parserID;
|
||||
this.parser = parserID.map(id -> Parsers.getById(PacketEvents.getAPI()
|
||||
.getServerManager().getVersion().toClientVersion(), id));
|
||||
}
|
||||
|
||||
public Optional<List<Object>> getProperties() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2022 retrooper and contributors
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -16,170 +16,265 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.chat;
|
||||
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.mappings.MappingHelper;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilder;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class Parsers {
|
||||
private static final List<Parser> parsers = Arrays.asList(
|
||||
new Parser("brigadier:bool", null, null),
|
||||
new Parser("brigadier:float",
|
||||
packetWrapper -> {
|
||||
byte flags = packetWrapper.readByte();
|
||||
float min = (flags & 0x01) != 0 ? packetWrapper.readFloat() : -Float.MAX_VALUE;
|
||||
float max = (flags & 0x02) != 0 ? packetWrapper.readFloat() : Float.MAX_VALUE;
|
||||
return Arrays.asList(flags, min, max);
|
||||
},
|
||||
(packetWrapper, properties) -> {
|
||||
byte flags = (byte) properties.get(0);
|
||||
packetWrapper.writeByte(flags);
|
||||
if ((flags & 0x01) != 0) packetWrapper.writeFloat((float) properties.get(1));
|
||||
if ((flags & 0x02) != 0) packetWrapper.writeFloat((float) properties.get(2));
|
||||
}
|
||||
),
|
||||
new Parser("brigadier:double",
|
||||
packetWrapper -> {
|
||||
byte flags = packetWrapper.readByte();
|
||||
double min = (flags & 0x01) != 0 ? packetWrapper.readDouble() : -Double.MAX_VALUE;
|
||||
double max = (flags & 0x02) != 0 ? packetWrapper.readDouble() : Double.MAX_VALUE;
|
||||
return Arrays.asList(flags, min, max);
|
||||
},
|
||||
(packetWrapper, properties) -> {
|
||||
byte flags = (byte) properties.get(0);
|
||||
packetWrapper.writeByte(flags);
|
||||
if ((flags & 0x01) != 0) packetWrapper.writeDouble((double) properties.get(1));
|
||||
if ((flags & 0x02) != 0) packetWrapper.writeDouble((double) properties.get(2));
|
||||
}
|
||||
),
|
||||
new Parser("brigadier:integer",
|
||||
packetWrapper -> {
|
||||
byte flags = packetWrapper.readByte();
|
||||
int min = (flags & 0x01) != 0 ? packetWrapper.readInt() : Integer.MIN_VALUE;
|
||||
int max = (flags & 0x02) != 0 ? packetWrapper.readInt() : Integer.MAX_VALUE;
|
||||
return Arrays.asList(flags, min, max);
|
||||
},
|
||||
(packetWrapper, properties) -> {
|
||||
byte flags = (byte) properties.get(0);
|
||||
packetWrapper.writeByte(flags);
|
||||
if ((flags & 0x01) != 0) packetWrapper.writeInt((int) properties.get(1));
|
||||
if ((flags & 0x02) != 0) packetWrapper.writeInt((int) properties.get(2));
|
||||
}
|
||||
),
|
||||
new Parser("brigadier:long",
|
||||
packetWrapper -> {
|
||||
byte flags = packetWrapper.readByte();
|
||||
long min = (flags & 0x01) != 0 ? packetWrapper.readLong() : Long.MIN_VALUE;
|
||||
long max = (flags & 0x02) != 0 ? packetWrapper.readLong() : Long.MAX_VALUE;
|
||||
return Arrays.asList(flags, min, max);
|
||||
},
|
||||
(packetWrapper, properties) -> {
|
||||
byte flags = (byte) properties.get(0);
|
||||
packetWrapper.writeByte(flags);
|
||||
if ((flags & 0x01) != 0) packetWrapper.writeLong((long) properties.get(1));
|
||||
if ((flags & 0x02) != 0) packetWrapper.writeLong((long) properties.get(2));
|
||||
}
|
||||
),
|
||||
new Parser("brigadier:string",
|
||||
packetWrapper -> Collections.singletonList(packetWrapper.readVarInt()),
|
||||
(packetWrapper, properties) -> packetWrapper.writeVarInt((Integer) properties.get(0))
|
||||
),
|
||||
new Parser("brigadier:entity",
|
||||
packetWrapper -> Collections.singletonList(packetWrapper.readByte()),
|
||||
(packetWrapper, properties) -> packetWrapper.writeByte(((Byte) properties.get(0)).intValue())
|
||||
),
|
||||
new Parser("brigadier:game_profile", null, null),
|
||||
new Parser("brigadier:block_pos", null, null),
|
||||
new Parser("brigadier:column_pos", null, null),
|
||||
new Parser("brigadier:vec3", null, null),
|
||||
new Parser("brigadier:vec2", null, null),
|
||||
new Parser("brigadier:block_state", null, null),
|
||||
new Parser("brigadier:block_predicate", null, null),
|
||||
new Parser("brigadier:item_stack", null, null),
|
||||
new Parser("brigadier:item_predicate", null, null),
|
||||
new Parser("brigadier:color", null, null),
|
||||
new Parser("brigadier:component", null, null),
|
||||
new Parser("brigadier:message", null, null),
|
||||
new Parser("brigadier:nbt", null, null),
|
||||
new Parser("brigadier:nbt_tag", null, null),
|
||||
new Parser("brigadier:nbt_path", null, null),
|
||||
new Parser("brigadier:objective", null, null),
|
||||
new Parser("brigadier:objective_criteria", null, null),
|
||||
new Parser("brigadier:operation", null, null),
|
||||
new Parser("brigadier:particle", null, null),
|
||||
new Parser("brigadier:angle", null, null),
|
||||
new Parser("brigadier:rotation", null, null),
|
||||
new Parser("brigadier:scoreboard_slot", null, null),
|
||||
new Parser("brigadier:score_holder",
|
||||
packetWrapper -> Collections.singletonList(packetWrapper.readByte()),
|
||||
(packetWrapper, properties) -> packetWrapper.writeByte(((Byte) properties.get(0)).intValue())
|
||||
),
|
||||
new Parser("brigadier:swizzle", null, null),
|
||||
new Parser("brigadier:team", null, null),
|
||||
new Parser("brigadier:item_slot", null, null),
|
||||
new Parser("brigadier:resource_location", null, null),
|
||||
new Parser("brigadier:function", null, null),
|
||||
new Parser("brigadier:entity_anchor", null, null),
|
||||
new Parser("brigadier:int_range", null, null),
|
||||
new Parser("brigadier:float_range", null, null),
|
||||
new Parser("brigadier:dimension", null, null),
|
||||
new Parser("brigadier:gamemode", null, null),
|
||||
new Parser("brigadier:time",
|
||||
packetWrapper -> Collections.singletonList(packetWrapper.readInt()),
|
||||
(packetWrapper, properties) -> packetWrapper.writeInt((int) properties.get(0))
|
||||
),
|
||||
new Parser("brigadier:resource_or_tag",
|
||||
packetWrapper -> Collections.singletonList(packetWrapper.readIdentifier()),
|
||||
(packetWrapper, properties) -> packetWrapper.writeIdentifier((ResourceLocation) properties.get(0))
|
||||
),
|
||||
new Parser("brigadier:resource_or_tag_key",
|
||||
packetWrapper -> Collections.singletonList(packetWrapper.readIdentifier()),
|
||||
(packetWrapper, properties) -> packetWrapper.writeIdentifier((ResourceLocation) properties.get(0))
|
||||
),
|
||||
new Parser("brigadier:resource",
|
||||
packetWrapper -> Collections.singletonList(packetWrapper.readIdentifier()),
|
||||
(packetWrapper, properties) -> packetWrapper.writeIdentifier((ResourceLocation) properties.get(0))
|
||||
),
|
||||
new Parser("brigadier:resource_key",
|
||||
packetWrapper -> Collections.singletonList(packetWrapper.readIdentifier()),
|
||||
(packetWrapper, properties) -> packetWrapper.writeIdentifier((ResourceLocation) properties.get(0))
|
||||
),
|
||||
new Parser("brigadier:template_mirror", null, null),
|
||||
new Parser("brigadier:template_rotation", null, null),
|
||||
new Parser("brigadier:heightmap", null, null),
|
||||
new Parser("brigadier:uuid", null, null)
|
||||
);
|
||||
|
||||
public static List<Parser> getParsers() {
|
||||
return parsers;
|
||||
private static final List<Parser> ALL_PARSERS = new ArrayList<>(); // support for old methods
|
||||
private static final Map<String, Parser> PARSER_MAP = new HashMap<>();
|
||||
private static final Map<Byte, Map<Integer, Parser>> PARSER_ID_MAP = new HashMap<>();
|
||||
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("command/argument_parser_mappings");
|
||||
|
||||
public static Parser define(String key) {
|
||||
return define(key, null, null);
|
||||
}
|
||||
|
||||
public static final class Parser {
|
||||
private final String name; //not really needed, just for toString or something
|
||||
private final Optional<Function<PacketWrapper<?>, List<Object>>> read;
|
||||
private final Optional<BiConsumer<PacketWrapper<?>, List<Object>>> write;
|
||||
public static Parser define(String key, @Nullable Reader reader, @Nullable Writer writer) {
|
||||
TypesBuilderData data = TYPES_BUILDER.define(key);
|
||||
Parser parser = new Parser(data, reader, writer);
|
||||
|
||||
ALL_PARSERS.add(parser);
|
||||
MappingHelper.registerMapping(TYPES_BUILDER, PARSER_MAP, PARSER_ID_MAP, parser);
|
||||
return parser;
|
||||
}
|
||||
|
||||
// with key
|
||||
public static Parser getByName(String name) {
|
||||
return PARSER_MAP.get(name);
|
||||
}
|
||||
|
||||
public static Parser getById(ClientVersion version, int id) {
|
||||
int index = TYPES_BUILDER.getDataIndex(version);
|
||||
Map<Integer, Parser> idMap = PARSER_ID_MAP.get((byte) index);
|
||||
return idMap.get(id);
|
||||
}
|
||||
|
||||
public static List<Parser> getParsers() {
|
||||
return Collections.unmodifiableList(ALL_PARSERS);
|
||||
}
|
||||
|
||||
public static final Parser BRIGADIER_BOOL = define("brigadier:bool", null, null);
|
||||
public static final Parser BRIGADIER_FLOAT = define("brigadier:float",
|
||||
packetWrapper -> {
|
||||
byte flags = packetWrapper.readByte();
|
||||
float min = (flags & 0x01) != 0 ? packetWrapper.readFloat() : -Float.MAX_VALUE;
|
||||
float max = (flags & 0x02) != 0 ? packetWrapper.readFloat() : Float.MAX_VALUE;
|
||||
return Arrays.asList(flags, min, max);
|
||||
},
|
||||
(packetWrapper, properties) -> {
|
||||
byte flags = (byte) properties.get(0);
|
||||
packetWrapper.writeByte(flags);
|
||||
if ((flags & 0x01) != 0) packetWrapper.writeFloat((float) properties.get(1));
|
||||
if ((flags & 0x02) != 0) packetWrapper.writeFloat((float) properties.get(2));
|
||||
}
|
||||
);
|
||||
public static final Parser BRIGADIER_DOUBLE = define("brigadier:double",
|
||||
packetWrapper -> {
|
||||
byte flags = packetWrapper.readByte();
|
||||
double min = (flags & 0x01) != 0 ? packetWrapper.readDouble() : -Double.MAX_VALUE;
|
||||
double max = (flags & 0x02) != 0 ? packetWrapper.readDouble() : Double.MAX_VALUE;
|
||||
return Arrays.asList(flags, min, max);
|
||||
},
|
||||
(packetWrapper, properties) -> {
|
||||
byte flags = (byte) properties.get(0);
|
||||
packetWrapper.writeByte(flags);
|
||||
if ((flags & 0x01) != 0) packetWrapper.writeDouble((double) properties.get(1));
|
||||
if ((flags & 0x02) != 0) packetWrapper.writeDouble((double) properties.get(2));
|
||||
}
|
||||
);
|
||||
public static final Parser BRIGADIER_INTEGER = define("brigadier:integer",
|
||||
packetWrapper -> {
|
||||
byte flags = packetWrapper.readByte();
|
||||
int min = (flags & 0x01) != 0 ? packetWrapper.readInt() : Integer.MIN_VALUE;
|
||||
int max = (flags & 0x02) != 0 ? packetWrapper.readInt() : Integer.MAX_VALUE;
|
||||
return Arrays.asList(flags, min, max);
|
||||
},
|
||||
(packetWrapper, properties) -> {
|
||||
byte flags = (byte) properties.get(0);
|
||||
packetWrapper.writeByte(flags);
|
||||
if ((flags & 0x01) != 0) packetWrapper.writeInt((int) properties.get(1));
|
||||
if ((flags & 0x02) != 0) packetWrapper.writeInt((int) properties.get(2));
|
||||
}
|
||||
);
|
||||
public static final Parser BRIGADIER_LONG = define("brigadier:long",
|
||||
packetWrapper -> {
|
||||
byte flags = packetWrapper.readByte();
|
||||
long min = (flags & 0x01) != 0 ? packetWrapper.readLong() : Long.MIN_VALUE;
|
||||
long max = (flags & 0x02) != 0 ? packetWrapper.readLong() : Long.MAX_VALUE;
|
||||
return Arrays.asList(flags, min, max);
|
||||
},
|
||||
(packetWrapper, properties) -> {
|
||||
byte flags = (byte) properties.get(0);
|
||||
packetWrapper.writeByte(flags);
|
||||
if ((flags & 0x01) != 0) packetWrapper.writeLong((long) properties.get(1));
|
||||
if ((flags & 0x02) != 0) packetWrapper.writeLong((long) properties.get(2));
|
||||
}
|
||||
);
|
||||
public static final Parser BRIGADIER_STRING = define("brigadier:string",
|
||||
packetWrapper -> Collections.singletonList(packetWrapper.readVarInt()),
|
||||
(packetWrapper, properties) -> packetWrapper.writeVarInt((Integer) properties.get(0))
|
||||
);
|
||||
public static final Parser ENTITY = define("entity",
|
||||
packetWrapper -> Collections.singletonList(packetWrapper.readByte()),
|
||||
(packetWrapper, properties) -> packetWrapper.writeByte(((Byte) properties.get(0)).intValue())
|
||||
);
|
||||
public static final Parser GAME_PROFILE = define("game_profile", null, null);
|
||||
public static final Parser BLOCK_POS = define("block_pos", null, null);
|
||||
public static final Parser COLUMN_POS = define("column_pos", null, null);
|
||||
public static final Parser VEC3 = define("vec3", null, null);
|
||||
public static final Parser VEC2 = define("vec2", null, null);
|
||||
public static final Parser BLOCK_STATE = define("block_state", null, null);
|
||||
public static final Parser BLOCK_PREDICATE = define("block_predicate", null, null);
|
||||
public static final Parser ITEM_STACK = define("item_stack", null, null);
|
||||
public static final Parser ITEM_PREDICATE = define("item_predicate", null, null);
|
||||
public static final Parser COLOR = define("color", null, null);
|
||||
public static final Parser COMPONENT = define("component", null, null);
|
||||
public static final Parser STYLE = define("style", null, null);
|
||||
public static final Parser MESSAGE = define("message", null, null);
|
||||
public static final Parser NBT_COMPOUND_TAG = define("nbt_compound_tag", null, null);
|
||||
@Deprecated
|
||||
public static final Parser NBT = NBT_COMPOUND_TAG;
|
||||
public static final Parser NBT_TAG = define("nbt_tag", null, null);
|
||||
public static final Parser NBT_PATH = define("nbt_path", null, null);
|
||||
public static final Parser OBJECTIVE = define("objective", null, null);
|
||||
public static final Parser OBJECTIVE_CRITERIA = define("objective_criteria", null, null);
|
||||
public static final Parser OPERATION = define("operation", null, null);
|
||||
public static final Parser PARTICLE = define("particle", null, null);
|
||||
public static final Parser ANGLE = define("angle", null, null);
|
||||
public static final Parser ROTATION = define("rotation", null, null);
|
||||
public static final Parser SCOREBOARD_SLOT = define("scoreboard_slot", null, null);
|
||||
public static final Parser SCORE_HOLDER = define("score_holder",
|
||||
packetWrapper -> Collections.singletonList(packetWrapper.readByte()),
|
||||
(packetWrapper, properties) -> packetWrapper.writeByte(((Byte) properties.get(0)).intValue())
|
||||
);
|
||||
public static final Parser SWIZZLE = define("swizzle", null, null);
|
||||
public static final Parser TEAM = define("team", null, null);
|
||||
public static final Parser ITEM_SLOT = define("item_slot", null, null);
|
||||
public static final Parser ITEM_SLOTS = define("item_slots", null, null);
|
||||
public static final Parser RESOURCE_LOCATION = define("resource_location", null, null);
|
||||
public static final Parser MOB_EFFECT = define("mob_effect", null, null);
|
||||
public static final Parser FUNCTION = define("function", null, null);
|
||||
public static final Parser ENTITY_ANCHOR = define("entity_anchor", null, null);
|
||||
public static final Parser INT_RANGE = define("int_range", null, null);
|
||||
public static final Parser FLOAT_RANGE = define("float_range", null, null);
|
||||
public static final Parser ITEM_ENCHANTMENT = define("item_enchantment", null, null);
|
||||
public static final Parser ENTITY_SUMMON = define("entity_summon", null, null);
|
||||
public static final Parser DIMENSION = define("dimension", null, null);
|
||||
public static final Parser GAMEMODE = define("gamemode", null, null);
|
||||
public static final Parser TIME = define("time",
|
||||
wrapper -> Collections.singletonList(wrapper.getServerVersion()
|
||||
.isNewerThanOrEquals(ServerVersion.V_1_19_4) ? wrapper.readInt() : 0),
|
||||
(wrapper, properties) -> {
|
||||
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_19_4)) {
|
||||
wrapper.writeInt((int) properties.get(0));
|
||||
}
|
||||
}
|
||||
);
|
||||
public static final Parser RESOURCE_OR_TAG = define("resource_or_tag",
|
||||
packetWrapper -> Collections.singletonList(packetWrapper.readIdentifier()),
|
||||
(packetWrapper, properties) -> packetWrapper.writeIdentifier((ResourceLocation) properties.get(0))
|
||||
);
|
||||
public static final Parser RESOURCE_OR_TAG_KEY = define("resource_or_tag_key",
|
||||
packetWrapper -> Collections.singletonList(packetWrapper.readIdentifier()),
|
||||
(packetWrapper, properties) -> packetWrapper.writeIdentifier((ResourceLocation) properties.get(0))
|
||||
);
|
||||
public static final Parser RESOURCE = define("resource",
|
||||
packetWrapper -> Collections.singletonList(packetWrapper.readIdentifier()),
|
||||
(packetWrapper, properties) -> packetWrapper.writeIdentifier((ResourceLocation) properties.get(0))
|
||||
);
|
||||
public static final Parser RESOURCE_KEY = define("resource_key",
|
||||
packetWrapper -> Collections.singletonList(packetWrapper.readIdentifier()),
|
||||
(packetWrapper, properties) -> packetWrapper.writeIdentifier((ResourceLocation) properties.get(0))
|
||||
);
|
||||
public static final Parser TEMPLATE_MIRROR = define("template_mirror", null, null);
|
||||
public static final Parser TEMPLATE_ROTATION = define("template_rotation", null, null);
|
||||
public static final Parser HEIGHTMAP = define("heightmap", null, null);
|
||||
public static final Parser LOOT_TABLE = define("loot_table", null, null);
|
||||
public static final Parser LOOT_PREDICATE = define("loot_predicate", null, null);
|
||||
public static final Parser LOOT_MODIFIER = define("loot_modifier", null, null);
|
||||
public static final Parser UUID = define("uuid", null, null);
|
||||
|
||||
static {
|
||||
TYPES_BUILDER.unloadFileMappings();
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Reader extends Function<PacketWrapper<?>, List<Object>> {}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Writer extends BiConsumer<PacketWrapper<?>, List<Object>> {}
|
||||
|
||||
public static final class Parser implements MappedEntity {
|
||||
|
||||
private final TypesBuilderData data;
|
||||
private final Reader reader;
|
||||
private final Writer writer;
|
||||
|
||||
@Deprecated
|
||||
public Parser(String name, @Nullable Function<PacketWrapper<?>, List<Object>> read, @Nullable BiConsumer<PacketWrapper<?>, List<Object>> write) {
|
||||
this.name = name;
|
||||
this.read = Optional.ofNullable(read);
|
||||
this.write = Optional.ofNullable(write);
|
||||
this(
|
||||
new TypesBuilderData(new ResourceLocation(name), new int[0]),
|
||||
read == null ? null : read::apply,
|
||||
write == null ? null : write::accept
|
||||
);
|
||||
}
|
||||
|
||||
public Optional<List<Object>> readProperties(PacketWrapper<?> packetWrapper) {
|
||||
return read.map(fn -> fn.apply(packetWrapper));
|
||||
private Parser(TypesBuilderData data, @Nullable Reader reader, Writer writer) {
|
||||
this.data = data;
|
||||
this.reader = reader;
|
||||
this.writer = writer;
|
||||
}
|
||||
|
||||
public void writeProperties(PacketWrapper<?> packetWrapper, List<Object> properties) {
|
||||
write.ifPresent(fn -> fn.accept(packetWrapper, properties));
|
||||
public Optional<List<Object>> readProperties(PacketWrapper<?> wrapper) {
|
||||
if (this.reader != null) {
|
||||
return Optional.of(this.reader.apply(wrapper));
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public void writeProperties(PacketWrapper<?> wrapper, List<Object> properties) {
|
||||
if (this.writer != null) {
|
||||
this.writer.accept(wrapper, properties);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getName() {
|
||||
return this.data.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId(ClientVersion version) {
|
||||
int index = TYPES_BUILDER.getDataIndex(version);
|
||||
return this.data.getData()[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof Parser) {
|
||||
return this.getName().equals(((Parser) obj).getName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -2,9 +2,9 @@ package com.github.retrooper.packetevents.protocol.chat;
|
||||
|
||||
public class SignedCommandArgument {
|
||||
private String argument;
|
||||
private byte[] signature;
|
||||
private MessageSignature signature;
|
||||
|
||||
public SignedCommandArgument(String argument, byte[] signature) {
|
||||
public SignedCommandArgument(String argument, MessageSignature signature) {
|
||||
this.argument = argument;
|
||||
this.signature = signature;
|
||||
}
|
||||
@@ -17,11 +17,11 @@ public class SignedCommandArgument {
|
||||
this.argument = argument;
|
||||
}
|
||||
|
||||
public byte[] getSignature() {
|
||||
public MessageSignature getSignature() {
|
||||
return signature;
|
||||
}
|
||||
|
||||
public void setSignature(byte[] signature) {
|
||||
public void setSignature(MessageSignature signature) {
|
||||
this.signature = signature;
|
||||
}
|
||||
}
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.chat;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.UnknownNullability;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class StaticChatType extends AbstractMappedEntity implements ChatType {
|
||||
|
||||
private final @UnknownNullability("only nullable for 1.19") ChatTypeDecoration chatDecoration;
|
||||
private final @Nullable ChatTypeDecoration overlayDecoration;
|
||||
private final @UnknownNullability("only nullable for 1.19") ChatTypeDecoration narrationDecoration;
|
||||
private final @Nullable NarrationPriority narrationPriority;
|
||||
|
||||
public StaticChatType(
|
||||
ChatTypeDecoration chatDecoration,
|
||||
ChatTypeDecoration narrationDecoration
|
||||
) {
|
||||
this(null, chatDecoration, null, narrationDecoration, null);
|
||||
}
|
||||
|
||||
public StaticChatType(
|
||||
@Nullable TypesBuilderData data,
|
||||
ChatTypeDecoration chatDecoration,
|
||||
ChatTypeDecoration narrationDecoration
|
||||
) {
|
||||
this(data, chatDecoration, null, narrationDecoration, null);
|
||||
}
|
||||
|
||||
public StaticChatType(
|
||||
@UnknownNullability("only nullable for 1.19") ChatTypeDecoration chatDecoration,
|
||||
@Nullable ChatTypeDecoration overlayDecoration,
|
||||
@UnknownNullability("only nullable for 1.19") ChatTypeDecoration narrationDecoration,
|
||||
@Nullable NarrationPriority narrationPriority
|
||||
) {
|
||||
this(null, chatDecoration, overlayDecoration, narrationDecoration, narrationPriority);
|
||||
}
|
||||
|
||||
public StaticChatType(
|
||||
@Nullable TypesBuilderData data,
|
||||
@UnknownNullability("only nullable for 1.19") ChatTypeDecoration chatDecoration,
|
||||
@Nullable ChatTypeDecoration overlayDecoration,
|
||||
@UnknownNullability("only nullable for 1.19") ChatTypeDecoration narrationDecoration,
|
||||
@Nullable NarrationPriority narrationPriority
|
||||
) {
|
||||
super(data);
|
||||
this.chatDecoration = chatDecoration;
|
||||
this.overlayDecoration = overlayDecoration;
|
||||
this.narrationDecoration = narrationDecoration;
|
||||
this.narrationPriority = narrationPriority;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatType copy(@Nullable TypesBuilderData newData) {
|
||||
return new StaticChatType(newData, this.chatDecoration,
|
||||
this.overlayDecoration, this.narrationDecoration, this.narrationPriority);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @UnknownNullability("only nullable for 1.19") ChatTypeDecoration getChatDecoration() {
|
||||
return this.chatDecoration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ChatTypeDecoration getOverlayDecoration() {
|
||||
return this.overlayDecoration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @UnknownNullability("only nullable for 1.19") ChatTypeDecoration getNarrationDecoration() {
|
||||
return this.narrationDecoration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable NarrationPriority getNarrationPriority() {
|
||||
return this.narrationPriority;
|
||||
}
|
||||
|
||||
public boolean deepEquals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof StaticChatType)) return false;
|
||||
if (!super.equals(obj)) return false;
|
||||
StaticChatType that = (StaticChatType) obj;
|
||||
if (!Objects.equals(this.chatDecoration, that.chatDecoration)) return false;
|
||||
if (!Objects.equals(this.overlayDecoration, that.overlayDecoration)) return false;
|
||||
if (!Objects.equals(this.narrationDecoration, that.narrationDecoration)) return false;
|
||||
return this.narrationPriority == that.narrationPriority;
|
||||
}
|
||||
|
||||
public int deepHashCode() {
|
||||
return Objects.hash(super.hashCode(), this.chatDecoration, this.overlayDecoration, this.narrationDecoration, this.narrationPriority);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "StaticChatType{chatDecoration=" + this.chatDecoration + ", overlayDecoration=" + this.overlayDecoration + ", narrationDecoration=" + this.narrationDecoration + ", narrationPriority=" + this.narrationPriority + '}';
|
||||
}
|
||||
}
|
||||
+32
-10
@@ -30,7 +30,7 @@ import java.util.UUID;
|
||||
public class ChatMessage_v1_19_1 extends ChatMessage_v1_16 {
|
||||
private String plainContent;
|
||||
private @Nullable Component unsignedChatContent;
|
||||
private ChatTypeBoundNetwork chatType;
|
||||
private ChatType.Bound chatFormatting;
|
||||
private byte @Nullable [] previousSignature;
|
||||
private byte[] signature;
|
||||
private Instant timestamp;
|
||||
@@ -40,15 +40,15 @@ public class ChatMessage_v1_19_1 extends ChatMessage_v1_16 {
|
||||
|
||||
public ChatMessage_v1_19_1(String plainContent, Component decoratedChatContent,
|
||||
@Nullable Component unsignedChatContent,
|
||||
UUID senderUUID, ChatTypeBoundNetwork chatType,
|
||||
UUID senderUUID, ChatType.Bound chatFormatting,
|
||||
byte @Nullable [] previousSignature, byte[] signature,
|
||||
Instant timestamp, long salt,
|
||||
LastSeenMessages lastSeenMessages,
|
||||
FilterMask filterMask) {
|
||||
super(decoratedChatContent, chatType.getType(), senderUUID);
|
||||
super(decoratedChatContent, chatFormatting.getType(), senderUUID);
|
||||
this.plainContent = plainContent;
|
||||
this.unsignedChatContent = unsignedChatContent;
|
||||
this.chatType = chatType;
|
||||
this.chatFormatting = chatFormatting;
|
||||
this.previousSignature = previousSignature;
|
||||
this.signature = signature;
|
||||
this.timestamp = timestamp;
|
||||
@@ -79,20 +79,38 @@ public class ChatMessage_v1_19_1 extends ChatMessage_v1_16 {
|
||||
|
||||
@Override
|
||||
public ChatType getType() {
|
||||
return chatType.getType();
|
||||
return chatFormatting.getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setType(ChatType type) {
|
||||
chatType.setType(type);
|
||||
chatFormatting.setType(type);
|
||||
}
|
||||
|
||||
public ChatTypeBoundNetwork getChatType() {
|
||||
return chatType;
|
||||
public ChatType.Bound getChatFormatting() {
|
||||
return chatFormatting;
|
||||
}
|
||||
|
||||
public void setChatType(ChatTypeBoundNetwork type) {
|
||||
this.chatType = type;
|
||||
public void setChatFormatting(ChatType.Bound chatFormatting) {
|
||||
this.chatFormatting = chatFormatting;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the chat formatting. Please refer to {@link ChatMessage_v1_19_1#getChatFormatting}
|
||||
* @return chat formatting which contains the actual chat type.
|
||||
*/
|
||||
@Deprecated
|
||||
public ChatType.Bound getChatType() {
|
||||
return chatFormatting;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the chat formatting. Please refer to {@link ChatMessage_v1_19_1#setChatFormatting}
|
||||
* @param chatFormatting formatting which contains the actual chat type.
|
||||
*/
|
||||
@Deprecated
|
||||
public void setChatType(ChatType.Bound chatFormatting) {
|
||||
this.chatFormatting = chatFormatting;
|
||||
}
|
||||
|
||||
public byte @Nullable [] getPreviousSignature() {
|
||||
@@ -143,6 +161,10 @@ public class ChatMessage_v1_19_1 extends ChatMessage_v1_16 {
|
||||
this.filterMask = filterMask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Please refer to {@link com.github.retrooper.packetevents.protocol.chat.ChatType.Bound}
|
||||
*/
|
||||
@Deprecated
|
||||
public static class ChatTypeBoundNetwork {
|
||||
private ChatType type;
|
||||
private Component name;
|
||||
|
||||
+28
-8
@@ -1,5 +1,6 @@
|
||||
package com.github.retrooper.packetevents.protocol.chat.message;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.chat.ChatType;
|
||||
import com.github.retrooper.packetevents.protocol.chat.LastSeenMessages;
|
||||
import com.github.retrooper.packetevents.protocol.chat.filter.FilterMask;
|
||||
import com.github.retrooper.packetevents.util.adventure.AdventureSerializer;
|
||||
@@ -19,10 +20,10 @@ public class ChatMessage_v1_19_3 extends ChatMessage_v1_16 {
|
||||
LastSeenMessages.Packed lastSeenMessagesPacked;
|
||||
@Nullable Component unsignedChatContent;
|
||||
FilterMask filterMask;
|
||||
ChatMessage_v1_19_1.ChatTypeBoundNetwork chatType;
|
||||
ChatType.Bound chatFormatting;
|
||||
|
||||
public ChatMessage_v1_19_3(UUID senderUUID, int index, byte[] signature, String plainContent, Instant timestamp, long salt, LastSeenMessages.Packed lastSeenMessagesPacked, @Nullable Component unsignedChatContent, FilterMask filterMask, ChatMessage_v1_19_1.ChatTypeBoundNetwork chatType) {
|
||||
super(Component.text(plainContent), chatType.getType(), senderUUID);
|
||||
public ChatMessage_v1_19_3(UUID senderUUID, int index, byte[] signature, String plainContent, Instant timestamp, long salt, LastSeenMessages.Packed lastSeenMessagesPacked, @Nullable Component unsignedChatContent, FilterMask filterMask, ChatType.Bound chatFormatting) {
|
||||
super(Component.text(plainContent), chatFormatting.getType(), senderUUID);
|
||||
this.index = index;
|
||||
this.signature = signature;
|
||||
this.plainContent = plainContent;
|
||||
@@ -31,7 +32,7 @@ public class ChatMessage_v1_19_3 extends ChatMessage_v1_16 {
|
||||
this.lastSeenMessagesPacked = lastSeenMessagesPacked;
|
||||
this.unsignedChatContent = unsignedChatContent;
|
||||
this.filterMask = filterMask;
|
||||
this.chatType = chatType;
|
||||
this.chatFormatting = chatFormatting;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
@@ -109,11 +110,30 @@ public class ChatMessage_v1_19_3 extends ChatMessage_v1_16 {
|
||||
this.filterMask = filterMask;
|
||||
}
|
||||
|
||||
public ChatMessage_v1_19_1.ChatTypeBoundNetwork getChatType() {
|
||||
return chatType;
|
||||
|
||||
public ChatType.Bound getChatFormatting() {
|
||||
return chatFormatting;
|
||||
}
|
||||
|
||||
public void setChatType(ChatMessage_v1_19_1.ChatTypeBoundNetwork chatType) {
|
||||
this.chatType = chatType;
|
||||
public void setChatFormatting(ChatType.Bound chatFormatting) {
|
||||
this.chatFormatting = chatFormatting;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the chat formatting. Please refer to {@link ChatMessage_v1_19_3#getChatFormatting}
|
||||
* @return chat formatting which contains the actual chat type.
|
||||
*/
|
||||
@Deprecated
|
||||
public ChatType.Bound getChatType() {
|
||||
return chatFormatting;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the chat formatting. Please refer to {@link ChatMessage_v1_19_3#setChatFormatting}
|
||||
* @param chatFormatting formatting which contains the actual chat type.
|
||||
*/
|
||||
@Deprecated
|
||||
public void setChatType(ChatType.Bound chatFormatting) {
|
||||
this.chatFormatting = chatFormatting;
|
||||
}
|
||||
}
|
||||
+2
-3
@@ -31,14 +31,13 @@ public class ChatMessageProcessorLegacy implements ChatMessageProcessor {
|
||||
@Override
|
||||
public ChatMessage readChatMessage(@NotNull PacketWrapper<?> wrapper) {
|
||||
Component chatContent = wrapper.readComponent();
|
||||
int id = wrapper.readByte();
|
||||
ChatType type = ChatTypes.getById(wrapper.getServerVersion().toClientVersion(), id);
|
||||
ChatType type = wrapper.readMappedEntity(ChatTypes.getRegistry());
|
||||
return new ChatMessageLegacy(chatContent, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeChatMessage(@NotNull PacketWrapper<?> wrapper, @NotNull ChatMessage data) {
|
||||
wrapper.writeComponent(data.getChatContent());
|
||||
wrapper.writeByte(data.getType().getId(wrapper.getServerVersion().toClientVersion()));
|
||||
wrapper.writeMappedEntity(data.getType());
|
||||
}
|
||||
}
|
||||
+2
-3
@@ -33,8 +33,7 @@ public class ChatMessageProcessor_v1_16 implements ChatMessageProcessor {
|
||||
@Override
|
||||
public ChatMessage readChatMessage(@NotNull PacketWrapper<?> wrapper) {
|
||||
Component chatContent = wrapper.readComponent();
|
||||
int id = wrapper.readByte();
|
||||
ChatType type = ChatTypes.getById(wrapper.getServerVersion().toClientVersion(), id);
|
||||
ChatType type = wrapper.readMappedEntity(ChatTypes.getRegistry());
|
||||
UUID senderUUID = wrapper.readUUID();
|
||||
return new ChatMessage_v1_16(chatContent, type, senderUUID);
|
||||
}
|
||||
@@ -42,7 +41,7 @@ public class ChatMessageProcessor_v1_16 implements ChatMessageProcessor {
|
||||
@Override
|
||||
public void writeChatMessage(@NotNull PacketWrapper<?> wrapper, @NotNull ChatMessage data) {
|
||||
wrapper.writeComponent(data.getChatContent());
|
||||
wrapper.writeByte(data.getType().getId(wrapper.getServerVersion().toClientVersion()));
|
||||
wrapper.writeMappedEntity(data.getType());
|
||||
wrapper.writeUUID(((ChatMessage_v1_16) data).getSenderUUID());
|
||||
}
|
||||
}
|
||||
+2
-3
@@ -36,8 +36,7 @@ public class ChatMessageProcessor_v1_19 implements ChatMessageProcessor {
|
||||
public ChatMessage readChatMessage(@NotNull PacketWrapper<?> wrapper) {
|
||||
Component chatContent = wrapper.readComponent();
|
||||
Component unsignedChatContent = wrapper.readOptional(PacketWrapper::readComponent);
|
||||
int id = wrapper.readVarInt();
|
||||
ChatType type = ChatTypes.getById(wrapper.getServerVersion().toClientVersion(), id);
|
||||
ChatType type = wrapper.readMappedEntity(ChatTypes.getRegistry());
|
||||
UUID senderUUID = wrapper.readUUID();
|
||||
Component senderDisplayName = wrapper.readComponent();
|
||||
@Nullable Component teamName = wrapper.readOptional(PacketWrapper::readComponent);
|
||||
@@ -53,7 +52,7 @@ public class ChatMessageProcessor_v1_19 implements ChatMessageProcessor {
|
||||
ChatMessage_v1_19 newData = (ChatMessage_v1_19) data;
|
||||
wrapper.writeComponent(newData.getChatContent());
|
||||
wrapper.writeOptional(newData.getUnsignedChatContent(), PacketWrapper::writeComponent);
|
||||
wrapper.writeVarInt(newData.getType().getId(wrapper.getServerVersion().toClientVersion()));
|
||||
wrapper.writeMappedEntity(newData.getType());
|
||||
wrapper.writeUUID(newData.getSenderUUID());
|
||||
wrapper.writeComponent(newData.getSenderDisplayName());
|
||||
wrapper.writeOptional(newData.getTeamName(), PacketWrapper::writeComponent);
|
||||
|
||||
+3
-3
@@ -50,8 +50,8 @@ public class ChatMessageProcessor_v1_19_1 implements ChatMessageProcessor {
|
||||
LastSeenMessages lastSeenMessages = wrapper.readLastSeenMessages();
|
||||
Component unsignedChatContent = wrapper.readOptional(PacketWrapper::readComponent);
|
||||
FilterMask filterMask = wrapper.readFilterMask();
|
||||
ChatMessage_v1_19_1.ChatTypeBoundNetwork chatType = wrapper.readChatTypeBoundNetwork();
|
||||
return new ChatMessage_v1_19_1(plainContent, chatContent, unsignedChatContent, senderUUID, chatType,
|
||||
ChatType.Bound chatFormatting = wrapper.readChatTypeBoundNetwork();
|
||||
return new ChatMessage_v1_19_1(plainContent, chatContent, unsignedChatContent, senderUUID, chatFormatting,
|
||||
previousSignature, signature, timestamp, salt, lastSeenMessages, filterMask);
|
||||
}
|
||||
|
||||
@@ -68,6 +68,6 @@ public class ChatMessageProcessor_v1_19_1 implements ChatMessageProcessor {
|
||||
wrapper.writeLastSeenMessages(newData.getLastSeenMessages());
|
||||
wrapper.writeOptional(newData.getUnsignedChatContent(), PacketWrapper::writeComponent);
|
||||
wrapper.writeFilterMask(newData.getFilterMask());
|
||||
wrapper.writeChatTypeBoundNetwork(newData.getChatType());
|
||||
wrapper.writeChatTypeBoundNetwork(newData.getChatFormatting());
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -1,5 +1,6 @@
|
||||
package com.github.retrooper.packetevents.protocol.chat.message.reader.impl;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.chat.ChatType;
|
||||
import com.github.retrooper.packetevents.protocol.chat.LastSeenMessages;
|
||||
import com.github.retrooper.packetevents.protocol.chat.filter.FilterMask;
|
||||
import com.github.retrooper.packetevents.protocol.chat.message.ChatMessage;
|
||||
@@ -25,7 +26,7 @@ public class ChatMessageProcessor_v1_19_3 implements ChatMessageProcessor {
|
||||
LastSeenMessages.Packed lastSeenMessagesPacked = wrapper.readLastSeenMessagesPacked();
|
||||
Component unsignedChatContent = wrapper.readOptional(PacketWrapper::readComponent);
|
||||
FilterMask filterMask = wrapper.readFilterMask();
|
||||
ChatMessage_v1_19_1.ChatTypeBoundNetwork chatType = wrapper.readChatTypeBoundNetwork();
|
||||
ChatType.Bound chatType = wrapper.readChatTypeBoundNetwork();
|
||||
|
||||
return new ChatMessage_v1_19_3(senderUUID, index, signature, plainContent, timestamp, salt, lastSeenMessagesPacked, unsignedChatContent, filterMask, chatType);
|
||||
}
|
||||
@@ -42,6 +43,6 @@ public class ChatMessageProcessor_v1_19_3 implements ChatMessageProcessor {
|
||||
wrapper.writeLastSeenMessagesPacked(newData.getLastSeenMessagesPacked());
|
||||
wrapper.writeOptional(newData.getUnsignedChatContent().orElse(null), PacketWrapper::writeComponent);
|
||||
wrapper.writeFilterMask(newData.getFilterMask());
|
||||
wrapper.writeChatTypeBoundNetwork(newData.getChatType());
|
||||
wrapper.writeChatTypeBoundNetwork(newData.getChatFormatting());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.color;
|
||||
|
||||
import net.kyori.adventure.util.RGBLike;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Range;
|
||||
|
||||
public final class Color implements RGBLike {
|
||||
|
||||
private static final int BIT_MASK = 0xFF;
|
||||
|
||||
private final int red, green, blue;
|
||||
|
||||
public Color(@Range(from = 0L, to = 255L) int red, @Range(from = 0L, to = 255L) int green, @Range(from = 0L, to = 255L) int blue) {
|
||||
this.red = red;
|
||||
this.green = green;
|
||||
this.blue = blue;
|
||||
}
|
||||
|
||||
public Color(int rgb) {
|
||||
this((rgb >> 16) & BIT_MASK, (rgb >> 8) & BIT_MASK, rgb & BIT_MASK);
|
||||
}
|
||||
|
||||
public @NotNull Color withRed(@Range(from = 0L, to = 255L) int red) {
|
||||
return new Color(red, green, blue);
|
||||
}
|
||||
|
||||
public @NotNull Color withGreen(@Range(from = 0L, to = 255L) int green) {
|
||||
return new Color(red, green, blue);
|
||||
}
|
||||
|
||||
public @NotNull Color withBlue(@Range(from = 0L, to = 255L) int blue) {
|
||||
return new Color(red, green, blue);
|
||||
}
|
||||
|
||||
public int asRGB() {
|
||||
int rgb = red;
|
||||
rgb = (rgb << 8) + green;
|
||||
return (rgb << 8) + blue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Range(from = 0L, to = 255L) int red() {
|
||||
return red;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Range(from = 0L, to = 255L) int green() {
|
||||
return green;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Range(from = 0L, to = 255L) int blue() {
|
||||
return blue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.color;
|
||||
|
||||
import net.kyori.adventure.util.RGBLike;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public enum DyeColor implements RGBLike {
|
||||
WHITE(new Color(0xf9fffe), new Color(0xffffff), new Color(0xf0f0f0), 8),
|
||||
|
||||
ORANGE(new Color(0xf9801d), new Color(0xff681f), new Color(0xeb8844), 15),
|
||||
|
||||
MAGENTA(new Color(0xc74ebd), new Color(0xff00ff), new Color(0xc354cd), 16),
|
||||
|
||||
LIGHT_BLUE(new Color(0x3ab3da), new Color(0x9ac0cd), new Color(0x6689d3), 17),
|
||||
|
||||
YELLOW(new Color(0xfed83d), new Color(0xffff00), new Color(0xdecf2a), 18),
|
||||
|
||||
LIME(new Color(0x80c71f), new Color(0xbfff00), new Color(0x41cd34), 19),
|
||||
|
||||
PINK(new Color(0xf38baa), new Color(0xff69b4), new Color(0xd88198), 20),
|
||||
|
||||
GRAY(new Color(0x474f52), new Color(0x808080), new Color(0x434343), 21),
|
||||
|
||||
LIGHT_GRAY(new Color(0x9d9d97), new Color(0xd3d3d3), new Color(0xababab), 22),
|
||||
|
||||
CYAN(new Color(0x169c9c), new Color(0xffff), new Color(0x287697), 23),
|
||||
|
||||
PURPLE(new Color(0x8932b8), new Color(0xa020f0), new Color(0x7b2fbe), 24),
|
||||
|
||||
BLUE(new Color(0x3c44aa), new Color(0xff), new Color(0x253192), 25),
|
||||
|
||||
BROWN(new Color(0x835432), new Color(0x8b4513), new Color(0x51301a), 26),
|
||||
|
||||
GREEN(new Color(0x5e7c16), new Color(0xff00), new Color(0x3b511a), 27),
|
||||
|
||||
RED(new Color(0xb02e26), new Color(0xff0000), new Color(0xb3312c), 28),
|
||||
|
||||
BLACK(new Color(0x1d1d21), new Color(0x0), new Color(0x1e1b1b), 29);
|
||||
|
||||
private final Color textureDiffuseColor;
|
||||
|
||||
private final Color textColor;
|
||||
|
||||
private final Color fireworkColor;
|
||||
|
||||
private final int mapColorId;
|
||||
|
||||
DyeColor(@NotNull Color textureDiffuseColor, @NotNull Color textColor,
|
||||
@NotNull Color fireworkColor, int mapColorId) {
|
||||
this.textureDiffuseColor = textureDiffuseColor;
|
||||
this.textColor = textColor;
|
||||
this.fireworkColor = fireworkColor;
|
||||
this.mapColorId = mapColorId;
|
||||
}
|
||||
|
||||
public @NotNull Color color() {
|
||||
return this.textureDiffuseColor;
|
||||
}
|
||||
|
||||
public @NotNull Color textColor() {
|
||||
return this.textColor;
|
||||
}
|
||||
|
||||
public @NotNull Color fireworkColor() {
|
||||
return this.fireworkColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int red() {
|
||||
return this.textureDiffuseColor.red();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int green() {
|
||||
return this.textureDiffuseColor.green();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int blue() {
|
||||
return this.textureDiffuseColor.blue();
|
||||
}
|
||||
|
||||
public int mapColorId() {
|
||||
return this.mapColorId;
|
||||
}
|
||||
}
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component;
|
||||
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class ComponentPredicate implements Predicate<IComponentMap> {
|
||||
|
||||
private List<ComponentValue<?>> requiredComponents;
|
||||
|
||||
public ComponentPredicate(List<ComponentValue<?>> requiredComponents) {
|
||||
this.requiredComponents = requiredComponents;
|
||||
}
|
||||
|
||||
public static ComponentPredicate read(PacketWrapper<?> wrapper) {
|
||||
List<ComponentValue<?>> components = wrapper.readList(ComponentValue::read);
|
||||
return new ComponentPredicate(components);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, ComponentPredicate predicate) {
|
||||
wrapper.writeList(predicate.requiredComponents, ComponentValue::write);
|
||||
}
|
||||
|
||||
public static ComponentPredicate emptyPredicate() {
|
||||
return new ComponentPredicate(new ArrayList<>());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static ComponentPredicate fromPatches(PatchableComponentMap components) {
|
||||
Map<ComponentType<?>, Optional<?>> patches = components.getPatches();
|
||||
List<ComponentValue<?>> values = new ArrayList<>(patches.size());
|
||||
for (Map.Entry<ComponentType<?>, Optional<?>> patch : patches.entrySet()) {
|
||||
if (patch.getValue().isPresent()) {
|
||||
values.add(new ComponentValue<>(
|
||||
(ComponentType<Object>) patch.getKey(),
|
||||
patch.getValue().get()
|
||||
));
|
||||
}
|
||||
}
|
||||
return new ComponentPredicate(values);
|
||||
}
|
||||
|
||||
public PatchableComponentMap asPatches(StaticComponentMap base) {
|
||||
PatchableComponentMap patched = new PatchableComponentMap(base);
|
||||
for (ComponentValue<?> component : this.requiredComponents) {
|
||||
patched.set(component);
|
||||
}
|
||||
return patched;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(IComponentMap components) {
|
||||
for (ComponentValue<?> component : this.requiredComponents) {
|
||||
Optional<?> value = components.getOptional(component.getType());
|
||||
if (!value.isPresent() || !component.getValue().equals(value.get())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public List<ComponentValue<?>> getRequiredComponents() {
|
||||
return this.requiredComponents;
|
||||
}
|
||||
|
||||
public void setRequiredComponents(List<ComponentValue<?>> requiredComponents) {
|
||||
this.requiredComponents = requiredComponents;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof ComponentPredicate)) return false;
|
||||
ComponentPredicate that = (ComponentPredicate) obj;
|
||||
return this.requiredComponents.equals(that.requiredComponents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(this.requiredComponents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ComponentPredicate{requiredComponents=" + this.requiredComponents + '}';
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBT;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
|
||||
public interface ComponentType<T> extends MappedEntity {
|
||||
|
||||
T read(PacketWrapper<?> wrapper);
|
||||
|
||||
void write(PacketWrapper<?> wrapper, T content);
|
||||
|
||||
T decode(NBT nbt, ClientVersion version);
|
||||
|
||||
NBT encode(T value, ClientVersion version);
|
||||
|
||||
interface Decoder<T> {
|
||||
|
||||
T decode(NBT nbt, ClientVersion version);
|
||||
}
|
||||
|
||||
interface Encoder<T> {
|
||||
|
||||
NBT encode(T value, ClientVersion version);
|
||||
}
|
||||
}
|
||||
+235
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.color.DyeColor;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.ArmorTrim;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.BannerLayers;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.BundleContents;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.ChargedProjectiles;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.CustomData;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.DebugStickState;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.FireworkExplosion;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.FoodProperties;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemAdventurePredicate;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemAttributeModifiers;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemBees;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemBlockStateProperties;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemContainerContents;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemContainerLoot;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemDyeColor;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemEnchantments;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemFireworks;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemJukeboxPlayable;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemLock;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemLore;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemMapDecorations;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemMapPostProcessingState;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemPotionContents;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemProfile;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemRarity;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemRecipes;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemTool;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.LodestoneTracker;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.PotDecorations;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.SuspiciousStewEffects;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.WritableBookContent;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.WrittenBookContent;
|
||||
import com.github.retrooper.packetevents.protocol.item.instrument.Instrument;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.Dummy;
|
||||
import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper.Reader;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper.Writer;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Contains all item data component types.
|
||||
*
|
||||
* @see EnchantEffectComponentTypes
|
||||
*/
|
||||
public final class ComponentTypes {
|
||||
|
||||
private static final VersionedRegistry<ComponentType<?>> REGISTRY = new VersionedRegistry<>(
|
||||
"data_component_type", "item/item_component_mappings");
|
||||
|
||||
private ComponentTypes() {
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static <T> ComponentType<T> define(String key) {
|
||||
return define(key, null, null);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static <T> ComponentType<T> define(String key, @Nullable Reader<T> reader, @Nullable Writer<T> writer) {
|
||||
return REGISTRY.define(key, data -> new StaticComponentType<>(data, reader, writer));
|
||||
}
|
||||
|
||||
public static VersionedRegistry<ComponentType<?>> getRegistry() {
|
||||
return REGISTRY;
|
||||
}
|
||||
|
||||
public static ComponentType<?> getByName(String name) {
|
||||
return REGISTRY.getByName(name);
|
||||
}
|
||||
|
||||
public static ComponentType<?> getById(ClientVersion version, int id) {
|
||||
return REGISTRY.getById(version, id);
|
||||
}
|
||||
|
||||
public static final ComponentType<NBTCompound> CUSTOM_DATA = define("custom_data",
|
||||
// mojang wraps their "persistent" codec as a stream codec just here,
|
||||
// so packetevents has to handle nbt strings
|
||||
CustomData::read, CustomData::write);
|
||||
public static final ComponentType<Integer> MAX_STACK_SIZE = define("max_stack_size",
|
||||
PacketWrapper::readVarInt, PacketWrapper::writeVarInt);
|
||||
public static final ComponentType<Integer> MAX_DAMAGE = define("max_damage",
|
||||
PacketWrapper::readVarInt, PacketWrapper::writeVarInt);
|
||||
public static final ComponentType<Integer> DAMAGE = define("damage",
|
||||
PacketWrapper::readVarInt, PacketWrapper::writeVarInt);
|
||||
public static final ComponentType<Boolean> UNBREAKABLE = define("unbreakable",
|
||||
PacketWrapper::readBoolean, PacketWrapper::writeBoolean);
|
||||
public static final ComponentType<Component> CUSTOM_NAME = define("custom_name",
|
||||
PacketWrapper::readComponent, PacketWrapper::writeComponent);
|
||||
public static final ComponentType<Component> ITEM_NAME = define("item_name",
|
||||
PacketWrapper::readComponent, PacketWrapper::writeComponent);
|
||||
public static final ComponentType<ItemLore> LORE = define("lore",
|
||||
ItemLore::read, ItemLore::write);
|
||||
public static final ComponentType<ItemRarity> RARITY = define("rarity",
|
||||
wrapper -> wrapper.readEnum(ItemRarity.values()), PacketWrapper::writeEnum);
|
||||
public static final ComponentType<ItemEnchantments> ENCHANTMENTS = define("enchantments",
|
||||
ItemEnchantments::read, ItemEnchantments::write);
|
||||
public static final ComponentType<ItemAdventurePredicate> CAN_PLACE_ON = define("can_place_on",
|
||||
ItemAdventurePredicate::read, ItemAdventurePredicate::write);
|
||||
public static final ComponentType<ItemAdventurePredicate> CAN_BREAK = define("can_break",
|
||||
ItemAdventurePredicate::read, ItemAdventurePredicate::write);
|
||||
public static final ComponentType<ItemAttributeModifiers> ATTRIBUTE_MODIFIERS = define("attribute_modifiers",
|
||||
ItemAttributeModifiers::read, ItemAttributeModifiers::write);
|
||||
public static final ComponentType<Integer> CUSTOM_MODEL_DATA = define("custom_model_data",
|
||||
PacketWrapper::readVarInt, PacketWrapper::writeVarInt);
|
||||
public static final ComponentType<Dummy> HIDE_ADDITIONAL_TOOLTIP = define("hide_additional_tooltip",
|
||||
Dummy::dummyRead, Dummy::dummyWrite);
|
||||
public static final ComponentType<Dummy> HIDE_TOOLTIP = define("hide_tooltip",
|
||||
Dummy::dummyRead, Dummy::dummyWrite);
|
||||
public static final ComponentType<Integer> REPAIR_COST = define("repair_cost",
|
||||
PacketWrapper::readVarInt, PacketWrapper::writeVarInt);
|
||||
public static final ComponentType<Dummy> CREATIVE_SLOT_LOCK = define("creative_slot_lock",
|
||||
Dummy::dummyRead, Dummy::dummyWrite);
|
||||
public static final ComponentType<Boolean> ENCHANTMENT_GLINT_OVERRIDE = define("enchantment_glint_override",
|
||||
PacketWrapper::readBoolean, PacketWrapper::writeBoolean);
|
||||
public static final ComponentType<Dummy> INTANGIBLE_PROJECTILE = define("intangible_projectile",
|
||||
Dummy::dummyReadNbt, Dummy::dummyWriteNbt);
|
||||
public static final ComponentType<FoodProperties> FOOD = define("food",
|
||||
FoodProperties::read, FoodProperties::write);
|
||||
public static final ComponentType<Dummy> FIRE_RESISTANT = define("fire_resistant",
|
||||
Dummy::dummyRead, Dummy::dummyWrite);
|
||||
public static final ComponentType<ItemTool> TOOL = define("tool",
|
||||
ItemTool::read, ItemTool::write);
|
||||
public static final ComponentType<ItemEnchantments> STORED_ENCHANTMENTS = define("stored_enchantments",
|
||||
ItemEnchantments::read, ItemEnchantments::write);
|
||||
public static final ComponentType<ItemDyeColor> DYED_COLOR = define("dyed_color",
|
||||
ItemDyeColor::read, ItemDyeColor::write);
|
||||
public static final ComponentType<Integer> MAP_COLOR = define("map_color",
|
||||
PacketWrapper::readInt, PacketWrapper::writeInt);
|
||||
public static final ComponentType<Integer> MAP_ID = define("map_id",
|
||||
PacketWrapper::readVarInt, PacketWrapper::writeVarInt);
|
||||
public static final ComponentType<ItemMapDecorations> MAP_DECORATIONS = define("map_decorations",
|
||||
ItemMapDecorations::read, ItemMapDecorations::write);
|
||||
public static final ComponentType<ItemMapPostProcessingState> MAP_POST_PROCESSING = define("map_post_processing",
|
||||
wrapper -> wrapper.readEnum(ItemMapPostProcessingState.values()), PacketWrapper::writeEnum);
|
||||
public static final ComponentType<ChargedProjectiles> CHARGED_PROJECTILES = define("charged_projectiles",
|
||||
ChargedProjectiles::read, ChargedProjectiles::write);
|
||||
public static final ComponentType<BundleContents> BUNDLE_CONTENTS = define("bundle_contents",
|
||||
BundleContents::read, BundleContents::write);
|
||||
public static final ComponentType<ItemPotionContents> POTION_CONTENTS = define("potion_contents",
|
||||
ItemPotionContents::read, ItemPotionContents::write);
|
||||
public static final ComponentType<SuspiciousStewEffects> SUSPICIOUS_STEW_EFFECTS = define("suspicious_stew_effects",
|
||||
SuspiciousStewEffects::read, SuspiciousStewEffects::write);
|
||||
public static final ComponentType<WritableBookContent> WRITABLE_BOOK_CONTENT = define("writable_book_content",
|
||||
WritableBookContent::read, WritableBookContent::write);
|
||||
public static final ComponentType<WrittenBookContent> WRITTEN_BOOK_CONTENT = define("written_book_content",
|
||||
WrittenBookContent::read, WrittenBookContent::write);
|
||||
public static final ComponentType<ArmorTrim> TRIM = define("trim",
|
||||
ArmorTrim::read, ArmorTrim::write);
|
||||
public static final ComponentType<DebugStickState> DEBUG_STICK_STATE = define("debug_stick_state",
|
||||
DebugStickState::read, DebugStickState::write);
|
||||
public static final ComponentType<NBTCompound> ENTITY_DATA = define("entity_data",
|
||||
PacketWrapper::readNBT, PacketWrapper::writeNBT);
|
||||
public static final ComponentType<NBTCompound> BUCKET_ENTITY_DATA = define("bucket_entity_data",
|
||||
PacketWrapper::readNBT, PacketWrapper::writeNBT);
|
||||
public static final ComponentType<NBTCompound> BLOCK_ENTITY_DATA = define("block_entity_data",
|
||||
PacketWrapper::readNBT, PacketWrapper::writeNBT);
|
||||
public static final ComponentType<Instrument> INSTRUMENT = define("instrument",
|
||||
Instrument::read, Instrument::write);
|
||||
public static final ComponentType<Integer> OMINOUS_BOTTLE_AMPLIFIER = define("ominous_bottle_amplifier",
|
||||
PacketWrapper::readVarInt, PacketWrapper::writeVarInt);
|
||||
public static final ComponentType<ItemRecipes> RECIPES = define("recipes",
|
||||
ItemRecipes::read, ItemRecipes::write);
|
||||
public static final ComponentType<LodestoneTracker> LODESTONE_TRACKER = define("lodestone_tracker",
|
||||
LodestoneTracker::read, LodestoneTracker::write);
|
||||
public static final ComponentType<FireworkExplosion> FIREWORK_EXPLOSION = define("firework_explosion",
|
||||
FireworkExplosion::read, FireworkExplosion::write);
|
||||
public static final ComponentType<ItemFireworks> FIREWORKS = define("fireworks",
|
||||
ItemFireworks::read, ItemFireworks::write);
|
||||
public static final ComponentType<ItemProfile> PROFILE = define("profile",
|
||||
ItemProfile::read, ItemProfile::write);
|
||||
public static final ComponentType<ResourceLocation> NOTE_BLOCK_SOUND = define("note_block_sound",
|
||||
PacketWrapper::readIdentifier, PacketWrapper::writeIdentifier);
|
||||
public static final ComponentType<BannerLayers> BANNER_PATTERNS = define("banner_patterns",
|
||||
BannerLayers::read, BannerLayers::write);
|
||||
public static final ComponentType<DyeColor> BASE_COLOR = define("base_color",
|
||||
wrapper -> wrapper.readEnum(DyeColor.values()), PacketWrapper::writeEnum);
|
||||
public static final ComponentType<PotDecorations> POT_DECORATIONS = define("pot_decorations",
|
||||
PotDecorations::read, PotDecorations::write);
|
||||
public static final ComponentType<ItemContainerContents> CONTAINER = define("container",
|
||||
ItemContainerContents::read, ItemContainerContents::write);
|
||||
public static final ComponentType<ItemBlockStateProperties> BLOCK_STATE = define("block_state",
|
||||
ItemBlockStateProperties::read, ItemBlockStateProperties::write);
|
||||
public static final ComponentType<ItemBees> BEES = define("bees",
|
||||
ItemBees::read, ItemBees::write);
|
||||
public static final ComponentType<ItemLock> LOCK = define("lock",
|
||||
ItemLock::read, ItemLock::write);
|
||||
public static final ComponentType<ItemContainerLoot> CONTAINER_LOOT = define("container_loot",
|
||||
ItemContainerLoot::read, ItemContainerLoot::write);
|
||||
|
||||
// added in 1.21
|
||||
public static final ComponentType<ItemJukeboxPlayable> JUKEBOX_PLAYABLE = define("jukebox_playable",
|
||||
ItemJukeboxPlayable::read, ItemJukeboxPlayable::write);
|
||||
|
||||
/**
|
||||
* Returns an immutable view of the component types.
|
||||
*
|
||||
* @return Component Types
|
||||
*/
|
||||
public static Collection<ComponentType<?>> values() {
|
||||
return REGISTRY.getEntries();
|
||||
}
|
||||
|
||||
static {
|
||||
REGISTRY.unloadMappings();
|
||||
}
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component;
|
||||
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public final class ComponentValue<T> {
|
||||
|
||||
private final ComponentType<T> type;
|
||||
private final T value;
|
||||
|
||||
public ComponentValue(ComponentType<T> type, T value) {
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static ComponentValue<?> read(PacketWrapper<?> wrapper) {
|
||||
ComponentType<?> type = wrapper.readMappedEntity(ComponentTypes::getById);
|
||||
return read0(wrapper, type);
|
||||
}
|
||||
|
||||
private static <T> ComponentValue<T> read0(PacketWrapper<?> wrapper, ComponentType<T> type) {
|
||||
// additional method required here for proper handling because of how generics work
|
||||
return new ComponentValue<>(type, type.read(wrapper));
|
||||
}
|
||||
|
||||
public static <T> void write(PacketWrapper<?> wrapper, ComponentValue<T> value) {
|
||||
wrapper.writeMappedEntity(value.type);
|
||||
value.type.write(wrapper, value.value);
|
||||
}
|
||||
|
||||
public ComponentType<T> getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public T getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof ComponentValue)) return false;
|
||||
ComponentValue<?> that = (ComponentValue<?>) obj;
|
||||
if (!this.type.equals(that.type)) return false;
|
||||
return this.value.equals(that.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.type, this.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ComponentValue{type=" + this.type + ", value=" + this.value + '}';
|
||||
}
|
||||
}
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.component.ComponentType.Decoder;
|
||||
import com.github.retrooper.packetevents.protocol.component.ComponentType.Encoder;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBT;
|
||||
import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Contains all enchantment effect component types.
|
||||
*
|
||||
* @see ComponentTypes
|
||||
*/
|
||||
public final class EnchantEffectComponentTypes {
|
||||
|
||||
private static final VersionedRegistry<ComponentType<?>> REGISTRY = new VersionedRegistry<>(
|
||||
"enchantment_effect_component_type", "enchantment/effect_component_type");
|
||||
|
||||
private EnchantEffectComponentTypes() {
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static <T> ComponentType<T> define(String key) {
|
||||
return define(key, null, null);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static <T> ComponentType<T> define(String key, @Nullable Decoder<T> reader, @Nullable Encoder<T> writer) {
|
||||
return REGISTRY.define(key, data -> new StaticComponentType<>(data, reader, writer));
|
||||
}
|
||||
|
||||
public static VersionedRegistry<ComponentType<?>> getRegistry() {
|
||||
return REGISTRY;
|
||||
}
|
||||
|
||||
// just pass everything through for now
|
||||
public static ComponentType<NBT> DAMAGE_PROTECTION = define("damage_protection",
|
||||
(nbt, version) -> nbt, (val, version) -> val);
|
||||
public static ComponentType<NBT> DAMAGE_IMMUNITY = define("damage_immunity",
|
||||
(nbt, version) -> nbt, (val, version) -> val);
|
||||
public static ComponentType<NBT> DAMAGE = define("damage",
|
||||
(nbt, version) -> nbt, (val, version) -> val);
|
||||
public static ComponentType<NBT> SMASH_DAMAGE_PER_FALLEN_BLOCK = define("smash_damage_per_fallen_block",
|
||||
(nbt, version) -> nbt, (val, version) -> val);
|
||||
public static ComponentType<NBT> KNOCKBACK = define("knockback",
|
||||
(nbt, version) -> nbt, (val, version) -> val);
|
||||
public static ComponentType<NBT> ARMOR_EFFECTIVENESS = define("armor_effectiveness",
|
||||
(nbt, version) -> nbt, (val, version) -> val);
|
||||
public static ComponentType<NBT> POST_ATTACK = define("post_attack",
|
||||
(nbt, version) -> nbt, (val, version) -> val);
|
||||
public static ComponentType<NBT> HIT_BLOCK = define("hit_block",
|
||||
(nbt, version) -> nbt, (val, version) -> val);
|
||||
public static ComponentType<NBT> ITEM_DAMAGE = define("item_damage",
|
||||
(nbt, version) -> nbt, (val, version) -> val);
|
||||
public static ComponentType<NBT> ATTRIBUTES = define("attributes",
|
||||
(nbt, version) -> nbt, (val, version) -> val);
|
||||
public static ComponentType<NBT> EQUIPMENT_DROPS = define("equipment_drops",
|
||||
(nbt, version) -> nbt, (val, version) -> val);
|
||||
public static ComponentType<NBT> LOCATION_CHANGED = define("location_changed",
|
||||
(nbt, version) -> nbt, (val, version) -> val);
|
||||
public static ComponentType<NBT> TICK = define("tick",
|
||||
(nbt, version) -> nbt, (val, version) -> val);
|
||||
public static ComponentType<NBT> AMMO_USE = define("ammo_use",
|
||||
(nbt, version) -> nbt, (val, version) -> val);
|
||||
public static ComponentType<NBT> PROJECTILE_PIERCING = define("projectile_piercing",
|
||||
(nbt, version) -> nbt, (val, version) -> val);
|
||||
public static ComponentType<NBT> PROJECTILE_SPAWNED = define("projectile_spawned",
|
||||
(nbt, version) -> nbt, (val, version) -> val);
|
||||
public static ComponentType<NBT> PROJECTILE_SPREAD = define("projectile_spread",
|
||||
(nbt, version) -> nbt, (val, version) -> val);
|
||||
public static ComponentType<NBT> PROJECTILE_COUNT = define("projectile_count",
|
||||
(nbt, version) -> nbt, (val, version) -> val);
|
||||
public static ComponentType<NBT> TRIDENT_RETURN_ACCELERATION = define("trident_return_acceleration",
|
||||
(nbt, version) -> nbt, (val, version) -> val);
|
||||
public static ComponentType<NBT> FISHING_TIME_REDUCTION = define("fishing_time_reduction",
|
||||
(nbt, version) -> nbt, (val, version) -> val);
|
||||
public static ComponentType<NBT> FISHING_LUCK_BONUS = define("fishing_luck_bonus",
|
||||
(nbt, version) -> nbt, (val, version) -> val);
|
||||
public static ComponentType<NBT> BLOCK_EXPERIENCE = define("block_experience",
|
||||
(nbt, version) -> nbt, (val, version) -> val);
|
||||
public static ComponentType<NBT> MOB_EXPERIENCE = define("mob_experience",
|
||||
(nbt, version) -> nbt, (val, version) -> val);
|
||||
public static ComponentType<NBT> REPAIR_WITH_XP = define("repair_with_xp",
|
||||
(nbt, version) -> nbt, (val, version) -> val);
|
||||
public static ComponentType<NBT> CROSSBOW_CHARGE_TIME = define("crossbow_charge_time",
|
||||
(nbt, version) -> nbt, (val, version) -> val);
|
||||
public static ComponentType<NBT> CROSSBOW_CHARGING_SOUNDS = define("crossbow_charging_sounds",
|
||||
(nbt, version) -> nbt, (val, version) -> val);
|
||||
public static ComponentType<NBT> TRIDENT_SOUND = define("trident_sound",
|
||||
(nbt, version) -> nbt, (val, version) -> val);
|
||||
public static ComponentType<NBT> PREVENT_EQUIPMENT_DROP = define("prevent_equipment_drop",
|
||||
(nbt, version) -> nbt, (val, version) -> val);
|
||||
public static ComponentType<NBT> PREVENT_ARMOR_CHANGE = define("prevent_armor_change",
|
||||
(nbt, version) -> nbt, (val, version) -> val);
|
||||
public static ComponentType<NBT> TRIDENT_SPIN_ATTACK_STRENGTH = define("trident_spin_attack_strength",
|
||||
(nbt, version) -> nbt, (val, version) -> val);
|
||||
|
||||
static {
|
||||
REGISTRY.unloadMappings();
|
||||
}
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBT;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.util.mappings.IRegistry;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface IComponentMap {
|
||||
|
||||
@SuppressWarnings("unchecked") // safe in this case
|
||||
static StaticComponentMap decode(NBT nbt, ClientVersion version, IRegistry<? extends ComponentType<?>> registry) {
|
||||
NBTCompound compound = (NBTCompound) nbt;
|
||||
StaticComponentMap.Builder components = StaticComponentMap.builder();
|
||||
for (Map.Entry<String, NBT> entry : compound.getTags().entrySet()) {
|
||||
ComponentType<?> type = registry.getByName(entry.getKey());
|
||||
if (type == null) {
|
||||
throw new IllegalStateException("Unknown component type named " + entry.getKey() + " encountered");
|
||||
}
|
||||
Object value = type.decode(entry.getValue(), version);
|
||||
components.set((ComponentType<? super Object>) type, value);
|
||||
}
|
||||
return components.build();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") // safe in this case
|
||||
static NBT encode(StaticComponentMap components, ClientVersion version) {
|
||||
NBTCompound compound = new NBTCompound();
|
||||
for (Map.Entry<ComponentType<?>, ?> entry : components.getDelegate().entrySet()) {
|
||||
String key = entry.getKey().getName().toString();
|
||||
NBT value = ((ComponentType<? super Object>) entry.getKey()).encode(entry.getValue(), version);
|
||||
compound.setTag(key, value);
|
||||
}
|
||||
return compound;
|
||||
}
|
||||
|
||||
default <T> Optional<T> getOptional(ComponentType<T> type) {
|
||||
return Optional.ofNullable(this.get(type));
|
||||
}
|
||||
|
||||
boolean has(ComponentType<?> type);
|
||||
|
||||
@Contract("_, !null -> !null")
|
||||
default <T> @Nullable T getOr(ComponentType<T> type, @Nullable T otherValue) {
|
||||
T value = this.get(type);
|
||||
if (value != null) {
|
||||
return value;
|
||||
}
|
||||
return otherValue;
|
||||
}
|
||||
|
||||
<T> @Nullable T get(ComponentType<T> type);
|
||||
|
||||
default <T> void set(ComponentValue<T> component) {
|
||||
this.set(component.getType(), component.getValue());
|
||||
}
|
||||
|
||||
default <T> void set(ComponentType<T> type, @Nullable T value) {
|
||||
this.set(type, Optional.ofNullable(value));
|
||||
}
|
||||
|
||||
default <T> void unset(ComponentType<T> type) {
|
||||
this.set(type, Optional.empty());
|
||||
}
|
||||
|
||||
<T> void set(ComponentType<T> type, Optional<T> value);
|
||||
}
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
public class PatchableComponentMap implements IComponentMap {
|
||||
|
||||
public static final PatchableComponentMap EMPTY = new PatchableComponentMap(
|
||||
Collections.emptyMap(), Collections.emptyMap());
|
||||
|
||||
private final Map<ComponentType<?>, ?> base;
|
||||
private final Map<ComponentType<?>, Optional<?>> patches;
|
||||
|
||||
public PatchableComponentMap(StaticComponentMap base) {
|
||||
this(base.getDelegate(), new HashMap<>());
|
||||
}
|
||||
|
||||
public PatchableComponentMap(Map<ComponentType<?>, ?> base) {
|
||||
this(base, new HashMap<>());
|
||||
}
|
||||
|
||||
public PatchableComponentMap(
|
||||
StaticComponentMap base,
|
||||
Map<ComponentType<?>, Optional<?>> patches
|
||||
) {
|
||||
this(base.getDelegate(), patches);
|
||||
}
|
||||
|
||||
public PatchableComponentMap(
|
||||
Map<ComponentType<?>, ?> base,
|
||||
Map<ComponentType<?>, Optional<?>> patches
|
||||
) {
|
||||
this.base = Collections.unmodifiableMap(new HashMap<>(base));
|
||||
this.patches = patches;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") // no
|
||||
@Override
|
||||
public <T> @Nullable T get(ComponentType<T> type) {
|
||||
Optional<?> patched = this.patches.get(type);
|
||||
if (patched != null) {
|
||||
return (T) patched.orElse(null);
|
||||
}
|
||||
return (T) this.base.get(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void set(ComponentType<T> type, Optional<T> value) {
|
||||
Object baseVal = this.base.get(type);
|
||||
T newVal = value.orElse(null);
|
||||
if (Objects.equals(baseVal, newVal)) {
|
||||
this.patches.remove(type); // fallback to base
|
||||
} else {
|
||||
this.patches.put(type, value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean has(ComponentType<?> type) {
|
||||
Optional<?> patched = this.patches.get(type);
|
||||
return patched != null ? patched.isPresent() : this.base.containsKey(type);
|
||||
}
|
||||
|
||||
public PatchableComponentMap copy() {
|
||||
return new PatchableComponentMap(this.base, new HashMap<>(this.patches));
|
||||
}
|
||||
|
||||
public Map<ComponentType<?>, ?> getBase() {
|
||||
return this.base;
|
||||
}
|
||||
|
||||
public Map<ComponentType<?>, Optional<?>> getPatches() {
|
||||
return this.patches;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof PatchableComponentMap)) return false;
|
||||
PatchableComponentMap that = (PatchableComponentMap) obj;
|
||||
if (!this.base.equals(that.base)) return false;
|
||||
return this.patches.equals(that.patches);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.base, this.patches);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PatchableComponentMap{base=" + this.base + ", patches=" + this.patches + '}';
|
||||
}
|
||||
}
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemAttributeModifiers;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemEnchantments;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemLore;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemRarity;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
public class StaticComponentMap implements IComponentMap {
|
||||
|
||||
public static final StaticComponentMap EMPTY = new StaticComponentMap(Collections.emptyMap());
|
||||
public static final StaticComponentMap SHARED_ITEM_COMPONENTS = builder()
|
||||
.set(ComponentTypes.MAX_STACK_SIZE, 64)
|
||||
.set(ComponentTypes.LORE, ItemLore.EMPTY)
|
||||
.set(ComponentTypes.ENCHANTMENTS, ItemEnchantments.EMPTY)
|
||||
.set(ComponentTypes.REPAIR_COST, 0)
|
||||
.set(ComponentTypes.ATTRIBUTE_MODIFIERS, ItemAttributeModifiers.EMPTY)
|
||||
.set(ComponentTypes.RARITY, ItemRarity.COMMON)
|
||||
.build();
|
||||
|
||||
private final boolean empty;
|
||||
private final Map<ComponentType<?>, ?> delegate;
|
||||
|
||||
public StaticComponentMap(Map<ComponentType<?>, ?> delegate) {
|
||||
this.empty = delegate.isEmpty();
|
||||
this.delegate = this.empty ? Collections.emptyMap()
|
||||
: Collections.unmodifiableMap(new HashMap<>(delegate));
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean has(ComponentType<?> type) {
|
||||
return !this.empty && this.delegate.containsKey(type);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked") // no
|
||||
@Override
|
||||
public <T> @Nullable T get(ComponentType<T> type) {
|
||||
return this.empty ? null : (T) this.delegate.get(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void set(ComponentType<T> type, Optional<T> value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public StaticComponentMap merge(StaticComponentMap prioritizedMap) {
|
||||
return builder().setAll(this).setAll(prioritizedMap).build();
|
||||
}
|
||||
|
||||
public Map<ComponentType<?>, ?> getDelegate() {
|
||||
return this.delegate;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this.empty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof StaticComponentMap)) return false;
|
||||
StaticComponentMap that = (StaticComponentMap) obj;
|
||||
return this.delegate.equals(that.delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(this.delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "StaticComponentMap{empty=" + this.empty + ", delegate=" + this.delegate + '}';
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private final Map<ComponentType<?>, Object> map = new HashMap<>();
|
||||
|
||||
public Builder() {
|
||||
}
|
||||
|
||||
public StaticComponentMap build() {
|
||||
return new StaticComponentMap(this.map);
|
||||
}
|
||||
|
||||
public Builder setAll(StaticComponentMap map) {
|
||||
return this.setAll(map.getDelegate());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Builder setAll(Map<ComponentType<?>, ?> map) {
|
||||
for (Map.Entry<ComponentType<?>, ?> entry : map.entrySet()) {
|
||||
this.set((ComponentType<Object>) entry.getKey(), entry.getValue());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public <T> Builder set(ComponentType<T> type, Optional<T> value) {
|
||||
return this.set(type, value.orElse(null));
|
||||
}
|
||||
|
||||
public <T> Builder set(ComponentType<T> type, @Nullable T value) {
|
||||
if (value == null) {
|
||||
this.map.remove(type);
|
||||
} else {
|
||||
this.map.put(type, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBT;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper.Reader;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper.Writer;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class StaticComponentType<T> extends AbstractMappedEntity implements ComponentType<T> {
|
||||
|
||||
private final @Nullable Reader<T> reader;
|
||||
private final @Nullable Writer<T> writer;
|
||||
private final @Nullable Decoder<T> decoder;
|
||||
private final @Nullable Encoder<T> encoder;
|
||||
|
||||
public StaticComponentType(
|
||||
@Nullable TypesBuilderData data,
|
||||
@Nullable Reader<T> reader,
|
||||
@Nullable Writer<T> writer
|
||||
) {
|
||||
this(data, reader, writer, null, null);
|
||||
}
|
||||
|
||||
public StaticComponentType(
|
||||
@Nullable TypesBuilderData data,
|
||||
@Nullable Decoder<T> decoder,
|
||||
@Nullable Encoder<T> encoder
|
||||
) {
|
||||
this(data, null, null, decoder, encoder);
|
||||
}
|
||||
|
||||
public StaticComponentType(
|
||||
@Nullable TypesBuilderData data,
|
||||
@Nullable Reader<T> reader,
|
||||
@Nullable Writer<T> writer,
|
||||
@Nullable Decoder<T> decoder,
|
||||
@Nullable Encoder<T> encoder
|
||||
) {
|
||||
super(data);
|
||||
this.reader = reader;
|
||||
this.writer = writer;
|
||||
this.decoder = decoder;
|
||||
this.encoder = encoder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T read(PacketWrapper<?> wrapper) {
|
||||
return this.reader != null ? this.reader.apply(wrapper) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketWrapper<?> wrapper, T content) {
|
||||
if (this.writer != null) {
|
||||
this.writer.accept(wrapper, content);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public T decode(NBT nbt, ClientVersion version) {
|
||||
if (this.decoder != null) {
|
||||
return this.decoder.decode(nbt, version);
|
||||
}
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBT encode(T value, ClientVersion version) {
|
||||
if (this.encoder != null) {
|
||||
return this.encoder.encode(value, version);
|
||||
}
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.item.trimmaterial.TrimMaterial;
|
||||
import com.github.retrooper.packetevents.protocol.item.trimpattern.TrimPattern;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class ArmorTrim {
|
||||
|
||||
private TrimMaterial material;
|
||||
private TrimPattern pattern;
|
||||
private boolean showInTooltip;
|
||||
|
||||
public ArmorTrim(TrimMaterial material, TrimPattern pattern, boolean showInTooltip) {
|
||||
this.material = material;
|
||||
this.pattern = pattern;
|
||||
this.showInTooltip = showInTooltip;
|
||||
}
|
||||
|
||||
public static ArmorTrim read(PacketWrapper<?> wrapper) {
|
||||
TrimMaterial material = TrimMaterial.read(wrapper);
|
||||
TrimPattern pattern = TrimPattern.read(wrapper);
|
||||
boolean showInTooltip = wrapper.readBoolean();
|
||||
return new ArmorTrim(material, pattern, showInTooltip);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, ArmorTrim trim) {
|
||||
TrimMaterial.write(wrapper, trim.material);
|
||||
TrimPattern.write(wrapper, trim.pattern);
|
||||
wrapper.writeBoolean(trim.showInTooltip);
|
||||
}
|
||||
|
||||
public TrimMaterial getMaterial() {
|
||||
return this.material;
|
||||
}
|
||||
|
||||
public void setMaterial(TrimMaterial material) {
|
||||
this.material = material;
|
||||
}
|
||||
|
||||
public TrimPattern getPattern() {
|
||||
return this.pattern;
|
||||
}
|
||||
|
||||
public void setPattern(TrimPattern pattern) {
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
public boolean isShowInTooltip() {
|
||||
return this.showInTooltip;
|
||||
}
|
||||
|
||||
public void setShowInTooltip(boolean showInTooltip) {
|
||||
this.showInTooltip = showInTooltip;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof ArmorTrim)) return false;
|
||||
ArmorTrim armorTrim = (ArmorTrim) obj;
|
||||
if (this.showInTooltip != armorTrim.showInTooltip) return false;
|
||||
if (!this.material.equals(armorTrim.material)) return false;
|
||||
return this.pattern.equals(armorTrim.pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.material, this.pattern, this.showInTooltip);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ArmorTrim{material=" + this.material + ", pattern=" + this.pattern + ", showInTooltip=" + this.showInTooltip + '}';
|
||||
}
|
||||
}
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.color.DyeColor;
|
||||
import com.github.retrooper.packetevents.protocol.item.banner.BannerPattern;
|
||||
import com.github.retrooper.packetevents.protocol.item.banner.BannerPatterns;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class BannerLayers {
|
||||
|
||||
private List<Layer> layers;
|
||||
|
||||
public BannerLayers(List<Layer> layers) {
|
||||
this.layers = layers;
|
||||
}
|
||||
|
||||
public static BannerLayers read(PacketWrapper<?> wrapper) {
|
||||
List<Layer> layers = wrapper.readList(Layer::read);
|
||||
return new BannerLayers(layers);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, BannerLayers patterns) {
|
||||
wrapper.writeList(patterns.layers, Layer::write);
|
||||
}
|
||||
|
||||
public void addLayer(Layer layer) {
|
||||
this.layers.add(layer);
|
||||
}
|
||||
|
||||
public List<Layer> getLayers() {
|
||||
return this.layers;
|
||||
}
|
||||
|
||||
public void setLayers(List<Layer> layers) {
|
||||
this.layers = layers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof BannerLayers)) return false;
|
||||
BannerLayers that = (BannerLayers) obj;
|
||||
return this.layers.equals(that.layers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(this.layers);
|
||||
}
|
||||
|
||||
public static class Layer {
|
||||
|
||||
private BannerPattern pattern;
|
||||
private DyeColor color;
|
||||
|
||||
public Layer(BannerPattern pattern, DyeColor color) {
|
||||
this.pattern = pattern;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public static Layer read(PacketWrapper<?> wrapper) {
|
||||
BannerPattern pattern = wrapper.readMappedEntityOrDirect(
|
||||
BannerPatterns.getRegistry(), BannerPattern::readDirect);
|
||||
DyeColor color = wrapper.readEnum(DyeColor.values());
|
||||
return new Layer(pattern, color);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, Layer layer) {
|
||||
wrapper.writeMappedEntityOrDirect(layer.pattern, BannerPattern::writeDirect);
|
||||
wrapper.writeEnum(layer.color);
|
||||
}
|
||||
|
||||
public BannerPattern getPattern() {
|
||||
return this.pattern;
|
||||
}
|
||||
|
||||
public void setPattern(BannerPattern pattern) {
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
public DyeColor getColor() {
|
||||
return this.color;
|
||||
}
|
||||
|
||||
public void setColor(DyeColor color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof Layer)) return false;
|
||||
Layer layer = (Layer) obj;
|
||||
if (!this.pattern.equals(layer.pattern)) return false;
|
||||
return this.color == layer.color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.pattern, this.color);
|
||||
}
|
||||
}
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.item.ItemStack;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class BundleContents {
|
||||
|
||||
private List<ItemStack> items;
|
||||
|
||||
public BundleContents(List<ItemStack> items) {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
public static BundleContents read(PacketWrapper<?> wrapper) {
|
||||
List<ItemStack> items = wrapper.readList(PacketWrapper::readPresentItemStack);
|
||||
return new BundleContents(items);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, BundleContents projectiles) {
|
||||
wrapper.writeList(projectiles.items, PacketWrapper::writePresentItemStack);
|
||||
}
|
||||
|
||||
public void addItem(ItemStack itemStack) {
|
||||
this.items.add(itemStack);
|
||||
}
|
||||
|
||||
public List<ItemStack> getItems() {
|
||||
return this.items;
|
||||
}
|
||||
|
||||
public void setItems(List<ItemStack> items) {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof BundleContents)) return false;
|
||||
BundleContents that = (BundleContents) obj;
|
||||
return this.items.equals(that.items);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(this.items);
|
||||
}
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.item.ItemStack;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class ChargedProjectiles {
|
||||
|
||||
private List<ItemStack> items;
|
||||
|
||||
public ChargedProjectiles(List<ItemStack> items) {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
public static ChargedProjectiles read(PacketWrapper<?> wrapper) {
|
||||
List<ItemStack> items = wrapper.readList(PacketWrapper::readPresentItemStack);
|
||||
return new ChargedProjectiles(items);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, ChargedProjectiles projectiles) {
|
||||
wrapper.writeList(projectiles.items, PacketWrapper::writePresentItemStack);
|
||||
}
|
||||
|
||||
public void addItem(ItemStack itemStack) {
|
||||
this.items.add(itemStack);
|
||||
}
|
||||
|
||||
public List<ItemStack> getItems() {
|
||||
return this.items;
|
||||
}
|
||||
|
||||
public void setItems(List<ItemStack> items) {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof ChargedProjectiles)) return false;
|
||||
ChargedProjectiles that = (ChargedProjectiles) obj;
|
||||
return this.items.equals(that.items);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(this.items);
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBT;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
|
||||
public class CustomData {
|
||||
|
||||
private CustomData() {
|
||||
}
|
||||
|
||||
public static NBTCompound read(PacketWrapper<?> wrapper) {
|
||||
NBT nbt = wrapper.readNBTRaw();
|
||||
if (nbt instanceof NBTCompound) {
|
||||
return (NBTCompound) nbt;
|
||||
}
|
||||
if (nbt instanceof NBTString) {
|
||||
// TODO: parse nbt string
|
||||
}
|
||||
throw new UnsupportedOperationException("Unsupported custom data nbt type: " + nbt.getType());
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, NBTCompound compound) {
|
||||
wrapper.writeNBT(compound);
|
||||
}
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBT;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class DebugStickState {
|
||||
|
||||
private Map<StateType, String> properties;
|
||||
|
||||
public DebugStickState(Map<StateType, String> properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public static DebugStickState read(PacketWrapper<?> wrapper) {
|
||||
NBTCompound compound = wrapper.readNBT();
|
||||
Map<StateType, String> properties = new HashMap<>(compound.size());
|
||||
for (Map.Entry<String, NBT> tag : compound.getTags().entrySet()) {
|
||||
StateType stateType = StateTypes.getByName(tag.getKey());
|
||||
String property = ((NBTString) tag.getValue()).getValue();
|
||||
properties.put(stateType, property);
|
||||
}
|
||||
return new DebugStickState(properties);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, DebugStickState state) {
|
||||
NBTCompound compound = new NBTCompound();
|
||||
for (Map.Entry<StateType, String> property : state.properties.entrySet()) {
|
||||
compound.setTag(property.getKey().getName(),
|
||||
new NBTString(property.getValue()));
|
||||
}
|
||||
wrapper.writeNBT(compound);
|
||||
}
|
||||
|
||||
public @Nullable String getProperty(StateType stateType) {
|
||||
return this.properties.get(stateType);
|
||||
}
|
||||
|
||||
public void setProperty(StateType stateType, @Nullable String property) {
|
||||
if (property != null) {
|
||||
this.properties.put(stateType, property);
|
||||
} else {
|
||||
this.properties.remove(stateType);
|
||||
}
|
||||
}
|
||||
|
||||
public Map<StateType, String> getProperties() {
|
||||
return this.properties;
|
||||
}
|
||||
|
||||
public void setProperties(Map<StateType, String> properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof DebugStickState)) return false;
|
||||
DebugStickState that = (DebugStickState) o;
|
||||
return this.properties.equals(that.properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(this.properties);
|
||||
}
|
||||
}
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class FireworkExplosion {
|
||||
|
||||
private Shape shape;
|
||||
private List<Integer> colors;
|
||||
private List<Integer> fadeColors;
|
||||
private boolean hasTrail;
|
||||
private boolean hasTwinkle;
|
||||
|
||||
public FireworkExplosion(
|
||||
Shape shape, List<Integer> colors, List<Integer> fadeColors,
|
||||
boolean hasTrail, boolean hasTwinkle
|
||||
) {
|
||||
this.shape = shape;
|
||||
this.colors = colors;
|
||||
this.fadeColors = fadeColors;
|
||||
this.hasTrail = hasTrail;
|
||||
this.hasTwinkle = hasTwinkle;
|
||||
}
|
||||
|
||||
public static FireworkExplosion read(PacketWrapper<?> wrapper) {
|
||||
Shape shape = wrapper.readEnum(Shape.values());
|
||||
List<Integer> colors = wrapper.readList(PacketWrapper::readInt);
|
||||
List<Integer> fadeColors = wrapper.readList(PacketWrapper::readInt);
|
||||
boolean hasTrail = wrapper.readBoolean();
|
||||
boolean hasTwinkle = wrapper.readBoolean();
|
||||
return new FireworkExplosion(shape, colors, fadeColors, hasTrail, hasTwinkle);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, FireworkExplosion explosion) {
|
||||
wrapper.writeEnum(explosion.shape);
|
||||
wrapper.writeList(explosion.colors, PacketWrapper::writeInt);
|
||||
wrapper.writeList(explosion.fadeColors, PacketWrapper::writeInt);
|
||||
wrapper.writeBoolean(explosion.hasTrail);
|
||||
wrapper.writeBoolean(explosion.hasTwinkle);
|
||||
}
|
||||
|
||||
public Shape getShape() {
|
||||
return this.shape;
|
||||
}
|
||||
|
||||
public void setShape(Shape shape) {
|
||||
this.shape = shape;
|
||||
}
|
||||
|
||||
public void addColor(int color) {
|
||||
this.colors.add(color);
|
||||
}
|
||||
|
||||
public List<Integer> getColors() {
|
||||
return this.colors;
|
||||
}
|
||||
|
||||
public void setColors(List<Integer> colors) {
|
||||
this.colors = colors;
|
||||
}
|
||||
|
||||
public void addFadeColor(int color) {
|
||||
this.fadeColors.add(color);
|
||||
}
|
||||
|
||||
public List<Integer> getFadeColors() {
|
||||
return this.fadeColors;
|
||||
}
|
||||
|
||||
public void setFadeColors(List<Integer> fadeColors) {
|
||||
this.fadeColors = fadeColors;
|
||||
}
|
||||
|
||||
public boolean isHasTrail() {
|
||||
return this.hasTrail;
|
||||
}
|
||||
|
||||
public void setHasTrail(boolean hasTrail) {
|
||||
this.hasTrail = hasTrail;
|
||||
}
|
||||
|
||||
public boolean isHasTwinkle() {
|
||||
return this.hasTwinkle;
|
||||
}
|
||||
|
||||
public void setHasTwinkle(boolean hasTwinkle) {
|
||||
this.hasTwinkle = hasTwinkle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof FireworkExplosion)) return false;
|
||||
FireworkExplosion that = (FireworkExplosion) obj;
|
||||
if (this.hasTrail != that.hasTrail) return false;
|
||||
if (this.hasTwinkle != that.hasTwinkle) return false;
|
||||
if (this.shape != that.shape) return false;
|
||||
if (!this.colors.equals(that.colors)) return false;
|
||||
return this.fadeColors.equals(that.fadeColors);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.shape, this.colors, this.fadeColors, this.hasTrail, this.hasTwinkle);
|
||||
}
|
||||
|
||||
public enum Shape {
|
||||
SMALL_BALL,
|
||||
LARGE_BALL,
|
||||
STAR,
|
||||
CREEPER,
|
||||
BURST,
|
||||
}
|
||||
}
|
||||
+203
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.item.ItemStack;
|
||||
import com.github.retrooper.packetevents.protocol.potion.PotionEffect;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class FoodProperties {
|
||||
|
||||
private int nutrition;
|
||||
private float saturation;
|
||||
private boolean canAlwaysEat;
|
||||
private float eatSeconds;
|
||||
private List<PossibleEffect> effects;
|
||||
private @Nullable ItemStack usingConvertsTo;
|
||||
|
||||
public FoodProperties(
|
||||
int nutrition, float saturation, boolean canAlwaysEat,
|
||||
float eatSeconds, List<PossibleEffect> effects
|
||||
) {
|
||||
this(nutrition, saturation, canAlwaysEat, eatSeconds, effects, null);
|
||||
}
|
||||
|
||||
public FoodProperties(
|
||||
int nutrition, float saturation, boolean canAlwaysEat, float eatSeconds,
|
||||
List<PossibleEffect> effects, @Nullable ItemStack usingConvertsTo
|
||||
) {
|
||||
this.nutrition = nutrition;
|
||||
this.saturation = saturation;
|
||||
this.canAlwaysEat = canAlwaysEat;
|
||||
this.eatSeconds = eatSeconds;
|
||||
this.effects = effects;
|
||||
this.usingConvertsTo = usingConvertsTo;
|
||||
}
|
||||
|
||||
public static FoodProperties read(PacketWrapper<?> wrapper) {
|
||||
int nutrition = wrapper.readVarInt();
|
||||
float saturation = wrapper.readFloat();
|
||||
boolean canAlwaysEat = wrapper.readBoolean();
|
||||
float eatSeconds = wrapper.readFloat();
|
||||
List<PossibleEffect> effects = wrapper.readList(PossibleEffect::read);
|
||||
ItemStack usingConvertsTo = wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21)
|
||||
? wrapper.readOptional(PacketWrapper::readItemStack) : null;
|
||||
return new FoodProperties(nutrition, saturation, canAlwaysEat, eatSeconds, effects, usingConvertsTo);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, FoodProperties props) {
|
||||
wrapper.writeVarInt(props.nutrition);
|
||||
wrapper.writeFloat(props.saturation);
|
||||
wrapper.writeBoolean(props.canAlwaysEat);
|
||||
wrapper.writeFloat(props.eatSeconds);
|
||||
wrapper.writeList(props.effects, PossibleEffect::write);
|
||||
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21)) {
|
||||
wrapper.writeOptional(props.usingConvertsTo, PacketWrapper::writeItemStack);
|
||||
}
|
||||
}
|
||||
|
||||
public int getNutrition() {
|
||||
return this.nutrition;
|
||||
}
|
||||
|
||||
public void setNutrition(int nutrition) {
|
||||
this.nutrition = nutrition;
|
||||
}
|
||||
|
||||
public float getSaturation() {
|
||||
return this.saturation;
|
||||
}
|
||||
|
||||
public void setSaturation(float saturation) {
|
||||
this.saturation = saturation;
|
||||
}
|
||||
|
||||
public boolean isCanAlwaysEat() {
|
||||
return this.canAlwaysEat;
|
||||
}
|
||||
|
||||
public void setCanAlwaysEat(boolean canAlwaysEat) {
|
||||
this.canAlwaysEat = canAlwaysEat;
|
||||
}
|
||||
|
||||
public float getEatSeconds() {
|
||||
return this.eatSeconds;
|
||||
}
|
||||
|
||||
public void setEatSeconds(float eatSeconds) {
|
||||
this.eatSeconds = eatSeconds;
|
||||
}
|
||||
|
||||
public void addEffect(PossibleEffect effect) {
|
||||
this.effects.add(effect);
|
||||
}
|
||||
|
||||
public List<PossibleEffect> getEffects() {
|
||||
return this.effects;
|
||||
}
|
||||
|
||||
public void setEffects(List<PossibleEffect> effects) {
|
||||
this.effects = effects;
|
||||
}
|
||||
|
||||
public @Nullable ItemStack getUsingConvertsTo() {
|
||||
return this.usingConvertsTo;
|
||||
}
|
||||
|
||||
public void setUsingConvertsTo(@Nullable ItemStack usingConvertsTo) {
|
||||
this.usingConvertsTo = usingConvertsTo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof FoodProperties)) return false;
|
||||
FoodProperties that = (FoodProperties) obj;
|
||||
if (this.nutrition != that.nutrition) return false;
|
||||
if (Float.compare(that.saturation, this.saturation) != 0) return false;
|
||||
if (this.canAlwaysEat != that.canAlwaysEat) return false;
|
||||
if (Float.compare(that.eatSeconds, this.eatSeconds) != 0) return false;
|
||||
if (!this.effects.equals(that.effects)) return false;
|
||||
return Objects.equals(this.usingConvertsTo, that.usingConvertsTo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.nutrition, this.saturation, this.canAlwaysEat, this.eatSeconds, this.effects, this.usingConvertsTo);
|
||||
}
|
||||
|
||||
public static class PossibleEffect {
|
||||
|
||||
private PotionEffect effect;
|
||||
private float probability;
|
||||
|
||||
public PossibleEffect(PotionEffect effect, float probability) {
|
||||
this.effect = effect;
|
||||
this.probability = probability;
|
||||
}
|
||||
|
||||
public static PossibleEffect read(PacketWrapper<?> wrapper) {
|
||||
PotionEffect effect = PotionEffect.read(wrapper);
|
||||
float probability = wrapper.readFloat();
|
||||
return new PossibleEffect(effect, probability);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, PossibleEffect effect) {
|
||||
PotionEffect.write(wrapper, effect.effect);
|
||||
wrapper.writeFloat(effect.probability);
|
||||
}
|
||||
|
||||
public PotionEffect getEffect() {
|
||||
return this.effect;
|
||||
}
|
||||
|
||||
public void setEffect(PotionEffect effect) {
|
||||
this.effect = effect;
|
||||
}
|
||||
|
||||
public float getProbability() {
|
||||
return this.probability;
|
||||
}
|
||||
|
||||
public void setProbability(float probability) {
|
||||
this.probability = probability;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof PossibleEffect)) return false;
|
||||
PossibleEffect that = (PossibleEffect) obj;
|
||||
if (Float.compare(that.probability, this.probability) != 0) return false;
|
||||
return this.effect.equals(that.effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.effect, this.probability);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+330
@@ -0,0 +1,330 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.mapper.MappedEntitySet;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
// why do I have to implement this mess, I just want to deserialize items
|
||||
public class ItemAdventurePredicate {
|
||||
|
||||
private List<BlockPredicate> predicates;
|
||||
private boolean showInTooltip;
|
||||
|
||||
public ItemAdventurePredicate(List<BlockPredicate> predicates, boolean showInTooltip) {
|
||||
this.predicates = predicates;
|
||||
this.showInTooltip = showInTooltip;
|
||||
}
|
||||
|
||||
public static ItemAdventurePredicate read(PacketWrapper<?> wrapper) {
|
||||
List<BlockPredicate> predicates = wrapper.readList(BlockPredicate::read);
|
||||
boolean showInTooltip = wrapper.readBoolean();
|
||||
return new ItemAdventurePredicate(predicates, showInTooltip);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, ItemAdventurePredicate predicate) {
|
||||
wrapper.writeList(predicate.predicates, BlockPredicate::write);
|
||||
wrapper.writeBoolean(predicate.showInTooltip);
|
||||
}
|
||||
|
||||
public void addPredicate(BlockPredicate predicate) {
|
||||
this.predicates.add(predicate);
|
||||
}
|
||||
|
||||
public List<BlockPredicate> getPredicates() {
|
||||
return this.predicates;
|
||||
}
|
||||
|
||||
public void setPredicates(List<BlockPredicate> predicates) {
|
||||
this.predicates = predicates;
|
||||
}
|
||||
|
||||
public boolean isShowInTooltip() {
|
||||
return this.showInTooltip;
|
||||
}
|
||||
|
||||
public void setShowInTooltip(boolean showInTooltip) {
|
||||
this.showInTooltip = showInTooltip;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof ItemAdventurePredicate)) return false;
|
||||
ItemAdventurePredicate that = (ItemAdventurePredicate) obj;
|
||||
if (this.showInTooltip != that.showInTooltip) return false;
|
||||
return this.predicates.equals(that.predicates);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.predicates, this.showInTooltip);
|
||||
}
|
||||
|
||||
public static class BlockPredicate {
|
||||
|
||||
private @Nullable MappedEntitySet<StateType.Mapped> blocks;
|
||||
private @Nullable List<PropertyMatcher> properties;
|
||||
private @Nullable NBTCompound nbt;
|
||||
|
||||
public BlockPredicate(
|
||||
@Nullable MappedEntitySet<StateType.Mapped> blocks,
|
||||
@Nullable List<PropertyMatcher> properties,
|
||||
@Nullable NBTCompound nbt
|
||||
) {
|
||||
this.blocks = blocks;
|
||||
this.properties = properties;
|
||||
this.nbt = nbt;
|
||||
}
|
||||
|
||||
public static BlockPredicate read(PacketWrapper<?> wrapper) {
|
||||
MappedEntitySet<StateType.Mapped> blocks = wrapper.readOptional(
|
||||
ew -> MappedEntitySet.read(ew, StateTypes::getMappedById));
|
||||
List<PropertyMatcher> properties = wrapper.readOptional(
|
||||
ew -> wrapper.readList(PropertyMatcher::read));
|
||||
NBTCompound nbt = wrapper.readOptional(PacketWrapper::readNBT);
|
||||
return new BlockPredicate(blocks, properties, nbt);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, BlockPredicate predicate) {
|
||||
wrapper.writeOptional(predicate.blocks, MappedEntitySet::write);
|
||||
wrapper.writeOptional(predicate.properties,
|
||||
(ew, val) -> ew.writeList(val, PropertyMatcher::write));
|
||||
wrapper.writeOptional(predicate.nbt, PacketWrapper::writeNBT);
|
||||
}
|
||||
|
||||
public @Nullable MappedEntitySet<StateType.Mapped> getBlocks() {
|
||||
return this.blocks;
|
||||
}
|
||||
|
||||
public void setBlocks(@Nullable MappedEntitySet<StateType.Mapped> blocks) {
|
||||
this.blocks = blocks;
|
||||
}
|
||||
|
||||
public void addProperty(PropertyMatcher propertyMatcher) {
|
||||
if (this.properties == null) {
|
||||
this.properties = new ArrayList<>(4);
|
||||
}
|
||||
this.properties.add(propertyMatcher);
|
||||
}
|
||||
|
||||
public @Nullable List<PropertyMatcher> getProperties() {
|
||||
return this.properties;
|
||||
}
|
||||
|
||||
public void setProperties(@Nullable List<PropertyMatcher> properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public @Nullable NBTCompound getNbt() {
|
||||
return this.nbt;
|
||||
}
|
||||
|
||||
public void setNbt(@Nullable NBTCompound nbt) {
|
||||
this.nbt = nbt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof BlockPredicate)) return false;
|
||||
BlockPredicate that = (BlockPredicate) obj;
|
||||
if (!Objects.equals(this.blocks, that.blocks)) return false;
|
||||
if (!Objects.equals(this.properties, that.properties)) return false;
|
||||
return Objects.equals(this.nbt, that.nbt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.blocks, this.properties, this.nbt);
|
||||
}
|
||||
}
|
||||
|
||||
public static class PropertyMatcher {
|
||||
|
||||
private String name;
|
||||
private ValueMatcher matcher;
|
||||
|
||||
public PropertyMatcher(String name, ValueMatcher matcher) {
|
||||
this.name = name;
|
||||
this.matcher = matcher;
|
||||
}
|
||||
|
||||
public static PropertyMatcher read(PacketWrapper<?> wrapper) {
|
||||
String name = wrapper.readString();
|
||||
ValueMatcher matcher = ValueMatcher.read(wrapper);
|
||||
return new PropertyMatcher(name, matcher);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, PropertyMatcher matcher) {
|
||||
wrapper.writeString(matcher.name);
|
||||
ValueMatcher.write(wrapper, matcher.matcher);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public ValueMatcher getMatcher() {
|
||||
return this.matcher;
|
||||
}
|
||||
|
||||
public void setMatcher(ValueMatcher matcher) {
|
||||
this.matcher = matcher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof PropertyMatcher)) return false;
|
||||
PropertyMatcher that = (PropertyMatcher) obj;
|
||||
if (!this.name.equals(that.name)) return false;
|
||||
return this.matcher.equals(that.matcher);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.name, this.matcher);
|
||||
}
|
||||
}
|
||||
|
||||
public interface ValueMatcher {
|
||||
|
||||
static ValueMatcher read(PacketWrapper<?> wrapper) {
|
||||
if (wrapper.readBoolean()) {
|
||||
return ExactValueMatcher.read(wrapper);
|
||||
}
|
||||
return RangedValueMatcher.read(wrapper);
|
||||
}
|
||||
|
||||
static void write(PacketWrapper<?> wrapper, ValueMatcher matcher) {
|
||||
if (matcher instanceof ExactValueMatcher) {
|
||||
wrapper.writeBoolean(true);
|
||||
ExactValueMatcher.write(wrapper, (ExactValueMatcher) matcher);
|
||||
} else if (matcher instanceof RangedValueMatcher) {
|
||||
wrapper.writeBoolean(false);
|
||||
RangedValueMatcher.write(wrapper, (RangedValueMatcher) matcher);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Illegal matcher implementation: " + matcher);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class ExactValueMatcher implements ValueMatcher {
|
||||
|
||||
private String value;
|
||||
|
||||
public ExactValueMatcher(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static ExactValueMatcher read(PacketWrapper<?> wrapper) {
|
||||
return new ExactValueMatcher(wrapper.readString());
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, ExactValueMatcher matcher) {
|
||||
wrapper.writeString(matcher.value);
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof ExactValueMatcher)) return false;
|
||||
ExactValueMatcher that = (ExactValueMatcher) obj;
|
||||
return this.value.equals(that.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(this.value);
|
||||
}
|
||||
}
|
||||
|
||||
public static class RangedValueMatcher implements ValueMatcher {
|
||||
|
||||
private @Nullable String minValue;
|
||||
private @Nullable String maxValue;
|
||||
|
||||
public RangedValueMatcher(@Nullable String minValue, @Nullable String maxValue) {
|
||||
this.minValue = minValue;
|
||||
this.maxValue = maxValue;
|
||||
}
|
||||
|
||||
public static RangedValueMatcher read(PacketWrapper<?> wrapper) {
|
||||
String minValue = wrapper.readOptional(PacketWrapper::readString);
|
||||
String maxValue = wrapper.readOptional(PacketWrapper::readString);
|
||||
return new RangedValueMatcher(minValue, maxValue);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, RangedValueMatcher matcher) {
|
||||
wrapper.writeOptional(matcher.minValue, PacketWrapper::writeString);
|
||||
wrapper.writeOptional(matcher.maxValue, PacketWrapper::writeString);
|
||||
}
|
||||
|
||||
public @Nullable String getMinValue() {
|
||||
return this.minValue;
|
||||
}
|
||||
|
||||
public void setMinValue(@Nullable String minValue) {
|
||||
this.minValue = minValue;
|
||||
}
|
||||
|
||||
public @Nullable String getMaxValue() {
|
||||
return this.maxValue;
|
||||
}
|
||||
|
||||
public void setMaxValue(@Nullable String maxValue) {
|
||||
this.maxValue = maxValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof RangedValueMatcher)) return false;
|
||||
RangedValueMatcher that = (RangedValueMatcher) obj;
|
||||
if (!Objects.equals(this.minValue, that.minValue)) return false;
|
||||
return Objects.equals(this.maxValue, that.maxValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.minValue, this.maxValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
+312
@@ -0,0 +1,312 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.attribute.Attribute;
|
||||
import com.github.retrooper.packetevents.protocol.attribute.AttributeOperation;
|
||||
import com.github.retrooper.packetevents.protocol.attribute.Attributes;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateAttributes.PropertyModifier;
|
||||
import net.kyori.adventure.util.Index;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ItemAttributeModifiers {
|
||||
|
||||
public static final ItemAttributeModifiers EMPTY = new ItemAttributeModifiers(
|
||||
Collections.emptyList(), true) {
|
||||
@Override
|
||||
public void setShowInTooltip(boolean showInTooltip) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
|
||||
private List<ModifierEntry> modifiers;
|
||||
private boolean showInTooltip;
|
||||
|
||||
public ItemAttributeModifiers(List<ModifierEntry> modifiers, boolean showInTooltip) {
|
||||
this.modifiers = modifiers;
|
||||
this.showInTooltip = showInTooltip;
|
||||
}
|
||||
|
||||
public static ItemAttributeModifiers read(PacketWrapper<?> wrapper) {
|
||||
List<ModifierEntry> modifiers = wrapper.readList(ModifierEntry::read);
|
||||
boolean showInTooltip = wrapper.readBoolean();
|
||||
return new ItemAttributeModifiers(modifiers, showInTooltip);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, ItemAttributeModifiers modifiers) {
|
||||
wrapper.writeList(modifiers.modifiers, ModifierEntry::write);
|
||||
wrapper.writeBoolean(modifiers.showInTooltip);
|
||||
}
|
||||
|
||||
public void addModifier(ModifierEntry modifier) {
|
||||
this.modifiers.add(modifier);
|
||||
}
|
||||
|
||||
public List<ModifierEntry> getModifiers() {
|
||||
return this.modifiers;
|
||||
}
|
||||
|
||||
public void setModifiers(List<ModifierEntry> modifiers) {
|
||||
this.modifiers = modifiers;
|
||||
}
|
||||
|
||||
public boolean isShowInTooltip() {
|
||||
return this.showInTooltip;
|
||||
}
|
||||
|
||||
public void setShowInTooltip(boolean showInTooltip) {
|
||||
this.showInTooltip = showInTooltip;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof ItemAttributeModifiers)) return false;
|
||||
ItemAttributeModifiers that = (ItemAttributeModifiers) obj;
|
||||
if (this.showInTooltip != that.showInTooltip) return false;
|
||||
return this.modifiers.equals(that.modifiers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.modifiers, this.showInTooltip);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ItemAttributeModifiers{modifiers=" + this.modifiers + ", showInTooltip=" + this.showInTooltip + '}';
|
||||
}
|
||||
|
||||
public static class ModifierEntry {
|
||||
|
||||
private Attribute attribute;
|
||||
private Modifier modifier;
|
||||
private EquipmentSlotGroup slotGroup;
|
||||
|
||||
public ModifierEntry(Attribute attribute, Modifier modifier, EquipmentSlotGroup slotGroup) {
|
||||
this.attribute = attribute;
|
||||
this.modifier = modifier;
|
||||
this.slotGroup = slotGroup;
|
||||
}
|
||||
|
||||
public static ModifierEntry read(PacketWrapper<?> wrapper) {
|
||||
Attribute attribute = wrapper.readMappedEntity(Attributes::getById);
|
||||
Modifier modifier = Modifier.read(wrapper);
|
||||
EquipmentSlotGroup slot = wrapper.readEnum(EquipmentSlotGroup.values());
|
||||
return new ModifierEntry(attribute, modifier, slot);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, ModifierEntry entry) {
|
||||
wrapper.writeMappedEntity(entry.attribute);
|
||||
Modifier.write(wrapper, entry.modifier);
|
||||
wrapper.writeEnum(entry.slotGroup);
|
||||
}
|
||||
|
||||
public Attribute getAttribute() {
|
||||
return this.attribute;
|
||||
}
|
||||
|
||||
public void setAttribute(Attribute attribute) {
|
||||
this.attribute = attribute;
|
||||
}
|
||||
|
||||
public Modifier getModifier() {
|
||||
return this.modifier;
|
||||
}
|
||||
|
||||
public void setModifier(Modifier modifier) {
|
||||
this.modifier = modifier;
|
||||
}
|
||||
|
||||
public EquipmentSlotGroup getSlotGroup() {
|
||||
return this.slotGroup;
|
||||
}
|
||||
|
||||
public void setSlotGroup(EquipmentSlotGroup slotGroup) {
|
||||
this.slotGroup = slotGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof ModifierEntry)) return false;
|
||||
ModifierEntry that = (ModifierEntry) obj;
|
||||
if (!this.attribute.equals(that.attribute)) return false;
|
||||
if (!this.modifier.equals(that.modifier)) return false;
|
||||
return this.slotGroup == that.slotGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.attribute, this.modifier, this.slotGroup);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ModifierEntry{attribute=" + this.attribute + ", modifier=" + this.modifier + ", slotGroup=" + this.slotGroup + '}';
|
||||
}
|
||||
}
|
||||
|
||||
public static class Modifier {
|
||||
|
||||
private UUID id; // removed in 1.21
|
||||
private String name; // ResourceLocation since 1.21
|
||||
private double value;
|
||||
private AttributeOperation operation;
|
||||
|
||||
public Modifier(ResourceLocation name, double value, AttributeOperation operation) {
|
||||
this(PropertyModifier.generateSemiUniqueId(name), name.toString(), value, operation);
|
||||
}
|
||||
|
||||
@ApiStatus.Obsolete
|
||||
public Modifier(UUID id, String name, double value, AttributeOperation operation) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
this.operation = operation;
|
||||
}
|
||||
|
||||
public static Modifier read(PacketWrapper<?> wrapper) {
|
||||
UUID id;
|
||||
String name;
|
||||
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21)) {
|
||||
ResourceLocation nameKey = wrapper.readIdentifier();
|
||||
name = nameKey.toString();
|
||||
id = PropertyModifier.generateSemiUniqueId(nameKey);
|
||||
} else {
|
||||
id = wrapper.readUUID();
|
||||
name = wrapper.readString();
|
||||
}
|
||||
double value = wrapper.readDouble();
|
||||
AttributeOperation operation = wrapper.readEnum(AttributeOperation.values());
|
||||
return new Modifier(id, name, value, operation);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, Modifier modifier) {
|
||||
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21)) {
|
||||
wrapper.writeIdentifier(new ResourceLocation(modifier.name));
|
||||
} else {
|
||||
wrapper.writeUUID(modifier.id);
|
||||
wrapper.writeString(modifier.name);
|
||||
}
|
||||
wrapper.writeDouble(modifier.value);
|
||||
wrapper.writeEnum(modifier.operation);
|
||||
}
|
||||
|
||||
public ResourceLocation getNameKey() {
|
||||
return new ResourceLocation(this.name);
|
||||
}
|
||||
|
||||
public void setNameKey(ResourceLocation nameKey) {
|
||||
this.name = nameKey.toString();
|
||||
}
|
||||
|
||||
@ApiStatus.Obsolete
|
||||
public UUID getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@ApiStatus.Obsolete
|
||||
public void setId(UUID id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@ApiStatus.Obsolete
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
@ApiStatus.Obsolete
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public double getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public void setValue(double value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public AttributeOperation getOperation() {
|
||||
return this.operation;
|
||||
}
|
||||
|
||||
public void setOperation(AttributeOperation operation) {
|
||||
this.operation = operation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof Modifier)) return false;
|
||||
Modifier modifier = (Modifier) obj;
|
||||
if (Double.compare(modifier.value, this.value) != 0) return false;
|
||||
if (!this.id.equals(modifier.id)) return false;
|
||||
if (!this.name.equals(modifier.name)) return false;
|
||||
return this.operation == modifier.operation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.id, this.name, this.value, this.operation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Modifier{id=" + this.id + ", name='" + this.name + '\'' + ", value=" + this.value + ", operation=" + this.operation + '}';
|
||||
}
|
||||
}
|
||||
|
||||
public enum EquipmentSlotGroup {
|
||||
|
||||
ANY("any"),
|
||||
MAINHAND("mainhand"),
|
||||
OFFHAND("offhand"),
|
||||
HAND("hand"),
|
||||
FEET("feet"),
|
||||
LEGS("legs"),
|
||||
CHEST("chest"),
|
||||
HEAD("head"),
|
||||
ARMOR("armor"),
|
||||
BODY("body");
|
||||
|
||||
public static final Index<String, EquipmentSlotGroup> ID_INDEX = Index.create(
|
||||
EquipmentSlotGroup.class, EquipmentSlotGroup::getId);
|
||||
|
||||
private final String id;
|
||||
|
||||
EquipmentSlotGroup(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class ItemBees {
|
||||
|
||||
private List<BeeEntry> bees;
|
||||
|
||||
public ItemBees(List<BeeEntry> bees) {
|
||||
this.bees = bees;
|
||||
}
|
||||
|
||||
public static ItemBees read(PacketWrapper<?> wrapper) {
|
||||
List<BeeEntry> bees = wrapper.readList(BeeEntry::read);
|
||||
return new ItemBees(bees);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, ItemBees bees) {
|
||||
wrapper.writeList(bees.bees, BeeEntry::write);
|
||||
}
|
||||
|
||||
public void addBee(BeeEntry bee) {
|
||||
this.bees.add(bee);
|
||||
}
|
||||
|
||||
public List<BeeEntry> getBees() {
|
||||
return this.bees;
|
||||
}
|
||||
|
||||
public void setBees(List<BeeEntry> bees) {
|
||||
this.bees = bees;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof ItemBees)) return false;
|
||||
ItemBees itemBees = (ItemBees) obj;
|
||||
return this.bees.equals(itemBees.bees);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(this.bees);
|
||||
}
|
||||
|
||||
public static class BeeEntry {
|
||||
|
||||
private NBTCompound entityData;
|
||||
private int ticksInHive;
|
||||
private int minTicksInHive;
|
||||
|
||||
public BeeEntry(NBTCompound entityData, int ticksInHive, int minTicksInHive) {
|
||||
this.entityData = entityData;
|
||||
this.ticksInHive = ticksInHive;
|
||||
this.minTicksInHive = minTicksInHive;
|
||||
}
|
||||
|
||||
public static BeeEntry read(PacketWrapper<?> wrapper) {
|
||||
NBTCompound entityData = wrapper.readNBT();
|
||||
int ticksInHive = wrapper.readVarInt();
|
||||
int minTicksInHive = wrapper.readVarInt();
|
||||
return new BeeEntry(entityData, ticksInHive, minTicksInHive);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, BeeEntry bee) {
|
||||
wrapper.writeNBT(bee.entityData);
|
||||
wrapper.writeVarInt(bee.ticksInHive);
|
||||
wrapper.writeVarInt(bee.minTicksInHive);
|
||||
}
|
||||
|
||||
public NBTCompound getEntityData() {
|
||||
return this.entityData;
|
||||
}
|
||||
|
||||
public void setEntityData(NBTCompound entityData) {
|
||||
this.entityData = entityData;
|
||||
}
|
||||
|
||||
public int getTicksInHive() {
|
||||
return this.ticksInHive;
|
||||
}
|
||||
|
||||
public void setTicksInHive(int ticksInHive) {
|
||||
this.ticksInHive = ticksInHive;
|
||||
}
|
||||
|
||||
public int getMinTicksInHive() {
|
||||
return this.minTicksInHive;
|
||||
}
|
||||
|
||||
public void setMinTicksInHive(int minTicksInHive) {
|
||||
this.minTicksInHive = minTicksInHive;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof BeeEntry)) return false;
|
||||
BeeEntry beeEntry = (BeeEntry) obj;
|
||||
if (this.ticksInHive != beeEntry.ticksInHive) return false;
|
||||
if (this.minTicksInHive != beeEntry.minTicksInHive) return false;
|
||||
return this.entityData.equals(beeEntry.entityData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.entityData, this.ticksInHive, this.minTicksInHive);
|
||||
}
|
||||
}
|
||||
}
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateValue;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class ItemBlockStateProperties {
|
||||
|
||||
private Map<String, String> properties;
|
||||
|
||||
public ItemBlockStateProperties(Map<String, String> properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public static ItemBlockStateProperties read(PacketWrapper<?> wrapper) {
|
||||
Map<String, String> properties = wrapper.readMap(
|
||||
PacketWrapper::readString, PacketWrapper::readString);
|
||||
return new ItemBlockStateProperties(properties);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, ItemBlockStateProperties props) {
|
||||
wrapper.writeMap(props.properties,
|
||||
PacketWrapper::writeString,
|
||||
PacketWrapper::writeString);
|
||||
}
|
||||
|
||||
public @Nullable Object getProperty(StateValue stateValue) {
|
||||
String value = this.getProperty(stateValue.getName());
|
||||
if (value != null) {
|
||||
return stateValue.getParser().apply(value);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public @Nullable String getProperty(String key) {
|
||||
return this.properties.get(key);
|
||||
}
|
||||
|
||||
public void setProperty(StateValue stateValue, @Nullable Object value) {
|
||||
this.setProperty(stateValue.getName(), value == null ? null : value.toString());
|
||||
}
|
||||
|
||||
public void setProperty(String key, @Nullable String value) {
|
||||
if (value == null) {
|
||||
this.properties.remove(key);
|
||||
} else {
|
||||
this.properties.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
public void unsetProperty(StateValue stateValue) {
|
||||
this.unsetProperty(stateValue.getName());
|
||||
}
|
||||
|
||||
public void unsetProperty(String key) {
|
||||
this.setProperty(key, null);
|
||||
}
|
||||
|
||||
public Map<String, String> getProperties() {
|
||||
return this.properties;
|
||||
}
|
||||
|
||||
public void setProperties(Map<String, String> properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof ItemBlockStateProperties)) return false;
|
||||
ItemBlockStateProperties that = (ItemBlockStateProperties) obj;
|
||||
return this.properties.equals(that.properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(this.properties);
|
||||
}
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.item.ItemStack;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class ItemContainerContents {
|
||||
|
||||
private List<ItemStack> items;
|
||||
|
||||
public ItemContainerContents(List<ItemStack> items) {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
public static ItemContainerContents read(PacketWrapper<?> wrapper) {
|
||||
List<ItemStack> items = wrapper.readList(PacketWrapper::readItemStack);
|
||||
return new ItemContainerContents(items);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, ItemContainerContents contents) {
|
||||
wrapper.writeList(contents.items, PacketWrapper::writeItemStack);
|
||||
}
|
||||
|
||||
public void addItem(ItemStack itemStack) {
|
||||
this.items.add(itemStack);
|
||||
}
|
||||
|
||||
public List<ItemStack> getItems() {
|
||||
return this.items;
|
||||
}
|
||||
|
||||
public void setItems(List<ItemStack> items) {
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof ItemContainerContents)) return false;
|
||||
ItemContainerContents that = (ItemContainerContents) obj;
|
||||
return this.items.equals(that.items);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(this.items);
|
||||
}
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTLong;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTNumber;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class ItemContainerLoot {
|
||||
|
||||
private ResourceLocation lootTable;
|
||||
private long seed;
|
||||
|
||||
public ItemContainerLoot(ResourceLocation lootTable, long seed) {
|
||||
this.lootTable = lootTable;
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
public static ItemContainerLoot read(PacketWrapper<?> wrapper) {
|
||||
NBTCompound compound = wrapper.readNBT();
|
||||
ResourceLocation lootTable = new ResourceLocation(compound.getStringTagValueOrThrow("loot_table"));
|
||||
NBTNumber seedTag = compound.getNumberTagOrNull("seed");
|
||||
long seed = seedTag == null ? 0L : seedTag.getAsLong();
|
||||
return new ItemContainerLoot(lootTable, seed);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, ItemContainerLoot loot) {
|
||||
NBTCompound compound = new NBTCompound();
|
||||
compound.setTag("loot_table", new NBTString(loot.lootTable.toString()));
|
||||
if (loot.seed != 0L) {
|
||||
compound.setTag("seed", new NBTLong(loot.seed));
|
||||
}
|
||||
wrapper.writeNBT(compound);
|
||||
}
|
||||
|
||||
public ResourceLocation getLootTable() {
|
||||
return this.lootTable;
|
||||
}
|
||||
|
||||
public void setLootTable(ResourceLocation lootTable) {
|
||||
this.lootTable = lootTable;
|
||||
}
|
||||
|
||||
public long getSeed() {
|
||||
return this.seed;
|
||||
}
|
||||
|
||||
public void setSeed(long seed) {
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof ItemContainerLoot)) return false;
|
||||
ItemContainerLoot that = (ItemContainerLoot) obj;
|
||||
if (this.seed != that.seed) return false;
|
||||
return this.lootTable.equals(that.lootTable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.lootTable, this.seed);
|
||||
}
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class ItemDyeColor {
|
||||
|
||||
private int rgb;
|
||||
private boolean showInTooltip;
|
||||
|
||||
public ItemDyeColor(int rgb, boolean showInTooltip) {
|
||||
this.rgb = rgb;
|
||||
this.showInTooltip = showInTooltip;
|
||||
}
|
||||
|
||||
public static ItemDyeColor read(PacketWrapper<?> wrapper) {
|
||||
int rgb = wrapper.readInt();
|
||||
boolean showInTooltip = wrapper.readBoolean();
|
||||
return new ItemDyeColor(rgb, showInTooltip);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, ItemDyeColor color) {
|
||||
wrapper.writeInt(color.rgb);
|
||||
wrapper.writeBoolean(color.showInTooltip);
|
||||
}
|
||||
|
||||
public int getRgb() {
|
||||
return this.rgb;
|
||||
}
|
||||
|
||||
public void setRgb(int rgb) {
|
||||
this.rgb = rgb;
|
||||
}
|
||||
|
||||
public boolean isShowInTooltip() {
|
||||
return this.showInTooltip;
|
||||
}
|
||||
|
||||
public void setShowInTooltip(boolean showInTooltip) {
|
||||
this.showInTooltip = showInTooltip;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof ItemDyeColor)) return false;
|
||||
ItemDyeColor that = (ItemDyeColor) obj;
|
||||
if (this.rgb != that.rgb) return false;
|
||||
return this.showInTooltip == that.showInTooltip;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.rgb, this.showInTooltip);
|
||||
}
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.item.enchantment.type.EnchantmentType;
|
||||
import com.github.retrooper.packetevents.protocol.item.enchantment.type.EnchantmentTypes;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class ItemEnchantments implements Iterable<Map.Entry<EnchantmentType, Integer>> {
|
||||
|
||||
public static final ItemEnchantments EMPTY = new ItemEnchantments(
|
||||
Collections.emptyMap(), true) {
|
||||
@Override
|
||||
public void setShowInTooltip(boolean showInTooltip) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
|
||||
private Map<EnchantmentType, Integer> enchantments;
|
||||
private boolean showInTooltip;
|
||||
|
||||
public ItemEnchantments(Map<EnchantmentType, Integer> enchantments, boolean showInTooltip) {
|
||||
this.enchantments = Collections.unmodifiableMap(enchantments);
|
||||
this.showInTooltip = showInTooltip;
|
||||
}
|
||||
|
||||
public static ItemEnchantments read(PacketWrapper<?> wrapper) {
|
||||
Map<EnchantmentType, Integer> enchantments = wrapper.readMap(
|
||||
ew -> wrapper.readMappedEntity(EnchantmentTypes.getRegistry()),
|
||||
PacketWrapper::readVarInt
|
||||
);
|
||||
boolean showInTooltip = wrapper.readBoolean();
|
||||
return new ItemEnchantments(enchantments, showInTooltip);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, ItemEnchantments enchantments) {
|
||||
ClientVersion version = wrapper.getServerVersion().toClientVersion();
|
||||
wrapper.writeMap(enchantments.getEnchantments(),
|
||||
(ew, enchantment) -> ew.writeVarInt(enchantment.getId(version)),
|
||||
PacketWrapper::writeVarInt
|
||||
);
|
||||
wrapper.writeBoolean(enchantments.isShowInTooltip());
|
||||
}
|
||||
|
||||
public int getEnchantmentLevel(EnchantmentType enchantment) {
|
||||
return this.enchantments.getOrDefault(enchantment, 0);
|
||||
}
|
||||
|
||||
public void setEnchantmentLevel(EnchantmentType enchantment, int level) {
|
||||
if (level == 0) {
|
||||
this.enchantments.remove(enchantment);
|
||||
} else {
|
||||
this.enchantments.put(enchantment, level);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this.getEnchantmentCount() < 1;
|
||||
}
|
||||
|
||||
public int getEnchantmentCount() {
|
||||
return this.enchantments.size();
|
||||
}
|
||||
|
||||
public Map<EnchantmentType, Integer> getEnchantments() {
|
||||
return this.enchantments;
|
||||
}
|
||||
|
||||
public void setEnchantments(Map<EnchantmentType, Integer> enchantments) {
|
||||
this.enchantments = enchantments;
|
||||
}
|
||||
|
||||
public boolean isShowInTooltip() {
|
||||
return this.showInTooltip;
|
||||
}
|
||||
|
||||
public void setShowInTooltip(boolean showInTooltip) {
|
||||
this.showInTooltip = showInTooltip;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Map.Entry<EnchantmentType, Integer>> iterator() {
|
||||
return this.enchantments.entrySet().iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof ItemEnchantments)) return false;
|
||||
ItemEnchantments that = (ItemEnchantments) obj;
|
||||
if (this.showInTooltip != that.showInTooltip) return false;
|
||||
return this.enchantments.equals(that.enchantments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.enchantments, this.showInTooltip);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ItemEnchantments{enchantments=" + this.enchantments + ", showInTooltip=" + this.showInTooltip + '}';
|
||||
}
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class ItemFireworks {
|
||||
|
||||
private int flightDuration;
|
||||
private List<FireworkExplosion> explosions;
|
||||
|
||||
public ItemFireworks(int flightDuration, List<FireworkExplosion> explosions) {
|
||||
this.flightDuration = flightDuration;
|
||||
this.explosions = explosions;
|
||||
}
|
||||
|
||||
public static ItemFireworks read(PacketWrapper<?> wrapper) {
|
||||
int flightDuration = wrapper.readVarInt();
|
||||
List<FireworkExplosion> explosions = wrapper.readList(FireworkExplosion::read);
|
||||
return new ItemFireworks(flightDuration, explosions);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, ItemFireworks fireworks) {
|
||||
wrapper.writeVarInt(fireworks.flightDuration);
|
||||
wrapper.writeList(fireworks.explosions, FireworkExplosion::write);
|
||||
}
|
||||
|
||||
public int getFlightDuration() {
|
||||
return this.flightDuration;
|
||||
}
|
||||
|
||||
public void setFlightDuration(int flightDuration) {
|
||||
this.flightDuration = flightDuration;
|
||||
}
|
||||
|
||||
public void addExplosion(FireworkExplosion explosion) {
|
||||
this.explosions.add(explosion);
|
||||
}
|
||||
|
||||
public List<FireworkExplosion> getExplosions() {
|
||||
return this.explosions;
|
||||
}
|
||||
|
||||
public void setExplosions(List<FireworkExplosion> explosions) {
|
||||
this.explosions = explosions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof ItemFireworks)) return false;
|
||||
ItemFireworks that = (ItemFireworks) obj;
|
||||
if (this.flightDuration != that.flightDuration) return false;
|
||||
return this.explosions.equals(that.explosions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.flightDuration, this.explosions);
|
||||
}
|
||||
}
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.item.jukebox.IJukeboxSong;
|
||||
import com.github.retrooper.packetevents.protocol.item.jukebox.JukeboxSong;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class ItemJukeboxPlayable {
|
||||
|
||||
private @Nullable IJukeboxSong song;
|
||||
private @Nullable ResourceLocation songKey;
|
||||
private boolean showInTooltip;
|
||||
|
||||
public ItemJukeboxPlayable(
|
||||
@Nullable JukeboxSong song,
|
||||
@Nullable ResourceLocation songKey,
|
||||
boolean showInTooltip
|
||||
) {
|
||||
this((IJukeboxSong) song, songKey, showInTooltip);
|
||||
}
|
||||
|
||||
public ItemJukeboxPlayable(
|
||||
@Nullable IJukeboxSong song,
|
||||
@Nullable ResourceLocation songKey,
|
||||
boolean showInTooltip
|
||||
) {
|
||||
if ((song == null) == (songKey == null)) {
|
||||
throw new IllegalStateException("Illegal state of both song and "
|
||||
+ "song key combined: " + song + " / " + songKey);
|
||||
}
|
||||
|
||||
this.song = song;
|
||||
this.songKey = songKey;
|
||||
this.showInTooltip = showInTooltip;
|
||||
}
|
||||
|
||||
public static ItemJukeboxPlayable read(PacketWrapper<?> wrapper) {
|
||||
IJukeboxSong song;
|
||||
ResourceLocation songKey;
|
||||
if (wrapper.readBoolean()) {
|
||||
song = IJukeboxSong.read(wrapper);
|
||||
songKey = null;
|
||||
} else {
|
||||
song = null;
|
||||
songKey = wrapper.readIdentifier();
|
||||
}
|
||||
boolean showInTooltip = wrapper.readBoolean();
|
||||
return new ItemJukeboxPlayable(song, songKey, showInTooltip);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, ItemJukeboxPlayable jukeboxPlayable) {
|
||||
if (jukeboxPlayable.song != null) {
|
||||
wrapper.writeBoolean(true);
|
||||
IJukeboxSong.write(wrapper, jukeboxPlayable.song);
|
||||
} else {
|
||||
assert jukeboxPlayable.songKey != null;
|
||||
wrapper.writeBoolean(false);
|
||||
wrapper.writeIdentifier(jukeboxPlayable.songKey);
|
||||
}
|
||||
wrapper.writeBoolean(jukeboxPlayable.showInTooltip);
|
||||
}
|
||||
|
||||
public @Nullable IJukeboxSong getJukeboxSong() {
|
||||
return this.song;
|
||||
}
|
||||
|
||||
public void setJukeboxSong(@Nullable JukeboxSong song) {
|
||||
this.song = song;
|
||||
this.songKey = null;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public @Nullable JukeboxSong getSong() {
|
||||
if (this.song == null) {
|
||||
return null;
|
||||
} else if (this.song instanceof JukeboxSong) {
|
||||
return (JukeboxSong) this.song;
|
||||
}
|
||||
return (JukeboxSong) this.song.copy(null);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setSong(JukeboxSong song) {
|
||||
this.song = song;
|
||||
this.songKey = null;
|
||||
}
|
||||
|
||||
public @Nullable ResourceLocation getSongKey() {
|
||||
return this.songKey;
|
||||
}
|
||||
|
||||
public void setSongKey(ResourceLocation songKey) {
|
||||
this.song = null;
|
||||
this.songKey = songKey;
|
||||
}
|
||||
|
||||
public boolean isShowInTooltip() {
|
||||
return this.showInTooltip;
|
||||
}
|
||||
|
||||
public void setShowInTooltip(boolean showInTooltip) {
|
||||
this.showInTooltip = showInTooltip;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof ItemJukeboxPlayable)) return false;
|
||||
ItemJukeboxPlayable that = (ItemJukeboxPlayable) obj;
|
||||
if (this.showInTooltip != that.showInTooltip) return false;
|
||||
if (!Objects.equals(this.song, that.song)) return false;
|
||||
return Objects.equals(this.songKey, that.songKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.song, this.songKey, this.showInTooltip);
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class ItemLock {
|
||||
|
||||
private String code;
|
||||
|
||||
public ItemLock(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public static ItemLock read(PacketWrapper<?> wrapper) {
|
||||
NBTString codeTag = (NBTString) wrapper.readNBTRaw();
|
||||
return new ItemLock(codeTag.getValue());
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, ItemLock lock) {
|
||||
wrapper.writeNBTRaw(new NBTString(lock.code));
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof ItemLock)) return false;
|
||||
ItemLock itemLock = (ItemLock) obj;
|
||||
return this.code.equals(itemLock.code);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(this.code);
|
||||
}
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class ItemLore {
|
||||
|
||||
public static final ItemLore EMPTY = new ItemLore(Collections.emptyList());
|
||||
|
||||
private List<Component> lines;
|
||||
|
||||
public ItemLore(List<Component> lines) {
|
||||
this.lines = lines;
|
||||
}
|
||||
|
||||
public static ItemLore read(PacketWrapper<?> wrapper) {
|
||||
List<Component> lines = wrapper.readList(PacketWrapper::readComponent);
|
||||
return new ItemLore(lines);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, ItemLore lore) {
|
||||
wrapper.writeList(lore.lines, PacketWrapper::writeComponent);
|
||||
}
|
||||
|
||||
public void addLine(Component line) {
|
||||
this.lines.add(line);
|
||||
}
|
||||
|
||||
public List<Component> getLines() {
|
||||
return this.lines;
|
||||
}
|
||||
|
||||
public void setLines(List<Component> lines) {
|
||||
this.lines = lines;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof ItemLore)) return false;
|
||||
ItemLore itemLore = (ItemLore) obj;
|
||||
return this.lines.equals(itemLore.lines);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.lines);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ItemLore{lines=" + this.lines + '}';
|
||||
}
|
||||
}
|
||||
+176
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.item.mapdecoration.MapDecorationType;
|
||||
import com.github.retrooper.packetevents.protocol.item.mapdecoration.MapDecorationTypes;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBT;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTDouble;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTFloat;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class ItemMapDecorations {
|
||||
|
||||
private Map<String, Decoration> decorations;
|
||||
|
||||
public ItemMapDecorations(Map<String, Decoration> decorations) {
|
||||
this.decorations = decorations;
|
||||
}
|
||||
|
||||
public static ItemMapDecorations read(PacketWrapper<?> wrapper) {
|
||||
NBTCompound compound = wrapper.readNBT();
|
||||
Map<String, Decoration> decorations = new HashMap<>(compound.size());
|
||||
for (Map.Entry<String, NBT> tag : compound.getTags().entrySet()) {
|
||||
Decoration decoration = Decoration.readCompound((NBTCompound) tag.getValue());
|
||||
decorations.put(tag.getKey(), decoration);
|
||||
}
|
||||
return new ItemMapDecorations(decorations);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, ItemMapDecorations decorations) {
|
||||
NBTCompound compound = new NBTCompound();
|
||||
for (Map.Entry<String, Decoration> decoration : decorations.decorations.entrySet()) {
|
||||
NBTCompound entry = new NBTCompound();
|
||||
Decoration.writeCompound(entry, decoration.getValue());
|
||||
compound.setTag(decoration.getKey(), entry);
|
||||
}
|
||||
wrapper.writeNBT(compound);
|
||||
}
|
||||
|
||||
public @Nullable Decoration getDecoration(String key) {
|
||||
return this.decorations.get(key);
|
||||
}
|
||||
|
||||
public void setDecoration(String key, @Nullable Decoration decoration) {
|
||||
if (decoration != null) {
|
||||
this.decorations.put(key, decoration);
|
||||
} else {
|
||||
this.decorations.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, Decoration> getDecorations() {
|
||||
return this.decorations;
|
||||
}
|
||||
|
||||
public void setDecorations(Map<String, Decoration> decorations) {
|
||||
this.decorations = decorations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof ItemMapDecorations)) return false;
|
||||
ItemMapDecorations that = (ItemMapDecorations) obj;
|
||||
return this.decorations.equals(that.decorations);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(this.decorations);
|
||||
}
|
||||
|
||||
public static final class Decoration {
|
||||
|
||||
private MapDecorationType type;
|
||||
private double x;
|
||||
private double z;
|
||||
private float rotation;
|
||||
|
||||
public Decoration(MapDecorationType type, double x, double z, float rotation) {
|
||||
this.type = type;
|
||||
this.x = x;
|
||||
this.z = z;
|
||||
this.rotation = rotation;
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static Decoration readCompound(NBTCompound compound) {
|
||||
MapDecorationType type = MapDecorationTypes.getByName(compound.getStringTagValueOrThrow("type"));
|
||||
double x = compound.getNumberTagOrThrow("x").getAsDouble();
|
||||
double z = compound.getNumberTagOrThrow("z").getAsDouble();
|
||||
float rotation = compound.getNumberTagOrThrow("rotation").getAsFloat();
|
||||
return new Decoration(type, x, z, rotation);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static void writeCompound(NBTCompound compound, Decoration decoration) {
|
||||
compound.setTag("type", new NBTString(decoration.type.getName().toString()));
|
||||
compound.setTag("x", new NBTDouble(decoration.x));
|
||||
compound.setTag("z", new NBTDouble(decoration.z));
|
||||
compound.setTag("rotation", new NBTFloat(decoration.rotation));
|
||||
}
|
||||
|
||||
public MapDecorationType getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public void setType(MapDecorationType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
public void setX(double x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public double getZ() {
|
||||
return this.z;
|
||||
}
|
||||
|
||||
public void setZ(double z) {
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public float getRotation() {
|
||||
return this.rotation;
|
||||
}
|
||||
|
||||
public void setRotation(float rotation) {
|
||||
this.rotation = rotation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof Decoration)) return false;
|
||||
Decoration that = (Decoration) obj;
|
||||
if (Double.compare(that.x, this.x) != 0) return false;
|
||||
if (Double.compare(that.z, this.z) != 0) return false;
|
||||
if (Float.compare(that.rotation, this.rotation) != 0) return false;
|
||||
return this.type.equals(that.type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.type, this.x, this.z, this.rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
public enum ItemMapPostProcessingState {
|
||||
LOCKED,
|
||||
SCALED,
|
||||
}
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.potion.Potion;
|
||||
import com.github.retrooper.packetevents.protocol.potion.PotionEffect;
|
||||
import com.github.retrooper.packetevents.protocol.potion.Potions;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class ItemPotionContents {
|
||||
|
||||
private @Nullable Potion potion;
|
||||
private @Nullable Integer customColor;
|
||||
private List<PotionEffect> customEffects;
|
||||
|
||||
public ItemPotionContents(
|
||||
@Nullable Potion potion,
|
||||
@Nullable Integer customColor,
|
||||
List<PotionEffect> customEffects
|
||||
) {
|
||||
this.potion = potion;
|
||||
this.customColor = customColor;
|
||||
this.customEffects = customEffects;
|
||||
}
|
||||
|
||||
public static ItemPotionContents read(PacketWrapper<?> wrapper) {
|
||||
Potion potionId = wrapper.readOptional(ew -> ew.readMappedEntity(Potions::getById));
|
||||
Integer customColor = wrapper.readOptional(PacketWrapper::readInt);
|
||||
List<PotionEffect> customEffects = wrapper.readList(PotionEffect::read);
|
||||
return new ItemPotionContents(potionId, customColor, customEffects);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, ItemPotionContents contents) {
|
||||
wrapper.writeOptional(contents.potion, PacketWrapper::writeMappedEntity);
|
||||
wrapper.writeOptional(contents.customColor, PacketWrapper::writeInt);
|
||||
wrapper.writeList(contents.customEffects, PotionEffect::write);
|
||||
}
|
||||
|
||||
public @Nullable Potion getPotion() {
|
||||
return this.potion;
|
||||
}
|
||||
|
||||
public void setPotion(@Nullable Potion potion) {
|
||||
this.potion = potion;
|
||||
}
|
||||
|
||||
public @Nullable Integer getCustomColor() {
|
||||
return this.customColor;
|
||||
}
|
||||
|
||||
public void setCustomColor(@Nullable Integer customColor) {
|
||||
this.customColor = customColor;
|
||||
}
|
||||
|
||||
private void addCustomEffect(PotionEffect effect) {
|
||||
this.customEffects.add(effect);
|
||||
}
|
||||
|
||||
public List<PotionEffect> getCustomEffects() {
|
||||
return this.customEffects;
|
||||
}
|
||||
|
||||
public void setCustomEffects(List<PotionEffect> customEffects) {
|
||||
this.customEffects = customEffects;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof ItemPotionContents)) return false;
|
||||
ItemPotionContents that = (ItemPotionContents) obj;
|
||||
if (!Objects.equals(this.potion, that.potion)) return false;
|
||||
if (!Objects.equals(this.customColor, that.customColor)) return false;
|
||||
return this.customEffects.equals(that.customEffects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.potion, this.customColor, this.customEffects);
|
||||
}
|
||||
}
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ItemProfile {
|
||||
|
||||
private @Nullable String name;
|
||||
private @Nullable UUID id;
|
||||
private List<Property> properties;
|
||||
|
||||
public ItemProfile(
|
||||
@Nullable String name,
|
||||
@Nullable UUID id,
|
||||
List<Property> properties
|
||||
) {
|
||||
this.name = name;
|
||||
this.id = id;
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public static ItemProfile read(PacketWrapper<?> wrapper) {
|
||||
String name = wrapper.readOptional(ew -> ew.readString(16));
|
||||
UUID id = wrapper.readOptional(PacketWrapper::readUUID);
|
||||
List<Property> properties = wrapper.readList(Property::read);
|
||||
return new ItemProfile(name, id, properties);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, ItemProfile profile) {
|
||||
wrapper.writeOptional(profile.name, (ew, name) -> ew.writeString(name, 16));
|
||||
wrapper.writeOptional(profile.id, PacketWrapper::writeUUID);
|
||||
wrapper.writeList(profile.properties, Property::write);
|
||||
}
|
||||
|
||||
public @Nullable String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setName(@Nullable String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public @Nullable UUID getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void setId(@Nullable UUID id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void addProperty(Property property) {
|
||||
this.properties.add(property);
|
||||
}
|
||||
|
||||
public List<Property> getProperties() {
|
||||
return this.properties;
|
||||
}
|
||||
|
||||
public void setProperties(List<Property> properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof ItemProfile)) return false;
|
||||
ItemProfile that = (ItemProfile) obj;
|
||||
if (!Objects.equals(this.name, that.name)) return false;
|
||||
if (!Objects.equals(this.id, that.id)) return false;
|
||||
return this.properties.equals(that.properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.name, this.id, this.properties);
|
||||
}
|
||||
|
||||
public static class Property {
|
||||
|
||||
private String name;
|
||||
private String value;
|
||||
private @Nullable String signature;
|
||||
|
||||
public Property(String name, String value, @Nullable String signature) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
this.signature = signature;
|
||||
}
|
||||
|
||||
public static Property read(PacketWrapper<?> wrapper) {
|
||||
String name = wrapper.readString(64);
|
||||
String value = wrapper.readString(32767);
|
||||
String signature = wrapper.readOptional(ew -> ew.readString(1024));
|
||||
return new Property(name, value, signature);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, Property property) {
|
||||
wrapper.writeString(property.name, 64);
|
||||
wrapper.writeString(property.value, 32767);
|
||||
wrapper.writeOptional(property.signature,
|
||||
(ew, signature) -> ew.writeString(signature, 1024));
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public @Nullable String getSignature() {
|
||||
return this.signature;
|
||||
}
|
||||
|
||||
public void setSignature(@Nullable String signature) {
|
||||
this.signature = signature;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof Property)) return false;
|
||||
Property property = (Property) obj;
|
||||
if (!this.name.equals(property.name)) return false;
|
||||
if (!this.value.equals(property.value)) return false;
|
||||
return Objects.equals(this.signature, property.signature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.name, this.value, this.signature);
|
||||
}
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
public enum ItemRarity {
|
||||
COMMON,
|
||||
UNCOMMON,
|
||||
RARE,
|
||||
EPIC,
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class ItemRecipes {
|
||||
|
||||
private List<ResourceLocation> recipes;
|
||||
|
||||
public ItemRecipes(List<ResourceLocation> recipes) {
|
||||
this.recipes = recipes;
|
||||
}
|
||||
|
||||
public static ItemRecipes read(PacketWrapper<?> wrapper) {
|
||||
List<ResourceLocation> recipes = wrapper.readList(PacketWrapper::readIdentifier);
|
||||
return new ItemRecipes(recipes);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, ItemRecipes recipes) {
|
||||
wrapper.writeList(recipes.recipes, PacketWrapper::writeIdentifier);
|
||||
}
|
||||
|
||||
public void addRecipe(ResourceLocation recipeKey) {
|
||||
this.recipes.add(recipeKey);
|
||||
}
|
||||
|
||||
public void removeRecipe(ResourceLocation recipeKey) {
|
||||
this.recipes.remove(recipeKey);
|
||||
}
|
||||
|
||||
public List<ResourceLocation> getRecipes() {
|
||||
return this.recipes;
|
||||
}
|
||||
|
||||
public void setRecipes(List<ResourceLocation> recipes) {
|
||||
this.recipes = recipes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof ItemRecipes)) return false;
|
||||
ItemRecipes that = (ItemRecipes) obj;
|
||||
return this.recipes.equals(that.recipes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(this.recipes);
|
||||
}
|
||||
}
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.mapper.MappedEntitySet;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class ItemTool {
|
||||
|
||||
private List<Rule> rules;
|
||||
private float defaultMiningSpeed;
|
||||
private int damagePerBlock;
|
||||
|
||||
public ItemTool(List<Rule> rules, float defaultMiningSpeed, int damagePerBlock) {
|
||||
this.rules = rules;
|
||||
this.defaultMiningSpeed = defaultMiningSpeed;
|
||||
this.damagePerBlock = damagePerBlock;
|
||||
}
|
||||
|
||||
public static ItemTool read(PacketWrapper<?> wrapper) {
|
||||
List<Rule> rules = wrapper.readList(Rule::read);
|
||||
float defaultMiningSpeed = wrapper.readFloat();
|
||||
int damagePerBlock = wrapper.readVarInt();
|
||||
return new ItemTool(rules, defaultMiningSpeed, damagePerBlock);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, ItemTool tool) {
|
||||
wrapper.writeList(tool.rules, Rule::write);
|
||||
wrapper.writeFloat(tool.defaultMiningSpeed);
|
||||
wrapper.writeVarInt(tool.damagePerBlock);
|
||||
}
|
||||
|
||||
public void addRule(Rule rule) {
|
||||
this.rules.add(rule);
|
||||
}
|
||||
|
||||
public List<Rule> getRules() {
|
||||
return this.rules;
|
||||
}
|
||||
|
||||
public void setRules(List<Rule> rules) {
|
||||
this.rules = rules;
|
||||
}
|
||||
|
||||
public float getDefaultMiningSpeed() {
|
||||
return this.defaultMiningSpeed;
|
||||
}
|
||||
|
||||
public void setDefaultMiningSpeed(float defaultMiningSpeed) {
|
||||
this.defaultMiningSpeed = defaultMiningSpeed;
|
||||
}
|
||||
|
||||
public int getDamagePerBlock() {
|
||||
return this.damagePerBlock;
|
||||
}
|
||||
|
||||
public void setDamagePerBlock(int damagePerBlock) {
|
||||
this.damagePerBlock = damagePerBlock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof ItemTool)) return false;
|
||||
ItemTool itemTool = (ItemTool) obj;
|
||||
if (Float.compare(itemTool.defaultMiningSpeed, this.defaultMiningSpeed) != 0) return false;
|
||||
if (this.damagePerBlock != itemTool.damagePerBlock) return false;
|
||||
return this.rules.equals(itemTool.rules);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.rules, this.defaultMiningSpeed, this.damagePerBlock);
|
||||
}
|
||||
|
||||
public static class Rule {
|
||||
|
||||
private MappedEntitySet<StateType.Mapped> blocks;
|
||||
private @Nullable Float speed;
|
||||
private @Nullable Boolean correctForDrops;
|
||||
|
||||
public Rule(
|
||||
MappedEntitySet<StateType.Mapped> blocks,
|
||||
@Nullable Float speed,
|
||||
@Nullable Boolean correctForDrops
|
||||
) {
|
||||
this.blocks = blocks;
|
||||
this.speed = speed;
|
||||
this.correctForDrops = correctForDrops;
|
||||
}
|
||||
|
||||
public static Rule read(PacketWrapper<?> wrapper) {
|
||||
MappedEntitySet<StateType.Mapped> blocks = MappedEntitySet.read(wrapper, StateTypes::getMappedById);
|
||||
Float speed = wrapper.readOptional(PacketWrapper::readFloat);
|
||||
Boolean correctForDrops = wrapper.readOptional(PacketWrapper::readBoolean);
|
||||
return new Rule(blocks, speed, correctForDrops);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, Rule rule) {
|
||||
MappedEntitySet.write(wrapper, rule.blocks);
|
||||
wrapper.writeOptional(rule.speed, PacketWrapper::writeFloat);
|
||||
wrapper.writeOptional(rule.correctForDrops, PacketWrapper::writeBoolean);
|
||||
}
|
||||
|
||||
public MappedEntitySet<StateType.Mapped> getBlocks() {
|
||||
return this.blocks;
|
||||
}
|
||||
|
||||
public void setBlocks(MappedEntitySet<StateType.Mapped> blocks) {
|
||||
this.blocks = blocks;
|
||||
}
|
||||
|
||||
public @Nullable Float getSpeed() {
|
||||
return this.speed;
|
||||
}
|
||||
|
||||
public void setSpeed(@Nullable Float speed) {
|
||||
this.speed = speed;
|
||||
}
|
||||
|
||||
public @Nullable Boolean getCorrectForDrops() {
|
||||
return this.correctForDrops;
|
||||
}
|
||||
|
||||
public void setCorrectForDrops(@Nullable Boolean correctForDrops) {
|
||||
this.correctForDrops = correctForDrops;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof Rule)) return false;
|
||||
Rule rule = (Rule) obj;
|
||||
if (!this.blocks.equals(rule.blocks)) return false;
|
||||
if (!Objects.equals(this.speed, rule.speed)) return false;
|
||||
return Objects.equals(this.correctForDrops, rule.correctForDrops);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.blocks, this.speed, this.correctForDrops);
|
||||
}
|
||||
}
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.world.WorldBlockPosition;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class LodestoneTracker {
|
||||
|
||||
private @Nullable WorldBlockPosition target;
|
||||
private boolean tracked;
|
||||
|
||||
public LodestoneTracker(@Nullable WorldBlockPosition target, boolean tracked) {
|
||||
this.target = target;
|
||||
this.tracked = tracked;
|
||||
}
|
||||
|
||||
public static LodestoneTracker read(PacketWrapper<?> wrapper) {
|
||||
WorldBlockPosition target = wrapper.readOptional(PacketWrapper::readWorldBlockPosition);
|
||||
boolean tracked = wrapper.readBoolean();
|
||||
return new LodestoneTracker(target, tracked);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, LodestoneTracker tracker) {
|
||||
wrapper.writeOptional(tracker.target, PacketWrapper::writeWorldBlockPosition);
|
||||
wrapper.writeBoolean(tracker.tracked);
|
||||
}
|
||||
|
||||
public @Nullable WorldBlockPosition getTarget() {
|
||||
return this.target;
|
||||
}
|
||||
|
||||
public void setTarget(@Nullable WorldBlockPosition target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public boolean isTracked() {
|
||||
return this.tracked;
|
||||
}
|
||||
|
||||
public void setTracked(boolean tracked) {
|
||||
this.tracked = tracked;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof LodestoneTracker)) return false;
|
||||
LodestoneTracker that = (LodestoneTracker) obj;
|
||||
if (this.tracked != that.tracked) return false;
|
||||
return Objects.equals(this.target, that.target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.target, this.tracked);
|
||||
}
|
||||
}
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.item.type.ItemType;
|
||||
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Queue;
|
||||
|
||||
public class PotDecorations {
|
||||
|
||||
private @Nullable ItemType back;
|
||||
private @Nullable ItemType left;
|
||||
private @Nullable ItemType right;
|
||||
private @Nullable ItemType front;
|
||||
|
||||
private PotDecorations(Queue<Optional<ItemType>> items) {
|
||||
this(
|
||||
items.isEmpty() ? null : items.remove().orElse(null),
|
||||
items.isEmpty() ? null : items.remove().orElse(null),
|
||||
items.isEmpty() ? null : items.remove().orElse(null),
|
||||
items.isEmpty() ? null : items.remove().orElse(null)
|
||||
);
|
||||
}
|
||||
|
||||
public PotDecorations(
|
||||
@Nullable ItemType back,
|
||||
@Nullable ItemType left,
|
||||
@Nullable ItemType right,
|
||||
@Nullable ItemType front
|
||||
) {
|
||||
this.back = back;
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
this.front = front;
|
||||
}
|
||||
|
||||
private List<Optional<ItemType>> asList() {
|
||||
return Arrays.asList(
|
||||
Optional.ofNullable(this.back),
|
||||
Optional.ofNullable(this.left),
|
||||
Optional.ofNullable(this.right),
|
||||
Optional.ofNullable(this.front)
|
||||
);
|
||||
}
|
||||
|
||||
private static Optional<ItemType> readItem(PacketWrapper<?> wrapper) {
|
||||
ItemType type = wrapper.readMappedEntity(ItemTypes::getById);
|
||||
return type == ItemTypes.BRICK ? Optional.empty() : Optional.of(type);
|
||||
}
|
||||
|
||||
public static PotDecorations read(PacketWrapper<?> wrapper) {
|
||||
Queue<Optional<ItemType>> items = wrapper.<Optional<ItemType>, Queue<Optional<ItemType>>>
|
||||
readCollection(ArrayDeque::new, PotDecorations::readItem);
|
||||
return new PotDecorations(items);
|
||||
}
|
||||
|
||||
private static void writeItem(PacketWrapper<?> wrapper, Optional<ItemType> type) {
|
||||
wrapper.writeMappedEntity(type.orElse(ItemTypes.BRICK));
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, PotDecorations decorations) {
|
||||
wrapper.writeList(decorations.asList(), PotDecorations::writeItem);
|
||||
}
|
||||
|
||||
public @Nullable ItemType getBack() {
|
||||
return this.back;
|
||||
}
|
||||
|
||||
public void setBack(@Nullable ItemType back) {
|
||||
this.back = back;
|
||||
}
|
||||
|
||||
public @Nullable ItemType getLeft() {
|
||||
return this.left;
|
||||
}
|
||||
|
||||
public void setLeft(@Nullable ItemType left) {
|
||||
this.left = left;
|
||||
}
|
||||
|
||||
public @Nullable ItemType getRight() {
|
||||
return this.right;
|
||||
}
|
||||
|
||||
public void setRight(@Nullable ItemType right) {
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
public @Nullable ItemType getFront() {
|
||||
return this.front;
|
||||
}
|
||||
|
||||
public void setFront(@Nullable ItemType front) {
|
||||
this.front = front;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof PotDecorations)) return false;
|
||||
PotDecorations that = (PotDecorations) obj;
|
||||
if (!Objects.equals(this.back, that.back)) return false;
|
||||
if (!Objects.equals(this.left, that.left)) return false;
|
||||
if (!Objects.equals(this.right, that.right)) return false;
|
||||
return Objects.equals(this.front, that.front);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.back, this.left, this.right, this.front);
|
||||
}
|
||||
}
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.potion.PotionType;
|
||||
import com.github.retrooper.packetevents.protocol.potion.PotionTypes;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class SuspiciousStewEffects {
|
||||
|
||||
private List<EffectEntry> effects;
|
||||
|
||||
public SuspiciousStewEffects(List<EffectEntry> effects) {
|
||||
this.effects = effects;
|
||||
}
|
||||
|
||||
public static SuspiciousStewEffects read(PacketWrapper<?> wrapper) {
|
||||
List<EffectEntry> effects = wrapper.readList(EffectEntry::read);
|
||||
return new SuspiciousStewEffects(effects);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, SuspiciousStewEffects effects) {
|
||||
wrapper.writeList(effects.effects, EffectEntry::write);
|
||||
}
|
||||
|
||||
public void addEffect(EffectEntry effect) {
|
||||
this.effects.add(effect);
|
||||
}
|
||||
|
||||
public List<EffectEntry> getEffects() {
|
||||
return this.effects;
|
||||
}
|
||||
|
||||
public void setEffects(List<EffectEntry> effects) {
|
||||
this.effects = effects;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof SuspiciousStewEffects)) return false;
|
||||
SuspiciousStewEffects that = (SuspiciousStewEffects) obj;
|
||||
return this.effects.equals(that.effects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(this.effects);
|
||||
}
|
||||
|
||||
public static class EffectEntry {
|
||||
|
||||
private PotionType type;
|
||||
private int duration;
|
||||
|
||||
public EffectEntry(PotionType type, int duration) {
|
||||
this.type = type;
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
public static EffectEntry read(PacketWrapper<?> wrapper) {
|
||||
PotionType type = wrapper.readMappedEntity(PotionTypes::getById);
|
||||
int duration = wrapper.readVarInt();
|
||||
return new EffectEntry(type, duration);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, EffectEntry effect) {
|
||||
wrapper.writeMappedEntity(effect.type);
|
||||
wrapper.writeVarInt(effect.duration);
|
||||
}
|
||||
|
||||
public PotionType getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public void setType(PotionType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public int getDuration() {
|
||||
return this.duration;
|
||||
}
|
||||
|
||||
public void setDuration(int duration) {
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof EffectEntry)) return false;
|
||||
EffectEntry that = (EffectEntry) obj;
|
||||
if (this.duration != that.duration) return false;
|
||||
return this.type.equals(that.type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.type, this.duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
import com.github.retrooper.packetevents.util.Filterable;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class WritableBookContent {
|
||||
|
||||
private List<Filterable<String>> pages;
|
||||
|
||||
public WritableBookContent(List<Filterable<String>> pages) {
|
||||
this.pages = pages;
|
||||
}
|
||||
|
||||
public static WritableBookContent read(PacketWrapper<?> wrapper) {
|
||||
List<Filterable<String>> pages = wrapper.readList(ew -> Filterable.read(
|
||||
ew, eew -> eew.readString(1024)));
|
||||
return new WritableBookContent(pages);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, WritableBookContent content) {
|
||||
wrapper.writeList(content.pages, (ew, page) -> Filterable.write(
|
||||
ew, page, (eew, text) -> eew.writeString(text, 1024)));
|
||||
}
|
||||
|
||||
public @Nullable Filterable<String> getPage(int index) {
|
||||
return index >= 0 && index < this.pages.size() ? this.pages.get(index) : null;
|
||||
}
|
||||
|
||||
public void addPage(Filterable<String> page) {
|
||||
this.pages.add(page);
|
||||
}
|
||||
|
||||
public List<Filterable<String>> getPages() {
|
||||
return this.pages;
|
||||
}
|
||||
|
||||
public void setPages(List<Filterable<String>> pages) {
|
||||
this.pages = pages;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof WritableBookContent)) return false;
|
||||
WritableBookContent that = (WritableBookContent) obj;
|
||||
return this.pages.equals(that.pages);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(this.pages);
|
||||
}
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.component.builtin.item;
|
||||
|
||||
import com.github.retrooper.packetevents.util.Filterable;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class WrittenBookContent {
|
||||
|
||||
private Filterable<String> title;
|
||||
private String author;
|
||||
private int generation;
|
||||
private List<Filterable<Component>> pages;
|
||||
private boolean resolved;
|
||||
|
||||
public WrittenBookContent(
|
||||
Filterable<String> title, String author, int generation,
|
||||
List<Filterable<Component>> pages, boolean resolved
|
||||
) {
|
||||
this.title = title;
|
||||
this.author = author;
|
||||
this.generation = generation;
|
||||
this.pages = pages;
|
||||
this.resolved = resolved;
|
||||
}
|
||||
|
||||
public static WrittenBookContent read(PacketWrapper<?> wrapper) {
|
||||
Filterable<String> title = Filterable.read(wrapper, ew -> ew.readString(32));
|
||||
String author = wrapper.readString();
|
||||
int generation = wrapper.readVarInt();
|
||||
List<Filterable<Component>> pages = wrapper.readList(ew -> Filterable.read(
|
||||
ew, PacketWrapper::readComponent));
|
||||
boolean resolved = wrapper.readBoolean();
|
||||
return new WrittenBookContent(title, author, generation, pages, resolved);
|
||||
}
|
||||
|
||||
public static void write(PacketWrapper<?> wrapper, WrittenBookContent content) {
|
||||
Filterable.write(wrapper, content.title, (ew, text) -> ew.writeString(text, 32));
|
||||
wrapper.writeString(content.author);
|
||||
wrapper.writeVarInt(content.generation);
|
||||
wrapper.writeList(content.pages, (ew, page) -> Filterable.write(
|
||||
ew, page, PacketWrapper::writeComponent));
|
||||
wrapper.writeBoolean(content.resolved);
|
||||
}
|
||||
|
||||
public Filterable<String> getTitle() {
|
||||
return this.title;
|
||||
}
|
||||
|
||||
public void setTitle(Filterable<String> title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getAuthor() {
|
||||
return this.author;
|
||||
}
|
||||
|
||||
public void setAuthor(String author) {
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
public int getGeneration() {
|
||||
return this.generation;
|
||||
}
|
||||
|
||||
public void setGeneration(int generation) {
|
||||
this.generation = generation;
|
||||
}
|
||||
|
||||
public @Nullable Filterable<Component> getPage(int index) {
|
||||
return index >= 0 && index < this.pages.size() ? this.pages.get(index) : null;
|
||||
}
|
||||
|
||||
public void addPage(Filterable<Component> page) {
|
||||
this.pages.add(page);
|
||||
}
|
||||
|
||||
public List<Filterable<Component>> getPages() {
|
||||
return this.pages;
|
||||
}
|
||||
|
||||
public void setPages(List<Filterable<Component>> pages) {
|
||||
this.pages = pages;
|
||||
}
|
||||
|
||||
public boolean isResolved() {
|
||||
return this.resolved;
|
||||
}
|
||||
|
||||
public void setResolved(boolean resolved) {
|
||||
this.resolved = resolved;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof WrittenBookContent)) return false;
|
||||
WrittenBookContent that = (WrittenBookContent) obj;
|
||||
if (this.generation != that.generation) return false;
|
||||
if (this.resolved != that.resolved) return false;
|
||||
if (!this.title.equals(that.title)) return false;
|
||||
if (!this.author.equals(that.author)) return false;
|
||||
return this.pages.equals(that.pages);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.title, this.author, this.generation, this.pages, this.resolved);
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2023 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.entity.armadillo;
|
||||
|
||||
public enum ArmadilloState {
|
||||
|
||||
IDLE,
|
||||
ROLLING,
|
||||
SCARED,
|
||||
UNROLLING,
|
||||
}
|
||||
+72
-39
@@ -20,25 +20,26 @@ package com.github.retrooper.packetevents.protocol.entity.data;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.entity.armadillo.ArmadilloState;
|
||||
import com.github.retrooper.packetevents.protocol.entity.pose.EntityPose;
|
||||
import com.github.retrooper.packetevents.protocol.entity.sniffer.SnifferState;
|
||||
import com.github.retrooper.packetevents.protocol.entity.villager.VillagerData;
|
||||
import com.github.retrooper.packetevents.protocol.item.ItemStack;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
|
||||
import com.github.retrooper.packetevents.protocol.particle.Particle;
|
||||
import com.github.retrooper.packetevents.protocol.particle.type.ParticleType;
|
||||
import com.github.retrooper.packetevents.protocol.particle.type.ParticleTypes;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.world.BlockFace;
|
||||
import com.github.retrooper.packetevents.protocol.world.WorldBlockPosition;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.*;
|
||||
import com.github.retrooper.packetevents.util.Quaternion4f;
|
||||
import com.github.retrooper.packetevents.util.Vector3f;
|
||||
import com.github.retrooper.packetevents.util.Vector3i;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilder;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
@@ -50,15 +51,7 @@ public class EntityDataTypes {
|
||||
|
||||
private static final Map<String, EntityDataType<?>> ENTITY_DATA_TYPE_MAP = new HashMap<>();
|
||||
private static final Map<Byte, Map<Integer, EntityDataType<?>>> ENTITY_DATA_TYPE_ID_MAP = new HashMap<>();
|
||||
protected static final TypesBuilder TYPES_BUILDER = new TypesBuilder("entity/entity_data_type_mappings",
|
||||
ClientVersion.V_1_8,
|
||||
ClientVersion.V_1_9,
|
||||
ClientVersion.V_1_11,
|
||||
ClientVersion.V_1_13,
|
||||
ClientVersion.V_1_14,
|
||||
ClientVersion.V_1_19,
|
||||
ClientVersion.V_1_19_3,
|
||||
ClientVersion.V_1_19_4);
|
||||
protected static final TypesBuilder TYPES_BUILDER = new TypesBuilder("entity/entity_data_type_mappings");
|
||||
|
||||
public static final EntityDataType<Byte> BYTE = define("byte", PacketWrapper::readByte, PacketWrapper::writeByte);
|
||||
|
||||
@@ -84,9 +77,13 @@ public class EntityDataTypes {
|
||||
|
||||
public static final EntityDataType<String> STRING = define("string", PacketWrapper::readString, PacketWrapper::writeString);
|
||||
|
||||
@Deprecated
|
||||
public static final EntityDataType<String> COMPONENT = define("component", PacketWrapper::readComponentJSON, PacketWrapper::writeComponentJSON);
|
||||
public static final EntityDataType<Component> ADV_COMPONENT = define("component", PacketWrapper::readComponent, PacketWrapper::writeComponent);
|
||||
|
||||
public static final EntityDataType<Optional<String>> OPTIONAL_COMPONENT = define("optional_component", readOptionalComponentDeserializer(), writeOptionalComponentSerializer());
|
||||
@Deprecated
|
||||
public static final EntityDataType<Optional<String>> OPTIONAL_COMPONENT = define("optional_component", readOptionalComponentJSONDeserializer(), writeOptionalComponentJSONSerializer());
|
||||
public static final EntityDataType<Optional<Component>> OPTIONAL_ADV_COMPONENT = define("optional_component", readOptionalComponentDeserializer(), writeOptionalComponentSerializer());
|
||||
|
||||
public static final EntityDataType<ItemStack> ITEMSTACK = define("itemstack", PacketWrapper::readItemStack, PacketWrapper::writeItemStack);
|
||||
|
||||
@@ -144,14 +141,7 @@ public class EntityDataTypes {
|
||||
|
||||
public static final EntityDataType<NBTCompound> NBT = define("nbt", PacketWrapper::readNBT, PacketWrapper::writeNBT);
|
||||
|
||||
public static final EntityDataType<Particle> PARTICLE = define("particle", wrapper -> {
|
||||
int id = wrapper.readVarInt();
|
||||
ParticleType type = ParticleTypes.getById(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion(), id);
|
||||
return new Particle(type, type.readDataFunction().apply(wrapper));
|
||||
}, (wrapper, particle) -> {
|
||||
wrapper.writeVarInt(particle.getType().getId(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion()));
|
||||
particle.getType().writeDataFunction().accept(wrapper, particle.getData());
|
||||
});
|
||||
public static final EntityDataType<Particle<?>> PARTICLE = define("particle", Particle::read, Particle::write);
|
||||
|
||||
public static final EntityDataType<VillagerData> VILLAGER_DATA = define("villager_data", PacketWrapper::readVillagerData, PacketWrapper::writeVillagerData);
|
||||
|
||||
@@ -185,7 +175,6 @@ public class EntityDataTypes {
|
||||
return SnifferState.values()[id];
|
||||
}, (PacketWrapper<?> wrapper, SnifferState value) -> wrapper.writeVarInt(value.ordinal()));
|
||||
|
||||
|
||||
public static final EntityDataType<Vector3f> VECTOR3F = define("vector3f",
|
||||
(PacketWrapper<?> wrapper) -> new Vector3f(wrapper.readFloat(), wrapper.readFloat(), wrapper.readFloat()),
|
||||
(PacketWrapper<?> wrapper, Vector3f value) -> {
|
||||
@@ -203,6 +192,28 @@ public class EntityDataTypes {
|
||||
wrapper.writeFloat(value.getW());
|
||||
});
|
||||
|
||||
// Added in 1.20.5
|
||||
public static final EntityDataType<ArmadilloState> ARMADILLO_STATE = define("armadillo_state",
|
||||
(PacketWrapper<?> wrapper) -> ArmadilloState.values()[wrapper.readVarInt()],
|
||||
(PacketWrapper<?> wrapper, ArmadilloState value) -> wrapper.writeVarInt(value.ordinal())
|
||||
);
|
||||
|
||||
public static final EntityDataType<List<Particle<?>>> PARTICLES = define("particles",
|
||||
wrapper -> wrapper.readList(Particle::read),
|
||||
(wrapper, particles) -> wrapper.writeList(particles, Particle::write)
|
||||
);
|
||||
|
||||
public static final EntityDataType<Integer> WOLF_VARIANT =
|
||||
define("wolf_variant_type", readIntDeserializer(), writeIntSerializer());
|
||||
|
||||
/**
|
||||
* Returns an immutable view of the entity-data types.
|
||||
* @return Entity-Data Types
|
||||
*/
|
||||
public static Collection<EntityDataType<?>> values() {
|
||||
return Collections.unmodifiableCollection(ENTITY_DATA_TYPE_MAP.values());
|
||||
}
|
||||
|
||||
public static EntityDataType<?> getById(ClientVersion version, int id) {
|
||||
int index = TYPES_BUILDER.getDataIndex(version);
|
||||
Map<Integer, EntityDataType<?>> typeIdMap = ENTITY_DATA_TYPE_ID_MAP.get((byte) index);
|
||||
@@ -256,26 +267,44 @@ public class EntityDataTypes {
|
||||
};
|
||||
}
|
||||
|
||||
private static <T> Function<PacketWrapper<?>, T> readOptionalComponentDeserializer() {
|
||||
@Deprecated
|
||||
private static Function<PacketWrapper<?>, Optional<String>> readOptionalComponentJSONDeserializer() {
|
||||
return (PacketWrapper<?> wrapper) -> {
|
||||
if (wrapper.readBoolean()) {
|
||||
return (T) Optional.of(wrapper.readString());
|
||||
return Optional.of(wrapper.readComponentJSON());
|
||||
} else {
|
||||
return (T) Optional.empty();
|
||||
return Optional.empty();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static <T> BiConsumer<PacketWrapper<?>, T> writeOptionalComponentSerializer() {
|
||||
return (PacketWrapper<?> wrapper, T value) -> {
|
||||
if (value instanceof Optional) {
|
||||
Optional<String> optional = (Optional<String>) value;
|
||||
if (optional.isPresent()) {
|
||||
wrapper.writeBoolean(true);
|
||||
wrapper.writeString(optional.get());
|
||||
} else {
|
||||
wrapper.writeBoolean(false);
|
||||
}
|
||||
@Deprecated
|
||||
private static BiConsumer<PacketWrapper<?>, Optional<String>> writeOptionalComponentJSONSerializer() {
|
||||
return (PacketWrapper<?> wrapper, Optional<String> value) -> {
|
||||
if (value != null && value.isPresent()) {
|
||||
wrapper.writeBoolean(true);
|
||||
wrapper.writeComponentJSON(value.get());
|
||||
} else {
|
||||
wrapper.writeBoolean(false);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static Function<PacketWrapper<?>, Optional<Component>> readOptionalComponentDeserializer() {
|
||||
return (PacketWrapper<?> wrapper) -> {
|
||||
if (wrapper.readBoolean()) {
|
||||
return Optional.of(wrapper.readComponent());
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static BiConsumer<PacketWrapper<?>, Optional<Component>> writeOptionalComponentSerializer() {
|
||||
return (PacketWrapper<?> wrapper, Optional<Component> value) -> {
|
||||
if (value != null && value.isPresent()) {
|
||||
wrapper.writeBoolean(true);
|
||||
wrapper.writeComponent(value.get());
|
||||
} else {
|
||||
wrapper.writeBoolean(false);
|
||||
}
|
||||
@@ -340,4 +369,8 @@ public class EntityDataTypes {
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
TYPES_BUILDER.unloadFileMappings();
|
||||
}
|
||||
|
||||
}
|
||||
+29
-1
@@ -1,7 +1,35 @@
|
||||
package com.github.retrooper.packetevents.protocol.entity.data;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This is an interface that provides a list of entity data.
|
||||
* This allows custom addon libraries to implement metadata classes for various entities
|
||||
* which can then be used in our API.
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public interface EntityMetadataProvider {
|
||||
List<EntityData> entityData();
|
||||
/**
|
||||
* PacketEvents is retrieving the metadata of this specific entity.
|
||||
* PacketEvents provides you with the protocol version that the library is running on
|
||||
* to allow you tu specify different metadata depending on the version.
|
||||
* You are free to ignore it at the cost of your features not working on all versions.
|
||||
* @param version The protocol version of the format we expect the metadata to be in.
|
||||
* @return Metadata (list of entity data)
|
||||
*/
|
||||
List<EntityData> entityData(ClientVersion version);
|
||||
|
||||
/**
|
||||
* Similar to {@link #entityData(ClientVersion)} but does not provide a protocol version.
|
||||
* It is not advised to use nor implement this.
|
||||
* It is deprecated because it restricts you by not providing you the format in which the metadata should be.
|
||||
* @return Metadata (list of entity data)
|
||||
* @deprecated Does not specify format of metadata, therefore not advised to use this. It will assume the current latest version.
|
||||
*/
|
||||
@Deprecated
|
||||
default List<EntityData> entityData() {
|
||||
return entityData(ClientVersion.getLatest());
|
||||
}
|
||||
}
|
||||
+5
-1
@@ -35,7 +35,11 @@ public enum EntityPose {
|
||||
ROARING,
|
||||
SNIFFING,
|
||||
EMERGING,
|
||||
DIGGING;
|
||||
DIGGING,
|
||||
//Added in 1.20.4
|
||||
SLIDING,
|
||||
SHOOTING,
|
||||
INHALING;
|
||||
|
||||
public int getId(ClientVersion version) {
|
||||
if (this == DYING && version.isOlderThan(ClientVersion.V_1_17)) {
|
||||
|
||||
+31
-32
@@ -20,45 +20,19 @@ package com.github.retrooper.packetevents.protocol.entity.type;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.TypesBuilder;
|
||||
import com.github.retrooper.packetevents.util.TypesBuilderData;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilder;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.*;
|
||||
|
||||
public class EntityTypes {
|
||||
private static final Map<String, EntityType> ENTITY_TYPE_MAP = new HashMap<>();
|
||||
//Key - mappings version, value - map with entity type ids and entity types
|
||||
private static final Map<Byte, Map<Integer, EntityType>> ENTITY_TYPE_ID_MAP = new HashMap<>();
|
||||
private static final Map<Byte, Map<Integer, EntityType>> LEGACY_ENTITY_TYPE_ID_MAP = new HashMap<>();
|
||||
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("entity/entity_type_mappings",
|
||||
ClientVersion.V_1_10,
|
||||
ClientVersion.V_1_11,
|
||||
ClientVersion.V_1_12,
|
||||
ClientVersion.V_1_13,
|
||||
ClientVersion.V_1_14,
|
||||
ClientVersion.V_1_15,
|
||||
ClientVersion.V_1_16,
|
||||
ClientVersion.V_1_16_2,
|
||||
ClientVersion.V_1_17,
|
||||
ClientVersion.V_1_19,
|
||||
ClientVersion.V_1_19_3,
|
||||
ClientVersion.V_1_19_4);
|
||||
private static final TypesBuilder LEGACY_TYPES_BUILDER = new TypesBuilder("entity/legacy_entity_type_mappings",
|
||||
ClientVersion.V_1_8,
|
||||
ClientVersion.V_1_9,
|
||||
ClientVersion.V_1_10,
|
||||
ClientVersion.V_1_11,
|
||||
ClientVersion.V_1_12,
|
||||
ClientVersion.V_1_13);
|
||||
|
||||
|
||||
static {
|
||||
TYPES_BUILDER.unloadFileMappings();
|
||||
LEGACY_TYPES_BUILDER.unloadFileMappings();
|
||||
}
|
||||
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("entity/entity_type_mappings");
|
||||
private static final TypesBuilder LEGACY_TYPES_BUILDER = new TypesBuilder("entity/legacy_entity_type_mappings");
|
||||
|
||||
public static EntityType define(String key, @Nullable EntityType parent) {
|
||||
TypesBuilderData data = TYPES_BUILDER.define(key);
|
||||
@@ -301,11 +275,36 @@ public class EntityTypes {
|
||||
public static final EntityType MINECART_TNT = define("minecart_tnt", MINECART_ABSTRACT);
|
||||
public static final EntityType MINECART_HOPPER = define("minecart_hopper", MINECART_ABSTRACT);
|
||||
public static final EntityType MINECART_MOB_SPAWNER = define("minecart_mob_spawner", MINECART_ABSTRACT);
|
||||
// Display type entities added in 1.19.4
|
||||
|
||||
// Added in 1.19.4
|
||||
public static final EntityType DISPLAY = define("display", ENTITY);
|
||||
public static final EntityType BLOCK_DISPLAY = define("block_display", DISPLAY);
|
||||
public static final EntityType ITEM_DISPLAY = define("item_display", DISPLAY);
|
||||
public static final EntityType TEXT_DISPLAY = define("text_display", DISPLAY);
|
||||
public static final EntityType INTERACTION = define("interaction", DISPLAY);
|
||||
public static final EntityType SNIFFER = define("sniffer", ABSTRACT_ANIMAL);
|
||||
|
||||
// Added in 1.20.3
|
||||
public static final EntityType BREEZE = define("breeze", ABSTRACT_MONSTER);
|
||||
public static final EntityType ABSTRACT_WIND_CHARGE = define("abstract_wind_charge", PROJECTILE_ABSTRACT);
|
||||
public static final EntityType WIND_CHARGE = define("wind_charge", ABSTRACT_WIND_CHARGE);
|
||||
|
||||
// Added in 1.20.5
|
||||
public static final EntityType ARMADILLO = define("armadillo", ABSTRACT_ANIMAL);
|
||||
public static final EntityType BOGGED = define("bogged", ABSTRACT_SKELETON);
|
||||
public static final EntityType BREEZE_WIND_CHARGE = define("breeze_wind_charge", ABSTRACT_WIND_CHARGE);
|
||||
public static final EntityType OMINOUS_ITEM_SPAWNER = define("ominous_item_spawner", ENTITY);
|
||||
|
||||
/**
|
||||
* Returns an immutable view of the entity types.
|
||||
* @return Entity Types
|
||||
*/
|
||||
public static Collection<EntityType> values() {
|
||||
return Collections.unmodifiableCollection(ENTITY_TYPE_MAP.values());
|
||||
}
|
||||
|
||||
static {
|
||||
TYPES_BUILDER.unloadFileMappings();
|
||||
LEGACY_TYPES_BUILDER.unloadFileMappings();
|
||||
}
|
||||
}
|
||||
+16
-1
@@ -18,16 +18,23 @@
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.entity.villager;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.entity.villager.level.VillagerLevel;
|
||||
import com.github.retrooper.packetevents.protocol.entity.villager.profession.VillagerProfession;
|
||||
import com.github.retrooper.packetevents.protocol.entity.villager.profession.VillagerProfessions;
|
||||
import com.github.retrooper.packetevents.protocol.entity.villager.type.VillagerType;
|
||||
import com.github.retrooper.packetevents.protocol.entity.villager.type.VillagerTypes;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class VillagerData {
|
||||
|
||||
private VillagerType type;
|
||||
private VillagerProfession profession;
|
||||
private int level;
|
||||
|
||||
public VillagerData(VillagerType type, VillagerProfession profession, VillagerLevel level) {
|
||||
this(type, profession, level.getId());
|
||||
}
|
||||
|
||||
public VillagerData(VillagerType type, VillagerProfession profession, int level) {
|
||||
this.type = type;
|
||||
this.profession = profession;
|
||||
@@ -55,10 +62,18 @@ public class VillagerData {
|
||||
}
|
||||
|
||||
public int getLevel() {
|
||||
return level;
|
||||
return this.level;
|
||||
}
|
||||
|
||||
public @Nullable VillagerLevel getVillagerLevel() {
|
||||
return VillagerLevel.getById(this.level);
|
||||
}
|
||||
|
||||
public void setLevel(int level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public void setLevel(VillagerLevel level) {
|
||||
this.level = level.getId();
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.entity.villager.level;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public enum VillagerLevel {
|
||||
|
||||
NOVICE,
|
||||
APPRENTICE,
|
||||
JOURNEYMAN,
|
||||
EXPERT,
|
||||
MASTER;
|
||||
|
||||
private static final VillagerLevel[] VALUES = values();
|
||||
|
||||
public static @Nullable VillagerLevel getById(int id) {
|
||||
if (id >= 1 && id <= VALUES.length) {
|
||||
return VALUES[id - 1];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return this.ordinal() + 1;
|
||||
}
|
||||
}
|
||||
|
||||
-2
@@ -19,7 +19,6 @@
|
||||
package com.github.retrooper.packetevents.protocol.entity.villager.profession;
|
||||
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.TypesBuilder;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -50,7 +49,6 @@ public class VillagerProfessions {
|
||||
return VILLAGER_PROFESSION_ID_MAP.get((byte)id);
|
||||
}
|
||||
|
||||
|
||||
public static VillagerProfession getByName(String name) {
|
||||
return VILLAGER_PROFESSION_MAP.get(name);
|
||||
}
|
||||
|
||||
+10
@@ -20,6 +20,8 @@ package com.github.retrooper.packetevents.protocol.entity.villager.type;
|
||||
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -62,4 +64,12 @@ public class VillagerTypes {
|
||||
public static final VillagerType SNOW = define(4, "minecraft:snow");
|
||||
public static final VillagerType SWAMP = define(5, "minecraft:swamp");
|
||||
public static final VillagerType TAIGA = define(6, "minecraft:taiga");
|
||||
|
||||
/**
|
||||
* Returns an immutable view of the villager types.
|
||||
* @return Villager Types
|
||||
*/
|
||||
public static Collection<VillagerType> values() {
|
||||
return Collections.unmodifiableCollection(VILLAGER_TYPE_MAP.values());
|
||||
}
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.entity.wolfvariant;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
|
||||
import com.github.retrooper.packetevents.protocol.mapper.MappedEntitySet;
|
||||
import com.github.retrooper.packetevents.protocol.world.biome.Biome;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class StaticWolfVariant extends AbstractMappedEntity implements WolfVariant {
|
||||
|
||||
private final ResourceLocation wildTexture;
|
||||
private final ResourceLocation tameTexture;
|
||||
private final ResourceLocation angryTexture;
|
||||
private final MappedEntitySet<Biome> biomes;
|
||||
|
||||
public StaticWolfVariant(
|
||||
ResourceLocation wildTexture,
|
||||
ResourceLocation tameTexture,
|
||||
ResourceLocation angryTexture,
|
||||
MappedEntitySet<Biome> biomes
|
||||
) {
|
||||
this(null, wildTexture, tameTexture, angryTexture, biomes);
|
||||
}
|
||||
|
||||
public StaticWolfVariant(
|
||||
@Nullable TypesBuilderData data,
|
||||
ResourceLocation wildTexture,
|
||||
ResourceLocation tameTexture,
|
||||
ResourceLocation angryTexture,
|
||||
MappedEntitySet<Biome> biomes
|
||||
) {
|
||||
super(data);
|
||||
this.wildTexture = wildTexture;
|
||||
this.tameTexture = tameTexture;
|
||||
this.angryTexture = angryTexture;
|
||||
this.biomes = biomes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WolfVariant copy(@Nullable TypesBuilderData newData) {
|
||||
return new StaticWolfVariant(newData, this.wildTexture, this.tameTexture, this.angryTexture, this.biomes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getWildTexture() {
|
||||
return this.wildTexture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getTameTexture() {
|
||||
return this.tameTexture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getAngryTexture() {
|
||||
return this.angryTexture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MappedEntitySet<Biome> getBiomes() {
|
||||
return this.biomes;
|
||||
}
|
||||
|
||||
public boolean deepEquals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof StaticWolfVariant)) return false;
|
||||
if (!super.equals(obj)) return false;
|
||||
StaticWolfVariant that = (StaticWolfVariant) obj;
|
||||
if (!this.wildTexture.equals(that.wildTexture)) return false;
|
||||
if (!this.tameTexture.equals(that.tameTexture)) return false;
|
||||
if (!this.angryTexture.equals(that.angryTexture)) return false;
|
||||
return this.biomes.equals(that.biomes);
|
||||
}
|
||||
|
||||
public int deepHashCode() {
|
||||
return Objects.hash(super.hashCode(), this.wildTexture, this.tameTexture, this.angryTexture, this.biomes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "StaticWolfVariant{wildTexture=" + this.wildTexture + ", tameTexture=" + this.tameTexture + ", angryTexture=" + this.angryTexture + ", biomes=" + this.biomes + '}';
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.entity.wolfvariant;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.mapper.CopyableEntity;
|
||||
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
|
||||
import com.github.retrooper.packetevents.protocol.mapper.MappedEntitySet;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBT;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.world.biome.Biome;
|
||||
import com.github.retrooper.packetevents.protocol.world.biome.Biomes;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface WolfVariant extends MappedEntity, CopyableEntity<WolfVariant> {
|
||||
|
||||
ResourceLocation getWildTexture();
|
||||
|
||||
ResourceLocation getTameTexture();
|
||||
|
||||
ResourceLocation getAngryTexture();
|
||||
|
||||
MappedEntitySet<Biome> getBiomes();
|
||||
|
||||
static WolfVariant decode(NBT nbt, ClientVersion version, @Nullable TypesBuilderData data) {
|
||||
NBTCompound compound = (NBTCompound) nbt;
|
||||
ResourceLocation wildTexture = new ResourceLocation(compound.getStringTagValueOrThrow("wild_texture"));
|
||||
ResourceLocation tameTexture = new ResourceLocation(compound.getStringTagValueOrThrow("tame_texture"));
|
||||
ResourceLocation angryTexture = new ResourceLocation(compound.getStringTagValueOrThrow("angry_texture"));
|
||||
MappedEntitySet<Biome> biomes = MappedEntitySet.decode(
|
||||
compound.getTagOrThrow("biomes"), version, Biomes.getRegistry());
|
||||
return new StaticWolfVariant(data, wildTexture, tameTexture, angryTexture, biomes);
|
||||
}
|
||||
|
||||
static NBT encode(WolfVariant variant, ClientVersion version) {
|
||||
NBTCompound compound = new NBTCompound();
|
||||
compound.setTag("wild_texture", new NBTString(variant.getWildTexture().toString()));
|
||||
compound.setTag("tame_texture", new NBTString(variant.getTameTexture().toString()));
|
||||
compound.setTag("angry_texture", new NBTString(variant.getAngryTexture().toString()));
|
||||
compound.setTag("biomes", MappedEntitySet.encode(variant.getBiomes(), version));
|
||||
return compound;
|
||||
}
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.entity.wolfvariant;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.mapper.MappedEntitySet;
|
||||
import com.github.retrooper.packetevents.protocol.world.biome.Biome;
|
||||
import com.github.retrooper.packetevents.protocol.world.biome.Biomes;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public final class WolfVariants {
|
||||
|
||||
private static final VersionedRegistry<WolfVariant> REGISTRY = new VersionedRegistry<>(
|
||||
"wolf_variant", "entity/wolf_variant_mappings");
|
||||
|
||||
private WolfVariants() {
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static WolfVariant define(String key, MappedEntitySet<Biome> biomes) {
|
||||
return define(key, "wolf_" + key, biomes);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static WolfVariant define(String key, String assetId, MappedEntitySet<Biome> biomes) {
|
||||
return define(key, ResourceLocation.minecraft("entity/wolf/" + assetId),
|
||||
ResourceLocation.minecraft("entity/wolf/" + assetId + "_tame"),
|
||||
ResourceLocation.minecraft("entity/wolf/" + assetId + "_angry"), biomes);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static WolfVariant define(
|
||||
String key,
|
||||
ResourceLocation wildTexture,
|
||||
ResourceLocation tameTexture,
|
||||
ResourceLocation angryTexture,
|
||||
MappedEntitySet<Biome> biomes
|
||||
) {
|
||||
return REGISTRY.define(key, data -> new StaticWolfVariant(
|
||||
data, wildTexture, tameTexture, angryTexture, biomes));
|
||||
}
|
||||
|
||||
public static VersionedRegistry<WolfVariant> getRegistry() {
|
||||
return REGISTRY;
|
||||
}
|
||||
|
||||
public static final WolfVariant PALE = define("pale", "wolf",
|
||||
new MappedEntitySet<>(Arrays.asList(Biomes.TAIGA)));
|
||||
public static final WolfVariant SPOTTED = define("spotted",
|
||||
new MappedEntitySet<>(ResourceLocation.minecraft("is_savanna")));
|
||||
public static final WolfVariant SNOWY = define("snowy",
|
||||
new MappedEntitySet<>(Arrays.asList(Biomes.GROVE)));
|
||||
public static final WolfVariant BLACK = define("black",
|
||||
new MappedEntitySet<>(Arrays.asList(Biomes.OLD_GROWTH_PINE_TAIGA)));
|
||||
public static final WolfVariant ASHEN = define("ashen",
|
||||
new MappedEntitySet<>(Arrays.asList(Biomes.SNOWY_TAIGA)));
|
||||
public static final WolfVariant RUSTY = define("rusty",
|
||||
new MappedEntitySet<>(ResourceLocation.minecraft("is_jungle")));
|
||||
public static final WolfVariant WOODS = define("woods",
|
||||
new MappedEntitySet<>(Arrays.asList(Biomes.FOREST)));
|
||||
public static final WolfVariant CHESTNUT = define("chestnut",
|
||||
new MappedEntitySet<>(Arrays.asList(Biomes.OLD_GROWTH_SPRUCE_TAIGA)));
|
||||
public static final WolfVariant STRIPED = define("striped",
|
||||
new MappedEntitySet<>(ResourceLocation.minecraft("is_badlands")));
|
||||
|
||||
static {
|
||||
REGISTRY.unloadMappings();
|
||||
}
|
||||
}
|
||||
@@ -18,18 +18,40 @@
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.item;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.component.ComponentType;
|
||||
import com.github.retrooper.packetevents.protocol.component.ComponentTypes;
|
||||
import com.github.retrooper.packetevents.protocol.component.PatchableComponentMap;
|
||||
import com.github.retrooper.packetevents.protocol.component.StaticComponentMap;
|
||||
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemEnchantments;
|
||||
import com.github.retrooper.packetevents.protocol.item.enchantment.Enchantment;
|
||||
import com.github.retrooper.packetevents.protocol.item.enchantment.type.EnchantmentType;
|
||||
import com.github.retrooper.packetevents.protocol.item.enchantment.type.EnchantmentTypes;
|
||||
import com.github.retrooper.packetevents.protocol.item.type.ItemType;
|
||||
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.*;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBT;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTInt;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTList;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTNumber;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTShort;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import static com.github.retrooper.packetevents.protocol.component.ComponentTypes.DAMAGE;
|
||||
import static com.github.retrooper.packetevents.protocol.component.ComponentTypes.ENCHANTMENTS;
|
||||
import static com.github.retrooper.packetevents.protocol.component.ComponentTypes.MAX_DAMAGE;
|
||||
import static com.github.retrooper.packetevents.protocol.component.ComponentTypes.MAX_STACK_SIZE;
|
||||
import static com.github.retrooper.packetevents.protocol.component.ComponentTypes.STORED_ENCHANTMENTS;
|
||||
|
||||
public class ItemStack {
|
||||
public static final ItemStack EMPTY = new ItemStack(ItemTypes.AIR, 0, new NBTCompound(), 0);
|
||||
@@ -37,20 +59,83 @@ public class ItemStack {
|
||||
private int amount;
|
||||
@Nullable
|
||||
private NBTCompound nbt;
|
||||
@Nullable // lazy loaded
|
||||
private PatchableComponentMap components; // Added in 1.20.5
|
||||
private int legacyData = -1;
|
||||
|
||||
private boolean cachedIsEmpty = false;
|
||||
|
||||
private ItemStack(ItemType type, int amount, @Nullable NBTCompound nbt, int legacyData) {
|
||||
this(type, amount, nbt, null, legacyData);
|
||||
}
|
||||
|
||||
private ItemStack(
|
||||
ItemType type,
|
||||
int amount,
|
||||
@Nullable NBTCompound nbt,
|
||||
@Nullable PatchableComponentMap components,
|
||||
int legacyData
|
||||
) {
|
||||
this.type = type;
|
||||
this.amount = amount;
|
||||
this.nbt = nbt;
|
||||
this.components = components;
|
||||
this.legacyData = legacyData;
|
||||
updateCachedEmptyStatus();
|
||||
}
|
||||
|
||||
public static ItemStack decode(NBT nbt, ClientVersion version) {
|
||||
if (nbt instanceof NBTString) {
|
||||
ResourceLocation itemName = new ResourceLocation(((NBTString) nbt).getValue());
|
||||
return ItemStack.builder().type(ItemTypes.getByName(itemName.toString())).build();
|
||||
}
|
||||
NBTCompound compound = (NBTCompound) nbt;
|
||||
ItemStack.Builder builder = ItemStack.builder();
|
||||
|
||||
ResourceLocation itemName = Optional.ofNullable(compound.getStringTagValueOrNull("id")).map(Optional::of)
|
||||
.orElseGet(() -> Optional.ofNullable(compound.getStringTagValueOrNull("item")))
|
||||
.map(ResourceLocation::new).orElseThrow(() -> new IllegalArgumentException(
|
||||
"No item type specified: " + compound.getTags().keySet()));
|
||||
builder.type(ItemTypes.getByName(itemName.toString()));
|
||||
builder.nbt(compound.getCompoundTagOrNull("tag"));
|
||||
|
||||
Optional.ofNullable(compound.getNumberTagOrNull("Count")).map(Optional::of)
|
||||
.orElseGet(() -> Optional.ofNullable(compound.getNumberTagOrNull("count")))
|
||||
.map(NBTNumber::getAsInt).ifPresent(builder::amount);
|
||||
|
||||
// TODO components
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public static NBT encodeForParticle(ItemStack itemStack, ClientVersion version) {
|
||||
if (version.isNewerThanOrEquals(ClientVersion.V_1_20_5)) {
|
||||
boolean simple = itemStack.isEmpty()
|
||||
|| itemStack.components == null
|
||||
|| itemStack.components.getPatches().isEmpty();
|
||||
if (simple) {
|
||||
return new NBTString(itemStack.type.getName().toString());
|
||||
}
|
||||
}
|
||||
|
||||
NBTCompound compound = new NBTCompound();
|
||||
compound.setTag("id", new NBTString(itemStack.type.getName().toString()));
|
||||
if (version.isOlderThan(ClientVersion.V_1_20_5)) {
|
||||
compound.setTag("Count", new NBTInt(itemStack.amount));
|
||||
if (itemStack.nbt != null) {
|
||||
compound.setTag("tag", itemStack.nbt);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO components
|
||||
|
||||
return compound;
|
||||
}
|
||||
|
||||
public int getMaxStackSize() {
|
||||
return getType().getMaxAmount();
|
||||
return this.getComponentOr(MAX_STACK_SIZE,
|
||||
// fallback to legacy specified max stack size
|
||||
this.getType().getMaxAmount());
|
||||
}
|
||||
|
||||
public boolean isStackable() {
|
||||
@@ -58,11 +143,9 @@ public class ItemStack {
|
||||
}
|
||||
|
||||
public boolean isDamageableItem() {
|
||||
if (!this.cachedIsEmpty && this.getType().getMaxDurability() > 0) {
|
||||
NBTCompound tag = this.getNBT();
|
||||
return tag == null || !tag.getBoolean("Unbreakable");
|
||||
}
|
||||
return false;
|
||||
return !this.cachedIsEmpty && this.getMaxDamage() > 0
|
||||
&& (this.nbt == null || !this.nbt.getBoolean("Unbreakable"))
|
||||
&& !this.getComponentOr(ComponentTypes.UNBREAKABLE, false);
|
||||
}
|
||||
|
||||
public boolean isDamaged() {
|
||||
@@ -70,17 +153,27 @@ public class ItemStack {
|
||||
}
|
||||
|
||||
public int getDamageValue() {
|
||||
if (nbt == null) return 0;
|
||||
NBTInt damage = this.nbt.getTagOfTypeOrNull("Damage", NBTInt.class);
|
||||
return damage == null ? 0 : damage.getAsInt();
|
||||
if (this.nbt != null) {
|
||||
NBTInt damage = this.nbt.getTagOfTypeOrNull("Damage", NBTInt.class);
|
||||
if (damage != null) {
|
||||
return damage.getAsInt();
|
||||
}
|
||||
}
|
||||
return this.getComponentOr(DAMAGE, 0);
|
||||
}
|
||||
|
||||
public void setDamageValue(int damage) {
|
||||
this.getOrCreateTag().setTag("Damage", new NBTInt(Math.max(0, damage)));
|
||||
int cappedDamage = Math.max(0, damage);
|
||||
// set in legacy nbt
|
||||
this.getOrCreateTag().setTag("Damage", new NBTInt(cappedDamage));
|
||||
// set in components
|
||||
this.setComponent(DAMAGE, cappedDamage);
|
||||
}
|
||||
|
||||
public int getMaxDamage() {
|
||||
return this.getType().getMaxDurability();
|
||||
return this.getComponentOr(MAX_DAMAGE,
|
||||
// fallback to legacy specified max durability
|
||||
this.getType().getMaxDurability());
|
||||
}
|
||||
|
||||
public NBTCompound getOrCreateTag() {
|
||||
@@ -125,7 +218,12 @@ public class ItemStack {
|
||||
}
|
||||
|
||||
public ItemStack copy() {
|
||||
return cachedIsEmpty ? EMPTY : new ItemStack(type, amount, nbt == null ? null : nbt.copy(), legacyData);
|
||||
return cachedIsEmpty ? EMPTY : new ItemStack(
|
||||
type, amount,
|
||||
nbt == null ? null : nbt.copy(),
|
||||
components == null ? null : components.copy(),
|
||||
legacyData
|
||||
);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -137,6 +235,58 @@ public class ItemStack {
|
||||
this.nbt = nbt;
|
||||
}
|
||||
|
||||
public <T> T getComponentOr(ComponentType<T> type, T otherValue) {
|
||||
if (this.hasComponentPatches()) {
|
||||
return this.getComponents().getOr(type, otherValue);
|
||||
}
|
||||
return this.getType().getComponents().getOr(type, otherValue);
|
||||
}
|
||||
|
||||
public <T> Optional<T> getComponent(ComponentType<T> type) {
|
||||
if (this.hasComponentPatches()) {
|
||||
return this.getComponents().getOptional(type);
|
||||
}
|
||||
return this.getType().getComponents().getOptional(type);
|
||||
}
|
||||
|
||||
public <T> void setComponent(ComponentType<T> type, T value) {
|
||||
this.getComponents().set(type, value);
|
||||
}
|
||||
|
||||
public <T> void unsetComponent(ComponentType<T> type) {
|
||||
this.getComponents().unset(type);
|
||||
}
|
||||
|
||||
public <T> void setComponent(ComponentType<T> type, Optional<T> value) {
|
||||
this.getComponents().set(type, value);
|
||||
}
|
||||
|
||||
public boolean hasComponent(ComponentType<?> type) {
|
||||
if (this.hasComponentPatches()) {
|
||||
return this.getComponents().has(type);
|
||||
}
|
||||
return this.getType().getComponents().has(type);
|
||||
}
|
||||
|
||||
public boolean hasComponentPatches() {
|
||||
return this.components != null && !this.components.getPatches().isEmpty();
|
||||
}
|
||||
|
||||
public PatchableComponentMap getComponents() {
|
||||
if (this.components == null) { // lazy load on access
|
||||
this.components = new PatchableComponentMap(
|
||||
this.type.getComponents(), new HashMap<>(4));
|
||||
}
|
||||
return this.components;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param components if set null will reset to components of {@link ItemType}
|
||||
*/
|
||||
public void setComponents(@Nullable PatchableComponentMap components) {
|
||||
this.components = components;
|
||||
}
|
||||
|
||||
public int getLegacyData() {
|
||||
return legacyData;
|
||||
}
|
||||
@@ -152,47 +302,99 @@ public class ItemStack {
|
||||
}
|
||||
|
||||
public boolean isEnchanted(ClientVersion version) {
|
||||
String tagName = getEnchantmentsTagName(version);
|
||||
return !isEmpty() && this.nbt != null && this.nbt.getCompoundListTagOrNull(tagName) != null && !this.nbt.getCompoundListTagOrNull(tagName).getTags().isEmpty();
|
||||
}
|
||||
|
||||
private List<Enchantment> getEnchantments(@Nullable NBTCompound nbt, ClientVersion version) {
|
||||
String tagName = getEnchantmentsTagName(version);
|
||||
|
||||
if (nbt == null || nbt.getCompoundListTagOrNull(tagName) == null)
|
||||
return new ArrayList<>(0);
|
||||
|
||||
NBTList<NBTCompound> nbtList = nbt.getCompoundListTagOrNull(tagName);
|
||||
List<NBTCompound> compounds = nbtList.getTags();
|
||||
List<Enchantment> enchantments = new ArrayList<>(compounds.size());
|
||||
|
||||
for (NBTCompound compound : compounds) {
|
||||
EnchantmentType type = getEnchantmentTypeFromTag(compound, version);
|
||||
|
||||
if (type != null) {
|
||||
NBTShort levelTag = compound.getTagOfTypeOrNull("lvl", NBTShort.class);
|
||||
int level = levelTag.getAsInt();
|
||||
Enchantment enchantment = Enchantment.builder().type(type).level(level).build();
|
||||
enchantments.add(enchantment);
|
||||
}
|
||||
if (this.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return enchantments;
|
||||
// check for components
|
||||
if (!this.getComponentOr(ENCHANTMENTS, ItemEnchantments.EMPTY).isEmpty()
|
||||
|| !this.getComponentOr(STORED_ENCHANTMENTS, ItemEnchantments.EMPTY).isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
// check for legacy nbt
|
||||
if (this.nbt != null) {
|
||||
String tagName = this.getEnchantmentsTagName(version);
|
||||
NBTList<NBTCompound> enchantments = this.nbt.getCompoundListTagOrNull(tagName);
|
||||
return enchantments != null && !enchantments.getTags().isEmpty();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<Enchantment> getEnchantments(ClientVersion version) {
|
||||
return getEnchantments(this.nbt, version);
|
||||
if (this.isEmpty()) {
|
||||
return new ArrayList<>(0);
|
||||
}
|
||||
|
||||
// check for components
|
||||
ItemEnchantments enchantmentsComp = this.getComponentOr(ENCHANTMENTS, ItemEnchantments.EMPTY);
|
||||
ItemEnchantments storedEnchantmentsComp = this.getComponentOr(STORED_ENCHANTMENTS, ItemEnchantments.EMPTY);
|
||||
if (!enchantmentsComp.isEmpty() || !storedEnchantmentsComp.isEmpty()) {
|
||||
List<Enchantment> enchantmentsList = new ArrayList<>(
|
||||
enchantmentsComp.getEnchantmentCount() + storedEnchantmentsComp.getEnchantmentCount());
|
||||
for (Map.Entry<EnchantmentType, Integer> enchantment : enchantmentsComp) {
|
||||
enchantmentsList.add(new Enchantment(enchantment.getKey(), enchantment.getValue()));
|
||||
}
|
||||
for (Map.Entry<EnchantmentType, Integer> enchantment : storedEnchantmentsComp) {
|
||||
enchantmentsList.add(new Enchantment(enchantment.getKey(), enchantment.getValue()));
|
||||
}
|
||||
return enchantmentsList;
|
||||
}
|
||||
|
||||
// check for legacy nbt
|
||||
if (this.nbt != null) {
|
||||
String tagName = this.getEnchantmentsTagName(version);
|
||||
NBTList<NBTCompound> nbtList = this.nbt.getCompoundListTagOrNull(tagName);
|
||||
if (nbtList != null) {
|
||||
List<NBTCompound> compounds = nbtList.getTags();
|
||||
List<Enchantment> enchantments = new ArrayList<>(compounds.size());
|
||||
|
||||
for (NBTCompound compound : compounds) {
|
||||
EnchantmentType type = getEnchantmentTypeFromTag(compound, version);
|
||||
|
||||
if (type != null) {
|
||||
NBTShort levelTag = compound.getTagOfTypeOrNull("lvl", NBTShort.class);
|
||||
int level = levelTag.getAsInt();
|
||||
Enchantment enchantment = Enchantment.builder().type(type).level(level).build();
|
||||
enchantments.add(enchantment);
|
||||
}
|
||||
}
|
||||
return enchantments;
|
||||
}
|
||||
}
|
||||
|
||||
return new ArrayList<>(0);
|
||||
}
|
||||
|
||||
public int getEnchantmentLevel(EnchantmentType enchantment, ClientVersion version) {
|
||||
if (isEnchanted(version)) {
|
||||
// isEnchanted() is true, so we can assume that nbt is not null
|
||||
assert nbt != null;
|
||||
String tagName = getEnchantmentsTagName(version);
|
||||
for (NBTCompound base : nbt.getCompoundListTagOrNull(tagName).getTags()) {
|
||||
EnchantmentType type = getEnchantmentTypeFromTag(base, version);
|
||||
if (enchantment == type) {
|
||||
return base.getTagOfTypeOrNull("lvl", NBTShort.class).getAsInt();
|
||||
if (this.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// check for components
|
||||
ItemEnchantments enchantmentsComp = this.getComponentOr(ENCHANTMENTS, ItemEnchantments.EMPTY);
|
||||
if (!enchantmentsComp.isEmpty()) {
|
||||
int level = enchantmentsComp.getEnchantmentLevel(enchantment);
|
||||
if (level > 0) {
|
||||
return level;
|
||||
}
|
||||
}
|
||||
ItemEnchantments storedEnchantmentsComp = this.getComponentOr(STORED_ENCHANTMENTS, ItemEnchantments.EMPTY);
|
||||
if (!storedEnchantmentsComp.isEmpty()) {
|
||||
int level = storedEnchantmentsComp.getEnchantmentLevel(enchantment);
|
||||
if (level > 0) {
|
||||
return level;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.nbt != null) {
|
||||
String tagName = this.getEnchantmentsTagName(version);
|
||||
NBTList<NBTCompound> nbtList = this.nbt.getCompoundListTagOrNull(tagName);
|
||||
if (nbtList != null) {
|
||||
for (NBTCompound base : nbtList.getTags()) {
|
||||
EnchantmentType type = getEnchantmentTypeFromTag(base, version);
|
||||
if (enchantment == type) {
|
||||
NBTShort nbtShort = base.getTagOfTypeOrNull("lvl", NBTShort.class);
|
||||
return nbtShort != null ? nbtShort.getAsInt() : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -200,8 +402,7 @@ public class ItemStack {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static EnchantmentType getEnchantmentTypeFromTag(NBTCompound tag, ClientVersion version) {
|
||||
private static @Nullable EnchantmentType getEnchantmentTypeFromTag(NBTCompound tag, ClientVersion version) {
|
||||
if (version.isNewerThanOrEquals(ClientVersion.V_1_13)) {
|
||||
String id = tag.getStringTagValueOrNull("id");
|
||||
return EnchantmentTypes.getByName(id);
|
||||
@@ -212,6 +413,7 @@ public class ItemStack {
|
||||
}
|
||||
|
||||
public void setEnchantments(List<Enchantment> enchantments, ClientVersion version) {
|
||||
// set in legacy nbt
|
||||
nbt = getOrCreateTag(); // Create tag if null
|
||||
String tagName = getEnchantmentsTagName(version);
|
||||
if (enchantments.isEmpty()) {
|
||||
@@ -235,8 +437,20 @@ public class ItemStack {
|
||||
assert nbt != null; // NBT was created in getOrCreateTag()
|
||||
nbt.setTag(tagName, new NBTList<>(NBTType.COMPOUND, list));
|
||||
}
|
||||
|
||||
// set in components
|
||||
Map<EnchantmentType, Integer> enchantmentsMap = new HashMap<>(enchantments.size());
|
||||
for (Enchantment enchantment : enchantments) {
|
||||
enchantmentsMap.put(enchantment.getType(), enchantment.getLevel());
|
||||
}
|
||||
ComponentType<ItemEnchantments> componentType = this.type == ItemTypes.ENCHANTED_BOOK
|
||||
? STORED_ENCHANTMENTS : ENCHANTMENTS;
|
||||
Optional<ItemEnchantments> prevEnchantments = this.getComponent(componentType);
|
||||
boolean showInTooltip = prevEnchantments.map(ItemEnchantments::isShowInTooltip).orElse(true);
|
||||
this.setComponent(componentType, new ItemEnchantments(enchantmentsMap, showInTooltip));
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public String getEnchantmentsTagName(ClientVersion version) {
|
||||
String tagName = version.isNewerThanOrEquals(ClientVersion.V_1_13) ? "Enchantments" : "ench";
|
||||
if (type == ItemTypes.ENCHANTED_BOOK) {
|
||||
@@ -254,7 +468,10 @@ public class ItemStack {
|
||||
}
|
||||
|
||||
public static boolean isSameItemSameTags(ItemStack stack, ItemStack otherStack) {
|
||||
return stack.is(otherStack.getType()) && ItemStack.tagMatches(stack, otherStack);
|
||||
return stack.is(otherStack.getType())
|
||||
&& (stack.isEmpty() && otherStack.isEmpty()
|
||||
|| (ItemStack.tagMatches(stack, otherStack)
|
||||
&& Objects.equals(stack.components, otherStack.components)));
|
||||
}
|
||||
|
||||
public static boolean tagMatches(ItemStack left, ItemStack right) {
|
||||
@@ -267,7 +484,8 @@ public class ItemStack {
|
||||
if (right == null) {
|
||||
return left.isEmpty();
|
||||
}
|
||||
return Objects.equals(left.nbt, right.nbt);
|
||||
return Objects.equals(left.nbt, right.nbt)
|
||||
&& Objects.equals(left.components, right.components);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -279,6 +497,7 @@ public class ItemStack {
|
||||
return getType().equals(itemStack.getType())
|
||||
&& amount == itemStack.amount
|
||||
&& Objects.equals(nbt, itemStack.nbt)
|
||||
&& Objects.equals(components, itemStack.components)
|
||||
&& legacyData == itemStack.legacyData;
|
||||
}
|
||||
return false;
|
||||
@@ -292,7 +511,8 @@ public class ItemStack {
|
||||
String identifier = type == null ? "null" : type.getName().toString();
|
||||
int maxAmount = getType().getMaxAmount();
|
||||
return "ItemStack[type=" + identifier + ", amount=" + amount + "/" + maxAmount
|
||||
+ ", nbt tag names: " + (nbt != null ? nbt.getTagNames() : "[null]") + ", legacyData=" + legacyData + "]";
|
||||
+ ", nbt tag names: " + (nbt != null ? nbt.getTagNames() : "[null]")
|
||||
+ ", legacyData=" + legacyData + ", components=" + components + "]";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,6 +528,7 @@ public class ItemStack {
|
||||
private ItemType type;
|
||||
private int amount = 1;
|
||||
private NBTCompound nbt = null;
|
||||
private PatchableComponentMap components = null;
|
||||
private int legacyData = -1;
|
||||
|
||||
public Builder type(ItemType type) {
|
||||
@@ -325,13 +546,35 @@ public class ItemStack {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder nbt(String key, NBT tag) {
|
||||
if (this.nbt == null) {
|
||||
this.nbt = new NBTCompound();
|
||||
}
|
||||
this.nbt.setTag(key, tag);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder components(@Nullable PatchableComponentMap components) {
|
||||
this.components = components;
|
||||
return this;
|
||||
}
|
||||
|
||||
public <T> Builder component(ComponentType<T> type, @Nullable T value) {
|
||||
if (this.components == null) {
|
||||
this.components = new PatchableComponentMap(this.type == null
|
||||
? StaticComponentMap.SHARED_ITEM_COMPONENTS : this.type.getComponents());
|
||||
}
|
||||
this.components.set(type, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder legacyData(int legacyData) {
|
||||
this.legacyData = legacyData;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemStack build() {
|
||||
return new ItemStack(type, amount, nbt, legacyData);
|
||||
return new ItemStack(type, amount, nbt, components, legacyData);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.item.armormaterial;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
|
||||
|
||||
public interface ArmorMaterial extends MappedEntity {
|
||||
}
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.item.armormaterial;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.mappings.MappingHelper;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilder;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ArmorMaterials {
|
||||
|
||||
private static final Map<String, ArmorMaterial> MATERIAL_MAP = new HashMap<>();
|
||||
private static final Map<Byte, Map<Integer, ArmorMaterial>> MATERIAL_ID_MAP = new HashMap<>();
|
||||
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("item/item_armor_material_mappings");
|
||||
|
||||
public static ArmorMaterial define(String key) {
|
||||
TypesBuilderData data = TYPES_BUILDER.define(key);
|
||||
ArmorMaterial instrument = new ArmorMaterial() {
|
||||
@Override
|
||||
public ResourceLocation getName() {
|
||||
return data.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId(ClientVersion version) {
|
||||
return MappingHelper.getId(version, TYPES_BUILDER, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof ArmorMaterial) {
|
||||
return getName().equals(((ArmorMaterial) obj).getName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
MappingHelper.registerMapping(TYPES_BUILDER, MATERIAL_MAP, MATERIAL_ID_MAP, instrument);
|
||||
return instrument;
|
||||
}
|
||||
|
||||
// with key
|
||||
public static ArmorMaterial getByName(String name) {
|
||||
return MATERIAL_MAP.get(name);
|
||||
}
|
||||
|
||||
public static ArmorMaterial getById(ClientVersion version, int id) {
|
||||
int index = TYPES_BUILDER.getDataIndex(version);
|
||||
Map<Integer, ArmorMaterial> idMap = MATERIAL_ID_MAP.get((byte) index);
|
||||
return idMap.get(id);
|
||||
}
|
||||
|
||||
public static final ArmorMaterial LEATHER = define("leather");
|
||||
public static final ArmorMaterial CHAINMAIL = define("chainmail");
|
||||
public static final ArmorMaterial IRON = define("iron");
|
||||
public static final ArmorMaterial GOLD = define("gold");
|
||||
public static final ArmorMaterial DIAMOND = define("diamond");
|
||||
|
||||
// Added with 1.13
|
||||
public static final ArmorMaterial TURTLE = define("turtle");
|
||||
|
||||
// Added with 1.16
|
||||
public static final ArmorMaterial NETHERITE = define("netherite");
|
||||
|
||||
// Added with 1.20.5
|
||||
public static final ArmorMaterial ARMADILLO = define("armadillo");
|
||||
|
||||
static {
|
||||
TYPES_BUILDER.unloadFileMappings();
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.item.banner;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.mapper.CopyableEntity;
|
||||
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBT;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface BannerPattern extends MappedEntity, CopyableEntity<BannerPattern> {
|
||||
|
||||
ResourceLocation getAssetId();
|
||||
|
||||
String getTranslationKey();
|
||||
|
||||
static BannerPattern readDirect(PacketWrapper<?> wrapper) {
|
||||
ResourceLocation assetId = wrapper.readIdentifier();
|
||||
String translationKey = wrapper.readString();
|
||||
return new StaticBannerPattern(assetId, translationKey);
|
||||
}
|
||||
|
||||
static void writeDirect(PacketWrapper<?> wrapper, BannerPattern pattern) {
|
||||
wrapper.writeIdentifier(pattern.getAssetId());
|
||||
wrapper.writeString(pattern.getTranslationKey());
|
||||
}
|
||||
|
||||
static BannerPattern decode(NBT nbt, ClientVersion version, @Nullable TypesBuilderData data) {
|
||||
NBTCompound compound = (NBTCompound) nbt;
|
||||
ResourceLocation assetId = new ResourceLocation(compound.getStringTagValueOrThrow("asset_id"));
|
||||
String translationKey = compound.getStringTagValueOrThrow("translation_key");
|
||||
return new StaticBannerPattern(data, assetId, translationKey);
|
||||
}
|
||||
|
||||
static NBT encode(BannerPattern bannerPattern, ClientVersion version) {
|
||||
NBTCompound compound = new NBTCompound();
|
||||
compound.setTag("asset_id", new NBTString(bannerPattern.getAssetId().toString()));
|
||||
compound.setTag("translation_key", new NBTString(bannerPattern.getTranslationKey()));
|
||||
return compound;
|
||||
}
|
||||
}
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2024 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.github.retrooper.packetevents.protocol.item.banner;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public final class BannerPatterns {
|
||||
|
||||
private static final VersionedRegistry<BannerPattern> REGISTRY = new VersionedRegistry<>(
|
||||
"banner_pattern", "item/item_banner_pattern_mappings");
|
||||
|
||||
private BannerPatterns() {
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static BannerPattern define(String key) {
|
||||
ResourceLocation assetId = ResourceLocation.minecraft(key);
|
||||
String translationKey = "block.minecraft.banner." + key;
|
||||
return define(key, assetId, translationKey);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static BannerPattern define(String key, ResourceLocation assetId, String translationKey) {
|
||||
return REGISTRY.define(key, data ->
|
||||
new StaticBannerPattern(data, assetId, translationKey));
|
||||
}
|
||||
|
||||
public static VersionedRegistry<BannerPattern> getRegistry() {
|
||||
return REGISTRY;
|
||||
}
|
||||
|
||||
public static BannerPattern getByName(String name) {
|
||||
return REGISTRY.getByName(name);
|
||||
}
|
||||
|
||||
public static BannerPattern getById(ClientVersion version, int id) {
|
||||
return REGISTRY.getById(version, id);
|
||||
}
|
||||
|
||||
public static final BannerPattern SQUARE_BOTTOM_LEFT = define("square_bottom_left");
|
||||
public static final BannerPattern STRIPE_BOTTOM = define("stripe_bottom");
|
||||
public static final BannerPattern CREEPER = define("creeper");
|
||||
public static final BannerPattern HALF_HORIZONTAL = define("half_horizontal");
|
||||
public static final BannerPattern STRIPE_MIDDLE = define("stripe_middle");
|
||||
public static final BannerPattern BASE = define("base");
|
||||
public static final BannerPattern DIAGONAL_UP_RIGHT = define("diagonal_up_right");
|
||||
public static final BannerPattern HALF_HORIZONTAL_BOTTOM = define("half_horizontal_bottom");
|
||||
public static final BannerPattern SMALL_STRIPES = define("small_stripes");
|
||||
public static final BannerPattern GRADIENT_UP = define("gradient_up");
|
||||
public static final BannerPattern CIRCLE = define("circle");
|
||||
public static final BannerPattern STRIPE_DOWNLEFT = define("stripe_downleft");
|
||||
public static final BannerPattern RHOMBUS = define("rhombus");
|
||||
public static final BannerPattern TRIANGLES_BOTTOM = define("triangles_bottom");
|
||||
public static final BannerPattern STRIPE_CENTER = define("stripe_center");
|
||||
public static final BannerPattern SQUARE_BOTTOM_RIGHT = define("square_bottom_right");
|
||||
public static final BannerPattern DIAGONAL_RIGHT = define("diagonal_right");
|
||||
public static final BannerPattern MOJANG = define("mojang");
|
||||
public static final BannerPattern STRIPE_LEFT = define("stripe_left");
|
||||
public static final BannerPattern SQUARE_TOP_LEFT = define("square_top_left");
|
||||
public static final BannerPattern TRIANGLE_BOTTOM = define("triangle_bottom");
|
||||
public static final BannerPattern SKULL = define("skull");
|
||||
public static final BannerPattern SQUARE_TOP_RIGHT = define("square_top_right");
|
||||
public static final BannerPattern GLOBE = define("globe");
|
||||
public static final BannerPattern STRIPE_TOP = define("stripe_top");
|
||||
public static final BannerPattern CROSS = define("cross");
|
||||
public static final BannerPattern BRICKS = define("bricks");
|
||||
public static final BannerPattern HALF_VERTICAL = define("half_vertical");
|
||||
public static final BannerPattern STRIPE_DOWNRIGHT = define("stripe_downright");
|
||||
public static final BannerPattern TRIANGLES_TOP = define("triangles_top");
|
||||
public static final BannerPattern STRIPE_RIGHT = define("stripe_right");
|
||||
public static final BannerPattern DIAGONAL_UP_LEFT = define("diagonal_up_left");
|
||||
public static final BannerPattern HALF_VERTICAL_RIGHT = define("half_vertical_right");
|
||||
public static final BannerPattern TRIANGLE_TOP = define("triangle_top");
|
||||
public static final BannerPattern FLOWER = define("flower");
|
||||
public static final BannerPattern STRAIGHT_CROSS = define("straight_cross");
|
||||
public static final BannerPattern GRADIENT = define("gradient");
|
||||
public static final BannerPattern CURLY_BORDER = define("curly_border");
|
||||
public static final BannerPattern BORDER = define("border");
|
||||
public static final BannerPattern PIGLIN = define("piglin");
|
||||
public static final BannerPattern DIAGONAL_LEFT = define("diagonal_left");
|
||||
|
||||
// Added with 1.21
|
||||
public static final BannerPattern FLOW = define("flow");
|
||||
public static final BannerPattern GUSTER = define("guster");
|
||||
|
||||
/**
|
||||
* Returns an immutable view of the banner patterns.
|
||||
*
|
||||
* @return Banner Patterns
|
||||
*/
|
||||
public static Collection<BannerPattern> values() {
|
||||
return REGISTRY.getEntries();
|
||||
}
|
||||
|
||||
static {
|
||||
REGISTRY.unloadMappings();
|
||||
}
|
||||
}
|
||||
Loaded 100 of 538 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user