Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
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,339 +1,21 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
MIT License
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
Copyright (c) 2020 retrooper
|
||||
|
||||
Preamble
|
||||
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 licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
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
|
||||
this service 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 make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. 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.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
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
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the 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 a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE 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.
|
||||
|
||||
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
|
||||
convey 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 2 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, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision 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, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This 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.
|
||||
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,30 +1,20 @@
|
||||
# packetevents by retrooper
|
||||
# packetevents
|
||||
|
||||
A lightweight spigot packetlistener & packetsender coded by retrooper.
|
||||
A spigot packet API with some nice utlities.
|
||||
|
||||
## Credit
|
||||
|
||||
PacketEvents uses [TinyProtocol](https://github.com/dmulloy2/ProtocolLib/blob/master/TinyProtocol)'s [Reflection](https://github.com/dmulloy2/ProtocolLib/blob/master/TinyProtocol/src/main/java/com/comphenix/tinyprotocol/Reflection.java) util class.
|
||||
|
||||
[Find it here in our source](https://github.com/retrooper/packetevents/blob/master/src/main/java/io/github/retrooper/packetevents/reflectionutils/Reflection.java)
|
||||
|
||||
PacketEvents forked [Atlas](https://github.com/funkemunky/Atlas)' [Packet](https://github.com/funkemunky/Atlas/blob/master/AtlasParent/Atlas/src/main/java/cc/funkemunky/api/tinyprotocol/api/Packet.java) class.
|
||||
|
||||
[Find our forked version](https://github.com/retrooper/packetevents/blob/master/src/main/java/io/github/retrooper/packetevents/packet/PacketType.java)
|
||||
## About
|
||||
|
||||
This packetlistener is **only** supported on spigot servers and has been tested to work on these spigot forks: PaperSpigot, Tuinity
|
||||
|
||||
* No dependencies
|
||||
|
||||
* Licensed under the GPL2 license.
|
||||
* Licensed under the MIT license
|
||||
|
||||
[](https://www.gnu.org/licenses/gpl-2.0)
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
|
||||
Join my discord server(to talk to me): https://discord.gg/ZWTkg4v
|
||||
Our discord server: https://discord.me/packetevents
|
||||
|
||||
[](https://jitpack.io/#retrooper/packetevents)
|
||||
|
||||
To learn how to setup this API please click on the link below
|
||||
[Setup Guide](https://github.com/retrooper/packetevents/wiki/PacketEvents-Setup-Guide)
|
||||
(or just paste this into your browser: https://github.com/retrooper/packetevents/wiki/PacketEvents-Setup-Guide)
|
||||
[](https://jitci.com/gh/retrooper/packetevents)
|
||||
|
||||
@@ -6,42 +6,48 @@
|
||||
|
||||
<groupId>io.github.retrooper</groupId>
|
||||
<artifactId>packetevents</artifactId>
|
||||
<version>1.3.5.2</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.6.8</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>
|
||||
@@ -60,22 +66,35 @@
|
||||
<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.7.10</artifactId>
|
||||
<version>1.7.10</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>
|
||||
@@ -90,11 +109,10 @@
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
<version>4.1.50.Final</version>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.8.8-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -1,275 +1,218 @@
|
||||
/*
|
||||
* 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.annotations.NotNull;
|
||||
import io.github.retrooper.packetevents.annotations.Nullable;
|
||||
import io.github.retrooper.packetevents.annotations.PacketHandler;
|
||||
import io.github.retrooper.packetevents.enums.ClientVersion;
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.event.PacketListener;
|
||||
import io.github.retrooper.packetevents.event.impl.*;
|
||||
import io.github.retrooper.packetevents.event.manager.EventManager;
|
||||
import io.github.retrooper.packetevents.handler.NettyPacketHandler;
|
||||
import io.github.retrooper.packetevents.packet.Packet;
|
||||
import io.github.retrooper.packetevents.packet.PacketType;
|
||||
import io.github.retrooper.packetevents.packetwrappers.Sendable;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import io.github.retrooper.packetevents.event.impl.BukkitMoveEvent;
|
||||
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.settings.PacketEventsSettings;
|
||||
import io.github.retrooper.packetevents.utils.entityfinder.EntityFinderUtils;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
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.PlayerMoveEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
|
||||
public final class PacketEvents implements PacketListener, Listener {
|
||||
|
||||
private static final ServerVersion version = ServerVersion.getVersion();
|
||||
private static final EventManager eventManager = new EventManager();
|
||||
private static boolean hasRegistered;
|
||||
private static PacketEvents instance;
|
||||
private static int currentTick;
|
||||
private static BukkitTask serverTickTask;
|
||||
|
||||
private static final HashMap<UUID, ClientVersion> clientVersionsMap = new HashMap<UUID, ClientVersion>();
|
||||
|
||||
public static EventManager getEventManager() {
|
||||
return eventManager;
|
||||
}
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
|
||||
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<Plugin>(1);
|
||||
private static boolean loaded, initialized, isBungee;
|
||||
|
||||
/**
|
||||
* Starts the server tick task and initiates the TinyProtocolHandler
|
||||
*
|
||||
* @param plugin
|
||||
*/
|
||||
public static void start(final Plugin plugin) {
|
||||
if (!hasRegistered) {
|
||||
//Register Bukkit and PacketListener
|
||||
getEventManager().registerListener(getInstance());
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(getInstance(), plugin);
|
||||
|
||||
//Start the server tick task
|
||||
final Runnable tickRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
getEventManager().callEvent(new ServerTickEvent(currentTick++, PacketEvents.highlyPreciseMillis()));
|
||||
}
|
||||
};
|
||||
serverTickTask = Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, tickRunnable, 0L, 1L);
|
||||
hasRegistered = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop all tasks and unregisters all PacketEvents' listeners
|
||||
*/
|
||||
public static void stop() {
|
||||
if (serverTickTask != null) {
|
||||
serverTickTask.cancel();
|
||||
}
|
||||
getEventManager().unregisterAllListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the server's version
|
||||
*
|
||||
* @return version
|
||||
*/
|
||||
public static ServerVersion getServerVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the server tick task, you may cancel it if you wish.
|
||||
* To cancel it do PacketEvents.getServerTickTask().cancel();
|
||||
* This loads the PacketEvents API.
|
||||
* <p>
|
||||
* This bukkit task runs asynchronously every tick and is started in the start(plugin) function
|
||||
*
|
||||
* @return serverTickTask
|
||||
* 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 BukkitTask getServerTickTask() {
|
||||
return serverTickTask;
|
||||
public static void load() {
|
||||
ServerVersion version = ServerVersion.getVersion();
|
||||
WrappedPacket.version = version;
|
||||
PacketEvent.version = version;
|
||||
NMSUtils.version = version;
|
||||
EntityFinderUtils.version = version;
|
||||
|
||||
NMSUtils.load();
|
||||
|
||||
PacketTypeClasses.Client.load();
|
||||
PacketTypeClasses.Server.load();
|
||||
|
||||
EntityFinderUtils.load();
|
||||
|
||||
ClientVersion.prepareLookUp();
|
||||
|
||||
WrappedPacket.loadAllWrappers();
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of the PacketEvents API class
|
||||
* Initiates PacketEvents
|
||||
* <p>
|
||||
* Loading:
|
||||
* Loads PacketEvents if you haven't already.
|
||||
* <p>
|
||||
* Registering:
|
||||
* Registers this class as a Bukkit listener to inject/eject players.
|
||||
*
|
||||
* @return instance
|
||||
* @param pl JavaPlugin instance
|
||||
*/
|
||||
public static PacketEvents getInstance() {
|
||||
return instance == null ? instance = new PacketEvents() : instance;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the server's recent TPS values
|
||||
* TPS stands for ticks per second.
|
||||
* See to learn more about TPS<a href="https://apexminecrafthosting.com/what-is-minecraft-tps/">"https://apexminecrafthosting.com/what-is-minecraft-tps/"</a>
|
||||
*
|
||||
* @return recentTPS[]
|
||||
*/
|
||||
public static double[] getRecentServerTPS() {
|
||||
double[] tpsArray = new double[0];
|
||||
try {
|
||||
tpsArray = NMSUtils.recentTPS();
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
public static void init(final Plugin pl) {
|
||||
if (!loaded) {
|
||||
load();
|
||||
}
|
||||
if (!initialized) {
|
||||
plugins.add(pl);
|
||||
//Register Bukkit listener
|
||||
Bukkit.getPluginManager().registerEvents(instance, plugins.get(0));
|
||||
|
||||
for (final Player p : Bukkit.getOnlinePlayers()) {
|
||||
getAPI().getPlayerUtils().injectPlayer(p);
|
||||
}
|
||||
initialized = true;
|
||||
|
||||
Class<?> spigotConfigClass;
|
||||
try {
|
||||
spigotConfigClass = Class.forName("org.spigotmc.SpigotConfig");
|
||||
Field f = spigotConfigClass.getDeclaredField("bungee");
|
||||
isBungee = f.getBoolean(null);
|
||||
} catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
|
||||
isBungee = false;
|
||||
}
|
||||
}
|
||||
return tpsArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the server's current TPS
|
||||
* TPS stands for ticks per second.
|
||||
* See to learn more about TPS <a href="https://apexminecrafthosting.com/what-is-minecraft-tps/">"https://apexminecrafthosting.com/what-is-minecraft-tps/"</a>
|
||||
* Loads PacketEvents if you haven't already, Sets everything up, injects all players
|
||||
*
|
||||
* @return {@link PacketEvents#getRecentServerTPS()[0]}
|
||||
*/
|
||||
public static double getCurrentServerTPS() {
|
||||
return getRecentServerTPS()[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player's ping.
|
||||
* Learn more about ping <a href="https://en.wikipedia.org/wiki/Ping_(networking_utility)">https://en.wikipedia.org/wiki/Ping_(networking_utility)</a>
|
||||
*
|
||||
* @param player
|
||||
* @return ping
|
||||
*/
|
||||
public static int getPing(@NotNull final Player player) {
|
||||
return NMSUtils.getPlayerPing(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* When to use this(nano / 1 million) over {@link System#currentTimeMillis()}
|
||||
* This is preciser than System.currentTimeMillis(), System.currentTimeMillis() can be up to 50ms off on some operating systems, but using this isn't cheap.
|
||||
* Java documentation recommend using nano time if you are measuring elapsed time.
|
||||
* In this function nanoTime is divided by 1 million giving us milliseconds.
|
||||
* It is also important to mention that using this method doesn't guarantee thread safety.
|
||||
*
|
||||
* @return nanoTime / 1 million
|
||||
*/
|
||||
public static long highlyPreciseMillis() {
|
||||
return System.nanoTime() / 1000000;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is deprecated, use {@link #highlyPreciseMillis()} as they do the same thing, I just renamed the method.
|
||||
* @param pl Plugin instance
|
||||
* @deprecated Use {@link #init(Plugin)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static long currentCalculatedMS() {
|
||||
return System.nanoTime() / 1000000;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the player's version.
|
||||
* Do not call this method in the PlayerInjectEvent, it is safe to call it in the PostPlayerInjectEvent.
|
||||
* The EntityPlayer object is null at that time, resulting in the version lookup to fail.
|
||||
*
|
||||
* @param player
|
||||
* @return ClientVersion
|
||||
*/
|
||||
|
||||
@Nullable
|
||||
public static ClientVersion getClientVersion(@NotNull final Player player) {
|
||||
return getClientVersion(player.getUniqueId());
|
||||
}
|
||||
|
||||
public static ClientVersion getClientVersion(@NotNull final UUID uuid) {
|
||||
return clientVersionsMap.get(uuid);
|
||||
public static void start(final Plugin pl) {
|
||||
init(pl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Version independent player injection
|
||||
*
|
||||
* @param player
|
||||
*/
|
||||
public static void injectPlayer(final Player player) {
|
||||
final PlayerInjectEvent injectEvent = new PlayerInjectEvent(player);
|
||||
PacketEvents.getEventManager().callEvent(injectEvent);
|
||||
if (!injectEvent.isCancelled()) {
|
||||
PacketEvents.getEventManager().callEvent(new PostPlayerInjectEvent(player));
|
||||
NettyPacketHandler.injectPlayer(player);
|
||||
public static void stop() {
|
||||
if (initialized) {
|
||||
for (final Player p : Bukkit.getOnlinePlayers()) {
|
||||
getAPI().getPlayerUtils().ejectPlayer(p);
|
||||
}
|
||||
getAPI().getEventManager().unregisterAllListeners();
|
||||
|
||||
initialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Version independant player injection
|
||||
*
|
||||
* @param player
|
||||
*/
|
||||
public static void uninjectPlayer(final Player player) {
|
||||
final PlayerUninjectEvent uninjectEvent = new PlayerUninjectEvent(player);
|
||||
PacketEvents.getEventManager().callEvent(uninjectEvent);
|
||||
if(!uninjectEvent.isCancelled()) {
|
||||
NettyPacketHandler.uninjectPlayer(player);
|
||||
}
|
||||
public static boolean hasLoaded() {
|
||||
return loaded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether we have injected the player
|
||||
*
|
||||
* @param player
|
||||
* @return hasInjected
|
||||
*/
|
||||
public static boolean hasInjected(final Player player) {
|
||||
return NettyPacketHandler.hasInjected(player);
|
||||
@Deprecated
|
||||
public static boolean hasStarted() {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a wrapped sendable packet to a player
|
||||
*
|
||||
* @param player
|
||||
* @param sendable
|
||||
*/
|
||||
public static void sendPacket(final Player player, final Sendable sendable) {
|
||||
NMSUtils.sendSendableWrapper(player, sendable);
|
||||
public static boolean isInitialized() {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not check the client version in or before the PlayerInjectEvent, use the PostPlayerInjectEvent.
|
||||
* It is not recommended to do much in the PlayerInjectEvent, as some fields in the Player object are be null.
|
||||
* Use the PostPlayerInjectEvent which is only called after the PlayerJoinEvent if the player was injected.
|
||||
*
|
||||
* @param e
|
||||
*/
|
||||
@PacketHandler
|
||||
public void onInject(final PlayerInjectEvent e) {
|
||||
clientVersionsMap.put(e.getPlayer().getUniqueId(), e.getClientVersion());
|
||||
public static PacketEventsAPI getAPI() {
|
||||
return packetEventsAPI;
|
||||
}
|
||||
|
||||
@PacketHandler
|
||||
public void onReceive(final PacketReceiveEvent e) {
|
||||
@Deprecated
|
||||
public static Plugin getPlugin() {
|
||||
return plugins.get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated, please do not use this anymore
|
||||
*
|
||||
* @param e
|
||||
*/
|
||||
@PacketHandler
|
||||
public void onPostInject(final PostPlayerInjectEvent e) {
|
||||
public static ArrayList<Plugin> getPlugins() {
|
||||
return plugins;
|
||||
}
|
||||
|
||||
public static String getHandlerName(final String name) {
|
||||
return "pe-" + PacketEvents.getAPI().getSettings().getIdentifier() + "-" + name;
|
||||
}
|
||||
|
||||
public static PacketEventsSettings getSettings() {
|
||||
return PacketEvents.getAPI().getSettings();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(final PlayerJoinEvent e) {
|
||||
if (!hasInjected(e.getPlayer())) {
|
||||
injectPlayer(e.getPlayer());
|
||||
|
||||
if (!VersionLookupUtils.hasLoaded()) {
|
||||
VersionLookupUtils.load();
|
||||
}
|
||||
//for now we don't support bungee, rather handle it than have it FALSE
|
||||
//and return the version of the server.
|
||||
if (isBungee) {
|
||||
PacketEvents.getAPI().getPlayerUtils().clientVersionsMap.put(e.getPlayer().getUniqueId(), ClientVersion.ACCESS_FAILURE);
|
||||
} else {
|
||||
ClientVersion version = ClientVersion.fromProtocolVersion(VersionLookupUtils.getProtocolVersion(e.getPlayer()));
|
||||
PacketEvents.getAPI().getPlayerUtils().clientVersionsMap.put(e.getPlayer().getUniqueId(), version);
|
||||
PacketEvents.getAPI().getPlayerUtils().injectPlayer(e.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onMove(final PlayerMoveEvent e) {
|
||||
PacketEvents.getEventManager().callEvent(new BukkitMoveEvent(e));
|
||||
public void onQuit(final PlayerQuitEvent e) {
|
||||
PacketEvents.getAPI().getPlayerUtils().ejectPlayer(e.getPlayer());
|
||||
PacketEvents.getAPI().getPlayerUtils().clientVersionsMap.remove(e.getPlayer().getUniqueId());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onMove(final PlayerMoveEvent e) {
|
||||
BukkitMoveEvent moveEvent = new BukkitMoveEvent(e);
|
||||
PacketEvents.getAPI().getEventManager().callEvent(moveEvent);
|
||||
e.setCancelled(moveEvent.isCancelled());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
import io.github.retrooper.packetevents.event.manager.EventManager;
|
||||
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();
|
||||
private final PacketEventsSettings settings = new PacketEventsSettings();
|
||||
//private final UpdateChecker updateChecker = new UpdateChecker();
|
||||
|
||||
/**
|
||||
* Not thread safe
|
||||
* Preciser than #currentMillis()
|
||||
* Expensive
|
||||
* Returns crazy values when you change system time
|
||||
*
|
||||
* @return {@link System#nanoTime()} / 1000000(1 million)
|
||||
*/
|
||||
@Deprecated
|
||||
public long currentPreciseMillis() {
|
||||
return System.nanoTime() / 1000000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Thread safe
|
||||
* Less precise compared to #currentPreciseMillis()
|
||||
* Cheap
|
||||
* Doesn't break when system time is changed
|
||||
*
|
||||
* @return {@link System#currentTimeMillis()}
|
||||
*/
|
||||
@Deprecated
|
||||
public long currentMillis() {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the PacketEvents settings.
|
||||
*
|
||||
* @return Configure some settings for the API
|
||||
*/
|
||||
public PacketEventsSettings getSettings() {
|
||||
return settings;
|
||||
}
|
||||
/*
|
||||
/**
|
||||
* Get the update checker
|
||||
* @return Update Checker
|
||||
*
|
||||
public UpdateChecker getUpdateChecker() {
|
||||
return updateChecker;
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -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 {
|
||||
}
|
||||
@@ -1,3 +1,27 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
|
||||
@@ -6,7 +30,7 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* Is for sure not null.
|
||||
* Guaranteed to not be null.
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
|
||||
@@ -1,3 +1,27 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
|
||||
@@ -6,7 +30,7 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* Could be null.
|
||||
* Possible that it is null.
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
|
||||
@@ -1,5 +1,33 @@
|
||||
/*
|
||||
* 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 io.github.retrooper.packetevents.enums.EventSynchronization;
|
||||
import io.github.retrooper.packetevents.enums.PacketEventPriority;
|
||||
import org.bukkit.event.EventHandler;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@@ -7,11 +35,10 @@ import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
/**
|
||||
* Just like Bukkit's @EventHandler, but for packets.
|
||||
* Make sure your class implements the PacketListener interface, and is registered!
|
||||
*/
|
||||
|
||||
public @interface PacketHandler {
|
||||
@Deprecated
|
||||
EventSynchronization synchronization() default EventSynchronization.NORMAL;
|
||||
|
||||
|
||||
byte priority() default PacketEventPriority.NORMAL;
|
||||
}
|
||||
@@ -1,77 +1,107 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public enum ClientVersion {
|
||||
LESS_THAN_V_1_7_10, v_1_7_10, v_1_8, v_1_9, v_1_9_1, v_1_9_2, v_1_9_3, v_1_10, v_1_11, v_1_11_1, v_1_12, v_1_12_1, v_1_12_2,
|
||||
v_1_13, v_1_13_1, v_1_13_2, v_1_14, v_1_14_1, v_1_14_2, v_1_14_3, v_1_14_4, v_1_15, v_1_15_1, v_1_15_2, HIGHER_THAN_V_1_15_2, INVALID, ACCESS_FAILURE;
|
||||
v_1_13, v_1_13_1, v_1_13_2, v_1_14, v_1_14_1, v_1_14_2, v_1_14_3, v_1_14_4, v_1_15_PRE_1, v_1_15_PRE_2, v_1_15_PRE_3, v_1_15_PRE_4, v_1_15_PRE_5, v_1_15_PRE_6, v_1_15_PRE_7,
|
||||
v_1_15, v_1_15_1, v_1_15_2, v_1_16, v_1_16_PRE_1, v_1_16_PRE_2, v_1_16_PRE_3, v_1_16_PRE_4, v_1_16_PRE_5, v_1_16_PRE_6, v_1_16_PRE_7, v_1_16_PRE_8, v_1_16_RC_1, v_1_16_1, v_1_16_2, HIGHER_THAN_V_1_16_2, INVALID, ACCESS_FAILURE;
|
||||
|
||||
public static ClientVersion fromProtocolVersion(final int protocolVersion) {
|
||||
int remainder = -1;
|
||||
switch (protocolVersion) {
|
||||
case -1:
|
||||
return ACCESS_FAILURE;
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
return LESS_THAN_V_1_7_10;
|
||||
case 47://ranging from 1.8->1.8.9
|
||||
return v_1_8;
|
||||
case 107:
|
||||
return v_1_9;
|
||||
case 108:
|
||||
return v_1_9_1;
|
||||
case 109:
|
||||
return v_1_9_2;
|
||||
case 110:
|
||||
return v_1_9_3; //can be 1.9.3 or 1.9.4
|
||||
case 210:
|
||||
return v_1_10; //could be 1.10,1.10.1, 1.10.2
|
||||
case 315:
|
||||
return v_1_11;
|
||||
case 316: //could be 11.1 or 11.2
|
||||
return v_1_11_1;
|
||||
case 335:
|
||||
return v_1_12;
|
||||
case 338:
|
||||
return v_1_12_1;
|
||||
case 340:
|
||||
return v_1_12_2;
|
||||
case 393:
|
||||
return v_1_13;
|
||||
case 401:
|
||||
return v_1_13_1;
|
||||
case 404:
|
||||
return v_1_13_2;
|
||||
case 477:
|
||||
return v_1_14;
|
||||
case 480:
|
||||
return v_1_14_1;
|
||||
case 485:
|
||||
return v_1_14_2;
|
||||
case 490:
|
||||
return v_1_14_3;
|
||||
case 498:
|
||||
return v_1_14_4;
|
||||
case 573:
|
||||
return v_1_15;
|
||||
case 575:
|
||||
return v_1_15_1;
|
||||
case 578:
|
||||
return v_1_15_2;
|
||||
default:
|
||||
remainder = protocolVersion;
|
||||
private static final Map<Integer, ClientVersion> VERSION_LOOKUP = new HashMap<Integer, ClientVersion>();
|
||||
|
||||
public static void prepareLookUp() {
|
||||
VERSION_LOOKUP.put(-1, ACCESS_FAILURE);
|
||||
VERSION_LOOKUP.put(1, LESS_THAN_V_1_7_10);
|
||||
VERSION_LOOKUP.put(2, LESS_THAN_V_1_7_10);
|
||||
VERSION_LOOKUP.put(3, LESS_THAN_V_1_7_10);
|
||||
VERSION_LOOKUP.put(4, LESS_THAN_V_1_7_10);
|
||||
VERSION_LOOKUP.put(5, v_1_7_10);
|
||||
VERSION_LOOKUP.put(47, v_1_8);
|
||||
VERSION_LOOKUP.put(107, v_1_9);
|
||||
VERSION_LOOKUP.put(108, v_1_9_1);
|
||||
VERSION_LOOKUP.put(109, v_1_9_2);
|
||||
VERSION_LOOKUP.put(110, v_1_9_3);
|
||||
VERSION_LOOKUP.put(210, v_1_10);
|
||||
VERSION_LOOKUP.put(315, v_1_11);
|
||||
VERSION_LOOKUP.put(316, v_1_11_1);
|
||||
VERSION_LOOKUP.put(335, v_1_12);
|
||||
VERSION_LOOKUP.put(338, v_1_12_1);
|
||||
VERSION_LOOKUP.put(340, v_1_12_2);
|
||||
VERSION_LOOKUP.put(393, v_1_13);
|
||||
VERSION_LOOKUP.put(401, v_1_13_1);
|
||||
VERSION_LOOKUP.put(404, v_1_13_2);
|
||||
VERSION_LOOKUP.put(477, v_1_14);
|
||||
VERSION_LOOKUP.put(480, v_1_14_1);
|
||||
VERSION_LOOKUP.put(485, v_1_14_2);
|
||||
VERSION_LOOKUP.put(490, v_1_14_3);
|
||||
VERSION_LOOKUP.put(498, v_1_14_4);
|
||||
VERSION_LOOKUP.put(565, v_1_15_PRE_1);
|
||||
VERSION_LOOKUP.put(566, v_1_15_PRE_2);
|
||||
VERSION_LOOKUP.put(567, v_1_15_PRE_3);
|
||||
VERSION_LOOKUP.put(569, v_1_15_PRE_4);
|
||||
VERSION_LOOKUP.put(570, v_1_15_PRE_5);
|
||||
VERSION_LOOKUP.put(571, v_1_15_PRE_6);
|
||||
VERSION_LOOKUP.put(572, v_1_15_PRE_7);
|
||||
VERSION_LOOKUP.put(573, v_1_15);
|
||||
VERSION_LOOKUP.put(575, v_1_15_1);
|
||||
VERSION_LOOKUP.put(578, v_1_15_2);
|
||||
VERSION_LOOKUP.put(721, v_1_16_PRE_1);
|
||||
VERSION_LOOKUP.put(722, v_1_16_PRE_2);
|
||||
VERSION_LOOKUP.put(725, v_1_16_PRE_3);
|
||||
VERSION_LOOKUP.put(727, v_1_16_PRE_4);
|
||||
VERSION_LOOKUP.put(729, v_1_16_PRE_5);
|
||||
VERSION_LOOKUP.put(730, v_1_16_PRE_6);
|
||||
VERSION_LOOKUP.put(732, v_1_16_PRE_7);
|
||||
VERSION_LOOKUP.put(733, v_1_16_PRE_8);
|
||||
VERSION_LOOKUP.put(734, v_1_16_RC_1);
|
||||
VERSION_LOOKUP.put(735, v_1_16);
|
||||
VERSION_LOOKUP.put(736, v_1_16_1);
|
||||
VERSION_LOOKUP.put(737, v_1_16_2);
|
||||
}
|
||||
|
||||
public static ClientVersion fromProtocolVersion(int protocolVersion) {
|
||||
if (protocolVersion == -1 && PacketEvents.getSettings().doAutoResolveClientProtocolVersion()) {
|
||||
protocolVersion = ServerVersion.getVersion().toProtocolVersion();
|
||||
}
|
||||
if (remainder > 578) {
|
||||
return HIGHER_THAN_V_1_15_2;
|
||||
final ClientVersion lookedUp = VERSION_LOOKUP.get(protocolVersion);
|
||||
if (lookedUp != null) {
|
||||
return lookedUp;
|
||||
}
|
||||
return INVALID;
|
||||
return protocolVersion > 737 ? HIGHER_THAN_V_1_16_2 : INVALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the client's version is more up to date than the argument passed version
|
||||
*
|
||||
* @param version
|
||||
* @return
|
||||
* @param version The version to compare to the client's value.
|
||||
* @return True if the supplied version is lower, false if it is equal or higher than the client's version.
|
||||
*/
|
||||
public boolean isHigherThan(final ClientVersion version) {
|
||||
if (this == version) return false;
|
||||
@@ -81,14 +111,14 @@ public enum ClientVersion {
|
||||
/**
|
||||
* Returns if the client's version is more outdated than the argument passed version
|
||||
*
|
||||
* @param version
|
||||
* @return
|
||||
* @param version The version to compare to the client's value.
|
||||
* @return True if the supplied version is higher, false if it is equal or lower than the client's version.
|
||||
*/
|
||||
public boolean isLowerThan(final ClientVersion version) {
|
||||
if (version == this) return false;
|
||||
byte len = (byte) values().length;
|
||||
if (this == version) return false;
|
||||
final int len = ClientVersion.values().length;
|
||||
for (byte i = 0; i < len; i++) {
|
||||
final ClientVersion v = values()[i];
|
||||
final ClientVersion v = ClientVersion.values()[i];
|
||||
if (v == this) {
|
||||
return true;
|
||||
} else if (v == version) {
|
||||
|
||||
@@ -1,3 +1,27 @@
|
||||
/*
|
||||
* 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 {
|
||||
@@ -9,7 +33,7 @@ public enum Direction {
|
||||
SOUTH_SOUTH_EAST, SOUTH_SOUTH_WEST,
|
||||
WEST_SOUTH_WEST, SELF, NULL;
|
||||
|
||||
public static Direction get(final byte i) {
|
||||
public static Direction get(final int i) {
|
||||
return values()[i];
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package io.github.retrooper.packetevents.enums;
|
||||
|
||||
public enum EntityAnimationType {
|
||||
SWING_MAIN_ARM, DAMAGE, LEAVE_BED, SWING_OFFHAND, CRITICAL_EFFECT, MAGIC_CRITICAL_EFFECT;
|
||||
|
||||
public static final EntityAnimationType get(final int i) {
|
||||
return values()[i];
|
||||
}
|
||||
|
||||
public final int getIndex() {
|
||||
for (int i = 0; i < values().length; i++) {
|
||||
final EntityAnimationType curType = values()[0];
|
||||
if (curType == this) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package io.github.retrooper.packetevents.enums;
|
||||
|
||||
public enum EntityUseAction {
|
||||
INTERACT, INTERACT_AT, ATTACK, INVALID;
|
||||
|
||||
public static EntityUseAction get(final byte i) {
|
||||
return values()[i];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
@Deprecated
|
||||
public enum EventSynchronization {
|
||||
NORMAL, FORCE_SYNC, FORCE_ASYNC
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
package io.github.retrooper.packetevents.enums;
|
||||
|
||||
public enum Hand {
|
||||
MAIN_HAND,
|
||||
OFF_HAND
|
||||
}
|
||||
@@ -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.enums;
|
||||
@Deprecated
|
||||
public interface PacketEventPriority {
|
||||
byte LOWEST = 0;
|
||||
byte LOW = 1;
|
||||
byte NORMAL = 2;
|
||||
byte HIGH = 3;
|
||||
byte HIGHEST = 4;
|
||||
byte MONITOR = 5;
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package io.github.retrooper.packetevents.enums;
|
||||
|
||||
public enum PlayerAction {
|
||||
START_SNEAKING,
|
||||
|
||||
STOP_SNEAKING,
|
||||
|
||||
STOP_SLEEPING,
|
||||
|
||||
START_SPRINTING,
|
||||
|
||||
STOP_SPRINTING,
|
||||
|
||||
START_RIDING_JUMP,
|
||||
|
||||
STOP_RIDING_JUMP,
|
||||
|
||||
OPEN_INVENTORY,
|
||||
|
||||
START_FALL_FLYING;
|
||||
|
||||
public static PlayerAction get(final byte i) {
|
||||
return values()[i];
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package io.github.retrooper.packetevents.enums;
|
||||
|
||||
public enum PlayerDigType {
|
||||
|
||||
START_DESTROY_BLOCK,
|
||||
|
||||
ABORT_DESTROY_BLOCK,
|
||||
|
||||
STOP_DESTROY_BLOCK,
|
||||
|
||||
DROP_ALL_ITEMS,
|
||||
|
||||
DROP_ITEM,
|
||||
|
||||
RELEASE_USE_ITEM,
|
||||
|
||||
SWAP_HELD_ITEMS,
|
||||
|
||||
WRONG_PACKET;
|
||||
|
||||
public static PlayerDigType get(final byte i) {
|
||||
return values()[i];
|
||||
}
|
||||
}
|
||||
@@ -1,34 +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.enums;
|
||||
|
||||
import org.apache.commons.lang.ArrayUtils;
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Server;
|
||||
|
||||
|
||||
/**
|
||||
* @author retrooper
|
||||
*/
|
||||
public enum ServerVersion {
|
||||
v_1_7_10, v_1_8, v_1_8_3, v_1_8_8, v_1_9, v_1_9_4, v_1_10, v_1_11, v_1_12, v_1_13, v_1_13_2, v_1_14, v_1_15, v_1_16,
|
||||
ERROR;
|
||||
|
||||
v_1_7_10, v_1_8, v_1_8_3, v_1_8_4, v_1_8_5, v_1_8_6, v_1_8_7, v_1_8_8,
|
||||
v_1_9, v_1_9_2, v_1_9_4, v_1_10, v_1_10_2, v_1_11, v_1_11_1, v_1_11_2,
|
||||
v_1_12, v_1_12_1, v_1_12_2, v_1_13, v_1_13_1, v_1_13_2, v_1_14, v_1_14_1,
|
||||
v_1_14_2, v_1_14_3, v_1_14_4, v_1_15, v_1_15_1, v_1_15_2, v_1_16, v_1_16_1,
|
||||
v_1_16_2, ERROR, EMPTY;
|
||||
|
||||
private static final String nmsVersionSuffix = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
|
||||
public static ServerVersion[] reversedValues = new ServerVersion[values().length];
|
||||
private static ServerVersion cachedVersion;
|
||||
|
||||
public static ServerVersion getVersion() {
|
||||
ServerVersion[] vals = values();
|
||||
ArrayUtils.reverse(vals);
|
||||
for (ServerVersion val : vals) {
|
||||
private static ServerVersion getVersionNoCache() {
|
||||
if(reversedValues[0] == null) {
|
||||
reversedValues = ServerVersion.reverse(values());
|
||||
}
|
||||
for (final ServerVersion val : reversedValues) {
|
||||
String valName = val.name().substring(2).replace("_", ".");
|
||||
if (Bukkit.getBukkitVersion().contains(valName)) {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
if(PacketEvents.getSettings().getDefaultServerVersion() != null) {
|
||||
return PacketEvents.getSettings().getDefaultServerVersion();
|
||||
}
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
public static ServerVersion getVersion() {
|
||||
if (cachedVersion == null) {
|
||||
cachedVersion = getVersionNoCache();
|
||||
}
|
||||
return cachedVersion;
|
||||
}
|
||||
|
||||
|
||||
public static ServerVersion[] reverse(final ServerVersion[] arr) {
|
||||
ServerVersion[] array = arr.clone();
|
||||
if (array == null) {
|
||||
return null;
|
||||
}
|
||||
int i = 0;
|
||||
int j = array.length - 1;
|
||||
ServerVersion tmp;
|
||||
while (j > i) {
|
||||
tmp = array[j];
|
||||
array[j] = array[i];
|
||||
array[i] = tmp;
|
||||
j--;
|
||||
i++;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public static String getNmsSuffix() {
|
||||
return nmsVersionSuffix;
|
||||
}
|
||||
|
||||
public static String getNMSDirectory() {
|
||||
return "net.minecraft.server." + nmsVersionSuffix;
|
||||
return "net.minecraft.server." + getNmsSuffix();
|
||||
}
|
||||
|
||||
public static String getOBCDirectory() {
|
||||
@@ -38,8 +100,8 @@ public enum ServerVersion {
|
||||
/**
|
||||
* Returns if the current version is more up to date than the argument passed version
|
||||
*
|
||||
* @param version
|
||||
* @return
|
||||
* @param version The version to compare to the server's value.
|
||||
* @return True if the supplied version is lower, false if it is equal or higher than the server's version.
|
||||
*/
|
||||
public boolean isHigherThan(final ServerVersion version) {
|
||||
if (this == version) return false;
|
||||
@@ -49,14 +111,14 @@ public enum ServerVersion {
|
||||
/**
|
||||
* Returns if the current version is more outdated than the argument passed version
|
||||
*
|
||||
* @param version
|
||||
* @return
|
||||
* @param version The version to compare to the server's value.
|
||||
* @return True if the supplied version is higher, false if it is equal or lower than the server's version.
|
||||
*/
|
||||
public boolean isLowerThan(final ServerVersion version) {
|
||||
if (version == this) return false;
|
||||
byte len = (byte) values().length;
|
||||
if (this == version) return false;
|
||||
final int len = ServerVersion.values().length;
|
||||
for (byte i = 0; i < len; i++) {
|
||||
final ServerVersion v = values()[i];
|
||||
final ServerVersion v = ServerVersion.values()[i];
|
||||
if (v == this) {
|
||||
return true;
|
||||
} else if (v == version) {
|
||||
@@ -66,5 +128,73 @@ public enum ServerVersion {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the server version to a protocol version.
|
||||
* Recommended to cache.
|
||||
* @return protocol version
|
||||
*/
|
||||
public short toProtocolVersion() {
|
||||
switch (this) {
|
||||
case v_1_7_10:
|
||||
return 5;
|
||||
case v_1_8:
|
||||
case v_1_8_3:
|
||||
case v_1_8_4:
|
||||
case v_1_8_5:
|
||||
case v_1_8_6:
|
||||
case v_1_8_7:
|
||||
case v_1_8_8:
|
||||
return 47;
|
||||
case v_1_9:
|
||||
return 107;
|
||||
case v_1_9_2:
|
||||
return 109;
|
||||
case v_1_9_4:
|
||||
return 110;
|
||||
case v_1_10:
|
||||
case v_1_10_2:
|
||||
return 210;
|
||||
case v_1_11:
|
||||
return 315;
|
||||
case v_1_11_1:
|
||||
case v_1_11_2:
|
||||
return 316;
|
||||
case v_1_12:
|
||||
return 335;
|
||||
case v_1_12_1:
|
||||
return 338;
|
||||
case v_1_12_2:
|
||||
return 340;
|
||||
case v_1_13:
|
||||
return 393;
|
||||
case v_1_13_1:
|
||||
return 401;
|
||||
case v_1_13_2:
|
||||
return 404;
|
||||
case v_1_14:
|
||||
return 477;
|
||||
case v_1_14_1:
|
||||
return 480;
|
||||
case v_1_14_2:
|
||||
return 485;
|
||||
case v_1_14_3:
|
||||
return 490;
|
||||
case v_1_14_4:
|
||||
return 498;
|
||||
case v_1_15:
|
||||
return 573;
|
||||
case v_1_15_1:
|
||||
return 575;
|
||||
case v_1_15_2:
|
||||
return 578;
|
||||
case v_1_16:
|
||||
return 735;
|
||||
case v_1_16_1:
|
||||
return 736;
|
||||
case v_1_16_2:
|
||||
return 751;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.enums;
|
||||
|
||||
public enum SystemOS {
|
||||
WINDOWS, MACOS, LINUX, OTHER;
|
||||
|
||||
private static SystemOS value;
|
||||
|
||||
private static SystemOS getOS() {
|
||||
final String os = System.getProperty("os.name");
|
||||
for (final String osName : getOperatingSystemNames()) {
|
||||
if (os.toLowerCase().contains(osName.toLowerCase())) {
|
||||
return SystemOS.valueOf(osName);
|
||||
}
|
||||
}
|
||||
return OTHER;
|
||||
}
|
||||
|
||||
public static SystemOS getOperatingSystem() {
|
||||
if (value == null) {
|
||||
value = getOS();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static String[] getOperatingSystemNames() {
|
||||
final String[] arr = new String[values().length - 1];
|
||||
for (int i = 0; i < values().length - 1; i++) {
|
||||
arr[i] = values()[i].name();
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
@@ -1,23 +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.PacketEvents;
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
|
||||
/**
|
||||
* Incoming and sent packets are called asynchronously,
|
||||
* recommended to avoid non thread safe bukkit operations
|
||||
* An event in the PacketEvents EventManager system.
|
||||
*/
|
||||
public class PacketEvent {
|
||||
protected static ServerVersion version = PacketEvents.getServerVersion();
|
||||
protected long timestamp = PacketEvents.highlyPreciseMillis();
|
||||
public abstract class PacketEvent {
|
||||
public static ServerVersion version;
|
||||
private long timestamp = System.currentTimeMillis();
|
||||
|
||||
/**
|
||||
* Timestamp of the packet
|
||||
*
|
||||
* @return
|
||||
* @return timestamp in milliseconds
|
||||
*/
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +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 {
|
||||
}
|
||||
@@ -1,13 +1,18 @@
|
||||
package io.github.retrooper.packetevents.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.event.CancellableEvent;
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
|
||||
public final class BukkitMoveEvent extends PacketEvent {
|
||||
//Do not use this, I plan to remove this event.
|
||||
//If you wish you may recreate this class yourself and use it.
|
||||
@Deprecated
|
||||
public final class BukkitMoveEvent extends PacketEvent implements CancellableEvent {
|
||||
private final Player player;
|
||||
private final Location to, from;
|
||||
private boolean cancelled;
|
||||
|
||||
public BukkitMoveEvent(final Player player, final Location to, final Location from) {
|
||||
this.player = player;
|
||||
@@ -32,4 +37,24 @@ public final class BukkitMoveEvent extends PacketEvent {
|
||||
public Location getTo() {
|
||||
return to;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(final boolean val) {
|
||||
this.cancelled = val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
this.cancelled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uncancel() {
|
||||
this.cancelled = false;
|
||||
}
|
||||
}
|
||||
@@ -1,67 +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.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.event.CancellableEvent;
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import io.github.retrooper.packetevents.packettype.PacketType;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public final class PacketReceiveEvent extends PacketEvent {
|
||||
/**
|
||||
* This event is called each time a packet is received from a client.
|
||||
*/
|
||||
public final class PacketReceiveEvent extends PacketEvent implements CancellableEvent {
|
||||
private final Player player;
|
||||
private final String name;
|
||||
private final Object packet;
|
||||
private boolean cancelled;
|
||||
|
||||
public PacketReceiveEvent(final Player player, final String packetName, final Object packet) {
|
||||
public PacketReceiveEvent(final Player player, final Object packet) {
|
||||
this.player = player;
|
||||
this.name = packetName;
|
||||
this.packet = packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player sending the packet
|
||||
*
|
||||
* @return
|
||||
* Get the packet sender
|
||||
* @return player
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the packet's name (NMS packet class simple name)
|
||||
*
|
||||
* @return
|
||||
* Get the packet's name (NMS packet class simple name).
|
||||
* @return Name of the packet
|
||||
* @deprecated It is recommended not to use this.
|
||||
*/
|
||||
@Deprecated
|
||||
public String getPacketName() {
|
||||
return this.name;
|
||||
return this.packet.getClass().getSimpleName();
|
||||
}
|
||||
|
||||
/**
|
||||
* This is deprecated, please us {@link #getNMSPacket()}
|
||||
*
|
||||
* @return packet
|
||||
* Get the raw packet object
|
||||
* @return packet object
|
||||
*/
|
||||
@Deprecated
|
||||
public Object getPacket() {
|
||||
return this.packet;
|
||||
}
|
||||
|
||||
public Object getNMSPacket() {
|
||||
return this.packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the packet has been cancelled
|
||||
*
|
||||
* @return cancelled
|
||||
* Get the class of the NMS packet object
|
||||
* @deprecated It is useless, rather use getNMSPacket().getClass()
|
||||
* @return packet object class
|
||||
*/
|
||||
@Deprecated
|
||||
public Class<?> getNMSPacketClass() {
|
||||
return packet.getClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
this.cancelled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uncancel() {
|
||||
this.cancelled = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel the packet
|
||||
*
|
||||
* @param cancelled
|
||||
*/
|
||||
@Override
|
||||
public void setCancelled(boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,18 +1,44 @@
|
||||
/*
|
||||
* 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.CancellableEvent;
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import io.github.retrooper.packetevents.packettype.PacketType;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
|
||||
public final class PacketSendEvent extends PacketEvent {
|
||||
/**
|
||||
* This event is called each time the server sends a packet to the client.
|
||||
*/
|
||||
public final class PacketSendEvent extends PacketEvent implements CancellableEvent {
|
||||
private final Player player;
|
||||
private final String name;
|
||||
private final Object packet;
|
||||
private boolean cancelled;
|
||||
|
||||
public PacketSendEvent(final Player player, final String packetName, final Object packet) {
|
||||
public PacketSendEvent(final Player player, final Object packet) {
|
||||
this.player = player;
|
||||
this.name = packetName;
|
||||
this.packet = packet;
|
||||
this.cancelled = false;
|
||||
}
|
||||
@@ -22,35 +48,61 @@ public final class PacketSendEvent extends PacketEvent {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
public String getPacketName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is deprecated, please us {@link #getNMSPacket()}
|
||||
*
|
||||
* @return packet
|
||||
* Get the packet's name (NMS packet class simple name)
|
||||
* @deprecated It is recommended not to use this, as it is an expensive function to call.
|
||||
* @return Name of the packet
|
||||
*/
|
||||
@Deprecated
|
||||
public Object getPacket() {
|
||||
return this.packet;
|
||||
public String getPacketName() {
|
||||
return this.packet.getClass().getSimpleName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the raw packet object
|
||||
* Get the ID of the packet
|
||||
*
|
||||
* @return 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 this.packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the class of the NMS packet object.
|
||||
* Deprecated because it is useless, rather use getNMSPacket().getClass().
|
||||
*
|
||||
* @return packet object class
|
||||
*/
|
||||
@Deprecated
|
||||
public Class<?> getNMSPacketClass() {
|
||||
return packet.getClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
this.cancelled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uncancel() { this.cancelled = false;}
|
||||
}
|
||||
|
||||
@@ -1,37 +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.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.enums.ClientVersion;
|
||||
import io.github.retrooper.packetevents.event.CancellableEvent;
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import io.github.retrooper.packetevents.utils.VersionLookupUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public final class PlayerInjectEvent extends PacketEvent {
|
||||
/**
|
||||
* This event is called each time you inject a player.
|
||||
*/
|
||||
public final class PlayerInjectEvent extends PacketEvent implements CancellableEvent {
|
||||
private final Player player;
|
||||
private final boolean async;
|
||||
private boolean cancelled;
|
||||
private final ClientVersion clientVersion;
|
||||
|
||||
public PlayerInjectEvent(final Player player) {
|
||||
this.player = player;
|
||||
this.clientVersion = ClientVersion.fromProtocolVersion(VersionLookupUtils.getProtocolVersion(player));
|
||||
this(player, false);
|
||||
}
|
||||
|
||||
public PlayerInjectEvent(final Player player, boolean isAsync) {
|
||||
this.player= player;
|
||||
this.async = isAsync;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
setCancelled(true);
|
||||
this.cancelled = true;
|
||||
}
|
||||
|
||||
public ClientVersion getClientVersion() {
|
||||
return clientVersion;
|
||||
}
|
||||
@Override
|
||||
public void uncancel() {this.cancelled = false; }
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public boolean isAsync() {
|
||||
return async;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,29 +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.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.event.CancellableEvent;
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public final class PlayerUninjectEvent extends PacketEvent {
|
||||
/**
|
||||
* This event is called each time you eject a player.
|
||||
*/
|
||||
public final class PlayerUninjectEvent extends PacketEvent implements CancellableEvent {
|
||||
private final Player player;
|
||||
private final boolean async;
|
||||
private boolean cancelled;
|
||||
|
||||
public PlayerUninjectEvent(final Player player) {
|
||||
public PlayerUninjectEvent(final Player player, final boolean isAsync) {
|
||||
this.player = player;
|
||||
this.async = isAsync;
|
||||
}
|
||||
|
||||
public void setCancelled(final boolean val) {
|
||||
this.cancelled = val;
|
||||
public PlayerUninjectEvent(final Player player) {
|
||||
this(player, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
setCancelled(true);
|
||||
this.cancelled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uncancel() {this.cancelled = false; }
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return this.cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(final boolean val) {
|
||||
this.cancelled = val;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public boolean isAsync() {
|
||||
return async;
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package io.github.retrooper.packetevents.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* Please use {@link PlayerInjectEvent}
|
||||
*/
|
||||
@Deprecated
|
||||
public final class PostPlayerInjectEvent extends PacketEvent {
|
||||
private final Player player;
|
||||
|
||||
public PostPlayerInjectEvent(final Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package io.github.retrooper.packetevents.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
|
||||
public final class ServerTickEvent extends PacketEvent {
|
||||
private final int tick;
|
||||
private final double tps;
|
||||
|
||||
public ServerTickEvent(final int tick, final long timestamp) {
|
||||
this.tick = tick;
|
||||
this.timestamp = timestamp;
|
||||
this.tps = PacketEvents.getCurrentServerTPS();
|
||||
}
|
||||
|
||||
public ServerTickEvent(final int tick) {
|
||||
this.tick = tick;
|
||||
this.tps = PacketEvents.getCurrentServerTPS();
|
||||
}
|
||||
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public int getCurrentTick() {
|
||||
return tick;
|
||||
}
|
||||
|
||||
public double getCurrentServerTPS() {
|
||||
return tps;
|
||||
}
|
||||
}
|
||||
@@ -1,53 +1,128 @@
|
||||
/*
|
||||
* 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.annotations.PacketHandler;
|
||||
import io.github.retrooper.packetevents.enums.PacketEventPriority;
|
||||
import io.github.retrooper.packetevents.event.CancellableEvent;
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import io.github.retrooper.packetevents.event.PacketListener;
|
||||
import io.github.retrooper.packetevents.utils.protocollib.ProtocolLibListener;
|
||||
import io.github.retrooper.packetevents.utils.protocollib.ProtocolLibUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
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.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
public final class EventManager {
|
||||
|
||||
private static final ExecutorService executorService = Executors.newCachedThreadPool();
|
||||
private final HashMap<PacketListener, List<Method>> registeredMethods = new HashMap<PacketListener, List<Method>>();
|
||||
private final ConcurrentHashMap<PacketListener, ConcurrentLinkedQueue<Method>> registeredMethods = new ConcurrentHashMap<>();
|
||||
|
||||
public void callEvent(final PacketEvent e) {
|
||||
for (final PacketListener listener : registeredMethods.keySet()) {
|
||||
//Annotated methods
|
||||
final List<Method> methods = registeredMethods.get(listener);
|
||||
for (final Method method : methods) {
|
||||
final Class<?> parameterType = method.getParameterTypes()[0];
|
||||
ConcurrentLinkedQueue<Method> methods = registeredMethods.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)) {
|
||||
try {
|
||||
method.invoke(listener, e);
|
||||
} catch (IllegalAccessException | InvocationTargetException ex) {
|
||||
ex.printStackTrace();
|
||||
|
||||
PacketHandler annotation = method.getAnnotation(PacketHandler.class);
|
||||
Runnable invokeMethod = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
switch (annotation.synchronization()) {
|
||||
case FORCE_ASYNC:
|
||||
Bukkit.getScheduler().runTaskAsynchronously(PacketEvents.getPlugin(), invokeMethod);
|
||||
break;
|
||||
case FORCE_SYNC:
|
||||
Bukkit.getScheduler().runTask(PacketEvents.getPlugin(), invokeMethod);
|
||||
break;
|
||||
default:
|
||||
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();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (e instanceof CancellableEvent) {
|
||||
CancellableEvent cancellableEvent = (CancellableEvent) e;
|
||||
cancellableEvent.setCancelled(isCancelled[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void registerListener(final PacketListener e) {
|
||||
if (registeredMethods.containsKey(e)) {
|
||||
return;
|
||||
}
|
||||
final List<Method> methods = new ArrayList<Method>();
|
||||
for (final Method m : e.getClass().getMethods()) {
|
||||
public void registerListener(final PacketListener listener) {
|
||||
final ConcurrentLinkedQueue<Method> methods = new ConcurrentLinkedQueue<>();
|
||||
for (final Method m : listener.getClass().getDeclaredMethods()) {
|
||||
if (m.isAnnotationPresent(PacketHandler.class)
|
||||
&& m.getParameterTypes().length == 1) {
|
||||
methods.add(m);
|
||||
}
|
||||
}
|
||||
|
||||
if (!methods.isEmpty()) {
|
||||
registeredMethods.put(e, methods);
|
||||
if (ProtocolLibUtils.isAvailable()
|
||||
&& PacketEvents.getAPI().getSettings().isUseProtocolLibIfAvailable()) {
|
||||
ProtocolLibListener.registerProtocolLibListener(listener, methods);
|
||||
} else {
|
||||
registeredMethods.put(listener, methods);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void registerListeners(final PacketListener... listeners) {
|
||||
for (final PacketListener listener : listeners) {
|
||||
registerListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,6 +130,12 @@ public final class EventManager {
|
||||
registeredMethods.remove(e);
|
||||
}
|
||||
|
||||
public void unregisterListeners(final PacketListener... listeners) {
|
||||
for (final PacketListener listener : listeners) {
|
||||
unregisterListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public void unregisterAllListeners() {
|
||||
registeredMethods.clear();
|
||||
}
|
||||
|
||||
+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;
|
||||
}
|
||||
@@ -1,15 +1,59 @@
|
||||
/*
|
||||
* 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.annotations.PacketHandler;
|
||||
import io.github.retrooper.packetevents.event.PacketListener;
|
||||
import io.github.retrooper.packetevents.event.impl.PacketReceiveEvent;
|
||||
import io.github.retrooper.packetevents.packettype.PacketType;
|
||||
import io.github.retrooper.packetevents.packetwrappers.in.updatesign.WrappedPacketInUpdateSign;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.entityvelocity.WrappedPacketOutEntityVelocity;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class MainExample extends JavaPlugin {
|
||||
public class MainExample extends JavaPlugin implements PacketListener {
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
PacketEvents.load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
PacketEvents.start(this);
|
||||
//Deprecated, as it is no longer needed.
|
||||
/*
|
||||
*
|
||||
* PacketEvents will generate a random identifier for you if you do not set one
|
||||
* before initializing PacketEvents
|
||||
*
|
||||
*/
|
||||
|
||||
PacketEvents.getServerTickTask().cancel();
|
||||
PacketEvents.getSettings().setIdentifier("official_api");
|
||||
|
||||
PacketEvents.init(this);
|
||||
PacketEvents.getAPI().getEventManager().registerListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
package io.github.retrooper.packetevents.handler;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.event.impl.PacketReceiveEvent;
|
||||
import io.github.retrooper.packetevents.event.impl.PacketSendEvent;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
public class NettyPacketHandler {
|
||||
public static final String handlerName = "packet_handler";
|
||||
private static final ServerVersion version = PacketEvents.getServerVersion();
|
||||
|
||||
public static final HashSet<UUID> injectedSet = new HashSet<UUID>();
|
||||
|
||||
public static void injectPlayer(final Player player) {
|
||||
if (!hasInjected(player)) {
|
||||
if (version.isLowerThan(ServerVersion.v_1_8)) {
|
||||
NettyPacketHandler_7.injectPlayer(player);
|
||||
} else {
|
||||
NettyPacketHandler_8.injectPlayer(player);
|
||||
}
|
||||
injectedSet.add(player.getUniqueId());
|
||||
}
|
||||
}
|
||||
|
||||
public static Future<?> uninjectPlayer(final Player player) {
|
||||
if (hasInjected(player)) {
|
||||
injectedSet.remove(player.getUniqueId());
|
||||
if (version.isLowerThan(ServerVersion.v_1_8)) {
|
||||
return NettyPacketHandler_7.uninjectPlayer(player);
|
||||
} else {
|
||||
return NettyPacketHandler_8.uninjectPlayer(player);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean hasInjected(final Player player) {
|
||||
return injectedSet.contains(player.getUniqueId());
|
||||
}
|
||||
|
||||
public static Object read(final Player receiver, final Object packet) {
|
||||
final String packetName = packet.getClass().getSimpleName();
|
||||
final PacketSendEvent packetSendEvent = new PacketSendEvent(receiver, packetName, packet);
|
||||
PacketEvents.getEventManager().callEvent(packetSendEvent);
|
||||
if (!packetSendEvent.isCancelled()) {
|
||||
return packet;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Object write(final Player sender, final Object packet) {
|
||||
final String packetName = packet.getClass().getSimpleName();
|
||||
final PacketReceiveEvent packetReceiveEvent = new PacketReceiveEvent(sender, packetName, packet);
|
||||
PacketEvents.getEventManager().callEvent(packetReceiveEvent);
|
||||
if (!packetReceiveEvent.isCancelled()) {
|
||||
return packet;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package io.github.retrooper.packetevents.handler;
|
||||
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
import net.minecraft.util.io.netty.channel.*;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
final class NettyPacketHandler_7 {
|
||||
|
||||
public static void injectPlayer(final Player player) {
|
||||
final ChannelDuplexHandler channelDuplexHandler = new ChannelDuplexHandler() {
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
Object packet = NettyPacketHandler.read(player, msg);
|
||||
if(packet == null) {
|
||||
return;
|
||||
}
|
||||
super.channelRead(ctx, msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
|
||||
Object packet = NettyPacketHandler.write(player, msg);
|
||||
if(packet == null) {
|
||||
return;
|
||||
}
|
||||
super.write(ctx, msg, promise);
|
||||
}
|
||||
};
|
||||
final ChannelPipeline pipeline = ((Channel) NMSUtils.getChannel(player)).pipeline();
|
||||
pipeline.addBefore(NettyPacketHandler.handlerName, player.getName(), channelDuplexHandler);
|
||||
}
|
||||
|
||||
public static Future<?> uninjectPlayer(final Player player) {
|
||||
final Channel channel = (Channel) NMSUtils.getChannel(player);
|
||||
return channel.eventLoop().submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
channel.pipeline().remove(player.getName());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package io.github.retrooper.packetevents.handler;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
import io.netty.channel.*;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
final class NettyPacketHandler_8 {
|
||||
private static final ServerVersion version = PacketEvents.getServerVersion();
|
||||
public static void injectPlayer(final Player player) {
|
||||
final ChannelDuplexHandler channelDuplexHandler = new ChannelDuplexHandler() {
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
Object packet = NettyPacketHandler.write(player, msg);
|
||||
if(packet == null) {
|
||||
return;
|
||||
}
|
||||
super.channelRead(ctx, msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
|
||||
Object packet = NettyPacketHandler.read(player, msg);
|
||||
if(packet == null) {
|
||||
return;
|
||||
}
|
||||
super.write(ctx, msg, promise);
|
||||
}
|
||||
};
|
||||
final ChannelPipeline pipeline = ((Channel) NMSUtils.getChannel(player)).pipeline();
|
||||
pipeline.addBefore(NettyPacketHandler.handlerName, player.getName(), channelDuplexHandler);
|
||||
}
|
||||
|
||||
public static Future<?> uninjectPlayer(final Player player) {
|
||||
final Channel channel = (Channel) NMSUtils.getChannel(player);
|
||||
return channel.eventLoop().submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
channel.pipeline().remove(player.getName());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
package io.github.retrooper.packetevents.mojang;
|
||||
|
||||
import com.mojang.authlib.properties.PropertyMap;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public final class GameProfile {
|
||||
private final UUID id;
|
||||
private final String name;
|
||||
private final PropertyMap properties = new PropertyMap();
|
||||
private boolean legacy;
|
||||
|
||||
public GameProfile(UUID id, String name) {
|
||||
if (id == null && name.isEmpty()) {
|
||||
throw new IllegalArgumentException("Name and ID cannot both be blank");
|
||||
} else {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
public UUID getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public PropertyMap getProperties() {
|
||||
return this.properties;
|
||||
}
|
||||
|
||||
public boolean isComplete() {
|
||||
return this.id != null && !getName().isEmpty();
|
||||
}
|
||||
|
||||
|
||||
public boolean isLegacy() {
|
||||
return this.legacy;
|
||||
}
|
||||
|
||||
public boolean equals(com.mojang.authlib.GameProfile profile) {
|
||||
if (profile != null) {
|
||||
return profile.getId() != null && getId() != null && profile.getId() == getId()
|
||||
&& profile.getName() != null && getName() != null && profile.getName().equals(getName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
} else if (o != null && this.getClass() == o.getClass()) {
|
||||
GameProfile that = (GameProfile) o;
|
||||
if (this.id != null) {
|
||||
if (!this.id.equals(that.id)) {
|
||||
return false;
|
||||
}
|
||||
} else if (that.id != null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.name != null) {
|
||||
return this.name.equals(that.name);
|
||||
} else return that.name == null;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = this.id != null ? this.id.hashCode() : 0;
|
||||
result = 31 * result + (this.name != null ? this.name.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "id: " + id + ", name: " + name + ", legacy: " + legacy;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* 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.nettyhandler;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.event.impl.PacketReceiveEvent;
|
||||
import io.github.retrooper.packetevents.event.impl.PacketSendEvent;
|
||||
import io.github.retrooper.packetevents.event.impl.PlayerInjectEvent;
|
||||
import io.github.retrooper.packetevents.event.impl.PlayerUninjectEvent;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
public class NettyPacketHandler {
|
||||
private static boolean v1_7_nettyMode = false;
|
||||
private static final ExecutorService singleThreadedExecutor = Executors.newSingleThreadExecutor();
|
||||
|
||||
static {
|
||||
try {
|
||||
Class.forName("io.netty.channel.Channel");
|
||||
} catch (ClassNotFoundException e) {
|
||||
v1_7_nettyMode = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronously inject a player
|
||||
*
|
||||
* @param player Target player to inject
|
||||
*/
|
||||
public static void injectPlayer(final Player player) {
|
||||
try {
|
||||
final PlayerInjectEvent injectEvent = new PlayerInjectEvent(player);
|
||||
PacketEvents.getAPI().getEventManager().callEvent(injectEvent);
|
||||
if (!injectEvent.isCancelled()) {
|
||||
if (v1_7_nettyMode) {
|
||||
NettyPacketHandler_7.injectPlayer(player);
|
||||
} else {
|
||||
NettyPacketHandler_8.injectPlayer(player);
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously inject a player
|
||||
*
|
||||
* @param player
|
||||
* @return {@link java.util.concurrent.Future}
|
||||
*/
|
||||
public static Future<?> injectPlayerAsync(final Player player) {
|
||||
return singleThreadedExecutor.submit(() -> {
|
||||
try {
|
||||
final PlayerInjectEvent injectEvent = new PlayerInjectEvent(player, true);
|
||||
PacketEvents.getAPI().getEventManager().callEvent(injectEvent);
|
||||
if (!injectEvent.isCancelled()) {
|
||||
if (v1_7_nettyMode) {
|
||||
NettyPacketHandler_7.injectPlayer(player);
|
||||
} else {
|
||||
NettyPacketHandler_8.injectPlayer(player);
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronously eject a player.
|
||||
*
|
||||
* @param player
|
||||
*/
|
||||
public static void ejectPlayer(final Player player) {
|
||||
try {
|
||||
final PlayerUninjectEvent uninjectEvent = new PlayerUninjectEvent(player);
|
||||
PacketEvents.getAPI().getEventManager().callEvent(uninjectEvent);
|
||||
if (!uninjectEvent.isCancelled()) {
|
||||
if (v1_7_nettyMode) {
|
||||
NettyPacketHandler_7.ejectPlayer(player);
|
||||
} else {
|
||||
NettyPacketHandler_8.ejectPlayer(player);
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously eject a player
|
||||
*
|
||||
* @param player
|
||||
* @return {@link java.util.concurrent.Future}
|
||||
*/
|
||||
public static Future<?> ejectPlayerAsync(final Player player) {
|
||||
return singleThreadedExecutor.submit(() -> {
|
||||
try {
|
||||
final PlayerUninjectEvent uninjectEvent = new PlayerUninjectEvent(player, true);
|
||||
PacketEvents.getAPI().getEventManager().callEvent(uninjectEvent);
|
||||
if (!uninjectEvent.isCancelled()) {
|
||||
if (v1_7_nettyMode) {
|
||||
NettyPacketHandler_7.ejectPlayer(player);
|
||||
} else {
|
||||
NettyPacketHandler_8.ejectPlayer(player);
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called each time the server plans to send a packet to the client.
|
||||
*
|
||||
* @param sender
|
||||
* @param packet
|
||||
* @return
|
||||
*/
|
||||
public static Object write(final Player sender, final Object packet) {
|
||||
final PacketSendEvent packetSendEvent = new PacketSendEvent(sender, packet);
|
||||
PacketEvents.getAPI().getEventManager().callEvent(packetSendEvent);
|
||||
if (!packetSendEvent.isCancelled()) {
|
||||
return packet;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function is called each time the server receives a packet from the client.
|
||||
*
|
||||
* @param receiver
|
||||
* @param packet
|
||||
* @return
|
||||
*/
|
||||
public static Object read(final Player receiver, final Object packet) {
|
||||
final PacketReceiveEvent packetReceiveEvent = new PacketReceiveEvent(receiver, packet);
|
||||
PacketEvents.getAPI().getEventManager().callEvent(packetReceiveEvent);
|
||||
if (!packetReceiveEvent.isCancelled()) {
|
||||
return packet;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void sendPacket(Object channel, Object packet) {
|
||||
if(v1_7_nettyMode) {
|
||||
NettyPacketHandler_7.sendPacket(channel, packet);
|
||||
}
|
||||
else {
|
||||
NettyPacketHandler_8.sendPacket(channel, packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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.nettyhandler;
|
||||
|
||||
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 NettyPacketHandler_7 {
|
||||
|
||||
/**
|
||||
* Inject a player using 1.7.10's netty import location
|
||||
* @param player
|
||||
*/
|
||||
public static void injectPlayer(final Player player) {
|
||||
final ChannelDuplexHandler channelDuplexHandler = new ChannelDuplexHandler() {
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
Object packet = NettyPacketHandler.read(player, msg);
|
||||
if (packet == null) {
|
||||
return;
|
||||
}
|
||||
super.channelRead(ctx, msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
|
||||
Object packet = NettyPacketHandler.write(player, msg);
|
||||
if (packet == null) {
|
||||
return;
|
||||
}
|
||||
super.write(ctx, msg, promise);
|
||||
}
|
||||
};
|
||||
final ChannelPipeline pipeline = ((Channel) NMSUtils.getChannel(player)).pipeline();
|
||||
pipeline.addBefore("packet_handler", PacketEvents.getHandlerName(player.getName()), channelDuplexHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Eject a player using 1.7.10 netty import location.
|
||||
* @param player
|
||||
*/
|
||||
public static void ejectPlayer(final Player player) {
|
||||
Channel channel = (Channel) NMSUtils.getChannel(player);
|
||||
channel.pipeline().remove(PacketEvents.getHandlerName(player.getName()));
|
||||
NMSUtils.channelCache.remove(player.getUniqueId());
|
||||
}
|
||||
|
||||
public static void sendPacket(Object rawChannel, Object packet) {
|
||||
Channel channel = (Channel)rawChannel;
|
||||
channel.pipeline().writeAndFlush(packet);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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.nettyhandler;
|
||||
|
||||
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 NettyPacketHandler_8 {
|
||||
/**
|
||||
* Inject a player with 1.8+ netty import location.
|
||||
* @param player
|
||||
*/
|
||||
public static void injectPlayer(final Player player) {
|
||||
final ChannelDuplexHandler channelDuplexHandler = new ChannelDuplexHandler() {
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
Object packet = NettyPacketHandler.read(player, msg);
|
||||
if (packet == null) {
|
||||
return;
|
||||
}
|
||||
super.channelRead(ctx, msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
|
||||
Object packet = NettyPacketHandler.write(player, msg);
|
||||
if (packet == null) {
|
||||
return;
|
||||
}
|
||||
super.write(ctx, msg, promise);
|
||||
}
|
||||
};
|
||||
final ChannelPipeline pipeline = ((Channel) NMSUtils.getChannel(player)).pipeline();
|
||||
pipeline.addBefore("packet_handler", PacketEvents.getHandlerName(player.getName()), channelDuplexHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Eject a player with 1.8+ netty import location.
|
||||
* @param player
|
||||
*/
|
||||
public static void ejectPlayer(final Player player) {
|
||||
final Channel channel = (Channel) NMSUtils.getChannel(player);
|
||||
channel.pipeline().remove(PacketEvents.getHandlerName(player.getName()));
|
||||
NMSUtils.channelCache.remove(player.getUniqueId());
|
||||
}
|
||||
|
||||
public static void sendPacket(Object rawChannel, Object packet) {
|
||||
Channel channel = (Channel)rawChannel;
|
||||
channel.pipeline().writeAndFlush(packet);
|
||||
}
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
package io.github.retrooper.packetevents.packet;
|
||||
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
|
||||
@Deprecated
|
||||
public final class Packet {
|
||||
|
||||
private static Class<?> packetPlayInFlying, packetPlayInPosition, packetPlayInPositionLook, packetPlayInLook;
|
||||
|
||||
static {
|
||||
try {
|
||||
packetPlayInFlying = NMSUtils.getNMSClass(Client.FLYING);
|
||||
} catch (ClassNotFoundException e) {
|
||||
//That is fine, they are on 1.9+
|
||||
}
|
||||
try {
|
||||
packetPlayInPosition = NMSUtils.getNMSClass(Client.POSITION);
|
||||
packetPlayInPositionLook = NMSUtils.getNMSClass(Client.POSITION_LOOK);
|
||||
packetPlayInLook = NMSUtils.getNMSClass(Client.LOOK);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this NMS packet an instanceof the "PacketPlayInFlying" packet in the 1.8 protocol?
|
||||
* Supports 1.9->1.15.2 too!
|
||||
*
|
||||
* @param nmsPacket
|
||||
* @return If the nms packet provided is an instanceof the "PacketPlayInFlying" packet in the 1.8 protocol!
|
||||
*/
|
||||
public static boolean isInstanceOfFlyingPacket(Object nmsPacket) {
|
||||
//1.7->1.8.8
|
||||
if (packetPlayInFlying != null) {
|
||||
return packetPlayInFlying.isInstance(nmsPacket);
|
||||
} else {
|
||||
//1.9->1.15.2
|
||||
return packetPlayInPosition.isInstance(nmsPacket)
|
||||
|| packetPlayInPositionLook.isInstance(nmsPacket)
|
||||
|| packetPlayInLook.isInstance(nmsPacket);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this NMS Packet an instanceof the "PacketPlayInPosition" or "PacketPlayInPositionLook"
|
||||
* @param nmsPacket
|
||||
* @return
|
||||
*/
|
||||
public static boolean isInstanceOfPositionOrPositionLook(final Object nmsPacket) {
|
||||
return packetPlayInPosition.isInstance(nmsPacket) || packetPlayInPositionLook.isInstance(nmsPacket);
|
||||
}
|
||||
|
||||
public static boolean isInstanceOfLook(final Object nmsPacket) {
|
||||
return packetPlayInLook.isInstance(nmsPacket);
|
||||
}
|
||||
|
||||
|
||||
public static class Client {
|
||||
private static final String c = "PacketPlayIn";
|
||||
|
||||
@Deprecated
|
||||
public static final String FLYING = c + "Flying";
|
||||
|
||||
|
||||
public static final String POSITION = c + "Position";
|
||||
|
||||
public static final String POSITION_LOOK = c + "PositionLook";
|
||||
|
||||
public static final String LOOK = c + "Look";
|
||||
public static final String CLIENT_COMMAND = c + "ClientCommand";
|
||||
|
||||
public static final String TRANSACTION = c + "Transaction";
|
||||
public static final String BLOCK_DIG = c + "BlockDig";
|
||||
public static final String ENTITY_ACTION = c + "EntityAction";
|
||||
public static final String USE_ENTITY = c + "UseEntity";
|
||||
public static final String WINDOW_CLICK = c + "WindowClick";
|
||||
public static final String STEER_VEHICLE = c + "SteerVehicle";
|
||||
public static final String CUSTOM_PAYLOAD = c + "CustomPayload";
|
||||
public static final String ARM_ANIMATION = c + "ArmAnimation";
|
||||
/**
|
||||
* The packet name of the block place depending on your server version, "PacketPlayInBlockPlace" or "PacketPlayInUseItem"
|
||||
*/
|
||||
public static final String BLOCK_PLACE = c + ((ServerVersion.getVersion().isHigherThan(ServerVersion.v_1_8_8)) ? "UseItem" : "BlockPlace");
|
||||
|
||||
public static final String ABILITIES = c + "Abilities";
|
||||
public static final String HELD_ITEM_SLOT = c + "HeldItemSlot";
|
||||
public static final String CLOSE_WINDOW = c + "CloseWindow";
|
||||
public static final String TAB_COMPLETE = c + "TabComplete";
|
||||
public static final String CHAT = c + "Chat";
|
||||
public static final String SET_CREATIVE_SLOT = c + "SetCreativeSlot";
|
||||
|
||||
public static final String KEEP_ALIVE = c + "KeepAlive";
|
||||
|
||||
}
|
||||
|
||||
public static class Server {
|
||||
private static final String s = "PacketPlayOut";
|
||||
|
||||
public static final String ANIMATION = s + "Animation";
|
||||
public static final String KEEP_ALIVE = s + "KeepAlive";
|
||||
public static final String CHAT = s + "Chat";
|
||||
public static final String POSITION = s + "Position";
|
||||
public static final String TRANSACTION = s + "Transaction";
|
||||
public static final String NAMED_ENTITY_SPAWN = s + "NamedEntitySpawn";
|
||||
public static final String SPAWN_ENTITY_LIVING = s + "SpawnEntityLiving";
|
||||
public static final String SPAWN_ENTITY = s + "SpawnEntity";
|
||||
public static final String CUSTOM_PAYLOAD = s + "CustomPayload";
|
||||
public static final String ABILITIES = s + "Abilities";
|
||||
public static final String ENTITY_METADATA = s + "EntityMetadata";
|
||||
public static final String ENTITY_VELOCITY = s + "EntityVelocity";
|
||||
public static final String ENTITY_DESTROY = s + "EntityDestroy";
|
||||
public static final String ENTITY_HEAD_ROTATION = s + "EntityHeadRotation";
|
||||
public static final String BLOCK_CHANGE = s + "BlockChange";
|
||||
public static final String CLOSE_WINDOW = s + "CloseWindow";
|
||||
public static final String HELD_ITEM_SLOT = s + "HeldItemSlot";
|
||||
public static final String TAB_COMPLETE = s + "TabComplete";
|
||||
public static final String RESPAWN = s + "Respawn";
|
||||
public static final String WORLD_PARTICLES = s + "WorldParticles";
|
||||
public static final String COMMANDS = s + "Commands";
|
||||
public static final String OPEN_WINDOW = s + "OpenWindow";
|
||||
public static final String LOGIN = s + "Login";
|
||||
public static final String SERVER_DIFFICULTY = s + "ServerDifficulty";
|
||||
}
|
||||
|
||||
public static class Login {
|
||||
public static final String HANDSHAKE = "PacketHandshakingInSetProtocol";
|
||||
public static final String PING = "PacketStatusInPing";
|
||||
public static final String START = "PacketStatusInStart";
|
||||
public static final String SUCCESS = "PacketLoginOutSuccess";
|
||||
public static final String ENCRYPTION_BEGIN_IN = "PacketLoginInEncryptionBegin";
|
||||
public static final String ENCRYPTION_BEGIN_OUT = "PacketLoginOutEncryptionBegin";
|
||||
|
||||
public static final String[] LOGIN_PACKETS = new String[]{"PacketHandshakingInSetProtocol", "PacketLoginInStart", "PacketLoginInEncryptionBegin"};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,183 +0,0 @@
|
||||
package io.github.retrooper.packetevents.packet;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
|
||||
public final class PacketType {
|
||||
private static final ServerVersion version = PacketEvents.getServerVersion();
|
||||
|
||||
|
||||
public static final class Util {
|
||||
/**
|
||||
* Is this NMS packet an instance of the "PacketPlayInFlying" packet?
|
||||
* Supports 1.9->1.15.2 too!
|
||||
*
|
||||
* @param nmsPacket
|
||||
* @return If the nms packet provided is an instanceof the "PacketPlayInFlying" packet in the 1.8 protocol & 1.16 protocol!
|
||||
*/
|
||||
public static boolean isInstanceOfFlyingPacket(final Object nmsPacket) {
|
||||
//1.7->1.8.8
|
||||
if (packetPlayInFlying != null) {
|
||||
return packetPlayInFlying.isInstance(nmsPacket);
|
||||
} else {
|
||||
//1.9->1.15.2
|
||||
return isInstanceOfPositionOrPositionLook(nmsPacket) || isInstanceOfPositionLookPacket(nmsPacket);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this NMS packet an instance of the "PacketPlayInPosition" packet?
|
||||
*
|
||||
* @param nmsPacket
|
||||
* @return nmsPacket instanceof PacketPlayInPosition
|
||||
*/
|
||||
public static boolean isInstanceOfPositionPacket(final Object nmsPacket) {
|
||||
return packetPlayInPosition.isInstance(nmsPacket);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this NMS packet an instance of the "PacketPlayInPositionLook" packet?
|
||||
*
|
||||
* @param nmsPacket
|
||||
* @return nmsPacket instanceof PacketPlayInPositionLook
|
||||
*/
|
||||
public static boolean isInstanceOfPositionLookPacket(final Object nmsPacket) {
|
||||
return packetPlayInPositionLook.isInstance(nmsPacket);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this NMS Packet an instanceof the "PacketPlayInPosition" or "PacketPlayInPositionLook"
|
||||
*
|
||||
* @param nmsPacket
|
||||
* @return nmsPacket instanceof PacketPlayInPosition || nmsPacket instanceof PacketPlayInPositionLook
|
||||
*/
|
||||
public static boolean isInstanceOfPositionOrPositionLook(final Object nmsPacket) {
|
||||
return isInstanceOfPositionPacket(nmsPacket) || isInstanceOfPositionLookPacket(nmsPacket);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this NMS Packet an instance of the "PacketPlayInLook" packet?
|
||||
*
|
||||
* @param nmsPacket
|
||||
* @return nmsPacket instanceof PacketPlayInLook
|
||||
*/
|
||||
public static boolean isInstanceOfLook(final Object nmsPacket) {
|
||||
return packetPlayInLook.isInstance(nmsPacket);
|
||||
}
|
||||
|
||||
public static boolean isInstanceOfUseEntity(final Object nmsPacket) {
|
||||
return packetPlayInUseEntity.isInstance(nmsPacket);
|
||||
}
|
||||
|
||||
private static Class<?> packetPlayInFlying, packetPlayInPosition, packetPlayInPositionLook, packetPlayInLook, packetPlayInUseEntity;
|
||||
|
||||
static {
|
||||
try {
|
||||
//Only exists in 1.7->1.8.8 & 1.16 protocol
|
||||
packetPlayInFlying = NMSUtils.getNMSClass(Client.FLYING);
|
||||
} catch (ClassNotFoundException e) {
|
||||
//That is fine, they are on 1.9->1.15.2
|
||||
}
|
||||
try {
|
||||
packetPlayInPosition = NMSUtils.getNMSClass(Client.POSITION);
|
||||
packetPlayInPositionLook = NMSUtils.getNMSClass(Client.POSITION_LOOK);
|
||||
packetPlayInLook = NMSUtils.getNMSClass(Client.LOOK);
|
||||
|
||||
} catch (ClassNotFoundException e) {
|
||||
for (final Class<?> cls : packetPlayInFlying.getDeclaredClasses()) {
|
||||
if (cls.getSimpleName().equals(Client.POSITION)) {
|
||||
packetPlayInPosition = cls;
|
||||
} else if (cls.getSimpleName().equals(Client.POSITION_LOOK)) {
|
||||
packetPlayInPositionLook = cls;
|
||||
} else if (cls.getSimpleName().equals(Client.LOOK)) {
|
||||
packetPlayInLook = cls;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
packetPlayInUseEntity = NMSUtils.getNMSClass(Client.USE_ENTITY);
|
||||
}
|
||||
catch(ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Client {
|
||||
private static final String c = "PacketPlayIn";
|
||||
|
||||
@Deprecated
|
||||
public static final String FLYING = c + "Flying";
|
||||
|
||||
|
||||
public static final String POSITION = c + "Position";
|
||||
|
||||
public static final String POSITION_LOOK = c + "PositionLook";
|
||||
|
||||
public static final String LOOK = c + "Look";
|
||||
public static final String CLIENT_COMMAND = c + "ClientCommand";
|
||||
|
||||
public static final String TRANSACTION = c + "Transaction";
|
||||
public static final String BLOCK_DIG = c + "BlockDig";
|
||||
public static final String ENTITY_ACTION = c + "EntityAction";
|
||||
public static final String USE_ENTITY = c + "UseEntity";
|
||||
public static final String WINDOW_CLICK = c + "WindowClick";
|
||||
public static final String STEER_VEHICLE = c + "SteerVehicle";
|
||||
public static final String CUSTOM_PAYLOAD = c + "CustomPayload";
|
||||
public static final String ARM_ANIMATION = c + "ArmAnimation";
|
||||
/**
|
||||
* The packet name of the block place depending on your server version, "PacketPlayInBlockPlace" or "PacketPlayInUseItem"
|
||||
*/
|
||||
public static final String BLOCK_PLACE = c + ((ServerVersion.getVersion().isHigherThan(ServerVersion.v_1_8_8)) ? "UseItem" : "BlockPlace");
|
||||
|
||||
public static final String ABILITIES = c + "Abilities";
|
||||
public static final String HELD_ITEM_SLOT = c + "HeldItemSlot";
|
||||
public static final String CLOSE_WINDOW = c + "CloseWindow";
|
||||
public static final String TAB_COMPLETE = c + "TabComplete";
|
||||
public static final String CHAT = c + "Chat";
|
||||
public static final String SET_CREATIVE_SLOT = c + "SetCreativeSlot";
|
||||
|
||||
public static final String KEEP_ALIVE = c + "KeepAlive";
|
||||
}
|
||||
|
||||
public static final class Server {
|
||||
private static final String s = "PacketPlayOut";
|
||||
|
||||
public static final String ANIMATION = s + "Animation";
|
||||
public static final String KEEP_ALIVE = s + "KeepAlive";
|
||||
public static final String CHAT = s + "Chat";
|
||||
public static final String POSITION = s + "Position";
|
||||
public static final String TRANSACTION = s + "Transaction";
|
||||
public static final String NAMED_ENTITY_SPAWN = s + "NamedEntitySpawn";
|
||||
public static final String SPAWN_ENTITY_LIVING = s + "SpawnEntityLiving";
|
||||
public static final String SPAWN_ENTITY = s + "SpawnEntity";
|
||||
public static final String CUSTOM_PAYLOAD = s + "CustomPayload";
|
||||
public static final String ABILITIES = s + "Abilities";
|
||||
public static final String ENTITY_METADATA = s + "EntityMetadata";
|
||||
public static final String ENTITY_VELOCITY = s + "EntityVelocity";
|
||||
public static final String ENTITY_DESTROY = s + "EntityDestroy";
|
||||
public static final String ENTITY_HEAD_ROTATION = s + "EntityHeadRotation";
|
||||
public static final String BLOCK_CHANGE = s + "BlockChange";
|
||||
public static final String CLOSE_WINDOW = s + "CloseWindow";
|
||||
public static final String HELD_ITEM_SLOT = s + "HeldItemSlot";
|
||||
public static final String TAB_COMPLETE = s + "TabComplete";
|
||||
public static final String RESPAWN = s + "Respawn";
|
||||
public static final String WORLD_PARTICLES = s + "WorldParticles";
|
||||
public static final String COMMANDS = s + "Commands";
|
||||
public static final String OPEN_WINDOW = s + "OpenWindow";
|
||||
public static final String LOGIN = s + "Login";
|
||||
public static final String SERVER_DIFFICULTY = s + "ServerDifficulty";
|
||||
}
|
||||
|
||||
public static final class Login {
|
||||
public static final String HANDSHAKE = "PacketHandshakingInSetProtocol";
|
||||
public static final String PING = "PacketStatusInPing";
|
||||
public static final String START = "PacketStatusInStart";
|
||||
public static final String SUCCESS = "PacketLoginOutSuccess";
|
||||
public static final String ENCRYPTION_BEGIN_IN = "PacketLoginInEncryptionBegin";
|
||||
public static final String ENCRYPTION_BEGIN_OUT = "PacketLoginOutEncryptionBegin";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
* 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.packet;
|
||||
|
||||
import io.github.retrooper.packetevents.packettype.PacketType;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
|
||||
|
||||
public class PacketTypeClasses {
|
||||
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();
|
||||
}
|
||||
//Block place
|
||||
try {
|
||||
BLOCK_PLACE = NMSUtils.getNMSClass(c + "BlockPlace");
|
||||
} catch (ClassNotFoundException e) {
|
||||
//They are just on a newer version
|
||||
try {
|
||||
USE_ITEM = NMSUtils.getNMSClass(c + "UseItem");
|
||||
} catch (ClassNotFoundException e2) {
|
||||
e.printStackTrace();
|
||||
e2.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
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,253 @@
|
||||
/*
|
||||
* 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.packet.PacketTypeClasses;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class PacketType {
|
||||
public static class Client {
|
||||
public static final Map<Class<?>, Byte> packetIds = new HashMap<Class<?>, Byte>();
|
||||
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<Class<?>, Byte>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers;
|
||||
|
||||
public interface Sendable {
|
||||
Object asNMSPacket();
|
||||
}
|
||||
@@ -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,357 @@
|
||||
/*
|
||||
* 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.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.in.abilities.WrappedPacketInAbilities;
|
||||
import io.github.retrooper.packetevents.packetwrappers.in.armanimation.WrappedPacketInArmAnimation;
|
||||
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.chat.WrappedPacketInChat;
|
||||
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.flying.WrappedPacketInFlying;
|
||||
import io.github.retrooper.packetevents.packetwrappers.in.helditemslot.WrappedPacketInHeldItemSlot;
|
||||
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.steervehicle.WrappedPacketInSteerVehicle;
|
||||
import io.github.retrooper.packetevents.packetwrappers.in.transaction.WrappedPacketInTransaction;
|
||||
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.entity.WrappedPacketOutEntity;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.entityvelocity.WrappedPacketOutEntityVelocity;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.gamestatechange.WrappedPacketOutGameStateChange;
|
||||
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 org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class WrappedPacket implements WrapperPacketReader {
|
||||
protected final List<Field> fields = new ArrayList<>();
|
||||
public static ServerVersion version;
|
||||
protected final Player player;
|
||||
protected Object packet;
|
||||
private Class<?> packetClass;
|
||||
|
||||
public WrappedPacket() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public WrappedPacket(final Object packet) {
|
||||
this(null, packet);
|
||||
}
|
||||
|
||||
public WrappedPacket(final Player player, final Object packet) {
|
||||
if (packet == null) {
|
||||
this.player = null;
|
||||
return;
|
||||
}
|
||||
this.packetClass = packet.getClass();
|
||||
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;
|
||||
}
|
||||
for (Field f : packetClass.getDeclaredFields()) {
|
||||
f.setAccessible(true);
|
||||
fields.add(f);
|
||||
}
|
||||
this.player = player;
|
||||
this.packet = packet;
|
||||
setup();
|
||||
}
|
||||
|
||||
public static void loadAllWrappers() {
|
||||
//SERVER BOUND
|
||||
WrappedPacketInAbilities.load();
|
||||
WrappedPacketInArmAnimation.load();
|
||||
WrappedPacketInBlockDig.load();
|
||||
WrappedPacketInBlockPlace.load();
|
||||
WrappedPacketInChat.load();
|
||||
WrappedPacketInClientCommand.load();
|
||||
WrappedPacketInCustomPayload.load();
|
||||
WrappedPacketInEntityAction.load();
|
||||
WrappedPacketInFlying.load();
|
||||
WrappedPacketInHeldItemSlot.load();
|
||||
WrappedPacketInKeepAlive.load();
|
||||
WrappedPacketInSettings.load();
|
||||
WrappedPacketInSteerVehicle.load();
|
||||
WrappedPacketInTransaction.load();
|
||||
WrappedPacketInUseEntity.load();
|
||||
WrappedPacketInUpdateSign.load();
|
||||
WrappedPacketInWindowClick.load();
|
||||
|
||||
//CLIENTBOUND
|
||||
WrappedPacketOutAbilities.load();
|
||||
WrappedPacketOutAnimation.load();
|
||||
WrappedPacketOutChat.load();
|
||||
WrappedPacketOutEntity.load();
|
||||
WrappedPacketOutEntityVelocity.load();
|
||||
WrappedPacketOutKeepAlive.load();
|
||||
WrappedPacketOutKickDisconnect.load();
|
||||
WrappedPacketOutPosition.load();
|
||||
WrappedPacketOutTransaction.load();
|
||||
WrappedPacketOutUpdateHealth.load();
|
||||
WrappedPacketOutGameStateChange.load();
|
||||
//WrappedPacketOutCustomPayload.load();
|
||||
}
|
||||
|
||||
protected void setup() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean readBoolean(int index) {
|
||||
return (boolean) readObject(index, boolean.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte readByte(int index) {
|
||||
return (byte) readObject(index, byte.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public short readShort(int index) {
|
||||
return (short) readObject(index, short.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readInt(int index) {
|
||||
return (int) readObject(index, int.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long readLong(int index) {
|
||||
return (long) readObject(index, long.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float readFloat(int index) {
|
||||
return (float) readObject(index, float.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double readDouble(int index) {
|
||||
return (double) readObject(index, double.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean[] readBooleanArray(int index) {
|
||||
int currentIndex = 0;
|
||||
for(Field f : fields) {
|
||||
if (boolean[].class.isAssignableFrom(f.getType())) {
|
||||
if(index == currentIndex++) {
|
||||
try {
|
||||
return (boolean[]) f.get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new boolean[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] readByteArray(int index) {
|
||||
int currentIndex = 0;
|
||||
for(Field f : fields) {
|
||||
if (byte[].class.isAssignableFrom(f.getType())) {
|
||||
if(index == currentIndex++) {
|
||||
try {
|
||||
return (byte[]) f.get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public short[] readShortArray(int index) {
|
||||
int currentIndex = 0;
|
||||
for(Field f : fields) {
|
||||
if (short[].class.isAssignableFrom(f.getType())) {
|
||||
if(index == currentIndex++) {
|
||||
try {
|
||||
return (short[]) f.get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new short[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] readIntArray(int index) {
|
||||
int currentIndex = 0;
|
||||
for(Field f : fields) {
|
||||
if (int[].class.isAssignableFrom(f.getType())) {
|
||||
if(index == currentIndex++) {
|
||||
try {
|
||||
return (int[]) f.get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new int[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public long[] readLongArray(int index) {
|
||||
int currentIndex = 0;
|
||||
for(Field f : fields) {
|
||||
if (long[].class.isAssignableFrom(f.getType())) {
|
||||
if(index == currentIndex++) {
|
||||
try {
|
||||
return (long[]) f.get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new long[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public float[] readFloatArray(int index) {
|
||||
int currentIndex = 0;
|
||||
for(Field f : fields) {
|
||||
if (float.class.isAssignableFrom(f.getType())) {
|
||||
if(index == currentIndex++) {
|
||||
try {
|
||||
return (float[]) f.get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new float[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] readDoubleArray(int index) {
|
||||
int currentIndex = 0;
|
||||
for(Field f : fields) {
|
||||
if (double[].class.isAssignableFrom(f.getType())) {
|
||||
if(index == currentIndex++) {
|
||||
try {
|
||||
return (double[]) f.get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new double[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] readStringArray(int index) {
|
||||
Object[] array = readObjectArray(index, String[].class);
|
||||
int len = array.length;
|
||||
String[] stringArray = new String[len];
|
||||
for(int i = 0; i < len; i++) {
|
||||
stringArray[i] = array[i].toString();
|
||||
}
|
||||
return stringArray;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] readObjectArray(int index, Class<?> type) {
|
||||
int currentIndex = 0;
|
||||
for(Field f : fields) {
|
||||
if (type.isAssignableFrom(f.getType())) {
|
||||
if(index == currentIndex++) {
|
||||
try {
|
||||
return (Object[]) f.get(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new Object[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readObject(int index, Class<?> type) {
|
||||
int currentIndex = 0;
|
||||
for (Field f : fields) {
|
||||
if (type.isAssignableFrom(f.getType())) {
|
||||
if (index == currentIndex++) {
|
||||
try {
|
||||
return f.get(packet);
|
||||
} catch (Exception exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object readAnyObject(int index) {
|
||||
int currentIndex = 0;
|
||||
for (Field f : fields) {
|
||||
if (index == currentIndex++) {
|
||||
try {
|
||||
return f.get(packet);
|
||||
} catch (Exception exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readString(int index) {
|
||||
return readObject(index, String.class).toString();
|
||||
}
|
||||
}
|
||||
+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);
|
||||
|
||||
Object[] readObjectArray(int index, Class<?> type);
|
||||
|
||||
Object readObject(int index, Class<?> type);
|
||||
|
||||
Object readAnyObject(int index);
|
||||
|
||||
String readString(int index);
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.api;
|
||||
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class WrappedPacket {
|
||||
protected static ServerVersion version = ServerVersion.getVersion();
|
||||
protected final Player player;
|
||||
protected Object packet;
|
||||
|
||||
public WrappedPacket(final Object packet) {
|
||||
this.player = null;
|
||||
if (packet == null) return;
|
||||
this.packet = packet;
|
||||
try {
|
||||
setup();
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public WrappedPacket(final Player player, final Object packet) {
|
||||
this.player = player;
|
||||
if (packet == null) return;
|
||||
this.packet = packet;
|
||||
try {
|
||||
setup();
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
protected void setup() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+81
-54
@@ -1,41 +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.in.abilities;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import io.github.retrooper.packetevents.annotations.NotNull;
|
||||
import io.github.retrooper.packetevents.annotations.Nullable;
|
||||
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
|
||||
public final class WrappedPacketInAbilities extends WrappedPacket {
|
||||
private static Class<?> abilitiesClass;
|
||||
private static final Field[] fields = new Field[6];
|
||||
|
||||
static {
|
||||
|
||||
try {
|
||||
abilitiesClass = NMSUtils.getNMSClass("PacketPlayInAbilities");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
fields[0] = abilitiesClass.getDeclaredField("a");
|
||||
fields[1] = abilitiesClass.getDeclaredField("b");
|
||||
fields[2] = abilitiesClass.getDeclaredField("c");
|
||||
fields[3] = abilitiesClass.getDeclaredField("d");
|
||||
fields[4] = abilitiesClass.getDeclaredField("e");
|
||||
fields[5] = abilitiesClass.getDeclaredField("f");
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
for (Field f : fields) {
|
||||
if (f != null) {
|
||||
f.setAccessible(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isMoreThanOneBoolPresent;
|
||||
private boolean isVulnerable;
|
||||
private boolean isFlying;
|
||||
private boolean allowFly;
|
||||
@@ -47,50 +43,81 @@ public final class WrappedPacketInAbilities extends WrappedPacket {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
isMoreThanOneBoolPresent = Reflection.getField(PacketTypeClasses.Client.ABILITIES, boolean.class, 1) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
try {
|
||||
this.isVulnerable = fields[0].getBoolean(packet);
|
||||
this.isFlying = fields[1].getBoolean(packet);
|
||||
this.allowFly = fields[2].getBoolean(packet);
|
||||
this.instantBuild = fields[3].getBoolean(packet);
|
||||
this.flySpeed = fields[4].getFloat(packet);
|
||||
this.walkSpeed = fields[5].getFloat(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
if (isMoreThanOneBoolPresent) {
|
||||
this.isVulnerable = readBoolean(0);
|
||||
this.isFlying = readBoolean(1);
|
||||
this.allowFly = readBoolean(2);
|
||||
this.instantBuild = readBoolean(3);
|
||||
this.flySpeed = readFloat(0);
|
||||
this.walkSpeed = readFloat(1);
|
||||
} else {
|
||||
this.isFlying = readBoolean(0);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isVulnerable() {
|
||||
/**
|
||||
* 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 isVulnerable;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public boolean isFlying() {
|
||||
return isFlying;
|
||||
}
|
||||
|
||||
public boolean isFlightAllowed() {
|
||||
/**
|
||||
* 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 allowFly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use {@link WrappedPacketInAbilities#isFlightAllowed()}
|
||||
* @return
|
||||
* 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
|
||||
public boolean canFly() {
|
||||
return allowFly;
|
||||
}
|
||||
|
||||
public boolean canInstantlyBuild() {
|
||||
@Nullable
|
||||
public Boolean canInstantlyBuild() {
|
||||
return instantBuild;
|
||||
}
|
||||
|
||||
public float getFlySpeed() {
|
||||
/**
|
||||
* 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 flySpeed;
|
||||
}
|
||||
|
||||
public float getWalkSpeed() {
|
||||
/**
|
||||
* 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 walkSpeed;
|
||||
}
|
||||
}
|
||||
+46
@@ -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.packetwrappers.in.armanimation;
|
||||
|
||||
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
|
||||
public final class WrappedPacketInArmAnimation extends WrappedPacket {
|
||||
private static Class<?> packetClass;
|
||||
|
||||
public WrappedPacketInArmAnimation(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
packetClass = PacketTypeClasses.Client.ARM_ANIMATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+120
-79
@@ -1,129 +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.blockdig;
|
||||
|
||||
import io.github.retrooper.packetevents.enums.Direction;
|
||||
import io.github.retrooper.packetevents.enums.PlayerDigType;
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
import io.github.retrooper.packetevents.packet.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 io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
|
||||
import io.github.retrooper.packetevents.utils.vector.Vector3i;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public final class WrappedPacketInBlockDig extends WrappedPacket {
|
||||
//ALL
|
||||
private static Class<?> blockDigClass;
|
||||
//1.8
|
||||
private static final Field[] fields = new Field[3];
|
||||
private static Class<?> blockPositionClass;
|
||||
private static final Reflection.FieldAccessor<Integer>[] blockPosXYZ = new Reflection.FieldAccessor[3];
|
||||
//1.7
|
||||
private static Field face;
|
||||
private static Field e;
|
||||
|
||||
static {
|
||||
private static Class<?> blockDigClass, blockPositionClass, enumDirectionClass, digTypeClass;
|
||||
private static boolean isVersionLowerThan_v_1_8;
|
||||
private Vector3i blockPosition;
|
||||
private Direction direction;
|
||||
private PlayerDigType digType;
|
||||
public WrappedPacketInBlockDig(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
blockDigClass = PacketTypeClasses.Client.BLOCK_DIG;
|
||||
try {
|
||||
blockDigClass = NMSUtils.getNMSClass("PacketPlayInBlockDig");
|
||||
if (version != ServerVersion.v_1_7_10) {
|
||||
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);
|
||||
|
||||
|
||||
try {
|
||||
//blockpos
|
||||
fields[0] = blockDigClass.getDeclaredField("a");
|
||||
//direction
|
||||
fields[1] = blockDigClass.getDeclaredField("b");
|
||||
//digtype
|
||||
fields[2] = blockDigClass.getDeclaredField("c");
|
||||
|
||||
if (version != ServerVersion.v_1_7_10) {
|
||||
blockPosXYZ[0] = Reflection.getField(blockPositionClass.getSuperclass(), int.class, 0);
|
||||
blockPosXYZ[1] = Reflection.getField(blockPositionClass.getSuperclass(), int.class, 1);
|
||||
blockPosXYZ[2] = Reflection.getField(blockPositionClass.getSuperclass(), int.class, 2);
|
||||
} else {
|
||||
face = blockDigClass.getDeclaredField("face");
|
||||
e = blockDigClass.getDeclaredField("e");
|
||||
}
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
for (Field f : fields) {
|
||||
if (f != null) {
|
||||
f.setAccessible(true);
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
if (e != null) {
|
||||
e.setAccessible(true);
|
||||
}
|
||||
|
||||
if (face != null) {
|
||||
face.setAccessible(true);
|
||||
}
|
||||
}
|
||||
|
||||
private Vector3i blockPosition;
|
||||
private Direction direction;
|
||||
private PlayerDigType digType;
|
||||
|
||||
public WrappedPacketInBlockDig(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
Direction enumDirection = null;
|
||||
PlayerDigType enumDigType = null;
|
||||
int x = 0, y = 0, z = 0;
|
||||
//1.7.10
|
||||
try {
|
||||
if (version == ServerVersion.v_1_7_10) {
|
||||
final int x = fields[0].getInt(packet);
|
||||
final int y = fields[1].getInt(packet);
|
||||
final int z = fields[2].getInt(packet);
|
||||
|
||||
this.blockPosition = new Vector3i(x, y, z);
|
||||
|
||||
enumDirection = Direction.get((byte) face.getInt(packet));
|
||||
enumDigType = PlayerDigType.get((byte) e.getInt(packet));
|
||||
if (isVersionLowerThan_v_1_8) {
|
||||
enumDigType = PlayerDigType.values()[(readInt(4))];
|
||||
x = readInt(0);
|
||||
y = readInt(1);
|
||||
z = readInt(2);
|
||||
enumDirection = null;
|
||||
} else {
|
||||
//1.8+
|
||||
final Object blockPosObj = fields[0].get(packet);
|
||||
final Object enumDirectionObj = fields[1].get(packet);
|
||||
final Object digTypeObj = fields[2].get(packet);
|
||||
final Object blockPosObj = readObject(0, blockPositionClass);
|
||||
final Object enumDirectionObj = readObject(0, enumDirectionClass);
|
||||
final Object digTypeObj = readObject(0, digTypeClass);
|
||||
|
||||
final int x = blockPosXYZ[0].get(blockPosObj);
|
||||
final int y = blockPosXYZ[1].get(blockPosObj);
|
||||
final int z = blockPosXYZ[2].get(blockPosObj);
|
||||
x = Reflection.getField(blockPositionClass, int.class, 0).getInt(blockPosObj);
|
||||
y = Reflection.getField(blockPositionClass, int.class, 1).getInt(blockPosObj);
|
||||
z = Reflection.getField(blockPositionClass, int.class, 2).getInt(blockPosObj);
|
||||
|
||||
this.blockPosition = new Vector3i(x, y, z);
|
||||
|
||||
enumDirection = Direction.valueOf(((Enum) enumDirectionObj).name());
|
||||
enumDigType = PlayerDigType.valueOf(((Enum) digTypeObj).name());
|
||||
//.toString() won't work so we must do this
|
||||
enumDirection = Direction.valueOf(((Enum)enumDirectionObj).name());
|
||||
enumDigType = PlayerDigType.valueOf(((Enum)digTypeObj).name());
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.direction = enumDirection;
|
||||
this.blockPosition = new Vector3i(x, y, z);
|
||||
if (enumDirection == null) {
|
||||
this.direction = Direction.NULL;
|
||||
} else {
|
||||
this.direction = enumDirection;
|
||||
}
|
||||
this.digType = enumDigType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get X position of the block
|
||||
* @return Block Position X
|
||||
*/
|
||||
public int getBlockPositionX() {
|
||||
return blockPosition.x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Y position of the block
|
||||
* @return Block Position Y
|
||||
*/
|
||||
public int getBlockPositionY() {
|
||||
return blockPosition.y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Z position of the block
|
||||
* @return Block Position Z
|
||||
*/
|
||||
public int getBlockPositionZ() {
|
||||
return blockPosition.z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use {@link #getBlockPositionX()}, {@link #getBlockPositionY()}, {@link #getBlockPositionZ()}
|
||||
* @return Block Position
|
||||
*/
|
||||
@Deprecated
|
||||
public Vector3i getBlockPosition() {
|
||||
return blockPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the direction
|
||||
* Is Direction.NULL on 1.7.10 FOR NOW
|
||||
* @return Direction
|
||||
*/
|
||||
public Direction getDirection() {
|
||||
return direction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the PlayerDigType enum sent in this packet.
|
||||
* @return Dig Type
|
||||
*/
|
||||
public PlayerDigType getDigType() {
|
||||
return digType;
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+77
-15
@@ -1,7 +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.in.blockplace;
|
||||
|
||||
import io.github.retrooper.packetevents.annotations.Nullable;
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.vector.Vector3i;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -9,33 +34,40 @@ import org.bukkit.inventory.ItemStack;
|
||||
|
||||
|
||||
public final class WrappedPacketInBlockPlace extends WrappedPacket {
|
||||
private static boolean isHigherThan_v_1_8_8, isHigherThan_v_1_7_10;
|
||||
private Vector3i blockPosition;
|
||||
private ItemStack itemStack;
|
||||
|
||||
public WrappedPacketInBlockPlace(final Player player, final Object packet) {
|
||||
super(player, 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_7_10) {
|
||||
WrappedPacketInBlockPlace_1_8.load();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
//1.7.10
|
||||
Vector3i position = null;
|
||||
ItemStack itemStack = null;
|
||||
try {
|
||||
if (version.isHigherThan(ServerVersion.v_1_8_8)) {
|
||||
if (isHigherThan_v_1_8_8) {
|
||||
final WrappedPacketInBlockPlace_1_9 blockPlace_1_9 = new WrappedPacketInBlockPlace_1_9(getPlayer(), packet);
|
||||
final Block block = blockPlace_1_9.getBlock();
|
||||
position = new Vector3i(block.getX(), block.getY(), block.getZ());
|
||||
itemStack = new ItemStack(block.getType());
|
||||
} else if(version.isHigherThan(ServerVersion.v_1_7_10)){
|
||||
} else if (isHigherThan_v_1_7_10) {
|
||||
final WrappedPacketInBlockPlace_1_8 blockPlace_1_8 = new WrappedPacketInBlockPlace_1_8(packet);
|
||||
position = blockPlace_1_8.getBlockPosition();
|
||||
itemStack = blockPlace_1_8.getItemStack();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
final WrappedPacketInBlockPlace_1_7_10 blockPlace_1_7_10 = new WrappedPacketInBlockPlace_1_7_10(getPlayer(), packet);
|
||||
position = blockPlace_1_7_10.getBlockPosition();
|
||||
this.itemStack = blockPlace_1_7_10.getItemStack();
|
||||
itemStack = blockPlace_1_7_10.getItemStack();
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
@@ -44,24 +76,54 @@ public final class WrappedPacketInBlockPlace extends WrappedPacket {
|
||||
this.itemStack = itemStack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player that placed the block
|
||||
* @return Block placer
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get X position of the block
|
||||
* @return Block Position X
|
||||
*/
|
||||
public int getBlockPositionX() {
|
||||
return blockPosition.x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Y position of the block
|
||||
* @return Block Position Y
|
||||
*/
|
||||
public int getBlockPositionY() {
|
||||
return blockPosition.y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Z position of the block
|
||||
* @return Block Position Z
|
||||
*/
|
||||
public int getBlockPositionZ() {
|
||||
return blockPosition.z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use {@link #getBlockPositionX()}, {@link #getBlockPositionY()}, {@link #getBlockPositionZ()}
|
||||
* @return Block Position
|
||||
*/
|
||||
@Deprecated
|
||||
public Vector3i getBlockPosition() {
|
||||
return blockPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* The ItemStack of the placed block.
|
||||
* @return ItemStack
|
||||
*/
|
||||
@Nullable
|
||||
public ItemStack getItemStack() {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
static {
|
||||
if (version.isHigherThan(ServerVersion.v_1_8_8)) {
|
||||
WrappedPacketInBlockPlace_1_9.initStatic();
|
||||
} else if (version.isHigherThan(ServerVersion.v_1_7_10)) {
|
||||
WrappedPacketInBlockPlace_1_8.initStatic();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+25
-1
@@ -1,6 +1,30 @@
|
||||
/*
|
||||
* 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.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.vector.Vector3i;
|
||||
import net.minecraft.server.v1_7_R4.PacketPlayInBlockPlace;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
+57
-24
@@ -1,15 +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.in.blockplace;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
import io.github.retrooper.packetevents.packet.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 io.github.retrooper.packetevents.utils.vector.Vector3i;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
final class WrappedPacketInBlockPlace_1_8 extends WrappedPacket {
|
||||
private static final Reflection.MethodInvoker[] blockPositionXYZInvoker = new Reflection.MethodInvoker[3];
|
||||
private static Class<?> blockPlaceClass, blockPositionClass;
|
||||
private static Reflection.FieldAccessor<?> blockPositionAccessor, itemStackFieldAccessor;
|
||||
private static Class<?> blockPlaceClass, blockPositionClass, blockPositionSuperClass;
|
||||
private Vector3i blockPosition;
|
||||
private ItemStack itemStack;
|
||||
|
||||
@@ -17,41 +42,49 @@ final class WrappedPacketInBlockPlace_1_8 extends WrappedPacket {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
protected static void initStatic() {
|
||||
protected static void load() {
|
||||
blockPlaceClass = PacketTypeClasses.Client.BLOCK_PLACE;
|
||||
try {
|
||||
blockPlaceClass = NMSUtils.getNMSClass("PacketPlayInBlockPlace");
|
||||
|
||||
blockPositionClass = NMSUtils.getNMSClass("BlockPosition");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
itemStackFieldAccessor = Reflection.getField(blockPlaceClass, NMSUtils.nmsItemStackClass, 0);
|
||||
|
||||
blockPositionAccessor = Reflection.getField(blockPlaceClass, blockPositionClass, 1);
|
||||
|
||||
blockPositionXYZInvoker[0] = Reflection.getMethod(blockPositionClass.getSuperclass(), "getX");
|
||||
blockPositionXYZInvoker[1] = Reflection.getMethod(blockPositionClass.getSuperclass(), "getY");
|
||||
blockPositionXYZInvoker[2] = Reflection.getMethod(blockPositionClass.getSuperclass(), "getZ");
|
||||
blockPositionSuperClass = blockPositionClass.getSuperclass();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
Object nmsBlockPos = blockPositionAccessor.get(packet);
|
||||
try {
|
||||
Object nmsBlockPos = Reflection.getField(blockPlaceClass, blockPositionClass, 1).get(packet);
|
||||
this.blockPosition = new Vector3i(0, 0, 0);
|
||||
this.blockPosition.x = (int) Reflection.getMethod(blockPositionSuperClass, "getX", 0).invoke(nmsBlockPos);
|
||||
this.blockPosition.y = (int) Reflection.getMethod(blockPositionSuperClass, "getY", 0).invoke(nmsBlockPos);
|
||||
this.blockPosition.z = (int) Reflection.getMethod(blockPositionSuperClass, "getZ", 0).invoke(nmsBlockPos);
|
||||
|
||||
int x = (int) blockPositionXYZInvoker[0].invoke(nmsBlockPos);
|
||||
int y = (int) blockPositionXYZInvoker[1].invoke(nmsBlockPos);
|
||||
int z = (int) blockPositionXYZInvoker[2].invoke(nmsBlockPos);
|
||||
|
||||
this.blockPosition = new Vector3i(x, y, z);
|
||||
|
||||
this.itemStack = NMSUtils.toBukkitItemStack(itemStackFieldAccessor.get(packet));
|
||||
this.itemStack = NMSUtils.toBukkitItemStack(readObject(0, NMSUtils.nmsItemStackClass));
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Vector3i getBlockPosition() {
|
||||
return blockPosition;
|
||||
}
|
||||
|
||||
public int getBlockPositionX() {
|
||||
return blockPosition.x;
|
||||
}
|
||||
|
||||
public int getBlockPositionY() {
|
||||
return blockPosition.y;
|
||||
}
|
||||
|
||||
public int getBlockPositionZ() {
|
||||
return blockPosition.z;
|
||||
}
|
||||
|
||||
public ItemStack getItemStack() {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
+27
-24
@@ -1,43 +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.packetwrappers.in.blockplace;
|
||||
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
import org.bukkit.Material;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.BlockIteratorUtils;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashSet;
|
||||
|
||||
final class WrappedPacketInBlockPlace_1_9 extends WrappedPacket {
|
||||
private Block block;
|
||||
|
||||
private static Method getTargetBlockMethod;
|
||||
|
||||
public WrappedPacketInBlockPlace_1_9(final Player player, final Object packet) {
|
||||
super(player, packet);
|
||||
}
|
||||
|
||||
protected static void initStatic() {
|
||||
try {
|
||||
getTargetBlockMethod = Player.class.getMethod("getTargetBlock", HashSet.class, int.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
try {
|
||||
this.block = (Block) getTargetBlockMethod.invoke(getPlayer(), null, 3);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
this.block = BlockIteratorUtils.getBlockLookingAt(getPlayer(), 3);
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
|
||||
+33
-35
@@ -1,55 +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.chat;
|
||||
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
|
||||
public final class WrappedPacketInChat extends WrappedPacket {
|
||||
private static Class<?> chatPacketClass;
|
||||
private static Field field;
|
||||
|
||||
static {
|
||||
|
||||
try {
|
||||
chatPacketClass = NMSUtils.getNMSClass("PacketPlayInChat");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
field = chatPacketClass.getDeclaredField(getChatFieldName());
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
field.setAccessible(true);
|
||||
}
|
||||
|
||||
private String message;
|
||||
|
||||
public WrappedPacketInChat(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
private static String getChatFieldName() {
|
||||
if (version == ServerVersion.v_1_7_10) {
|
||||
return "message";
|
||||
}
|
||||
return "a";
|
||||
public static void load() {
|
||||
chatPacketClass = PacketTypeClasses.Client.CHAT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
try {
|
||||
final Object obj = field.get(packet);
|
||||
this.message = obj.toString();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.message = readString(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message.
|
||||
* @return Chat Message
|
||||
*/
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
+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.clientcommand;
|
||||
|
||||
import io.github.retrooper.packetevents.packet.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<?> packetClass;
|
||||
private static Class<?> enumClientCommandClass;
|
||||
private ClientCommand clientCommand;
|
||||
|
||||
public WrappedPacketInClientCommand(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
packetClass = PacketTypeClasses.Client.CLIENT_COMMAND;
|
||||
|
||||
try {
|
||||
enumClientCommandClass = NMSUtils.getNMSClass("EnumClientCommand");
|
||||
} catch (ClassNotFoundException e) {
|
||||
//Probably a subclass
|
||||
enumClientCommandClass = SubclassUtil.getSubClass(packetClass, "EnumClientCommand");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
Object enumObj = readObject(0, enumClientCommandClass);
|
||||
this.clientCommand = ClientCommand.valueOf(enumObj.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Client Command enum sent in the packet
|
||||
*
|
||||
* @return ClientCommand
|
||||
*/
|
||||
public ClientCommand getClientCommand() {
|
||||
return clientCommand;
|
||||
}
|
||||
|
||||
public enum ClientCommand {
|
||||
PERFORM_RESPAWN,
|
||||
REQUEST_STATS,
|
||||
OPEN_INVENTORY_ACHIEVEMENT
|
||||
}
|
||||
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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.annotations.Nullable;
|
||||
import io.github.retrooper.packetevents.packet.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 java.lang.reflect.Field;
|
||||
|
||||
public final class WrappedPacketInCustomPayload extends WrappedPacket {
|
||||
private static Class<?> packetClass, nmsMinecraftKey, nmsPacketDataSerializer;
|
||||
|
||||
private static boolean strPresentInIndex0;
|
||||
private String data;
|
||||
private Object minecraftKey, dataSerializer;
|
||||
public WrappedPacketInCustomPayload(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
packetClass = PacketTypeClasses.Client.CUSTOM_PAYLOAD;
|
||||
strPresentInIndex0 = Reflection.getField(packetClass, String.class, 0) != null;
|
||||
try {
|
||||
nmsPacketDataSerializer = NMSUtils.getNMSClass("PacketDataSerializer");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
if (!strPresentInIndex0) {
|
||||
this.minecraftKey = readObject(0, nmsMinecraftKey);
|
||||
this.dataSerializer = readObject(0, nmsPacketDataSerializer);
|
||||
|
||||
} else {
|
||||
Field dataSerializerField = Reflection.getField(packetClass, nmsPacketDataSerializer, 0);
|
||||
try {
|
||||
this.data = (String) Reflection.getField(packetClass, String.class, 0).get(packet);
|
||||
if (dataSerializerField != null) {
|
||||
this.dataSerializer = dataSerializerField.get(packet);
|
||||
}
|
||||
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data
|
||||
* @return String data
|
||||
*/
|
||||
public String getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the minecraft key
|
||||
* @return Minecraft Key object
|
||||
*/
|
||||
public Object getMinecraftKey() {
|
||||
return minecraftKey;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the data serializer
|
||||
* @return Data Serializer object
|
||||
*/
|
||||
@Nullable
|
||||
public Object getDataSerializer() {
|
||||
return dataSerializer;
|
||||
}
|
||||
}
|
||||
+116
-69
@@ -1,49 +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.in.entityaction;
|
||||
|
||||
import io.github.retrooper.packetevents.annotations.Nullable;
|
||||
import io.github.retrooper.packetevents.enums.PlayerAction;
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
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.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
|
||||
public final class WrappedPacketInEntityAction extends WrappedPacket {
|
||||
private static final HashMap<String, PlayerAction> cachedPlayerActionNames = new HashMap<String, PlayerAction>();
|
||||
private static final HashMap<Integer, PlayerAction> cachedPlayerActionIDs = new HashMap<Integer, PlayerAction>();
|
||||
private static Class<?> entityActionClass;
|
||||
@Nullable
|
||||
private static Class<?> enumPlayerActionClass;
|
||||
private static final Field[] fields = new Field[3];
|
||||
@Nullable
|
||||
private static Object[] enumPlayerActionConstants;
|
||||
|
||||
static {
|
||||
try {
|
||||
entityActionClass = NMSUtils.getNMSClass("PacketPlayInEntityAction");
|
||||
if (version.isHigherThan(ServerVersion.v_1_7_10)) {
|
||||
enumPlayerActionClass = NMSUtils.getNMSClass("PacketPlayInEntityAction$EnumPlayerAction");
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
//ints in 1.7.10, EnumPlayerAction in 1.8+
|
||||
fields[0] = entityActionClass.getDeclaredField("a");
|
||||
fields[1] = entityActionClass.getDeclaredField("animation");
|
||||
fields[2] = entityActionClass.getDeclaredField("c");
|
||||
if (version.isHigherThan(ServerVersion.v_1_7_10)) {
|
||||
enumPlayerActionConstants = enumPlayerActionClass.getEnumConstants();
|
||||
}
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
for (final Field f : fields) {
|
||||
f.setAccessible(true);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isLowerThan_v_1_8;
|
||||
private Entity entity;
|
||||
private int entityId;
|
||||
private PlayerAction action;
|
||||
@@ -53,56 +49,107 @@ public final class WrappedPacketInEntityAction extends WrappedPacket {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
try {
|
||||
final int entityId = fields[0].getInt(packet);
|
||||
final int jumpBoost = fields[2].getInt(packet);
|
||||
|
||||
int animationIndex = -1;
|
||||
|
||||
//1.7.10
|
||||
if (version.isLowerThan(ServerVersion.v_1_8)) {
|
||||
animationIndex = fields[1].getInt(packet);
|
||||
} else {
|
||||
final Object enumObj = fields[1].get(packet);
|
||||
|
||||
final Object[] enumValues = enumPlayerActionConstants;
|
||||
final int len = enumValues.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
final Object val = enumValues[i];
|
||||
if (val.toString().equals(enumObj.toString())) {
|
||||
animationIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.entityId = entityId;
|
||||
this.action = action;
|
||||
this.jumpBoost = jumpBoost;
|
||||
this.action = PlayerAction.get((byte) animationIndex);
|
||||
|
||||
this.entity = NMSUtils.getEntityById(this.entityId);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
public static void load() {
|
||||
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
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
final int entityId = readInt(0);
|
||||
final int jumpBoost;
|
||||
if (isLowerThan_v_1_8) {
|
||||
jumpBoost = readInt(2);
|
||||
} else {
|
||||
jumpBoost = readInt(1);
|
||||
}
|
||||
|
||||
//1.7.10
|
||||
if (isLowerThan_v_1_8) {
|
||||
int animationIndex = readInt(1);
|
||||
this.action = cachedPlayerActionIDs.get(animationIndex);
|
||||
} else {
|
||||
final Object enumObj = readObject(0, enumPlayerActionClass);
|
||||
final String enumValueName = enumObj.toString();
|
||||
this.action = cachedPlayerActionNames.get(enumValueName);
|
||||
}
|
||||
|
||||
|
||||
this.entityId = entityId;
|
||||
this.jumpBoost = jumpBoost;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(this.entityId);
|
||||
}
|
||||
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() {
|
||||
return entityId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player action.
|
||||
*
|
||||
* @return Player Action
|
||||
*/
|
||||
public PlayerAction getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the jump boost integer.
|
||||
*
|
||||
* @return Jump Boost
|
||||
*/
|
||||
public int getJumpBoost() {
|
||||
return jumpBoost;
|
||||
}
|
||||
|
||||
public enum PlayerAction {
|
||||
START_SNEAKING,
|
||||
STOP_SNEAKING,
|
||||
STOP_SLEEPING,
|
||||
START_SPRINTING,
|
||||
STOP_SPRINTING,
|
||||
START_RIDING_JUMP,
|
||||
STOP_RIDING_JUMP,
|
||||
OPEN_INVENTORY,
|
||||
START_FALL_FLYING
|
||||
}
|
||||
|
||||
}
|
||||
+44
-94
@@ -1,45 +1,35 @@
|
||||
/*
|
||||
* 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.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
|
||||
public class WrappedPacketInFlying extends WrappedPacket {
|
||||
private static Class<?> flyingClass;
|
||||
private static final Field[] fields = new Field[8]; //x, y, z, yaw pitch, onGround, isPositionPacket, isLookPacket
|
||||
|
||||
static {
|
||||
|
||||
try {
|
||||
flyingClass = NMSUtils.getNMSClass("PacketPlayInFlying");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
fields[0] = flyingClass.getDeclaredField("x");
|
||||
fields[1] = flyingClass.getDeclaredField("y");
|
||||
fields[2] = flyingClass.getDeclaredField("z");
|
||||
fields[3] = flyingClass.getDeclaredField("yaw");
|
||||
fields[4] = flyingClass.getDeclaredField("pitch");
|
||||
fields[5] = flyingClass.getDeclaredField(getOnGroundFieldName());
|
||||
fields[6] = flyingClass.getDeclaredField("hasPos");
|
||||
fields[7] = flyingClass.getDeclaredField("hasLook");
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
for (Field f : fields) {
|
||||
if (f != null) {
|
||||
f.setAccessible(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private double x;
|
||||
private double y;
|
||||
private double z;
|
||||
@@ -48,99 +38,59 @@ public class WrappedPacketInFlying extends WrappedPacket {
|
||||
private boolean onGround;
|
||||
private boolean isPosition;
|
||||
private boolean isLook;
|
||||
|
||||
public WrappedPacketInFlying(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
private static String getOnGroundFieldName() {
|
||||
if (version == ServerVersion.v_1_7_10) {
|
||||
return "g";
|
||||
}
|
||||
return "f";
|
||||
public static void load() {
|
||||
flyingClass = PacketTypeClasses.Client.FLYING;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
try {
|
||||
this.x = fields[0].getDouble(packet);
|
||||
this.y = fields[1].getDouble(packet);
|
||||
this.z = fields[2].getDouble(packet);
|
||||
x = readDouble(0);
|
||||
y = readDouble(1);
|
||||
z = readDouble(2);
|
||||
|
||||
this.yaw = fields[3].getFloat(packet);
|
||||
this.pitch = fields[4].getFloat(packet);
|
||||
yaw = readFloat(0);
|
||||
pitch = readFloat(1);
|
||||
|
||||
this.onGround = fields[5].getBoolean(packet);
|
||||
onGround = readBoolean(0);
|
||||
|
||||
this.isPosition = fields[6].getBoolean(packet);
|
||||
this.isLook = fields[7].getBoolean(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
isPosition = readBoolean(1);
|
||||
isLook = readBoolean(2);
|
||||
}
|
||||
|
||||
public final double getX() {
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public final double getY() {
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public final double getZ() {
|
||||
public double getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public final float getYaw() {
|
||||
public float getYaw() {
|
||||
return yaw;
|
||||
}
|
||||
|
||||
public final float getPitch() {
|
||||
public float getPitch() {
|
||||
return pitch;
|
||||
}
|
||||
|
||||
public final boolean isOnGround() {
|
||||
public boolean isOnGround() {
|
||||
return onGround;
|
||||
}
|
||||
|
||||
public boolean isPosition() {
|
||||
public final boolean isPosition() {
|
||||
return isPosition;
|
||||
}
|
||||
|
||||
public boolean isLook() {
|
||||
public final boolean isLook() {
|
||||
return isLook;
|
||||
}
|
||||
|
||||
public static class WrappedPacketInPosition extends WrappedPacketInFlying {
|
||||
public WrappedPacketInPosition(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPosition() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLook() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static class WrappedPacketInPosition_Look extends WrappedPacketInFlying {
|
||||
public WrappedPacketInPosition_Look(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLook() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPosition() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.packet.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
|
||||
public final class WrappedPacketInHeldItemSlot extends WrappedPacket {
|
||||
private static Class<?> packetClass;
|
||||
private int itemInHandIndex;
|
||||
|
||||
public WrappedPacketInHeldItemSlot(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
packetClass = PacketTypeClasses.Client.HELD_ITEM_SLOT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
try {
|
||||
itemInHandIndex = readInt(0);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index of the item we currently have in hand.
|
||||
* @return Item in hand Index
|
||||
*/
|
||||
public int getItemInHandIndex() {
|
||||
return itemInHandIndex;
|
||||
}
|
||||
|
||||
}
|
||||
+42
-35
@@ -1,55 +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.in.keepalive;
|
||||
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
|
||||
public final class WrappedPacketInKeepAlive extends WrappedPacket {
|
||||
private static Class<?> keepAliveClass;
|
||||
//1.7.10->1.12.2 has int field "a", rest as long field "a"
|
||||
private static Field idField;
|
||||
|
||||
static {
|
||||
try {
|
||||
keepAliveClass = NMSUtils.getNMSClass("PacketPlayInKeepAlive");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
idField = keepAliveClass.getDeclaredField("a");
|
||||
idField.setAccessible(true);
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static Class<?> packetClass;
|
||||
private static boolean integerPresentInIndex0;
|
||||
private long id;
|
||||
|
||||
public WrappedPacketInKeepAlive(final Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
packetClass = PacketTypeClasses.Client.KEEP_ALIVE;
|
||||
integerPresentInIndex0 = Reflection.getField(packetClass, int.class, 0) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
try {
|
||||
if (version.isHigherThan(ServerVersion.v_1_12)) {
|
||||
this.id = idField.getLong(packet);
|
||||
} else {
|
||||
this.id = idField.getInt(packet);
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
if (!integerPresentInIndex0) {
|
||||
this.id = readLong(0);
|
||||
} else {
|
||||
this.id = readInt(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cast this long to an integer if you are using 1.7.10->1.12.2!
|
||||
* In 1.13.2->1.15.2 a long is sent
|
||||
* Get the ID response from the client.
|
||||
*
|
||||
* @return
|
||||
* 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() {
|
||||
return id;
|
||||
|
||||
+197
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* 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.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class WrappedPacketInSettings extends WrappedPacket {
|
||||
private static Class<?> packetClass;
|
||||
private static Class<?> chatVisibilityEnumClass;
|
||||
|
||||
private static boolean isLowerThan_v_1_8;
|
||||
private String locale;
|
||||
private int viewDistance;
|
||||
private ChatVisibility chatVisibility;
|
||||
private boolean chatColors;
|
||||
private HashMap<DisplayedSkinPart, Boolean> displayedSkinParts;
|
||||
|
||||
public WrappedPacketInSettings(final Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
packetClass = PacketTypeClasses.Client.SETTINGS;
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
public static Class<?> getChatVisibilityEnumClass() {
|
||||
return chatVisibilityEnumClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
try {
|
||||
//LOCALE
|
||||
this.locale = readString(0);
|
||||
//VIEW DISTANCE
|
||||
this.viewDistance = readInt(0);
|
||||
|
||||
//CHAT VISIBILITY
|
||||
Object chatVisibilityEnumObject = readObject(0, chatVisibilityEnumClass);
|
||||
String enumValueAsString = chatVisibilityEnumObject.toString();
|
||||
if (enumValueAsString.equals("FULL")) {
|
||||
chatVisibility = ChatVisibility.ENABLED;
|
||||
} else if (enumValueAsString.equals("SYSTEM")) {
|
||||
chatVisibility = ChatVisibility.COMMANDS_ONLY;
|
||||
} else {
|
||||
chatVisibility = ChatVisibility.HIDDEN;
|
||||
}
|
||||
|
||||
//CHAT COLORS
|
||||
this.chatColors = readBoolean(0);
|
||||
|
||||
//DISPLAYED SKIN PARTS
|
||||
this.displayedSkinParts = new HashMap<DisplayedSkinPart, Boolean>();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get language client setting
|
||||
*
|
||||
* @return String Locale
|
||||
*/
|
||||
public String getLocale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get client view distance.
|
||||
*
|
||||
* @return View Distance
|
||||
*/
|
||||
public int getViewDistance() {
|
||||
return viewDistance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Chat Visibility
|
||||
*
|
||||
* @return Chat Visibility
|
||||
*/
|
||||
public ChatVisibility getChatVisibility() {
|
||||
return chatVisibility;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is chat colors
|
||||
*
|
||||
* @return Chat Colors
|
||||
*/
|
||||
public boolean isChatColors() {
|
||||
return chatColors;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
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) {
|
||||
//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
|
||||
}
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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.packet.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
|
||||
public class WrappedPacketInSteerVehicle extends WrappedPacket {
|
||||
private static Class<?> packetClass;
|
||||
private float side, forward;
|
||||
private boolean jump, unmount;
|
||||
public WrappedPacketInSteerVehicle(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
packetClass = PacketTypeClasses.Client.STEER_VEHICLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
this.side = readFloat(0);
|
||||
this.forward = readFloat(1);
|
||||
|
||||
this.jump = readBoolean(0);
|
||||
this.unmount = readBoolean(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the side value.
|
||||
*
|
||||
* If positive, they are moving to the left, if negative, they are moving to the right.
|
||||
* @return Side Value
|
||||
*/
|
||||
public float getSideValue() {
|
||||
return side;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the forward value.
|
||||
*
|
||||
* If positive, they are moving forward, if negative, they are moving backwards.
|
||||
* @return Forward Value
|
||||
*/
|
||||
public float getForwardValue() {
|
||||
return forward;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is a Jump
|
||||
* @return Is Jump
|
||||
*/
|
||||
public boolean isJump() {
|
||||
return jump;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is an unmount
|
||||
* @return Is Unmounting
|
||||
*/
|
||||
public boolean isUnmount() {
|
||||
return unmount;
|
||||
}
|
||||
}
|
||||
+48
-26
@@ -1,10 +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.packetwrappers.in.transaction;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
|
||||
public final class WrappedPacketInTransaction extends WrappedPacket {
|
||||
private static Class<?> packetClass;
|
||||
private int windowId;
|
||||
private short actionNumber;
|
||||
private boolean accepted;
|
||||
@@ -12,40 +36,38 @@ public final class WrappedPacketInTransaction extends WrappedPacket {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
this.windowId = windowIdAccessor.get(packet);
|
||||
this.actionNumber = actionNumberAccessor.get(packet);
|
||||
this.accepted = acceptedAccessor.get(packet);
|
||||
public static void load() {
|
||||
packetClass = PacketTypeClasses.Client.TRANSACTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
this.windowId = readInt(0);
|
||||
this.actionNumber = readShort(0);
|
||||
this.accepted = readBoolean(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the window ID.
|
||||
* @return Window ID
|
||||
*/
|
||||
public int getWindowId() {
|
||||
return windowId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the action number.
|
||||
* @return Action number
|
||||
*/
|
||||
public short getActionNumber() {
|
||||
return actionNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is transaction accepted.
|
||||
* @return Transaction Accepted
|
||||
*/
|
||||
public boolean isAccepted() {
|
||||
return accepted;
|
||||
}
|
||||
|
||||
private static Class<?> packetClass;
|
||||
|
||||
private static final Reflection.FieldAccessor<Integer> windowIdAccessor;
|
||||
private static final Reflection.FieldAccessor<Short> actionNumberAccessor;
|
||||
private static final Reflection.FieldAccessor<Boolean> acceptedAccessor;
|
||||
|
||||
static {
|
||||
try {
|
||||
packetClass = NMSUtils.getNMSClass("PacketPlayInTransaction");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
windowIdAccessor = Reflection.getField(packetClass, int.class, 0);
|
||||
actionNumberAccessor = Reflection.getField(packetClass, short.class, 0);
|
||||
acceptedAccessor= Reflection.getField(packetClass, boolean.class, 0);
|
||||
}
|
||||
}
|
||||
+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.in.updatesign;
|
||||
|
||||
import io.github.retrooper.packetevents.packet.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;
|
||||
|
||||
public class WrappedPacketInUpdateSign extends WrappedPacket {
|
||||
private static boolean v_1_7_mode, strArrayMode;
|
||||
private static Class<?> blockPosClass, iChatBaseComponentClass;
|
||||
|
||||
private int x, y, z;
|
||||
private String[] lines;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
if (v_1_7_mode) {
|
||||
x = readInt(0);
|
||||
y = readInt(1);
|
||||
z = readInt(2);
|
||||
} else {
|
||||
Object blockPos = readObject(0, blockPosClass);
|
||||
try {
|
||||
x = Reflection.getField(blockPosClass, int.class, 0).getInt(packet);
|
||||
y = Reflection.getField(blockPosClass, int.class, 1).getInt(packet);
|
||||
z = Reflection.getField(blockPosClass, int.class, 2).getInt(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (strArrayMode) {
|
||||
//1.7.10 and the newest versions use this
|
||||
lines = readStringArray(0);
|
||||
} else {
|
||||
//1.8 uses this for example
|
||||
Object[] iChatComponents = readObjectArray(0, iChatBaseComponentClass);
|
||||
for (int i = 0; i < iChatComponents.length; i++) {
|
||||
lines[i] = WrappedPacketOutChat.
|
||||
toStringFromIChatBaseComponent(iChatComponents[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getBlockPositionX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getBlockPositionY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public int getBlockPositionZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public String[] getTextLines() {
|
||||
return lines;
|
||||
}
|
||||
}
|
||||
+73
-47
@@ -1,72 +1,98 @@
|
||||
/*
|
||||
* 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.enums.EntityUseAction;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
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.lang.reflect.Field;
|
||||
|
||||
public final class WrappedPacketInUseEntity extends WrappedPacket {
|
||||
private static Class<?> useEntityClass, entityClass;
|
||||
private static final Field[] fields = new Field[2];
|
||||
|
||||
static {
|
||||
|
||||
try {
|
||||
useEntityClass = NMSUtils.getNMSClass("PacketPlayInUseEntity");
|
||||
entityClass = NMSUtils.getNMSClass("Entity");
|
||||
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
fields[0] = useEntityClass.getDeclaredField("a");
|
||||
fields[1] = useEntityClass.getDeclaredField("action");
|
||||
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
for (Field f : fields) {
|
||||
if (f != null) {
|
||||
f.setAccessible(true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private int entityId;
|
||||
private static Class<?> useEntityClass;
|
||||
private static Class<?> enumEntityUseActionClass;
|
||||
private Entity entity;
|
||||
private int entityID;
|
||||
private EntityUseAction action;
|
||||
|
||||
public WrappedPacketInUseEntity(final Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
public static void load() {
|
||||
//System.out.println("USE ENTITY HAS BEEN LOADED BROOOIOII");
|
||||
useEntityClass = NMSUtils.getNMSClassWithoutException("PacketPlayInUseEntity");
|
||||
/*if(useEntityClass == null) {
|
||||
System.out.println("failed to init use entity wtfffff");
|
||||
}*/
|
||||
try {
|
||||
this.entityId = fields[0].getInt(packet);
|
||||
this.entity = NMSUtils.getEntityById(this.entityId);
|
||||
final Object useActionEnum = fields[1].get(packet);
|
||||
this.action = EntityUseAction.valueOf(useActionEnum.toString());
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
enumEntityUseActionClass = NMSUtils.getNMSClass("EnumEntityUseAction");
|
||||
} catch (ClassNotFoundException e) {
|
||||
//That is fine, it is probably a subclass
|
||||
enumEntityUseActionClass = SubclassUtil.getSubClass(useEntityClass, "EnumEntityUseAction");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
this.entityID = readInt(0);
|
||||
if(enumEntityUseActionClass == null) {
|
||||
System.out.println("cls is null");
|
||||
}
|
||||
final Object useActionEnum = readObject(0, enumEntityUseActionClass);
|
||||
this.action = EntityUseAction.valueOf(useActionEnum.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup the associated entity by the ID that was sent in the packet.
|
||||
* @return Entity
|
||||
*/
|
||||
public Entity getEntity() {
|
||||
return entity;
|
||||
if(entity != null) {
|
||||
return entity;
|
||||
}
|
||||
return entity = NMSUtils.getEntityById(this.entityID);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
return entityId;
|
||||
return entityID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the associated action.
|
||||
* @return Get EntityUseAction
|
||||
*/
|
||||
public EntityUseAction getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
public enum EntityUseAction {
|
||||
INTERACT, INTERACT_AT, ATTACK, INVALID
|
||||
}
|
||||
}
|
||||
+231
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* 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.packet.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<String, Integer>();
|
||||
private static final HashMap<Integer, ArrayList<WindowClickType>> windowClickTypeCache = new HashMap<Integer, ArrayList<WindowClickType>>();
|
||||
private static Class<?> packetClass, invClickTypeClass;
|
||||
private static boolean isClickModePrimitive = false;
|
||||
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() {
|
||||
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;
|
||||
}
|
||||
|
||||
private static ArrayList<WindowClickType> getArrayListOfWindowClickTypes(WindowClickType... types) {
|
||||
ArrayList<WindowClickType> arrayList = new ArrayList<WindowClickType>(types.length);
|
||||
arrayList.addAll(Arrays.asList(types));
|
||||
return arrayList;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
this.id = readInt(0);
|
||||
this.slot = readInt(1);
|
||||
this.button = readInt(2);
|
||||
this.actionNumber = readShort(0);
|
||||
Object nmsItemStack = readObject(0, NMSUtils.nmsItemStackClass);
|
||||
this.clickedItem = NMSUtils.toBukkitItemStack(nmsItemStack);
|
||||
Object clickMode = readAnyObject(5);
|
||||
|
||||
if (isClickModePrimitive) {
|
||||
mode = (int) clickMode;
|
||||
} else {
|
||||
mode = invClickTypeMapCache.get(clickMode.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Window ID.
|
||||
* @return Get Window ID
|
||||
*/
|
||||
public int getWindowID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Window slot.
|
||||
* @return Get Window Slot
|
||||
*/
|
||||
public int getWindowSlot() {
|
||||
return slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Window button.
|
||||
* @return Get Window Button
|
||||
*/
|
||||
public int getWindowButton() {
|
||||
return button;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the action number.
|
||||
* @return Get Action Number
|
||||
*/
|
||||
public short getActionNumber() {
|
||||
return actionNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
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() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the clicked item.
|
||||
* @return Get Clicked ItemStack
|
||||
*/
|
||||
public ItemStack getClickedItem() {
|
||||
return clickedItem;
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
+37
-27
@@ -1,34 +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.packetwrappers.out.abilities;
|
||||
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
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;
|
||||
|
||||
private static final Reflection.FieldAccessor<Boolean>[] booleanFieldAccessors = new Reflection.FieldAccessor[4];
|
||||
private static final Reflection.FieldAccessor<Float>[] floatFieldAccessors = new Reflection.FieldAccessor[2];
|
||||
|
||||
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();
|
||||
booleanFieldAccessors[0].set(instance, isVulnerable);
|
||||
booleanFieldAccessors[1].set(instance, isFlying);
|
||||
booleanFieldAccessors[2].set(instance, allowFlight);
|
||||
booleanFieldAccessors[3].set(instance, canBuildInstantly);
|
||||
|
||||
floatFieldAccessors[0].set(instance, flySpeed);
|
||||
floatFieldAccessors[1].set(instance, walkSpeed);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
static {
|
||||
try {
|
||||
playerAbilitiesClass = NMSUtils.getNMSClass("PlayerAbilities");
|
||||
@@ -40,13 +45,18 @@ final class PlayerAbilitiesUtils {
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
for (byte i = 0; i < booleanFieldAccessors.length; i++) {
|
||||
booleanFieldAccessors[i] = Reflection.getField(playerAbilitiesClass, boolean.class, i);
|
||||
}
|
||||
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();
|
||||
Reflection.getField(playerAbilitiesClass, boolean.class, 0).setBoolean(instance, isVulnerable);
|
||||
Reflection.getField(playerAbilitiesClass, boolean.class, 1).setBoolean(instance, isFlying);
|
||||
Reflection.getField(playerAbilitiesClass, boolean.class, 2).setBoolean(instance, allowFlight);
|
||||
Reflection.getField(playerAbilitiesClass, boolean.class, 3).setBoolean(instance, canBuildInstantly);
|
||||
|
||||
for (byte i = 0; i < floatFieldAccessors.length; i++) {
|
||||
floatFieldAccessors[i] = Reflection.getField(playerAbilitiesClass, float.class, i);
|
||||
}
|
||||
Reflection.getField(playerAbilitiesClass, float.class, 0).setFloat(instance, flySpeed);
|
||||
Reflection.getField(playerAbilitiesClass, float.class, 1).setFloat(instance, walkSpeed);
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
+90
-61
@@ -1,24 +1,48 @@
|
||||
/*
|
||||
* 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.Sendable;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
import io.github.retrooper.packetevents.packet.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 Sendable {
|
||||
public final class WrappedPacketOutAbilities extends WrappedPacket implements SendableWrapper {
|
||||
private static Class<?> packetClass;
|
||||
private static Constructor<?> packetConstructor;
|
||||
private boolean vulnerable, flying, allowFlight, instantBuild;
|
||||
private float flySpeed, walkSpeed;
|
||||
|
||||
public WrappedPacketOutAbilities(final Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public WrappedPacketOutAbilities(final boolean isVulnerable, final boolean isFlying, final boolean allowFlight, final boolean canBuildInstantly,
|
||||
final float flySpeed, final float walkSpeed) {
|
||||
super(null);
|
||||
super();
|
||||
this.vulnerable = isVulnerable;
|
||||
this.flying = isFlying;
|
||||
this.allowFlight = allowFlight;
|
||||
@@ -27,68 +51,73 @@ public final class WrappedPacketOutAbilities extends WrappedPacket implements Se
|
||||
this.walkSpeed = walkSpeed;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
this.vulnerable = booleanFieldAccessors[0].get(packet);
|
||||
this.flying = booleanFieldAccessors[1].get(packet);
|
||||
this.allowFlight = booleanFieldAccessors[2].get(packet);
|
||||
this.instantBuild = booleanFieldAccessors[3].get(packet);
|
||||
|
||||
this.flySpeed = floatFieldAccessors[0].get(packet);
|
||||
this.walkSpeed = floatFieldAccessors[1].get(packet);
|
||||
}
|
||||
|
||||
public boolean isVulnerable() {
|
||||
return vulnerable;
|
||||
}
|
||||
|
||||
public boolean isFlying() {
|
||||
return flying;
|
||||
}
|
||||
|
||||
public boolean isFlightAllowed() {
|
||||
return allowFlight;
|
||||
}
|
||||
|
||||
public boolean canInstantlyBuild() {
|
||||
return instantBuild;
|
||||
}
|
||||
|
||||
public float getFlySpeed() {
|
||||
return flySpeed;
|
||||
}
|
||||
|
||||
public float getWalkSpeed() {
|
||||
return walkSpeed;
|
||||
}
|
||||
|
||||
private static Class<?> packetClass;
|
||||
|
||||
private static Constructor<?> packetConstructor;
|
||||
|
||||
private static final Reflection.FieldAccessor<Boolean>[] booleanFieldAccessors = new Reflection.FieldAccessor[4];
|
||||
private static final Reflection.FieldAccessor<Float>[] floatFieldAccessors = new Reflection.FieldAccessor[2];
|
||||
|
||||
static {
|
||||
try {
|
||||
packetClass = NMSUtils.getNMSClass("PacketPlayOutAbilities");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
public static void load() {
|
||||
packetClass = PacketTypeClasses.Server.ABILITIES;
|
||||
|
||||
try {
|
||||
packetConstructor = packetClass.getConstructor(PlayerAbilitiesUtils.playerAbilitiesClass);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
for (byte i = 0; i < booleanFieldAccessors.length; i++) {
|
||||
booleanFieldAccessors[i] = Reflection.getField(packetClass, boolean.class, i);
|
||||
}
|
||||
@Override
|
||||
protected void setup() {
|
||||
this.vulnerable = readBoolean(0);
|
||||
this.flying = readBoolean(1);
|
||||
this.allowFlight = readBoolean(2);
|
||||
this.instantBuild = readBoolean(3);
|
||||
|
||||
for (byte i = 0; i < floatFieldAccessors.length; i++) {
|
||||
floatFieldAccessors[i] = Reflection.getField(packetClass, float.class, i);
|
||||
}
|
||||
this.flySpeed = readFloat(0);
|
||||
this.walkSpeed = readFloat(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the client be vulnerable?
|
||||
* @return Is Vulnerable
|
||||
*/
|
||||
public boolean isVulnerable() {
|
||||
return vulnerable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the client be flying?
|
||||
* @return Is Flying
|
||||
*/
|
||||
public boolean isFlying() {
|
||||
return flying;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the client be allowed to fly?
|
||||
* @return Is Allowed To Fly
|
||||
*/
|
||||
public boolean isFlightAllowed() {
|
||||
return allowFlight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the client be able to build instantly?
|
||||
* @return Is Allowed To Build Instantly
|
||||
*/
|
||||
public boolean canInstantlyBuild() {
|
||||
return instantBuild;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the client's defined fly speed.
|
||||
* @return Get Fly Speed
|
||||
*/
|
||||
public float getFlySpeed() {
|
||||
return flySpeed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the client's defined walk speed.
|
||||
* @return Get Walk Speed
|
||||
*/
|
||||
public float getWalkSpeed() {
|
||||
return walkSpeed;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+84
-47
@@ -1,23 +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.animation;
|
||||
|
||||
import io.github.retrooper.packetevents.enums.EntityAnimationType;
|
||||
import io.github.retrooper.packetevents.packetwrappers.Sendable;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
import io.github.retrooper.packetevents.packet.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.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.HashMap;
|
||||
|
||||
public final class WrappedPacketOutAnimation extends WrappedPacket implements Sendable {
|
||||
public final class WrappedPacketOutAnimation extends WrappedPacket implements SendableWrapper {
|
||||
private static Class<?> animationClass, nmsEntityClass;
|
||||
private static Constructor<?> animationConstructor;
|
||||
private static final Field[] fields = new Field[2];
|
||||
|
||||
static {
|
||||
private static final HashMap<Integer, EntityAnimationType> cachedAnimationIDS = new HashMap<Integer, EntityAnimationType>();
|
||||
private static final HashMap<EntityAnimationType, Integer> cachedAnimations = new HashMap<EntityAnimationType, Integer>();
|
||||
private Entity entity;
|
||||
private int entityID;
|
||||
private EntityAnimationType type;
|
||||
public WrappedPacketOutAnimation(final Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public WrappedPacketOutAnimation(final Entity target, final EntityAnimationType type) {
|
||||
super();
|
||||
this.entityID = target.getEntityId();
|
||||
this.entity = target;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
animationClass = PacketTypeClasses.Server.ANIMATION;
|
||||
try {
|
||||
animationClass = NMSUtils.getNMSClass("PacketPlayOutAnimation");
|
||||
nmsEntityClass = NMSUtils.getNMSClass("Entity");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
@@ -28,56 +67,50 @@ public final class WrappedPacketOutAnimation extends WrappedPacket implements Se
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
fields[0] = animationClass.getDeclaredField("a");
|
||||
fields[1] = animationClass.getDeclaredField("b");
|
||||
} catch (NoSuchFieldException 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);
|
||||
|
||||
for (final Field f : fields) {
|
||||
f.setAccessible(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Entity entity;
|
||||
private int entityID;
|
||||
private EntityAnimationType type;
|
||||
|
||||
public WrappedPacketOutAnimation(final Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public WrappedPacketOutAnimation(final Entity target, final EntityAnimationType type) {
|
||||
super(null);
|
||||
this.entityID = target.getEntityId();
|
||||
this.entity = target;
|
||||
this.type = type;
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
try {
|
||||
//a - ID
|
||||
//b - TYPE
|
||||
this.entityID = fields[0].getInt(packet);
|
||||
this.entity = NMSUtils.getEntityById(this.entityID);
|
||||
this.type = EntityAnimationType.get(fields[1].getInt(packet));
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
this.entityID = readInt(0);
|
||||
int animationID = readInt(1);
|
||||
this.type = cachedAnimationIDS.get(animationID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup the associated entity by the ID that was sent in the packet.
|
||||
* @return Entity
|
||||
*/
|
||||
public Entity getEntity() {
|
||||
return this.entity;
|
||||
return NMSUtils.getEntityById(this.entityID);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
return this.entityID;
|
||||
return entityID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the entity animation type.
|
||||
* @return Get Entity Animation Type
|
||||
*/
|
||||
public EntityAnimationType getAnimationType() {
|
||||
return type;
|
||||
}
|
||||
@@ -85,7 +118,7 @@ public final class WrappedPacketOutAnimation extends WrappedPacket implements Se
|
||||
@Override
|
||||
public Object asNMSPacket() {
|
||||
final Object nmsEntity = NMSUtils.getNMSEntity(this.entity);
|
||||
final int index = type.getIndex();
|
||||
final int index = cachedAnimations.get(type);
|
||||
try {
|
||||
return animationConstructor.newInstance(nmsEntity, index);
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
@@ -93,4 +126,8 @@ public final class WrappedPacketOutAnimation extends WrappedPacket implements Se
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public enum EntityAnimationType {
|
||||
SWING_MAIN_ARM, TAKE_DAMAGE, LEAVE_BED, SWING_OFFHAND, CRITICAL_EFFECT, MAGIC_CRITICAL_EFFECT
|
||||
}
|
||||
}
|
||||
+232
-73
@@ -1,77 +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.out.chat;
|
||||
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.packetwrappers.Sendable;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
import io.github.retrooper.packetevents.annotations.Beta;
|
||||
import io.github.retrooper.packetevents.annotations.NotNull;
|
||||
import io.github.retrooper.packetevents.packet.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.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
|
||||
public final class WrappedPacketOutChat extends WrappedPacket implements Sendable {
|
||||
/**
|
||||
* This wrapper MIGHT not be stable
|
||||
*/
|
||||
@Beta
|
||||
public final class WrappedPacketOutChat extends WrappedPacket implements SendableWrapper {
|
||||
private static Constructor<?> chatClassConstructor;
|
||||
private static Class<?> chatClass, iChatBaseComponentClass, chatSerializerClass;
|
||||
private static Field iChatBaseField;
|
||||
private static Method serialize, getStringOfIChatBase;
|
||||
|
||||
static {
|
||||
try {
|
||||
chatClass = NMSUtils.getNMSClass("PacketPlayOutChat");
|
||||
iChatBaseComponentClass = NMSUtils.getNMSClass("IChatBaseComponent");
|
||||
|
||||
//In 1.8.3+ the ChatSerializer class is declared in the IChatBaseComponent class, so we have to handle tahat
|
||||
if (version.isHigherThan(ServerVersion.v_1_8)) {
|
||||
for (final Class<?> cls : iChatBaseComponentClass.getDeclaredClasses()) {
|
||||
if (cls.getSimpleName().equals("ChatSerializer")) {
|
||||
chatSerializerClass = cls;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
chatSerializerClass = NMSUtils.getNMSClass("ChatSerializer");
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
chatClassConstructor = chatClass.getConstructor(iChatBaseComponentClass);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
serialize = chatSerializerClass.getMethod("a", String.class);
|
||||
getStringOfIChatBase = iChatBaseComponentClass.getMethod(getTextMethodName());
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
iChatBaseField = chatClass.getDeclaredField("a");
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
iChatBaseField.setAccessible(true);
|
||||
|
||||
}
|
||||
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<ChatPosition, Byte>();
|
||||
private static final HashMap<Byte, ChatPosition> cachedChatPositionIntegers = new HashMap<Byte, ChatPosition>();
|
||||
private static final HashMap<String, Byte> cachedChatMessageTypeIntegers = new HashMap<String, Byte>();
|
||||
private String message;
|
||||
private ChatPosition chatPosition;
|
||||
private UUID uuid;
|
||||
|
||||
|
||||
@Deprecated
|
||||
public WrappedPacketOutChat(String message) {
|
||||
this(message, null);
|
||||
}
|
||||
|
||||
public WrappedPacketOutChat(final Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public WrappedPacketOutChat(final String message) {
|
||||
super(null);
|
||||
this.message = "{\"text\": \"" + message + "\"}";
|
||||
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 getStringOfIChatBase.invoke(obj).toString();
|
||||
return Reflection.getMethod(iChatBaseComponentClass, String.class, 0).invoke(obj).toString();
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -80,32 +173,38 @@ public final class WrappedPacketOutChat extends WrappedPacket implements Sendabl
|
||||
|
||||
public static Object toIChatBaseComponent(String msg) {
|
||||
try {
|
||||
return serialize.invoke(null, msg);
|
||||
return Reflection.getMethod(chatSerializerClass, 0, String.class).invoke(null, msg);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String getTextMethodName() {
|
||||
//1.7.10
|
||||
if (version.isLowerThan(ServerVersion.v_1_8)) {
|
||||
return "e"; //or c
|
||||
} else {
|
||||
return "getText";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
//all fields are IChatBaseComponents, and named 'a'
|
||||
|
||||
try {
|
||||
Object iChatBaseObj = iChatBaseField.get(packet);
|
||||
final Object iChatBaseObj = readObject(0, iChatBaseComponentClass);
|
||||
|
||||
Object contentString = getStringOfIChatBase.invoke(iChatBaseObj);
|
||||
final Object contentString = Reflection.getMethod(iChatBaseComponentClass, String.class, 0).invoke(iChatBaseObj);
|
||||
|
||||
this.message = contentString.toString();
|
||||
|
||||
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;
|
||||
}
|
||||
this.chatPosition = cachedChatPositionIntegers.get(chatPosInteger);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -113,16 +212,76 @@ public final class WrappedPacketOutChat extends WrappedPacket implements Sendabl
|
||||
|
||||
@Override
|
||||
public Object asNMSPacket() {
|
||||
try {
|
||||
return chatClassConstructor.newInstance(toIChatBaseComponent(this.message));
|
||||
} catch (InstantiationException | InvocationTargetException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
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() {
|
||||
return this.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
|
||||
*/
|
||||
@NotNull
|
||||
public ChatPosition getChatPosition() {
|
||||
if(this.chatPosition == null) {
|
||||
this.chatPosition = ChatPosition.CHAT;
|
||||
}
|
||||
return this.chatPosition;
|
||||
}
|
||||
}
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* 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.packet.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.nms.NMSUtils;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
class WrappedPacketOutCustomPayload extends WrappedPacket implements SendableWrapper {
|
||||
//TODO load the outcustompayload wrapper
|
||||
|
||||
private static Class<?> packetClass;
|
||||
private static Constructor<?> constructor;
|
||||
private static Constructor<?> packetDataSerializerConstructor;
|
||||
private static Constructor<?> minecraftKeyConstructor;
|
||||
private static Class<?> byteBufClass;
|
||||
private static Class<?> unpooledClass;
|
||||
private static Class<?> packetDataSerializerClass;
|
||||
private static Class<?> minecraftKeyClass;
|
||||
|
||||
private static byte constructorMode = 1;
|
||||
|
||||
public static void load() {
|
||||
packetClass = PacketTypeClasses.Server.CUSTOM_PAYLOAD;
|
||||
packetDataSerializerClass = NMSUtils.getNMSClassWithoutException("PacketDataSerializer");
|
||||
minecraftKeyClass = NMSUtils.getNMSClassWithoutException("MinecraftKey");
|
||||
|
||||
try {
|
||||
unpooledClass = NMSUtils.getNettyClass("buffer.Unpooled");
|
||||
byteBufClass = NMSUtils.getNettyClass("buffer.ByteBuf");
|
||||
} catch (ClassNotFoundException e) {
|
||||
|
||||
}
|
||||
try {
|
||||
packetDataSerializerConstructor = packetDataSerializerClass.getConstructor(NMSUtils.getNettyClass("ByteBuf"));
|
||||
} catch (NullPointerException e) {
|
||||
//Nothing
|
||||
} catch (NoSuchMethodException | ClassNotFoundException e) {
|
||||
//also nothing
|
||||
}
|
||||
|
||||
try {
|
||||
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 {
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
|
||||
}
|
||||
*/
|
||||
public String getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object asNMSPacket() {
|
||||
Object byteBufObject = null;
|
||||
try {
|
||||
byteBufObject = Reflection.getMethod(unpooledClass, "copiedBuffer", 0).invoke(null, data);
|
||||
} catch (InvocationTargetException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
+475
@@ -0,0 +1,475 @@
|
||||
/*
|
||||
* 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.packet.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.entity.Entity;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class WrappedPacketOutEntity extends WrappedPacket {
|
||||
private static Class<?> packetClass;
|
||||
//Byte = 1.7.10->1.8.8, Int = 1.9->1.15.x, Short = 1.16.x
|
||||
private static byte mode = 0; //byte = 0, int = 1, short = 2
|
||||
private static double dXYZDivisor = 0.0;
|
||||
private Entity entity;
|
||||
private int entityID;
|
||||
private double deltaX, deltaY, deltaZ;
|
||||
private byte yaw, pitch;
|
||||
private boolean onGround;
|
||||
|
||||
public WrappedPacketOutEntity(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
packetClass = PacketTypeClasses.Server.ENTITY;
|
||||
|
||||
Field dxField = Reflection.getField(packetClass, 1);
|
||||
assert dxField != null;
|
||||
if (dxField.equals(Reflection.getField(packetClass, byte.class, 0))) {
|
||||
mode = 0;
|
||||
} 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
this.entityID = readInt(0);
|
||||
this.onGround = readBoolean(0);
|
||||
int dX = 1, dY = 1, dZ = 1;
|
||||
switch (mode) {
|
||||
case 0:
|
||||
dX = readByte(0);
|
||||
dY = readByte(1);
|
||||
dZ = readByte(2);
|
||||
this.yaw = readByte(3);
|
||||
this.pitch = readByte(4);
|
||||
break;
|
||||
case 1:
|
||||
dX = readInt(1);
|
||||
dY = readInt(2);
|
||||
dZ = readInt(3);
|
||||
this.yaw = readByte(0);
|
||||
this.pitch = readByte(1);
|
||||
break;
|
||||
case 2:
|
||||
dX = readShort(0);
|
||||
dY = readShort(1);
|
||||
dZ = readShort(2);
|
||||
this.yaw = readByte(0);
|
||||
this.pitch = readByte(1);
|
||||
break;
|
||||
}
|
||||
this.deltaX = dX / dXYZDivisor;
|
||||
this.deltaY = dY / dXYZDivisor;
|
||||
this.deltaZ = dZ / dXYZDivisor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the pitch.
|
||||
*
|
||||
* @return Get Byte Pitch
|
||||
*/
|
||||
public byte getPitch() {
|
||||
return pitch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Yaw.
|
||||
*
|
||||
* @return Get Byte Yaw
|
||||
*/
|
||||
public byte getYaw() {
|
||||
return yaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Delta X
|
||||
*
|
||||
* @return Delta X
|
||||
*/
|
||||
public double getDeltaX() {
|
||||
return deltaX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Delta Y
|
||||
*
|
||||
* @return Delta Y
|
||||
*/
|
||||
public double getDeltaY() {
|
||||
return deltaY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Delta Z
|
||||
*
|
||||
* @return Delta Z
|
||||
*/
|
||||
public double getDeltaZ() {
|
||||
return deltaZ;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(this.entityID);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
return entityID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the entity on the ground?
|
||||
*
|
||||
* @return On Ground
|
||||
*/
|
||||
public boolean isOnGround() {
|
||||
return onGround;
|
||||
}
|
||||
|
||||
public static class WrappedPacketOutRelEntityMove extends WrappedPacket {
|
||||
private int entityID;
|
||||
private Entity entity;
|
||||
private double deltaX, deltaY, deltaZ;
|
||||
private boolean onGround;
|
||||
|
||||
public WrappedPacketOutRelEntityMove(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
int dX = 1, dY = 1, dZ = 1;
|
||||
switch (mode) {
|
||||
case 0:
|
||||
dX = readByte(0);
|
||||
dY = readByte(1);
|
||||
dZ = readByte(2);
|
||||
break;
|
||||
case 1:
|
||||
dX = readInt(1);
|
||||
dY = readInt(2);
|
||||
dZ = readInt(3);
|
||||
break;
|
||||
case 2:
|
||||
dX = readShort(0);
|
||||
dY = readShort(1);
|
||||
dZ = readShort(2);
|
||||
break;
|
||||
}
|
||||
deltaX = dX / dXYZDivisor;
|
||||
deltaY = dY / dXYZDivisor;
|
||||
deltaZ = dZ / dXYZDivisor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Delta X
|
||||
*
|
||||
* @return Delta X
|
||||
*/
|
||||
public double getDeltaX() {
|
||||
return deltaX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Delta Y
|
||||
*
|
||||
* @return Delta Y
|
||||
*/
|
||||
public double getDeltaY() {
|
||||
return deltaY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Delta Z
|
||||
*
|
||||
* @return Delta Z
|
||||
*/
|
||||
public double getDeltaZ() {
|
||||
return deltaZ;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(this.entityID);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
return entityID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the entity on the ground?
|
||||
*
|
||||
* @return On Ground
|
||||
*/
|
||||
public boolean isOnGround() {
|
||||
return onGround;
|
||||
}
|
||||
}
|
||||
|
||||
public static class WrappedPacketOutRelEntityMoveLook extends WrappedPacket {
|
||||
private int entityID;
|
||||
private Entity entity;
|
||||
private double deltaX, deltaY, deltaZ;
|
||||
private byte yaw, pitch;
|
||||
private boolean onGround;
|
||||
|
||||
public WrappedPacketOutRelEntityMoveLook(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
entityID = readInt(0);
|
||||
onGround = readBoolean(0);
|
||||
int dX = 1, dY = 1, dZ = 1;
|
||||
switch (mode) {
|
||||
case 0:
|
||||
dX = readByte(0);
|
||||
dY = readByte(1);
|
||||
dZ = readByte(2);
|
||||
yaw = readByte(3);
|
||||
pitch = readByte(4);
|
||||
break;
|
||||
case 1:
|
||||
dX = readInt(1);
|
||||
dY = readInt(2);
|
||||
dZ = readInt(3);
|
||||
yaw = readByte(0);
|
||||
pitch = readByte(1);
|
||||
break;
|
||||
case 2:
|
||||
dX = readShort(0);
|
||||
dY = readShort(1);
|
||||
dZ = readShort(2);
|
||||
yaw = readByte(0);
|
||||
pitch = readByte(1);
|
||||
break;
|
||||
}
|
||||
deltaX = dX / dXYZDivisor;
|
||||
deltaY = dY / dXYZDivisor;
|
||||
deltaZ = dZ / dXYZDivisor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the pitch.
|
||||
*
|
||||
* @return Get Byte Pitch
|
||||
*/
|
||||
public byte getPitch() {
|
||||
return pitch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Yaw.
|
||||
*
|
||||
* @return Get Byte Yaw
|
||||
*/
|
||||
public byte getYaw() {
|
||||
return yaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Delta X
|
||||
*
|
||||
* @return Delta X
|
||||
*/
|
||||
public double getDeltaX() {
|
||||
return deltaX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Delta Y
|
||||
*
|
||||
* @return Delta Y
|
||||
*/
|
||||
public double getDeltaY() {
|
||||
return deltaY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Delta Z
|
||||
*
|
||||
* @return Delta Z
|
||||
*/
|
||||
public double getDeltaZ() {
|
||||
return deltaZ;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(this.entityID);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
return entityID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the entity on the ground?
|
||||
*
|
||||
* @return On Ground
|
||||
*/
|
||||
public boolean isOnGround() {
|
||||
return onGround;
|
||||
}
|
||||
}
|
||||
|
||||
public static class WrappedPacketOutRelEntityLook extends WrappedPacket {
|
||||
private int entityID;
|
||||
private Entity entity;
|
||||
private byte yaw, pitch;
|
||||
private boolean onGround;
|
||||
|
||||
public WrappedPacketOutRelEntityLook(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
entityID = readInt(0);
|
||||
onGround = readBoolean(0);
|
||||
switch (mode) {
|
||||
case 0:
|
||||
yaw = readByte(3);
|
||||
pitch = readByte(4);
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
yaw = readByte(0);
|
||||
pitch = readByte(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the pitch.
|
||||
*
|
||||
* @return Get Byte Pitch
|
||||
*/
|
||||
public byte getPitch() {
|
||||
return pitch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Yaw.
|
||||
*
|
||||
* @return Get Byte Yaw
|
||||
*/
|
||||
public byte getYaw() {
|
||||
return yaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the entity on the ground?
|
||||
*
|
||||
* @return On Ground
|
||||
*/
|
||||
public boolean isOnGround() {
|
||||
return onGround;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(this.entityID);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
return entityID;
|
||||
}
|
||||
}
|
||||
}
|
||||
+112
-82
@@ -1,137 +1,167 @@
|
||||
/*
|
||||
* 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.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.packetwrappers.Sendable;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
import io.github.retrooper.packetevents.packet.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.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public final class WrappedPacketOutEntityVelocity extends WrappedPacket implements Sendable {
|
||||
public final class WrappedPacketOutEntityVelocity extends WrappedPacket implements SendableWrapper {
|
||||
private static Constructor<?> velocityConstructor, vec3dConstructor;
|
||||
private static Class<?> velocityClass, vec3dClass;
|
||||
private static final Field[] fields = new Field[4];
|
||||
|
||||
/**
|
||||
* Velocity Constructor parameter types:
|
||||
* 1.7.10->1.13.2 use int, double, double, double style,
|
||||
* 1.14+ use int, Vec3D style
|
||||
*/
|
||||
static {
|
||||
try {
|
||||
|
||||
velocityClass = NMSUtils.getNMSClass("PacketPlayOutEntityVelocity");
|
||||
if (version.isHigherThan(ServerVersion.v_1_13_2)) {
|
||||
vec3dClass = NMSUtils.getNMSClass("Vec3D");
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
if (version.isHigherThan(ServerVersion.v_1_13_2)) {
|
||||
velocityConstructor = velocityClass.getConstructor(int.class, vec3dClass);
|
||||
//vec3d constructor
|
||||
vec3dConstructor = vec3dClass.getConstructor(double.class, double.class, double.class);
|
||||
} else {
|
||||
velocityConstructor = velocityClass.getConstructor(int.class, double.class, double.class, double.class);
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
//entity id
|
||||
fields[0] = velocityClass.getDeclaredField("a");
|
||||
//x
|
||||
fields[1] = velocityClass.getDeclaredField("b");
|
||||
//y
|
||||
fields[2] = velocityClass.getDeclaredField("c");
|
||||
//z
|
||||
fields[3] = velocityClass.getDeclaredField("d");
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
for (final Field f : fields) {
|
||||
f.setAccessible(true);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private Entity entity;
|
||||
private int entityId;
|
||||
private static boolean isVec3dPresent;
|
||||
private int entityID;
|
||||
private double velocityX, velocityY, velocityZ;
|
||||
|
||||
private Entity entity;
|
||||
public WrappedPacketOutEntityVelocity(final Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public WrappedPacketOutEntityVelocity(final Entity entity, final double velocityX, final double velocityY, final double velocityZ) {
|
||||
super(null);
|
||||
this.entityId = entity.getEntityId();
|
||||
this.entityID = entity.getEntityId();
|
||||
this.entity = entity;
|
||||
this.velocityX = velocityX;
|
||||
this.velocityY = velocityY;
|
||||
this.velocityZ = velocityZ;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
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() {
|
||||
velocityClass = PacketTypeClasses.Server.ENTITY_VELOCITY;
|
||||
if (version.isHigherThan(ServerVersion.v_1_13_2)) {
|
||||
try {
|
||||
vec3dClass = NMSUtils.getNMSClass("Vec3D");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
int i = 0;
|
||||
final int entityId = fields[0].getInt(packet);
|
||||
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();
|
||||
}
|
||||
|
||||
final int x = fields[1].getInt(packet);
|
||||
final int y = fields[2].getInt(packet);
|
||||
final int z = fields[3].getInt(packet);
|
||||
|
||||
this.entityId = entityId;
|
||||
this.entity = NMSUtils.getEntityById(this.entityId);
|
||||
|
||||
this.velocityX = x / 8000.0D;
|
||||
this.velocityY = y / 8000.0D;
|
||||
this.velocityZ = z / 8000.0D;
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public int getEntityId() {
|
||||
return entityId;
|
||||
@Override
|
||||
protected void setup() {
|
||||
//ENTITY ID
|
||||
this.entityID = readInt(0);
|
||||
|
||||
int x = readInt(1);
|
||||
int y = readInt(2);
|
||||
int z = readInt(3);
|
||||
|
||||
//VELOCITY XYZ
|
||||
this.velocityX = x / 8000.0D;
|
||||
this.velocityY = y / 8000.0D;
|
||||
this.velocityZ = z / 8000.0D;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup the associated entity by the ID that was sent in the packet.
|
||||
* @return Entity
|
||||
*/
|
||||
public Entity getEntity() {
|
||||
return entity;
|
||||
if(entity != null) {
|
||||
return entity;
|
||||
}
|
||||
return entity = NMSUtils.getEntityById(this.entityID);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
return entityID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Velocity X
|
||||
* @return Get Velocity X
|
||||
*/
|
||||
public double getVelocityX() {
|
||||
return velocityX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Velocity Y
|
||||
* @return Get Velocity Y
|
||||
*/
|
||||
public double getVelocityY() {
|
||||
return velocityY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Velocity Z
|
||||
* @return Get Velocity Z
|
||||
*/
|
||||
public double getVelocityZ() {
|
||||
return velocityZ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object asNMSPacket() {
|
||||
if (version.isLowerThan(ServerVersion.v_1_14)) {
|
||||
if (!isVec3dPresent) {
|
||||
try {
|
||||
return velocityConstructor.newInstance(entityId, velocityX, velocityY, velocityZ);
|
||||
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));
|
||||
return velocityConstructor.newInstance(entityID, vec3dConstructor.newInstance(velocityX, velocityY, velocityZ));
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* 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.packet.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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public WrappedPacketOutGameStateChange(int reason, double value) {
|
||||
this.reason = reason;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public WrappedPacketOutGameStateChange(int reason, float value){
|
||||
this(reason, (double)value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
if (reasonIntMode) {
|
||||
reason = readInt(0);
|
||||
} else {
|
||||
//this packet is obfuscated quite strongly(1.16), so we must do this
|
||||
Object reasonObject = readObject(12, reasonClassType);
|
||||
try {
|
||||
reason = Reflection.getField(reasonClassType, int.class, 0).getInt(reasonObject);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (valueFloatMode) {
|
||||
value = readFloat(0);
|
||||
} else {
|
||||
value = readDouble(0);
|
||||
}
|
||||
}
|
||||
|
||||
public int getReason() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
public double getValue() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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.packet.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 Class<?> packetClass;
|
||||
private static Constructor<?> keepAliveConstructor;
|
||||
private static boolean integerMode;
|
||||
private long id;
|
||||
|
||||
public WrappedPacketOutKeepAlive(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public WrappedPacketOutKeepAlive(long id) {
|
||||
super();
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
if(integerMode) {
|
||||
this.id = readInt(0);
|
||||
}
|
||||
else {
|
||||
this.id = readLong(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Keep Alive ID.
|
||||
*
|
||||
* 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() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object asNMSPacket() {
|
||||
if (integerMode) {
|
||||
try {
|
||||
return keepAliveConstructor.newInstance((int) id);
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
return keepAliveConstructor.newInstance(id);
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+48
-22
@@ -1,22 +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.packetwrappers.out.kickdisconnect;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.Sendable;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.packet.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.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
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 Sendable {
|
||||
private static final Reflection.FieldAccessor<?> iChatBaseComponentAccessor;
|
||||
public final class WrappedPacketOutKickDisconnect extends WrappedPacket implements SendableWrapper {
|
||||
private static Class<?> packetClass, iChatBaseComponentClass;
|
||||
private static Constructor<?> kickDisconnectConstructor;
|
||||
private String kickMessage;
|
||||
|
||||
static {
|
||||
public WrappedPacketOutKickDisconnect(final Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public WrappedPacketOutKickDisconnect(final String kickMessage) {
|
||||
super();
|
||||
this.kickMessage = kickMessage;
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
packetClass = PacketTypeClasses.Server.KICK_DISCONNECT;
|
||||
try {
|
||||
packetClass = NMSUtils.getNMSClass("PacketPlayOutKickDisconnect");
|
||||
iChatBaseComponentClass = NMSUtils.getNMSClass("IChatBaseComponent");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
@@ -27,25 +60,18 @@ public final class WrappedPacketOutKickDisconnect extends WrappedPacket implemen
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
iChatBaseComponentAccessor = Reflection.getField(packetClass, iChatBaseComponentClass, 0);
|
||||
}
|
||||
|
||||
private String kickMessage;
|
||||
|
||||
public WrappedPacketOutKickDisconnect(final Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public WrappedPacketOutKickDisconnect(final String kickMessage) {
|
||||
super(null);
|
||||
this.kickMessage = kickMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
this.kickMessage = WrappedPacketOutChat.toStringFromIChatBaseComponent(iChatBaseComponentAccessor.get(packet));
|
||||
Object ichatbaseComponentoObject = readObject(0, iChatBaseComponentClass);
|
||||
this.kickMessage = WrappedPacketOutChat.toStringFromIChatBaseComponent(ichatbaseComponentoObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the kick message.
|
||||
* @return Get Kick Message
|
||||
*/
|
||||
public String getKickMessage() {
|
||||
return kickMessage;
|
||||
}
|
||||
@@ -53,7 +79,7 @@ public final class WrappedPacketOutKickDisconnect extends WrappedPacket implemen
|
||||
@Override
|
||||
public Object asNMSPacket() {
|
||||
try {
|
||||
return kickDisconnectConstructor.newInstance(WrappedPacketOutChat.toIChatBaseComponent("{\"text\": \"" + kickMessage + "\"}"));
|
||||
return kickDisconnectConstructor.newInstance(WrappedPacketOutChat.toIChatBaseComponent(WrappedPacketOutChat.fromStringToJSON(kickMessage)));
|
||||
} catch (InstantiationException | InvocationTargetException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
+96
@@ -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.packetwrappers.out.position;
|
||||
|
||||
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
|
||||
public final class WrappedPacketOutPosition extends WrappedPacket {
|
||||
private static Class<?> packetClass;
|
||||
private double x;
|
||||
private double y;
|
||||
private double z;
|
||||
private float yaw;
|
||||
private float pitch;
|
||||
|
||||
public WrappedPacketOutPosition(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
packetClass = PacketTypeClasses.Server.POSITION;
|
||||
}
|
||||
|
||||
@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() {
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Y position.
|
||||
* @return Get Y Position
|
||||
*/
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Z position.
|
||||
* @return Get Z Position
|
||||
*/
|
||||
public double getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Yaw.
|
||||
* @return Get Yaw
|
||||
*/
|
||||
public float getYaw() {
|
||||
return yaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Pitch,
|
||||
* @return Get Pitch
|
||||
*/
|
||||
public float getPitch() {
|
||||
return pitch;
|
||||
}
|
||||
}
|
||||
+60
-37
@@ -1,14 +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.packetwrappers.out.transaction;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.Sendable;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
import io.github.retrooper.packetevents.packet.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 Sendable {
|
||||
public class WrappedPacketOutTransaction extends WrappedPacket implements SendableWrapper {
|
||||
private static Class<?> packetClass;
|
||||
private static Constructor<?> packetConstructor;
|
||||
private int windowId;
|
||||
private short actionNumber;
|
||||
private boolean accepted;
|
||||
@@ -17,26 +42,50 @@ public class WrappedPacketOutTransaction extends WrappedPacket implements Sendab
|
||||
}
|
||||
|
||||
public WrappedPacketOutTransaction(final int windowId, final short actionNumber, final boolean accepted) {
|
||||
super(null);
|
||||
super();
|
||||
this.windowId = windowId;
|
||||
this.actionNumber = actionNumber;
|
||||
this.accepted = accepted;
|
||||
}
|
||||
@Override
|
||||
protected void setup() {
|
||||
this.windowId = windowIdAccessor.get(packet);
|
||||
this.actionNumber = actionNumberAccessor.get(packet);
|
||||
this.accepted = acceptedAccessor.get(packet);
|
||||
|
||||
public static void load() {
|
||||
packetClass = PacketTypeClasses.Server.TRANSACTION;
|
||||
|
||||
try {
|
||||
packetConstructor = packetClass.getConstructor(int.class, short.class, boolean.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
this.windowId = readInt(0);
|
||||
this.actionNumber = readShort(0);
|
||||
this.accepted = readBoolean(0);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Window ID.
|
||||
* @return Get Window ID
|
||||
*/
|
||||
public int getWindowId() {
|
||||
return windowId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the action number.
|
||||
* @return Get Action Number
|
||||
*/
|
||||
public short getActionNumber() {
|
||||
return actionNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has the transaction packet been accepted?
|
||||
* @return Is Accepted
|
||||
*/
|
||||
public boolean isAccepted() {
|
||||
return accepted;
|
||||
}
|
||||
@@ -51,30 +100,4 @@ public class WrappedPacketOutTransaction extends WrappedPacket implements Sendab
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Class<?> packetClass;
|
||||
|
||||
private static Constructor<?> packetConstructor;
|
||||
|
||||
private static final Reflection.FieldAccessor<Integer> windowIdAccessor;
|
||||
private static final Reflection.FieldAccessor<Short> actionNumberAccessor;
|
||||
private static final Reflection.FieldAccessor<Boolean> acceptedAccessor;
|
||||
|
||||
static {
|
||||
try {
|
||||
packetClass = NMSUtils.getNMSClass("PacketPlayOutTransaction");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
packetConstructor = packetClass.getConstructor(int.class, short.class, boolean.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
windowIdAccessor = Reflection.getField(packetClass, int.class, 0);
|
||||
actionNumberAccessor = Reflection.getField(packetClass, short.class, 0);
|
||||
acceptedAccessor= Reflection.getField(packetClass, boolean.class, 0);
|
||||
}
|
||||
|
||||
}
|
||||
+69
-41
@@ -1,14 +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.out.updatehealth;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.Sendable;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
import io.github.retrooper.packetevents.packet.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 Sendable {
|
||||
public final class WrappedPacketOutUpdateHealth extends WrappedPacket implements SendableWrapper {
|
||||
private static Class<?> packetClass;
|
||||
private static Constructor<?> packetConstructor;
|
||||
private float health, foodSaturation;
|
||||
private int food;
|
||||
public WrappedPacketOutUpdateHealth(final Object packet) {
|
||||
@@ -17,32 +43,60 @@ public final class WrappedPacketOutUpdateHealth extends WrappedPacket implements
|
||||
|
||||
/**
|
||||
* See https://wiki.vg/Protocol#Update_Health
|
||||
* @param health
|
||||
* @param food
|
||||
* @param foodSaturation
|
||||
*
|
||||
* @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(null);
|
||||
this.health= health;
|
||||
super();
|
||||
this.health = health;
|
||||
this.food = food;
|
||||
this.foodSaturation = foodSaturation;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
this.health = healthAccessor.get(packet);
|
||||
this.foodSaturation = foodSaturationAccessor.get(packet);
|
||||
this.food = foodAccessor.get(packet);
|
||||
public static void load() {
|
||||
packetClass = PacketTypeClasses.Server.UPDATE_HEALTH;
|
||||
|
||||
try {
|
||||
packetConstructor = packetClass.getConstructor(float.class, int.class, float.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
try {
|
||||
this.health = readFloat(0);
|
||||
this.foodSaturation = readFloat(1);
|
||||
this.food = Reflection.getField(packetClass, int.class, 0).getInt(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get health value.
|
||||
* @return Get Health
|
||||
*/
|
||||
public float getHealth() {
|
||||
return health;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get food saturation value.
|
||||
* @return Get Food Saturation
|
||||
*/
|
||||
public float getFoodSaturation() {
|
||||
return foodSaturation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get food value.
|
||||
* @return Get Food
|
||||
*/
|
||||
public int getFood() {
|
||||
return food;
|
||||
}
|
||||
@@ -56,30 +110,4 @@ public final class WrappedPacketOutUpdateHealth extends WrappedPacket implements
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Class<?> packetClass;
|
||||
|
||||
private static Constructor<?> packetConstructor;
|
||||
|
||||
private static final Reflection.FieldAccessor<Float> healthAccessor, foodSaturationAccessor;
|
||||
|
||||
private static final Reflection.FieldAccessor<Integer> foodAccessor;
|
||||
|
||||
static {
|
||||
try {
|
||||
packetClass = NMSUtils.getNMSClass("PacketPlayOutUpdateHealth");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
packetConstructor = packetClass.getConstructor(float.class, int.class, float.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
healthAccessor = Reflection.getField(packetClass, float.class, 0);
|
||||
foodSaturationAccessor = Reflection.getField(packetClass, float.class, 1);
|
||||
foodAccessor = Reflection.getField(packetClass, int.class, 0);
|
||||
}
|
||||
}
|
||||
@@ -1,401 +0,0 @@
|
||||
package io.github.retrooper.packetevents.reflectionutils;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* An utility class that simplifies reflection in Bukkit plugins.
|
||||
*
|
||||
* @author Kristian
|
||||
*/
|
||||
public final class Reflection {
|
||||
// Deduce the net.minecraft.server.v* package
|
||||
private static final String OBC_PREFIX = Bukkit.getServer().getClass().getPackage().getName();
|
||||
private static final String NMS_PREFIX = OBC_PREFIX.replace("org.bukkit.craftbukkit", "net.minecraft.server");
|
||||
private static final String VERSION = OBC_PREFIX.replace("org.bukkit.craftbukkit", "").replace(".", "");
|
||||
// Variable replacement
|
||||
private static final 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>
|
||||
*
|
||||
* @param lookupName - the class name with variables.
|
||||
* @return The class.
|
||||
* @see {@link #getClass()} for more information.
|
||||
*/
|
||||
public static Class<Object> getUntypedClass(String lookupName) {
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
Class<Object> clazz = (Class) getClass(lookupName);
|
||||
return clazz;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a class from its full name.
|
||||
* <p>
|
||||
* Strings enclosed with curly brackets - such as {TEXT} - will be replaced according to the following table:
|
||||
* <p>
|
||||
* <table border="1">
|
||||
* <tr>
|
||||
* <th>Variable</th>
|
||||
* <th>Content</th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{nms}</td>
|
||||
* <td>Actual package name of net.minecraft.server.VERSION</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{obc}</td>
|
||||
* <td>Actual pacakge name of org.bukkit.craftbukkit.VERSION</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{version}</td>
|
||||
* <td>The current Minecraft package VERSION, if any.</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* @param lookupName - the class name with variables.
|
||||
* @return The looked up class.
|
||||
* @throws IllegalArgumentException If a variable or class could not be found.
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* 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.enums.ServerVersion;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class PacketEventsSettings {
|
||||
|
||||
private ServerVersion defaultServerVersion = ServerVersion.v_1_7_10;
|
||||
private String identifier = "";
|
||||
private boolean autoResolveClientProtocolVersion = false;
|
||||
private boolean uninjectAsync = true;
|
||||
private boolean injectAsync = true;
|
||||
private boolean useProtocolLibIfAvailable = true;
|
||||
private boolean checkForUpdates = true;
|
||||
|
||||
/**
|
||||
* If PacketEvents fails to detect your server version, it will use the recommended version
|
||||
*
|
||||
* @return Recommended version
|
||||
*/
|
||||
public ServerVersion getDefaultServerVersion() {
|
||||
return this.defaultServerVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default version
|
||||
*
|
||||
* @param version ServerVersion
|
||||
*/
|
||||
public void setDefaultServerVersion(final ServerVersion version) {
|
||||
this.defaultServerVersion = version;
|
||||
}
|
||||
|
||||
/**
|
||||
* The identifier is a unique string that is used to generate a player's handler name.
|
||||
* Two plugins cannot have the same handler name.
|
||||
* If you manually set the identifier using its setter '#setIdentifier(String)'.
|
||||
* We will use that identifier to generate each player's handler name.
|
||||
* If you do not set the identifier manually, we automatically generate one for you.
|
||||
*
|
||||
* @return stored identifier or new generated identifier
|
||||
*/
|
||||
public String getIdentifier() {
|
||||
if (this.identifier.isEmpty()) {
|
||||
String alphabet = "abcdefghijklmnopqrstuvwxyz";
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Random random = new Random();
|
||||
while (sb.length() < 13) {
|
||||
int index = (int) (random.nextFloat() * alphabet.length());
|
||||
sb.append(alphabet.charAt(index));
|
||||
}
|
||||
|
||||
this.identifier = sb.toString();
|
||||
}
|
||||
return this.identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a unique Identifier (Usually something that represents your plugin, For example: MyPluginPacketHandler)
|
||||
* If another present plugin uses the same Identifier, It will cause incompatibilities.
|
||||
*
|
||||
* @param identifier Unique string
|
||||
* @deprecated This method is deprecated as you no longer need to set an identifier,
|
||||
* a unique identifier is already automatically generated for you.
|
||||
*/
|
||||
public void setIdentifier(final String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public boolean doAutoResolveClientProtocolVersion() {
|
||||
return autoResolveClientProtocolVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* If PacketEvents fails to detect a client's version
|
||||
* (when ViaVersion, ProtocolLib or ProtocolSupport can't be found on the server),
|
||||
* should it assume that the client is using the same version as the server?
|
||||
* Returns ACCESS_FAILURE if this is set to FALSE(default value is false).
|
||||
*
|
||||
* @param autoResolveClientProtocolVersion boolean
|
||||
*/
|
||||
public void setDoAutoResolveClientProtocolVersion(boolean autoResolveClientProtocolVersion) {
|
||||
this.autoResolveClientProtocolVersion = autoResolveClientProtocolVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Would you like PacketEvents to Uninject players Asynchronously?
|
||||
* WARNING! This might make reloading unsupported
|
||||
*
|
||||
* @param uninjectAsync boolean
|
||||
*/
|
||||
public void setUninjectAsync(boolean uninjectAsync) {
|
||||
this.uninjectAsync = uninjectAsync;
|
||||
}
|
||||
|
||||
public boolean isUninjectAsync() {
|
||||
return this.uninjectAsync;
|
||||
}
|
||||
|
||||
public boolean isInjectAsync() {
|
||||
return this.injectAsync;
|
||||
}
|
||||
|
||||
/**
|
||||
* Would you like PacketEvents to Inject players Asynchronously?
|
||||
* WARNING! This might make reloading unsupported
|
||||
*
|
||||
* @param injectAsync boolean
|
||||
*/
|
||||
public void setInjectAsync(boolean injectAsync) {
|
||||
this.injectAsync = injectAsync;
|
||||
}
|
||||
|
||||
public boolean isUseProtocolLibIfAvailable() {
|
||||
return this.useProtocolLibIfAvailable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Would you like PacketEvents to make use of ProtocolLib if it is available?
|
||||
* If yes, enable this, if not disable this.
|
||||
* Having this on can help your plugin have compatibility
|
||||
* with other plugins that might be using ProtocolLib.
|
||||
* Especially if they or you are doing packet cancellations,
|
||||
* PacketEvents passes the event priority to ProtocolLib.
|
||||
*
|
||||
* @param val boolean
|
||||
*/
|
||||
public void setUseProtocolLibIfAvailable(boolean val) {
|
||||
this.useProtocolLibIfAvailable = val;
|
||||
}
|
||||
|
||||
/*public void setShouldCheckForUpdates(boolean val) {
|
||||
this.checkForUpdates = val;
|
||||
}
|
||||
|
||||
public boolean shouldCheckForUpdates() {
|
||||
return checkForUpdates;
|
||||
}*/
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package io.github.retrooper.packetevents.utils;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import protocolsupport.api.ProtocolSupportAPI;
|
||||
|
||||
class ProtocolSupportAPIAccessor {
|
||||
public static int getProtocolVersion(final Player player) {
|
||||
return ProtocolSupportAPI.getProtocolVersion(player).getId();
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package io.github.retrooper.packetevents.utils;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import protocolsupport.api.ProtocolSupportAPI;
|
||||
|
||||
public class ProtocolSupportUtils {
|
||||
public static boolean isProtocolSupportAvailable() {
|
||||
return Bukkit.getPluginManager().getPlugin("ProtocolSupport") != null;
|
||||
}
|
||||
|
||||
public static int getProtocolVersion(final Player player) {
|
||||
return ProtocolSupportAPI.getProtocolVersion(player).getId();
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package io.github.retrooper.packetevents.utils;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class VersionLookupUtils {
|
||||
public static int getProtocolVersion(final Player player) {
|
||||
if (ViaUtils.isViaAPIAvaialable()) {
|
||||
return ViaUtils.getProtocolVersion(player);
|
||||
} else if (ProtocolSupportUtils.isProtocolSupportAvailable()) {
|
||||
return ProtocolSupportUtils.getProtocolVersion(player);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package io.github.retrooper.packetevents.utils;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
class ViaAPIAccessor {
|
||||
public static int getProtocolVersion(final Player player) {
|
||||
return getProtocolVersion(player.getUniqueId());
|
||||
}
|
||||
|
||||
public static int getProtocolVersion(final UUID uuid) {
|
||||
return Via.getAPI().getPlayerVersion(uuid);
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package io.github.retrooper.packetevents.utils;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
|
||||
public class ViaUtils {
|
||||
public static int getProtocolVersion(final Player player) {
|
||||
return ViaAPIAccessor.getProtocolVersion(player);
|
||||
}
|
||||
|
||||
public static boolean isViaAPIAvaialable() {
|
||||
return Bukkit.getPluginManager().getPlugin("ViaVersion") != null;
|
||||
}
|
||||
}
|
||||
+54
-9
@@ -1,9 +1,32 @@
|
||||
package io.github.retrooper.packetevents.utils.nms_entityfinder;
|
||||
/*
|
||||
* 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.PacketEvents;
|
||||
import io.github.retrooper.packetevents.annotations.Nullable;
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
@@ -13,7 +36,7 @@ import java.lang.reflect.Method;
|
||||
|
||||
public final class EntityFinderUtils {
|
||||
@Nullable
|
||||
private static final ServerVersion version = PacketEvents.getServerVersion();
|
||||
public static ServerVersion version;
|
||||
private static Class<?> worldServerClass;
|
||||
private static Class<?> craftWorldClass;
|
||||
private static Class<?> entityClass;
|
||||
@@ -21,7 +44,10 @@ public final class EntityFinderUtils {
|
||||
private static Method craftWorldGetHandle;
|
||||
private static Method getBukkitEntity;
|
||||
|
||||
static {
|
||||
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");
|
||||
@@ -31,7 +57,7 @@ public final class EntityFinderUtils {
|
||||
}
|
||||
|
||||
try {
|
||||
getEntityByIdMethod = worldServerClass.getMethod(getEntityByNameMethodName(), int.class);
|
||||
getEntityByIdMethod = worldServerClass.getMethod(getEntityByIDMethodName(), int.class);
|
||||
craftWorldGetHandle = craftWorldClass.getMethod("getHandle");
|
||||
getBukkitEntity = entityClass.getMethod("getBukkitEntity");
|
||||
} catch (NoSuchMethodException e) {
|
||||
@@ -39,6 +65,11 @@ public final class EntityFinderUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an entity by their ID.
|
||||
* @param id
|
||||
* @return Entity
|
||||
*/
|
||||
public static Entity getEntityById(final int id) {
|
||||
for (final World world : Bukkit.getWorlds()) {
|
||||
final Entity entity = getEntityByIdWithWorld(world, id);
|
||||
@@ -46,14 +77,23 @@ public final class EntityFinderUtils {
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
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;
|
||||
@@ -80,8 +120,13 @@ public final class EntityFinderUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getEntityByNameMethodName() {
|
||||
if (version.isHigherThan(ServerVersion.v_1_7_10) && version.isLowerThan(ServerVersion.v_1_9)) {
|
||||
/**
|
||||
* 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";
|
||||
+85
-58
@@ -1,10 +1,35 @@
|
||||
package io.github.retrooper.packetevents.utils;
|
||||
/*
|
||||
* 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.nms;
|
||||
|
||||
import io.github.retrooper.packetevents.annotations.Nullable;
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.packetwrappers.Sendable;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.nms_entityfinder.EntityFinderUtils;
|
||||
import io.github.retrooper.packetevents.nettyhandler.NettyPacketHandler;
|
||||
import io.github.retrooper.packetevents.packetwrappers.SendableWrapper;
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.entityfinder.EntityFinderUtils;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -13,26 +38,34 @@ import org.bukkit.inventory.ItemStack;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
|
||||
public final class NMSUtils {
|
||||
private static final ServerVersion version = ServerVersion.getVersion();
|
||||
|
||||
|
||||
public static final String nettyPrefix = version.isLowerThan(ServerVersion.v_1_8) ? "net.minecraft.util.io.netty" : "io.netty";
|
||||
public static ServerVersion version;
|
||||
private static final String nmsDir = ServerVersion.getNMSDirectory();
|
||||
private static final String obcDir = ServerVersion.getOBCDirectory();
|
||||
|
||||
public static String nettyPrefix = "io.netty";
|
||||
public static Class<?> minecraftServerClass, craftWorldsClass,
|
||||
packetClass, entityPlayerClass, playerConnectionClass,
|
||||
craftPlayerClass, serverConnectionClass, craftEntityClass,
|
||||
craftItemStack, nmsItemStackClass, networkManagerClass, nettyChannelClass;
|
||||
craftItemStack, nmsItemStackClass, networkManagerClass, nettyChannelClass;
|
||||
private static Method getCraftWorldHandleMethod, getServerConnection, getCraftPlayerHandle, getCraftEntityHandle, sendPacketMethod, asBukkitCopy;
|
||||
private static Field entityPlayerPingField, playerConnectionField;
|
||||
|
||||
private static Method getServerMethod, getCraftWorldHandleMethod, getServerConnection, getCraftPlayerHandle, getCraftEntityHandle, sendPacketMethod, asBukkitCopy;
|
||||
public static final HashMap<UUID, Object> channelCache = new HashMap<UUID, Object>();
|
||||
|
||||
private static Field recentTPSField, entityPlayerPingField, playerConnectionField;
|
||||
public static final Reflection.FieldAccessor<?> networkManagerFieldAccesssor, channelFieldAccessor;
|
||||
|
||||
static {
|
||||
public static void load() {
|
||||
try {
|
||||
Class.forName(nettyPrefix + ".channel.Channel");
|
||||
} catch (ClassNotFoundException e) {
|
||||
nettyPrefix = "net.minecraft.util.io.netty";
|
||||
try {
|
||||
Class.forName(nettyPrefix + ".channel.Channel");
|
||||
} catch (ClassNotFoundException e2) {
|
||||
throw new IllegalStateException("PacketEvents failed to locate Netty's location.");
|
||||
}
|
||||
}
|
||||
try {
|
||||
nettyChannelClass = getNettyClass("channel.Channel");
|
||||
minecraftServerClass = getNMSClass("MinecraftServer");
|
||||
@@ -52,7 +85,6 @@ public final class NMSUtils {
|
||||
|
||||
//METHODS
|
||||
try {
|
||||
getServerMethod = minecraftServerClass.getMethod("getServer");
|
||||
getCraftWorldHandleMethod = craftWorldsClass.getMethod("getHandle");
|
||||
getCraftPlayerHandle = craftPlayerClass.getMethod("getHandle");
|
||||
getCraftEntityHandle = craftEntityClass.getMethod("getHandle");
|
||||
@@ -65,31 +97,35 @@ public final class NMSUtils {
|
||||
|
||||
|
||||
try {
|
||||
recentTPSField = minecraftServerClass.getField("recentTps");
|
||||
entityPlayerPingField = entityPlayerClass.getField("ping");
|
||||
playerConnectionField = entityPlayerClass.getField("playerConnection");
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
networkManagerFieldAccesssor = Reflection.getField(playerConnectionClass, networkManagerClass, 0);
|
||||
channelFieldAccessor = Reflection.getField(networkManagerClass, nettyChannelClass, 0);
|
||||
}
|
||||
|
||||
public static Object getMinecraftServerInstance() throws InvocationTargetException, IllegalAccessException {
|
||||
return getServerMethod.invoke(null);
|
||||
return Reflection.getMethod(minecraftServerClass, "getServer", 0).invoke(null);
|
||||
}
|
||||
|
||||
public static double[] recentTPS() throws IllegalAccessException, InvocationTargetException {
|
||||
final Object minecraftServerObj = getMinecraftServerInstance();
|
||||
double[] recentTPS = (double[]) recentTPSField.get(minecraftServerObj);
|
||||
return recentTPS;
|
||||
return (double[]) Reflection.getField(minecraftServerClass, double[].class, 0).get(minecraftServerObj);
|
||||
}
|
||||
|
||||
public static Class<?> getNMSClass(String name) throws ClassNotFoundException {
|
||||
return Class.forName(nmsDir + "." + name);
|
||||
}
|
||||
|
||||
public static Class<?> getNMSClassWithoutException(String name) {
|
||||
try {
|
||||
return getNMSClass(name);
|
||||
} catch (ClassNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Class<?> getOBCClass(String name) throws ClassNotFoundException {
|
||||
return Class.forName(obcDir + "." + name);
|
||||
}
|
||||
@@ -98,11 +134,13 @@ public final class NMSUtils {
|
||||
return Class.forName(nettyPrefix + "." + name);
|
||||
}
|
||||
|
||||
public static final String getChannelFutureListFieldName() {
|
||||
if (version.isLowerThan(ServerVersion.v_1_8))
|
||||
public static String getChannelFutureListFieldName() {
|
||||
if (version.isLowerThan(ServerVersion.v_1_8)) {
|
||||
return "e";
|
||||
if (version.isLowerThan(ServerVersion.v_1_13))
|
||||
}
|
||||
if (version.isLowerThan(ServerVersion.v_1_13)) {
|
||||
return "g";
|
||||
}
|
||||
return "f";
|
||||
}
|
||||
|
||||
@@ -131,7 +169,6 @@ public final class NMSUtils {
|
||||
}
|
||||
|
||||
public static Object getEntityPlayer(final Player player) {
|
||||
Object entityPlayer = null;
|
||||
try {
|
||||
return getCraftPlayerHandle.invoke(getCraftPlayer(player));
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
@@ -142,7 +179,7 @@ public final class NMSUtils {
|
||||
|
||||
public static Object getPlayerConnection(final Player player) {
|
||||
try {
|
||||
return playerConnectionField.get( getEntityPlayer(player));
|
||||
return playerConnectionField.get(getEntityPlayer(player));
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -150,11 +187,25 @@ public final class NMSUtils {
|
||||
}
|
||||
|
||||
public static Object getNetworkManager(final Player player) {
|
||||
return networkManagerFieldAccesssor.get(getPlayerConnection(player));
|
||||
try {
|
||||
return Reflection.getField(playerConnectionClass, networkManagerClass, 0).get(getPlayerConnection(player));
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Object getChannel(final Player player) {
|
||||
return channelFieldAccessor.get(getNetworkManager(player));
|
||||
UUID uuid = player.getUniqueId();
|
||||
if(!channelCache.containsKey(uuid)) {
|
||||
try {
|
||||
Object channel = Reflection.getField(networkManagerClass, nettyChannelClass, 0).get(getNetworkManager(player));
|
||||
channelCache.put(uuid, channel);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return channelCache.get(uuid);
|
||||
}
|
||||
|
||||
public static int getPlayerPing(final Player player) {
|
||||
@@ -170,41 +221,17 @@ public final class NMSUtils {
|
||||
public static ItemStack toBukkitItemStack(final Object nmsItemstack) {
|
||||
try {
|
||||
return (ItemStack) asBukkitCopy.invoke(null, nmsItemstack);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean is_1_8() {
|
||||
return version.isHigherThan(ServerVersion.v_1_7_10)
|
||||
&& version.isLowerThan(ServerVersion.v_1_9);
|
||||
}
|
||||
|
||||
public static void sendSendableWrapper(final Player player, final Sendable sendable) {
|
||||
sendNMSPacket(player, sendable.asNMSPacket());
|
||||
public static void sendSendableWrapper(final Player player, final SendableWrapper sendableWrapper) {
|
||||
NMSUtils.sendNMSPacket(player, sendableWrapper.asNMSPacket());
|
||||
}
|
||||
|
||||
public static void sendNMSPacket(final Player player, final Object nmsPacket) {
|
||||
Object entityPlayer = getEntityPlayer(player);
|
||||
Object playerConnection = null;
|
||||
try {
|
||||
playerConnection = playerConnectionField.get(entityPlayer);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
sendPacketMethod.invoke(playerConnection, nmsPacket);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String getServerConnectionFieldName() {
|
||||
return "p";
|
||||
NettyPacketHandler.sendPacket(getChannel(player), nmsPacket);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* 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.player;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.enums.ClientVersion;
|
||||
import io.github.retrooper.packetevents.nettyhandler.NettyPacketHandler;
|
||||
import io.github.retrooper.packetevents.packetwrappers.SendableWrapper;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.versionlookup.VersionLookupUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
|
||||
public final class PlayerUtils {
|
||||
|
||||
/**
|
||||
* This map stores each player's client version.
|
||||
*/
|
||||
public final HashMap<UUID, ClientVersion> clientVersionsMap = new HashMap<UUID, ClientVersion>();
|
||||
|
||||
/**
|
||||
* Get the player's ping.
|
||||
* @param player
|
||||
* @return Get Player Ping
|
||||
*/
|
||||
public int getPing(final Player player) {
|
||||
return NMSUtils.getPlayerPing(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the client version by a UUID.
|
||||
* @param uuid
|
||||
* @return Get Client Version
|
||||
*/
|
||||
public ClientVersion getClientVersion(final UUID uuid) {
|
||||
return clientVersionsMap.get(uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the client version by a player object.
|
||||
* @param player
|
||||
* @return Get Client Version
|
||||
*/
|
||||
public ClientVersion getClientVersion(final Player player) {
|
||||
return clientVersionsMap.get(player.getUniqueId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the protocol version.
|
||||
* @param player
|
||||
* @return Get Protocol Version
|
||||
*/
|
||||
public int getProtocolVersion(Player player) {
|
||||
return VersionLookupUtils.getProtocolVersion(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject a player.
|
||||
*
|
||||
* (This also calls the {@link io.github.retrooper.packetevents.event.impl.PlayerInjectEvent})
|
||||
* @param player
|
||||
*/
|
||||
public void injectPlayer(final Player player) {
|
||||
if (PacketEvents.getSettings().isInjectAsync()) {
|
||||
NettyPacketHandler.injectPlayerAsync(player);
|
||||
} else {
|
||||
NettyPacketHandler.injectPlayer(player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use {@link #ejectPlayer(Player)}
|
||||
* @param player
|
||||
*/
|
||||
@Deprecated
|
||||
public void uninjectPlayer(final Player player) {
|
||||
if (PacketEvents.getSettings().isUninjectAsync()) {
|
||||
NettyPacketHandler.ejectPlayerAsync(player);
|
||||
} else {
|
||||
NettyPacketHandler.ejectPlayer(player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Eject a player.
|
||||
* (This also calls the {@link io.github.retrooper.packetevents.event.impl.PlayerUninjectEvent})
|
||||
* @param player
|
||||
*/
|
||||
public void ejectPlayer(final Player player) {
|
||||
if (PacketEvents.getSettings().isUninjectAsync()) {
|
||||
NettyPacketHandler.ejectPlayerAsync(player);
|
||||
} else {
|
||||
NettyPacketHandler.ejectPlayer(player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a {@link SendableWrapper} wrapper to a player.
|
||||
* @param player
|
||||
* @param sendableWrapper
|
||||
*/
|
||||
public void sendPacket(final Player player, final SendableWrapper sendableWrapper) {
|
||||
NMSUtils.sendSendableWrapper(player, sendableWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a raw NMS packet to a player.
|
||||
* @param player
|
||||
* @param nmsPacket
|
||||
*/
|
||||
public void sendNMSPacket(final Player player, Object nmsPacket) {
|
||||
NMSUtils.sendNMSPacket(player, nmsPacket);
|
||||
}
|
||||
}
|
||||
+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.utils.protocollib;
|
||||
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
class ProtocolLibAPIAccessor {
|
||||
public static int getProtocolVersion(final Player player) {
|
||||
return ProtocolLibrary.getProtocolManager().getProtocolVersion(player);
|
||||
}
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* 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.protocollib;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.events.ListenerPriority;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.annotations.PacketHandler;
|
||||
import io.github.retrooper.packetevents.event.priority.PacketEventPriority;
|
||||
import io.github.retrooper.packetevents.event.PacketListener;
|
||||
import io.github.retrooper.packetevents.event.impl.PacketReceiveEvent;
|
||||
import io.github.retrooper.packetevents.event.impl.PacketSendEvent;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
public class ProtocolLibListener {
|
||||
|
||||
public static void registerProtocolLibListener(PacketListener listener, ConcurrentLinkedQueue<Method> methods) {
|
||||
if (ProtocolLibUtils.isAvailable()) {
|
||||
for (Method m : methods) {
|
||||
if (m.getParameterTypes()[0].equals(PacketReceiveEvent.class)) {
|
||||
PacketHandler annotation = m.getAnnotation(PacketHandler.class);
|
||||
ListenerPriority priority;
|
||||
switch (annotation.priority()) {
|
||||
case PacketEventPriority.LOWEST:
|
||||
priority = ListenerPriority.LOWEST;
|
||||
break;
|
||||
case PacketEventPriority.LOW:
|
||||
priority = ListenerPriority.LOW;
|
||||
break;
|
||||
case PacketEventPriority.HIGH:
|
||||
priority = ListenerPriority.HIGH;
|
||||
break;
|
||||
case PacketEventPriority.HIGHEST:
|
||||
priority = ListenerPriority.HIGHEST;
|
||||
break;
|
||||
case PacketEventPriority.MONITOR:
|
||||
priority = ListenerPriority.MONITOR;
|
||||
break;
|
||||
default:
|
||||
priority = ListenerPriority.NORMAL;
|
||||
break;
|
||||
}
|
||||
ProtocolLibrary.getProtocolManager().
|
||||
addPacketListener(new PacketAdapter(PacketEvents.getPlugins().get(0),
|
||||
priority, PacketType.Play.Client.getInstance().values()) {
|
||||
@Override
|
||||
public void onPacketReceiving(PacketEvent event) {
|
||||
event.setReadOnly(false);
|
||||
PacketReceiveEvent receiveEvent = new PacketReceiveEvent(event.getPlayer(), event.getPacket().getHandle());
|
||||
try {
|
||||
m.invoke(listener, receiveEvent);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
event.setCancelled(receiveEvent.isCancelled());
|
||||
}
|
||||
});
|
||||
} else if (m.getParameterTypes()[0].equals(PacketSendEvent.class)) {
|
||||
PacketHandler annotation = m.getAnnotation(PacketHandler.class);
|
||||
ListenerPriority priority;
|
||||
switch (annotation.priority()) {
|
||||
case PacketEventPriority.LOWEST:
|
||||
priority = ListenerPriority.LOWEST;
|
||||
break;
|
||||
case PacketEventPriority.LOW:
|
||||
priority = ListenerPriority.LOW;
|
||||
break;
|
||||
case PacketEventPriority.HIGH:
|
||||
priority = ListenerPriority.HIGH;
|
||||
break;
|
||||
case PacketEventPriority.HIGHEST:
|
||||
priority = ListenerPriority.HIGHEST;
|
||||
break;
|
||||
case PacketEventPriority.MONITOR:
|
||||
priority = ListenerPriority.MONITOR;
|
||||
break;
|
||||
default:
|
||||
priority = ListenerPriority.NORMAL;
|
||||
break;
|
||||
}
|
||||
ProtocolLibrary.getProtocolManager().
|
||||
addPacketListener(new PacketAdapter(PacketEvents.getPlugins().get(0),
|
||||
priority, PacketType.Play.Server.getInstance().values()) {
|
||||
@Override
|
||||
public void onPacketSending(PacketEvent event) {
|
||||
event.setReadOnly(false);
|
||||
PacketSendEvent sendEvent = new PacketSendEvent(event.getPlayer(), event.getPacket().getHandle());
|
||||
try {
|
||||
m.invoke(listener, sendEvent);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
event.setCancelled(sendEvent.isCancelled());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.protocollib;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class ProtocolLibUtils {
|
||||
public static boolean isAvailable() {
|
||||
return Bukkit.getPluginManager().isPluginEnabled("ProtocolLib");
|
||||
}
|
||||
|
||||
public static int getProtocolVersion(final Player player) {
|
||||
return ProtocolLibAPIAccessor.getProtocolVersion(player);
|
||||
}
|
||||
}
|
||||
+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.utils.protocolsupport;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import protocolsupport.api.ProtocolSupportAPI;
|
||||
|
||||
class ProtocolSupportAPIAccessor {
|
||||
public static int getProtocolVersion(final Player player) {
|
||||
return ProtocolSupportAPI.getProtocolVersion(player).getId();
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.protocolsupport;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class ProtocolSupportUtils {
|
||||
public static boolean isAvailable() {
|
||||
return Bukkit.getPluginManager().isPluginEnabled("ProtocolSupport");
|
||||
}
|
||||
|
||||
public static int getProtocolVersion(final Player player) {
|
||||
return ProtocolSupportAPIAccessor.getProtocolVersion(player);
|
||||
}
|
||||
}
|
||||
Loaded 100 of 111 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user