Compare commits
507 Commits
Minecraft-
...
Minecraft-
Author | SHA1 | Date | |
---|---|---|---|
![]() |
db5510cc4e | ||
![]() |
5ed5c71aea | ||
![]() |
38a8469ab4 | ||
![]() |
9538dcf4d4 | ||
![]() |
33f654ce6f | ||
![]() |
c108e4e1ce | ||
![]() |
e998faeec1 | ||
![]() |
d67acd7bc9 | ||
![]() |
702f434db1 | ||
![]() |
47b5631562 | ||
![]() |
80e23d6646 | ||
![]() |
1dca12cffb | ||
![]() |
29c897c9cf | ||
![]() |
042f47cbb9 | ||
![]() |
422e97f495 | ||
![]() |
08789d8f9f | ||
![]() |
96444ae304 | ||
![]() |
af58db8a67 | ||
![]() |
49cffebd9b | ||
![]() |
ffdb917f2c | ||
![]() |
9c9657e36d | ||
![]() |
1342baed47 | ||
![]() |
e3a7490bcd | ||
![]() |
3e8693793c | ||
![]() |
bb47aba682 | ||
![]() |
d0e5ee4e09 | ||
![]() |
07e330b005 | ||
![]() |
024288e587 | ||
![]() |
53a6bb1dee | ||
![]() |
0f06b2c4e0 | ||
![]() |
d3c1acce83 | ||
![]() |
eaea090d37 | ||
![]() |
7384e797fc | ||
![]() |
d4d93ddbb9 | ||
![]() |
ccdf2a89d8 | ||
![]() |
89edb00c05 | ||
![]() |
00a0277a13 | ||
![]() |
68f11e46f7 | ||
![]() |
c352e854ee | ||
![]() |
d8c92cd311 | ||
![]() |
99f361ca77 | ||
![]() |
738ed99d54 | ||
![]() |
ad0da59267 | ||
![]() |
1dcc8d6a4b | ||
![]() |
0840a77153 | ||
![]() |
61a93a54a9 | ||
![]() |
da0281508e | ||
![]() |
51e92de2dd | ||
![]() |
f948acd634 | ||
![]() |
773ce089c1 | ||
![]() |
a07eba7965 | ||
![]() |
b68b6a76c7 | ||
![]() |
332033bb02 | ||
![]() |
172b8bc75b | ||
![]() |
db5a147491 | ||
![]() |
f083e27649 | ||
![]() |
b64a7be19b | ||
![]() |
c4d60a8fa9 | ||
![]() |
f07cfe0cf7 | ||
![]() |
4463b0c1b2 | ||
![]() |
ee8f33c196 | ||
![]() |
14ac2dd308 | ||
![]() |
fb94612315 | ||
![]() |
4c96880580 | ||
![]() |
4c4cdd51a1 | ||
![]() |
1f38152530 | ||
![]() |
911f08d52c | ||
![]() |
8f961c9d4e | ||
![]() |
8a5d8a57f7 | ||
![]() |
c54553d0f9 | ||
![]() |
600a1b4ff5 | ||
![]() |
09e592295f | ||
![]() |
fa0ee02beb | ||
![]() |
b23b54d9e4 | ||
![]() |
b3e8feb4cb | ||
![]() |
d0d1562155 | ||
![]() |
f510ab2a0b | ||
![]() |
fb1cab499d | ||
![]() |
58ca63e2b1 | ||
![]() |
499337c98e | ||
![]() |
526137be7b | ||
![]() |
47839cb11c | ||
![]() |
55a6cc56ef | ||
![]() |
8c2bea5be2 | ||
![]() |
daa58ffe58 | ||
![]() |
0189ad9c17 | ||
![]() |
9adcb05d45 | ||
![]() |
10e81041b2 | ||
![]() |
0c56945ffd | ||
![]() |
0a36cbd5bc | ||
![]() |
61b4777177 | ||
![]() |
7d1904584b | ||
![]() |
475571986c | ||
![]() |
55c2bcd634 | ||
![]() |
db4abfe486 | ||
![]() |
9424bdedca | ||
![]() |
52b3c6b77c | ||
![]() |
be29799f5a | ||
![]() |
c0d581d41f | ||
![]() |
6b50c7c599 | ||
![]() |
b4101874cc | ||
![]() |
66de4c95ef | ||
![]() |
927a295add | ||
![]() |
2cbea83c02 | ||
![]() |
87884ad084 | ||
![]() |
94cc2412e7 | ||
![]() |
924b90e325 | ||
![]() |
3f476a30b4 | ||
![]() |
f579b31bca | ||
![]() |
cac35116c3 | ||
![]() |
bd42fb23a0 | ||
![]() |
ffbebaff69 | ||
![]() |
b741722e5d | ||
![]() |
07288c722c | ||
![]() |
85e82a2e34 | ||
![]() |
3aef35ccbb | ||
![]() |
d1760dad93 | ||
![]() |
d3d11cf283 | ||
![]() |
d3bada58d4 | ||
![]() |
23517a9a97 | ||
![]() |
fdc87e88f5 | ||
![]() |
12941ffe62 | ||
![]() |
06e732d8c7 | ||
![]() |
5c4ea3c7a0 | ||
![]() |
632fa8bd94 | ||
![]() |
8732904bfd | ||
![]() |
788b96dc0a | ||
![]() |
1296783d9b | ||
![]() |
a9603a6372 | ||
![]() |
b15ed87ad5 | ||
![]() |
3e816f628b | ||
![]() |
7bfc4bf819 | ||
![]() |
f8d15f4c88 | ||
![]() |
a73b06eee3 | ||
![]() |
2069679140 | ||
![]() |
9a173968f1 | ||
![]() |
13f1fa7443 | ||
![]() |
0f7da279ef | ||
![]() |
a6ba661a32 | ||
![]() |
22133bc8d2 | ||
![]() |
f9c9517958 | ||
![]() |
7a79bd0816 | ||
![]() |
6a60376033 | ||
![]() |
4ce0eee232 | ||
![]() |
72f3a79759 | ||
![]() |
dbb6aebf58 | ||
![]() |
54040ec48d | ||
![]() |
8c4ddf458c | ||
![]() |
07fb6490f8 | ||
![]() |
d9eb8c66b8 | ||
![]() |
7fab3ba372 | ||
![]() |
92c3ef1989 | ||
![]() |
fbf2d8969e | ||
![]() |
1881507712 | ||
![]() |
fd2a72477f | ||
![]() |
d4cbac1bdf | ||
![]() |
fa0671ab2a | ||
![]() |
184154a8b3 | ||
![]() |
cbec4e836a | ||
![]() |
3ce7982778 | ||
![]() |
b55944e2fb | ||
![]() |
12cba14657 | ||
![]() |
78e67283cc | ||
![]() |
f0f1e71c93 | ||
![]() |
3c1a5aabfd | ||
![]() |
f0d4e8c24a | ||
![]() |
ba8bd7faf0 | ||
![]() |
787692070e | ||
![]() |
523e991018 | ||
![]() |
7733fbfb28 | ||
![]() |
44ac36941f | ||
![]() |
0235c4a01e | ||
![]() |
b4220e9229 | ||
![]() |
9b9addfccd | ||
![]() |
b75a2b5060 | ||
![]() |
b5aecd5dcc | ||
![]() |
4d51d16512 | ||
![]() |
05a9342854 | ||
![]() |
483fede234 | ||
![]() |
ce8f1b44b6 | ||
![]() |
b1e3f6a75b | ||
![]() |
33d315b719 | ||
![]() |
d11e130d61 | ||
![]() |
45a93c8cfc | ||
![]() |
fd411edddb | ||
![]() |
ac5e8dbaff | ||
![]() |
340d82812a | ||
![]() |
eaf99cf4a6 | ||
![]() |
4baae5a230 | ||
![]() |
aa1a871967 | ||
![]() |
18f5ed3102 | ||
![]() |
d1dd7379b1 | ||
![]() |
0b0d09427d | ||
![]() |
dce0f6b408 | ||
![]() |
c5307c4451 | ||
![]() |
4f2b98188e | ||
![]() |
d5eb37c7a6 | ||
![]() |
2a421cdd8d | ||
![]() |
757f8f0cb9 | ||
![]() |
388d2620db | ||
![]() |
3ba52cb98b | ||
![]() |
e652214071 | ||
![]() |
0821404f92 | ||
![]() |
11b90b91b7 | ||
![]() |
aa3989db19 | ||
![]() |
76c914db14 | ||
![]() |
639e5f3c1d | ||
![]() |
9fd69068ae | ||
![]() |
9c35cad824 | ||
![]() |
d82b29e15a | ||
![]() |
9b0c827c37 | ||
![]() |
125d3f07f7 | ||
![]() |
2f45f0d578 | ||
![]() |
ad4c143ce4 | ||
![]() |
835e4e332c | ||
![]() |
0578f94522 | ||
![]() |
0cd4c9030c | ||
![]() |
0d666168f0 | ||
![]() |
cfb823f077 | ||
![]() |
36a5e89ff9 | ||
![]() |
bb4e8e29a5 | ||
![]() |
8e34e038d6 | ||
![]() |
d1950389cc | ||
![]() |
9d841bb91a | ||
![]() |
828cebcc4b | ||
![]() |
12fec2fcdd | ||
![]() |
8b6b134662 | ||
![]() |
538beb33a6 | ||
![]() |
97338cbfad | ||
![]() |
3e28decef2 | ||
![]() |
f93b647df3 | ||
![]() |
775ffdc998 | ||
![]() |
80c22027de | ||
![]() |
122987dd83 | ||
![]() |
ac4bab2425 | ||
![]() |
a51ffb1f4c | ||
![]() |
77e0dcc7f8 | ||
![]() |
ddb93fd988 | ||
![]() |
7eac22d362 | ||
![]() |
185dc97ca6 | ||
![]() |
e0d19cf305 | ||
![]() |
0e9002091b | ||
![]() |
9fdcded97f | ||
![]() |
32fdc83841 | ||
![]() |
1bf126d4f8 | ||
![]() |
56533c6259 | ||
![]() |
4cb46c6e5c | ||
![]() |
6decf860c9 | ||
![]() |
29f22f9be9 | ||
![]() |
98860ffd02 | ||
![]() |
2c225a05e7 | ||
![]() |
c1dfd0fb7b | ||
![]() |
9be44d51a6 | ||
![]() |
2a2c2717d5 | ||
![]() |
3f994a1c4c | ||
![]() |
9a0da50e6c | ||
![]() |
67fdc830c2 | ||
![]() |
64e8a79551 | ||
![]() |
afc387ce0d | ||
![]() |
8a70af5293 | ||
![]() |
57793e93f0 | ||
![]() |
a48ef137bd | ||
![]() |
ff32d29e09 | ||
![]() |
9f3359f8fa | ||
![]() |
539fccb873 | ||
![]() |
b25c81daf3 | ||
![]() |
21a354fa75 | ||
![]() |
aefe3333a9 | ||
![]() |
0afefa8f61 | ||
![]() |
834ac24b38 | ||
![]() |
c465eca03b | ||
![]() |
beb0bf9836 | ||
![]() |
688c42219c | ||
![]() |
1ea53f01aa | ||
![]() |
202dab5c98 | ||
![]() |
49ea7f908f | ||
![]() |
9d3bddedb6 | ||
![]() |
332bdaaec0 | ||
![]() |
904a1bfaa3 | ||
![]() |
5eb7a6eba7 | ||
![]() |
8e262cf428 | ||
![]() |
125df5c22d | ||
![]() |
7b631092f5 | ||
![]() |
d3c1339cc9 | ||
![]() |
679bf2fca9 | ||
![]() |
7436621481 | ||
![]() |
6236cff658 | ||
![]() |
6b504d9160 | ||
![]() |
d1124ca70b | ||
![]() |
779582d441 | ||
![]() |
b91564f77a | ||
![]() |
30b2e5008b | ||
![]() |
140830efe0 | ||
![]() |
5f8e76c61c | ||
![]() |
b7511abfda | ||
![]() |
09d04c34cb | ||
![]() |
3132d2c7cf | ||
![]() |
3682e8ba3a | ||
![]() |
82d5954f2f | ||
![]() |
384228b751 | ||
![]() |
50f8bd2eb0 | ||
![]() |
ff32764f9a | ||
![]() |
a1f928b210 | ||
![]() |
5bf616dc4d | ||
![]() |
0d7759f50b | ||
![]() |
824bdc5491 | ||
![]() |
ebff48ff86 | ||
![]() |
6efba44e5a | ||
![]() |
9f8ad518e8 | ||
![]() |
885a96c0c6 | ||
![]() |
5d0ff24f70 | ||
![]() |
ca5db43f70 | ||
![]() |
49a22f188f | ||
![]() |
ce7c095243 | ||
![]() |
cbb08ec58b | ||
![]() |
349949d154 | ||
![]() |
92e7faa346 | ||
![]() |
6b21fdaaea | ||
![]() |
fa9dd7e27f | ||
![]() |
f44cf6c8e9 | ||
![]() |
6bf9df31f5 | ||
![]() |
c08764990d | ||
![]() |
a82e6f3eea | ||
![]() |
26cee397e6 | ||
![]() |
dc6835c21b | ||
![]() |
be30c8b89a | ||
![]() |
70e10c382e | ||
![]() |
93ea108acb | ||
![]() |
a63739277b | ||
![]() |
112d543c2a | ||
![]() |
7338e20e98 | ||
![]() |
18a5534499 | ||
![]() |
e540626a28 | ||
![]() |
5e2bcc2907 | ||
![]() |
a38b3ce9f2 | ||
![]() |
c615b2362f | ||
![]() |
5620c4679d | ||
![]() |
a9ad4889f7 | ||
![]() |
7108bd4deb | ||
![]() |
ac1119bef8 | ||
![]() |
dac259933b | ||
![]() |
a57ae83d62 | ||
![]() |
a00c91c03a | ||
![]() |
a67d4a1697 | ||
![]() |
b87fff2614 | ||
![]() |
0c144c38db | ||
![]() |
5592f81e97 | ||
![]() |
5d1a2c59a7 | ||
![]() |
88c99f071e | ||
![]() |
19c3c23b86 | ||
![]() |
5dfe83cf6d | ||
![]() |
fecaf76acf | ||
![]() |
c8c1028bd9 | ||
![]() |
51be33dbd7 | ||
![]() |
8cac038a07 | ||
![]() |
edceaf072c | ||
![]() |
f935f93d98 | ||
![]() |
e5c457df04 | ||
![]() |
d4f60e65c3 | ||
![]() |
548b2f2c60 | ||
![]() |
3733ecf628 | ||
![]() |
6e9cdb2e20 | ||
![]() |
d900a5eae7 | ||
![]() |
68712ab854 | ||
![]() |
d067662967 | ||
![]() |
88a52bc4e9 | ||
![]() |
d684f5de69 | ||
![]() |
a316d6ccdc | ||
![]() |
5de8ac89e5 | ||
![]() |
8707995503 | ||
![]() |
caea1e3fa5 | ||
![]() |
4096012d8e | ||
![]() |
acbf6d3137 | ||
![]() |
3a3fb27d9a | ||
![]() |
e506957d38 | ||
![]() |
8003dc50c4 | ||
![]() |
75bc2738b9 | ||
![]() |
cf4846baa9 | ||
![]() |
120a4dc401 | ||
![]() |
6881597692 | ||
![]() |
0ffb557557 | ||
![]() |
5f7ecf9d3b | ||
![]() |
e07f1e603a | ||
![]() |
430b5ff392 | ||
![]() |
81fe547a7c | ||
![]() |
04fb1df3e1 | ||
![]() |
73aaf58009 | ||
![]() |
fd062503e1 | ||
![]() |
c97f113497 | ||
![]() |
14fcb90395 | ||
![]() |
39009d8c96 | ||
![]() |
13f394b9a7 | ||
![]() |
9838a09a8c | ||
![]() |
ffddcf939f | ||
![]() |
3d8143c36e | ||
![]() |
5e31b158e9 | ||
![]() |
a59e0f0b6b | ||
![]() |
517655f54e | ||
![]() |
55ec76beee | ||
![]() |
a564d4c7f1 | ||
![]() |
86b864ce21 | ||
![]() |
6813b82b84 | ||
![]() |
27d454524f | ||
![]() |
8827feacfb | ||
![]() |
692610cd7e | ||
![]() |
1edd27963f | ||
![]() |
730c05aaad | ||
![]() |
2bae6cafc2 | ||
![]() |
5a15d5387c | ||
![]() |
3fed94fbf2 | ||
![]() |
1dd661f619 | ||
![]() |
e364cff44e | ||
![]() |
dfa47f740d | ||
![]() |
87fcef0658 | ||
![]() |
49f2f5f28b | ||
![]() |
a12debf6d0 | ||
![]() |
5d3cb452fe | ||
![]() |
b3c34815b0 | ||
![]() |
40768c1711 | ||
![]() |
b16da7d048 | ||
![]() |
e681c8906d | ||
![]() |
ce40391717 | ||
![]() |
2e51ec4fba | ||
![]() |
54098c8989 | ||
![]() |
156ea30c32 | ||
![]() |
34f4bae923 | ||
![]() |
6bb089074e | ||
![]() |
70c73211a0 | ||
![]() |
c059345802 | ||
![]() |
f5b4e1242d | ||
![]() |
5365e5fb92 | ||
![]() |
dc2ef1eac7 | ||
![]() |
113dada511 | ||
![]() |
8ea5205fef | ||
![]() |
05d76c3f67 | ||
![]() |
d6e29b3f29 | ||
![]() |
bd479ba083 | ||
![]() |
704fe11b05 | ||
![]() |
4811e7be4f | ||
![]() |
ac426f0c3f | ||
![]() |
0f30024040 | ||
![]() |
5bfab582df | ||
![]() |
ec1de0f636 | ||
![]() |
9bf6a58ba2 | ||
![]() |
9483c0228b | ||
![]() |
09bb7a93d2 | ||
![]() |
8935e77118 | ||
![]() |
b71d253de2 | ||
![]() |
d54f2462a8 | ||
![]() |
c1ff4ffb89 | ||
![]() |
58f1ab208b | ||
![]() |
d5f25b07e5 | ||
![]() |
30b381853c | ||
![]() |
b0820208e6 | ||
![]() |
bc0a076e4b | ||
![]() |
1763dd3078 | ||
![]() |
373ec187fb | ||
![]() |
ac2c96c2ea | ||
![]() |
5688099605 | ||
![]() |
1d2afae98e | ||
![]() |
4805087e38 | ||
![]() |
e2f134ec08 | ||
![]() |
92c1450909 | ||
![]() |
fea3642550 | ||
![]() |
f02d17c979 | ||
![]() |
3dac86a94c | ||
![]() |
758e196479 | ||
![]() |
5dd3384b31 | ||
![]() |
59efec128d | ||
![]() |
3b90737273 | ||
![]() |
f9f664f9b6 | ||
![]() |
9edcda7ace | ||
![]() |
cd1420d9cd | ||
![]() |
a3e1493ce1 | ||
![]() |
9fb814003b | ||
![]() |
76319371f7 | ||
![]() |
2e33ab1460 | ||
![]() |
cfd10f5714 | ||
![]() |
6ae5feee60 | ||
![]() |
0b7b87d9c3 | ||
![]() |
fa5804ec86 | ||
![]() |
6e18403cd9 | ||
![]() |
f67ad024f5 | ||
![]() |
a0989a8932 | ||
![]() |
3be83cb5a4 | ||
![]() |
0ce02251d4 | ||
![]() |
b4d104d258 | ||
![]() |
0c69814db7 | ||
![]() |
f0766ebcfb | ||
![]() |
f0a19e0f45 | ||
![]() |
6525502836 | ||
![]() |
504f703fbb | ||
![]() |
4fb85721a9 | ||
![]() |
e12bc1d92e | ||
![]() |
bcaafc206f | ||
![]() |
8a96555cc7 | ||
![]() |
45c848a4fd | ||
![]() |
9e0ae0a70d | ||
![]() |
9ad9003974 | ||
![]() |
e18fe49cf9 | ||
![]() |
c3d702a5b3 | ||
![]() |
cdf26f7950 | ||
![]() |
644deee3c6 | ||
![]() |
b6e76f4054 | ||
![]() |
0f9cc76633 | ||
![]() |
0afc52c130 | ||
![]() |
0077af58d0 |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,12 +1,11 @@
|
||||
# Eclipse stuff
|
||||
.classpath/
|
||||
.project/
|
||||
.classpath
|
||||
.project
|
||||
.settings/
|
||||
|
||||
# netbeans
|
||||
nbproject/
|
||||
nbactions.xml
|
||||
nb-configuration.xml
|
||||
|
||||
# we use maven!
|
||||
build.xml
|
||||
|
31
api/nb-configuration.xml
Normal file
31
api/nb-configuration.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project-shared-configuration>
|
||||
<!--
|
||||
This file contains additional configuration written by modules in the NetBeans IDE.
|
||||
The configuration is intended to be shared among all the users of project and
|
||||
therefore it is assumed to be part of version control checkout.
|
||||
Without this configuration present, some functionality in the IDE may be limited or fail altogether.
|
||||
-->
|
||||
<properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
|
||||
<!--
|
||||
Properties that influence various parts of the IDE, especially code formatting and the like.
|
||||
You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
|
||||
That way multiple projects can share the same settings (useful for formatting rules for example).
|
||||
Any value defined here will override the pom.xml file value but is only applicable to the current project.
|
||||
-->
|
||||
<org-netbeans-modules-editor-indent.CodeStyle.usedProfile>project</org-netbeans-modules-editor-indent.CodeStyle.usedProfile>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.classDeclBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.classDeclBracePlacement>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.otherBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.otherBracePlacement>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.methodDeclBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.methodDeclBracePlacement>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinMethodCallParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinMethodCallParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSwitchParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSwitchParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinCatchParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinCatchParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinTryParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinTryParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSynchronizedParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSynchronizedParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinArrayInitBrackets>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinArrayInitBrackets>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinWhileParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinWhileParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinIfParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinIfParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinForParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinForParens>
|
||||
</properties>
|
||||
</project-shared-configuration>
|
20
api/pom.xml
20
api/pom.xml
@@ -6,13 +6,13 @@
|
||||
<parent>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-parent</artifactId>
|
||||
<version>1.4.7-SNAPSHOT</version>
|
||||
<version>1.6.2-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-api</artifactId>
|
||||
<version>1.4.7-SNAPSHOT</version>
|
||||
<version>1.6.2-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>BungeeCord-API</name>
|
||||
@@ -22,13 +22,25 @@
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>13.0.1</version>
|
||||
<version>14.0.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-event</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-protocol</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
<version>1.11</version>
|
||||
<version>1.12</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
@@ -0,0 +1,46 @@
|
||||
package net.md_5.bungee.api;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.PendingConnection;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
public abstract class AbstractReconnectHandler implements ReconnectHandler
|
||||
{
|
||||
|
||||
@Override
|
||||
public ServerInfo getServer(ProxiedPlayer player)
|
||||
{
|
||||
ServerInfo server = getForcedHost( player.getPendingConnection() );
|
||||
if ( server == null )
|
||||
{
|
||||
server = getStoredServer( player );
|
||||
if ( server == null )
|
||||
{
|
||||
server = ProxyServer.getInstance().getServerInfo( player.getPendingConnection().getListener().getDefaultServer() );
|
||||
}
|
||||
|
||||
Preconditions.checkState( server != null, "Default server not defined" );
|
||||
}
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
public static ServerInfo getForcedHost(PendingConnection con)
|
||||
{
|
||||
if ( con.getVirtualHost() == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
String forced = con.getListener().getForcedHosts().get( con.getVirtualHost().getHostString() );
|
||||
|
||||
if ( forced == null && con.getListener().isForceDefault() )
|
||||
{
|
||||
forced = con.getListener().getDefaultServer();
|
||||
}
|
||||
return ProxyServer.getInstance().getServerInfo( forced );
|
||||
}
|
||||
|
||||
protected abstract ServerInfo getStoredServer(ProxiedPlayer player);
|
||||
}
|
@@ -1,5 +1,7 @@
|
||||
package net.md_5.bungee.api;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
@@ -105,13 +107,30 @@ public enum ChatColor
|
||||
* Pattern to remove all colour codes.
|
||||
*/
|
||||
private static final Pattern STRIP_COLOR_PATTERN = Pattern.compile( "(?i)" + String.valueOf( COLOR_CHAR ) + "[0-9A-FK-OR]" );
|
||||
/**
|
||||
* Colour instances keyed by their active character.
|
||||
*/
|
||||
private static final Map<Character, ChatColor> BY_CHAR = new HashMap<>();
|
||||
/**
|
||||
* The code appended to {@link #COLOR_CHAR} to make usable colour.
|
||||
*/
|
||||
private final char code;
|
||||
/**
|
||||
* This colour's colour char prefixed by the {@link #COLOR_CHAR}.
|
||||
*/
|
||||
private final String toString;
|
||||
|
||||
static
|
||||
{
|
||||
for ( ChatColor colour : values() )
|
||||
{
|
||||
BY_CHAR.put( colour.code, colour );
|
||||
}
|
||||
}
|
||||
|
||||
private ChatColor(char code)
|
||||
{
|
||||
this.code = code;
|
||||
this.toString = new String( new char[]
|
||||
{
|
||||
COLOR_CHAR, code
|
||||
@@ -153,4 +172,15 @@ public enum ChatColor
|
||||
}
|
||||
return new String( b );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the colour represented by the specified code.
|
||||
*
|
||||
* @param code the code to search for
|
||||
* @return the mapped colour, or null if non exists
|
||||
*/
|
||||
public static ChatColor getByChar(char code)
|
||||
{
|
||||
return BY_CHAR.get( code );
|
||||
}
|
||||
}
|
||||
|
@@ -19,6 +19,14 @@ public interface CommandSender
|
||||
*/
|
||||
public void sendMessage(String message);
|
||||
|
||||
/**
|
||||
* Send several messages to this sender. Each message will be sent
|
||||
* separately.
|
||||
*
|
||||
* @param messages the messages to send
|
||||
*/
|
||||
public void sendMessages(String... messages);
|
||||
|
||||
/**
|
||||
* Get all groups this user is part of. This returns an unmodifiable
|
||||
* collection.
|
||||
|
@@ -2,6 +2,7 @@ package net.md_5.bungee.api;
|
||||
|
||||
import net.md_5.bungee.api.plugin.PluginManager;
|
||||
import com.google.common.base.Preconditions;
|
||||
import java.io.File;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
@@ -10,8 +11,9 @@ import lombok.Getter;
|
||||
import net.md_5.bungee.api.config.ConfigurationAdapter;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.connection.Server;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
import net.md_5.bungee.api.scheduler.TaskScheduler;
|
||||
import net.md_5.bungee.api.tab.CustomTabList;
|
||||
|
||||
public abstract class ProxyServer
|
||||
{
|
||||
@@ -46,6 +48,13 @@ public abstract class ProxyServer
|
||||
*/
|
||||
public abstract String getVersion();
|
||||
|
||||
/**
|
||||
* Gets a localized string from the .properties file.
|
||||
*
|
||||
* @return the localized string
|
||||
*/
|
||||
public abstract String getTranslation(String name);
|
||||
|
||||
/**
|
||||
* Gets the main logger which can be used as a suitable replacement for
|
||||
* {@link System#out} and {@link System#err}.
|
||||
@@ -69,20 +78,6 @@ public abstract class ProxyServer
|
||||
*/
|
||||
public abstract ProxiedPlayer getPlayer(String name);
|
||||
|
||||
/**
|
||||
* Get a server by its name. The instance returned will be taken from a
|
||||
* player currently on that server to facilitate abstract proxy -> server
|
||||
* actions.
|
||||
*
|
||||
* @param name the name to lookup
|
||||
* @return the associated server
|
||||
* @deprecated in most cases the {@link #getServerInfo(java.lang.String)}
|
||||
* method should be used, as it will return a server even when no players
|
||||
* are online.
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract Server getServer(String name);
|
||||
|
||||
/**
|
||||
* Return all servers registered to this proxy, keyed by name. Unlike the
|
||||
* methods in {@link ConfigurationAdapter#getServers()}, this will not
|
||||
@@ -124,21 +119,6 @@ public abstract class ProxyServer
|
||||
*/
|
||||
public abstract void setConfigurationAdapter(ConfigurationAdapter adapter);
|
||||
|
||||
/**
|
||||
* Get the currently in use tab list handle.
|
||||
*
|
||||
* @return the tab list handler
|
||||
*/
|
||||
public abstract TabListHandler getTabListHandler();
|
||||
|
||||
/**
|
||||
* Set the used tab list handler, should not be changed once players have
|
||||
* connected
|
||||
*
|
||||
* @param handler the tab list handler to set
|
||||
*/
|
||||
public abstract void setTabListHandler(TabListHandler handler);
|
||||
|
||||
/**
|
||||
* Get the currently in use reconnect handler.
|
||||
*
|
||||
@@ -208,7 +188,63 @@ public abstract class ProxyServer
|
||||
*
|
||||
* @param name name of the server
|
||||
* @param address connectable Minecraft address + port of the server
|
||||
* @param motd the motd when used as a forced server
|
||||
* @param restricted whether the server info restricted property will be set
|
||||
* @return the constructed instance
|
||||
*/
|
||||
public abstract ServerInfo constructServerInfo(String name, InetSocketAddress address);
|
||||
public abstract ServerInfo constructServerInfo(String name, InetSocketAddress address, String motd, boolean restricted);
|
||||
|
||||
/**
|
||||
* Returns the console overlord for this proxy. Being the console, this
|
||||
* command server cannot have permissions or groups, and will be able to
|
||||
* execute anything.
|
||||
*
|
||||
* @return the console command sender of this proxy
|
||||
*/
|
||||
public abstract CommandSender getConsole();
|
||||
|
||||
/**
|
||||
* Return the folder used to load plugins from.
|
||||
*
|
||||
* @return the folder used to load plugin
|
||||
*/
|
||||
public abstract File getPluginsFolder();
|
||||
|
||||
/**
|
||||
* Get the scheduler instance for this proxy.
|
||||
*
|
||||
* @return the in use scheduler
|
||||
*/
|
||||
public abstract TaskScheduler getScheduler();
|
||||
|
||||
/**
|
||||
* Get the current number of connected users. The default implementation is
|
||||
* more efficient than {@link #getPlayers()} as it does not take a lock or
|
||||
* make a copy.
|
||||
*
|
||||
* @return the current number of connected players
|
||||
*/
|
||||
public abstract int getOnlineCount();
|
||||
|
||||
/**
|
||||
* Send the specified message to the console and all connected players.
|
||||
*
|
||||
* @param message the message to broadcast
|
||||
*/
|
||||
public abstract void broadcast(String message);
|
||||
|
||||
/**
|
||||
* Gets a new instance of this proxies custom tab list.
|
||||
*
|
||||
* @param player the player to generate this list in the context of
|
||||
* @return a new {@link CustomTabList} instance
|
||||
*/
|
||||
public abstract CustomTabList customTabList(ProxiedPlayer player);
|
||||
|
||||
/**
|
||||
* Gets the commands which are disabled and will not be run on this proxy.
|
||||
*
|
||||
* @return the set of disabled commands
|
||||
*/
|
||||
public abstract Collection<String> getDisabledCommands();
|
||||
}
|
||||
|
@@ -12,7 +12,7 @@ public interface ReconnectHandler
|
||||
* @param player the connecting player
|
||||
* @return the server to connect to
|
||||
*/
|
||||
public ServerInfo getServer(ProxiedPlayer player);
|
||||
ServerInfo getServer(ProxiedPlayer player);
|
||||
|
||||
/**
|
||||
* Save the server of this player before they disconnect so it can be
|
||||
@@ -20,12 +20,20 @@ public interface ReconnectHandler
|
||||
*
|
||||
* @param player the player to save
|
||||
*/
|
||||
public void setServer(ProxiedPlayer player);
|
||||
void setServer(ProxiedPlayer player); // TOOD: String + String arguments?
|
||||
|
||||
/**
|
||||
* Save all pending reconnect locations. Whilst not used for database
|
||||
* connections, this method will be called at a predefined interval to allow
|
||||
* the saving of reconnect files.
|
||||
*/
|
||||
public void save();
|
||||
void save();
|
||||
|
||||
/**
|
||||
* Close all connections indicating that the proxy is about to shutdown and
|
||||
* all data should be saved. No new requests will be made after this method
|
||||
* has been called.
|
||||
*
|
||||
*/
|
||||
void close();
|
||||
}
|
||||
|
@@ -43,6 +43,15 @@ public interface ConfigurationAdapter
|
||||
*/
|
||||
public boolean getBoolean(String path, boolean def);
|
||||
|
||||
/**
|
||||
* Get a list from the specified path.
|
||||
*
|
||||
* @param path the path to retrieve the list form.
|
||||
* @param def the default value
|
||||
* @return the retrieved list
|
||||
*/
|
||||
public Collection<?> getList(String path, Collection<?> def);
|
||||
|
||||
/**
|
||||
* Get the configuration all servers which may be accessible via the proxy.
|
||||
*
|
||||
|
@@ -3,6 +3,7 @@ package net.md_5.bungee.api.config;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Map;
|
||||
import lombok.Data;
|
||||
import net.md_5.bungee.api.tab.TabListHandler;
|
||||
|
||||
/**
|
||||
* Class representing the configuration of a server listener. Used for allowing
|
||||
@@ -32,6 +33,11 @@ public class ListenerInfo
|
||||
* Name of the server which users will be taken to by default.
|
||||
*/
|
||||
private final String defaultServer;
|
||||
/**
|
||||
* Name of the server which users will be taken when current server goes
|
||||
* down.
|
||||
*/
|
||||
private final String fallbackServer;
|
||||
/**
|
||||
* Whether reconnect locations will be used, or else the user is simply
|
||||
* transferred to the default server on connect.
|
||||
@@ -42,4 +48,17 @@ public class ListenerInfo
|
||||
* transferred depending on the host they connect to.
|
||||
*/
|
||||
private final Map<String, String> forcedHosts;
|
||||
/**
|
||||
* Class used to build tab lists for this player.
|
||||
*/
|
||||
private final Class<? extends TabListHandler> tabList;
|
||||
/**
|
||||
* Whether to set the local address when connecting to servers.
|
||||
*/
|
||||
private final boolean setLocalAddress;
|
||||
/**
|
||||
* Whether to pass the ping through when we can reliably get the target
|
||||
* server (force default server).
|
||||
*/
|
||||
private final boolean pingPassthrough;
|
||||
}
|
||||
|
@@ -1,69 +1,56 @@
|
||||
package net.md_5.bungee.api.config;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.Synchronized;
|
||||
import net.md_5.bungee.api.Callback;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.ServerPing;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
/**
|
||||
* Class used to represent a server to connect to.
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public abstract class ServerInfo
|
||||
public interface ServerInfo
|
||||
{
|
||||
|
||||
/**
|
||||
* Name this server displays as.
|
||||
*/
|
||||
private final String name;
|
||||
/**
|
||||
* Connectable address of this server.
|
||||
*/
|
||||
private final InetSocketAddress address;
|
||||
/**
|
||||
* Players connected to a server defined by these properties.
|
||||
*/
|
||||
private final Collection<ProxiedPlayer> players = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Add a player to the internal set of this server.
|
||||
* Get the name of this server.
|
||||
*
|
||||
* @param player the player to add
|
||||
* @return the configured name for this server address
|
||||
*/
|
||||
@Synchronized("players")
|
||||
public void addPlayer(ProxiedPlayer player)
|
||||
{
|
||||
players.add( player );
|
||||
}
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Remove a player form the internal set of this server.
|
||||
* Gets the connectable host + port pair for this server. Implementations
|
||||
* expect this to be used as the unique identifier per each instance of this
|
||||
* class.
|
||||
*
|
||||
* @param player the player to remove
|
||||
* @return the IP and port pair for this server
|
||||
*/
|
||||
@Synchronized("players")
|
||||
public void removePlayer(ProxiedPlayer player)
|
||||
{
|
||||
players.remove( player );
|
||||
}
|
||||
InetSocketAddress getAddress();
|
||||
|
||||
/**
|
||||
* Get the set of all players on this server.
|
||||
*
|
||||
* @return an unmodifiable collection of all players on this server
|
||||
*/
|
||||
@Synchronized("players")
|
||||
public Collection<ProxiedPlayer> getPlayers()
|
||||
{
|
||||
return Collections.unmodifiableCollection( players );
|
||||
}
|
||||
Collection<ProxiedPlayer> getPlayers();
|
||||
|
||||
/**
|
||||
* Returns the MOTD which should be used when this server is a forced host.
|
||||
*
|
||||
* @return the motd
|
||||
*/
|
||||
String getMotd();
|
||||
|
||||
/**
|
||||
* Whether the player can access this server. It will only return false when
|
||||
* the player has no permission and this server is restricted.
|
||||
*
|
||||
* @param sender the player to check access for
|
||||
* @return whether access is granted to this server
|
||||
*/
|
||||
boolean canAccess(CommandSender sender);
|
||||
|
||||
/**
|
||||
* Send data by any available means to this server.
|
||||
@@ -71,12 +58,12 @@ public abstract class ServerInfo
|
||||
* @param channel the channel to send this data via
|
||||
* @param data the data to send
|
||||
*/
|
||||
public abstract void sendData(String channel, byte[] data);
|
||||
void sendData(String channel, byte[] data);
|
||||
|
||||
/**
|
||||
* Asynchronously gets the current player count on this server.
|
||||
*
|
||||
* @param callback the callback to call when the count has been retrieved.
|
||||
*/
|
||||
public abstract void ping(Callback<ServerPing> callback);
|
||||
void ping(Callback<ServerPing> callback);
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package net.md_5.bungee.api.connection;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import net.md_5.bungee.protocol.packet.DefinedPacket;
|
||||
|
||||
/**
|
||||
* A proxy connection is defined as a connection directly connected to a socket.
|
||||
@@ -15,5 +16,33 @@ public interface Connection
|
||||
*
|
||||
* @return the remote address
|
||||
*/
|
||||
public InetSocketAddress getAddress();
|
||||
InetSocketAddress getAddress();
|
||||
|
||||
/**
|
||||
* Disconnects this end of the connection for the specified reason. If this
|
||||
* is an {@link ProxiedPlayer} the respective server connection will be
|
||||
* closed too.
|
||||
*
|
||||
* @param reason the reason shown to the player / sent to the server on
|
||||
* disconnect
|
||||
*/
|
||||
void disconnect(String reason);
|
||||
|
||||
/**
|
||||
* Get the unsafe methods of this class.
|
||||
*
|
||||
* @return the unsafe method interface
|
||||
*/
|
||||
Unsafe unsafe();
|
||||
|
||||
interface Unsafe
|
||||
{
|
||||
|
||||
/**
|
||||
* Send a packet to this connection.
|
||||
*
|
||||
* @param packet the packet to send
|
||||
*/
|
||||
void sendPacket(DefinedPacket packet);
|
||||
}
|
||||
}
|
||||
|
@@ -30,14 +30,6 @@ public interface PendingConnection extends Connection
|
||||
*/
|
||||
public InetSocketAddress getVirtualHost();
|
||||
|
||||
/**
|
||||
* Completely kick this user from the proxy and all of its child
|
||||
* connections.
|
||||
*
|
||||
* @param reason the disconnect reason displayed to the player
|
||||
*/
|
||||
public void disconnect(String reason);
|
||||
|
||||
/**
|
||||
* Get the listener that accepted this connection.
|
||||
*
|
||||
|
@@ -2,6 +2,7 @@ package net.md_5.bungee.api.connection;
|
||||
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.tab.TabListHandler;
|
||||
|
||||
/**
|
||||
* Represents a player who's connection is being connected to somewhere else,
|
||||
@@ -15,7 +16,7 @@ public interface ProxiedPlayer extends Connection, CommandSender
|
||||
*
|
||||
* @return the players current display name
|
||||
*/
|
||||
public String getDisplayName();
|
||||
String getDisplayName();
|
||||
|
||||
/**
|
||||
* Sets this players display name to be used as their nametag and tab list
|
||||
@@ -23,7 +24,7 @@ public interface ProxiedPlayer extends Connection, CommandSender
|
||||
*
|
||||
* @param name the name to set
|
||||
*/
|
||||
public void setDisplayName(String name);
|
||||
void setDisplayName(String name);
|
||||
|
||||
/**
|
||||
* Connects / transfers this user to the specified connection, gracefully
|
||||
@@ -32,28 +33,21 @@ public interface ProxiedPlayer extends Connection, CommandSender
|
||||
*
|
||||
* @param target the new server to connect to
|
||||
*/
|
||||
public void connect(ServerInfo target);
|
||||
void connect(ServerInfo target);
|
||||
|
||||
/**
|
||||
* Gets the server this player is connected to.
|
||||
*
|
||||
* @return the server this player is connected to
|
||||
*/
|
||||
public Server getServer();
|
||||
Server getServer();
|
||||
|
||||
/**
|
||||
* Gets the ping time between the proxy and this connection.
|
||||
*
|
||||
* @return the current ping time
|
||||
*/
|
||||
public int getPing();
|
||||
|
||||
/**
|
||||
* Disconnect (remove) this player from the proxy with the specified reason.
|
||||
*
|
||||
* @param reason the reason displayed to the player
|
||||
*/
|
||||
public void disconnect(String reason);
|
||||
int getPing();
|
||||
|
||||
/**
|
||||
* Send a plugin message to this player.
|
||||
@@ -61,12 +55,48 @@ public interface ProxiedPlayer extends Connection, CommandSender
|
||||
* @param channel the channel to send this data via
|
||||
* @param data the data to send
|
||||
*/
|
||||
public void sendData(String channel, byte[] data);
|
||||
void sendData(String channel, byte[] data);
|
||||
|
||||
/**
|
||||
* Get the pending connection that belongs to this player.
|
||||
*
|
||||
* @return the pending connection that this player used
|
||||
*/
|
||||
public PendingConnection getPendingConnection();
|
||||
PendingConnection getPendingConnection();
|
||||
|
||||
/**
|
||||
* Make this player chat (say something), to the server he is currently on.
|
||||
*
|
||||
* @param message the message to say
|
||||
*/
|
||||
void chat(String message);
|
||||
|
||||
/**
|
||||
* Sets the new tab list for the user. At this stage it is not advisable to
|
||||
* change after the user has logged in!
|
||||
*
|
||||
* @param list the new list
|
||||
*/
|
||||
void setTabList(TabListHandler list);
|
||||
|
||||
/**
|
||||
* Get the current tab list.
|
||||
*
|
||||
* @return the tab list in use by this user
|
||||
*/
|
||||
TabListHandler getTabList();
|
||||
|
||||
/**
|
||||
* Get the server which this player will be sent to next time the log in.
|
||||
*
|
||||
* @return the server, or null if default
|
||||
*/
|
||||
ServerInfo getReconnectServer();
|
||||
|
||||
/**
|
||||
* Set the server which this player will be sent to next time the log in.
|
||||
*
|
||||
* @param server the server to set
|
||||
*/
|
||||
void setReconnectServer(ServerInfo server);
|
||||
}
|
||||
|
@@ -1,7 +1,5 @@
|
||||
package net.md_5.bungee.api.connection;
|
||||
|
||||
import net.md_5.bungee.api.Callback;
|
||||
import net.md_5.bungee.api.ServerPing;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
|
||||
/**
|
||||
@@ -24,14 +22,4 @@ public interface Server extends Connection
|
||||
* @param data the data to send
|
||||
*/
|
||||
public abstract void sendData(String channel, byte[] data);
|
||||
|
||||
/**
|
||||
* Asynchronously gets the current player count on this server.
|
||||
*
|
||||
* @param callback the callback to call when the count has been retrieved.
|
||||
* @deprecated use the corresponding method in {@link ServerInfo} for
|
||||
* clarity
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract void ping(Callback<ServerPing> callback);
|
||||
}
|
||||
|
75
api/src/main/java/net/md_5/bungee/api/event/AsyncEvent.java
Normal file
75
api/src/main/java/net/md_5/bungee/api/event/AsyncEvent.java
Normal file
@@ -0,0 +1,75 @@
|
||||
package net.md_5.bungee.api.event;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import net.md_5.bungee.api.Callback;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* Represents an event which depends on the result of asynchronous operations.
|
||||
*
|
||||
* @param <T> Type of this event
|
||||
*/
|
||||
@Data
|
||||
@ToString(callSuper = true)
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class AsyncEvent<T> extends Event
|
||||
{
|
||||
|
||||
private final Callback<T> done;
|
||||
private final Set<Plugin> intents = Collections.newSetFromMap( new ConcurrentHashMap<Plugin, Boolean>() );
|
||||
private final AtomicBoolean fired = new AtomicBoolean();
|
||||
private final AtomicInteger latch = new AtomicInteger();
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void postCall()
|
||||
{
|
||||
fired.set( true );
|
||||
if ( latch.get() == 0 )
|
||||
{
|
||||
done.done( (T) this, null );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an intent that this plugin will continue to perform work on a
|
||||
* background task, and wishes to let the event proceed once the registered
|
||||
* background task has completed.
|
||||
*
|
||||
* @param plugin the plugin registering this intent
|
||||
*/
|
||||
public void registerIntent(Plugin plugin)
|
||||
{
|
||||
Preconditions.checkState( !fired.get(), "Event %s has already been fired", this );
|
||||
Preconditions.checkState( !intents.contains( plugin ), "Plugin %s already registered intent for event %s", plugin, this );
|
||||
|
||||
intents.add( plugin );
|
||||
latch.incrementAndGet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this event that this plugin has done all its required processing
|
||||
* and wishes to let the event proceed.
|
||||
*
|
||||
* @param plugin a plugin which has an intent registered for this event
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void completeIntent(Plugin plugin)
|
||||
{
|
||||
Preconditions.checkState( intents.contains( plugin ), "Plugin %s has not registered intent for event %s", plugin, this );
|
||||
intents.remove( plugin );
|
||||
if ( latch.decrementAndGet() == 0 && fired.get() )
|
||||
{
|
||||
done.done( (T) this, null );
|
||||
}
|
||||
}
|
||||
}
|
@@ -30,4 +30,14 @@ public class ChatEvent extends TargetedEvent implements Cancellable
|
||||
super( sender, receiver );
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this message is valid as a command
|
||||
*
|
||||
* @return if this message is a command
|
||||
*/
|
||||
public boolean isCommand()
|
||||
{
|
||||
return message.length() > 0 && message.charAt( 0 ) == '/';
|
||||
}
|
||||
}
|
||||
|
@@ -3,9 +3,9 @@ package net.md_5.bungee.api.event;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import net.md_5.bungee.api.Callback;
|
||||
import net.md_5.bungee.api.connection.PendingConnection;
|
||||
import net.md_5.bungee.api.plugin.Cancellable;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
/**
|
||||
* Event called to represent a player logging in.
|
||||
@@ -13,7 +13,7 @@ import net.md_5.bungee.api.plugin.Event;
|
||||
@Data
|
||||
@ToString(callSuper = false)
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class LoginEvent extends Event implements Cancellable
|
||||
public class LoginEvent extends AsyncEvent<LoginEvent> implements Cancellable
|
||||
{
|
||||
|
||||
/**
|
||||
@@ -28,4 +28,10 @@ public class LoginEvent extends Event implements Cancellable
|
||||
* Connection attempting to login.
|
||||
*/
|
||||
private final PendingConnection connection;
|
||||
|
||||
public LoginEvent(PendingConnection connection, Callback<LoginEvent> done)
|
||||
{
|
||||
super( done );
|
||||
this.connection = connection;
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,40 @@
|
||||
package net.md_5.bungee.api.event;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
/**
|
||||
* Called when the permission of a CommandSender is checked.
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@ToString(callSuper = false)
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class PermissionCheckEvent extends Event
|
||||
{
|
||||
|
||||
/**
|
||||
* The command sender being checked for a permission.
|
||||
*/
|
||||
private final CommandSender sender;
|
||||
/**
|
||||
* The permission to check.
|
||||
*/
|
||||
private final String permission;
|
||||
/**
|
||||
* The outcome of this permission check.
|
||||
*/
|
||||
@Getter(AccessLevel.NONE)
|
||||
private boolean hasPermission;
|
||||
|
||||
public boolean hasPermission()
|
||||
{
|
||||
return hasPermission;
|
||||
}
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
package net.md_5.bungee.api.event;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
/**
|
||||
* Event called as soon as a connection has an {@link ProxiedPlayer} and is
|
||||
* ready to be connected to a server.
|
||||
*/
|
||||
@Data
|
||||
@ToString(callSuper = false)
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class PostLoginEvent extends Event
|
||||
{
|
||||
|
||||
/**
|
||||
* The player involved with this event.
|
||||
*/
|
||||
private final ProxiedPlayer player;
|
||||
}
|
@@ -1,18 +1,17 @@
|
||||
package net.md_5.bungee.api.event;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Cancellable;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@ToString(callSuper = false)
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class ServerConnectEvent extends Event
|
||||
public class ServerConnectEvent extends Event implements Cancellable
|
||||
{
|
||||
|
||||
/**
|
||||
@@ -23,4 +22,14 @@ public class ServerConnectEvent extends Event
|
||||
* Server the player will be connected to.
|
||||
*/
|
||||
private ServerInfo target;
|
||||
/**
|
||||
* Cancelled state.
|
||||
*/
|
||||
private boolean cancelled;
|
||||
|
||||
public ServerConnectEvent(ProxiedPlayer player, ServerInfo target)
|
||||
{
|
||||
this.player = player;
|
||||
this.target = target;
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,59 @@
|
||||
package net.md_5.bungee.api.event;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Cancellable;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
/**
|
||||
* Represents a player getting kicked from a server.
|
||||
*/
|
||||
@Data
|
||||
@ToString(callSuper = false)
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class ServerKickEvent extends Event implements Cancellable
|
||||
{
|
||||
|
||||
/**
|
||||
* Cancelled status.
|
||||
*/
|
||||
private boolean cancelled;
|
||||
/**
|
||||
* Player being kicked.
|
||||
*/
|
||||
private final ProxiedPlayer player;
|
||||
/**
|
||||
* Kick reason.
|
||||
*/
|
||||
private String kickReason;
|
||||
/**
|
||||
* Server to send player to if this event is cancelled.
|
||||
*/
|
||||
private ServerInfo cancelServer;
|
||||
/**
|
||||
* State in which the kick occured.
|
||||
*/
|
||||
private State state;
|
||||
|
||||
public enum State
|
||||
{
|
||||
|
||||
CONNECTING, CONNECTED, UNKNOWN;
|
||||
}
|
||||
|
||||
public ServerKickEvent(ProxiedPlayer player, String kickReason, ServerInfo cancelServer)
|
||||
{
|
||||
this( player, kickReason, cancelServer, State.UNKNOWN );
|
||||
}
|
||||
|
||||
public ServerKickEvent(ProxiedPlayer player, String kickReason, ServerInfo cancelServer, State state)
|
||||
{
|
||||
this.player = player;
|
||||
this.kickReason = kickReason;
|
||||
this.cancelServer = cancelServer;
|
||||
this.state = state;
|
||||
}
|
||||
}
|
@@ -0,0 +1,22 @@
|
||||
package net.md_5.bungee.api.event;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
|
||||
/**
|
||||
* Called when a player has changed servers.
|
||||
*/
|
||||
@Data
|
||||
@ToString(callSuper = false)
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class ServerSwitchEvent extends Event
|
||||
{
|
||||
|
||||
/**
|
||||
* Player whom the server is for.
|
||||
*/
|
||||
private final ProxiedPlayer player;
|
||||
}
|
@@ -4,5 +4,12 @@ package net.md_5.bungee.api.plugin;
|
||||
* Dummy class which all callable events must extend.
|
||||
*/
|
||||
public abstract class Event
|
||||
{
|
||||
|
||||
/**
|
||||
* Method called after this event has been dispatched to all handlers.
|
||||
*/
|
||||
public void postCall()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,10 @@
|
||||
package net.md_5.bungee.api.plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.util.logging.Logger;
|
||||
import lombok.Getter;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.config.ConfigurationAdapter;
|
||||
|
||||
/**
|
||||
@@ -12,6 +16,12 @@ public class Plugin
|
||||
|
||||
@Getter
|
||||
private PluginDescription description;
|
||||
@Getter
|
||||
private ProxyServer proxy;
|
||||
@Getter
|
||||
private File file;
|
||||
@Getter
|
||||
private Logger logger;
|
||||
|
||||
/**
|
||||
* Called when the plugin has just been loaded. Most of the proxy will not
|
||||
@@ -36,13 +46,41 @@ public class Plugin
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the data folder where this plugin may store arbitrary data. It will
|
||||
* be a child of {@link ProxyServer#getPluginsFolder()}.
|
||||
*
|
||||
* @return the data folder of this plugin
|
||||
*/
|
||||
public final File getDataFolder()
|
||||
{
|
||||
return new File( getProxy().getPluginsFolder(), getDescription().getName() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a resource from within this plugins jar or container. Care must be
|
||||
* taken to close the returned stream.
|
||||
*
|
||||
* @param name the full path name of this resource
|
||||
* @return the stream for getting this resource, or null if it does not
|
||||
* exist
|
||||
*/
|
||||
public final InputStream getResourceAsStream(String name)
|
||||
{
|
||||
return getClass().getClassLoader().getResourceAsStream( name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the loader to initialize the fields in this plugin.
|
||||
*
|
||||
* @param description the description that describes this plugin
|
||||
* @param jarfile this plugins jar or container
|
||||
*/
|
||||
final void init(PluginDescription description)
|
||||
final void init(ProxyServer proxy, PluginDescription description)
|
||||
{
|
||||
this.proxy = proxy;
|
||||
this.description = description;
|
||||
this.file = description.getFile();
|
||||
this.logger = new PluginLogger( this );
|
||||
}
|
||||
}
|
||||
|
@@ -2,13 +2,18 @@ package net.md_5.bungee.api.plugin;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
public class PluginClassloader extends URLClassLoader
|
||||
{
|
||||
|
||||
private static final Set<PluginClassloader> allLoaders = new HashSet<>();
|
||||
private static final Set<PluginClassloader> allLoaders = new CopyOnWriteArraySet<>();
|
||||
|
||||
static
|
||||
{
|
||||
ClassLoader.registerAsParallelCapable();
|
||||
}
|
||||
|
||||
public PluginClassloader(URL[] urls)
|
||||
{
|
||||
|
@@ -1,12 +1,17 @@
|
||||
package net.md_5.bungee.api.plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* POJO representing the plugin.yml file.
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class PluginDescription
|
||||
{
|
||||
@@ -27,8 +32,12 @@ public class PluginDescription
|
||||
* Plugin author.
|
||||
*/
|
||||
private String author;
|
||||
|
||||
public PluginDescription()
|
||||
{
|
||||
}
|
||||
/**
|
||||
* Plugin hard dependencies.
|
||||
*/
|
||||
private Set<String> depends = new HashSet<>();
|
||||
/**
|
||||
* File we were loaded from.
|
||||
*/
|
||||
private File file = null;
|
||||
}
|
||||
|
@@ -0,0 +1,24 @@
|
||||
package net.md_5.bungee.api.plugin;
|
||||
|
||||
import java.util.logging.LogRecord;
|
||||
import java.util.logging.Logger;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
|
||||
public class PluginLogger extends Logger
|
||||
{
|
||||
|
||||
private String pluginName;
|
||||
|
||||
protected PluginLogger(Plugin plugin)
|
||||
{
|
||||
super( plugin.getClass().getCanonicalName(), null );
|
||||
pluginName = "[" + plugin.getDescription().getName() + "] ";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(LogRecord logRecord)
|
||||
{
|
||||
logRecord.setMessage( pluginName + logRecord.getMessage() );
|
||||
ProxyServer.getInstance().getLogger().log( logRecord );
|
||||
}
|
||||
}
|
@@ -1,51 +1,75 @@
|
||||
package net.md_5.bungee.api.plugin;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Stack;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Pattern;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.event.EventBus;
|
||||
import net.md_5.bungee.event.EventHandler;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
/**
|
||||
* Class to manage bridging between plugin duties and implementation duties, for
|
||||
* example event handling and plugin management.
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class PluginManager
|
||||
{
|
||||
|
||||
private static final Pattern argsSplit = Pattern.compile( " " );
|
||||
/*========================================================================*/
|
||||
private final ProxyServer proxy;
|
||||
/*========================================================================*/
|
||||
private final Yaml yaml = new Yaml();
|
||||
private final EventBus eventBus = new EventBus();
|
||||
private final Map<String, Plugin> plugins = new HashMap<>();
|
||||
private final EventBus eventBus;
|
||||
private final Map<String, Plugin> plugins = new LinkedHashMap<>();
|
||||
private final Map<String, Command> commandMap = new HashMap<>();
|
||||
private Map<String, PluginDescription> toLoad = new HashMap<>();
|
||||
private Multimap<Plugin, Command> commandsByPlugin = ArrayListMultimap.create();
|
||||
private Multimap<Plugin, Listener> listenersByPlugin = ArrayListMultimap.create();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public PluginManager(ProxyServer proxy)
|
||||
{
|
||||
this.proxy = proxy;
|
||||
eventBus = new EventBus( proxy.getLogger() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a command so that it may be executed.
|
||||
*
|
||||
* @param plugin the plugin owning this command
|
||||
* @param command the command to register
|
||||
*/
|
||||
public void registerCommand(Command command)
|
||||
public void registerCommand(Plugin plugin, Command command)
|
||||
{
|
||||
commandMap.put( command.getName().toLowerCase(), command );
|
||||
for ( String alias : command.getAliases() )
|
||||
{
|
||||
commandMap.put( alias.toLowerCase(), command );
|
||||
}
|
||||
commandsByPlugin.put( plugin, command );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,6 +80,26 @@ public class PluginManager
|
||||
public void unregisterCommand(Command command)
|
||||
{
|
||||
commandMap.values().remove( command );
|
||||
commandsByPlugin.values().remove( command );
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister all commands owned by a {@link Plugin}
|
||||
*
|
||||
* @param plugin the plugin to register the commands of
|
||||
*/
|
||||
public void unregisterCommands(Plugin plugin)
|
||||
{
|
||||
for ( Iterator<Command> it = commandsByPlugin.get( plugin ).iterator(); it.hasNext(); )
|
||||
{
|
||||
commandMap.values().remove( it.next() );
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean dispatchCommand(CommandSender sender, String commandLine)
|
||||
{
|
||||
return dispatchCommand( sender, commandLine, null );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,10 +110,21 @@ public class PluginManager
|
||||
* arguments
|
||||
* @return whether the command was handled
|
||||
*/
|
||||
public boolean dispatchCommand(CommandSender sender, String commandLine)
|
||||
public boolean dispatchCommand(CommandSender sender, String commandLine, List<String> tabResults)
|
||||
{
|
||||
String[] split = argsSplit.split( commandLine );
|
||||
Command command = commandMap.get( split[0].toLowerCase() );
|
||||
// Check for chat that only contains " "
|
||||
if ( split.length == 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
String commandName = split[0].toLowerCase();
|
||||
if ( proxy.getDisabledCommands().contains( commandName ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Command command = commandMap.get( commandName );
|
||||
if ( command == null )
|
||||
{
|
||||
return false;
|
||||
@@ -78,14 +133,23 @@ public class PluginManager
|
||||
String permission = command.getPermission();
|
||||
if ( permission != null && !permission.isEmpty() && !sender.hasPermission( permission ) )
|
||||
{
|
||||
sender.sendMessage( ChatColor.RED + "You do not have permission to execute this command!" );
|
||||
sender.sendMessage( proxy.getTranslation( "no_permission" ) );
|
||||
return true;
|
||||
}
|
||||
|
||||
String[] args = Arrays.copyOfRange( split, 1, split.length );
|
||||
try
|
||||
{
|
||||
if ( tabResults == null )
|
||||
{
|
||||
command.execute( sender, args );
|
||||
} else if ( command instanceof TabExecutor )
|
||||
{
|
||||
for ( String s : ( (TabExecutor) command ).onTabComplete( sender, args ) )
|
||||
{
|
||||
tabResults.add( s );
|
||||
}
|
||||
}
|
||||
} catch ( Exception ex )
|
||||
{
|
||||
sender.sendMessage( ChatColor.RED + "An internal error occurred whilst executing this command, please check the console log for details." );
|
||||
@@ -115,65 +179,114 @@ public class PluginManager
|
||||
return plugins.get( name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable all plugins by calling the {@link Plugin#onEnable()} method.
|
||||
*/
|
||||
public void enablePlugins()
|
||||
public void loadAndEnablePlugins()
|
||||
{
|
||||
for ( Map.Entry<String, Plugin> entry : plugins.entrySet() )
|
||||
Map<PluginDescription, Boolean> pluginStatuses = new HashMap<>();
|
||||
for ( Map.Entry<String, PluginDescription> entry : toLoad.entrySet() )
|
||||
{
|
||||
PluginDescription plugin = entry.getValue();
|
||||
if ( !enablePlugin( pluginStatuses, new Stack<PluginDescription>(), plugin ) )
|
||||
{
|
||||
ProxyServer.getInstance().getLogger().warning( "Failed to enable " + entry.getKey() );
|
||||
}
|
||||
}
|
||||
toLoad.clear();
|
||||
toLoad = null;
|
||||
|
||||
for ( Plugin plugin : plugins.values() )
|
||||
{
|
||||
Plugin plugin = entry.getValue();
|
||||
try
|
||||
{
|
||||
plugin.onEnable();
|
||||
ProxyServer.getInstance().getLogger().log( Level.INFO, "Enabled plugin {0} version {1} by {2}", new Object[]
|
||||
{
|
||||
entry.getKey(), plugin.getDescription().getVersion(), plugin.getDescription().getAuthor()
|
||||
plugin.getDescription().getName(), plugin.getDescription().getVersion(), plugin.getDescription().getAuthor()
|
||||
} );
|
||||
} catch ( Exception ex )
|
||||
} catch ( Throwable t )
|
||||
{
|
||||
ProxyServer.getInstance().getLogger().log( Level.WARNING, "Exception encountered when loading plugin: " + entry.getKey(), ex );
|
||||
ProxyServer.getInstance().getLogger().log( Level.WARNING, "Exception encountered when loading plugin: " + plugin.getDescription().getName(), t );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a plugin from the specified file. This file must be in jar format.
|
||||
* This will not enable plugins, {@link #enablePlugins()} must be called.
|
||||
*
|
||||
* @param file the file to load from
|
||||
* @throws Exception Any exceptions encountered when loading a plugin from
|
||||
* this file.
|
||||
*/
|
||||
public void loadPlugin(File file) throws Exception
|
||||
private boolean enablePlugin(Map<PluginDescription, Boolean> pluginStatuses, Stack<PluginDescription> dependStack, PluginDescription plugin)
|
||||
{
|
||||
Preconditions.checkNotNull( file, "file" );
|
||||
Preconditions.checkArgument( file.isFile(), "Must load from file" );
|
||||
if ( pluginStatuses.containsKey( plugin ) )
|
||||
{
|
||||
return pluginStatuses.get( plugin );
|
||||
}
|
||||
|
||||
try ( JarFile jar = new JarFile( file ) )
|
||||
{
|
||||
JarEntry pdf = jar.getJarEntry( "plugin.yml" );
|
||||
Preconditions.checkNotNull( pdf, "Plugin must have a plugin.yml" );
|
||||
// success status
|
||||
boolean status = true;
|
||||
|
||||
try ( InputStream in = jar.getInputStream( pdf ) )
|
||||
// try to load dependencies first
|
||||
for ( String dependName : plugin.getDepends() )
|
||||
{
|
||||
PluginDescription depend = toLoad.get( dependName );
|
||||
Boolean dependStatus = ( depend != null ) ? pluginStatuses.get( depend ) : Boolean.FALSE;
|
||||
|
||||
if ( dependStatus == null )
|
||||
{
|
||||
if ( dependStack.contains( depend ) )
|
||||
{
|
||||
StringBuilder dependencyGraph = new StringBuilder();
|
||||
for ( PluginDescription element : dependStack )
|
||||
{
|
||||
dependencyGraph.append( element.getName() ).append( " -> " );
|
||||
}
|
||||
dependencyGraph.append( plugin.getName() ).append( " -> " ).append( dependName );
|
||||
ProxyServer.getInstance().getLogger().log( Level.WARNING, "Circular dependency detected: " + dependencyGraph );
|
||||
status = false;
|
||||
} else
|
||||
{
|
||||
dependStack.push( plugin );
|
||||
dependStatus = this.enablePlugin( pluginStatuses, dependStack, depend );
|
||||
dependStack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
if ( dependStatus == Boolean.FALSE )
|
||||
{
|
||||
ProxyServer.getInstance().getLogger().log( Level.WARNING, "{0} (required by {1}) is unavailable", new Object[]
|
||||
{
|
||||
String.valueOf( depend.getName() ), plugin.getName()
|
||||
} );
|
||||
status = false;
|
||||
}
|
||||
|
||||
if ( !status )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// do actual loading
|
||||
if ( status )
|
||||
{
|
||||
try
|
||||
{
|
||||
PluginDescription desc = yaml.loadAs( in, PluginDescription.class );
|
||||
URLClassLoader loader = new PluginClassloader( new URL[]
|
||||
{
|
||||
file.toURI().toURL()
|
||||
plugin.getFile().toURI().toURL()
|
||||
} );
|
||||
Class<?> main = loader.loadClass( desc.getMain() );
|
||||
Plugin plugin = (Plugin) main.getDeclaredConstructor().newInstance();
|
||||
Class<?> main = loader.loadClass( plugin.getMain() );
|
||||
Plugin clazz = (Plugin) main.getDeclaredConstructor().newInstance();
|
||||
|
||||
plugin.init( desc );
|
||||
plugins.put( desc.getName(), plugin );
|
||||
plugin.onLoad();
|
||||
clazz.init( proxy, plugin );
|
||||
plugins.put( plugin.getName(), clazz );
|
||||
clazz.onLoad();
|
||||
ProxyServer.getInstance().getLogger().log( Level.INFO, "Loaded plugin {0} version {1} by {2}", new Object[]
|
||||
{
|
||||
desc.getName(), desc.getVersion(), desc.getAuthor()
|
||||
plugin.getName(), plugin.getVersion(), plugin.getAuthor()
|
||||
} );
|
||||
} catch ( Throwable t )
|
||||
{
|
||||
proxy.getLogger().log( Level.WARNING, "Error enabling plugin " + plugin.getName(), t );
|
||||
}
|
||||
}
|
||||
|
||||
pluginStatuses.put( plugin, status );
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -181,7 +294,7 @@ public class PluginManager
|
||||
*
|
||||
* @param folder the folder to search for plugins in
|
||||
*/
|
||||
public void loadPlugins(File folder)
|
||||
public void detectPlugins(File folder)
|
||||
{
|
||||
Preconditions.checkNotNull( folder, "folder" );
|
||||
Preconditions.checkArgument( folder.isDirectory(), "Must load from a directory" );
|
||||
@@ -190,9 +303,17 @@ public class PluginManager
|
||||
{
|
||||
if ( file.isFile() && file.getName().endsWith( ".jar" ) )
|
||||
{
|
||||
try
|
||||
try ( JarFile jar = new JarFile( file ) )
|
||||
{
|
||||
loadPlugin( file );
|
||||
JarEntry pdf = jar.getJarEntry( "plugin.yml" );
|
||||
Preconditions.checkNotNull( pdf, "Plugin must have a plugin.yml" );
|
||||
|
||||
try ( InputStream in = jar.getInputStream( pdf ) )
|
||||
{
|
||||
PluginDescription desc = yaml.loadAs( in, PluginDescription.class );
|
||||
desc.setFile( file );
|
||||
toLoad.put( desc.getName(), desc );
|
||||
}
|
||||
} catch ( Exception ex )
|
||||
{
|
||||
ProxyServer.getInstance().getLogger().log( Level.WARNING, "Could not load plugin from file " + file, ex );
|
||||
@@ -211,19 +332,64 @@ public class PluginManager
|
||||
*/
|
||||
public <T extends Event> T callEvent(T event)
|
||||
{
|
||||
Preconditions.checkNotNull( event, "event" );
|
||||
|
||||
long start = System.nanoTime();
|
||||
eventBus.post( event );
|
||||
event.postCall();
|
||||
|
||||
long elapsed = start - System.nanoTime();
|
||||
if ( elapsed > 250000 )
|
||||
{
|
||||
ProxyServer.getInstance().getLogger().log( Level.WARNING, "Event {0} took more {1}ns to process!", new Object[]
|
||||
{
|
||||
event, elapsed
|
||||
} );
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a {@link Listener} for receiving called events. Methods in this
|
||||
* Object which wish to receive events must be annotated with the
|
||||
* {@link Subscribe} annotation.
|
||||
* {@link EventHandler} annotation.
|
||||
*
|
||||
* @param plugin the owning plugin
|
||||
* @param listener the listener to register events for
|
||||
*/
|
||||
public void registerListener(Listener listener)
|
||||
public void registerListener(Plugin plugin, Listener listener)
|
||||
{
|
||||
for ( Method method : listener.getClass().getDeclaredMethods() )
|
||||
{
|
||||
Preconditions.checkArgument( !method.isAnnotationPresent( Subscribe.class ),
|
||||
"Listener %s has registered using deprecated subscribe annotation! Please update to @EventHandler.", listener );
|
||||
}
|
||||
eventBus.register( listener );
|
||||
listenersByPlugin.put( plugin, listener );
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a {@link Listener} so that the events do not reach it anymore.
|
||||
*
|
||||
* @param listener the listener to unregister
|
||||
*/
|
||||
public void unregisterListener(Listener listener)
|
||||
{
|
||||
eventBus.unregister( listener );
|
||||
listenersByPlugin.values().remove( listener );
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister all of a Plugin's listener.
|
||||
*
|
||||
* @param plugin
|
||||
*/
|
||||
public void unregisterListeners(Plugin plugin)
|
||||
{
|
||||
for ( Iterator<Listener> it = listenersByPlugin.get( plugin ).iterator(); it.hasNext(); )
|
||||
{
|
||||
eventBus.unregister( it.next() );
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,10 @@
|
||||
package net.md_5.bungee.api.plugin;
|
||||
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
|
||||
|
||||
public interface TabExecutor
|
||||
{
|
||||
|
||||
public Iterable<String> onTabComplete(CommandSender sender, String[] args);
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
package net.md_5.bungee.api.scheduler;
|
||||
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* Represents a task scheduled for execution by the {@link TaskScheduler}.
|
||||
*/
|
||||
public interface ScheduledTask
|
||||
{
|
||||
|
||||
/**
|
||||
* Gets the unique ID of this task.
|
||||
*
|
||||
* @return this tasks ID
|
||||
*/
|
||||
int getId();
|
||||
|
||||
/**
|
||||
* Return the plugin which scheduled this task for execution.
|
||||
*
|
||||
* @return the owning plugin
|
||||
*/
|
||||
Plugin getOwner();
|
||||
|
||||
/**
|
||||
* Get the actual method which will be executed by this task.
|
||||
*
|
||||
* @return the {@link Runnable} behind this task
|
||||
*/
|
||||
Runnable getTask();
|
||||
|
||||
/**
|
||||
* Cancel this task to suppress subsequent executions.
|
||||
*/
|
||||
void cancel();
|
||||
}
|
@@ -0,0 +1,74 @@
|
||||
package net.md_5.bungee.api.scheduler;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* This interface represents a scheduler which may be used to queue, delay and
|
||||
* execute tasks in an asynchronous fashion.
|
||||
*/
|
||||
public interface TaskScheduler
|
||||
{
|
||||
|
||||
/**
|
||||
* Cancel a task to prevent it from executing, or if its a repeating task,
|
||||
* prevent its further execution.
|
||||
*
|
||||
* @param id the id of the task to cancel
|
||||
*/
|
||||
void cancel(int id);
|
||||
|
||||
/**
|
||||
* Cancel a task to prevent it from executing, or if its a repeating task,
|
||||
* prevent its further execution.
|
||||
*
|
||||
* @param task the task to cancel
|
||||
*/
|
||||
void cancel(ScheduledTask task);
|
||||
|
||||
/**
|
||||
* Cancel all tasks owned by this plugin, this preventing them from being
|
||||
* executed hereon in.
|
||||
*
|
||||
* @param plugin the plugin owning the tasks to be cancelled
|
||||
* @return the number of tasks cancelled by this method
|
||||
*/
|
||||
int cancel(Plugin plugin);
|
||||
|
||||
/**
|
||||
* Schedule a task to be executed asynchronously. The task will commence
|
||||
* running as soon as this method returns.
|
||||
*
|
||||
* @param owner the plugin owning this task
|
||||
* @param task the task to run
|
||||
* @return the scheduled task
|
||||
*/
|
||||
ScheduledTask runAsync(Plugin owner, Runnable task);
|
||||
|
||||
/**
|
||||
* Schedules a task to be executed asynchronously after the specified delay
|
||||
* is up.
|
||||
*
|
||||
* @param owner the plugin owning this task
|
||||
* @param task the task to run
|
||||
* @param delay the delay before this task will be executed
|
||||
* @param unit the unit in which the delay will be measured
|
||||
* @return the scheduled task
|
||||
*/
|
||||
ScheduledTask schedule(Plugin owner, Runnable task, long delay, TimeUnit unit);
|
||||
|
||||
/**
|
||||
* Schedules a task to be executed asynchronously after the specified delay
|
||||
* is up. The scheduled task will continue running at the specified
|
||||
* interval. The interval will not begin to count down until the last task
|
||||
* invocation is complete.
|
||||
*
|
||||
* @param owner the plugin owning this task
|
||||
* @param task the task to run
|
||||
* @param delay the delay in milliseconds before this task will be executed
|
||||
* @param period the interval before subsequent executions of this task
|
||||
* @param unit the unit in which the delay and period will be measured
|
||||
* @return the scheduled task
|
||||
*/
|
||||
ScheduledTask schedule(Plugin owner, Runnable task, long delay, long period, TimeUnit unit);
|
||||
}
|
20
api/src/main/java/net/md_5/bungee/api/score/Objective.java
Normal file
20
api/src/main/java/net/md_5/bungee/api/score/Objective.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package net.md_5.bungee.api.score;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Represents an objective entry.
|
||||
*/
|
||||
@Data
|
||||
public class Objective
|
||||
{
|
||||
|
||||
/**
|
||||
* Name of the objective.
|
||||
*/
|
||||
private final String name;
|
||||
/**
|
||||
* Value of the objective.
|
||||
*/
|
||||
private final String value; // displayName
|
||||
}
|
10
api/src/main/java/net/md_5/bungee/api/score/Position.java
Normal file
10
api/src/main/java/net/md_5/bungee/api/score/Position.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package net.md_5.bungee.api.score;
|
||||
|
||||
/**
|
||||
* Represents locations for a scoreboard to be displayed.
|
||||
*/
|
||||
public enum Position
|
||||
{
|
||||
|
||||
LIST, SIDEBAR, BELOW;
|
||||
}
|
24
api/src/main/java/net/md_5/bungee/api/score/Score.java
Normal file
24
api/src/main/java/net/md_5/bungee/api/score/Score.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package net.md_5.bungee.api.score;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Represents a scoreboard score entry.
|
||||
*/
|
||||
@Data
|
||||
public class Score
|
||||
{
|
||||
|
||||
/**
|
||||
* Name to be displayed in the list.
|
||||
*/
|
||||
private final String itemName; // Player
|
||||
/**
|
||||
* Unique name of the score.
|
||||
*/
|
||||
private final String scoreName; // Score
|
||||
/**
|
||||
* Value of the score.
|
||||
*/
|
||||
private final int value;
|
||||
}
|
100
api/src/main/java/net/md_5/bungee/api/score/Scoreboard.java
Normal file
100
api/src/main/java/net/md_5/bungee/api/score/Scoreboard.java
Normal file
@@ -0,0 +1,100 @@
|
||||
package net.md_5.bungee.api.score;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class Scoreboard
|
||||
{
|
||||
|
||||
/**
|
||||
* Unique name for this scoreboard.
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* Position of this scoreboard.
|
||||
*/
|
||||
private Position position;
|
||||
/**
|
||||
* Objectives for this scoreboard.
|
||||
*/
|
||||
private final Map<String, Objective> objectives = new HashMap<>();
|
||||
/**
|
||||
* Scores for this scoreboard.
|
||||
*/
|
||||
private final Map<String, Score> scores = new HashMap<>();
|
||||
/**
|
||||
* Teams on this board.
|
||||
*/
|
||||
private final Map<String, Team> teams = new HashMap<>();
|
||||
|
||||
public Collection<Objective> getObjectives()
|
||||
{
|
||||
return Collections.unmodifiableCollection( objectives.values() );
|
||||
}
|
||||
|
||||
public Collection<Score> getScores()
|
||||
{
|
||||
return Collections.unmodifiableCollection( scores.values() );
|
||||
}
|
||||
|
||||
public Collection<Team> getTeams()
|
||||
{
|
||||
return Collections.unmodifiableCollection( teams.values() );
|
||||
}
|
||||
|
||||
public void addObjective(Objective objective)
|
||||
{
|
||||
Preconditions.checkNotNull( objective, "objective" );
|
||||
Preconditions.checkArgument( !objectives.containsKey( objective.getName() ), "Objective %s already exists in this scoreboard", objective.getName() );
|
||||
objectives.put( objective.getName(), objective );
|
||||
}
|
||||
|
||||
public void addScore(Score score)
|
||||
{
|
||||
Preconditions.checkNotNull( score, "score" );
|
||||
scores.put( score.getItemName(), score );
|
||||
}
|
||||
|
||||
public void addTeam(Team team)
|
||||
{
|
||||
Preconditions.checkNotNull( team, "team" );
|
||||
Preconditions.checkArgument( !teams.containsKey( team.getName() ), "Team %s already exists in this scoreboard", team.getName() );
|
||||
teams.put( team.getName(), team );
|
||||
}
|
||||
|
||||
public Team getTeam(String name)
|
||||
{
|
||||
return teams.get( name );
|
||||
}
|
||||
|
||||
public void removeObjective(String objectiveName)
|
||||
{
|
||||
objectives.remove( objectiveName );
|
||||
}
|
||||
|
||||
public void removeScore(String scoreName)
|
||||
{
|
||||
scores.remove( scoreName );
|
||||
}
|
||||
|
||||
public void removeTeam(String teamName)
|
||||
{
|
||||
teams.remove( teamName );
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
name = null;
|
||||
position = null;
|
||||
objectives.clear();
|
||||
scores.clear();
|
||||
teams.clear();
|
||||
}
|
||||
}
|
36
api/src/main/java/net/md_5/bungee/api/score/Team.java
Normal file
36
api/src/main/java/net/md_5/bungee/api/score/Team.java
Normal file
@@ -0,0 +1,36 @@
|
||||
package net.md_5.bungee.api.score;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import lombok.Data;
|
||||
import lombok.NonNull;
|
||||
|
||||
@Data
|
||||
public class Team
|
||||
{
|
||||
|
||||
@NonNull
|
||||
private final String name;
|
||||
private String displayName;
|
||||
private String prefix;
|
||||
private String suffix;
|
||||
private boolean friendlyFire;
|
||||
private Set<String> players = new HashSet<>();
|
||||
|
||||
public Collection<String> getPlayers()
|
||||
{
|
||||
return Collections.unmodifiableSet( players );
|
||||
}
|
||||
|
||||
public void addPlayer(String name)
|
||||
{
|
||||
players.add( name );
|
||||
}
|
||||
|
||||
public void removePlayer(String name)
|
||||
{
|
||||
players.remove( name );
|
||||
}
|
||||
}
|
60
api/src/main/java/net/md_5/bungee/api/tab/CustomTabList.java
Normal file
60
api/src/main/java/net/md_5/bungee/api/tab/CustomTabList.java
Normal file
@@ -0,0 +1,60 @@
|
||||
package net.md_5.bungee.api.tab;
|
||||
|
||||
/**
|
||||
* Represents a custom tab list, which may have slots manipulated.
|
||||
*/
|
||||
public interface CustomTabList extends TabListHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* Blank out this tab list and update immediately.
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/**
|
||||
* Gets the columns in this list.
|
||||
*
|
||||
* @return the width of this list
|
||||
*/
|
||||
int getColumns();
|
||||
|
||||
/**
|
||||
* Gets the rows in this list.
|
||||
*
|
||||
* @return the height of this list
|
||||
*/
|
||||
int getRows();
|
||||
|
||||
/**
|
||||
* Get the total size of this list.
|
||||
*
|
||||
* @return {@link #getRows()} * {@link #getColumns()}
|
||||
*/
|
||||
int getSize();
|
||||
|
||||
/**
|
||||
* Set the text in the specified slot and update immediately.
|
||||
*
|
||||
* @param row the row to set
|
||||
* @param column the column to set
|
||||
* @param text the text to set
|
||||
* @return the padded text
|
||||
*/
|
||||
String setSlot(int row, int column, String text);
|
||||
|
||||
/**
|
||||
* Set the text in the specified slot.
|
||||
*
|
||||
* @param row the row to set
|
||||
* @param column the column to set
|
||||
* @param text the text to set
|
||||
* @param update whether or not to invoke {@link #update()} upon completion
|
||||
* @return the padded text
|
||||
*/
|
||||
String setSlot(int row, int column, String text, boolean update);
|
||||
|
||||
/**
|
||||
* Flush all queued changes to the user.
|
||||
*/
|
||||
void update();
|
||||
}
|
@@ -0,0 +1,39 @@
|
||||
package net.md_5.bungee.api.tab;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
@NoArgsConstructor
|
||||
public abstract class TabListAdapter implements TabListHandler
|
||||
{
|
||||
|
||||
@Getter
|
||||
private ProxiedPlayer player;
|
||||
|
||||
@Override
|
||||
public void init(ProxiedPlayer player)
|
||||
{
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnect()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnect()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServerChange()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPingChange(int ping)
|
||||
{
|
||||
}
|
||||
}
|
@@ -1,23 +1,30 @@
|
||||
package net.md_5.bungee.api;
|
||||
package net.md_5.bungee.api.tab;
|
||||
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
public interface TabListHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* Called so that this class may set member fields to keep track of its
|
||||
* internal state. You should not do any packet sending or manipulation of
|
||||
* the passed player, other than storing it.
|
||||
*
|
||||
* @param player the player to be associated with this list
|
||||
*/
|
||||
void init(ProxiedPlayer player);
|
||||
|
||||
/**
|
||||
* Called when this player first connects to the proxy.
|
||||
*/
|
||||
void onConnect();
|
||||
|
||||
/**
|
||||
* Called when a player first connects to the proxy.
|
||||
*
|
||||
* @param player the connecting player
|
||||
*/
|
||||
public void onConnect(ProxiedPlayer player);
|
||||
|
||||
/**
|
||||
* Called when a player changes their connected server.
|
||||
*
|
||||
* @param player the player who changed servers
|
||||
*/
|
||||
public void onServerChange(ProxiedPlayer player);
|
||||
void onServerChange();
|
||||
|
||||
/**
|
||||
* Called when a players ping changes. The new ping will have not updated in
|
||||
@@ -26,14 +33,14 @@ public interface TabListHandler
|
||||
* @param player the player who's ping changed
|
||||
* @param ping the player's new ping.
|
||||
*/
|
||||
public void onPingChange(ProxiedPlayer player, int ping);
|
||||
void onPingChange(int ping);
|
||||
|
||||
/**
|
||||
* Called when a player disconnects.
|
||||
*
|
||||
* @param player the disconnected player
|
||||
*/
|
||||
public void onDisconnect(ProxiedPlayer player);
|
||||
void onDisconnect();
|
||||
|
||||
/**
|
||||
* Called when a list update packet is sent from server to client.
|
||||
@@ -44,5 +51,5 @@ public interface TabListHandler
|
||||
* @param ping ping of the subject player
|
||||
* @return whether to send the packet to the client
|
||||
*/
|
||||
public boolean onListUpdate(ProxiedPlayer player, String name, boolean online, int ping);
|
||||
boolean onListUpdate(String name, boolean online, int ping);
|
||||
}
|
31
config/nb-configuration.xml
Normal file
31
config/nb-configuration.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project-shared-configuration>
|
||||
<!--
|
||||
This file contains additional configuration written by modules in the NetBeans IDE.
|
||||
The configuration is intended to be shared among all the users of project and
|
||||
therefore it is assumed to be part of version control checkout.
|
||||
Without this configuration present, some functionality in the IDE may be limited or fail altogether.
|
||||
-->
|
||||
<properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
|
||||
<!--
|
||||
Properties that influence various parts of the IDE, especially code formatting and the like.
|
||||
You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
|
||||
That way multiple projects can share the same settings (useful for formatting rules for example).
|
||||
Any value defined here will override the pom.xml file value but is only applicable to the current project.
|
||||
-->
|
||||
<org-netbeans-modules-editor-indent.CodeStyle.usedProfile>project</org-netbeans-modules-editor-indent.CodeStyle.usedProfile>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.classDeclBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.classDeclBracePlacement>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.otherBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.otherBracePlacement>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.methodDeclBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.methodDeclBracePlacement>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinMethodCallParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinMethodCallParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSwitchParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSwitchParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinCatchParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinCatchParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinTryParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinTryParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSynchronizedParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSynchronizedParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinArrayInitBrackets>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinArrayInitBrackets>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinWhileParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinWhileParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinIfParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinIfParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinForParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinForParens>
|
||||
</properties>
|
||||
</project-shared-configuration>
|
@@ -6,13 +6,13 @@
|
||||
<parent>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-parent</artifactId>
|
||||
<version>1.4.7-SNAPSHOT</version>
|
||||
<version>1.6.2-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-config</artifactId>
|
||||
<version>1.4.7-SNAPSHOT</version>
|
||||
<version>1.6.2-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>BungeeCord-Config</name>
|
||||
|
31
event/nb-configuration.xml
Normal file
31
event/nb-configuration.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project-shared-configuration>
|
||||
<!--
|
||||
This file contains additional configuration written by modules in the NetBeans IDE.
|
||||
The configuration is intended to be shared among all the users of project and
|
||||
therefore it is assumed to be part of version control checkout.
|
||||
Without this configuration present, some functionality in the IDE may be limited or fail altogether.
|
||||
-->
|
||||
<properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
|
||||
<!--
|
||||
Properties that influence various parts of the IDE, especially code formatting and the like.
|
||||
You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
|
||||
That way multiple projects can share the same settings (useful for formatting rules for example).
|
||||
Any value defined here will override the pom.xml file value but is only applicable to the current project.
|
||||
-->
|
||||
<org-netbeans-modules-editor-indent.CodeStyle.usedProfile>project</org-netbeans-modules-editor-indent.CodeStyle.usedProfile>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.classDeclBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.classDeclBracePlacement>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.otherBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.otherBracePlacement>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.methodDeclBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.methodDeclBracePlacement>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinMethodCallParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinMethodCallParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSwitchParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSwitchParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinCatchParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinCatchParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinTryParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinTryParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSynchronizedParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSynchronizedParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinArrayInitBrackets>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinArrayInitBrackets>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinWhileParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinWhileParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinIfParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinIfParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinForParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinForParens>
|
||||
</properties>
|
||||
</project-shared-configuration>
|
20
event/pom.xml
Normal file
20
event/pom.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-parent</artifactId>
|
||||
<version>1.6.2-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-event</artifactId>
|
||||
<version>1.6.2-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>BungeeCord-Event</name>
|
||||
<description>Generic java event dispatching API intended for use with BungeeCord</description>
|
||||
</project>
|
202
event/src/main/java/net/md_5/bungee/event/EventBus.java
Normal file
202
event/src/main/java/net/md_5/bungee/event/EventBus.java
Normal file
@@ -0,0 +1,202 @@
|
||||
package net.md_5.bungee.event;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class EventBus
|
||||
{
|
||||
|
||||
private final Map<Class<?>, Map<Byte, Map<Object, Method[]>>> byListenerAndPriority = new HashMap<>();
|
||||
private final Map<Class<?>, EventHandlerMethod[]> byEventBaked = new HashMap<>();
|
||||
private final ReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
private final Logger logger;
|
||||
|
||||
public EventBus()
|
||||
{
|
||||
this( null );
|
||||
}
|
||||
|
||||
public EventBus(Logger logger)
|
||||
{
|
||||
this.logger = ( logger == null ) ? Logger.getGlobal() : logger;
|
||||
}
|
||||
|
||||
public void post(Object event)
|
||||
{
|
||||
lock.readLock().lock();
|
||||
try
|
||||
{
|
||||
EventHandlerMethod[] handlers = byEventBaked.get( event.getClass() );
|
||||
if ( handlers != null )
|
||||
{
|
||||
for ( EventHandlerMethod method : handlers )
|
||||
{
|
||||
try
|
||||
{
|
||||
method.invoke( event );
|
||||
} catch ( IllegalAccessException ex )
|
||||
{
|
||||
throw new Error( "Method became inaccessible: " + event, ex );
|
||||
} catch ( IllegalArgumentException ex )
|
||||
{
|
||||
throw new Error( "Method rejected target/argument: " + event, ex );
|
||||
} catch ( InvocationTargetException ex )
|
||||
{
|
||||
logger.log( Level.WARNING, MessageFormat.format( "Error dispatching event {0} to listener {1}", event, method.getListener() ), ex.getCause() );
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally
|
||||
{
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private Map<Class<?>, Map<Byte, Set<Method>>> findHandlers(Object listener)
|
||||
{
|
||||
Map<Class<?>, Map<Byte, Set<Method>>> handler = new HashMap<>();
|
||||
for ( Method m : listener.getClass().getDeclaredMethods() )
|
||||
{
|
||||
EventHandler annotation = m.getAnnotation( EventHandler.class );
|
||||
if ( annotation != null )
|
||||
{
|
||||
Class<?>[] params = m.getParameterTypes();
|
||||
if ( params.length != 1 )
|
||||
{
|
||||
logger.log( Level.INFO, "Method {0} in class {1} annotated with {2} does not have single argument", new Object[]
|
||||
{
|
||||
m, listener.getClass(), annotation
|
||||
} );
|
||||
continue;
|
||||
}
|
||||
Map<Byte, Set<Method>> prioritiesMap = handler.get( params[0] );
|
||||
if ( prioritiesMap == null )
|
||||
{
|
||||
prioritiesMap = new HashMap<>();
|
||||
handler.put( params[0], prioritiesMap );
|
||||
}
|
||||
Set<Method> priority = prioritiesMap.get( annotation.priority() );
|
||||
if ( priority == null )
|
||||
{
|
||||
priority = new HashSet<>();
|
||||
prioritiesMap.put( annotation.priority(), priority );
|
||||
}
|
||||
priority.add( m );
|
||||
}
|
||||
}
|
||||
return handler;
|
||||
}
|
||||
|
||||
public void register(Object listener)
|
||||
{
|
||||
Map<Class<?>, Map<Byte, Set<Method>>> handler = findHandlers( listener );
|
||||
lock.writeLock().lock();
|
||||
try
|
||||
{
|
||||
for ( Map.Entry<Class<?>, Map<Byte, Set<Method>>> e : handler.entrySet() )
|
||||
{
|
||||
Map<Byte, Map<Object, Method[]>> prioritiesMap = byListenerAndPriority.get( e.getKey() );
|
||||
if ( prioritiesMap == null )
|
||||
{
|
||||
prioritiesMap = new HashMap<>();
|
||||
byListenerAndPriority.put( e.getKey(), prioritiesMap );
|
||||
}
|
||||
for ( Map.Entry<Byte, Set<Method>> entry : e.getValue().entrySet() )
|
||||
{
|
||||
Map<Object, Method[]> currentPriorityMap = prioritiesMap.get( entry.getKey() );
|
||||
if ( currentPriorityMap == null )
|
||||
{
|
||||
currentPriorityMap = new HashMap<>();
|
||||
prioritiesMap.put( entry.getKey(), currentPriorityMap );
|
||||
}
|
||||
Method[] baked = new Method[ entry.getValue().size() ];
|
||||
currentPriorityMap.put( listener, entry.getValue().toArray( baked ) );
|
||||
}
|
||||
bakeHandlers( e.getKey() );
|
||||
}
|
||||
} finally
|
||||
{
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void unregister(Object listener)
|
||||
{
|
||||
Map<Class<?>, Map<Byte, Set<Method>>> handler = findHandlers( listener );
|
||||
lock.writeLock().lock();
|
||||
try
|
||||
{
|
||||
for ( Map.Entry<Class<?>, Map<Byte, Set<Method>>> e : handler.entrySet() )
|
||||
{
|
||||
Map<Byte, Map<Object, Method[]>> prioritiesMap = byListenerAndPriority.get( e.getKey() );
|
||||
if ( prioritiesMap != null )
|
||||
{
|
||||
for ( Byte priority : e.getValue().keySet() )
|
||||
{
|
||||
Map<Object, Method[]> currentPriority = prioritiesMap.get( priority );
|
||||
if ( currentPriority != null )
|
||||
{
|
||||
currentPriority.remove( listener );
|
||||
if ( currentPriority.isEmpty() )
|
||||
{
|
||||
prioritiesMap.remove( priority );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( prioritiesMap.isEmpty() )
|
||||
{
|
||||
byListenerAndPriority.remove( e.getKey() );
|
||||
}
|
||||
}
|
||||
bakeHandlers( e.getKey() );
|
||||
}
|
||||
} finally
|
||||
{
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shouldn't be called without first locking the writeLock; intended for use
|
||||
* only inside {@link #register(java.lang.Object) register(Object)} or
|
||||
* {@link #unregister(java.lang.Object) unregister(Object)}.
|
||||
*/
|
||||
private void bakeHandlers(Class<?> eventClass)
|
||||
{
|
||||
Map<Byte, Map<Object, Method[]>> handlersByPriority = byListenerAndPriority.get( eventClass );
|
||||
if ( handlersByPriority != null )
|
||||
{
|
||||
List<EventHandlerMethod> handlersList = new ArrayList<>( handlersByPriority.size() * 2 );
|
||||
for ( byte value = Byte.MIN_VALUE; value < Byte.MAX_VALUE; value++ )
|
||||
{
|
||||
Map<Object, Method[]> handlersByListener = handlersByPriority.get( value );
|
||||
if ( handlersByListener != null )
|
||||
{
|
||||
for ( Map.Entry<Object, Method[]> listenerHandlers : handlersByListener.entrySet() )
|
||||
{
|
||||
for ( Method method : listenerHandlers.getValue() )
|
||||
{
|
||||
EventHandlerMethod ehm = new EventHandlerMethod( listenerHandlers.getKey(), method );
|
||||
handlersList.add( ehm );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
byEventBaked.put( eventClass, handlersList.toArray( new EventHandlerMethod[ handlersList.size() ] ) );
|
||||
} else
|
||||
{
|
||||
byEventBaked.put( eventClass, null );
|
||||
}
|
||||
}
|
||||
}
|
26
event/src/main/java/net/md_5/bungee/event/EventHandler.java
Normal file
26
event/src/main/java/net/md_5/bungee/event/EventHandler.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package net.md_5.bungee.event;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface EventHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* Define the priority of the event handler.
|
||||
* <p>
|
||||
* Event handlers are called in order of priority:
|
||||
* <ol>
|
||||
* <li>LOWEST</li>
|
||||
* <li>LOW</li>
|
||||
* <li>NORMAL</li>
|
||||
* <li>HIGH</li>
|
||||
* <li>HIGHEST</li>
|
||||
* </ol>
|
||||
*/
|
||||
byte priority() default EventPriority.NORMAL;
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
package net.md_5.bungee.event;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class EventHandlerMethod
|
||||
{
|
||||
|
||||
@Getter
|
||||
private final Object listener;
|
||||
@Getter
|
||||
private final Method method;
|
||||
|
||||
public void invoke(Object event) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
|
||||
{
|
||||
method.invoke( listener, event );
|
||||
}
|
||||
}
|
19
event/src/main/java/net/md_5/bungee/event/EventPriority.java
Normal file
19
event/src/main/java/net/md_5/bungee/event/EventPriority.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package net.md_5.bungee.event;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* Importance of the {@link EventHandler}. When executing an Event, the handlers
|
||||
* are called in order of their Priority.
|
||||
*/
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class EventPriority
|
||||
{
|
||||
|
||||
public static final byte LOWEST = -64;
|
||||
public static final byte LOW = -32;
|
||||
public static final byte NORMAL = 0;
|
||||
public static final byte HIGH = 32;
|
||||
public static final byte HIGHEST = 64;
|
||||
}
|
42
event/src/test/java/net/md_5/bungee/event/EventBusTest.java
Normal file
42
event/src/test/java/net/md_5/bungee/event/EventBusTest.java
Normal file
@@ -0,0 +1,42 @@
|
||||
package net.md_5.bungee.event;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class EventBusTest
|
||||
{
|
||||
|
||||
private final EventBus bus = new EventBus();
|
||||
private final CountDownLatch latch = new CountDownLatch( 2 );
|
||||
|
||||
@Test
|
||||
public void testNestedEvents()
|
||||
{
|
||||
bus.register( this );
|
||||
bus.post( new FirstEvent() );
|
||||
Assert.assertEquals( 0, latch.getCount() );
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void firstListener(FirstEvent event)
|
||||
{
|
||||
bus.post( new SecondEvent() );
|
||||
Assert.assertEquals( 1, latch.getCount() );
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void secondListener(SecondEvent event)
|
||||
{
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
public static class FirstEvent
|
||||
{
|
||||
}
|
||||
|
||||
public static class SecondEvent
|
||||
{
|
||||
}
|
||||
}
|
@@ -0,0 +1,64 @@
|
||||
package net.md_5.bungee.event;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class EventPriorityTest
|
||||
{
|
||||
|
||||
private final EventBus bus = new EventBus();
|
||||
private final CountDownLatch latch = new CountDownLatch( 5 );
|
||||
|
||||
@Test
|
||||
public void testPriority()
|
||||
{
|
||||
bus.register( this );
|
||||
bus.register( new EventPriorityListenerPartner() );
|
||||
bus.post( new PriorityTestEvent() );
|
||||
Assert.assertEquals( 0, latch.getCount() );
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onLowestPriority(PriorityTestEvent event)
|
||||
{
|
||||
Assert.assertEquals( 5, latch.getCount() );
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onNormalPriority(PriorityTestEvent event)
|
||||
{
|
||||
Assert.assertEquals( 3, latch.getCount() );
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onHighestPriority(PriorityTestEvent event)
|
||||
{
|
||||
Assert.assertEquals( 1, latch.getCount() );
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
public static class PriorityTestEvent
|
||||
{
|
||||
}
|
||||
|
||||
public class EventPriorityListenerPartner
|
||||
{
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onHighPriority(PriorityTestEvent event)
|
||||
{
|
||||
Assert.assertEquals( 2, latch.getCount() );
|
||||
latch.countDown();
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onLowPriority(PriorityTestEvent event)
|
||||
{
|
||||
Assert.assertEquals( 4, latch.getCount() );
|
||||
latch.countDown();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
package net.md_5.bungee.event;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class UnregisteringListenerTest
|
||||
{
|
||||
|
||||
private final EventBus bus = new EventBus();
|
||||
|
||||
@Test
|
||||
public void testPriority()
|
||||
{
|
||||
bus.register( this );
|
||||
bus.unregister( this );
|
||||
bus.post( new TestEvent() );
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onEvent(TestEvent evt)
|
||||
{
|
||||
Assert.fail( "Event listener wasn't unregistered" );
|
||||
}
|
||||
|
||||
public static class TestEvent
|
||||
{
|
||||
}
|
||||
}
|
31
nb-configuration.xml
Normal file
31
nb-configuration.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project-shared-configuration>
|
||||
<!--
|
||||
This file contains additional configuration written by modules in the NetBeans IDE.
|
||||
The configuration is intended to be shared among all the users of project and
|
||||
therefore it is assumed to be part of version control checkout.
|
||||
Without this configuration present, some functionality in the IDE may be limited or fail altogether.
|
||||
-->
|
||||
<properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
|
||||
<!--
|
||||
Properties that influence various parts of the IDE, especially code formatting and the like.
|
||||
You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
|
||||
That way multiple projects can share the same settings (useful for formatting rules for example).
|
||||
Any value defined here will override the pom.xml file value but is only applicable to the current project.
|
||||
-->
|
||||
<org-netbeans-modules-editor-indent.CodeStyle.usedProfile>project</org-netbeans-modules-editor-indent.CodeStyle.usedProfile>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.classDeclBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.classDeclBracePlacement>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.otherBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.otherBracePlacement>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.methodDeclBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.methodDeclBracePlacement>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinMethodCallParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinMethodCallParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSwitchParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSwitchParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinCatchParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinCatchParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinTryParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinTryParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSynchronizedParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSynchronizedParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinArrayInitBrackets>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinArrayInitBrackets>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinWhileParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinWhileParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinIfParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinIfParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinForParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinForParens>
|
||||
</properties>
|
||||
</project-shared-configuration>
|
28
pom.xml
28
pom.xml
@@ -11,16 +11,16 @@
|
||||
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-parent</artifactId>
|
||||
<version>1.4.7-SNAPSHOT</version>
|
||||
<version>1.6.2-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>BungeeCord</name>
|
||||
<description>Parent project for all BungeeCord modules.</description>
|
||||
<url>https://github.com/ElasticPortalSuite/BungeeCord</url>
|
||||
<url>https://github.com/SpigotMC/BungeeCord</url>
|
||||
<inceptionYear>2012</inceptionYear>
|
||||
<organization>
|
||||
<name>Elastic Portal Suite</name>
|
||||
<url>https://github.com/ElasticPortalSuite</url>
|
||||
<url>https://github.com/SpigotMC</url>
|
||||
</organization>
|
||||
<licenses>
|
||||
<license>
|
||||
@@ -38,18 +38,19 @@
|
||||
|
||||
<modules>
|
||||
<module>api</module>
|
||||
<module>event</module>
|
||||
<module>protocol</module>
|
||||
<module>proxy</module>
|
||||
</modules>
|
||||
|
||||
<scm>
|
||||
<connection>scm:git:git@github.com:ElasticPortalSuite/BungeeCord.git</connection>
|
||||
<developerConnection>scm:git:git@github.com:ElasticPortalSuite/BungeeCord.git</developerConnection>
|
||||
<url>git@github.com:ElasticPortalSuite/BungeeCord.git</url>
|
||||
<connection>scm:git:git@github.com:SpigotMC/BungeeCord.git</connection>
|
||||
<developerConnection>scm:git:git@github.com:SpigotMC/BungeeCord.git</developerConnection>
|
||||
<url>git@github.com:SpigotMC/BungeeCord.git</url>
|
||||
</scm>
|
||||
<issueManagement>
|
||||
<system>GitHub</system>
|
||||
<url>https://github.com/ElasticPortalSuite/BungeeCord/issues</url>
|
||||
<url>https://github.com/SpigotMC/BungeeCord/issues</url>
|
||||
</issueManagement>
|
||||
<ciManagement>
|
||||
<system>jenkins</system>
|
||||
@@ -57,15 +58,22 @@
|
||||
</ciManagement>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<build.number>unknown</build.number>
|
||||
<netty.version>4.0.9.Final</netty.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.11</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>0.11.6</version>
|
||||
<version>0.12.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
@@ -92,7 +100,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.0</version>
|
||||
<version>2.5.1</version>
|
||||
<configuration>
|
||||
<source>1.7</source>
|
||||
<target>1.7</target>
|
||||
|
31
protocol/nb-configuration.xml
Normal file
31
protocol/nb-configuration.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project-shared-configuration>
|
||||
<!--
|
||||
This file contains additional configuration written by modules in the NetBeans IDE.
|
||||
The configuration is intended to be shared among all the users of project and
|
||||
therefore it is assumed to be part of version control checkout.
|
||||
Without this configuration present, some functionality in the IDE may be limited or fail altogether.
|
||||
-->
|
||||
<properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
|
||||
<!--
|
||||
Properties that influence various parts of the IDE, especially code formatting and the like.
|
||||
You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
|
||||
That way multiple projects can share the same settings (useful for formatting rules for example).
|
||||
Any value defined here will override the pom.xml file value but is only applicable to the current project.
|
||||
-->
|
||||
<org-netbeans-modules-editor-indent.CodeStyle.usedProfile>project</org-netbeans-modules-editor-indent.CodeStyle.usedProfile>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.classDeclBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.classDeclBracePlacement>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.otherBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.otherBracePlacement>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.methodDeclBracePlacement>NEW_LINE</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.methodDeclBracePlacement>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinMethodCallParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinMethodCallParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSwitchParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSwitchParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinCatchParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinCatchParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinTryParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinTryParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSynchronizedParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinSynchronizedParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinArrayInitBrackets>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinArrayInitBrackets>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinWhileParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinWhileParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinIfParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinIfParens>
|
||||
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinForParens>true</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaceWithinForParens>
|
||||
</properties>
|
||||
</project-shared-configuration>
|
@@ -6,15 +6,24 @@
|
||||
<parent>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-parent</artifactId>
|
||||
<version>1.4.7-SNAPSHOT</version>
|
||||
<version>1.6.2-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-protocol</artifactId>
|
||||
<version>1.4.7-SNAPSHOT</version>
|
||||
<version>1.6.2-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>BungeeCord-Protocol</name>
|
||||
<description>Minimal implementation of the Minecraft protocol for use in BungeeCord</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-buffer</artifactId>
|
||||
<version>${netty.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
33
protocol/src/main/java/net/md_5/bungee/protocol/Forge.java
Normal file
33
protocol/src/main/java/net/md_5/bungee/protocol/Forge.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package net.md_5.bungee.protocol;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.Getter;
|
||||
import net.md_5.bungee.protocol.packet.DefinedPacket;
|
||||
import net.md_5.bungee.protocol.packet.forge.Forge1Login;
|
||||
import net.md_5.bungee.protocol.skip.PacketReader;
|
||||
|
||||
public class Forge extends Vanilla
|
||||
{
|
||||
|
||||
@Getter
|
||||
private static final Forge instance = new Forge();
|
||||
|
||||
public Forge()
|
||||
{
|
||||
classes[0x01] = Forge1Login.class;
|
||||
skipper = new PacketReader( this ); // TODO: :(
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefinedPacket read(short packetId, ByteBuf buf)
|
||||
{
|
||||
int start = buf.readerIndex();
|
||||
DefinedPacket packet = read( packetId, buf, this );
|
||||
if ( buf.readerIndex() == start )
|
||||
{
|
||||
packet = super.read( packetId, buf );
|
||||
}
|
||||
|
||||
return packet;
|
||||
}
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
package net.md_5.bungee.protocol;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class MinecraftInput
|
||||
{
|
||||
|
||||
private final ByteBuf buf;
|
||||
|
||||
public byte readByte()
|
||||
{
|
||||
return buf.readByte();
|
||||
}
|
||||
|
||||
public short readUnisgnedByte()
|
||||
{
|
||||
return buf.readUnsignedByte();
|
||||
}
|
||||
|
||||
public int readInt()
|
||||
{
|
||||
return buf.readInt();
|
||||
}
|
||||
|
||||
public String readString()
|
||||
{
|
||||
short len = buf.readShort();
|
||||
char[] c = new char[ len ];
|
||||
for ( int i = 0; i < c.length; i++ )
|
||||
{
|
||||
c[i] = buf.readChar();
|
||||
}
|
||||
|
||||
return new String( c );
|
||||
}
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
package net.md_5.bungee.protocol;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class MinecraftOutput
|
||||
{
|
||||
|
||||
private final ByteBuf buf;
|
||||
|
||||
public MinecraftOutput()
|
||||
{
|
||||
buf = Unpooled.buffer();
|
||||
}
|
||||
|
||||
public byte[] toArray()
|
||||
{
|
||||
if ( buf.hasArray() )
|
||||
{
|
||||
return Arrays.copyOfRange( buf.array(), buf.arrayOffset(), buf.arrayOffset() + buf.writerIndex() );
|
||||
} else
|
||||
{
|
||||
byte[] b = new byte[ buf.writerIndex() ];
|
||||
buf.readBytes( b );
|
||||
return b;
|
||||
}
|
||||
}
|
||||
|
||||
public MinecraftOutput writeByte(byte b)
|
||||
{
|
||||
buf.writeByte( b );
|
||||
return this;
|
||||
}
|
||||
|
||||
public void writeInt(int i)
|
||||
{
|
||||
buf.writeInt( i );
|
||||
}
|
||||
|
||||
public void writeString(String s)
|
||||
{
|
||||
char[] cc = s.toCharArray();
|
||||
buf.writeShort( cc.length );
|
||||
for ( char c : cc )
|
||||
{
|
||||
buf.writeChar( c );
|
||||
}
|
||||
}
|
||||
|
||||
public void writeStringUTF8WithoutLengthHeaderBecauseDinnerboneStuffedUpTheMCBrandPacket(String s)
|
||||
{
|
||||
buf.writeBytes( s.getBytes( Charset.forName( "UTF-8" ) ) );
|
||||
}
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
package net.md_5.bungee.protocol;
|
||||
|
||||
public enum OpCode
|
||||
{
|
||||
|
||||
BOOLEAN, BULK_CHUNK, BYTE, BYTE_INT, DOUBLE, FLOAT, INT, INT_3, INT_BYTE, ITEM, LONG, METADATA, OPTIONAL_MOTION, SHORT, SHORT_BYTE, SHORT_ITEM, STRING, USHORT_BYTE, OPTIONAL_WINDOW
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
package net.md_5.bungee.protocol;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import java.lang.reflect.Constructor;
|
||||
import net.md_5.bungee.protocol.packet.DefinedPacket;
|
||||
import net.md_5.bungee.protocol.skip.PacketReader;
|
||||
|
||||
public interface Protocol
|
||||
{
|
||||
|
||||
PacketReader getSkipper();
|
||||
|
||||
DefinedPacket read(short packetId, ByteBuf buf);
|
||||
|
||||
OpCode[][] getOpCodes();
|
||||
|
||||
Class<? extends DefinedPacket>[] getClasses();
|
||||
|
||||
Constructor<? extends DefinedPacket>[] getConstructors();
|
||||
}
|
@@ -1,39 +1,131 @@
|
||||
package net.md_5.mendax;
|
||||
package net.md_5.bungee.protocol;
|
||||
|
||||
import static net.md_5.mendax.PacketDefinitions.OpCode.*;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import lombok.Getter;
|
||||
import static net.md_5.bungee.protocol.OpCode.*;
|
||||
import net.md_5.bungee.protocol.packet.DefinedPacket;
|
||||
import net.md_5.bungee.protocol.packet.Packet0KeepAlive;
|
||||
import net.md_5.bungee.protocol.packet.Packet1Login;
|
||||
import net.md_5.bungee.protocol.packet.Packet2CEntityProperties;
|
||||
import net.md_5.bungee.protocol.packet.Packet2Handshake;
|
||||
import net.md_5.bungee.protocol.packet.Packet3Chat;
|
||||
import net.md_5.bungee.protocol.packet.Packet9Respawn;
|
||||
import net.md_5.bungee.protocol.packet.PacketC9PlayerListItem;
|
||||
import net.md_5.bungee.protocol.packet.PacketCBTabComplete;
|
||||
import net.md_5.bungee.protocol.packet.PacketCCSettings;
|
||||
import net.md_5.bungee.protocol.packet.PacketCDClientStatus;
|
||||
import net.md_5.bungee.protocol.packet.PacketCEScoreboardObjective;
|
||||
import net.md_5.bungee.protocol.packet.PacketCFScoreboardScore;
|
||||
import net.md_5.bungee.protocol.packet.PacketD0DisplayScoreboard;
|
||||
import net.md_5.bungee.protocol.packet.PacketD1Team;
|
||||
import net.md_5.bungee.protocol.packet.PacketFAPluginMessage;
|
||||
import net.md_5.bungee.protocol.packet.PacketFCEncryptionResponse;
|
||||
import net.md_5.bungee.protocol.packet.PacketFDEncryptionRequest;
|
||||
import net.md_5.bungee.protocol.packet.PacketFEPing;
|
||||
import net.md_5.bungee.protocol.packet.PacketFFKick;
|
||||
import net.md_5.bungee.protocol.skip.PacketReader;
|
||||
|
||||
public class PacketDefinitions
|
||||
public class Vanilla implements Protocol
|
||||
{
|
||||
|
||||
private static final int MAX_PACKET = 256;
|
||||
public static final OpCode[][] opCodes = new OpCode[ MAX_PACKET * 2 ][];
|
||||
public static final int VANILLA_PROTOCOL = 0;
|
||||
public static final int FORGE_PROTOCOL = MAX_PACKET;
|
||||
public static final byte PROTOCOL_VERSION = 74;
|
||||
public static final String GAME_VERSION = "1.6.2";
|
||||
@Getter
|
||||
private static final Vanilla instance = new Vanilla();
|
||||
/*========================================================================*/
|
||||
@Getter
|
||||
private final OpCode[][] opCodes = new OpCode[ 256 ][];
|
||||
@SuppressWarnings("unchecked")
|
||||
@Getter
|
||||
protected Class<? extends DefinedPacket>[] classes = new Class[ 256 ];
|
||||
@SuppressWarnings("unchecked")
|
||||
@Getter
|
||||
private Constructor<? extends DefinedPacket>[] constructors = new Constructor[ 256 ];
|
||||
@Getter
|
||||
protected PacketReader skipper;
|
||||
/*========================================================================*/
|
||||
|
||||
public enum OpCode
|
||||
public Vanilla()
|
||||
{
|
||||
|
||||
BOOLEAN, BULK_CHUNK, BYTE, BYTE_INT, DOUBLE, FLOAT, INT, INT_3, INT_BYTE, ITEM, LONG, METADATA, OPTIONAL_MOTION, SHORT, SHORT_BYTE, SHORT_ITEM, STRING, USHORT_BYTE
|
||||
classes[0x00] = Packet0KeepAlive.class;
|
||||
classes[0x01] = Packet1Login.class;
|
||||
classes[0x02] = Packet2Handshake.class;
|
||||
classes[0x03] = Packet3Chat.class;
|
||||
classes[0x09] = Packet9Respawn.class;
|
||||
classes[0xC9] = PacketC9PlayerListItem.class;
|
||||
classes[0x2C] = Packet2CEntityProperties.class;
|
||||
classes[0xCC] = PacketCCSettings.class;
|
||||
classes[0xCB] = PacketCBTabComplete.class;
|
||||
classes[0xCD] = PacketCDClientStatus.class;
|
||||
classes[0xCE] = PacketCEScoreboardObjective.class;
|
||||
classes[0xCF] = PacketCFScoreboardScore.class;
|
||||
classes[0xD0] = PacketD0DisplayScoreboard.class;
|
||||
classes[0xD1] = PacketD1Team.class;
|
||||
classes[0xFA] = PacketFAPluginMessage.class;
|
||||
classes[0xFC] = PacketFCEncryptionResponse.class;
|
||||
classes[0xFD] = PacketFDEncryptionRequest.class;
|
||||
classes[0xFE] = PacketFEPing.class;
|
||||
classes[0xFF] = PacketFFKick.class;
|
||||
skipper = new PacketReader( this );
|
||||
}
|
||||
|
||||
static
|
||||
@Override
|
||||
public DefinedPacket read(short packetId, ByteBuf buf)
|
||||
{
|
||||
opCodes[0x00] = new OpCode[]
|
||||
int start = buf.readerIndex();
|
||||
DefinedPacket packet = read( packetId, buf, this );
|
||||
if ( buf.readerIndex() == start )
|
||||
{
|
||||
INT
|
||||
};
|
||||
opCodes[0x01] = new OpCode[]
|
||||
throw new RuntimeException( "Unknown packet id " + packetId );
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
|
||||
public static DefinedPacket read(short id, ByteBuf buf, Protocol protocol)
|
||||
{
|
||||
INT, STRING, BYTE, BYTE, BYTE, BYTE, BYTE
|
||||
};
|
||||
opCodes[0x02] = new OpCode[]
|
||||
DefinedPacket packet = packet( id, protocol );
|
||||
if ( packet != null )
|
||||
{
|
||||
BYTE, STRING, STRING, INT
|
||||
};
|
||||
opCodes[0x03] = new OpCode[]
|
||||
packet.read( buf );
|
||||
return packet;
|
||||
}
|
||||
protocol.getSkipper().tryRead( id, buf );
|
||||
return null;
|
||||
}
|
||||
|
||||
public static DefinedPacket packet(short id, Protocol protocol)
|
||||
{
|
||||
DefinedPacket ret = null;
|
||||
Class<? extends DefinedPacket> clazz = protocol.getClasses()[id];
|
||||
|
||||
if ( clazz != null )
|
||||
{
|
||||
try
|
||||
{
|
||||
Constructor<? extends DefinedPacket> constructor = protocol.getConstructors()[id];
|
||||
if ( constructor == null )
|
||||
{
|
||||
constructor = clazz.getDeclaredConstructor();
|
||||
constructor.setAccessible( true );
|
||||
protocol.getConstructors()[id] = constructor;
|
||||
}
|
||||
|
||||
if ( constructor != null )
|
||||
{
|
||||
ret = constructor.newInstance();
|
||||
}
|
||||
} catch ( NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex )
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
STRING
|
||||
};
|
||||
opCodes[0x04] = new OpCode[]
|
||||
{
|
||||
LONG, LONG
|
||||
@@ -52,11 +144,7 @@ public class PacketDefinitions
|
||||
};
|
||||
opCodes[0x08] = new OpCode[]
|
||||
{
|
||||
SHORT, SHORT, FLOAT
|
||||
};
|
||||
opCodes[0x09] = new OpCode[]
|
||||
{
|
||||
INT, BYTE, BYTE, SHORT, STRING
|
||||
FLOAT, SHORT, FLOAT
|
||||
};
|
||||
opCodes[0x0A] = new OpCode[]
|
||||
{
|
||||
@@ -96,7 +184,7 @@ public class PacketDefinitions
|
||||
};
|
||||
opCodes[0x13] = new OpCode[]
|
||||
{
|
||||
INT, BYTE
|
||||
INT, BYTE, INT
|
||||
};
|
||||
opCodes[0x14] = new OpCode[]
|
||||
{
|
||||
@@ -122,6 +210,10 @@ public class PacketDefinitions
|
||||
{
|
||||
INT, INT, INT, INT, SHORT
|
||||
};
|
||||
opCodes[0x1B] = new OpCode[]
|
||||
{
|
||||
FLOAT, FLOAT, BOOLEAN, BOOLEAN
|
||||
};
|
||||
opCodes[0x1C] = new OpCode[]
|
||||
{
|
||||
INT, SHORT, SHORT, SHORT
|
||||
@@ -160,7 +252,7 @@ public class PacketDefinitions
|
||||
};
|
||||
opCodes[0x27] = new OpCode[]
|
||||
{
|
||||
INT, INT
|
||||
INT, INT, BOOLEAN
|
||||
};
|
||||
opCodes[0x28] = new OpCode[]
|
||||
{
|
||||
@@ -214,6 +306,10 @@ public class PacketDefinitions
|
||||
{
|
||||
STRING, INT, INT, INT, FLOAT, BYTE
|
||||
};
|
||||
opCodes[0x3F] = new OpCode[]
|
||||
{
|
||||
STRING, FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, INT
|
||||
};
|
||||
opCodes[0x46] = new OpCode[]
|
||||
{
|
||||
BYTE, BYTE
|
||||
@@ -224,7 +320,7 @@ public class PacketDefinitions
|
||||
};
|
||||
opCodes[0x64] = new OpCode[]
|
||||
{
|
||||
BYTE, BYTE, STRING, BYTE
|
||||
OPTIONAL_WINDOW
|
||||
};
|
||||
opCodes[0x65] = new OpCode[]
|
||||
{
|
||||
@@ -270,57 +366,25 @@ public class PacketDefinitions
|
||||
{
|
||||
INT, SHORT, INT, BYTE, SHORT_BYTE
|
||||
};
|
||||
opCodes[0x85] = new OpCode[]
|
||||
{
|
||||
BYTE, INT, INT, INT
|
||||
};
|
||||
opCodes[0xC3] = new OpCode[]
|
||||
{
|
||||
SHORT, SHORT, INT_BYTE
|
||||
};
|
||||
opCodes[0xC8] = new OpCode[]
|
||||
{
|
||||
INT, BYTE
|
||||
};
|
||||
opCodes[0xC9] = new OpCode[]
|
||||
{
|
||||
STRING, BOOLEAN, SHORT
|
||||
INT, INT
|
||||
};
|
||||
opCodes[0xCA] = new OpCode[]
|
||||
{
|
||||
BYTE, BYTE, BYTE
|
||||
BYTE, FLOAT, FLOAT
|
||||
};
|
||||
opCodes[0xCB] = new OpCode[]
|
||||
{
|
||||
STRING
|
||||
};
|
||||
opCodes[0xCC] = new OpCode[]
|
||||
{
|
||||
STRING, BYTE, BYTE, BYTE, BOOLEAN
|
||||
};
|
||||
opCodes[0xCD] = new OpCode[]
|
||||
{
|
||||
BYTE
|
||||
};
|
||||
opCodes[0xFA] = new OpCode[]
|
||||
{
|
||||
STRING, SHORT_BYTE
|
||||
};
|
||||
opCodes[0xFC] = new OpCode[]
|
||||
{
|
||||
SHORT_BYTE, SHORT_BYTE
|
||||
};
|
||||
opCodes[0xFD] = new OpCode[]
|
||||
{
|
||||
STRING, SHORT_BYTE, SHORT_BYTE
|
||||
};
|
||||
opCodes[0xFE] = new OpCode[]
|
||||
{
|
||||
}; // Should be byte, screw you too bitchy server admins!
|
||||
opCodes[0xFF] = new OpCode[]
|
||||
{
|
||||
STRING
|
||||
};
|
||||
/*========================== Minecraft Forge ===========================*/
|
||||
opCodes[0x01 + FORGE_PROTOCOL] = new OpCode[]
|
||||
{
|
||||
INT, STRING, BYTE, INT, BYTE, BYTE, BYTE
|
||||
};
|
||||
}
|
||||
}
|
@@ -1,70 +1,81 @@
|
||||
package net.md_5.bungee.packet;
|
||||
package net.md_5.bungee.protocol.packet;
|
||||
|
||||
public abstract class PacketHandler
|
||||
public abstract class AbstractPacketHandler
|
||||
{
|
||||
|
||||
private void nop(DefinedPacket packet)
|
||||
{
|
||||
throw new UnsupportedOperationException( "No handler defined for packet " + packet.getClass() );
|
||||
}
|
||||
|
||||
public void handle(Packet0KeepAlive alive) throws Exception
|
||||
{
|
||||
nop( alive );
|
||||
}
|
||||
|
||||
public void handle(Packet1Login login) throws Exception
|
||||
{
|
||||
nop( login );
|
||||
}
|
||||
|
||||
public void handle(Packet2Handshake handshake) throws Exception
|
||||
{
|
||||
nop( handshake );
|
||||
}
|
||||
|
||||
public void handle(Packet3Chat chat) throws Exception
|
||||
{
|
||||
nop( chat );
|
||||
}
|
||||
|
||||
public void handle(Packet9Respawn respawn) throws Exception
|
||||
{
|
||||
nop( respawn );
|
||||
}
|
||||
|
||||
public void handle(Packet2CEntityProperties properties) throws Exception
|
||||
{
|
||||
}
|
||||
|
||||
public void handle(PacketC9PlayerListItem playerList) throws Exception
|
||||
{
|
||||
nop( playerList );
|
||||
}
|
||||
|
||||
public void handle(PacketCCSettings settings) throws Exception
|
||||
{
|
||||
}
|
||||
|
||||
public void handle(PacketCDClientStatus clientStatus) throws Exception
|
||||
{
|
||||
nop( clientStatus );
|
||||
}
|
||||
|
||||
public void handle(PacketCEScoreboardObjective objective) throws Exception
|
||||
{
|
||||
}
|
||||
|
||||
public void handle(PacketCFScoreboardScore score) throws Exception
|
||||
{
|
||||
}
|
||||
|
||||
public void handle(PacketD0DisplayScoreboard displayScoreboard) throws Exception
|
||||
{
|
||||
}
|
||||
|
||||
public void handle(PacketD1Team team) throws Exception
|
||||
{
|
||||
}
|
||||
|
||||
public void handle(PacketFAPluginMessage pluginMessage) throws Exception
|
||||
{
|
||||
nop( pluginMessage );
|
||||
}
|
||||
|
||||
public void handle(PacketFCEncryptionResponse encryptResponse) throws Exception
|
||||
{
|
||||
nop( encryptResponse );
|
||||
}
|
||||
|
||||
public void handle(PacketFDEncryptionRequest encryptRequest) throws Exception
|
||||
{
|
||||
nop( encryptRequest );
|
||||
}
|
||||
|
||||
public void handle(PacketFEPing ping) throws Exception
|
||||
{
|
||||
nop( ping );
|
||||
}
|
||||
|
||||
public void handle(PacketFFKick kick) throws Exception
|
||||
{
|
||||
nop( kick );
|
||||
}
|
||||
|
||||
public void handle(PacketCBTabComplete tabComplete) throws Exception
|
||||
{
|
||||
}
|
||||
}
|
@@ -0,0 +1,69 @@
|
||||
package net.md_5.bungee.protocol.packet;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public abstract class DefinedPacket
|
||||
{
|
||||
|
||||
private final int id;
|
||||
|
||||
public final int getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
public void writeString(String s, ByteBuf buf)
|
||||
{
|
||||
// TODO: Check len - use Guava?
|
||||
buf.writeShort( s.length() );
|
||||
for ( char c : s.toCharArray() )
|
||||
{
|
||||
buf.writeChar( c );
|
||||
}
|
||||
}
|
||||
|
||||
public String readString(ByteBuf buf)
|
||||
{
|
||||
// TODO: Check len - use Guava?
|
||||
short len = buf.readShort();
|
||||
char[] chars = new char[ len ];
|
||||
for ( int i = 0; i < len; i++ )
|
||||
{
|
||||
chars[i] = buf.readChar();
|
||||
}
|
||||
return new String( chars );
|
||||
}
|
||||
|
||||
public void writeArray(byte[] b, ByteBuf buf)
|
||||
{
|
||||
// TODO: Check len - use Guava?
|
||||
buf.writeShort( b.length );
|
||||
buf.writeBytes( b );
|
||||
}
|
||||
|
||||
public byte[] readArray(ByteBuf buf)
|
||||
{
|
||||
// TODO: Check len - use Guava?
|
||||
short len = buf.readShort();
|
||||
byte[] ret = new byte[ len ];
|
||||
buf.readBytes( ret );
|
||||
return ret;
|
||||
}
|
||||
|
||||
public abstract void read(ByteBuf buf);
|
||||
|
||||
public abstract void write(ByteBuf buf);
|
||||
|
||||
public abstract void handle(AbstractPacketHandler handler) throws Exception;
|
||||
|
||||
@Override
|
||||
public abstract boolean equals(Object obj);
|
||||
|
||||
@Override
|
||||
public abstract int hashCode();
|
||||
|
||||
@Override
|
||||
public abstract String toString();
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
package net.md_5.bungee.protocol.packet;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class Packet0KeepAlive extends DefinedPacket
|
||||
{
|
||||
|
||||
private int randomId;
|
||||
|
||||
private Packet0KeepAlive()
|
||||
{
|
||||
super( 0x00 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ByteBuf buf)
|
||||
{
|
||||
randomId = buf.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buf)
|
||||
{
|
||||
buf.writeInt( randomId );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(AbstractPacketHandler handler) throws Exception
|
||||
{
|
||||
handler.handle( this );
|
||||
}
|
||||
}
|
@@ -0,0 +1,73 @@
|
||||
package net.md_5.bungee.protocol.packet;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class Packet1Login extends DefinedPacket
|
||||
{
|
||||
|
||||
protected int entityId;
|
||||
protected String levelType;
|
||||
protected byte gameMode;
|
||||
protected int dimension;
|
||||
protected byte difficulty;
|
||||
protected byte unused;
|
||||
protected byte maxPlayers;
|
||||
|
||||
protected Packet1Login()
|
||||
{
|
||||
super( 0x01 );
|
||||
}
|
||||
|
||||
public Packet1Login(int entityId, String levelType, byte gameMode, byte dimension, byte difficulty, byte unused, byte maxPlayers)
|
||||
{
|
||||
this( entityId, levelType, gameMode, (int) dimension, difficulty, unused, maxPlayers );
|
||||
}
|
||||
|
||||
public Packet1Login(int entityId, String levelType, byte gameMode, int dimension, byte difficulty, byte unused, byte maxPlayers)
|
||||
{
|
||||
this();
|
||||
this.entityId = entityId;
|
||||
this.levelType = levelType;
|
||||
this.gameMode = gameMode;
|
||||
this.dimension = dimension;
|
||||
this.difficulty = difficulty;
|
||||
this.unused = unused;
|
||||
this.maxPlayers = maxPlayers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ByteBuf buf)
|
||||
{
|
||||
entityId = buf.readInt();
|
||||
levelType = readString( buf );
|
||||
gameMode = buf.readByte();
|
||||
dimension = buf.readByte();
|
||||
difficulty = buf.readByte();
|
||||
unused = buf.readByte();
|
||||
maxPlayers = buf.readByte();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buf)
|
||||
{
|
||||
buf.writeInt( entityId );
|
||||
writeString( levelType, buf );
|
||||
buf.writeByte( gameMode );
|
||||
buf.writeByte( dimension );
|
||||
buf.writeByte( difficulty );
|
||||
buf.writeByte( unused );
|
||||
buf.writeByte( maxPlayers );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(AbstractPacketHandler handler) throws Exception
|
||||
{
|
||||
handler.handle( this );
|
||||
}
|
||||
}
|
@@ -0,0 +1,49 @@
|
||||
package net.md_5.bungee.protocol.packet;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class Packet2CEntityProperties extends DefinedPacket
|
||||
{
|
||||
|
||||
public Packet2CEntityProperties()
|
||||
{
|
||||
super( 0x2C );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ByteBuf buf)
|
||||
{
|
||||
buf.readInt();
|
||||
int recordCount = buf.readInt();
|
||||
for ( int i = 0; i < recordCount; i++ )
|
||||
{
|
||||
readString( buf );
|
||||
buf.readDouble();
|
||||
short size = buf.readShort();
|
||||
for ( short s = 0; s < size; s++ )
|
||||
{
|
||||
buf.skipBytes( 25 ); // long, long, double, byte
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buf)
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(AbstractPacketHandler handler) throws Exception
|
||||
{
|
||||
handler.handle( this );
|
||||
}
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
package net.md_5.bungee.protocol.packet;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class Packet2Handshake extends DefinedPacket
|
||||
{
|
||||
|
||||
private byte procolVersion;
|
||||
private String username;
|
||||
private String host;
|
||||
private int port;
|
||||
|
||||
private Packet2Handshake()
|
||||
{
|
||||
super( 0x02 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ByteBuf buf)
|
||||
{
|
||||
procolVersion = buf.readByte();
|
||||
username = readString( buf );
|
||||
host = readString( buf );
|
||||
port = buf.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buf)
|
||||
{
|
||||
buf.writeByte( procolVersion );
|
||||
writeString( username, buf );
|
||||
writeString( host, buf );
|
||||
buf.writeInt( port );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(AbstractPacketHandler handler) throws Exception
|
||||
{
|
||||
handler.handle( this );
|
||||
}
|
||||
}
|
@@ -0,0 +1,46 @@
|
||||
package net.md_5.bungee.protocol.packet;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@ToString
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class Packet3Chat extends DefinedPacket
|
||||
{
|
||||
|
||||
private String message;
|
||||
|
||||
private Packet3Chat()
|
||||
{
|
||||
super( 0x03 );
|
||||
}
|
||||
|
||||
public Packet3Chat(String message)
|
||||
{
|
||||
this();
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ByteBuf buf)
|
||||
{
|
||||
message = readString( buf );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buf)
|
||||
{
|
||||
writeString( message, buf );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(AbstractPacketHandler handler) throws Exception
|
||||
{
|
||||
handler.handle( this );
|
||||
}
|
||||
}
|
@@ -0,0 +1,58 @@
|
||||
package net.md_5.bungee.protocol.packet;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@ToString
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class Packet9Respawn extends DefinedPacket
|
||||
{
|
||||
|
||||
private int dimension;
|
||||
private byte difficulty;
|
||||
private byte gameMode;
|
||||
private short worldHeight;
|
||||
private String levelType;
|
||||
|
||||
private Packet9Respawn()
|
||||
{
|
||||
super( 0x09 );
|
||||
}
|
||||
|
||||
public Packet9Respawn(int dimension, byte difficulty, byte gameMode, short worldHeight, String levelType)
|
||||
{
|
||||
this();
|
||||
this.dimension = dimension;
|
||||
this.difficulty = difficulty;
|
||||
this.gameMode = gameMode;
|
||||
this.worldHeight = worldHeight;
|
||||
this.levelType = levelType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ByteBuf buf)
|
||||
{
|
||||
dimension = buf.readInt();
|
||||
difficulty = buf.readByte();
|
||||
gameMode = buf.readByte();
|
||||
worldHeight = buf.readShort();
|
||||
levelType = readString( buf );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buf)
|
||||
{
|
||||
buf.writeInt( dimension );
|
||||
buf.writeByte( difficulty );
|
||||
buf.writeByte( gameMode );
|
||||
buf.writeShort( worldHeight );
|
||||
writeString( levelType, buf );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(AbstractPacketHandler handler) throws Exception
|
||||
{
|
||||
handler.handle( this );
|
||||
}
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
package net.md_5.bungee.protocol.packet;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class PacketC9PlayerListItem extends DefinedPacket
|
||||
{
|
||||
|
||||
private String username;
|
||||
private boolean online;
|
||||
private short ping;
|
||||
|
||||
private PacketC9PlayerListItem()
|
||||
{
|
||||
super( 0xC9 );
|
||||
}
|
||||
|
||||
public PacketC9PlayerListItem(String username, boolean online, short ping)
|
||||
{
|
||||
super( 0xC9 );
|
||||
this.username = username;
|
||||
this.online = online;
|
||||
this.ping = ping;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ByteBuf buf)
|
||||
{
|
||||
username = readString( buf );
|
||||
online = buf.readBoolean();
|
||||
ping = buf.readShort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buf)
|
||||
{
|
||||
writeString( username, buf );
|
||||
buf.writeBoolean( online );
|
||||
buf.writeShort( ping );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(AbstractPacketHandler handler) throws Exception
|
||||
{
|
||||
handler.handle( this );
|
||||
}
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
package net.md_5.bungee.protocol.packet;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class PacketCBTabComplete extends DefinedPacket
|
||||
{
|
||||
|
||||
private String cursor;
|
||||
private String[] commands;
|
||||
|
||||
private PacketCBTabComplete()
|
||||
{
|
||||
super( 0xCB );
|
||||
}
|
||||
|
||||
public PacketCBTabComplete(String[] alternatives)
|
||||
{
|
||||
this();
|
||||
commands = alternatives;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ByteBuf buf)
|
||||
{
|
||||
cursor = readString( buf );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buf)
|
||||
{
|
||||
String tab = "";
|
||||
for ( String alternative : commands )
|
||||
{
|
||||
if ( tab.isEmpty() )
|
||||
{
|
||||
tab = alternative + " ";
|
||||
} else
|
||||
{
|
||||
tab += "\0" + alternative + " ";
|
||||
}
|
||||
}
|
||||
writeString( tab, buf );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(AbstractPacketHandler handler) throws Exception
|
||||
{
|
||||
handler.handle( this );
|
||||
}
|
||||
}
|
@@ -0,0 +1,48 @@
|
||||
package net.md_5.bungee.protocol.packet;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@ToString
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class PacketCCSettings extends DefinedPacket
|
||||
{
|
||||
|
||||
private String locale;
|
||||
private byte viewDistance;
|
||||
private byte chatFlags;
|
||||
private byte difficulty;
|
||||
private boolean showCape;
|
||||
|
||||
private PacketCCSettings()
|
||||
{
|
||||
super( 0xCC );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ByteBuf buf)
|
||||
{
|
||||
locale = readString( buf );
|
||||
viewDistance = buf.readByte();
|
||||
chatFlags = buf.readByte();
|
||||
difficulty = buf.readByte();
|
||||
showCape = buf.readBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buf)
|
||||
{
|
||||
writeString( locale, buf );
|
||||
buf.writeByte( viewDistance );
|
||||
buf.writeByte( chatFlags );
|
||||
buf.writeByte( difficulty );
|
||||
buf.writeBoolean( showCape );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(AbstractPacketHandler handler) throws Exception
|
||||
{
|
||||
handler.handle( this );
|
||||
}
|
||||
}
|
@@ -0,0 +1,42 @@
|
||||
package net.md_5.bungee.protocol.packet;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@ToString
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class PacketCDClientStatus extends DefinedPacket
|
||||
{
|
||||
|
||||
private byte payload;
|
||||
|
||||
private PacketCDClientStatus()
|
||||
{
|
||||
super( 0xCD );
|
||||
}
|
||||
|
||||
public PacketCDClientStatus(byte payload)
|
||||
{
|
||||
this();
|
||||
this.payload = payload;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ByteBuf buf)
|
||||
{
|
||||
payload = buf.readByte();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buf)
|
||||
{
|
||||
buf.writeByte( payload );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(AbstractPacketHandler handler) throws Exception
|
||||
{
|
||||
handler.handle( this );
|
||||
}
|
||||
}
|
@@ -0,0 +1,55 @@
|
||||
package net.md_5.bungee.protocol.packet;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class PacketCEScoreboardObjective extends DefinedPacket
|
||||
{
|
||||
|
||||
private String name;
|
||||
private String text;
|
||||
/**
|
||||
* 0 to create, 1 to remove.
|
||||
*/
|
||||
private byte action;
|
||||
|
||||
private PacketCEScoreboardObjective()
|
||||
{
|
||||
super( 0xCE );
|
||||
}
|
||||
|
||||
public PacketCEScoreboardObjective(String name, String text, byte action)
|
||||
{
|
||||
this();
|
||||
this.name = name;
|
||||
this.text = text;
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ByteBuf buf)
|
||||
{
|
||||
name = readString( buf );
|
||||
text = readString( buf );
|
||||
action = buf.readByte();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buf)
|
||||
{
|
||||
writeString( name, buf );
|
||||
writeString( text, buf );
|
||||
buf.writeByte( action );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(AbstractPacketHandler handler) throws Exception
|
||||
{
|
||||
handler.handle( this );
|
||||
}
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
package net.md_5.bungee.protocol.packet;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class PacketCFScoreboardScore extends DefinedPacket
|
||||
{
|
||||
|
||||
private String itemName;
|
||||
/**
|
||||
* 0 = create / update, 1 = remove.
|
||||
*/
|
||||
private byte action;
|
||||
private String scoreName;
|
||||
private int value;
|
||||
|
||||
private PacketCFScoreboardScore()
|
||||
{
|
||||
super( 0xCF );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ByteBuf buf)
|
||||
{
|
||||
itemName = readString( buf );
|
||||
action = buf.readByte();
|
||||
if ( action != 1 )
|
||||
{
|
||||
scoreName = readString( buf );
|
||||
value = buf.readInt();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buf)
|
||||
{
|
||||
writeString( itemName, buf );
|
||||
buf.writeByte( action );
|
||||
if ( action != 1 )
|
||||
{
|
||||
writeString( scoreName, buf );
|
||||
buf.writeInt( value );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(AbstractPacketHandler handler) throws Exception
|
||||
{
|
||||
handler.handle( this );
|
||||
}
|
||||
}
|
@@ -0,0 +1,44 @@
|
||||
package net.md_5.bungee.protocol.packet;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class PacketD0DisplayScoreboard extends DefinedPacket
|
||||
{
|
||||
|
||||
/**
|
||||
* 0 = list, 1 = side, 2 = below.
|
||||
*/
|
||||
private byte position;
|
||||
private String name;
|
||||
|
||||
private PacketD0DisplayScoreboard()
|
||||
{
|
||||
super( 0xD0 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ByteBuf buf)
|
||||
{
|
||||
position = buf.readByte();
|
||||
name = readString( buf );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buf)
|
||||
{
|
||||
buf.writeByte( position );
|
||||
writeString( name, buf );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(AbstractPacketHandler handler) throws Exception
|
||||
{
|
||||
handler.handle( this );
|
||||
}
|
||||
}
|
@@ -0,0 +1,92 @@
|
||||
package net.md_5.bungee.protocol.packet;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class PacketD1Team extends DefinedPacket
|
||||
{
|
||||
|
||||
private String name;
|
||||
/**
|
||||
* 0 - create, 1 remove, 2 info update, 3 player add, 4 player remove.
|
||||
*/
|
||||
private byte mode;
|
||||
private String displayName;
|
||||
private String prefix;
|
||||
private String suffix;
|
||||
private boolean friendlyFire;
|
||||
private short playerCount;
|
||||
private String[] players;
|
||||
|
||||
private PacketD1Team()
|
||||
{
|
||||
super( 0xD1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Packet to destroy a team.
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
public PacketD1Team(String name)
|
||||
{
|
||||
this();
|
||||
this.name = name;
|
||||
this.mode = 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ByteBuf buf)
|
||||
{
|
||||
name = readString( buf );
|
||||
mode = buf.readByte();
|
||||
if ( mode == 0 || mode == 2 )
|
||||
{
|
||||
displayName = readString( buf );
|
||||
prefix = readString( buf );
|
||||
suffix = readString( buf );
|
||||
friendlyFire = buf.readBoolean();
|
||||
}
|
||||
if ( mode == 0 || mode == 3 || mode == 4 )
|
||||
{
|
||||
players = new String[ buf.readShort() ];
|
||||
for ( int i = 0; i < getPlayers().length; i++ )
|
||||
{
|
||||
players[i] = readString( buf );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buf)
|
||||
{
|
||||
writeString( name, buf );
|
||||
buf.writeByte( mode );
|
||||
if ( mode == 0 || mode == 2 )
|
||||
{
|
||||
writeString( displayName, buf );
|
||||
writeString( prefix, buf );
|
||||
writeString( suffix, buf );
|
||||
buf.writeBoolean( friendlyFire );
|
||||
}
|
||||
if ( mode == 0 || mode == 3 || mode == 4 )
|
||||
{
|
||||
buf.writeShort( players.length );
|
||||
for ( int i = 0; i < players.length; i++ )
|
||||
{
|
||||
writeString( players[i], buf );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(AbstractPacketHandler handler) throws Exception
|
||||
{
|
||||
handler.handle( this );
|
||||
}
|
||||
}
|
@@ -0,0 +1,64 @@
|
||||
package net.md_5.bungee.protocol.packet;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.DataInput;
|
||||
import java.io.DataInputStream;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
import net.md_5.bungee.protocol.MinecraftInput;
|
||||
import net.md_5.bungee.protocol.MinecraftOutput;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class PacketFAPluginMessage extends DefinedPacket
|
||||
{
|
||||
|
||||
private String tag;
|
||||
private byte[] data;
|
||||
|
||||
private PacketFAPluginMessage()
|
||||
{
|
||||
super( 0xFA );
|
||||
}
|
||||
|
||||
public PacketFAPluginMessage(String tag, byte[] data)
|
||||
{
|
||||
this();
|
||||
this.tag = tag;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ByteBuf buf)
|
||||
{
|
||||
tag = readString( buf );
|
||||
data = readArray( buf );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buf)
|
||||
{
|
||||
writeString( tag, buf );
|
||||
writeArray( data, buf );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(AbstractPacketHandler handler) throws Exception
|
||||
{
|
||||
handler.handle( this );
|
||||
}
|
||||
|
||||
public DataInput getStream()
|
||||
{
|
||||
return new DataInputStream( new ByteArrayInputStream( data ) );
|
||||
}
|
||||
|
||||
public MinecraftInput getMCStream()
|
||||
{
|
||||
return new MinecraftInput( Unpooled.wrappedBuffer( data ) );
|
||||
}
|
||||
}
|
@@ -0,0 +1,48 @@
|
||||
package net.md_5.bungee.protocol.packet;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class PacketFCEncryptionResponse extends DefinedPacket
|
||||
{
|
||||
|
||||
private byte[] sharedSecret;
|
||||
private byte[] verifyToken;
|
||||
|
||||
private PacketFCEncryptionResponse()
|
||||
{
|
||||
super( 0xFC );
|
||||
}
|
||||
|
||||
public PacketFCEncryptionResponse(byte[] sharedSecret, byte[] verifyToken)
|
||||
{
|
||||
this();
|
||||
this.sharedSecret = sharedSecret;
|
||||
this.verifyToken = verifyToken;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ByteBuf buf)
|
||||
{
|
||||
sharedSecret = readArray( buf );
|
||||
verifyToken = readArray( buf );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buf)
|
||||
{
|
||||
writeArray( sharedSecret, buf );
|
||||
writeArray( verifyToken, buf );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(AbstractPacketHandler handler) throws Exception
|
||||
{
|
||||
handler.handle( this );
|
||||
}
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
package net.md_5.bungee.protocol.packet;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class PacketFDEncryptionRequest extends DefinedPacket
|
||||
{
|
||||
|
||||
private String serverId;
|
||||
private byte[] publicKey;
|
||||
private byte[] verifyToken;
|
||||
|
||||
private PacketFDEncryptionRequest()
|
||||
{
|
||||
super( 0xFD );
|
||||
}
|
||||
|
||||
public PacketFDEncryptionRequest(String serverId, byte[] publicKey, byte[] verifyToken)
|
||||
{
|
||||
this();
|
||||
this.serverId = serverId;
|
||||
this.publicKey = publicKey;
|
||||
this.verifyToken = verifyToken;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ByteBuf buf)
|
||||
{
|
||||
serverId = readString( buf );
|
||||
publicKey = readArray( buf );
|
||||
verifyToken = readArray( buf );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buf)
|
||||
{
|
||||
writeString( serverId, buf );
|
||||
writeArray( publicKey, buf );
|
||||
writeArray( verifyToken, buf );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(AbstractPacketHandler handler) throws Exception
|
||||
{
|
||||
handler.handle( this );
|
||||
}
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
package net.md_5.bungee.protocol.packet;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@ToString
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class PacketFEPing extends DefinedPacket
|
||||
{
|
||||
|
||||
private byte version;
|
||||
|
||||
private PacketFEPing()
|
||||
{
|
||||
super( 0xFE );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ByteBuf buf)
|
||||
{
|
||||
version = buf.readByte();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buf)
|
||||
{
|
||||
buf.writeByte( version );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(AbstractPacketHandler handler) throws Exception
|
||||
{
|
||||
handler.handle( this );
|
||||
}
|
||||
}
|
@@ -0,0 +1,44 @@
|
||||
package net.md_5.bungee.protocol.packet;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class PacketFFKick extends DefinedPacket
|
||||
{
|
||||
|
||||
private String message;
|
||||
|
||||
private PacketFFKick()
|
||||
{
|
||||
super( 0xFF );
|
||||
}
|
||||
|
||||
public PacketFFKick(String message)
|
||||
{
|
||||
this();
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ByteBuf buf)
|
||||
{
|
||||
message = readString( buf );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buf)
|
||||
{
|
||||
writeString( message, buf );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(AbstractPacketHandler handler) throws Exception
|
||||
{
|
||||
handler.handle( this );
|
||||
}
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
package net.md_5.bungee.protocol.packet.forge;
|
||||
|
||||
import net.md_5.bungee.protocol.packet.*;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@ToString
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class Forge1Login extends Packet1Login
|
||||
{
|
||||
|
||||
private Forge1Login()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public Forge1Login(int entityId, String levelType, byte gameMode, int dimension, byte difficulty, byte unused, byte maxPlayers)
|
||||
{
|
||||
super( entityId, levelType, gameMode, dimension, difficulty, unused, maxPlayers );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(ByteBuf buf)
|
||||
{
|
||||
entityId = buf.readInt();
|
||||
levelType = readString( buf );
|
||||
gameMode = buf.readByte();
|
||||
dimension = buf.readInt();
|
||||
difficulty = buf.readByte();
|
||||
unused = buf.readByte();
|
||||
maxPlayers = buf.readByte();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuf buf)
|
||||
{
|
||||
buf.writeInt( entityId );
|
||||
writeString( levelType, buf );
|
||||
buf.writeByte( gameMode );
|
||||
buf.writeInt( dimension );
|
||||
buf.writeByte( difficulty );
|
||||
buf.writeByte( unused );
|
||||
buf.writeByte( maxPlayers );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(AbstractPacketHandler handler) throws Exception
|
||||
{
|
||||
handler.handle( this );
|
||||
}
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
package net.md_5.bungee.protocol.skip;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public class BulkChunk extends Instruction
|
||||
{
|
||||
|
||||
@Override
|
||||
void read(ByteBuf in)
|
||||
{
|
||||
short count = in.readShort();
|
||||
int size = in.readInt();
|
||||
in.readBoolean();
|
||||
in.skipBytes( size + count * 12 );
|
||||
}
|
||||
}
|
@@ -1,7 +1,6 @@
|
||||
package net.md_5.mendax.datainput;
|
||||
package net.md_5.bungee.protocol.skip;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.IOException;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
class ByteHeader extends Instruction
|
||||
{
|
||||
@@ -14,12 +13,12 @@ class ByteHeader extends Instruction
|
||||
}
|
||||
|
||||
@Override
|
||||
void read(DataInput in, byte[] buffer) throws IOException
|
||||
void read(ByteBuf in)
|
||||
{
|
||||
byte size = in.readByte();
|
||||
for ( byte b = 0; b < size; b++ )
|
||||
{
|
||||
child.read( in, buffer );
|
||||
child.read( in );
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,7 +1,6 @@
|
||||
package net.md_5.mendax.datainput;
|
||||
package net.md_5.bungee.protocol.skip;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.IOException;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
abstract class Instruction
|
||||
{
|
||||
@@ -24,13 +23,11 @@ abstract class Instruction
|
||||
static final Instruction SHORT_ITEM = new ShortHeader( ITEM );
|
||||
static final Instruction STRING = new ShortHeader( new Jump( 2 ) );
|
||||
static final Instruction USHORT_BYTE = new UnsignedShortByte();
|
||||
static final Instruction OPTIONAL_WINDOW = new OptionalWindow();
|
||||
// Illegal forward references below this line
|
||||
static final Instruction BYTE_INT = new ByteHeader( INT );
|
||||
// Custom instructions
|
||||
static final Instruction STRING_ARRAY = new ShortHeader( STRING );
|
||||
|
||||
abstract void read(DataInput in, byte[] buffer) throws IOException;
|
||||
|
||||
final void skip(DataInput in, byte[] buffer, int len) throws IOException
|
||||
{
|
||||
in.readFully( buffer, 0, len );
|
||||
}
|
||||
abstract void read(ByteBuf in);
|
||||
}
|
@@ -1,7 +1,6 @@
|
||||
package net.md_5.mendax.datainput;
|
||||
package net.md_5.bungee.protocol.skip;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.IOException;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
class IntHeader extends Instruction
|
||||
{
|
||||
@@ -14,12 +13,12 @@ class IntHeader extends Instruction
|
||||
}
|
||||
|
||||
@Override
|
||||
void read(DataInput in, byte[] buffer) throws IOException
|
||||
void read(ByteBuf in)
|
||||
{
|
||||
int size = in.readInt();
|
||||
for ( int i = 0; i < size; i++ )
|
||||
{
|
||||
child.read( in, buffer );
|
||||
child.read( in );
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,18 @@
|
||||
package net.md_5.bungee.protocol.skip;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
class Item extends Instruction
|
||||
{
|
||||
|
||||
@Override
|
||||
void read(ByteBuf in)
|
||||
{
|
||||
short type = in.readShort();
|
||||
if ( type >= 0 )
|
||||
{
|
||||
in.skipBytes( 3 );
|
||||
SHORT_BYTE.read( in );
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,7 +1,6 @@
|
||||
package net.md_5.mendax.datainput;
|
||||
package net.md_5.bungee.protocol.skip;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.IOException;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
class Jump extends Instruction
|
||||
{
|
||||
@@ -18,8 +17,8 @@ class Jump extends Instruction
|
||||
}
|
||||
|
||||
@Override
|
||||
void read(DataInput in, byte[] buffer) throws IOException
|
||||
void read(ByteBuf in)
|
||||
{
|
||||
skip( in, buffer, len );
|
||||
in.skipBytes( len );
|
||||
}
|
||||
}
|
@@ -1,13 +1,12 @@
|
||||
package net.md_5.mendax.datainput;
|
||||
package net.md_5.bungee.protocol.skip;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.IOException;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
class MetaData extends Instruction
|
||||
{
|
||||
|
||||
@Override
|
||||
void read(DataInput in, byte[] buffer) throws IOException
|
||||
void read(ByteBuf in)
|
||||
{
|
||||
int x = in.readUnsignedByte();
|
||||
while ( x != 127 )
|
||||
@@ -16,25 +15,25 @@ class MetaData extends Instruction
|
||||
switch ( type )
|
||||
{
|
||||
case 0:
|
||||
BYTE.read( in, buffer );
|
||||
BYTE.read( in );
|
||||
break;
|
||||
case 1:
|
||||
SHORT.read( in, buffer );
|
||||
SHORT.read( in );
|
||||
break;
|
||||
case 2:
|
||||
INT.read( in, buffer );
|
||||
INT.read( in );
|
||||
break;
|
||||
case 3:
|
||||
FLOAT.read( in, buffer );
|
||||
FLOAT.read( in );
|
||||
break;
|
||||
case 4:
|
||||
STRING.read( in, buffer );
|
||||
STRING.read( in );
|
||||
break;
|
||||
case 5:
|
||||
ITEM.read( in, buffer );
|
||||
ITEM.read( in );
|
||||
break;
|
||||
case 6:
|
||||
skip( in, buffer, 12 ); // int, int, int
|
||||
in.skipBytes( 12 ); // int, int, int
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException( "Unknown metadata type " + type );
|
@@ -0,0 +1,17 @@
|
||||
package net.md_5.bungee.protocol.skip;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
class OptionalMotion extends Instruction
|
||||
{
|
||||
|
||||
@Override
|
||||
void read(ByteBuf in)
|
||||
{
|
||||
int data = in.readInt();
|
||||
if ( data > 0 )
|
||||
{
|
||||
in.skipBytes( 6 );
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
package net.md_5.bungee.protocol.skip;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
public class OptionalWindow extends Instruction
|
||||
{
|
||||
|
||||
@Override
|
||||
void read(ByteBuf in)
|
||||
{
|
||||
BYTE.read( in );
|
||||
byte type = in.readByte();
|
||||
STRING.read( in );
|
||||
BYTE.read( in );
|
||||
BOOLEAN.read( in );
|
||||
if ( type == 11 )
|
||||
{
|
||||
INT.read( in );
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,24 +1,24 @@
|
||||
package net.md_5.mendax.datainput;
|
||||
package net.md_5.bungee.protocol.skip;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.IOException;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.md_5.mendax.PacketDefinitions;
|
||||
import net.md_5.mendax.PacketDefinitions.OpCode;
|
||||
import net.md_5.bungee.protocol.OpCode;
|
||||
import net.md_5.bungee.protocol.Protocol;
|
||||
|
||||
public class DataInputPacketReader
|
||||
public class PacketReader
|
||||
{
|
||||
|
||||
private static final Instruction[][] instructions = new Instruction[ 256 ][];
|
||||
private final Instruction[][] instructions;
|
||||
|
||||
static
|
||||
public PacketReader(Protocol protocol)
|
||||
{
|
||||
instructions = new Instruction[ protocol.getOpCodes().length ][];
|
||||
for ( int i = 0; i < instructions.length; i++ )
|
||||
{
|
||||
List<Instruction> output = new ArrayList<>();
|
||||
|
||||
OpCode[] enums = PacketDefinitions.opCodes[i];
|
||||
OpCode[] enums = protocol.getOpCodes()[i];
|
||||
if ( enums != null )
|
||||
{
|
||||
for ( OpCode struct : enums )
|
||||
@@ -59,35 +59,16 @@ public class DataInputPacketReader
|
||||
}
|
||||
}
|
||||
|
||||
private static void readPacket(int packetId, DataInput in, byte[] buffer, int protocol) throws IOException
|
||||
public void tryRead(short packetId, ByteBuf in)
|
||||
{
|
||||
Instruction[] packetDef = null;
|
||||
if ( packetId + protocol < instructions.length )
|
||||
{
|
||||
packetDef = instructions[packetId + protocol];
|
||||
}
|
||||
Instruction[] packetDef = instructions[packetId];
|
||||
|
||||
if ( packetDef == null )
|
||||
if ( packetDef != null )
|
||||
{
|
||||
if ( protocol == PacketDefinitions.VANILLA_PROTOCOL )
|
||||
{
|
||||
throw new IOException( "Unknown packet id " + packetId );
|
||||
} else
|
||||
{
|
||||
readPacket( packetId, in, buffer, PacketDefinitions.VANILLA_PROTOCOL );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for ( Instruction instruction : packetDef )
|
||||
{
|
||||
instruction.read( in, buffer );
|
||||
instruction.read( in );
|
||||
}
|
||||
}
|
||||
|
||||
public static void readPacket(DataInput in, byte[] buffer, int protocol) throws IOException
|
||||
{
|
||||
int packetId = in.readUnsignedByte();
|
||||
readPacket( packetId, in, buffer, protocol );
|
||||
}
|
||||
}
|
@@ -1,7 +1,6 @@
|
||||
package net.md_5.mendax.datainput;
|
||||
package net.md_5.bungee.protocol.skip;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.IOException;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
class ShortHeader extends Instruction
|
||||
{
|
||||
@@ -14,12 +13,12 @@ class ShortHeader extends Instruction
|
||||
}
|
||||
|
||||
@Override
|
||||
void read(DataInput in, byte[] buffer) throws IOException
|
||||
void read(ByteBuf in)
|
||||
{
|
||||
short size = in.readShort();
|
||||
for ( short s = 0; s < size; s++ )
|
||||
{
|
||||
child.read( in, buffer );
|
||||
child.read( in );
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
package net.md_5.bungee.protocol.skip;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
class UnsignedShortByte extends Instruction
|
||||
{
|
||||
|
||||
@Override
|
||||
void read(ByteBuf in)
|
||||
{
|
||||
int size = in.readUnsignedShort();
|
||||
in.skipBytes( size );
|
||||
}
|
||||
}
|
@@ -1,17 +0,0 @@
|
||||
package net.md_5.mendax.datainput;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.IOException;
|
||||
|
||||
public class BulkChunk extends Instruction
|
||||
{
|
||||
|
||||
@Override
|
||||
void read(DataInput in, byte[] buffer) throws IOException
|
||||
{
|
||||
short count = in.readShort();
|
||||
int size = in.readInt();
|
||||
in.readBoolean();
|
||||
skip( in, buffer, size + count * 12 );
|
||||
}
|
||||
}
|
@@ -1,19 +0,0 @@
|
||||
package net.md_5.mendax.datainput;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.IOException;
|
||||
|
||||
class Item extends Instruction
|
||||
{
|
||||
|
||||
@Override
|
||||
void read(DataInput in, byte[] buffer) throws IOException
|
||||
{
|
||||
short type = in.readShort();
|
||||
if ( type >= 0 )
|
||||
{
|
||||
skip( in, buffer, 3 );
|
||||
SHORT_BYTE.read( in, buffer );
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,18 +0,0 @@
|
||||
package net.md_5.mendax.datainput;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.IOException;
|
||||
|
||||
public class OptionalMotion extends Instruction
|
||||
{
|
||||
|
||||
@Override
|
||||
void read(DataInput in, byte[] buffer) throws IOException
|
||||
{
|
||||
int data = in.readInt();
|
||||
if ( data > 0 )
|
||||
{
|
||||
skip( in, buffer, 6 );
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,15 +0,0 @@
|
||||
package net.md_5.mendax.datainput;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.IOException;
|
||||
|
||||
public class UnsignedShortByte extends Instruction
|
||||
{
|
||||
|
||||
@Override
|
||||
void read(DataInput in, byte[] buffer) throws IOException
|
||||
{
|
||||
int size = in.readUnsignedShort();
|
||||
skip( in, buffer, size );
|
||||
}
|
||||
}
|
@@ -0,0 +1,45 @@
|
||||
package net.md_5.bungee.protocol;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import net.md_5.bungee.protocol.packet.AbstractPacketHandler;
|
||||
import net.md_5.bungee.protocol.packet.DefinedPacket;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class PacketTest
|
||||
{
|
||||
|
||||
@Test
|
||||
public void testPackets() throws Exception
|
||||
{
|
||||
AbstractPacketHandler handler = new AbstractPacketHandler()
|
||||
{
|
||||
};
|
||||
|
||||
for ( short i = 0; i < 256; i++ )
|
||||
{
|
||||
Class<? extends DefinedPacket> clazz = Vanilla.getInstance().getClasses()[ i];
|
||||
if ( clazz != null )
|
||||
{
|
||||
Assert.assertTrue( "Packet " + clazz + " is not public", Modifier.isPublic( clazz.getModifiers() ) );
|
||||
DefinedPacket packet = Vanilla.packet( i, Vanilla.getInstance() );
|
||||
Assert.assertTrue( "Could not create packet with id " + i + " and class " + clazz, packet != null );
|
||||
Assert.assertTrue( "Packet with id " + i + " does not have correct class (expected " + clazz + " but got " + packet.getClass(), packet.getClass() == clazz );
|
||||
Assert.assertTrue( "Packet " + clazz + " does not report correct id", packet.getId() == i );
|
||||
Assert.assertTrue( "Packet " + clazz + " does not have custom hash code", packet.hashCode() != System.identityHashCode( packet ) );
|
||||
Assert.assertTrue( "Packet " + clazz + " does not have custom toString", packet.toString().indexOf( '@' ) == -1 );
|
||||
// TODO: Enable this test again in v2
|
||||
// Assert.assertTrue( "Packet " + clazz + " does not have private no args constructor", Modifier.isPrivate( clazz.getDeclaredConstructor().getModifiers() ) );
|
||||
|
||||
for ( Field field : clazz.getDeclaredFields() )
|
||||
{
|
||||
// TODO: Enable this test again in v2
|
||||
// Assert.assertTrue( "Packet " + clazz + " has non private field " + field, Modifier.isPrivate( field.getModifiers() ) );
|
||||
}
|
||||
|
||||
packet.handle( handler ); // Make sure there are no exceptions
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user