Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
04ca446d44 | ||
|
|
d8cfd826c0 | ||
|
|
30689a74bd | ||
|
|
957adbb3a2 | ||
|
|
e59ff04f2b | ||
|
|
3511099f78 | ||
|
|
7dc6f89585 | ||
|
|
e899b0cebb | ||
|
|
40ba25d011 | ||
|
|
43e5e0200a | ||
|
|
7906ac7fa9 | ||
|
|
706f5331b6 | ||
|
|
3e13ea6aaa | ||
|
|
fb13834048 | ||
|
|
3e8bd7f649 | ||
|
|
dfc898e0bf | ||
|
|
38fc0cf4be | ||
|
|
7204b85664 | ||
|
|
c0642a69a1 | ||
|
|
251e01f6e7 | ||
|
|
612a7b50cf | ||
|
|
c4d04d10d7 | ||
|
|
e87bfe0ef9 | ||
|
|
6d87a03412 | ||
|
|
13bea01eac | ||
|
|
9a8126cc1e | ||
|
|
45f705e351 | ||
|
|
1c3577a5e7 | ||
|
|
a2aedf680a | ||
|
|
14cfb6b8c5 | ||
|
|
5e98e8a192 | ||
|
|
bb65610e74 | ||
|
|
19ccfb87e3 | ||
|
|
514298b942 | ||
|
|
267480b563 | ||
|
|
a50a5f8f89 | ||
|
|
f06cd69b27 | ||
|
|
c0bf7f7069 | ||
|
|
d884c5324d | ||
|
|
16caeeee89 | ||
|
|
17e5d84907 | ||
|
|
fe4037b850 | ||
|
|
564f65d2d2 | ||
|
|
2a944d9376 | ||
|
|
3dc1bbc671 | ||
|
|
1a141b114e | ||
|
|
f9e7589d87 | ||
|
|
f77ab58b3b | ||
|
|
a3e744d883 | ||
|
|
8680f0f43b | ||
|
|
a981caa386 | ||
|
|
06644f5fe6 | ||
|
|
bcb79a0ac5 | ||
|
|
b6c48d95db | ||
|
|
f28092bccb | ||
|
|
a566b6f8cb | ||
|
|
ba7e178cb1 | ||
|
|
b88ac0191e | ||
|
|
f864eeb646 | ||
|
|
cc2f810be3 | ||
|
|
d41da16c56 | ||
|
|
9d3390b1bb | ||
|
|
3fe96333e1 | ||
|
|
a17c782c2e | ||
|
|
2f9a2ce435 | ||
|
|
d78776be6f | ||
|
|
e23d1a87f6 | ||
|
|
b27f86c073 | ||
|
|
2a5f5448a4 | ||
|
|
c84472270e | ||
|
|
e3b667d5b2 | ||
|
|
7079c50deb | ||
|
|
b3e07b9188 | ||
|
|
41427d8698 | ||
|
|
6e2177e27c | ||
|
|
25bba6e306 | ||
|
|
64c0c79edd | ||
|
|
9f6e79cb16 | ||
|
|
917959743e | ||
|
|
577660b58c | ||
|
|
4377d85a05 | ||
|
|
fb8fcf7d50 | ||
|
|
faf8e4664c | ||
|
|
7e52b8e979 | ||
|
|
55ab2fa043 | ||
|
|
560a1b5e2f | ||
|
|
db61b202c0 | ||
|
|
ebc697dd89 | ||
|
|
784d99c03d | ||
|
|
d48ab480c9 | ||
|
|
052f1108c3 | ||
|
|
b42f5b68ca | ||
|
|
3926c48114 | ||
|
|
0a5f2d2b8e | ||
|
|
57f80b5196 | ||
|
|
7ac3b7e65b | ||
|
|
4ce2f88d4a | ||
|
|
374025f5bf | ||
|
|
450da1ce3f | ||
|
|
4a5cfd141a | ||
|
|
56ea329b5c | ||
|
|
3104cda55e | ||
|
|
111b28ba7e | ||
|
|
7754a6e183 | ||
|
|
2d2063cac2 | ||
|
|
494edfa095 | ||
|
|
e3a9d4e6de | ||
|
|
c8f766735a | ||
|
|
83899c8fac | ||
|
|
99d56a520e | ||
|
|
c1b2caad8b | ||
|
|
53cd0feba3 | ||
|
|
e83945d875 | ||
|
|
31def9a711 | ||
|
|
b4514dca63 | ||
|
|
add5f9853d | ||
|
|
419c08780f | ||
|
|
d39b50b02c | ||
|
|
2d8b2ae523 | ||
|
|
3e5366f374 | ||
|
|
2b10325f7f | ||
|
|
4c5fdf6dce | ||
|
|
8a8616c124 | ||
|
|
8095e506e4 | ||
|
|
e067208755 | ||
|
|
f9bf042178 | ||
|
|
23db4a6506 | ||
|
|
2e0468ed74 | ||
|
|
e932fb5707 | ||
|
|
337551119b | ||
|
|
7ec7336b9a | ||
|
|
a136729532 | ||
|
|
2da41d03ef | ||
|
|
3c65754fca | ||
|
|
688931aa7e | ||
|
|
e5338caa29 | ||
|
|
b45bc73396 | ||
|
|
918d5b89ef | ||
|
|
9f06d583ab | ||
|
|
1c87cf7982 | ||
|
|
75f7eaf74f | ||
|
|
a4f4163412 | ||
|
|
ef529b7949 | ||
|
|
6e52acb677 | ||
|
|
826695a677 | ||
|
|
e403469e52 | ||
|
|
084acb8894 | ||
|
|
948e260460 | ||
|
|
f4efdea4b2 | ||
|
|
1cb7730c3c | ||
|
|
5b558b50e2 | ||
|
|
00986f2341 | ||
|
|
b83e8887ff | ||
|
|
7bfadfa233 | ||
|
|
a3f75f1237 | ||
|
|
1e21d3f6ea | ||
|
|
73d0c6ea7d | ||
|
|
278b27da6b | ||
|
|
fbb0692f80 | ||
|
|
f4307ab524 | ||
|
|
cafda14c89 | ||
|
|
2e7e81be9f | ||
|
|
83b5697d40 | ||
|
|
e0a1c39e54 | ||
|
|
6608203ddc | ||
|
|
1f811ba90e | ||
|
|
70f33f56e8 | ||
|
|
39c2a157c4 | ||
|
|
761352cbbc | ||
|
|
44016e1a03 | ||
|
|
a2233c434a | ||
|
|
fb4863cbe9 | ||
|
|
e60d50a957 | ||
|
|
c53d69d03c | ||
|
|
9e294d7185 | ||
|
|
e9cd983131 | ||
|
|
e6798d4901 | ||
|
|
1c0e8cdd91 | ||
|
|
a3f9fc9cb3 | ||
|
|
808bbabff1 | ||
|
|
4a5e579256 | ||
|
|
7c74d22700 | ||
|
|
cf11930f05 | ||
|
|
f814d20cbb | ||
|
|
6313fca6fa | ||
|
|
f0bcfc62c8 | ||
|
|
cf930c6013 | ||
|
|
052a65f6ef | ||
|
|
4078418376 | ||
|
|
68e8d4f788 | ||
|
|
be6e0ce222 | ||
|
|
67dd097a0f | ||
|
|
ed9007da44 | ||
|
|
81632cdf6d | ||
|
|
727e02a235 | ||
|
|
39e105c69c | ||
|
|
1a2145b413 | ||
|
|
05a981de6e | ||
|
|
79c07642a2 | ||
|
|
e2352fe3bf | ||
|
|
2d9ac56f2e | ||
|
|
8e1d70b6be | ||
|
|
7c6a675173 | ||
|
|
feeff01654 | ||
|
|
0e53005867 | ||
|
|
98b4ee2bac | ||
|
|
efc2dc1c54 | ||
|
|
827c974908 | ||
|
|
05b9c8efca | ||
|
|
42a9745196 | ||
|
|
5a283b7ffa | ||
|
|
59d25df76b | ||
|
|
c42a00ddcf | ||
|
|
b3e06caf7c | ||
|
|
a0b84c0552 | ||
|
|
e8be5eb8ba | ||
|
|
2531988a59 | ||
|
|
7204b06870 | ||
|
|
6289543ea5 | ||
|
|
6a1ce5e234 | ||
|
|
bd1e4e7e6d | ||
|
|
feda5b96b6 | ||
|
|
809396ff21 | ||
|
|
2428487eb1 | ||
|
|
df0c769111 | ||
|
|
5e0cd75bb0 | ||
|
|
b21e6b4a67 | ||
|
|
bfc3aa7ad8 | ||
|
|
72458ddfd2 | ||
|
|
a8a04b137b | ||
|
|
4e11df1fc7 | ||
|
|
c3ab35bd6b | ||
|
|
af1025da1f | ||
|
|
f2ce9eacb1 | ||
|
|
27307e034b | ||
|
|
808357735f | ||
|
|
ece8b6d395 | ||
|
|
8643e14900 | ||
|
|
cbfd52d926 | ||
|
|
e266e43d19 | ||
|
|
c9d58e08c9 | ||
|
|
24eda2b3a5 | ||
|
|
38c4f3234d | ||
|
|
e94b6f24dc | ||
|
|
85dab8eb7a | ||
|
|
5fb8634880 | ||
|
|
e551421867 | ||
|
|
3dfb1ce0b5 | ||
|
|
aca321c332 | ||
|
|
e0f4891a72 | ||
|
|
08b207d80a | ||
|
|
6121349a6f | ||
|
|
2b58a9ad97 | ||
|
|
8e922a7676 | ||
|
|
7967b6851f | ||
|
|
18b37abf5b | ||
|
|
53b713f574 | ||
|
|
655f162272 | ||
|
|
686c50a7bb | ||
|
|
a88e95e116 | ||
|
|
7c583bf8ec | ||
|
|
c3911483a5 | ||
|
|
f37d7f4040 | ||
|
|
c39c9691a8 | ||
|
|
a1c591a616 | ||
|
|
999e21bf77 | ||
|
|
c8e5a37472 | ||
|
|
c6fffca506 | ||
|
|
f1206a1fc6 | ||
|
|
29a4280b50 | ||
|
|
552f63a27f | ||
|
|
612608181d | ||
|
|
8e652f0c44 | ||
|
|
4a3e89d713 | ||
|
|
3dd6d1e0b9 | ||
|
|
f42e1ad71d | ||
|
|
b44f36185a | ||
|
|
1621adad02 | ||
|
|
d2682242ae | ||
|
|
0b26fe3266 | ||
|
|
0354ddf765 | ||
|
|
82e0d01c29 | ||
|
|
57b68f185c | ||
|
|
8f9b8c0433 | ||
|
|
27ced0fc36 | ||
|
|
1d383a7d37 | ||
|
|
ae81019fd8 | ||
|
|
d05019adac | ||
|
|
1d45ec916c | ||
|
|
7328fc9381 | ||
|
|
89f21b927f | ||
|
|
04c33929cd | ||
|
|
fa2aab5e74 | ||
|
|
ebc81c0986 | ||
|
|
c6348e0dc9 | ||
|
|
f84d3000f4 | ||
|
|
7ddfc681cc | ||
|
|
cdb67c80c0 | ||
|
|
ed78c9d746 | ||
|
|
b7128d5f33 | ||
|
|
ba0b32ffdb | ||
|
|
3b420a4c28 | ||
|
|
5abc9c7154 | ||
|
|
c5f377476c | ||
|
|
105ea434da | ||
|
|
f0196bdab9 | ||
|
|
982d1ee9a0 | ||
|
|
a7bbb20f60 | ||
|
|
2ca79017e2 | ||
|
|
c4a3d26d96 | ||
|
|
93292fb2f2 | ||
|
|
3a9be091ea | ||
|
|
92f3944049 | ||
|
|
27f90655f1 | ||
|
|
4b868392e6 | ||
|
|
ebb1ba990d | ||
|
|
b4bb72e236 | ||
|
|
e876ebe078 | ||
|
|
d6af873b9d | ||
|
|
c10d309180 | ||
|
|
c33ab2c52c | ||
|
|
ec6cef3526 | ||
|
|
c61738bbab | ||
|
|
00990a49f9 | ||
|
|
72a199ce48 | ||
|
|
ac585f7c81 | ||
|
|
a8b286c6fc | ||
|
|
364747986b | ||
|
|
b51c3ad20a | ||
|
|
df8c77291d | ||
|
|
9dde0e54fe | ||
|
|
72f1b2bf02 | ||
|
|
332782e99c | ||
|
|
9f7e49b453 | ||
|
|
e17f53ca3c | ||
|
|
5fc1abaff2 | ||
|
|
a9ad25d3fc | ||
|
|
bf3c0cda46 | ||
|
|
e9680c287d | ||
|
|
e05dda9ea6 | ||
|
|
7db442682e | ||
|
|
61911ac09a | ||
|
|
381dc28831 | ||
|
|
1686d38f0b | ||
|
|
509b93968d | ||
|
|
1458331e3f | ||
|
|
d5777a55f0 | ||
|
|
d7c4d2c425 | ||
|
|
a268687cea | ||
|
|
d679e43058 | ||
|
|
1f609f8732 | ||
|
|
30e9d38bf2 | ||
|
|
922342345d | ||
|
|
80c8c5453b | ||
|
|
ba72ec37c6 | ||
|
|
9bfb696c9d | ||
|
|
4a9848f51d | ||
|
|
383eacc814 | ||
|
|
860b80e2c2 | ||
|
|
0259bc8d9d | ||
|
|
37238e1226 | ||
|
|
c51880941b | ||
|
|
451bbe7597 | ||
|
|
d99e20d95e | ||
|
|
5eca22a9df | ||
|
|
c4d6b26986 | ||
|
|
197acc4d2f | ||
|
|
da5a5cf15a | ||
|
|
0797df24d2 | ||
|
|
7fca4ac8d6 | ||
|
|
0516513c67 | ||
|
|
4603794436 | ||
|
|
a5bbe4047b | ||
|
|
770a2d3287 | ||
|
|
3bd4b82d94 | ||
|
|
218b2d7782 | ||
|
|
76a08e6c12 | ||
|
|
4d28a58dcb | ||
|
|
9347e7a133 | ||
|
|
33ed5ff904 | ||
|
|
291994d388 | ||
|
|
f6ea9675bf | ||
|
|
cc303f56a4 | ||
|
|
290bd0a8fe | ||
|
|
a8573cc8e1 | ||
|
|
814bd941c0 | ||
|
|
d3f6d32848 | ||
|
|
5e1b82ea8a | ||
|
|
e49cae5d67 | ||
|
|
8168bb2085 | ||
|
|
621a7c98b9 | ||
|
|
28da2aafc4 | ||
|
|
e89e6fac28 | ||
|
|
a5e067af9e | ||
|
|
04de7fd5ea | ||
|
|
815428f35b | ||
|
|
833f569150 | ||
|
|
6b227d55aa | ||
|
|
57a6c26c07 | ||
|
|
b2da168f6a | ||
|
|
4c1e14af57 | ||
|
|
5f9e82617f | ||
|
|
9868facdde | ||
|
|
d45f8bddac | ||
|
|
e4b086e7e5 | ||
|
|
7afe3c63cd | ||
|
|
5103acf414 | ||
|
|
70b763b5a3 | ||
|
|
e1370b803f | ||
|
|
ac3ca0ddf7 | ||
|
|
15bec5525a | ||
|
|
0e8dcb6a40 | ||
|
|
836efcfa03 | ||
|
|
774e6decf3 | ||
|
|
839265e0b9 | ||
|
|
32c94c85f1 | ||
|
|
a36df67f6f | ||
|
|
cdb46f476c | ||
|
|
96e5e7393e | ||
|
|
130001a44c | ||
|
|
1328ea81e8 | ||
|
|
a42153cff9 | ||
|
|
79929f5700 | ||
|
|
8c3726c165 | ||
|
|
51a58f79a5 | ||
|
|
8691304925 | ||
|
|
9fef95d96e | ||
|
|
4d42a23510 | ||
|
|
787df36fe0 | ||
|
|
a59ea40e12 | ||
|
|
fdb3a23acc | ||
|
|
60d24ac3c1 | ||
|
|
7634540bd7 | ||
|
|
0a475e4242 | ||
|
|
ff3b66b22e | ||
|
|
8be5f5bfa6 | ||
|
|
8d887335e2 | ||
|
|
553f429a53 | ||
|
|
a4a8b36665 | ||
|
|
49d46b79df | ||
|
|
08a2b92bcf | ||
|
|
f32dafc3ee | ||
|
|
84e391ffc8 | ||
|
|
26a369af89 | ||
|
|
56c752b487 | ||
|
|
890fcadac2 | ||
|
|
27f09f6627 | ||
|
|
e5b89271ee | ||
|
|
48ef0e7852 | ||
|
|
192851b03f | ||
|
|
dd30876e70 | ||
|
|
ce2603549b | ||
|
|
c645124e55 | ||
|
|
3c3a00b7bb | ||
|
|
d34e152b98 | ||
|
|
d5454b918a | ||
|
|
427a0fff4a | ||
|
|
7fc446321d | ||
|
|
3f85f4998b | ||
|
|
4799fb67c4 | ||
|
|
5ed9038f7b | ||
|
|
8c1cd4b824 | ||
|
|
50a09de212 | ||
|
|
e66710f5ed | ||
|
|
33131f4fcd | ||
|
|
9834787279 | ||
|
|
227b569138 | ||
|
|
ad1a8a3dba | ||
|
|
262c470031 | ||
|
|
4c9b9be23f | ||
|
|
d1c04d39d2 | ||
|
|
afbe7b44b6 | ||
|
|
f76f1687fb | ||
|
|
8eb4015cab | ||
|
|
3ec44f72da | ||
|
|
3797c45d98 | ||
|
|
94b7523774 | ||
|
|
6f0de9f01c | ||
|
|
16cc63447f | ||
|
|
bb6661b4eb | ||
|
|
63a5005257 | ||
|
|
8b4fdd4773 | ||
|
|
333bea795f | ||
|
|
3ee972a4ff | ||
|
|
94a1f67975 | ||
|
|
e00b55842d |
No files matched your search
@@ -0,0 +1,5 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: retrooper
|
||||
custom: ['https://paypal.me/retrooperdev']
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Report a bug to help us fix
|
||||
title: "[BUG REPORT]"
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
*Example:*
|
||||
1. Login on the 1.16.4 minecraft client.
|
||||
2. Join the server while it is still starting up.
|
||||
3. ....
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**About your server (please complete the following information):**
|
||||
- Spigot: [eg. Paper or Tuinity]
|
||||
We only accept reports that are reproducible
|
||||
on one of the supported spigots.
|
||||
|
||||
- Server Version: [eg. 1.16.4]
|
||||
Feel free to report bugs for versions newer than 1.7.10, even if we
|
||||
don’t support them yet, but be aware that we might have already
|
||||
found the bug and fixed it in a dev build, just before you reported it.
|
||||
Please don’t get frustrated in such cases.
|
||||
|
||||
- Plugins List if possible: [eg. ViaVersion, ProtocolLib, HolographicDisplays]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
@@ -0,0 +1,21 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: FEATURE REQUEST
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered to solve your solution without
|
||||
us adding this as a feature?**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
@@ -0,0 +1,67 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master, dev ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ master, dev ]
|
||||
schedule:
|
||||
- cron: '39 0 * * 0'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'java' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
|
||||
# Learn more:
|
||||
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
#
|
||||
# JetBrains
|
||||
#
|
||||
|
||||
# User-specific stuff
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Gradle and Maven with auto-import
|
||||
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||
# since they will be recreated, and may cause churn. Uncomment if using
|
||||
# auto-import.
|
||||
# .idea/artifacts
|
||||
# .idea/compiler.xml
|
||||
# .idea/jarRepositories.xml
|
||||
# .idea/modules.xml
|
||||
# .idea/*.iml
|
||||
# .idea/modules
|
||||
# *.iml
|
||||
# *.ipr
|
||||
|
||||
# CMake
|
||||
cmake-build-*/
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# File-based project format
|
||||
*.iws
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
||||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
|
||||
#
|
||||
# Java
|
||||
#
|
||||
|
||||
# Compiled class file
|
||||
*.class
|
||||
|
||||
# Log file
|
||||
*.log
|
||||
|
||||
# BlueJ files
|
||||
*.ctxt
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.nar
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
#
|
||||
# Maven
|
||||
#
|
||||
target/
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
pom.xml.next
|
||||
release.properties
|
||||
dependency-reduced-pom.xml
|
||||
buildNumber.properties
|
||||
.mvn/timing.properties
|
||||
# https://github.com/takari/maven-wrapper#usage-without-binary-jar
|
||||
.mvn/wrapper/maven-wrapper.jar
|
||||
@@ -1,20 +1,82 @@
|
||||
# packetevents by retrooper
|
||||
# packetevents
|
||||
|
||||
A lightweight spigot packetlistener & packetsender coded by retrooper.
|
||||
Some tasks require you to work at the packet level.
|
||||
It is very common for people to write their own packet system and event manager.
|
||||
PacketEvents is here to save you a ton of work.
|
||||
We provide high level packet-wrappers.
|
||||
The PacketEvents API focuses on providing you easy to use packet-wrappers supporting 1.7.10 spigots up to the current latest version!
|
||||
This API even comes with two event systems.
|
||||
The first one (currently deprecated) is extremely similar to Bukkit's event system making it really easy to use for
|
||||
experienced Bukkit plugin developers.
|
||||
The second one (recommended) prioritizes performance.
|
||||
PacketEvents listens to its community.
|
||||
Many users love shading the API into their plugin, so that their customers won't need to
|
||||
download the API as an external dependency.
|
||||
We have gone out of our way to support multiple plugins shading the API (resulting in duplicate PacketEvents APIs)
|
||||
and they all work together.
|
||||
|
||||
## About
|
||||
### Resources
|
||||
* [Website](https://packetevents.github.io)
|
||||
* [SpigotMC](https://www.spigotmc.org/resources/packetevents-api.80279/)
|
||||
* [JavaDoc](https://retrooper.github.io/packetevents)
|
||||
|
||||
This packetlistener is **only** supported on spigot servers and has been tested to work on these spigot forks: PaperSpigot, Tuinity
|
||||
### Licensing
|
||||
[](https://opensource.org/licenses/MIT)\
|
||||
PacketEvents is licensed under the MIT License.
|
||||
We intentionally selected this license compared to stricter options.\
|
||||
[Summary of the license](https://tldrlegal.com/license/mit-license)
|
||||
|
||||
* No dependencies
|
||||
### Contributing
|
||||
[](CONTRIBUTOR_CODE_OF_CONDUCT.md)\
|
||||
PacketEvents is an open source project.
|
||||
We appreciate contributions.
|
||||
It is amazing that you want to take an extra step to contribute a change to the API that will
|
||||
hopefully benefit the majority of users.
|
||||
Before taking this step, please read the Contributor Code Of Conduct. (click on the badge above)
|
||||
Please also read [this](CONTRIBUTING.md) if you consider contributing.
|
||||
Our discord server has a role for contributors.\
|
||||
[Learn more about it in our discord server](https://discord.me/packetevents)
|
||||
|
||||
* Licensed under the MIT license
|
||||
### Forking
|
||||
We also appreciate forks.
|
||||
It is always great news to us knowing someone is building their own API off of the PacketEvents API.
|
||||
If you are developing a feature that is only going to benefit you and not the majority of the community,
|
||||
please do not contribute!
|
||||
Make a fork instead!
|
||||
Our discord server has a discord role for forkers.\
|
||||
[Learn more about it in our discord server](https://discord.me/packetevents)
|
||||
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
|
||||
Our discord server: https://discord.me/packetevents
|
||||
### Compilation
|
||||
PacketEvents is built with Maven and all past releases have always used maven.
|
||||
The majority of users (currently) in the Bukkit community use Maven.
|
||||
It should be easier for most people to contribute if we use Maven too.
|
||||
Just because PacketEvents is built with Maven doesn't mean you can't use other dependency managers to use the API.
|
||||
|
||||
### Setup
|
||||
You can either use the API with a dependency manager(like Maven or Gradle), depend on a pre-built build or compile it yourself with the source code.
|
||||
We recommend using a dependency manager.
|
||||
#### 1. Using a dependency manager
|
||||
[](https://jitpack.io/#retrooper/packetevents)
|
||||
|
||||
[](https://jitci.com/gh/retrooper/packetevents)
|
||||
#### 2. Using as an external pre-built dependency.
|
||||
* Download the [latest build from SpigotMC](https://www.spigotmc.org/resources/packetevents-api.80279/)
|
||||
* Add PacketEvents as a depend or soft-depend to your plugin.yml like this:
|
||||
```yml
|
||||
depend: [packetevents]
|
||||
```
|
||||
Your customers are now required to download this external pre-built dependency on their minecraft server.\
|
||||
It is an API and a Bukkit plugin at the same time.
|
||||
The version of the pre-built dependency is recommended to be the same as the version
|
||||
of the API you used in your plugin incase there have been API changes.
|
||||
|
||||
#### 3. Compiling source code.
|
||||
When compiling the source code yourself, you are required to use Maven. (unless you switch yourself)\
|
||||
We currently do not have a guide showing you how to do this, but it should be self explanatory if you know what you are doing.
|
||||
|
||||
### Author
|
||||
PacketEvents was started by retrooper.
|
||||
This API was initially for his private anti-cheat he was developing just to test around with.
|
||||
He has quit anti-cheat development and is now prioritizing this API and a few other private projects.
|
||||
PacketEvents now has a handfull of contributors improving the API.
|
||||
Share the API, donate, contribute, fork.
|
||||
Thanks.
|
||||
@@ -1,23 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>io.github.retrooper</groupId>
|
||||
<artifactId>packetevents</artifactId>
|
||||
<version>1.5.9</version>
|
||||
|
||||
<!-- You can build the project with this: "mvn clean compile assembly:single" -->
|
||||
<version>1.8-PRE-1</version>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
</configuration>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.2.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<minimizeJar>true</minimizeJar>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
@@ -27,7 +34,25 @@
|
||||
<target>8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-javadocs</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
<packaging>jar</packaging>
|
||||
<name>packetevents</name>
|
||||
@@ -58,10 +83,47 @@
|
||||
<id>dmulloy2-repo</id>
|
||||
<url>https://repo.dmulloy2.net/nexus/repository/public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>sonotype</id>
|
||||
<url>https://oss.sonatype.org/content/repositories/releases/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
<version>20.1.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.github.spigot</groupId>
|
||||
<artifactId>1.16.2</artifactId>
|
||||
<version>1.16.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.github.spigot</groupId>
|
||||
<artifactId>1.13.2</artifactId>
|
||||
<version>1.13.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.github.spigot</groupId>
|
||||
<artifactId>1.12.2</artifactId>
|
||||
<version>1.12.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.github.spigot</groupId>
|
||||
<artifactId>1.9</artifactId>
|
||||
<version>1.9</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.github.spigot</groupId>
|
||||
@@ -87,14 +149,14 @@
|
||||
<dependency>
|
||||
<groupId>us.myles</groupId>
|
||||
<artifactId>viaversion</artifactId>
|
||||
<version>3.0.1</version>
|
||||
<version>3.2.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.ProtocolSupport</groupId>
|
||||
<artifactId>ProtocolSupport</artifactId>
|
||||
<version>4fdd683</version>
|
||||
<version>3d24efeda6</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -104,13 +166,5 @@
|
||||
<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,122 +1,323 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents;
|
||||
|
||||
import io.github.retrooper.packetevents.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.packet.PacketType;
|
||||
import io.github.retrooper.packetevents.packet.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.event.impl.PostPlayerInjectEvent;
|
||||
import io.github.retrooper.packetevents.event.manager.EventManager;
|
||||
import io.github.retrooper.packetevents.event.manager.PEEventManager;
|
||||
import io.github.retrooper.packetevents.exceptions.PacketEventsLoadFailureException;
|
||||
import io.github.retrooper.packetevents.handler.PacketHandlerInternal;
|
||||
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.settings.PacketEventsSettings;
|
||||
import io.github.retrooper.packetevents.updatechecker.UpdateChecker;
|
||||
import io.github.retrooper.packetevents.utils.entityfinder.EntityFinderUtils;
|
||||
import io.github.retrooper.packetevents.utils.netty.bytebuf.ByteBufUtil;
|
||||
import io.github.retrooper.packetevents.utils.netty.bytebuf.ByteBufUtil_7;
|
||||
import io.github.retrooper.packetevents.utils.netty.bytebuf.ByteBufUtil_8;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.player.ClientVersion;
|
||||
import io.github.retrooper.packetevents.utils.player.PlayerUtils;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerUtils;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
import io.github.retrooper.packetevents.utils.version.PEVersion;
|
||||
import io.github.retrooper.packetevents.utils.versionlookup.VersionLookupUtils;
|
||||
import io.github.retrooper.packetevents.utils.versionlookup.protocollib.ProtocolLibVersionLookupUtils;
|
||||
import io.github.retrooper.packetevents.utils.versionlookup.v_1_7_10.ProtocolVersionAccessor_v_1_7;
|
||||
import io.github.retrooper.packetevents.utils.versionlookup.viaversion.ViaVersionLookupUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.event.player.PlayerLoginEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public final class PacketEvents implements PacketListener, Listener {
|
||||
private static final PacketEventsAPI packetEventsAPI = new PacketEventsAPI();
|
||||
private static final PacketEvents instance = new PacketEvents();
|
||||
private static final PacketEventsSettings settings = new PacketEventsSettings();
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public final class PacketEvents implements Listener, EventManager {
|
||||
private static PacketEvents instance;
|
||||
private final PEVersion version = new PEVersion(1, 7, 9, 1);
|
||||
private final EventManager eventManager = new PEEventManager();
|
||||
private final PlayerUtils playerUtils = new PlayerUtils();
|
||||
private final ServerUtils serverUtils = new ServerUtils();
|
||||
private static Plugin plugin;
|
||||
private static boolean hasLoaded, hasStarted;
|
||||
|
||||
public static String handlerName;
|
||||
/**
|
||||
* Call this before start()
|
||||
* General executor service, basically for anything that the packet executor service doesn't do.
|
||||
* For example update checking when you initialize PacketEvents.
|
||||
*/
|
||||
public static void load() {
|
||||
//SERVER VERSION LOADING
|
||||
public ExecutorService generalExecutorService = Executors.newSingleThreadExecutor(r -> new Thread(r, "PacketEvents-general"));
|
||||
|
||||
//Server Version reversed values caching
|
||||
ServerVersion.reversedValues = ServerVersion.reverse(ServerVersion.values());
|
||||
//Executor used for player injecting/ejecting.
|
||||
public ExecutorService injectAndEjectExecutorService;//Initiated in init method
|
||||
|
||||
PacketTypeClasses.Client.load();
|
||||
PacketTypeClasses.Server.load();
|
||||
ClientVersion.prepareLookUp();
|
||||
hasLoaded = true;
|
||||
public PacketHandlerInternal packetHandlerInternal;
|
||||
private boolean loading, loaded, initialized, initializing, stopping;
|
||||
private PacketEventsSettings settings = new PacketEventsSettings();
|
||||
private final ByteBufUtil byteBufUtil = NMSUtils.legacyNettyImportMode ? new ByteBufUtil_7() : new ByteBufUtil_8();
|
||||
|
||||
|
||||
public static PacketEvents create(final Plugin plugin) {
|
||||
if (!Bukkit.getServicesManager().isProvidedFor(PacketEvents.class)) {
|
||||
instance = new PacketEvents();
|
||||
Bukkit.getServicesManager().register(PacketEvents.class, instance,
|
||||
plugin, ServicePriority.Normal);
|
||||
return instance;
|
||||
}
|
||||
return instance = Bukkit.getServicesManager().load(PacketEvents.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads PacketEvents if you haven't already, Sets everything up, injects all players
|
||||
*/
|
||||
public static void start(final Plugin pl) {
|
||||
if (!hasLoaded) {
|
||||
load();
|
||||
public static PacketEvents get() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static PacketEvents getAPI() {
|
||||
return get();
|
||||
}
|
||||
|
||||
|
||||
public void load() {
|
||||
if (!loaded && !loading) {
|
||||
loading = true;
|
||||
ServerVersion version = ServerVersion.getVersion();
|
||||
WrappedPacket.version = version;
|
||||
NMSUtils.version = version;
|
||||
EntityFinderUtils.version = version;
|
||||
|
||||
try {
|
||||
NMSUtils.load();
|
||||
|
||||
//Load all classes
|
||||
PacketTypeClasses.load();
|
||||
|
||||
EntityFinderUtils.load();
|
||||
} catch (Exception ex) {
|
||||
loading = false;
|
||||
throw new PacketEventsLoadFailureException(ex);
|
||||
}
|
||||
loaded = true;
|
||||
loading = false;
|
||||
}
|
||||
if (!hasStarted) {
|
||||
}
|
||||
|
||||
public void loadSettings(PacketEventsSettings settings) {
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
public void init(final Plugin plugin) {
|
||||
init(plugin, settings);
|
||||
}
|
||||
|
||||
public void init(final Plugin pl, PacketEventsSettings packetEventsSettings) {
|
||||
load();
|
||||
if (!initialized && !initializing) {
|
||||
initializing = true;
|
||||
settings = packetEventsSettings;
|
||||
if (settings.getInjectAndEjectThreadCount() < 1) {
|
||||
settings.injectAndEjectThreadCount(1);
|
||||
}
|
||||
settings.lock();
|
||||
|
||||
int injectAndEjectThreadCount = settings.getInjectAndEjectThreadCount();
|
||||
injectAndEjectExecutorService = Executors.newFixedThreadPool(injectAndEjectThreadCount, new ThreadFactory() {
|
||||
|
||||
private final AtomicInteger id = new AtomicInteger();
|
||||
|
||||
@Override
|
||||
public Thread newThread(@NotNull Runnable r) {
|
||||
return new Thread(r, "PacketEvents-inject-eject #" + id.getAndIncrement());
|
||||
}
|
||||
});
|
||||
|
||||
//Register Bukkit listener
|
||||
plugin = pl;
|
||||
//Register Bukkit and PacketListener
|
||||
getAPI().getEventManager().registerListener(instance);
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(instance, plugin);
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
handlerName = "pe-" + plugin.getName();
|
||||
packetHandlerInternal = new PacketHandlerInternal(plugin);
|
||||
for (final Player p : Bukkit.getOnlinePlayers()) {
|
||||
getAPI().getPlayerUtils().injectPlayer(p);
|
||||
try {
|
||||
getPlayerUtils().injectPlayer(p);
|
||||
} catch (Exception ex) {
|
||||
p.kickPlayer(getSettings().getInjectionFailureMessage());
|
||||
}
|
||||
}
|
||||
hasStarted = true;
|
||||
|
||||
if (settings.shouldCheckForUpdates()) {
|
||||
generalExecutorService.execute(() -> new UpdateChecker().handleUpdate());
|
||||
|
||||
}
|
||||
initialized = true;
|
||||
initializing = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop all tasks and unregisters all PacketEvents' listeners
|
||||
*/
|
||||
public static void stop() {
|
||||
if (hasStarted) {
|
||||
for (final Player p : Bukkit.getOnlinePlayers()) {
|
||||
|
||||
getAPI().getPlayerUtils().uninjectPlayerNow(p);
|
||||
public void terminate() {
|
||||
if (initialized && !stopping) {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
packetHandlerInternal.ejectPlayer(player);
|
||||
}
|
||||
getAPI().getEventManager().unregisterAllListeners();
|
||||
packetHandlerInternal.cleanup();
|
||||
|
||||
PacketType.Client.packetIds.clear();
|
||||
PacketType.Server.packetIds.clear();
|
||||
getEventManager().unregisterAllListeners();
|
||||
generalExecutorService.shutdownNow();
|
||||
injectAndEjectExecutorService.shutdownNow();
|
||||
initialized = false;
|
||||
stopping = false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean hasLoaded() {
|
||||
return hasLoaded;
|
||||
@Deprecated
|
||||
public void stop() {
|
||||
terminate();
|
||||
}
|
||||
|
||||
public static boolean hasStarted() {
|
||||
return hasStarted;
|
||||
public boolean hasLoaded() {
|
||||
return loaded;
|
||||
}
|
||||
|
||||
public static PacketEventsAPI getAPI() {
|
||||
return packetEventsAPI;
|
||||
public boolean isLoading() {
|
||||
return loading;
|
||||
}
|
||||
|
||||
public static Plugin getPlugin() {
|
||||
public boolean isInitializing() {
|
||||
return initializing;
|
||||
}
|
||||
|
||||
public boolean isStopping() {
|
||||
return stopping;
|
||||
}
|
||||
|
||||
public boolean isInitialized() {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
public Plugin getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
public static String getHandlerName(final String name) {
|
||||
return "pe-" + getSettings().getIdentifier() + "-" + name;
|
||||
}
|
||||
|
||||
public static PacketEventsSettings getSettings() {
|
||||
/**
|
||||
* Get the PacketEvents settings.
|
||||
*
|
||||
* @return Configure some settings for the API
|
||||
*/
|
||||
public PacketEventsSettings getSettings() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public PEVersion getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public EventManager getEventManager() {
|
||||
return eventManager;
|
||||
}
|
||||
|
||||
public PlayerUtils getPlayerUtils() {
|
||||
return playerUtils;
|
||||
}
|
||||
|
||||
public ServerUtils getServerUtils() {
|
||||
return serverUtils;
|
||||
}
|
||||
|
||||
public ByteBufUtil getByteBufUtil() {
|
||||
return byteBufUtil;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onLogin(final PlayerLoginEvent e) {
|
||||
if (getSettings().shouldInjectEarly()) {
|
||||
try {
|
||||
packetHandlerInternal.injectPlayer(e.getPlayer());
|
||||
} catch (Exception ex) {
|
||||
e.disallow(PlayerLoginEvent.Result.KICK_OTHER, PacketEvents.get().getSettings().getInjectionFailureMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void onJoin(final PlayerJoinEvent e) {
|
||||
getAPI().getPlayerUtils().injectPlayer(e.getPlayer());
|
||||
getAPI().getPlayerUtils().setClientVersion(e.getPlayer(), ClientVersion.fromProtocolVersion(VersionLookupUtils.getProtocolVersion(e.getPlayer())));
|
||||
final InetSocketAddress address = e.getPlayer().getAddress();
|
||||
boolean viaAvailable = ViaVersionLookupUtils.isAvailable();
|
||||
if (viaAvailable) {
|
||||
PacketEvents.get().getPlayerUtils().clientVersionsMap.put(e.getPlayer().getAddress(), ClientVersion.TEMP_UNRESOLVED);
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(getPlugin(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int protocolVersion = VersionLookupUtils.getProtocolVersion(e.getPlayer());
|
||||
ClientVersion version = ClientVersion.getClientVersion(protocolVersion);
|
||||
PacketEvents.get().getPlayerUtils().clientVersionsMap.put(address, version);
|
||||
PacketEvents.get().getEventManager().callEvent(new PostPlayerInjectEvent(e.getPlayer(), true));
|
||||
}
|
||||
}, 1L);
|
||||
} else if (getServerUtils().getVersion() == ServerVersion.v_1_7_10) {
|
||||
ClientVersion version = ClientVersion.getClientVersion(ProtocolVersionAccessor_v_1_7.getProtocolVersion(e.getPlayer()));
|
||||
if (version == ClientVersion.UNRESOLVED) {
|
||||
version = getPlayerUtils().tempClientVersionMap.get(address);
|
||||
if (version == null) {
|
||||
version = ClientVersion.UNRESOLVED;
|
||||
}
|
||||
}
|
||||
getPlayerUtils().clientVersionsMap.put(address, version);
|
||||
}
|
||||
|
||||
if (!getSettings().shouldInjectEarly()) {
|
||||
try {
|
||||
packetHandlerInternal.injectPlayer(e.getPlayer());
|
||||
//Injection was successful as no exception was thrown...
|
||||
if (!viaAvailable) {
|
||||
if (ProtocolLibVersionLookupUtils.isAvailable()) {
|
||||
ClientVersion version = ClientVersion.getClientVersion(ProtocolLibVersionLookupUtils.getProtocolVersion(e.getPlayer()));
|
||||
PacketEvents.get().getPlayerUtils().clientVersionsMap.put(address, version);
|
||||
}
|
||||
PacketEvents.get().getEventManager().callEvent(new PostPlayerInjectEvent(e.getPlayer(), false));
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
e.getPlayer().kickPlayer(getSettings().getInjectionFailureMessage());
|
||||
}
|
||||
} else {
|
||||
if (!viaAvailable) {
|
||||
PacketEvents.get().getEventManager().callEvent(new PostPlayerInjectEvent(e.getPlayer(), false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onQuit(final PlayerQuitEvent e) {
|
||||
getAPI().getPlayerUtils().clearClientVersion(e.getPlayer());
|
||||
getAPI().getPlayerUtils().uninjectPlayerNow(e.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onMove(final PlayerMoveEvent e) {
|
||||
BukkitMoveEvent moveEvent = new BukkitMoveEvent(e);
|
||||
getAPI().getEventManager().callEvent(moveEvent);
|
||||
e.setCancelled(moveEvent.isCancelled());
|
||||
packetHandlerInternal.ejectPlayer(e.getPlayer());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents;
|
||||
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class PacketEventsPlugin extends JavaPlugin {
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
if (PacketEvents.get() == null) {
|
||||
PacketEvents.create(this);
|
||||
PacketEvents.get().load();
|
||||
PacketEvents.get().init(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
if (PacketEvents.get() != null) {
|
||||
PacketEvents.get().terminate();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package io.github.retrooper.packetevents.annotations;
|
||||
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* Is for sure not null.
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface NotNull {
|
||||
|
||||
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package io.github.retrooper.packetevents.annotations;
|
||||
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* Could be null.
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Nullable {
|
||||
|
||||
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package io.github.retrooper.packetevents.annotations;
|
||||
|
||||
import io.github.retrooper.packetevents.enums.EventSynchronization;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
/**
|
||||
* Just like Bukkit's @EventHandler, but for PacketEvents' custom event system.
|
||||
* Make sure your class implements the PacketListener interface, and is registered when annotating your method with this annotation!
|
||||
*/
|
||||
public @interface PacketHandler {
|
||||
EventSynchronization synchronization() default EventSynchronization.NORMAL;
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
package io.github.retrooper.packetevents.api;
|
||||
|
||||
import io.github.retrooper.packetevents.event.manager.EventManager;
|
||||
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();
|
||||
|
||||
/**
|
||||
* Not thread safe
|
||||
* Preciser than #currentMillis()
|
||||
* Expensive
|
||||
* Returns crazy values when you change system time
|
||||
*
|
||||
* @return {@link System#nanoTime()} / 1000000(1 million)
|
||||
*/
|
||||
public long currentPreciseMillis() {
|
||||
return System.nanoTime() / 1000000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Thread safe
|
||||
* Less precise compared to #currentPreciseMillis()
|
||||
* Cheap
|
||||
* Doesn't break when system time is changed
|
||||
*
|
||||
* @return {@link System#currentTimeMillis()}
|
||||
*/
|
||||
public long currentMillis() {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all utilities to do with the player
|
||||
*
|
||||
* @return Player Utilities
|
||||
*/
|
||||
public PlayerUtils getPlayerUtils() {
|
||||
return playerUtils;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all utilities to do with the server
|
||||
*
|
||||
* @return Server Utilities
|
||||
*/
|
||||
public ServerUtils getServerUtils() {
|
||||
return serverUtils;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the event manager
|
||||
* Used to call events, register and unregister listeners
|
||||
*
|
||||
* @return PacketEvents' event manager
|
||||
*/
|
||||
public EventManager getEventManager() {
|
||||
return eventManager;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
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_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;
|
||||
|
||||
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();
|
||||
}
|
||||
final ClientVersion lookedUp = VERSION_LOOKUP.get(protocolVersion);
|
||||
if (lookedUp != null) {
|
||||
return lookedUp;
|
||||
}
|
||||
return protocolVersion > 737 ? HIGHER_THAN_V_1_16_2 : INVALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the client's version is more up to date than the argument passed version
|
||||
*
|
||||
* @param version
|
||||
* @return
|
||||
*/
|
||||
public boolean isHigherThan(final ClientVersion version) {
|
||||
if (this == version) return false;
|
||||
return !isLowerThan(version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the client's version is more outdated than the argument passed version
|
||||
*
|
||||
* @param version
|
||||
* @return
|
||||
*/
|
||||
public boolean isLowerThan(final ClientVersion version) {
|
||||
if (this == version) return false;
|
||||
final int len = ClientVersion.values().length;
|
||||
for (byte i = 0; i < len; i++) {
|
||||
final ClientVersion v = ClientVersion.values()[i];
|
||||
if (v == this) {
|
||||
return true;
|
||||
} else if (v == version) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package io.github.retrooper.packetevents.enums;
|
||||
|
||||
public enum Direction {
|
||||
DOWN, UP, NORTH, SOUTH, WEST, EAST, NORTH_EAST,
|
||||
NORTH_WEST, SOUTH_EAST,
|
||||
SOUTH_WEST, WEST_NORTH_WEST,
|
||||
NORTH_NORTH_WEST, NORTH_NORTH_EAST,
|
||||
EAST_NORTH_EAST, EAST_SOUTH_EAST,
|
||||
SOUTH_SOUTH_EAST, SOUTH_SOUTH_WEST,
|
||||
WEST_SOUTH_WEST, SELF, NULL;
|
||||
|
||||
public static Direction get(final int i) {
|
||||
return values()[i];
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
package io.github.retrooper.packetevents.enums;
|
||||
|
||||
public enum EventSynchronization {
|
||||
NORMAL, FORCE_SYNC, FORCE_ASYNC
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
package io.github.retrooper.packetevents.enums;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
/**
|
||||
* @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, v_1_16_1, v_1_16_2,
|
||||
ERROR, EMPTY;
|
||||
|
||||
private static final String nmsVersionSuffix = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
|
||||
public static ServerVersion[] reversedValues;
|
||||
private static ServerVersion cachedVersion;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public static ServerVersion getVersion() {
|
||||
if (cachedVersion == null) {
|
||||
cachedVersion = getVers();
|
||||
}
|
||||
return cachedVersion;
|
||||
}
|
||||
|
||||
|
||||
public static ServerVersion[] reverse(final ServerVersion[] arr) {
|
||||
ServerVersion[] array = arr.clone();
|
||||
if (array == null) {
|
||||
return null;
|
||||
}
|
||||
int i = 0;
|
||||
int j = array.length - 1;
|
||||
ServerVersion tmp;
|
||||
while (j > i) {
|
||||
tmp = array[j];
|
||||
array[j] = array[i];
|
||||
array[i] = tmp;
|
||||
j--;
|
||||
i++;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public static String getNmsSuffix() {
|
||||
return nmsVersionSuffix;
|
||||
}
|
||||
|
||||
public static String getNMSDirectory() {
|
||||
return "net.minecraft.server." + getNmsSuffix();
|
||||
}
|
||||
|
||||
public static String getOBCDirectory() {
|
||||
return "org.bukkit.craftbukkit." + getNmsSuffix();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the current version is more up to date than the argument passed version
|
||||
*
|
||||
* @param version
|
||||
* @return
|
||||
*/
|
||||
public boolean isHigherThan(final ServerVersion version) {
|
||||
if (this == version) return false;
|
||||
return !isLowerThan(version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the current version is more outdated than the argument passed version
|
||||
*
|
||||
* @param version
|
||||
* @return
|
||||
*/
|
||||
public boolean isLowerThan(final ServerVersion version) {
|
||||
if (this == version) return false;
|
||||
final int len = ServerVersion.values().length;
|
||||
for (byte i = 0; i < len; i++) {
|
||||
final ServerVersion v = ServerVersion.values()[i];
|
||||
if (v == this) {
|
||||
return true;
|
||||
} else if (v == version) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package io.github.retrooper.packetevents.enums;
|
||||
|
||||
public enum SystemOS {
|
||||
WINDOWS, MACOS, LINUX, OTHER;
|
||||
|
||||
private static SystemOS value;
|
||||
|
||||
private static SystemOS getOS() {
|
||||
final String os = System.getProperty("os.name");
|
||||
for (final String osName : getOperatingSystemNames()) {
|
||||
if (os.toLowerCase().contains(osName.toLowerCase())) {
|
||||
return SystemOS.valueOf(osName);
|
||||
}
|
||||
}
|
||||
return OTHER;
|
||||
}
|
||||
|
||||
public static SystemOS getOperatingSystem() {
|
||||
if (value == null) {
|
||||
value = getOS();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static String[] getOperatingSystemNames() {
|
||||
final String[] arr = new String[values().length - 1];
|
||||
for (int i = 0; i < values().length - 1; i++) {
|
||||
arr[i] = values()[i].name();
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
}
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
package io.github.retrooper.packetevents.enums.minecraft;
|
||||
|
||||
public enum EntityAnimationType {
|
||||
SWING_MAIN_ARM, DAMAGE, LEAVE_BED, SWING_OFFHAND, CRITICAL_EFFECT, MAGIC_CRITICAL_EFFECT;
|
||||
|
||||
public static final EntityAnimationType get(final int i) {
|
||||
return values()[i];
|
||||
}
|
||||
|
||||
public final int getIndex() {
|
||||
for (int i = 0; i < values().length; i++) {
|
||||
final EntityAnimationType curType = values()[0];
|
||||
if (curType == this) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package io.github.retrooper.packetevents.enums.minecraft;
|
||||
|
||||
public enum EntityUseAction {
|
||||
INTERACT, INTERACT_AT, ATTACK, INVALID;
|
||||
|
||||
public static EntityUseAction get(final int i) {
|
||||
return values()[i];
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
package io.github.retrooper.packetevents.enums.minecraft;
|
||||
|
||||
public enum Hand {
|
||||
MAIN_HAND,
|
||||
OFF_HAND
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
package io.github.retrooper.packetevents.enums.minecraft;
|
||||
|
||||
public enum PlayerAction {
|
||||
START_SNEAKING,
|
||||
|
||||
STOP_SNEAKING,
|
||||
|
||||
STOP_SLEEPING,
|
||||
|
||||
START_SPRINTING,
|
||||
|
||||
STOP_SPRINTING,
|
||||
|
||||
START_RIDING_JUMP,
|
||||
|
||||
STOP_RIDING_JUMP,
|
||||
|
||||
OPEN_INVENTORY,
|
||||
|
||||
START_FALL_FLYING;
|
||||
|
||||
public static PlayerAction get(final int i) {
|
||||
return values()[i];
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
for (int i = 0; i < values().length; i++) {
|
||||
final PlayerAction action = values()[i];
|
||||
if (action == this) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public enum UpdatedPlayerAction {
|
||||
PRESS_SHIFT_KEY, RELEASE_SHIFT_KEY, STOP_SLEEPING, START_SPRINTING, STOP_SPRINTING, START_RIDING_JUMP, STOP_RIDING_JUMP, OPEN_INVENTORY, START_FALL_FLYING;
|
||||
|
||||
public static UpdatedPlayerAction get(final int index) {
|
||||
for (int i = 0; i < index + 1; i++) {
|
||||
final UpdatedPlayerAction action = values()[i];
|
||||
if (i == index) {
|
||||
return action;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
for (int i = 0; i < values().length; i++) {
|
||||
final UpdatedPlayerAction action = values()[i];
|
||||
if (action == this) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package io.github.retrooper.packetevents.enums.minecraft;
|
||||
|
||||
public enum PlayerDigType {
|
||||
|
||||
START_DESTROY_BLOCK,
|
||||
|
||||
ABORT_DESTROY_BLOCK,
|
||||
|
||||
STOP_DESTROY_BLOCK,
|
||||
|
||||
DROP_ALL_ITEMS,
|
||||
|
||||
DROP_ITEM,
|
||||
|
||||
RELEASE_USE_ITEM,
|
||||
|
||||
SWAP_HELD_ITEMS,
|
||||
|
||||
SWAP_ITEM_WITH_OFFHAND,
|
||||
|
||||
WRONG_PACKET;
|
||||
|
||||
public static PlayerDigType get(final int i) {
|
||||
return values()[i];
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package io.github.retrooper.packetevents.enums.minecraft;
|
||||
|
||||
public enum PlayerInfoAction {
|
||||
ADD_PLAYER, UPDATE_GAME_MODE, UPDATE_LATENCY, UPDATE_DISPLAY_NAME, REMOVE_PLAYER;
|
||||
|
||||
PlayerInfoAction() {
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,61 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event;
|
||||
|
||||
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.CallableEvent;
|
||||
|
||||
public class PacketEvent {
|
||||
protected static ServerVersion version = ServerVersion.getVersion();
|
||||
/**
|
||||
* An event in both of PacketEvents' event systems.
|
||||
*
|
||||
* @author retrooper
|
||||
* @since 1.2.6
|
||||
*/
|
||||
public abstract class PacketEvent implements CallableEvent {
|
||||
private long timestamp = System.currentTimeMillis();
|
||||
|
||||
/**
|
||||
* Timestamp of the packet
|
||||
* Timestamp of when the PacketEvent was created.
|
||||
* Basically timestamp of the packet.
|
||||
*
|
||||
* @return
|
||||
* @return Packet timestamp in milliseconds.
|
||||
*/
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(long timestamp) {
|
||||
/**
|
||||
* Setter for the timestamp.
|
||||
*
|
||||
* @param timestamp Packet timestamp in milliseconds.
|
||||
*/
|
||||
public void setTimestamp(final long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
public void callPacketEvent(final PacketListenerDynamic listener) {
|
||||
listener.onPacketEvent(this);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,38 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event;
|
||||
|
||||
/**
|
||||
* The legacy Packet listener.
|
||||
* Implement this interface in your listener if you are using the legacy event system.
|
||||
*
|
||||
* @author retrooper
|
||||
* @see PacketListenerDynamic
|
||||
* @since 1.2.6
|
||||
* @deprecated There is a new and better listener for the new event system.
|
||||
*/
|
||||
@Deprecated
|
||||
public interface PacketListener {
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event;
|
||||
|
||||
import io.github.retrooper.packetevents.event.impl.*;
|
||||
import io.github.retrooper.packetevents.event.priority.PacketEventPriority;
|
||||
|
||||
/**
|
||||
* Dynamic packet event listener.
|
||||
* Implement whatever event method you need.
|
||||
* Nothing will happen if you don't implement an event method.
|
||||
*
|
||||
* @author retrooper
|
||||
* @since 1.7.7
|
||||
*/
|
||||
public abstract class PacketListenerDynamic {
|
||||
private final PacketEventPriority priority;
|
||||
|
||||
public PacketListenerDynamic(final PacketEventPriority priority) {
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
public PacketListenerDynamic() {
|
||||
this(PacketEventPriority.NORMAL);
|
||||
}
|
||||
|
||||
public PacketEventPriority getPriority() {
|
||||
return priority;
|
||||
}
|
||||
|
||||
public void onPacketStatusReceive(PacketStatusReceiveEvent event) {
|
||||
|
||||
}
|
||||
|
||||
public void onPacketStatusSend(PacketStatusSendEvent event) {
|
||||
}
|
||||
|
||||
public void onPacketLoginReceive(PacketLoginReceiveEvent event) {
|
||||
}
|
||||
|
||||
public void onPacketLoginSend(PacketLoginSendEvent event) {
|
||||
|
||||
}
|
||||
|
||||
public void onPacketPlayReceive(PacketPlayReceiveEvent event) {
|
||||
}
|
||||
|
||||
public void onPacketPlaySend(PacketPlaySendEvent event) {
|
||||
}
|
||||
|
||||
public void onPostPacketPlayReceive(PostPacketPlayReceiveEvent event) {
|
||||
}
|
||||
|
||||
public void onPostPacketPlaySend(PostPacketPlaySendEvent event) {
|
||||
}
|
||||
|
||||
public void onPostPlayerInject(PostPlayerInjectEvent event) {
|
||||
|
||||
}
|
||||
|
||||
public void onPlayerInject(PlayerInjectEvent event) {
|
||||
}
|
||||
|
||||
public void onPlayerEject(PlayerEjectEvent event) {
|
||||
}
|
||||
|
||||
public void onPacketEvent(PacketEvent event) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* This is what you override your event listener with on the old event system.
|
||||
* You can specify the event priority of the listener method.
|
||||
*
|
||||
* @author retrooper
|
||||
* @since 1.0
|
||||
* @deprecated Was used for the old event system, the new one doesn't need this anymore.
|
||||
*/
|
||||
@Target({ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Deprecated
|
||||
public @interface PacketHandler {
|
||||
byte priority() default 2; //NORMAL priority value
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.eventtypes;
|
||||
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import io.github.retrooper.packetevents.event.PacketListenerDynamic;
|
||||
import io.github.retrooper.packetevents.event.impl.PacketPlayReceiveEvent;
|
||||
|
||||
/**
|
||||
* The {@link PacketEvent} implements this interface.
|
||||
* Every inbuilt event should implement the {@link #call(PacketListenerDynamic)} method.
|
||||
* If you are making a custom event, don't implement this.
|
||||
* The {@link PacketListenerDynamic#onPacketEvent(PacketEvent)} method is called for every event,
|
||||
* including custom events.
|
||||
*
|
||||
* @author retrooper
|
||||
* @see PacketPlayReceiveEvent
|
||||
* @since 1.8
|
||||
*/
|
||||
public interface CallableEvent {
|
||||
void call(PacketListenerDynamic listener);
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.eventtypes;
|
||||
|
||||
import io.github.retrooper.packetevents.event.impl.PacketPlayReceiveEvent;
|
||||
|
||||
/**
|
||||
* Every event that supports cancellation should implement this interface.
|
||||
* PacketEvents' event system lets the highest priority listener be have the highest priority
|
||||
* in deciding whether the event will cancel.
|
||||
* This means an event with a lower priority than the higher priority one would not be able to decide.
|
||||
* Cancelling the event means the action assosiated with the event will be cancelled.
|
||||
* For example, cancelling the {@link PacketPlayReceiveEvent}
|
||||
* will prevent minecraft from processing the incoming packet.
|
||||
*
|
||||
* @author retrooper
|
||||
* @see PacketPlayReceiveEvent
|
||||
* @since 1.7
|
||||
*/
|
||||
public interface CancellableEvent {
|
||||
|
||||
/**
|
||||
* This method returns if the event will be cancelled.
|
||||
*
|
||||
* @return Will the event be cancelled.
|
||||
*/
|
||||
boolean isCancelled();
|
||||
|
||||
/**
|
||||
* Cancel or proceed with the event.
|
||||
*
|
||||
* @param val Is the event cancelled
|
||||
*/
|
||||
void setCancelled(boolean val);
|
||||
|
||||
/**
|
||||
* Cancel the event.
|
||||
* You can achieve the same result by just using {@link #setCancelled(boolean)}
|
||||
*/
|
||||
@Deprecated
|
||||
void cancel();
|
||||
|
||||
/**
|
||||
* Uncancel the event.
|
||||
* You can achieve the same result by just using {@link #setCancelled(boolean)}
|
||||
*/
|
||||
@Deprecated
|
||||
void uncancel();
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package io.github.retrooper.packetevents.event.eventtypes;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
public abstract class CancellableNMSPacketEvent extends NMSPacketEvent implements CancellableEvent {
|
||||
private boolean cancelled;
|
||||
|
||||
public CancellableNMSPacketEvent(Object channel, NMSPacket packet) {
|
||||
super(channel, packet);
|
||||
}
|
||||
|
||||
public CancellableNMSPacketEvent(InetSocketAddress address, NMSPacket packet) {
|
||||
super(address, packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
cancelled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uncancel() {
|
||||
cancelled = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean value) {
|
||||
cancelled = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.eventtypes;
|
||||
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import io.github.retrooper.packetevents.packettype.PacketType;
|
||||
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
|
||||
import io.github.retrooper.packetevents.utils.netty.channel.ChannelUtils;
|
||||
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
/**
|
||||
* The {@code NMSPacketEvent} abstract class represents an event that has to do with an actual packet.
|
||||
* Don't mix this up with {@link io.github.retrooper.packetevents.event.PacketEvent}.
|
||||
* The PacketEvent class represents an event that belongs to PacketEvent's packet system.
|
||||
*
|
||||
* @author retrooper
|
||||
* @since 1.8
|
||||
*/
|
||||
public abstract class NMSPacketEvent extends PacketEvent implements CallableEvent {
|
||||
private final InetSocketAddress socketAddress;
|
||||
protected NMSPacket packet;
|
||||
protected boolean cancelled;
|
||||
|
||||
public NMSPacketEvent(Object channel, NMSPacket packet) {
|
||||
this.socketAddress = ChannelUtils.getSocketAddress(channel);
|
||||
this.packet = packet;
|
||||
}
|
||||
|
||||
public NMSPacketEvent(InetSocketAddress address, NMSPacket packet) {
|
||||
this.socketAddress = address;
|
||||
this.packet = packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the associated player's socket address.
|
||||
*
|
||||
* @return Socket address of the associated player.
|
||||
*/
|
||||
public final InetSocketAddress getSocketAddress() {
|
||||
return socketAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the name of the packet.
|
||||
* To get the name of the packet we get the class of the packet and then the name of the class.
|
||||
* See also: {@link Class#getSimpleName()}
|
||||
* We cache the name after the first call to improve performance.
|
||||
* Java 8 does not cache the name.
|
||||
* It is not recommended to call this method unless you NEED it.
|
||||
* If you are comparing packet types, use the {@link PacketType} byte system.
|
||||
* You would only need the packet name if packet type system doesn't contain your desired packet yet.
|
||||
*
|
||||
* @return Name of the packet.
|
||||
*/
|
||||
@Deprecated
|
||||
public final String getPacketName() {
|
||||
return ClassUtil.getClassSimpleName(packet.getRawNMSPacket().getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the NMS packet.
|
||||
*
|
||||
* @return Get NMS packet.
|
||||
*/
|
||||
public final NMSPacket getNMSPacket() {
|
||||
return packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the NMS Packet.
|
||||
*
|
||||
* @param packet NMS Object
|
||||
*/
|
||||
public final void setNMSPacket(NMSPacket packet) {
|
||||
this.packet = packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Packet ID.
|
||||
*
|
||||
* @return Packet ID.
|
||||
*/
|
||||
public abstract byte getPacketId();
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.eventtypes;
|
||||
|
||||
import io.github.retrooper.packetevents.event.impl.PacketPlayReceiveEvent;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* Every event that has an associated player is recommended to implement this interface.
|
||||
*
|
||||
* @author retrooper
|
||||
* @see PacketPlayReceiveEvent
|
||||
* @since 1.6.9
|
||||
*/
|
||||
public interface PlayerEvent {
|
||||
/**
|
||||
* Associated player.
|
||||
*
|
||||
* @return Player.
|
||||
*/
|
||||
Player getPlayer();
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
package io.github.retrooper.packetevents.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
|
||||
public final class BukkitMoveEvent extends PacketEvent {
|
||||
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;
|
||||
this.to = to;
|
||||
this.from = from;
|
||||
}
|
||||
|
||||
public BukkitMoveEvent(final PlayerMoveEvent e) {
|
||||
this.player = e.getPlayer();
|
||||
this.to = e.getTo();
|
||||
this.from = e.getFrom();
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public Location getFrom() {
|
||||
return from;
|
||||
}
|
||||
|
||||
public Location getTo() {
|
||||
return to;
|
||||
}
|
||||
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
public void setCancelled(final boolean val) {
|
||||
this.cancelled = val;
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
setCancelled(true);
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.event.PacketListenerDynamic;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.CancellableNMSPacketEvent;
|
||||
import io.github.retrooper.packetevents.packettype.PacketType;
|
||||
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
/**
|
||||
* The {@code PacketLoginReceiveEvent} event is fired whenever the a LOGIN packet is received from a client.
|
||||
* The {@code PacketLoginReceiveEvent} does not have to do with a bukkit player object due to
|
||||
* the player object being null in this state.
|
||||
* Use the {@link #getSocketAddress()} to identify who sends the packet.
|
||||
*
|
||||
* @author retrooper
|
||||
* @see <a href="https://wiki.vg/Protocol#Login">https://wiki.vg/Protocol#Login</a>
|
||||
* @since 1.8
|
||||
*/
|
||||
public class PacketLoginReceiveEvent extends CancellableNMSPacketEvent {
|
||||
public PacketLoginReceiveEvent(final Object channel, final NMSPacket packet) {
|
||||
super(channel, packet);
|
||||
}
|
||||
|
||||
public PacketLoginReceiveEvent(final InetSocketAddress socketAddress, final NMSPacket packet) {
|
||||
super(socketAddress, packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Each binding in each packet state has their own constants.
|
||||
* Example Usage:
|
||||
* <p>
|
||||
* {@code if (getPacketId() == PacketType.Login.Client.HANDSHAKE) }
|
||||
* </p>
|
||||
*
|
||||
* @return Packet ID.
|
||||
*/
|
||||
@Override
|
||||
public byte getPacketId() {
|
||||
return PacketType.Login.Client.packetIds.getOrDefault(packet.getRawNMSPacket().getClass(), PacketType.INVALID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void call(PacketListenerDynamic listener) {
|
||||
listener.onPacketLoginReceive(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.event.PacketListenerDynamic;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.CancellableNMSPacketEvent;
|
||||
import io.github.retrooper.packetevents.packettype.PacketType;
|
||||
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
/**
|
||||
* The {@code PacketLoginSendEvent} event is fired whenever the a LOGIN packet is being planned to be sent to the client.
|
||||
* The {@code PacketLoginSendEvent} does not have to do with a bukkit player object due to
|
||||
* the player object being null in this state.
|
||||
* Use the {@link #getSocketAddress()} to identify who sends the packet.
|
||||
*
|
||||
* @author retrooper
|
||||
* @see <a href="https://wiki.vg/Protocol#Login">https://wiki.vg/Protocol#Login</a>
|
||||
* @since 1.8
|
||||
*/
|
||||
public class PacketLoginSendEvent extends CancellableNMSPacketEvent {
|
||||
public PacketLoginSendEvent(Object channel, NMSPacket packet) {
|
||||
super(channel, packet);
|
||||
}
|
||||
|
||||
public PacketLoginSendEvent(InetSocketAddress address, NMSPacket packet) {
|
||||
super(address, packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getPacketId() {
|
||||
return PacketType.Login.Server.packetIds.getOrDefault(packet.getRawNMSPacket().getClass(), PacketType.INVALID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void call(PacketListenerDynamic listener) {
|
||||
listener.onPacketLoginSend(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.event.PacketListenerDynamic;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.CancellableNMSPacketEvent;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.PlayerEvent;
|
||||
import io.github.retrooper.packetevents.packettype.PacketType;
|
||||
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* The {@code PacketPlayReceiveEvent} event is fired whenever the a PLAY packet is
|
||||
* received from any connected client.
|
||||
* Cancelling this event will result in preventing minecraft from processing the incoming packet.
|
||||
* It would be as if the player never sent the packet from the server's view.
|
||||
*
|
||||
* @author retrooper
|
||||
* @see <a href="https://wiki.vg/Protocol#Play">https://wiki.vg/Protocol#Play</a>
|
||||
* @since 1.2.6
|
||||
*/
|
||||
public final class PacketPlayReceiveEvent extends CancellableNMSPacketEvent implements PlayerEvent {
|
||||
private final Player player;
|
||||
|
||||
public PacketPlayReceiveEvent(final Player player, final Object channel, final NMSPacket packet) {
|
||||
super(channel, packet);
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the bukkit player object of the packet sender.
|
||||
* The player object might be null during early packets.
|
||||
*
|
||||
* @return Packet sender.
|
||||
*/
|
||||
@NotNull
|
||||
@Override
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the socket address of the packet sender.
|
||||
* This address if guaranteed to never be null.
|
||||
* You could use this to identify who is sending packets
|
||||
* whenever the player object is null.
|
||||
*
|
||||
* @return Packet sender's socket address.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Each binding in each packet state has their own constants.
|
||||
* Example Usage:
|
||||
* <p>
|
||||
* {@code if (getPacketId() == PacketType.Play.Client.USE_ENTITY) }
|
||||
* </p>
|
||||
*
|
||||
* @return Packet ID.
|
||||
*/
|
||||
@Override
|
||||
public byte getPacketId() {
|
||||
return PacketType.Play.Client.packetIds.getOrDefault(packet.getRawNMSPacket().getClass(), PacketType.INVALID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void call(PacketListenerDynamic listener) {
|
||||
listener.onPacketPlayReceive(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.event.PacketListenerDynamic;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.CancellableNMSPacketEvent;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.PlayerEvent;
|
||||
import io.github.retrooper.packetevents.packettype.PacketType;
|
||||
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* The {@code PacketPlaySendEvent} event is fired whenever the a PLAY packet is about to be sent.
|
||||
* Cancelling this event will result in preventing minecraft from sending the packet.
|
||||
* The player won't receive the packet if you cancel it.
|
||||
*
|
||||
* @author retrooper
|
||||
* @see <a href="https://wiki.vg/Protocol#Play">https://wiki.vg/Protocol#Play</a>
|
||||
* @since 1.2.6
|
||||
*/
|
||||
public final class PacketPlaySendEvent extends CancellableNMSPacketEvent implements PlayerEvent {
|
||||
private final Player player;
|
||||
|
||||
public PacketPlaySendEvent(final Player player, final Object channel, final NMSPacket packet) {
|
||||
super(channel, packet);
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the bukkit player object of the packet receiver.
|
||||
* The player object might be null during early packets.
|
||||
*
|
||||
* @return Packet receiver.
|
||||
*/
|
||||
@NotNull
|
||||
@Override
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Each binding in each packet state has their own constants.
|
||||
* Example Usage:
|
||||
* <p>
|
||||
* {@code if (getPacketId() == PacketType.Play.Server.KEEP_ALIVE) }
|
||||
* </p>
|
||||
*
|
||||
* @return Packet ID.
|
||||
*/
|
||||
@Override
|
||||
public byte getPacketId() {
|
||||
return PacketType.Play.Server.packetIds.getOrDefault(packet.getRawNMSPacket().getClass(), PacketType.INVALID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void call(PacketListenerDynamic listener) {
|
||||
listener.onPacketPlaySend(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
package io.github.retrooper.packetevents.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import io.github.retrooper.packetevents.packet.PacketType;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public final class PacketReceiveEvent extends PacketEvent {
|
||||
private final Player player;
|
||||
private final Object packet;
|
||||
private boolean cancelled;
|
||||
|
||||
public PacketReceiveEvent(final Player player, final Object packet) {
|
||||
this.player = player;
|
||||
this.packet = packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player sending the packet
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the packet's name (NMS packet class simple name).
|
||||
* Deprecated, it is recommended not to use this for performance reasons.
|
||||
*/
|
||||
@Deprecated
|
||||
public String getPacketName() {
|
||||
return this.packet.getClass().getSimpleName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the NMS packet object
|
||||
*
|
||||
* @return packet object
|
||||
*/
|
||||
public Object getNMSPacket() {
|
||||
return this.packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the class of the NMS packet object
|
||||
* Deprecated, as it is useless, rather use getNMSPacket().getClass()
|
||||
*
|
||||
* @return packet object class
|
||||
*/
|
||||
@Deprecated
|
||||
public Class<?> getNMSPacketClass() {
|
||||
return packet.getClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID of the packet
|
||||
*
|
||||
* @return packet id
|
||||
*/
|
||||
public byte getPacketId() {
|
||||
return PacketType.Client.packetIds.getOrDefault(packet.getClass(), (byte) -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the packet has been cancelled
|
||||
*
|
||||
* @return cancelled
|
||||
*/
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel the packet
|
||||
*
|
||||
* @param cancelled
|
||||
*/
|
||||
public void setCancelled(boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
package io.github.retrooper.packetevents.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import io.github.retrooper.packetevents.packet.PacketType;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
|
||||
public final class PacketSendEvent extends PacketEvent {
|
||||
private final Player player;
|
||||
private final Object packet;
|
||||
private boolean cancelled;
|
||||
|
||||
public PacketSendEvent(final Player player, final Object packet) {
|
||||
this.player = player;
|
||||
this.packet = packet;
|
||||
this.cancelled = false;
|
||||
}
|
||||
|
||||
|
||||
public Player getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the packet's name (NMS packet class simple name)
|
||||
* Deprecated, it is recommended not to use this for performance reasons.
|
||||
*/
|
||||
@Deprecated
|
||||
public String getPacketName() {
|
||||
return this.packet.getClass().getSimpleName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ID of the packet
|
||||
*
|
||||
* @return packet id
|
||||
*/
|
||||
public byte getPacketId() {
|
||||
return PacketType.Server.packetIds.getOrDefault(packet.getClass(), (byte) -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the NMS packet object
|
||||
*
|
||||
* @return packet object
|
||||
*/
|
||||
public Object getNMSPacket() {
|
||||
return this.packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the class of the NMS packet object.
|
||||
* Deprecated because it is useless, rather use getNMSPacket().getClass().
|
||||
*
|
||||
* @return packet object class
|
||||
*/
|
||||
@Deprecated
|
||||
public Class<?> getNMSPacketClass() {
|
||||
return packet.getClass();
|
||||
}
|
||||
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
public void setCancelled(boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
}
|
||||
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.event.PacketListenerDynamic;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.CancellableNMSPacketEvent;
|
||||
import io.github.retrooper.packetevents.packettype.PacketType;
|
||||
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
/**
|
||||
* The {@code PacketStatusReceiveEvent} event is fired whenever the server receives a STATUS packet from a client.
|
||||
* The {@code PacketStatusSendEvent} does not have to do with a bukkit player object due to
|
||||
* the player object being null in this state.
|
||||
* Use the {@link #getSocketAddress()} to identify who sends the packet.
|
||||
*
|
||||
* @author retrooper
|
||||
* @see <a href="https://wiki.vg/Protocol#Status">https://wiki.vg/Protocol#Status</a>
|
||||
* @since 1.8
|
||||
*/
|
||||
public class PacketStatusReceiveEvent extends CancellableNMSPacketEvent {
|
||||
public PacketStatusReceiveEvent(final Object channel, final NMSPacket packet) {
|
||||
super(channel, packet);
|
||||
}
|
||||
|
||||
public PacketStatusReceiveEvent(final InetSocketAddress socketAddress, final NMSPacket packet) {
|
||||
super(socketAddress, packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Each binding in each packet state has their own constants.
|
||||
* Example Usage:
|
||||
* <p>
|
||||
* {@code if (getPacketId() == PacketType.Status.Client.PING) }
|
||||
* </p>
|
||||
*
|
||||
* @return Packet ID.
|
||||
*/
|
||||
@Override
|
||||
public byte getPacketId() {
|
||||
return PacketType.Status.Client.packetIds.getOrDefault(packet.getRawNMSPacket().getClass(), PacketType.INVALID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void call(PacketListenerDynamic listener) {
|
||||
listener.onPacketStatusReceive(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.event.PacketListenerDynamic;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.CancellableEvent;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.CancellableNMSPacketEvent;
|
||||
import io.github.retrooper.packetevents.packettype.PacketType;
|
||||
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
/**
|
||||
* The {@code PacketStatusSendEvent} event is fired whenever the server wants to send a STATUS packet to the client.
|
||||
* This class implements {@link CancellableEvent}.
|
||||
* The {@code PacketStatusSendEvent} does not have to do with a bukkit player object due to
|
||||
* the player object being null in this state.
|
||||
* Use the {@link #getSocketAddress()} to identify who sends the packet.
|
||||
*
|
||||
* @author retrooper
|
||||
* @see <a href="https://wiki.vg/Protocol#Status">https://wiki.vg/Protocol#Status</a>
|
||||
* @since 1.8
|
||||
*/
|
||||
public class PacketStatusSendEvent extends CancellableNMSPacketEvent {
|
||||
public PacketStatusSendEvent(Object channel, NMSPacket packet) {
|
||||
super(channel, packet);
|
||||
}
|
||||
|
||||
public PacketStatusSendEvent(InetSocketAddress address, NMSPacket packet) {
|
||||
super(address, packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Each binding in each packet state has their own constants.
|
||||
* Example Usage:
|
||||
* <p>
|
||||
* {@code if (getPacketId() == PacketType.Status.Server.PONG) }
|
||||
* </p>
|
||||
*
|
||||
* @return Packet ID.
|
||||
*/
|
||||
@Override
|
||||
public byte getPacketId() {
|
||||
return PacketType.Status.Server.packetIds.getOrDefault(packet.getRawNMSPacket().getClass(), PacketType.INVALID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void call(PacketListenerDynamic listener) {
|
||||
listener.onPacketStatusSend(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import io.github.retrooper.packetevents.event.PacketListenerDynamic;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.CancellableEvent;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.PlayerEvent;
|
||||
import io.github.retrooper.packetevents.settings.PacketEventsSettings;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* The {@code PlayerEjectEvent} event is fired whenever a player is ejected.
|
||||
* A player is ejected by PacketEvents whenever they quit the server.
|
||||
* This class implements {@link CancellableEvent} and {@link PlayerEvent}.
|
||||
*
|
||||
* @author retrooper
|
||||
* @see <a href="https://github.com/retrooper/packetevents/blob/dev/src/main/java/io/github/retrooper/packetevents/handler/PacketHandlerInternal.java">https://github.com/retrooper/packetevents/blob/dev/src/main/java/io/github/retrooper/packetevents/handler/PacketHandlerInternal.java</a>
|
||||
* @since 1.6.9
|
||||
*/
|
||||
public final class PlayerEjectEvent extends PacketEvent implements CancellableEvent, PlayerEvent {
|
||||
private final Player player;
|
||||
private final boolean async;
|
||||
private boolean cancelled;
|
||||
|
||||
public PlayerEjectEvent(final Player player, final boolean isAsync) {
|
||||
this.player = player;
|
||||
this.async = isAsync;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
cancelled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uncancel() {
|
||||
cancelled = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean value) {
|
||||
cancelled = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the bukkit player object of the player being ejected.
|
||||
* The player object is guaranteed to NOT be null.
|
||||
*
|
||||
* @return Ejected player.
|
||||
*/
|
||||
@NotNull
|
||||
@Override
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns if the event has been called asynchronously.
|
||||
* If the {@link PacketEventsSettings#shouldEjectAsync()} is enabled, the event will be called asynchronously
|
||||
* and the player will be ejected asynchronously.
|
||||
* The {@link PacketEventsSettings} can be accessed here:
|
||||
*
|
||||
* @return Is the ejection asynchronous.
|
||||
* @see PacketEvents#getSettings()
|
||||
*/
|
||||
public boolean isAsync() {
|
||||
return async;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void call(PacketListenerDynamic listener) {
|
||||
listener.onPlayerEject(this);
|
||||
}
|
||||
}
|
||||
@@ -1,29 +1,120 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import io.github.retrooper.packetevents.event.PacketListenerDynamic;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.CancellableEvent;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.PlayerEvent;
|
||||
import io.github.retrooper.packetevents.settings.PacketEventsSettings;
|
||||
import io.github.retrooper.packetevents.utils.netty.channel.ChannelUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public final class PlayerInjectEvent extends PacketEvent {
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
/**
|
||||
* The {@code PlayerInjectEvent} event is fired whenever a player is injected.
|
||||
* A player is injected by PacketEvents whenever they join the server.
|
||||
* This class implements {@link CancellableEvent} and {@link PlayerEvent}.
|
||||
*
|
||||
* @author retrooper
|
||||
* @see <a href="https://github.com/retrooper/packetevents/blob/dev/src/main/java/io/github/retrooper/packetevents/handler/PacketHandlerInternal.java">https://github.com/retrooper/packetevents/blob/dev/src/main/java/io/github/retrooper/packetevents/handler/PacketHandlerInternal.java</a>
|
||||
* @since 1.6.9
|
||||
*/
|
||||
public final class PlayerInjectEvent extends PacketEvent implements CancellableEvent, PlayerEvent {
|
||||
private final Player player;
|
||||
private final InetSocketAddress address;
|
||||
private final boolean async;
|
||||
private boolean cancelled;
|
||||
|
||||
public PlayerInjectEvent(final Player player) {
|
||||
public PlayerInjectEvent(final Player player, final boolean isAsync) {
|
||||
this.player = player;
|
||||
this.address = ChannelUtils.getSocketAddress(PacketEvents.get().packetHandlerInternal.getChannel(player));
|
||||
this.async = isAsync;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
cancelled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uncancel() {
|
||||
cancelled = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
public void setCancelled(boolean cancelled) {
|
||||
this.cancelled = cancelled;
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
setCancelled(true);
|
||||
@Override
|
||||
public void setCancelled(boolean value) {
|
||||
cancelled = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the bukkit player object of the player being injected.
|
||||
* This player might not be fully initialized.
|
||||
*
|
||||
* @return Injected Player.
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the socket address injecting player.
|
||||
*
|
||||
* @return Socket address of the injecting player.
|
||||
*/
|
||||
@NotNull
|
||||
public InetSocketAddress getSocketAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns if the event has been called asynchronously.
|
||||
* If the {@link PacketEventsSettings#shouldInjectAsync()} is enabled, the event will be called asynchronously
|
||||
* and the player will be injected asynchronously.
|
||||
* The {@link PacketEventsSettings} can be accessed here:
|
||||
*
|
||||
* @return Is the injection asynchronous.
|
||||
* @see PacketEvents#getSettings()
|
||||
*/
|
||||
public boolean isAsync() {
|
||||
return async;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void call(PacketListenerDynamic listener) {
|
||||
listener.onPlayerInject(this);
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
package io.github.retrooper.packetevents.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public final class PlayerUninjectEvent extends PacketEvent {
|
||||
private final Player player;
|
||||
private final boolean sync;
|
||||
private boolean cancelled;
|
||||
|
||||
@Deprecated
|
||||
public PlayerUninjectEvent(final Player player, @Deprecated final boolean sync) {
|
||||
this.player = player;
|
||||
this.sync = sync;
|
||||
}
|
||||
|
||||
public PlayerUninjectEvent(final Player player) {
|
||||
this.player = player;
|
||||
this.sync = true;
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
setCancelled(true);
|
||||
}
|
||||
|
||||
public boolean isCancelled() {
|
||||
return this.cancelled;
|
||||
}
|
||||
|
||||
public void setCancelled(final boolean val) {
|
||||
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
|
||||
* @deprecated because it is unneeded
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean isSync() {
|
||||
return sync;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.event.PacketListenerDynamic;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.NMSPacketEvent;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.PlayerEvent;
|
||||
import io.github.retrooper.packetevents.packettype.PacketType;
|
||||
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* The {@code PostPacketPlayReceiveEvent} event is fired after minecraft processes
|
||||
* a PLAY server-bound packet.
|
||||
* You cannot cancel this event since minecraft already processed/is processing this packet.
|
||||
* If the incoming packet was cancelled, resulting in it not being processed by minecraft,
|
||||
* this event won't be called.
|
||||
* This event assures you that the {@link PacketPlayReceiveEvent} event wasn't cancelled.
|
||||
*
|
||||
* @author retrooper
|
||||
* @see <a href="https://wiki.vg/Protocol#Serverbound_4">https://wiki.vg/Protocol#Serverbound_4</a>
|
||||
* @since 1.7
|
||||
*/
|
||||
public class PostPacketPlayReceiveEvent extends NMSPacketEvent implements PlayerEvent {
|
||||
private final Player player;
|
||||
|
||||
public PostPacketPlayReceiveEvent(final Player player, final Object channel, final NMSPacket packet) {
|
||||
super(channel, packet);
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the bukkit player object of the packet sender.
|
||||
* The player object might be null during early packets.
|
||||
*
|
||||
* @return Packet sender.
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Each binding in each packet state has their own constants.
|
||||
* Example Usage:
|
||||
* <p>
|
||||
* {@code if (getPacketId() == PacketType.Play.Client.ARM_ANIMATION) }
|
||||
* </p>
|
||||
*
|
||||
* @return Packet ID.
|
||||
*/
|
||||
@Override
|
||||
public byte getPacketId() {
|
||||
return PacketType.Play.Client.packetIds.getOrDefault(packet.getRawNMSPacket().getClass(), PacketType.INVALID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void call(PacketListenerDynamic listener) {
|
||||
listener.onPostPacketPlayReceive(this);
|
||||
}
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.event.PacketListenerDynamic;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.NMSPacketEvent;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.PlayerEvent;
|
||||
import io.github.retrooper.packetevents.packettype.PacketType;
|
||||
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* The {@code PostPacketPlaySendEvent} event is fired after minecraft processes
|
||||
* a PLAY client-bound packet.
|
||||
* You cannot cancel this event since minecraft already processed this packet.
|
||||
* If the incoming packet was cancelled, resulting in it not being processed by minecraft,
|
||||
* this event won't be called.
|
||||
* This event assures you that the {@link PacketPlaySendEvent} event wasn't cancelled.
|
||||
*
|
||||
* @author retrooper
|
||||
* @see <a href="https://wiki.vg/Protocol#Clientbound_4">https://wiki.vg/Protocol#Clientbound_4</a>
|
||||
* @since 1.7
|
||||
*/
|
||||
public class PostPacketPlaySendEvent extends NMSPacketEvent implements PlayerEvent {
|
||||
private final Player player;
|
||||
|
||||
public PostPacketPlaySendEvent(final Player player, final Object channel, final NMSPacket packet) {
|
||||
super(channel, packet);
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the bukkit player object of the packet sender.
|
||||
* The player object is might be null during early packets.
|
||||
*
|
||||
* @return Packet receiver.
|
||||
*/
|
||||
@Nullable
|
||||
@Override
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Each binding in each packet state has their own constants.
|
||||
* Example Usage:
|
||||
* <p>
|
||||
* {@code if (getPacketId() == PacketType.Play.Server.KEEP_ALIVE) }
|
||||
* </p>
|
||||
*
|
||||
* @return Packet ID.
|
||||
*/
|
||||
@Override
|
||||
public byte getPacketId() {
|
||||
return PacketType.Play.Server.packetIds.getOrDefault(packet.getRawNMSPacket().getClass(), PacketType.INVALID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void call(PacketListenerDynamic listener) {
|
||||
listener.onPostPacketPlaySend(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import io.github.retrooper.packetevents.event.PacketListenerDynamic;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.PlayerEvent;
|
||||
import io.github.retrooper.packetevents.utils.netty.channel.ChannelUtils;
|
||||
import io.github.retrooper.packetevents.utils.player.ClientVersion;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
/**
|
||||
* The {@code PostPlayerInjectEvent} event is fired after a successful injection.
|
||||
* If you are on an older version of PacketEvents DON'T use this to register player data.
|
||||
* This event might be called asynchronously and sometimes synchronously.
|
||||
* Use the {@link #isAsync()} method to figure out if is being called sync or async.
|
||||
* Make sure you do null checks in your packet listeners as this might be called a bit later.
|
||||
* A player is injected by PacketEvents whenever they join the server.
|
||||
*
|
||||
* @author retrooper
|
||||
* @see <a href="https://github.com/retrooper/packetevents/blob/dev/src/main/java/io/github/retrooper/packetevents/handler/PacketHandlerInternal.java">https://github.com/retrooper/packetevents/blob/dev/src/main/java/io/github/retrooper/packetevents/handler/PacketHandlerInternal.java</a>
|
||||
* @since 1.3
|
||||
*/
|
||||
public class PostPlayerInjectEvent extends PacketEvent implements PlayerEvent {
|
||||
private final Player player;
|
||||
private final boolean async;
|
||||
|
||||
public PostPlayerInjectEvent(Player player, boolean async) {
|
||||
this.player = player;
|
||||
this.async = async;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the bukkit player object of the player that has been injected.
|
||||
* The player is guaranteed to not be null.
|
||||
*
|
||||
* @return Injected Player.
|
||||
*/
|
||||
@NotNull
|
||||
@Override
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the cached netty channel of the player.
|
||||
*
|
||||
* @return Netty channel of the injected player.
|
||||
*/
|
||||
@NotNull
|
||||
public Object getChannel() {
|
||||
return PacketEvents.get().packetHandlerInternal.getChannel(player);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public InetSocketAddress getSocketAddress() {
|
||||
return ChannelUtils.getSocketAddress(getChannel());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the ClientVersion of the injected player.
|
||||
*
|
||||
* @return ClientVersion of injected player.
|
||||
* @see ClientVersion
|
||||
*/
|
||||
@Nullable
|
||||
public ClientVersion getClientVersion() {
|
||||
return PacketEvents.get().getPlayerUtils().getClientVersion(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Has the event been called async or sync?
|
||||
*
|
||||
* @return Was the event call in an async context?
|
||||
*/
|
||||
public boolean isAsync() {
|
||||
return async;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void call(PacketListenerDynamic listener) {
|
||||
listener.onPostPlayerInject(this);
|
||||
}
|
||||
}
|
||||
@@ -1,94 +1,173 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.manager;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.annotations.PacketHandler;
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import io.github.retrooper.packetevents.event.PacketListener;
|
||||
import org.bukkit.Bukkit;
|
||||
import io.github.retrooper.packetevents.event.PacketListenerDynamic;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
/**
|
||||
* This is the event manager interface.
|
||||
* Every method is already implemented, we just use this
|
||||
* to have less code duplications.
|
||||
* You can either call event manager methods in the
|
||||
* {@link io.github.retrooper.packetevents.PacketEvents} instance or with an instance of the
|
||||
* {@link PEEventManager} stored in {@link PacketEvents}.
|
||||
*
|
||||
* @author retrooper
|
||||
* @see PacketEvents#getEventManager()
|
||||
* @since 1.0
|
||||
*/
|
||||
public interface EventManager {
|
||||
|
||||
public final class EventManager {
|
||||
private final HashMap<PacketListener, List<Method>> registeredMethods = new HashMap<PacketListener, List<Method>>();
|
||||
/**
|
||||
* Call a packet event.
|
||||
* This will let all listeners(new and deprecated listeners) process the event.
|
||||
* It isn't recommended to use a mix of both listeners(new and deprecated),
|
||||
* but it will work and they are compatible.
|
||||
*
|
||||
* @param event {@link PacketEvent}
|
||||
* @return Same event manager instance.
|
||||
*/
|
||||
default EventManager callEvent(PacketEvent event) {
|
||||
//The dynamic event manager calls the legacy event manager.
|
||||
PEEventManager.EVENT_MANAGER_DYNAMIC.callEvent(event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void callEvent(final PacketEvent e) {
|
||||
for (final PacketListener listener : registeredMethods.keySet()) {
|
||||
//Annotated methods
|
||||
final List<Method> methods = registeredMethods.get(listener);
|
||||
for (final Method method : methods) {
|
||||
final Class<?> parameterType = method.getParameterTypes()[0];
|
||||
if (parameterType.equals(PacketEvent.class)
|
||||
|| parameterType.isInstance(e)) {
|
||||
final PacketHandler annotation = method.getAnnotation(PacketHandler.class);
|
||||
final Runnable invokeMethod = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
method.invoke(listener, e);
|
||||
} catch (IllegalAccessException | InvocationTargetException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
switch (annotation.synchronization()) {
|
||||
case FORCE_ASYNC:
|
||||
Bukkit.getScheduler().runTaskAsynchronously(PacketEvents.getPlugin(), invokeMethod);
|
||||
break;
|
||||
case FORCE_SYNC:
|
||||
Bukkit.getScheduler().runTask(PacketEvents.getPlugin(), invokeMethod);
|
||||
break;
|
||||
default:
|
||||
try {
|
||||
method.invoke(listener, e);
|
||||
} catch (IllegalAccessException | InvocationTargetException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Register a deprecated event listener.
|
||||
* Not recommended to use the deprecated event listener.
|
||||
*
|
||||
* @param listener {@link PacketListener}
|
||||
* @return Same event manager instance.
|
||||
*/
|
||||
@Deprecated
|
||||
default EventManager registerListener(PacketListener listener) {
|
||||
if (listener != null) {
|
||||
PEEventManager.EVENT_MANAGER_LEGACY.registerListener(listener);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public void registerListener(final PacketListener e) {
|
||||
final List<Method> methods = new ArrayList<Method>();
|
||||
for (final Method m : e.getClass().getMethods()) {
|
||||
if (m.isAnnotationPresent(PacketHandler.class)
|
||||
&& m.getParameterTypes().length == 1) {
|
||||
methods.add(m);
|
||||
}
|
||||
}
|
||||
if (!methods.isEmpty()) {
|
||||
registeredMethods.put(e, methods);
|
||||
/**
|
||||
* Register multiple deprecated event listeners with one method.
|
||||
* Not recommended to use the deprecated event listener.
|
||||
*
|
||||
* @param listeners {@link PacketListener}
|
||||
* @return Same event manager instance.
|
||||
*/
|
||||
@Deprecated
|
||||
default EventManager registerListeners(PacketListener... listeners) {
|
||||
PEEventManager.EVENT_MANAGER_LEGACY.registerListeners(listeners);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a deprecated event listener.
|
||||
* Not recommended to use the deprecated event listener.
|
||||
*
|
||||
* @param listener {@link PacketListener}
|
||||
* @return Same event manager instance.
|
||||
*/
|
||||
@Deprecated
|
||||
default EventManager unregisterListener(PacketListener listener) {
|
||||
PEEventManager.EVENT_MANAGER_LEGACY.unregisterListener(listener);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister multiple deprecated event listeners with one method.
|
||||
* Not recommended to use the deprecated event listener.
|
||||
*
|
||||
* @param listeners {@link PacketListener}
|
||||
* @return Same event manager instance.
|
||||
*/
|
||||
@Deprecated
|
||||
default EventManager unregisterListeners(PacketListener... listeners) {
|
||||
PEEventManager.EVENT_MANAGER_LEGACY.unregisterListeners(listeners);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the dynamic event listener.
|
||||
*
|
||||
* @param listener {@link PacketListenerDynamic}
|
||||
* @return Same event manager instance.
|
||||
*/
|
||||
default EventManager registerListener(PacketListenerDynamic listener) {
|
||||
if (listener != null) {
|
||||
PEEventManager.EVENT_MANAGER_DYNAMIC.registerListener(listener);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public void registerListeners(final PacketListener... listeners) {
|
||||
for (final PacketListener listener : listeners) {
|
||||
registerListener(listener);
|
||||
}
|
||||
/**
|
||||
* Register multiple dynamic event listeners with one method.
|
||||
*
|
||||
* @param listeners {@link PacketListenerDynamic}
|
||||
* @return Same event manager instance.
|
||||
*/
|
||||
default EventManager registerListeners(PacketListenerDynamic... listeners) {
|
||||
PEEventManager.EVENT_MANAGER_DYNAMIC.registerListeners(listeners);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void unregisterListener(final PacketListener e) {
|
||||
registeredMethods.remove(e);
|
||||
/**
|
||||
* Unregister the dynamic event listener.
|
||||
*
|
||||
* @param listener {@link PacketListenerDynamic}
|
||||
* @return Same event manager instance.
|
||||
*/
|
||||
default EventManager unregisterListener(PacketListenerDynamic listener) {
|
||||
PEEventManager.EVENT_MANAGER_DYNAMIC.unregisterListener(listener);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void unregisterListeners(final PacketListener... listeners) {
|
||||
for (final PacketListener listener : listeners) {
|
||||
unregisterListener(listener);
|
||||
}
|
||||
/**
|
||||
* Unregister multiple dynamic event listeners with one method.
|
||||
* Recommended to use the dynamic event listener.
|
||||
*
|
||||
* @param listeners {@link PacketListenerDynamic}
|
||||
* @return Same event manager instance.
|
||||
*/
|
||||
default EventManager unregisterListeners(PacketListenerDynamic... listeners) {
|
||||
PEEventManager.EVENT_MANAGER_DYNAMIC.unregisterListeners(listeners);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void unregisterAllListeners() {
|
||||
registeredMethods.clear();
|
||||
}
|
||||
|
||||
public boolean isRegistered(final PacketListener listener) {
|
||||
return registeredMethods.containsKey(listener);
|
||||
/**
|
||||
* Unregister all registered event listeners.
|
||||
* All the deprecated and the dynamic listeners will be unregistered.
|
||||
*
|
||||
* @return Same event manager instance.
|
||||
*/
|
||||
default EventManager unregisterAllListeners() {
|
||||
PEEventManager.EVENT_MANAGER_DYNAMIC.unregisterAllListeners();
|
||||
PEEventManager.EVENT_MANAGER_LEGACY.unregisterAllListeners();
|
||||
return this;
|
||||
}
|
||||
}
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.manager;
|
||||
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import io.github.retrooper.packetevents.event.PacketListenerDynamic;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.CancellableEvent;
|
||||
import io.github.retrooper.packetevents.event.priority.PacketEventPriority;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class EventManagerDynamic {
|
||||
/**
|
||||
* All listeners ordered by their priority.
|
||||
* The most low priority ones are at the begging of the list and the most high priority ones are at the end.
|
||||
*/
|
||||
private final List<PacketListenerDynamic> listeners = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Call the PacketEvent.
|
||||
* This method processes the event on all the registered dynamic packet event listeners.
|
||||
* The {@link PacketEventPriority#LOWEST} prioritized listeners will be processing first,
|
||||
* the {@link PacketEventPriority#MONITOR} will be processing last and can
|
||||
* be the final decider whether the event has been cancelled or not.
|
||||
* This call event also calls the legacy event manager call event.
|
||||
*
|
||||
* @param event {@link PacketEvent}
|
||||
* @see EventManagerLegacy#callEvent(PacketEvent, byte)
|
||||
*/
|
||||
public void callEvent(final PacketEvent event) {
|
||||
boolean cancel = false;
|
||||
if (event instanceof CancellableEvent) {
|
||||
cancel = ((CancellableEvent) event).isCancelled();
|
||||
}
|
||||
byte highestReachedPriority = PacketEventPriority.LOWEST.getPriorityValue();
|
||||
for (PacketListenerDynamic listener : listeners) {
|
||||
highestReachedPriority = listener.getPriority().getPriorityValue();
|
||||
try {
|
||||
event.callPacketEvent(listener);
|
||||
event.call(listener);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException("PacketEvents found an exception while calling a packet listener.", ex);
|
||||
}
|
||||
if (event instanceof CancellableEvent) {
|
||||
CancellableEvent ce = (CancellableEvent) event;
|
||||
cancel = ce.isCancelled();
|
||||
}
|
||||
}
|
||||
if (event instanceof CancellableEvent) {
|
||||
CancellableEvent ce = (CancellableEvent) event;
|
||||
ce.setCancelled(cancel);
|
||||
}
|
||||
|
||||
PEEventManager.EVENT_MANAGER_LEGACY.callEvent(event, highestReachedPriority);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the dynamic packet event listener.
|
||||
*
|
||||
* @param listener {@link PacketListenerDynamic}
|
||||
*/
|
||||
public void registerListener(final PacketListenerDynamic listener) {
|
||||
final byte priorityValue = listener.getPriority().getPriorityValue();
|
||||
if (listeners.isEmpty()) {
|
||||
listeners.add(listener);
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < listeners.size(); i++) {
|
||||
PacketListenerDynamic other = listeners.get(i);
|
||||
byte otherPriorityValue = other.getPriority().getPriorityValue();
|
||||
if (i + 1 == listeners.size()) {
|
||||
listeners.add(listener);
|
||||
break;
|
||||
} else if (otherPriorityValue == priorityValue) {
|
||||
listeners.add(i + 1, listener);
|
||||
break;
|
||||
} else if (otherPriorityValue > priorityValue) {
|
||||
listeners.add(i, listener);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register multiple dynamic packet event listeners with one method.
|
||||
*
|
||||
* @param listeners {@link PacketListenerDynamic}
|
||||
*/
|
||||
public void registerListeners(PacketListenerDynamic... listeners) {
|
||||
for (PacketListenerDynamic listener : listeners) {
|
||||
registerListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister the dynamic packet event listener.
|
||||
*
|
||||
* @param listener {@link PacketListenerDynamic}
|
||||
*/
|
||||
public void unregisterListener(PacketListenerDynamic listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister multiple dynamic packet event listeners with one method.
|
||||
*
|
||||
* @param listeners {@link PacketListenerDynamic}
|
||||
*/
|
||||
public void unregisterListeners(PacketListenerDynamic... listeners) {
|
||||
for (PacketListenerDynamic listener : listeners) {
|
||||
unregisterListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister all dynamic packet event listeners.
|
||||
*/
|
||||
public void unregisterAllListeners() {
|
||||
listeners.clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.manager;
|
||||
|
||||
import io.github.retrooper.packetevents.event.PacketEvent;
|
||||
import io.github.retrooper.packetevents.event.PacketListener;
|
||||
import io.github.retrooper.packetevents.event.annotation.PacketHandler;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.CancellableEvent;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
|
||||
@Deprecated
|
||||
class EventManagerLegacy {
|
||||
/**
|
||||
* Map storing all all legacy packet event listeners.
|
||||
* The key is an individual listener, the values are the key's event methods.
|
||||
*/
|
||||
|
||||
private final Map<PacketListener, HashSet<Method>> staticRegisteredMethods = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Call a PacketEvent with the legacy event manager.
|
||||
* This method processes the event on all legacy packet event listeners.
|
||||
* This method is actually called by {@link EventManagerDynamic#callEvent(PacketEvent)} as the
|
||||
* if you mix the two event systems, the dynamic listeners are always processed first and pass
|
||||
* their highest reached event priority that this legacy one has to beat/reach to be able to cancel
|
||||
* the event.
|
||||
* This downside of this system is the event listeners aren't executed in any particular order, just
|
||||
* in the order they were registered.
|
||||
* This system is also slower than the other event system.
|
||||
*
|
||||
* @param event {@link PacketEvent}
|
||||
* @param eventPriority Priority the legacy listeners should beat to decide cancellation of the event.
|
||||
*/
|
||||
@Deprecated
|
||||
public void callEvent(final PacketEvent event, byte eventPriority) {
|
||||
boolean isCancelled = false;
|
||||
if (event instanceof CancellableEvent) {
|
||||
isCancelled = ((CancellableEvent) event).isCancelled();
|
||||
}
|
||||
//STATIC LISTENERS
|
||||
for (final PacketListener listener : staticRegisteredMethods.keySet()) {
|
||||
HashSet<Method> methods = staticRegisteredMethods.get(listener);
|
||||
|
||||
for (Method method : methods) {
|
||||
Class<?> parameterType = method.getParameterTypes()[0];
|
||||
if (parameterType.equals(PacketEvent.class)
|
||||
|| parameterType.isInstance(event)) {
|
||||
|
||||
PacketHandler annotation = method.getAnnotation(PacketHandler.class);
|
||||
try {
|
||||
method.invoke(listener, event);
|
||||
} catch (IllegalAccessException | InvocationTargetException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
if (event instanceof CancellableEvent) {
|
||||
CancellableEvent ce = (CancellableEvent) event;
|
||||
if (annotation.priority() >= eventPriority) {
|
||||
eventPriority = annotation.priority();
|
||||
isCancelled = ce.isCancelled();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (event instanceof CancellableEvent) {
|
||||
CancellableEvent ce = (CancellableEvent) event;
|
||||
ce.setCancelled(isCancelled);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a legacy packet event listener.
|
||||
* Not recommended to use the deprecated event listener.
|
||||
*
|
||||
* @param listener {@link PacketListener}
|
||||
*/
|
||||
@Deprecated
|
||||
public void registerListener(final PacketListener listener) {
|
||||
final HashSet<Method> methods = new HashSet<>();
|
||||
for (final Method m : listener.getClass().getDeclaredMethods()) {
|
||||
if (!m.isAccessible()) {
|
||||
m.setAccessible(true);
|
||||
}
|
||||
if (m.isAnnotationPresent(PacketHandler.class)
|
||||
&& m.getParameterTypes().length == 1) {
|
||||
methods.add(m);
|
||||
}
|
||||
}
|
||||
|
||||
if (!methods.isEmpty()) {
|
||||
staticRegisteredMethods.put(listener, methods);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register multiple legacy packet event listeners with one method.
|
||||
* Not recommended to use the deprecated event listener.
|
||||
*
|
||||
* @param listeners {@link PacketListener}
|
||||
*/
|
||||
@Deprecated
|
||||
public void registerListeners(final PacketListener... listeners) {
|
||||
for (final PacketListener listener : listeners) {
|
||||
registerListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a legacy packet event listener.
|
||||
* Not recommended to use the deprecated event listener.
|
||||
*
|
||||
* @param listener {@link PacketListener}
|
||||
*/
|
||||
@Deprecated
|
||||
public void unregisterListener(final PacketListener listener) {
|
||||
staticRegisteredMethods.remove(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister multiple legacy packet event listeners with one method.
|
||||
* Not recommended to use the deprecated event listener.
|
||||
*
|
||||
* @param listeners {@link PacketListener}
|
||||
*/
|
||||
@Deprecated
|
||||
public void unregisterListeners(final PacketListener... listeners) {
|
||||
for (final PacketListener listener : listeners) {
|
||||
unregisterListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister all legacy packet event listeners.
|
||||
*/
|
||||
@Deprecated
|
||||
public void unregisterAllListeners() {
|
||||
staticRegisteredMethods.clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.manager;
|
||||
|
||||
/**
|
||||
* Class storing a static instance of the dynamic and the legacy event manager.
|
||||
*
|
||||
* @author retrooper
|
||||
* @since 1.8
|
||||
*/
|
||||
public class PEEventManager implements EventManager {
|
||||
|
||||
public static final EventManagerLegacy EVENT_MANAGER_LEGACY = new EventManagerLegacy();
|
||||
public static final EventManagerDynamic EVENT_MANAGER_DYNAMIC = new EventManagerDynamic();
|
||||
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.priority;
|
||||
|
||||
/**
|
||||
* Event priority enum for the new event system.
|
||||
* The event priority counts for the whole {@link io.github.retrooper.packetevents.event.PacketListenerDynamic}
|
||||
* and not for just one event.
|
||||
* The priority can be specified in the PacketListenerDynamic constructor.
|
||||
* If you don't specify a priority in the constructor, it will use the {@link #NORMAL} priority.
|
||||
*
|
||||
* @author retrooper
|
||||
* @since 1.6.9
|
||||
*/
|
||||
public enum PacketEventPriority {
|
||||
/**
|
||||
* The weakest event priority.
|
||||
* The first to be processed(IN THE DYNAMIC EVENT SYSTEM ONLY).
|
||||
* Use this if you need to be the first processing the event and
|
||||
* need no power in cancelling an event or preventing an event cancellation.
|
||||
*/
|
||||
LOWEST((byte) 0),
|
||||
|
||||
/**
|
||||
* A weak event priority.
|
||||
* Second to be processed(IN THE DYNAMIC EVENT SYSTEM ONLY).
|
||||
* Use this if you would prefer to be one of the first to process the event,
|
||||
* but don't mind if some other listener processes before you.
|
||||
*/
|
||||
LOW((byte) 1),
|
||||
|
||||
/**
|
||||
* Default event priority.
|
||||
* Third to be processed(IN THE DYNAMIC EVENT SYSTEM ONLY).
|
||||
* Use this if you don't really care/know when you process or just want to
|
||||
* be in the middle.
|
||||
*/
|
||||
NORMAL((byte) 2),
|
||||
|
||||
/**
|
||||
* Higher than the {@link PacketEventPriority#NORMAL} event priority.
|
||||
* Fourth to be processed(IN THE DYNAMIC EVENT SYSTEM ONLY).
|
||||
* Use this if you want to process before the default event prioritized listeners.
|
||||
*/
|
||||
HIGH((byte) 3),
|
||||
|
||||
/**
|
||||
* Second most powerful event priority.
|
||||
* Fifth to be processed(IN THE DYNAMIC EVENT SYSTEM ONLY).
|
||||
* Use this if you prefer to be one of the last to process,
|
||||
* but don't mind if some other listener really needs to process after you.
|
||||
* Also use this if you prefer deciding if the event cancelled or not, but don't
|
||||
* mind if some other listener urgently needs to decide over you.
|
||||
* {@link PacketEventPriority#MONITOR} is rarely ever recommended to use.
|
||||
*/
|
||||
HIGHEST((byte) 4),
|
||||
|
||||
/**
|
||||
* Most powerful event priority.
|
||||
* Last(Sixth) to be processed(IN THE DYNAMIC EVENT SYSTEM ONLY).
|
||||
* Use this if you urgently need to be the last to process
|
||||
* or urgently need to be the final decider whether the event has cancelled or not.
|
||||
* This is rarely recommended.
|
||||
*/
|
||||
MONITOR((byte) 5);
|
||||
|
||||
final byte priorityValue;
|
||||
|
||||
PacketEventPriority(byte priorityValue) {
|
||||
this.priorityValue = priorityValue;
|
||||
}
|
||||
|
||||
public byte getPriorityValue() {
|
||||
return priorityValue;
|
||||
}
|
||||
|
||||
public static PacketEventPriority getPacketEventPriority(byte bytePriority) {
|
||||
for (PacketEventPriority priority : values()) {
|
||||
if (priority.priorityValue == bytePriority) {
|
||||
return priority;
|
||||
}
|
||||
}
|
||||
return NORMAL;
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package io.github.retrooper.packetevents.example;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.annotations.PacketHandler;
|
||||
import io.github.retrooper.packetevents.enums.EventSynchronization;
|
||||
import io.github.retrooper.packetevents.event.PacketListener;
|
||||
import io.github.retrooper.packetevents.event.impl.PacketSendEvent;
|
||||
import io.github.retrooper.packetevents.packet.PacketType;
|
||||
import io.github.retrooper.packetevents.packetwrappers.out.entity.WrappedPacketOutEntity;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class MainExample extends JavaPlugin implements PacketListener {
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
PacketEvents.load();
|
||||
}
|
||||
|
||||
@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);
|
||||
//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
|
||||
public void onDisable() {
|
||||
PacketEvents.stop();
|
||||
}
|
||||
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.exceptions;
|
||||
|
||||
/**
|
||||
* An exception thrown by PacketEvents when the {@link io.github.retrooper.packetevents.PacketEvents#load}
|
||||
* method fails to execute without any exceptions.
|
||||
* Resulting in PacketEvents failing to load.
|
||||
*
|
||||
* @author retrooper
|
||||
* @since 1.7.6
|
||||
*/
|
||||
public class PacketEventsLoadFailureException extends RuntimeException {
|
||||
public PacketEventsLoadFailureException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public PacketEventsLoadFailureException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public PacketEventsLoadFailureException() {
|
||||
this("PacketEvents failed to load...");
|
||||
}
|
||||
|
||||
public PacketEventsLoadFailureException(Throwable cause) {
|
||||
this("PacketEvents failed to load...", cause);
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.exceptions;
|
||||
|
||||
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
|
||||
|
||||
/**
|
||||
* An exception thrown by PacketEvents when a wrapper fails
|
||||
* to find a field.
|
||||
*
|
||||
* @author retrooper
|
||||
* @see io.github.retrooper.packetevents.packetwrappers.WrappedPacket#read(int, Class)
|
||||
* @see io.github.retrooper.packetevents.packetwrappers.WrappedPacket#write(Class, int, Object)
|
||||
* @since 1.6.9
|
||||
*/
|
||||
public class WrapperFieldNotFoundException extends RuntimeException {
|
||||
public WrapperFieldNotFoundException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public WrapperFieldNotFoundException(Class<?> packetClass, Class<?> type, int index) {
|
||||
this("PacketEvents failed to find a " + ClassUtil.getClassSimpleName(type) + " indexed " + index + " by its type in the " + packetClass.getName() + " class!");
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
package io.github.retrooper.packetevents.handler;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.event.impl.PacketReceiveEvent;
|
||||
import io.github.retrooper.packetevents.event.impl.PacketSendEvent;
|
||||
import io.github.retrooper.packetevents.event.impl.PlayerInjectEvent;
|
||||
import io.github.retrooper.packetevents.event.impl.PlayerUninjectEvent;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
public class NettyPacketHandler {
|
||||
private static boolean v1_7_nettyMode = false;
|
||||
|
||||
static {
|
||||
try {
|
||||
Class.forName("io.netty.channel.Channel");
|
||||
} catch (ClassNotFoundException e) {
|
||||
v1_7_nettyMode = true;
|
||||
}
|
||||
}
|
||||
|
||||
public static void injectPlayer(final Player player) {
|
||||
final PlayerInjectEvent injectEvent = new PlayerInjectEvent(player);
|
||||
PacketEvents.getAPI().getEventManager().callEvent(injectEvent);
|
||||
if (!injectEvent.isCancelled()) {
|
||||
if (v1_7_nettyMode) {
|
||||
NettyPacketHandler_7.injectPlayer(player);
|
||||
} else {
|
||||
NettyPacketHandler_8.injectPlayer(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Future<?> uninjectPlayer(final Player player) {
|
||||
try {
|
||||
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);
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void uninjectPlayerNow(final Player player) {
|
||||
try {
|
||||
final PlayerUninjectEvent uninjectEvent = new PlayerUninjectEvent(player);
|
||||
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 PacketSendEvent packetSendEvent = new PacketSendEvent(sender, packet);
|
||||
PacketEvents.getAPI().getEventManager().callEvent(packetSendEvent);
|
||||
if (!packetSendEvent.isCancelled()) {
|
||||
return packet;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Object read(final Player receiver, final Object packet) {
|
||||
final PacketReceiveEvent packetReceiveEvent = new PacketReceiveEvent(receiver, packet);
|
||||
PacketEvents.getAPI().getEventManager().callEvent(packetReceiveEvent);
|
||||
if (!packetReceiveEvent.isCancelled()) {
|
||||
return packet;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
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 org.bukkit.entity.Player;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
final class NettyPacketHandler_7 {
|
||||
|
||||
public static void injectPlayer(final Player player) {
|
||||
final ChannelDuplexHandler channelDuplexHandler = new ChannelDuplexHandler() {
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
Object packet = NettyPacketHandler.read(player, msg);
|
||||
if (packet == null) {
|
||||
return;
|
||||
}
|
||||
super.channelRead(ctx, msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
|
||||
Object packet = NettyPacketHandler.write(player, msg);
|
||||
if (packet == null) {
|
||||
return;
|
||||
}
|
||||
super.write(ctx, msg, promise);
|
||||
}
|
||||
};
|
||||
final ChannelPipeline pipeline = ((Channel) NMSUtils.getChannel(player)).pipeline();
|
||||
pipeline.addBefore("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(() -> {
|
||||
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,47 +0,0 @@
|
||||
package io.github.retrooper.packetevents.handler;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
import io.netty.channel.*;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
final class NettyPacketHandler_8 {
|
||||
|
||||
public static void injectPlayer(final Player player) {
|
||||
final ChannelDuplexHandler channelDuplexHandler = new ChannelDuplexHandler() {
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
Object packet = NettyPacketHandler.read(player, msg);
|
||||
if (packet == null) {
|
||||
return;
|
||||
}
|
||||
super.channelRead(ctx, msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
|
||||
Object packet = NettyPacketHandler.write(player, msg);
|
||||
if (packet == null) {
|
||||
return;
|
||||
}
|
||||
super.write(ctx, msg, promise);
|
||||
}
|
||||
};
|
||||
final ChannelPipeline pipeline = ((Channel) NMSUtils.getChannel(player)).pipeline();
|
||||
pipeline.addBefore("packet_handler", PacketEvents.getHandlerName(player.getName()), channelDuplexHandler);
|
||||
}
|
||||
|
||||
public static Future<?> uninjectPlayer(final Player player) {
|
||||
final Channel channel = (Channel) NMSUtils.getChannel(player);
|
||||
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()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,446 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.handler;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.event.impl.*;
|
||||
import io.github.retrooper.packetevents.injector.GlobalChannelInjector;
|
||||
import io.github.retrooper.packetevents.packettype.PacketType;
|
||||
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
|
||||
import io.github.retrooper.packetevents.packetwrappers.login.in.handshake.WrappedPacketLoginInHandshake;
|
||||
import io.github.retrooper.packetevents.packetwrappers.login.in.start.WrappedPacketLoginInStart;
|
||||
import io.github.retrooper.packetevents.settings.PacketEventsSettings;
|
||||
import io.github.retrooper.packetevents.utils.gameprofile.WrappedGameProfile;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.player.ClientVersion;
|
||||
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Internal manager of everything related to packets.
|
||||
* For example injecting, channel caching, internal processing, packet sending....
|
||||
* This class is only meant to be used internally.
|
||||
* This could end up being refactored or renamed without a deprecation as it is only meant to be used internally.
|
||||
*
|
||||
* @author retrooper
|
||||
* @see <a href="http://netty.io">http://netty.io</a>
|
||||
* @since 1.7.9
|
||||
*/
|
||||
public class PacketHandlerInternal {
|
||||
public final GlobalChannelInjector injector;
|
||||
public final HashMap<UUID, Long> keepAliveMap = new HashMap<>();
|
||||
public final Map<String, Object> channelMap = new WeakHashMap<>();
|
||||
|
||||
public PacketHandlerInternal(Plugin plugin) {
|
||||
injector = new GlobalChannelInjector();
|
||||
injector.prepare();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a player's netty channel object with their name.
|
||||
* This netty channel object is cached in a {@link ConcurrentHashMap} as the value and
|
||||
* the name is the key.
|
||||
* We cache the name and the channel quite early infact,
|
||||
* once we receive the {@link PacketType.Login.Client#START} packet(which contains the game profile)
|
||||
* and the game profile contains the player name.
|
||||
* The wrapper for that packet is {@link WrappedPacketLoginInStart}.
|
||||
* If PacketEvents couldn't cache(when you have {@link PacketEventsSettings#shouldInjectEarly()} set to false),
|
||||
* PacketEvents will use some reflection to see if CraftBukkit has the netty channel.
|
||||
* If you access this before the START login packet was sent, you will for sure experience issues.
|
||||
*
|
||||
* @param player Target player.
|
||||
* @return Netty channel of a player by their name.
|
||||
* @see <a href="https://wiki.vg/Protocol#Login_Start">https://wiki.vg/Protocol#Login_Start</a>
|
||||
* @see Player#getName()
|
||||
*/
|
||||
public Object getChannel(Player player) {
|
||||
String name = player.getName();
|
||||
Object channel = channelMap.get(name);
|
||||
if (channel == null) {
|
||||
channel = NMSUtils.getChannel(player);
|
||||
channelMap.put(name, channel);
|
||||
}
|
||||
return channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject a player.
|
||||
* Executed synchronously or asynchronously depending on what you have the associated setting set to.
|
||||
* Injecting a player is basically pairing the cached netty channel
|
||||
* {@link #getChannel(Player)} to a bukkit player object.
|
||||
* Bukkit initializes the {@link Player} object some time after
|
||||
* we inject the netty channel, so we need to pair the two.
|
||||
* PacketEvents already injects a player when the bukkit
|
||||
* {@link org.bukkit.event.player.PlayerJoinEvent} or {@link org.bukkit.event.player.PlayerLoginEvent}
|
||||
* is called, depending on your {@link PacketEventsSettings#shouldInjectEarly()} setting is set to.
|
||||
*
|
||||
* @param player Target bukkit player.
|
||||
*/
|
||||
public void injectPlayer(Player player) {
|
||||
if (PacketEvents.get().getSettings().shouldInjectAsync()) {
|
||||
injectPlayerAsync(player);
|
||||
} else {
|
||||
injectPlayerSync(player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Eject a player.
|
||||
* Executed synchronously or asynchronously depending on what you have the associated setting set to.
|
||||
* Ejecting a player is basically unpairing the cached netty channel
|
||||
* {@link #getChannel(Player)} from the bukkit player.
|
||||
* Do this if you want to stop listening to a user's packets.
|
||||
* PacketEvents already ejects a player when the bukkit
|
||||
* {@link org.bukkit.event.player.PlayerQuitEvent} is called.
|
||||
*
|
||||
* @param player Target player.
|
||||
*/
|
||||
public void ejectPlayer(Player player) {
|
||||
if (PacketEvents.get().getSettings().shouldEjectAsync()) {
|
||||
ejectPlayerAsync(player);
|
||||
} else {
|
||||
ejectPlayerSync(player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronously inject a player.
|
||||
*
|
||||
* @param player Target player.
|
||||
* @see #injectPlayer(Player)
|
||||
*/
|
||||
public void injectPlayerSync(Player player) {
|
||||
PlayerInjectEvent injectEvent = new PlayerInjectEvent(player, false);
|
||||
PacketEvents.get().getEventManager().callEvent(injectEvent);
|
||||
if (!injectEvent.isCancelled()) {
|
||||
injector.injectPlayerSync(player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously inject a player.
|
||||
*
|
||||
* @param player Target player.
|
||||
* @see #injectPlayer(Player)
|
||||
*/
|
||||
public void injectPlayerAsync(Player player) {
|
||||
PlayerInjectEvent injectEvent = new PlayerInjectEvent(player, true);
|
||||
PacketEvents.get().getEventManager().callEvent(injectEvent);
|
||||
if (!injectEvent.isCancelled()) {
|
||||
injector.injectPlayerAsync(player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronously eject a player.
|
||||
*
|
||||
* @param player Target player.
|
||||
* @see #ejectPlayer(Player)
|
||||
*/
|
||||
public void ejectPlayerSync(Player player) {
|
||||
PlayerEjectEvent ejectEvent = new PlayerEjectEvent(player, false);
|
||||
PacketEvents.get().getEventManager().callEvent(ejectEvent);
|
||||
if (!ejectEvent.isCancelled()) {
|
||||
injector.ejectPlayerSync(player);
|
||||
keepAliveMap.remove(player.getUniqueId());
|
||||
channelMap.remove(player.getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously eject a player.
|
||||
*
|
||||
* @param player Target player.
|
||||
* @see #ejectPlayer(Player)
|
||||
*/
|
||||
public void ejectPlayerAsync(Player player) {
|
||||
PlayerEjectEvent ejectEvent = new PlayerEjectEvent(player, true);
|
||||
PacketEvents.get().getEventManager().callEvent(ejectEvent);
|
||||
if (!ejectEvent.isCancelled()) {
|
||||
injector.ejectPlayerAsync(player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write and flush a packet to a netty channel.
|
||||
* This netty channel is an object as 1.7.10 and 1.8 and above
|
||||
* have different netty package locations.
|
||||
*
|
||||
* @param channel Netty channel.
|
||||
* @param packet NMS Packet.
|
||||
*/
|
||||
public void sendPacket(Object channel, Object packet) {
|
||||
injector.sendPacket(channel, packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make PacketEvents process an incoming packet.
|
||||
*
|
||||
* @param player Packet sender.
|
||||
* @param channel Packet sender's netty channel.
|
||||
* @param packet NMS Packet.
|
||||
* @return NMS Packet, null if the event was cancelled.
|
||||
*/
|
||||
public Object read(Player player, Object channel, Object packet) {
|
||||
if (PacketTypeClasses.Login.Client.START.equals(packet.getClass())) {
|
||||
WrappedPacketLoginInStart startWrapper = new WrappedPacketLoginInStart(new NMSPacket(packet));
|
||||
WrappedGameProfile gameProfile = startWrapper.getGameProfile();
|
||||
channelMap.put(gameProfile.name, channel);
|
||||
}
|
||||
if (player == null) {
|
||||
String simpleClassName = ClassUtil.getClassSimpleName(packet.getClass());
|
||||
//Status packet
|
||||
if (simpleClassName.startsWith("PacketS")) {
|
||||
final PacketStatusReceiveEvent event = new PacketStatusReceiveEvent(channel, new NMSPacket(packet));
|
||||
PacketEvents.get().getEventManager().callEvent(event);
|
||||
packet = event.getNMSPacket().getRawNMSPacket();
|
||||
interceptStatusReceive(event);
|
||||
if (event.isCancelled()) {
|
||||
packet = null;
|
||||
}
|
||||
} else {
|
||||
//Login packet
|
||||
final PacketLoginReceiveEvent event = new PacketLoginReceiveEvent(channel, new NMSPacket(packet));//Cache the channel
|
||||
//f (event.getPacketId() == PacketType.Login.Client.START) {
|
||||
// WrappedPacketLoginInStart startWrapper = new WrappedPacketLoginInStart(event.getNMSPacket());
|
||||
//WrappedGameProfile gameProfile = startWrapper.getGameProfile();
|
||||
//channelMap.put(gameProfile.name, channel);
|
||||
//}
|
||||
PacketEvents.get().getEventManager().callEvent(event);
|
||||
packet = event.getNMSPacket().getRawNMSPacket();
|
||||
interceptLoginReceive(event);
|
||||
if (event.isCancelled()) {
|
||||
packet = null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
final PacketPlayReceiveEvent event = new PacketPlayReceiveEvent(player, channel, new NMSPacket(packet));
|
||||
PacketEvents.get().getEventManager().callEvent(event);
|
||||
packet = event.getNMSPacket().getRawNMSPacket();
|
||||
interceptRead(event);
|
||||
if (event.isCancelled()) {
|
||||
packet = null;
|
||||
}
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make PacketEvents process an outgoing packet.
|
||||
* The NMS Packet will be null when netty should cancel a packet.
|
||||
*
|
||||
* @param player Packet receiver.
|
||||
* @param channel Packet receiver's netty channel.
|
||||
* @param packet NMS Packet.
|
||||
* @return NMS Packet, null if the event was cancelled.
|
||||
*/
|
||||
public Object write(Player player, Object channel, Object packet) {
|
||||
if (player == null) {
|
||||
String simpleClassName = ClassUtil.getClassSimpleName(packet.getClass());
|
||||
//Status packet
|
||||
if (simpleClassName.startsWith("PacketS")) {
|
||||
final PacketStatusSendEvent event = new PacketStatusSendEvent(channel, new NMSPacket(packet));
|
||||
PacketEvents.get().getEventManager().callEvent(event);
|
||||
packet = event.getNMSPacket().getRawNMSPacket();
|
||||
interceptStatusSend(event);
|
||||
if (event.isCancelled()) {
|
||||
packet = null;
|
||||
}
|
||||
}
|
||||
//Login packet
|
||||
else {
|
||||
final PacketLoginSendEvent event = new PacketLoginSendEvent(channel, new NMSPacket(packet));
|
||||
PacketEvents.get().getEventManager().callEvent(event);
|
||||
packet = event.getNMSPacket().getRawNMSPacket();
|
||||
interceptLoginSend(event);
|
||||
if (event.isCancelled()) {
|
||||
packet = null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
final PacketPlaySendEvent event = new PacketPlaySendEvent(player, channel, new NMSPacket(packet));
|
||||
PacketEvents.get().getEventManager().callEvent(event);
|
||||
packet = event.getNMSPacket().getRawNMSPacket();
|
||||
interceptWrite(event);
|
||||
if (event.isCancelled()) {
|
||||
packet = null;
|
||||
}
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make PacketEvents process an incoming PLAY packet after minecraft has processed it.
|
||||
* As minecraft has already processed the packet, we cannot cancel the action, nor the event.
|
||||
*
|
||||
* @param player Packet sender.
|
||||
* @param channel Netty channel of the packet sender.
|
||||
* @param packet NMS Packet.
|
||||
*/
|
||||
public void postRead(Player player, Object channel, Object packet) {
|
||||
if (player != null) {
|
||||
//Since player != null check is done, status and login packets won't come passed this point.
|
||||
PostPacketPlayReceiveEvent event = new PostPacketPlayReceiveEvent(player, channel, new NMSPacket(packet));
|
||||
PacketEvents.get().getEventManager().callEvent(event);
|
||||
interceptPostPlayReceive(event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make PacketEvents process an outgoing PLAY packet after minecraft has already sent the packet.
|
||||
* This doesn't necessarily mean the client already received the packet,
|
||||
* but the server has sent it for sure by this time.
|
||||
* As minecraft has already processed the packet, we cannot cancel the action, nor the event.
|
||||
*
|
||||
* @param player Packet receiver.
|
||||
* @param channel Netty channel of the packet receiver.
|
||||
* @param packet NMS Packet.
|
||||
*/
|
||||
public void postWrite(Player player, Object channel, Object packet) {
|
||||
if (player != null) {
|
||||
//Since player != null check is done, status and login packets won't come passed this point.
|
||||
PostPacketPlaySendEvent event = new PostPacketPlaySendEvent(player, channel, new NMSPacket(packet));
|
||||
PacketEvents.get().getEventManager().callEvent(event);
|
||||
interceptPostPlaySend(event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal processing of an incoming PLAY packet.
|
||||
*
|
||||
* @param event PLAY server-bound packet event.
|
||||
*/
|
||||
private void interceptRead(PacketPlayReceiveEvent event) {
|
||||
if (event.getPacketId() == PacketType.Play.Client.KEEP_ALIVE) {
|
||||
UUID uuid = event.getPlayer().getUniqueId();
|
||||
long timestamp = keepAliveMap.getOrDefault(uuid, event.getTimestamp());
|
||||
long currentTime = event.getTimestamp();
|
||||
long ping = currentTime - timestamp;
|
||||
long smoothedPing = (PacketEvents.get().getPlayerUtils().getSmoothedPing(event.getPlayer()) * 3 + ping) / 4;
|
||||
PacketEvents.get().getPlayerUtils().playerPingMap.put(uuid, (short) ping);
|
||||
PacketEvents.get().getPlayerUtils().playerSmoothedPingMap.put(uuid, (short) smoothedPing);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal processing of an outgoing PLAY packet.
|
||||
*
|
||||
* @param event PLAY client-bound packet event.
|
||||
*/
|
||||
private void interceptWrite(PacketPlaySendEvent event) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal processing of an incoming LOGIN packet.
|
||||
*
|
||||
* @param event LOGIN server-bound packet event.
|
||||
*/
|
||||
private void interceptLoginReceive(PacketLoginReceiveEvent event) {
|
||||
if (event.getPacketId() == PacketType.Login.Client.HANDSHAKE) {
|
||||
WrappedPacketLoginInHandshake handshake = new WrappedPacketLoginInHandshake(event.getNMSPacket());
|
||||
int protocolVersion = handshake.getProtocolVersion();
|
||||
ClientVersion version = ClientVersion.getClientVersion(protocolVersion);
|
||||
PacketEvents.get().getPlayerUtils().tempClientVersionMap.put(event.getSocketAddress(), version);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal processing of an outgoing LOGIN packet.
|
||||
*
|
||||
* @param event client-bound LOGIN packet event.
|
||||
*/
|
||||
private void interceptLoginSend(PacketLoginSendEvent event) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal processing of an incoming STATUS packet.
|
||||
*
|
||||
* @param event server-bound STATUS packet event.
|
||||
*/
|
||||
private void interceptStatusReceive(PacketStatusReceiveEvent event) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal processing of an outgoing STATUS packet.
|
||||
*
|
||||
* @param event client-bound STATUS packet event.
|
||||
*/
|
||||
private void interceptStatusSend(PacketStatusSendEvent event) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal processing of a packet that has already been processed by minecraft.
|
||||
*
|
||||
* @param event post server-bound play packet event.
|
||||
*/
|
||||
private void interceptPostPlayReceive(PostPacketPlayReceiveEvent event) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal processing of a packet that has already been sent to a client.
|
||||
* Doesn't necessarily mean the client has received it yet.
|
||||
*
|
||||
* @param event post client-bound play packet event.
|
||||
*/
|
||||
private void interceptPostPlaySend(PostPacketPlaySendEvent event) {
|
||||
if (event.getPacketId() == PacketType.Play.Server.KEEP_ALIVE) {
|
||||
if (event.getPlayer() != null) {
|
||||
keepAliveMap.put(event.getPlayer().getUniqueId(), event.getTimestamp());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If you are using the EarlyInjector,
|
||||
* calling this close method will unregister the channel handlers it registered when the plugin enabled.
|
||||
* PacketEvents already unregisters them in the {@link PacketEvents#terminate()} method.
|
||||
*/
|
||||
public void cleanup() {
|
||||
injector.cleanup();
|
||||
}
|
||||
|
||||
/**
|
||||
* If you are using the EarlyInjector,
|
||||
* calling this close method will unregister the channel handlers it registered when the plugin enabled
|
||||
* ASYNCHRONOUSLY.
|
||||
* PacketEvents already unregisters them in the {@link PacketEvents#terminate()} method.
|
||||
*/
|
||||
public void cleanupAsync() {
|
||||
injector.cleanupAsync();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package io.github.retrooper.packetevents.injector;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public interface ChannelInjector {
|
||||
default void prepare() {
|
||||
|
||||
}
|
||||
|
||||
default void cleanup() {
|
||||
|
||||
}
|
||||
|
||||
default void cleanupAsync() {
|
||||
PacketEvents.get().injectAndEjectExecutorService.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
cleanup();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void injectPlayerSync(Player player);
|
||||
|
||||
void ejectPlayerSync(Player player);
|
||||
|
||||
void injectPlayerAsync(Player player);
|
||||
|
||||
void ejectPlayerAsync(Player player);
|
||||
|
||||
void sendPacket(Object channel, Object rawNMSPacket);
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package io.github.retrooper.packetevents.injector;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.injector.earlyinjector.EarlyChannelInjector7;
|
||||
import io.github.retrooper.packetevents.injector.earlyinjector.EarlyChannelInjector8;
|
||||
import io.github.retrooper.packetevents.injector.lateinjector.LateChannelInjector7;
|
||||
import io.github.retrooper.packetevents.injector.lateinjector.LateChannelInjector8;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class GlobalChannelInjector implements ChannelInjector {
|
||||
private final ChannelInjector injector;
|
||||
|
||||
public GlobalChannelInjector() {
|
||||
boolean legacy = NMSUtils.legacyNettyImportMode;
|
||||
//Early injector
|
||||
if (PacketEvents.get().getSettings().shouldInjectEarly()) {
|
||||
injector = legacy ? new EarlyChannelInjector7() : new EarlyChannelInjector8();
|
||||
}
|
||||
//Late injector
|
||||
else {
|
||||
injector = legacy ? new LateChannelInjector7() : new LateChannelInjector8();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepare() {
|
||||
injector.prepare();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup() {
|
||||
injector.cleanup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanupAsync() {
|
||||
injector.cleanupAsync();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectPlayerSync(Player player) {
|
||||
injector.injectPlayerSync(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ejectPlayerSync(Player player) {
|
||||
injector.ejectPlayerSync(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectPlayerAsync(Player player) {
|
||||
injector.injectPlayerAsync(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ejectPlayerAsync(Player player) {
|
||||
injector.ejectPlayerAsync(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacket(Object channel, Object rawNMSPacket) {
|
||||
injector.sendPacket(channel, rawNMSPacket);
|
||||
}
|
||||
}
|
||||
+337
@@ -0,0 +1,337 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.injector.earlyinjector;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
import net.minecraft.util.io.netty.channel.*;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* 1.7.10 Spigot Early channel injector.
|
||||
* This is an early injector for 1.7.10 spigot servers.
|
||||
* The netty import on spigot changed since 1.8.
|
||||
* So we needed to make a new class using the older import location to support 1.7.10.
|
||||
* This is why we also commonly use a java {@link Object} class when it comes to netty channels
|
||||
* in some classes to maintain support for both netty imports.
|
||||
*
|
||||
* @author retrooper
|
||||
* @since 1.8
|
||||
*/
|
||||
public class EarlyChannelInjector7 implements EarlyInjector {
|
||||
/**
|
||||
* Netty minecraft server channels.
|
||||
*/
|
||||
private final List<Channel> serverChannels = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* First channel initializer.
|
||||
* Used to inject incoming channels.
|
||||
*/
|
||||
private ChannelInitializer<Channel> firstChannelInitializer;
|
||||
|
||||
/**
|
||||
* Second channel initializer.
|
||||
*/
|
||||
private ChannelInitializer<Channel> secondChannelInitializer;
|
||||
|
||||
/**
|
||||
* Channel handler.
|
||||
*/
|
||||
private ChannelInboundHandlerAdapter channelHandler;
|
||||
|
||||
/**
|
||||
* Network managers.
|
||||
*/
|
||||
private List<Object> networkMarkers;
|
||||
|
||||
|
||||
/**
|
||||
* Access minecraft's network managers to synchronize against as they interfere with our channel injection.
|
||||
* Initiate the channel initializers and the channel handler.
|
||||
* Access minecraft's server channels and add our own.
|
||||
*/
|
||||
@Override
|
||||
public void prepare() {
|
||||
networkMarkers = NMSUtils.getNetworkMarkers();
|
||||
firstChannelInitializer = new ChannelInitializer<Channel>() {
|
||||
@Override
|
||||
protected void initChannel(final Channel channel) {
|
||||
if (networkMarkers != null) {
|
||||
synchronized (networkMarkers) {
|
||||
channel.eventLoop().execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (PacketEvents.get().getServerUtils().getVersion().isHigherThan(ServerVersion.v_1_11_2)) {
|
||||
channel.eventLoop().execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
injectChannel(channel);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
injectChannel(channel);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
channel.eventLoop().execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (PacketEvents.get().getServerUtils().getVersion().isHigherThan(ServerVersion.v_1_11_2)) {
|
||||
channel.eventLoop().execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
injectChannel(channel);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
injectChannel(channel);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
secondChannelInitializer = new ChannelInitializer<Channel>() {
|
||||
@Override
|
||||
protected void initChannel(Channel channel) {
|
||||
channel.pipeline().addLast(firstChannelInitializer);
|
||||
}
|
||||
};
|
||||
|
||||
channelHandler = new ChannelInboundHandlerAdapter() {
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) {
|
||||
Channel channel = (Channel) msg;
|
||||
channel.pipeline().addFirst(secondChannelInitializer);
|
||||
ctx.fireChannelRead(msg);
|
||||
}
|
||||
};
|
||||
|
||||
//Wrapper for the minecraft server connection.
|
||||
WrappedPacket serverConnectionWrapper = new WrappedPacket(new NMSPacket(NMSUtils.getMinecraftServerConnection()));
|
||||
boolean searching = true;
|
||||
for (int i = 0; searching; i++) {
|
||||
try {
|
||||
//Get the list.
|
||||
List<Object> serverChannelList = (List<Object>) serverConnectionWrapper.readObject(i, List.class);
|
||||
for (Object serverChannel : serverChannelList) {
|
||||
//Is this the server channel list?
|
||||
if (serverChannel instanceof ChannelFuture) {
|
||||
//Yes it is...
|
||||
Channel channel = ((ChannelFuture) serverChannel).channel();
|
||||
serverChannels.add(channel);
|
||||
//Add our channel handler to all the server channel pipelines.
|
||||
channel.pipeline().addFirst(channelHandler);
|
||||
searching = false;
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove our channel handler from all server channel pipelines from the current thread.
|
||||
*/
|
||||
@Override
|
||||
public void cleanup() {
|
||||
for (Channel channel : serverChannels) {
|
||||
try {
|
||||
channel.pipeline().remove(channelHandler);
|
||||
} catch (NoSuchElementException ignored) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject a netty channel to listen to packets.
|
||||
* If already injected, get the channel interceptor.
|
||||
*
|
||||
* @param ch Netty channel.
|
||||
* @return {@link PlayerChannelInterceptor}
|
||||
*/
|
||||
@Override
|
||||
public PlayerChannelInterceptor injectChannel(Object ch) {
|
||||
Channel channel = (Channel) ch;
|
||||
String handlerName = PacketEvents.handlerName;
|
||||
PlayerChannelInterceptor interceptor = (PlayerChannelInterceptor) channel.pipeline().get(handlerName);
|
||||
if (interceptor == null) {
|
||||
interceptor = new PlayerChannelInterceptor();
|
||||
if (channel.pipeline().get("packet_handler") != null) {
|
||||
channel.pipeline().addBefore("packet_handler", handlerName, interceptor);
|
||||
} else {
|
||||
throw new IllegalStateException("Failed to inject an incoming channel due to \"packet_handler\" not being added to the pipeline! Let them rejoin!");
|
||||
}
|
||||
}
|
||||
return interceptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Eject a netty channel.
|
||||
*
|
||||
* @param ch Netty channel.
|
||||
*/
|
||||
@Override
|
||||
public void ejectChannel(Object ch) {
|
||||
Channel channel = (Channel) ch;
|
||||
String handlerName = PacketEvents.handlerName;
|
||||
if (channel.pipeline().get(handlerName) != null) {
|
||||
channel.pipeline().remove(handlerName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject a player on the current thread.
|
||||
*
|
||||
* @param player Target player.
|
||||
*/
|
||||
@Override
|
||||
public void injectPlayerSync(Player player) {
|
||||
Channel channel = (Channel) PacketEvents.get().packetHandlerInternal.getChannel(player);
|
||||
injectChannel(channel).player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Eject a player on the current thread.
|
||||
*
|
||||
* @param player Target player.
|
||||
*/
|
||||
@Override
|
||||
public void ejectPlayerSync(Player player) {
|
||||
Channel channel = (Channel) PacketEvents.get().packetHandlerInternal.getChannel(player);
|
||||
ejectChannel(channel);
|
||||
PacketEvents.get().getPlayerUtils().clientVersionsMap.remove(player.getAddress());
|
||||
PacketEvents.get().getPlayerUtils().tempClientVersionMap.remove(player.getAddress());
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject a player on our custom inject and eject (fixed) thread pool (=asynchronously).
|
||||
*
|
||||
* @param player Target player.
|
||||
*/
|
||||
@Override
|
||||
public void injectPlayerAsync(Player player) {
|
||||
PacketEvents.get().injectAndEjectExecutorService.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Channel channel = (Channel) PacketEvents.get().packetHandlerInternal.getChannel(player);
|
||||
injectChannel(channel).player = player;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Eject a player on our custom inject and eject (fixed) thread pool (=asynchronously).
|
||||
*
|
||||
* @param player Target player.
|
||||
*/
|
||||
@Override
|
||||
public void ejectPlayerAsync(Player player) {
|
||||
PacketEvents.get().injectAndEjectExecutorService.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Channel channel = (Channel) PacketEvents.get().packetHandlerInternal.getChannel(player);
|
||||
ejectChannel(channel);
|
||||
PacketEvents.get().packetHandlerInternal.keepAliveMap.remove(player.getUniqueId());
|
||||
PacketEvents.get().packetHandlerInternal.channelMap.remove(player.getName());
|
||||
PacketEvents.get().getPlayerUtils().clientVersionsMap.remove(player.getAddress());
|
||||
PacketEvents.get().getPlayerUtils().tempClientVersionMap.remove(player.getAddress());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a raw NMS packet to a netty channel.
|
||||
*
|
||||
* @param ch Netty channel.
|
||||
* @param packet Raw NMS Packet.
|
||||
*/
|
||||
@Override
|
||||
public void sendPacket(Object ch, Object packet) {
|
||||
Channel channel = (Channel) ch;
|
||||
channel.writeAndFlush(packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Player channel interceptor.
|
||||
*
|
||||
* @author retrooper
|
||||
* @since 1.8
|
||||
*/
|
||||
public static class PlayerChannelInterceptor extends ChannelDuplexHandler {
|
||||
/**
|
||||
* Associated player.
|
||||
* This is null until you inject the player.
|
||||
* (We inject the PLAYER by PlayerLoginEvent or PlayerJoinEvent depending on your settings)
|
||||
*/
|
||||
public volatile Player player;
|
||||
|
||||
/**
|
||||
* Incoming packet interception.
|
||||
*
|
||||
* @param ctx Netty channel handler context.
|
||||
* @param packet Raw NMS Packet.
|
||||
* @throws Exception Possible exception.
|
||||
*/
|
||||
@Override
|
||||
public void channelRead(final ChannelHandlerContext ctx, Object packet) throws Exception {
|
||||
packet = PacketEvents.get().packetHandlerInternal.read(player, ctx.channel(), packet);
|
||||
if (packet != null) {
|
||||
super.channelRead(ctx, packet);
|
||||
PacketEvents.get().packetHandlerInternal.postRead(player, ctx.channel(), packet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Outgoing packet interception.
|
||||
*
|
||||
* @param ctx Netty channel handler context.
|
||||
* @param packet Raw NMS Packet
|
||||
* @param promise Netty channel promise.
|
||||
* @throws Exception Possible exception.
|
||||
*/
|
||||
@Override
|
||||
public void write(final ChannelHandlerContext ctx, Object packet, final ChannelPromise promise) throws Exception {
|
||||
packet = PacketEvents.get().packetHandlerInternal.write(player, ctx.channel(), packet);
|
||||
if (packet != null) {
|
||||
super.write(ctx, packet, promise);
|
||||
PacketEvents.get().packetHandlerInternal.postWrite(player, ctx.channel(), packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+332
@@ -0,0 +1,332 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.injector.earlyinjector;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
import io.netty.channel.*;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* 1.8 (and above) Spigot Early channel injector.
|
||||
* This is an early injector for 1.8 (and above) spigot servers.
|
||||
* The netty import on spigot changed since 1.8.
|
||||
* So we needed to make separate classes for the 1.7.10 and the 1.8+ injector.
|
||||
* This is why we also commonly use a java {@link Object} class when it comes to netty channels
|
||||
* in some classes to maintain support for both netty imports.
|
||||
*
|
||||
* @author retrooper
|
||||
* @since 1.8
|
||||
*/
|
||||
public class EarlyChannelInjector8 implements EarlyInjector {
|
||||
/**
|
||||
* Netty minecraft server channels.
|
||||
*/
|
||||
private final List<Channel> serverChannels = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* First channel initializer.
|
||||
* Used to inject incoming channels.
|
||||
*/
|
||||
private ChannelInitializer<Channel> firstChannelInitializer;
|
||||
|
||||
/**
|
||||
* Second channel initializer.
|
||||
*/
|
||||
private ChannelInitializer<Channel> secondChannelInitializer;
|
||||
|
||||
/**
|
||||
* Channel handler.
|
||||
*/
|
||||
private ChannelInboundHandlerAdapter channelHandler;
|
||||
|
||||
/**
|
||||
* Network managers.
|
||||
*/
|
||||
private List<Object> networkMarkers;
|
||||
|
||||
/**
|
||||
* Access minecraft's network managers to synchronize against as they interfere with our channel injection.
|
||||
* Initiate the channel initializers and the channel handler.
|
||||
* Access minecraft's server channels and add our own.
|
||||
*/
|
||||
@Override
|
||||
public void prepare() {
|
||||
networkMarkers = NMSUtils.getNetworkMarkers();
|
||||
firstChannelInitializer = new ChannelInitializer<Channel>() {
|
||||
@Override
|
||||
protected void initChannel(final Channel channel) {
|
||||
if (networkMarkers != null) {
|
||||
synchronized (networkMarkers) {
|
||||
if (PacketEvents.get().getServerUtils().getVersion().isHigherThan(ServerVersion.v_1_11_2)) {
|
||||
channel.eventLoop().execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
injectChannel(channel);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
injectChannel(channel);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
channel.eventLoop().execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (PacketEvents.get().getServerUtils().getVersion().isHigherThan(ServerVersion.v_1_11_2)) {
|
||||
channel.eventLoop().execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
injectChannel(channel);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
injectChannel(channel);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
secondChannelInitializer = new ChannelInitializer<Channel>() {
|
||||
@Override
|
||||
protected void initChannel(Channel channel) {
|
||||
channel.pipeline().addLast(firstChannelInitializer);
|
||||
}
|
||||
};
|
||||
|
||||
channelHandler = new ChannelInboundHandlerAdapter() {
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) {
|
||||
Channel channel = (Channel) msg;
|
||||
channel.pipeline().addFirst(secondChannelInitializer);
|
||||
ctx.fireChannelRead(msg);
|
||||
}
|
||||
};
|
||||
//Wrapper for the minecraft server connection.
|
||||
WrappedPacket serverConnectionWrapper = new WrappedPacket(new NMSPacket(NMSUtils.getMinecraftServerConnection()));
|
||||
boolean searching = true;
|
||||
for (int i = 0; searching; i++) {
|
||||
try {
|
||||
//Get the list.
|
||||
List<Object> serverChannelList = (List<Object>) serverConnectionWrapper.readObject(i, List.class);
|
||||
for (Object serverChannel : serverChannelList) {
|
||||
//Is this the server channel list?
|
||||
if (serverChannel instanceof ChannelFuture) {
|
||||
//Yes it is...
|
||||
Channel channel = ((ChannelFuture) serverChannel).channel();
|
||||
serverChannels.add(channel);
|
||||
//Add our channel handler to all server channel pipelines.
|
||||
channel.pipeline().addFirst(channelHandler);
|
||||
searching = false;
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove our channel handler from all server channel pipelines from the current thread.
|
||||
*/
|
||||
@Override
|
||||
public void cleanup() {
|
||||
for (Channel channel : serverChannels) {
|
||||
try {
|
||||
channel.pipeline().remove(channelHandler);
|
||||
} catch (NoSuchElementException ignored) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject a netty channel to listen to packets.
|
||||
* If already injected, get the channel interceptor.
|
||||
*
|
||||
* @param ch Netty channel.
|
||||
* @return {@link PlayerChannelInterceptor}
|
||||
*/
|
||||
@Override
|
||||
public PlayerChannelInterceptor injectChannel(Object ch) {
|
||||
Channel channel = (Channel) ch;
|
||||
final String handlerName = PacketEvents.handlerName;
|
||||
try {
|
||||
PlayerChannelInterceptor interceptor = (PlayerChannelInterceptor) channel.pipeline().get(handlerName);
|
||||
if (interceptor == null) {
|
||||
interceptor = new PlayerChannelInterceptor();
|
||||
if (channel.pipeline().get("packet_handler") != null) {
|
||||
channel.pipeline().addBefore("packet_handler", handlerName, interceptor);
|
||||
}
|
||||
}
|
||||
return interceptor;
|
||||
} catch (IllegalArgumentException ex) {
|
||||
//Let us try again
|
||||
return (PlayerChannelInterceptor) channel.pipeline().get(handlerName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Eject a netty channel.
|
||||
*
|
||||
* @param ch Netty channel.
|
||||
*/
|
||||
@Override
|
||||
public void ejectChannel(Object ch) {
|
||||
Channel channel = (Channel) ch;
|
||||
String handlerName = PacketEvents.handlerName;
|
||||
if (channel.pipeline().get(handlerName) != null) {
|
||||
channel.pipeline().remove(handlerName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject a player on the current thread.
|
||||
*
|
||||
* @param player Target player.
|
||||
*/
|
||||
@Override
|
||||
public void injectPlayerSync(Player player) {
|
||||
Channel channel = (Channel) PacketEvents.get().packetHandlerInternal.getChannel(player);
|
||||
injectChannel(channel).player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Eject a player on the current thread.
|
||||
*
|
||||
* @param player Target player.
|
||||
*/
|
||||
@Override
|
||||
public void ejectPlayerSync(Player player) {
|
||||
Channel channel = (Channel) PacketEvents.get().packetHandlerInternal.getChannel(player);
|
||||
ejectChannel(channel);
|
||||
PacketEvents.get().getPlayerUtils().clientVersionsMap.remove(player.getAddress());
|
||||
PacketEvents.get().getPlayerUtils().tempClientVersionMap.remove(player.getAddress());
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject a player on our custom inject and eject (fixed) thread pool (=asynchronously).
|
||||
*
|
||||
* @param player Target player.
|
||||
*/
|
||||
@Override
|
||||
public void injectPlayerAsync(Player player) {
|
||||
PacketEvents.get().injectAndEjectExecutorService.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Channel channel = (Channel) PacketEvents.get().packetHandlerInternal.getChannel(player);
|
||||
injectChannel(channel).player = player;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Eject a player on our custom inject and eject (fixed) thread pool (=asynchronously).
|
||||
*
|
||||
* @param player Target player.
|
||||
*/
|
||||
@Override
|
||||
public void ejectPlayerAsync(Player player) {
|
||||
PacketEvents.get().injectAndEjectExecutorService.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Channel channel = (Channel) PacketEvents.get().packetHandlerInternal.getChannel(player);
|
||||
ejectChannel(channel);
|
||||
PacketEvents.get().packetHandlerInternal.keepAliveMap.remove(player.getUniqueId());
|
||||
PacketEvents.get().packetHandlerInternal.channelMap.remove(player.getName());
|
||||
PacketEvents.get().getPlayerUtils().clientVersionsMap.remove(player.getAddress());
|
||||
PacketEvents.get().getPlayerUtils().tempClientVersionMap.remove(player.getAddress());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a raw NMS packet to a netty channel.
|
||||
*
|
||||
* @param ch Netty channel.
|
||||
* @param packet Raw NMS Packet.
|
||||
*/
|
||||
@Override
|
||||
public void sendPacket(Object ch, Object packet) {
|
||||
Channel channel = (Channel) ch;
|
||||
channel.writeAndFlush(packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Player channel interceptor.
|
||||
*
|
||||
* @author retrooper
|
||||
* @since 1.8
|
||||
*/
|
||||
public static class PlayerChannelInterceptor extends ChannelDuplexHandler {
|
||||
/**
|
||||
* Associated player.
|
||||
* This is null until you inject the player.
|
||||
* (We inject the PLAYER by PlayerLoginEvent or PlayerJoinEvent depending on your settings)
|
||||
*/
|
||||
public volatile Player player;
|
||||
|
||||
/**
|
||||
* Incoming packet interception.
|
||||
*
|
||||
* @param ctx Netty channel handler context.
|
||||
* @param packet Raw NMS Packet.
|
||||
* @throws Exception Possible exception.
|
||||
*/
|
||||
@Override
|
||||
public void channelRead(final ChannelHandlerContext ctx, Object packet) throws Exception {
|
||||
packet = PacketEvents.get().packetHandlerInternal.read(player, ctx.channel(), packet);
|
||||
if (packet != null) {
|
||||
super.channelRead(ctx, packet);
|
||||
PacketEvents.get().packetHandlerInternal.postRead(player, ctx.channel(), packet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Outgoing packet interception.
|
||||
*
|
||||
* @param ctx Netty channel handler context.
|
||||
* @param packet Raw NMS Packet
|
||||
* @param promise Netty channel promise.
|
||||
* @throws Exception Possible exception.
|
||||
*/
|
||||
@Override
|
||||
public void write(final ChannelHandlerContext ctx, Object packet, final ChannelPromise promise) throws Exception {
|
||||
packet = PacketEvents.get().packetHandlerInternal.write(player, ctx.channel(), packet);
|
||||
if (packet != null) {
|
||||
super.write(ctx, packet, promise);
|
||||
PacketEvents.get().packetHandlerInternal.postWrite(player, ctx.channel(), packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package io.github.retrooper.packetevents.injector.earlyinjector;
|
||||
|
||||
import io.github.retrooper.packetevents.injector.ChannelInjector;
|
||||
|
||||
public interface EarlyInjector extends ChannelInjector {
|
||||
void prepare();
|
||||
|
||||
void cleanup();
|
||||
|
||||
Object injectChannel(Object channel);
|
||||
|
||||
void ejectChannel(Object channel);
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.injector.lateinjector;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
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.ChannelPromise;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class LateChannelInjector7 implements LateInjector {
|
||||
@Override
|
||||
public void injectPlayerSync(Player player) {
|
||||
final ChannelDuplexHandler channelDuplexHandler = new ChannelDuplexHandler() {
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object packet) throws Exception {
|
||||
packet = PacketEvents.get().packetHandlerInternal.read(player, ctx.channel(), packet);
|
||||
if (packet != null) {
|
||||
super.channelRead(ctx, packet);
|
||||
PacketEvents.get().packetHandlerInternal.postRead(player, ctx.channel(), packet);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ChannelHandlerContext ctx, Object packet, ChannelPromise promise) throws Exception {
|
||||
packet = PacketEvents.get().packetHandlerInternal.write(player, ctx.channel(), packet);
|
||||
if (packet != null) {
|
||||
super.write(ctx, packet, promise);
|
||||
PacketEvents.get().packetHandlerInternal.postWrite(player, ctx.channel(), packet);
|
||||
}
|
||||
}
|
||||
};
|
||||
final Channel channel = (Channel) PacketEvents.get().packetHandlerInternal.getChannel(player);
|
||||
channel.pipeline().addBefore("packet_handler", PacketEvents.handlerName, channelDuplexHandler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ejectPlayerSync(Player player) {
|
||||
final Channel channel = (Channel) PacketEvents.get().packetHandlerInternal.getChannel(player);
|
||||
if (channel.pipeline().get(PacketEvents.handlerName) != null) {
|
||||
channel.pipeline().remove(PacketEvents.handlerName);
|
||||
}
|
||||
PacketEvents.get().getPlayerUtils().clientVersionsMap.remove(player.getAddress());
|
||||
PacketEvents.get().getPlayerUtils().tempClientVersionMap.remove(player.getAddress());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectPlayerAsync(Player player) {
|
||||
PacketEvents.get().injectAndEjectExecutorService.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
injectPlayerSync(player);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ejectPlayerAsync(Player player) {
|
||||
PacketEvents.get().injectAndEjectExecutorService.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Channel channel = (Channel) PacketEvents.get().packetHandlerInternal.getChannel(player);
|
||||
if (channel.pipeline().get(PacketEvents.handlerName) != null) {
|
||||
channel.pipeline().remove(PacketEvents.handlerName);
|
||||
}
|
||||
PacketEvents.get().packetHandlerInternal.keepAliveMap.remove(player.getUniqueId());
|
||||
PacketEvents.get().packetHandlerInternal.channelMap.remove(player.getName());
|
||||
PacketEvents.get().getPlayerUtils().clientVersionsMap.remove(player.getAddress());
|
||||
PacketEvents.get().getPlayerUtils().tempClientVersionMap.remove(player.getAddress());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacket(Object rawChannel, Object packet) {
|
||||
Channel channel = (Channel) rawChannel;
|
||||
channel.pipeline().writeAndFlush(packet);
|
||||
}
|
||||
}
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.injector.lateinjector;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelDuplexHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
public class LateChannelInjector8 implements LateInjector {
|
||||
@Override
|
||||
public void injectPlayerSync(Player player) {
|
||||
final ChannelDuplexHandler channelDuplexHandler = new ChannelDuplexHandler() {
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object packet) throws Exception {
|
||||
packet = PacketEvents.get().packetHandlerInternal.read(player, ctx.channel(), packet);
|
||||
if (packet != null) {
|
||||
super.channelRead(ctx, packet);
|
||||
PacketEvents.get().packetHandlerInternal.postRead(player, ctx.channel(), packet);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ChannelHandlerContext ctx, Object packet, ChannelPromise promise) throws Exception {
|
||||
packet = PacketEvents.get().packetHandlerInternal.write(player, ctx.channel(), packet);
|
||||
if (packet != null) {
|
||||
super.write(ctx, packet, promise);
|
||||
PacketEvents.get().packetHandlerInternal.postWrite(player, ctx.channel(), packet);
|
||||
}
|
||||
}
|
||||
};
|
||||
final Channel channel = (Channel) PacketEvents.get().packetHandlerInternal.getChannel(player);
|
||||
channel.pipeline().addBefore("packet_handler", PacketEvents.handlerName, channelDuplexHandler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ejectPlayerSync(Player player) {
|
||||
final Channel channel = (Channel) PacketEvents.get().packetHandlerInternal.getChannel(player);
|
||||
if (channel.pipeline().get(PacketEvents.handlerName) != null) {
|
||||
try {
|
||||
channel.pipeline().remove(PacketEvents.handlerName);
|
||||
} catch (NoSuchElementException ignored) {
|
||||
|
||||
}
|
||||
}
|
||||
PacketEvents.get().getPlayerUtils().clientVersionsMap.remove(player.getAddress());
|
||||
PacketEvents.get().getPlayerUtils().tempClientVersionMap.remove(player.getAddress());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectPlayerAsync(Player player) {
|
||||
PacketEvents.get().injectAndEjectExecutorService.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
injectPlayerSync(player);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ejectPlayerAsync(Player player) {
|
||||
PacketEvents.get().injectAndEjectExecutorService.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Channel channel = (Channel) PacketEvents.get().packetHandlerInternal.getChannel(player);
|
||||
if (channel.pipeline().get(PacketEvents.handlerName) != null) {
|
||||
try {
|
||||
channel.pipeline().remove(PacketEvents.handlerName);
|
||||
} catch (NoSuchElementException ignored) {
|
||||
|
||||
}
|
||||
}
|
||||
PacketEvents.get().packetHandlerInternal.keepAliveMap.remove(player.getUniqueId());
|
||||
PacketEvents.get().packetHandlerInternal.channelMap.remove(player.getName());
|
||||
PacketEvents.get().getPlayerUtils().clientVersionsMap.remove(player.getAddress());
|
||||
PacketEvents.get().getPlayerUtils().tempClientVersionMap.remove(player.getAddress());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacket(Object rawChannel, Object packet) {
|
||||
Channel channel = (Channel) rawChannel;
|
||||
channel.pipeline().writeAndFlush(packet);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package io.github.retrooper.packetevents.injector.lateinjector;
|
||||
|
||||
import io.github.retrooper.packetevents.injector.ChannelInjector;
|
||||
|
||||
public interface LateInjector extends ChannelInjector {
|
||||
|
||||
}
|
||||
@@ -1,216 +0,0 @@
|
||||
package io.github.retrooper.packetevents.packet;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class PacketType {
|
||||
|
||||
public static class Client {
|
||||
public static final Map<Class<?>, Byte> packetIds = new HashMap<Class<?>, Byte>();
|
||||
public static final byte TELEPORT_ACCEPT = 0,
|
||||
TILE_NBT_QUERY = 1, DIFFICULTY_CHANGE = 2, CHAT = 3, CLIENT_COMMAND = 4,
|
||||
SETTINGS = 5, TAB_COMPLETE = 6, TRANSACTION = 7, ENCHANT_ITEM = 8,
|
||||
WINDOW_CLICK = 9, CLOSE_WINDOW = 10, CUSTOM_PAYLOAD = 11, B_EDIT = 12,
|
||||
ENTITY_NBT_QUERY = 13, USE_ENTITY = 14, JIGSAW_GENERATE = 15, KEEP_ALIVE = 16,
|
||||
DIFFICULTY_LOCK = 17, POSITION = 18, POSITION_LOOK = 19, LOOK = 20,
|
||||
FLYING = 21, VEHICLE_MOVE = 22, BOAT_MOVE = 23, PICK_ITEM = 24,
|
||||
AUTO_RECIPE = 25, ABILITIES = 26, BLOCK_DIG = 27, ENTITY_ACTION = 28,
|
||||
STEER_VEHICLE = 29, RECIPE_DISPLAYED = 30, ITEM_NAME = 31, RESOURCE_PACK_STATUS = 32,
|
||||
ADVANCEMENTS = 33, TR_SEL = 34, BEACON = 35, HELD_ITEM_SLOT = 36,
|
||||
SET_COMMAND_BLOCK = 37, SET_COMMAND_MINECART = 38, SET_CREATIVE_SLOT = 39, SET_JIGSAW = 40,
|
||||
STRUCT = 41, UPDATE_SIGN = 42, ARM_ANIMATION = 43, SPECTATE = 44,
|
||||
USE_ITEM = 45, BLOCK_PLACE = 46;
|
||||
|
||||
public static void init() {
|
||||
packetIds.put(PacketTypeClasses.Client.TELEPORT_ACCEPT, TELEPORT_ACCEPT);
|
||||
packetIds.put(PacketTypeClasses.Client.TILE_NBT_QUERY, TILE_NBT_QUERY);
|
||||
packetIds.put(PacketTypeClasses.Client.DIFFICULTY_CHANGE, DIFFICULTY_CHANGE);
|
||||
packetIds.put(PacketTypeClasses.Client.CHAT, CHAT);
|
||||
packetIds.put(PacketTypeClasses.Client.CLIENT_COMMAND, CLIENT_COMMAND);
|
||||
packetIds.put(PacketTypeClasses.Client.SETTINGS, SETTINGS);
|
||||
packetIds.put(PacketTypeClasses.Client.TAB_COMPLETE, TAB_COMPLETE);
|
||||
packetIds.put(PacketTypeClasses.Client.TRANSACTION, TRANSACTION);
|
||||
packetIds.put(PacketTypeClasses.Client.ENCHANT_ITEM, ENCHANT_ITEM);
|
||||
packetIds.put(PacketTypeClasses.Client.WINDOW_CLICK, WINDOW_CLICK);
|
||||
packetIds.put(PacketTypeClasses.Client.CLOSE_WINDOW, CLOSE_WINDOW);
|
||||
packetIds.put(PacketTypeClasses.Client.CUSTOM_PAYLOAD, CUSTOM_PAYLOAD);
|
||||
packetIds.put(PacketTypeClasses.Client.B_EDIT, B_EDIT);
|
||||
packetIds.put(PacketTypeClasses.Client.ENTITY_NBT_QUERY, ENTITY_NBT_QUERY);
|
||||
packetIds.put(PacketTypeClasses.Client.USE_ENTITY, USE_ENTITY);
|
||||
packetIds.put(PacketTypeClasses.Client.JIGSAW_GENERATE, JIGSAW_GENERATE);
|
||||
packetIds.put(PacketTypeClasses.Client.KEEP_ALIVE, KEEP_ALIVE);
|
||||
packetIds.put(PacketTypeClasses.Client.DIFFICULTY_LOCK, DIFFICULTY_LOCK);
|
||||
packetIds.put(PacketTypeClasses.Client.POSITION, POSITION);
|
||||
packetIds.put(PacketTypeClasses.Client.POSITION_LOOK, POSITION_LOOK);
|
||||
packetIds.put(PacketTypeClasses.Client.LOOK, LOOK);
|
||||
packetIds.put(PacketTypeClasses.Client.FLYING, FLYING);
|
||||
packetIds.put(PacketTypeClasses.Client.VEHICLE_MOVE, VEHICLE_MOVE);
|
||||
packetIds.put(PacketTypeClasses.Client.BOAT_MOVE, BOAT_MOVE);
|
||||
packetIds.put(PacketTypeClasses.Client.PICK_ITEM, PICK_ITEM);
|
||||
packetIds.put(PacketTypeClasses.Client.AUTO_RECIPE, AUTO_RECIPE);
|
||||
packetIds.put(PacketTypeClasses.Client.ABILITIES, ABILITIES);
|
||||
packetIds.put(PacketTypeClasses.Client.BLOCK_DIG, BLOCK_DIG);
|
||||
packetIds.put(PacketTypeClasses.Client.ENTITY_ACTION, ENTITY_ACTION);
|
||||
packetIds.put(PacketTypeClasses.Client.STEER_VEHICLE, STEER_VEHICLE);
|
||||
packetIds.put(PacketTypeClasses.Client.RECIPE_DISPLAYED, RECIPE_DISPLAYED);
|
||||
packetIds.put(PacketTypeClasses.Client.ITEM_NAME, ITEM_NAME);
|
||||
packetIds.put(PacketTypeClasses.Client.RESOURCE_PACK_STATUS, RESOURCE_PACK_STATUS);
|
||||
packetIds.put(PacketTypeClasses.Client.ADVANCEMENTS, ADVANCEMENTS);
|
||||
packetIds.put(PacketTypeClasses.Client.TR_SEL, TR_SEL);
|
||||
packetIds.put(PacketTypeClasses.Client.BEACON, BEACON);
|
||||
packetIds.put(PacketTypeClasses.Client.HELD_ITEM_SLOT, HELD_ITEM_SLOT);
|
||||
packetIds.put(PacketTypeClasses.Client.SET_COMMAND_BLOCK, SET_COMMAND_BLOCK);
|
||||
packetIds.put(PacketTypeClasses.Client.SET_COMMAND_MINECART, SET_COMMAND_MINECART);
|
||||
packetIds.put(PacketTypeClasses.Client.SET_CREATIVE_SLOT, SET_CREATIVE_SLOT);
|
||||
packetIds.put(PacketTypeClasses.Client.SET_JIGSAW, SET_JIGSAW);
|
||||
packetIds.put(PacketTypeClasses.Client.STRUCT, STRUCT);
|
||||
packetIds.put(PacketTypeClasses.Client.UPDATE_SIGN, UPDATE_SIGN);
|
||||
packetIds.put(PacketTypeClasses.Client.ARM_ANIMATION, ARM_ANIMATION);
|
||||
packetIds.put(PacketTypeClasses.Client.SPECTATE, SPECTATE);
|
||||
packetIds.put(PacketTypeClasses.Client.USE_ITEM, USE_ITEM);
|
||||
packetIds.put(PacketTypeClasses.Client.BLOCK_PLACE, BLOCK_PLACE);
|
||||
}
|
||||
|
||||
public static class Util {
|
||||
public static boolean isInstanceOfFlying(final byte packetId) {
|
||||
return packetId == FLYING
|
||||
|| packetId == POSITION
|
||||
|| packetId == POSITION_LOOK
|
||||
|| packetId == LOOK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class Server {
|
||||
public static final Map<Class<?>, Byte> packetIds = new HashMap<Class<?>, Byte>();
|
||||
public static byte SPAWN_ENTITY = 0, SPAWN_ENTITY_EXPERIENCE_ORB = 1, SPAWN_ENTITY_WEATHER = 2, SPAWN_ENTITY_LIVING = 3,
|
||||
SPAWN_ENTITY_PAINTING = 4, SPAWN_ENTITY_SPAWN = 5, ANIMATION = 6, STATISTIC = 7,
|
||||
BLOCK_BREAK = 8, BLOCK_BREAK_ANIMATION = 9, TILE_ENTITY_DATA = 10, BLOCK_ACTION = 11,
|
||||
BLOCK_CHANGE = 12, BOSS = 13, SERVER_DIFFICULTY = 14, CHAT = 15, MULTI_BLOCK_CHANGE = 16,
|
||||
TAB_COMPLETE = 17, COMMANDS = 18, TRANSACTION = 19, CLOSE_WINDOW = 20,
|
||||
WINDOW_ITEMS = 21, WINDOW_DATA = 22, SET_SLOT = 23, SET_COOLDOWN = 24,
|
||||
CUSTOM_PAYLOAD = 25, CUSTOM_SOUND_EFFECT = 26, KICK_DISCONNECT = 27, ENTITY_STATUS = 28,
|
||||
EXPLOSION = 29, UNLOAD_CHUNK = 30, GAME_STATE_CHANGE = 31, OPEN_WINDOW_HORSE = 32,
|
||||
KEEP_ALIVE = 33, MAP_CHUNK = 34, WORLD_EVENT = 35, WORLD_PARTICLES = 36,
|
||||
LIGHT_UPDATE = 37, LOGIN = 38, MAP = 39, OPEN_WINDOW_MERCHANT = 40,
|
||||
REL_ENTITY_MOVE = 41, REL_ENTITY_MOVE_LOOK = 42, ENTITY_LOOK = 43, ENTITY = 44,
|
||||
VEHICLE_MOVE = 45, OPEN_BOOK = 46, OPEN_WINDOW = 47, OPEN_SIGN_EDITOR = 48,
|
||||
AUTO_RECIPE = 49, ABILITIES = 50, COMBAT_EVENT = 51, PLAYER_INFO = 52,
|
||||
LOOK_AT = 53, POSITION = 54, RECIPES = 55, ENTITY_DESTROY = 56,
|
||||
REMOVE_ENTITY_EFFECT = 57, RESOURCE_PACK_SEND = 58, RESPAWN = 59, ENTITY_HEAD_ROTATION = 60,
|
||||
SELECT_ADVANCEMENT_TAB = 61, WORLD_BORDER = 62, CAMERA = 63, HELD_ITEM_SLOT = 64,
|
||||
VIEW_CENTRE = 65, VIEW_DISTANCE = 66, SCOREBOARD_DISPLAY_OBJECTIVE = 67, ENTITY_METADATA = 68,
|
||||
ATTACH_ENTITY = 69, ENTITY_VELOCITY = 70, ENTITY_EQUIPMENT = 71, EXPERIENCE = 72,
|
||||
UPDATE_HEALTH = 73, SCOREBOARD_OBJECTIVE = 74, MOUNT = 75, SCOREBOARD_TEAM = 76,
|
||||
SCOREBOARD_SCORE = 77, SPAWN_POSITION = 78, UPDATE_TIME = 79, TITLE = 80,
|
||||
ENTITY_SOUND = 81, NAMED_SOUND_EFFECT = 82, STOP_SOUND = 83, PLAYER_LIST_HEADER_FOOTER = 84,
|
||||
NBT_QUERY = 85, COLLECT = 86, ENTITY_TELEPORT = 87, ADVANCEMENTS = 88, UPDATE_ATTRIBUTES = 89,
|
||||
ENTITY_EFFECT = 90, RECIPE_UPDATE = 91, TAGS = 92, MAP_CHUNK_BULK = 93;
|
||||
|
||||
public static void init() {
|
||||
packetIds.put(PacketTypeClasses.Server.SPAWN_ENTITY, SPAWN_ENTITY);
|
||||
packetIds.put(PacketTypeClasses.Server.SPAWN_ENTITY_EXPERIENCE_ORB, SPAWN_ENTITY_EXPERIENCE_ORB);
|
||||
packetIds.put(PacketTypeClasses.Server.SPAWN_ENTITY_WEATHER, SPAWN_ENTITY_WEATHER);
|
||||
packetIds.put(PacketTypeClasses.Server.SPAWN_ENTITY_LIVING, SPAWN_ENTITY_LIVING);
|
||||
packetIds.put(PacketTypeClasses.Server.SPAWN_ENTITY_PAINTING, SPAWN_ENTITY_PAINTING);
|
||||
packetIds.put(PacketTypeClasses.Server.SPAWN_ENTITY_SPAWN, SPAWN_ENTITY_SPAWN);
|
||||
packetIds.put(PacketTypeClasses.Server.ANIMATION, ANIMATION);
|
||||
packetIds.put(PacketTypeClasses.Server.STATISTIC, STATISTIC);
|
||||
packetIds.put(PacketTypeClasses.Server.BLOCK_BREAK, BLOCK_BREAK);
|
||||
packetIds.put(PacketTypeClasses.Server.BLOCK_BREAK_ANIMATION, BLOCK_BREAK_ANIMATION);
|
||||
packetIds.put(PacketTypeClasses.Server.TILE_ENTITY_DATA, TILE_ENTITY_DATA);
|
||||
packetIds.put(PacketTypeClasses.Server.BLOCK_ACTION, BLOCK_ACTION);
|
||||
packetIds.put(PacketTypeClasses.Server.BLOCK_CHANGE, BLOCK_CHANGE);
|
||||
packetIds.put(PacketTypeClasses.Server.BOSS, BOSS);
|
||||
packetIds.put(PacketTypeClasses.Server.SPAWN_ENTITY, SPAWN_ENTITY);
|
||||
packetIds.put(PacketTypeClasses.Server.SERVER_DIFFICULTY, SERVER_DIFFICULTY);
|
||||
packetIds.put(PacketTypeClasses.Server.CHAT, CHAT);
|
||||
packetIds.put(PacketTypeClasses.Server.MULTI_BLOCK_CHANGE, MULTI_BLOCK_CHANGE);
|
||||
packetIds.put(PacketTypeClasses.Server.TAB_COMPLETE, TAB_COMPLETE);
|
||||
packetIds.put(PacketTypeClasses.Server.COMMANDS, COMMANDS);
|
||||
packetIds.put(PacketTypeClasses.Server.TRANSACTION, TRANSACTION);
|
||||
packetIds.put(PacketTypeClasses.Server.CLOSE_WINDOW, CLOSE_WINDOW);
|
||||
packetIds.put(PacketTypeClasses.Server.WINDOW_ITEMS, WINDOW_ITEMS);
|
||||
packetIds.put(PacketTypeClasses.Server.WINDOW_DATA, WINDOW_DATA);
|
||||
packetIds.put(PacketTypeClasses.Server.SET_SLOT, SET_SLOT);
|
||||
packetIds.put(PacketTypeClasses.Server.CUSTOM_PAYLOAD, CUSTOM_PAYLOAD);
|
||||
packetIds.put(PacketTypeClasses.Server.CUSTOM_SOUND_EFFECT, CUSTOM_SOUND_EFFECT);
|
||||
packetIds.put(PacketTypeClasses.Server.KICK_DISCONNECT, KICK_DISCONNECT);
|
||||
packetIds.put(PacketTypeClasses.Server.ENTITY_STATUS, ENTITY_STATUS);
|
||||
packetIds.put(PacketTypeClasses.Server.EXPLOSION, EXPLOSION);
|
||||
packetIds.put(PacketTypeClasses.Server.UNLOAD_CHUNK, UNLOAD_CHUNK);
|
||||
packetIds.put(PacketTypeClasses.Server.GAME_STATE_CHANGE, GAME_STATE_CHANGE);
|
||||
packetIds.put(PacketTypeClasses.Server.OPEN_WINDOW_HORSE, OPEN_WINDOW_HORSE);
|
||||
packetIds.put(PacketTypeClasses.Server.KEEP_ALIVE, KEEP_ALIVE);
|
||||
packetIds.put(PacketTypeClasses.Server.MAP_CHUNK, MAP_CHUNK);
|
||||
packetIds.put(PacketTypeClasses.Server.WORLD_EVENT, SPAWN_ENTITY);
|
||||
packetIds.put(PacketTypeClasses.Server.WORLD_PARTICLES, WORLD_PARTICLES);
|
||||
packetIds.put(PacketTypeClasses.Server.LIGHT_UPDATE, LIGHT_UPDATE);
|
||||
packetIds.put(PacketTypeClasses.Server.LOGIN, LOGIN);
|
||||
packetIds.put(PacketTypeClasses.Server.MAP, MAP);
|
||||
packetIds.put(PacketTypeClasses.Server.OPEN_WINDOW_MERCHANT, OPEN_WINDOW_MERCHANT);
|
||||
packetIds.put(PacketTypeClasses.Server.REL_ENTITY_MOVE, REL_ENTITY_MOVE);
|
||||
packetIds.put(PacketTypeClasses.Server.REL_ENTITY_MOVE_LOOK, REL_ENTITY_MOVE_LOOK);
|
||||
packetIds.put(PacketTypeClasses.Server.ENTITY_LOOK, ENTITY_LOOK);
|
||||
packetIds.put(PacketTypeClasses.Server.ENTITY, ENTITY);
|
||||
packetIds.put(PacketTypeClasses.Server.VEHICLE_MOVE, VEHICLE_MOVE);
|
||||
packetIds.put(PacketTypeClasses.Server.OPEN_BOOK, OPEN_BOOK);
|
||||
packetIds.put(PacketTypeClasses.Server.OPEN_WINDOW, OPEN_WINDOW);
|
||||
packetIds.put(PacketTypeClasses.Server.OPEN_SIGN_EDITOR, OPEN_SIGN_EDITOR);
|
||||
packetIds.put(PacketTypeClasses.Server.AUTO_RECIPE, AUTO_RECIPE);
|
||||
packetIds.put(PacketTypeClasses.Server.ABILITIES, ABILITIES);
|
||||
packetIds.put(PacketTypeClasses.Server.COMBAT_EVENT, COMBAT_EVENT);
|
||||
packetIds.put(PacketTypeClasses.Server.PLAYER_INFO, PLAYER_INFO);
|
||||
packetIds.put(PacketTypeClasses.Server.LOOK_AT, LOOK_AT);
|
||||
packetIds.put(PacketTypeClasses.Server.POSITION, POSITION);
|
||||
packetIds.put(PacketTypeClasses.Server.RECIPES, RECIPES);
|
||||
packetIds.put(PacketTypeClasses.Server.ENTITY_DESTROY, ENTITY_DESTROY);
|
||||
packetIds.put(PacketTypeClasses.Server.REMOVE_ENTITY_EFFECT, REMOVE_ENTITY_EFFECT);
|
||||
packetIds.put(PacketTypeClasses.Server.RESOURCE_PACK_SEND, RESOURCE_PACK_SEND);
|
||||
packetIds.put(PacketTypeClasses.Server.RESPAWN, RESPAWN);
|
||||
packetIds.put(PacketTypeClasses.Server.ENTITY_HEAD_ROTATION, ENTITY_HEAD_ROTATION);
|
||||
packetIds.put(PacketTypeClasses.Server.SELECT_ADVANCEMENT_TAB, SELECT_ADVANCEMENT_TAB);
|
||||
packetIds.put(PacketTypeClasses.Server.WORLD_BORDER, WORLD_BORDER);
|
||||
packetIds.put(PacketTypeClasses.Server.CAMERA, CAMERA);
|
||||
packetIds.put(PacketTypeClasses.Server.HELD_ITEM_SLOT, HELD_ITEM_SLOT);
|
||||
packetIds.put(PacketTypeClasses.Server.VIEW_CENTRE, VIEW_CENTRE);
|
||||
packetIds.put(PacketTypeClasses.Server.VIEW_DISTANCE, VIEW_DISTANCE);
|
||||
packetIds.put(PacketTypeClasses.Server.SCOREBOARD_DISPLAY_OBJECTIVE, SCOREBOARD_DISPLAY_OBJECTIVE);
|
||||
packetIds.put(PacketTypeClasses.Server.ENTITY_METADATA, ENTITY_METADATA);
|
||||
packetIds.put(PacketTypeClasses.Server.ATTACH_ENTITY, ATTACH_ENTITY);
|
||||
packetIds.put(PacketTypeClasses.Server.ENTITY_VELOCITY, ENTITY_VELOCITY);
|
||||
packetIds.put(PacketTypeClasses.Server.ENTITY_EQUIPMENT, ENTITY_EQUIPMENT);
|
||||
packetIds.put(PacketTypeClasses.Server.EXPERIENCE, EXPERIENCE);
|
||||
packetIds.put(PacketTypeClasses.Server.UPDATE_HEALTH, UPDATE_HEALTH);
|
||||
packetIds.put(PacketTypeClasses.Server.SCOREBOARD_OBJECTIVE, SCOREBOARD_OBJECTIVE);
|
||||
packetIds.put(PacketTypeClasses.Server.MOUNT, MOUNT);
|
||||
packetIds.put(PacketTypeClasses.Server.SCOREBOARD_TEAM, SCOREBOARD_TEAM);
|
||||
packetIds.put(PacketTypeClasses.Server.SCOREBOARD_SCORE, SCOREBOARD_SCORE);
|
||||
packetIds.put(PacketTypeClasses.Server.SPAWN_POSITION, SPAWN_POSITION);
|
||||
packetIds.put(PacketTypeClasses.Server.UPDATE_TIME, UPDATE_TIME);
|
||||
packetIds.put(PacketTypeClasses.Server.TITLE, TITLE);
|
||||
packetIds.put(PacketTypeClasses.Server.ENTITY_SOUND, ENTITY_SOUND);
|
||||
packetIds.put(PacketTypeClasses.Server.NAMED_SOUND_EFFECT, NAMED_SOUND_EFFECT);
|
||||
packetIds.put(PacketTypeClasses.Server.STOP_SOUND, STOP_SOUND);
|
||||
packetIds.put(PacketTypeClasses.Server.PLAYER_LIST_HEADER_FOOTER, PLAYER_LIST_HEADER_FOOTER);
|
||||
packetIds.put(PacketTypeClasses.Server.NBT_QUERY, NBT_QUERY);
|
||||
packetIds.put(PacketTypeClasses.Server.COLLECT, COLLECT);
|
||||
packetIds.put(PacketTypeClasses.Server.ENTITY_TELEPORT, ENTITY_TELEPORT);
|
||||
packetIds.put(PacketTypeClasses.Server.ADVANCEMENTS, ADVANCEMENTS);
|
||||
packetIds.put(PacketTypeClasses.Server.UPDATE_ATTRIBUTES, UPDATE_ATTRIBUTES);
|
||||
packetIds.put(PacketTypeClasses.Server.ENTITY_EFFECT, ENTITY_EFFECT);
|
||||
packetIds.put(PacketTypeClasses.Server.RECIPE_UPDATE, RECIPE_UPDATE);
|
||||
packetIds.put(PacketTypeClasses.Server.TAGS, TAGS);
|
||||
packetIds.put(PacketTypeClasses.Server.MAP_CHUNK_BULK, MAP_CHUNK_BULK);
|
||||
}
|
||||
|
||||
public static class Util {
|
||||
public static boolean isInstanceOfEntity(final byte packetId) {
|
||||
return packetId == ENTITY || packetId == REL_ENTITY_MOVE ||
|
||||
packetId == REL_ENTITY_MOVE_LOOK || packetId == ENTITY_LOOK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,234 +0,0 @@
|
||||
package io.github.retrooper.packetevents.packet;
|
||||
|
||||
import io.github.retrooper.packetevents.annotations.Nullable;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
|
||||
public class PacketTypeClasses {
|
||||
public static class Client {
|
||||
private static final String c = "PacketPlayIn";
|
||||
@Nullable
|
||||
public static final Class<?> FLYING = NMSUtils.getNMSClassWithoutException(c + "Flying");
|
||||
public static Class<?> POSITION, POSITION_LOOK, LOOK, CLIENT_COMMAND,
|
||||
TRANSACTION, BLOCK_DIG, ENTITY_ACTION, USE_ENTITY,
|
||||
WINDOW_CLICK, STEER_VEHICLE, CUSTOM_PAYLOAD, ARM_ANIMATION,
|
||||
BLOCK_PLACE, USE_ITEM, ABILITIES, HELD_ITEM_SLOT,
|
||||
CLOSE_WINDOW, TAB_COMPLETE, CHAT, SET_CREATIVE_SLOT,
|
||||
KEEP_ALIVE, SETTINGS, ENCHANT_ITEM, TELEPORT_ACCEPT,
|
||||
TILE_NBT_QUERY, DIFFICULTY_CHANGE, B_EDIT, ENTITY_NBT_QUERY,
|
||||
JIGSAW_GENERATE, DIFFICULTY_LOCK, VEHICLE_MOVE, BOAT_MOVE, PICK_ITEM,
|
||||
AUTO_RECIPE, RECIPE_DISPLAYED, ITEM_NAME, RESOURCE_PACK_STATUS,
|
||||
ADVANCEMENTS, TR_SEL, BEACON, SET_COMMAND_BLOCK,
|
||||
SET_COMMAND_MINECART, SET_JIGSAW, STRUCT, UPDATE_SIGN, SPECTATE;
|
||||
|
||||
public static void load() {
|
||||
try {
|
||||
POSITION = NMSUtils.getNMSClass(c + "Position");
|
||||
POSITION_LOOK = NMSUtils.getNMSClass(c + "PositionLook");
|
||||
LOOK = NMSUtils.getNMSClass(c + "Look");
|
||||
} catch (ClassNotFoundException e) {
|
||||
POSITION = Reflection.getSubClass(FLYING, c + "Position");
|
||||
POSITION_LOOK = Reflection.getSubClass(FLYING, c + "PositionLook");
|
||||
LOOK = Reflection.getSubClass(FLYING, c + "Look");
|
||||
}
|
||||
|
||||
try {
|
||||
SETTINGS = NMSUtils.getNMSClass(c + "Settings");
|
||||
ENCHANT_ITEM = NMSUtils.getNMSClass(c + "EnchantItem");
|
||||
|
||||
CLIENT_COMMAND = NMSUtils.getNMSClass(c + "ClientCommand");
|
||||
TRANSACTION = NMSUtils.getNMSClass(c + "Transaction");
|
||||
BLOCK_DIG = NMSUtils.getNMSClass(c + "BlockDig");
|
||||
ENTITY_ACTION = NMSUtils.getNMSClass(c + "EntityAction");
|
||||
USE_ENTITY = NMSUtils.getNMSClass(c + "UseEntity");
|
||||
WINDOW_CLICK = NMSUtils.getNMSClass(c + "WindowClick");
|
||||
STEER_VEHICLE = NMSUtils.getNMSClass(c + "SteerVehicle");
|
||||
CUSTOM_PAYLOAD = NMSUtils.getNMSClass(c + "CustomPayload");
|
||||
ARM_ANIMATION = NMSUtils.getNMSClass(c + "ArmAnimation");
|
||||
ABILITIES = NMSUtils.getNMSClass(c + "Abilities");
|
||||
HELD_ITEM_SLOT = NMSUtils.getNMSClass(c + "HeldItemSlot");
|
||||
CLOSE_WINDOW = NMSUtils.getNMSClass(c + "CloseWindow");
|
||||
TAB_COMPLETE = NMSUtils.getNMSClass(c + "TabComplete");
|
||||
CHAT = NMSUtils.getNMSClass(c + "Chat");
|
||||
SET_CREATIVE_SLOT = NMSUtils.getNMSClass(c + "SetCreativeSlot");
|
||||
KEEP_ALIVE = NMSUtils.getNMSClass(c + "KeepAlive");
|
||||
UPDATE_SIGN = NMSUtils.getNMSClassWithoutException(c + "UpdateSign");
|
||||
|
||||
TELEPORT_ACCEPT = NMSUtils.getNMSClassWithoutException(c + "TeleportAccept");
|
||||
TILE_NBT_QUERY = NMSUtils.getNMSClassWithoutException(c + "TileNBTQuery");
|
||||
DIFFICULTY_CHANGE = NMSUtils.getNMSClassWithoutException(c + "DifficultyChange");
|
||||
B_EDIT = NMSUtils.getNMSClassWithoutException(c + "BEdit");
|
||||
ENTITY_NBT_QUERY = NMSUtils.getNMSClassWithoutException(c + "EntityNBTQuery");
|
||||
JIGSAW_GENERATE = NMSUtils.getNMSClassWithoutException(c + "JigsawGenerate");
|
||||
DIFFICULTY_LOCK = NMSUtils.getNMSClassWithoutException(c + "DifficultyLock");
|
||||
VEHICLE_MOVE = NMSUtils.getNMSClassWithoutException(c + "VehicleMove");
|
||||
BOAT_MOVE = NMSUtils.getNMSClassWithoutException(c + "BoatMove");
|
||||
PICK_ITEM = NMSUtils.getNMSClassWithoutException(c + "PickItem");
|
||||
AUTO_RECIPE = NMSUtils.getNMSClassWithoutException(c + "AutoRecipe");
|
||||
RECIPE_DISPLAYED = NMSUtils.getNMSClassWithoutException(c + "RecipeDisplayed");
|
||||
ITEM_NAME = NMSUtils.getNMSClassWithoutException(c + "ItemName");
|
||||
//1.8+
|
||||
RESOURCE_PACK_STATUS = NMSUtils.getNMSClassWithoutException(c + "ResourcePackStatus");
|
||||
|
||||
ADVANCEMENTS = NMSUtils.getNMSClassWithoutException(c + "Advancements");
|
||||
TR_SEL = NMSUtils.getNMSClassWithoutException(c + "TrSel");
|
||||
BEACON = NMSUtils.getNMSClassWithoutException(c + "Beacon");
|
||||
SET_COMMAND_BLOCK = NMSUtils.getNMSClassWithoutException(c + "SetCommandBlock");
|
||||
SET_COMMAND_MINECART = NMSUtils.getNMSClassWithoutException(c + "SetCommandMinecart");
|
||||
SET_JIGSAW = NMSUtils.getNMSClassWithoutException(c + "SetJigsaw");
|
||||
STRUCT = NMSUtils.getNMSClassWithoutException(c + "Struct");
|
||||
SPECTATE = NMSUtils.getNMSClassWithoutException(c + "Spectate");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
//Block place
|
||||
try {
|
||||
BLOCK_PLACE = NMSUtils.getNMSClass(c + "BlockPlace");
|
||||
} catch (ClassNotFoundException e) {
|
||||
//They are just on a newer version
|
||||
try {
|
||||
USE_ITEM = NMSUtils.getNMSClass(c + "UseItem");
|
||||
} catch (ClassNotFoundException e2) {
|
||||
e.printStackTrace();
|
||||
e2.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PacketType.Client.init();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Server {
|
||||
private static final String s = "PacketPlayOut";
|
||||
public static Class<?> SPAWN_ENTITY, SPAWN_ENTITY_EXPERIENCE_ORB, SPAWN_ENTITY_WEATHER, SPAWN_ENTITY_LIVING,
|
||||
SPAWN_ENTITY_PAINTING, SPAWN_ENTITY_SPAWN, ANIMATION, STATISTIC,
|
||||
BLOCK_BREAK, BLOCK_BREAK_ANIMATION, TILE_ENTITY_DATA, BLOCK_ACTION,
|
||||
BLOCK_CHANGE, BOSS, SERVER_DIFFICULTY, CHAT, MULTI_BLOCK_CHANGE,
|
||||
TAB_COMPLETE, COMMANDS, TRANSACTION, CLOSE_WINDOW,
|
||||
WINDOW_ITEMS, WINDOW_DATA, SET_SLOT, SET_COOLDOWN,
|
||||
CUSTOM_PAYLOAD, CUSTOM_SOUND_EFFECT, KICK_DISCONNECT, ENTITY_STATUS,
|
||||
EXPLOSION, UNLOAD_CHUNK, GAME_STATE_CHANGE, OPEN_WINDOW_HORSE,
|
||||
KEEP_ALIVE, MAP_CHUNK, WORLD_EVENT, WORLD_PARTICLES,
|
||||
LIGHT_UPDATE, LOGIN, MAP, OPEN_WINDOW_MERCHANT,
|
||||
REL_ENTITY_MOVE, REL_ENTITY_MOVE_LOOK, ENTITY_LOOK, ENTITY,
|
||||
VEHICLE_MOVE, OPEN_BOOK, OPEN_WINDOW, OPEN_SIGN_EDITOR,
|
||||
AUTO_RECIPE, ABILITIES, COMBAT_EVENT, PLAYER_INFO,
|
||||
LOOK_AT, POSITION, RECIPES, ENTITY_DESTROY,
|
||||
REMOVE_ENTITY_EFFECT, RESOURCE_PACK_SEND, RESPAWN, ENTITY_HEAD_ROTATION,
|
||||
SELECT_ADVANCEMENT_TAB, WORLD_BORDER, CAMERA, HELD_ITEM_SLOT,
|
||||
VIEW_CENTRE, VIEW_DISTANCE, SCOREBOARD_DISPLAY_OBJECTIVE, ENTITY_METADATA,
|
||||
ATTACH_ENTITY, ENTITY_VELOCITY, ENTITY_EQUIPMENT, EXPERIENCE,
|
||||
UPDATE_HEALTH, SCOREBOARD_OBJECTIVE, MOUNT, SCOREBOARD_TEAM,
|
||||
SCOREBOARD_SCORE, SPAWN_POSITION, UPDATE_TIME, TITLE,
|
||||
ENTITY_SOUND, NAMED_SOUND_EFFECT, STOP_SOUND, PLAYER_LIST_HEADER_FOOTER,
|
||||
NBT_QUERY, COLLECT, ENTITY_TELEPORT, ADVANCEMENTS, UPDATE_ATTRIBUTES,
|
||||
ENTITY_EFFECT, RECIPE_UPDATE, TAGS, MAP_CHUNK_BULK;
|
||||
|
||||
public static void load() {
|
||||
SPAWN_ENTITY = NMSUtils.getNMSClassWithoutException(s + "SpawnEntity");
|
||||
SPAWN_ENTITY_EXPERIENCE_ORB = NMSUtils.getNMSClassWithoutException(s + "SpawnEntityExperienceOrb");
|
||||
SPAWN_ENTITY_WEATHER = NMSUtils.getNMSClassWithoutException(s + "SpawnEntityWeather");
|
||||
SPAWN_ENTITY_LIVING = NMSUtils.getNMSClassWithoutException(s + "SpawnEntityLiving");
|
||||
SPAWN_ENTITY_PAINTING = NMSUtils.getNMSClassWithoutException(s + "SpawnEntityPainting");
|
||||
SPAWN_ENTITY_SPAWN = NMSUtils.getNMSClassWithoutException(s + "SpawnEntitySpawn");
|
||||
ANIMATION = NMSUtils.getNMSClassWithoutException(s + "Animation");
|
||||
STATISTIC = NMSUtils.getNMSClassWithoutException(s + "Statistic");
|
||||
BLOCK_BREAK = NMSUtils.getNMSClassWithoutException(s + "BlockBreak");
|
||||
BLOCK_BREAK_ANIMATION = NMSUtils.getNMSClassWithoutException(s + "BlockBreakAnimation");
|
||||
TILE_ENTITY_DATA = NMSUtils.getNMSClassWithoutException(s + "TileEntityData");
|
||||
BLOCK_ACTION = NMSUtils.getNMSClassWithoutException(s + "BlockAction");
|
||||
BLOCK_CHANGE = NMSUtils.getNMSClassWithoutException(s + "BlockChange");
|
||||
BOSS = NMSUtils.getNMSClassWithoutException(s + "Boss");
|
||||
SERVER_DIFFICULTY = NMSUtils.getNMSClassWithoutException(s + "ServerDifficulty");
|
||||
CHAT = NMSUtils.getNMSClassWithoutException(s + "Chat");
|
||||
MULTI_BLOCK_CHANGE = NMSUtils.getNMSClassWithoutException(s + "MultiBlockChange");
|
||||
TAB_COMPLETE = NMSUtils.getNMSClassWithoutException(s + "TabComplete");
|
||||
COMMANDS = NMSUtils.getNMSClassWithoutException(s + "Commands");
|
||||
TRANSACTION = NMSUtils.getNMSClassWithoutException(s + "Transaction");
|
||||
CLOSE_WINDOW = NMSUtils.getNMSClassWithoutException(s + "CloseWindow");
|
||||
WINDOW_ITEMS = NMSUtils.getNMSClassWithoutException(s + "WindowItems");
|
||||
WINDOW_DATA = NMSUtils.getNMSClassWithoutException(s + "WindowData");
|
||||
SET_SLOT = NMSUtils.getNMSClassWithoutException(s + "SetSlot");
|
||||
SET_COOLDOWN = NMSUtils.getNMSClassWithoutException(s + "SetCooldown");
|
||||
CUSTOM_PAYLOAD = NMSUtils.getNMSClassWithoutException(s + "CustomPayload");
|
||||
CUSTOM_SOUND_EFFECT = NMSUtils.getNMSClassWithoutException(s + "CustomSoundEffect");
|
||||
KICK_DISCONNECT = NMSUtils.getNMSClassWithoutException(s + "KickDisconnect");
|
||||
ENTITY_STATUS = NMSUtils.getNMSClassWithoutException(s + "EntityStatus");
|
||||
EXPLOSION = NMSUtils.getNMSClassWithoutException(s + "Explosion");
|
||||
UNLOAD_CHUNK = NMSUtils.getNMSClassWithoutException(s + "UnloadChunk");
|
||||
GAME_STATE_CHANGE = NMSUtils.getNMSClassWithoutException(s + "GameStateChange");
|
||||
OPEN_WINDOW_HORSE = NMSUtils.getNMSClassWithoutException(s + "OpenWindowHorse");
|
||||
KEEP_ALIVE = NMSUtils.getNMSClassWithoutException(s + "KeepAlive");
|
||||
MAP_CHUNK = NMSUtils.getNMSClassWithoutException(s + "MapChunk");
|
||||
WORLD_EVENT = NMSUtils.getNMSClassWithoutException(s + "WorldEvent");
|
||||
WORLD_PARTICLES = NMSUtils.getNMSClassWithoutException(s + "WorldParticles");
|
||||
LIGHT_UPDATE = NMSUtils.getNMSClassWithoutException(s + "LightUpdate");
|
||||
LOGIN = NMSUtils.getNMSClassWithoutException(s + "Login");
|
||||
MAP = NMSUtils.getNMSClassWithoutException(s + "Map");
|
||||
OPEN_WINDOW_MERCHANT = NMSUtils.getNMSClassWithoutException(s + "OpenWindowMerchant");
|
||||
ENTITY = NMSUtils.getNMSClassWithoutException(s + "Entity");
|
||||
REL_ENTITY_MOVE = Reflection.getSubClass(ENTITY, s + "RelEntityMove");
|
||||
REL_ENTITY_MOVE_LOOK = Reflection.getSubClass(ENTITY, s + "RelEntityMoveLook");
|
||||
ENTITY_LOOK = Reflection.getSubClass(ENTITY, s + "EntityLook");
|
||||
if (REL_ENTITY_MOVE == null) {
|
||||
//is not a subclass and should be accessed normally
|
||||
REL_ENTITY_MOVE = NMSUtils.getNMSClassWithoutException(s + "RelEntityMove");
|
||||
REL_ENTITY_MOVE_LOOK = NMSUtils.getNMSClassWithoutException(s + "RelEntityMoveLook");
|
||||
ENTITY_LOOK = NMSUtils.getNMSClassWithoutException(s + "RelEntityLook");
|
||||
}
|
||||
VEHICLE_MOVE = NMSUtils.getNMSClassWithoutException(s + "VehicleMove");
|
||||
OPEN_BOOK = NMSUtils.getNMSClassWithoutException(s + "OpenBook");
|
||||
OPEN_WINDOW = NMSUtils.getNMSClassWithoutException(s + "OpenWindow");
|
||||
OPEN_SIGN_EDITOR = NMSUtils.getNMSClassWithoutException(s + "OpenSignEditor");
|
||||
AUTO_RECIPE = NMSUtils.getNMSClassWithoutException(s + "AutoRecipe");
|
||||
ABILITIES = NMSUtils.getNMSClassWithoutException(s + "Abilities");
|
||||
COMBAT_EVENT = NMSUtils.getNMSClassWithoutException(s + "CombatEvent");
|
||||
PLAYER_INFO = NMSUtils.getNMSClassWithoutException(s + "PlayerInfo");
|
||||
LOOK_AT = NMSUtils.getNMSClassWithoutException(s + "LookAt");
|
||||
POSITION = NMSUtils.getNMSClassWithoutException(s + "Position");
|
||||
RECIPES = NMSUtils.getNMSClassWithoutException(s + "Recipes");
|
||||
ENTITY_DESTROY = NMSUtils.getNMSClassWithoutException(s + "EntityDestroy");
|
||||
REMOVE_ENTITY_EFFECT = NMSUtils.getNMSClassWithoutException(s + "RemoveEntityEffect");
|
||||
RESOURCE_PACK_SEND = NMSUtils.getNMSClassWithoutException(s + "ResourcePackSend");
|
||||
RESPAWN = NMSUtils.getNMSClassWithoutException(s + "Respawn");
|
||||
ENTITY_HEAD_ROTATION = NMSUtils.getNMSClassWithoutException(s + "EntityHeadRotation");
|
||||
SELECT_ADVANCEMENT_TAB = NMSUtils.getNMSClassWithoutException(s + "SelectAdvancementTab");
|
||||
WORLD_BORDER = NMSUtils.getNMSClassWithoutException(s + "WorldBorder");
|
||||
CAMERA = NMSUtils.getNMSClassWithoutException(s + "Camera");
|
||||
HELD_ITEM_SLOT = NMSUtils.getNMSClassWithoutException(s + "HeldItemSlot");
|
||||
VIEW_CENTRE = NMSUtils.getNMSClassWithoutException(s + "ViewCentre");
|
||||
VIEW_DISTANCE = NMSUtils.getNMSClassWithoutException(s + "ViewDistance");
|
||||
SCOREBOARD_DISPLAY_OBJECTIVE = NMSUtils.getNMSClassWithoutException(s + "ScoreboardDisplayObjective");
|
||||
ENTITY_METADATA = NMSUtils.getNMSClassWithoutException(s + "EntityMetadata");
|
||||
ATTACH_ENTITY = NMSUtils.getNMSClassWithoutException(s + "AttachEntity");
|
||||
ENTITY_VELOCITY = NMSUtils.getNMSClassWithoutException(s + "EntityVelocity");
|
||||
ENTITY_EQUIPMENT = NMSUtils.getNMSClassWithoutException(s + "EntityEquipment");
|
||||
EXPERIENCE = NMSUtils.getNMSClassWithoutException(s + "Experience");
|
||||
UPDATE_HEALTH = NMSUtils.getNMSClassWithoutException(s + "UpdateHealth");
|
||||
SCOREBOARD_OBJECTIVE = NMSUtils.getNMSClassWithoutException(s + "ScoreboardObjective");
|
||||
MOUNT = NMSUtils.getNMSClassWithoutException(s + "Mount");
|
||||
SCOREBOARD_TEAM = NMSUtils.getNMSClassWithoutException(s + "ScoreboardTeam");
|
||||
SCOREBOARD_SCORE = NMSUtils.getNMSClassWithoutException(s + "ScoreboardScore");
|
||||
SPAWN_POSITION = NMSUtils.getNMSClassWithoutException(s + "SpawnPosition");
|
||||
UPDATE_TIME = NMSUtils.getNMSClassWithoutException(s + "UpdateTime");
|
||||
TITLE = NMSUtils.getNMSClassWithoutException(s + "Title");
|
||||
ENTITY_SOUND = NMSUtils.getNMSClassWithoutException(s + "EntitySound");
|
||||
NAMED_SOUND_EFFECT = NMSUtils.getNMSClassWithoutException(s + "NamedSoundEffect");
|
||||
STOP_SOUND = NMSUtils.getNMSClassWithoutException(s + "StopSound");
|
||||
PLAYER_LIST_HEADER_FOOTER = NMSUtils.getNMSClassWithoutException(s + "PlayerListHeaderFooter");
|
||||
NBT_QUERY = NMSUtils.getNMSClassWithoutException(s + "NBTQuery");
|
||||
COLLECT = NMSUtils.getNMSClassWithoutException(s + "Collect");
|
||||
ENTITY_TELEPORT = NMSUtils.getNMSClassWithoutException(s + "EntityTeleport");
|
||||
ADVANCEMENTS = NMSUtils.getNMSClassWithoutException(s + "Advancements");
|
||||
UPDATE_ATTRIBUTES = NMSUtils.getNMSClassWithoutException(s + "UpdateAttributes");
|
||||
ENTITY_EFFECT = NMSUtils.getNMSClassWithoutException(s + "EntityEffect");
|
||||
RECIPE_UPDATE = NMSUtils.getNMSClassWithoutException(s + "RecipeUpdate");
|
||||
TAGS = NMSUtils.getNMSClassWithoutException(s + "Tags");
|
||||
MAP_CHUNK_BULK = NMSUtils.getNMSClassWithoutException(s + "MapChunkBulk");
|
||||
PacketType.Server.init();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,437 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packettype;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Packet Type IDs.
|
||||
* This is the Packet ID system, it is recommended to use this over packet comparisons by packet name.
|
||||
* This is also faster than comparing packet names.
|
||||
*
|
||||
* @author retrooper
|
||||
* @since 1.6.8
|
||||
*/
|
||||
public class PacketType {
|
||||
/**
|
||||
* If a Packet Type could not be resolved, it will be set to the current value of this constant.
|
||||
* This value may change over the versions so it is important to use the variable and not hard code its value.
|
||||
*/
|
||||
public static final byte INVALID = -1;
|
||||
/**
|
||||
* Status Packet IDs.
|
||||
*
|
||||
* @author retrooper
|
||||
* @see <a href="https://wiki.vg/Protocol#Status">https://wiki.vg/Protocol#Status</a>
|
||||
* @since 1.7
|
||||
*/
|
||||
public static class Status {
|
||||
/**
|
||||
* Server-bound (client-sided) Status Packet IDs.
|
||||
*
|
||||
* @author retrooper
|
||||
* @see <a href="https://wiki.vg/Protocol#Serverbound_2">https://wiki.vg/Protocol#Serverbound_2</a>
|
||||
* @since 1.8
|
||||
*/
|
||||
public static class Client {
|
||||
public static final byte START = 0, PING = 1;
|
||||
public static final Map<Class<?>, Byte> packetIds = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Load the server-bound status Packet IDs.
|
||||
*/
|
||||
public static void init() {
|
||||
packetIds.put(PacketTypeClasses.Status.Client.START, Client.START);
|
||||
packetIds.put(PacketTypeClasses.Status.Client.PING, Client.PING);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Client-bound (server-sided) Status Packet IDs.
|
||||
*
|
||||
* @author retrooper
|
||||
* @see <a href="https://wiki.vg/Protocol#Clientbound_2">https://wiki.vg/Protocol#Clientbound_2</a>
|
||||
* @since 1.8
|
||||
*/
|
||||
public static class Server {
|
||||
public static final byte PONG = 0, SERVER_INFO = 1;
|
||||
public static final Map<Class<?>, Byte> packetIds = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Load the client-bound Status Packet IDs.
|
||||
*/
|
||||
public static void init() {
|
||||
packetIds.put(PacketTypeClasses.Status.Server.PONG, Server.PONG);
|
||||
packetIds.put(PacketTypeClasses.Status.Server.SERVER_INFO, Server.SERVER_INFO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Login Packet IDs.
|
||||
*
|
||||
* @author retrooper
|
||||
* @see <a href="https://wiki.vg/Protocol#Login">https://wiki.vg/Protocol#Login</a>
|
||||
* @since 1.7
|
||||
*/
|
||||
public static class Login {
|
||||
/**
|
||||
* Server-bound (client-sided) Login Packet IDs.
|
||||
*
|
||||
* @author retrooper
|
||||
* @see <a href="https://wiki.vg/Protocol#Serverbound_3">https://wiki.vg/Protocol#Serverbound_3</a>
|
||||
* @since 1.8
|
||||
*/
|
||||
public static class Client {
|
||||
public static final Map<Class<?>, Byte> packetIds = new HashMap<>();
|
||||
public static final byte HANDSHAKE = 0, CUSTOM_PAYLOAD = 1, START = 2, ENCRYPTION_BEGIN = 3;
|
||||
|
||||
/**
|
||||
* Load the server-bound Login Packet IDs.
|
||||
*/
|
||||
public static void init() {
|
||||
packetIds.put(PacketTypeClasses.Login.Client.HANDSHAKE, Client.HANDSHAKE);
|
||||
packetIds.put(PacketTypeClasses.Login.Client.CUSTOM_PAYLOAD, Client.CUSTOM_PAYLOAD);
|
||||
packetIds.put(PacketTypeClasses.Login.Client.START, Client.START);
|
||||
packetIds.put(PacketTypeClasses.Login.Client.ENCRYPTION_BEGIN, Client.ENCRYPTION_BEGIN);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Client-bound (server-sided) Login Packet IDs.
|
||||
*
|
||||
* @author retrooper
|
||||
* @see <a href="https://wiki.vg/Protocol#Clientbound_3">https://wiki.vg/Protocol#Clientbound_3</a>
|
||||
* @since 1.8
|
||||
*/
|
||||
public static class Server {
|
||||
public static final Map<Class<?>, Byte> packetIds = new HashMap<>();
|
||||
public static final byte CUSTOM_PAYLOAD = 0, DISCONNECT = 1, ENCRYPTION_BEGIN = 2, SUCCESS = 3, SET_COMPRESSION = 4;
|
||||
|
||||
/**
|
||||
* Load the client-bound Login Packet IDs.
|
||||
*/
|
||||
public static void init() {
|
||||
packetIds.put(PacketTypeClasses.Login.Server.CUSTOM_PAYLOAD, Server.CUSTOM_PAYLOAD);
|
||||
packetIds.put(PacketTypeClasses.Login.Server.DISCONNECT, Server.DISCONNECT);
|
||||
packetIds.put(PacketTypeClasses.Login.Server.ENCRYPTION_BEGIN, Server.ENCRYPTION_BEGIN);
|
||||
packetIds.put(PacketTypeClasses.Login.Server.SUCCESS, Server.SUCCESS);
|
||||
packetIds.put(PacketTypeClasses.Login.Server.SET_COMPRESSION, Server.SET_COMPRESSION);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Play Packet IDs.
|
||||
*
|
||||
* @author retrooper
|
||||
* @see <a href="https://wiki.vg/Protocol#Play">https://wiki.vg/Protocol#Play</a>
|
||||
* @since 1.8
|
||||
*/
|
||||
public static class Play {
|
||||
/**
|
||||
* Server-bound (client-sided) Play Packet IDs.
|
||||
*
|
||||
* @author retrooper
|
||||
* @see <a href="https://wiki.vg/Protocol#Serverbound_4">https://wiki.vg/Protocol#Serverbound_4</a>
|
||||
* @since 1.8
|
||||
*/
|
||||
public static class Client {
|
||||
public static final Map<Class<?>, Byte> packetIds = new HashMap<>();
|
||||
public static final byte TELEPORT_ACCEPT = 0,
|
||||
TILE_NBT_QUERY = 1, DIFFICULTY_CHANGE = 2, CHAT = 3, CLIENT_COMMAND = 4,
|
||||
SETTINGS = 5, TAB_COMPLETE = 6, TRANSACTION = 7, ENCHANT_ITEM = 8,
|
||||
WINDOW_CLICK = 9, CLOSE_WINDOW = 10, CUSTOM_PAYLOAD = 11, B_EDIT = 12,
|
||||
ENTITY_NBT_QUERY = 13, USE_ENTITY = 14, JIGSAW_GENERATE = 15, KEEP_ALIVE = 16,
|
||||
DIFFICULTY_LOCK = 17, POSITION = 18, POSITION_LOOK = 19, LOOK = 20,
|
||||
FLYING = 21, VEHICLE_MOVE = 22, BOAT_MOVE = 23, PICK_ITEM = 24,
|
||||
AUTO_RECIPE = 25, ABILITIES = 26, BLOCK_DIG = 27, ENTITY_ACTION = 28,
|
||||
STEER_VEHICLE = 29, RECIPE_DISPLAYED = 30, ITEM_NAME = 31, RESOURCE_PACK_STATUS = 32,
|
||||
ADVANCEMENTS = 33, TR_SEL = 34, BEACON = 35, HELD_ITEM_SLOT = 36,
|
||||
SET_COMMAND_BLOCK = 37, SET_COMMAND_MINECART = 38, SET_CREATIVE_SLOT = 39, SET_JIGSAW = 40,
|
||||
STRUCT = 41, UPDATE_SIGN = 42, ARM_ANIMATION = 43, SPECTATE = 44,
|
||||
USE_ITEM = 45, BLOCK_PLACE = 46;
|
||||
|
||||
/**
|
||||
* Load the server-bound Play Packet IDs.
|
||||
*/
|
||||
public static void init() {
|
||||
packetIds.put(PacketTypeClasses.Play.Client.TELEPORT_ACCEPT, TELEPORT_ACCEPT);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.TILE_NBT_QUERY, TILE_NBT_QUERY);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.DIFFICULTY_CHANGE, DIFFICULTY_CHANGE);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.CHAT, CHAT);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.CLIENT_COMMAND, CLIENT_COMMAND);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.SETTINGS, SETTINGS);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.TAB_COMPLETE, TAB_COMPLETE);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.TRANSACTION, TRANSACTION);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.ENCHANT_ITEM, ENCHANT_ITEM);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.WINDOW_CLICK, WINDOW_CLICK);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.CLOSE_WINDOW, CLOSE_WINDOW);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.CUSTOM_PAYLOAD, CUSTOM_PAYLOAD);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.B_EDIT, B_EDIT);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.ENTITY_NBT_QUERY, ENTITY_NBT_QUERY);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.USE_ENTITY, USE_ENTITY);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.JIGSAW_GENERATE, JIGSAW_GENERATE);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.KEEP_ALIVE, KEEP_ALIVE);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.DIFFICULTY_LOCK, DIFFICULTY_LOCK);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.POSITION, POSITION);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.POSITION_LOOK, POSITION_LOOK);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.LOOK, LOOK);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.FLYING, FLYING);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.VEHICLE_MOVE, VEHICLE_MOVE);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.BOAT_MOVE, BOAT_MOVE);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.PICK_ITEM, PICK_ITEM);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.AUTO_RECIPE, AUTO_RECIPE);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.ABILITIES, ABILITIES);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.BLOCK_DIG, BLOCK_DIG);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.ENTITY_ACTION, ENTITY_ACTION);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.STEER_VEHICLE, STEER_VEHICLE);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.RECIPE_DISPLAYED, RECIPE_DISPLAYED);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.ITEM_NAME, ITEM_NAME);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.RESOURCE_PACK_STATUS, RESOURCE_PACK_STATUS);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.ADVANCEMENTS, ADVANCEMENTS);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.TR_SEL, TR_SEL);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.BEACON, BEACON);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.HELD_ITEM_SLOT, HELD_ITEM_SLOT);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.SET_COMMAND_BLOCK, SET_COMMAND_BLOCK);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.SET_COMMAND_MINECART, SET_COMMAND_MINECART);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.SET_CREATIVE_SLOT, SET_CREATIVE_SLOT);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.SET_JIGSAW, SET_JIGSAW);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.STRUCT, STRUCT);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.UPDATE_SIGN, UPDATE_SIGN);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.ARM_ANIMATION, ARM_ANIMATION);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.SPECTATE, SPECTATE);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.USE_ITEM, USE_ITEM);
|
||||
packetIds.put(PacketTypeClasses.Play.Client.BLOCK_PLACE, BLOCK_PLACE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Server-bound Play Packet Type utility.
|
||||
* Save a few lines of code by using this.
|
||||
*
|
||||
* @author retrooper
|
||||
* @since 1.8
|
||||
*/
|
||||
public static class Util {
|
||||
/**
|
||||
* Is the play packet a PacketPlayInFlying, PacketPlayInPosition, PacketPlayInPositionLook
|
||||
* or a PacketPlayInLook packet?
|
||||
*
|
||||
* @param packetID Play Packet ID.
|
||||
* @return Is the Packet ID an instance of the PacketPlayInFlying packet?
|
||||
*/
|
||||
public static boolean isInstanceOfFlying(final byte packetID) {
|
||||
return packetID == FLYING
|
||||
|| packetID == POSITION
|
||||
|| packetID == POSITION_LOOK
|
||||
|| packetID == LOOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this the packet where the client places a block?
|
||||
* On 1.7.10 - 1.8.8 the client sends a PacketPlayInBlockPlace packet when actually placing the block.
|
||||
* On 1.9 - now the client sends a PacketPlayInUseItem packet when placing the block and the
|
||||
* PacketPlayInBlockPlace has a different use.
|
||||
* This method is a nice utility supporting all these versions letting you know
|
||||
* if the client played a block.
|
||||
* The {@link io.github.retrooper.packetevents.packetwrappers.play.in.blockplace.WrappedPacketInBlockPlace} wrapper
|
||||
* only works on an actual block place.
|
||||
* Use this method before using the wrapper to support all minecraft versions.
|
||||
*
|
||||
* @param packetID Play Packet ID.
|
||||
* @return Has the client placed a block?
|
||||
*/
|
||||
public static boolean isBlockPlace(final byte packetID) {
|
||||
final ServerVersion version = PacketEvents.get().getServerUtils().getVersion();
|
||||
return version.isHigherThan(ServerVersion.v_1_8_8) ?
|
||||
packetID == Client.USE_ITEM
|
||||
: packetID == Client.BLOCK_PLACE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Client-bound (server-sided) Play Packet IDs.
|
||||
*
|
||||
* @author retrooper
|
||||
* @see <a href="https://wiki.vg/Protocol#Clientbound_4">https://wiki.vg/Protocol#Clientbound_4</a>
|
||||
* @since 1.8
|
||||
*/
|
||||
public static class Server {
|
||||
public static final Map<Class<?>, Byte> packetIds = new HashMap<>();
|
||||
public static final byte SPAWN_ENTITY = 0, SPAWN_ENTITY_EXPERIENCE_ORB = 1, SPAWN_ENTITY_WEATHER = 2, SPAWN_ENTITY_LIVING = 3,
|
||||
SPAWN_ENTITY_PAINTING = 4, SPAWN_ENTITY_SPAWN = 5, ANIMATION = 6, STATISTIC = 7,
|
||||
BLOCK_BREAK = 8, BLOCK_BREAK_ANIMATION = 9, TILE_ENTITY_DATA = 10, BLOCK_ACTION = 11,
|
||||
BLOCK_CHANGE = 12, BOSS = 13, SERVER_DIFFICULTY = 14, CHAT = 15, MULTI_BLOCK_CHANGE = 16,
|
||||
TAB_COMPLETE = 17, COMMANDS = 18, TRANSACTION = 19, CLOSE_WINDOW = 20,
|
||||
WINDOW_ITEMS = 21, WINDOW_DATA = 22, SET_SLOT = 23, SET_COOLDOWN = 24,
|
||||
CUSTOM_PAYLOAD = 25, CUSTOM_SOUND_EFFECT = 26, KICK_DISCONNECT = 27, ENTITY_STATUS = 28,
|
||||
EXPLOSION = 29, UNLOAD_CHUNK = 30, GAME_STATE_CHANGE = 31, OPEN_WINDOW_HORSE = 32,
|
||||
KEEP_ALIVE = 33, MAP_CHUNK = 34, WORLD_EVENT = 35, WORLD_PARTICLES = 36,
|
||||
LIGHT_UPDATE = 37, LOGIN = 38, MAP = 39, OPEN_WINDOW_MERCHANT = 40,
|
||||
REL_ENTITY_MOVE = 41, REL_ENTITY_MOVE_LOOK = 42, ENTITY_LOOK = 43, ENTITY = 44,
|
||||
VEHICLE_MOVE = 45, OPEN_BOOK = 46, OPEN_WINDOW = 47, OPEN_SIGN_EDITOR = 48,
|
||||
AUTO_RECIPE = 49, ABILITIES = 50, COMBAT_EVENT = 51, PLAYER_INFO = 52,
|
||||
LOOK_AT = 53, POSITION = 54, RECIPES = 55, ENTITY_DESTROY = 56,
|
||||
REMOVE_ENTITY_EFFECT = 57, RESOURCE_PACK_SEND = 58, RESPAWN = 59, ENTITY_HEAD_ROTATION = 60,
|
||||
SELECT_ADVANCEMENT_TAB = 61, WORLD_BORDER = 62, CAMERA = 63, HELD_ITEM_SLOT = 64,
|
||||
VIEW_CENTRE = 65, VIEW_DISTANCE = 66, SCOREBOARD_DISPLAY_OBJECTIVE = 67, ENTITY_METADATA = 68,
|
||||
ATTACH_ENTITY = 69, ENTITY_VELOCITY = 70, ENTITY_EQUIPMENT = 71, EXPERIENCE = 72,
|
||||
UPDATE_HEALTH = 73, SCOREBOARD_OBJECTIVE = 74, MOUNT = 75, SCOREBOARD_TEAM = 76,
|
||||
SCOREBOARD_SCORE = 77, SPAWN_POSITION = 78, UPDATE_TIME = 79, TITLE = 80,
|
||||
ENTITY_SOUND = 81, NAMED_SOUND_EFFECT = 82, STOP_SOUND = 83, PLAYER_LIST_HEADER_FOOTER = 84,
|
||||
NBT_QUERY = 85, COLLECT = 86, ENTITY_TELEPORT = 87, ADVANCEMENTS = 88, UPDATE_ATTRIBUTES = 89,
|
||||
ENTITY_EFFECT = 90, RECIPE_UPDATE = 91, TAGS = 92, MAP_CHUNK_BULK = 93, NAMED_ENTITY_SPAWN = 94;
|
||||
|
||||
/**
|
||||
* Load the client-bound Play Packet IDs.
|
||||
*/
|
||||
public static void init() {
|
||||
packetIds.put(PacketTypeClasses.Play.Server.SPAWN_ENTITY, SPAWN_ENTITY);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.SPAWN_ENTITY_EXPERIENCE_ORB, SPAWN_ENTITY_EXPERIENCE_ORB);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.SPAWN_ENTITY_WEATHER, SPAWN_ENTITY_WEATHER);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.SPAWN_ENTITY_LIVING, SPAWN_ENTITY_LIVING);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.SPAWN_ENTITY_PAINTING, SPAWN_ENTITY_PAINTING);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.SPAWN_ENTITY_SPAWN, SPAWN_ENTITY_SPAWN);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.ANIMATION, ANIMATION);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.STATISTIC, STATISTIC);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.BLOCK_BREAK, BLOCK_BREAK);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.BLOCK_BREAK_ANIMATION, BLOCK_BREAK_ANIMATION);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.TILE_ENTITY_DATA, TILE_ENTITY_DATA);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.BLOCK_ACTION, BLOCK_ACTION);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.BLOCK_CHANGE, BLOCK_CHANGE);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.BOSS, BOSS);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.SPAWN_ENTITY, SPAWN_ENTITY);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.SERVER_DIFFICULTY, SERVER_DIFFICULTY);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.CHAT, CHAT);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.MULTI_BLOCK_CHANGE, MULTI_BLOCK_CHANGE);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.TAB_COMPLETE, TAB_COMPLETE);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.COMMANDS, COMMANDS);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.TRANSACTION, TRANSACTION);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.CLOSE_WINDOW, CLOSE_WINDOW);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.WINDOW_ITEMS, WINDOW_ITEMS);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.WINDOW_DATA, WINDOW_DATA);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.SET_SLOT, SET_SLOT);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.SET_COOLDOWN, SET_COOLDOWN);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.CUSTOM_PAYLOAD, CUSTOM_PAYLOAD);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.CUSTOM_SOUND_EFFECT, CUSTOM_SOUND_EFFECT);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.KICK_DISCONNECT, KICK_DISCONNECT);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.ENTITY_STATUS, ENTITY_STATUS);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.EXPLOSION, EXPLOSION);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.UNLOAD_CHUNK, UNLOAD_CHUNK);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.GAME_STATE_CHANGE, GAME_STATE_CHANGE);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.OPEN_WINDOW_HORSE, OPEN_WINDOW_HORSE);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.KEEP_ALIVE, KEEP_ALIVE);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.MAP_CHUNK, MAP_CHUNK);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.WORLD_EVENT, WORLD_EVENT);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.WORLD_EVENT, SPAWN_ENTITY);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.WORLD_PARTICLES, WORLD_PARTICLES);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.LIGHT_UPDATE, LIGHT_UPDATE);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.LOGIN, LOGIN);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.MAP, MAP);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.OPEN_WINDOW_MERCHANT, OPEN_WINDOW_MERCHANT);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.REL_ENTITY_MOVE, REL_ENTITY_MOVE);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.REL_ENTITY_MOVE_LOOK, REL_ENTITY_MOVE_LOOK);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.ENTITY_LOOK, ENTITY_LOOK);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.ENTITY, ENTITY);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.VEHICLE_MOVE, VEHICLE_MOVE);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.OPEN_BOOK, OPEN_BOOK);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.OPEN_WINDOW, OPEN_WINDOW);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.OPEN_SIGN_EDITOR, OPEN_SIGN_EDITOR);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.AUTO_RECIPE, AUTO_RECIPE);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.ABILITIES, ABILITIES);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.COMBAT_EVENT, COMBAT_EVENT);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.PLAYER_INFO, PLAYER_INFO);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.LOOK_AT, LOOK_AT);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.POSITION, POSITION);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.RECIPES, RECIPES);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.ENTITY_DESTROY, ENTITY_DESTROY);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.REMOVE_ENTITY_EFFECT, REMOVE_ENTITY_EFFECT);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.RESOURCE_PACK_SEND, RESOURCE_PACK_SEND);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.RESPAWN, RESPAWN);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.ENTITY_HEAD_ROTATION, ENTITY_HEAD_ROTATION);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.SELECT_ADVANCEMENT_TAB, SELECT_ADVANCEMENT_TAB);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.WORLD_BORDER, WORLD_BORDER);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.CAMERA, CAMERA);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.HELD_ITEM_SLOT, HELD_ITEM_SLOT);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.VIEW_CENTRE, VIEW_CENTRE);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.VIEW_DISTANCE, VIEW_DISTANCE);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.SCOREBOARD_DISPLAY_OBJECTIVE, SCOREBOARD_DISPLAY_OBJECTIVE);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.ENTITY_METADATA, ENTITY_METADATA);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.ATTACH_ENTITY, ATTACH_ENTITY);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.ENTITY_VELOCITY, ENTITY_VELOCITY);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.ENTITY_EQUIPMENT, ENTITY_EQUIPMENT);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.EXPERIENCE, EXPERIENCE);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.UPDATE_HEALTH, UPDATE_HEALTH);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.SCOREBOARD_OBJECTIVE, SCOREBOARD_OBJECTIVE);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.MOUNT, MOUNT);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.SCOREBOARD_TEAM, SCOREBOARD_TEAM);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.SCOREBOARD_SCORE, SCOREBOARD_SCORE);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.SPAWN_POSITION, SPAWN_POSITION);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.UPDATE_TIME, UPDATE_TIME);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.TITLE, TITLE);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.ENTITY_SOUND, ENTITY_SOUND);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.NAMED_SOUND_EFFECT, NAMED_SOUND_EFFECT);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.STOP_SOUND, STOP_SOUND);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.PLAYER_LIST_HEADER_FOOTER, PLAYER_LIST_HEADER_FOOTER);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.NBT_QUERY, NBT_QUERY);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.COLLECT, COLLECT);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.ENTITY_TELEPORT, ENTITY_TELEPORT);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.ADVANCEMENTS, ADVANCEMENTS);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.UPDATE_ATTRIBUTES, UPDATE_ATTRIBUTES);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.ENTITY_EFFECT, ENTITY_EFFECT);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.RECIPE_UPDATE, RECIPE_UPDATE);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.TAGS, TAGS);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.MAP_CHUNK_BULK, MAP_CHUNK_BULK);
|
||||
packetIds.put(PacketTypeClasses.Play.Server.NAMED_ENTITY_SPAWN, NAMED_ENTITY_SPAWN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Client-bound Play Packet Type utility.
|
||||
* Save a few lines of code by using this.
|
||||
*
|
||||
* @author retrooper
|
||||
* @since 1.8
|
||||
*/
|
||||
public static class Util {
|
||||
/**
|
||||
* Is the play packet a PacketPlayOutEntity, PacketPlayOutRelEntityMove, PacketPlayOutRelEntityMoveLook
|
||||
* or a PacketPlayOutEntityLook packet?
|
||||
*
|
||||
* @param packetID Play Packet ID.
|
||||
* @return Is the Packet ID an instance of the PacketPlayOutEntity packet?
|
||||
*/
|
||||
public static boolean isInstanceOfEntity(final byte packetID) {
|
||||
return packetID == ENTITY || packetID == REL_ENTITY_MOVE ||
|
||||
packetID == REL_ENTITY_MOVE_LOOK || packetID == ENTITY_LOOK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,319 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packettype;
|
||||
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
|
||||
|
||||
public class PacketTypeClasses {
|
||||
public static void load() {
|
||||
//PLAY
|
||||
PacketTypeClasses.Play.Client.load();
|
||||
PacketTypeClasses.Play.Server.load();
|
||||
//LOGIN
|
||||
PacketTypeClasses.Login.Client.load();
|
||||
PacketTypeClasses.Login.Server.load();
|
||||
//STATUS
|
||||
PacketTypeClasses.Status.Client.load();
|
||||
PacketTypeClasses.Status.Server.load();
|
||||
}
|
||||
|
||||
public static class Status {
|
||||
public static class Client {
|
||||
public static Class<?> START, PING;
|
||||
|
||||
public static void load() {
|
||||
Client.START = NMSUtils.getNMSClassWithoutException("PacketStatusInStart");
|
||||
Client.PING = NMSUtils.getNMSClassWithoutException("PacketStatusInPing");
|
||||
PacketType.Status.Client.init();
|
||||
}
|
||||
}
|
||||
|
||||
public static class Server {
|
||||
public static Class<?> PONG, SERVER_INFO;
|
||||
|
||||
public static void load() {
|
||||
Server.PONG = NMSUtils.getNMSClassWithoutException("PacketStatusOutPong");
|
||||
Server.SERVER_INFO = NMSUtils.getNMSClassWithoutException("PacketStatusOutServerInfo");
|
||||
PacketType.Status.Server.init();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class Login {
|
||||
public static class Client {
|
||||
public static Class<?> HANDSHAKE, CUSTOM_PAYLOAD, START, ENCRYPTION_BEGIN;
|
||||
|
||||
public static void load() {
|
||||
Client.HANDSHAKE = NMSUtils.getNMSClassWithoutException("PacketHandshakingInSetProtocol");
|
||||
//In and Out custom payload login packets have been here since AROUND 1.13.2.
|
||||
Client.CUSTOM_PAYLOAD = NMSUtils.getNMSClassWithoutException("PacketLoginInCustomPayload");
|
||||
Client.START = NMSUtils.getNMSClassWithoutException("PacketLoginInStart");
|
||||
Client.ENCRYPTION_BEGIN = NMSUtils.getNMSClassWithoutException("PacketLoginInEncryptionBegin");
|
||||
PacketType.Login.Client.init();
|
||||
}
|
||||
}
|
||||
|
||||
public static class Server {
|
||||
public static Class<?> CUSTOM_PAYLOAD, DISCONNECT, ENCRYPTION_BEGIN, SUCCESS, SET_COMPRESSION;
|
||||
|
||||
public static void load() {
|
||||
Server.CUSTOM_PAYLOAD = NMSUtils.getNMSClassWithoutException("PacketLoginOutCustomPayload");
|
||||
Server.DISCONNECT = NMSUtils.getNMSClassWithoutException("PacketLoginOutDisconnect");
|
||||
Server.ENCRYPTION_BEGIN = NMSUtils.getNMSClassWithoutException("PacketLoginOutEncryptionBegin");
|
||||
Server.SUCCESS = NMSUtils.getNMSClassWithoutException("PacketLoginOutSuccess");
|
||||
Server.SET_COMPRESSION = NMSUtils.getNMSClassWithoutException("PacketLoginOutSetCompression");
|
||||
PacketType.Login.Server.init();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class Play {
|
||||
public static class Client {
|
||||
private static final String PREFIX = "PacketPlayIn";
|
||||
public static Class<?> FLYING, POSITION, POSITION_LOOK, LOOK, CLIENT_COMMAND,
|
||||
TRANSACTION, BLOCK_DIG, ENTITY_ACTION, USE_ENTITY,
|
||||
WINDOW_CLICK, STEER_VEHICLE, CUSTOM_PAYLOAD, ARM_ANIMATION,
|
||||
BLOCK_PLACE, USE_ITEM, ABILITIES, HELD_ITEM_SLOT,
|
||||
CLOSE_WINDOW, TAB_COMPLETE, CHAT, SET_CREATIVE_SLOT,
|
||||
KEEP_ALIVE, SETTINGS, ENCHANT_ITEM, TELEPORT_ACCEPT,
|
||||
TILE_NBT_QUERY, DIFFICULTY_CHANGE, B_EDIT, ENTITY_NBT_QUERY,
|
||||
JIGSAW_GENERATE, DIFFICULTY_LOCK, VEHICLE_MOVE, BOAT_MOVE, PICK_ITEM,
|
||||
AUTO_RECIPE, RECIPE_DISPLAYED, ITEM_NAME, RESOURCE_PACK_STATUS,
|
||||
ADVANCEMENTS, TR_SEL, BEACON, SET_COMMAND_BLOCK,
|
||||
SET_COMMAND_MINECART, SET_JIGSAW, STRUCT, UPDATE_SIGN, SPECTATE;
|
||||
|
||||
/**
|
||||
* Initiate all server-bound play packet classes.
|
||||
*/
|
||||
public static void load() {
|
||||
FLYING = NMSUtils.getNMSClassWithoutException(PREFIX + "Flying");
|
||||
try {
|
||||
POSITION = NMSUtils.getNMSClass(PREFIX + "Position");
|
||||
POSITION_LOOK = NMSUtils.getNMSClass(PREFIX + "PositionLook");
|
||||
LOOK = NMSUtils.getNMSClass(PREFIX + "Look");
|
||||
} catch (ClassNotFoundException e) {
|
||||
POSITION = SubclassUtil.getSubClass(FLYING, PREFIX + "Position");
|
||||
POSITION_LOOK = SubclassUtil.getSubClass(FLYING, PREFIX + "PositionLook");
|
||||
LOOK = SubclassUtil.getSubClass(FLYING, PREFIX + "Look");
|
||||
}
|
||||
|
||||
try {
|
||||
SETTINGS = NMSUtils.getNMSClass(PREFIX + "Settings");
|
||||
ENCHANT_ITEM = NMSUtils.getNMSClass(PREFIX + "EnchantItem");
|
||||
|
||||
CLIENT_COMMAND = NMSUtils.getNMSClass(PREFIX + "ClientCommand");
|
||||
TRANSACTION = NMSUtils.getNMSClass(PREFIX + "Transaction");
|
||||
BLOCK_DIG = NMSUtils.getNMSClass(PREFIX + "BlockDig");
|
||||
ENTITY_ACTION = NMSUtils.getNMSClass(PREFIX + "EntityAction");
|
||||
USE_ENTITY = NMSUtils.getNMSClass(PREFIX + "UseEntity");
|
||||
WINDOW_CLICK = NMSUtils.getNMSClass(PREFIX + "WindowClick");
|
||||
STEER_VEHICLE = NMSUtils.getNMSClass(PREFIX + "SteerVehicle");
|
||||
CUSTOM_PAYLOAD = NMSUtils.getNMSClass(PREFIX + "CustomPayload");
|
||||
ARM_ANIMATION = NMSUtils.getNMSClass(PREFIX + "ArmAnimation");
|
||||
ABILITIES = NMSUtils.getNMSClass(PREFIX + "Abilities");
|
||||
HELD_ITEM_SLOT = NMSUtils.getNMSClass(PREFIX + "HeldItemSlot");
|
||||
CLOSE_WINDOW = NMSUtils.getNMSClass(PREFIX + "CloseWindow");
|
||||
TAB_COMPLETE = NMSUtils.getNMSClass(PREFIX + "TabComplete");
|
||||
CHAT = NMSUtils.getNMSClass(PREFIX + "Chat");
|
||||
SET_CREATIVE_SLOT = NMSUtils.getNMSClass(PREFIX + "SetCreativeSlot");
|
||||
KEEP_ALIVE = NMSUtils.getNMSClass(PREFIX + "KeepAlive");
|
||||
UPDATE_SIGN = NMSUtils.getNMSClassWithoutException(PREFIX + "UpdateSign");
|
||||
|
||||
TELEPORT_ACCEPT = NMSUtils.getNMSClassWithoutException(PREFIX + "TeleportAccept");
|
||||
TILE_NBT_QUERY = NMSUtils.getNMSClassWithoutException(PREFIX + "TileNBTQuery");
|
||||
DIFFICULTY_CHANGE = NMSUtils.getNMSClassWithoutException(PREFIX + "DifficultyChange");
|
||||
B_EDIT = NMSUtils.getNMSClassWithoutException(PREFIX + "BEdit");
|
||||
ENTITY_NBT_QUERY = NMSUtils.getNMSClassWithoutException(PREFIX + "EntityNBTQuery");
|
||||
JIGSAW_GENERATE = NMSUtils.getNMSClassWithoutException(PREFIX + "JigsawGenerate");
|
||||
DIFFICULTY_LOCK = NMSUtils.getNMSClassWithoutException(PREFIX + "DifficultyLock");
|
||||
VEHICLE_MOVE = NMSUtils.getNMSClassWithoutException(PREFIX + "VehicleMove");
|
||||
BOAT_MOVE = NMSUtils.getNMSClassWithoutException(PREFIX + "BoatMove");
|
||||
PICK_ITEM = NMSUtils.getNMSClassWithoutException(PREFIX + "PickItem");
|
||||
AUTO_RECIPE = NMSUtils.getNMSClassWithoutException(PREFIX + "AutoRecipe");
|
||||
RECIPE_DISPLAYED = NMSUtils.getNMSClassWithoutException(PREFIX + "RecipeDisplayed");
|
||||
ITEM_NAME = NMSUtils.getNMSClassWithoutException(PREFIX + "ItemName");
|
||||
//1.8+
|
||||
RESOURCE_PACK_STATUS = NMSUtils.getNMSClassWithoutException(PREFIX + "ResourcePackStatus");
|
||||
|
||||
ADVANCEMENTS = NMSUtils.getNMSClassWithoutException(PREFIX + "Advancements");
|
||||
TR_SEL = NMSUtils.getNMSClassWithoutException(PREFIX + "TrSel");
|
||||
BEACON = NMSUtils.getNMSClassWithoutException(PREFIX + "Beacon");
|
||||
SET_COMMAND_BLOCK = NMSUtils.getNMSClassWithoutException(PREFIX + "SetCommandBlock");
|
||||
SET_COMMAND_MINECART = NMSUtils.getNMSClassWithoutException(PREFIX + "SetCommandMinecart");
|
||||
SET_JIGSAW = NMSUtils.getNMSClassWithoutException(PREFIX + "SetJigsaw");
|
||||
STRUCT = NMSUtils.getNMSClassWithoutException(PREFIX + "Struct");
|
||||
SPECTATE = NMSUtils.getNMSClassWithoutException(PREFIX + "Spectate");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
BLOCK_PLACE = NMSUtils.getNMSClass(PREFIX + "BlockPlace");
|
||||
USE_ITEM = NMSUtils.getNMSClass(PREFIX + "UseItem");
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
}
|
||||
|
||||
PacketType.Play.Client.init();
|
||||
}
|
||||
}
|
||||
|
||||
public static class Server {
|
||||
private static final String s = "PacketPlayOut";
|
||||
public static Class<?> SPAWN_ENTITY, SPAWN_ENTITY_EXPERIENCE_ORB, SPAWN_ENTITY_WEATHER, SPAWN_ENTITY_LIVING,
|
||||
SPAWN_ENTITY_PAINTING, SPAWN_ENTITY_SPAWN, ANIMATION, STATISTIC,
|
||||
BLOCK_BREAK, BLOCK_BREAK_ANIMATION, TILE_ENTITY_DATA, BLOCK_ACTION,
|
||||
BLOCK_CHANGE, BOSS, SERVER_DIFFICULTY, CHAT, MULTI_BLOCK_CHANGE,
|
||||
TAB_COMPLETE, COMMANDS, TRANSACTION, CLOSE_WINDOW,
|
||||
WINDOW_ITEMS, WINDOW_DATA, SET_SLOT, SET_COOLDOWN,
|
||||
CUSTOM_PAYLOAD, CUSTOM_SOUND_EFFECT, KICK_DISCONNECT, ENTITY_STATUS,
|
||||
EXPLOSION, UNLOAD_CHUNK, GAME_STATE_CHANGE, OPEN_WINDOW_HORSE,
|
||||
KEEP_ALIVE, MAP_CHUNK, WORLD_EVENT, WORLD_PARTICLES,
|
||||
LIGHT_UPDATE, LOGIN, MAP, OPEN_WINDOW_MERCHANT,
|
||||
REL_ENTITY_MOVE, REL_ENTITY_MOVE_LOOK, ENTITY_LOOK, ENTITY,
|
||||
VEHICLE_MOVE, OPEN_BOOK, OPEN_WINDOW, OPEN_SIGN_EDITOR,
|
||||
AUTO_RECIPE, ABILITIES, COMBAT_EVENT, PLAYER_INFO,
|
||||
LOOK_AT, POSITION, RECIPES, ENTITY_DESTROY,
|
||||
REMOVE_ENTITY_EFFECT, RESOURCE_PACK_SEND, RESPAWN, ENTITY_HEAD_ROTATION,
|
||||
SELECT_ADVANCEMENT_TAB, WORLD_BORDER, CAMERA, HELD_ITEM_SLOT,
|
||||
VIEW_CENTRE, VIEW_DISTANCE, SCOREBOARD_DISPLAY_OBJECTIVE, ENTITY_METADATA,
|
||||
ATTACH_ENTITY, ENTITY_VELOCITY, ENTITY_EQUIPMENT, EXPERIENCE,
|
||||
UPDATE_HEALTH, SCOREBOARD_OBJECTIVE, MOUNT, SCOREBOARD_TEAM,
|
||||
SCOREBOARD_SCORE, SPAWN_POSITION, UPDATE_TIME, TITLE,
|
||||
ENTITY_SOUND, NAMED_SOUND_EFFECT, STOP_SOUND, PLAYER_LIST_HEADER_FOOTER,
|
||||
NBT_QUERY, COLLECT, ENTITY_TELEPORT, ADVANCEMENTS, UPDATE_ATTRIBUTES,
|
||||
ENTITY_EFFECT, RECIPE_UPDATE, TAGS, MAP_CHUNK_BULK, NAMED_ENTITY_SPAWN;
|
||||
|
||||
/**
|
||||
* Initiate all client-bound packet classes.
|
||||
*/
|
||||
public static void load() {
|
||||
SPAWN_ENTITY = NMSUtils.getNMSClassWithoutException(s + "SpawnEntity");
|
||||
SPAWN_ENTITY_EXPERIENCE_ORB = NMSUtils.getNMSClassWithoutException(s + "SpawnEntityExperienceOrb");
|
||||
SPAWN_ENTITY_WEATHER = NMSUtils.getNMSClassWithoutException(s + "SpawnEntityWeather");
|
||||
SPAWN_ENTITY_LIVING = NMSUtils.getNMSClassWithoutException(s + "SpawnEntityLiving");
|
||||
SPAWN_ENTITY_PAINTING = NMSUtils.getNMSClassWithoutException(s + "SpawnEntityPainting");
|
||||
SPAWN_ENTITY_SPAWN = NMSUtils.getNMSClassWithoutException(s + "SpawnEntitySpawn");
|
||||
ANIMATION = NMSUtils.getNMSClassWithoutException(s + "Animation");
|
||||
STATISTIC = NMSUtils.getNMSClassWithoutException(s + "Statistic");
|
||||
BLOCK_BREAK = NMSUtils.getNMSClassWithoutException(s + "BlockBreak");
|
||||
BLOCK_BREAK_ANIMATION = NMSUtils.getNMSClassWithoutException(s + "BlockBreakAnimation");
|
||||
TILE_ENTITY_DATA = NMSUtils.getNMSClassWithoutException(s + "TileEntityData");
|
||||
BLOCK_ACTION = NMSUtils.getNMSClassWithoutException(s + "BlockAction");
|
||||
BLOCK_CHANGE = NMSUtils.getNMSClassWithoutException(s + "BlockChange");
|
||||
BOSS = NMSUtils.getNMSClassWithoutException(s + "Boss");
|
||||
SERVER_DIFFICULTY = NMSUtils.getNMSClassWithoutException(s + "ServerDifficulty");
|
||||
CHAT = NMSUtils.getNMSClassWithoutException(s + "Chat");
|
||||
MULTI_BLOCK_CHANGE = NMSUtils.getNMSClassWithoutException(s + "MultiBlockChange");
|
||||
TAB_COMPLETE = NMSUtils.getNMSClassWithoutException(s + "TabComplete");
|
||||
COMMANDS = NMSUtils.getNMSClassWithoutException(s + "Commands");
|
||||
TRANSACTION = NMSUtils.getNMSClassWithoutException(s + "Transaction");
|
||||
CLOSE_WINDOW = NMSUtils.getNMSClassWithoutException(s + "CloseWindow");
|
||||
WINDOW_ITEMS = NMSUtils.getNMSClassWithoutException(s + "WindowItems");
|
||||
WINDOW_DATA = NMSUtils.getNMSClassWithoutException(s + "WindowData");
|
||||
SET_SLOT = NMSUtils.getNMSClassWithoutException(s + "SetSlot");
|
||||
SET_COOLDOWN = NMSUtils.getNMSClassWithoutException(s + "SetCooldown");
|
||||
CUSTOM_PAYLOAD = NMSUtils.getNMSClassWithoutException(s + "CustomPayload");
|
||||
CUSTOM_SOUND_EFFECT = NMSUtils.getNMSClassWithoutException(s + "CustomSoundEffect");
|
||||
KICK_DISCONNECT = NMSUtils.getNMSClassWithoutException(s + "KickDisconnect");
|
||||
ENTITY_STATUS = NMSUtils.getNMSClassWithoutException(s + "EntityStatus");
|
||||
EXPLOSION = NMSUtils.getNMSClassWithoutException(s + "Explosion");
|
||||
UNLOAD_CHUNK = NMSUtils.getNMSClassWithoutException(s + "UnloadChunk");
|
||||
GAME_STATE_CHANGE = NMSUtils.getNMSClassWithoutException(s + "GameStateChange");
|
||||
OPEN_WINDOW_HORSE = NMSUtils.getNMSClassWithoutException(s + "OpenWindowHorse");
|
||||
KEEP_ALIVE = NMSUtils.getNMSClassWithoutException(s + "KeepAlive");
|
||||
MAP_CHUNK = NMSUtils.getNMSClassWithoutException(s + "MapChunk");
|
||||
WORLD_EVENT = NMSUtils.getNMSClassWithoutException(s + "WorldEvent");
|
||||
WORLD_PARTICLES = NMSUtils.getNMSClassWithoutException(s + "WorldParticles");
|
||||
LIGHT_UPDATE = NMSUtils.getNMSClassWithoutException(s + "LightUpdate");
|
||||
LOGIN = NMSUtils.getNMSClassWithoutException(s + "Login");
|
||||
MAP = NMSUtils.getNMSClassWithoutException(s + "Map");
|
||||
OPEN_WINDOW_MERCHANT = NMSUtils.getNMSClassWithoutException(s + "OpenWindowMerchant");
|
||||
ENTITY = NMSUtils.getNMSClassWithoutException(s + "Entity");
|
||||
REL_ENTITY_MOVE = SubclassUtil.getSubClass(ENTITY, s + "RelEntityMove");
|
||||
REL_ENTITY_MOVE_LOOK = SubclassUtil.getSubClass(ENTITY, s + "RelEntityMoveLook");
|
||||
ENTITY_LOOK = SubclassUtil.getSubClass(ENTITY, s + "EntityLook");
|
||||
if (REL_ENTITY_MOVE == null) {
|
||||
//is not a subclass and should be accessed normally
|
||||
REL_ENTITY_MOVE = NMSUtils.getNMSClassWithoutException(s + "RelEntityMove");
|
||||
REL_ENTITY_MOVE_LOOK = NMSUtils.getNMSClassWithoutException(s + "RelEntityMoveLook");
|
||||
ENTITY_LOOK = NMSUtils.getNMSClassWithoutException(s + "RelEntityLook");
|
||||
}
|
||||
VEHICLE_MOVE = NMSUtils.getNMSClassWithoutException(s + "VehicleMove");
|
||||
OPEN_BOOK = NMSUtils.getNMSClassWithoutException(s + "OpenBook");
|
||||
OPEN_WINDOW = NMSUtils.getNMSClassWithoutException(s + "OpenWindow");
|
||||
OPEN_SIGN_EDITOR = NMSUtils.getNMSClassWithoutException(s + "OpenSignEditor");
|
||||
AUTO_RECIPE = NMSUtils.getNMSClassWithoutException(s + "AutoRecipe");
|
||||
ABILITIES = NMSUtils.getNMSClassWithoutException(s + "Abilities");
|
||||
COMBAT_EVENT = NMSUtils.getNMSClassWithoutException(s + "CombatEvent");
|
||||
PLAYER_INFO = NMSUtils.getNMSClassWithoutException(s + "PlayerInfo");
|
||||
LOOK_AT = NMSUtils.getNMSClassWithoutException(s + "LookAt");
|
||||
POSITION = NMSUtils.getNMSClassWithoutException(s + "Position");
|
||||
RECIPES = NMSUtils.getNMSClassWithoutException(s + "Recipes");
|
||||
ENTITY_DESTROY = NMSUtils.getNMSClassWithoutException(s + "EntityDestroy");
|
||||
REMOVE_ENTITY_EFFECT = NMSUtils.getNMSClassWithoutException(s + "RemoveEntityEffect");
|
||||
RESOURCE_PACK_SEND = NMSUtils.getNMSClassWithoutException(s + "ResourcePackSend");
|
||||
RESPAWN = NMSUtils.getNMSClassWithoutException(s + "Respawn");
|
||||
ENTITY_HEAD_ROTATION = NMSUtils.getNMSClassWithoutException(s + "EntityHeadRotation");
|
||||
SELECT_ADVANCEMENT_TAB = NMSUtils.getNMSClassWithoutException(s + "SelectAdvancementTab");
|
||||
WORLD_BORDER = NMSUtils.getNMSClassWithoutException(s + "WorldBorder");
|
||||
CAMERA = NMSUtils.getNMSClassWithoutException(s + "Camera");
|
||||
HELD_ITEM_SLOT = NMSUtils.getNMSClassWithoutException(s + "HeldItemSlot");
|
||||
VIEW_CENTRE = NMSUtils.getNMSClassWithoutException(s + "ViewCentre");
|
||||
VIEW_DISTANCE = NMSUtils.getNMSClassWithoutException(s + "ViewDistance");
|
||||
SCOREBOARD_DISPLAY_OBJECTIVE = NMSUtils.getNMSClassWithoutException(s + "ScoreboardDisplayObjective");
|
||||
ENTITY_METADATA = NMSUtils.getNMSClassWithoutException(s + "EntityMetadata");
|
||||
ATTACH_ENTITY = NMSUtils.getNMSClassWithoutException(s + "AttachEntity");
|
||||
ENTITY_VELOCITY = NMSUtils.getNMSClassWithoutException(s + "EntityVelocity");
|
||||
ENTITY_EQUIPMENT = NMSUtils.getNMSClassWithoutException(s + "EntityEquipment");
|
||||
EXPERIENCE = NMSUtils.getNMSClassWithoutException(s + "Experience");
|
||||
UPDATE_HEALTH = NMSUtils.getNMSClassWithoutException(s + "UpdateHealth");
|
||||
SCOREBOARD_OBJECTIVE = NMSUtils.getNMSClassWithoutException(s + "ScoreboardObjective");
|
||||
MOUNT = NMSUtils.getNMSClassWithoutException(s + "Mount");
|
||||
SCOREBOARD_TEAM = NMSUtils.getNMSClassWithoutException(s + "ScoreboardTeam");
|
||||
SCOREBOARD_SCORE = NMSUtils.getNMSClassWithoutException(s + "ScoreboardScore");
|
||||
SPAWN_POSITION = NMSUtils.getNMSClassWithoutException(s + "SpawnPosition");
|
||||
UPDATE_TIME = NMSUtils.getNMSClassWithoutException(s + "UpdateTime");
|
||||
TITLE = NMSUtils.getNMSClassWithoutException(s + "Title");
|
||||
ENTITY_SOUND = NMSUtils.getNMSClassWithoutException(s + "EntitySound");
|
||||
NAMED_SOUND_EFFECT = NMSUtils.getNMSClassWithoutException(s + "NamedSoundEffect");
|
||||
STOP_SOUND = NMSUtils.getNMSClassWithoutException(s + "StopSound");
|
||||
PLAYER_LIST_HEADER_FOOTER = NMSUtils.getNMSClassWithoutException(s + "PlayerListHeaderFooter");
|
||||
NBT_QUERY = NMSUtils.getNMSClassWithoutException(s + "NBTQuery");
|
||||
COLLECT = NMSUtils.getNMSClassWithoutException(s + "Collect");
|
||||
ENTITY_TELEPORT = NMSUtils.getNMSClassWithoutException(s + "EntityTeleport");
|
||||
ADVANCEMENTS = NMSUtils.getNMSClassWithoutException(s + "Advancements");
|
||||
UPDATE_ATTRIBUTES = NMSUtils.getNMSClassWithoutException(s + "UpdateAttributes");
|
||||
ENTITY_EFFECT = NMSUtils.getNMSClassWithoutException(s + "EntityEffect");
|
||||
RECIPE_UPDATE = NMSUtils.getNMSClassWithoutException(s + "RecipeUpdate");
|
||||
TAGS = NMSUtils.getNMSClassWithoutException(s + "Tags");
|
||||
MAP_CHUNK_BULK = NMSUtils.getNMSClassWithoutException(s + "MapChunkBulk");
|
||||
NAMED_ENTITY_SPAWN = NMSUtils.getNMSClassWithoutException(s + "NamedEntitySpawn");
|
||||
PacketType.Play.Server.init();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers;
|
||||
|
||||
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
|
||||
|
||||
public class NMSPacket {
|
||||
private final Object rawNMSPacket;
|
||||
|
||||
public NMSPacket(Object rawNMSPacket) {
|
||||
this.rawNMSPacket = rawNMSPacket;
|
||||
}
|
||||
|
||||
public Object getRawNMSPacket() {
|
||||
return rawNMSPacket;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return ClassUtil.getClassSimpleName(rawNMSPacket.getClass());
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers;
|
||||
|
||||
public interface Sendable {
|
||||
Object asNMSPacket();
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers;
|
||||
|
||||
/**
|
||||
* This interface indicates that a packet wrapper supports being sent to a client.
|
||||
*/
|
||||
public interface SendableWrapper {
|
||||
Object asNMSPacket();
|
||||
}
|
||||
@@ -0,0 +1,273 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers;
|
||||
|
||||
import io.github.retrooper.packetevents.exceptions.WrapperFieldNotFoundException;
|
||||
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class WrappedPacket implements WrapperPacketReader, WrapperPacketWriter {
|
||||
|
||||
private static final Map<Class<? extends WrappedPacket>, Boolean> LOADED_WRAPPERS = new ConcurrentHashMap<>();
|
||||
private static final Map<Class<?>, Map<Class<?>, Field[]>> FIELD_CACHE = new ConcurrentHashMap<>();
|
||||
private static final Field[] EMPTY_FIELD_ARRAY = new Field[0];
|
||||
public static ServerVersion version;
|
||||
protected NMSPacket packet;
|
||||
private final Class<?> packetClass;
|
||||
|
||||
public WrappedPacket() {
|
||||
packet = null;
|
||||
packetClass = null;
|
||||
load0();
|
||||
}
|
||||
|
||||
public WrappedPacket(final NMSPacket packet) {
|
||||
this(packet, packet.getRawNMSPacket().getClass());
|
||||
}
|
||||
|
||||
public WrappedPacket(final NMSPacket packet, Class<?> packetClass) {
|
||||
if (packetClass.getSuperclass().equals(PacketTypeClasses.Play.Client.FLYING)) {
|
||||
packetClass = PacketTypeClasses.Play.Client.FLYING;
|
||||
} else if (packetClass.getSuperclass().equals(PacketTypeClasses.Play.Server.ENTITY)) {
|
||||
packetClass = PacketTypeClasses.Play.Server.ENTITY;
|
||||
}
|
||||
this.packetClass = packetClass;
|
||||
this.packet = packet;
|
||||
load0();
|
||||
}
|
||||
|
||||
private void load0() {
|
||||
final Class<? extends WrappedPacket> clazz = getClass();
|
||||
if (!LOADED_WRAPPERS.containsKey(clazz)) {
|
||||
load();
|
||||
LOADED_WRAPPERS.put(clazz, true);
|
||||
}
|
||||
}
|
||||
|
||||
protected void load() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean readBoolean(int index) {
|
||||
return read(index, boolean.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte readByte(int index) {
|
||||
return read(index, byte.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public short readShort(int index) {
|
||||
return read(index, short.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readInt(int index) {
|
||||
return read(index, int.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long readLong(int index) {
|
||||
return read(index, long.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float readFloat(int index) {
|
||||
return read(index, float.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double readDouble(int index) {
|
||||
return read(index, double.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean[] readBooleanArray(int index) {
|
||||
return read(index, boolean[].class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] readByteArray(int index) {
|
||||
return read(index, byte[].class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public short[] readShortArray(int index) {
|
||||
return read(index, short[].class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] readIntArray(int index) {
|
||||
return read(index, int[].class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long[] readLongArray(int index) {
|
||||
return read(index, long[].class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float[] readFloatArray(int index) {
|
||||
return read(index, float[].class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] readDoubleArray(int index) {
|
||||
return read(index, double[].class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] readStringArray(int index) {
|
||||
return read(index, String[].class); // Can we be sure that returning the original array is okay?
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readString(int index) {
|
||||
return read(index, String.class);
|
||||
}
|
||||
|
||||
public Object readAnyObject(int index) {
|
||||
try {
|
||||
Field f = packetClass.getDeclaredFields()[index];
|
||||
if (!f.isAccessible()) {
|
||||
f.setAccessible(true);
|
||||
}
|
||||
try {
|
||||
return f.get(packet.getRawNMSPacket());
|
||||
} catch (IllegalAccessException | NullPointerException | ArrayIndexOutOfBoundsException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
throw new WrapperFieldNotFoundException("PacketEvents failed to find any field indexed " + index + " in the " + ClassUtil.getClassSimpleName(packetClass) + " class!");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object readObject(int index, Class<?> type) {
|
||||
return read(index, type);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T read(int index, Class<? extends T> type) {
|
||||
Field field = getField(type, index);
|
||||
try {
|
||||
return (T) field.get(packet.getRawNMSPacket());
|
||||
} catch (IllegalAccessException | NullPointerException e) {
|
||||
throw new WrapperFieldNotFoundException(packetClass, type, index);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBoolean(int index, boolean value) {
|
||||
write(boolean.class, index, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeByte(int index, byte value) {
|
||||
write(byte.class, index, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeShort(int index, short value) {
|
||||
write(short.class, index, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeInt(int index, int value) {
|
||||
write(int.class, index, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeLong(int index, long value) {
|
||||
write(long.class, index, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeFloat(int index, float value) {
|
||||
write(float.class, index, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDouble(int index, double value) {
|
||||
write(double.class, index, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeString(int index, String value) {
|
||||
write(String.class, index, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeObject(int index, Object value) {
|
||||
write(value.getClass(), index, value);
|
||||
}
|
||||
|
||||
public void write(Class<?> type, int index, Object value) throws WrapperFieldNotFoundException {
|
||||
Field field = getField(type, index);
|
||||
if (field == null) {
|
||||
throw new WrapperFieldNotFoundException(packetClass, type, index);
|
||||
}
|
||||
try {
|
||||
field.set(packet.getRawNMSPacket(), value);
|
||||
} catch (IllegalAccessException | NullPointerException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private Field getField(Class<?> type, int index) {
|
||||
Map<Class<?>, Field[]> cached = FIELD_CACHE.computeIfAbsent(packetClass, k -> new HashMap<>());
|
||||
Field[] fields = cached.computeIfAbsent(type, typeClass -> getFields(typeClass, packetClass.getDeclaredFields()));
|
||||
return fields[index];
|
||||
}
|
||||
|
||||
private Field[] getFields(Class<?> type, Field[] fields) {
|
||||
List<Field> ret = new ArrayList<>();
|
||||
for (Field field : fields) {
|
||||
if (field.getType().equals(type)) {
|
||||
if (!field.isAccessible()) {
|
||||
field.setAccessible(true);
|
||||
}
|
||||
ret.add(field);
|
||||
}
|
||||
}
|
||||
return ret.toArray(EMPTY_FIELD_ARRAY);
|
||||
}
|
||||
|
||||
// Does the server version support reading/sending this packet?
|
||||
public boolean isSupported() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers;
|
||||
|
||||
public interface WrapperPacketReader {
|
||||
|
||||
boolean readBoolean(int index);
|
||||
|
||||
byte readByte(int index);
|
||||
|
||||
short readShort(int index);
|
||||
|
||||
int readInt(int index);
|
||||
|
||||
long readLong(int index);
|
||||
|
||||
float readFloat(int index);
|
||||
|
||||
double readDouble(int index);
|
||||
|
||||
boolean[] readBooleanArray(int index);
|
||||
|
||||
byte[] readByteArray(int index);
|
||||
|
||||
short[] readShortArray(int index);
|
||||
|
||||
int[] readIntArray(int index);
|
||||
|
||||
long[] readLongArray(int index);
|
||||
|
||||
float[] readFloatArray(int index);
|
||||
|
||||
double[] readDoubleArray(int index);
|
||||
|
||||
String[] readStringArray(int index);
|
||||
|
||||
String readString(int index);
|
||||
|
||||
Object readObject(int index, Class<?> type);
|
||||
|
||||
Object readAnyObject(int index);
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers;
|
||||
|
||||
public interface WrapperPacketWriter {
|
||||
|
||||
// TODO write for the arrays
|
||||
void writeBoolean(int index, boolean value);
|
||||
|
||||
void writeByte(int index, byte value);
|
||||
|
||||
void writeShort(int index, short value);
|
||||
|
||||
void writeInt(int index, int value);
|
||||
|
||||
void writeLong(int index, long value);
|
||||
|
||||
void writeFloat(int index, float value);
|
||||
|
||||
void writeDouble(int index, double value);
|
||||
|
||||
void writeString(int index, String value);
|
||||
|
||||
void writeObject(int index, Object object);
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.api;
|
||||
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class WrappedPacket {
|
||||
protected static ServerVersion version = ServerVersion.getVersion();
|
||||
protected final Player player;
|
||||
protected Object packet;
|
||||
|
||||
public WrappedPacket() {
|
||||
this.player= null;
|
||||
this.packet = null;
|
||||
}
|
||||
|
||||
public WrappedPacket(final Object packet) {
|
||||
this.player = null;
|
||||
if (packet == null) return;
|
||||
this.packet = packet;
|
||||
try {
|
||||
setup();
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public WrappedPacket(final Player player, final Object packet) {
|
||||
this.player = player;
|
||||
if (packet == null) return;
|
||||
this.packet = packet;
|
||||
try {
|
||||
setup();
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void setup() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-67
@@ -1,67 +0,0 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.abilities;
|
||||
|
||||
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 WrappedPacketInAbilities extends WrappedPacket {
|
||||
private static Class<?> abilitiesClass;
|
||||
|
||||
static {
|
||||
|
||||
try {
|
||||
abilitiesClass = NMSUtils.getNMSClass("PacketPlayInAbilities");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isVulnerable;
|
||||
private boolean isFlying;
|
||||
private boolean allowFly;
|
||||
private boolean instantBuild;
|
||||
private float flySpeed;
|
||||
private float walkSpeed;
|
||||
|
||||
public WrappedPacketInAbilities(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
try {
|
||||
this.isVulnerable = Reflection.getField(abilitiesClass, boolean.class, 0).getBoolean(packet);
|
||||
this.isFlying = Reflection.getField(abilitiesClass, boolean.class, 1).getBoolean(packet);
|
||||
this.allowFly = Reflection.getField(abilitiesClass, boolean.class, 2).getBoolean(packet);
|
||||
this.instantBuild = Reflection.getField(abilitiesClass, boolean.class, 3).getBoolean(packet);
|
||||
this.flySpeed = Reflection.getField(abilitiesClass, float.class, 0).getFloat(packet);
|
||||
this.walkSpeed = Reflection.getField(abilitiesClass, float.class, 1).getFloat(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isVulnerable() {
|
||||
return isVulnerable;
|
||||
}
|
||||
|
||||
public boolean isFlying() {
|
||||
return isFlying;
|
||||
}
|
||||
|
||||
public boolean isFlightAllowed() {
|
||||
return allowFly;
|
||||
}
|
||||
|
||||
public boolean canInstantlyBuild() {
|
||||
return instantBuild;
|
||||
}
|
||||
|
||||
public float getFlySpeed() {
|
||||
return flySpeed;
|
||||
}
|
||||
|
||||
public float getWalkSpeed() {
|
||||
return walkSpeed;
|
||||
}
|
||||
}
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.armanimation;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
-96
@@ -1,96 +0,0 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.blockdig;
|
||||
|
||||
import io.github.retrooper.packetevents.enums.Direction;
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.enums.minecraft.PlayerDigType;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.vector.Vector3i;
|
||||
|
||||
public final class WrappedPacketInBlockDig extends WrappedPacket {
|
||||
private static Class<?> blockDigClass, blockPositionClass, enumDirectionClass, digTypeClass;
|
||||
|
||||
static {
|
||||
|
||||
try {
|
||||
blockDigClass = NMSUtils.getNMSClass("PacketPlayInBlockDig");
|
||||
if (version.isHigherThan(ServerVersion.v_1_7_10)) {
|
||||
blockPositionClass = NMSUtils.getNMSClass("BlockPosition");
|
||||
enumDirectionClass = NMSUtils.getNMSClass("EnumDirection");
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (version.isHigherThan(ServerVersion.v_1_7_10)) {
|
||||
try {
|
||||
digTypeClass = NMSUtils.getNMSClass("EnumPlayerDigType");
|
||||
} catch (ClassNotFoundException e) {
|
||||
//It is probably a subclass
|
||||
digTypeClass = Reflection.getSubClass(blockDigClass, "EnumPlayerDigType");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Vector3i blockPosition;
|
||||
private Direction direction;
|
||||
private PlayerDigType digType;
|
||||
|
||||
public WrappedPacketInBlockDig(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
Direction enumDirection = null;
|
||||
PlayerDigType enumDigType = null;
|
||||
int x = 0, y = 0, z = 0;
|
||||
//1.7.10
|
||||
try {
|
||||
if (version.isLowerThan(ServerVersion.v_1_8)) {
|
||||
enumDigType = PlayerDigType.get(Reflection.getField(blockDigClass, int.class, 4).getInt(packet));
|
||||
x = Reflection.getField(blockDigClass, int.class, 0).getInt(packet);
|
||||
y = Reflection.getField(blockDigClass, int.class, 1).getInt(packet);
|
||||
z = Reflection.getField(blockDigClass, int.class, 2).getInt(packet);
|
||||
enumDirection = null;
|
||||
} else {
|
||||
//1.8+
|
||||
final Object blockPosObj = Reflection.getField(blockDigClass, blockPositionClass, 0).get(packet);
|
||||
final Object enumDirectionObj = Reflection.getField(blockDigClass, enumDirectionClass, 0).get(packet);
|
||||
final Object digTypeObj = Reflection.getField(blockDigClass, digTypeClass, 0).get(packet);
|
||||
|
||||
Class<?> blockPosSuper = blockPositionClass;
|
||||
x = Reflection.getField(blockPosSuper, int.class, 0).getInt(blockPosObj);
|
||||
y = Reflection.getField(blockPosSuper, int.class, 1).getInt(blockPosObj);
|
||||
z = Reflection.getField(blockPosSuper, int.class, 2).getInt(blockPosObj);
|
||||
|
||||
enumDirection = Direction.valueOf(((Enum) enumDirectionObj).name());
|
||||
enumDigType = PlayerDigType.valueOf(((Enum) digTypeObj).name());
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.blockPosition = new Vector3i(x, y, z);
|
||||
if (enumDirection == null) {
|
||||
this.direction = Direction.NULL;
|
||||
} else {
|
||||
this.direction = enumDirection;
|
||||
}
|
||||
this.digType = enumDigType;
|
||||
}
|
||||
|
||||
public Vector3i getBlockPosition() {
|
||||
return blockPosition;
|
||||
}
|
||||
|
||||
public Direction getDirection() {
|
||||
return direction;
|
||||
}
|
||||
|
||||
public PlayerDigType getDigType() {
|
||||
return digType;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
-64
@@ -1,64 +0,0 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.blockplace;
|
||||
|
||||
import io.github.retrooper.packetevents.enums.ServerVersion;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.vector.Vector3i;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
|
||||
public final class WrappedPacketInBlockPlace extends WrappedPacket {
|
||||
static {
|
||||
if (version.isHigherThan(ServerVersion.v_1_7_10)) {
|
||||
WrappedPacketInBlockPlace_1_8.initStatic();
|
||||
}
|
||||
}
|
||||
|
||||
private Vector3i blockPosition;
|
||||
private ItemStack itemStack;
|
||||
|
||||
public WrappedPacketInBlockPlace(final Player player, final Object packet) {
|
||||
super(player, packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
//1.7.10
|
||||
Vector3i position = null;
|
||||
ItemStack itemStack = null;
|
||||
try {
|
||||
if (version.isHigherThan(ServerVersion.v_1_8_8)) {
|
||||
final WrappedPacketInBlockPlace_1_9 blockPlace_1_9 = new WrappedPacketInBlockPlace_1_9(getPlayer(), packet);
|
||||
final Block block = blockPlace_1_9.getBlock();
|
||||
position = new Vector3i(block.getX(), block.getY(), block.getZ());
|
||||
itemStack = new ItemStack(block.getType());
|
||||
} else if (version.isHigherThan(ServerVersion.v_1_7_10)) {
|
||||
final WrappedPacketInBlockPlace_1_8 blockPlace_1_8 = new WrappedPacketInBlockPlace_1_8(packet);
|
||||
position = blockPlace_1_8.getBlockPosition();
|
||||
itemStack = blockPlace_1_8.getItemStack();
|
||||
} else {
|
||||
final WrappedPacketInBlockPlace_1_7_10 blockPlace_1_7_10 = new WrappedPacketInBlockPlace_1_7_10(getPlayer(), packet);
|
||||
position = blockPlace_1_7_10.getBlockPosition();
|
||||
this.itemStack = blockPlace_1_7_10.getItemStack();
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.blockPosition = position;
|
||||
this.itemStack = itemStack;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
public Vector3i getBlockPosition() {
|
||||
return blockPosition;
|
||||
}
|
||||
|
||||
public ItemStack getItemStack() {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
}
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.blockplace;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.vector.Vector3i;
|
||||
import net.minecraft.server.v1_7_R4.PacketPlayInBlockPlace;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
final class WrappedPacketInBlockPlace_1_7_10 extends WrappedPacket {
|
||||
private Vector3i blockPosition;
|
||||
private ItemStack itemStack;
|
||||
private int blockFace;
|
||||
|
||||
WrappedPacketInBlockPlace_1_7_10(final Player player, final Object packet) {
|
||||
super(player, packet);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
final PacketPlayInBlockPlace blockPlace = (PacketPlayInBlockPlace) packet;
|
||||
|
||||
this.blockPosition = new Vector3i(blockPlace.c(), blockPlace.d(), blockPlace.e());
|
||||
|
||||
this.blockFace = blockPlace.d();
|
||||
|
||||
net.minecraft.server.v1_7_R4.ItemStack stack = blockPlace.getItemStack();
|
||||
this.itemStack = org.bukkit.craftbukkit.v1_7_R4.inventory.CraftItemStack.asBukkitCopy(stack);
|
||||
}
|
||||
|
||||
public Vector3i getBlockPosition() {
|
||||
return blockPosition;
|
||||
}
|
||||
|
||||
public ItemStack getItemStack() {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
public int getBlockFace() {
|
||||
return blockFace;
|
||||
}
|
||||
}
|
||||
-56
@@ -1,56 +0,0 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.blockplace;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.vector.Vector3i;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
final class WrappedPacketInBlockPlace_1_8 extends WrappedPacket {
|
||||
private static Class<?> blockPlaceClass, blockPositionClass;
|
||||
private Vector3i blockPosition;
|
||||
private ItemStack itemStack;
|
||||
|
||||
WrappedPacketInBlockPlace_1_8(final Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
protected static void initStatic() {
|
||||
try {
|
||||
blockPlaceClass = NMSUtils.getNMSClass("PacketPlayInBlockPlace");
|
||||
|
||||
blockPositionClass = NMSUtils.getNMSClass("BlockPosition");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
try {
|
||||
Object nmsBlockPos = Reflection.getField(blockPlaceClass, blockPositionClass, 1).get(packet);
|
||||
|
||||
final int[] coords = new int[3];
|
||||
for (int i = 0; i < 3; i++) {
|
||||
final String s = "get" + (i == 0 ? "X" : i == 1 ? "Y" : "Z");
|
||||
coords[i] = (int) Reflection.getMethod(blockPositionClass.getSuperclass(), s, 0).invoke(nmsBlockPos);
|
||||
}
|
||||
|
||||
this.blockPosition = new Vector3i(coords[0], coords[1], coords[2]);
|
||||
|
||||
this.itemStack = NMSUtils.toBukkitItemStack(Reflection.getField(blockPlaceClass, NMSUtils.nmsItemStackClass, 0).get(packet));
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3i getBlockPosition() {
|
||||
return blockPosition;
|
||||
}
|
||||
|
||||
public ItemStack getItemStack() {
|
||||
return itemStack;
|
||||
}
|
||||
}
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.blockplace;
|
||||
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.BlockIteratorUtils;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
final class WrappedPacketInBlockPlace_1_9 extends WrappedPacket {
|
||||
private Block block;
|
||||
|
||||
public WrappedPacketInBlockPlace_1_9(final Player player, final Object packet) {
|
||||
super(player, packet);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
this.block = BlockIteratorUtils.getBlockLookingAt(getPlayer(), 3);
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
public Block getBlock() {
|
||||
return block;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.chat;
|
||||
|
||||
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 WrappedPacketInChat extends WrappedPacket {
|
||||
private static Class<?> chatPacketClass;
|
||||
|
||||
static {
|
||||
try {
|
||||
chatPacketClass = NMSUtils.getNMSClass("PacketPlayInChat");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private String message;
|
||||
|
||||
public WrappedPacketInChat(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
try {
|
||||
final Object obj = Reflection.getField(chatPacketClass, String.class, 0).get(packet);
|
||||
this.message = obj.toString();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
-58
@@ -1,58 +0,0 @@
|
||||
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.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.values()[(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 enum ClientCommand {
|
||||
PERFORM_RESPAWN,
|
||||
REQUEST_STATS,
|
||||
OPEN_INVENTORY_ACHIEVEMENT;
|
||||
}
|
||||
|
||||
}
|
||||
-62
@@ -1,62 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
-91
@@ -1,91 +0,0 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.entityaction;
|
||||
|
||||
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;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
public final class WrappedPacketInEntityAction extends WrappedPacket {
|
||||
private static Class<?> entityActionClass;
|
||||
@Nullable
|
||||
private static Class<?> enumPlayerActionClass;
|
||||
|
||||
static {
|
||||
try {
|
||||
entityActionClass = NMSUtils.getNMSClass("PacketPlayInEntityAction");
|
||||
if (version.isHigherThan(ServerVersion.v_1_7_10)) {
|
||||
enumPlayerActionClass = Reflection.getSubClass(entityActionClass, "EnumPlayerAction");
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private Entity entity;
|
||||
private int entityId;
|
||||
private PlayerAction action;
|
||||
private int jumpBoost;
|
||||
|
||||
public WrappedPacketInEntityAction(final Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
try {
|
||||
final int entityId = Reflection.getField(entityActionClass, int.class, 0).getInt(packet);
|
||||
final int jumpBoost;
|
||||
if (version.isLowerThan(ServerVersion.v_1_8)) {
|
||||
jumpBoost = Reflection.getField(entityActionClass, int.class, 2).getInt(packet);
|
||||
} else {
|
||||
jumpBoost = Reflection.getField(entityActionClass, int.class, 1).getInt(packet);
|
||||
}
|
||||
|
||||
int animationIndex = -1;
|
||||
|
||||
//1.7.10
|
||||
if (version.isLowerThan(ServerVersion.v_1_8)) {
|
||||
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();
|
||||
try {
|
||||
this.action = PlayerAction.valueOf(enumValue);
|
||||
} catch (IllegalArgumentException e) {
|
||||
//They aren't on a legacy version and the enum has changed
|
||||
final PlayerAction.UpdatedPlayerAction updatedPlayerAction = PlayerAction.UpdatedPlayerAction.valueOf(enumValue);
|
||||
this.action = PlayerAction.get(updatedPlayerAction.getIndex());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.entityId = entityId;
|
||||
this.jumpBoost = jumpBoost;
|
||||
if (animationIndex != -1) {
|
||||
this.action = PlayerAction.get(animationIndex);
|
||||
}
|
||||
this.entity = NMSUtils.getEntityById(this.entityId);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public Entity getEntity() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
public int getEntityId() {
|
||||
return entityId;
|
||||
}
|
||||
|
||||
public PlayerAction getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
public int getJumpBoost() {
|
||||
return jumpBoost;
|
||||
}
|
||||
}
|
||||
-164
@@ -1,164 +0,0 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.flying;
|
||||
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
|
||||
public class WrappedPacketInFlying extends WrappedPacket {
|
||||
private static Class<?> flyingClass;
|
||||
|
||||
static {
|
||||
|
||||
try {
|
||||
flyingClass = NMSUtils.getNMSClass("PacketPlayInFlying");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private double x;
|
||||
private double y;
|
||||
private double z;
|
||||
private float yaw;
|
||||
private float pitch;
|
||||
private boolean onGround;
|
||||
private boolean isPosition;
|
||||
private boolean isLook;
|
||||
|
||||
public WrappedPacketInFlying(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
try {
|
||||
//x, y, z, yaw pitch, onGround, isPosition, isLook
|
||||
this.x = Reflection.getField(flyingClass, double.class, 0).getDouble(packet);
|
||||
this.y = Reflection.getField(flyingClass, double.class, 1).getDouble(packet);
|
||||
this.z = Reflection.getField(flyingClass, double.class, 2).getDouble(packet);
|
||||
|
||||
this.yaw = Reflection.getField(flyingClass, float.class, 0).getFloat(packet);
|
||||
this.pitch = Reflection.getField(flyingClass, float.class, 1).getFloat(packet);
|
||||
|
||||
this.onGround = Reflection.getField(flyingClass, boolean.class, 0).getBoolean(packet);
|
||||
|
||||
this.isPosition = Reflection.getField(flyingClass, boolean.class, 1).getBoolean(packet);
|
||||
this.isLook = Reflection.getField(flyingClass, boolean.class, 2).getBoolean(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public final double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public final double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public final double getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public final float getYaw() {
|
||||
return yaw;
|
||||
}
|
||||
|
||||
public final float getPitch() {
|
||||
return pitch;
|
||||
}
|
||||
|
||||
public final boolean isOnGround() {
|
||||
return onGround;
|
||||
}
|
||||
|
||||
public boolean isPosition() {
|
||||
return isPosition;
|
||||
}
|
||||
|
||||
public boolean isLook() {
|
||||
return isLook;
|
||||
}
|
||||
|
||||
public static class WrappedPacketInPosition extends WrappedPacketInFlying {
|
||||
public WrappedPacketInPosition(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPosition() {
|
||||
try {
|
||||
return Reflection.getField(flyingClass, boolean.class, 1).getBoolean(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLook() {
|
||||
try {
|
||||
return Reflection.getField(flyingClass, boolean.class, 2).getBoolean(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static class WrappedPacketInPosition_Look extends WrappedPacketInFlying {
|
||||
public WrappedPacketInPosition_Look(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPosition() {
|
||||
try {
|
||||
return Reflection.getField(flyingClass, boolean.class, 1).getBoolean(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLook() {
|
||||
try {
|
||||
return Reflection.getField(flyingClass, boolean.class, 2).getBoolean(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static class WrappedPacketInLook extends WrappedPacketInFlying {
|
||||
|
||||
public WrappedPacketInLook(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPosition() {
|
||||
try {
|
||||
return Reflection.getField(flyingClass, boolean.class, 1).getBoolean(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLook() {
|
||||
try {
|
||||
return Reflection.getField(flyingClass, boolean.class, 2).getBoolean(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.keepalive;
|
||||
|
||||
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<?> packetClass;
|
||||
|
||||
static {
|
||||
try {
|
||||
packetClass = NMSUtils.getNMSClass("PacketPlayInKeepAlive");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private long id;
|
||||
|
||||
public WrappedPacketInKeepAlive(final Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
-139
@@ -1,139 +0,0 @@
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
private String locale;
|
||||
private byte viewDistance;
|
||||
private ChatVisibility chatVisibility;
|
||||
private boolean chatColors;
|
||||
private HashMap<DisplayedSkinPart, Boolean> displayedSkinParts;
|
||||
public WrappedPacketInSettings(final Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public static Class<?> getChatVisibilityEnumClass() {
|
||||
return chatVisibilityEnumClass;
|
||||
}
|
||||
|
||||
@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 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);
|
||||
}
|
||||
|
||||
public enum ChatVisibility {
|
||||
ENABLED, COMMANDS_ONLY, HIDDEN
|
||||
}
|
||||
|
||||
public enum DisplayedSkinPart {
|
||||
CAPE, JACKET, LEFT_SLEEVE, RIGHT_SLEEVE, LEFT_PANTS, RIGHT_PANTS, HAT
|
||||
}
|
||||
}
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.steervehicle;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
|
||||
public class WrappedPacketInSteerVehicle extends WrappedPacket {
|
||||
private static Class<?> packetClass;
|
||||
|
||||
static {
|
||||
try {
|
||||
packetClass = NMSUtils.getNMSClass("PacketPlayInSteerVehicle");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private float side, forward;
|
||||
private boolean jump, unmount;
|
||||
|
||||
public WrappedPacketInSteerVehicle(Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
try {
|
||||
this.side = Reflection.getField(packetClass, float.class, 0).getFloat(packet);
|
||||
this.forward = Reflection.getField(packetClass, float.class, 1).getFloat(packet);
|
||||
|
||||
this.jump = Reflection.getField(packetClass, boolean.class, 0).getBoolean(packet);
|
||||
this.unmount = Reflection.getField(packetClass, boolean.class, 1).getBoolean(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
//Positive side value means left, negative means right
|
||||
public float getSideValue() {
|
||||
return side;
|
||||
}
|
||||
|
||||
//Positive forward value means forward, negative is backwards
|
||||
public float getForwardValue() {
|
||||
return forward;
|
||||
}
|
||||
|
||||
public boolean isJump() {
|
||||
return jump;
|
||||
}
|
||||
|
||||
public boolean isUnmount() {
|
||||
return unmount;
|
||||
}
|
||||
}
|
||||
-49
@@ -1,49 +0,0 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.transaction;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
|
||||
public final class WrappedPacketInTransaction extends WrappedPacket {
|
||||
private static Class<?> packetClass;
|
||||
|
||||
static {
|
||||
try {
|
||||
packetClass = NMSUtils.getNMSClass("PacketPlayInTransaction");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private int windowId;
|
||||
private short actionNumber;
|
||||
private boolean accepted;
|
||||
|
||||
public WrappedPacketInTransaction(final Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
try {
|
||||
this.windowId = Reflection.getField(packetClass, int.class, 0).getInt(packet);
|
||||
this.actionNumber = Reflection.getField(packetClass, short.class, 0).getShort(packet);
|
||||
this.accepted = Reflection.getField(packetClass, boolean.class, 0).getBoolean(packet);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int getWindowId() {
|
||||
return windowId;
|
||||
}
|
||||
|
||||
public short getActionNumber() {
|
||||
return actionNumber;
|
||||
}
|
||||
|
||||
public boolean isAccepted() {
|
||||
return accepted;
|
||||
}
|
||||
}
|
||||
-63
@@ -1,63 +0,0 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.in.useentity;
|
||||
|
||||
import io.github.retrooper.packetevents.enums.minecraft.EntityUseAction;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.reflectionutils.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.NMSUtils;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
public final class WrappedPacketInUseEntity extends WrappedPacket {
|
||||
private static Class<?> useEntityClass, entityClass, enumEntityUseActionClass;
|
||||
|
||||
static {
|
||||
|
||||
try {
|
||||
useEntityClass = NMSUtils.getNMSClass("PacketPlayInUseEntity");
|
||||
entityClass = NMSUtils.getNMSClass("Entity");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
enumEntityUseActionClass = NMSUtils.getNMSClass("EnumEntityUseAction");
|
||||
} catch (ClassNotFoundException e) {
|
||||
//That is fine, it is probably a subclass
|
||||
for (final Class<?> sub : useEntityClass.getDeclaredClasses()) {
|
||||
if (sub.getSimpleName().equals("EnumEntityUseAction")) {
|
||||
enumEntityUseActionClass = sub;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int entityId;
|
||||
private EntityUseAction action;
|
||||
|
||||
public WrappedPacketInUseEntity(final Object packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
try {
|
||||
this.entityId = Reflection.getField(useEntityClass, int.class, 0).getInt(packet);
|
||||
final Object useActionEnum = Reflection.getField(useEntityClass, enumEntityUseActionClass, 0).get(packet);
|
||||
this.action = EntityUseAction.valueOf(useActionEnum.toString());
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public Entity getEntity() {
|
||||
return NMSUtils.getEntityById(this.entityId);
|
||||
}
|
||||
|
||||
public int getEntityId() {
|
||||
return entityId;
|
||||
}
|
||||
|
||||
public EntityUseAction getAction() {
|
||||
return action;
|
||||
}
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.login.in.custompayload;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
|
||||
/**
|
||||
* This packet exists since 1.13
|
||||
*/
|
||||
public class WrappedPacketLoginInCustomPayload extends WrappedPacket {
|
||||
private static Class<?> byteBufClass;
|
||||
private static Class<?> packetDataSerializerClass;
|
||||
|
||||
public WrappedPacketLoginInCustomPayload(NMSPacket packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void load() {
|
||||
packetDataSerializerClass = NMSUtils.getNMSClassWithoutException("PacketDataSerializer");
|
||||
try {
|
||||
byteBufClass = NMSUtils.getNettyClass("buffer.ByteBuf");
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
public int getMessageId() {
|
||||
return readInt(0);
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
Object dataSerializer = readObject(0, packetDataSerializerClass);
|
||||
WrappedPacket byteBufWrapper = new WrappedPacket(new NMSPacket(dataSerializer));
|
||||
Object byteBuf = byteBufWrapper.readObject(0, byteBufClass);
|
||||
return PacketEvents.get().getByteBufUtil().getBytes(byteBuf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
return version.isHigherThan(ServerVersion.v_1_12_2);
|
||||
}
|
||||
}
|
||||
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 retrooper
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.packetwrappers.login.in.encryptionbegin;
|
||||
|
||||
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
|
||||
public class WrappedPacketLoginInEncryptionBegin extends WrappedPacket {
|
||||
public WrappedPacketLoginInEncryptionBegin(NMSPacket packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public byte[] getPublicKey() {
|
||||
return readByteArray(0);
|
||||
}
|
||||
|
||||
public byte[] getVerifyToken() {
|
||||
return readByteArray(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
return PacketTypeClasses.Login.Client.ENCRYPTION_BEGIN != null;
|
||||
}
|
||||
}
|
||||
Loaded 100 of 228 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user