Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a1c591a616 | ||
|
|
999e21bf77 | ||
|
|
c8e5a37472 | ||
|
|
c6fffca506 | ||
|
|
f1206a1fc6 | ||
|
|
29a4280b50 | ||
|
|
552f63a27f | ||
|
|
612608181d | ||
|
|
8e652f0c44 | ||
|
|
4a3e89d713 | ||
|
|
3dd6d1e0b9 | ||
|
|
f42e1ad71d | ||
|
|
b44f36185a | ||
|
|
1621adad02 | ||
|
|
d2682242ae | ||
|
|
0b26fe3266 | ||
|
|
0354ddf765 | ||
|
|
82e0d01c29 | ||
|
|
57b68f185c | ||
|
|
8f9b8c0433 | ||
|
|
27ced0fc36 | ||
|
|
1d383a7d37 | ||
|
|
ae81019fd8 | ||
|
|
d05019adac | ||
|
|
1d45ec916c | ||
|
|
7328fc9381 | ||
|
|
89f21b927f | ||
|
|
04c33929cd | ||
|
|
fa2aab5e74 | ||
|
|
ebc81c0986 | ||
|
|
c6348e0dc9 | ||
|
|
f84d3000f4 | ||
|
|
7ddfc681cc | ||
|
|
cdb67c80c0 | ||
|
|
ed78c9d746 | ||
|
|
b7128d5f33 | ||
|
|
ba0b32ffdb | ||
|
|
3b420a4c28 | ||
|
|
5abc9c7154 | ||
|
|
c5f377476c | ||
|
|
105ea434da | ||
|
|
f0196bdab9 | ||
|
|
982d1ee9a0 | ||
|
|
a7bbb20f60 | ||
|
|
2ca79017e2 | ||
|
|
c4a3d26d96 | ||
|
|
93292fb2f2 | ||
|
|
3a9be091ea | ||
|
|
92f3944049 | ||
|
|
27f90655f1 | ||
|
|
4b868392e6 | ||
|
|
ebb1ba990d | ||
|
|
b4bb72e236 | ||
|
|
e876ebe078 | ||
|
|
d6af873b9d | ||
|
|
c10d309180 | ||
|
|
c33ab2c52c | ||
|
|
ec6cef3526 | ||
|
|
c61738bbab | ||
|
|
00990a49f9 | ||
|
|
72a199ce48 | ||
|
|
ac585f7c81 | ||
|
|
a8b286c6fc | ||
|
|
364747986b | ||
|
|
b51c3ad20a | ||
|
|
df8c77291d | ||
|
|
9dde0e54fe | ||
|
|
72f1b2bf02 | ||
|
|
332782e99c | ||
|
|
9f7e49b453 | ||
|
|
e17f53ca3c | ||
|
|
5fc1abaff2 | ||
|
|
a9ad25d3fc | ||
|
|
bf3c0cda46 | ||
|
|
e9680c287d | ||
|
|
e05dda9ea6 | ||
|
|
7db442682e | ||
|
|
61911ac09a | ||
|
|
381dc28831 | ||
|
|
1686d38f0b | ||
|
|
509b93968d | ||
|
|
1458331e3f | ||
|
|
d5777a55f0 | ||
|
|
d7c4d2c425 | ||
|
|
a268687cea | ||
|
|
d679e43058 | ||
|
|
1f609f8732 | ||
|
|
30e9d38bf2 | ||
|
|
922342345d | ||
|
|
80c8c5453b | ||
|
|
ba72ec37c6 | ||
|
|
9bfb696c9d | ||
|
|
4a9848f51d | ||
|
|
383eacc814 | ||
|
|
860b80e2c2 | ||
|
|
0259bc8d9d | ||
|
|
37238e1226 | ||
|
|
c51880941b | ||
|
|
451bbe7597 | ||
|
|
d99e20d95e | ||
|
|
5eca22a9df | ||
|
|
c4d6b26986 | ||
|
|
197acc4d2f | ||
|
|
da5a5cf15a | ||
|
|
0797df24d2 | ||
|
|
7fca4ac8d6 | ||
|
|
0516513c67 | ||
|
|
4603794436 | ||
|
|
a5bbe4047b | ||
|
|
770a2d3287 | ||
|
|
3bd4b82d94 | ||
|
|
218b2d7782 | ||
|
|
76a08e6c12 | ||
|
|
4d28a58dcb | ||
|
|
9347e7a133 | ||
|
|
33ed5ff904 | ||
|
|
291994d388 | ||
|
|
f6ea9675bf | ||
|
|
cc303f56a4 | ||
|
|
290bd0a8fe | ||
|
|
a8573cc8e1 | ||
|
|
814bd941c0 | ||
|
|
d3f6d32848 | ||
|
|
5e1b82ea8a | ||
|
|
e49cae5d67 | ||
|
|
8168bb2085 | ||
|
|
621a7c98b9 | ||
|
|
28da2aafc4 | ||
|
|
e89e6fac28 | ||
|
|
a5e067af9e | ||
|
|
04de7fd5ea | ||
|
|
815428f35b | ||
|
|
833f569150 | ||
|
|
6b227d55aa | ||
|
|
57a6c26c07 | ||
|
|
b2da168f6a | ||
|
|
4c1e14af57 | ||
|
|
5f9e82617f | ||
|
|
9868facdde | ||
|
|
d45f8bddac | ||
|
|
e4b086e7e5 | ||
|
|
7afe3c63cd | ||
|
|
5103acf414 | ||
|
|
70b763b5a3 | ||
|
|
e1370b803f | ||
|
|
ac3ca0ddf7 | ||
|
|
15bec5525a | ||
|
|
0e8dcb6a40 | ||
|
|
836efcfa03 | ||
|
|
774e6decf3 | ||
|
|
839265e0b9 | ||
|
|
32c94c85f1 | ||
|
|
a36df67f6f | ||
|
|
cdb46f476c | ||
|
|
96e5e7393e | ||
|
|
130001a44c | ||
|
|
1328ea81e8 | ||
|
|
a42153cff9 | ||
|
|
79929f5700 | ||
|
|
8c3726c165 | ||
|
|
51a58f79a5 | ||
|
|
8691304925 | ||
|
|
9fef95d96e | ||
|
|
4d42a23510 | ||
|
|
787df36fe0 | ||
|
|
a59ea40e12 | ||
|
|
fdb3a23acc | ||
|
|
60d24ac3c1 | ||
|
|
7634540bd7 | ||
|
|
0a475e4242 | ||
|
|
ff3b66b22e | ||
|
|
8be5f5bfa6 | ||
|
|
8d887335e2 | ||
|
|
553f429a53 | ||
|
|
a4a8b36665 | ||
|
|
49d46b79df | ||
|
|
08a2b92bcf | ||
|
|
f32dafc3ee | ||
|
|
84e391ffc8 | ||
|
|
26a369af89 | ||
|
|
56c752b487 | ||
|
|
890fcadac2 | ||
|
|
27f09f6627 | ||
|
|
e5b89271ee | ||
|
|
48ef0e7852 | ||
|
|
192851b03f | ||
|
|
dd30876e70 | ||
|
|
ce2603549b | ||
|
|
c645124e55 | ||
|
|
3c3a00b7bb | ||
|
|
d34e152b98 | ||
|
|
d5454b918a | ||
|
|
427a0fff4a | ||
|
|
7fc446321d | ||
|
|
3f85f4998b | ||
|
|
4799fb67c4 | ||
|
|
5ed9038f7b | ||
|
|
8c1cd4b824 | ||
|
|
50a09de212 | ||
|
|
e66710f5ed | ||
|
|
33131f4fcd | ||
|
|
9834787279 | ||
|
|
227b569138 | ||
|
|
ad1a8a3dba | ||
|
|
262c470031 | ||
|
|
4c9b9be23f | ||
|
|
d1c04d39d2 | ||
|
|
afbe7b44b6 | ||
|
|
f76f1687fb | ||
|
|
8eb4015cab | ||
|
|
3ec44f72da | ||
|
|
3797c45d98 | ||
|
|
94b7523774 | ||
|
|
6f0de9f01c | ||
|
|
16cc63447f | ||
|
|
bb6661b4eb | ||
|
|
63a5005257 | ||
|
|
8b4fdd4773 | ||
|
|
333bea795f | ||
|
|
3ee972a4ff | ||
|
|
94a1f67975 | ||
|
|
e00b55842d | ||
|
|
ba1a4afa79 | ||
|
|
d2925592fc | ||
|
|
d97c1a03ee | ||
|
|
a1d48d3b20 | ||
|
|
4ce0463465 | ||
|
|
6725caad36 | ||
|
|
17e9d667a8 | ||
|
|
92d85822f3 | ||
|
|
bdeb421ca3 | ||
|
|
b5a5aa4748 | ||
|
|
096d8ab807 | ||
|
|
da7d2c7929 | ||
|
|
ead6156bfa | ||
|
|
4220b2d7b3 | ||
|
|
e7c598d29e | ||
|
|
1677383049 | ||
|
|
23ec389798 | ||
|
|
0ceaf9a3b2 | ||
|
|
5fbb775ab4 | ||
|
|
8914842e71 | ||
|
|
3e912f5282 | ||
|
|
360562e80e | ||
|
|
8ffc8836d6 | ||
|
|
2f629ac77f | ||
|
|
f1ead98a46 | ||
|
|
c3747cfebd | ||
|
|
21d6970b0d | ||
|
|
d9072d54d0 | ||
|
|
a963980f9d | ||
|
|
45f8ce1a44 | ||
|
|
eb981ef06a | ||
|
|
56030945e9 | ||
|
|
d4e52967ca | ||
|
|
4b3a998ae2 | ||
|
|
b0dd3dae9b | ||
|
|
372a802c98 | ||
|
|
16f2f29bf2 | ||
|
|
e0aba994b6 | ||
|
|
6aea77cdbc | ||
|
|
07d96cd486 | ||
|
|
9b21a4d07a | ||
|
|
dea483d362 | ||
|
|
636e246c70 | ||
|
|
0d5c7b5250 | ||
|
|
1b5f066eb0 | ||
|
|
ffe224c4bf | ||
|
|
792fe16124 | ||
|
|
3c92108c44 | ||
|
|
3b71327245 | ||
|
|
6d70978285 | ||
|
|
953ad680ee | ||
|
|
765f2fad92 | ||
|
|
bede734af7 | ||
|
|
31853376d6 | ||
|
|
3a100ce325 | ||
|
|
bbb2ef0668 | ||
|
|
9f697673c0 | ||
|
|
b1deb8629b | ||
|
|
70d0400c67 | ||
|
|
b0c08ce813 | ||
|
|
3af91fcac9 | ||
|
|
d1c2fe4169 | ||
|
|
1900d37c94 | ||
|
|
5d17a2a613 | ||
|
|
4a93603614 | ||
|
|
9a1a59f15f | ||
|
|
0c350a3f27 | ||
|
|
c3d75f1e8d | ||
|
|
b847e53221 | ||
|
|
c9570b0ad7 | ||
|
|
ee5caaa81c | ||
|
|
a81976b5a5 | ||
|
|
fd32638787 | ||
|
|
816cd945f8 | ||
|
|
07f1f5f426 | ||
|
|
8ac124a19e | ||
|
|
e90116291f | ||
|
|
2dbb3f08cb | ||
|
|
71c333af5d | ||
|
|
925eca89d4 | ||
|
|
a712245ebe | ||
|
|
8c15df942d | ||
|
|
6ce4fbd7fc | ||
|
|
3e4fc70442 | ||
|
|
fc91416ab7 | ||
|
|
0f6ee71733 | ||
|
|
4dafa959c1 | ||
|
|
66a6c2d8f9 | ||
|
|
b2654e11a3 | ||
|
|
e2cfdda9cf | ||
|
|
b5085a8959 | ||
|
|
dccf01220c | ||
|
|
12dc5b69c0 | ||
|
|
0423b5f335 | ||
|
|
a4c37da10e | ||
|
|
de49279aab | ||
|
|
f651ffddf5 | ||
|
|
ee959b68dc | ||
|
|
b1d1201083 | ||
|
|
faff8fadc8 | ||
|
|
85a0f55b20 | ||
|
|
cf2e571d80 | ||
|
|
68596469eb | ||
|
|
181eda6ae4 | ||
|
|
31ed9c0e4c | ||
|
|
2916fb7112 | ||
|
|
1ca1a960b5 | ||
|
|
6c6a1c9465 | ||
|
|
0be7a21bab | ||
|
|
ca51988694 | ||
|
|
9184d54cb7 | ||
|
|
ca43582e4f | ||
|
|
a1552990bf | ||
|
|
99c9f50dfb | ||
|
|
565e14ecf3 | ||
|
|
521a8e0777 | ||
|
|
0141db4a64 | ||
|
|
9ed9db88b7 | ||
|
|
f52a05b477 | ||
|
|
8936204849 | ||
|
|
50efff2819 | ||
|
|
af325f9a62 | ||
|
|
fe29188e3f | ||
|
|
b753a98971 | ||
|
|
c73d88a7e2 | ||
|
|
bd872bc271 | ||
|
|
c0c03a0629 | ||
|
|
18f3f135c8 | ||
|
|
0304d0ac5a | ||
|
|
643fa1ad18 | ||
|
|
5c65874749 | ||
|
|
5a4db46427 | ||
|
|
305d376128 | ||
|
|
4308936c1a | ||
|
|
87b0ac9295 | ||
|
|
3dee3b2a0e | ||
|
|
c2f0e30511 | ||
|
|
a824a70cc6 | ||
|
|
07692f87f2 | ||
|
|
7f94b254a2 | ||
|
|
ceb3581c28 | ||
|
|
c3bf5d75d3 | ||
|
|
297d261ca9 | ||
|
|
89a67e7ee4 | ||
|
|
0d6d34a93b | ||
|
|
cb89a42184 | ||
|
|
6837b1d803 | ||
|
|
8967babc37 | ||
|
|
a4f93cfe8d | ||
|
|
5dde0b56f8 | ||
|
|
43dee3dfeb | ||
|
|
937dbc5c03 | ||
|
|
78e17c2abb | ||
|
|
4653dbcaba | ||
|
|
057e1b960a | ||
|
|
5feaabad92 | ||
|
|
2c395d4313 | ||
|
|
6af68cfc7a | ||
|
|
66f2c371ec | ||
|
|
c5bcf50d66 | ||
|
|
86625694fc | ||
|
|
dcaae8a15a | ||
|
|
1996399cde | ||
|
|
62d3fdd276 | ||
|
|
7740cf6eae | ||
|
|
5bbaa5d7c2 | ||
|
|
70cb1ad0fb | ||
|
|
fcfc404120 | ||
|
|
2f855874a6 | ||
|
|
26d5542864 | ||
|
|
ee5e0ef3a7 | ||
|
|
51e5cf5c55 | ||
|
|
3c09b8c3a7 | ||
|
|
6e25876230 | ||
|
|
c5a3e57974 | ||
|
|
508fb5f1e2 | ||
|
|
e9b6f5ab0f | ||
|
|
efb79cc7d2 | ||
|
|
901084f1f6 | ||
|
|
acb4ca7619 | ||
|
|
691684c828 | ||
|
|
06482124ce | ||
|
|
d61fda966f | ||
|
|
63df6cdf80 | ||
|
|
3365fb569f | ||
|
|
f9c48e488e | ||
|
|
0c81e0fd54 | ||
|
|
0cddca1847 | ||
|
|
23574cd075 | ||
|
|
cc7897752d | ||
|
|
dc4dc80bdc | ||
|
|
808a7b69d8 | ||
|
|
5b3b6ff509 | ||
|
|
b923e86a91 | ||
|
|
2c078dd1d4 | ||
|
|
feb80c38b8 | ||
|
|
b525407ad5 | ||
|
|
b660673743 | ||
|
|
ba6e7c03fb | ||
|
|
50e4b46018 | ||
|
|
a837bf38b1 | ||
|
|
6fb102edf9 | ||
|
|
e45ed75e91 | ||
|
|
ef6b6b9466 | ||
|
|
f6df333304 | ||
|
|
83aee85f48 | ||
|
|
73c5a0dfad | ||
|
|
555c2b86c7 | ||
|
|
b5fd4b68bf | ||
|
|
3baaa64754 | ||
|
|
e142d95abc | ||
|
|
6ac93a97df | ||
|
|
7db7e44bfc | ||
|
|
4792bda57b | ||
|
|
cd009e7080 | ||
|
|
bcc967d72d | ||
|
|
913cbf94f4 | ||
|
|
1941d2c34d | ||
|
|
36140fb42b | ||
|
|
91e2668998 | ||
|
|
b6f625b498 | ||
|
|
0c176aabd2 | ||
|
|
39ec5958e1 | ||
|
|
6467fece64 | ||
|
|
c6a8d5ad84 | ||
|
|
42b1f2b1a9 | ||
|
|
208823466c | ||
|
|
0c67bfb999 | ||
|
|
d64e92d84a | ||
|
|
29ec5f6638 | ||
|
|
9d10d5001d | ||
|
|
834b29f84a | ||
|
|
7787ce9f33 | ||
|
|
4775e9f815 | ||
|
|
7764939208 | ||
|
|
9c331ef630 | ||
|
|
3c3261bd96 | ||
|
|
f71530a4ee | ||
|
|
c9e4f627c8 | ||
|
|
75a5ec6022 | ||
|
|
366490d7fc | ||
|
|
9f22bebd3b | ||
|
|
35b0e6ccd8 | ||
|
|
3073342482 | ||
|
|
e83086fd21 | ||
|
|
9c886d8abb | ||
|
|
36b574edda |
No files matched your search
@@ -0,0 +1,30 @@
|
||||
name: Generate and deploy JavaDocs
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK 1.8
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 1.8
|
||||
- name: Build with Maven
|
||||
run: mvn install
|
||||
- name: List target/apidocs
|
||||
run: ls target/apidocs
|
||||
- name: GitHub Pages
|
||||
uses: crazy-max/ghaction-github-pages@v2.1.2
|
||||
env:
|
||||
GH_PAT: ${{ secrets.GH_PAT }}
|
||||
with:
|
||||
target_branch: javadocs
|
||||
keep_history: true
|
||||
build_dir: target/apidocs
|
||||
commit_message: Update JavaDocs
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
#
|
||||
# JetBrains
|
||||
#
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/artifacts
|
||||
# .idea/compiler.xml
|
||||
# .idea/jarRepositories.xml
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
|
||||
#
|
||||
# Java
|
||||
#
|
||||
|
||||
# Compiled class file
|
||||
*.class
|
||||
|
||||
# Log file
|
||||
*.log
|
||||
|
||||
# BlueJ files
|
||||
*.ctxt
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.nar
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
#
|
||||
# Maven
|
||||
#
|
||||
target/
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
pom.xml.next
|
||||
release.properties
|
||||
dependency-reduced-pom.xml
|
||||
buildNumber.properties
|
||||
.mvn/timing.properties
|
||||
# https://github.com/takari/maven-wrapper#usage-without-binary-jar
|
||||
.mvn/wrapper/maven-wrapper.jar
|
||||
@@ -1,674 +1,21 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 retrooper
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -1,68 +1,20 @@
|
||||
# packetevents by purplex
|
||||
# packetevents
|
||||
|
||||
PacketListener coded by purplex.
|
||||
A Spigot packet API with some nice utlities.
|
||||
|
||||
Licensed with the GPL3 license.
|
||||
## About
|
||||
|
||||
[](https://www.gnu.org/licenses/gpl-3.0)
|
||||
This packetlistener is **only** supported on Spigot servers and has been tested to work on these Spigot forks: PaperMC, Tuinity
|
||||
|
||||
Coding help discord server: https://discord.gg/ZWTkg4v
|
||||
* No dependencies
|
||||
|
||||
How to use with **Gradle, Maven, sbt and leiningen**.
|
||||
* Licensed under the MIT license
|
||||
|
||||
The lastest stable tested versions are displayed below.
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
|
||||
[](https://jitpack.io/#purplexdev/packetevents)
|
||||
|
||||
# Gradle
|
||||
|
||||
```gradle
|
||||
allprojects {
|
||||
repositories {
|
||||
...
|
||||
maven { url 'https://jitpack.io' }
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.github.purplexdev:packetevents:1.1.5'
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
# Maven
|
||||
|
||||
```xml
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>jitpack.io</id>
|
||||
<url>https://jitpack.io</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.github.purplexdev</groupId>
|
||||
<artifactId>packetevents</artifactId>
|
||||
<version>1.1.5</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
```
|
||||
|
||||
# sbt
|
||||
|
||||
```
|
||||
resolvers += "jitpack" at "https://jitpack.io"
|
||||
|
||||
libraryDependencies += "com.github.purplexdev" % "packetevents" % "1.1.5"
|
||||
```
|
||||
|
||||
# leiningen
|
||||
```
|
||||
:repositories [["jitpack" "https://jitpack.io"]]
|
||||
|
||||
:dependencies [[com.github.purplexdev/packetevents "1.1.5"]]
|
||||
```
|
||||
Our discord server: https://discord.me/packetevents
|
||||
|
||||
[](https://jitpack.io/#retrooper/packetevents)
|
||||
|
||||
[](https://jitci.com/gh/retrooper/packetevents)
|
||||
|
||||
@@ -4,44 +4,50 @@
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>me.purplex</groupId>
|
||||
<groupId>io.github.retrooper</groupId>
|
||||
<artifactId>packetevents</artifactId>
|
||||
<version>1.1.7</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>packetevents</name>
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
<version>1.7.4</version>
|
||||
|
||||
<!-- You can build the project with this: "mvn clean compile assembly:single" -->
|
||||
<build>
|
||||
<defaultGoal>clean package</defaultGoal>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.7.0</version>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.7.0</version>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
<source>8</source>
|
||||
<target>8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-javadocs</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
<packaging>jar</packaging>
|
||||
<name>packetevents</name>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
@@ -56,137 +62,85 @@
|
||||
<id>funkemunky-releases</id>
|
||||
<url>https://nexus.funkemunky.cc/content/repositories/releases/</url>
|
||||
</repository>
|
||||
|
||||
<repository>
|
||||
<id>viaversion-repo</id>
|
||||
<url>https://repo.viaversion.com</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>dmulloy2-repo</id>
|
||||
<url>https://repo.dmulloy2.net/nexus/repository/public/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.github.spigot</groupId>
|
||||
<artifactId>1.14.1</artifactId>
|
||||
<version>1.14.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.github.spigot</groupId>
|
||||
<artifactId>1.15.1</artifactId>
|
||||
<version>1.15.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.github.spigot</groupId>
|
||||
<artifactId>1.14.3</artifactId>
|
||||
<version>1.14.3</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.github.spigot</groupId>
|
||||
<artifactId>1.14.2</artifactId>
|
||||
<version>1.14.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.github.spigot</groupId>
|
||||
<artifactId>1.15</artifactId>
|
||||
<version>1.15</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.github.spigot</groupId>
|
||||
<artifactId>1.15.2</artifactId>
|
||||
<version>1.15.2</version>
|
||||
<artifactId>1.16.2</artifactId>
|
||||
<version>1.16.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.github.spigot</groupId>
|
||||
<artifactId>1.13.2</artifactId>
|
||||
<version>1.13.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.github.spigot</groupId>
|
||||
<artifactId>1.7.10</artifactId>
|
||||
<version>1.7.10</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.github.spigot</groupId>
|
||||
<artifactId>1.8</artifactId>
|
||||
<version>1.8</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.github.spigot</groupId>
|
||||
<artifactId>1.8.3</artifactId>
|
||||
<version>1.8.3</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.github.spigot</groupId>
|
||||
<artifactId>1.8.8</artifactId>
|
||||
<version>1.8.8</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.github.spigot</groupId>
|
||||
<artifactId>1.9</artifactId>
|
||||
<version>1.9</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.github.spigot</groupId>
|
||||
<artifactId>1.9.4</artifactId>
|
||||
<version>1.9.4</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.github.spigot</groupId>
|
||||
<artifactId>1.10.2</artifactId>
|
||||
<version>1.10.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.github.spigot</groupId>
|
||||
<artifactId>1.11.1</artifactId>
|
||||
<version>1.11.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.github.spigot</groupId>
|
||||
<artifactId>1.11.2</artifactId>
|
||||
<version>1.11.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.github.spigot</groupId>
|
||||
<artifactId>1.12.1</artifactId>
|
||||
<version>1.12.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.github.spigot</groupId>
|
||||
<artifactId>1.12.2</artifactId>
|
||||
<version>1.12.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.github.spigot</groupId>
|
||||
<artifactId>1.13</artifactId>
|
||||
<version>1.13</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.github.spigot</groupId>
|
||||
<artifactId>1.14</artifactId>
|
||||
<version>1.14</version>
|
||||
<artifactId>1.9</artifactId>
|
||||
<version>1.9</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.github.spigot</groupId>
|
||||
<artifactId>1.8.8</artifactId>
|
||||
<version>1.8.8</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.github.spigot</groupId>
|
||||
<artifactId>1.7.10</artifactId>
|
||||
<version>1.7.10</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.comphenix.protocol</groupId>
|
||||
<artifactId>ProtocolLib</artifactId>
|
||||
<version>4.5.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>us.myles</groupId>
|
||||
<artifactId>viaversion</artifactId>
|
||||
<version>3.0.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.ProtocolSupport</groupId>
|
||||
<artifactId>ProtocolSupport</artifactId>
|
||||
<version>4fdd683</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!--Bukkit-->
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.8-R0.1-SNAPSHOT</version>
|
||||
<version>1.8.8-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents;
|
||||
|
||||
import io.github.retrooper.packetevents.bungee.BungeePluginMessageListener;
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import io.github.retrooper.packetevents.packetmanager.PacketManager;
|
||||
import io.github.retrooper.packetevents.packetmanager.netty.NettyPacketManager;
|
||||
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.settings.PacketEventsSettings;
|
||||
import io.github.retrooper.packetevents.updatechecker.UpdateChecker;
|
||||
import io.github.retrooper.packetevents.utils.entityfinder.EntityFinderUtils;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.player.ClientVersion;
|
||||
import io.github.retrooper.packetevents.utils.server.PEVersion;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
import io.github.retrooper.packetevents.utils.versionlookup.VersionLookupUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerLoginEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
public final class PacketEvents implements Listener {
|
||||
private static final PacketEventsAPI packetEventsAPI = new PacketEventsAPI();
|
||||
private static final PacketEvents instance = new PacketEvents();
|
||||
private static final ArrayList<Plugin> plugins = new ArrayList<>(1);
|
||||
private static boolean loaded, initialized;
|
||||
private static final PEVersion version = new PEVersion(1, 7, 4);
|
||||
|
||||
private static PacketEventsSettings settings = new PacketEventsSettings();
|
||||
/** General executor service, basically for anything that the packet executor service doesn't do.
|
||||
*/
|
||||
public static ExecutorService generalExecutorService = Executors.newCachedThreadPool();
|
||||
//Executor used for player injecting/ejecting and for packet processing/event calling
|
||||
public static ExecutorService packetHandlingExecutorService = Executors.newSingleThreadExecutor();
|
||||
|
||||
/**
|
||||
* This loads the PacketEvents API.
|
||||
* <p>
|
||||
* ServerVersion:
|
||||
* In this method we detect and cache the server version.
|
||||
* <p>
|
||||
* NMSUtils:
|
||||
* We setup some NMS utilities.
|
||||
* <p>
|
||||
* Packet ID System:
|
||||
* All the packet classes we will be needing are cached in a Map with an integer ID.
|
||||
* <p>
|
||||
* Version Lookup Utils:
|
||||
* We setup the client protocol version system.
|
||||
* We check if ViaVersion, ProtocolSupport or ProtocolLib is present.
|
||||
* <p>
|
||||
* Wrappers:
|
||||
* All PacketEvents' wrappers are setup and do all loading they need to do.
|
||||
*/
|
||||
public static void load() {
|
||||
if (!loaded) {
|
||||
ServerVersion version = ServerVersion.getVersion();
|
||||
WrappedPacket.version = version;
|
||||
PacketEvent.version = version;
|
||||
NMSUtils.version = version;
|
||||
EntityFinderUtils.version = version;
|
||||
|
||||
try {
|
||||
NMSUtils.load();
|
||||
|
||||
PacketTypeClasses.Client.load();
|
||||
PacketTypeClasses.Server.load();
|
||||
PacketTypeClasses.Login.load();
|
||||
PacketTypeClasses.Status.load();
|
||||
|
||||
EntityFinderUtils.load();
|
||||
|
||||
WrappedPacket.loadAllWrappers();
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalStateException("PacketEvents failed to successfully load...", ex);
|
||||
}
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void loadSettings(PacketEventsSettings settings) {
|
||||
PacketEvents.settings = settings;
|
||||
}
|
||||
|
||||
public static void init(final Plugin plugin) {
|
||||
init(plugin, settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiates PacketEvents
|
||||
* <p>
|
||||
* Loading:
|
||||
* Loads PacketEvents if you haven't already.
|
||||
* <p>
|
||||
* Registering:
|
||||
* Registers this class as a Bukkit listener to inject/eject players.
|
||||
*
|
||||
* @param pl JavaPlugin instance
|
||||
*/
|
||||
public static void init(final Plugin pl, PacketEventsSettings packetEventsSettings) {
|
||||
load();
|
||||
if (!initialized) {
|
||||
settings = packetEventsSettings;
|
||||
int packetHandlingThreadCount = settings.getPacketHandlingThreadCount();
|
||||
//if the count is 1 or is invalid
|
||||
if(packetHandlingThreadCount == 1 || packetHandlingThreadCount < 0) {
|
||||
packetHandlingExecutorService = Executors.newSingleThreadExecutor();
|
||||
}
|
||||
else {
|
||||
packetHandlingExecutorService = Executors.newFixedThreadPool(packetHandlingThreadCount);
|
||||
}
|
||||
plugins.add(pl);
|
||||
|
||||
//Register Bukkit listener
|
||||
Bukkit.getPluginManager().registerEvents(instance, plugins.get(0));
|
||||
PacketEvents.getAPI().packetManager = new PacketManager(plugins.get(0), settings.shouldInjectEarly());
|
||||
|
||||
for (final Player p : Bukkit.getOnlinePlayers()) {
|
||||
getAPI().getPlayerUtils().injectPlayer(p);
|
||||
}
|
||||
|
||||
if (settings.shouldCheckForUpdates()) {
|
||||
PacketEvents.generalExecutorService.execute(() -> new UpdateChecker().handleUpdate());
|
||||
}
|
||||
|
||||
if (getAPI().getServerUtils().isBungeeCordEnabled()) {
|
||||
Bukkit.getMessenger().registerOutgoingPluginChannel(plugins.get(0), "BungeeCord");
|
||||
Bukkit.getServer().getMessenger().registerIncomingPluginChannel(plugins.get(0), BungeePluginMessageListener.tagName, new BungeePluginMessageListener());
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static void stop() {
|
||||
if (initialized) {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
PacketEvents.getAPI().packetManager.ejectPlayer(player);
|
||||
}
|
||||
|
||||
if (PacketEvents.getAPI().packetManager.tinyProtocol != null) {
|
||||
PacketEvents.getAPI().packetManager.tinyProtocol.unregisterChannelHandler();
|
||||
}
|
||||
getAPI().getEventManager().unregisterAllListeners();
|
||||
PacketEvents.generalExecutorService.shutdownNow();
|
||||
PacketEvents.packetHandlingExecutorService.shutdownNow();
|
||||
initialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean hasLoaded() {
|
||||
return loaded;
|
||||
}
|
||||
|
||||
public static boolean isInitialized() {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
public static PacketEventsAPI getAPI() {
|
||||
return packetEventsAPI;
|
||||
}
|
||||
|
||||
public static ArrayList<Plugin> getPlugins() {
|
||||
return plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the PacketEvents settings.
|
||||
*
|
||||
* @return Configure some settings for the API
|
||||
*/
|
||||
public static PacketEventsSettings getSettings() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
public static PEVersion getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onLogin(PlayerLoginEvent e) {
|
||||
if (PacketEvents.getSettings().shouldInjectEarly()) {
|
||||
assert getAPI().packetManager.tinyProtocol != null;
|
||||
try {
|
||||
if (getAPI().packetManager.canInject(e.getPlayer())) {
|
||||
getAPI().packetManager.injectPlayer(e.getPlayer());
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
e.disallow(PlayerLoginEvent.Result.KICK_OTHER, "We are unable to inject you. Please try again!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(final PlayerJoinEvent e) {
|
||||
if (!VersionLookupUtils.hasHandledLoadedDependencies()) {
|
||||
VersionLookupUtils.handleLoadedDependencies();
|
||||
}
|
||||
Object channel = NMSUtils.getChannel(e.getPlayer());
|
||||
//Waiting for the BungeeCord server to send their plugin message with your version,
|
||||
//So we leave bungee alone
|
||||
if (!PacketEvents.getAPI().getServerUtils().isBungeeCordEnabled()) {
|
||||
if (VersionLookupUtils.isDependencyAvailable()) {
|
||||
ClientVersion version = ClientVersion.getClientVersion(VersionLookupUtils.getProtocolVersion(e.getPlayer()));
|
||||
PacketEvents.getAPI().getPlayerUtils().clientVersionsMap.put(channel, version);
|
||||
}
|
||||
}
|
||||
if (!PacketEvents.getSettings().shouldInjectEarly()) {
|
||||
if (getAPI().packetManager.canInject(e.getPlayer())) {
|
||||
PacketEvents.getAPI().packetManager.injectPlayer(e.getPlayer());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@EventHandler
|
||||
public void onQuit(final PlayerQuitEvent e) {
|
||||
PacketEvents.getAPI().getPlayerUtils().clientVersionsMap.remove(e.getPlayer().getUniqueId());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents;
|
||||
|
||||
import io.github.retrooper.packetevents.event.manager.EventManager;
|
||||
import io.github.retrooper.packetevents.packetmanager.PacketManager;
|
||||
import io.github.retrooper.packetevents.settings.PacketEventsSettings;
|
||||
import io.github.retrooper.packetevents.utils.player.PlayerUtils;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerUtils;
|
||||
|
||||
public final class PacketEventsAPI {
|
||||
private final EventManager eventManager = new EventManager();
|
||||
private final PlayerUtils playerUtils = new PlayerUtils();
|
||||
private final ServerUtils serverUtils = new ServerUtils();
|
||||
public PacketManager packetManager = null;
|
||||
|
||||
/**
|
||||
* Get all utilities to do with the player
|
||||
*
|
||||
* @return Player Utilities
|
||||
*/
|
||||
public PlayerUtils getPlayerUtils() {
|
||||
return playerUtils;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all utilities to do with the server
|
||||
*
|
||||
* @return Server Utilities
|
||||
*/
|
||||
public ServerUtils getServerUtils() {
|
||||
return serverUtils;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the event manager
|
||||
* Used to call events, register and unregister listeners
|
||||
*
|
||||
* @return PacketEvents' event manager
|
||||
*/
|
||||
public EventManager getEventManager() {
|
||||
return eventManager;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.annotations;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* This annotation indicates that something might be unstable.
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Beta {
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.annotations;
|
||||
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* Guaranteed to not be null.
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface NotNull {
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.annotations;
|
||||
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* Possible that it is null.
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Nullable {
|
||||
|
||||
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.bungee;
|
||||
|
||||
import com.google.common.io.ByteArrayDataInput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.player.ClientVersion;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.messaging.PluginMessageListener;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class BungeePluginMessageListener implements PluginMessageListener {
|
||||
public static String tagName = "packetevents";
|
||||
|
||||
@Override
|
||||
public void onPluginMessageReceived(String tag, Player player, byte[] bytes) {
|
||||
if (tag.equals(tagName)) {
|
||||
ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
|
||||
if (in.readUTF().equals("version")) {
|
||||
String uuidString = in.readUTF();
|
||||
Object channel = NMSUtils.getChannel(player);
|
||||
short protocolVersion = in.readShort();
|
||||
ClientVersion version = ClientVersion.getClientVersion(protocolVersion);
|
||||
PacketEvents.getAPI().getPlayerUtils().clientVersionsMap.put(channel, version);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.enums;
|
||||
|
||||
public enum Direction {
|
||||
/**
|
||||
* -Y offset
|
||||
*/
|
||||
DOWN,
|
||||
|
||||
/**
|
||||
* +Y offset
|
||||
*/
|
||||
UP,
|
||||
|
||||
/**
|
||||
* -Z offset
|
||||
*/
|
||||
NORTH,
|
||||
|
||||
/**
|
||||
* +Z offset
|
||||
*/
|
||||
SOUTH,
|
||||
|
||||
/**
|
||||
* -X offset
|
||||
*/
|
||||
WEST,
|
||||
|
||||
/**
|
||||
* +X offset
|
||||
*/
|
||||
EAST;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event;
|
||||
|
||||
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
|
||||
/**
|
||||
* An event in the PacketEvents EventManager system.
|
||||
*/
|
||||
public abstract class PacketEvent {
|
||||
public static ServerVersion version;
|
||||
private long timestamp = System.currentTimeMillis();
|
||||
|
||||
/**
|
||||
* Timestamp of the packet
|
||||
*
|
||||
* @return timestamp in milliseconds
|
||||
*/
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event;
|
||||
|
||||
/**
|
||||
* A Packet listener.
|
||||
* Implement this interface in your listeners.
|
||||
*/
|
||||
public interface PacketListener {
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.annotation;
|
||||
|
||||
import io.github.retrooper.packetevents.event.priority.PacketEventPriority;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
|
||||
public @interface PacketHandler {
|
||||
byte priority() default PacketEventPriority.NORMAL;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.eventtypes;
|
||||
|
||||
/**
|
||||
* This indicates that it is possible to cancel an event,
|
||||
* which should result in cancelling the planned action.
|
||||
*/
|
||||
public interface CancellableEvent {
|
||||
|
||||
/**
|
||||
* Has the event been cancelled?
|
||||
* @return is event cancelled
|
||||
*/
|
||||
boolean isCancelled();
|
||||
|
||||
/**
|
||||
* Cancel or proceed with the event.
|
||||
* @param val
|
||||
*/
|
||||
void setCancelled(boolean val);
|
||||
|
||||
/**
|
||||
* Cancel the event.
|
||||
* You can achieve the same result by just using {@link #setCancelled(boolean)}
|
||||
*/
|
||||
void cancel();
|
||||
|
||||
/**
|
||||
* Uncancel the event.
|
||||
* You can achieve the same result by just using {@link #setCancelled(boolean)}
|
||||
*/
|
||||
void uncancel();
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.eventtypes;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* Event having to do with a player.
|
||||
*/
|
||||
public interface PlayerEvent {
|
||||
/**
|
||||
* Associated player.
|
||||
*/
|
||||
Player getPlayer();
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.CancellableEvent;
|
||||
import io.github.retrooper.packetevents.packettype.PacketType;
|
||||
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
|
||||
|
||||
/**
|
||||
* This event is called when we receive a login packet.
|
||||
*/
|
||||
public class PacketLoginEvent extends PacketEvent implements CancellableEvent {
|
||||
private final Object channel;
|
||||
private final Object packet;
|
||||
private boolean cancelled;
|
||||
|
||||
public PacketLoginEvent(final Object channel, final Object packet) {
|
||||
this.channel = channel;
|
||||
this.packet = packet;
|
||||
}
|
||||
|
||||
public Object getChannel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the packet's name (NMS packet class simple name).
|
||||
* The class simple name is cached.
|
||||
*
|
||||
* @return Name of the packet
|
||||
*/
|
||||
public String getPacketName() {
|
||||
return ClassUtil.getClassSimpleName(packet.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the raw packet object
|
||||
*
|
||||
* @return packet object
|
||||
*/
|
||||
public Object getNMSPacket() {
|
||||
return packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID of the packet
|
||||
*
|
||||
* @return packet id
|
||||
*/
|
||||
public byte getPacketId() {
|
||||
return PacketType.Login.packetIds.getOrDefault(packet.getClass(), (byte) -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
cancelled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uncancel() {
|
||||
cancelled = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean value) {
|
||||
cancelled = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.event.eventtypes.CancellableEvent;
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.PlayerEvent;
|
||||
import io.github.retrooper.packetevents.packettype.PacketType;
|
||||
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* This event is called each time a packet is received from a client.
|
||||
*/
|
||||
public final class PacketReceiveEvent extends PacketEvent implements CancellableEvent, PlayerEvent {
|
||||
private final Player player;
|
||||
private final Object packet;
|
||||
private boolean cancelled;
|
||||
|
||||
public PacketReceiveEvent(final Player player, final Object packet) {
|
||||
this.player = player;
|
||||
this.packet = packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the packet sender
|
||||
* @return player
|
||||
*/
|
||||
@Override
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the packet's name (NMS packet class simple name).
|
||||
* The class simple name is cached.
|
||||
* @return Name of the packet
|
||||
*/
|
||||
public String getPacketName() {
|
||||
return ClassUtil.getClassSimpleName(packet.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the raw packet object
|
||||
* @return packet object
|
||||
*/
|
||||
public Object getNMSPacket() {
|
||||
return packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID of the packet
|
||||
* @return packet id
|
||||
*/
|
||||
public byte getPacketId() {
|
||||
return PacketType.Client.packetIds.getOrDefault(packet.getClass(), (byte) -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
cancelled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uncancel() {
|
||||
cancelled = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean value) {
|
||||
cancelled = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.event.eventtypes.CancellableEvent;
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.PlayerEvent;
|
||||
import io.github.retrooper.packetevents.packettype.PacketType;
|
||||
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* This event is called each time the server sends a packet to the client.
|
||||
*/
|
||||
public final class PacketSendEvent extends PacketEvent implements CancellableEvent, PlayerEvent {
|
||||
private final Player player;
|
||||
private final Object packet;
|
||||
private boolean cancelled;
|
||||
|
||||
public PacketSendEvent(final Player player, final Object packet) {
|
||||
this.player = player;
|
||||
this.packet = packet;
|
||||
this.cancelled = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the packet's name (NMS packet class simple name).
|
||||
* The class simple name is cached.
|
||||
* @return Name of the packet
|
||||
*/
|
||||
public String getPacketName() {
|
||||
return ClassUtil.getClassSimpleName(packet.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID of the packet
|
||||
*
|
||||
* @return packet id
|
||||
*/
|
||||
public byte getPacketId() {
|
||||
return PacketType.Server.packetIds.getOrDefault(packet.getClass(), (byte) -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the NMS packet object
|
||||
*
|
||||
* @return packet object
|
||||
*/
|
||||
public Object getNMSPacket() {
|
||||
return packet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
cancelled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uncancel() {
|
||||
cancelled = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean value) {
|
||||
cancelled = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.CancellableEvent;
|
||||
import io.github.retrooper.packetevents.packettype.PacketType;
|
||||
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
|
||||
|
||||
public class PacketStatusEvent extends PacketEvent implements CancellableEvent {
|
||||
private final Object channel;
|
||||
private final Object packet;
|
||||
private boolean cancelled;
|
||||
|
||||
public PacketStatusEvent(final Object channel, final Object packet) {
|
||||
this.channel = channel;
|
||||
this.packet = packet;
|
||||
}
|
||||
|
||||
public Object getChannel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the packet's name (NMS packet class simple name).
|
||||
* The class simple name is cached.
|
||||
*
|
||||
* @return Name of the packet
|
||||
*/
|
||||
public String getPacketName() {
|
||||
return ClassUtil.getClassSimpleName(packet.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the raw packet object
|
||||
*
|
||||
* @return packet object
|
||||
*/
|
||||
public Object getNMSPacket() {
|
||||
return packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID of the packet
|
||||
*
|
||||
* @return packet id
|
||||
*/
|
||||
public byte getPacketId() {
|
||||
return PacketType.Status.packetIds.getOrDefault(packet.getClass(), (byte) -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
cancelled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uncancel() {
|
||||
cancelled = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean value) {
|
||||
cancelled = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.event.eventtypes.CancellableEvent;
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.PlayerEvent;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* This event is called each time you eject a player.
|
||||
*/
|
||||
public final class PlayerEjectEvent extends PacketEvent implements CancellableEvent, PlayerEvent {
|
||||
private final Player player;
|
||||
private final boolean async;
|
||||
private boolean cancelled;
|
||||
|
||||
public PlayerEjectEvent(final Player player, final boolean isAsync) {
|
||||
this.player = player;
|
||||
this.async = isAsync;
|
||||
}
|
||||
|
||||
public PlayerEjectEvent(final Player player) {
|
||||
this.player = player;
|
||||
this.async = true; //default value
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
cancelled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uncancel() {
|
||||
cancelled = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean value) {
|
||||
cancelled = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public boolean isAsync() {
|
||||
return async;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.event.eventtypes.CancellableEvent;
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.PlayerEvent;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* This event is called each time you inject a player.
|
||||
*/
|
||||
public final class PlayerInjectEvent extends PacketEvent implements CancellableEvent, PlayerEvent {
|
||||
private final Player player;
|
||||
private final boolean async;
|
||||
private boolean cancelled;
|
||||
|
||||
public PlayerInjectEvent(final Player player) {
|
||||
this(player, false);
|
||||
}
|
||||
|
||||
public PlayerInjectEvent(final Player player, boolean isAsync) {
|
||||
this.player= player;
|
||||
this.async = isAsync;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
cancelled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uncancel() {
|
||||
cancelled = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean value) {
|
||||
cancelled = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public boolean isAsync() {
|
||||
return async;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.PlayerEvent;
|
||||
import io.github.retrooper.packetevents.packettype.PacketType;
|
||||
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class PostPacketReceiveEvent extends PacketEvent implements PlayerEvent {
|
||||
private final Player player;
|
||||
private final Object packet;
|
||||
|
||||
public PostPacketReceiveEvent(final Player player, final Object packet) {
|
||||
this.player = player;
|
||||
this.packet = packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the packet sender
|
||||
* @return player
|
||||
*/
|
||||
@Override
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the packet's name (NMS packet class simple name).
|
||||
* The class simple name is cached.
|
||||
* @return Name of the packet
|
||||
*/
|
||||
public String getPacketName() {
|
||||
return ClassUtil.getClassSimpleName(packet.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the raw packet object
|
||||
* @return packet object
|
||||
*/
|
||||
public Object getNMSPacket() {
|
||||
return packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID of the packet
|
||||
* @return packet id
|
||||
*/
|
||||
public byte getPacketId() {
|
||||
return PacketType.Client.packetIds.getOrDefault(packet.getClass(), (byte) -1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.PlayerEvent;
|
||||
import io.github.retrooper.packetevents.packettype.PacketType;
|
||||
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class PostPacketSendEvent extends PacketEvent implements PlayerEvent {
|
||||
private final Player player;
|
||||
private final Object packet;
|
||||
|
||||
public PostPacketSendEvent(final Player player, final Object packet) {
|
||||
this.player = player;
|
||||
this.packet = packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the packet sender
|
||||
* @return player
|
||||
*/
|
||||
@Override
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the packet's name (NMS packet class simple name).
|
||||
* The class simple name is cached.
|
||||
* @return Name of the packet
|
||||
*/
|
||||
public String getPacketName() {
|
||||
return ClassUtil.getClassSimpleName(packet.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the raw packet object
|
||||
* @return packet object
|
||||
*/
|
||||
public Object getNMSPacket() {
|
||||
return packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID of the packet
|
||||
* @return packet id
|
||||
*/
|
||||
public byte getPacketId() {
|
||||
return PacketType.Server.packetIds.getOrDefault(packet.getClass(), (byte) -1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.manager;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import io.github.retrooper.packetevents.event.PacketListener;
|
||||
import io.github.retrooper.packetevents.event.annotation.PacketHandler;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.CancellableEvent;
|
||||
import io.github.retrooper.packetevents.event.impl.*;
|
||||
import io.github.retrooper.packetevents.event.priority.PacketEventPriority;
|
||||
import io.github.retrooper.packetevents.utils.protocollib.ProtocolLibAPIListener;
|
||||
import io.github.retrooper.packetevents.utils.protocollib.ProtocolLibUtils;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
public final class EventManager {
|
||||
private final Map<PacketListener, List<Method>> staticRegisteredMethods = new HashMap<>();
|
||||
public void callEvent(final PacketEvent e) {
|
||||
//STATIC LISTENERS
|
||||
for (final PacketListener listener : staticRegisteredMethods.keySet()) {
|
||||
List<Method> methods = staticRegisteredMethods.get(listener);
|
||||
final boolean[] isCancelled = {false};
|
||||
final byte[] eventPriority = {PacketEventPriority.LOWEST};
|
||||
for (Method method : methods) {
|
||||
Class<?> parameterType = method.getParameterTypes()[0];
|
||||
if (parameterType.equals(PacketEvent.class)
|
||||
|| parameterType.isInstance(e)) {
|
||||
|
||||
PacketHandler annotation = method.getAnnotation(PacketHandler.class);
|
||||
try {
|
||||
method.invoke(listener, e);
|
||||
} catch (IllegalAccessException | InvocationTargetException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
if (e instanceof CancellableEvent) {
|
||||
CancellableEvent ce = (CancellableEvent) e;
|
||||
if (annotation.priority() >= eventPriority[0]) {
|
||||
eventPriority[0] = annotation.priority();
|
||||
isCancelled[0] = ce.isCancelled();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void registerListener(final PacketListener listener) {
|
||||
final List<Method> methods = new ArrayList<>();
|
||||
for (final Method m : listener.getClass().getDeclaredMethods()) {
|
||||
if (!m.isAccessible()) {
|
||||
m.setAccessible(true);
|
||||
}
|
||||
if (m.isAnnotationPresent(PacketHandler.class)
|
||||
&& m.getParameterTypes().length == 1) {
|
||||
methods.add(m);
|
||||
}
|
||||
}
|
||||
|
||||
if (!methods.isEmpty()) {
|
||||
if (ProtocolLibUtils.isAvailable()
|
||||
&& PacketEvents.getSettings().shouldUseProtocolLibIfAvailable()) {
|
||||
ProtocolLibAPIListener.registerProtocolLibListener(listener, methods);
|
||||
} else {
|
||||
staticRegisteredMethods.put(listener, methods);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void registerListeners(final PacketListener... listeners) {
|
||||
for (final PacketListener listener : listeners) {
|
||||
registerListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public void unregisterListener(final PacketListener e) {
|
||||
staticRegisteredMethods.remove(e);
|
||||
}
|
||||
|
||||
public void unregisterListeners(final PacketListener... listeners) {
|
||||
for (final PacketListener listener : listeners) {
|
||||
unregisterListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public void unregisterAllListeners() {
|
||||
staticRegisteredMethods.clear();
|
||||
}
|
||||
|
||||
public boolean isRegistered(final PacketListener listener) {
|
||||
return staticRegisteredMethods.containsKey(listener);
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.priority;
|
||||
|
||||
public interface PacketEventPriority {
|
||||
byte LOWEST = 0;
|
||||
byte LOW = 1;
|
||||
byte NORMAL = 2;
|
||||
byte HIGH = 3;
|
||||
byte HIGHEST = 4;
|
||||
byte MONITOR = 5;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.example;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.event.PacketListener;
|
||||
import io.github.retrooper.packetevents.event.annotation.PacketHandler;
|
||||
import io.github.retrooper.packetevents.event.impl.PacketReceiveEvent;
|
||||
import io.github.retrooper.packetevents.event.impl.PlayerEjectEvent;
|
||||
import io.github.retrooper.packetevents.event.impl.PlayerInjectEvent;
|
||||
import io.github.retrooper.packetevents.packettype.PacketType;
|
||||
import io.github.retrooper.packetevents.packetwrappers.in.chat.WrappedPacketInChat;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.helditemslot.WrappedPacketOutHeldItemSlot;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class MainExample extends JavaPlugin implements PacketListener {
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
PacketEvents.load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
PacketEvents.getSettings().injectAsync(true).ejectAsync(true).
|
||||
backupServerVersion(ServerVersion.v_1_7_10).useProtocolLibIfAvailable(true).
|
||||
checkForUpdates(true).injectEarly(true).packetHandlingThreadCount(1);
|
||||
PacketEvents.getAPI().getEventManager().registerListener(this);
|
||||
PacketEvents.init(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
PacketEvents.stop();
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.exceptions;
|
||||
|
||||
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
|
||||
|
||||
public class WrapperFieldNotFoundException extends RuntimeException{
|
||||
public WrapperFieldNotFoundException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public WrapperFieldNotFoundException(Class<?> packetClass, Class<?> type, int index) {
|
||||
this("PacketEvents failed to find a " + ClassUtil.getClassSimpleName(type) + " indexed " + index + " by its type in the " + packetClass.getName() + " class!");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,299 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetmanager;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.event.impl.*;
|
||||
import io.github.retrooper.packetevents.packetmanager.netty.NettyPacketManager;
|
||||
import io.github.retrooper.packetevents.packetmanager.tinyprotocol.TinyProtocol;
|
||||
import io.github.retrooper.packetevents.packettype.PacketType;
|
||||
import io.github.retrooper.packetevents.packetwrappers.login.in.WrappedPacketLoginHandshake;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.player.ClientVersion;
|
||||
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
|
||||
import io.github.retrooper.packetevents.utils.versionlookup.VersionLookupUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class PacketManager {
|
||||
|
||||
private static final AtomicInteger handlerID = new AtomicInteger();
|
||||
private final int handlerNumber = handlerID.getAndIncrement();
|
||||
private final Plugin plugin;
|
||||
private final boolean tinyProtocolMode;
|
||||
public final TinyProtocol tinyProtocol;
|
||||
public final NettyPacketManager nettyProtocol;
|
||||
private final HashMap<UUID, Long> keepAliveMap = new HashMap<>();
|
||||
|
||||
public PacketManager(Plugin plugin, boolean tinyProtocolMode) {
|
||||
this.plugin = plugin;
|
||||
this.tinyProtocolMode = tinyProtocolMode;
|
||||
if (tinyProtocolMode) {
|
||||
tinyProtocol = new TinyProtocol(plugin);
|
||||
nettyProtocol = null;
|
||||
} else {
|
||||
tinyProtocol = null;
|
||||
nettyProtocol = new NettyPacketManager(plugin);
|
||||
}
|
||||
}
|
||||
|
||||
public void injectPlayer(Player player) {
|
||||
if (PacketEvents.getSettings().shouldInjectAsync()) {
|
||||
injectPlayerAsync(player);
|
||||
} else {
|
||||
injectPlayerSync(player);
|
||||
}
|
||||
}
|
||||
|
||||
public void ejectPlayer(Player player) {
|
||||
if (PacketEvents.getSettings().shouldEjectAsync()) {
|
||||
ejectPlayerAsync(player);
|
||||
} else {
|
||||
ejectPlayerSync(player);
|
||||
}
|
||||
}
|
||||
|
||||
public void injectPlayerSync(Player player) {
|
||||
PlayerInjectEvent injectEvent = new PlayerInjectEvent(player, false);
|
||||
PacketEvents.getAPI().getEventManager().callEvent(injectEvent);
|
||||
if (!injectEvent.isCancelled()) {
|
||||
if (tinyProtocolMode) {
|
||||
tinyProtocol.injectPlayer(player);
|
||||
} else {
|
||||
nettyProtocol.injectPlayer(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void injectPlayerAsync(Player player) {
|
||||
PlayerInjectEvent injectEvent = new PlayerInjectEvent(player, true);
|
||||
PacketEvents.getAPI().getEventManager().callEvent(injectEvent);
|
||||
if (!injectEvent.isCancelled()) {
|
||||
if (tinyProtocolMode) {
|
||||
tinyProtocol.injectPlayerAsync(player);
|
||||
} else {
|
||||
nettyProtocol.injectPlayerAsync(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ejectPlayerSync(Player player) {
|
||||
PlayerEjectEvent ejectEvent = new PlayerEjectEvent(player, false);
|
||||
PacketEvents.getAPI().getEventManager().callEvent(ejectEvent);
|
||||
if (!ejectEvent.isCancelled()) {
|
||||
keepAliveMap.remove(player.getUniqueId());
|
||||
if (tinyProtocolMode) {
|
||||
tinyProtocol.ejectPlayer(player);
|
||||
} else {
|
||||
nettyProtocol.ejectPlayer(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ejectPlayerAsync(Player player) {
|
||||
PlayerEjectEvent ejectEvent = new PlayerEjectEvent(player, true);
|
||||
PacketEvents.getAPI().getEventManager().callEvent(ejectEvent);
|
||||
if (!ejectEvent.isCancelled()) {
|
||||
keepAliveMap.remove(player.getUniqueId());
|
||||
if (tinyProtocolMode) {
|
||||
tinyProtocol.ejectPlayerAsync(player);
|
||||
} else {
|
||||
nettyProtocol.ejectPlayerAsync(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ejectChannel(Object channel) {
|
||||
if (!PacketEvents.getSettings().shouldEjectAsync()) {
|
||||
ejectChannelSync(channel);
|
||||
} else {
|
||||
ejectChannelAsync(channel);
|
||||
}
|
||||
}
|
||||
|
||||
public void ejectChannelSync(Object channel) {
|
||||
if (tinyProtocolMode) {
|
||||
tinyProtocol.ejectChannelSync(channel);
|
||||
} else {
|
||||
nettyProtocol.ejectChannelSync(channel);
|
||||
}
|
||||
}
|
||||
|
||||
public void ejectChannelAsync(Object channel) {
|
||||
if (tinyProtocolMode) {
|
||||
tinyProtocol.ejectChannelAsync(channel);
|
||||
} else {
|
||||
nettyProtocol.ejectChannelAsync(channel);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendPacket(Object channel, Object packet) {
|
||||
if (tinyProtocolMode) {
|
||||
tinyProtocol.sendPacket(channel, packet);
|
||||
} else {
|
||||
nettyProtocol.sendPacket(channel, packet);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canInject(Player player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getNettyHandlerName() {
|
||||
return "pe-" + plugin.getName() + "-" + handlerNumber;
|
||||
}
|
||||
|
||||
public Object read(Player player, Object channel, Object packet) {
|
||||
if (player == null) {
|
||||
String simpleClassName = ClassUtil.getClassSimpleName(packet.getClass());
|
||||
//Status packet
|
||||
if (simpleClassName.startsWith("PacketS")) {
|
||||
final PacketStatusEvent packetStatusEvent = new PacketStatusEvent(channel, packet);
|
||||
PacketEvents.getAPI().getEventManager().callEvent(packetStatusEvent);
|
||||
interceptStatus(packetStatusEvent);
|
||||
if (packetStatusEvent.isCancelled()) {
|
||||
packet = null;
|
||||
}
|
||||
} else {
|
||||
//Login packet
|
||||
final PacketLoginEvent packetLoginEvent = new PacketLoginEvent(channel, packet);
|
||||
PacketEvents.getAPI().getEventManager().callEvent(packetLoginEvent);
|
||||
interceptLogin(packetLoginEvent);
|
||||
if (packetLoginEvent.isCancelled()) {
|
||||
packet = null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
final PacketReceiveEvent packetReceiveEvent = new PacketReceiveEvent(player, packet);
|
||||
PacketEvents.getAPI().getEventManager().callEvent(packetReceiveEvent);
|
||||
interceptRead(packetReceiveEvent);
|
||||
if (packetReceiveEvent.isCancelled()) {
|
||||
packet = null;
|
||||
}
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
|
||||
public Object write(Player player, Object channel, Object packet) {
|
||||
if (player == null) {
|
||||
String simpleClassName = ClassUtil.getClassSimpleName(packet.getClass());
|
||||
//Status packet
|
||||
if (simpleClassName.startsWith("PacketS")) {
|
||||
final PacketStatusEvent packetStatusEvent = new PacketStatusEvent(channel, packet);
|
||||
PacketEvents.getAPI().getEventManager().callEvent(packetStatusEvent);
|
||||
interceptStatus(packetStatusEvent);
|
||||
if (packetStatusEvent.isCancelled()) {
|
||||
packet = null;
|
||||
}
|
||||
}
|
||||
//Login packet
|
||||
else {
|
||||
final PacketLoginEvent packetLoginEvent = new PacketLoginEvent(channel, packet);
|
||||
PacketEvents.getAPI().getEventManager().callEvent(packetLoginEvent);
|
||||
interceptLogin(packetLoginEvent);
|
||||
if (packetLoginEvent.isCancelled()) {
|
||||
packet = null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
final PacketSendEvent packetSendEvent = new PacketSendEvent(player, packet);
|
||||
PacketEvents.getAPI().getEventManager().callEvent(packetSendEvent);
|
||||
interceptWrite(packetSendEvent);
|
||||
if (packetSendEvent.isCancelled()) {
|
||||
packet = null;
|
||||
}
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
|
||||
public void postRead(Player player, Object packet) {
|
||||
switch (ClassUtil.getClassSimpleName(packet.getClass())) {
|
||||
case "PacketHandshakingInSetProtocol":
|
||||
case "PacketLoginInCustomPayload":
|
||||
case "PacketLoginInStart":
|
||||
case "PacketLoginInEncryptionBegin":
|
||||
case "PacketStatusInPing":
|
||||
break;
|
||||
default:
|
||||
PacketEvents.getAPI().getEventManager().callEvent(new PostPacketReceiveEvent(player, packet));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void postWrite(Player player, Object packet) {
|
||||
switch (ClassUtil.getClassSimpleName(packet.getClass())) {
|
||||
case "PacketLoginOutDisconnect":
|
||||
case "PacketLoginOutEncryptionBegin":
|
||||
case "PacketLoginOutSetCompression":
|
||||
case "PacketLoginOutSuccess":
|
||||
case "PacketStatusOutPong":
|
||||
case "PacketStatusOutServerInfo":
|
||||
break;
|
||||
default:
|
||||
PacketEvents.getAPI().getEventManager().callEvent(new PostPacketSendEvent(player, packet));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void interceptRead(PacketReceiveEvent event) {
|
||||
if (event.getPacketId() == PacketType.Client.KEEP_ALIVE) {
|
||||
UUID uuid = event.getPlayer().getUniqueId();
|
||||
long timestamp = keepAliveMap.getOrDefault(uuid, event.getTimestamp());
|
||||
long currentTime = event.getTimestamp();
|
||||
long ping = currentTime - timestamp;
|
||||
long smoothedPing = ((PacketEvents.getAPI().getPlayerUtils().getSmoothedPing(event.getPlayer()) * 3) + ping) / 4;
|
||||
PacketEvents.getAPI().getPlayerUtils().playerPingMap.put(uuid, (short) ping);
|
||||
PacketEvents.getAPI().getPlayerUtils().playerSmoothedPingMap.put(uuid, (short) smoothedPing);
|
||||
}
|
||||
}
|
||||
|
||||
private void interceptWrite(PacketSendEvent event) {
|
||||
if (event.getPacketId() == PacketType.Server.KEEP_ALIVE) {
|
||||
keepAliveMap.put(event.getPlayer().getUniqueId(), event.getTimestamp());
|
||||
}
|
||||
}
|
||||
|
||||
private void interceptLogin(PacketLoginEvent event) {
|
||||
if (event.getPacketId() == PacketType.Login.HANDSHAKE) {
|
||||
if (!VersionLookupUtils.isDependencyAvailable()) {
|
||||
WrappedPacketLoginHandshake handshake = new WrappedPacketLoginHandshake(event.getNMSPacket());
|
||||
int protocolVersion = handshake.getProtocolVersion();
|
||||
ClientVersion version = ClientVersion.getClientVersion(protocolVersion);
|
||||
PacketEvents.getAPI().getPlayerUtils().clientVersionsMap.put(event.getChannel(), version);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void interceptStatus(PacketStatusEvent event) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetmanager.netty;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class NettyPacketManager {
|
||||
public static final boolean v1_7_nettyMode;
|
||||
|
||||
static {
|
||||
boolean v1_7_nettyMode1;
|
||||
try {
|
||||
Class.forName("net.minecraft.util.io.netty.channel.Channel");
|
||||
v1_7_nettyMode1 = true;
|
||||
} catch (ClassNotFoundException e) {
|
||||
v1_7_nettyMode1 = false;
|
||||
}
|
||||
v1_7_nettyMode = v1_7_nettyMode1;
|
||||
}
|
||||
|
||||
private final Object npm;
|
||||
|
||||
public NettyPacketManager(Plugin plugin) {
|
||||
if (v1_7_nettyMode) {
|
||||
npm = new NettyPacketManager_7();
|
||||
} else {
|
||||
npm = new NettyPacketManager_8();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronously inject a player
|
||||
*
|
||||
* @param player Target player to inject
|
||||
*/
|
||||
public void injectPlayer(final Player player) {
|
||||
if (v1_7_nettyMode) {
|
||||
NettyPacketManager_7 npm_7 = (NettyPacketManager_7) npm;
|
||||
npm_7.injectPlayer(player);
|
||||
} else {
|
||||
NettyPacketManager_8 npm_8 = (NettyPacketManager_8) npm;
|
||||
npm_8.injectPlayer(player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously inject a player
|
||||
*
|
||||
* @param player
|
||||
*/
|
||||
public void injectPlayerAsync(final Player player) {
|
||||
//Redundant channel variable created just so we can cache it synchronously.
|
||||
Object channel = NMSUtils.getChannel(player);
|
||||
PacketEvents.packetHandlingExecutorService.execute(() -> {
|
||||
if (v1_7_nettyMode) {
|
||||
NettyPacketManager_7 npm_7 = (NettyPacketManager_7) npm;
|
||||
npm_7.injectPlayer(player);
|
||||
} else {
|
||||
NettyPacketManager_8 npm_8 = (NettyPacketManager_8) npm;
|
||||
npm_8.injectPlayer(player);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronously eject a player.
|
||||
*
|
||||
* @param player
|
||||
*/
|
||||
public void ejectPlayer(final Player player) {
|
||||
if (v1_7_nettyMode) {
|
||||
NettyPacketManager_7 npm_7 = (NettyPacketManager_7) npm;
|
||||
npm_7.ejectPlayer(player);
|
||||
} else {
|
||||
NettyPacketManager_8 npm_8 = (NettyPacketManager_8) npm;
|
||||
npm_8.ejectPlayer(player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously eject a player
|
||||
*
|
||||
* @param player
|
||||
*/
|
||||
public void ejectPlayerAsync(final Player player) {
|
||||
PacketEvents.packetHandlingExecutorService.execute(() -> {
|
||||
if (v1_7_nettyMode) {
|
||||
NettyPacketManager_7 npm_7 = (NettyPacketManager_7) npm;
|
||||
npm_7.ejectPlayer(player);
|
||||
} else {
|
||||
NettyPacketManager_8 npm_8 = (NettyPacketManager_8) npm;
|
||||
npm_8.ejectPlayer(player);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void ejectChannelSync(Object channel) {
|
||||
if (v1_7_nettyMode) {
|
||||
NettyPacketManager_7 npm_7 = (NettyPacketManager_7) npm;
|
||||
npm_7.ejectChannel(channel);
|
||||
} else {
|
||||
NettyPacketManager_8 npm_8 = (NettyPacketManager_8) npm;
|
||||
npm_8.ejectChannel(channel);
|
||||
}
|
||||
}
|
||||
|
||||
public void ejectChannelAsync(Object channel) {
|
||||
PacketEvents.packetHandlingExecutorService.execute(() -> {
|
||||
if (v1_7_nettyMode) {
|
||||
NettyPacketManager_7 npm_7 = (NettyPacketManager_7) npm;
|
||||
npm_7.ejectChannel(channel);
|
||||
} else {
|
||||
NettyPacketManager_8 npm_8 = (NettyPacketManager_8) npm;
|
||||
npm_8.ejectChannel(channel);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void sendPacket(Object channel, Object packet) {
|
||||
if (v1_7_nettyMode) {
|
||||
NettyPacketManager_7 npm_7 = (NettyPacketManager_7) npm;
|
||||
npm_7.sendPacket(channel, packet);
|
||||
} else {
|
||||
NettyPacketManager_8 npm_8 = (NettyPacketManager_8) npm;
|
||||
npm_8.sendPacket(channel, packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetmanager.netty;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import net.minecraft.util.io.netty.channel.Channel;
|
||||
import net.minecraft.util.io.netty.channel.ChannelDuplexHandler;
|
||||
import net.minecraft.util.io.netty.channel.ChannelHandlerContext;
|
||||
import net.minecraft.util.io.netty.channel.ChannelPipeline;
|
||||
import net.minecraft.util.io.netty.channel.ChannelPromise;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
final class NettyPacketManager_7 {
|
||||
NettyPacketManager_7() {
|
||||
|
||||
}
|
||||
/**
|
||||
* Inject a player using 1.7.10's netty import location
|
||||
* @param player
|
||||
*/
|
||||
public void injectPlayer(final Player player) {
|
||||
final ChannelDuplexHandler channelDuplexHandler = new ChannelDuplexHandler() {
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
Object packet = PacketEvents.getAPI().packetManager.read(player, ctx.channel(), msg);
|
||||
if (packet == null) {
|
||||
return;
|
||||
}
|
||||
super.channelRead(ctx, msg);
|
||||
PacketEvents.getAPI().packetManager.postRead(player, packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
|
||||
Object packet = PacketEvents.getAPI().packetManager.write(player, ctx.channel(),msg);
|
||||
if (packet == null) {
|
||||
return;
|
||||
}
|
||||
super.write(ctx, msg, promise);
|
||||
PacketEvents.getAPI().packetManager.postWrite(player, packet);
|
||||
}
|
||||
};
|
||||
final ChannelPipeline pipeline = ((Channel) NMSUtils.getChannel(player)).pipeline();
|
||||
pipeline.addBefore("packet_handler", PacketEvents.getAPI().packetManager.getNettyHandlerName(), channelDuplexHandler);
|
||||
}
|
||||
|
||||
public void ejectPlayer(Player player) {
|
||||
Channel channel = (Channel) NMSUtils.getChannel(player);
|
||||
assert channel != null;
|
||||
ejectChannel(channel);
|
||||
}
|
||||
|
||||
public void ejectChannel(Object ch) {
|
||||
Channel channel = (Channel) ch;
|
||||
channel.pipeline().remove(PacketEvents.getAPI().packetManager.getNettyHandlerName());
|
||||
}
|
||||
|
||||
public void sendPacket(Object rawChannel, Object packet) {
|
||||
Channel channel = (Channel) rawChannel;
|
||||
channel.pipeline().writeAndFlush(packet);
|
||||
}
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetmanager.netty;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelDuplexHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
final class NettyPacketManager_8 {
|
||||
NettyPacketManager_8() {
|
||||
|
||||
}
|
||||
/**
|
||||
* Inject a player with 1.8+ netty import location.
|
||||
* @param player
|
||||
*/
|
||||
public void injectPlayer(final Player player) {
|
||||
final ChannelDuplexHandler channelDuplexHandler = new ChannelDuplexHandler() {
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
Object packet = PacketEvents.getAPI().packetManager.read(player, ctx.channel(),msg);
|
||||
if (packet == null) {
|
||||
return;
|
||||
}
|
||||
super.channelRead(ctx, msg);
|
||||
PacketEvents.getAPI().packetManager.postRead(player, packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
|
||||
Object packet = PacketEvents.getAPI().packetManager.write(player, ctx.channel(),msg);
|
||||
if (packet == null) {
|
||||
return;
|
||||
}
|
||||
super.write(ctx, msg, promise);
|
||||
PacketEvents.getAPI().packetManager.postWrite(player, packet);
|
||||
}
|
||||
};
|
||||
final ChannelPipeline pipeline = ((Channel) NMSUtils.getChannel(player)).pipeline();
|
||||
pipeline.addBefore("packet_handler", PacketEvents.getAPI().packetManager.getNettyHandlerName(), channelDuplexHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Eject a player with 1.8+ netty import location.
|
||||
* @param player
|
||||
*/
|
||||
public void ejectPlayer(final Player player) {
|
||||
final Channel channel = (Channel) NMSUtils.getChannel(player);
|
||||
assert channel != null;
|
||||
ejectChannel(channel);
|
||||
}
|
||||
|
||||
public void ejectChannel(Object channel) {
|
||||
Channel ch = (Channel)channel;
|
||||
ch.pipeline().remove(PacketEvents.getAPI().packetManager.getNettyHandlerName());
|
||||
}
|
||||
|
||||
public void sendPacket(Object rawChannel, Object packet) {
|
||||
Channel channel = (Channel)rawChannel;
|
||||
channel.pipeline().writeAndFlush(packet);
|
||||
}
|
||||
}
|
||||
+376
@@ -0,0 +1,376 @@
|
||||
package io.github.retrooper.packetevents.packetmanager.tinyprotocol;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
/**
|
||||
* An utility class that simplifies reflection in Bukkit plugins.
|
||||
*
|
||||
* @author Kristian
|
||||
*/
|
||||
public final class Reflection {
|
||||
/**
|
||||
* An interface for invoking a specific constructor.
|
||||
*/
|
||||
public interface ConstructorInvoker {
|
||||
/**
|
||||
* Invoke a constructor for a specific class.
|
||||
*
|
||||
* @param arguments - the arguments to pass to the constructor.
|
||||
* @return The constructed object.
|
||||
*/
|
||||
Object invoke(Object... arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* An interface for invoking a specific method.
|
||||
*/
|
||||
public interface MethodInvoker {
|
||||
/**
|
||||
* Invoke a method on a specific target object.
|
||||
*
|
||||
* @param target - the target object, or NULL for a static method.
|
||||
* @param arguments - the arguments to pass to the method.
|
||||
* @return The return value, or NULL if is void.
|
||||
*/
|
||||
Object invoke(Object target, Object... arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* An interface for retrieving the field content.
|
||||
*
|
||||
* @param <T> - field type.
|
||||
*/
|
||||
public interface FieldAccessor<T> {
|
||||
/**
|
||||
* Retrieve the content of a field.
|
||||
*
|
||||
* @param target - the target object, or NULL for a static field.
|
||||
* @return The value of the field.
|
||||
*/
|
||||
T get(Object target);
|
||||
|
||||
/**
|
||||
* Set the content of a field.
|
||||
*
|
||||
* @param target - the target object, or NULL for a static field.
|
||||
* @param value - the new value of the field.
|
||||
*/
|
||||
void set(Object target, Object value);
|
||||
|
||||
/**
|
||||
* Determine if the given object has this field.
|
||||
*
|
||||
* @param target - the object to test.
|
||||
* @return TRUE if it does, FALSE otherwise.
|
||||
*/
|
||||
boolean hasField(Object target);
|
||||
}
|
||||
|
||||
// Deduce the net.minecraft.server.v* package
|
||||
private static String OBC_PREFIX = Bukkit.getServer().getClass().getPackage().getName();
|
||||
private static String NMS_PREFIX = OBC_PREFIX.replace("org.bukkit.craftbukkit", "net.minecraft.server");
|
||||
private static String VERSION = OBC_PREFIX.replace("org.bukkit.craftbukkit", "").replace(".", "");
|
||||
|
||||
// Variable replacement
|
||||
private static Pattern MATCH_VARIABLE = Pattern.compile("\\{([^\\}]+)\\}");
|
||||
|
||||
private Reflection() {
|
||||
// Seal class
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a field accessor for a specific field type and name.
|
||||
*
|
||||
* @param target - the target type.
|
||||
* @param name - the name of the field, or NULL to ignore.
|
||||
* @param fieldType - a compatible field type.
|
||||
* @return The field accessor.
|
||||
*/
|
||||
public static <T> FieldAccessor<T> getField(Class<?> target, String name, Class<T> fieldType) {
|
||||
return getField(target, name, fieldType, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a field accessor for a specific field type and name.
|
||||
*
|
||||
* @param className - lookup name of the class, see {@link #getClass(String)}.
|
||||
* @param name - the name of the field, or NULL to ignore.
|
||||
* @param fieldType - a compatible field type.
|
||||
* @return The field accessor.
|
||||
*/
|
||||
public static <T> FieldAccessor<T> getField(String className, String name, Class<T> fieldType) {
|
||||
return getField(getClass(className), name, fieldType, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a field accessor for a specific field type and name.
|
||||
*
|
||||
* @param target - the target type.
|
||||
* @param fieldType - a compatible field type.
|
||||
* @param index - the number of compatible fields to skip.
|
||||
* @return The field accessor.
|
||||
*/
|
||||
public static <T> FieldAccessor<T> getField(Class<?> target, Class<T> fieldType, int index) {
|
||||
return getField(target, null, fieldType, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a field accessor for a specific field type and name.
|
||||
*
|
||||
* @param className - lookup name of the class, see {@link #getClass(String)}.
|
||||
* @param fieldType - a compatible field type.
|
||||
* @param index - the number of compatible fields to skip.
|
||||
* @return The field accessor.
|
||||
*/
|
||||
public static <T> FieldAccessor<T> getField(String className, Class<T> fieldType, int index) {
|
||||
return getField(getClass(className), fieldType, index);
|
||||
}
|
||||
|
||||
// Common method
|
||||
private static <T> FieldAccessor<T> getField(Class<?> target, String name, Class<T> fieldType, int index) {
|
||||
for (final Field field : target.getDeclaredFields()) {
|
||||
if ((name == null || field.getName().equals(name)) && fieldType.isAssignableFrom(field.getType()) && index-- <= 0) {
|
||||
field.setAccessible(true);
|
||||
|
||||
// A function for retrieving a specific field value
|
||||
return new FieldAccessor<T>() {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public T get(Object target) {
|
||||
try {
|
||||
return (T) field.get(target);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException("Cannot access reflection.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(Object target, Object value) {
|
||||
try {
|
||||
field.set(target, value);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException("Cannot access reflection.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasField(Object target) {
|
||||
// target instanceof DeclaringClass
|
||||
return field.getDeclaringClass().isAssignableFrom(target.getClass());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Search in parent classes
|
||||
if (target.getSuperclass() != null)
|
||||
return getField(target.getSuperclass(), name, fieldType, index);
|
||||
|
||||
throw new IllegalArgumentException("Cannot find field with type " + fieldType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for the first publicly and privately defined method of the given name and parameter count.
|
||||
*
|
||||
* @param className - lookup name of the class, see {@link #getClass(String)}.
|
||||
* @param methodName - the method name, or NULL to skip.
|
||||
* @param params - the expected parameters.
|
||||
* @return An object that invokes this specific method.
|
||||
* @throws IllegalStateException If we cannot find this method.
|
||||
*/
|
||||
public static MethodInvoker getMethod(String className, String methodName, Class<?>... params) {
|
||||
return getTypedMethod(getClass(className), methodName, null, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for the first publicly and privately defined method of the given name and parameter count.
|
||||
*
|
||||
* @param clazz - a class to start with.
|
||||
* @param methodName - the method name, or NULL to skip.
|
||||
* @param params - the expected parameters.
|
||||
* @return An object that invokes this specific method.
|
||||
* @throws IllegalStateException If we cannot find this method.
|
||||
*/
|
||||
public static MethodInvoker getMethod(Class<?> clazz, String methodName, Class<?>... params) {
|
||||
return getTypedMethod(clazz, methodName, null, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for the first publicly and privately defined method of the given name and parameter count.
|
||||
*
|
||||
* @param clazz - a class to start with.
|
||||
* @param methodName - the method name, or NULL to skip.
|
||||
* @param returnType - the expected return type, or NULL to ignore.
|
||||
* @param params - the expected parameters.
|
||||
* @return An object that invokes this specific method.
|
||||
* @throws IllegalStateException If we cannot find this method.
|
||||
*/
|
||||
public static MethodInvoker getTypedMethod(Class<?> clazz, String methodName, Class<?> returnType, Class<?>... params) {
|
||||
for (final Method method : clazz.getDeclaredMethods()) {
|
||||
if ((methodName == null || method.getName().equals(methodName))
|
||||
&& (returnType == null || method.getReturnType().equals(returnType))
|
||||
&& Arrays.equals(method.getParameterTypes(), params)) {
|
||||
method.setAccessible(true);
|
||||
|
||||
return new MethodInvoker() {
|
||||
|
||||
@Override
|
||||
public Object invoke(Object target, Object... arguments) {
|
||||
try {
|
||||
return method.invoke(target, arguments);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot invoke method " + method, e);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Search in every superclass
|
||||
if (clazz.getSuperclass() != null)
|
||||
return getMethod(clazz.getSuperclass(), methodName, params);
|
||||
|
||||
throw new IllegalStateException(String.format("Unable to find method %s (%s).", methodName, Arrays.asList(params)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for the first publically and privately defined constructor of the given name and parameter count.
|
||||
*
|
||||
* @param className - lookup name of the class, see {@link #getClass(String)}.
|
||||
* @param params - the expected parameters.
|
||||
* @return An object that invokes this constructor.
|
||||
* @throws IllegalStateException If we cannot find this method.
|
||||
*/
|
||||
public static ConstructorInvoker getConstructor(String className, Class<?>... params) {
|
||||
return getConstructor(getClass(className), params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for the first publically and privately defined constructor of the given name and parameter count.
|
||||
*
|
||||
* @param clazz - a class to start with.
|
||||
* @param params - the expected parameters.
|
||||
* @return An object that invokes this constructor.
|
||||
* @throws IllegalStateException If we cannot find this method.
|
||||
*/
|
||||
public static ConstructorInvoker getConstructor(Class<?> clazz, Class<?>... params) {
|
||||
for (final Constructor<?> constructor : clazz.getDeclaredConstructors()) {
|
||||
if (Arrays.equals(constructor.getParameterTypes(), params)) {
|
||||
constructor.setAccessible(true);
|
||||
|
||||
return new ConstructorInvoker() {
|
||||
|
||||
@Override
|
||||
public Object invoke(Object... arguments) {
|
||||
try {
|
||||
return constructor.newInstance(arguments);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot invoke constructor " + constructor, e);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalStateException(String.format("Unable to find constructor for %s (%s).", clazz, Arrays.asList(params)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a class from its full name, without knowing its type on compile time.
|
||||
* <p>
|
||||
* This is useful when looking up fields by a NMS or OBC type.
|
||||
* <p>
|
||||
*
|
||||
* See {@link #getClass()} for more information.
|
||||
* @param lookupName - the class name with variables.
|
||||
* @return The class.
|
||||
*/
|
||||
public static Class<Object> getUntypedClass(String lookupName) {
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
Class<Object> clazz = (Class) getClass(lookupName);
|
||||
return clazz;
|
||||
}
|
||||
|
||||
|
||||
public static Class<?> getClass(String lookupName) {
|
||||
return getCanonicalClass(expandVariables(lookupName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a class in the net.minecraft.server.VERSION.* package.
|
||||
*
|
||||
* @param name - the name of the class, excluding the package.
|
||||
* @throws IllegalArgumentException If the class doesn't exist.
|
||||
*/
|
||||
public static Class<?> getMinecraftClass(String name) {
|
||||
return getCanonicalClass(NMS_PREFIX + "." + name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a class in the org.bukkit.craftbukkit.VERSION.* package.
|
||||
*
|
||||
* @param name - the name of the class, excluding the package.
|
||||
* @throws IllegalArgumentException If the class doesn't exist.
|
||||
*/
|
||||
public static Class<?> getCraftBukkitClass(String name) {
|
||||
return getCanonicalClass(OBC_PREFIX + "." + name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a class by its canonical name.
|
||||
*
|
||||
* @param canonicalName - the canonical name.
|
||||
* @return The class.
|
||||
*/
|
||||
private static Class<?> getCanonicalClass(String canonicalName) {
|
||||
try {
|
||||
return Class.forName(canonicalName);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new IllegalArgumentException("Cannot find " + canonicalName, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand variables such as "{nms}" and "{obc}" to their corresponding packages.
|
||||
*
|
||||
* @param name - the full name of the class.
|
||||
* @return The expanded string.
|
||||
*/
|
||||
private static String expandVariables(String name) {
|
||||
StringBuffer output = new StringBuffer();
|
||||
Matcher matcher = MATCH_VARIABLE.matcher(name);
|
||||
|
||||
while (matcher.find()) {
|
||||
String variable = matcher.group(1);
|
||||
String replacement = "";
|
||||
|
||||
// Expand all detected variables
|
||||
if ("nms".equalsIgnoreCase(variable))
|
||||
replacement = NMS_PREFIX;
|
||||
else if ("obc".equalsIgnoreCase(variable))
|
||||
replacement = OBC_PREFIX;
|
||||
else if ("version".equalsIgnoreCase(variable))
|
||||
replacement = VERSION;
|
||||
else
|
||||
throw new IllegalArgumentException("Unknown variable: " + variable);
|
||||
|
||||
// Assume the expanded variables are all packages, and append a dot
|
||||
if (replacement.length() > 0 && matcher.end() < name.length() && name.charAt(matcher.end()) != '.')
|
||||
replacement += ".";
|
||||
matcher.appendReplacement(output, Matcher.quoteReplacement(replacement));
|
||||
}
|
||||
|
||||
matcher.appendTail(output);
|
||||
return output.toString();
|
||||
}
|
||||
}
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetmanager.tinyprotocol;
|
||||
|
||||
import io.github.retrooper.packetevents.packetmanager.netty.NettyPacketManager;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class TinyProtocol {
|
||||
private final Object tinyProt;
|
||||
|
||||
public TinyProtocol(Plugin plugin) {
|
||||
if (NettyPacketManager.v1_7_nettyMode) {
|
||||
tinyProt = new TinyProtocol7(plugin);
|
||||
} else {
|
||||
tinyProt = new TinyProtocol8(plugin);
|
||||
}
|
||||
}
|
||||
|
||||
public void injectPlayer(Player player) {
|
||||
if (!NettyPacketManager.v1_7_nettyMode) {
|
||||
TinyProtocol8 tp8 = (TinyProtocol8) tinyProt;
|
||||
tp8.injectPlayer(player);
|
||||
} else {
|
||||
TinyProtocol7 tp7 = (TinyProtocol7) tinyProt;
|
||||
tp7.injectPlayer(player);
|
||||
}
|
||||
}
|
||||
|
||||
public void injectPlayerAsync(Player player) {
|
||||
if (!NettyPacketManager.v1_7_nettyMode) {
|
||||
TinyProtocol8 tp8 = (TinyProtocol8) tinyProt;
|
||||
tp8.injectPlayerAsync(player);
|
||||
} else {
|
||||
TinyProtocol7 tp7 = (TinyProtocol7) tinyProt;
|
||||
tp7.injectPlayerAsync(player);
|
||||
}
|
||||
}
|
||||
|
||||
public void ejectPlayer(Player player) {
|
||||
if (!NettyPacketManager.v1_7_nettyMode) {
|
||||
TinyProtocol8 tp8 = (TinyProtocol8) tinyProt;
|
||||
tp8.uninjectPlayer(player);
|
||||
} else {
|
||||
TinyProtocol7 tp7 = (TinyProtocol7) tinyProt;
|
||||
tp7.uninjectPlayer(player);
|
||||
}
|
||||
}
|
||||
|
||||
public void ejectPlayerAsync(Player player) {
|
||||
if (!NettyPacketManager.v1_7_nettyMode) {
|
||||
TinyProtocol8 tp8 = (TinyProtocol8) tinyProt;
|
||||
tp8.uninjectPlayerAsync(player);
|
||||
} else {
|
||||
TinyProtocol7 tp7 = (TinyProtocol7) tinyProt;
|
||||
tp7.uninjectPlayerAsync(player);
|
||||
}
|
||||
}
|
||||
|
||||
public void ejectChannelSync(Object channel) {
|
||||
if (!NettyPacketManager.v1_7_nettyMode) {
|
||||
TinyProtocol8 tp8 = (TinyProtocol8) tinyProt;
|
||||
tp8.ejectChannelSync(channel);
|
||||
} else {
|
||||
TinyProtocol7 tp7 = (TinyProtocol7) tinyProt;
|
||||
tp7.ejectChannelSync(channel);
|
||||
}
|
||||
}
|
||||
|
||||
public void ejectChannelAsync(Object channel) {
|
||||
if (!NettyPacketManager.v1_7_nettyMode) {
|
||||
TinyProtocol8 tp8 = (TinyProtocol8) tinyProt;
|
||||
tp8.ejectChannelAsync(channel);
|
||||
} else {
|
||||
TinyProtocol7 tp7 = (TinyProtocol7) tinyProt;
|
||||
tp7.ejectChannelAsync(channel);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendPacket(Object channel, Object packet) {
|
||||
if (!NettyPacketManager.v1_7_nettyMode) {
|
||||
TinyProtocol8 tp8 = (TinyProtocol8) tinyProt;
|
||||
tp8.sendPacket(channel, packet);
|
||||
} else {
|
||||
TinyProtocol7 tp7 = (TinyProtocol7) tinyProt;
|
||||
tp7.sendPacket(channel, packet);
|
||||
}
|
||||
}
|
||||
|
||||
public Object getChannel(Player player) {
|
||||
if (NettyPacketManager.v1_7_nettyMode) {
|
||||
TinyProtocol7 tp7 = (TinyProtocol7) tinyProt;
|
||||
return tp7.getChannel(player);
|
||||
} else {
|
||||
TinyProtocol8 tp8 = (TinyProtocol8) tinyProt;
|
||||
return tp8.getChannel(player);
|
||||
}
|
||||
}
|
||||
|
||||
public void unregisterChannelHandler() {
|
||||
|
||||
}
|
||||
}
|
||||
+507
@@ -0,0 +1,507 @@
|
||||
package io.github.retrooper.packetevents.packetmanager.tinyprotocol;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.packetmanager.netty.NettyPacketManager;
|
||||
import io.github.retrooper.packetevents.packetmanager.tinyprotocol.Reflection.FieldAccessor;
|
||||
import io.github.retrooper.packetevents.packetmanager.tinyprotocol.Reflection.MethodInvoker;
|
||||
import net.minecraft.util.com.google.common.collect.Lists;
|
||||
import net.minecraft.util.com.google.common.collect.MapMaker;
|
||||
import net.minecraft.util.com.mojang.authlib.GameProfile;
|
||||
import net.minecraft.util.io.netty.channel.*;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* Represents a very tiny alternative to ProtocolLib.
|
||||
* <p>
|
||||
* It now supports intercepting packets during login and status ping (such as OUT_SERVER_PING)!
|
||||
*
|
||||
* @author Kristian
|
||||
*/
|
||||
|
||||
//BROKEN: NPEs when player joins while server is starting, and using PlayerJoinEvent instead will cause NPE for protocol version lookup.
|
||||
//Protocol version number lookup method from DeprecatedLuke's version of TinyProtocol
|
||||
public class TinyProtocol7 {
|
||||
private static final AtomicInteger ID = new AtomicInteger();
|
||||
|
||||
// Used in order to lookup a channel
|
||||
private static final MethodInvoker getPlayerHandle = Reflection.getMethod("{obc}.entity.CraftPlayer", "getHandle");
|
||||
private static final FieldAccessor<Object> getConnection = Reflection.getField("{nms}.EntityPlayer", "playerConnection", Object.class);
|
||||
private static final FieldAccessor<Object> getManager = Reflection.getField("{nms}.PlayerConnection", "networkManager", Object.class);
|
||||
private static final FieldAccessor<Channel> getChannel = Reflection.getField("{nms}.NetworkManager", Channel.class, 0);
|
||||
|
||||
// Looking up ServerConnection
|
||||
private static final Class<Object> minecraftServerClass = Reflection.getUntypedClass("{nms}.MinecraftServer");
|
||||
private static final Class<Object> serverConnectionClass = Reflection.getUntypedClass("{nms}.ServerConnection");
|
||||
private static final FieldAccessor<Object> getMinecraftServer = Reflection.getField("{obc}.CraftServer", minecraftServerClass, 0);
|
||||
private static final FieldAccessor<Object> getServerConnection = Reflection.getField(minecraftServerClass, serverConnectionClass, 0);
|
||||
private static final MethodInvoker getNetworkMarkers = Reflection.getTypedMethod(serverConnectionClass, null, List.class, serverConnectionClass);
|
||||
|
||||
// Packets we have to intercept
|
||||
private static final Class<?> PACKET_LOGIN_IN_START = Reflection.getMinecraftClass("PacketLoginInStart");
|
||||
private static final Class<?> PACKET_HANDSHAKING_IN_SET_PROTOCOL = Reflection.getMinecraftClass("PacketHandshakingInSetProtocol");
|
||||
private static final FieldAccessor<GameProfile> getGameProfile = Reflection.getField(PACKET_LOGIN_IN_START, GameProfile.class, 0);
|
||||
|
||||
// Speedup channel/protocol lookup
|
||||
private final Map<String, Channel> channelLookup = new MapMaker().weakValues().makeMap();
|
||||
|
||||
// List of network markers
|
||||
private List<Object> networkManagers;
|
||||
|
||||
// Injected channel handlers
|
||||
private final List<Channel> serverChannels = Lists.newArrayList();
|
||||
private ChannelInboundHandlerAdapter serverChannelHandler;
|
||||
private ChannelInitializer<Channel> beginInitProtocol;
|
||||
private ChannelInitializer<Channel> endInitProtocol;
|
||||
|
||||
// Current handler name
|
||||
private final String handlerName;
|
||||
|
||||
protected volatile boolean closed;
|
||||
protected Plugin plugin;
|
||||
|
||||
/**
|
||||
* Construct a new instance of TinyProtocol, and start intercepting packets for all connected clients and future clients.
|
||||
* <p>
|
||||
* You can construct multiple instances per plugin.
|
||||
*
|
||||
* @param plugin - the plugin.
|
||||
*/
|
||||
public TinyProtocol7(final Plugin plugin) {
|
||||
this.plugin = plugin;
|
||||
|
||||
// Compute handler name
|
||||
this.handlerName = getHandlerName();
|
||||
|
||||
try {
|
||||
registerChannelHandler();
|
||||
registerPlayers(plugin);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// Damn you, late bind
|
||||
plugin.getLogger().info("Delaying server channel injection due to late bind.");
|
||||
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
registerChannelHandler();
|
||||
registerPlayers(plugin);
|
||||
plugin.getLogger().info("Late bind injection successful.");
|
||||
}
|
||||
}.runTask(plugin);
|
||||
}
|
||||
}
|
||||
|
||||
private void createServerChannelHandler() {
|
||||
// Handle connected channels
|
||||
endInitProtocol = new ChannelInitializer<Channel>() {
|
||||
|
||||
@Override
|
||||
protected void initChannel(Channel channel) throws Exception {
|
||||
try {
|
||||
// This can take a while, so we need to stop the main thread from interfering
|
||||
synchronized (networkManagers) {
|
||||
// Stop injecting channels
|
||||
if (!closed) {
|
||||
channel.eventLoop().submit(() -> injectChannelInternal(channel));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
plugin.getLogger().log(Level.SEVERE, "Cannot inject incomming channel " + channel, e);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// This is executed before Minecraft's channel handler
|
||||
beginInitProtocol = new ChannelInitializer<Channel>() {
|
||||
|
||||
@Override
|
||||
protected void initChannel(Channel channel) throws Exception {
|
||||
channel.pipeline().addLast(endInitProtocol);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
serverChannelHandler = new ChannelInboundHandlerAdapter() {
|
||||
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
Channel channel = (Channel) msg;
|
||||
|
||||
// Prepare to initialize ths channel
|
||||
channel.pipeline().addFirst(beginInitProtocol);
|
||||
ctx.fireChannelRead(msg);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void registerChannelHandler() {
|
||||
Object mcServer = getMinecraftServer.get(Bukkit.getServer());
|
||||
Object serverConnection = getServerConnection.get(mcServer);
|
||||
boolean looking = true;
|
||||
|
||||
// We need to synchronize against this list
|
||||
networkManagers = (List<Object>) getNetworkMarkers.invoke(null, serverConnection);
|
||||
createServerChannelHandler();
|
||||
|
||||
// Find the correct list, or implicitly throw an exception
|
||||
for (int i = 0; looking; i++) {
|
||||
List<Object> list = Reflection.getField(serverConnection.getClass(), List.class, i).get(serverConnection);
|
||||
|
||||
for (Object item : list) {
|
||||
if (!(item instanceof ChannelFuture))
|
||||
break;
|
||||
|
||||
// Channel future that contains the server connection
|
||||
Channel serverChannel = ((ChannelFuture) item).channel();
|
||||
|
||||
serverChannels.add(serverChannel);
|
||||
serverChannel.pipeline().addFirst(serverChannelHandler);
|
||||
looking = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void unregisterChannelHandler() {
|
||||
if (serverChannelHandler == null)
|
||||
return;
|
||||
|
||||
for (Channel serverChannel : serverChannels) {
|
||||
final ChannelPipeline pipeline = serverChannel.pipeline();
|
||||
|
||||
// Remove channel handler
|
||||
serverChannel.eventLoop().execute(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
pipeline.remove(serverChannelHandler);
|
||||
} catch (NoSuchElementException e) {
|
||||
// That's fine
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void registerPlayers(Plugin plugin) {
|
||||
for (Player player : plugin.getServer().getOnlinePlayers()) {
|
||||
injectPlayer(player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when the server is starting to send a packet to a player.
|
||||
* <p>
|
||||
* Note that this is not executed on the main thread.
|
||||
*
|
||||
* @param receiver - the receiving player, NULL for early login/status packets.
|
||||
* @param channel - the channel that received the packet. Never NULL.
|
||||
* @param packet - the packet being sent.
|
||||
* @return The packet to send instead, or NULL to cancel the transmission.
|
||||
*/
|
||||
public Object onPacketOutAsync(Player receiver, Channel channel, Object packet) {
|
||||
return PacketEvents.getAPI().packetManager.write(receiver, channel, packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when the server has received a packet from a given player.
|
||||
* <p>
|
||||
* Use {@link Channel#remoteAddress()} to get the remote address of the client.
|
||||
*
|
||||
* @param sender - the player that sent the packet, NULL for early login/status packets.
|
||||
* @param channel - channel that received the packet. Never NULL.
|
||||
* @param packet - the packet being received.
|
||||
* @return The packet to recieve instead, or NULL to cancel.
|
||||
*/
|
||||
public Object onPacketInAsync(Player sender, Channel channel, Object packet) {
|
||||
return PacketEvents.getAPI().packetManager.read(sender, channel, packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a packet to a particular player.
|
||||
* <p>
|
||||
* Note that {@link #onPacketOutAsync(Player, Channel, Object)} will be invoked with this packet.
|
||||
*
|
||||
* @param player - the destination player.
|
||||
* @param packet - the packet to send.
|
||||
*/
|
||||
public void sendPacket(Player player, Object packet) {
|
||||
sendPacket(getChannel(player), packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a packet to a particular client.
|
||||
* <p>
|
||||
* Note that {@link #onPacketOutAsync(Player, Channel, Object)} will be invoked with this packet.
|
||||
*
|
||||
* @param channel - client identified by a channel.
|
||||
* @param packet - the packet to send.
|
||||
*/
|
||||
public void sendPacket(Channel channel, Object packet) {
|
||||
channel.pipeline().writeAndFlush(packet);
|
||||
}
|
||||
|
||||
public void sendPacket(Object channel, Object packet) {
|
||||
sendPacket((Channel) channel, packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pretend that a given packet has been received from a player.
|
||||
* <p>
|
||||
* Note that {@link #onPacketInAsync(Player, Channel, Object)} will be invoked with this packet.
|
||||
*
|
||||
* @param player - the player that sent the packet.
|
||||
* @param packet - the packet that will be received by the server.
|
||||
*/
|
||||
public void receivePacket(Player player, Object packet) {
|
||||
receivePacket(getChannel(player), packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pretend that a given packet has been received from a given client.
|
||||
* <p>
|
||||
* Note that {@link #onPacketInAsync(Player, Channel, Object)} will be invoked with this packet.
|
||||
*
|
||||
* @param channel - client identified by a channel.
|
||||
* @param packet - the packet that will be received by the server.
|
||||
*/
|
||||
public void receivePacket(Channel channel, Object packet) {
|
||||
channel.pipeline().context("encoder").fireChannelRead(packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the name of the channel injector, default implementation is "tiny-" + plugin name + "-" + a unique ID.
|
||||
* <p>
|
||||
* Note that this method will only be invoked once. It is no longer necessary to override this to support multiple instances.
|
||||
*
|
||||
* @return A unique channel handler name.
|
||||
*/
|
||||
protected String getHandlerName() {
|
||||
return "PacketEvents-" + ID.incrementAndGet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a custom channel handler to the given player's channel pipeline, allowing us to intercept sent and received packets.
|
||||
* <p>
|
||||
* This will automatically be called when a player has logged in.
|
||||
*
|
||||
* @param player - the player to inject.
|
||||
*/
|
||||
public void injectPlayer(Player player) {
|
||||
injectChannelInternal(getChannel(player)).player = player;
|
||||
}
|
||||
|
||||
public void injectPlayerAsync(Player player) {
|
||||
Channel channel = getChannel(player);
|
||||
injectChannelInternalAsync(channel).player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a custom channel handler to the given channel.
|
||||
*
|
||||
* @param channel - the channel to inject.
|
||||
*/
|
||||
public void injectChannel(Channel channel) {
|
||||
injectChannelInternal(channel);
|
||||
}
|
||||
|
||||
public void injectChannelAsync(Channel channel) {
|
||||
injectChannelInternalAsync(channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a custom channel handler to the given channel.
|
||||
*
|
||||
* @param channel - the channel to inject.
|
||||
* @return The packet interceptor.
|
||||
*/
|
||||
private PacketInterceptor injectChannelInternal(Channel channel) {
|
||||
try {
|
||||
PacketInterceptor interceptor = (PacketInterceptor) channel.pipeline().get(handlerName);
|
||||
|
||||
// Inject our packet interceptor
|
||||
if (interceptor == null) {
|
||||
interceptor = new PacketInterceptor();
|
||||
channel.pipeline().addBefore("packet_handler", handlerName, interceptor);
|
||||
}
|
||||
|
||||
return interceptor;
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Try again
|
||||
return (PacketInterceptor) channel.pipeline().get(handlerName);
|
||||
}
|
||||
}
|
||||
|
||||
private PacketInterceptor injectChannelInternalAsync(Channel channel) {
|
||||
try {
|
||||
PacketInterceptor interceptor = (PacketInterceptor) channel.pipeline().get(handlerName);
|
||||
|
||||
// Inject our packet interceptor
|
||||
if (interceptor == null) {
|
||||
interceptor = new PacketInterceptor();
|
||||
final PacketInterceptor pi = interceptor;
|
||||
PacketEvents.packetHandlingExecutorService.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
channel.pipeline().addBefore("packet_handler", handlerName, pi);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return interceptor;
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Try again
|
||||
return (PacketInterceptor) channel.pipeline().get(handlerName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the Netty channel associated with a player. This is cached.
|
||||
*
|
||||
* @param player - the player.
|
||||
* @return The Netty channel.
|
||||
*/
|
||||
public Channel getChannel(Player player) {
|
||||
Channel channel = channelLookup.get(player.getName());
|
||||
|
||||
// Lookup channel again
|
||||
if (channel == null) {
|
||||
Object connection = getConnection.get(getPlayerHandle.invoke(player));
|
||||
Object manager = getManager.get(connection);
|
||||
|
||||
channelLookup.put(player.getName(), channel = getChannel.get(manager));
|
||||
}
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninject a specific player.
|
||||
*
|
||||
* @param player - the injected player.
|
||||
*/
|
||||
public void uninjectPlayer(Player player) {
|
||||
uninjectChannel(getChannel(player));
|
||||
}
|
||||
|
||||
public void uninjectPlayerAsync(Player player) {
|
||||
Channel channel = getChannel(player);
|
||||
uninjectChannelAsync(channel);
|
||||
}
|
||||
|
||||
public void ejectChannelSync(Object ch) {
|
||||
uninjectChannel((Channel)ch);
|
||||
}
|
||||
|
||||
public void ejectChannelAsync(Object ch) {
|
||||
uninjectChannelAsync((Channel)ch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninject a specific channel.
|
||||
* <p>
|
||||
* This will also disable the automatic channel injection that occurs when a player has properly logged in.
|
||||
*
|
||||
* @param channel - the injected channel.
|
||||
*/
|
||||
public void uninjectChannel(final Channel channel) {
|
||||
// See ChannelInjector in ProtocolLib, line 590
|
||||
channel.pipeline().remove(handlerName);
|
||||
}
|
||||
|
||||
public void uninjectChannelAsync(Channel channel) {
|
||||
// See ChannelInjector in ProtocolLib, line 590
|
||||
PacketEvents.packetHandlingExecutorService.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
channel.pipeline().remove(handlerName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given player has been injected by TinyProtocol.
|
||||
*
|
||||
* @param player - the player.
|
||||
* @return TRUE if it is, FALSE otherwise.
|
||||
*/
|
||||
public boolean hasInjected(Player player) {
|
||||
return hasInjected(getChannel(player));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given channel has been injected by TinyProtocol.
|
||||
*
|
||||
* @param channel - the channel.
|
||||
* @return TRUE if it is, FALSE otherwise.
|
||||
*/
|
||||
public boolean hasInjected(Channel channel) {
|
||||
return channel.pipeline().get(handlerName) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cease listening for packets. This is called automatically when your plugin is disabled.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Channel handler that is inserted into the player's channel pipeline, allowing us to intercept sent and received packets.
|
||||
*
|
||||
* @author Kristian
|
||||
*/
|
||||
private final class PacketInterceptor extends ChannelDuplexHandler {
|
||||
// Updated by the login event
|
||||
public volatile Player player;
|
||||
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
// Intercept channel
|
||||
final Channel channel = ctx.channel();
|
||||
handleLoginStart(channel, msg);
|
||||
|
||||
try {
|
||||
msg = onPacketInAsync(player, channel, msg);
|
||||
} catch (Exception e) {
|
||||
plugin.getLogger().log(Level.SEVERE, "Error in onPacketInAsync().", e);
|
||||
}
|
||||
|
||||
if (msg != null) {
|
||||
super.channelRead(ctx, msg);
|
||||
PacketEvents.getAPI().packetManager.postRead(player, msg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
|
||||
try {
|
||||
msg = onPacketOutAsync(player, ctx.channel(), msg);
|
||||
} catch (Exception e) {
|
||||
plugin.getLogger().log(Level.SEVERE, "Error in onPacketOutAsync().", e);
|
||||
}
|
||||
|
||||
if (msg != null) {
|
||||
super.write(ctx, msg, promise);
|
||||
PacketEvents.getAPI().packetManager.postWrite(player, msg);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleLoginStart(Channel channel, Object packet) {
|
||||
if (PACKET_LOGIN_IN_START.isInstance(packet)) {
|
||||
GameProfile profile = getGameProfile.get(packet);
|
||||
channelLookup.put(profile.getName(), channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+538
@@ -0,0 +1,538 @@
|
||||
package io.github.retrooper.packetevents.packetmanager.tinyprotocol;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.MapMaker;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.packetmanager.netty.NettyPacketManager;
|
||||
import io.github.retrooper.packetevents.packetmanager.tinyprotocol.Reflection.FieldAccessor;
|
||||
import io.github.retrooper.packetevents.packetmanager.tinyprotocol.Reflection.MethodInvoker;
|
||||
import io.netty.channel.*;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* Represents a very tiny alternative to ProtocolLib.
|
||||
* <p>
|
||||
* It now supports intercepting packets during login and status ping (such as OUT_SERVER_PING)!
|
||||
*
|
||||
* @author Kristian
|
||||
*/
|
||||
|
||||
//BROKEN: NPEs when player joins while server is starting, and using PlayerJoinEvent instead will cause NPE for protocol version lookup.
|
||||
//Protocol version number lookup method from DeprecatedLuke's version of TinyProtocol
|
||||
public class TinyProtocol8 {
|
||||
private static final AtomicInteger ID = new AtomicInteger();
|
||||
|
||||
// Used in order to lookup a channel
|
||||
private static final MethodInvoker getPlayerHandle = Reflection.getMethod("{obc}.entity.CraftPlayer", "getHandle");
|
||||
private static final FieldAccessor<Object> getConnection = Reflection.getField("{nms}.EntityPlayer", "playerConnection", Object.class);
|
||||
private static final FieldAccessor<Object> getManager = Reflection.getField("{nms}.PlayerConnection", "networkManager", Object.class);
|
||||
private static final FieldAccessor<Channel> getChannel = Reflection.getField("{nms}.NetworkManager", Channel.class, 0);
|
||||
|
||||
// Looking up ServerConnection
|
||||
private static final Class<Object> minecraftServerClass = Reflection.getUntypedClass("{nms}.MinecraftServer");
|
||||
private static final Class<Object> serverConnectionClass = Reflection.getUntypedClass("{nms}.ServerConnection");
|
||||
private static final FieldAccessor<Object> getMinecraftServer = Reflection.getField("{obc}.CraftServer", minecraftServerClass, 0);
|
||||
private static final FieldAccessor<Object> getServerConnection = Reflection.getField(minecraftServerClass, serverConnectionClass, 0);
|
||||
private static final MethodInvoker getNetworkMarkers;
|
||||
|
||||
// Packets we have to intercept
|
||||
private static final Class<?> PACKET_LOGIN_IN_START = Reflection.getMinecraftClass("PacketLoginInStart");
|
||||
private static final FieldAccessor<GameProfile> getGameProfile = Reflection.getField(PACKET_LOGIN_IN_START, GameProfile.class, 0);
|
||||
|
||||
static {
|
||||
MethodInvoker tempNetworkMarkers;
|
||||
try {
|
||||
tempNetworkMarkers = Reflection.getTypedMethod(serverConnectionClass, null, List.class, serverConnectionClass);
|
||||
} catch (Exception ex) {
|
||||
tempNetworkMarkers = null;
|
||||
}
|
||||
getNetworkMarkers = tempNetworkMarkers;
|
||||
}
|
||||
|
||||
// Speedup channel/protocol lookup
|
||||
private final Map<String, Channel> channelLookup = new MapMaker().weakValues().makeMap();
|
||||
|
||||
// List of network markers
|
||||
private List<Object> networkManagers;
|
||||
|
||||
// Injected channel handlers
|
||||
private final List<Channel> serverChannels = Lists.newArrayList();
|
||||
private ChannelInboundHandlerAdapter serverChannelHandler;
|
||||
private ChannelInitializer<Channel> beginInitProtocol;
|
||||
private ChannelInitializer<Channel> endInitProtocol;
|
||||
|
||||
// Current handler name
|
||||
private final String handlerName;
|
||||
|
||||
protected volatile boolean closed;
|
||||
protected Plugin plugin;
|
||||
|
||||
/**
|
||||
* Construct a new instance of TinyProtocol, and start intercepting packets for all connected clients and future clients.
|
||||
* <p>
|
||||
* You can construct multiple instances per plugin.
|
||||
*
|
||||
* @param plugin - the plugin.
|
||||
*/
|
||||
public TinyProtocol8(final Plugin plugin) {
|
||||
this.plugin = plugin;
|
||||
|
||||
// Compute handler name
|
||||
this.handlerName = getHandlerName();
|
||||
|
||||
try {
|
||||
registerChannelHandler();
|
||||
registerPlayers(plugin);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// Damn you, late bind
|
||||
plugin.getLogger().info("Delaying server channel injection due to late bind.");
|
||||
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
registerChannelHandler();
|
||||
registerPlayers(plugin);
|
||||
plugin.getLogger().info("Late bind injection successful.");
|
||||
}
|
||||
}.runTask(plugin);
|
||||
}
|
||||
}
|
||||
|
||||
private void createServerChannelHandler() {
|
||||
// Handle connected channels
|
||||
endInitProtocol = new ChannelInitializer<Channel>() {
|
||||
|
||||
@Override
|
||||
protected void initChannel(Channel channel) throws Exception {
|
||||
try {
|
||||
// This can take a while, so we need to stop the main thread from interfering
|
||||
synchronized (networkManagers) {
|
||||
// Stop injecting channels
|
||||
if (!closed) {
|
||||
channel.eventLoop().submit(() -> injectChannelInternal(channel));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
plugin.getLogger().log(Level.SEVERE, "Cannot inject incoming channel " + channel, e);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// This is executed before Minecraft's channel handler
|
||||
beginInitProtocol = new ChannelInitializer<Channel>() {
|
||||
|
||||
@Override
|
||||
protected void initChannel(Channel channel) throws Exception {
|
||||
channel.pipeline().addLast(endInitProtocol);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
serverChannelHandler = new ChannelInboundHandlerAdapter() {
|
||||
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
Channel channel = (Channel) msg;
|
||||
|
||||
// Prepare to initialize ths channel
|
||||
channel.pipeline().addFirst(beginInitProtocol);
|
||||
ctx.fireChannelRead(msg);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Register bukkit events.
|
||||
*/
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void registerChannelHandler() {
|
||||
Object mcServer = getMinecraftServer.get(Bukkit.getServer());
|
||||
Object serverConnection = getServerConnection.get(mcServer);
|
||||
boolean looking = true;
|
||||
|
||||
// We need to synchronize against this list
|
||||
if(getNetworkMarkers != null) {
|
||||
networkManagers = (List<Object>) getNetworkMarkers.invoke(null, serverConnection);}
|
||||
else {
|
||||
networkManagers = new ArrayList<>();
|
||||
}
|
||||
createServerChannelHandler();
|
||||
|
||||
// Find the correct list, or implicitly throw an exception
|
||||
for (int i = 0; looking; i++) {
|
||||
List<Object> list = Reflection.getField(serverConnection.getClass(), List.class, i).get(serverConnection);
|
||||
|
||||
for (Object item : list) {
|
||||
if (!(item instanceof ChannelFuture))
|
||||
break;
|
||||
|
||||
// Channel future that contains the server connection
|
||||
Channel serverChannel = ((ChannelFuture) item).channel();
|
||||
|
||||
serverChannels.add(serverChannel);
|
||||
serverChannel.pipeline().addFirst(serverChannelHandler);
|
||||
looking = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void unregisterChannelHandler() {
|
||||
if (serverChannelHandler == null)
|
||||
return;
|
||||
|
||||
for (Channel serverChannel : serverChannels) {
|
||||
final ChannelPipeline pipeline = serverChannel.pipeline();
|
||||
|
||||
// Remove channel handler
|
||||
serverChannel.eventLoop().execute(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
pipeline.remove(serverChannelHandler);
|
||||
} catch (NoSuchElementException e) {
|
||||
// That's fine
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void registerPlayers(Plugin plugin) {
|
||||
for (Player player : plugin.getServer().getOnlinePlayers()) {
|
||||
injectPlayer(player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when the server is starting to send a packet to a player.
|
||||
* <p>
|
||||
* Note that this is not executed on the main thread.
|
||||
*
|
||||
* @param receiver - the receiving player, NULL for early login/status packets.
|
||||
* @param channel - the channel that received the packet. Never NULL.
|
||||
* @param packet - the packet being sent.
|
||||
* @return The packet to send instead, or NULL to cancel the transmission.
|
||||
*/
|
||||
public Object onPacketOutAsync(Player receiver, Channel channel, Object packet) {
|
||||
return PacketEvents.getAPI().packetManager.write(receiver, channel, packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when the server has received a packet from a given player.
|
||||
* <p>
|
||||
* Use {@link Channel#remoteAddress()} to get the remote address of the client.
|
||||
*
|
||||
* @param sender - the player that sent the packet, NULL for early login/status packets.
|
||||
* @param channel - channel that received the packet. Never NULL.
|
||||
* @param packet - the packet being received.
|
||||
* @return The packet to recieve instead, or NULL to cancel.
|
||||
*/
|
||||
public Object onPacketInAsync(Player sender, Channel channel, Object packet) {
|
||||
return PacketEvents.getAPI().packetManager.read(sender, channel, packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a packet to a particular player.
|
||||
* <p>
|
||||
* Note that {@link #onPacketOutAsync(Player, Channel, Object)} will be invoked with this packet.
|
||||
*
|
||||
* @param player - the destination player.
|
||||
* @param packet - the packet to send.
|
||||
*/
|
||||
public void sendPacket(Player player, Object packet) {
|
||||
sendPacket(getChannel(player), packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a packet to a particular client.
|
||||
* <p>
|
||||
* Note that {@link #onPacketOutAsync(Player, Channel, Object)} will be invoked with this packet.
|
||||
*
|
||||
* @param channel - client identified by a channel.
|
||||
* @param packet - the packet to send.
|
||||
*/
|
||||
public void sendPacket(Channel channel, Object packet) {
|
||||
channel.pipeline().writeAndFlush(packet);
|
||||
}
|
||||
|
||||
public void sendPacket(Object channel, Object packet) {
|
||||
sendPacket((Channel) channel, packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pretend that a given packet has been received from a player.
|
||||
* <p>
|
||||
* Note that {@link #onPacketInAsync(Player, Channel, Object)} will be invoked with this packet.
|
||||
*
|
||||
* @param player - the player that sent the packet.
|
||||
* @param packet - the packet that will be received by the server.
|
||||
*/
|
||||
public void receivePacket(Player player, Object packet) {
|
||||
receivePacket(getChannel(player), packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pretend that a given packet has been received from a given client.
|
||||
* <p>
|
||||
* Note that {@link #onPacketInAsync(Player, Channel, Object)} will be invoked with this packet.
|
||||
*
|
||||
* @param channel - client identified by a channel.
|
||||
* @param packet - the packet that will be received by the server.
|
||||
*/
|
||||
public void receivePacket(Channel channel, Object packet) {
|
||||
channel.pipeline().context("encoder").fireChannelRead(packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the name of the channel injector, default implementation is "tiny-" + plugin name + "-" + a unique ID.
|
||||
* <p>
|
||||
* Note that this method will only be invoked once. It is no longer necessary to override this to support multiple instances.
|
||||
*
|
||||
* @return A unique channel handler name.
|
||||
*/
|
||||
protected String getHandlerName() {
|
||||
return "PacketEvents-" + ID.incrementAndGet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a custom channel handler to the given player's channel pipeline, allowing us to intercept sent and received packets.
|
||||
* <p>
|
||||
* This will automatically be called when a player has logged in.
|
||||
*
|
||||
* @param player - the player to inject.
|
||||
*/
|
||||
public void injectPlayer(Player player) {
|
||||
injectChannelInternal(getChannel(player)).player = player;
|
||||
}
|
||||
|
||||
public void injectPlayerAsync(Player player) {
|
||||
Channel channel = getChannel(player);
|
||||
injectChannelInternalAsync(channel).player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a custom channel handler to the given channel.
|
||||
*
|
||||
* @param channel - the channel to inject.
|
||||
*/
|
||||
public void injectChannel(Channel channel) {
|
||||
injectChannelInternal(channel);
|
||||
}
|
||||
|
||||
public void injectChannelAsync(Channel channel) {
|
||||
injectChannelInternalAsync(channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a custom channel handler to the given channel.
|
||||
*
|
||||
* @param channel - the channel to inject.
|
||||
* @return The packet interceptor.
|
||||
*/
|
||||
private PacketInterceptor injectChannelInternal(Channel channel) {
|
||||
try {
|
||||
PacketInterceptor interceptor = (PacketInterceptor) channel.pipeline().get(handlerName);
|
||||
|
||||
// Inject our packet interceptor
|
||||
if (interceptor == null) {
|
||||
interceptor = new PacketInterceptor();
|
||||
channel.pipeline().addBefore("packet_handler", handlerName, interceptor);
|
||||
}
|
||||
|
||||
return interceptor;
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Try again
|
||||
return (PacketInterceptor) channel.pipeline().get(handlerName);
|
||||
}
|
||||
}
|
||||
|
||||
private PacketInterceptor injectChannelInternalAsync(Channel channel) {
|
||||
try {
|
||||
PacketInterceptor interceptor = (PacketInterceptor) channel.pipeline().get(handlerName);
|
||||
|
||||
// Inject our packet interceptor
|
||||
if (interceptor == null) {
|
||||
interceptor = new PacketInterceptor();
|
||||
final PacketInterceptor pi = interceptor;
|
||||
PacketEvents.packetHandlingExecutorService.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
channel.pipeline().addBefore("packet_handler", handlerName, pi);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return interceptor;
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Try again
|
||||
return (PacketInterceptor) channel.pipeline().get(handlerName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the Netty channel associated with a player. This is cached.
|
||||
*
|
||||
* @param player - the player.
|
||||
* @return The Netty channel.
|
||||
*/
|
||||
public Channel getChannel(Player player) {
|
||||
Channel channel = channelLookup.get(player.getName());
|
||||
|
||||
// Lookup channel again
|
||||
if (channel == null) {
|
||||
Object connection = getConnection.get(getPlayerHandle.invoke(player));
|
||||
Object manager = getManager.get(connection);
|
||||
|
||||
channelLookup.put(player.getName(), channel = getChannel.get(manager));
|
||||
}
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninject a specific player.
|
||||
*
|
||||
* @param player - the injected player.
|
||||
*/
|
||||
public void uninjectPlayer(Player player) {
|
||||
uninjectChannel(getChannel(player));
|
||||
}
|
||||
|
||||
public void uninjectPlayerAsync(Player player) {
|
||||
Channel channel = getChannel(player);
|
||||
uninjectChannelAsync(channel);
|
||||
}
|
||||
|
||||
public void ejectChannelSync(Object ch) {
|
||||
uninjectChannel((Channel) ch);
|
||||
}
|
||||
|
||||
public void ejectChannelAsync(Object ch) {
|
||||
uninjectChannelAsync((Channel) ch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninject a specific channel.
|
||||
* <p>
|
||||
* This will also disable the automatic channel injection that occurs when a player has properly logged in.
|
||||
*
|
||||
* @param channel - the injected channel.
|
||||
*/
|
||||
public void uninjectChannel(final Channel channel) {
|
||||
// See ChannelInjector in ProtocolLib, line 590
|
||||
channel.pipeline().remove(handlerName);
|
||||
}
|
||||
|
||||
public void uninjectChannelAsync(Channel channel) {
|
||||
// See ChannelInjector in ProtocolLib, line 590
|
||||
PacketEvents.packetHandlingExecutorService.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
channel.pipeline().remove(handlerName);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given player has been injected by TinyProtocol.
|
||||
*
|
||||
* @param player - the player.
|
||||
* @return TRUE if it is, FALSE otherwise.
|
||||
*/
|
||||
public boolean hasInjected(Player player) {
|
||||
return hasInjected(getChannel(player));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given channel has been injected by TinyProtocol.
|
||||
*
|
||||
* @param channel - the channel.
|
||||
* @return TRUE if it is, FALSE otherwise.
|
||||
*/
|
||||
public boolean hasInjected(Channel channel) {
|
||||
return channel.pipeline().get(handlerName) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cease listening for packets. This is called automatically when your plugin is disabled.
|
||||
*/
|
||||
public final void close() {
|
||||
if (!closed) {
|
||||
closed = true;
|
||||
|
||||
// Remove our handlers
|
||||
for (Player player : plugin.getServer().getOnlinePlayers()) {
|
||||
uninjectPlayer(player);
|
||||
}
|
||||
|
||||
// Clean up Bukkit
|
||||
unregisterChannelHandler();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Channel handler that is inserted into the player's channel pipeline, allowing us to intercept sent and received packets.
|
||||
*
|
||||
* @author Kristian
|
||||
*/
|
||||
private final class PacketInterceptor extends ChannelDuplexHandler {
|
||||
// Updated by the login event
|
||||
public volatile Player player;
|
||||
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
// Intercept channel
|
||||
final Channel channel = ctx.channel();
|
||||
handleLoginStart(channel, msg);
|
||||
|
||||
try {
|
||||
msg = onPacketInAsync(player, channel, msg);
|
||||
} catch (Exception e) {
|
||||
plugin.getLogger().log(Level.SEVERE, "Error in onPacketInAsync().", e);
|
||||
}
|
||||
|
||||
if (msg != null) {
|
||||
super.channelRead(ctx, msg);
|
||||
PacketEvents.getAPI().packetManager.postRead(player, msg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
|
||||
try {
|
||||
msg = onPacketOutAsync(player, ctx.channel(), msg);
|
||||
} catch (Exception e) {
|
||||
plugin.getLogger().log(Level.SEVERE, "Error in onPacketOutAsync().", e);
|
||||
}
|
||||
|
||||
if (msg != null) {
|
||||
super.write(ctx, msg, promise);
|
||||
PacketEvents.getAPI().packetManager.postWrite(player, msg);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleLoginStart(Channel channel, Object packet) {
|
||||
if (PACKET_LOGIN_IN_START.isInstance(packet)) {
|
||||
GameProfile profile = getGameProfile.get(packet);
|
||||
channelLookup.put(profile.getName(), channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,282 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packettype;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class PacketType {
|
||||
public static class Status {
|
||||
public static final Map<Class<?>, Byte> packetIds = new HashMap<>();
|
||||
public static final byte IN_START = 0, PING = 1, PONG = 2, SERVER_INFO = 3;
|
||||
|
||||
public static void init() {
|
||||
packetIds.put(PacketTypeClasses.Status.IN_START, IN_START);
|
||||
packetIds.put(PacketTypeClasses.Status.PING, PING);
|
||||
packetIds.put(PacketTypeClasses.Status.PONG, PONG);
|
||||
packetIds.put(PacketTypeClasses.Status.SERVER_INFO, SERVER_INFO);
|
||||
}
|
||||
}
|
||||
public static class Login {
|
||||
public static final Map<Class<?>, Byte> packetIds = new HashMap<>();
|
||||
public static final byte HANDSHAKE = 0,
|
||||
IN_CUSTOM_PAYLOAD = 1, OUT_CUSTOM_PAYLOAD = 2,IN_START = 3, IN_ENCRYPTION_BEGIN = 4,
|
||||
DISCONNECT = 5, OUT_ENCRYPTION_BEGIN = 6, OUT_SUCCESS = 7;
|
||||
|
||||
public static void init() {
|
||||
packetIds.put(PacketTypeClasses.Login.HANDSHAKE, HANDSHAKE);
|
||||
packetIds.put(PacketTypeClasses.Login.IN_CUSTOM_PAYLOAD, IN_CUSTOM_PAYLOAD);
|
||||
packetIds.put(PacketTypeClasses.Login.OUT_CUSTOM_PAYLOAD, OUT_CUSTOM_PAYLOAD);
|
||||
packetIds.put(PacketTypeClasses.Login.IN_START, IN_START);
|
||||
packetIds.put(PacketTypeClasses.Login.IN_ENCRYPTION_BEGIN, IN_ENCRYPTION_BEGIN);
|
||||
packetIds.put(PacketTypeClasses.Login.DISCONNECT, DISCONNECT);
|
||||
packetIds.put(PacketTypeClasses.Login.OUT_ENCRYPTION_BEGIN, OUT_ENCRYPTION_BEGIN);
|
||||
packetIds.put(PacketTypeClasses.Login.OUT_SUCCESS, OUT_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Client {
|
||||
public static final Map<Class<?>, Byte> packetIds = new HashMap<>();
|
||||
public static final byte TELEPORT_ACCEPT = 0,
|
||||
TILE_NBT_QUERY = 1, DIFFICULTY_CHANGE = 2, CHAT = 3, CLIENT_COMMAND = 4,
|
||||
SETTINGS = 5, TAB_COMPLETE = 6, TRANSACTION = 7, ENCHANT_ITEM = 8,
|
||||
WINDOW_CLICK = 9, CLOSE_WINDOW = 10, CUSTOM_PAYLOAD = 11, B_EDIT = 12,
|
||||
ENTITY_NBT_QUERY = 13, USE_ENTITY = 14, JIGSAW_GENERATE = 15, KEEP_ALIVE = 16,
|
||||
DIFFICULTY_LOCK = 17, POSITION = 18, POSITION_LOOK = 19, LOOK = 20,
|
||||
FLYING = 21, VEHICLE_MOVE = 22, BOAT_MOVE = 23, PICK_ITEM = 24,
|
||||
AUTO_RECIPE = 25, ABILITIES = 26, BLOCK_DIG = 27, ENTITY_ACTION = 28,
|
||||
STEER_VEHICLE = 29, RECIPE_DISPLAYED = 30, ITEM_NAME = 31, RESOURCE_PACK_STATUS = 32,
|
||||
ADVANCEMENTS = 33, TR_SEL = 34, BEACON = 35, HELD_ITEM_SLOT = 36,
|
||||
SET_COMMAND_BLOCK = 37, SET_COMMAND_MINECART = 38, SET_CREATIVE_SLOT = 39, SET_JIGSAW = 40,
|
||||
STRUCT = 41, UPDATE_SIGN = 42, ARM_ANIMATION = 43, SPECTATE = 44,
|
||||
USE_ITEM = 45, BLOCK_PLACE = 46;
|
||||
|
||||
public static void init() {
|
||||
packetIds.put(PacketTypeClasses.Client.TELEPORT_ACCEPT, TELEPORT_ACCEPT);
|
||||
packetIds.put(PacketTypeClasses.Client.TILE_NBT_QUERY, TILE_NBT_QUERY);
|
||||
packetIds.put(PacketTypeClasses.Client.DIFFICULTY_CHANGE, DIFFICULTY_CHANGE);
|
||||
packetIds.put(PacketTypeClasses.Client.CHAT, CHAT);
|
||||
packetIds.put(PacketTypeClasses.Client.CLIENT_COMMAND, CLIENT_COMMAND);
|
||||
packetIds.put(PacketTypeClasses.Client.SETTINGS, SETTINGS);
|
||||
packetIds.put(PacketTypeClasses.Client.TAB_COMPLETE, TAB_COMPLETE);
|
||||
packetIds.put(PacketTypeClasses.Client.TRANSACTION, TRANSACTION);
|
||||
packetIds.put(PacketTypeClasses.Client.ENCHANT_ITEM, ENCHANT_ITEM);
|
||||
packetIds.put(PacketTypeClasses.Client.WINDOW_CLICK, WINDOW_CLICK);
|
||||
packetIds.put(PacketTypeClasses.Client.CLOSE_WINDOW, CLOSE_WINDOW);
|
||||
packetIds.put(PacketTypeClasses.Client.CUSTOM_PAYLOAD, CUSTOM_PAYLOAD);
|
||||
packetIds.put(PacketTypeClasses.Client.B_EDIT, B_EDIT);
|
||||
packetIds.put(PacketTypeClasses.Client.ENTITY_NBT_QUERY, ENTITY_NBT_QUERY);
|
||||
packetIds.put(PacketTypeClasses.Client.USE_ENTITY, USE_ENTITY);
|
||||
packetIds.put(PacketTypeClasses.Client.JIGSAW_GENERATE, JIGSAW_GENERATE);
|
||||
packetIds.put(PacketTypeClasses.Client.KEEP_ALIVE, KEEP_ALIVE);
|
||||
packetIds.put(PacketTypeClasses.Client.DIFFICULTY_LOCK, DIFFICULTY_LOCK);
|
||||
packetIds.put(PacketTypeClasses.Client.POSITION, POSITION);
|
||||
packetIds.put(PacketTypeClasses.Client.POSITION_LOOK, POSITION_LOOK);
|
||||
packetIds.put(PacketTypeClasses.Client.LOOK, LOOK);
|
||||
packetIds.put(PacketTypeClasses.Client.FLYING, FLYING);
|
||||
packetIds.put(PacketTypeClasses.Client.VEHICLE_MOVE, VEHICLE_MOVE);
|
||||
packetIds.put(PacketTypeClasses.Client.BOAT_MOVE, BOAT_MOVE);
|
||||
packetIds.put(PacketTypeClasses.Client.PICK_ITEM, PICK_ITEM);
|
||||
packetIds.put(PacketTypeClasses.Client.AUTO_RECIPE, AUTO_RECIPE);
|
||||
packetIds.put(PacketTypeClasses.Client.ABILITIES, ABILITIES);
|
||||
packetIds.put(PacketTypeClasses.Client.BLOCK_DIG, BLOCK_DIG);
|
||||
packetIds.put(PacketTypeClasses.Client.ENTITY_ACTION, ENTITY_ACTION);
|
||||
packetIds.put(PacketTypeClasses.Client.STEER_VEHICLE, STEER_VEHICLE);
|
||||
packetIds.put(PacketTypeClasses.Client.RECIPE_DISPLAYED, RECIPE_DISPLAYED);
|
||||
packetIds.put(PacketTypeClasses.Client.ITEM_NAME, ITEM_NAME);
|
||||
packetIds.put(PacketTypeClasses.Client.RESOURCE_PACK_STATUS, RESOURCE_PACK_STATUS);
|
||||
packetIds.put(PacketTypeClasses.Client.ADVANCEMENTS, ADVANCEMENTS);
|
||||
packetIds.put(PacketTypeClasses.Client.TR_SEL, TR_SEL);
|
||||
packetIds.put(PacketTypeClasses.Client.BEACON, BEACON);
|
||||
packetIds.put(PacketTypeClasses.Client.HELD_ITEM_SLOT, HELD_ITEM_SLOT);
|
||||
packetIds.put(PacketTypeClasses.Client.SET_COMMAND_BLOCK, SET_COMMAND_BLOCK);
|
||||
packetIds.put(PacketTypeClasses.Client.SET_COMMAND_MINECART, SET_COMMAND_MINECART);
|
||||
packetIds.put(PacketTypeClasses.Client.SET_CREATIVE_SLOT, SET_CREATIVE_SLOT);
|
||||
packetIds.put(PacketTypeClasses.Client.SET_JIGSAW, SET_JIGSAW);
|
||||
packetIds.put(PacketTypeClasses.Client.STRUCT, STRUCT);
|
||||
packetIds.put(PacketTypeClasses.Client.UPDATE_SIGN, UPDATE_SIGN);
|
||||
packetIds.put(PacketTypeClasses.Client.ARM_ANIMATION, ARM_ANIMATION);
|
||||
packetIds.put(PacketTypeClasses.Client.SPECTATE, SPECTATE);
|
||||
packetIds.put(PacketTypeClasses.Client.USE_ITEM, USE_ITEM);
|
||||
packetIds.put(PacketTypeClasses.Client.BLOCK_PLACE, BLOCK_PLACE);
|
||||
}
|
||||
|
||||
public static class Util {
|
||||
/**
|
||||
* Is the packet an instance of the PacketPlayInFlying packet?
|
||||
*
|
||||
* @param packetID
|
||||
* @return packetID == FLYING or POSITION or POSITION_LOOK or LOOK
|
||||
*/
|
||||
public static boolean isInstanceOfFlying(final byte packetID) {
|
||||
return packetID == FLYING
|
||||
|| packetID == POSITION
|
||||
|| packetID == POSITION_LOOK
|
||||
|| packetID == LOOK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class Server {
|
||||
public static final Map<Class<?>, Byte> packetIds = new HashMap<>();
|
||||
public static final byte SPAWN_ENTITY = 0, SPAWN_ENTITY_EXPERIENCE_ORB = 1, SPAWN_ENTITY_WEATHER = 2, SPAWN_ENTITY_LIVING = 3,
|
||||
SPAWN_ENTITY_PAINTING = 4, SPAWN_ENTITY_SPAWN = 5, ANIMATION = 6, STATISTIC = 7,
|
||||
BLOCK_BREAK = 8, BLOCK_BREAK_ANIMATION = 9, TILE_ENTITY_DATA = 10, BLOCK_ACTION = 11,
|
||||
BLOCK_CHANGE = 12, BOSS = 13, SERVER_DIFFICULTY = 14, CHAT = 15, MULTI_BLOCK_CHANGE = 16,
|
||||
TAB_COMPLETE = 17, COMMANDS = 18, TRANSACTION = 19, CLOSE_WINDOW = 20,
|
||||
WINDOW_ITEMS = 21, WINDOW_DATA = 22, SET_SLOT = 23, SET_COOLDOWN = 24,
|
||||
CUSTOM_PAYLOAD = 25, CUSTOM_SOUND_EFFECT = 26, KICK_DISCONNECT = 27, ENTITY_STATUS = 28,
|
||||
EXPLOSION = 29, UNLOAD_CHUNK = 30, GAME_STATE_CHANGE = 31, OPEN_WINDOW_HORSE = 32,
|
||||
KEEP_ALIVE = 33, MAP_CHUNK = 34, WORLD_EVENT = 35, WORLD_PARTICLES = 36,
|
||||
LIGHT_UPDATE = 37, LOGIN = 38, MAP = 39, OPEN_WINDOW_MERCHANT = 40,
|
||||
REL_ENTITY_MOVE = 41, REL_ENTITY_MOVE_LOOK = 42, ENTITY_LOOK = 43, ENTITY = 44,
|
||||
VEHICLE_MOVE = 45, OPEN_BOOK = 46, OPEN_WINDOW = 47, OPEN_SIGN_EDITOR = 48,
|
||||
AUTO_RECIPE = 49, ABILITIES = 50, COMBAT_EVENT = 51, PLAYER_INFO = 52,
|
||||
LOOK_AT = 53, POSITION = 54, RECIPES = 55, ENTITY_DESTROY = 56,
|
||||
REMOVE_ENTITY_EFFECT = 57, RESOURCE_PACK_SEND = 58, RESPAWN = 59, ENTITY_HEAD_ROTATION = 60,
|
||||
SELECT_ADVANCEMENT_TAB = 61, WORLD_BORDER = 62, CAMERA = 63, HELD_ITEM_SLOT = 64,
|
||||
VIEW_CENTRE = 65, VIEW_DISTANCE = 66, SCOREBOARD_DISPLAY_OBJECTIVE = 67, ENTITY_METADATA = 68,
|
||||
ATTACH_ENTITY = 69, ENTITY_VELOCITY = 70, ENTITY_EQUIPMENT = 71, EXPERIENCE = 72,
|
||||
UPDATE_HEALTH = 73, SCOREBOARD_OBJECTIVE = 74, MOUNT = 75, SCOREBOARD_TEAM = 76,
|
||||
SCOREBOARD_SCORE = 77, SPAWN_POSITION = 78, UPDATE_TIME = 79, TITLE = 80,
|
||||
ENTITY_SOUND = 81, NAMED_SOUND_EFFECT = 82, STOP_SOUND = 83, PLAYER_LIST_HEADER_FOOTER = 84,
|
||||
NBT_QUERY = 85, COLLECT = 86, ENTITY_TELEPORT = 87, ADVANCEMENTS = 88, UPDATE_ATTRIBUTES = 89,
|
||||
ENTITY_EFFECT = 90, RECIPE_UPDATE = 91, TAGS = 92, MAP_CHUNK_BULK = 93;
|
||||
|
||||
public static void init() {
|
||||
packetIds.put(PacketTypeClasses.Server.SPAWN_ENTITY, SPAWN_ENTITY);
|
||||
packetIds.put(PacketTypeClasses.Server.SPAWN_ENTITY_EXPERIENCE_ORB, SPAWN_ENTITY_EXPERIENCE_ORB);
|
||||
packetIds.put(PacketTypeClasses.Server.SPAWN_ENTITY_WEATHER, SPAWN_ENTITY_WEATHER);
|
||||
packetIds.put(PacketTypeClasses.Server.SPAWN_ENTITY_LIVING, SPAWN_ENTITY_LIVING);
|
||||
packetIds.put(PacketTypeClasses.Server.SPAWN_ENTITY_PAINTING, SPAWN_ENTITY_PAINTING);
|
||||
packetIds.put(PacketTypeClasses.Server.SPAWN_ENTITY_SPAWN, SPAWN_ENTITY_SPAWN);
|
||||
packetIds.put(PacketTypeClasses.Server.ANIMATION, ANIMATION);
|
||||
packetIds.put(PacketTypeClasses.Server.STATISTIC, STATISTIC);
|
||||
packetIds.put(PacketTypeClasses.Server.BLOCK_BREAK, BLOCK_BREAK);
|
||||
packetIds.put(PacketTypeClasses.Server.BLOCK_BREAK_ANIMATION, BLOCK_BREAK_ANIMATION);
|
||||
packetIds.put(PacketTypeClasses.Server.TILE_ENTITY_DATA, TILE_ENTITY_DATA);
|
||||
packetIds.put(PacketTypeClasses.Server.BLOCK_ACTION, BLOCK_ACTION);
|
||||
packetIds.put(PacketTypeClasses.Server.BLOCK_CHANGE, BLOCK_CHANGE);
|
||||
packetIds.put(PacketTypeClasses.Server.BOSS, BOSS);
|
||||
packetIds.put(PacketTypeClasses.Server.SPAWN_ENTITY, SPAWN_ENTITY);
|
||||
packetIds.put(PacketTypeClasses.Server.SERVER_DIFFICULTY, SERVER_DIFFICULTY);
|
||||
packetIds.put(PacketTypeClasses.Server.CHAT, CHAT);
|
||||
packetIds.put(PacketTypeClasses.Server.MULTI_BLOCK_CHANGE, MULTI_BLOCK_CHANGE);
|
||||
packetIds.put(PacketTypeClasses.Server.TAB_COMPLETE, TAB_COMPLETE);
|
||||
packetIds.put(PacketTypeClasses.Server.COMMANDS, COMMANDS);
|
||||
packetIds.put(PacketTypeClasses.Server.TRANSACTION, TRANSACTION);
|
||||
packetIds.put(PacketTypeClasses.Server.CLOSE_WINDOW, CLOSE_WINDOW);
|
||||
packetIds.put(PacketTypeClasses.Server.WINDOW_ITEMS, WINDOW_ITEMS);
|
||||
packetIds.put(PacketTypeClasses.Server.WINDOW_DATA, WINDOW_DATA);
|
||||
packetIds.put(PacketTypeClasses.Server.SET_SLOT, SET_SLOT);
|
||||
packetIds.put(PacketTypeClasses.Server.SET_COOLDOWN, SET_COOLDOWN);
|
||||
packetIds.put(PacketTypeClasses.Server.CUSTOM_PAYLOAD, CUSTOM_PAYLOAD);
|
||||
packetIds.put(PacketTypeClasses.Server.CUSTOM_SOUND_EFFECT, CUSTOM_SOUND_EFFECT);
|
||||
packetIds.put(PacketTypeClasses.Server.KICK_DISCONNECT, KICK_DISCONNECT);
|
||||
packetIds.put(PacketTypeClasses.Server.ENTITY_STATUS, ENTITY_STATUS);
|
||||
packetIds.put(PacketTypeClasses.Server.EXPLOSION, EXPLOSION);
|
||||
packetIds.put(PacketTypeClasses.Server.UNLOAD_CHUNK, UNLOAD_CHUNK);
|
||||
packetIds.put(PacketTypeClasses.Server.GAME_STATE_CHANGE, GAME_STATE_CHANGE);
|
||||
packetIds.put(PacketTypeClasses.Server.OPEN_WINDOW_HORSE, OPEN_WINDOW_HORSE);
|
||||
packetIds.put(PacketTypeClasses.Server.KEEP_ALIVE, KEEP_ALIVE);
|
||||
packetIds.put(PacketTypeClasses.Server.MAP_CHUNK, MAP_CHUNK);
|
||||
packetIds.put(PacketTypeClasses.Server.WORLD_EVENT, WORLD_EVENT);
|
||||
packetIds.put(PacketTypeClasses.Server.WORLD_EVENT, SPAWN_ENTITY);
|
||||
packetIds.put(PacketTypeClasses.Server.WORLD_PARTICLES, WORLD_PARTICLES);
|
||||
packetIds.put(PacketTypeClasses.Server.LIGHT_UPDATE, LIGHT_UPDATE);
|
||||
packetIds.put(PacketTypeClasses.Server.LOGIN, LOGIN);
|
||||
packetIds.put(PacketTypeClasses.Server.MAP, MAP);
|
||||
packetIds.put(PacketTypeClasses.Server.OPEN_WINDOW_MERCHANT, OPEN_WINDOW_MERCHANT);
|
||||
packetIds.put(PacketTypeClasses.Server.REL_ENTITY_MOVE, REL_ENTITY_MOVE);
|
||||
packetIds.put(PacketTypeClasses.Server.REL_ENTITY_MOVE_LOOK, REL_ENTITY_MOVE_LOOK);
|
||||
packetIds.put(PacketTypeClasses.Server.ENTITY_LOOK, ENTITY_LOOK);
|
||||
packetIds.put(PacketTypeClasses.Server.ENTITY, ENTITY);
|
||||
packetIds.put(PacketTypeClasses.Server.VEHICLE_MOVE, VEHICLE_MOVE);
|
||||
packetIds.put(PacketTypeClasses.Server.OPEN_BOOK, OPEN_BOOK);
|
||||
packetIds.put(PacketTypeClasses.Server.OPEN_WINDOW, OPEN_WINDOW);
|
||||
packetIds.put(PacketTypeClasses.Server.OPEN_SIGN_EDITOR, OPEN_SIGN_EDITOR);
|
||||
packetIds.put(PacketTypeClasses.Server.AUTO_RECIPE, AUTO_RECIPE);
|
||||
packetIds.put(PacketTypeClasses.Server.ABILITIES, ABILITIES);
|
||||
packetIds.put(PacketTypeClasses.Server.COMBAT_EVENT, COMBAT_EVENT);
|
||||
packetIds.put(PacketTypeClasses.Server.PLAYER_INFO, PLAYER_INFO);
|
||||
packetIds.put(PacketTypeClasses.Server.LOOK_AT, LOOK_AT);
|
||||
packetIds.put(PacketTypeClasses.Server.POSITION, POSITION);
|
||||
packetIds.put(PacketTypeClasses.Server.RECIPES, RECIPES);
|
||||
packetIds.put(PacketTypeClasses.Server.ENTITY_DESTROY, ENTITY_DESTROY);
|
||||
packetIds.put(PacketTypeClasses.Server.REMOVE_ENTITY_EFFECT, REMOVE_ENTITY_EFFECT);
|
||||
packetIds.put(PacketTypeClasses.Server.RESOURCE_PACK_SEND, RESOURCE_PACK_SEND);
|
||||
packetIds.put(PacketTypeClasses.Server.RESPAWN, RESPAWN);
|
||||
packetIds.put(PacketTypeClasses.Server.ENTITY_HEAD_ROTATION, ENTITY_HEAD_ROTATION);
|
||||
packetIds.put(PacketTypeClasses.Server.SELECT_ADVANCEMENT_TAB, SELECT_ADVANCEMENT_TAB);
|
||||
packetIds.put(PacketTypeClasses.Server.WORLD_BORDER, WORLD_BORDER);
|
||||
packetIds.put(PacketTypeClasses.Server.CAMERA, CAMERA);
|
||||
packetIds.put(PacketTypeClasses.Server.HELD_ITEM_SLOT, HELD_ITEM_SLOT);
|
||||
packetIds.put(PacketTypeClasses.Server.VIEW_CENTRE, VIEW_CENTRE);
|
||||
packetIds.put(PacketTypeClasses.Server.VIEW_DISTANCE, VIEW_DISTANCE);
|
||||
packetIds.put(PacketTypeClasses.Server.SCOREBOARD_DISPLAY_OBJECTIVE, SCOREBOARD_DISPLAY_OBJECTIVE);
|
||||
packetIds.put(PacketTypeClasses.Server.ENTITY_METADATA, ENTITY_METADATA);
|
||||
packetIds.put(PacketTypeClasses.Server.ATTACH_ENTITY, ATTACH_ENTITY);
|
||||
packetIds.put(PacketTypeClasses.Server.ENTITY_VELOCITY, ENTITY_VELOCITY);
|
||||
packetIds.put(PacketTypeClasses.Server.ENTITY_EQUIPMENT, ENTITY_EQUIPMENT);
|
||||
packetIds.put(PacketTypeClasses.Server.EXPERIENCE, EXPERIENCE);
|
||||
packetIds.put(PacketTypeClasses.Server.UPDATE_HEALTH, UPDATE_HEALTH);
|
||||
packetIds.put(PacketTypeClasses.Server.SCOREBOARD_OBJECTIVE, SCOREBOARD_OBJECTIVE);
|
||||
packetIds.put(PacketTypeClasses.Server.MOUNT, MOUNT);
|
||||
packetIds.put(PacketTypeClasses.Server.SCOREBOARD_TEAM, SCOREBOARD_TEAM);
|
||||
packetIds.put(PacketTypeClasses.Server.SCOREBOARD_SCORE, SCOREBOARD_SCORE);
|
||||
packetIds.put(PacketTypeClasses.Server.SPAWN_POSITION, SPAWN_POSITION);
|
||||
packetIds.put(PacketTypeClasses.Server.UPDATE_TIME, UPDATE_TIME);
|
||||
packetIds.put(PacketTypeClasses.Server.TITLE, TITLE);
|
||||
packetIds.put(PacketTypeClasses.Server.ENTITY_SOUND, ENTITY_SOUND);
|
||||
packetIds.put(PacketTypeClasses.Server.NAMED_SOUND_EFFECT, NAMED_SOUND_EFFECT);
|
||||
packetIds.put(PacketTypeClasses.Server.STOP_SOUND, STOP_SOUND);
|
||||
packetIds.put(PacketTypeClasses.Server.PLAYER_LIST_HEADER_FOOTER, PLAYER_LIST_HEADER_FOOTER);
|
||||
packetIds.put(PacketTypeClasses.Server.NBT_QUERY, NBT_QUERY);
|
||||
packetIds.put(PacketTypeClasses.Server.COLLECT, COLLECT);
|
||||
packetIds.put(PacketTypeClasses.Server.ENTITY_TELEPORT, ENTITY_TELEPORT);
|
||||
packetIds.put(PacketTypeClasses.Server.ADVANCEMENTS, ADVANCEMENTS);
|
||||
packetIds.put(PacketTypeClasses.Server.UPDATE_ATTRIBUTES, UPDATE_ATTRIBUTES);
|
||||
packetIds.put(PacketTypeClasses.Server.ENTITY_EFFECT, ENTITY_EFFECT);
|
||||
packetIds.put(PacketTypeClasses.Server.RECIPE_UPDATE, RECIPE_UPDATE);
|
||||
packetIds.put(PacketTypeClasses.Server.TAGS, TAGS);
|
||||
packetIds.put(PacketTypeClasses.Server.MAP_CHUNK_BULK, MAP_CHUNK_BULK);
|
||||
}
|
||||
|
||||
public static class Util {
|
||||
/**
|
||||
* Is the packet an instance of the PacketPlayOutEntity packet?
|
||||
*
|
||||
* @param packetID
|
||||
* @return packetID == ENTITY or REL_ENTITY_MOVE or REL_ENTITY_MOVE_LOOK or ENTITY_LOOK
|
||||
*/
|
||||
public static boolean isInstanceOfEntity(final byte packetID) {
|
||||
return packetID == ENTITY || packetID == REL_ENTITY_MOVE ||
|
||||
packetID == REL_ENTITY_MOVE_LOOK || packetID == ENTITY_LOOK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,285 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packettype;
|
||||
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
|
||||
|
||||
public class PacketTypeClasses {
|
||||
public static class Status {
|
||||
public static Class<?> IN_START, PING, PONG, SERVER_INFO;
|
||||
|
||||
public static void load() {
|
||||
IN_START = NMSUtils.getNMSClassWithoutException("PacketStatusInStart");
|
||||
PING = NMSUtils.getNMSClassWithoutException("PacketStatusInPing");
|
||||
PONG = NMSUtils.getNMSClassWithoutException("PacketStatusOutPong");
|
||||
SERVER_INFO = NMSUtils.getNMSClassWithoutException("PacketStatusOutServerInfo");
|
||||
PacketType.Status.init();
|
||||
}
|
||||
}
|
||||
public static class Login {
|
||||
public static Class<?> HANDSHAKE,
|
||||
IN_CUSTOM_PAYLOAD, OUT_CUSTOM_PAYLOAD,IN_START, IN_ENCRYPTION_BEGIN,
|
||||
DISCONNECT, OUT_ENCRYPTION_BEGIN, OUT_SUCCESS;
|
||||
|
||||
public static void load() {
|
||||
HANDSHAKE = NMSUtils.getNMSClassWithoutException("PacketHandshakingInSetProtocol");
|
||||
//In and Out custom payload login packets have been here since AROUND 1.13.2.
|
||||
IN_CUSTOM_PAYLOAD = NMSUtils.getNMSClassWithoutException("PacketLoginInCustomPayload");
|
||||
OUT_CUSTOM_PAYLOAD = NMSUtils.getNMSClassWithoutException("PacketLoginOutCustomPayload");
|
||||
IN_START = NMSUtils.getNMSClassWithoutException("PacketLoginInStart");
|
||||
IN_ENCRYPTION_BEGIN = NMSUtils.getNMSClassWithoutException("PacketLoginInEncryptionBegin");
|
||||
DISCONNECT = NMSUtils.getNMSClassWithoutException("PacketLoginOutDisconnect");
|
||||
OUT_ENCRYPTION_BEGIN = NMSUtils.getNMSClassWithoutException("PacketLoginOutEncryptionBegin");
|
||||
OUT_SUCCESS = NMSUtils.getNMSClassWithoutException("PacketLoginOutSuccess");
|
||||
PacketType.Login.init();
|
||||
}
|
||||
}
|
||||
|
||||
public static class Client {
|
||||
private static final String c = "PacketPlayIn";
|
||||
public static Class<?> FLYING, POSITION, POSITION_LOOK, LOOK, CLIENT_COMMAND,
|
||||
TRANSACTION, BLOCK_DIG, ENTITY_ACTION, USE_ENTITY,
|
||||
WINDOW_CLICK, STEER_VEHICLE, CUSTOM_PAYLOAD, ARM_ANIMATION,
|
||||
BLOCK_PLACE, USE_ITEM, ABILITIES, HELD_ITEM_SLOT,
|
||||
CLOSE_WINDOW, TAB_COMPLETE, CHAT, SET_CREATIVE_SLOT,
|
||||
KEEP_ALIVE, SETTINGS, ENCHANT_ITEM, TELEPORT_ACCEPT,
|
||||
TILE_NBT_QUERY, DIFFICULTY_CHANGE, B_EDIT, ENTITY_NBT_QUERY,
|
||||
JIGSAW_GENERATE, DIFFICULTY_LOCK, VEHICLE_MOVE, BOAT_MOVE, PICK_ITEM,
|
||||
AUTO_RECIPE, RECIPE_DISPLAYED, ITEM_NAME, RESOURCE_PACK_STATUS,
|
||||
ADVANCEMENTS, TR_SEL, BEACON, SET_COMMAND_BLOCK,
|
||||
SET_COMMAND_MINECART, SET_JIGSAW, STRUCT, UPDATE_SIGN, SPECTATE;
|
||||
|
||||
/**
|
||||
* Initiate all server-bound packet classes.
|
||||
*/
|
||||
public static void load() {
|
||||
FLYING = NMSUtils.getNMSClassWithoutException(c + "Flying");
|
||||
try {
|
||||
POSITION = NMSUtils.getNMSClass(c + "Position");
|
||||
POSITION_LOOK = NMSUtils.getNMSClass(c + "PositionLook");
|
||||
LOOK = NMSUtils.getNMSClass(c + "Look");
|
||||
} catch (ClassNotFoundException e) {
|
||||
POSITION = SubclassUtil.getSubClass(FLYING, c + "Position");
|
||||
POSITION_LOOK = SubclassUtil.getSubClass(FLYING, c + "PositionLook");
|
||||
LOOK = SubclassUtil.getSubClass(FLYING, c + "Look");
|
||||
}
|
||||
|
||||
try {
|
||||
SETTINGS = NMSUtils.getNMSClass(c + "Settings");
|
||||
ENCHANT_ITEM = NMSUtils.getNMSClass(c + "EnchantItem");
|
||||
|
||||
CLIENT_COMMAND = NMSUtils.getNMSClass(c + "ClientCommand");
|
||||
TRANSACTION = NMSUtils.getNMSClass(c + "Transaction");
|
||||
BLOCK_DIG = NMSUtils.getNMSClass(c + "BlockDig");
|
||||
ENTITY_ACTION = NMSUtils.getNMSClass(c + "EntityAction");
|
||||
USE_ENTITY = NMSUtils.getNMSClass(c + "UseEntity");
|
||||
WINDOW_CLICK = NMSUtils.getNMSClass(c + "WindowClick");
|
||||
STEER_VEHICLE = NMSUtils.getNMSClass(c + "SteerVehicle");
|
||||
CUSTOM_PAYLOAD = NMSUtils.getNMSClass(c + "CustomPayload");
|
||||
ARM_ANIMATION = NMSUtils.getNMSClass(c + "ArmAnimation");
|
||||
ABILITIES = NMSUtils.getNMSClass(c + "Abilities");
|
||||
HELD_ITEM_SLOT = NMSUtils.getNMSClass(c + "HeldItemSlot");
|
||||
CLOSE_WINDOW = NMSUtils.getNMSClass(c + "CloseWindow");
|
||||
TAB_COMPLETE = NMSUtils.getNMSClass(c + "TabComplete");
|
||||
CHAT = NMSUtils.getNMSClass(c + "Chat");
|
||||
SET_CREATIVE_SLOT = NMSUtils.getNMSClass(c + "SetCreativeSlot");
|
||||
KEEP_ALIVE = NMSUtils.getNMSClass(c + "KeepAlive");
|
||||
UPDATE_SIGN = NMSUtils.getNMSClassWithoutException(c + "UpdateSign");
|
||||
|
||||
TELEPORT_ACCEPT = NMSUtils.getNMSClassWithoutException(c + "TeleportAccept");
|
||||
TILE_NBT_QUERY = NMSUtils.getNMSClassWithoutException(c + "TileNBTQuery");
|
||||
DIFFICULTY_CHANGE = NMSUtils.getNMSClassWithoutException(c + "DifficultyChange");
|
||||
B_EDIT = NMSUtils.getNMSClassWithoutException(c + "BEdit");
|
||||
ENTITY_NBT_QUERY = NMSUtils.getNMSClassWithoutException(c + "EntityNBTQuery");
|
||||
JIGSAW_GENERATE = NMSUtils.getNMSClassWithoutException(c + "JigsawGenerate");
|
||||
DIFFICULTY_LOCK = NMSUtils.getNMSClassWithoutException(c + "DifficultyLock");
|
||||
VEHICLE_MOVE = NMSUtils.getNMSClassWithoutException(c + "VehicleMove");
|
||||
BOAT_MOVE = NMSUtils.getNMSClassWithoutException(c + "BoatMove");
|
||||
PICK_ITEM = NMSUtils.getNMSClassWithoutException(c + "PickItem");
|
||||
AUTO_RECIPE = NMSUtils.getNMSClassWithoutException(c + "AutoRecipe");
|
||||
RECIPE_DISPLAYED = NMSUtils.getNMSClassWithoutException(c + "RecipeDisplayed");
|
||||
ITEM_NAME = NMSUtils.getNMSClassWithoutException(c + "ItemName");
|
||||
//1.8+
|
||||
RESOURCE_PACK_STATUS = NMSUtils.getNMSClassWithoutException(c + "ResourcePackStatus");
|
||||
|
||||
ADVANCEMENTS = NMSUtils.getNMSClassWithoutException(c + "Advancements");
|
||||
TR_SEL = NMSUtils.getNMSClassWithoutException(c + "TrSel");
|
||||
BEACON = NMSUtils.getNMSClassWithoutException(c + "Beacon");
|
||||
SET_COMMAND_BLOCK = NMSUtils.getNMSClassWithoutException(c + "SetCommandBlock");
|
||||
SET_COMMAND_MINECART = NMSUtils.getNMSClassWithoutException(c + "SetCommandMinecart");
|
||||
SET_JIGSAW = NMSUtils.getNMSClassWithoutException(c + "SetJigsaw");
|
||||
STRUCT = NMSUtils.getNMSClassWithoutException(c + "Struct");
|
||||
SPECTATE = NMSUtils.getNMSClassWithoutException(c + "Spectate");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
BLOCK_PLACE = NMSUtils.getNMSClass(c + "BlockPlace");
|
||||
USE_ITEM = NMSUtils.getNMSClass(c + "UseItem");
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
|
||||
}
|
||||
|
||||
PacketType.Client.init();
|
||||
}
|
||||
}
|
||||
|
||||
public static class Server {
|
||||
private static final String s = "PacketPlayOut";
|
||||
public static Class<?> SPAWN_ENTITY, SPAWN_ENTITY_EXPERIENCE_ORB, SPAWN_ENTITY_WEATHER, SPAWN_ENTITY_LIVING,
|
||||
SPAWN_ENTITY_PAINTING, SPAWN_ENTITY_SPAWN, ANIMATION, STATISTIC,
|
||||
BLOCK_BREAK, BLOCK_BREAK_ANIMATION, TILE_ENTITY_DATA, BLOCK_ACTION,
|
||||
BLOCK_CHANGE, BOSS, SERVER_DIFFICULTY, CHAT, MULTI_BLOCK_CHANGE,
|
||||
TAB_COMPLETE, COMMANDS, TRANSACTION, CLOSE_WINDOW,
|
||||
WINDOW_ITEMS, WINDOW_DATA, SET_SLOT, SET_COOLDOWN,
|
||||
CUSTOM_PAYLOAD, CUSTOM_SOUND_EFFECT, KICK_DISCONNECT, ENTITY_STATUS,
|
||||
EXPLOSION, UNLOAD_CHUNK, GAME_STATE_CHANGE, OPEN_WINDOW_HORSE,
|
||||
KEEP_ALIVE, MAP_CHUNK, WORLD_EVENT, WORLD_PARTICLES,
|
||||
LIGHT_UPDATE, LOGIN, MAP, OPEN_WINDOW_MERCHANT,
|
||||
REL_ENTITY_MOVE, REL_ENTITY_MOVE_LOOK, ENTITY_LOOK, ENTITY,
|
||||
VEHICLE_MOVE, OPEN_BOOK, OPEN_WINDOW, OPEN_SIGN_EDITOR,
|
||||
AUTO_RECIPE, ABILITIES, COMBAT_EVENT, PLAYER_INFO,
|
||||
LOOK_AT, POSITION, RECIPES, ENTITY_DESTROY,
|
||||
REMOVE_ENTITY_EFFECT, RESOURCE_PACK_SEND, RESPAWN, ENTITY_HEAD_ROTATION,
|
||||
SELECT_ADVANCEMENT_TAB, WORLD_BORDER, CAMERA, HELD_ITEM_SLOT,
|
||||
VIEW_CENTRE, VIEW_DISTANCE, SCOREBOARD_DISPLAY_OBJECTIVE, ENTITY_METADATA,
|
||||
ATTACH_ENTITY, ENTITY_VELOCITY, ENTITY_EQUIPMENT, EXPERIENCE,
|
||||
UPDATE_HEALTH, SCOREBOARD_OBJECTIVE, MOUNT, SCOREBOARD_TEAM,
|
||||
SCOREBOARD_SCORE, SPAWN_POSITION, UPDATE_TIME, TITLE,
|
||||
ENTITY_SOUND, NAMED_SOUND_EFFECT, STOP_SOUND, PLAYER_LIST_HEADER_FOOTER,
|
||||
NBT_QUERY, COLLECT, ENTITY_TELEPORT, ADVANCEMENTS, UPDATE_ATTRIBUTES,
|
||||
ENTITY_EFFECT, RECIPE_UPDATE, TAGS, MAP_CHUNK_BULK;
|
||||
|
||||
/**
|
||||
* Initiate all client-bound packet classes.
|
||||
*/
|
||||
public static void load() {
|
||||
SPAWN_ENTITY = NMSUtils.getNMSClassWithoutException(s + "SpawnEntity");
|
||||
SPAWN_ENTITY_EXPERIENCE_ORB = NMSUtils.getNMSClassWithoutException(s + "SpawnEntityExperienceOrb");
|
||||
SPAWN_ENTITY_WEATHER = NMSUtils.getNMSClassWithoutException(s + "SpawnEntityWeather");
|
||||
SPAWN_ENTITY_LIVING = NMSUtils.getNMSClassWithoutException(s + "SpawnEntityLiving");
|
||||
SPAWN_ENTITY_PAINTING = NMSUtils.getNMSClassWithoutException(s + "SpawnEntityPainting");
|
||||
SPAWN_ENTITY_SPAWN = NMSUtils.getNMSClassWithoutException(s + "SpawnEntitySpawn");
|
||||
ANIMATION = NMSUtils.getNMSClassWithoutException(s + "Animation");
|
||||
STATISTIC = NMSUtils.getNMSClassWithoutException(s + "Statistic");
|
||||
BLOCK_BREAK = NMSUtils.getNMSClassWithoutException(s + "BlockBreak");
|
||||
BLOCK_BREAK_ANIMATION = NMSUtils.getNMSClassWithoutException(s + "BlockBreakAnimation");
|
||||
TILE_ENTITY_DATA = NMSUtils.getNMSClassWithoutException(s + "TileEntityData");
|
||||
BLOCK_ACTION = NMSUtils.getNMSClassWithoutException(s + "BlockAction");
|
||||
BLOCK_CHANGE = NMSUtils.getNMSClassWithoutException(s + "BlockChange");
|
||||
BOSS = NMSUtils.getNMSClassWithoutException(s + "Boss");
|
||||
SERVER_DIFFICULTY = NMSUtils.getNMSClassWithoutException(s + "ServerDifficulty");
|
||||
CHAT = NMSUtils.getNMSClassWithoutException(s + "Chat");
|
||||
MULTI_BLOCK_CHANGE = NMSUtils.getNMSClassWithoutException(s + "MultiBlockChange");
|
||||
TAB_COMPLETE = NMSUtils.getNMSClassWithoutException(s + "TabComplete");
|
||||
COMMANDS = NMSUtils.getNMSClassWithoutException(s + "Commands");
|
||||
TRANSACTION = NMSUtils.getNMSClassWithoutException(s + "Transaction");
|
||||
CLOSE_WINDOW = NMSUtils.getNMSClassWithoutException(s + "CloseWindow");
|
||||
WINDOW_ITEMS = NMSUtils.getNMSClassWithoutException(s + "WindowItems");
|
||||
WINDOW_DATA = NMSUtils.getNMSClassWithoutException(s + "WindowData");
|
||||
SET_SLOT = NMSUtils.getNMSClassWithoutException(s + "SetSlot");
|
||||
SET_COOLDOWN = NMSUtils.getNMSClassWithoutException(s + "SetCooldown");
|
||||
CUSTOM_PAYLOAD = NMSUtils.getNMSClassWithoutException(s + "CustomPayload");
|
||||
CUSTOM_SOUND_EFFECT = NMSUtils.getNMSClassWithoutException(s + "CustomSoundEffect");
|
||||
KICK_DISCONNECT = NMSUtils.getNMSClassWithoutException(s + "KickDisconnect");
|
||||
ENTITY_STATUS = NMSUtils.getNMSClassWithoutException(s + "EntityStatus");
|
||||
EXPLOSION = NMSUtils.getNMSClassWithoutException(s + "Explosion");
|
||||
UNLOAD_CHUNK = NMSUtils.getNMSClassWithoutException(s + "UnloadChunk");
|
||||
GAME_STATE_CHANGE = NMSUtils.getNMSClassWithoutException(s + "GameStateChange");
|
||||
OPEN_WINDOW_HORSE = NMSUtils.getNMSClassWithoutException(s + "OpenWindowHorse");
|
||||
KEEP_ALIVE = NMSUtils.getNMSClassWithoutException(s + "KeepAlive");
|
||||
MAP_CHUNK = NMSUtils.getNMSClassWithoutException(s + "MapChunk");
|
||||
WORLD_EVENT = NMSUtils.getNMSClassWithoutException(s + "WorldEvent");
|
||||
WORLD_PARTICLES = NMSUtils.getNMSClassWithoutException(s + "WorldParticles");
|
||||
LIGHT_UPDATE = NMSUtils.getNMSClassWithoutException(s + "LightUpdate");
|
||||
LOGIN = NMSUtils.getNMSClassWithoutException(s + "Login");
|
||||
MAP = NMSUtils.getNMSClassWithoutException(s + "Map");
|
||||
OPEN_WINDOW_MERCHANT = NMSUtils.getNMSClassWithoutException(s + "OpenWindowMerchant");
|
||||
ENTITY = NMSUtils.getNMSClassWithoutException(s + "Entity");
|
||||
REL_ENTITY_MOVE = SubclassUtil.getSubClass(ENTITY, s + "RelEntityMove");
|
||||
REL_ENTITY_MOVE_LOOK = SubclassUtil.getSubClass(ENTITY, s + "RelEntityMoveLook");
|
||||
ENTITY_LOOK = SubclassUtil.getSubClass(ENTITY, s + "EntityLook");
|
||||
if (REL_ENTITY_MOVE == null) {
|
||||
//is not a subclass and should be accessed normally
|
||||
REL_ENTITY_MOVE = NMSUtils.getNMSClassWithoutException(s + "RelEntityMove");
|
||||
REL_ENTITY_MOVE_LOOK = NMSUtils.getNMSClassWithoutException(s + "RelEntityMoveLook");
|
||||
ENTITY_LOOK = NMSUtils.getNMSClassWithoutException(s + "RelEntityLook");
|
||||
}
|
||||
VEHICLE_MOVE = NMSUtils.getNMSClassWithoutException(s + "VehicleMove");
|
||||
OPEN_BOOK = NMSUtils.getNMSClassWithoutException(s + "OpenBook");
|
||||
OPEN_WINDOW = NMSUtils.getNMSClassWithoutException(s + "OpenWindow");
|
||||
OPEN_SIGN_EDITOR = NMSUtils.getNMSClassWithoutException(s + "OpenSignEditor");
|
||||
AUTO_RECIPE = NMSUtils.getNMSClassWithoutException(s + "AutoRecipe");
|
||||
ABILITIES = NMSUtils.getNMSClassWithoutException(s + "Abilities");
|
||||
COMBAT_EVENT = NMSUtils.getNMSClassWithoutException(s + "CombatEvent");
|
||||
PLAYER_INFO = NMSUtils.getNMSClassWithoutException(s + "PlayerInfo");
|
||||
LOOK_AT = NMSUtils.getNMSClassWithoutException(s + "LookAt");
|
||||
POSITION = NMSUtils.getNMSClassWithoutException(s + "Position");
|
||||
RECIPES = NMSUtils.getNMSClassWithoutException(s + "Recipes");
|
||||
ENTITY_DESTROY = NMSUtils.getNMSClassWithoutException(s + "EntityDestroy");
|
||||
REMOVE_ENTITY_EFFECT = NMSUtils.getNMSClassWithoutException(s + "RemoveEntityEffect");
|
||||
RESOURCE_PACK_SEND = NMSUtils.getNMSClassWithoutException(s + "ResourcePackSend");
|
||||
RESPAWN = NMSUtils.getNMSClassWithoutException(s + "Respawn");
|
||||
ENTITY_HEAD_ROTATION = NMSUtils.getNMSClassWithoutException(s + "EntityHeadRotation");
|
||||
SELECT_ADVANCEMENT_TAB = NMSUtils.getNMSClassWithoutException(s + "SelectAdvancementTab");
|
||||
WORLD_BORDER = NMSUtils.getNMSClassWithoutException(s + "WorldBorder");
|
||||
CAMERA = NMSUtils.getNMSClassWithoutException(s + "Camera");
|
||||
HELD_ITEM_SLOT = NMSUtils.getNMSClassWithoutException(s + "HeldItemSlot");
|
||||
VIEW_CENTRE = NMSUtils.getNMSClassWithoutException(s + "ViewCentre");
|
||||
VIEW_DISTANCE = NMSUtils.getNMSClassWithoutException(s + "ViewDistance");
|
||||
SCOREBOARD_DISPLAY_OBJECTIVE = NMSUtils.getNMSClassWithoutException(s + "ScoreboardDisplayObjective");
|
||||
ENTITY_METADATA = NMSUtils.getNMSClassWithoutException(s + "EntityMetadata");
|
||||
ATTACH_ENTITY = NMSUtils.getNMSClassWithoutException(s + "AttachEntity");
|
||||
ENTITY_VELOCITY = NMSUtils.getNMSClassWithoutException(s + "EntityVelocity");
|
||||
ENTITY_EQUIPMENT = NMSUtils.getNMSClassWithoutException(s + "EntityEquipment");
|
||||
EXPERIENCE = NMSUtils.getNMSClassWithoutException(s + "Experience");
|
||||
UPDATE_HEALTH = NMSUtils.getNMSClassWithoutException(s + "UpdateHealth");
|
||||
SCOREBOARD_OBJECTIVE = NMSUtils.getNMSClassWithoutException(s + "ScoreboardObjective");
|
||||
MOUNT = NMSUtils.getNMSClassWithoutException(s + "Mount");
|
||||
SCOREBOARD_TEAM = NMSUtils.getNMSClassWithoutException(s + "ScoreboardTeam");
|
||||
SCOREBOARD_SCORE = NMSUtils.getNMSClassWithoutException(s + "ScoreboardScore");
|
||||
SPAWN_POSITION = NMSUtils.getNMSClassWithoutException(s + "SpawnPosition");
|
||||
UPDATE_TIME = NMSUtils.getNMSClassWithoutException(s + "UpdateTime");
|
||||
TITLE = NMSUtils.getNMSClassWithoutException(s + "Title");
|
||||
ENTITY_SOUND = NMSUtils.getNMSClassWithoutException(s + "EntitySound");
|
||||
NAMED_SOUND_EFFECT = NMSUtils.getNMSClassWithoutException(s + "NamedSoundEffect");
|
||||
STOP_SOUND = NMSUtils.getNMSClassWithoutException(s + "StopSound");
|
||||
PLAYER_LIST_HEADER_FOOTER = NMSUtils.getNMSClassWithoutException(s + "PlayerListHeaderFooter");
|
||||
NBT_QUERY = NMSUtils.getNMSClassWithoutException(s + "NBTQuery");
|
||||
COLLECT = NMSUtils.getNMSClassWithoutException(s + "Collect");
|
||||
ENTITY_TELEPORT = NMSUtils.getNMSClassWithoutException(s + "EntityTeleport");
|
||||
ADVANCEMENTS = NMSUtils.getNMSClassWithoutException(s + "Advancements");
|
||||
UPDATE_ATTRIBUTES = NMSUtils.getNMSClassWithoutException(s + "UpdateAttributes");
|
||||
ENTITY_EFFECT = NMSUtils.getNMSClassWithoutException(s + "EntityEffect");
|
||||
RECIPE_UPDATE = NMSUtils.getNMSClassWithoutException(s + "RecipeUpdate");
|
||||
TAGS = NMSUtils.getNMSClassWithoutException(s + "Tags");
|
||||
MAP_CHUNK_BULK = NMSUtils.getNMSClassWithoutException(s + "MapChunkBulk");
|
||||
PacketType.Server.init();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers;
|
||||
|
||||
/**
|
||||
* This interface indicates that a packet wrapper supports being sent to a client.
|
||||
*/
|
||||
public interface SendableWrapper {
|
||||
Object asNMSPacket();
|
||||
}
|
||||
@@ -0,0 +1,644 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers;
|
||||
|
||||
import io.github.retrooper.packetevents.exceptions.WrapperFieldNotFoundException;
|
||||
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.in.blockdig.WrappedPacketInBlockDig;
|
||||
import io.github.retrooper.packetevents.packetwrappers.in.blockplace.WrappedPacketInBlockPlace;
|
||||
import io.github.retrooper.packetevents.packetwrappers.in.clientcommand.WrappedPacketInClientCommand;
|
||||
import io.github.retrooper.packetevents.packetwrappers.in.custompayload.WrappedPacketInCustomPayload;
|
||||
import io.github.retrooper.packetevents.packetwrappers.in.entityaction.WrappedPacketInEntityAction;
|
||||
import io.github.retrooper.packetevents.packetwrappers.in.keepalive.WrappedPacketInKeepAlive;
|
||||
import io.github.retrooper.packetevents.packetwrappers.in.settings.WrappedPacketInSettings;
|
||||
import io.github.retrooper.packetevents.packetwrappers.in.updatesign.WrappedPacketInUpdateSign;
|
||||
import io.github.retrooper.packetevents.packetwrappers.in.useentity.WrappedPacketInUseEntity;
|
||||
import io.github.retrooper.packetevents.packetwrappers.in.windowclick.WrappedPacketInWindowClick;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.abilities.WrappedPacketOutAbilities;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.animation.WrappedPacketOutAnimation;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.chat.WrappedPacketOutChat;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.custompayload.WrappedPacketOutCustomPayload;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.entity.WrappedPacketOutEntity;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.entitystatus.WrappedPacketOutEntityStatus;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.entityteleport.WrappedPacketOutEntityTeleport;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.entityvelocity.WrappedPacketOutEntityVelocity;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.experience.WrappedPacketOutExperience;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.explosion.WrappedPacketOutExplosion;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.gamestatechange.WrappedPacketOutGameStateChange;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.helditemslot.WrappedPacketOutHeldItemSlot;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.keepalive.WrappedPacketOutKeepAlive;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.kickdisconnect.WrappedPacketOutKickDisconnect;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.position.WrappedPacketOutPosition;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.transaction.WrappedPacketOutTransaction;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.updatehealth.WrappedPacketOutUpdateHealth;
|
||||
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class WrappedPacket implements WrapperPacketReader, WrapperPacketWriter {
|
||||
private static final Map<Class<?>, Map<Class<?>, Field[]>> fieldCache = new HashMap<>();
|
||||
public static ServerVersion version;
|
||||
protected Object packet;
|
||||
private Class<?> packetClass;
|
||||
|
||||
public WrappedPacket() {
|
||||
|
||||
}
|
||||
|
||||
public WrappedPacket(final Object packet) {
|
||||
this(packet, packet.getClass());
|
||||
}
|
||||
|
||||
public WrappedPacket(final Object packet, Class<?> packetClass) {
|
||||
if (packet.getClass().getSuperclass().equals(PacketTypeClasses.Client.FLYING)) {
|
||||
packetClass = PacketTypeClasses.Client.FLYING;
|
||||
} else if (packet.getClass().getSuperclass().equals(PacketTypeClasses.Server.ENTITY)) {
|
||||
packetClass = PacketTypeClasses.Server.ENTITY;
|
||||
}
|
||||
this.packetClass = packetClass;
|
||||
|
||||
|
||||
if (!fieldCache.containsKey(packetClass)) {
|
||||
final Field[] declaredFields = packetClass.getDeclaredFields();
|
||||
for (Field f : declaredFields) {
|
||||
f.setAccessible(true);
|
||||
}
|
||||
List<Field> boolFields = getFields(boolean.class, declaredFields);
|
||||
List<Field> byteFields = getFields(byte.class, declaredFields);
|
||||
List<Field> shortFields = getFields(short.class, declaredFields);
|
||||
List<Field> intFields = getFields(int.class, declaredFields);
|
||||
;
|
||||
List<Field> longFields = getFields(long.class, declaredFields);
|
||||
;
|
||||
List<Field> floatFields = getFields(float.class, declaredFields);
|
||||
;
|
||||
List<Field> doubleFields = getFields(double.class, declaredFields);
|
||||
;
|
||||
List<Field> stringFields = getFields(String.class, declaredFields);
|
||||
;
|
||||
|
||||
List<Field> boolArrayFields = getFields(boolean[].class, declaredFields);
|
||||
;
|
||||
List<Field> byteArrayFields = getFields(byte[].class, declaredFields);
|
||||
;
|
||||
List<Field> shortArrayFields = getFields(short[].class, declaredFields);
|
||||
;
|
||||
List<Field> intArrayFields = getFields(int[].class, declaredFields);
|
||||
;
|
||||
List<Field> longArrayFields = getFields(long[].class, declaredFields);
|
||||
;
|
||||
List<Field> floatArrayFields = getFields(float[].class, declaredFields);
|
||||
;
|
||||
List<Field> doubleArrayFields = getFields(double[].class, declaredFields);
|
||||
;
|
||||
List<Field> stringArrayFields = getFields(String[].class, declaredFields);
|
||||
;
|
||||
|
||||
Field[] tmp = new Field[0];
|
||||
|
||||
Map<Class<?>, Field[]> map = new HashMap<>();
|
||||
if (boolFields != null) {
|
||||
map.put(boolean.class, boolFields.toArray(tmp));
|
||||
}
|
||||
|
||||
if (byteFields != null) {
|
||||
map.put(byte.class, byteFields.toArray(tmp));
|
||||
}
|
||||
|
||||
if (shortFields != null) {
|
||||
map.put(short.class, shortFields.toArray(tmp));
|
||||
}
|
||||
|
||||
if (intFields != null) {
|
||||
map.put(int.class, intFields.toArray(tmp));
|
||||
}
|
||||
|
||||
if (longFields != null) {
|
||||
map.put(long.class, longFields.toArray(tmp));
|
||||
}
|
||||
|
||||
if (floatFields != null) {
|
||||
map.put(float.class, floatFields.toArray(tmp));
|
||||
}
|
||||
|
||||
if (doubleFields != null) {
|
||||
map.put(double.class, doubleFields.toArray(tmp));
|
||||
}
|
||||
|
||||
if (stringFields != null) {
|
||||
map.put(String.class, stringFields.toArray(tmp));
|
||||
}
|
||||
|
||||
if (boolArrayFields != null) {
|
||||
map.put(boolean[].class, boolArrayFields.toArray(tmp));
|
||||
}
|
||||
|
||||
if (byteArrayFields != null) {
|
||||
map.put(byte[].class, byteArrayFields.toArray(tmp));
|
||||
}
|
||||
|
||||
if (shortArrayFields != null) {
|
||||
map.put(short[].class, shortArrayFields.toArray(tmp));
|
||||
}
|
||||
|
||||
if (intArrayFields != null) {
|
||||
map.put(int[].class, intArrayFields.toArray(tmp));
|
||||
}
|
||||
|
||||
if (longArrayFields != null) {
|
||||
map.put(long[].class, longArrayFields.toArray(tmp));
|
||||
}
|
||||
|
||||
if (floatArrayFields != null) {
|
||||
map.put(float[].class, floatArrayFields.toArray(tmp));
|
||||
}
|
||||
|
||||
if (doubleArrayFields != null) {
|
||||
map.put(double[].class, doubleArrayFields.toArray(tmp));
|
||||
}
|
||||
|
||||
if (stringArrayFields != null) {
|
||||
map.put(String[].class, stringArrayFields.toArray(tmp));
|
||||
}
|
||||
fieldCache.put(packetClass, map);
|
||||
}
|
||||
this.packet = packet;
|
||||
setup();
|
||||
}
|
||||
|
||||
public static void loadAllWrappers() {
|
||||
//SERVER BOUND
|
||||
WrappedPacketInBlockDig.load();
|
||||
WrappedPacketInBlockPlace.load();
|
||||
WrappedPacketInClientCommand.load();
|
||||
WrappedPacketInCustomPayload.load();
|
||||
WrappedPacketInEntityAction.load();
|
||||
WrappedPacketInKeepAlive.load();
|
||||
WrappedPacketInSettings.load();
|
||||
WrappedPacketInUseEntity.load();
|
||||
WrappedPacketInUpdateSign.load();
|
||||
WrappedPacketInWindowClick.load();
|
||||
|
||||
//CLIENTBOUND
|
||||
WrappedPacketOutAbilities.load();
|
||||
WrappedPacketOutAnimation.load();
|
||||
WrappedPacketOutChat.load();
|
||||
WrappedPacketOutEntity.load();
|
||||
WrappedPacketOutEntityVelocity.load();
|
||||
WrappedPacketOutEntityTeleport.load();
|
||||
WrappedPacketOutKeepAlive.load();
|
||||
WrappedPacketOutKickDisconnect.load();
|
||||
WrappedPacketOutPosition.load();
|
||||
WrappedPacketOutTransaction.load();
|
||||
WrappedPacketOutUpdateHealth.load();
|
||||
WrappedPacketOutGameStateChange.load();
|
||||
WrappedPacketOutCustomPayload.load();
|
||||
WrappedPacketOutExplosion.load();
|
||||
WrappedPacketOutEntityStatus.load();
|
||||
WrappedPacketOutExperience.load();
|
||||
WrappedPacketOutHeldItemSlot.load();
|
||||
}
|
||||
|
||||
protected void setup() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean readBoolean(int index) {
|
||||
return (boolean) read(boolean.class, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte readByte(int index) {
|
||||
return (byte) read(byte.class, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public short readShort(int index) {
|
||||
return (short) read(short.class, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readInt(int index) {
|
||||
return (int) read(int.class, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long readLong(int index) {
|
||||
return (long) read(long.class, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float readFloat(int index) {
|
||||
return (float) read(float.class, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double readDouble(int index) {
|
||||
return (double) read(double.class, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean[] readBooleanArray(int index) {
|
||||
Map<Class<?>, Field[]> cached = fieldCache.get(packetClass);
|
||||
if (cached != null) {
|
||||
try {
|
||||
return (boolean[]) cached.get(boolean[].class)[index].get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
int currentIndex = 0;
|
||||
for (Field f : packetClass.getDeclaredFields()) {
|
||||
f.setAccessible(true);
|
||||
if (boolean[].class.isAssignableFrom(f.getType())) {
|
||||
if (index == currentIndex++) {
|
||||
try {
|
||||
return (boolean[]) f.get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new WrapperFieldNotFoundException(packetClass, boolean[].class, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] readByteArray(int index) {
|
||||
Map<Class<?>, Field[]> cached = fieldCache.get(packetClass);
|
||||
if (cached != null) {
|
||||
try {
|
||||
return (byte[]) cached.get(byte[].class)[index].get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
int currentIndex = 0;
|
||||
for (Field f : packetClass.getDeclaredFields()) {
|
||||
f.setAccessible(true);
|
||||
if (byte[].class.isAssignableFrom(f.getType())) {
|
||||
if (index == currentIndex++) {
|
||||
try {
|
||||
return (byte[]) f.get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new WrapperFieldNotFoundException(packetClass, byte[].class, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public short[] readShortArray(int index) {
|
||||
Map<Class<?>, Field[]> cached = fieldCache.get(packetClass);
|
||||
if (cached != null) {
|
||||
try {
|
||||
return (short[]) cached.get(short[].class)[index].get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
int currentIndex = 0;
|
||||
for (Field f : packetClass.getDeclaredFields()) {
|
||||
f.setAccessible(true);
|
||||
if (short[].class.isAssignableFrom(f.getType())) {
|
||||
if (index == currentIndex++) {
|
||||
try {
|
||||
return (short[]) f.get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new WrapperFieldNotFoundException(packetClass, short[].class, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] readIntArray(int index) {
|
||||
Map<Class<?>, Field[]> cached = fieldCache.get(packetClass);
|
||||
if (cached != null) {
|
||||
try {
|
||||
return (int[]) cached.get(int[].class)[index].get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
int currentIndex = 0;
|
||||
for (Field f : packetClass.getDeclaredFields()) {
|
||||
f.setAccessible(true);
|
||||
if (int[].class.isAssignableFrom(f.getType())) {
|
||||
if (index == currentIndex++) {
|
||||
try {
|
||||
return (int[]) f.get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new WrapperFieldNotFoundException(packetClass, int[].class, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long[] readLongArray(int index) {
|
||||
Map<Class<?>, Field[]> cached = fieldCache.get(packetClass);
|
||||
if (cached != null) {
|
||||
try {
|
||||
return (long[]) cached.get(long[].class)[index].get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
int currentIndex = 0;
|
||||
for (Field f : packetClass.getDeclaredFields()) {
|
||||
f.setAccessible(true);
|
||||
if (long[].class.isAssignableFrom(f.getType())) {
|
||||
if (index == currentIndex++) {
|
||||
try {
|
||||
return (long[]) f.get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new WrapperFieldNotFoundException(packetClass, long[].class, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float[] readFloatArray(int index) {
|
||||
Map<Class<?>, Field[]> cached = fieldCache.get(packetClass);
|
||||
if (cached != null) {
|
||||
try {
|
||||
return (float[]) cached.get(float[].class)[index].get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
int currentIndex = 0;
|
||||
for (Field f : packetClass.getDeclaredFields()) {
|
||||
f.setAccessible(true);
|
||||
if (float.class.isAssignableFrom(f.getType())) {
|
||||
if (index == currentIndex++) {
|
||||
try {
|
||||
return (float[]) f.get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new WrapperFieldNotFoundException(packetClass, float[].class, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] readDoubleArray(int index) {
|
||||
Map<Class<?>, Field[]> cached = fieldCache.get(packetClass);
|
||||
if (cached != null) {
|
||||
try {
|
||||
return (double[]) cached.get(double[].class)[index].get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
int currentIndex = 0;
|
||||
for (Field f : packetClass.getDeclaredFields()) {
|
||||
f.setAccessible(true);
|
||||
if (double[].class.isAssignableFrom(f.getType())) {
|
||||
if (index == currentIndex++) {
|
||||
try {
|
||||
return (double[]) f.get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new WrapperFieldNotFoundException(packetClass, double[].class, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] readStringArray(int index) {
|
||||
Map<Class<?>, Field[]> cached = fieldCache.get(packetClass);
|
||||
if (cached != null) {
|
||||
try {
|
||||
Object[] array = (Object[]) cached.get(String[].class)[index].get(packet);
|
||||
int len = array.length;
|
||||
String[] stringArray = new String[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
stringArray[i] = array[i].toString();
|
||||
}
|
||||
return stringArray;
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
throw new WrapperFieldNotFoundException(packetClass, String[].class, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readString(int index) {
|
||||
return (String) read(String.class, index);
|
||||
}
|
||||
|
||||
public Object readAnyObject(int index) {
|
||||
try {
|
||||
Field f = packetClass.getDeclaredFields()[index];
|
||||
if (!f.isAccessible()) {
|
||||
f.setAccessible(true);
|
||||
}
|
||||
try {
|
||||
return f.get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
throw new WrapperFieldNotFoundException("PacketEvents failed to find any field indexed " + index + " in the " + ClassUtil.getClassSimpleName(packetClass) + " class!");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object readObject(int index, Class<?> type) {
|
||||
Map<Class<?>, Field[]> cached = fieldCache.get(packetClass);
|
||||
if (cached != null) {
|
||||
if (!cached.containsKey(type)) {
|
||||
List<Field> typeFields = new ArrayList<>();
|
||||
for (Field f : packetClass.getDeclaredFields()) {
|
||||
f.setAccessible(true);
|
||||
if (f.getType().equals(type)) {
|
||||
typeFields.add(f);
|
||||
}
|
||||
}
|
||||
if (!typeFields.isEmpty()) {
|
||||
cached.put(type, typeFields.toArray(new Field[0]));
|
||||
}
|
||||
}
|
||||
try {
|
||||
return cached.get(type)[index].get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
throw new WrapperFieldNotFoundException(packetClass, type, index);
|
||||
}
|
||||
|
||||
public Object[] readObjectArray(int index, Class<?> type) {
|
||||
if (type.equals(String.class)) {
|
||||
return readStringArray(index);
|
||||
}
|
||||
try {
|
||||
return (Object[]) readObject(index, getArrayClass(type));
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new IllegalStateException("PacketEvents failed to find the array class of type " + type.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBoolean(int index, boolean value) {
|
||||
write(boolean.class, index, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeByte(int index, byte value) {
|
||||
write(byte.class, index, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeShort(int index, short value) {
|
||||
write(short.class, index, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeInt(int index, int value) {
|
||||
write(int.class, index, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeLong(int index, long value) {
|
||||
write(long.class, index, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeFloat(int index, float value) {
|
||||
write(float.class, index, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDouble(int index, double value) {
|
||||
write(double.class, index, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeString(int index, String value) {
|
||||
write(String.class, index, value);
|
||||
}
|
||||
|
||||
private void write(Class<?> type, int index, Object value) throws WrapperFieldNotFoundException {
|
||||
Field field = getField(type, index);
|
||||
if (field == null) {
|
||||
throw new WrapperFieldNotFoundException(packetClass, type, index);
|
||||
}
|
||||
try {
|
||||
field.set(packet, value);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private Object read(Class<?> type, int index) throws WrapperFieldNotFoundException {
|
||||
Field field = getField(type, index);
|
||||
if (field == null) {
|
||||
throw new WrapperFieldNotFoundException(packetClass, type, index);
|
||||
}
|
||||
try {
|
||||
return field.get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Field getField(Class<?> type, int index) {
|
||||
Map<Class<?>, Field[]> cached = fieldCache.get(packetClass);
|
||||
if (cached == null) {
|
||||
return null;
|
||||
}
|
||||
Field[] fields = cached.get(type);
|
||||
if (fields != null) {
|
||||
return fields[index];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<Field> getFields(Class<?> type, Field[] fields) {
|
||||
List<Field> ret = null;
|
||||
for (Field field : fields) {
|
||||
if (field.getType() == type) {
|
||||
if (ret == null) {
|
||||
ret = new ArrayList<>();
|
||||
}
|
||||
ret.add(field);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private Class<?> getArrayClass(Class<?> componentType) throws ClassNotFoundException {
|
||||
ClassLoader classLoader = componentType.getClassLoader();
|
||||
String name;
|
||||
if (componentType.isArray()) {
|
||||
// just add a leading "["
|
||||
name = "[" + componentType.getName();
|
||||
} else if (componentType == boolean.class) {
|
||||
name = "[Z";
|
||||
} else if (componentType == byte.class) {
|
||||
name = "[B";
|
||||
} else if (componentType == char.class) {
|
||||
name = "[C";
|
||||
} else if (componentType == double.class) {
|
||||
name = "[D";
|
||||
} else if (componentType == float.class) {
|
||||
name = "[F";
|
||||
} else if (componentType == int.class) {
|
||||
name = "[I";
|
||||
} else if (componentType == long.class) {
|
||||
name = "[J";
|
||||
} else if (componentType == short.class) {
|
||||
name = "[S";
|
||||
} else {
|
||||
// must be an object non-array class
|
||||
name = "[L" + componentType.getName() + ";";
|
||||
}
|
||||
return classLoader != null ? classLoader.loadClass(name) : Class.forName(name);
|
||||
}
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers;
|
||||
|
||||
public interface WrapperPacketReader {
|
||||
|
||||
boolean readBoolean(int index);
|
||||
|
||||
byte readByte(int index);
|
||||
|
||||
short readShort(int index);
|
||||
|
||||
int readInt(int index);
|
||||
|
||||
long readLong(int index);
|
||||
|
||||
float readFloat(int index);
|
||||
|
||||
double readDouble(int index);
|
||||
|
||||
boolean[] readBooleanArray(int index);
|
||||
|
||||
byte[] readByteArray(int index);
|
||||
|
||||
short[] readShortArray(int index);
|
||||
|
||||
int[] readIntArray(int index);
|
||||
|
||||
long[] readLongArray(int index);
|
||||
|
||||
float[] readFloatArray(int index);
|
||||
|
||||
double[] readDoubleArray(int index);
|
||||
|
||||
String[] readStringArray(int index);
|
||||
|
||||
String readString(int index);
|
||||
|
||||
Object readObject(int index, Class<?> type);
|
||||
|
||||
Object readAnyObject(int index);
|
||||
|
||||
Object[] readObjectArray(int index, Class<?> type);
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers;
|
||||
|
||||
public interface WrapperPacketWriter {
|
||||
|
||||
// TODO write for the arrays
|
||||
void writeBoolean(int index, boolean value);
|
||||
|
||||
void writeByte(int index, byte value);
|
||||
|
||||
void writeShort(int index, short value);
|
||||
|
||||
void writeInt(int index, int value);
|
||||
|
||||
void writeLong(int index, long value);
|
||||
|
||||
void writeFloat(int index, float value);
|
||||
|
||||
void writeDouble(int index, double value);
|
||||
|
||||
void writeString(int index, String value);
|
||||
}
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.abilities;
|
||||
|
||||
import io.github.retrooper.packetevents.annotations.NotNull;
|
||||
import io.github.retrooper.packetevents.annotations.Nullable;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
|
||||
public final class WrappedPacketInAbilities extends WrappedPacket {
|
||||
|
||||
public WrappedPacketInAbilities(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
/**
|
||||
* This will return null if the server version is not available in 1.16.x and above
|
||||
*
|
||||
* @return Whether the player is vulnerable to damage or not.
|
||||
*/
|
||||
@Deprecated
|
||||
@Nullable
|
||||
public boolean isVulnerable() {
|
||||
return readBoolean(0);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public boolean isFlying() {
|
||||
return readBoolean(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* This will return null if the server version is not available in 1.16.x and above
|
||||
*
|
||||
* @return Whether or not the player can fly.
|
||||
*/
|
||||
@Deprecated
|
||||
@Nullable
|
||||
public boolean isFlightAllowed() {
|
||||
return readBoolean(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* This will return null if the server version is not available in 1.16.x and above
|
||||
*
|
||||
* @return Whether or not the player can break blocks instantly.
|
||||
*/
|
||||
@Deprecated
|
||||
@Nullable
|
||||
public boolean canInstantlyBuild() {
|
||||
return readBoolean(3);
|
||||
}
|
||||
|
||||
/**
|
||||
* This will return null if the server version is not available in 1.16.x and above
|
||||
*
|
||||
* @return The speed at which the player can fly, as a float.
|
||||
*/
|
||||
@Deprecated
|
||||
@Nullable
|
||||
public float getFlySpeed() {
|
||||
return readFloat(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* This will return null if the server version is not available in 1.16.x and above
|
||||
*
|
||||
* @return The speed at which the player can walk, as a float.
|
||||
*/
|
||||
@Deprecated
|
||||
@Nullable
|
||||
public float getWalkSpeed() {
|
||||
return readFloat(1);
|
||||
}
|
||||
}
|
||||
+172
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.blockdig;
|
||||
|
||||
import io.github.retrooper.packetevents.enums.Direction;
|
||||
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public final class WrappedPacketInBlockDig extends WrappedPacket {
|
||||
private static Class<?> blockDigClass, blockPositionClass, enumDirectionClass, digTypeClass;
|
||||
private static boolean isVersionLowerThan_v_1_8;
|
||||
private Object blockPosObj;
|
||||
private Object enumDirObj;
|
||||
|
||||
public WrappedPacketInBlockDig(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
blockDigClass = PacketTypeClasses.Client.BLOCK_DIG;
|
||||
try {
|
||||
if (version.isHigherThan(ServerVersion.v_1_7_10)) {
|
||||
blockPositionClass = NMSUtils.getNMSClass("BlockPosition");
|
||||
enumDirectionClass = NMSUtils.getNMSClass("EnumDirection");
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
isVersionLowerThan_v_1_8 = version.isLowerThan(ServerVersion.v_1_8);
|
||||
|
||||
if (version != ServerVersion.v_1_7_10) {
|
||||
try {
|
||||
digTypeClass = NMSUtils.getNMSClass("EnumPlayerDigType");
|
||||
} catch (ClassNotFoundException e) {
|
||||
//It is probably a subclass
|
||||
digTypeClass = SubclassUtil.getSubClass(blockDigClass, "EnumPlayerDigType");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get X position of the block
|
||||
* @return Block Position X
|
||||
*/
|
||||
public int getX() {
|
||||
if(isVersionLowerThan_v_1_8) {
|
||||
return readInt(0);
|
||||
}
|
||||
else {
|
||||
if(blockPosObj == null) {
|
||||
blockPosObj = readObject(0, blockPositionClass);
|
||||
}
|
||||
try {
|
||||
return (int) Reflection.getMethod(blockPosObj.getClass().getSuperclass(), "getX", 0).invoke(blockPosObj);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Y position of the block
|
||||
* @return Block Position Y
|
||||
*/
|
||||
public int getY() {
|
||||
if(isVersionLowerThan_v_1_8) {
|
||||
return readInt(1);
|
||||
}
|
||||
else {
|
||||
if(blockPosObj == null) {
|
||||
blockPosObj = readObject(0, blockPositionClass);
|
||||
}
|
||||
try {
|
||||
return (int) Reflection.getMethod(blockPosObj.getClass().getSuperclass(), "getY", 0).invoke(blockPosObj);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Z position of the block
|
||||
* @return Block Position Z
|
||||
*/
|
||||
public int getZ() {
|
||||
if(isVersionLowerThan_v_1_8) {
|
||||
return readInt(2);
|
||||
}
|
||||
else {
|
||||
if(blockPosObj == null) {
|
||||
blockPosObj = readObject(0, blockPositionClass);
|
||||
}
|
||||
try {
|
||||
return (int) Reflection.getMethod(blockPosObj.getClass().getSuperclass(), "getZ", 0).invoke(blockPosObj);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the direction / Get the face.
|
||||
* @return Direction
|
||||
*/
|
||||
public Direction getDirection() {
|
||||
if(isVersionLowerThan_v_1_8) {
|
||||
return Direction.values()[readInt(3)];
|
||||
}
|
||||
else {
|
||||
if(enumDirObj == null) {
|
||||
enumDirObj = readObject(0, enumDirectionClass);
|
||||
}
|
||||
return Direction.valueOf(((Enum)enumDirObj).name());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the PlayerDigType enum sent in this packet.
|
||||
* @return Dig Type
|
||||
*/
|
||||
public PlayerDigType getDigType() {
|
||||
if(isVersionLowerThan_v_1_8) {
|
||||
return PlayerDigType.values()[readInt(4)];
|
||||
}
|
||||
else {
|
||||
return PlayerDigType.valueOf(((Enum)readObject(0, digTypeClass)).name());
|
||||
}
|
||||
}
|
||||
|
||||
public enum PlayerDigType {
|
||||
START_DESTROY_BLOCK,
|
||||
ABORT_DESTROY_BLOCK,
|
||||
STOP_DESTROY_BLOCK,
|
||||
DROP_ALL_ITEMS,
|
||||
DROP_ITEM,
|
||||
RELEASE_USE_ITEM,
|
||||
SWAP_HELD_ITEMS,
|
||||
SWAP_ITEM_WITH_OFFHAND,
|
||||
WRONG_PACKET
|
||||
}
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.blockplace;
|
||||
|
||||
import io.github.retrooper.packetevents.enums.Direction;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
|
||||
public final class WrappedPacketInBlockPlace extends WrappedPacket {
|
||||
private static boolean isHigherThan_v_1_8_8, isHigherThan_v_1_7_10;
|
||||
|
||||
public WrappedPacketInBlockPlace(final Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
isHigherThan_v_1_8_8 = version.isHigherThan(ServerVersion.v_1_8_8);
|
||||
isHigherThan_v_1_7_10 = version.isHigherThan(ServerVersion.v_1_7_10);
|
||||
if (isHigherThan_v_1_8_8) {
|
||||
WrappedPacketInBlockPlace_1_9.load();
|
||||
}
|
||||
}
|
||||
|
||||
public Direction getDirection() {
|
||||
if(isHigherThan_v_1_8_8) {
|
||||
WrappedPacketInBlockPlace_1_9 blockPlace_1_9 = new WrappedPacketInBlockPlace_1_9(packet);
|
||||
return Direction.valueOf(((Enum)blockPlace_1_9.getEnumDirectionObject()).name());
|
||||
}
|
||||
else if(isHigherThan_v_1_7_10) {
|
||||
WrappedPacketInBlockPlace_1_8 blockPlace_1_8 = new WrappedPacketInBlockPlace_1_8(packet);
|
||||
return Direction.values()[blockPlace_1_8.getFace()];
|
||||
}
|
||||
else {
|
||||
WrappedPacketInBlockPlace_1_7_10 blockPlace_1_7_10 = new WrappedPacketInBlockPlace_1_7_10(packet);
|
||||
return Direction.values()[blockPlace_1_7_10.face];
|
||||
}
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
if (isHigherThan_v_1_8_8) {
|
||||
WrappedPacketInBlockPlace_1_9 blockPlace_1_9 = new WrappedPacketInBlockPlace_1_9(packet);
|
||||
return blockPlace_1_9.getX();
|
||||
} else if (isHigherThan_v_1_7_10) {
|
||||
WrappedPacketInBlockPlace_1_8 blockPlace_1_8 = new WrappedPacketInBlockPlace_1_8(packet);
|
||||
return blockPlace_1_8.getX();
|
||||
} else {
|
||||
WrappedPacketInBlockPlace_1_7_10 blockPlace_1_7_10 = new WrappedPacketInBlockPlace_1_7_10(packet);
|
||||
return blockPlace_1_7_10.x;
|
||||
}
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
if (isHigherThan_v_1_8_8) {
|
||||
WrappedPacketInBlockPlace_1_9 blockPlace_1_9 = new WrappedPacketInBlockPlace_1_9(packet);
|
||||
return blockPlace_1_9.getY();
|
||||
|
||||
} else if (isHigherThan_v_1_7_10) {
|
||||
WrappedPacketInBlockPlace_1_8 blockPlace_1_8 = new WrappedPacketInBlockPlace_1_8(packet);
|
||||
return blockPlace_1_8.getY();
|
||||
} else {
|
||||
WrappedPacketInBlockPlace_1_7_10 blockPlace_1_7_10 = new WrappedPacketInBlockPlace_1_7_10(packet);
|
||||
return blockPlace_1_7_10.y;
|
||||
}
|
||||
}
|
||||
|
||||
public int getZ() {
|
||||
if (isHigherThan_v_1_8_8) {
|
||||
WrappedPacketInBlockPlace_1_9 blockPlace_1_9 = new WrappedPacketInBlockPlace_1_9(packet);
|
||||
return blockPlace_1_9.getZ();
|
||||
} else if (isHigherThan_v_1_7_10) {
|
||||
WrappedPacketInBlockPlace_1_8 blockPlace_1_8 = new WrappedPacketInBlockPlace_1_8(packet);
|
||||
return blockPlace_1_8.getZ();
|
||||
} else {
|
||||
WrappedPacketInBlockPlace_1_7_10 blockPlace_1_7_10 = new WrappedPacketInBlockPlace_1_7_10(packet);
|
||||
return blockPlace_1_7_10.z;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.blockplace;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
final class WrappedPacketInBlockPlace_1_7_10 extends WrappedPacket {
|
||||
public int x, y, z;
|
||||
public ItemStack itemStack;
|
||||
public int face;
|
||||
|
||||
WrappedPacketInBlockPlace_1_7_10(final Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
final net.minecraft.server.v1_7_R4.PacketPlayInBlockPlace blockPlace =
|
||||
(net.minecraft.server.v1_7_R4.PacketPlayInBlockPlace) packet;
|
||||
|
||||
x = blockPlace.c();
|
||||
y = blockPlace.d();
|
||||
z = blockPlace.e();
|
||||
|
||||
this.face = blockPlace.d();
|
||||
|
||||
net.minecraft.server.v1_7_R4.ItemStack stack = blockPlace.getItemStack();
|
||||
this.itemStack = org.bukkit.craftbukkit.v1_7_R4.inventory.CraftItemStack.asBukkitCopy(stack);
|
||||
}
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.blockplace;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
final class WrappedPacketInBlockPlace_1_8 extends WrappedPacket {
|
||||
private Object blockPosObj;
|
||||
|
||||
WrappedPacketInBlockPlace_1_8(final Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
if(blockPosObj == null) {
|
||||
blockPosObj = readObject(0, NMSUtils.blockPosClass);
|
||||
}
|
||||
try {
|
||||
return (int) Reflection.getMethod(blockPosObj.getClass().getSuperclass(), "getX", 0).invoke(blockPosObj);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
if(blockPosObj == null) {
|
||||
blockPosObj = readObject(0, NMSUtils.blockPosClass);
|
||||
}
|
||||
try {
|
||||
return (int) Reflection.getMethod(blockPosObj.getClass().getSuperclass(), "getY", 0).invoke(blockPosObj);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int getZ() {
|
||||
if(blockPosObj == null) {
|
||||
blockPosObj = readObject(0, NMSUtils.blockPosClass);
|
||||
}
|
||||
try {
|
||||
return (int) Reflection.getMethod(blockPosObj.getClass().getSuperclass(), "getZ", 0).invoke(blockPosObj);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public ItemStack getItemStack() {
|
||||
return NMSUtils.toBukkitItemStack(readObject(0, NMSUtils.nmsItemStackClass));
|
||||
}
|
||||
|
||||
public int getFace() {
|
||||
return readInt(0);
|
||||
}
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.blockplace;
|
||||
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
final class WrappedPacketInBlockPlace_1_9 extends WrappedPacket {
|
||||
private Object blockPosObj;
|
||||
private static Class<?> movingObjectPositionBlockClass;
|
||||
|
||||
public static void load() {
|
||||
movingObjectPositionBlockClass = NMSUtils.getNMSClassWithoutException("MovingObjectPositionBlock");
|
||||
}
|
||||
|
||||
public WrappedPacketInBlockPlace_1_9(final Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
if (blockPosObj == null) {
|
||||
if (movingObjectPositionBlockClass == null) {
|
||||
blockPosObj = readObject(0, NMSUtils.blockPosClass);
|
||||
} else {
|
||||
Object movingObjectPos = readObject(0, movingObjectPositionBlockClass);
|
||||
WrappedPacket movingObjectPosWrapper = new WrappedPacket(movingObjectPos);
|
||||
blockPosObj = movingObjectPosWrapper.readObject(0, NMSUtils.blockPosClass);
|
||||
}
|
||||
}
|
||||
try {
|
||||
return (int) Reflection.getMethod(blockPosObj.getClass().getSuperclass(), "getX", 0).invoke(blockPosObj);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
if (blockPosObj == null) {
|
||||
if (movingObjectPositionBlockClass == null) {
|
||||
blockPosObj = readObject(0, NMSUtils.blockPosClass);
|
||||
} else {
|
||||
Object movingObjectPos = readObject(0, movingObjectPositionBlockClass);
|
||||
WrappedPacket movingObjectPosWrapper = new WrappedPacket(movingObjectPos);
|
||||
blockPosObj = movingObjectPosWrapper.readObject(0, NMSUtils.blockPosClass);
|
||||
}
|
||||
}
|
||||
try {
|
||||
return (int) Reflection.getMethod(blockPosObj.getClass().getSuperclass(), "getY", 0).invoke(blockPosObj);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int getZ() {
|
||||
if (blockPosObj == null) {
|
||||
if (movingObjectPositionBlockClass == null) {
|
||||
blockPosObj = readObject(0, NMSUtils.blockPosClass);
|
||||
} else {
|
||||
Object movingObjectPos = readObject(0, movingObjectPositionBlockClass);
|
||||
WrappedPacket movingObjectPosWrapper = new WrappedPacket(movingObjectPos);
|
||||
blockPosObj = movingObjectPosWrapper.readObject(0, NMSUtils.blockPosClass);
|
||||
}
|
||||
}
|
||||
try {
|
||||
return (int) Reflection.getMethod(blockPosObj.getClass().getSuperclass(), "getZ", 0).invoke(blockPosObj);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public Object getEnumDirectionObject() {
|
||||
if (movingObjectPositionBlockClass == null) {
|
||||
return readObject(0, NMSUtils.enumDirectionClass);
|
||||
} else {
|
||||
Object movingObjectPos = readObject(0, movingObjectPositionBlockClass);
|
||||
WrappedPacket movingObjectPosWrapper = new WrappedPacket(movingObjectPos);
|
||||
return movingObjectPosWrapper.readObject(0, NMSUtils.enumDirectionClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.chat;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
|
||||
public final class WrappedPacketInChat extends WrappedPacket {
|
||||
public WrappedPacketInChat(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message.
|
||||
*
|
||||
* @return Chat Message
|
||||
*/
|
||||
public String getMessage() {
|
||||
return readString(0);
|
||||
}
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.clientcommand;
|
||||
|
||||
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
|
||||
|
||||
public final class WrappedPacketInClientCommand extends WrappedPacket {
|
||||
private static Class<?> enumClientCommandClass;
|
||||
private Object enumObj;
|
||||
|
||||
public WrappedPacketInClientCommand(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
Class<?> packetClass = PacketTypeClasses.Client.CLIENT_COMMAND;
|
||||
|
||||
try {
|
||||
enumClientCommandClass = NMSUtils.getNMSClass("EnumClientCommand");
|
||||
} catch (ClassNotFoundException e) {
|
||||
//Probably a subclass
|
||||
enumClientCommandClass = SubclassUtil.getSubClass(packetClass, "EnumClientCommand");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Client Command enum sent in the packet
|
||||
*
|
||||
* @return ClientCommand
|
||||
*/
|
||||
public ClientCommand getClientCommand() {
|
||||
if(enumObj == null) {
|
||||
enumObj = readObject(0, enumClientCommandClass);
|
||||
}
|
||||
return ClientCommand.valueOf(enumObj.toString());
|
||||
}
|
||||
|
||||
public enum ClientCommand {
|
||||
PERFORM_RESPAWN,
|
||||
REQUEST_STATS,
|
||||
OPEN_INVENTORY_ACHIEVEMENT
|
||||
}
|
||||
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.custompayload;
|
||||
|
||||
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.bytebuf.ByteBufUtil;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
|
||||
public final class WrappedPacketInCustomPayload extends WrappedPacket {
|
||||
private static Class<?> nmsMinecraftKey, packetDataSerializerClass, byteBufClass;
|
||||
|
||||
private static boolean strPresent, byteArrayPresent;
|
||||
|
||||
public WrappedPacketInCustomPayload(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
Class<?> packetClass = PacketTypeClasses.Client.CUSTOM_PAYLOAD;
|
||||
strPresent = Reflection.getField(packetClass, String.class, 0) != null;
|
||||
byteArrayPresent = Reflection.getField(packetClass, byte[].class, 0) != null;
|
||||
packetDataSerializerClass = NMSUtils.getNMSClassWithoutException("PacketDataSerializer");
|
||||
try {
|
||||
byteBufClass = NMSUtils.getNettyClass("buffer.ByteBuf");
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
|
||||
}
|
||||
try {
|
||||
//Only on 1.13+
|
||||
nmsMinecraftKey = NMSUtils.getNMSClass("MinecraftKey");
|
||||
} catch (ClassNotFoundException e) {
|
||||
//Its okay, this means they are on versions 1.7.10 - 1.12.2
|
||||
}
|
||||
}
|
||||
|
||||
public String getTag() {
|
||||
if (strPresent) {
|
||||
return readString(0);
|
||||
} else {
|
||||
Object minecraftKey = readObject(0, nmsMinecraftKey);
|
||||
WrappedPacket minecraftKeyWrapper = new WrappedPacket(minecraftKey);
|
||||
return minecraftKeyWrapper.readString(1);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
if (byteArrayPresent) {
|
||||
return readByteArray(0);
|
||||
} else {
|
||||
Object dataSerializer = readObject(0, packetDataSerializerClass);
|
||||
WrappedPacket byteBufWrapper = new WrappedPacket(dataSerializer);
|
||||
|
||||
Object byteBuf = byteBufWrapper.readObject(0, byteBufClass);
|
||||
|
||||
return ByteBufUtil.getBytes(byteBuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.entityaction;
|
||||
|
||||
import io.github.retrooper.packetevents.annotations.Nullable;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public final class WrappedPacketInEntityAction extends WrappedPacket {
|
||||
private static final HashMap<String, PlayerAction> cachedPlayerActionNames = new HashMap<>();
|
||||
private static final HashMap<Integer, PlayerAction> cachedPlayerActionIDs = new HashMap<>();
|
||||
@Nullable
|
||||
private static Class<?> enumPlayerActionClass;
|
||||
private static boolean isLowerThan_v_1_8;
|
||||
private Entity entity;
|
||||
private int entityId = -1;
|
||||
|
||||
public WrappedPacketInEntityAction(final Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
Class<?> entityActionClass = NMSUtils.getNMSClassWithoutException("PacketPlayInEntityAction");
|
||||
isLowerThan_v_1_8 = version.isLowerThan(ServerVersion.v_1_8);
|
||||
if (!isLowerThan_v_1_8) {
|
||||
enumPlayerActionClass = SubclassUtil.getSubClass(entityActionClass, "EnumPlayerAction");
|
||||
}
|
||||
//All the already existing values
|
||||
for (PlayerAction val : PlayerAction.values()) {
|
||||
cachedPlayerActionNames.put(val.name(), val);
|
||||
}
|
||||
|
||||
cachedPlayerActionNames.put("PRESS_SHIFT_KEY", PlayerAction.START_SNEAKING);
|
||||
cachedPlayerActionNames.put("RELEASE_SHIFT_KEY", PlayerAction.STOP_SNEAKING);
|
||||
cachedPlayerActionNames.put("RIDING_JUMP", PlayerAction.START_RIDING_JUMP);
|
||||
|
||||
cachedPlayerActionIDs.put(1, PlayerAction.START_SNEAKING);
|
||||
cachedPlayerActionIDs.put(2, PlayerAction.STOP_SNEAKING);
|
||||
cachedPlayerActionIDs.put(3, PlayerAction.STOP_SLEEPING);
|
||||
cachedPlayerActionIDs.put(4, PlayerAction.START_SPRINTING);
|
||||
cachedPlayerActionIDs.put(5, PlayerAction.STOP_SPRINTING);
|
||||
cachedPlayerActionIDs.put(6, PlayerAction.START_RIDING_JUMP); //riding jump
|
||||
cachedPlayerActionIDs.put(7, PlayerAction.OPEN_INVENTORY); //horse interaction
|
||||
|
||||
}
|
||||
/**
|
||||
* Lookup the associated entity by the ID that was sent in the packet.
|
||||
*
|
||||
* @return Entity
|
||||
*/
|
||||
public Entity getEntity() {
|
||||
if(entity == null) {
|
||||
return entity = NMSUtils.getEntityById(getEntityId());
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID of the entity.
|
||||
* If you do not want to use {@link #getEntity()},
|
||||
* you lookup the entity by yourself with this entity ID.
|
||||
*
|
||||
* @return Entity ID
|
||||
*/
|
||||
public int getEntityId() {
|
||||
if(entityId == -1) {
|
||||
entityId = readInt(0);
|
||||
}
|
||||
return entityId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player action.
|
||||
*
|
||||
* @return Player Action
|
||||
*/
|
||||
public PlayerAction getAction() {
|
||||
if (isLowerThan_v_1_8) {
|
||||
int animationIndex = readInt(1);
|
||||
return cachedPlayerActionIDs.get(animationIndex);
|
||||
} else {
|
||||
final Object enumObj = readObject(0, enumPlayerActionClass);
|
||||
final String enumValueName = enumObj.toString();
|
||||
return cachedPlayerActionNames.get(enumValueName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the jump boost integer.
|
||||
*
|
||||
* @return Jump Boost
|
||||
*/
|
||||
public int getJumpBoost() {
|
||||
if (isLowerThan_v_1_8) {
|
||||
return readInt(2);
|
||||
} else {
|
||||
return readInt(1);
|
||||
}
|
||||
}
|
||||
|
||||
public enum PlayerAction {
|
||||
START_SNEAKING,
|
||||
STOP_SNEAKING,
|
||||
STOP_SLEEPING,
|
||||
START_SPRINTING,
|
||||
STOP_SPRINTING,
|
||||
START_RIDING_JUMP,
|
||||
STOP_RIDING_JUMP,
|
||||
OPEN_INVENTORY,
|
||||
START_FALL_FLYING
|
||||
}
|
||||
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.flying;
|
||||
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
|
||||
public class WrappedPacketInFlying extends WrappedPacket {
|
||||
public WrappedPacketInFlying(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return readDouble(0);
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return readDouble(1);
|
||||
}
|
||||
|
||||
public double getZ() {
|
||||
return readDouble(2);
|
||||
}
|
||||
|
||||
public float getYaw() {
|
||||
return readFloat(0);
|
||||
}
|
||||
|
||||
public float getPitch() {
|
||||
return readFloat(1);
|
||||
}
|
||||
|
||||
public boolean isOnGround() {
|
||||
return readBoolean(0);
|
||||
}
|
||||
|
||||
public final boolean isPosition() {
|
||||
return readBoolean(1);
|
||||
}
|
||||
|
||||
public final boolean isLook() {
|
||||
return readBoolean(2);
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.helditemslot;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
|
||||
public final class WrappedPacketInHeldItemSlot extends WrappedPacket {
|
||||
public WrappedPacketInHeldItemSlot(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index of the item we currently have in hand.
|
||||
* @return Item in hand Index
|
||||
*/
|
||||
public int getCurrentSelectedSlot() {
|
||||
return readInt(0);
|
||||
}
|
||||
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.keepalive;
|
||||
|
||||
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
|
||||
public final class WrappedPacketInKeepAlive extends WrappedPacket {
|
||||
private static boolean integerPresentInIndex0;
|
||||
|
||||
public WrappedPacketInKeepAlive(final Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
Class<?> packetClass = PacketTypeClasses.Client.KEEP_ALIVE;
|
||||
integerPresentInIndex0 = Reflection.getField(packetClass, int.class, 0) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID response from the client.
|
||||
*
|
||||
* You may cast this down to an int if you are on 1.7.10 - 1.12.2.
|
||||
* On 1.13.2 - 1.16.3 a long is sent.
|
||||
* @return response ID
|
||||
*/
|
||||
public long getId() {
|
||||
if(!integerPresentInIndex0) {
|
||||
return readLong(0);
|
||||
}
|
||||
else {
|
||||
return readInt(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
+170
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.settings;
|
||||
|
||||
import io.github.retrooper.packetevents.annotations.Nullable;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class WrappedPacketInSettings extends WrappedPacket {
|
||||
private static Class<?> chatVisibilityEnumClass;
|
||||
|
||||
private static boolean isLowerThan_v_1_8;
|
||||
private Object chatVisibilityEnumObj;
|
||||
private HashMap<DisplayedSkinPart, Boolean> displayedSkinParts = new HashMap<>();
|
||||
|
||||
public WrappedPacketInSettings(final Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
|
||||
isLowerThan_v_1_8 = version.isLowerThan(ServerVersion.v_1_8);
|
||||
|
||||
try {
|
||||
chatVisibilityEnumClass = NMSUtils.getNMSClass("EnumChatVisibility");
|
||||
} catch (ClassNotFoundException e) {
|
||||
Class<?> entityHumanClass = NMSUtils.getNMSClassWithoutException("EntityHuman");
|
||||
//They are just on an outdated version
|
||||
assert entityHumanClass != null;
|
||||
chatVisibilityEnumClass = SubclassUtil.getSubClass(entityHumanClass, "EnumChatVisibility");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get language client setting
|
||||
*
|
||||
* @return String Locale
|
||||
*/
|
||||
public String getLocale() {
|
||||
return readString(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get client view distance.
|
||||
*
|
||||
* @return View Distance
|
||||
*/
|
||||
public int getViewDistance() {
|
||||
return readInt(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Chat Visibility
|
||||
*
|
||||
* @return Chat Visibility
|
||||
*/
|
||||
public ChatVisibility getChatVisibility() {
|
||||
if (chatVisibilityEnumObj == null) {
|
||||
chatVisibilityEnumObj = readObject(0, chatVisibilityEnumClass);
|
||||
}
|
||||
String enumValueAsString = chatVisibilityEnumObj.toString();
|
||||
if (enumValueAsString.equals("FULL")) {
|
||||
return ChatVisibility.ENABLED;
|
||||
} else if (enumValueAsString.equals("SYSTEM")) {
|
||||
return ChatVisibility.COMMANDS_ONLY;
|
||||
} else {
|
||||
return ChatVisibility.HIDDEN;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is chat colors
|
||||
*
|
||||
* @return Chat Colors
|
||||
*/
|
||||
public boolean isChatColors() {
|
||||
return readBoolean(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Displayed skin parts.
|
||||
* <p>
|
||||
* It is possible for some keys to not exist.
|
||||
* If that is the case, the server version is 1.7.10.
|
||||
* 1.7.10 only sends the cape skin part.
|
||||
*
|
||||
* @return A map with a Skin Parts as a key, and a boolean as a value.
|
||||
*/
|
||||
@Nullable
|
||||
public HashMap<DisplayedSkinPart, Boolean> getDisplayedSkinPartsMap() {
|
||||
if (displayedSkinParts.isEmpty()) {
|
||||
if (isLowerThan_v_1_8) {
|
||||
//in 1.7.10 only the cape display skin part is sent
|
||||
boolean capeEnabled = readBoolean(1);
|
||||
displayedSkinParts.put(DisplayedSkinPart.CAPE, capeEnabled);
|
||||
} else {
|
||||
//in 1.8, all the skin parts are sent
|
||||
int skinPartFlags = readInt(1);
|
||||
displayedSkinParts.put(DisplayedSkinPart.CAPE, (skinPartFlags & 0x01) != 0);
|
||||
displayedSkinParts.put(DisplayedSkinPart.JACKET, (skinPartFlags & 0x02) != 0);
|
||||
displayedSkinParts.put(DisplayedSkinPart.LEFT_SLEEVE, (skinPartFlags & 0x04) != 0);
|
||||
displayedSkinParts.put(DisplayedSkinPart.RIGHT_SLEEVE, (skinPartFlags & 0x08) != 0);
|
||||
displayedSkinParts.put(DisplayedSkinPart.LEFT_PANTS, (skinPartFlags & 0x10) != 0);
|
||||
displayedSkinParts.put(DisplayedSkinPart.RIGHT_PANTS, (skinPartFlags & 0x20) != 0);
|
||||
displayedSkinParts.put(DisplayedSkinPart.HAT, (skinPartFlags & 0x40) != 0);
|
||||
}
|
||||
}
|
||||
return displayedSkinParts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the skin part enabled.
|
||||
* <p>
|
||||
* On 1.7.10, some skin parts will default to 'false' as 1.7.10
|
||||
* only sends the 'cape' skin part.
|
||||
*
|
||||
* @param part The skin part to check the status of.
|
||||
* @return Is the skin part enabled
|
||||
*/
|
||||
public boolean isDisplaySkinPartEnabled(DisplayedSkinPart part) {
|
||||
if(displayedSkinParts.isEmpty()) {
|
||||
displayedSkinParts = getDisplayedSkinPartsMap();
|
||||
}
|
||||
//1.7.10, we will default the other skin parts to return false.
|
||||
if (!displayedSkinParts.containsKey(part)) {
|
||||
return false;
|
||||
}
|
||||
return displayedSkinParts.get(part);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum for the client chat visibility setting
|
||||
*/
|
||||
public enum ChatVisibility {
|
||||
ENABLED, COMMANDS_ONLY, HIDDEN
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum for the client displayed skin parts settings
|
||||
*/
|
||||
public enum DisplayedSkinPart {
|
||||
CAPE, JACKET, LEFT_SLEEVE, RIGHT_SLEEVE, LEFT_PANTS, RIGHT_PANTS, HAT
|
||||
}
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.steervehicle;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
|
||||
public class WrappedPacketInSteerVehicle extends WrappedPacket {
|
||||
public WrappedPacketInSteerVehicle(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the side value.
|
||||
* <p>
|
||||
* If positive, they are moving to the left, if negative, they are moving to the right.
|
||||
*
|
||||
* @return Side Value
|
||||
*/
|
||||
public float getSideValue() {
|
||||
return readFloat(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the forward value.
|
||||
* <p>
|
||||
* If positive, they are moving forward, if negative, they are moving backwards.
|
||||
*
|
||||
* @return Forward Value
|
||||
*/
|
||||
public float getForwardValue() {
|
||||
return readFloat(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is a Jump
|
||||
*
|
||||
* @return Is Jump
|
||||
*/
|
||||
public boolean isJump() {
|
||||
return readBoolean(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is an unmount
|
||||
*
|
||||
* @return Is Unmounting
|
||||
*/
|
||||
public boolean isUnmount() {
|
||||
return readBoolean(1);
|
||||
}
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.transaction;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
|
||||
public final class WrappedPacketInTransaction extends WrappedPacket {
|
||||
public WrappedPacketInTransaction(final Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the window ID.
|
||||
*
|
||||
* @return Window ID
|
||||
*/
|
||||
public int getWindowId() {
|
||||
return readInt(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the action number.
|
||||
*
|
||||
* @return Action number
|
||||
*/
|
||||
public short getActionNumber() {
|
||||
return readShort(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is transaction accepted.
|
||||
*
|
||||
* @return Transaction Accepted
|
||||
*/
|
||||
public boolean isAccepted() {
|
||||
return readBoolean(0);
|
||||
}
|
||||
}
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.updatesign;
|
||||
|
||||
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.chat.WrappedPacketOutChat;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public class WrappedPacketInUpdateSign extends WrappedPacket {
|
||||
private static boolean v_1_7_mode, strArrayMode;
|
||||
private static Class<?> blockPosClass, iChatBaseComponentClass;
|
||||
|
||||
private Object blockPosObj;
|
||||
|
||||
public static void load() {
|
||||
v_1_7_mode = Reflection.getField(PacketTypeClasses.Client.UPDATE_SIGN, int.class, 0) != null;
|
||||
strArrayMode = Reflection.getField(PacketTypeClasses.Client.UPDATE_SIGN, String[].class, 0) != null;
|
||||
|
||||
try {
|
||||
blockPosClass = NMSUtils.getNMSClass("BlockPosition");
|
||||
} catch (ClassNotFoundException e) {
|
||||
if (!v_1_7_mode) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
try {
|
||||
iChatBaseComponentClass = NMSUtils.getNMSClass("IChatBaseComponent");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public WrappedPacketInUpdateSign(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
if (v_1_7_mode) {
|
||||
return readInt(0);
|
||||
} else {
|
||||
if (blockPosObj == null) {
|
||||
blockPosObj = readObject(0, blockPosClass);
|
||||
|
||||
}
|
||||
try {
|
||||
return (int) Reflection.getMethod(blockPosObj.getClass().getSuperclass(), "getX", 0).invoke(blockPosObj);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
if (v_1_7_mode) {
|
||||
return readInt(1);
|
||||
} else {
|
||||
if (blockPosObj == null) {
|
||||
blockPosObj = readObject(0, blockPosClass);
|
||||
|
||||
}
|
||||
try {
|
||||
return (int) Reflection.getMethod(blockPosObj.getClass().getSuperclass(), "getY", 0).invoke(blockPosObj);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public int getZ() {
|
||||
if (v_1_7_mode) {
|
||||
return readInt(2);
|
||||
} else {
|
||||
if (blockPosObj == null) {
|
||||
blockPosObj = readObject(0, blockPosClass);
|
||||
|
||||
}
|
||||
try {
|
||||
return (int) Reflection.getMethod(blockPosObj.getClass().getSuperclass(), "getZ", 0).invoke(blockPosObj);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public String[] getTextLines() {
|
||||
if (strArrayMode) {
|
||||
//1.7.10 and the newest versions use this
|
||||
return readStringArray(0);
|
||||
} else {
|
||||
//1.8 uses this for example
|
||||
Object[] iChatComponents = (Object[]) readAnyObject(1);
|
||||
String[] lines = new String[iChatComponents.length];
|
||||
for (int i = 0; i < iChatComponents.length; i++) {
|
||||
lines[i] = WrappedPacketOutChat.
|
||||
toStringFromIChatBaseComponent(iChatComponents[i]);
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
}
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.useentity;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
public final class WrappedPacketInUseEntity extends WrappedPacket {
|
||||
private static Class<?> enumEntityUseActionClass;
|
||||
private Entity entity;
|
||||
private int entityID = -1;
|
||||
public WrappedPacketInUseEntity(final Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
//System.out.println("USE ENTITY HAS BEEN LOADED BROOOIOII");
|
||||
Class<?> useEntityClass = NMSUtils.getNMSClassWithoutException("PacketPlayInUseEntity");
|
||||
/*if(useEntityClass == null) {
|
||||
System.out.println("failed to init use entity wtfffff");
|
||||
}*/
|
||||
try {
|
||||
enumEntityUseActionClass = NMSUtils.getNMSClass("EnumEntityUseAction");
|
||||
} catch (ClassNotFoundException e) {
|
||||
//That is fine, it is probably a subclass
|
||||
enumEntityUseActionClass = SubclassUtil.getSubClass(useEntityClass, "EnumEntityUseAction");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Lookup the associated entity by the ID that was sent in the packet.
|
||||
* @return Entity
|
||||
*/
|
||||
public Entity getEntity() {
|
||||
if(entity != null) {
|
||||
return entity;
|
||||
}
|
||||
return entity = NMSUtils.getEntityById(getEntityID());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID of the entity.
|
||||
* If you do not want to use {@link #getEntity()},
|
||||
* you lookup the entity by yourself with this entity ID.
|
||||
* @return Entity ID
|
||||
*/
|
||||
public int getEntityID() {
|
||||
if(entityID != -1) {
|
||||
return entityID;
|
||||
}
|
||||
else {
|
||||
return entityID = readInt(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the associated action.
|
||||
* @return Get EntityUseAction
|
||||
*/
|
||||
public EntityUseAction getAction() {
|
||||
final Object useActionEnum = readObject(0, enumEntityUseActionClass);
|
||||
return EntityUseAction.valueOf(useActionEnum.toString());
|
||||
}
|
||||
|
||||
public enum EntityUseAction {
|
||||
INTERACT, INTERACT_AT, ATTACK, INVALID
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.vehiclemove;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
|
||||
public class WrappedPacketInVehicleMove extends WrappedPacket {
|
||||
public WrappedPacketInVehicleMove(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return readDouble(0);
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return readDouble(1);
|
||||
}
|
||||
|
||||
public double getZ() {
|
||||
return readDouble(2);
|
||||
}
|
||||
|
||||
public float getYaw() {
|
||||
return readFloat(0);
|
||||
}
|
||||
|
||||
public float getPitch() {
|
||||
return readFloat(1);
|
||||
}
|
||||
}
|
||||
+222
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.windowclick;
|
||||
|
||||
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class WrappedPacketInWindowClick extends WrappedPacket {
|
||||
private static final HashMap<String, Integer> invClickTypeMapCache = new HashMap<>();
|
||||
private static final HashMap<Integer, ArrayList<WindowClickType>> windowClickTypeCache = new HashMap<>();
|
||||
private static Class<?> invClickTypeClass;
|
||||
private static boolean isClickModePrimitive;
|
||||
// TODO: All the fields below are useless cuz there is never a value assigned to them - change this
|
||||
private int id;
|
||||
private int slot;
|
||||
private int button;
|
||||
private short actionNumber;
|
||||
private int mode;
|
||||
private ItemStack clickedItem;
|
||||
|
||||
public WrappedPacketInWindowClick(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
Class<?> packetClass = PacketTypeClasses.Client.WINDOW_CLICK;
|
||||
invClickTypeClass = NMSUtils.getNMSClassWithoutException("InventoryClickType");
|
||||
|
||||
invClickTypeMapCache.put("PICKUP", 0);
|
||||
invClickTypeMapCache.put("QUICK_MOVE", 1);
|
||||
invClickTypeMapCache.put("SWAP", 2);
|
||||
invClickTypeMapCache.put("CLONE", 3);
|
||||
invClickTypeMapCache.put("THROW", 4);
|
||||
invClickTypeMapCache.put("QUICK_CRAFT", 5);
|
||||
invClickTypeMapCache.put("PICKUP_ALL", 6);
|
||||
|
||||
//MODE 0
|
||||
windowClickTypeCache.put(0, getArrayListOfWindowClickTypes(WindowClickType.LEFT_MOUSE_CLICK,
|
||||
WindowClickType.RIGHT_MOUSE_CLICK));
|
||||
|
||||
//MODE 1
|
||||
windowClickTypeCache.put(1, getArrayListOfWindowClickTypes(WindowClickType.SHIFT_LEFT_MOUSE_CLICK,
|
||||
WindowClickType.SHIFT_RIGHT_MOUSE_CLICK));
|
||||
|
||||
//MODE 2
|
||||
windowClickTypeCache.put(2, getArrayListOfWindowClickTypes(
|
||||
WindowClickType.KEY_NUMBER1,
|
||||
WindowClickType.KEY_NUMBER2,
|
||||
WindowClickType.KEY_NUMBER3,
|
||||
WindowClickType.KEY_NUMBER4,
|
||||
WindowClickType.KEY_NUMBER5,
|
||||
WindowClickType.KEY_NUMBER6,
|
||||
WindowClickType.KEY_NUMBER7,
|
||||
WindowClickType.KEY_NUMBER8,
|
||||
WindowClickType.KEY_NUMBER9));
|
||||
|
||||
//MODE 3
|
||||
windowClickTypeCache.put(3, getArrayListOfWindowClickTypes(WindowClickType.UNKNOWN, WindowClickType.UNKNOWN, WindowClickType.CREATIVE_MIDDLE_CLICK));
|
||||
|
||||
//MODE 4
|
||||
windowClickTypeCache.put(4, getArrayListOfWindowClickTypes(WindowClickType.KEY_DROP,
|
||||
WindowClickType.KEY_DROP_STACK));
|
||||
|
||||
//MODE 5
|
||||
windowClickTypeCache.put(5, getArrayListOfWindowClickTypes(
|
||||
WindowClickType.STARTING_LEFT_MOUSE_DRAG,
|
||||
WindowClickType.ADD_SLOT_LEFT_MOUSE_DRAG,
|
||||
WindowClickType.ENDING_LEFT_MOUSE_DRAG,
|
||||
WindowClickType.UNKNOWN,
|
||||
WindowClickType.STARTING_RIGHT_MOUSE_DRAG,
|
||||
WindowClickType.ADD_SLOT_RIGHT_MOUSE_DRAG,
|
||||
WindowClickType.CREATIVE_STARTING_MIDDLE_MOUSE_DRAG,
|
||||
WindowClickType.ADD_SLOT_MIDDLE_MOUSE_DRAG,
|
||||
WindowClickType.ENDING_MIDDLE_MOUSE_DRAG));
|
||||
|
||||
windowClickTypeCache.put(6, getArrayListOfWindowClickTypes(WindowClickType.DOUBLE_CLICK));
|
||||
isClickModePrimitive = Reflection.getField(packetClass, int.class, 3) != null;
|
||||
invClickTypeClass = NMSUtils.getNMSClassWithoutException("InventoryClickType");
|
||||
}
|
||||
|
||||
private static ArrayList<WindowClickType> getArrayListOfWindowClickTypes(WindowClickType... types) {
|
||||
ArrayList<WindowClickType> arrayList = new ArrayList<WindowClickType>(types.length);
|
||||
arrayList.addAll(Arrays.asList(types));
|
||||
return arrayList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Window ID.
|
||||
* @return Get Window ID
|
||||
*/
|
||||
public int getWindowID() {
|
||||
return readInt(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Window slot.
|
||||
* @return Get Window Slot
|
||||
*/
|
||||
public int getWindowSlot() {
|
||||
return readInt(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Window button.
|
||||
* @return Get Window Button
|
||||
*/
|
||||
public int getWindowButton() {
|
||||
return readInt(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the action number.
|
||||
* @return Get Action Number
|
||||
*/
|
||||
public short getActionNumber() {
|
||||
return readShort(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the window click type.
|
||||
* @return Get Window Click Type
|
||||
*/
|
||||
public WindowClickType getWindowClickType() {
|
||||
if (windowClickTypeCache.get(mode) == null) {
|
||||
return WindowClickType.UNKNOWN;
|
||||
}
|
||||
if (button + 1 > windowClickTypeCache.size()) {
|
||||
return WindowClickType.UNKNOWN;
|
||||
}
|
||||
|
||||
// TODO: This has no use cuz the fields used are never getting assigned a value to them
|
||||
if (mode == 4) {
|
||||
if (slot == -999) {
|
||||
if (button == 0) {
|
||||
return WindowClickType.LEFT_CLICK_OUTSIDE_WINDOW_HOLDING_NOTHING;
|
||||
} else if (button == 1) {
|
||||
return WindowClickType.RIGHT_CLICK_OUTSIDE_WINDOW_HOLDING_NOTHING;
|
||||
}
|
||||
}
|
||||
}
|
||||
return windowClickTypeCache.get(mode).get(button);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Window mode.
|
||||
* @return Get Window Mode.
|
||||
*/
|
||||
public int getMode() {
|
||||
if (isClickModePrimitive) {
|
||||
return readInt(3);
|
||||
} else {
|
||||
return invClickTypeMapCache.get(readObject(5, invClickTypeClass).toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the clicked item.
|
||||
* @return Get Clicked ItemStack
|
||||
*/
|
||||
public ItemStack getClickedItem() {
|
||||
Object nmsItemStack = readObject(0, NMSUtils.nmsItemStackClass);
|
||||
return NMSUtils.toBukkitItemStack(nmsItemStack);
|
||||
}
|
||||
|
||||
public enum WindowClickType {
|
||||
LEFT_MOUSE_CLICK, RIGHT_MOUSE_CLICK,
|
||||
SHIFT_LEFT_MOUSE_CLICK, SHIFT_RIGHT_MOUSE_CLICK,
|
||||
|
||||
CREATIVE_MIDDLE_CLICK, CREATIVE_STARTING_MIDDLE_MOUSE_DRAG,
|
||||
|
||||
KEY_NUMBER1, KEY_NUMBER2, KEY_NUMBER3, KEY_NUMBER4,
|
||||
KEY_NUMBER5, KEY_NUMBER6, KEY_NUMBER7, KEY_NUMBER8,
|
||||
KEY_NUMBER9, KEY_DROP, KEY_DROP_STACK,
|
||||
|
||||
LEFT_CLICK_OUTSIDE_WINDOW_HOLDING_NOTHING,
|
||||
RIGHT_CLICK_OUTSIDE_WINDOW_HOLDING_NOTHING,
|
||||
|
||||
STARTING_LEFT_MOUSE_DRAG,
|
||||
STARTING_RIGHT_MOUSE_DRAG,
|
||||
|
||||
ADD_SLOT_LEFT_MOUSE_DRAG,
|
||||
ADD_SLOT_RIGHT_MOUSE_DRAG,
|
||||
ADD_SLOT_MIDDLE_MOUSE_DRAG,
|
||||
|
||||
ENDING_LEFT_MOUSE_DRAG,
|
||||
ENDING_RIGHT_MOUSE_DRAG,
|
||||
ENDING_MIDDLE_MOUSE_DRAG,
|
||||
|
||||
DOUBLE_CLICK,
|
||||
|
||||
UNKNOWN
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.login.in;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
|
||||
public class WrappedPacketLoginHandshake extends WrappedPacket {
|
||||
public WrappedPacketLoginHandshake(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public int getProtocolVersion() {
|
||||
return readInt(0);
|
||||
}
|
||||
|
||||
public String getHostName() {
|
||||
return readString(0);
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return readInt(1);
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.login.in;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
|
||||
public class WrappedPacketLoginInCustomPayload extends WrappedPacket {
|
||||
public WrappedPacketLoginInCustomPayload(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
|
||||
/* TODO wrappers
|
||||
* net.minecraft.server.v1_16_R2.PacketLoginInCustomPayload inCP;
|
||||
* net.minecraft.server.v1_16_R2.PacketLoginOutCustomPayload outCP;
|
||||
* net.minecraft.server.v1_16_R2.PacketPlayOutLogin outLogin;
|
||||
* Find out about the Status Response packet
|
||||
*/
|
||||
}
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.login.in;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.gameprofile.GameProfileUtil;
|
||||
import io.github.retrooper.packetevents.utils.gameprofile.WrappedGameProfile;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
|
||||
public class WrappedPacketLoginInStart extends WrappedPacket {
|
||||
public WrappedPacketLoginInStart(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public WrappedGameProfile getGameProfile() {
|
||||
return GameProfileUtil.getWrappedGameProfile(readObject(0, NMSUtils.gameProfileClass));
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.login.in;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
|
||||
public class WrapppedPacketLoginInEncryptionBegin extends WrappedPacket {
|
||||
public WrapppedPacketLoginInEncryptionBegin(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public byte[] getPublicKey() {
|
||||
return readByteArray(0);
|
||||
}
|
||||
|
||||
public byte[] getVerifyToken() {
|
||||
return readByteArray(1);
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.login.out;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.chat.WrappedPacketOutChat;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
|
||||
public class WrappedPacketLoginDisconnect extends WrappedPacket {
|
||||
public WrappedPacketLoginDisconnect(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public String getReason() {
|
||||
Object iChatBaseComponent = readObject(0, NMSUtils.iChatBaseComponentClass);
|
||||
return WrappedPacketOutChat.toStringFromIChatBaseComponent(iChatBaseComponent);
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.login.out;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
|
||||
import java.security.PublicKey;
|
||||
|
||||
public class WrappedPacketLoginOutEncryptionBegin extends WrappedPacket {
|
||||
public WrappedPacketLoginOutEncryptionBegin(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public String getEncodedString() {
|
||||
return readString(0);
|
||||
}
|
||||
|
||||
public PublicKey getPublicKey() {
|
||||
return (PublicKey) readObject(1, PublicKey.class);
|
||||
}
|
||||
|
||||
public byte[] getByteArray() {
|
||||
return readByteArray(0);
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.login.out;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
|
||||
//This packet does not exist on 1.7.10
|
||||
public class WrappedPacketLoginOutSetCompression extends WrappedPacket {
|
||||
public WrappedPacketLoginOutSetCompression(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Maximum size of a packet before it can be compressed.
|
||||
*/
|
||||
public int getThreshold() {
|
||||
return readInt(0);
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.login.out;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.gameprofile.GameProfileUtil;
|
||||
import io.github.retrooper.packetevents.utils.gameprofile.WrappedGameProfile;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
|
||||
public class WrappedPacketLoginOutSuccess extends WrappedPacket {
|
||||
public WrappedPacketLoginOutSuccess(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public WrappedGameProfile getGameProfile() {
|
||||
return GameProfileUtil.getWrappedGameProfile(readObject(0, NMSUtils.gameProfileClass));
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.out.abilities;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
final class PlayerAbilitiesUtils {
|
||||
public static Class<?> playerAbilitiesClass;
|
||||
public static Constructor<?> playerAbilitiesConstructor;
|
||||
|
||||
static {
|
||||
try {
|
||||
playerAbilitiesClass = NMSUtils.getNMSClass("PlayerAbilities");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
playerAbilitiesConstructor = playerAbilitiesClass.getConstructor();
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static Object getPlayerAbilities(final boolean isVulnerable, final boolean isFlying, final boolean allowFlight, final boolean canBuildInstantly,
|
||||
final float flySpeed, final float walkSpeed) throws IllegalAccessException, InvocationTargetException, InstantiationException {
|
||||
final Object instance = playerAbilitiesConstructor.newInstance();
|
||||
WrappedPacket wrapper = new WrappedPacket(instance);
|
||||
wrapper.writeBoolean(0, isVulnerable);
|
||||
wrapper.writeBoolean(1, isFlying);
|
||||
wrapper.writeBoolean(2, allowFlight);
|
||||
wrapper.writeBoolean(3, canBuildInstantly);
|
||||
wrapper.writeFloat(0, flySpeed);
|
||||
wrapper.writeFloat(1, walkSpeed);
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.out.abilities;
|
||||
|
||||
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.SendableWrapper;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public final class WrappedPacketOutAbilities extends WrappedPacket implements SendableWrapper {
|
||||
private static Constructor<?> packetConstructor;
|
||||
private boolean isListening;
|
||||
private boolean vulnerable, flying, allowFlight, instantBuild;
|
||||
private float flySpeed, walkSpeed;
|
||||
|
||||
public WrappedPacketOutAbilities(final Object packet) {
|
||||
super(packet);
|
||||
isListening = true;
|
||||
}
|
||||
|
||||
public WrappedPacketOutAbilities(final boolean isVulnerable, final boolean isFlying, final boolean allowFlight, final boolean canBuildInstantly,
|
||||
final float flySpeed, final float walkSpeed) {
|
||||
super();
|
||||
this.vulnerable = isVulnerable;
|
||||
this.flying = isFlying;
|
||||
this.allowFlight = allowFlight;
|
||||
this.instantBuild = canBuildInstantly;
|
||||
this.flySpeed = flySpeed;
|
||||
this.walkSpeed = walkSpeed;
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
Class<?> packetClass = PacketTypeClasses.Server.ABILITIES;
|
||||
|
||||
try {
|
||||
packetConstructor = packetClass.getConstructor(PlayerAbilitiesUtils.playerAbilitiesClass);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the client be vulnerable?
|
||||
*
|
||||
* @return Is Vulnerable
|
||||
*/
|
||||
public boolean isVulnerable() {
|
||||
if (isListening) {
|
||||
return readBoolean(0);
|
||||
} else {
|
||||
return vulnerable;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the client be flying?
|
||||
*
|
||||
* @return Is Flying
|
||||
*/
|
||||
public boolean isFlying() {
|
||||
if (isListening) {
|
||||
return readBoolean(1);
|
||||
} else {
|
||||
return flying;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the client be allowed to fly?
|
||||
*
|
||||
* @return Is Allowed To Fly
|
||||
*/
|
||||
public boolean isFlightAllowed() {
|
||||
if (isListening) {
|
||||
return readBoolean(2);
|
||||
} else {
|
||||
return allowFlight;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the client be able to build instantly?
|
||||
*
|
||||
* @return Is Allowed To Build Instantly
|
||||
*/
|
||||
public boolean canInstantlyBuild() {
|
||||
if (isListening) {
|
||||
return readBoolean(3);
|
||||
} else {
|
||||
return instantBuild;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the client's defined fly speed.
|
||||
*
|
||||
* @return Get Fly Speed
|
||||
*/
|
||||
public float getFlySpeed() {
|
||||
if (isListening) {
|
||||
return readFloat(0);
|
||||
} else {
|
||||
return flySpeed;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the client's defined walk speed.
|
||||
*
|
||||
* @return Get Walk Speed
|
||||
*/
|
||||
public float getWalkSpeed() {
|
||||
if (isListening) {
|
||||
return readFloat(1);
|
||||
} else {
|
||||
return walkSpeed;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object asNMSPacket() {
|
||||
try {
|
||||
return packetConstructor.newInstance(PlayerAbilitiesUtils.getPlayerAbilities(vulnerable, flying, allowFlight, instantBuild, flySpeed, walkSpeed));
|
||||
} catch (InstantiationException | InvocationTargetException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.out.animation;
|
||||
|
||||
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.SendableWrapper;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public final class WrappedPacketOutAnimation extends WrappedPacket implements SendableWrapper {
|
||||
private static Class<?> nmsEntityClass;
|
||||
private static Constructor<?> animationConstructor;
|
||||
|
||||
private static final Map<Integer, EntityAnimationType> cachedAnimationIDS = new HashMap<>();
|
||||
private static final Map<EntityAnimationType, Integer> cachedAnimations = new HashMap<>();
|
||||
private Entity entity;
|
||||
private int entityID = -1;
|
||||
private EntityAnimationType type;
|
||||
private boolean isListening = false;
|
||||
|
||||
public WrappedPacketOutAnimation(final Object packet) {
|
||||
super(packet);
|
||||
isListening = true;
|
||||
}
|
||||
|
||||
public WrappedPacketOutAnimation(final Entity target, final EntityAnimationType type) {
|
||||
super();
|
||||
this.entityID = target.getEntityId();
|
||||
this.entity = target;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
Class<?> animationClass = PacketTypeClasses.Server.ANIMATION;
|
||||
try {
|
||||
nmsEntityClass = NMSUtils.getNMSClass("Entity");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
animationConstructor = animationClass.getConstructor(nmsEntityClass, int.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
cachedAnimationIDS.put(0, EntityAnimationType.SWING_MAIN_ARM);
|
||||
cachedAnimationIDS.put(1, EntityAnimationType.TAKE_DAMAGE);
|
||||
cachedAnimationIDS.put(2, EntityAnimationType.LEAVE_BED);
|
||||
cachedAnimationIDS.put(3, EntityAnimationType.SWING_OFFHAND);
|
||||
cachedAnimationIDS.put(4, EntityAnimationType.CRITICAL_EFFECT);
|
||||
cachedAnimationIDS.put(5, EntityAnimationType.MAGIC_CRITICAL_EFFECT);
|
||||
|
||||
cachedAnimations.put(EntityAnimationType.SWING_MAIN_ARM, 0);
|
||||
cachedAnimations.put(EntityAnimationType.TAKE_DAMAGE, 1);
|
||||
cachedAnimations.put(EntityAnimationType.LEAVE_BED, 2);
|
||||
cachedAnimations.put(EntityAnimationType.SWING_OFFHAND, 3);
|
||||
cachedAnimations.put(EntityAnimationType.CRITICAL_EFFECT, 4);
|
||||
cachedAnimations.put(EntityAnimationType.MAGIC_CRITICAL_EFFECT, 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup the associated entity by the ID that was sent in the packet.
|
||||
*
|
||||
* @return Entity
|
||||
*/
|
||||
public Entity getEntity() {
|
||||
if (entity != null) {
|
||||
return entity;
|
||||
}
|
||||
return entity = NMSUtils.getEntityById(getEntityId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID of the entity.
|
||||
* If you do not want to use {@link #getEntity()},
|
||||
* you lookup the entity by yourself with this entity ID.
|
||||
*
|
||||
* @return Entity ID
|
||||
*/
|
||||
public int getEntityId() {
|
||||
if (entityID == -1) {
|
||||
entityID = readInt(0);
|
||||
}
|
||||
return entityID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the entity animation type.
|
||||
*
|
||||
* @return Get Entity Animation Type
|
||||
*/
|
||||
public EntityAnimationType getAnimationType() {
|
||||
if (isListening) {
|
||||
return cachedAnimationIDS.get(readInt(1));
|
||||
} else {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object asNMSPacket() {
|
||||
final Object nmsEntity = NMSUtils.getNMSEntity(this.entity);
|
||||
final int index = cachedAnimations.get(type);
|
||||
try {
|
||||
return animationConstructor.newInstance(nmsEntity, index);
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public enum EntityAnimationType {
|
||||
SWING_MAIN_ARM, TAKE_DAMAGE, LEAVE_BED, SWING_OFFHAND, CRITICAL_EFFECT, MAGIC_CRITICAL_EFFECT
|
||||
}
|
||||
}
|
||||
+286
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.out.chat;
|
||||
|
||||
import io.github.retrooper.packetevents.annotations.Beta;
|
||||
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.SendableWrapper;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* This wrapper MIGHT not be stable
|
||||
*/
|
||||
@Beta
|
||||
public final class WrappedPacketOutChat extends WrappedPacket implements SendableWrapper {
|
||||
private static Constructor<?> chatClassConstructor;
|
||||
private static Class<?> packetClass, iChatBaseComponentClass, chatSerializerClass, chatMessageTypeEnum;
|
||||
private static Method chatMessageTypeCreatorMethod;
|
||||
//0 = IChatBaseComponent, Byte
|
||||
//1 = IChatBaseComponent, Int
|
||||
//2 = IChatBaseComponent, ChatMessageType
|
||||
//3 = IChatBaseComponent, ChatMessageType, UUID
|
||||
private static byte constructorMode;
|
||||
|
||||
//0 = Byte
|
||||
//1 = Byte, Boolean
|
||||
private static byte chatTypeMessageEnumConstructorMode;
|
||||
private static final HashMap<ChatPosition, Byte> cachedChatPositions = new HashMap<>();
|
||||
private static final HashMap<Byte, ChatPosition> cachedChatPositionIntegers = new HashMap<>();
|
||||
private static final HashMap<String, Byte> cachedChatMessageTypeIntegers = new HashMap<>();
|
||||
private String message;
|
||||
private ChatPosition chatPosition;
|
||||
private UUID uuid;
|
||||
private boolean isListening = false;
|
||||
|
||||
@Deprecated
|
||||
public WrappedPacketOutChat(String message) {
|
||||
this(message, null);
|
||||
}
|
||||
|
||||
public WrappedPacketOutChat(final Object packet) {
|
||||
super(packet);
|
||||
isListening = true;
|
||||
}
|
||||
|
||||
public WrappedPacketOutChat(String message, UUID uuid) {
|
||||
this(message, ChatPosition.CHAT, uuid);
|
||||
}
|
||||
|
||||
public WrappedPacketOutChat(String message, ChatPosition chatPosition, UUID uuid) {
|
||||
this.uuid = uuid;
|
||||
this.message = message;
|
||||
this.chatPosition = chatPosition;
|
||||
}
|
||||
|
||||
public enum ChatPosition {
|
||||
CHAT, SYSTEM_MESSAGE, GAME_INFO
|
||||
}
|
||||
|
||||
|
||||
public static void load() {
|
||||
try {
|
||||
packetClass = PacketTypeClasses.Server.CHAT;
|
||||
iChatBaseComponentClass = NMSUtils.getNMSClass("IChatBaseComponent");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
//In 1.8.3+ the ChatSerializer class is declared in the IChatBaseComponent class, so we have to handle that
|
||||
try {
|
||||
chatSerializerClass = NMSUtils.getNMSClass("ChatSerializer");
|
||||
} catch (ClassNotFoundException e) {
|
||||
//That is fine, it is probably a subclass
|
||||
chatSerializerClass = SubclassUtil.getSubClass(iChatBaseComponentClass, "ChatSerializer");
|
||||
}
|
||||
|
||||
|
||||
boolean isVeryOutdated = false;
|
||||
try {
|
||||
chatMessageTypeEnum = NMSUtils.getNMSClass("ChatMessageType");
|
||||
} catch (ClassNotFoundException e) {
|
||||
isVeryOutdated = true;
|
||||
}
|
||||
|
||||
if (!isVeryOutdated) {
|
||||
chatMessageTypeCreatorMethod = Reflection.getMethod(chatMessageTypeEnum, 0, byte.class);
|
||||
|
||||
try {
|
||||
chatClassConstructor = packetClass.getConstructor(iChatBaseComponentClass, chatMessageTypeEnum);
|
||||
constructorMode = 2;
|
||||
} catch (NoSuchMethodException e) {
|
||||
//Just a much newer version(1.16.x and above right now)
|
||||
try {
|
||||
chatClassConstructor = packetClass.getConstructor(iChatBaseComponentClass, chatMessageTypeEnum, UUID.class);
|
||||
constructorMode = 3;
|
||||
} catch (NoSuchMethodException e2) {
|
||||
//Failed to resolve the constructor
|
||||
e2.printStackTrace();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
chatClassConstructor = packetClass.getConstructor(iChatBaseComponentClass, byte.class);
|
||||
constructorMode = 0;
|
||||
} catch (NoSuchMethodException e) {
|
||||
//That is fine, they are most likely on an older version.
|
||||
try {
|
||||
chatClassConstructor = packetClass.getConstructor(iChatBaseComponentClass, int.class);
|
||||
constructorMode = 1;
|
||||
} catch (NoSuchMethodException e2) {
|
||||
e2.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cachedChatPositions.put(ChatPosition.CHAT, (byte) 0);
|
||||
cachedChatPositions.put(ChatPosition.SYSTEM_MESSAGE, (byte) 1);
|
||||
cachedChatPositions.put(ChatPosition.GAME_INFO, (byte) 2);
|
||||
|
||||
cachedChatPositionIntegers.put((byte) 0, ChatPosition.CHAT);
|
||||
cachedChatPositionIntegers.put((byte) 1, ChatPosition.SYSTEM_MESSAGE);
|
||||
cachedChatPositionIntegers.put((byte) 2, ChatPosition.GAME_INFO);
|
||||
|
||||
|
||||
cachedChatMessageTypeIntegers.put("CHAT", (byte) 0);
|
||||
cachedChatMessageTypeIntegers.put("SYSTEM", (byte) 1);
|
||||
cachedChatMessageTypeIntegers.put("GAME_INFO", (byte) 2);
|
||||
|
||||
}
|
||||
|
||||
public static String fromStringToJSON(String message) {
|
||||
return "{\"text\": \"" + message + "\"}";
|
||||
}
|
||||
|
||||
public static String toStringFromIChatBaseComponent(Object obj) {
|
||||
try {
|
||||
return Reflection.getMethod(iChatBaseComponentClass, String.class, 0).invoke(obj).toString();
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Object toIChatBaseComponent(String msg) {
|
||||
try {
|
||||
return Reflection.getMethod(chatSerializerClass, 0, String.class).invoke(null, msg);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object asNMSPacket() {
|
||||
int integerChatPos = cachedChatPositions.get(chatPosition);
|
||||
Object chatMessageTypeInstance = null;
|
||||
if (chatMessageTypeEnum != null) {
|
||||
if (chatTypeMessageEnumConstructorMode == 0) {
|
||||
try {
|
||||
chatMessageTypeInstance = chatMessageTypeCreatorMethod.invoke(null, (byte) integerChatPos);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else if (chatTypeMessageEnumConstructorMode == 1) {
|
||||
try {
|
||||
chatMessageTypeInstance = chatMessageTypeCreatorMethod.invoke(null, (byte) integerChatPos);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (constructorMode) {
|
||||
case 0:
|
||||
try {
|
||||
return chatClassConstructor.newInstance(toIChatBaseComponent(this.message), (byte) integerChatPos);
|
||||
} catch (InstantiationException | InvocationTargetException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
try {
|
||||
return chatClassConstructor.newInstance(toIChatBaseComponent(this.message), integerChatPos);
|
||||
} catch (InstantiationException | InvocationTargetException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
try {
|
||||
return chatClassConstructor.newInstance(toIChatBaseComponent(this.message), chatMessageTypeInstance);
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
try {
|
||||
return chatClassConstructor.newInstance(toIChatBaseComponent(this.message), chatMessageTypeInstance, uuid);
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message.
|
||||
* @return Get String Message
|
||||
*/
|
||||
public String getMessage() {
|
||||
if(isListening) {
|
||||
final Object iChatBaseObj = readObject(0, iChatBaseComponentClass);
|
||||
|
||||
try {
|
||||
Object contentString = Reflection.getMethod(iChatBaseComponentClass, String.class, 0).invoke(iChatBaseObj);
|
||||
return contentString.toString();
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the chat position.
|
||||
*
|
||||
* On 1.7.10, Only CHAT and SYSTEM_MESSAGE exist.
|
||||
* If an invalid chat position is sent, it will be defaulted it to CHAT.
|
||||
* @return ChatPosition
|
||||
*/
|
||||
public ChatPosition getChatPosition() {
|
||||
if(isListening) {
|
||||
byte chatPosInteger = 0;
|
||||
switch (constructorMode) {
|
||||
case 0:
|
||||
chatPosInteger = readByte(0);
|
||||
break;
|
||||
case 1:
|
||||
chatPosInteger = (byte) readInt(0);
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
Object chatTypeEnumInstance = readObject(0, chatMessageTypeEnum);
|
||||
chatPosInteger = cachedChatMessageTypeIntegers.get(chatTypeEnumInstance.toString());
|
||||
break;
|
||||
}
|
||||
return cachedChatPositionIntegers.get(chatPosInteger);
|
||||
}
|
||||
else {
|
||||
return chatPosition;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+226
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.out.custompayload;
|
||||
|
||||
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.SendableWrapper;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.bytebuf.ByteBufUtil;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
public class WrappedPacketOutCustomPayload extends WrappedPacket implements SendableWrapper {
|
||||
private static Constructor<?> constructor;
|
||||
private static Constructor<?> packetDataSerializerConstructor;
|
||||
private static Constructor<?> minecraftKeyConstructor;
|
||||
private static Class<?> byteBufClass;
|
||||
private static Class<?> packetDataSerializerClass;
|
||||
private static Class<?> minecraftKeyClass;
|
||||
private static int minecraftKeyIndexInClass;
|
||||
|
||||
private static byte constructorMode = 0;
|
||||
private boolean isListening = false;
|
||||
|
||||
public static void load() {
|
||||
Class<?> packetClass = PacketTypeClasses.Server.CUSTOM_PAYLOAD;
|
||||
packetDataSerializerClass = NMSUtils.getNMSClassWithoutException("PacketDataSerializer");
|
||||
minecraftKeyClass = NMSUtils.getNMSClassWithoutException("MinecraftKey");
|
||||
|
||||
try {
|
||||
byteBufClass = NMSUtils.getNettyClass("buffer.ByteBuf");
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
|
||||
}
|
||||
try {
|
||||
packetDataSerializerConstructor = packetDataSerializerClass.getConstructor(byteBufClass);
|
||||
} catch (NullPointerException e) {
|
||||
//Nothing
|
||||
} catch (NoSuchMethodException e) {
|
||||
//also nothing
|
||||
}
|
||||
|
||||
try {
|
||||
if (minecraftKeyClass != null) {
|
||||
minecraftKeyConstructor = minecraftKeyClass.getConstructor(String.class);
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
//Nothing
|
||||
}
|
||||
|
||||
//Constructors:
|
||||
|
||||
//String, byte[]
|
||||
|
||||
//String, PacketDataSerializer
|
||||
|
||||
//MinecraftKey, PacketDataSerializer
|
||||
try {
|
||||
//1.7 constructor
|
||||
constructor = packetClass.getConstructor(String.class, byte[].class);
|
||||
constructorMode = 0;
|
||||
} catch (NoSuchMethodException e) {
|
||||
//That's fine, just a newer version
|
||||
try {
|
||||
constructor = packetClass.getConstructor(String.class, packetDataSerializerClass);
|
||||
constructorMode = 1;
|
||||
} catch (NoSuchMethodException e2) {
|
||||
//That's fine, just an even newer version
|
||||
try {
|
||||
//Minecraft key exists
|
||||
|
||||
for (int i = 0; i < packetClass.getDeclaredFields().length; i++) {
|
||||
Field f = packetClass.getDeclaredFields()[i];
|
||||
if (!Modifier.isStatic(f.getModifiers())) {
|
||||
minecraftKeyIndexInClass = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
constructor = packetClass.getConstructor(minecraftKeyClass, packetDataSerializerClass);
|
||||
constructorMode = 2;
|
||||
} catch (NoSuchMethodException e3) {
|
||||
throw new IllegalStateException("PacketEvents is unable to resolve the PacketPlayOutCustomPayload constructor.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String tag;
|
||||
private byte[] data;
|
||||
|
||||
public WrappedPacketOutCustomPayload(String tag, byte[] data) {
|
||||
this.tag = tag;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
|
||||
public WrappedPacketOutCustomPayload(Object packet) {
|
||||
super(packet);
|
||||
isListening = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
switch (constructorMode) {
|
||||
case 0:
|
||||
this.tag = readString(0);
|
||||
this.data = readByteArray(0);
|
||||
break;
|
||||
case 1:
|
||||
this.tag = readString(0);
|
||||
Object dataSerializer = readObject(0, packetDataSerializerClass);
|
||||
WrappedPacket byteBufWrapper = new WrappedPacket(dataSerializer);
|
||||
|
||||
Object byteBuf = byteBufWrapper.readObject(0, byteBufClass);
|
||||
|
||||
this.data = ByteBufUtil.getBytes(byteBuf);
|
||||
break;
|
||||
case 2:
|
||||
Object minecraftKey = readObject(minecraftKeyIndexInClass, minecraftKeyClass);
|
||||
WrappedPacket minecraftKeyWrapper = new WrappedPacket(minecraftKey);
|
||||
this.tag = minecraftKeyWrapper.readString(1);
|
||||
Object dataSerializer2 = readObject(0, packetDataSerializerClass);
|
||||
WrappedPacket byteBuf2Wrapper = new WrappedPacket(dataSerializer2);
|
||||
Object byteBuf2 = byteBuf2Wrapper.readObject(0, byteBufClass);
|
||||
this.data = ByteBufUtil.getBytes(byteBuf2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public String getTag() {
|
||||
if(isListening) {
|
||||
switch(constructorMode) {
|
||||
case 0:
|
||||
case 1:
|
||||
return readString(0);
|
||||
case 2:
|
||||
Object minecraftKey = readObject(minecraftKeyIndexInClass, minecraftKeyClass);
|
||||
WrappedPacket minecraftKeyWrapper = new WrappedPacket(minecraftKey);
|
||||
return minecraftKeyWrapper.readString(1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return tag;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
if(isListening) {
|
||||
switch(constructorMode) {
|
||||
case 0:
|
||||
return readByteArray(0);
|
||||
case 1:
|
||||
case 2:
|
||||
Object dataSerializer = readObject(0, packetDataSerializerClass);
|
||||
WrappedPacket byteBufWrapper = new WrappedPacket(dataSerializer);
|
||||
|
||||
Object byteBuf = byteBufWrapper.readObject(0, byteBufClass);
|
||||
|
||||
return ByteBufUtil.getBytes(byteBuf);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return data;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object asNMSPacket() {
|
||||
Object byteBufObject = ByteBufUtil.copiedBuffer(data);
|
||||
switch (constructorMode) {
|
||||
case 0:
|
||||
try {
|
||||
return constructor.newInstance(tag, data);
|
||||
} catch (InstantiationException | InvocationTargetException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
try {
|
||||
Object dataSerializer = packetDataSerializerConstructor.newInstance(byteBufObject);
|
||||
return constructor.newInstance(tag, dataSerializer);
|
||||
} catch (InstantiationException | InvocationTargetException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
|
||||
try {
|
||||
Object minecraftKey = minecraftKeyConstructor.newInstance(tag);
|
||||
Object dataSerializer = packetDataSerializerConstructor.newInstance(byteBufObject);
|
||||
return constructor.newInstance(minecraftKey, dataSerializer);
|
||||
} catch (InstantiationException | InvocationTargetException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+264
@@ -0,0 +1,264 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.out.entity;
|
||||
|
||||
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.SendableWrapper;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public class WrappedPacketOutEntity extends WrappedPacket implements SendableWrapper {
|
||||
//Byte = 1.7.10->1.8.8, Int = 1.9->1.15.x, Short = 1.16.x
|
||||
private static byte mode; //byte = 0, int = 1, short = 2
|
||||
private static double dXYZDivisor;
|
||||
private static int yawByteIndex;
|
||||
private static int pitchByteIndex = 1;
|
||||
private Entity entity;
|
||||
private boolean isListening;
|
||||
private static Constructor<?> entityPacketConstructor;
|
||||
private int entityID;
|
||||
private double deltaX, deltaY, deltaZ;
|
||||
private byte pitch, yaw;
|
||||
private boolean onGround;
|
||||
|
||||
public WrappedPacketOutEntity(Object packet) {
|
||||
super(packet);
|
||||
isListening = true;
|
||||
}
|
||||
|
||||
public WrappedPacketOutEntity(int entityID, double deltaX, double deltaY, double deltaZ,
|
||||
byte pitch, byte yaw, boolean onGround) {
|
||||
this.entityID = entityID;
|
||||
this.deltaX = deltaX;
|
||||
this.deltaY = deltaY;
|
||||
this.deltaZ = deltaZ;
|
||||
this.pitch = pitch;
|
||||
this.yaw = yaw;
|
||||
this.onGround = onGround;
|
||||
//Get entity player then pass it into the packetplayoutnamedentityspawn!
|
||||
// net.minecraft.server.v1_7_R4.EntityPlayer cp = null;
|
||||
//net.minecraft.server.v1_7_R4.PacketPlayOutNamedEntitySpawn es = new net.minecraft.server.v1_7_R4.PacketPlayOutNamedEntitySpawn(cp);
|
||||
}
|
||||
|
||||
public WrappedPacketOutEntity(Entity entity, double deltaX, double deltaY, double deltaZ,
|
||||
byte pitch, byte yaw, boolean onGround) {
|
||||
this(entity.getEntityId(), deltaX, deltaY, deltaZ, pitch, yaw, onGround);
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
Class<?> packetClass = PacketTypeClasses.Server.ENTITY;
|
||||
|
||||
Field dxField = Reflection.getField(packetClass, 1);
|
||||
assert dxField != null;
|
||||
if (dxField.equals(Reflection.getField(packetClass, byte.class, 0))) {
|
||||
mode = 0;
|
||||
yawByteIndex = 3;
|
||||
pitchByteIndex = 4;
|
||||
} else if (dxField.equals(Reflection.getField(packetClass, int.class, 1))) {
|
||||
mode = 1;
|
||||
} else if (dxField.equals(Reflection.getField(packetClass, short.class, 0))) {
|
||||
mode = 2;
|
||||
}
|
||||
|
||||
if (mode == 0) {
|
||||
dXYZDivisor = 32.0;
|
||||
} else {
|
||||
dXYZDivisor = 4096.0;
|
||||
}
|
||||
try {
|
||||
entityPacketConstructor = packetClass.getConstructor(int.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the pitch.
|
||||
*
|
||||
* @return Get Byte Pitch
|
||||
*/
|
||||
public byte getPitch() {
|
||||
if (isListening) {
|
||||
return readByte(pitchByteIndex);
|
||||
} else {
|
||||
return pitch;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Yaw.
|
||||
*
|
||||
* @return Get Byte Yaw
|
||||
*/
|
||||
public byte getYaw() {
|
||||
if (isListening) {
|
||||
return readByte(yawByteIndex);
|
||||
} else {
|
||||
return yaw;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Delta X
|
||||
*
|
||||
* @return Delta X
|
||||
*/
|
||||
public double getDeltaX() {
|
||||
if (isListening) {
|
||||
switch (mode) {
|
||||
case 0:
|
||||
return readByte(0) / dXYZDivisor;
|
||||
case 1:
|
||||
return readInt(1) / dXYZDivisor;
|
||||
case 2:
|
||||
return readShort(0) / dXYZDivisor;
|
||||
}
|
||||
} else {
|
||||
return deltaX;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Delta Y
|
||||
*
|
||||
* @return Delta Y
|
||||
*/
|
||||
public double getDeltaY() {
|
||||
if (isListening) {
|
||||
switch (mode) {
|
||||
case 0:
|
||||
return readByte(1) / dXYZDivisor;
|
||||
case 1:
|
||||
return readInt(2) / dXYZDivisor;
|
||||
case 2:
|
||||
return readShort(1) / dXYZDivisor;
|
||||
}
|
||||
} else {
|
||||
return deltaY;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Delta Z
|
||||
*
|
||||
* @return Delta Z
|
||||
*/
|
||||
public double getDeltaZ() {
|
||||
if (isListening) {
|
||||
switch (mode) {
|
||||
case 0:
|
||||
return readByte(2) / dXYZDivisor;
|
||||
case 1:
|
||||
return readInt(3) / dXYZDivisor;
|
||||
case 2:
|
||||
return readShort(2) / dXYZDivisor;
|
||||
}
|
||||
} else {
|
||||
return deltaZ;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup the associated entity by the ID that was sent in the packet.
|
||||
*
|
||||
* @return Entity
|
||||
*/
|
||||
public Entity getEntity() {
|
||||
if (entity != null) {
|
||||
return entity;
|
||||
}
|
||||
return entity = NMSUtils.getEntityById(getEntityId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID of the entity.
|
||||
* If you do not want to use {@link #getEntity()},
|
||||
* you lookup the entity by yourself with this entity ID.
|
||||
*
|
||||
* @return Entity ID
|
||||
*/
|
||||
public int getEntityId() {
|
||||
if (entityID != -1) {
|
||||
return entityID;
|
||||
} else {
|
||||
return entityID = readInt(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the entity on the ground?
|
||||
*
|
||||
* @return On Ground
|
||||
*/
|
||||
public boolean isOnGround() {
|
||||
if (isListening) {
|
||||
return readBoolean(0);
|
||||
} else {
|
||||
return onGround;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object asNMSPacket() {
|
||||
try {
|
||||
Object packetInstance = entityPacketConstructor.newInstance(entityID);
|
||||
WrappedPacket wrapper = new WrappedPacket(packetInstance);
|
||||
switch(mode) {
|
||||
case 0:
|
||||
wrapper.writeByte(0, (byte)(deltaX * dXYZDivisor));
|
||||
wrapper.writeByte(1, (byte)(deltaY * dXYZDivisor));
|
||||
wrapper.writeByte(2, (byte)(deltaZ * dXYZDivisor));
|
||||
break;
|
||||
case 1:
|
||||
wrapper.writeInt(1, (int)(deltaX * dXYZDivisor));
|
||||
wrapper.writeInt(2, (int)(deltaY * dXYZDivisor));
|
||||
wrapper.writeInt(3, (int)(deltaZ * dXYZDivisor));
|
||||
break;
|
||||
case 2:
|
||||
wrapper.writeShort(0, (short)(deltaX * dXYZDivisor));
|
||||
wrapper.writeShort(1, (short)(deltaY * dXYZDivisor));
|
||||
wrapper.writeShort(2, (short)(deltaZ * dXYZDivisor));
|
||||
break;
|
||||
}
|
||||
wrapper.writeByte(yawByteIndex, yaw);
|
||||
wrapper.writeByte(pitchByteIndex, pitch);
|
||||
wrapper.writeBoolean(0, onGround);
|
||||
return packetInstance;
|
||||
} catch (InstantiationException | InvocationTargetException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.out.entitymetadata;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
|
||||
public class WrappedPacketOutEntityMetadata extends WrappedPacket {
|
||||
private boolean isListening;
|
||||
public WrappedPacketOutEntityMetadata(Object packet) {
|
||||
super(packet);
|
||||
isListening = true;
|
||||
}
|
||||
|
||||
public int getEntityId() {
|
||||
if (isListening) {
|
||||
return readInt(0);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.out.entitystatus;
|
||||
|
||||
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.SendableWrapper;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public class WrappedPacketOutEntityStatus extends WrappedPacket implements SendableWrapper {
|
||||
private static Constructor<?> packetConstructor;
|
||||
|
||||
public static void load() {
|
||||
try {
|
||||
packetConstructor =
|
||||
PacketTypeClasses.Server.ENTITY_STATUS.getConstructor(NMSUtils.nmsEntityClass, byte.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private Entity entity;
|
||||
private byte status;
|
||||
private int entityID = -1;
|
||||
|
||||
public WrappedPacketOutEntityStatus(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public WrappedPacketOutEntityStatus(Entity entity, byte status) {
|
||||
this.entityID = entity.getEntityId();
|
||||
this.entity = entity;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public WrappedPacketOutEntityStatus(int entityID, byte status) {
|
||||
this.entityID = entityID;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public int getEntityId() {
|
||||
if (packet == null) {
|
||||
if (entityID != -1) {
|
||||
return entityID;
|
||||
}
|
||||
return entityID = readInt(0);
|
||||
} else {
|
||||
return entityID;
|
||||
}
|
||||
}
|
||||
|
||||
public Entity getEntity() {
|
||||
if (entity == null) {
|
||||
return entity = NMSUtils.getEntityById(getEntityId());
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
public byte getEntityStatus() {
|
||||
if (packet == null) {
|
||||
return status;
|
||||
} else {
|
||||
return readByte(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object asNMSPacket() {
|
||||
try {
|
||||
return packetConstructor.newInstance(NMSUtils.getNMSEntity(getEntity()), status);
|
||||
} catch (InstantiationException | InvocationTargetException
|
||||
| IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+219
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.out.entityteleport;
|
||||
|
||||
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.SendableWrapper;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public class WrappedPacketOutEntityTeleport extends WrappedPacket implements SendableWrapper {
|
||||
private static boolean legacyVersionMode;
|
||||
private static boolean ultraLegacyVersionMode;
|
||||
private boolean listeningMode = false;
|
||||
private static final float rotationMultiplier = 256.0F / 360.0F;
|
||||
private static Constructor<?> constructor;
|
||||
private Entity entity = null;
|
||||
private int entityID;
|
||||
private double x, y, z;
|
||||
private float yaw, pitch;
|
||||
private boolean onGround;
|
||||
|
||||
public static void load() {
|
||||
Class<?> packetClass = PacketTypeClasses.Server.ENTITY_TELEPORT;
|
||||
try {
|
||||
constructor = packetClass.getConstructor(int.class, int.class, int.class, int.class, byte.class, byte.class, boolean.class, boolean.class);
|
||||
ultraLegacyVersionMode = true;
|
||||
legacyVersionMode = true;
|
||||
} catch (NoSuchMethodException e) {
|
||||
try {
|
||||
constructor = packetClass.getConstructor(int.class, int.class, int.class, int.class, byte.class, byte.class, boolean.class);
|
||||
ultraLegacyVersionMode = false;
|
||||
legacyVersionMode = true;
|
||||
} catch (NoSuchMethodException e2) {
|
||||
try {
|
||||
constructor = packetClass.getConstructor();
|
||||
ultraLegacyVersionMode = false;
|
||||
legacyVersionMode = false;
|
||||
} catch (NoSuchMethodException e3) {
|
||||
e3.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public WrappedPacketOutEntityTeleport(Object packet) {
|
||||
super(packet);
|
||||
listeningMode = true;
|
||||
}
|
||||
|
||||
public WrappedPacketOutEntityTeleport(int entityID, Location loc, boolean onGround) {
|
||||
this(entityID, loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch(), onGround);
|
||||
}
|
||||
|
||||
public WrappedPacketOutEntityTeleport(int entityID, double x, double y, double z, float yaw, float pitch, boolean onGround) {
|
||||
this.entityID = entityID;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.yaw = yaw;
|
||||
this.pitch = pitch;
|
||||
this.onGround = onGround;
|
||||
}
|
||||
|
||||
public Entity getEntity() {
|
||||
if(entity == null) {
|
||||
entity = NMSUtils.getEntityById(getEntityId());
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
public int getEntityId() {
|
||||
if (listeningMode) {
|
||||
if (entityID != -1) {
|
||||
return readInt(0);
|
||||
} else {
|
||||
return entityID = readInt(0);
|
||||
}
|
||||
} else {
|
||||
return entityID;
|
||||
}
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
if (!listeningMode) {
|
||||
return x;
|
||||
} else {
|
||||
if (legacyVersionMode) {
|
||||
return readInt(1) / 32.0D;
|
||||
} else {
|
||||
return readDouble(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
if (!listeningMode) {
|
||||
return y;
|
||||
} else {
|
||||
if (legacyVersionMode) {
|
||||
return readInt(2) / 32.0D;
|
||||
} else {
|
||||
return readDouble(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public double getZ() {
|
||||
if (!listeningMode) {
|
||||
return z;
|
||||
} else {
|
||||
if (legacyVersionMode) {
|
||||
return readInt(3) / 32.0D;
|
||||
} else {
|
||||
return readDouble(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float getYaw() {
|
||||
if (!listeningMode) {
|
||||
return yaw;
|
||||
} else {
|
||||
return (readByte(0) / rotationMultiplier);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isOnGround() {
|
||||
if (listeningMode) {
|
||||
return readBoolean(0);
|
||||
} else {
|
||||
return onGround;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object asNMSPacket() {
|
||||
if (ultraLegacyVersionMode) {
|
||||
//1.7.10
|
||||
try {
|
||||
return constructor.newInstance(entityID, floor(x * 32.0D), floor(y * 32.0D), floor(z * 32.0D),
|
||||
(byte) ((int) yaw * rotationMultiplier), (byte) (int) (pitch * rotationMultiplier), false, false);
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else if (legacyVersionMode) {
|
||||
//1.8.x
|
||||
try {
|
||||
return constructor.newInstance(entityID, floor(x * 32.0D), floor(y * 32.0D), floor(z * 32.0D),
|
||||
(byte) ((int) yaw * rotationMultiplier), (byte) (int) (pitch * rotationMultiplier), false);
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
//newer versions
|
||||
Object instance = null;
|
||||
try {
|
||||
instance = constructor.newInstance();
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
WrappedPacket instanceWrapper = new WrappedPacket(instance);
|
||||
instanceWrapper.writeInt(0, entityID);
|
||||
instanceWrapper.writeDouble(0, x);
|
||||
instanceWrapper.writeDouble(1, y);
|
||||
instanceWrapper.writeDouble(2, z);
|
||||
|
||||
instanceWrapper.writeByte(0, (byte) (yaw * rotationMultiplier));
|
||||
instanceWrapper.writeByte(1, (byte) (pitch * rotationMultiplier));
|
||||
if (onGround) {
|
||||
//default value is false, so we can save a reflection call
|
||||
instanceWrapper.writeBoolean(0, true);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public float getPitch() {
|
||||
if (listeningMode) {
|
||||
return pitch;
|
||||
} else {
|
||||
return (readByte(1) / rotationMultiplier);
|
||||
}
|
||||
}
|
||||
|
||||
private static int floor(double value) {
|
||||
int i = (int) value;
|
||||
return value < (double) i ? i - 1 : i;
|
||||
}
|
||||
}
|
||||
+182
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.out.entityvelocity;
|
||||
|
||||
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.SendableWrapper;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public final class WrappedPacketOutEntityVelocity extends WrappedPacket implements SendableWrapper {
|
||||
private static Constructor<?> velocityConstructor, vec3dConstructor;
|
||||
private static Class<?> vec3dClass;
|
||||
private static boolean isVec3dPresent;
|
||||
private int entityID = -1;
|
||||
private double velocityX, velocityY, velocityZ;
|
||||
private Entity entity;
|
||||
private boolean isListening;
|
||||
|
||||
public WrappedPacketOutEntityVelocity(final Object packet) {
|
||||
super(packet);
|
||||
isListening = true;
|
||||
}
|
||||
|
||||
public WrappedPacketOutEntityVelocity(final Entity entity, final double velocityX, final double velocityY, final double velocityZ) {
|
||||
this.entityID = entity.getEntityId();
|
||||
this.entity = entity;
|
||||
this.velocityX = velocityX;
|
||||
this.velocityY = velocityY;
|
||||
this.velocityZ = velocityZ;
|
||||
}
|
||||
|
||||
public WrappedPacketOutEntityVelocity(int entityID, double velX, double velY, double velZ) {
|
||||
this.entityID = entityID;
|
||||
this.velocityX = velX;
|
||||
this.velocityY = velY;
|
||||
this.velocityZ = velZ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Velocity Constructor parameter types:
|
||||
* 1.7.10 -> 1.13.2 use int, double, double, double style,
|
||||
* 1.14+ use int, Vec3D style
|
||||
*/
|
||||
public static void load() {
|
||||
Class<?> velocityClass = PacketTypeClasses.Server.ENTITY_VELOCITY;
|
||||
if (version.isHigherThan(ServerVersion.v_1_13_2)) {
|
||||
try {
|
||||
vec3dClass = NMSUtils.getNMSClass("Vec3D");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
velocityConstructor = velocityClass.getConstructor(int.class, double.class, double.class, double.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
//That is fine, just a newer version
|
||||
try {
|
||||
velocityConstructor = velocityClass.getConstructor(int.class, vec3dClass);
|
||||
isVec3dPresent = true;
|
||||
//vec3d constructor
|
||||
vec3dConstructor = vec3dClass.getConstructor(double.class, double.class, double.class);
|
||||
} catch (NoSuchMethodException e2) {
|
||||
e2.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup the associated entity by the ID that was sent in the packet.
|
||||
*
|
||||
* @return Entity
|
||||
*/
|
||||
public Entity getEntity() {
|
||||
if (entity != null) {
|
||||
return entity;
|
||||
}
|
||||
return entity = NMSUtils.getEntityById(getEntityId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID of the entity.
|
||||
* If you do not want to use {@link #getEntity()},
|
||||
* you lookup the entity by yourself with this entity ID.
|
||||
*
|
||||
* @return Entity ID
|
||||
*/
|
||||
public int getEntityId() {
|
||||
if (entityID != -1) {
|
||||
return entityID;
|
||||
}
|
||||
return entityID = readInt(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Velocity X
|
||||
*
|
||||
* @return Get Velocity X
|
||||
*/
|
||||
public double getVelocityX() {
|
||||
if (isListening) {
|
||||
return readInt(1) / 8000.0D;
|
||||
} else {
|
||||
return velocityX;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Velocity Y
|
||||
*
|
||||
* @return Get Velocity Y
|
||||
*/
|
||||
public double getVelocityY() {
|
||||
if(isListening) {
|
||||
return readInt(2) / 8000.0D;
|
||||
}
|
||||
else {
|
||||
return velocityY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Velocity Z
|
||||
*
|
||||
* @return Get Velocity Z
|
||||
*/
|
||||
public double getVelocityZ() {
|
||||
if(isListening) {
|
||||
return readInt(3) / 8000.0D;
|
||||
}
|
||||
else {
|
||||
return velocityZ;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object asNMSPacket() {
|
||||
if (!isVec3dPresent) {
|
||||
try {
|
||||
return velocityConstructor.newInstance(entityID, velocityX, velocityY, velocityZ);
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
return velocityConstructor.newInstance(entityID, vec3dConstructor.newInstance(velocityX, velocityY, velocityZ));
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.out.experience;
|
||||
|
||||
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.SendableWrapper;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public class WrappedPacketOutExperience extends WrappedPacket implements SendableWrapper {
|
||||
private static Constructor<?> packetConstructor;
|
||||
public static void load() {
|
||||
try {
|
||||
packetConstructor = PacketTypeClasses.Server.EXPERIENCE.getConstructor(float.class,
|
||||
int.class, int.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private float expBar;
|
||||
private int expLevel, totalExp;
|
||||
|
||||
public WrappedPacketOutExperience(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public WrappedPacketOutExperience(float experienceBar, int experienceLevel,
|
||||
int totalExperience) {
|
||||
this.expBar = experienceBar;
|
||||
this.expLevel = experienceLevel;
|
||||
this.totalExp = totalExperience;
|
||||
}
|
||||
|
||||
public float getExperienceBar() {
|
||||
if (packet == null) {
|
||||
return expBar;
|
||||
} else {
|
||||
//constructor = float, int, int
|
||||
return readFloat(0);
|
||||
}
|
||||
}
|
||||
|
||||
public int getExperienceLevel() {
|
||||
if (packet == null) {
|
||||
return expLevel;
|
||||
} else {
|
||||
return readInt(0);
|
||||
}
|
||||
}
|
||||
|
||||
public int getTotalExperience() {
|
||||
if (packet == null) {
|
||||
return totalExp;
|
||||
} else {
|
||||
return readInt(1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object asNMSPacket() {
|
||||
try {
|
||||
return packetConstructor.newInstance(expBar, expLevel, totalExp);
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+198
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.out.explosion;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.SendableWrapper;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
import io.github.retrooper.packetevents.utils.vector.Vector3i;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class WrappedPacketOutExplosion extends WrappedPacket implements SendableWrapper {
|
||||
private static Constructor<?> chunkPosConstructor, blockPosConstructor, packetConstructor, vec3dConstructor;
|
||||
|
||||
public static void load() {
|
||||
Class<?> chunkPosClass = NMSUtils.getNMSClassWithoutException("ChunkPosition");
|
||||
Class<?> blockPosClass = NMSUtils.getNMSClassWithoutException("BlockPosition");
|
||||
Class<?> packetClass = NMSUtils.getNMSClassWithoutException("PacketPlayOutExplosion");
|
||||
Class<?> vec3DClass = NMSUtils.getNMSClassWithoutException("Vec3D");
|
||||
try {
|
||||
packetConstructor = packetClass.getConstructor(double.class, double.class, double.class, float.class, List.class, vec3DClass);
|
||||
vec3dConstructor = vec3DClass.getDeclaredConstructor(double.class, double.class, double.class);
|
||||
if (chunkPosClass != null) {
|
||||
chunkPosConstructor = chunkPosClass.getConstructor(int.class, int.class, int.class);
|
||||
}
|
||||
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
if (blockPosClass != null) {
|
||||
blockPosConstructor = blockPosClass.getConstructor(int.class, int.class, int.class);
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isListening = false;
|
||||
private double x, y, z;
|
||||
private float strength;
|
||||
private List<Vector3i> records;
|
||||
private float playerMotionX, playerMotionY, playerMotionZ;
|
||||
|
||||
public WrappedPacketOutExplosion(Object packet) {
|
||||
super(packet);
|
||||
isListening = true;
|
||||
}
|
||||
|
||||
public WrappedPacketOutExplosion(double x, double y, double z, float strength, List<Vector3i> records,
|
||||
float playerMotionX, float playerMotionY, float playerMotionZ) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.strength = strength;
|
||||
this.records = records;
|
||||
this.playerMotionX = playerMotionX;
|
||||
this.playerMotionY = playerMotionY;
|
||||
this.playerMotionZ = playerMotionZ;
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
if (isListening) {
|
||||
return readDouble(0);
|
||||
} else {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
if (isListening) {
|
||||
return readDouble(1);
|
||||
} else {
|
||||
return y;
|
||||
}
|
||||
}
|
||||
|
||||
public double getZ() {
|
||||
if (isListening) {
|
||||
return readDouble(2);
|
||||
} else {
|
||||
return z;
|
||||
}
|
||||
}
|
||||
|
||||
public float getStrength() {
|
||||
if (isListening) {
|
||||
return readFloat(0);
|
||||
} else {
|
||||
return strength;
|
||||
}
|
||||
}
|
||||
|
||||
public List<Vector3i> getRecords() {
|
||||
if (isListening) {
|
||||
List<Vector3i> recordsList = new ArrayList<>();
|
||||
List<?> rawRecordsList = (List<?>) readObject(0, List.class);
|
||||
if (rawRecordsList.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
for (Object position : rawRecordsList) {
|
||||
WrappedPacket posWrapper = new WrappedPacket(position);
|
||||
recordsList.add(new Vector3i(posWrapper.readInt(0), posWrapper.readInt(1), posWrapper.readInt(2)));
|
||||
}
|
||||
return recordsList;
|
||||
} else {
|
||||
return records;
|
||||
}
|
||||
}
|
||||
|
||||
public float getPlayerMotionX() {
|
||||
if (isListening) {
|
||||
return readFloat(1);
|
||||
} else {
|
||||
return playerMotionX;
|
||||
}
|
||||
}
|
||||
|
||||
public float getPlayerMotionY() {
|
||||
if (isListening) {
|
||||
return readFloat(2);
|
||||
} else {
|
||||
return playerMotionY;
|
||||
}
|
||||
}
|
||||
|
||||
public float getPlayerMotionZ() {
|
||||
if (isListening) {
|
||||
return readFloat(3);
|
||||
} else {
|
||||
return playerMotionZ;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object asNMSPacket() {
|
||||
if (version.equals(ServerVersion.v_1_7_10)) {
|
||||
List<Object> chunkPositions = new ArrayList<>();
|
||||
for (Vector3i vec : records) {
|
||||
try {
|
||||
chunkPositions.add(chunkPosConstructor.newInstance(vec.x, vec.y, vec.z));
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
try {
|
||||
Object vec = vec3dConstructor.newInstance(playerMotionX, playerMotionY, playerMotionZ);
|
||||
return packetConstructor.newInstance(x, y, z, strength, chunkPositions, vec);
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
} else {
|
||||
List<Object> blockPositions = new ArrayList<>();
|
||||
for (Vector3i vec : records) {
|
||||
try {
|
||||
blockPositions.add(blockPosConstructor.newInstance(vec.x, vec.y, vec.z));
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
try {
|
||||
Object vec = vec3dConstructor.newInstance(playerMotionX, playerMotionY, playerMotionZ);
|
||||
return packetConstructor.newInstance(x, y, z, strength, blockPositions, vec);
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+161
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.out.gamestatechange;
|
||||
|
||||
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.SendableWrapper;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public class WrappedPacketOutGameStateChange extends WrappedPacket implements SendableWrapper {
|
||||
private int reason;
|
||||
private double value;
|
||||
|
||||
private static Constructor<?> packetConstructor, reasonClassConstructor;
|
||||
private static Class<?> reasonClassType;
|
||||
|
||||
private static boolean reasonIntMode;
|
||||
private static boolean valueFloatMode;
|
||||
|
||||
private boolean isListening = false;
|
||||
|
||||
public static void load() {
|
||||
reasonClassType = SubclassUtil.getSubClass(PacketTypeClasses.Server.GAME_STATE_CHANGE, "a");
|
||||
if (reasonClassType != null) {
|
||||
try {
|
||||
reasonClassConstructor = reasonClassType.getConstructor(int.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
reasonIntMode = reasonClassType == null;
|
||||
valueFloatMode = Reflection.getField(PacketTypeClasses.Server.GAME_STATE_CHANGE, double.class, 0) == null;
|
||||
|
||||
try {
|
||||
Class<?> valueClassType;
|
||||
if (valueFloatMode) {
|
||||
valueClassType = float.class;
|
||||
} else {
|
||||
//Just an older version(1.7.10/1.8.x or so)
|
||||
valueClassType = double.class;
|
||||
}
|
||||
if (reasonClassType == null) {
|
||||
reasonClassType = int.class;
|
||||
}
|
||||
packetConstructor = PacketTypeClasses.Server.GAME_STATE_CHANGE.getConstructor(reasonClassType, valueClassType);
|
||||
reasonClassType = null;
|
||||
} catch (NullPointerException e) {
|
||||
Bukkit.getConsoleSender().sendMessage(ChatColor.RED + "PacketEvents failed to find the constructor for the outbound Game state packet wrapper.");
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public WrappedPacketOutGameStateChange(Object packet) {
|
||||
super(packet);
|
||||
isListening = true;
|
||||
}
|
||||
|
||||
public WrappedPacketOutGameStateChange(int reason, double value) {
|
||||
this.reason = reason;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public WrappedPacketOutGameStateChange(int reason, float value) {
|
||||
this(reason, (double) value);
|
||||
}
|
||||
|
||||
public int getReason() {
|
||||
if (isListening) {
|
||||
if (reasonIntMode) {
|
||||
return readInt(0);
|
||||
} else {
|
||||
//this packet is obfuscated quite strongly(1.16), so we must do this
|
||||
Object reasonObject = readObject(12, reasonClassType);
|
||||
try {
|
||||
return Reflection.getField(reasonClassType, int.class, 0).getInt(reasonObject);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return reason;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public double getValue() {
|
||||
if(isListening) {
|
||||
if (valueFloatMode) {
|
||||
return readFloat(0);
|
||||
} else {
|
||||
return readDouble(0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object asNMSPacket() {
|
||||
if (reasonClassType == null) {
|
||||
try {
|
||||
if (valueFloatMode) {
|
||||
return packetConstructor.newInstance(reason, (float) value);
|
||||
} else {
|
||||
return packetConstructor.newInstance(reason, value);
|
||||
}
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
Object reasonObject = null;
|
||||
try {
|
||||
reasonObject = reasonClassConstructor.newInstance(reason);
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
if (valueFloatMode) {
|
||||
return packetConstructor.newInstance(reasonObject, (float) value);
|
||||
} else {
|
||||
return packetConstructor.newInstance(reasonObject, value);
|
||||
}
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.out.helditemslot;
|
||||
|
||||
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.SendableWrapper;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public class WrappedPacketOutHeldItemSlot extends WrappedPacket implements SendableWrapper {
|
||||
private static Constructor<?> packetConstructor;
|
||||
public static void load() {
|
||||
try {
|
||||
packetConstructor = PacketTypeClasses.Server.HELD_ITEM_SLOT.getConstructor(int.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private int slot;
|
||||
public WrappedPacketOutHeldItemSlot(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public WrappedPacketOutHeldItemSlot(int slot) {
|
||||
this.slot = slot;
|
||||
}
|
||||
|
||||
public int getCurrentSelectedSlot() {
|
||||
if(packet == null){
|
||||
return slot;
|
||||
}
|
||||
return readInt(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object asNMSPacket() {
|
||||
try {
|
||||
return packetConstructor.newInstance(slot);
|
||||
} catch (InstantiationException |
|
||||
IllegalAccessException |
|
||||
InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.out.keepalive;
|
||||
|
||||
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.SendableWrapper;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public class WrappedPacketOutKeepAlive extends WrappedPacket implements SendableWrapper {
|
||||
private static Constructor<?> keepAliveConstructor;
|
||||
private static boolean integerMode;
|
||||
private long id;
|
||||
private boolean isListening;
|
||||
|
||||
public WrappedPacketOutKeepAlive(Object packet) {
|
||||
super(packet);
|
||||
isListening = true;
|
||||
}
|
||||
|
||||
public WrappedPacketOutKeepAlive(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
Class<?> packetClass = PacketTypeClasses.Server.KEEP_ALIVE;
|
||||
integerMode = Reflection.getField(packetClass, int.class, 0) != null;
|
||||
|
||||
if (integerMode) {
|
||||
try {
|
||||
keepAliveConstructor = packetClass.getConstructor(int.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
keepAliveConstructor = packetClass.getConstructor(long.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Keep Alive ID.
|
||||
* <p>
|
||||
* You may cast this down to an int if you are on 1.7.10 - 1.12.2.
|
||||
* On 1.13.2 - 1.16.3 a long is sent.
|
||||
*
|
||||
* @return Get Keep Alive ID
|
||||
*/
|
||||
public long getId() {
|
||||
if (isListening) {
|
||||
if (integerMode) {
|
||||
return readInt(0);
|
||||
} else {
|
||||
return readLong(0);
|
||||
}
|
||||
} else {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object asNMSPacket() {
|
||||
if (integerMode) {
|
||||
try {
|
||||
return keepAliveConstructor.newInstance(id);
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
return keepAliveConstructor.newInstance(id);
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.out.kickdisconnect;
|
||||
|
||||
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.SendableWrapper;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.chat.WrappedPacketOutChat;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public final class WrappedPacketOutKickDisconnect extends WrappedPacket implements SendableWrapper {
|
||||
private static Class<?> iChatBaseComponentClass;
|
||||
private static Constructor<?> kickDisconnectConstructor;
|
||||
private String kickMessage;
|
||||
private boolean isListening;
|
||||
|
||||
public WrappedPacketOutKickDisconnect(final Object packet) {
|
||||
super(packet);
|
||||
isListening = true;
|
||||
}
|
||||
|
||||
public WrappedPacketOutKickDisconnect(final String kickMessage) {
|
||||
super();
|
||||
this.kickMessage = kickMessage;
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
Class<?> packetClass = PacketTypeClasses.Server.KICK_DISCONNECT;
|
||||
try {
|
||||
iChatBaseComponentClass = NMSUtils.getNMSClass("IChatBaseComponent");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
kickDisconnectConstructor = packetClass.getConstructor(iChatBaseComponentClass);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the kick message.
|
||||
*
|
||||
* @return Get Kick Message
|
||||
*/
|
||||
public String getKickMessage() {
|
||||
if (isListening) {
|
||||
Object iChatBaseComponentObject = readObject(0, iChatBaseComponentClass);
|
||||
return WrappedPacketOutChat.toStringFromIChatBaseComponent(iChatBaseComponentObject);
|
||||
} else {
|
||||
return kickMessage;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object asNMSPacket() {
|
||||
try {
|
||||
return kickDisconnectConstructor.newInstance(WrappedPacketOutChat.toIChatBaseComponent(WrappedPacketOutChat.fromStringToJSON(kickMessage)));
|
||||
} catch (InstantiationException | InvocationTargetException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.out.position;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
|
||||
public final class WrappedPacketOutPosition extends WrappedPacket {
|
||||
private double x;
|
||||
private double y;
|
||||
private double z;
|
||||
private float yaw;
|
||||
private float pitch;
|
||||
|
||||
private final boolean isListening = true;
|
||||
|
||||
public WrappedPacketOutPosition(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public static void load() {}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
//TODO boolean onGround and flags
|
||||
this.x = readDouble(0);
|
||||
this.y = readDouble(1);
|
||||
this.z = readDouble(2);
|
||||
|
||||
this.yaw = readFloat(0);
|
||||
this.pitch = readFloat(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the X position.
|
||||
* @return Get X Position
|
||||
*/
|
||||
public double getX() {
|
||||
if(isListening) {
|
||||
return readDouble(0);
|
||||
}
|
||||
else {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Y position.
|
||||
* @return Get Y Position
|
||||
*/
|
||||
public double getY() {
|
||||
if(isListening) {
|
||||
return readDouble(1);
|
||||
}
|
||||
else {
|
||||
return y;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Z position.
|
||||
* @return Get Z Position
|
||||
*/
|
||||
public double getZ() {
|
||||
if(isListening) {
|
||||
return readDouble(2);
|
||||
}
|
||||
else {
|
||||
return z;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Yaw.
|
||||
* @return Get Yaw
|
||||
*/
|
||||
public float getYaw() {
|
||||
if(isListening) {
|
||||
return readFloat(0);
|
||||
}
|
||||
else {
|
||||
return yaw;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Pitch,
|
||||
* @return Get Pitch
|
||||
*/
|
||||
public float getPitch() {
|
||||
if(isListening) {
|
||||
return readFloat(1);
|
||||
}
|
||||
else {
|
||||
return pitch;
|
||||
}
|
||||
}
|
||||
}
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.out.transaction;
|
||||
|
||||
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.SendableWrapper;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public class WrappedPacketOutTransaction extends WrappedPacket implements SendableWrapper {
|
||||
private static Constructor<?> packetConstructor;
|
||||
private int windowId;
|
||||
private short actionNumber;
|
||||
private boolean accepted;
|
||||
private boolean isListening = false;
|
||||
public WrappedPacketOutTransaction(final Object packet) {
|
||||
super(packet);
|
||||
isListening = true;
|
||||
}
|
||||
|
||||
public WrappedPacketOutTransaction(final int windowId, final short actionNumber, final boolean accepted) {
|
||||
super();
|
||||
this.windowId = windowId;
|
||||
this.actionNumber = actionNumber;
|
||||
this.accepted = accepted;
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
Class<?> packetClass = PacketTypeClasses.Server.TRANSACTION;
|
||||
|
||||
try {
|
||||
packetConstructor = packetClass.getConstructor(int.class, short.class, boolean.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Window ID.
|
||||
* @return Get Window ID
|
||||
*/
|
||||
public int getWindowId() {
|
||||
if(isListening) {
|
||||
return readInt(0);
|
||||
}
|
||||
else {
|
||||
return windowId;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the action number.
|
||||
* @return Get Action Number
|
||||
*/
|
||||
public short getActionNumber() {
|
||||
if(isListening) {
|
||||
return readShort(0);
|
||||
}
|
||||
else {
|
||||
return actionNumber;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Has the transaction packet been accepted?
|
||||
* @return Is Accepted
|
||||
*/
|
||||
public boolean isAccepted() {
|
||||
if(isListening) {
|
||||
return readBoolean(0);
|
||||
}
|
||||
else {
|
||||
return accepted;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object asNMSPacket() {
|
||||
try {
|
||||
return packetConstructor.newInstance(windowId, actionNumber, accepted);
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.out.updatehealth;
|
||||
|
||||
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.SendableWrapper;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public final class WrappedPacketOutUpdateHealth extends WrappedPacket implements SendableWrapper {
|
||||
private static Constructor<?> packetConstructor;
|
||||
private float health, foodSaturation;
|
||||
private int food;
|
||||
private boolean isListening;
|
||||
|
||||
public WrappedPacketOutUpdateHealth(final Object packet) {
|
||||
super(packet);
|
||||
isListening = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* See https://wiki.vg/Protocol#Update_Health
|
||||
*
|
||||
* @param health 0 or less = dead, 20 = full HP
|
||||
* @param food 0–20
|
||||
* @param foodSaturation Seems to vary from 0.0 to 5.0 in integer increments
|
||||
*/
|
||||
public WrappedPacketOutUpdateHealth(final float health, final int food, final float foodSaturation) {
|
||||
super();
|
||||
this.health = health;
|
||||
this.food = food;
|
||||
this.foodSaturation = foodSaturation;
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
Class<?> packetClass = PacketTypeClasses.Server.UPDATE_HEALTH;
|
||||
|
||||
try {
|
||||
packetConstructor = packetClass.getConstructor(float.class, int.class, float.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get health value.
|
||||
*
|
||||
* @return Get Health
|
||||
*/
|
||||
public float getHealth() {
|
||||
if (isListening) {
|
||||
return readFloat(0);
|
||||
} else {
|
||||
return health;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get food saturation value.
|
||||
*
|
||||
* @return Get Food Saturation
|
||||
*/
|
||||
public float getFoodSaturation() {
|
||||
if (isListening) {
|
||||
return readFloat(1);
|
||||
} else {
|
||||
return foodSaturation;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get food value.
|
||||
*
|
||||
* @return Get Food
|
||||
*/
|
||||
public int getFood() {
|
||||
if(isListening) {
|
||||
return readInt(0);
|
||||
}
|
||||
else {
|
||||
return food;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object asNMSPacket() {
|
||||
try {
|
||||
return packetConstructor.newInstance(health, food, foodSaturation);
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.status;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
|
||||
public class WrappedPacketStatusPing extends WrappedPacket {
|
||||
public WrappedPacketStatusPing(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public long getPayload() {
|
||||
return readLong(0);
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.status;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
|
||||
public class WrappedPacketStatusPong extends WrappedPacket {
|
||||
public WrappedPacketStatusPong(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public long getPayload() {
|
||||
return readLong(0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.settings;
|
||||
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
import net.minecraft.server.v1_8_R3.Packet;
|
||||
|
||||
public class PacketEventsSettings {
|
||||
private ServerVersion backupServerVersion = ServerVersion.v_1_7_10;
|
||||
private boolean injectAsync = true;
|
||||
private boolean ejectAsync = true;
|
||||
private boolean useProtocolLibIfAvailable;
|
||||
private boolean checkForUpdates = true;
|
||||
private boolean injectEarly = true;
|
||||
private int packetHandlingThreadCount = 1;
|
||||
|
||||
public PacketEventsSettings backupServerVersion(ServerVersion serverVersion) {
|
||||
this.backupServerVersion = serverVersion;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public PacketEventsSettings injectAsync(boolean injectAsync) {
|
||||
this.injectAsync = injectAsync;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PacketEventsSettings ejectAsync(boolean ejectAsync) {
|
||||
this.ejectAsync = ejectAsync;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PacketEventsSettings useProtocolLibIfAvailable(boolean useProtocolLibIfAvailable) {
|
||||
this.useProtocolLibIfAvailable = useProtocolLibIfAvailable;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PacketEventsSettings checkForUpdates(boolean checkForUpdates) {
|
||||
this.checkForUpdates = checkForUpdates;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public PacketEventsSettings injectEarly(boolean injectEarly) {
|
||||
this.injectEarly = injectEarly;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PacketEventsSettings packetHandlingThreadCount(int threadCount) {
|
||||
this.packetHandlingThreadCount = threadCount;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ServerVersion getBackupServerVersion() {
|
||||
return backupServerVersion;
|
||||
}
|
||||
|
||||
public boolean shouldInjectAsync() {
|
||||
return injectAsync;
|
||||
}
|
||||
|
||||
public boolean shouldEjectAsync() {
|
||||
return ejectAsync;
|
||||
}
|
||||
|
||||
public boolean shouldUseProtocolLibIfAvailable() {
|
||||
return useProtocolLibIfAvailable;
|
||||
}
|
||||
|
||||
public boolean shouldCheckForUpdates() {
|
||||
return checkForUpdates;
|
||||
}
|
||||
|
||||
public boolean shouldInjectEarly() {
|
||||
return injectEarly;
|
||||
}
|
||||
|
||||
public int getPacketHandlingThreadCount() {
|
||||
return packetHandlingThreadCount;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.updatechecker;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.utils.server.PEVersion;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
|
||||
public class UpdateChecker {
|
||||
public void handleUpdate() {
|
||||
inform("Checking for an update, please wait...");
|
||||
PEVersion localVersion = PacketEvents.getVersion();
|
||||
try {
|
||||
String line = readLatestVersion();
|
||||
PEVersion newVersion = new PEVersion(line);
|
||||
if (localVersion.isOlder(newVersion)) {
|
||||
inform("There is an update available for the PacketEvents API! Your build: (" + localVersion.toString() + ") | Update: (" + newVersion.toString() + ")");
|
||||
}
|
||||
else if(localVersion.equals(newVersion)) {
|
||||
inform("You are on the latest released version of PacketEvents. Your build: (" + newVersion.toString() + ")");
|
||||
}
|
||||
else if(localVersion.isNewer(newVersion)) {
|
||||
inform("You are on a dev or pre released build of PacketEvents. Your build: (" + localVersion.toString() + ") | Last released build: (" + newVersion.toString() + ")");
|
||||
}
|
||||
} catch (IOException exception) {
|
||||
report("We failed to find the latest released version of PacketEvents. Your build: (" + localVersion.toString() + ")");
|
||||
}
|
||||
}
|
||||
|
||||
private void inform(String message) {
|
||||
Bukkit.getLogger().info("[PacketEvents] " + message);
|
||||
}
|
||||
|
||||
private void report(String message) {
|
||||
Bukkit.getLogger().info(ChatColor.DARK_RED + "[PacketEvents] " + message);
|
||||
}
|
||||
|
||||
private String readLatestVersion() throws IOException {
|
||||
URLConnection connection = new URL("https://api.spigotmc.org/legacy/update.php?resource=80279").openConnection();
|
||||
connection.addRequestProperty("User-Agent", "Mozilla/4.0");
|
||||
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||
return reader.readLine();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.utils;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.BlockIterator;
|
||||
|
||||
public class BlockIteratorUtils {
|
||||
public static Block getBlockLookingAt(final Player player, final int distance) {
|
||||
final Location location = player.getEyeLocation();
|
||||
final BlockIterator blocksToAdd = new BlockIterator(location, 0.0D, distance);
|
||||
Block block = null;
|
||||
while (blocksToAdd.hasNext()) {
|
||||
block = blocksToAdd.next();
|
||||
}
|
||||
return block;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.utils.bytebuf;
|
||||
|
||||
import io.github.retrooper.packetevents.packetmanager.netty.NettyPacketManager;
|
||||
|
||||
public class ByteBufUtil {
|
||||
public static Object copiedBuffer(byte[] bytes) {
|
||||
if (NettyPacketManager.v1_7_nettyMode) {
|
||||
return ByteBufUtil_7.copiedBuffer(bytes);
|
||||
} else {
|
||||
return ByteBufUtil_8.copiedBuffer(bytes);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] getBytes(Object byteBuf) {
|
||||
if(NettyPacketManager.v1_7_nettyMode) {
|
||||
return ByteBufUtil_7.getBytes(byteBuf);
|
||||
}
|
||||
else {
|
||||
return ByteBufUtil_8.getBytes(byteBuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.utils.bytebuf;
|
||||
|
||||
import net.minecraft.util.io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.util.io.netty.buffer.Unpooled;
|
||||
|
||||
class ByteBufUtil_7 {
|
||||
public static Object copiedBuffer(byte[] bytes) {
|
||||
return Unpooled.copiedBuffer(bytes);
|
||||
}
|
||||
|
||||
public static byte[] getBytes(Object byteBuf) {
|
||||
ByteBuf bb = (ByteBuf)byteBuf;
|
||||
byte[] bytes;
|
||||
if (bb.hasArray()) {
|
||||
bytes = bb.array();
|
||||
} else {
|
||||
bytes = new byte[bb.readableBytes()];
|
||||
bb.getBytes(bb.readerIndex(), bytes);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.utils.bytebuf;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
|
||||
class ByteBufUtil_8 {
|
||||
public static Object copiedBuffer(byte[] bytes) {
|
||||
return Unpooled.copiedBuffer(bytes);
|
||||
}
|
||||
|
||||
public static byte[] getBytes(Object byteBuf) {
|
||||
ByteBuf bb = (ByteBuf)byteBuf;
|
||||
byte[] bytes;
|
||||
if (bb.hasArray()) {
|
||||
bytes = bb.array();
|
||||
} else {
|
||||
bytes = new byte[bb.readableBytes()];
|
||||
bb.getBytes(bb.readerIndex(), bytes);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
+151
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.utils.entityfinder;
|
||||
|
||||
import io.github.retrooper.packetevents.annotations.Nullable;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public final class EntityFinderUtils {
|
||||
@Nullable
|
||||
public static ServerVersion version;
|
||||
private static Class<?> worldServerClass;
|
||||
private static Class<?> craftWorldClass;
|
||||
private static Class<?> entityClass;
|
||||
private static Method getEntityByIdMethod;
|
||||
private static Method craftWorldGetHandle;
|
||||
private static Method getBukkitEntity;
|
||||
|
||||
private static boolean isServerVersion_v_1_8_x;
|
||||
|
||||
public static void load() {
|
||||
isServerVersion_v_1_8_x = version.isHigherThan(ServerVersion.v_1_7_10) && version.isLowerThan(ServerVersion.v_1_9);
|
||||
try {
|
||||
worldServerClass = NMSUtils.getNMSClass("WorldServer");
|
||||
craftWorldClass = NMSUtils.getOBCClass("CraftWorld");
|
||||
entityClass = NMSUtils.getNMSClass("Entity");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
getEntityByIdMethod = worldServerClass.getMethod(getEntityByIDMethodName(), int.class);
|
||||
craftWorldGetHandle = craftWorldClass.getMethod("getHandle");
|
||||
getBukkitEntity = entityClass.getMethod("getBukkitEntity");
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static Object getNMSEntityById(final int id) {
|
||||
for (final World world : Bukkit.getWorlds()) {
|
||||
final Object entity = getNMSEntityByIdWithWorld(world, id);
|
||||
if (entity != null) {
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an entity by their ID.
|
||||
*
|
||||
* @param id
|
||||
* @return Entity
|
||||
*/
|
||||
public static Entity getEntityById(final int id) {
|
||||
Object nmsEntity = getNMSEntityById(id);
|
||||
try {
|
||||
return (Entity) getBukkitEntity.invoke(nmsEntity);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Object getNMSEntityByIdWithWorld(final World world, final int id) {
|
||||
if (world == null) {
|
||||
return null;
|
||||
} else if (craftWorldClass == null) {
|
||||
throw new IllegalStateException("PacketEvents failed to locate the CraftWorld class.");
|
||||
}
|
||||
Object craftWorld = craftWorldClass.cast(world);
|
||||
|
||||
Object worldServer = null;
|
||||
try {
|
||||
worldServer = craftWorldGetHandle.invoke(craftWorld);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Object nmsEntity = null;
|
||||
try {
|
||||
nmsEntity = getEntityByIdMethod.invoke(worldServer, id);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return nmsEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an entity by their ID, guaranteed to be in the specified world.
|
||||
*
|
||||
* @param world
|
||||
* @param id
|
||||
* @return Entity
|
||||
*/
|
||||
@Nullable
|
||||
public static Entity getEntityByIdWithWorld(final World world, final int id) {
|
||||
Object nmsEntity = getNMSEntityByIdWithWorld(world, id);
|
||||
if (nmsEntity == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return (Entity) getBukkitEntity.invoke(nmsEntity);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the name of the method that returns the NMS entity when you pass in its ID.
|
||||
* On 1.8-1.8.8 the function name is called 'a', on 1.7.10 and 1.9 and above the name is called 'getEntity'.
|
||||
*
|
||||
* @return entity by ID method name
|
||||
*/
|
||||
public static String getEntityByIDMethodName() {
|
||||
if (isServerVersion_v_1_8_x) {
|
||||
return "a";
|
||||
}
|
||||
return "getEntity";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.utils.gameprofile;
|
||||
|
||||
import io.github.retrooper.packetevents.packetmanager.netty.NettyPacketManager;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class GameProfileUtil {
|
||||
public static Object getGameProfile(UUID uuid, String username) {
|
||||
if(NettyPacketManager.v1_7_nettyMode) {
|
||||
return GameProfileUtil_7.getGameProfile(uuid, username);
|
||||
}
|
||||
else {
|
||||
return GameProfileUtil_8.getGameProfile(uuid, username);
|
||||
}
|
||||
}
|
||||
|
||||
public static WrappedGameProfile getWrappedGameProfile(Object gameProfile) {
|
||||
if(NettyPacketManager.v1_7_nettyMode) {
|
||||
return GameProfileUtil_7.getWrappedGameProfile(gameProfile);
|
||||
}
|
||||
else {
|
||||
return GameProfileUtil_8.getWrappedGameProfile(gameProfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loaded 100 of 199 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user