Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
No files matched your search
@@ -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.
|
||||
@@ -2,27 +2,19 @@
|
||||
|
||||
A lightweight spigot packetlistener & packetsender coded by retrooper.
|
||||
|
||||
## Credit
|
||||
|
||||
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)
|
||||
|
||||
[](https://jitci.com/gh/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)
|
||||
@@ -6,41 +6,36 @@
|
||||
|
||||
<groupId>io.github.retrooper</groupId>
|
||||
<artifactId>packetevents</artifactId>
|
||||
<version>1.4</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.5.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>
|
||||
</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>
|
||||
@@ -67,12 +62,6 @@
|
||||
|
||||
|
||||
<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>
|
||||
@@ -81,14 +70,20 @@
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- ProtocolLib API-->
|
||||
<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>
|
||||
<!-- ViaVersion API-->
|
||||
|
||||
<dependency>
|
||||
<groupId>us.myles</groupId>
|
||||
<artifactId>viaversion</artifactId>
|
||||
@@ -96,12 +91,26 @@
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- ProtocolSupport API-->
|
||||
<dependency>
|
||||
<groupId>com.github.ProtocolSupport</groupId>
|
||||
<artifactId>ProtocolSupport</artifactId>
|
||||
<version>4fdd683</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.8.8-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
<version>1.8.8-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -1,14 +1,20 @@
|
||||
package io.github.retrooper.packetevents;
|
||||
|
||||
import io.github.retrooper.packetevents.annotations.PacketHandler;
|
||||
import io.github.retrooper.packetevents.api.PacketEventsAPI;
|
||||
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.BukkitMoveEvent;
|
||||
import io.github.retrooper.packetevents.event.impl.PacketReceiveEvent;
|
||||
import io.github.retrooper.packetevents.event.impl.PlayerInjectEvent;
|
||||
import io.github.retrooper.packetevents.event.impl.ServerTickEvent;
|
||||
import io.github.retrooper.packetevents.packet.PacketType;
|
||||
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.in.settings.WrappedPacketInSettings;
|
||||
import io.github.retrooper.packetevents.settings.PacketEventsSettings;
|
||||
import io.github.retrooper.packetevents.utils.onlineplayers.OnlinePlayerUtilities;
|
||||
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;
|
||||
@@ -16,48 +22,48 @@ import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public final class PacketEvents implements PacketListener, Listener {
|
||||
private static Plugin plugin;
|
||||
private static final PacketEventsAPI packetEventsAPI = new PacketEventsAPI();
|
||||
private static final PacketEvents instance = new PacketEvents();
|
||||
private static boolean hasRegistered;
|
||||
private static int currentTick;
|
||||
private static Plugin plugin;
|
||||
private static boolean hasLoaded;
|
||||
private static boolean hasLoaded, hasStarted;
|
||||
private static final PacketEventsSettings settings = new PacketEventsSettings();
|
||||
|
||||
/**
|
||||
* Call this before start(), this is also very heavy
|
||||
* Call this before start()
|
||||
*/
|
||||
public static void load() {
|
||||
//SERVER VERSION LOADING
|
||||
|
||||
//Server Version reversed values caching
|
||||
ServerVersion.reversedValues = ServerVersion.reverse(ServerVersion.values());
|
||||
|
||||
PacketTypeClasses.Client.load();
|
||||
PacketTypeClasses.Server.load();
|
||||
ClientVersion.prepareLookUp();
|
||||
hasLoaded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the server tick task and registers what is needed to be registered
|
||||
*
|
||||
* @param plugin
|
||||
* Loads PacketEvents if you haven't already, Sets everything up, injects all players
|
||||
*/
|
||||
public static void start(final Plugin plugin) {
|
||||
public static void start(final Plugin pl) {
|
||||
if (!hasLoaded) {
|
||||
load();
|
||||
}
|
||||
if (!hasRegistered) {
|
||||
if (!hasStarted) {
|
||||
plugin = pl;
|
||||
//Register Bukkit and PacketListener
|
||||
getAPI().getEventManager().registerListener(getInstance());
|
||||
getAPI().getEventManager().registerListener(instance);
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(getInstance(), plugin);
|
||||
Bukkit.getPluginManager().registerEvents(instance, plugin);
|
||||
|
||||
//Start the server tick task
|
||||
final Runnable tickRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
getAPI().getEventManager().callEvent(new ServerTickEvent(currentTick++, PacketEvents.getAPI().currentMillis()));
|
||||
}
|
||||
};
|
||||
getAPI().setServerTickTask(Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, tickRunnable, 0L, 1L));
|
||||
hasRegistered = true;
|
||||
PacketEvents.plugin = plugin;
|
||||
for (final Player p : OnlinePlayerUtilities.getOnlinePlayers()) {
|
||||
getAPI().getPlayerUtils().injectPlayer(p);
|
||||
}
|
||||
hasStarted = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,61 +71,58 @@ public final class PacketEvents implements PacketListener, Listener {
|
||||
* Stop all tasks and unregisters all PacketEvents' listeners
|
||||
*/
|
||||
public static void stop() {
|
||||
if (getAPI().getServerTickTask() != null) {
|
||||
getAPI().getServerTickTask().cancel();
|
||||
}
|
||||
getAPI().getEventManager().unregisterAllListeners();
|
||||
if (hasStarted) {
|
||||
for (final Player p : OnlinePlayerUtilities.getOnlinePlayers()) {
|
||||
|
||||
PacketType.Client.packetIds.clear();
|
||||
PacketType.Server.packetIds.clear();
|
||||
getAPI().getPlayerUtils().uninjectPlayerNow(p);
|
||||
}
|
||||
getAPI().getEventManager().unregisterAllListeners();
|
||||
|
||||
PacketType.Client.packetIds.clear();
|
||||
PacketType.Server.packetIds.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean hasLoaded() {
|
||||
return hasLoaded;
|
||||
}
|
||||
|
||||
public static boolean hasStarted() {
|
||||
return hasStarted;
|
||||
}
|
||||
|
||||
public static PacketEventsAPI getAPI() {
|
||||
return packetEventsAPI;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get an instance of the PacketEvents API class
|
||||
*
|
||||
* @return instance
|
||||
*/
|
||||
private static PacketEvents getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static Plugin getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
getAPI().getPlayerUtilities().clientVersionsMap.put(e.getPlayer().getUniqueId(), e.getClientVersion());
|
||||
public static String getHandlerName(final String name) {
|
||||
return "pe-" + getSettings().getIdentifier() + "-" + name;
|
||||
}
|
||||
|
||||
@PacketHandler
|
||||
public void onReceive(final PacketReceiveEvent e) {
|
||||
public static PacketEventsSettings getSettings() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(final PlayerJoinEvent e) {
|
||||
getAPI().getPlayerUtilities().injectPlayer(e.getPlayer());
|
||||
getAPI().getPlayerUtils().injectPlayer(e.getPlayer());
|
||||
getAPI().getPlayerUtils().setClientVersion(e.getPlayer(), ClientVersion.fromProtocolVersion(VersionLookupUtils.getProtocolVersion(e.getPlayer())));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onQuit(final PlayerQuitEvent e) {
|
||||
getAPI().getPlayerUtilities().uninjectPlayer(e.getPlayer());
|
||||
getAPI().getPlayerUtils().clearClientVersion(e.getPlayer());
|
||||
getAPI().getPlayerUtils().uninjectPlayerNow(e.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onMove(final PlayerMoveEvent e) {
|
||||
getAPI().getEventManager().callEvent(new BukkitMoveEvent(e));
|
||||
BukkitMoveEvent moveEvent = new BukkitMoveEvent(e);
|
||||
getAPI().getEventManager().callEvent(moveEvent);
|
||||
e.setCancelled(moveEvent.isCancelled());
|
||||
}
|
||||
}
|
||||
+6
-24
@@ -1,15 +1,14 @@
|
||||
package io.github.retrooper.packetevents;
|
||||
package io.github.retrooper.packetevents.api;
|
||||
|
||||
import io.github.retrooper.packetevents.event.manager.EventManager;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import io.github.retrooper.packetevents.utils.api.PlayerUtils;
|
||||
import io.github.retrooper.packetevents.utils.api.ServerUtils;
|
||||
|
||||
public final class PacketEventsAPI {
|
||||
private final EventManager eventManager = new EventManager();
|
||||
private final PlayerUtils playerUtils = new PlayerUtils();
|
||||
private final ServerUtils serverUtils = new ServerUtils();
|
||||
|
||||
private BukkitTask serverTickTask;
|
||||
|
||||
/**
|
||||
* Not thread safe
|
||||
* Preciser than #currentMillis()
|
||||
@@ -39,7 +38,7 @@ public final class PacketEventsAPI {
|
||||
*
|
||||
* @return Player Utilities
|
||||
*/
|
||||
public PlayerUtils getPlayerUtilities() {
|
||||
public PlayerUtils getPlayerUtils() {
|
||||
return playerUtils;
|
||||
}
|
||||
|
||||
@@ -48,10 +47,11 @@ public final class PacketEventsAPI {
|
||||
*
|
||||
* @return Server Utilities
|
||||
*/
|
||||
public ServerUtils getServerUtilities() {
|
||||
public ServerUtils getServerUtils() {
|
||||
return serverUtils;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the event manager
|
||||
* Used to call events, register and unregister listeners
|
||||
@@ -62,23 +62,5 @@ public final class PacketEventsAPI {
|
||||
return eventManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the server tick task, called **asynchronously** every tick
|
||||
*
|
||||
* @return server tick task
|
||||
*/
|
||||
public BukkitTask getServerTickTask() {
|
||||
return serverTickTask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify the server tick task object
|
||||
*
|
||||
* @param task
|
||||
*/
|
||||
public void setServerTickTask(final BukkitTask task) {
|
||||
this.serverTickTask = task;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,74 +1,75 @@
|
||||
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, v_1_16, v_1_16_1, HIGHER_THAN_V_1_16_1, 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;
|
||||
case 735:
|
||||
return v_1_16;
|
||||
case 736:
|
||||
return v_1_16_1;
|
||||
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_16_1;
|
||||
final ClientVersion lookedUp = VERSION_LOOKUP.get(protocolVersion);
|
||||
if (lookedUp != null) {
|
||||
return lookedUp;
|
||||
}
|
||||
return INVALID;
|
||||
return protocolVersion > 737 ? HIGHER_THAN_V_1_16_2 : INVALID;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,10 +90,10 @@ public enum ClientVersion {
|
||||
* @return
|
||||
*/
|
||||
public boolean isLowerThan(final ClientVersion version) {
|
||||
if (version == this) return false;
|
||||
final int len = 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,27 +1,27 @@
|
||||
package io.github.retrooper.packetevents.enums;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* @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_1,
|
||||
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, v_1_16_1, v_1_16_2,
|
||||
ERROR, EMPTY;
|
||||
|
||||
private static final ServerVersion[] reversedValues;
|
||||
public static ServerVersion[] reversedValues;
|
||||
private static final String nmsVersionSuffix = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
|
||||
private static ServerVersion cachedVersion;
|
||||
|
||||
static {
|
||||
reversedValues = reverse(values());
|
||||
}
|
||||
|
||||
private static ServerVersion getVers() {
|
||||
for (final ServerVersion val : reversedValues) {
|
||||
String valName = val.name().substring(2).replace("_", ".");
|
||||
if (Bukkit.getBukkitVersion().contains(valName)) {
|
||||
return val;
|
||||
} else if (PacketEvents.getSettings().getDefaultServerVersion() != null) {
|
||||
return PacketEvents.getSettings().getDefaultServerVersion();
|
||||
}
|
||||
}
|
||||
return ERROR;
|
||||
@@ -34,7 +34,8 @@ public enum ServerVersion {
|
||||
return cachedVersion;
|
||||
}
|
||||
|
||||
private static ServerVersion[] reverse(final ServerVersion[] arr) {
|
||||
|
||||
public static ServerVersion[] reverse(final ServerVersion[] arr) {
|
||||
ServerVersion[] array = arr.clone();
|
||||
if (array == null) {
|
||||
return null;
|
||||
@@ -57,7 +58,7 @@ public enum ServerVersion {
|
||||
}
|
||||
|
||||
public static String getNMSDirectory() {
|
||||
return "net.minecraft.server." + nmsVersionSuffix;
|
||||
return "net.minecraft.server." + getNmsSuffix();
|
||||
}
|
||||
|
||||
public static String getOBCDirectory() {
|
||||
@@ -82,10 +83,10 @@ public enum ServerVersion {
|
||||
* @return
|
||||
*/
|
||||
public boolean isLowerThan(final ServerVersion version) {
|
||||
if (version == this) return false;
|
||||
final int len = 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) {
|
||||
@@ -95,4 +96,49 @@ public enum ServerVersion {
|
||||
return false;
|
||||
}
|
||||
|
||||
public int toProtocolVersion() {
|
||||
if (this.equals(ServerVersion.v_1_7_10)) {
|
||||
return 5;
|
||||
}
|
||||
if (this.name().startsWith("v_1_8")) {
|
||||
return 47;
|
||||
}
|
||||
if (this.equals(ServerVersion.v_1_9)) {
|
||||
return 107;
|
||||
}
|
||||
if (this.equals(ServerVersion.v_1_9_4)) {
|
||||
return 110;
|
||||
}
|
||||
if (this.equals(ServerVersion.v_1_10)) {
|
||||
return 210;
|
||||
}
|
||||
if (this.equals(ServerVersion.v_1_11)) {
|
||||
return 315;
|
||||
}
|
||||
if (this.equals(ServerVersion.v_1_12)) {
|
||||
return 335;
|
||||
}
|
||||
if (this.equals(ServerVersion.v_1_13)) {
|
||||
return 393;
|
||||
}
|
||||
if (this.equals(ServerVersion.v_1_13_2)) {
|
||||
return 404;
|
||||
}
|
||||
if (this.equals(ServerVersion.v_1_14)) {
|
||||
return 477;
|
||||
}
|
||||
if (this.equals(ServerVersion.v_1_15)) {
|
||||
return 573;
|
||||
}
|
||||
if (this.equals(ServerVersion.v_1_16)) {
|
||||
return 735;
|
||||
}
|
||||
if(this.equals(ServerVersion.v_1_16_1)) {
|
||||
return 736;
|
||||
}
|
||||
if(this.equals(ServerVersion.v_1_16_2)) {
|
||||
return 737;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package io.github.retrooper.packetevents.enums.minecraft;
|
||||
|
||||
public enum Gamemode {
|
||||
NOT_SET(-1, ""),
|
||||
SURVIVAL(0, "survival"),
|
||||
CREATIVE(1, "creative"),
|
||||
ADVENTURE(2, "adventure"),
|
||||
SPECTATOR(3, "spectator");
|
||||
|
||||
int f;
|
||||
String g;
|
||||
|
||||
Gamemode(int var3, String var4) {
|
||||
this.f = var3;
|
||||
this.g = var4;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return this.f;
|
||||
}
|
||||
|
||||
public String b() {
|
||||
return this.g;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package io.github.retrooper.packetevents.enums.minecraft;
|
||||
|
||||
public enum PlayerInfoAction {
|
||||
ADD_PLAYER, UPDATE_GAME_MODE, UPDATE_LATENCY, UPDATE_DISPLAY_NAME, REMOVE_PLAYER;
|
||||
|
||||
PlayerInfoAction() {
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,11 @@
|
||||
package io.github.retrooper.packetevents.event;
|
||||
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
|
||||
public class PacketEvent {
|
||||
protected static ServerVersion version = PacketEvents.getAPI().getServerUtilities().getServerVersion();
|
||||
private long timestamp = PacketEvents.getAPI().currentMillis();
|
||||
protected static ServerVersion version = ServerVersion.getVersion();
|
||||
private long timestamp = System.currentTimeMillis();
|
||||
|
||||
/**
|
||||
* Timestamp of the packet
|
||||
|
||||
@@ -8,6 +8,7 @@ import org.bukkit.event.player.PlayerMoveEvent;
|
||||
public final class BukkitMoveEvent extends PacketEvent {
|
||||
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 +33,16 @@ public final class BukkitMoveEvent extends PacketEvent {
|
||||
public Location getTo() {
|
||||
return to;
|
||||
}
|
||||
|
||||
public void setCancelled(final boolean val) {
|
||||
this.cancelled = val;
|
||||
}
|
||||
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
setCancelled(true);
|
||||
}
|
||||
}
|
||||
@@ -6,13 +6,11 @@ import org.bukkit.entity.Player;
|
||||
|
||||
public final class PacketReceiveEvent extends PacketEvent {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -27,11 +25,9 @@ public final class PacketReceiveEvent extends PacketEvent {
|
||||
|
||||
/**
|
||||
* Get the packet's name (NMS packet class simple name)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getPacketName() {
|
||||
return this.name;
|
||||
return this.packet.getClass().getSimpleName();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,8 +53,8 @@ public final class PacketReceiveEvent extends PacketEvent {
|
||||
*
|
||||
* @return packet id
|
||||
*/
|
||||
public int getPacketId() {
|
||||
Integer id = PacketType.Client.packetIds.get(getNMSPacketClass());
|
||||
public byte getPacketId() {
|
||||
Byte id = PacketType.Client.packetIds.get(getNMSPacketClass());
|
||||
if (id == null) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -7,13 +7,11 @@ import org.bukkit.entity.Player;
|
||||
|
||||
public final class PacketSendEvent extends PacketEvent {
|
||||
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;
|
||||
}
|
||||
@@ -23,8 +21,11 @@ public final class PacketSendEvent extends PacketEvent {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the packet's name (NMS packet class simple name)
|
||||
*/
|
||||
public String getPacketName() {
|
||||
return this.name;
|
||||
return this.packet.getClass().getSimpleName();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -32,8 +33,8 @@ public final class PacketSendEvent extends PacketEvent {
|
||||
*
|
||||
* @return packet id
|
||||
*/
|
||||
public int getPacketId() {
|
||||
Integer id =
|
||||
public byte getPacketId() {
|
||||
Byte id =
|
||||
PacketType.Server.packetIds.get(getNMSPacketClass());
|
||||
if (id == null) {
|
||||
return -1;
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
package io.github.retrooper.packetevents.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.enums.ClientVersion;
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import io.github.retrooper.packetevents.utils.api.VersionLookupUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public final class PlayerInjectEvent extends PacketEvent {
|
||||
private final Player player;
|
||||
private final ClientVersion clientVersion;
|
||||
private boolean cancelled;
|
||||
|
||||
public PlayerInjectEvent(final Player player) {
|
||||
this.player = player;
|
||||
this.clientVersion = ClientVersion.fromProtocolVersion(VersionLookupUtils.getProtocolVersion(player));
|
||||
}
|
||||
|
||||
public boolean isCancelled() {
|
||||
@@ -27,10 +23,6 @@ public final class PlayerInjectEvent extends PacketEvent {
|
||||
setCancelled(true);
|
||||
}
|
||||
|
||||
public ClientVersion getClientVersion() {
|
||||
return clientVersion;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
@@ -6,9 +6,11 @@ import org.bukkit.entity.Player;
|
||||
public final class PlayerUninjectEvent extends PacketEvent {
|
||||
private final Player player;
|
||||
private boolean cancelled;
|
||||
private final boolean sync;
|
||||
|
||||
public PlayerUninjectEvent(final Player player) {
|
||||
public PlayerUninjectEvent(final Player player, final boolean sync) {
|
||||
this.player = player;
|
||||
this.sync = sync;
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
@@ -23,6 +25,17 @@ public final class PlayerUninjectEvent extends PacketEvent {
|
||||
this.cancelled = val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the uninjection was called synchronously or asynchronously.
|
||||
* The event is still called synchronously.
|
||||
* By default all uninjections are called aynchronously in this build.
|
||||
*
|
||||
* @return If the uninjection was done async or sync
|
||||
*/
|
||||
public boolean isSync() {
|
||||
return sync;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
@@ -1,29 +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;
|
||||
setTimestamp(timestamp);
|
||||
this.tps = PacketEvents.getAPI().getServerUtilities().getCurrentServerTPS();
|
||||
}
|
||||
|
||||
public ServerTickEvent(final int tick) {
|
||||
this.tick = tick;
|
||||
this.tps = PacketEvents.getAPI().getServerUtilities().getCurrentServerTPS();
|
||||
}
|
||||
|
||||
|
||||
public int getCurrentTick() {
|
||||
return tick;
|
||||
}
|
||||
|
||||
public double getCurrentServerTPS() {
|
||||
return tps;
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,6 @@ public final class EventManager {
|
||||
}
|
||||
|
||||
public void callEvent(final PacketEvent e) {
|
||||
Integer i = 0;
|
||||
for (final PacketListener listener : registeredMethods.keySet()) {
|
||||
//Annotated methods
|
||||
final List<Method> methods = registeredMethods.get(listener);
|
||||
@@ -73,7 +72,7 @@ public final class EventManager {
|
||||
}
|
||||
|
||||
public void registerListeners(final PacketListener... listeners) {
|
||||
for(final PacketListener listener : listeners) {
|
||||
for (final PacketListener listener : listeners) {
|
||||
registerListener(listener);
|
||||
}
|
||||
}
|
||||
@@ -83,7 +82,7 @@ public final class EventManager {
|
||||
}
|
||||
|
||||
public void unregisterListeners(final PacketListener... listeners) {
|
||||
for(final PacketListener listener : listeners) {
|
||||
for (final PacketListener listener : listeners) {
|
||||
unregisterListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
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.packet.PacketType;
|
||||
import io.github.retrooper.packetevents.packetwrappers.in.armanimation.WrappedPacketInArmAnimation;
|
||||
import io.github.retrooper.packetevents.packetwrappers.in.custompayload.WrappedPacketInCustomPayload;
|
||||
import io.github.retrooper.packetevents.packetwrappers.in.helditemslot.WrappedPacketInHeldItemSlot;
|
||||
import io.github.retrooper.packetevents.packetwrappers.in.settings.WrappedPacketInSettings;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import static io.github.retrooper.packetevents.PacketEvents.getAPI;
|
||||
|
||||
public class MainExample extends JavaPlugin {
|
||||
public class MainExample extends JavaPlugin implements PacketListener {
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
@@ -14,8 +20,15 @@ public class MainExample extends JavaPlugin {
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
//Make sure you set a unique identifier, if another present plugin has the same identifier, you could run into issues
|
||||
PacketEvents.getSettings().setIdentifier("official_api");
|
||||
|
||||
PacketEvents.start(this);
|
||||
getAPI().getServerTickTask().cancel();
|
||||
//If packetevents cannot detect your server version, it will use the default you specify version
|
||||
// getAPI().getSettings().setDefaultServerVersion(ServerVersion.v_1_7_10);
|
||||
|
||||
|
||||
PacketEvents.getAPI().getEventManager().registerListeners(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -10,7 +10,6 @@ import org.bukkit.entity.Player;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
public class NettyPacketHandler {
|
||||
public static final String handlerName = "packet_handler";
|
||||
private static boolean v1_7_nettyMode = false;
|
||||
|
||||
static {
|
||||
@@ -34,21 +33,39 @@ public class NettyPacketHandler {
|
||||
}
|
||||
|
||||
public static Future<?> uninjectPlayer(final Player player) {
|
||||
final PlayerUninjectEvent uninjectEvent = new PlayerUninjectEvent(player);
|
||||
PacketEvents.getAPI().getEventManager().callEvent(uninjectEvent);
|
||||
if (!uninjectEvent.isCancelled()) {
|
||||
if (v1_7_nettyMode) {
|
||||
return NettyPacketHandler_7.uninjectPlayer(player);
|
||||
} else {
|
||||
return NettyPacketHandler_8.uninjectPlayer(player);
|
||||
try {
|
||||
final PlayerUninjectEvent uninjectEvent = new PlayerUninjectEvent(player, false);
|
||||
PacketEvents.getAPI().getEventManager().callEvent(uninjectEvent);
|
||||
if (!uninjectEvent.isCancelled()) {
|
||||
if (v1_7_nettyMode) {
|
||||
return NettyPacketHandler_7.uninjectPlayer(player);
|
||||
} else {
|
||||
return NettyPacketHandler_8.uninjectPlayer(player);
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void uninjectPlayerNow(final Player player) {
|
||||
try {
|
||||
final PlayerUninjectEvent uninjectEvent = new PlayerUninjectEvent(player, true);
|
||||
PacketEvents.getAPI().getEventManager().callEvent(uninjectEvent);
|
||||
if (!uninjectEvent.isCancelled()) {
|
||||
if (v1_7_nettyMode) {
|
||||
NettyPacketHandler_7.uninjectPlayerNow(player);
|
||||
} else {
|
||||
NettyPacketHandler_8.uninjectPlayerNow(player);
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
public static Object write(final Player sender, final Object packet) {
|
||||
final String packetName = packet.getClass().getSimpleName();
|
||||
final PacketSendEvent packetSendEvent = new PacketSendEvent(sender, packetName, packet);
|
||||
final PacketSendEvent packetSendEvent = new PacketSendEvent(sender, packet);
|
||||
PacketEvents.getAPI().getEventManager().callEvent(packetSendEvent);
|
||||
if (!packetSendEvent.isCancelled()) {
|
||||
return packet;
|
||||
@@ -57,8 +74,7 @@ public class NettyPacketHandler {
|
||||
}
|
||||
|
||||
public static Object read(final Player receiver, final Object packet) {
|
||||
final String packetName = packet.getClass().getSimpleName();
|
||||
final PacketReceiveEvent packetReceiveEvent = new PacketReceiveEvent(receiver, packetName, packet);
|
||||
final PacketReceiveEvent packetReceiveEvent = new PacketReceiveEvent(receiver, packet);
|
||||
PacketEvents.getAPI().getEventManager().callEvent(packetReceiveEvent);
|
||||
if (!packetReceiveEvent.isCancelled()) {
|
||||
return packet;
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
package io.github.retrooper.packetevents.handler;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
import net.minecraft.util.io.netty.channel.*;
|
||||
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;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
@@ -29,16 +34,18 @@ final class NettyPacketHandler_7 {
|
||||
}
|
||||
};
|
||||
final ChannelPipeline pipeline = ((Channel) NMSUtils.getChannel(player)).pipeline();
|
||||
pipeline.addBefore(NettyPacketHandler.handlerName, player.getName(), channelDuplexHandler);
|
||||
pipeline.addBefore("packet_handler", PacketEvents.getHandlerName(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());
|
||||
}
|
||||
return channel.eventLoop().submit(() -> {
|
||||
channel.pipeline().remove(PacketEvents.getHandlerName(player.getName()));
|
||||
});
|
||||
}
|
||||
|
||||
public static void uninjectPlayerNow(final Player player) {
|
||||
final Channel channel = (Channel) NMSUtils.getChannel(player);
|
||||
channel.pipeline().remove(PacketEvents.getHandlerName(player.getName()));
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,17 @@
|
||||
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 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;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
final class NettyPacketHandler_8 {
|
||||
private static final ServerVersion version = PacketEvents.getAPI().getServerUtilities().getServerVersion();
|
||||
|
||||
public static void injectPlayer(final Player player) {
|
||||
final ChannelDuplexHandler channelDuplexHandler = new ChannelDuplexHandler() {
|
||||
@@ -32,16 +34,18 @@ final class NettyPacketHandler_8 {
|
||||
}
|
||||
};
|
||||
final ChannelPipeline pipeline = ((Channel) NMSUtils.getChannel(player)).pipeline();
|
||||
pipeline.addBefore(NettyPacketHandler.handlerName, player.getName(), channelDuplexHandler);
|
||||
pipeline.addBefore("packet_handler", PacketEvents.getHandlerName(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());
|
||||
}
|
||||
return channel.eventLoop().submit(() -> {
|
||||
channel.pipeline().remove(PacketEvents.getHandlerName(player.getName()));
|
||||
});
|
||||
}
|
||||
|
||||
public static void uninjectPlayerNow(final Player player) {
|
||||
final Channel channel = (Channel) NMSUtils.getChannel(player);
|
||||
channel.pipeline().remove(PacketEvents.getHandlerName(player.getName()));
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ public class PacketType {
|
||||
|
||||
public static class Client {
|
||||
public static class Util {
|
||||
public static boolean isInstanceOfFlying(final int packetId) {
|
||||
public static boolean isInstanceOfFlying(final byte packetId) {
|
||||
return packetId == FLYING
|
||||
|| packetId == POSITION
|
||||
|| packetId == POSITION_LOOK
|
||||
@@ -16,9 +16,9 @@ public class PacketType {
|
||||
}
|
||||
}
|
||||
|
||||
public static final Map<Class<?>, Integer> packetIds = new HashMap<Class<?>, Integer>();
|
||||
public static final Map<Class<?>, Byte> packetIds = new HashMap<Class<?>, Byte>();
|
||||
|
||||
public static final int TELEPORT_ACCEPT = 0,
|
||||
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,
|
||||
@@ -84,8 +84,8 @@ public class PacketType {
|
||||
}
|
||||
|
||||
public static class Server {
|
||||
public static final Map<Class<?>, Integer> packetIds = new HashMap<Class<?>, Integer>();
|
||||
public static int SPAWN_ENTITY = 0, SPAWN_ENTITY_EXPERIENCE_ORB = 1, SPAWN_ENTITY_WEATHER = 2, SPAWN_ENTITY_LIVING = 3,
|
||||
public static final Map<Class<?>, Byte> packetIds = new HashMap<Class<?>, Byte>();
|
||||
public static 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,
|
||||
|
||||
@@ -30,6 +30,7 @@ public class WrappedPacket {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void setup() {
|
||||
|
||||
}
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.armanimation;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
|
||||
//TODO: Test on 1.9, 1.11, 1.13, 1.14
|
||||
public final class WrappedPacketInArmAnimation extends WrappedPacket {
|
||||
private static Class<?> packetClass;
|
||||
|
||||
static {
|
||||
try {
|
||||
packetClass = NMSUtils.getNMSClass("PacketPlayInArmAnimation");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private long timeStamp;
|
||||
|
||||
public WrappedPacketInArmAnimation(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
//Lazy way, do you really need to get the timestamp in the actual class? Edit by Retrooper: Yes lol
|
||||
//TODO: Get EnumHand value sent in 1.9+, however not really necessary
|
||||
timeStamp = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timeStamp;
|
||||
}
|
||||
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.clientcommand;
|
||||
|
||||
import io.github.retrooper.packetevents.annotations.Nullable;
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.enums.minecraft.PlayerAction;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
|
||||
//TODO: Test on 1.9, 1.10, 1.11, 1.13, 1.14
|
||||
public final class WrappedPacketInClientCommand extends WrappedPacket {
|
||||
private static Class<?> packetClass;
|
||||
@Nullable
|
||||
private static Class<?> enumClientCommandClass;
|
||||
|
||||
static {
|
||||
try {
|
||||
packetClass = NMSUtils.getNMSClass("PacketPlayInClientCommand");
|
||||
if(version.isHigherThan(ServerVersion.v_1_7_10)) {
|
||||
enumClientCommandClass = Reflection.getSubClass(packetClass, "EnumClientCommand");
|
||||
}else {
|
||||
enumClientCommandClass = NMSUtils.getNMSClass("EnumClientCommand");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private ClientCommand clientCommand;
|
||||
|
||||
public WrappedPacketInClientCommand(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
try {
|
||||
if(version.isLowerThan(ServerVersion.v_1_8)) {
|
||||
clientCommand = ClientCommand.get(Reflection.getField(enumClientCommandClass, int.class, 1).getInt(packet));
|
||||
} else {
|
||||
final Object enumObj = Reflection.getField(packetClass, enumClientCommandClass, 0).get(packet);
|
||||
this.clientCommand = ClientCommand.valueOf(enumObj.toString());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public ClientCommand getClientCommand() {
|
||||
return clientCommand;
|
||||
}
|
||||
|
||||
public static enum ClientCommand {
|
||||
PERFORM_RESPAWN,
|
||||
REQUEST_STATS,
|
||||
OPEN_INVENTORY_ACHIEVEMENT;
|
||||
|
||||
private ClientCommand() {
|
||||
}
|
||||
|
||||
public static ClientCommand get(final int i) {
|
||||
return values()[i];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.custompayload;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
|
||||
public final class WrappedPacketInCustomPayload extends WrappedPacket {
|
||||
private static Class<?> packetClass, nmsMinecraftKey, nmsPacketDataSerializer;
|
||||
|
||||
static {
|
||||
try {
|
||||
packetClass = NMSUtils.getNMSClass("PacketPlayInCustomPayload");
|
||||
nmsPacketDataSerializer = NMSUtils.getNMSClass("PacketDataSerializer");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try{
|
||||
//Only on 1.13+
|
||||
nmsMinecraftKey = NMSUtils.getNMSClass("MinecraftKey");
|
||||
} catch (Exception e) {
|
||||
//Its okay, this means they are on versions 1.7.10 ~ 1.12.2
|
||||
}
|
||||
}
|
||||
|
||||
private String data;
|
||||
private Object minecraftKey, dataSerializer;
|
||||
|
||||
public WrappedPacketInCustomPayload(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
if(Reflection.getField(packetClass, String.class, 0) == null) {
|
||||
try {
|
||||
this.minecraftKey = Reflection.getField(packetClass, nmsMinecraftKey, 0).get(packet);
|
||||
this.dataSerializer = Reflection.getField(packetClass, nmsPacketDataSerializer, 0).get(packet);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
this.data = (String)Reflection.getField(packetClass, String.class, 0).get(packet);
|
||||
this.dataSerializer = Reflection.getField(packetClass, nmsPacketDataSerializer, 0).get(packet);
|
||||
} catch (Exception e) {
|
||||
//intentionally empty, allegedly 1.7.10 produces a NPE?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public Object getMinecraftKey() {
|
||||
return minecraftKey;
|
||||
}
|
||||
|
||||
public Object getDataSerializer() {
|
||||
return dataSerializer;
|
||||
}
|
||||
}
|
||||
+2
-9
@@ -17,14 +17,7 @@ public final class WrappedPacketInEntityAction extends WrappedPacket {
|
||||
try {
|
||||
entityActionClass = NMSUtils.getNMSClass("PacketPlayInEntityAction");
|
||||
if (version.isHigherThan(ServerVersion.v_1_7_10)) {
|
||||
for (final Class<?> sub : entityActionClass.getDeclaredClasses()) {
|
||||
if (sub.getSimpleName().equals("EnumPlayerAction")) {
|
||||
enumPlayerActionClass = sub;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
enumPlayerActionClass = NMSUtils.getNMSClass("EnumPlayerAction");
|
||||
enumPlayerActionClass = Reflection.getSubClass(entityActionClass, "EnumPlayerAction");
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
@@ -55,7 +48,7 @@ public final class WrappedPacketInEntityAction extends WrappedPacket {
|
||||
|
||||
//1.7.10
|
||||
if (version.isLowerThan(ServerVersion.v_1_8)) {
|
||||
animationIndex = Reflection.getField(entityActionClass, int.class, 1).getInt(packet);
|
||||
animationIndex = Reflection.getField(entityActionClass, int.class, 1).getInt(packet); // TODO: += if packetdataserializer.version < 16
|
||||
} else {
|
||||
final Object enumObj = Reflection.getField(entityActionClass, enumPlayerActionClass, 0).get(packet);
|
||||
final String enumValue = enumObj.toString();
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.helditemslot;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
|
||||
public final class WrappedPacketInHeldItemSlot extends WrappedPacket {
|
||||
private static Class<?> packetClass;
|
||||
|
||||
static {
|
||||
try {
|
||||
packetClass = NMSUtils.getNMSClass("PacketPlayInHeldItemSlot");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private int itemInHandIndex;
|
||||
|
||||
public WrappedPacketInHeldItemSlot(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
try {
|
||||
itemInHandIndex = Reflection.getField(packetClass, int.class, 0).getInt(packet);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public int getItemInHandIndex() {
|
||||
return itemInHandIndex;
|
||||
}
|
||||
|
||||
}
|
||||
+16
-13
@@ -1,16 +1,15 @@
|
||||
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.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
|
||||
public final class WrappedPacketInKeepAlive extends WrappedPacket {
|
||||
private static Class<?> keepAliveClass;
|
||||
private static Class<?> packetClass;
|
||||
|
||||
static {
|
||||
try {
|
||||
keepAliveClass = NMSUtils.getNMSClass("PacketPlayInKeepAlive");
|
||||
packetClass = NMSUtils.getNMSClass("PacketPlayInKeepAlive");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -24,22 +23,26 @@ public final class WrappedPacketInKeepAlive extends WrappedPacket {
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
try {
|
||||
if (version.isHigherThan(ServerVersion.v_1_12)) {
|
||||
this.id = Reflection.getField(keepAliveClass, long.class, 0).getLong(packet);
|
||||
} else {
|
||||
this.id = Reflection.getField(keepAliveClass, int.class, 0).getInt(packet);
|
||||
if (Reflection.getField(packetClass, int.class, 0) == null) {
|
||||
try {
|
||||
this.id = Reflection.getField(packetClass, long.class, 0).getLong(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
this.id = Reflection.getField(packetClass, int.class, 0).getInt(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* Optionally Cast this long to an integer if you are using 1.7.10->1.12.2!
|
||||
* In 1.13.2->1.16.1 a long is sent
|
||||
*
|
||||
* @return
|
||||
* @return response is
|
||||
*/
|
||||
public long getId() {
|
||||
return id;
|
||||
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
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.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class WrappedPacketInSettings extends WrappedPacket {
|
||||
private static Class<?> packetClass;
|
||||
private static Class<?> chatVisibilityEnumClass;
|
||||
static {
|
||||
try {
|
||||
packetClass = NMSUtils.getNMSClass("PacketPlayInSettings");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
chatVisibilityEnumClass = NMSUtils.getNMSClass("EnumChatVisibility");
|
||||
} catch (ClassNotFoundException e) {
|
||||
Class<?> entityHumanClass = NMSUtils.getNMSClassWithoutException("EntityHuman");
|
||||
//They are just on an outdated version
|
||||
chatVisibilityEnumClass = Reflection.getSubClass(entityHumanClass, "EnumChatVisibility");
|
||||
}
|
||||
}
|
||||
|
||||
public enum ChatVisibility {
|
||||
ENABLED, COMMANDS_ONLY, HIDDEN
|
||||
}
|
||||
|
||||
|
||||
public enum DisplayedSkinPart {
|
||||
CAPE, JACKET, LEFT_SLEEVE, RIGHT_SLEEVE, LEFT_PANTS, RIGHT_PANTS, HAT
|
||||
}
|
||||
|
||||
private String locale;
|
||||
private byte viewDistance;
|
||||
private ChatVisibility chatVisibility;
|
||||
private boolean chatColors;
|
||||
private HashMap<DisplayedSkinPart, Boolean> displayedSkinParts;
|
||||
|
||||
public WrappedPacketInSettings(final Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
try {
|
||||
//LOCALE
|
||||
this.locale = Reflection.getField(packetClass, String.class, 0).get(packet).toString();
|
||||
//VIEW DISTANCE
|
||||
this.viewDistance = (byte) Reflection.getField(packetClass, int.class, 0).getInt(packet);
|
||||
|
||||
//CHAT VISIBILITY
|
||||
Object chatVisibilityEnumObject = Reflection.getField(packetClass, chatVisibilityEnumClass, 0).get(packet);
|
||||
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 = Reflection.getField(packetClass, boolean.class, 0).getBoolean(packet);
|
||||
|
||||
//DISPLAYED SKIN PARTS
|
||||
this.displayedSkinParts = new HashMap<DisplayedSkinPart, Boolean>();
|
||||
|
||||
if(version.isLowerThan(ServerVersion.v_1_8)) {
|
||||
//in 1.7.10 only the cape display skin part is sent
|
||||
boolean capeEnabled = Reflection.getField(packetClass, boolean.class, 1).getBoolean(packet);
|
||||
displayedSkinParts.put(DisplayedSkinPart.CAPE, capeEnabled);
|
||||
}
|
||||
else {
|
||||
//in 1.8, all the skin parts are sent
|
||||
int skinPartFlags = Reflection.getField(packetClass, int.class, 1).getInt(packet);
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Class<?> getChatVisibilityEnumClass() {
|
||||
return chatVisibilityEnumClass;
|
||||
}
|
||||
|
||||
public String getLocale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
public byte getViewDistance() {
|
||||
return viewDistance;
|
||||
}
|
||||
|
||||
public ChatVisibility getChatVisibility() {
|
||||
return chatVisibility;
|
||||
}
|
||||
|
||||
public boolean isChatColors() {
|
||||
return chatColors;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@Nullable
|
||||
public HashMap<DisplayedSkinPart, Boolean> getDisplayedSkinPartsMap() {
|
||||
return displayedSkinParts;
|
||||
}
|
||||
|
||||
/**
|
||||
* On 1.7.10, some skin parts will default to 'false' as 1.7.10
|
||||
* only sends the 'cape' skin part.
|
||||
* @param part
|
||||
* @return
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
+6
-6
@@ -10,18 +10,19 @@ public class WrappedPacketOutEntity extends WrappedPacket {
|
||||
private double deltaX, deltaY, deltaZ;
|
||||
private byte yaw, pitch;
|
||||
private boolean onGround;
|
||||
|
||||
public WrappedPacketOutEntity(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup(){
|
||||
protected void setup() {
|
||||
try {
|
||||
this.entityId = Reflection.getField(packetClass, int.class, 0).getInt(packet);
|
||||
this.onGround = Reflection.getField(packetClass, boolean.class, 0).getBoolean(packet);
|
||||
if(version.isLowerThan(ServerVersion.v_1_9)) {
|
||||
byte dX = Reflection.getField(packetClass, byte.class, 0).getByte(packet);
|
||||
byte dY = Reflection.getField(packetClass, byte.class, 1).getByte(packet);
|
||||
if (version.isLowerThan(ServerVersion.v_1_9)) {
|
||||
byte dX = Reflection.getField(packetClass, byte.class, 0).getByte(packet);
|
||||
byte dY = Reflection.getField(packetClass, byte.class, 1).getByte(packet);
|
||||
byte dZ = Reflection.getField(packetClass, byte.class, 2).getByte(packet);
|
||||
|
||||
this.deltaX = dX / 32.0;
|
||||
@@ -30,8 +31,7 @@ public class WrappedPacketOutEntity extends WrappedPacket {
|
||||
|
||||
this.yaw = Reflection.getField(packetClass, byte.class, 3).getByte(packet);
|
||||
this.pitch = Reflection.getField(packetClass, byte.class, 4).getByte(packet);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
short dX = Reflection.getField(packetClass, short.class, 0).getShort(packet);
|
||||
short dY = Reflection.getField(packetClass, short.class, 1).getShort(packet);
|
||||
short dZ = Reflection.getField(packetClass, short.class, 2).getShort(packet);
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.out.keepalive;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutKeepAlive;
|
||||
|
||||
public class WrappedPacketOutKeepAlive extends WrappedPacket {
|
||||
private long id;
|
||||
|
||||
public WrappedPacketOutKeepAlive(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Optionally Cast this long to an integer if you are using 1.7.10->1.12.2!
|
||||
* In 1.13.2->1.16.1 a long is sent
|
||||
*
|
||||
* @return response is
|
||||
*/
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
if (Reflection.getField(packetClass, int.class, 0) == null) {
|
||||
try {
|
||||
this.id = Reflection.getField(packetClass, long.class, 0).getLong(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
this.id = Reflection.getField(packetClass, int.class, 0).getInt(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Class<?> packetClass;
|
||||
|
||||
static {
|
||||
try {
|
||||
packetClass = NMSUtils.getNMSClass("PacketPlayOutKeepAlive");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
PacketPlayOutKeepAlive p;
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.out.playerinfo;
|
||||
|
||||
import io.github.retrooper.packetevents.enums.minecraft.Gamemode;
|
||||
import io.github.retrooper.packetevents.enums.minecraft.PlayerInfoAction;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutPlayerInfo;
|
||||
|
||||
public class WrappedPacketOutPlayerInfo extends WrappedPacket {
|
||||
private PlayerInfoAction action;
|
||||
|
||||
public WrappedPacketOutPlayerInfo(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
PacketPlayOutPlayerInfo.PlayerInfoData dl;
|
||||
}
|
||||
|
||||
private static Class<?> packetClass, enumPlayerInfoActionClass;
|
||||
|
||||
static {
|
||||
try {
|
||||
packetClass = NMSUtils.getNMSClass("PacketPlayOutPlayerInfo");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
enumPlayerInfoActionClass = NMSUtils.getNMSClass("EnumPLayerInfoAction");
|
||||
} catch (ClassNotFoundException e) {
|
||||
enumPlayerInfoActionClass = Reflection.getSubClass(packetClass, "EnumPlayerInfoAction");
|
||||
}
|
||||
}
|
||||
|
||||
public class PlayerDataInfo {
|
||||
public PlayerDataInfo(Object gameProfile, int var, Gamemode gamemode, String s) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -75,17 +75,16 @@ public final class Reflection {
|
||||
public static Field getField(final Class<?> cls, final int index) {
|
||||
final FieldWithIndex fwi = new FieldWithIndex(cls, index);
|
||||
if (!fieldWithIndexHashMap.containsKey(fwi)) {
|
||||
int i = 0;
|
||||
for (final Field f : getFields(cls)) {
|
||||
if (index == i++) {
|
||||
fieldWithIndexHashMap.put(fwi, f);
|
||||
return f;
|
||||
}
|
||||
final Field[] fields = getFields(cls);
|
||||
if (fields.length <= index) {
|
||||
return null;
|
||||
}
|
||||
final Field field = fields[index];
|
||||
fieldWithIndexHashMap.put(fwi, field);
|
||||
return field;
|
||||
} else {
|
||||
return fieldWithIndexHashMap.get(fwi);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//METHODS
|
||||
@@ -187,4 +186,4 @@ public final class Reflection {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
+17
@@ -1,5 +1,7 @@
|
||||
package io.github.retrooper.packetevents.reflectionutils.fielddata;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class FieldWithIndex {
|
||||
private final Class<?> cls;
|
||||
private final int index;
|
||||
@@ -16,4 +18,19 @@ public class FieldWithIndex {
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
FieldWithIndex that = (FieldWithIndex) o;
|
||||
return index == that.index &&
|
||||
Objects.equals(cls, that.cls);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(cls, index);
|
||||
}
|
||||
|
||||
}
|
||||
+17
@@ -1,5 +1,7 @@
|
||||
package io.github.retrooper.packetevents.reflectionutils.fielddata;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class FieldWithName {
|
||||
|
||||
private final Class<?> cls;
|
||||
@@ -17,4 +19,19 @@ public class FieldWithName {
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
FieldWithName that = (FieldWithName) o;
|
||||
return name.equals(that.name) &&
|
||||
Objects.equals(cls, that.cls);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(cls, name);
|
||||
}
|
||||
|
||||
}
|
||||
+18
@@ -1,5 +1,7 @@
|
||||
package io.github.retrooper.packetevents.reflectionutils.fielddata;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class FieldWithTypeAndIndex {
|
||||
private final Class<?> cls, type;
|
||||
private final int index;
|
||||
@@ -21,4 +23,20 @@ public class FieldWithTypeAndIndex {
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
FieldWithTypeAndIndex that = (FieldWithTypeAndIndex) o;
|
||||
return index == that.index &&
|
||||
Objects.equals(cls, that.cls) &&
|
||||
Objects.equals(type, that.type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(cls, type, index);
|
||||
}
|
||||
|
||||
}
|
||||
+18
@@ -1,5 +1,7 @@
|
||||
package io.github.retrooper.packetevents.reflectionutils.methoddata;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class MethodWithIndexAndParams {
|
||||
private final Class<?> cls;
|
||||
private final int index;
|
||||
@@ -22,4 +24,20 @@ public class MethodWithIndexAndParams {
|
||||
public Class<?>[] getParams() {
|
||||
return params;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
MethodWithIndexAndParams that = (MethodWithIndexAndParams) o;
|
||||
return index == that.index &&
|
||||
Objects.equals(cls, that.cls) &&
|
||||
Objects.equals(params, that.params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(cls, params, index);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package io.github.retrooper.packetevents.settings;
|
||||
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
|
||||
public class PacketEventsSettings {
|
||||
private ServerVersion defaultServerVersion;
|
||||
private String identifier = "";
|
||||
private boolean autoResolveClientProtocolVersion;
|
||||
|
||||
/**
|
||||
* If PacketEvents fails to detect your server version, it will use the recommended version
|
||||
*
|
||||
* @return Recommended version
|
||||
*/
|
||||
public ServerVersion getDefaultServerVersion() {
|
||||
return defaultServerVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the recommended version
|
||||
*
|
||||
* @param version
|
||||
*/
|
||||
public void setDefaultServerVersion(final ServerVersion version) {
|
||||
defaultServerVersion = version;
|
||||
}
|
||||
|
||||
public String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a unique Identifier (Usually something that represents your plugin, For example: MyPluginPacketHandler)
|
||||
* If another present plugin uses the same Identifier, It might cause incompatibilities
|
||||
*
|
||||
* @param identifier
|
||||
*/
|
||||
public void setIdentifier(final String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public boolean doAutoResolveClientProtocolVersion() {
|
||||
return autoResolveClientProtocolVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* If PacketEvents fails to detect a client's version
|
||||
* Should it assume that the client is using the same version that the server is?
|
||||
* <p>
|
||||
* Returns ACCESS_FAILURE if false
|
||||
*
|
||||
* @param autoResolveClientProtocolVersion
|
||||
*/
|
||||
public void setDoAutoResolveClientProtocolVersion(boolean autoResolveClientProtocolVersion) {
|
||||
this.autoResolveClientProtocolVersion = autoResolveClientProtocolVersion;
|
||||
}
|
||||
}
|
||||
@@ -15,4 +15,4 @@ public class BlockIteratorUtils {
|
||||
}
|
||||
return block;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,17 +16,23 @@ import java.lang.reflect.Method;
|
||||
|
||||
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 String nettyPrefix;
|
||||
private static final String nmsDir = ServerVersion.getNMSDirectory();
|
||||
private static final String obcDir = ServerVersion.getOBCDirectory();
|
||||
public static Class<?> minecraftServerClass, craftWorldsClass,
|
||||
packetClass, entityPlayerClass, playerConnectionClass,
|
||||
craftPlayerClass, serverConnectionClass, craftEntityClass,
|
||||
craftItemStack, nmsItemStackClass, networkManagerClass, nettyChannelClass;
|
||||
private static Method getServerMethod, getCraftWorldHandleMethod, getServerConnection, getCraftPlayerHandle, getCraftEntityHandle, sendPacketMethod, asBukkitCopy;
|
||||
private static Field recentTPSField, entityPlayerPingField, playerConnectionField;
|
||||
private static Method getCraftWorldHandleMethod, getServerConnection, getCraftPlayerHandle, getCraftEntityHandle, sendPacketMethod, asBukkitCopy;
|
||||
private static Field entityPlayerPingField, playerConnectionField;
|
||||
|
||||
static {
|
||||
try {
|
||||
nettyPrefix = "io.netty";
|
||||
Class.forName("io.netty.channel.Channel");
|
||||
} catch (ClassNotFoundException e) {
|
||||
nettyPrefix = "net.minecraft.util.io.netty";
|
||||
}
|
||||
try {
|
||||
nettyChannelClass = getNettyClass("channel.Channel");
|
||||
minecraftServerClass = getNMSClass("MinecraftServer");
|
||||
@@ -46,7 +52,6 @@ public final class NMSUtils {
|
||||
|
||||
//METHODS
|
||||
try {
|
||||
getServerMethod = minecraftServerClass.getMethod("getServer");
|
||||
getCraftWorldHandleMethod = craftWorldsClass.getMethod("getHandle");
|
||||
getCraftPlayerHandle = craftPlayerClass.getMethod("getHandle");
|
||||
getCraftEntityHandle = craftEntityClass.getMethod("getHandle");
|
||||
@@ -59,7 +64,6 @@ public final class NMSUtils {
|
||||
|
||||
|
||||
try {
|
||||
recentTPSField = minecraftServerClass.getField("recentTps");
|
||||
entityPlayerPingField = entityPlayerClass.getField("ping");
|
||||
playerConnectionField = entityPlayerClass.getField("playerConnection");
|
||||
} catch (NoSuchFieldException e) {
|
||||
@@ -68,13 +72,12 @@ public final class NMSUtils {
|
||||
}
|
||||
|
||||
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 {
|
||||
@@ -98,7 +101,7 @@ public final class NMSUtils {
|
||||
return Class.forName(nettyPrefix + "." + name);
|
||||
}
|
||||
|
||||
public static final String getChannelFutureListFieldName() {
|
||||
public static String getChannelFutureListFieldName() {
|
||||
if (version.isLowerThan(ServerVersion.v_1_8))
|
||||
return "e";
|
||||
if (version.isLowerThan(ServerVersion.v_1_13))
|
||||
@@ -131,7 +134,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) {
|
||||
@@ -180,9 +182,7 @@ 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;
|
||||
|
||||
+24
-6
@@ -1,4 +1,4 @@
|
||||
package io.github.retrooper.packetevents;
|
||||
package io.github.retrooper.packetevents.utils.api;
|
||||
|
||||
import io.github.retrooper.packetevents.enums.ClientVersion;
|
||||
import io.github.retrooper.packetevents.handler.NettyPacketHandler;
|
||||
@@ -9,10 +9,10 @@ import org.bukkit.entity.Player;
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
|
||||
public class PlayerUtils {
|
||||
protected final HashMap<UUID, ClientVersion> clientVersionsMap = new HashMap<UUID, ClientVersion>();
|
||||
public final class PlayerUtils {
|
||||
private final HashMap<UUID, ClientVersion> clientVersionsMap = new HashMap<UUID, ClientVersion>();
|
||||
|
||||
public int getPlayerPing(final Player player) {
|
||||
public int getPing(final Player player) {
|
||||
return NMSUtils.getPlayerPing(player);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,22 @@ public class PlayerUtils {
|
||||
return getClientVersion(player.getUniqueId());
|
||||
}
|
||||
|
||||
public void setClientVersion(final UUID uuid, final ClientVersion version) {
|
||||
clientVersionsMap.put(uuid, version);
|
||||
}
|
||||
|
||||
public void setClientVersion(final Player player, final ClientVersion version) {
|
||||
setClientVersion(player.getUniqueId(), version);
|
||||
}
|
||||
|
||||
public void clearClientVersion(final UUID uuid) {
|
||||
clientVersionsMap.remove(uuid);
|
||||
}
|
||||
|
||||
public void clearClientVersion(final Player player) {
|
||||
clearClientVersion(player.getUniqueId());
|
||||
}
|
||||
|
||||
public void injectPlayer(final Player player) {
|
||||
NettyPacketHandler.injectPlayer(player);
|
||||
}
|
||||
@@ -32,9 +48,11 @@ public class PlayerUtils {
|
||||
NettyPacketHandler.uninjectPlayer(player);
|
||||
}
|
||||
|
||||
public void uninjectPlayerNow(final Player player) {
|
||||
NettyPacketHandler.uninjectPlayerNow(player);
|
||||
}
|
||||
|
||||
public void sendPacket(final Player player, final Sendable sendable) {
|
||||
NMSUtils.sendSendableWrapper(player, sendable);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+7
-6
@@ -1,4 +1,4 @@
|
||||
package io.github.retrooper.packetevents;
|
||||
package io.github.retrooper.packetevents.utils.api;
|
||||
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.enums.SystemOS;
|
||||
@@ -6,12 +6,13 @@ import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public class ServerUtils {
|
||||
public ServerVersion getServerVersion() {
|
||||
public final class ServerUtils {
|
||||
|
||||
public ServerVersion getVersion() {
|
||||
return ServerVersion.getVersion();
|
||||
}
|
||||
|
||||
public double[] getRecentServerTPS() {
|
||||
public double[] getRecentTPS() {
|
||||
double[] tpsArray = new double[0];
|
||||
try {
|
||||
tpsArray = NMSUtils.recentTPS();
|
||||
@@ -21,8 +22,8 @@ public class ServerUtils {
|
||||
return tpsArray;
|
||||
}
|
||||
|
||||
public double getCurrentServerTPS() {
|
||||
return getRecentServerTPS()[0];
|
||||
public double getCurrentTPS() {
|
||||
return getRecentTPS()[0];
|
||||
}
|
||||
|
||||
public SystemOS getPlatform() {
|
||||
+1
-2
@@ -1,6 +1,5 @@
|
||||
package io.github.retrooper.packetevents.utils.nms_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;
|
||||
@@ -13,7 +12,7 @@ import java.lang.reflect.Method;
|
||||
|
||||
public final class EntityFinderUtils {
|
||||
@Nullable
|
||||
private static final ServerVersion version = PacketEvents.getAPI().getServerUtilities().getServerVersion();
|
||||
private static final ServerVersion version = ServerVersion.getVersion();
|
||||
private static Class<?> worldServerClass;
|
||||
private static Class<?> craftWorldClass;
|
||||
private static Class<?> entityClass;
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package io.github.retrooper.packetevents.utils.onlineplayers;
|
||||
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class OnlinePlayerUtilities {
|
||||
private static final ServerVersion version = ServerVersion.getVersion();
|
||||
|
||||
public static Player[] getOnlinePlayers() {
|
||||
if (version.isLowerThan(ServerVersion.v_1_9)) {
|
||||
return OnlinePlayerUtils_8.getOnlinePlayers();
|
||||
} else {
|
||||
return OnlinePlayerUtils_9.getOnlinePlayers();
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package io.github.retrooper.packetevents.utils.onlineplayers;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
|
||||
public class OnlinePlayerUtils_8 {
|
||||
public static Player[] getOnlinePlayers() {
|
||||
|
||||
return Bukkit.getServer().getOnlinePlayers().toArray(new Player[0]);
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package io.github.retrooper.packetevents.utils.onlineplayers;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class OnlinePlayerUtils_9 {
|
||||
public static Player[] getOnlinePlayers() {
|
||||
return Bukkit.getOnlinePlayers().toArray(new Player[0]);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package io.github.retrooper.packetevents.utils.api;
|
||||
package io.github.retrooper.packetevents.utils.versionlookup;
|
||||
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import org.bukkit.entity.Player;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package io.github.retrooper.packetevents.utils.api;
|
||||
package io.github.retrooper.packetevents.utils.versionlookup;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package io.github.retrooper.packetevents.utils.api;
|
||||
package io.github.retrooper.packetevents.utils.versionlookup;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import protocolsupport.api.ProtocolSupportAPI;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package io.github.retrooper.packetevents.utils.api;
|
||||
package io.github.retrooper.packetevents.utils.versionlookup;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package io.github.retrooper.packetevents.utils.api;
|
||||
package io.github.retrooper.packetevents.utils.versionlookup;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package io.github.retrooper.packetevents.utils.api;
|
||||
package io.github.retrooper.packetevents.utils.versionlookup;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package io.github.retrooper.packetevents.utils.api;
|
||||
package io.github.retrooper.packetevents.utils.versionlookup;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
Reference in new issue
Block a user