Compare commits
106
Commits
v1.8-pre-19
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e3a984ca72 | ||
|
|
f8fad9607b | ||
|
|
a9e40c2abc | ||
|
|
da12521d0b | ||
|
|
de1f91104d | ||
|
|
f02b77c0ba | ||
|
|
bf2e88ed8f | ||
|
|
f04a3c75a9 | ||
|
|
80408424dd | ||
|
|
cb897dabe5 | ||
|
|
92cb0d024d | ||
|
|
72e617624a | ||
|
|
239d712b5f | ||
|
|
9b9ab1ade6 | ||
|
|
63383579b4 | ||
|
|
a2e19f7020 | ||
|
|
7ff578e1c6 | ||
|
|
95952588f1 | ||
|
|
8d4d89f049 | ||
|
|
74ddbacff5 | ||
|
|
2b1d6c636d | ||
|
|
e47c10966e | ||
|
|
9153aa6945 | ||
|
|
34e4007f7d | ||
|
|
0528eb7035 | ||
|
|
3a25a933ff | ||
|
|
efa694c8e1 | ||
|
|
289a71106a | ||
|
|
012bcae2d5 | ||
|
|
c84641cc83 | ||
|
|
baf93f527c | ||
|
|
d95d5394eb | ||
|
|
2675b41c3e | ||
|
|
4d27d6e967 | ||
|
|
9ecadae4f9 | ||
|
|
5939573ee3 | ||
|
|
1bbc2cba77 | ||
|
|
1c35fe3b92 | ||
|
|
e6a7b7a3b1 | ||
|
|
3581e23923 | ||
|
|
33c0d9d934 | ||
|
|
70eaec04c7 | ||
|
|
be7aca69ef | ||
|
|
6777809d1c | ||
|
|
39ec3dc117 | ||
|
|
d52a96722d | ||
|
|
7e76aaa2af | ||
|
|
022c081527 | ||
|
|
0b3f49cc53 | ||
|
|
54a68013f8 | ||
|
|
3b947e7b9a | ||
|
|
01b201cef9 | ||
|
|
8fdd8e5676 | ||
|
|
7fd4015b4f | ||
|
|
4f2f355a98 | ||
|
|
62afe05c28 | ||
|
|
b910cd189f | ||
|
|
1692451244 | ||
|
|
26fde1e9a3 | ||
|
|
5e42bef488 | ||
|
|
f7aacf1ad6 | ||
|
|
87aedb23fd | ||
|
|
bf60cb0543 | ||
|
|
367f561eb3 | ||
|
|
bb9132a673 | ||
|
|
b843499ac6 | ||
|
|
8809088b66 | ||
|
|
d5d4a9bffc | ||
|
|
14f3d26630 | ||
|
|
dacf44dc29 | ||
|
|
b2d7219105 | ||
|
|
362bb8dbe7 | ||
|
|
59935293a6 | ||
|
|
1c0d932c48 | ||
|
|
c43d992619 | ||
|
|
c2e0fe6b4c | ||
|
|
14a783560c | ||
|
|
2767b99479 | ||
|
|
3d7a0d901f | ||
|
|
177e9b7f4e | ||
|
|
4711ede9bc | ||
|
|
6bd531efc0 | ||
|
|
d6f1bf972e | ||
|
|
3295b1fc89 | ||
|
|
f620e45a9c | ||
|
|
825b61a24e | ||
|
|
dc5d15ba85 | ||
|
|
0b458c2e4c | ||
|
|
bb9fe18a76 | ||
|
|
73420efbb7 | ||
|
|
c3bc1906b1 | ||
|
|
3c4a7323a0 | ||
|
|
0a4fedff09 | ||
|
|
d1fb535ca7 | ||
|
|
5865e056d8 | ||
|
|
eb561b98b2 | ||
|
|
13b3ac7107 | ||
|
|
1943ba2da1 | ||
|
|
f90925e09b | ||
|
|
e2ecb21892 | ||
|
|
80bc492370 | ||
|
|
691e8eb070 | ||
|
|
a83c3bac2a | ||
|
|
60a5357c34 | ||
|
|
af477f8479 | ||
|
|
6b82b38b59 |
No files matched your search
@@ -1,7 +1,7 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Report a bug to help us fix
|
||||
title: "[BUG REPORT]"
|
||||
about: Report bugs to help us improve our software.
|
||||
title: ""
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
@@ -10,11 +10,21 @@ assignees: ''
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
**Software brand**
|
||||
Please let us know what software you are using.
|
||||
Eg. Spigot 1.18.2, Paper 1.18.2, Tuinity 1.18.2, Pufferfish 1.18.2, etc...
|
||||
Make sure to mention the version of the software.
|
||||
|
||||
**Plugins**
|
||||
Please give us a list of your plugins. Sometimes we run into incompatibilities. Having an overview of the plugins on your server can really help identify the problem quicker.
|
||||
Eg. ViaVersion, ProtocolLib, HolographicDisplays
|
||||
You may also provide a screenshot.
|
||||
|
||||
**How 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.
|
||||
1. Join with the 1.18.2 vanilla minecraft client.
|
||||
2. Spam
|
||||
3. ....
|
||||
4. See error
|
||||
|
||||
@@ -24,18 +34,5 @@ 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.
|
||||
@@ -1,9 +1,9 @@
|
||||
# packetevents
|
||||
|
||||
[](https://github.com/retrooper/packetevents/blob/dev/LICENSE)
|
||||
[](https://github.com/retrooper/packetevents/blob/master/LICENSE)
|
||||
[](https://jitpack.io/#retrooper/packetevents)
|
||||
|
||||
PacketEvents is an open-source Packet API. It has many cross-version packet-wrappers. You can process incoming and outgoing packets on the server. You can even send packets with our packet-wrappers. We are here to save you a ton of time.
|
||||
PacketEvents is a powerful packet library. Our packet wrappers are efficient and easy to use. We support many protocol versions. (1.8+)
|
||||
|
||||
### Resources
|
||||
* [SpigotMC](https://www.spigotmc.org/resources/packetevents-api.80279/)
|
||||
@@ -13,15 +13,11 @@ PacketEvents is an open-source Packet API. It has many cross-version packet-wrap
|
||||
### Setup
|
||||
[Learn more](https://github.com/retrooper/packetevents/wiki/1.-Setup)
|
||||
|
||||
### Contributing/Forking
|
||||
[Learn more](https://github.com/retrooper/packetevents/wiki/2.-Contributing-and-Forking)\
|
||||
Our discord server has a role for contributors and forkers.
|
||||
|
||||
### Sponsorships
|
||||
[](https://www.ej-technologies.com/products/jprofiler/overview.html)
|
||||
|
||||
### Statistics
|
||||
PacketEvents collects statistics anonymously through bStats. Participation is completely optional and you can opt-out at any time, although it is really helpful in figuring out what environments the plugin is running in (i.e. versions of Spigot, Java), so I can adjust development accordingly.
|
||||
PacketEvents collects statistics anonymously using bStats. It helps give us an overview of what platforms use our project. If you really don't like, you can turn it off.
|
||||
|
||||
### Credit
|
||||
PacketEvents uses an injector that is extremely similar to ViaVersion's injector. I have included license and copyright holder notice in the files taken from ViaVersion. Thank you ViaVersion.
|
||||
+7
-11
@@ -34,10 +34,6 @@ repositories {
|
||||
url = uri('https://jitpack.io/')
|
||||
}
|
||||
|
||||
maven {
|
||||
url = uri('https://nexus.funkemunky.cc/content/repositories/releases/')
|
||||
}
|
||||
|
||||
maven {
|
||||
url = uri('https://repo.viaversion.com/')
|
||||
}
|
||||
@@ -49,27 +45,27 @@ repositories {
|
||||
maven {
|
||||
url = uri('https://repo.maven.apache.org/maven2/')
|
||||
}
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'org.jetbrains:annotations:20.1.0'
|
||||
implementation 'org.jetbrains:annotations:23.0.0'
|
||||
|
||||
compileOnly 'org.spigotmc:spigot-api:1.17-R0.1-SNAPSHOT'
|
||||
compileOnly 'com.destroystokyo.paper:paper-api:1.16.5-R0.1-SNAPSHOT'
|
||||
compileOnly 'org.geysermc:connector:1.4.2-SNAPSHOT'
|
||||
compileOnly 'com.viaversion:viaversion-api:4.0.1'
|
||||
compileOnly 'com.github.ProtocolSupport:ProtocolSupport:3d24efeda6'
|
||||
|
||||
compileOnly 'org.github.spigot:1.16.2:1.16.2'
|
||||
compileOnly 'org.github.spigot:1.8.8:1.8.8'
|
||||
compileOnly 'org.github.spigot:1.7.10:1.7.10'
|
||||
compileOnly group: 'com.github.azbh111', name: 'craftbukkit-1.14.3', version: 'R'
|
||||
compileOnly group: 'com.github.azbh111', name: 'craftbukkit-1.8.8', version: 'R'
|
||||
compileOnly group: 'com.github.azbh111', name: 'craftbukkit-1.7.10', version: 'R'
|
||||
}
|
||||
|
||||
group = 'io.github.retrooper'
|
||||
version = '1.8-pre-19'
|
||||
version = '1.8.4'
|
||||
description = 'packetevents'
|
||||
java.sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
|
||||
java.targetCompatibility = JavaVersion.VERSION_1_8
|
||||
publishing {
|
||||
publications {
|
||||
maven(MavenPublication) {
|
||||
|
||||
@@ -57,7 +57,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
public final class PacketEvents implements Listener, EventManager {
|
||||
private static PacketEvents instance;
|
||||
private static Plugin plugin;
|
||||
private final PEVersion version = new PEVersion(1, 7, 9, 19);
|
||||
private final PEVersion version = new PEVersion(1, 8, 4);
|
||||
private final EventManager eventManager = new PEEventManager();
|
||||
private final PlayerUtils playerUtils = new PlayerUtils();
|
||||
private final ServerUtils serverUtils = new ServerUtils();
|
||||
@@ -161,10 +161,12 @@ public final class PacketEvents implements Listener, EventManager {
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void loadAsyncNewThread() {
|
||||
new Thread(this::load).start();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void loadAsync(ExecutorService executorService) {
|
||||
executorService.execute(this::load);
|
||||
}
|
||||
@@ -191,6 +193,10 @@ public final class PacketEvents implements Listener, EventManager {
|
||||
|
||||
if (settings.isbStatsEnabled()) {
|
||||
Metrics metrics = new Metrics((JavaPlugin) getPlugin(), 11327);
|
||||
//Just to have an idea what versions of packetevents people use
|
||||
metrics.addCustomChart(new Metrics.SimplePie("packetevents_version", () -> {
|
||||
return getVersion().toString();
|
||||
}));
|
||||
}
|
||||
|
||||
//We must wait for the injector to initialize.
|
||||
|
||||
@@ -18,17 +18,34 @@
|
||||
|
||||
package io.github.retrooper.packetevents;
|
||||
|
||||
import io.github.retrooper.packetevents.event.PacketListenerAbstract;
|
||||
import io.github.retrooper.packetevents.event.impl.PacketConfigReceiveEvent;
|
||||
import io.github.retrooper.packetevents.event.impl.PacketPlayReceiveEvent;
|
||||
import io.github.retrooper.packetevents.event.impl.PacketPlaySendEvent;
|
||||
import io.github.retrooper.packetevents.packettype.PacketType;
|
||||
import io.github.retrooper.packetevents.packetwrappers.play.in.blockdig.WrappedPacketInBlockDig;
|
||||
import io.github.retrooper.packetevents.packetwrappers.play.in.custompayload.WrappedPacketInCustomPayload;
|
||||
import io.github.retrooper.packetevents.packetwrappers.play.in.entityaction.WrappedPacketInEntityAction;
|
||||
import io.github.retrooper.packetevents.packetwrappers.play.in.flying.WrappedPacketInFlying;
|
||||
import io.github.retrooper.packetevents.packetwrappers.play.in.useentity.WrappedPacketInUseEntity;
|
||||
import io.github.retrooper.packetevents.packetwrappers.play.out.entity.WrappedPacketOutEntity;
|
||||
import io.github.retrooper.packetevents.packetwrappers.play.out.entityeffect.WrappedPacketOutEntityEffect;
|
||||
import io.github.retrooper.packetevents.packetwrappers.play.out.entityvelocity.WrappedPacketOutEntityVelocity;
|
||||
import io.github.retrooper.packetevents.packetwrappers.play.out.setslot.WrappedPacketOutSetSlot;
|
||||
import io.github.retrooper.packetevents.settings.PacketEventsSettings;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class PacketEventsPlugin extends JavaPlugin {
|
||||
@Override
|
||||
public void onLoad() {
|
||||
PacketEventsSettings settings = PacketEvents.create(this).getSettings();
|
||||
settings
|
||||
.fallbackServerVersion(ServerVersion.getLatest())
|
||||
.compatInjector(false)
|
||||
.checkForUpdates(true)
|
||||
.bStats(true);
|
||||
PacketEvents.get().loadAsyncNewThread();
|
||||
@@ -37,6 +54,59 @@ public class PacketEventsPlugin extends JavaPlugin {
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
/*PacketEvents.get().getEventManager().registerListener(new PacketListenerAbstract() {
|
||||
@Override
|
||||
public void onPacketPlayReceive(PacketPlayReceiveEvent event) {
|
||||
if (event.getPacketId() == PacketType.Play.Client.USE_ENTITY) {
|
||||
System.out.println("Yes");
|
||||
WrappedPacketInUseEntity ue = new WrappedPacketInUseEntity(event.getNMSPacket());
|
||||
event.getPlayer().sendMessage("action: " + ue.getAction());
|
||||
event.getPlayer().sendMessage("target: " + ue.getTarget());
|
||||
ItemStack stack = new ItemStack(Material.STICK);
|
||||
WrappedPacketOutSetSlot setSlot = new WrappedPacketOutSetSlot(0, 37, stack);
|
||||
PacketEvents.get().getPlayerUtils().sendPacket(event.getPlayer(), setSlot);
|
||||
} else if (event.getPacketId() == PacketType.Play.Client.CUSTOM_PAYLOAD) {
|
||||
WrappedPacketInCustomPayload cp = new WrappedPacketInCustomPayload(event.getNMSPacket());
|
||||
String name = cp.getChannelName();
|
||||
System.out.println("name play: " + name);
|
||||
System.out.println("Data: " + ((new String(cp.getData(), StandardCharsets.UTF_8))));
|
||||
}
|
||||
else if (event.getPacketId() == PacketType.Play.Client.ENTITY_ACTION) {
|
||||
WrappedPacketInEntityAction ea = new WrappedPacketInEntityAction(event.getNMSPacket());
|
||||
event.getPlayer().sendMessage("EA: " + ea.getAction());
|
||||
} else if (PacketType.Play.Client.BLOCK_DIG == event.getPacketId()) {
|
||||
WrappedPacketInBlockDig bd = new WrappedPacketInBlockDig(event.getNMSPacket());
|
||||
event.getPlayer().sendMessage("bd: " + bd.getDigType());
|
||||
}
|
||||
else if (PacketType.Play.Client.Util.isInstanceOfFlying(event.getPacketId())) {
|
||||
WrappedPacketInFlying f = new WrappedPacketInFlying(event.getNMSPacket());
|
||||
System.out.println("flying: " + f.getPosition().toString() + ", pitch and yaw: " + f.getPitch() + ", " + f.getYaw());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketConfigReceive(PacketConfigReceiveEvent event) {
|
||||
if (event.getPacketId() == PacketType.Play.Client.CUSTOM_PAYLOAD) {
|
||||
WrappedPacketInCustomPayload cp = new WrappedPacketInCustomPayload(event.getNMSPacket());
|
||||
String name = cp.getChannelName();
|
||||
System.out.println("name: " + name);
|
||||
System.out.println("Data: " + ((new String(cp.getData(), StandardCharsets.UTF_8))));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketPlaySend(PacketPlaySendEvent event) {
|
||||
if (PacketType.Play.Server.Util.isInstanceOfEntity(event.getPacketId())) {
|
||||
WrappedPacketOutEntity entity = new WrappedPacketOutEntity(event.getNMSPacket());
|
||||
} else if (event.getPacketId() == PacketType.Play.Server.ENTITY_EFFECT) {
|
||||
WrappedPacketOutEntityEffect eff = new WrappedPacketOutEntityEffect(event.getNMSPacket());
|
||||
//TODO Broken on 1.20.5 eff.setEffectId(eff.getEffectId());
|
||||
System.out.println("eff: " + eff.getEffectId() + ", ampl: " + eff.getAmplifier() + ", dur:" + eff.getDuration());
|
||||
} else if (event.getPacketId() == PacketType.Play.Server.ENTITY_VELOCITY) {
|
||||
WrappedPacketOutEntityVelocity ev = new WrappedPacketOutEntityVelocity(event.getNMSPacket());
|
||||
}
|
||||
}
|
||||
});*/
|
||||
PacketEvents.get().init();
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +80,12 @@ public abstract class PacketListenerAbstract {
|
||||
public void onPacketLoginSend(PacketLoginSendEvent event) {
|
||||
}
|
||||
|
||||
public void onPacketConfigReceive(PacketConfigReceiveEvent event) {
|
||||
}
|
||||
|
||||
public void onPacketConfigSend(PacketConfigSendEvent event) {
|
||||
}
|
||||
|
||||
public void onPacketPlayReceive(PacketPlayReceiveEvent event) {
|
||||
}
|
||||
|
||||
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2021 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.event.PacketListenerAbstract;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.CancellableNMSPacketEvent;
|
||||
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
|
||||
|
||||
/**
|
||||
* The {@code PacketConfigReceiveEvent} event is fired whenever the a CONFIG packet is received from a client.
|
||||
* Use the {@link #getSocketAddress()} to identify who sends the packet.
|
||||
*
|
||||
* @author retrooper
|
||||
* @see <a href="https://wiki.vg/Protocol#Configuration">https://wiki.vg/Protocol#Configuration</a>
|
||||
* @since 1.8
|
||||
*/
|
||||
public class PacketConfigReceiveEvent extends CancellableNMSPacketEvent {
|
||||
public PacketConfigReceiveEvent(Object channel, NMSPacket packet) {
|
||||
super(channel, packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void call(PacketListenerAbstract listener) {
|
||||
if (listener.clientSidedLoginAllowance == null || listener.clientSidedLoginAllowance.contains(getPacketId())) {
|
||||
listener.onPacketConfigReceive(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2021 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.event.impl;
|
||||
|
||||
import io.github.retrooper.packetevents.event.PacketListenerAbstract;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.CancellableNMSPacketEvent;
|
||||
import io.github.retrooper.packetevents.event.eventtypes.PostTaskEvent;
|
||||
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* The {@code PacketConfigSendEvent} event is fired whenever the a LOGIN packet is being planned to be sent to the client.
|
||||
* Use the {@link #getSocketAddress()} to identify who sends the packet.
|
||||
*
|
||||
* @author retrooper
|
||||
* @see <a href="https://wiki.vg/Protocol#Configuration">https://wiki.vg/Protocol#Configuration</a>
|
||||
* @since 1.8
|
||||
*/
|
||||
public class PacketConfigSendEvent extends CancellableNMSPacketEvent implements PostTaskEvent {
|
||||
private Runnable postTask;
|
||||
public PacketConfigSendEvent(Object channel, NMSPacket packet) {
|
||||
super(channel, packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPostTaskAvailable() {
|
||||
return postTask != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Runnable getPostTask() {
|
||||
return postTask;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPostTask(@NotNull Runnable postTask) {
|
||||
this.postTask = postTask;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void call(PacketListenerAbstract listener) {
|
||||
if (listener.serverSidedLoginAllowance == null || listener.serverSidedLoginAllowance.contains(getPacketId())) {
|
||||
listener.onPacketConfigSend(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
-1
@@ -20,11 +20,13 @@ package io.github.retrooper.packetevents.injector.legacy;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.processor.PacketProcessorInternal;
|
||||
import net.minecraft.util.io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.util.io.netty.channel.ChannelDuplexHandler;
|
||||
import net.minecraft.util.io.netty.channel.ChannelHandler;
|
||||
import net.minecraft.util.io.netty.channel.ChannelHandlerContext;
|
||||
import net.minecraft.util.io.netty.channel.ChannelPromise;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@ChannelHandler.Sharable
|
||||
public class PlayerChannelHandlerLegacy extends ChannelDuplexHandler {
|
||||
/**
|
||||
* Associated player.
|
||||
@@ -43,6 +45,11 @@ public class PlayerChannelHandlerLegacy extends ChannelDuplexHandler {
|
||||
|
||||
@Override
|
||||
public void write(final ChannelHandlerContext ctx, Object packet, final ChannelPromise promise) throws Exception {
|
||||
if (packet instanceof ByteBuf) {
|
||||
//Ignore bytebufs!
|
||||
super.write(ctx, packet, promise);
|
||||
return;
|
||||
}
|
||||
PacketProcessorInternal.PacketData data = PacketEvents.get().getInternalPacketProcessor().write(player, ctx.channel(), packet);
|
||||
if (data.postAction != null) {
|
||||
promise.addListener(f -> {
|
||||
|
||||
+20
-4
@@ -25,6 +25,7 @@ import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.list.ListWrapper;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
|
||||
import net.minecraft.util.io.netty.channel.Channel;
|
||||
import net.minecraft.util.io.netty.channel.ChannelFuture;
|
||||
import net.minecraft.util.io.netty.channel.ChannelHandler;
|
||||
@@ -127,10 +128,10 @@ public class EarlyChannelInjectorLegacy implements EarlyInjector {
|
||||
for (Object networkManager : networkManagers) {
|
||||
WrappedPacket networkManagerWrapper = new WrappedPacket(new NMSPacket(networkManager), NMSUtils.networkManagerClass);
|
||||
Channel channel = (Channel) networkManagerWrapper.readObject(0, NMSUtils.nettyChannelClass);
|
||||
if (channel == null) {
|
||||
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|
||||
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (channel.pipeline().get(PacketEvents.get().getHandlerName()) != null) {
|
||||
channel.pipeline().remove(PacketEvents.get().getHandlerName());
|
||||
}
|
||||
@@ -226,7 +227,7 @@ public class EarlyChannelInjectorLegacy implements EarlyInjector {
|
||||
childHandlerField.set(bootstrapAcceptor, ((PEChannelInitializerLegacy) oldInit).getOldChannelInitializer());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
PacketEvents.get().getPlugin().getLogger().severe("PacketEvents failed to eject the injection handler! Please reboot!");
|
||||
//PacketEvents.get().getPlugin().getLogger().severe("PacketEvents failed to eject the injection handler! Please reboot!");
|
||||
}
|
||||
}
|
||||
injectedFutures.clear();
|
||||
@@ -242,7 +243,7 @@ public class EarlyChannelInjectorLegacy implements EarlyInjector {
|
||||
}
|
||||
|
||||
} catch (IllegalAccessException e) {
|
||||
PacketEvents.get().getPlugin().getLogger().severe("PacketEvents failed to eject the injection handler! Please reboot!!");
|
||||
//PacketEvents.get().getPlugin().getLogger().severe("PacketEvents failed to eject the injection handler! Please reboot!!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,18 +283,33 @@ public class EarlyChannelInjectorLegacy implements EarlyInjector {
|
||||
@Override
|
||||
public void writePacket(Object ch, Object rawNMSPacket) {
|
||||
Channel channel = (Channel) ch;
|
||||
//Don't write packets to fake channels
|
||||
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|
||||
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
|
||||
return;
|
||||
}
|
||||
channel.write(rawNMSPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flushPackets(Object ch) {
|
||||
Channel channel = (Channel) ch;
|
||||
//Don't flush packets for fake channels
|
||||
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|
||||
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
|
||||
return;
|
||||
}
|
||||
channel.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacket(Object ch, Object rawNMSPacket) {
|
||||
Channel channel = (Channel) ch;
|
||||
//Don't send packets to fake channels
|
||||
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|
||||
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
|
||||
return;
|
||||
}
|
||||
channel.writeAndFlush(rawNMSPacket);
|
||||
}
|
||||
|
||||
|
||||
+5
@@ -20,6 +20,7 @@ package io.github.retrooper.packetevents.injector.legacy.early;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.injector.legacy.PlayerChannelHandlerLegacy;
|
||||
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
import net.minecraft.util.io.netty.channel.Channel;
|
||||
import net.minecraft.util.io.netty.channel.ChannelInitializer;
|
||||
@@ -47,6 +48,10 @@ public class PEChannelInitializerLegacy extends ChannelInitializer<Channel> {
|
||||
protected void initChannel(Channel channel) throws Exception {
|
||||
initChannelMethod.invoke(oldChannelInitializer, channel);
|
||||
PlayerChannelHandlerLegacy channelHandler = new PlayerChannelHandlerLegacy();
|
||||
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|
||||
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
|
||||
return;
|
||||
}
|
||||
if (channel.pipeline().get("packet_handler") != null) {
|
||||
String handlerName = PacketEvents.get().getHandlerName();
|
||||
if (channel.pipeline().get(handlerName) != null) {
|
||||
|
||||
+22
-2
@@ -21,6 +21,7 @@ package io.github.retrooper.packetevents.injector.legacy.late;
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.injector.LateInjector;
|
||||
import io.github.retrooper.packetevents.injector.legacy.PlayerChannelHandlerLegacy;
|
||||
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
|
||||
import net.minecraft.util.io.netty.channel.Channel;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@@ -40,7 +41,11 @@ public class LateChannelInjectorLegacy implements LateInjector {
|
||||
PlayerChannelHandlerLegacy playerChannelHandlerLegacy = new PlayerChannelHandlerLegacy();
|
||||
playerChannelHandlerLegacy.player = player;
|
||||
Channel channel = (Channel) PacketEvents.get().getPlayerUtils().getChannel(player);
|
||||
channel.pipeline().addBefore("packet_handler", PacketEvents.get().getHandlerName(), playerChannelHandlerLegacy);
|
||||
if (channel != null) {
|
||||
channel.eventLoop().execute(() -> {
|
||||
channel.pipeline().addBefore("packet_handler", PacketEvents.get().getHandlerName(), playerChannelHandlerLegacy);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -58,24 +63,39 @@ public class LateChannelInjectorLegacy implements LateInjector {
|
||||
@Override
|
||||
public boolean hasInjected(Player player) {
|
||||
Channel channel = (Channel) PacketEvents.get().getPlayerUtils().getChannel(player);
|
||||
return channel.pipeline().get(PacketEvents.get().getHandlerName()) != null;
|
||||
return channel != null && channel.pipeline().get(PacketEvents.get().getHandlerName()) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writePacket(Object ch, Object rawNMSPacket) {
|
||||
Channel channel = (Channel) ch;
|
||||
//Don't write packets to fake channels
|
||||
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|
||||
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
|
||||
return;
|
||||
}
|
||||
channel.write(rawNMSPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flushPackets(Object ch) {
|
||||
Channel channel = (Channel) ch;
|
||||
//Don't flush packets for fake channels
|
||||
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|
||||
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
|
||||
return;
|
||||
}
|
||||
channel.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacket(Object rawChannel, Object packet) {
|
||||
Channel channel = (Channel) rawChannel;
|
||||
//Don't send packets to fake channels
|
||||
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|
||||
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
|
||||
return;
|
||||
}
|
||||
channel.pipeline().writeAndFlush(packet);
|
||||
}
|
||||
}
|
||||
+8
@@ -20,11 +20,14 @@ package io.github.retrooper.packetevents.injector.modern;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.processor.PacketProcessorInternal;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelDuplexHandler;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@ChannelHandler.Sharable
|
||||
public class PlayerChannelHandlerModern extends ChannelDuplexHandler {
|
||||
/**
|
||||
* Associated player.
|
||||
@@ -43,6 +46,11 @@ public class PlayerChannelHandlerModern extends ChannelDuplexHandler {
|
||||
|
||||
@Override
|
||||
public void write(final ChannelHandlerContext ctx, Object packet, final ChannelPromise promise) throws Exception {
|
||||
if (packet instanceof ByteBuf) {
|
||||
//Ignore bytebufs!
|
||||
super.write(ctx, packet, promise);
|
||||
return;
|
||||
}
|
||||
PacketProcessorInternal.PacketData data = PacketEvents.get().getInternalPacketProcessor().write(player, ctx.channel(), packet);
|
||||
if (data.postAction != null) {
|
||||
promise.addListener(f -> {
|
||||
|
||||
+25
-9
@@ -25,6 +25,7 @@ import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.list.ListWrapper;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
@@ -73,10 +74,10 @@ public class EarlyChannelInjectorModern implements EarlyInjector {
|
||||
@Override
|
||||
public void inject() {
|
||||
try {
|
||||
if (PaperChannelInjector.PAPER_INJECTION_METHOD) {
|
||||
/* if (PaperChannelInjector.PAPER_INJECTION_METHOD) {
|
||||
PaperChannelInjector.setPaperChannelInitializeListener();
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
Object serverConnection = NMSUtils.getMinecraftServerConnection();
|
||||
for (Field field : serverConnection.getClass().getDeclaredFields()) {
|
||||
field.setAccessible(true);
|
||||
@@ -130,7 +131,8 @@ public class EarlyChannelInjectorModern implements EarlyInjector {
|
||||
for (Object networkManager : networkManagers) {
|
||||
WrappedPacket networkManagerWrapper = new WrappedPacket(new NMSPacket(networkManager), NMSUtils.networkManagerClass);
|
||||
Channel channel = (Channel) networkManagerWrapper.readObject(0, NMSUtils.nettyChannelClass);
|
||||
if (channel == null) {
|
||||
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|
||||
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -195,13 +197,13 @@ public class EarlyChannelInjectorModern implements EarlyInjector {
|
||||
@Override
|
||||
public void eject() {
|
||||
// TODO: Uninject from players currently online to prevent protocol lib issues.
|
||||
if (PaperChannelInjector.PAPER_INJECTION_METHOD) {
|
||||
/* if (PaperChannelInjector.PAPER_INJECTION_METHOD) {
|
||||
try {
|
||||
PaperChannelInjector.removePaperChannelInitializeListener();
|
||||
} catch (ReflectiveOperationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}*/
|
||||
Field childHandlerField = null;
|
||||
for (ChannelFuture future : injectedFutures) {
|
||||
List<String> names = future.channel().pipeline().names();
|
||||
@@ -235,7 +237,7 @@ public class EarlyChannelInjectorModern implements EarlyInjector {
|
||||
childHandlerField.set(bootstrapAcceptor, ((PEChannelInitializerModern) oldInit).getOldChannelInitializer());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
PacketEvents.get().getPlugin().getLogger().severe("PacketEvents failed to eject the injection handler! Please reboot!");
|
||||
//PacketEvents.get().getPlugin().getLogger().severe("PacketEvents failed to eject the injection handler! Please reboot!");
|
||||
}
|
||||
}
|
||||
injectedFutures.clear();
|
||||
@@ -251,7 +253,7 @@ public class EarlyChannelInjectorModern implements EarlyInjector {
|
||||
}
|
||||
|
||||
} catch (IllegalAccessException e) {
|
||||
PacketEvents.get().getPlugin().getLogger().severe("PacketEvents failed to eject the injection handler! Please reboot!!");
|
||||
//PacketEvents.get().getPlugin().getLogger().severe("PacketEvents failed to eject the injection handler! Please reboot!!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,9 +272,8 @@ public class EarlyChannelInjectorModern implements EarlyInjector {
|
||||
public void ejectPlayer(Player player) {
|
||||
Object channel = PacketEvents.get().getPlayerUtils().getChannel(player);
|
||||
if (channel != null) {
|
||||
Channel chnl = (Channel) channel;
|
||||
try {
|
||||
chnl.pipeline().remove(PacketEvents.get().getHandlerName());
|
||||
((Channel)channel).pipeline().remove(PacketEvents.get().getHandlerName());
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
@@ -291,18 +292,33 @@ public class EarlyChannelInjectorModern implements EarlyInjector {
|
||||
@Override
|
||||
public void writePacket(Object ch, Object rawNMSPacket) {
|
||||
Channel channel = (Channel) ch;
|
||||
//Don't write packets to fake channels
|
||||
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|
||||
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
|
||||
return;
|
||||
}
|
||||
channel.write(rawNMSPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flushPackets(Object ch) {
|
||||
Channel channel = (Channel) ch;
|
||||
//Don't flush packets for fake channels
|
||||
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|
||||
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
|
||||
return;
|
||||
}
|
||||
channel.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacket(Object ch, Object rawNMSPacket) {
|
||||
Channel channel = (Channel) ch;
|
||||
//Don't send packets to fake channels
|
||||
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|
||||
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
|
||||
return;
|
||||
}
|
||||
channel.writeAndFlush(rawNMSPacket);
|
||||
}
|
||||
|
||||
|
||||
+7
-1
@@ -20,6 +20,7 @@ package io.github.retrooper.packetevents.injector.modern.early;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.injector.modern.PlayerChannelHandlerModern;
|
||||
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
@@ -36,11 +37,16 @@ public class PEChannelInitializerModern extends ChannelInitializer<Channel> {
|
||||
}
|
||||
|
||||
public static void postInitChannel(Channel channel) {
|
||||
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|
||||
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
|
||||
return;
|
||||
}
|
||||
PlayerChannelHandlerModern channelHandler = new PlayerChannelHandlerModern();
|
||||
if (channel.pipeline().get("packet_handler") != null) {
|
||||
String handlerName = PacketEvents.get().getHandlerName();
|
||||
if (channel.pipeline().get(handlerName) != null) {
|
||||
PacketEvents.get().getPlugin().getLogger().warning("[PacketEvents] Attempted to initialize a channel twice!");
|
||||
//Just ignore this to support latest ProtocolLib snapshots.
|
||||
//PacketEvents.get().getPlugin().getLogger().warning("[PacketEvents] Attempted to initialize a channel twice!");
|
||||
} else {
|
||||
channel.pipeline().addBefore("packet_handler", handlerName, channelHandler);
|
||||
}
|
||||
|
||||
-67
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2021 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.injector.modern.early;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.netty.channel.Channel;
|
||||
import net.kyori.adventure.key.Key;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
|
||||
public class PaperChannelInjector {
|
||||
public static final boolean PAPER_INJECTION_METHOD = hasPaperInjectionMethod();
|
||||
|
||||
private PaperChannelInjector() {
|
||||
}
|
||||
|
||||
public static void setPaperChannelInitializeListener() throws ReflectiveOperationException {
|
||||
// Call io.papermc.paper.network.ChannelInitializeListenerHolder.addListener(net.kyori.adventure.key.Key, io.papermc.paper.network.ChannelInitializeListener)
|
||||
// Create an interface proxy of ChannelInitializeListener
|
||||
Class<?> listenerClass = Class.forName("io.papermc.paper.network.ChannelInitializeListener");
|
||||
Object channelInitializeListener = Proxy.newProxyInstance(EarlyChannelInjectorModern.class.getClassLoader(), new Class[]{listenerClass}, (proxy, method, args) -> {
|
||||
if (method.getName().equals("afterInitChannel")) {
|
||||
PEChannelInitializerModern.postInitChannel((Channel) args[0]);
|
||||
return null;
|
||||
}
|
||||
return method.invoke(proxy, args);
|
||||
});
|
||||
|
||||
Class<?> holderClass = Class.forName("io.papermc.paper.network.ChannelInitializeListenerHolder");
|
||||
Method addListenerMethod = holderClass.getDeclaredMethod("addListener", Key.class, listenerClass);
|
||||
Key key = Key.key(PacketEvents.get().getHandlerName().toLowerCase(), "injector");
|
||||
addListenerMethod.invoke(null, key, channelInitializeListener);
|
||||
}
|
||||
|
||||
public static void removePaperChannelInitializeListener() throws ReflectiveOperationException {
|
||||
Class<?> holderClass = Class.forName("io.papermc.paper.network.ChannelInitializeListenerHolder");
|
||||
Method addListenerMethod = holderClass.getDeclaredMethod("removeListener", Key.class);
|
||||
Key key = Key.key(PacketEvents.get().getHandlerName().toLowerCase(), "injector");
|
||||
addListenerMethod.invoke(null, key);
|
||||
}
|
||||
|
||||
private static boolean hasPaperInjectionMethod() {
|
||||
try {
|
||||
Class.forName("io.papermc.paper.network.ChannelInitializeListener");
|
||||
return true;
|
||||
} catch (ReflectiveOperationException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
+23
-4
@@ -21,6 +21,7 @@ package io.github.retrooper.packetevents.injector.modern.late;
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.injector.LateInjector;
|
||||
import io.github.retrooper.packetevents.injector.modern.PlayerChannelHandlerModern;
|
||||
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
|
||||
import io.netty.channel.Channel;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@@ -40,16 +41,19 @@ public class LateChannelInjectorModern implements LateInjector {
|
||||
PlayerChannelHandlerModern playerChannelHandlerModern = new PlayerChannelHandlerModern();
|
||||
playerChannelHandlerModern.player = player;
|
||||
Channel channel = (Channel) PacketEvents.get().getPlayerUtils().getChannel(player);
|
||||
channel.pipeline().addBefore("packet_handler", PacketEvents.get().getHandlerName(), playerChannelHandlerModern);
|
||||
if (channel != null) {
|
||||
channel.eventLoop().execute(() -> {
|
||||
channel.pipeline().addBefore("packet_handler", PacketEvents.get().getHandlerName(), playerChannelHandlerModern);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ejectPlayer(Player player) {
|
||||
Object channel = PacketEvents.get().getPlayerUtils().getChannel(player);
|
||||
if (channel != null) {
|
||||
Channel chnl = (Channel) channel;
|
||||
try {
|
||||
chnl.pipeline().remove(PacketEvents.get().getHandlerName());
|
||||
((Channel) channel).pipeline().remove(PacketEvents.get().getHandlerName());
|
||||
} catch (Exception ex) {
|
||||
|
||||
}
|
||||
@@ -59,24 +63,39 @@ public class LateChannelInjectorModern implements LateInjector {
|
||||
@Override
|
||||
public boolean hasInjected(Player player) {
|
||||
Channel channel = (Channel) PacketEvents.get().getPlayerUtils().getChannel(player);
|
||||
return channel.pipeline().get(PacketEvents.get().getHandlerName()) != null;
|
||||
return channel != null && channel.pipeline().get(PacketEvents.get().getHandlerName()) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writePacket(Object ch, Object rawNMSPacket) {
|
||||
Channel channel = (Channel) ch;
|
||||
//Don't write packets to fake channels
|
||||
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|
||||
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
|
||||
return;
|
||||
}
|
||||
channel.write(rawNMSPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flushPackets(Object ch) {
|
||||
Channel channel = (Channel) ch;
|
||||
//Don't flush packets for fake channels
|
||||
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|
||||
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
|
||||
return;
|
||||
}
|
||||
channel.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacket(Object rawChannel, Object packet) {
|
||||
Channel channel = (Channel) rawChannel;
|
||||
//Don't send packets to fake channels
|
||||
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|
||||
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
|
||||
return;
|
||||
}
|
||||
channel.pipeline().writeAndFlush(packet);
|
||||
}
|
||||
}
|
||||
@@ -23,5 +23,5 @@ package io.github.retrooper.packetevents.packettype;
|
||||
* @since 1.8
|
||||
*/
|
||||
public enum PacketState {
|
||||
STATUS, HANDSHAKING, LOGIN, PLAY
|
||||
STATUS, HANDSHAKING, LOGIN, CONFIG, PLAY
|
||||
}
|
||||
@@ -326,7 +326,7 @@ public class PacketType {
|
||||
ADD_VIBRATION_SIGNAL = 30, CLEAR_TITLES = 31, INITIALIZE_BORDER = 32, PLAYER_COMBAT_END = 33,
|
||||
PLAYER_COMBAT_ENTER = 34, PLAYER_COMBAT_KILL = 35, SET_ACTIONBAR_TEXT = 36, SET_BORDER_CENTER = 37,
|
||||
SET_BORDER_LERP_SIZE = 38, SET_BORDER_SIZE = 39, SET_BORDER_WARNING_DELAY = 40, SET_BORDER_WARNING_DISTANCE = 41,
|
||||
SET_SUBTITLE_TEXT = 42, SET_TITLES_ANIMATION = 43, SET_TITLE_TEXT = 44;
|
||||
SET_SUBTITLE_TEXT = 42, SET_TITLES_ANIMATION = 43, SET_TITLE_TEXT = 44, SYSTEM_CHAT = 45;
|
||||
|
||||
private static void load() {
|
||||
insertPacketID(PacketTypeClasses.Play.Server.SPAWN_ENTITY, SPAWN_ENTITY);
|
||||
@@ -440,6 +440,7 @@ public class PacketType {
|
||||
insertPacketID(PacketTypeClasses.Play.Server.SET_SUBTITLE_TEXT, SET_SUBTITLE_TEXT);
|
||||
insertPacketID(PacketTypeClasses.Play.Server.SET_TITLES_ANIMATION, SET_TITLES_ANIMATION);
|
||||
insertPacketID(PacketTypeClasses.Play.Server.SET_TITLE_TEXT, SET_TITLE_TEXT);
|
||||
insertPacketID(PacketTypeClasses.Play.Server.SYSTEM_CHAT, SYSTEM_CHAT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -48,7 +48,7 @@ public class PacketTypeClasses {
|
||||
PREFIX = "net.minecraft.network.protocol.status.";
|
||||
}
|
||||
else {
|
||||
PREFIX = ServerVersion.getNMSDirectory() + ".";
|
||||
PREFIX = ServerVersion.getNMSDirectory();
|
||||
}
|
||||
Client.START = Reflection.getClassByNameWithoutException(PREFIX + "PacketStatusInStart");
|
||||
Client.PING = Reflection.getClassByNameWithoutException(PREFIX + "PacketStatusInPing");
|
||||
@@ -64,7 +64,7 @@ public class PacketTypeClasses {
|
||||
PREFIX = "net.minecraft.network.protocol.status.";
|
||||
}
|
||||
else {
|
||||
PREFIX = ServerVersion.getNMSDirectory() + ".";
|
||||
PREFIX = ServerVersion.getNMSDirectory();
|
||||
}
|
||||
Server.PONG = Reflection.getClassByNameWithoutException(PREFIX + "PacketStatusOutPong");
|
||||
Server.SERVER_INFO = Reflection.getClassByNameWithoutException(PREFIX + "PacketStatusOutServerInfo");
|
||||
@@ -82,7 +82,7 @@ public class PacketTypeClasses {
|
||||
PREFIX = "net.minecraft.network.protocol.handshake.";
|
||||
}
|
||||
else {
|
||||
PREFIX = ServerVersion.getNMSDirectory() + ".";
|
||||
PREFIX = ServerVersion.getNMSDirectory();
|
||||
}
|
||||
Handshaking.Client.SET_PROTOCOL = Reflection.getClassByNameWithoutException(PREFIX + "PacketHandshakingInSetProtocol");
|
||||
}
|
||||
@@ -99,7 +99,7 @@ public class PacketTypeClasses {
|
||||
PREFIX = "net.minecraft.network.protocol.login.";
|
||||
}
|
||||
else {
|
||||
PREFIX = ServerVersion.getNMSDirectory() + ".";
|
||||
PREFIX = ServerVersion.getNMSDirectory();
|
||||
}
|
||||
//In and Out custom payload login packets have been here since 1.13
|
||||
if (PacketEvents.get().getServerUtils().getVersion().isNewerThanOrEquals(ServerVersion.v_1_13)) {
|
||||
@@ -119,7 +119,7 @@ public class PacketTypeClasses {
|
||||
PREFIX = "net.minecraft.network.protocol.login.";
|
||||
}
|
||||
else {
|
||||
PREFIX = ServerVersion.getNMSDirectory() + ".";
|
||||
PREFIX = ServerVersion.getNMSDirectory();
|
||||
}
|
||||
//In and Out custom payload login packets have been here since 1.13
|
||||
if (PacketEvents.get().getServerUtils().getVersion().isNewerThanOrEquals(ServerVersion.v_1_13)) {
|
||||
@@ -137,8 +137,7 @@ public class PacketTypeClasses {
|
||||
|
||||
public static class Play {
|
||||
public static class Client {
|
||||
private static String COMMON_PREFIX;
|
||||
private static String PREFIX;
|
||||
private static String COMMON_PREFIX, PREFIX, PREFIX_COMMON_STATES;
|
||||
public static Class<?> FLYING, POSITION, POSITION_LOOK, LOOK, GROUND, CLIENT_COMMAND,
|
||||
TRANSACTION, BLOCK_DIG, ENTITY_ACTION, USE_ENTITY,
|
||||
WINDOW_CLICK, STEER_VEHICLE, CUSTOM_PAYLOAD, ARM_ANIMATION,
|
||||
@@ -157,9 +156,12 @@ public class PacketTypeClasses {
|
||||
public static void load() {
|
||||
if (PacketEvents.get().getServerUtils().getVersion().isNewerThanOrEquals(ServerVersion.v_1_17)) {
|
||||
PREFIX = "net.minecraft.network.protocol.game.";
|
||||
if (PacketEvents.get().getServerUtils().getVersion().isNewerThanOrEquals(ServerVersion.v_1_20_2)) {
|
||||
PREFIX_COMMON_STATES = "net.minecraft.network.protocol.common.";
|
||||
}
|
||||
}
|
||||
else {
|
||||
PREFIX = ServerVersion.getNMSDirectory() + ".";
|
||||
PREFIX = ServerVersion.getNMSDirectory();
|
||||
}
|
||||
COMMON_PREFIX = PREFIX + "PacketPlayIn";
|
||||
FLYING = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Flying");
|
||||
@@ -174,6 +176,19 @@ public class PacketTypeClasses {
|
||||
}
|
||||
if (PacketEvents.get().getServerUtils().getVersion().isNewerThanOrEquals(ServerVersion.v_1_17)) {
|
||||
GROUND = SubclassUtil.getSubClass(FLYING, "d");
|
||||
if (GROUND == null) {
|
||||
GROUND = SubclassUtil.getSubClass(FLYING, 0);
|
||||
}
|
||||
if (POSITION == null) {
|
||||
POSITION = SubclassUtil.getSubClass(FLYING, 2);
|
||||
}
|
||||
if (POSITION_LOOK == null) {
|
||||
POSITION_LOOK = SubclassUtil.getSubClass(FLYING, 3);
|
||||
}
|
||||
|
||||
if (LOOK == null) {
|
||||
LOOK = SubclassUtil.getSubClass(FLYING, 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
GROUND = FLYING;
|
||||
@@ -182,17 +197,25 @@ public class PacketTypeClasses {
|
||||
TRANSACTION = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Transaction");
|
||||
//This packet was added in 1.17 protocol
|
||||
PONG = Reflection.getClassByNameWithoutException(PREFIX + "ServerboundPongPacket");
|
||||
if (PONG == null) {
|
||||
PONG = Reflection.getClassByNameWithoutException(PREFIX_COMMON_STATES + "ServerboundPongPacket");
|
||||
}
|
||||
SETTINGS = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Settings");
|
||||
if (SETTINGS == null) {
|
||||
SETTINGS = Reflection.getClassByNameWithoutException(PREFIX_COMMON_STATES + "ServerboundClientInformationPacket");
|
||||
}
|
||||
try {
|
||||
SETTINGS = Class.forName(COMMON_PREFIX + "Settings");
|
||||
ENCHANT_ITEM = Class.forName(COMMON_PREFIX + "EnchantItem");
|
||||
|
||||
CLIENT_COMMAND = Class.forName(COMMON_PREFIX + "ClientCommand");
|
||||
BLOCK_DIG = Class.forName(COMMON_PREFIX + "BlockDig");
|
||||
ENTITY_ACTION = Class.forName(COMMON_PREFIX + "EntityAction");
|
||||
USE_ENTITY = Class.forName(COMMON_PREFIX + "UseEntity");
|
||||
WINDOW_CLICK = Class.forName(COMMON_PREFIX + "WindowClick");
|
||||
STEER_VEHICLE = Class.forName(COMMON_PREFIX + "SteerVehicle");
|
||||
CUSTOM_PAYLOAD = Class.forName(COMMON_PREFIX + "CustomPayload");
|
||||
CUSTOM_PAYLOAD = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "CustomPayload");
|
||||
if (CUSTOM_PAYLOAD == null) {
|
||||
CUSTOM_PAYLOAD = Reflection.getClassByNameWithoutException(PREFIX_COMMON_STATES + "ServerboundCustomPayloadPacket");
|
||||
}
|
||||
ARM_ANIMATION = Class.forName(COMMON_PREFIX + "ArmAnimation");
|
||||
ABILITIES = Class.forName(COMMON_PREFIX + "Abilities");
|
||||
HELD_ITEM_SLOT = Class.forName(COMMON_PREFIX + "HeldItemSlot");
|
||||
@@ -200,7 +223,10 @@ public class PacketTypeClasses {
|
||||
TAB_COMPLETE = Class.forName(COMMON_PREFIX + "TabComplete");
|
||||
CHAT = Class.forName(COMMON_PREFIX + "Chat");
|
||||
SET_CREATIVE_SLOT = Class.forName(COMMON_PREFIX + "SetCreativeSlot");
|
||||
KEEP_ALIVE = Class.forName(COMMON_PREFIX + "KeepAlive");
|
||||
KEEP_ALIVE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "KeepAlive");
|
||||
if (KEEP_ALIVE == null) {
|
||||
KEEP_ALIVE = Reflection.getClassByNameWithoutException(PREFIX_COMMON_STATES + "ServerboundKeepAlivePacket");
|
||||
}
|
||||
UPDATE_SIGN = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "UpdateSign");
|
||||
|
||||
TELEPORT_ACCEPT = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "TeleportAccept");
|
||||
@@ -241,7 +267,7 @@ public class PacketTypeClasses {
|
||||
}
|
||||
|
||||
public static class Server {
|
||||
private static String COMMON_PREFIX, PREFIX;
|
||||
private static String COMMON_PREFIX, PREFIX, PREFIX_COMMON_STATES;
|
||||
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,
|
||||
@@ -267,7 +293,8 @@ public class PacketTypeClasses {
|
||||
ENTITY_EFFECT, RECIPE_UPDATE, TAGS, MAP_CHUNK_BULK, NAMED_ENTITY_SPAWN, PING, ADD_VIBRATION_SIGNAL,
|
||||
CLEAR_TITLES, INITIALIZE_BORDER, PLAYER_COMBAT_END, PLAYER_COMBAT_ENTER, PLAYER_COMBAT_KILL,
|
||||
SET_ACTIONBAR_TEXT, SET_BORDER_CENTER, SET_BORDER_LERP_SIZE, SET_BORDER_SIZE, SET_BORDER_WARNING_DELAY,
|
||||
SET_BORDER_WARNING_DISTANCE, SET_SUBTITLE_TEXT, SET_TITLES_ANIMATION, SET_TITLE_TEXT;
|
||||
SET_BORDER_WARNING_DISTANCE, SET_SUBTITLE_TEXT, SET_TITLES_ANIMATION, SET_TITLE_TEXT,
|
||||
SYSTEM_CHAT;
|
||||
|
||||
/**
|
||||
* Initiate all client-bound packet classes.
|
||||
@@ -275,9 +302,12 @@ public class PacketTypeClasses {
|
||||
public static void load() {
|
||||
if (PacketEvents.get().getServerUtils().getVersion().isNewerThanOrEquals(ServerVersion.v_1_17)) {
|
||||
PREFIX = "net.minecraft.network.protocol.game.";
|
||||
if (PacketEvents.get().getServerUtils().getVersion().isNewerThanOrEquals(ServerVersion.v_1_20_2)) {
|
||||
PREFIX_COMMON_STATES = "net.minecraft.network.protocol.common.";
|
||||
}
|
||||
}
|
||||
else {
|
||||
PREFIX = ServerVersion.getNMSDirectory() + ".";
|
||||
PREFIX = ServerVersion.getNMSDirectory();
|
||||
}
|
||||
COMMON_PREFIX = PREFIX + "PacketPlayOut";
|
||||
SPAWN_ENTITY = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "SpawnEntity");
|
||||
@@ -296,6 +326,9 @@ public class PacketTypeClasses {
|
||||
BOSS = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Boss");
|
||||
SERVER_DIFFICULTY = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "ServerDifficulty");
|
||||
CHAT = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Chat");
|
||||
if (CHAT == null) {
|
||||
CHAT = Reflection.getClassByNameWithoutException(PREFIX + "ClientboundPlayerChatPacket");
|
||||
}
|
||||
MULTI_BLOCK_CHANGE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "MultiBlockChange");
|
||||
TAB_COMPLETE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "TabComplete");
|
||||
COMMANDS = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Commands");
|
||||
@@ -306,14 +339,23 @@ public class PacketTypeClasses {
|
||||
SET_SLOT = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "SetSlot");
|
||||
SET_COOLDOWN = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "SetCooldown");
|
||||
CUSTOM_PAYLOAD = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "CustomPayload");
|
||||
if (CUSTOM_PAYLOAD == null) {
|
||||
CUSTOM_PAYLOAD = Reflection.getClassByNameWithoutException(PREFIX_COMMON_STATES + "ClientboundCustomPayloadPacket");
|
||||
}
|
||||
CUSTOM_SOUND_EFFECT = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "CustomSoundEffect");
|
||||
KICK_DISCONNECT = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "KickDisconnect");
|
||||
if (KICK_DISCONNECT == null) {
|
||||
KICK_DISCONNECT = Reflection.getClassByNameWithoutException(PREFIX_COMMON_STATES + "ClientboundDisconnectPacket");
|
||||
}
|
||||
ENTITY_STATUS = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "EntityStatus");
|
||||
EXPLOSION = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Explosion");
|
||||
UNLOAD_CHUNK = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "UnloadChunk");
|
||||
GAME_STATE_CHANGE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "GameStateChange");
|
||||
OPEN_WINDOW_HORSE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "OpenWindowHorse");
|
||||
KEEP_ALIVE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "KeepAlive");
|
||||
if (KEEP_ALIVE == null) {
|
||||
KEEP_ALIVE = Reflection.getClassByNameWithoutException(PREFIX_COMMON_STATES + "ClientboundKeepAlivePacket");
|
||||
}
|
||||
MAP_CHUNK = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "MapChunk");
|
||||
WORLD_EVENT = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "WorldEvent");
|
||||
WORLD_PARTICLES = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "WorldParticles");
|
||||
@@ -330,6 +372,16 @@ public class PacketTypeClasses {
|
||||
REL_ENTITY_MOVE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "RelEntityMove");
|
||||
REL_ENTITY_MOVE_LOOK = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "RelEntityMoveLook");
|
||||
ENTITY_LOOK = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "RelEntityLook");
|
||||
|
||||
if (REL_ENTITY_MOVE == null) {
|
||||
REL_ENTITY_MOVE = SubclassUtil.getSubClass(ENTITY, 1);
|
||||
}
|
||||
if (REL_ENTITY_MOVE_LOOK == null) {
|
||||
REL_ENTITY_MOVE_LOOK = SubclassUtil.getSubClass(ENTITY, 2);
|
||||
}
|
||||
if (ENTITY_LOOK == null) {
|
||||
ENTITY_LOOK = SubclassUtil.getSubClass(ENTITY, 0);
|
||||
}
|
||||
}
|
||||
VEHICLE_MOVE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "VehicleMove");
|
||||
OPEN_BOOK = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "OpenBook");
|
||||
@@ -384,6 +436,9 @@ public class PacketTypeClasses {
|
||||
|
||||
//These packets were added in 1.17
|
||||
PING = Reflection.getClassByNameWithoutException(PREFIX + "ClientboundPingPacket");
|
||||
if (PING == null) {
|
||||
PING = Reflection.getClassByNameWithoutException(PREFIX_COMMON_STATES + "ClientboundPingPacket");
|
||||
}
|
||||
ADD_VIBRATION_SIGNAL = Reflection.getClassByNameWithoutException(PREFIX + "ClientboundAddVibrationSignalPacket");
|
||||
CLEAR_TITLES = Reflection.getClassByNameWithoutException(PREFIX + "ClientboundClearTitlesPacket");
|
||||
INITIALIZE_BORDER = Reflection.getClassByNameWithoutException(PREFIX + "ClientboundInitializeBorderPacket");
|
||||
@@ -399,6 +454,7 @@ public class PacketTypeClasses {
|
||||
SET_SUBTITLE_TEXT = Reflection.getClassByNameWithoutException(PREFIX + "ClientboundSetSubtitleTextPacket");
|
||||
SET_TITLES_ANIMATION = Reflection.getClassByNameWithoutException(PREFIX + "ClientboundSetTitlesAnimationPacket");
|
||||
SET_TITLE_TEXT = Reflection.getClassByNameWithoutException(PREFIX + "ClientboundSetTitleTextPacket");
|
||||
SYSTEM_CHAT = Reflection.getClassByNameWithoutException(PREFIX + "ClientboundSystemChatPacket");
|
||||
|
||||
// 1.18+ only, doesn't follow the naming convention
|
||||
if (MAP_CHUNK == null) {
|
||||
|
||||
@@ -24,6 +24,8 @@ import io.github.retrooper.packetevents.exceptions.WrapperUnsupportedUsageExcept
|
||||
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrapperPacketReader;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.WrapperPacketWriter;
|
||||
import io.github.retrooper.packetevents.utils.ConditionalValue;
|
||||
import io.github.retrooper.packetevents.utils.MojangEitherUtil;
|
||||
import io.github.retrooper.packetevents.utils.enums.EnumUtil;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.player.GameMode;
|
||||
@@ -43,11 +45,9 @@ import java.lang.annotation.Target;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class WrappedPacket implements WrapperPacketReader, WrapperPacketWriter {
|
||||
@@ -416,9 +416,17 @@ public class WrappedPacket implements WrapperPacketReader, WrapperPacketWriter {
|
||||
public Vector3i readBlockPosition(int index) {
|
||||
Object blockPosObj = readObject(index, NMSUtils.blockPosClass);
|
||||
try {
|
||||
int x = (Integer) NMSUtils.getBlockPosX.invoke(blockPosObj);
|
||||
int y = (Integer) NMSUtils.getBlockPosY.invoke(blockPosObj);
|
||||
int z = (Integer) NMSUtils.getBlockPosZ.invoke(blockPosObj);
|
||||
int x, y, z;
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_20_5)) {
|
||||
x = (int) NMSUtils.getBaseBlockPosX.get(blockPosObj);
|
||||
y = (int) NMSUtils.getBaseBlockPosY.get(blockPosObj);
|
||||
z = (int) NMSUtils.getBaseBlockPosZ.get(blockPosObj);
|
||||
}
|
||||
else {
|
||||
x = (int) NMSUtils.getBlockPosX.invoke(blockPosObj);
|
||||
y = (int) NMSUtils.getBlockPosY.invoke(blockPosObj);
|
||||
z = (int) NMSUtils.getBlockPosZ.invoke(blockPosObj);
|
||||
}
|
||||
return new Vector3i(x, y, z);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
@@ -525,12 +533,7 @@ public class WrappedPacket implements WrapperPacketReader, WrapperPacketWriter {
|
||||
}
|
||||
|
||||
public void writeMinecraftKey(int index, String content) {
|
||||
Object minecraftKey = null;
|
||||
try {
|
||||
minecraftKey = NMSUtils.minecraftKeyConstructor.newInstance(content);
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Object minecraftKey = NMSUtils.generateMinecraftKeyNew(content);
|
||||
write(NMSUtils.minecraftKeyClass, index, minecraftKey);
|
||||
}
|
||||
|
||||
@@ -542,6 +545,34 @@ public class WrappedPacket implements WrapperPacketReader, WrapperPacketWriter {
|
||||
write(List.class, index, list);
|
||||
}
|
||||
|
||||
public <T, K> ConditionalValue<T, K> readEither(int index) {
|
||||
Object either = readObject(index, NMSUtils.mojangEitherClass);
|
||||
Optional<T> left = MojangEitherUtil.getLeft(either);
|
||||
if (left.isPresent()) {
|
||||
return ConditionalValue.makeLeft(left.get());
|
||||
}
|
||||
else {
|
||||
Optional<K> right = MojangEitherUtil.getRight(either);
|
||||
try {
|
||||
return ConditionalValue.makeRight(right.orElseThrow((Supplier<Throwable>) () -> new IllegalStateException("Conditional value has no values. Atleast one side must have a value!")));
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public <T, K> void writeEither(int index, ConditionalValue<T, K> conditionalValue) {
|
||||
Object either;
|
||||
if (conditionalValue.left().isPresent()) {
|
||||
either = MojangEitherUtil.makeLeft(conditionalValue.left().get());
|
||||
}
|
||||
else {
|
||||
either = MojangEitherUtil.makeRight(conditionalValue.right().get());
|
||||
}
|
||||
write(NMSUtils.mojangEitherClass, index, either);
|
||||
}
|
||||
|
||||
private Field getField(Class<?> type, int index) {
|
||||
Map<Class<?>, Field[]> cached = FIELD_CACHE.computeIfAbsent(packetClass, k -> new ConcurrentHashMap<>());
|
||||
Field[] fields = cached.computeIfAbsent(type, typeClass -> getFields(typeClass, packetClass.getDeclaredFields()));
|
||||
|
||||
+6
-6
@@ -23,30 +23,30 @@ import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
|
||||
public class WrappedPacketHandshakingInSetProtocol extends WrappedPacket {
|
||||
private static boolean v_1_17;
|
||||
private static boolean between_V_1_17_And_1_20_1;
|
||||
public WrappedPacketHandshakingInSetProtocol(NMSPacket packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void load() {
|
||||
v_1_17 = version.isNewerThanOrEquals(ServerVersion.v_1_17);
|
||||
between_V_1_17_And_1_20_1 = version.isNewerThanOrEquals(ServerVersion.v_1_17) && version.isOlderThan(ServerVersion.v_1_20_2);
|
||||
}
|
||||
|
||||
public int getProtocolVersion() {
|
||||
return readInt(v_1_17 ? 1 : 0);
|
||||
return readInt(between_V_1_17_And_1_20_1 ? 1 : 0);
|
||||
}
|
||||
|
||||
public void setProtocolVersion(int protocolVersion) {
|
||||
writeInt(v_1_17 ? 1 : 0, protocolVersion);
|
||||
writeInt(between_V_1_17_And_1_20_1 ? 1 : 0, protocolVersion);
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return readInt(v_1_17 ? 2 : 1);
|
||||
return readInt(between_V_1_17_And_1_20_1 ? 2 : 1);
|
||||
}
|
||||
|
||||
public void setPort(int port) {
|
||||
writeInt(v_1_17 ? 2 : 1, port);
|
||||
writeInt(between_V_1_17_And_1_20_1 ? 2 : 1, port);
|
||||
}
|
||||
|
||||
public String getHostName() {
|
||||
|
||||
+64
-4
@@ -21,12 +21,38 @@ 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;
|
||||
import io.github.retrooper.packetevents.utils.ConditionalValue;
|
||||
import io.github.retrooper.packetevents.utils.MojangEitherUtil;
|
||||
import io.github.retrooper.packetevents.utils.SaltSignature;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public class WrappedPacketLoginInEncryptionBegin extends WrappedPacket {
|
||||
private static Class<?> VANILLA_SALT_SIGNATURE_CLASS;
|
||||
private static Constructor<?> VANILLA_SALT_SIGNATURE_CONSTRUCTOR;
|
||||
public WrappedPacketLoginInEncryptionBegin(NMSPacket packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void load() {
|
||||
Class<?> minecraftEncryptionClass = Reflection.getClassByNameWithoutException("net.minecraft.util.MinecraftEncryption");
|
||||
if (minecraftEncryptionClass != null) {
|
||||
VANILLA_SALT_SIGNATURE_CLASS = SubclassUtil.getSubClass(minecraftEncryptionClass, "b");
|
||||
try {
|
||||
VANILLA_SALT_SIGNATURE_CONSTRUCTOR = VANILLA_SALT_SIGNATURE_CLASS.getConstructor(long.class, byte[].class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] getPublicKey() {
|
||||
return readByteArray(0);
|
||||
}
|
||||
@@ -35,12 +61,46 @@ public class WrappedPacketLoginInEncryptionBegin extends WrappedPacket {
|
||||
writeByteArray(0, key);
|
||||
}
|
||||
|
||||
public byte[] getVerifyToken() {
|
||||
return readByteArray(1);
|
||||
|
||||
public ConditionalValue<byte[], SaltSignature> getVerifyTokenOrSaltSignature() {
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
|
||||
ConditionalValue<byte[], Object> rawEither = readEither(0);
|
||||
if (rawEither.left().isPresent()) {
|
||||
return ConditionalValue.makeLeft(rawEither.left().get());
|
||||
}
|
||||
else {
|
||||
Object rawRight = rawEither.right().get();
|
||||
WrappedPacket rawRightWrapper = new WrappedPacket(new NMSPacket(rawRight));
|
||||
SaltSignature ss = new SaltSignature(rawRightWrapper.readLong(0), rawRightWrapper.readByteArray(0));
|
||||
return ConditionalValue.makeRight(ss);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return ConditionalValue.makeLeft(readByteArray(1));
|
||||
}
|
||||
}
|
||||
|
||||
public void setVerifyToken(byte[] token) {
|
||||
writeByteArray(1, token);
|
||||
public void setVerifyTokenOrSaltSignature(ConditionalValue<byte[], SaltSignature> value) {
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
|
||||
Object either;
|
||||
if (value.left().isPresent()) {
|
||||
either = MojangEitherUtil.makeLeft(value.left().get());
|
||||
}
|
||||
else {
|
||||
SaltSignature ss = value.right().get();
|
||||
Object rawSS = null;
|
||||
try {
|
||||
rawSS = VANILLA_SALT_SIGNATURE_CONSTRUCTOR.newInstance(ss.getSalt(), ss.getSignature());
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
either = MojangEitherUtil.makeRight(rawSS);
|
||||
}
|
||||
write(NMSUtils.mojangEitherClass, 0, either);
|
||||
}
|
||||
else {
|
||||
writeByteArray(1, value.left().get());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+54
-4
@@ -24,21 +24,71 @@ import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.gameprofile.GameProfileUtil;
|
||||
import io.github.retrooper.packetevents.utils.gameprofile.WrappedGameProfile;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
// TODO: This wrapper needs Signature data @retrooper
|
||||
public class WrappedPacketLoginInStart extends WrappedPacket {
|
||||
public WrappedPacketLoginInStart(NMSPacket packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
//TODO Allow accessing game profile property
|
||||
public WrappedGameProfile getGameProfile() {
|
||||
return GameProfileUtil.getWrappedGameProfile(readObject(0, NMSUtils.gameProfileClass));
|
||||
public Optional<WrappedGameProfile> getGameProfile() {
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return Optional.of(GameProfileUtil.getWrappedGameProfile(readObject(0, NMSUtils.gameProfileClass)));
|
||||
}
|
||||
|
||||
//TODO Add support for game profile property
|
||||
public void setGameProfile(WrappedGameProfile wrappedGameProfile) {
|
||||
Object gameProfile = GameProfileUtil.getGameProfile(wrappedGameProfile.getId(), wrappedGameProfile.getName());
|
||||
write(NMSUtils.gameProfileClass, 0, gameProfile);
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
|
||||
writeString(0, wrappedGameProfile.getName());
|
||||
}
|
||||
else {
|
||||
Object gameProfile = GameProfileUtil.getGameProfile(wrappedGameProfile.getId(), wrappedGameProfile.getName());
|
||||
write(NMSUtils.gameProfileClass, 0, gameProfile);
|
||||
}
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
|
||||
return readString(0);
|
||||
}
|
||||
else {
|
||||
return GameProfileUtil.getWrappedGameProfile(readObject(0, NMSUtils.gameProfileClass)).getName();
|
||||
}
|
||||
}
|
||||
|
||||
public void setUsername(String username) throws IllegalAccessException {
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
|
||||
writeString(0, username);
|
||||
}
|
||||
else {
|
||||
throw new IllegalAccessException("Please use the setGameProfile method in the WrappedPacketLoginInStart wrapper to change the username!");
|
||||
}
|
||||
}
|
||||
|
||||
public @Nullable UUID getPlayerUUID() {
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_19_1)) {
|
||||
return readObject(0, UUID.class);
|
||||
}
|
||||
else {
|
||||
return GameProfileUtil.getWrappedGameProfile(readObject(0, NMSUtils.gameProfileClass)).getId();
|
||||
}
|
||||
}
|
||||
|
||||
public void setPlayerUUID(UUID playerUUID) throws IllegalAccessException {
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_19_1)) {
|
||||
writeObject(0, playerUUID);
|
||||
}
|
||||
else {
|
||||
throw new IllegalAccessException("Please use the setGameProfile method in the WrappedPacketLoginInStart wrapper to change the uuid!");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+3
-24
@@ -28,28 +28,14 @@ import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
public class WrappedPacketLoginOutSuccess extends WrappedPacket implements SendableWrapper {
|
||||
private static Constructor<?> packetConstructor;
|
||||
public class WrappedPacketLoginOutSuccess extends WrappedPacket {
|
||||
private WrappedGameProfile wrappedGameProfile;
|
||||
|
||||
public WrappedPacketLoginOutSuccess(final NMSPacket packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public WrappedPacketLoginOutSuccess(final WrappedGameProfile wrappedGameProfile) {
|
||||
this.wrappedGameProfile = wrappedGameProfile;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void load() {
|
||||
try {
|
||||
packetConstructor = PacketTypeClasses.Login.Server.SUCCESS.getConstructors()[1];
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
//TODO Support property reading in wrapped game profile
|
||||
//TODO Support property reading in wrapped game profile(NECESSARY IN 1.19!, PLEASE UPDATE TO 2.0 PACKETEVENTS)
|
||||
public WrappedGameProfile getGameProfile() {
|
||||
if (packet != null) {
|
||||
return GameProfileUtil.getWrappedGameProfile(readObject(0, NMSUtils.gameProfileClass));
|
||||
@@ -58,7 +44,7 @@ public class WrappedPacketLoginOutSuccess extends WrappedPacket implements Senda
|
||||
}
|
||||
}
|
||||
|
||||
//TODO Support writing property in wrapped game profile
|
||||
//TODO Support writing property in wrapped game profile(NECESSARY IN 1.19!, PLEASE UPDATE TO 2.0 PACKETEVENTS)
|
||||
public void setGameProfile(final WrappedGameProfile wrappedGameProfile) {
|
||||
if (packet != null) {
|
||||
final Object gameProfile = GameProfileUtil.getGameProfile(wrappedGameProfile.getId(), wrappedGameProfile.getName());
|
||||
@@ -68,13 +54,6 @@ public class WrappedPacketLoginOutSuccess extends WrappedPacket implements Senda
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object asNMSPacket() throws Exception {
|
||||
WrappedGameProfile gp = getGameProfile();
|
||||
//TODO Support writing property in wrapped game profile
|
||||
return packetConstructor.newInstance(GameProfileUtil.getGameProfile(gp.getId(), gp.getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
return PacketTypeClasses.Login.Server.SUCCESS != null;
|
||||
|
||||
+3
@@ -47,6 +47,9 @@ public final class WrappedPacketInBlockDig extends WrappedPacket {
|
||||
} catch (ClassNotFoundException e) {
|
||||
//It is probably a subclass
|
||||
digTypeClass = SubclassUtil.getEnumSubClass(blockDigClass, "EnumPlayerDigType");
|
||||
if (digTypeClass == null) {
|
||||
digTypeClass = SubclassUtil.getEnumSubClass(blockDigClass, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+75
@@ -20,12 +20,38 @@ package io.github.retrooper.packetevents.packetwrappers.play.in.chat;
|
||||
|
||||
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.SaltSignature;
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.time.Instant;
|
||||
import java.util.Optional;
|
||||
|
||||
public final class WrappedPacketInChat extends WrappedPacket {
|
||||
private static Class<?> VANILLA_SALT_SIGNATURE_CLASS;
|
||||
private static Constructor<?> VANILLA_SALT_SIGNATURE_CONSTRUCTOR;
|
||||
public WrappedPacketInChat(NMSPacket packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void load() {
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
|
||||
Class<?> minecraftEncryptionClass = Reflection.getClassByNameWithoutException("net.minecraft.util.MinecraftEncryption");
|
||||
if (minecraftEncryptionClass != null) {
|
||||
VANILLA_SALT_SIGNATURE_CLASS = SubclassUtil.getSubClass(minecraftEncryptionClass, "b");
|
||||
try {
|
||||
VANILLA_SALT_SIGNATURE_CONSTRUCTOR = VANILLA_SALT_SIGNATURE_CLASS.getConstructor(long.class, byte[].class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return readString(0);
|
||||
}
|
||||
@@ -33,4 +59,53 @@ public final class WrappedPacketInChat extends WrappedPacket {
|
||||
public void setMessage(String message) {
|
||||
writeString(0, message);
|
||||
}
|
||||
|
||||
public Optional<Instant> getInstant() {
|
||||
return version.isNewerThanOrEquals(ServerVersion.v_1_19) ? Optional.of(readObject(0, Instant.class)) : Optional.empty();
|
||||
}
|
||||
|
||||
public void setInstant(Instant instant) {
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
|
||||
writeObject(0, instant);
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<SaltSignature> getSaltSignature() {
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
|
||||
Object rawSS = readObject(0, VANILLA_SALT_SIGNATURE_CLASS);
|
||||
WrappedPacket rawSSWrapper = new WrappedPacket(new NMSPacket(rawSS));
|
||||
SaltSignature ss = new SaltSignature(rawSSWrapper.readLong(0), rawSSWrapper.readByteArray(0));
|
||||
return Optional.of(ss);
|
||||
}
|
||||
else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public void setSaltSignature(SaltSignature saltSignature) {
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
|
||||
Object rawSS = null;
|
||||
try {
|
||||
rawSS = VANILLA_SALT_SIGNATURE_CONSTRUCTOR.newInstance(saltSignature.getSalt(), saltSignature.getSignature());
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
write(VANILLA_SALT_SIGNATURE_CLASS, 0, rawSS);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isSignedPreview() {
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
|
||||
return readBoolean(0);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void setSignedPreview(boolean signedPreview) {
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
|
||||
writeBoolean(0, signedPreview);
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
@@ -41,6 +41,9 @@ public final class WrappedPacketInClientCommand extends WrappedPacket {
|
||||
if (enumClientCommandClass == null) {
|
||||
//Probably a subclass
|
||||
enumClientCommandClass = SubclassUtil.getEnumSubClass(PacketTypeClasses.Play.Client.CLIENT_COMMAND, "EnumClientCommand");
|
||||
if (enumClientCommandClass == null) {
|
||||
enumClientCommandClass = SubclassUtil.getEnumSubClass(PacketTypeClasses.Play.Client.CLIENT_COMMAND, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+92
-5
@@ -22,13 +22,21 @@ import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.netty.bytebuf.ByteBufUtil;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public final class WrappedPacketInCustomPayload extends WrappedPacket {
|
||||
private static boolean strPresent, byteArrayPresent;
|
||||
private static boolean strPresent, byteArrayPresent, customPacketPayloadPresent;
|
||||
private static Class<?> CUSTOM_PACKET_PAYLOAD, BRAND_PAYLOAD, DISCARDED_PAYLOAD;
|
||||
private static Method CUSTOM_PACKET_PAYLOAD_MINECRAFT_KEY, CUSTOM_PACKET_PAYLOAD_PACKETDATASERIALIZER;
|
||||
private static byte isVersion_1_17 = -1;
|
||||
private static boolean isVersion_1_20_5;
|
||||
private static boolean isVersion_1_20_6;
|
||||
|
||||
public WrappedPacketInCustomPayload(NMSPacket packet) {
|
||||
super(packet);
|
||||
@@ -38,10 +46,61 @@ public final class WrappedPacketInCustomPayload extends WrappedPacket {
|
||||
protected void load() {
|
||||
strPresent = Reflection.getField(PacketTypeClasses.Play.Client.CUSTOM_PAYLOAD, String.class, 0) != null;
|
||||
byteArrayPresent = Reflection.getField(PacketTypeClasses.Play.Client.CUSTOM_PAYLOAD, byte[].class, 0) != null;
|
||||
CUSTOM_PACKET_PAYLOAD = Reflection.getClassByNameWithoutException("net.minecraft.network.protocol.common.custom.CustomPacketPayload");
|
||||
customPacketPayloadPresent = Reflection.getField(PacketTypeClasses.Play.Client.CUSTOM_PAYLOAD, CUSTOM_PACKET_PAYLOAD, 0) != null;
|
||||
if (customPacketPayloadPresent) {
|
||||
CUSTOM_PACKET_PAYLOAD_MINECRAFT_KEY = Reflection.getMethod(CUSTOM_PACKET_PAYLOAD, NMSUtils.minecraftKeyClass, 0);
|
||||
CUSTOM_PACKET_PAYLOAD_PACKETDATASERIALIZER = Reflection.getMethod(CUSTOM_PACKET_PAYLOAD, 0, NMSUtils.packetDataSerializerClass);
|
||||
}
|
||||
isVersion_1_20_5 = version.isNewerThanOrEquals(ServerVersion.v_1_20_5);
|
||||
isVersion_1_20_6 = version.isNewerThanOrEquals(ServerVersion.v_1_20_6);
|
||||
if (isVersion_1_20_5) {
|
||||
BRAND_PAYLOAD = NMSUtils.getNMClassWithoutException("network.protocol.common.custom.BrandPayload");
|
||||
DISCARDED_PAYLOAD = NMSUtils.getNMClassWithoutException("network.protocol.common.custom.DiscardedPayload");
|
||||
}
|
||||
}
|
||||
|
||||
private Object getModernPayloadObject() {
|
||||
return readObject(0, CUSTOM_PACKET_PAYLOAD);
|
||||
}
|
||||
|
||||
public String getChannelName() {
|
||||
if (strPresent) {
|
||||
if (customPacketPayloadPresent) {
|
||||
Object payload = getModernPayloadObject();
|
||||
if (isVersion_1_20_5) {
|
||||
if (BRAND_PAYLOAD.isInstance(payload)) {
|
||||
WrappedPacket reflectBrandPayload = new WrappedPacket(new NMSPacket(payload));
|
||||
return reflectBrandPayload.readString(0);
|
||||
}
|
||||
else if (DISCARDED_PAYLOAD.isInstance(payload)) {
|
||||
WrappedPacket reflectBrandPayload = new WrappedPacket(new NMSPacket(payload));
|
||||
if (isVersion_1_20_6) {
|
||||
return reflectBrandPayload.readMinecraftKey(0);
|
||||
}
|
||||
else {
|
||||
return reflectBrandPayload.readString(0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
try {
|
||||
if (isVersion_1_17 == -1) {
|
||||
isVersion_1_17 = (byte) (version.isNewerThanOrEquals(ServerVersion.v_1_17) ? 1 : 0);
|
||||
}
|
||||
int namespaceIndex = isVersion_1_17 == 1 ? 2 : 0;
|
||||
int keyIndex = isVersion_1_17 == 1 ? 3 : 1;
|
||||
Object minecraftKey = CUSTOM_PACKET_PAYLOAD_MINECRAFT_KEY.invoke(payload);
|
||||
WrappedPacket minecraftKeyWrapper = new WrappedPacket(new NMSPacket(minecraftKey));
|
||||
return minecraftKeyWrapper.readString(namespaceIndex) + ":" + minecraftKeyWrapper.readString(keyIndex);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
} else if (strPresent) {
|
||||
return readString(0);
|
||||
} else {
|
||||
return readMinecraftKey(1);
|
||||
@@ -49,7 +108,10 @@ public final class WrappedPacketInCustomPayload extends WrappedPacket {
|
||||
}
|
||||
|
||||
public void setChannelName(String channelName) {
|
||||
if (strPresent) {
|
||||
if (customPacketPayloadPresent) {
|
||||
throw new UnsupportedOperationException("PacketEvents v1.8 is a dying version, setting the channel name is not supported!");
|
||||
}
|
||||
else if (strPresent) {
|
||||
writeString(0, channelName);
|
||||
} else {
|
||||
writeMinecraftKey(1, channelName);
|
||||
@@ -57,7 +119,32 @@ public final class WrappedPacketInCustomPayload extends WrappedPacket {
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
if (byteArrayPresent) {
|
||||
if (customPacketPayloadPresent) {
|
||||
Object payload = getModernPayloadObject();
|
||||
if (isVersion_1_20_6) {
|
||||
if (DISCARDED_PAYLOAD.isInstance(payload)) {
|
||||
WrappedPacket reflectDiscardedPayload = new WrappedPacket(new NMSPacket(payload));
|
||||
Object buffer = reflectDiscardedPayload.readObject(0, NMSUtils.byteBufClass);
|
||||
return PacketEvents.get().getByteBufUtil().getBytes(buffer);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Object buffer = PacketEvents.get().getByteBufUtil().buffer();
|
||||
Object packetDataSerializer = NMSUtils.generatePacketDataSerializer(buffer);
|
||||
try {
|
||||
CUSTOM_PACKET_PAYLOAD_PACKETDATASERIALIZER.invoke(payload, packetDataSerializer);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
byte[] data = PacketEvents.get().getByteBufUtil().getBytes(buffer);
|
||||
PacketEvents.get().getByteBufUtil().release(buffer);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
else if (byteArrayPresent) {
|
||||
return readByteArray(0);
|
||||
} else {
|
||||
return PacketEvents.get().getByteBufUtil().getBytes(getBuffer());
|
||||
|
||||
+3
@@ -43,6 +43,9 @@ public final class WrappedPacketInEntityAction extends WrappedPacketEntityAbstra
|
||||
if (enumPlayerActionClass == null) {
|
||||
enumPlayerActionClass = SubclassUtil.getEnumSubClass(PacketTypeClasses.Play.Client.ENTITY_ACTION, "EnumPlayerAction");
|
||||
}
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_20_6)) {
|
||||
enumPlayerActionClass = SubclassUtil.getEnumSubClass(PacketTypeClasses.Play.Client.ENTITY_ACTION, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
-1
@@ -26,7 +26,6 @@ import io.github.retrooper.packetevents.utils.vector.Vector3i;
|
||||
* Sent when Generate is pressed on the Jigsaw Block interface.
|
||||
*
|
||||
* @author Tecnio
|
||||
* @see <a href="https://wiki.vg/Protocol#Generate_Structure"</a>
|
||||
*/
|
||||
public class WrappedPacketInJigsawGenerate extends WrappedPacket {
|
||||
|
||||
|
||||
+16
@@ -23,6 +23,7 @@ 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.reflection.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
import io.github.retrooper.packetevents.utils.vector.Vector3i;
|
||||
|
||||
public class WrappedPacketInUpdateSign extends WrappedPacket {
|
||||
@@ -78,4 +79,19 @@ public class WrappedPacketInUpdateSign extends WrappedPacket {
|
||||
writeAnyObject(1, iChatComponents);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFrontText() {
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_20)) {
|
||||
return readBoolean(0);
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void setFrontText(boolean frontText) {
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_20)) {
|
||||
writeBoolean(0,frontText);
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
-1
@@ -38,7 +38,7 @@ public final class WrappedPacketInUseEntity extends WrappedPacketEntityAbstracti
|
||||
private static Class<? extends Enum<?>> enumEntityUseActionClass;
|
||||
private static Class<?> obfuscatedDataInterface, obfuscatedHandContainerClass, obfuscatedTargetAndHandContainerClass;
|
||||
private static Method getObfuscatedEntityUseActionMethod;
|
||||
private static boolean v_1_7_10, v_1_9, v_1_17;
|
||||
private static boolean v_1_7_10, v_1_9, v_1_17, v_1_20_5;
|
||||
private EntityUseAction action;
|
||||
private Object obfuscatedDataObj;
|
||||
|
||||
@@ -51,15 +51,27 @@ public final class WrappedPacketInUseEntity extends WrappedPacketEntityAbstracti
|
||||
v_1_7_10 = version.isOlderThan(ServerVersion.v_1_8);
|
||||
v_1_9 = version.isNewerThanOrEquals(ServerVersion.v_1_9);
|
||||
v_1_17 = version.isNewerThanOrEquals(ServerVersion.v_1_17);
|
||||
v_1_20_5 = version.isNewerThanOrEquals(ServerVersion.v_1_20_5);
|
||||
try {
|
||||
enumEntityUseActionClass = NMSUtils.getNMSEnumClass("EnumEntityUseAction");
|
||||
} catch (ClassNotFoundException e) {
|
||||
//That is fine, it is probably a subclass
|
||||
if (v_1_17) {
|
||||
enumEntityUseActionClass = SubclassUtil.getEnumSubClass(PacketTypeClasses.Play.Client.USE_ENTITY, "b");
|
||||
if (v_1_20_5) {
|
||||
if (enumEntityUseActionClass == null) {
|
||||
enumEntityUseActionClass = SubclassUtil.getEnumSubClass(PacketTypeClasses.Play.Client.USE_ENTITY, 3);
|
||||
}
|
||||
}
|
||||
obfuscatedDataInterface = SubclassUtil.getSubClass(PacketTypeClasses.Play.Client.USE_ENTITY, "EnumEntityUseAction");
|
||||
if (v_1_20_5) {
|
||||
obfuscatedDataInterface = SubclassUtil.getEnumSubClass(PacketTypeClasses.Play.Client.USE_ENTITY, 0);
|
||||
}
|
||||
obfuscatedHandContainerClass = SubclassUtil.getSubClass(PacketTypeClasses.Play.Client.USE_ENTITY, "d");
|
||||
obfuscatedTargetAndHandContainerClass = SubclassUtil.getSubClass(PacketTypeClasses.Play.Client.USE_ENTITY, "e");
|
||||
if (obfuscatedTargetAndHandContainerClass == null) {
|
||||
obfuscatedTargetAndHandContainerClass = SubclassUtil.getEnumSubClass(PacketTypeClasses.Play.Client.USE_ENTITY, 2);
|
||||
}
|
||||
getObfuscatedEntityUseActionMethod = Reflection.getMethod(obfuscatedDataInterface, enumEntityUseActionClass, 0);
|
||||
} else {
|
||||
enumEntityUseActionClass = SubclassUtil.getEnumSubClass(PacketTypeClasses.Play.Client.USE_ENTITY, "EnumEntityUseAction");
|
||||
|
||||
-1
@@ -30,7 +30,6 @@ import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author Tecnio
|
||||
* @see <a href="https://wiki.vg/Protocol#Edit_Book"</a>
|
||||
*/
|
||||
public class WrappedPacketInBEdit extends WrappedPacket {
|
||||
private static boolean v_1_13, v_1_17;
|
||||
|
||||
-1
@@ -32,7 +32,6 @@ import java.lang.reflect.Constructor;
|
||||
* This packet is used for a number of actions and animations performed by blocks, usually non-persistent.
|
||||
*
|
||||
* @author Tecnio
|
||||
* @see <a href="https://wiki.vg/Protocol#Block_Action"</a>
|
||||
*/
|
||||
public class WrappedPacketOutBlockAction extends WrappedPacket implements SendableWrapper {
|
||||
|
||||
|
||||
+8
@@ -71,7 +71,15 @@ public class WrappedPacketOutBlockChange extends WrappedPacket implements Sendab
|
||||
@Override
|
||||
protected void load() {
|
||||
getNMSBlockMethodCache = Reflection.getMethod(NMSUtils.iBlockDataClass, "getBlock", 0);
|
||||
if (getNMSBlockMethodCache == null) {
|
||||
Class<?> blockDataClass = NMSUtils.iBlockDataClass.getSuperclass();
|
||||
getNMSBlockMethodCache = Reflection.getMethod(blockDataClass, NMSUtils.blockClass, 0);
|
||||
}
|
||||
getNMSWorldTypeMethodCache = Reflection.getMethod(NMSUtils.nmsWorldClass, "getType", 0);
|
||||
if (getNMSWorldTypeMethodCache == null) {
|
||||
getNMSWorldTypeMethodCache = Reflection.getMethod(NMSUtils.nmsWorldClass,
|
||||
"getBlockStateIfLoaded", 0);
|
||||
}
|
||||
v_1_7_10 = version.isOlderThan(ServerVersion.v_1_8);
|
||||
v_1_17 = version.isNewerThanOrEquals(ServerVersion.v_1_17);
|
||||
if (v_1_17) {
|
||||
|
||||
+182
-42
@@ -25,16 +25,21 @@ import io.github.retrooper.packetevents.packetwrappers.api.SendableWrapper;
|
||||
import io.github.retrooper.packetevents.utils.enums.EnumUtil;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.chat.ComponentSerializer;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
|
||||
public final class WrappedPacketOutChat extends WrappedPacket implements SendableWrapper {
|
||||
private static Constructor<?> chatClassConstructor;
|
||||
private static Class<? extends Enum<?>> chatMessageTypeEnum;
|
||||
private static Class<?> PLAYER_CHAT_MESSAGE_CLASS, SIGNED_MESSAGE_BODY_CLASS,
|
||||
CHAT_MESSAGE_CONTENT_CLASS, CHAT_MESSAGE_TYPE_CLASS, NETWORK_BOUND_CHAT_TYPE_CLASS;
|
||||
//0 = IChatBaseComponent, Byte
|
||||
//1 = IChatBaseComponent, Int
|
||||
//2 = IChatBaseComponent, ChatMessageType
|
||||
@@ -69,50 +74,66 @@ public final class WrappedPacketOutChat extends WrappedPacket implements Sendabl
|
||||
@Override
|
||||
protected void load() {
|
||||
Class<?> packetClass = PacketTypeClasses.Play.Server.CHAT;
|
||||
chatMessageTypeEnum = NMSUtils.getNMSEnumClassWithoutException("ChatMessageType");
|
||||
if (chatMessageTypeEnum == null) {
|
||||
chatMessageTypeEnum = NMSUtils.getNMEnumClassWithoutException("network.chat.ChatMessageType");
|
||||
}
|
||||
if (chatMessageTypeEnum != null) {
|
||||
try {
|
||||
chatClassConstructor = packetClass.getConstructor(NMSUtils.iChatBaseComponentClass, chatMessageTypeEnum);
|
||||
constructorMode = 2;
|
||||
} catch (NoSuchMethodException e) {
|
||||
//Just a much newer version(1.16.x and above right now)
|
||||
try {
|
||||
chatClassConstructor = packetClass.getConstructor(NMSUtils.iChatBaseComponentClass, chatMessageTypeEnum, UUID.class);
|
||||
constructorMode = 3;
|
||||
} catch (NoSuchMethodException e2) {
|
||||
//Failed to resolve the constructor
|
||||
e2.printStackTrace();
|
||||
}
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_19_1)) {
|
||||
PLAYER_CHAT_MESSAGE_CLASS = NMSUtils.getNMClassWithoutException("network.chat.PlayerChatMessage");
|
||||
SIGNED_MESSAGE_BODY_CLASS = NMSUtils.getNMClassWithoutException("network.chat.SignedMessageBody");
|
||||
CHAT_MESSAGE_CONTENT_CLASS = NMSUtils.getNMClassWithoutException("network.chat.ChatMessageContent");
|
||||
CHAT_MESSAGE_TYPE_CLASS = NMSUtils.getNMClassWithoutException("network.chat.ChatMessageType");
|
||||
NETWORK_BOUND_CHAT_TYPE_CLASS = SubclassUtil.getSubClass(CHAT_MESSAGE_TYPE_CLASS, 1);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
chatClassConstructor = packetClass.getConstructor(NMSUtils.iChatBaseComponentClass, byte.class);
|
||||
constructorMode = 0;
|
||||
} catch (NoSuchMethodException e) {
|
||||
//That is fine, they are most likely on an older version.
|
||||
//Cause we read getChatPosition using constructor mode
|
||||
constructorMode = 4;
|
||||
}
|
||||
else {
|
||||
chatMessageTypeEnum = NMSUtils.getNMSEnumClassWithoutException("ChatMessageType");
|
||||
if (chatMessageTypeEnum == null) {
|
||||
chatMessageTypeEnum = NMSUtils.getNMEnumClassWithoutException("network.chat.ChatMessageType");
|
||||
}
|
||||
|
||||
if (chatMessageTypeEnum != null) {
|
||||
try {
|
||||
chatClassConstructor = packetClass.getConstructor(NMSUtils.iChatBaseComponentClass, int.class);
|
||||
constructorMode = 1;
|
||||
} catch (NoSuchMethodException e2) {
|
||||
chatClassConstructor = packetClass.getConstructor(NMSUtils.iChatBaseComponentClass, chatMessageTypeEnum);
|
||||
constructorMode = 2;
|
||||
} catch (NoSuchMethodException e) {
|
||||
//Just a much newer version(1.16.x and above right now)
|
||||
try {
|
||||
//Some weird 1.7.10 spigots remove that int parameter for no reason, I won't keep adding support for any more spigots and might stop
|
||||
//accepting pull requests for support for spigots breaking things that normal spigot has.
|
||||
chatClassConstructor = packetClass.getConstructor(NMSUtils.iChatBaseComponentClass);
|
||||
constructorMode = -1;
|
||||
} catch (NoSuchMethodException e3) {
|
||||
e3.printStackTrace();
|
||||
chatClassConstructor = packetClass.getConstructor(NMSUtils.iChatBaseComponentClass, chatMessageTypeEnum, UUID.class);
|
||||
constructorMode = 3;
|
||||
} catch (NoSuchMethodException e2) {
|
||||
//Failed to resolve the constructor
|
||||
e2.printStackTrace();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
chatClassConstructor = packetClass.getConstructor(NMSUtils.iChatBaseComponentClass, byte.class);
|
||||
constructorMode = 0;
|
||||
} catch (NoSuchMethodException e) {
|
||||
//That is fine, they are most likely on an older version.
|
||||
try {
|
||||
chatClassConstructor = packetClass.getConstructor(NMSUtils.iChatBaseComponentClass, int.class);
|
||||
constructorMode = 1;
|
||||
} catch (NoSuchMethodException e2) {
|
||||
try {
|
||||
//Some weird 1.7.10 spigots remove that int parameter for no reason, I won't keep adding support for any more spigots and might stop
|
||||
//accepting pull requests for support for spigots breaking things that normal spigot has.
|
||||
chatClassConstructor = packetClass.getConstructor(NMSUtils.iChatBaseComponentClass);
|
||||
constructorMode = -1;
|
||||
} catch (NoSuchMethodException e3) {
|
||||
e3.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object asNMSPacket() throws Exception {
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
|
||||
throw new IllegalStateException("You are trying to send the WrappedPacketOutChat packet on 1.19 or above. Please update to packetevents 2.0, this is not supported.");
|
||||
}
|
||||
byte chatPos = (byte) getChatPosition().ordinal();
|
||||
Enum<?> chatMessageTypeInstance = null;
|
||||
if (chatMessageTypeEnum != null) {
|
||||
@@ -141,6 +162,15 @@ public final class WrappedPacketOutChat extends WrappedPacket implements Sendabl
|
||||
*/
|
||||
public String getMessage() {
|
||||
if (packet != null) {
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_19_1)) {
|
||||
Object playerChatMessage = readObject(0, PLAYER_CHAT_MESSAGE_CLASS);
|
||||
WrappedPacket playerChatMessageWrapper = new WrappedPacket(new NMSPacket(playerChatMessage));
|
||||
Object signedMessageBody = playerChatMessageWrapper.readObject(0, SIGNED_MESSAGE_BODY_CLASS);
|
||||
WrappedPacket wrappedSignedMessageBody = new WrappedPacket(new NMSPacket(signedMessageBody));
|
||||
Object chatMessageContent = wrappedSignedMessageBody.readObject(0, CHAT_MESSAGE_CONTENT_CLASS);
|
||||
WrappedPacket wrappedChatMessage = new WrappedPacket(new NMSPacket(chatMessageContent));
|
||||
return wrappedChatMessage.readIChatBaseComponent(0);
|
||||
}
|
||||
return readIChatBaseComponent(0);
|
||||
} else {
|
||||
return message;
|
||||
@@ -149,12 +179,55 @@ public final class WrappedPacketOutChat extends WrappedPacket implements Sendabl
|
||||
|
||||
public void setMessage(String message) {
|
||||
if (packet != null) {
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_19_1)) {
|
||||
Object playerChatMessage = readObject(0, PLAYER_CHAT_MESSAGE_CLASS);
|
||||
WrappedPacket playerChatMessageWrapper = new WrappedPacket(new NMSPacket(playerChatMessage));
|
||||
Object signedMessageBody = playerChatMessageWrapper.readObject(0, SIGNED_MESSAGE_BODY_CLASS);
|
||||
WrappedPacket wrappedSignedMessageBody = new WrappedPacket(new NMSPacket(signedMessageBody));
|
||||
Object chatMessageContent = wrappedSignedMessageBody.readObject(0, CHAT_MESSAGE_CONTENT_CLASS);
|
||||
WrappedPacket wrappedChatMessage = new WrappedPacket(new NMSPacket(chatMessageContent));
|
||||
wrappedChatMessage.writeIChatBaseComponent(0, message);
|
||||
return;
|
||||
}
|
||||
writeIChatBaseComponent(0, message);
|
||||
} else {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<String> getUnsignedMessage() {
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_19_1)) {
|
||||
Object playerChatMessage = readObject(0, PLAYER_CHAT_MESSAGE_CLASS);
|
||||
WrappedPacket playerChatMessageWrapper = new WrappedPacket(new NMSPacket(playerChatMessage));
|
||||
Optional<?> opt = playerChatMessageWrapper.readObject(0, Optional.class);
|
||||
if (opt.isPresent()) {
|
||||
Object iChatBaseComponent = opt.get();
|
||||
return Optional.ofNullable(NMSUtils.readIChatBaseComponent(iChatBaseComponent));
|
||||
}
|
||||
}
|
||||
else if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
|
||||
Optional<?> opt = readObject(0, Optional.class);
|
||||
if (opt.isPresent()) {
|
||||
Object iChatBaseComponent = opt.get();
|
||||
return Optional.ofNullable(NMSUtils.readIChatBaseComponent(iChatBaseComponent));
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public void setUnsignedMessage(String unsignedMessage) {
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_19_1)) {
|
||||
Object playerChatMessage = readObject(0, PLAYER_CHAT_MESSAGE_CLASS);
|
||||
WrappedPacket playerChatMessageWrapper = new WrappedPacket(new NMSPacket(playerChatMessage));
|
||||
Object iChatBaseComponent = NMSUtils.generateIChatBaseComponent(unsignedMessage);
|
||||
playerChatMessageWrapper.write(Optional.class, 0, Optional.ofNullable(iChatBaseComponent));
|
||||
}
|
||||
else if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
|
||||
Object iChatBaseComponent = NMSUtils.generateIChatBaseComponent(unsignedMessage);
|
||||
write(Optional.class, 0, Optional.ofNullable(iChatBaseComponent));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the chat position.
|
||||
* <p>
|
||||
@@ -168,7 +241,7 @@ public final class WrappedPacketOutChat extends WrappedPacket implements Sendabl
|
||||
byte chatPositionValue;
|
||||
switch (constructorMode) {
|
||||
case -1:
|
||||
chatPositionValue = (byte) ChatPosition.CHAT.ordinal();
|
||||
chatPositionValue = (byte) ChatPosition.CHAT.getId(version);
|
||||
break;
|
||||
case 0:
|
||||
chatPositionValue = readByte(0);
|
||||
@@ -180,11 +253,16 @@ public final class WrappedPacketOutChat extends WrappedPacket implements Sendabl
|
||||
case 3:
|
||||
Enum<?> chatTypeEnumInstance = readEnumConstant(0, chatMessageTypeEnum);
|
||||
return ChatPosition.values()[chatTypeEnumInstance.ordinal()];
|
||||
case 4:
|
||||
Object chatMsgType = readObject(0, NETWORK_BOUND_CHAT_TYPE_CLASS);
|
||||
WrappedPacket chatMsgTypeWrapper = new WrappedPacket(new NMSPacket(chatMsgType));
|
||||
chatPositionValue = (byte) chatMsgTypeWrapper.readInt(0);
|
||||
break;
|
||||
default:
|
||||
chatPositionValue = 0;
|
||||
break;
|
||||
}
|
||||
return ChatPosition.values()[chatPositionValue];
|
||||
return ChatPosition.getById(version, chatPositionValue);
|
||||
} else {
|
||||
return chatPosition;
|
||||
}
|
||||
@@ -194,25 +272,87 @@ public final class WrappedPacketOutChat extends WrappedPacket implements Sendabl
|
||||
if (packet != null) {
|
||||
switch (constructorMode) {
|
||||
case 0:
|
||||
writeByte(0, (byte) chatPosition.ordinal());
|
||||
writeByte(0, (byte) chatPosition.getId(version));
|
||||
break;
|
||||
case 1:
|
||||
writeInt(0, chatPosition.ordinal());
|
||||
writeInt(0, chatPosition.getId(version));
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
Enum<?> chatTypeEnumInstance = EnumUtil.valueByIndex(chatMessageTypeEnum, chatPosition.ordinal());
|
||||
Enum<?> chatTypeEnumInstance = EnumUtil.valueByIndex(chatMessageTypeEnum,
|
||||
chatPosition.getId(version));
|
||||
writeEnumConstant(0, chatTypeEnumInstance);
|
||||
break;
|
||||
case 4:
|
||||
Object chatMsgType = readObject(0, NETWORK_BOUND_CHAT_TYPE_CLASS);
|
||||
WrappedPacket chatMsgTypeWrapper = new WrappedPacket(new NMSPacket(chatMsgType));
|
||||
chatMsgTypeWrapper.writeInt(0, chatPosition.getId(version));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
this.chatPosition = chatPosition;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Add support to every single Wrapper usage
|
||||
public enum ChatPosition {
|
||||
CHAT,
|
||||
SYSTEM_MESSAGE,
|
||||
GAME_INFO;
|
||||
CHAT(0),
|
||||
|
||||
@Deprecated
|
||||
SYSTEM(-1),
|
||||
@Deprecated
|
||||
GAME_INFO(-1),
|
||||
|
||||
SAY_COMMAND(1),
|
||||
|
||||
@Deprecated
|
||||
MSG_COMMAND(-1),
|
||||
|
||||
MSG_COMMAND_INCOMING(2),
|
||||
MSG_COMMAND_OUTGOING(3),
|
||||
|
||||
@Deprecated
|
||||
TEAM_MSG_COMMAND(-1),
|
||||
|
||||
TEAM_MSG_COMMAND_INCOMING(4),
|
||||
TEAM_MSG_COMMAND_OUTGOING(5),
|
||||
EMOTE_COMMAND(6),
|
||||
|
||||
@Deprecated
|
||||
TELLRAW_COMMAND(-1);
|
||||
|
||||
private final byte modernId;
|
||||
|
||||
ChatPosition(int modernId) {
|
||||
this.modernId = (byte) modernId;
|
||||
}
|
||||
|
||||
private static final ChatPosition[] VALUES;
|
||||
private static final Map<Byte, ChatPosition> MODERN_CHAT_TYPE_MAP;
|
||||
|
||||
static {
|
||||
VALUES = values();
|
||||
MODERN_CHAT_TYPE_MAP = new HashMap<>();
|
||||
|
||||
Arrays.stream(VALUES)
|
||||
.filter(chatType -> chatType.modernId != -1)
|
||||
.forEach(chatType -> MODERN_CHAT_TYPE_MAP.put(chatType.modernId, chatType));
|
||||
}
|
||||
|
||||
public int getId(ServerVersion version) {
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_19_1)) {
|
||||
return modernId;
|
||||
}
|
||||
return ordinal();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ChatPosition getById(ServerVersion version, int id) {
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_19_1)) {
|
||||
return MODERN_CHAT_TYPE_MAP.get((byte) id);
|
||||
} else {
|
||||
return VALUES[id];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+31
-21
@@ -35,11 +35,12 @@ public class WrappedPacketOutEntity extends WrappedPacketEntityAbstraction imple
|
||||
//Byte = 1.7.10->1.8.8, Int = 1.9->1.15.x, Short = 1.16.x
|
||||
private static byte mode; //byte = 0, int = 1, short = 2
|
||||
private static double dXYZDivisor;
|
||||
private static final float ROTATION_FACTOR = 256.0F / 360.0F;
|
||||
private static int yawByteIndex = 0;
|
||||
private static int pitchByteIndex = 1;
|
||||
private static Constructor<?> entityPacketConstructor, entityRelMovePacketConstructor, entityLookConstructor, entityRelMoveLookConstructor;
|
||||
private double deltaX, deltaY, deltaZ;
|
||||
private byte pitch, yaw;
|
||||
private float pitch, yaw;
|
||||
private boolean onGround, rotating, moving;
|
||||
|
||||
public WrappedPacketOutEntity(NMSPacket packet) {
|
||||
@@ -48,7 +49,7 @@ public class WrappedPacketOutEntity extends WrappedPacketEntityAbstraction imple
|
||||
}
|
||||
|
||||
public WrappedPacketOutEntity(int entityID, double deltaX, double deltaY, double deltaZ,
|
||||
byte yaw, byte pitch, boolean onGround, boolean rotating, boolean moving) {
|
||||
float yaw, float pitch, boolean onGround, boolean rotating, boolean moving) {
|
||||
this.entityID = entityID;
|
||||
this.deltaX = deltaX;
|
||||
this.deltaY = deltaY;
|
||||
@@ -61,22 +62,22 @@ public class WrappedPacketOutEntity extends WrappedPacketEntityAbstraction imple
|
||||
}
|
||||
|
||||
public WrappedPacketOutEntity(int entityID, double deltaX, double deltaY, double deltaZ,
|
||||
byte yaw, byte pitch, boolean onGround, boolean rotating) {
|
||||
float yaw, float pitch, boolean onGround, boolean rotating) {
|
||||
this(entityID, deltaX, deltaY, deltaZ, yaw, pitch, onGround, rotating, false);
|
||||
}
|
||||
|
||||
public WrappedPacketOutEntity(int entityID, double deltaX, double deltaY, double deltaZ,
|
||||
byte yaw, byte pitch, boolean onGround) {
|
||||
float yaw, float pitch, boolean onGround) {
|
||||
this(entityID, deltaX, deltaY, deltaZ, yaw, pitch, onGround, false, false);
|
||||
}
|
||||
|
||||
public WrappedPacketOutEntity(Entity entity, double deltaX, double deltaY, double deltaZ,
|
||||
byte yaw, byte pitch, boolean onGround, boolean isLook) {
|
||||
float yaw, float pitch, boolean onGround, boolean isLook) {
|
||||
this(entity.getEntityId(), deltaX, deltaY, deltaZ, yaw, pitch, onGround, isLook);
|
||||
}
|
||||
|
||||
public WrappedPacketOutEntity(Entity entity, double deltaX, double deltaY, double deltaZ,
|
||||
byte yaw, byte pitch, boolean onGround) {
|
||||
float yaw, float pitch, boolean onGround) {
|
||||
this(entity.getEntityId(), deltaX, deltaY, deltaZ, yaw, pitch, onGround, false);
|
||||
}
|
||||
|
||||
@@ -94,7 +95,9 @@ public class WrappedPacketOutEntity extends WrappedPacketEntityAbstraction imple
|
||||
pitchByteIndex = 4;
|
||||
} else if (dxField.equals(Reflection.getField(packetClass, int.class, 1))) {
|
||||
mode = 1;
|
||||
} else if (dxField.equals(Reflection.getField(packetClass, short.class, 0))) {
|
||||
} else if (dxField.equals(Reflection.getField(packetClass, short.class, 0))
|
||||
//1.19 support
|
||||
|| dxField.equals(Reflection.getField(packetClass, short.class, 1))) {
|
||||
mode = 2;
|
||||
}
|
||||
if (mode == 0) {
|
||||
@@ -116,33 +119,33 @@ public class WrappedPacketOutEntity extends WrappedPacketEntityAbstraction imple
|
||||
|
||||
}
|
||||
|
||||
public byte getPitch() {
|
||||
public float getPitch() {
|
||||
if (packet != null) {
|
||||
return readByte(pitchByteIndex);
|
||||
return readByte(pitchByteIndex) / ROTATION_FACTOR;
|
||||
} else {
|
||||
return pitch;
|
||||
}
|
||||
}
|
||||
|
||||
public void setPitch(byte pitch) {
|
||||
public void setPitch(float pitch) {
|
||||
if (packet != null) {
|
||||
writeByte(pitchByteIndex, pitch);
|
||||
writeByte(pitchByteIndex, (byte) (pitch * ROTATION_FACTOR));
|
||||
} else {
|
||||
this.pitch = pitch;
|
||||
}
|
||||
}
|
||||
|
||||
public byte getYaw() {
|
||||
public float getYaw() {
|
||||
if (packet != null) {
|
||||
return readByte(yawByteIndex);
|
||||
return readByte(yawByteIndex) / ROTATION_FACTOR;
|
||||
} else {
|
||||
return yaw;
|
||||
}
|
||||
}
|
||||
|
||||
public void setYaw(byte yaw) {
|
||||
public void setYaw(float yaw) {
|
||||
if (packet != null) {
|
||||
writeByte(yawByteIndex, yaw);
|
||||
writeByte(yawByteIndex, (byte) (yaw * ROTATION_FACTOR));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -315,10 +318,12 @@ public class WrappedPacketOutEntity extends WrappedPacketEntityAbstraction imple
|
||||
@Override
|
||||
public Object asNMSPacket() throws Exception {
|
||||
if (v_1_17) {
|
||||
byte angleYaw = (byte) (getYaw() * ROTATION_FACTOR);
|
||||
byte anglePitch = (byte) (getPitch() * ROTATION_FACTOR);
|
||||
return entityPacketConstructor.newInstance(getEntityId(),
|
||||
(short) (getDeltaX() * dXYZDivisor), (short) (getDeltaY() * dXYZDivisor),
|
||||
(short) (getDeltaZ() * dXYZDivisor),
|
||||
getYaw(), getPitch(), isOnGround(), isRotating().get(), isMoving().get());
|
||||
angleYaw, anglePitch, isOnGround(), isRotating().get(), isMoving().get());
|
||||
} else {
|
||||
Object packetInstance = entityPacketConstructor.newInstance(getEntityId());
|
||||
WrappedPacketOutEntity wrapper = new WrappedPacketOutEntity(new NMSPacket(packetInstance));
|
||||
@@ -343,7 +348,7 @@ public class WrappedPacketOutEntity extends WrappedPacketEntityAbstraction imple
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public WrappedPacketOutEntityLook(int entityID, byte yaw, byte pitch, boolean onGround) {
|
||||
public WrappedPacketOutEntityLook(int entityID, float yaw, float pitch, boolean onGround) {
|
||||
super(entityID, 0, 0, 0, yaw, pitch, onGround, true);
|
||||
}
|
||||
|
||||
@@ -366,7 +371,9 @@ public class WrappedPacketOutEntity extends WrappedPacketEntityAbstraction imple
|
||||
public Object asNMSPacket() throws Exception {
|
||||
Object packetInstance;
|
||||
if (v_1_17) {
|
||||
packetInstance = entityLookConstructor.newInstance(getEntityId(), getYaw(), getPitch(), isOnGround());
|
||||
byte angleYaw = (byte) (getYaw() * ROTATION_FACTOR);
|
||||
byte anglePitch = (byte) (getPitch() * ROTATION_FACTOR);
|
||||
packetInstance = entityLookConstructor.newInstance(getEntityId(), angleYaw, anglePitch, isOnGround());
|
||||
}
|
||||
else {
|
||||
packetInstance = entityLookConstructor.newInstance();
|
||||
@@ -389,7 +396,7 @@ public class WrappedPacketOutEntity extends WrappedPacketEntityAbstraction imple
|
||||
}
|
||||
|
||||
public WrappedPacketOutRelEntityMove(int entityID, double deltaX, double deltaY, double deltaZ, boolean onGround) {
|
||||
super(entityID, deltaX, deltaY, deltaZ, (byte) 0, (byte) 0, onGround, false);
|
||||
super(entityID, deltaX, deltaY, deltaZ, 0, 0, onGround, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -438,7 +445,8 @@ public class WrappedPacketOutEntity extends WrappedPacketEntityAbstraction imple
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public WrappedPacketOutRelEntityMoveLook(int entityID, double deltaX, double deltaY, double deltaZ, byte yaw, byte pitch, boolean onGround) {
|
||||
public WrappedPacketOutRelEntityMoveLook(int entityID, double deltaX, double deltaY, double deltaZ,
|
||||
float yaw, float pitch, boolean onGround) {
|
||||
super(entityID, deltaX, deltaY, deltaZ, yaw, pitch, onGround, false);
|
||||
}
|
||||
|
||||
@@ -464,7 +472,9 @@ public class WrappedPacketOutEntity extends WrappedPacketEntityAbstraction imple
|
||||
short dx = (short) (getDeltaX() * dXYZDivisor);
|
||||
short dy = (short) (getDeltaY() * dXYZDivisor);
|
||||
short dz = (short) (getDeltaZ() * dXYZDivisor);
|
||||
packetInstance = entityRelMoveLookConstructor.newInstance(getEntityId(), dx, dy, dz, getYaw(), getPitch(), isOnGround());
|
||||
byte angleYaw = (byte) (getYaw() * ROTATION_FACTOR);
|
||||
byte anglePitch = (byte) (getPitch() * ROTATION_FACTOR);
|
||||
packetInstance = entityRelMoveLookConstructor.newInstance(getEntityId(), dx, dy, dz, angleYaw, anglePitch, isOnGround());
|
||||
}
|
||||
else {
|
||||
packetInstance = entityRelMoveLookConstructor.newInstance();
|
||||
|
||||
+74
-42
@@ -22,18 +22,24 @@ import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.SendableWrapper;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.helper.WrappedPacketEntityAbstraction;
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* @author yanjulang, MWHunter
|
||||
* @since 1.8
|
||||
*/
|
||||
public class WrappedPacketOutEntityDestroy extends WrappedPacketEntityAbstraction implements SendableWrapper {
|
||||
private static Class<?> INT_COLLECTION_CLASS;
|
||||
private static Class<?> INT_LIST_CLASS;
|
||||
private static Class<?> INT_ARRAY_LIST_CLASS;
|
||||
private static Constructor<?> INT_ARRAY_LIST_CONSTRUCTOR;
|
||||
private static Method TO_INT_ARRAY_METHOD;
|
||||
private static boolean v_1_17;
|
||||
private static boolean v_1_17_1;
|
||||
private static Constructor<?> packetConstructor;
|
||||
@@ -61,12 +67,31 @@ public class WrappedPacketOutEntityDestroy extends WrappedPacketEntityAbstractio
|
||||
v_1_17_1 = version.isNewerThanOrEquals(ServerVersion.v_1_17_1);
|
||||
v_1_17 = version.equals(ServerVersion.v_1_17);
|
||||
|
||||
if (v_1_17_1) {
|
||||
if (INT_COLLECTION_CLASS == null) {
|
||||
INT_COLLECTION_CLASS = Reflection.getClassByNameWithoutException("it.unimi.dsi.fastutil.ints.IntCollection");
|
||||
INT_LIST_CLASS = Reflection.getClassByNameWithoutException("it.unimi.dsi.fastutil.ints.IntList");
|
||||
INT_ARRAY_LIST_CLASS = Reflection.getClassByNameWithoutException("it.unimi.dsi.fastutil.ints.IntArrayList");
|
||||
try {
|
||||
INT_ARRAY_LIST_CONSTRUCTOR = INT_ARRAY_LIST_CLASS.getConstructor(int[].class);
|
||||
INT_ARRAY_LIST_CONSTRUCTOR.setAccessible(true);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
TO_INT_ARRAY_METHOD = INT_COLLECTION_CLASS.getDeclaredMethod("toIntArray");
|
||||
TO_INT_ARRAY_METHOD.setAccessible(true);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (v_1_17) {
|
||||
packetConstructor =
|
||||
PacketTypeClasses.Play.Server.ENTITY_DESTROY.getConstructor(int.class);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
packetConstructor =
|
||||
PacketTypeClasses.Play.Server.ENTITY_DESTROY.getConstructor(int[].class);
|
||||
}
|
||||
@@ -80,15 +105,17 @@ public class WrappedPacketOutEntityDestroy extends WrappedPacketEntityAbstractio
|
||||
if (entityID != -1 || entityIds.length > 0 || packet == null) {
|
||||
if (v_1_17) {
|
||||
return entityID;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return entityIds[0];
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (v_1_17_1) {
|
||||
IntList list = readObject(0, IntList.class);
|
||||
entityIds = list.toIntArray();
|
||||
Object list = readObject(0, INT_LIST_CLASS);
|
||||
try {
|
||||
entityIds = (int[]) TO_INT_ARRAY_METHOD.invoke(list);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return entityIds[0];
|
||||
} else if (v_1_17) {
|
||||
return entityID = readInt(0);
|
||||
@@ -105,23 +132,25 @@ public class WrappedPacketOutEntityDestroy extends WrappedPacketEntityAbstractio
|
||||
if (packet != null) {
|
||||
if (v_1_17) {
|
||||
writeInt(0, this.entityID = entityID);
|
||||
}
|
||||
else {
|
||||
this.entityIds = new int[] {entityID};
|
||||
} else {
|
||||
this.entityIds = new int[]{entityID};
|
||||
if (v_1_17_1) {
|
||||
IntList intArrayList = new IntArrayList(this.entityIds);
|
||||
write(IntList.class, 0, intArrayList);
|
||||
}
|
||||
else {
|
||||
Object intArrayList = null;
|
||||
try {
|
||||
intArrayList = INT_ARRAY_LIST_CONSTRUCTOR.newInstance(this.entityIds);
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
write(INT_LIST_CLASS, 0, intArrayList);
|
||||
} else {
|
||||
writeIntArray(0, new int[]{this.entityIds[0]});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (v_1_17) {
|
||||
this.entityID = entityID;
|
||||
}
|
||||
else {
|
||||
this.entityIds = new int[] {entityID};
|
||||
} else {
|
||||
this.entityIds = new int[]{entityID};
|
||||
}
|
||||
}
|
||||
this.entity = null;
|
||||
@@ -130,19 +159,22 @@ public class WrappedPacketOutEntityDestroy extends WrappedPacketEntityAbstractio
|
||||
public int[] getEntityIds() {
|
||||
if (packet != null) {
|
||||
if (v_1_17) {
|
||||
return new int[] {getEntityId()};
|
||||
}
|
||||
else if (v_1_17_1) {
|
||||
return readObject(0, IntList.class).toIntArray();
|
||||
}
|
||||
else {
|
||||
return new int[]{getEntityId()};
|
||||
} else if (v_1_17_1) {
|
||||
Object list = readObject(0, INT_LIST_CLASS);
|
||||
try {
|
||||
return (int[]) TO_INT_ARRAY_METHOD.invoke(list);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
} else {
|
||||
return readIntArray(0);
|
||||
}
|
||||
} else {
|
||||
if (v_1_17) {
|
||||
return new int[] {entityID};
|
||||
}
|
||||
else {
|
||||
if (v_1_17) {
|
||||
return new int[]{entityID};
|
||||
} else {
|
||||
return entityIds;
|
||||
}
|
||||
}
|
||||
@@ -152,20 +184,21 @@ public class WrappedPacketOutEntityDestroy extends WrappedPacketEntityAbstractio
|
||||
if (packet != null) {
|
||||
if (v_1_17) {
|
||||
setEntityId(entityIds[0]);
|
||||
}
|
||||
else if (v_1_17_1) {
|
||||
IntList intList = new IntArrayList(entityIds);
|
||||
write(IntList.class, 0, intList);
|
||||
}
|
||||
else {
|
||||
} else if (v_1_17_1) {
|
||||
Object intArrayList = null;
|
||||
try {
|
||||
intArrayList = INT_ARRAY_LIST_CONSTRUCTOR.newInstance(entityIds);
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
write(INT_LIST_CLASS, 0, intArrayList);
|
||||
} else {
|
||||
writeIntArray(0, entityIds);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (v_1_17) {
|
||||
this.entityID = entityIds[0];
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
this.entityIds = entityIds;
|
||||
}
|
||||
}
|
||||
@@ -176,8 +209,7 @@ public class WrappedPacketOutEntityDestroy extends WrappedPacketEntityAbstractio
|
||||
public Object asNMSPacket() throws Exception {
|
||||
if (v_1_17) {
|
||||
return packetConstructor.newInstance(getEntityId());
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return packetConstructor.newInstance(getEntityIds());
|
||||
}
|
||||
}
|
||||
|
||||
+96
-13
@@ -24,17 +24,23 @@ import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.SendableWrapper;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.helper.WrappedPacketEntityAbstraction;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Optional;
|
||||
|
||||
public class WrappedPacketOutEntityEffect extends WrappedPacketEntityAbstraction implements SendableWrapper {
|
||||
private static boolean v_1_7_10, v_1_17;
|
||||
private static boolean v_1_7_10, v_1_17, v_1_18_2, v_1_19, v_1_20_5;
|
||||
private static Constructor<?> packetConstructor;
|
||||
private static Class<?> holderClass;
|
||||
private static Method accessHolderValueMethod;
|
||||
private static boolean hasHolder = false;
|
||||
private int effectID;
|
||||
private int amplifier;
|
||||
private int duration;
|
||||
@@ -104,12 +110,26 @@ public class WrappedPacketOutEntityEffect extends WrappedPacketEntityAbstraction
|
||||
protected void load() {
|
||||
v_1_7_10 = version.isOlderThan(ServerVersion.v_1_8);
|
||||
v_1_17 = version.isNewerThanOrEquals(ServerVersion.v_1_17);
|
||||
v_1_18_2 = version.isNewerThanOrEquals(ServerVersion.v_1_18_2);
|
||||
v_1_19 = version.isNewerThanOrEquals(ServerVersion.v_1_19);
|
||||
v_1_20_5 = version.isNewerThanOrEquals(ServerVersion.v_1_20_5);
|
||||
try {
|
||||
|
||||
if (v_1_17) {
|
||||
packetConstructor = PacketTypeClasses.Play.Server.ENTITY_EFFECT.getConstructor(NMSUtils.packetDataSerializerClass);
|
||||
/*packetConstructor = PacketTypeClasses.Play.Server.ENTITY_EFFECT.getDeclaredConstructor(NMSUtils.packetDataSerializerClass);
|
||||
packetConstructor.setAccessible(true);
|
||||
if (packetConstructor == null) {
|
||||
Class<?> registryFriendlyByteBuf = NMSUtils.getNMClassWithoutException("network.RegistryFriendlyByteBuf");
|
||||
packetConstructor = PacketTypeClasses.Play.Server.ENTITY_EFFECT.getDeclaredConstructor(registryFriendlyByteBuf);
|
||||
}*/
|
||||
} else {
|
||||
packetConstructor = PacketTypeClasses.Play.Server.ENTITY_EFFECT.getConstructor();
|
||||
}
|
||||
|
||||
holderClass = NMSUtils.getNMClassWithoutException("core.Holder");
|
||||
if (holderClass != null) {
|
||||
hasHolder = Reflection.getField(PacketTypeClasses.Play.Server.ENTITY_EFFECT, holderClass, 0) != null;
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -117,7 +137,28 @@ public class WrappedPacketOutEntityEffect extends WrappedPacketEntityAbstraction
|
||||
|
||||
public int getEffectId() {
|
||||
if (packet != null) {
|
||||
return readByte(0);
|
||||
if (v_1_19) {
|
||||
Object mobEffectList = null;
|
||||
if (hasHolder) {
|
||||
Object holder = readObject(0, holderClass);
|
||||
if (accessHolderValueMethod == null) {
|
||||
accessHolderValueMethod = Reflection.getMethod(holderClass, 0);
|
||||
}
|
||||
try {
|
||||
mobEffectList = accessHolderValueMethod.invoke(holder);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
else {
|
||||
mobEffectList = readObject(0, NMSUtils.mobEffectListClass);
|
||||
}
|
||||
return NMSUtils.getEffectId(mobEffectList);
|
||||
} else if (v_1_18_2) {
|
||||
return readInt(4);
|
||||
} else {
|
||||
return readByte(0);
|
||||
}
|
||||
} else {
|
||||
return effectID;
|
||||
}
|
||||
@@ -125,7 +166,14 @@ public class WrappedPacketOutEntityEffect extends WrappedPacketEntityAbstraction
|
||||
|
||||
public void setEffectId(int effectID) {
|
||||
if (packet != null) {
|
||||
writeByte(0, (byte) effectID);
|
||||
if (v_1_19) {
|
||||
Object mobEffectList = NMSUtils.getMobEffectListById(effectID);
|
||||
write(NMSUtils.mobEffectListClass, 0, mobEffectList);
|
||||
} else if (v_1_18_2) {
|
||||
writeInt(4, effectID);
|
||||
} else {
|
||||
writeByte(0, (byte) effectID);
|
||||
}
|
||||
} else {
|
||||
this.effectID = effectID;
|
||||
}
|
||||
@@ -133,7 +181,10 @@ public class WrappedPacketOutEntityEffect extends WrappedPacketEntityAbstraction
|
||||
|
||||
public int getAmplifier() {
|
||||
if (packet != null) {
|
||||
return readByte(1);
|
||||
if (v_1_20_5) {
|
||||
return readInt(5);
|
||||
}
|
||||
return readByte(v_1_18_2 ? 0 : 1);
|
||||
} else {
|
||||
return amplifier;
|
||||
}
|
||||
@@ -141,7 +192,10 @@ public class WrappedPacketOutEntityEffect extends WrappedPacketEntityAbstraction
|
||||
|
||||
public void setAmplifier(int amplifier) {
|
||||
if (packet != null) {
|
||||
writeByte(1, (byte) amplifier);
|
||||
if (v_1_20_5) {
|
||||
writeInt(5, amplifier);
|
||||
}
|
||||
writeByte(v_1_18_2 ? 0 : 1, (byte) amplifier);
|
||||
} else {
|
||||
this.amplifier = amplifier;
|
||||
}
|
||||
@@ -149,9 +203,22 @@ public class WrappedPacketOutEntityEffect extends WrappedPacketEntityAbstraction
|
||||
|
||||
public int getDuration() {
|
||||
if (packet != null) {
|
||||
//1.7 and only 1.7(below 1.8)
|
||||
if (v_1_7_10) {
|
||||
return readShort(1);
|
||||
} else {
|
||||
}
|
||||
else if (v_1_20_5) {
|
||||
return readInt(6);
|
||||
}
|
||||
else if (v_1_19) {
|
||||
return readInt(4);
|
||||
}
|
||||
//1.18.2+
|
||||
else if (v_1_18_2) {
|
||||
return readInt(5);
|
||||
}
|
||||
//1.17 - 1.8
|
||||
else {
|
||||
return readInt(v_1_17 ? 4 : 1);
|
||||
}
|
||||
} else {
|
||||
@@ -169,6 +236,14 @@ public class WrappedPacketOutEntityEffect extends WrappedPacketEntityAbstraction
|
||||
duration = Short.MIN_VALUE;
|
||||
}
|
||||
writeShort(0, (short) duration);
|
||||
}
|
||||
else if (v_1_20_5) {
|
||||
writeInt(6, duration);
|
||||
}
|
||||
else if (v_1_19) {
|
||||
writeInt(4, duration);
|
||||
} else if (v_1_18_2) {
|
||||
writeInt(5, duration);
|
||||
} else {
|
||||
writeInt(v_1_17 ? 4 : 1, duration);
|
||||
}
|
||||
@@ -178,21 +253,27 @@ public class WrappedPacketOutEntityEffect extends WrappedPacketEntityAbstraction
|
||||
}
|
||||
|
||||
private Optional<Byte> getByteMask() {
|
||||
if (version.isOlderThan(ServerVersion.v_1_8)) {
|
||||
if (v_1_7_10) {
|
||||
return Optional.empty();
|
||||
}
|
||||
if (packet != null && !byteMaskInitialized) {
|
||||
return Optional.of(byteMask = readByte(2));
|
||||
if (v_1_20_5) {
|
||||
return Optional.of(readByte(0));
|
||||
}
|
||||
return Optional.of(byteMask = readByte(v_1_18_2 ? 1 : 2));
|
||||
} else {
|
||||
return Optional.of(byteMask);
|
||||
}
|
||||
}
|
||||
|
||||
private void setByteMask(byte byteMask) {
|
||||
if (version.isNewerThan(ServerVersion.v_1_7_10)) {
|
||||
if (!v_1_7_10) {
|
||||
this.byteMask = byteMask;
|
||||
if (packet != null) {
|
||||
writeByte(2, byteMask);
|
||||
if (v_1_20_5) {
|
||||
writeByte(0, byteMask);
|
||||
}
|
||||
writeByte(v_1_18_2 ? 1 : 2, byteMask);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -293,8 +374,10 @@ public class WrappedPacketOutEntityEffect extends WrappedPacketEntityAbstraction
|
||||
public Object asNMSPacket() throws Exception {
|
||||
Object packetInstance;
|
||||
if (v_1_17) {
|
||||
//Lazy, but smart way :)
|
||||
Object packetDataSerializer = NMSUtils.generatePacketDataSerializer(PacketEvents.get().getByteBufUtil().newByteBuf(new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}));
|
||||
//Lazy and stupid way
|
||||
//was size 12
|
||||
byte[] buffer = new byte[30];
|
||||
Object packetDataSerializer = NMSUtils.generatePacketDataSerializer(PacketEvents.get().getByteBufUtil().newByteBuf(buffer));
|
||||
packetInstance = packetConstructor.newInstance(packetDataSerializer);
|
||||
} else {
|
||||
packetInstance = packetConstructor.newInstance();
|
||||
|
||||
+8
-7
@@ -32,18 +32,19 @@ import java.lang.reflect.Constructor;
|
||||
public class WrappedPacketOutEntityHeadRotation extends WrappedPacketEntityAbstraction implements SendableWrapper {
|
||||
private static boolean v_1_17;
|
||||
private static Constructor<?> packetConstructor;
|
||||
private byte yaw;
|
||||
private static final float ROTATION_FACTOR = 256.0F / 360.0F;
|
||||
private float yaw;
|
||||
|
||||
public WrappedPacketOutEntityHeadRotation(NMSPacket packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public WrappedPacketOutEntityHeadRotation(int entityID, byte yaw) {
|
||||
public WrappedPacketOutEntityHeadRotation(int entityID, float yaw) {
|
||||
this.entityID = entityID;
|
||||
this.yaw = yaw;
|
||||
}
|
||||
|
||||
public WrappedPacketOutEntityHeadRotation(Entity entity, byte yaw) {
|
||||
public WrappedPacketOutEntityHeadRotation(Entity entity, float yaw) {
|
||||
this.entityID = entity.getEntityId();
|
||||
this.entity = entity;
|
||||
this.yaw = yaw;
|
||||
@@ -64,17 +65,17 @@ public class WrappedPacketOutEntityHeadRotation extends WrappedPacketEntityAbstr
|
||||
}
|
||||
}
|
||||
|
||||
public byte getYaw() {
|
||||
public float getYaw() {
|
||||
if (packet != null) {
|
||||
return readByte(0);
|
||||
return readByte(0) / ROTATION_FACTOR;
|
||||
} else {
|
||||
return yaw;
|
||||
}
|
||||
}
|
||||
|
||||
public void setYaw(byte yaw) {
|
||||
public void setYaw(float yaw) {
|
||||
if (packet != null) {
|
||||
writeByte(0, yaw);
|
||||
writeByte(0, (byte) (yaw * ROTATION_FACTOR));
|
||||
} else {
|
||||
this.yaw = yaw;
|
||||
}
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ public class WrappedPacketOutEntityMetadata extends WrappedPacketEntityAbstracti
|
||||
|
||||
public List<WrappedWatchableObject> getWatchableObjects() {
|
||||
List<Object> nmsWatchableObjectList = readList(0);
|
||||
//Its annotated as nullable on 1.17 NMS, so lets just handle it being null
|
||||
//It's annotated as nullable on 1.17 NMS, so lets just handle it being null
|
||||
if (nmsWatchableObjectList == null) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
+17
-5
@@ -38,7 +38,15 @@ public class WrappedWatchableObject extends WrappedPacket {
|
||||
|
||||
@Override
|
||||
protected void load() {
|
||||
if (version.isNewerThan(ServerVersion.v_1_8_8)) {
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_19_3)) {
|
||||
valueIndex = 2;
|
||||
try {
|
||||
googleOptionalClass = Class.forName("com.google.common.base.Optional");
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
else if (version.isNewerThan(ServerVersion.v_1_8_8)) {
|
||||
valueIndex = 1;
|
||||
try {
|
||||
googleOptionalClass = Class.forName("com.google.common.base.Optional");
|
||||
@@ -49,17 +57,19 @@ public class WrappedWatchableObject extends WrappedPacket {
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
if (version.isNewerThan(ServerVersion.v_1_8_8)) {
|
||||
if (version.isNewerThan(ServerVersion.v_1_8_8) && version.isOlderThan(ServerVersion.v_1_19_3)) {
|
||||
Object dataWatcherObject = readAnyObject(0);
|
||||
WrappedPacket wrappedDataWatcher = new WrappedPacket(new NMSPacket(dataWatcherObject));
|
||||
return wrappedDataWatcher.readInt(0);
|
||||
|
||||
} else {
|
||||
//1.19.3 changed back to this
|
||||
return readInt(0);
|
||||
}
|
||||
}
|
||||
|
||||
public void setIndex(int index) {
|
||||
if (version.isNewerThan(ServerVersion.v_1_8_8)) {
|
||||
if (version.isNewerThan(ServerVersion.v_1_8_8) && version.isOlderThan(ServerVersion.v_1_19_3)) {
|
||||
Object dataWatcherObject = readAnyObject(0);
|
||||
WrappedPacket wrappedDataWatcher = new WrappedPacket(new NMSPacket(dataWatcherObject));
|
||||
wrappedDataWatcher.writeInt(0, index);
|
||||
@@ -69,11 +79,13 @@ public class WrappedWatchableObject extends WrappedPacket {
|
||||
}
|
||||
|
||||
public boolean isDirty() {
|
||||
return readBoolean(0);
|
||||
return !version.isOlderThan(ServerVersion.v_1_19_3) || readBoolean(0);
|
||||
}
|
||||
|
||||
public void setDirty(boolean dirty) {
|
||||
writeBoolean(0, dirty);
|
||||
if (version.isOlderThan(ServerVersion.v_1_19_3)) {
|
||||
writeBoolean(0, dirty);
|
||||
}
|
||||
}
|
||||
|
||||
public Object getRawValue() {
|
||||
|
||||
+1
-1
@@ -81,7 +81,7 @@ public class WrappedPacketOutExplosion extends WrappedPacket implements Sendable
|
||||
chunkPosConstructor = chunkPosClass.getConstructor(int.class, int.class, int.class);
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
//1.20.4 or newer
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -54,6 +54,7 @@ public class WrappedPacketOutGameStateChange extends WrappedPacket implements Se
|
||||
@Override
|
||||
protected void load() {
|
||||
reasonClassType = SubclassUtil.getSubClass(PacketTypeClasses.Play.Server.GAME_STATE_CHANGE, 0);
|
||||
net.minecraft.server.v1_8_R3.PacketPlayOutGameStateChange gsc;
|
||||
if (reasonClassType != null) {
|
||||
try {
|
||||
reasonClassConstructor = reasonClassType.getConstructor(int.class);
|
||||
@@ -140,7 +141,7 @@ public class WrappedPacketOutGameStateChange extends WrappedPacket implements Se
|
||||
|
||||
@Override
|
||||
public Object asNMSPacket() throws Exception {
|
||||
if (reasonClassType == null) {
|
||||
if (reasonIntMode) {
|
||||
if (valueFloatMode) {
|
||||
return packetConstructor.newInstance(getReason(), (float) getValue());
|
||||
} else {
|
||||
|
||||
+23
@@ -80,4 +80,27 @@ public class WrappedPacketOutLogin extends WrappedPacketEntityAbstraction {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public int getPortalCooldown() {
|
||||
if (packet != null) {
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_20)) {
|
||||
return readInt(4);
|
||||
}
|
||||
}
|
||||
else {
|
||||
//TODO unfinished
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void setPortalCooldown(int portalCooldown) {
|
||||
if (packet != null) {
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_20)) {
|
||||
writeInt(4, portalCooldown);
|
||||
}
|
||||
}
|
||||
else {
|
||||
//TODO unfinished
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
@@ -114,6 +114,7 @@ public class WrappedPacketOutPlayerInfo extends WrappedPacket implements Sendabl
|
||||
}
|
||||
}
|
||||
|
||||
//TODO Technically we would need to support profile signiture data for complete 1.19.1 support.
|
||||
public PlayerInfo[] getPlayerInfo() {
|
||||
if (packet != null) {
|
||||
PlayerInfo[] playerInfoArray = new PlayerInfo[1];
|
||||
@@ -126,6 +127,7 @@ public class WrappedPacketOutPlayerInfo extends WrappedPacket implements Sendabl
|
||||
playerInfoArray[0] = new PlayerInfo(username, gameProfile, gameMode, ping);
|
||||
} else {
|
||||
List<Object> nmsPlayerInfoDataList = readList(0);
|
||||
playerInfoArray = new PlayerInfo[nmsPlayerInfoDataList.size()];
|
||||
for (int i = 0; i < nmsPlayerInfoDataList.size(); i++) {
|
||||
Object nmsPlayerInfoData = nmsPlayerInfoDataList.get(i);
|
||||
WrappedPacket nmsPlayerInfoDataWrapper = new WrappedPacket(new NMSPacket(nmsPlayerInfoData));
|
||||
@@ -200,6 +202,14 @@ public class WrappedPacketOutPlayerInfo extends WrappedPacket implements Sendabl
|
||||
return packetInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
//1.19.3 removed this packet and replaced it with PlayerInfoRemove & PlayerInfoUpdate
|
||||
//TODO Since this is a minimal update, we won't add those. v1.8 will eventually be discontinued
|
||||
//so please consider updating to 2.0
|
||||
return version.isOlderThanOrEquals(ServerVersion.v_1_19_2);
|
||||
}
|
||||
|
||||
public enum PlayerInfoAction {
|
||||
ADD_PLAYER,
|
||||
UPDATE_GAME_MODE,
|
||||
|
||||
+37
-5
@@ -23,14 +23,20 @@ import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.SendableWrapper;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.helper.WrappedPacketEntityAbstraction;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class WrappedPacketOutRemoveEntityEffect extends WrappedPacketEntityAbstraction implements SendableWrapper {
|
||||
private static boolean v_1_8_x, v_1_17;
|
||||
private static Constructor<?> packetConstructor;
|
||||
private static Class<?> holderClass;
|
||||
private static Method accessHolderValueMethod;
|
||||
private static boolean hasHolder = false;
|
||||
private int effectID;
|
||||
|
||||
public WrappedPacketOutRemoveEntityEffect(NMSPacket packet) {
|
||||
@@ -54,11 +60,17 @@ public class WrappedPacketOutRemoveEntityEffect extends WrappedPacketEntityAbstr
|
||||
v_1_17 = version.isNewerThanOrEquals(ServerVersion.v_1_17);
|
||||
try {
|
||||
if (v_1_17) {
|
||||
packetConstructor = PacketTypeClasses.Play.Server.REMOVE_ENTITY_EFFECT.getConstructor(int.class, NMSUtils.mobEffectListClass);
|
||||
//packetConstructor = PacketTypeClasses.Play.Server.REMOVE_ENTITY_EFFECT.getConstructor(int.class, NMSUtils.mobEffectListClass);
|
||||
}
|
||||
else {
|
||||
packetConstructor = PacketTypeClasses.Play.Server.REMOVE_ENTITY_EFFECT.getConstructor();
|
||||
}
|
||||
|
||||
|
||||
holderClass = NMSUtils.getNMClassWithoutException("core.Holder");
|
||||
if (holderClass != null) {
|
||||
hasHolder = Reflection.getField(PacketTypeClasses.Play.Server.ENTITY_EFFECT, holderClass, 0) != null;
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -66,11 +78,28 @@ public class WrappedPacketOutRemoveEntityEffect extends WrappedPacketEntityAbstr
|
||||
|
||||
public int getEffectId() {
|
||||
if (packet != null) {
|
||||
//1.7 and 1.8
|
||||
if (v_1_8_x) {
|
||||
return readInt(1);
|
||||
} else {
|
||||
Object nmsMobEffectList = readObject(0, NMSUtils.mobEffectListClass);
|
||||
return NMSUtils.getEffectId(nmsMobEffectList);
|
||||
}
|
||||
//1.9+
|
||||
else {
|
||||
Object mobEffectList = null;
|
||||
if (hasHolder) {
|
||||
Object holder = readObject(0, holderClass);
|
||||
if (accessHolderValueMethod == null) {
|
||||
accessHolderValueMethod = Reflection.getMethod(holderClass, 0);
|
||||
}
|
||||
try {
|
||||
mobEffectList = accessHolderValueMethod.invoke(holder);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
else {
|
||||
mobEffectList = readObject(0, NMSUtils.mobEffectListClass);
|
||||
}
|
||||
return NMSUtils.getEffectId(mobEffectList);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -80,9 +109,12 @@ public class WrappedPacketOutRemoveEntityEffect extends WrappedPacketEntityAbstr
|
||||
|
||||
public void setEffectId(int effectID) {
|
||||
if (packet != null) {
|
||||
//1.7 and 1.8
|
||||
if (v_1_8_x) {
|
||||
writeInt(1, effectID);
|
||||
} else {
|
||||
}
|
||||
//1.9+
|
||||
else {
|
||||
Object nmsMobEffectList = NMSUtils.getMobEffectListById(effectID);
|
||||
write(NMSUtils.mobEffectListClass, 0, nmsMobEffectList);
|
||||
}
|
||||
|
||||
+19
@@ -33,6 +33,7 @@ class WrappedPacketOutRespawn extends WrappedPacket {
|
||||
private Difficulty difficulty;
|
||||
private GameMode gameMode;
|
||||
private WorldType levelType;
|
||||
private int portalCooldown;
|
||||
|
||||
public WrappedPacketOutRespawn(NMSPacket packet) {
|
||||
super(packet);
|
||||
@@ -76,6 +77,24 @@ class WrappedPacketOutRespawn extends WrappedPacket {
|
||||
}
|
||||
}
|
||||
|
||||
public int getPortalCooldown() {
|
||||
if (packet != null) {
|
||||
return readInt(0);
|
||||
}
|
||||
else {
|
||||
return portalCooldown;
|
||||
}
|
||||
}
|
||||
|
||||
public void setPortalCooldown(int portalCooldown) {
|
||||
if (packet != null) {
|
||||
writeInt(0, portalCooldown);
|
||||
}
|
||||
else {
|
||||
this.portalCooldown = portalCooldown;
|
||||
}
|
||||
}
|
||||
|
||||
/*public WorldType getLevelType() {
|
||||
if (packet != null) {
|
||||
//TODO finish
|
||||
|
||||
+1
-1
@@ -155,7 +155,7 @@ public class WrappedPacketOutSetSlot extends WrappedPacket implements SendableWr
|
||||
@Override
|
||||
public Object asNMSPacket() throws Exception {
|
||||
if (v_1_17_1) {
|
||||
return packetConstructor.newInstance(getWindowId(), getStateId(), getSlot(), NMSUtils.toNMSItemStack(getItemStack()));
|
||||
return packetConstructor.newInstance(getWindowId(), getStateId().get(), getSlot(), NMSUtils.toNMSItemStack(getItemStack()));
|
||||
}
|
||||
else {
|
||||
return packetConstructor.newInstance(getWindowId(), getSlot(), NMSUtils.toNMSItemStack(getItemStack()));
|
||||
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
package io.github.retrooper.packetevents.packetwrappers.play.out.systemchat;
|
||||
|
||||
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
|
||||
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
|
||||
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.packetwrappers.api.SendableWrapper;
|
||||
import io.github.retrooper.packetevents.packetwrappers.play.out.chat.WrappedPacketOutChat;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
public class WrappedPacketOutSystemChat extends WrappedPacket implements SendableWrapper {
|
||||
private static Constructor<?> packetConstructor;
|
||||
private String message;
|
||||
private WrappedPacketOutChat.ChatPosition position;
|
||||
|
||||
public WrappedPacketOutSystemChat(final NMSPacket packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
public WrappedPacketOutSystemChat(String messageJSON, WrappedPacketOutChat.ChatPosition position) {
|
||||
this.message = messageJSON;
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void load() {
|
||||
try {
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_19_1)) {
|
||||
packetConstructor = PacketTypeClasses.Play.Server.SYSTEM_CHAT.getConstructor(String.class, boolean.class);
|
||||
}
|
||||
else {
|
||||
packetConstructor = PacketTypeClasses.Play.Server.SYSTEM_CHAT.getConstructor(String.class, int.class);
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public String getMessageJSON() {
|
||||
if (packet != null) {
|
||||
return readString(0);
|
||||
} else {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
public void setMessageJSON(String message) {
|
||||
if (packet != null) {
|
||||
writeString(0, message);
|
||||
} else {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public WrappedPacketOutChat.ChatPosition getPosition() {
|
||||
if (packet != null) {
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_19_1)) {
|
||||
return readBoolean(1) ? WrappedPacketOutChat.ChatPosition.GAME_INFO : WrappedPacketOutChat.ChatPosition.SYSTEM;
|
||||
}
|
||||
return WrappedPacketOutChat.ChatPosition.getById(version, readInt(0));
|
||||
}
|
||||
else {
|
||||
return position;
|
||||
}
|
||||
}
|
||||
|
||||
public void setPosition(WrappedPacketOutChat.ChatPosition position) {
|
||||
if (packet != null) {
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_19_1)) {
|
||||
writeBoolean(1, position == WrappedPacketOutChat.ChatPosition.GAME_INFO);
|
||||
return;
|
||||
}
|
||||
writeInt(0, position.ordinal());
|
||||
}
|
||||
else {
|
||||
this.position = position;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object asNMSPacket() throws Exception {
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_19_1)) {
|
||||
return packetConstructor.newInstance(getMessageJSON(), getPosition() == WrappedPacketOutChat.ChatPosition.GAME_INFO);
|
||||
|
||||
}
|
||||
else {
|
||||
return packetConstructor.newInstance(getMessageJSON(), getPosition().ordinal());
|
||||
}
|
||||
}
|
||||
}
|
||||
-1
@@ -35,7 +35,6 @@ import org.bukkit.event.player.PlayerLoginEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.world.ChunkLoadEvent;
|
||||
import org.bukkit.event.world.WorldLoadEvent;
|
||||
import org.spigotmc.AsyncCatcher;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.UUID;
|
||||
|
||||
+31
-9
@@ -24,8 +24,7 @@ import io.github.retrooper.packetevents.packettype.PacketState;
|
||||
import io.github.retrooper.packetevents.packettype.PacketType;
|
||||
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
|
||||
import io.github.retrooper.packetevents.packetwrappers.handshaking.setprotocol.WrappedPacketHandshakingInSetProtocol;
|
||||
import io.github.retrooper.packetevents.packetwrappers.login.in.start.WrappedPacketLoginInStart;
|
||||
import io.github.retrooper.packetevents.utils.gameprofile.WrappedGameProfile;
|
||||
import io.github.retrooper.packetevents.packetwrappers.login.out.success.WrappedPacketLoginOutSuccess;
|
||||
import io.github.retrooper.packetevents.utils.player.ClientVersion;
|
||||
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -90,12 +89,7 @@ public class PacketProcessorInternal {
|
||||
}
|
||||
break;
|
||||
case LOGIN:
|
||||
PacketLoginReceiveEvent loginEvent = new PacketLoginReceiveEvent(channel, new NMSPacket(packet));//Cache the channel
|
||||
if (loginEvent.getPacketId() == PacketType.Login.Client.START) {
|
||||
WrappedPacketLoginInStart startWrapper = new WrappedPacketLoginInStart(loginEvent.getNMSPacket());
|
||||
WrappedGameProfile gameProfile = startWrapper.getGameProfile();
|
||||
PacketEvents.get().getPlayerUtils().channels.put(gameProfile.getName(), channel);
|
||||
}
|
||||
PacketLoginReceiveEvent loginEvent = new PacketLoginReceiveEvent(channel, new NMSPacket(packet));
|
||||
PacketEvents.get().getEventManager().callEvent(loginEvent);
|
||||
packet = loginEvent.getNMSPacket().getRawNMSPacket();
|
||||
interceptLoginReceive(loginEvent);
|
||||
@@ -103,6 +97,14 @@ public class PacketProcessorInternal {
|
||||
packet = null;
|
||||
}
|
||||
break;
|
||||
case CONFIG:
|
||||
PacketConfigReceiveEvent configEvent = new PacketConfigReceiveEvent(channel, new NMSPacket(packet));
|
||||
PacketEvents.get().getEventManager().callEvent(configEvent);
|
||||
packet = configEvent.getNMSPacket().getRawNMSPacket();
|
||||
if (configEvent.isCancelled()) {
|
||||
packet = null;
|
||||
}
|
||||
break;
|
||||
case PLAY:
|
||||
PacketPlayReceiveEvent event = new PacketPlayReceiveEvent(player, channel, new NMSPacket(packet));
|
||||
PacketEvents.get().getEventManager().callEvent(event);
|
||||
@@ -148,6 +150,11 @@ public class PacketProcessorInternal {
|
||||
break;
|
||||
case LOGIN:
|
||||
PacketLoginSendEvent loginEvent = new PacketLoginSendEvent(channel, new NMSPacket(packet));
|
||||
if (loginEvent.getPacketId() == PacketType.Login.Server.SUCCESS) {
|
||||
WrappedPacketLoginOutSuccess success = new WrappedPacketLoginOutSuccess(loginEvent.getNMSPacket());
|
||||
String username = success.getGameProfile().getName();
|
||||
PacketEvents.get().getPlayerUtils().channels.put(username, channel); //Cache channel
|
||||
}
|
||||
PacketEvents.get().getEventManager().callEvent(loginEvent);
|
||||
if (loginEvent.isPostTaskAvailable()) {
|
||||
data.postAction = loginEvent.getPostTask();
|
||||
@@ -158,6 +165,17 @@ public class PacketProcessorInternal {
|
||||
packet = null;
|
||||
}
|
||||
break;
|
||||
case CONFIG:
|
||||
PacketConfigSendEvent configEvent = new PacketConfigSendEvent(channel, new NMSPacket(packet));
|
||||
PacketEvents.get().getEventManager().callEvent(configEvent);
|
||||
if (configEvent.isPostTaskAvailable()) {
|
||||
data.postAction = configEvent.getPostTask();
|
||||
}
|
||||
packet = configEvent.getNMSPacket().getRawNMSPacket();
|
||||
if (configEvent.isCancelled()) {
|
||||
packet = null;
|
||||
}
|
||||
break;
|
||||
case PLAY:
|
||||
PacketPlaySendEvent playEvent = new PacketPlaySendEvent(player, channel, new NMSPacket(packet));
|
||||
PacketEvents.get().getEventManager().callEvent(playEvent);
|
||||
@@ -324,7 +342,11 @@ public class PacketProcessorInternal {
|
||||
return PacketState.LOGIN;
|
||||
} else if (packetName.startsWith("PacketS")) {
|
||||
return PacketState.STATUS;
|
||||
} else {
|
||||
}
|
||||
else if (packet.getClass().getName().contains("protocol.common")) {
|
||||
return PacketState.CONFIG;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,6 +124,7 @@ public class PacketEventsSettings {
|
||||
* @param compatInjector Value
|
||||
* @return Settings instance.
|
||||
*/
|
||||
@Deprecated
|
||||
public PacketEventsSettings compatInjector(boolean compatInjector) {
|
||||
if (!locked) {
|
||||
this.compatInjector = compatInjector;
|
||||
@@ -175,6 +176,7 @@ public class PacketEventsSettings {
|
||||
*
|
||||
* @return Getter for {@link #compatInjector}
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean shouldUseCompatibilityInjector() {
|
||||
return compatInjector;
|
||||
}
|
||||
|
||||
-45
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2021 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.updatechecker;
|
||||
|
||||
import net.minecraft.util.com.google.gson.JsonObject;
|
||||
import net.minecraft.util.com.google.gson.JsonParser;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class LowLevelUpdateCheckerLegacy implements LowLevelUpdateChecker {
|
||||
@Override
|
||||
public String getLatestRelease() {
|
||||
String jsonResponse;
|
||||
try {
|
||||
jsonResponse = getLatestReleaseJson();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new IllegalStateException("Failed to parse packetevents version!");
|
||||
}
|
||||
|
||||
JsonParser parser = new JsonParser();
|
||||
JsonObject jsonObject = parser.parse(jsonResponse).getAsJsonObject();
|
||||
String versionName = null;
|
||||
if (jsonObject != null) {
|
||||
versionName = jsonObject.get("tag_name").getAsString();
|
||||
}
|
||||
return versionName;
|
||||
}
|
||||
}
|
||||
-45
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2021 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.updatechecker;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class LowLevelUpdateCheckerModern implements LowLevelUpdateChecker {
|
||||
@Override
|
||||
public String getLatestRelease() {
|
||||
String jsonResponse;
|
||||
try {
|
||||
jsonResponse = getLatestReleaseJson();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new IllegalStateException("Failed to parse packetevents version!");
|
||||
}
|
||||
|
||||
JsonParser parser = new JsonParser();
|
||||
JsonObject jsonObject = parser.parse(jsonResponse).getAsJsonObject();
|
||||
String versionName = null;
|
||||
if (jsonObject != null) {
|
||||
versionName = jsonObject.get("tag_name").getAsString();
|
||||
}
|
||||
return versionName;
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,6 @@
|
||||
package io.github.retrooper.packetevents.updatechecker;
|
||||
|
||||
import io.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
import io.github.retrooper.packetevents.utils.version.PEVersion;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
@@ -31,14 +30,10 @@ import org.bukkit.ChatColor;
|
||||
* @since 1.6.9
|
||||
*/
|
||||
public class UpdateChecker {
|
||||
private final LowLevelUpdateChecker lowLevelUpdateChecker;
|
||||
private final UpdaterCheck lowLevelUpdateChecker;
|
||||
|
||||
public UpdateChecker() {
|
||||
if (PacketEvents.get().getServerUtils().getVersion().isOlderThan(ServerVersion.v_1_8)) {
|
||||
lowLevelUpdateChecker = new LowLevelUpdateCheckerLegacy();
|
||||
} else {
|
||||
lowLevelUpdateChecker = new LowLevelUpdateCheckerModern();
|
||||
}
|
||||
lowLevelUpdateChecker = new UpdaterCheck();
|
||||
}
|
||||
|
||||
public String checkLatestReleasedVersion() {
|
||||
@@ -50,23 +45,26 @@ public class UpdateChecker {
|
||||
*/
|
||||
public UpdateCheckerStatus checkForUpdate() {
|
||||
PEVersion localVersion = PacketEvents.get().getVersion();
|
||||
PEVersion newVersion;
|
||||
try {
|
||||
newVersion = new PEVersion(checkLatestReleasedVersion());
|
||||
} catch (Exception ex) {
|
||||
newVersion = null;
|
||||
|
||||
String version = checkLatestReleasedVersion();
|
||||
|
||||
if (version == null) {
|
||||
return UpdateCheckerStatus.FAILED;
|
||||
}
|
||||
if (newVersion != null && localVersion.isOlderThan(newVersion)) {
|
||||
inform("There is an update available for the PacketEvents API! Your build: (" + localVersion.toString() + ") | Latest released build: (" + newVersion.toString() + ")");
|
||||
|
||||
PEVersion newVersion = new PEVersion(checkLatestReleasedVersion());
|
||||
|
||||
if (localVersion.isOlderThan(newVersion)) {
|
||||
inform("There is an update available for the PacketEvents API! Your build: (" + localVersion + ") | Latest released build: (" + newVersion + ")");
|
||||
return UpdateCheckerStatus.OUTDATED;
|
||||
} else if (newVersion != null && localVersion.isNewerThan(newVersion)) {
|
||||
inform("You are on a dev or pre released build of PacketEvents. Your build: (" + localVersion.toString() + ") | Latest released build: (" + newVersion.toString() + ")");
|
||||
} else if (localVersion.isNewerThan(newVersion)) {
|
||||
inform("You are on a dev or pre released build of PacketEvents. Your build: (" + localVersion + ") | Latest released build: (" + newVersion + ")");
|
||||
return UpdateCheckerStatus.PRE_RELEASE;
|
||||
} else if (localVersion.equals(newVersion)) {
|
||||
inform("You are on the latest released version of PacketEvents. (" + newVersion.toString() + ")");
|
||||
inform("You are on the latest released version of PacketEvents. (" + newVersion + ")");
|
||||
return UpdateCheckerStatus.UP_TO_DATE;
|
||||
} else {
|
||||
report("Something went wrong while checking for an update. Your build: (" + localVersion.toString() + ") | Latest released build: (" + newVersion.toString() + ")");
|
||||
report("Something went wrong while checking for an update. Your build: (" + localVersion + ") | Latest released build: (" + newVersion + ")");
|
||||
return UpdateCheckerStatus.FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
+16
-3
@@ -24,10 +24,23 @@ import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
|
||||
public interface LowLevelUpdateChecker {
|
||||
String getLatestRelease();
|
||||
public class UpdaterCheck {
|
||||
public String getLatestRelease() {
|
||||
try {
|
||||
String jsonResponse = getLatestReleaseJson();
|
||||
|
||||
default String getLatestReleaseJson() throws IOException {
|
||||
String targetPart = "\"name\":";
|
||||
int nameIndex = jsonResponse.indexOf(targetPart);
|
||||
|
||||
int stringStart = nameIndex + targetPart.length();
|
||||
int stringEnd = jsonResponse.indexOf(",", stringStart);
|
||||
return jsonResponse.substring(stringStart + 1, stringEnd - 1);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private String getLatestReleaseJson() throws IOException {
|
||||
URLConnection connection = new URL("https://api.github.com/repos/retrooper/packetevents/releases/latest").openConnection();
|
||||
connection.addRequestProperty("User-Agent", "Mozilla/4.0");
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||
@@ -0,0 +1,32 @@
|
||||
package io.github.retrooper.packetevents.utils;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class ConditionalValue<T, K> {
|
||||
private final Optional<T> left;
|
||||
private final Optional<K> right;
|
||||
private ConditionalValue(Optional<T> left, Optional<K> right) {
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
}
|
||||
public Optional<T> left() {
|
||||
return left;
|
||||
}
|
||||
public Optional<K> right() {
|
||||
return right;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return left.map(t -> "ConditionalValue {left: " + t.toString() + "}")
|
||||
.orElseGet(() -> "ConditionalValue {right: " + right.get().toString() + "}");
|
||||
}
|
||||
|
||||
public static <L, R> ConditionalValue<L, R> makeLeft(L left) {
|
||||
return new ConditionalValue<>(Optional.of(left), Optional.empty());
|
||||
}
|
||||
|
||||
public static <L, R> ConditionalValue<L, R> makeRight(R right) {
|
||||
return new ConditionalValue<>(Optional.empty(), Optional.of(right));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package io.github.retrooper.packetevents.utils;
|
||||
|
||||
import com.mojang.datafixers.util.Either;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class MojangEitherUtil {
|
||||
public static <L, R> Either<L, R> makeLeft(L left) {
|
||||
return Either.left(left);
|
||||
}
|
||||
|
||||
public static <L, R> Either<L, R> makeRight(R right) {
|
||||
return Either.right(right);
|
||||
}
|
||||
|
||||
public static <L> Optional<L> getLeft(Object either) {
|
||||
return ((Either)either).left();
|
||||
}
|
||||
|
||||
public static <R> Optional<R> getRight(Object either) {
|
||||
return ((Either)either).right();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* This file is part of packetevents - https://github.com/retrooper/packetevents
|
||||
* Copyright (C) 2021 retrooper and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.github.retrooper.packetevents.utils;
|
||||
|
||||
public class SaltSignature {
|
||||
private final long salt;
|
||||
private final byte[] signature;
|
||||
|
||||
public SaltSignature(long salt, byte[] signature) {
|
||||
this.salt = salt;
|
||||
this.signature = signature;
|
||||
}
|
||||
|
||||
public long getSalt() {
|
||||
return salt;
|
||||
}
|
||||
|
||||
public byte[] getSignature() {
|
||||
return signature;
|
||||
}
|
||||
}
|
||||
+1
@@ -101,6 +101,7 @@ public class AttributeModifierWrapper extends WrappedPacket {
|
||||
}
|
||||
}
|
||||
|
||||
//TODO Might cause issues since now a resourcelocation
|
||||
public String getName() {
|
||||
if (supplierPresent) {
|
||||
//About 1.13 and above
|
||||
|
||||
+43
-3
@@ -24,6 +24,7 @@ import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
|
||||
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
@@ -40,6 +41,11 @@ public class AttributeSnapshotWrapper extends WrappedPacket {
|
||||
private static Class<?> attributeSnapshotClass, attributeBaseClass;
|
||||
private static Field iRegistryAttributeBaseField;
|
||||
private static Method getiRegistryByMinecraftKeyMethod;
|
||||
private static Method readStringMethod;
|
||||
|
||||
private static Class<?> holderClass;
|
||||
private static Method accessHolderValueMethod;
|
||||
private static boolean hasHolder = false;
|
||||
private static boolean stringKeyPresent;
|
||||
|
||||
public AttributeSnapshotWrapper(NMSPacket packet) {
|
||||
@@ -58,6 +64,11 @@ public class AttributeSnapshotWrapper extends WrappedPacket {
|
||||
attributeSnapshotClass = SubclassUtil.getSubClass(PacketTypeClasses.Play.Server.UPDATE_ATTRIBUTES, "AttributeSnapshot");
|
||||
}
|
||||
}
|
||||
|
||||
holderClass = NMSUtils.getNMClassWithoutException("core.Holder");
|
||||
if (holderClass != null) {
|
||||
hasHolder = Reflection.getField(attributeSnapshotClass, holderClass, 0) != null;
|
||||
}
|
||||
if (attributeSnapshotConstructor == null) {
|
||||
try {
|
||||
attributeSnapshotConstructor = attributeSnapshotClass.getConstructor(PacketTypeClasses.Play.Server.UPDATE_ATTRIBUTES, String.class, double.class, Collection.class);
|
||||
@@ -135,6 +146,11 @@ public class AttributeSnapshotWrapper extends WrappedPacket {
|
||||
}
|
||||
}
|
||||
|
||||
holderClass = NMSUtils.getNMClassWithoutException("core.Holder");
|
||||
if (holderClass != null) {
|
||||
hasHolder = Reflection.getField(attributeSnapshotClass, holderClass, 0) != null;
|
||||
}
|
||||
|
||||
if (attributeSnapshotConstructor == null) {
|
||||
try {
|
||||
attributeSnapshotConstructor = attributeSnapshotClass.getConstructor(attributeBaseClass, double.class, Collection.class);
|
||||
@@ -160,9 +176,33 @@ public class AttributeSnapshotWrapper extends WrappedPacket {
|
||||
if (stringKeyPresent) {
|
||||
return readString(0);
|
||||
} else {
|
||||
Object attributeBase = readObject(0, attributeBaseClass);
|
||||
WrappedPacket attributeBaseWrapper = new WrappedPacket(new NMSPacket(attributeBase), attributeBaseClass);
|
||||
return attributeBaseWrapper.readString(0);
|
||||
Object attributeBase = null;
|
||||
if (hasHolder) {
|
||||
Object holder = readObject(0, holderClass);
|
||||
if (accessHolderValueMethod == null) {
|
||||
accessHolderValueMethod = Reflection.getMethod(holderClass, 0);
|
||||
}
|
||||
try {
|
||||
attributeBase = accessHolderValueMethod.invoke(holder);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
attributeBase = readObject(0, attributeBaseClass);
|
||||
}
|
||||
if (version.isNewerThanOrEquals(ServerVersion.v_1_21)) {
|
||||
if (readStringMethod== null) {
|
||||
readStringMethod = Reflection.getMethod(attributeBaseClass, String.class, 0);
|
||||
}
|
||||
try {
|
||||
return (String) readStringMethod.invoke(attributeBase);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else {
|
||||
WrappedPacket attributeBaseWrapper = new WrappedPacket(new NMSPacket(attributeBase), attributeBaseClass);
|
||||
return attributeBaseWrapper.readString(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,12 +18,50 @@
|
||||
|
||||
package io.github.retrooper.packetevents.utils.geyser;
|
||||
|
||||
import org.geysermc.connector.GeyserConnector;
|
||||
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.UUID;
|
||||
|
||||
public class GeyserUtils {
|
||||
private static Class<?> GEYSER_CLASS;
|
||||
private static Class<?> GEYSER_API_CLASS;
|
||||
private static Method GEYSER_API_METHOD;
|
||||
private static Method CONNECTION_BY_UUID_METHOD;
|
||||
|
||||
public static boolean isGeyserPlayer(UUID uuid) {
|
||||
return GeyserConnector.getInstance().getPlayerByUuid(uuid) != null;
|
||||
if (GEYSER_CLASS == null) {
|
||||
GEYSER_CLASS = Reflection.getClassByNameWithoutException("org.geysermc.api.Geyser");
|
||||
}
|
||||
if (GEYSER_CLASS == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GEYSER_API_CLASS == null) {
|
||||
GEYSER_API_CLASS = Reflection.getClassByNameWithoutException("org.geysermc.api.GeyserApiBase");
|
||||
}
|
||||
if (GEYSER_API_METHOD == null) {
|
||||
GEYSER_API_METHOD = Reflection.getMethod(GEYSER_CLASS, "api", null, new Class<?>[]{});
|
||||
}
|
||||
if (CONNECTION_BY_UUID_METHOD == null) {
|
||||
CONNECTION_BY_UUID_METHOD = Reflection.getMethod(GEYSER_API_CLASS, "connectionByUuid", 0);
|
||||
}
|
||||
Object apiInstance = null;
|
||||
try {
|
||||
apiInstance = GEYSER_API_METHOD.invoke(null);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Object connection = null;
|
||||
try {
|
||||
if (apiInstance != null) {
|
||||
connection = CONNECTION_BY_UUID_METHOD.invoke(apiInstance, uuid);
|
||||
}
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return connection != null;
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,8 @@ package io.github.retrooper.packetevents.utils.netty.bytebuf;
|
||||
|
||||
public interface ByteBufUtil {
|
||||
|
||||
Object buffer();
|
||||
|
||||
Object newByteBuf(byte[] data);
|
||||
|
||||
void retain(Object byteBuf);
|
||||
|
||||
@@ -24,6 +24,11 @@ import net.minecraft.util.io.netty.util.internal.EmptyArrays;
|
||||
|
||||
public final class ByteBufUtil_7 implements ByteBufUtil {
|
||||
|
||||
@Override
|
||||
public Object buffer() {
|
||||
return Unpooled.buffer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object newByteBuf(byte[] data) {
|
||||
return Unpooled.wrappedBuffer(data);
|
||||
|
||||
@@ -24,6 +24,11 @@ import io.netty.util.internal.EmptyArrays;
|
||||
|
||||
public final class ByteBufUtil_8 implements ByteBufUtil {
|
||||
|
||||
@Override
|
||||
public Object buffer() {
|
||||
return Unpooled.buffer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object newByteBuf(byte[] data) {
|
||||
return Unpooled.wrappedBuffer(data);
|
||||
|
||||
@@ -21,6 +21,7 @@ package io.github.retrooper.packetevents.utils.nms;
|
||||
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.reflection.ClassUtil;
|
||||
import io.github.retrooper.packetevents.utils.reflection.Reflection;
|
||||
import io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
|
||||
import io.github.retrooper.packetevents.utils.server.ServerVersion;
|
||||
@@ -33,35 +34,33 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public final class NMSUtils {
|
||||
public static final String NMS_DIR = ServerVersion.getNMSDirectory() + ".";
|
||||
public static final String OBC_DIR = ServerVersion.getOBCDirectory() + ".";
|
||||
private static final ThreadLocal<Random> randomThreadLocal = ThreadLocal.withInitial(Random::new);
|
||||
public static boolean legacyNettyImportMode;
|
||||
public static ServerVersion version;
|
||||
public static Constructor<?> blockPosConstructor, minecraftKeyConstructor, vec3DConstructor, dataWatcherConstructor, packetDataSerializerConstructor, itemStackConstructor;
|
||||
public static Class<?> mobEffectListClass, nmsEntityClass, minecraftServerClass, craftWorldClass, playerInteractManagerClass, entityPlayerClass, playerConnectionClass, craftServerClass,
|
||||
public static Executable minecraftKeyConstructorOrMethod;
|
||||
public static Constructor<?> blockPosConstructor, vec3DConstructor, dataWatcherConstructor, packetDataSerializerConstructor, itemStackConstructor;
|
||||
public static Class<?> mobEffectListClass, nmsEntityClass, minecraftServerClass, craftWorldClass, playerInteractManagerClass, entityPlayerClass, playerConnectionClass, SERVER_COMMON_PACKETLISTENER_IMPL_CLASS, craftServerClass,
|
||||
craftPlayerClass, serverConnectionClass, craftEntityClass, nmsItemStackClass, networkManagerClass, nettyChannelClass, gameProfileClass, iChatBaseComponentClass,
|
||||
blockPosClass, sectionPositionClass, vec3DClass, channelFutureClass, blockClass, iBlockDataClass, nmsWorldClass, craftItemStackClass,
|
||||
soundEffectClass, minecraftKeyClass, chatSerializerClass, craftMagicNumbersClass, worldSettingsClass, worldServerClass, dataWatcherClass,
|
||||
dedicatedServerClass, entityHumanClass, packetDataSerializerClass, byteBufClass, dimensionManagerClass, nmsItemClass, iMaterialClass, movingObjectPositionBlockClass, boundingBoxClass,
|
||||
tileEntityCommandClass;
|
||||
tileEntityCommandClass, mojangEitherClass, registryMaterials, builtInRegistriesClass;
|
||||
public static Class<? extends Enum<?>> enumDirectionClass, enumHandClass, enumGameModeClass, enumDifficultyClass, tileEntityCommandTypeClass;
|
||||
public static Method getBlockPosX, getBlockPosY, getBlockPosZ;
|
||||
public static Method getBlockPosX, getBlockPosY, getBlockPosZ, mojangEitherLeft, mojangEitherRight, getRegistryId, getRegistryById;
|
||||
private static String nettyPrefix;
|
||||
private static Method getCraftPlayerHandle, getCraftEntityHandle, getCraftWorldHandle, asBukkitCopy,
|
||||
asNMSCopy, getMessageMethod, chatFromStringMethod, getMaterialFromNMSBlock, getNMSBlockFromMaterial,
|
||||
getMobEffectListId, getMobEffectListById, getItemId, getItemById, getBukkitEntity;
|
||||
private static Field entityPlayerPingField, entityBoundingBoxField;
|
||||
private static Field entityPlayerPingField, entityBoundingBoxField, mobEffectsRegistryField;
|
||||
public static Field getBaseBlockPosX, getBaseBlockPosY, getBaseBlockPosZ;
|
||||
private static Object minecraftServer;
|
||||
private static Object minecraftServerConnection;
|
||||
|
||||
@@ -133,6 +132,8 @@ public final class NMSUtils {
|
||||
playerConnectionClass = getNMSClassWithoutException("PlayerConnection");
|
||||
if (playerConnectionClass == null) {
|
||||
playerConnectionClass = getNMClassWithoutException("server.network.PlayerConnection");
|
||||
//Only for 1.20.2
|
||||
SERVER_COMMON_PACKETLISTENER_IMPL_CLASS = getNMClassWithoutException("server.network.ServerCommonPacketListenerImpl");
|
||||
}
|
||||
serverConnectionClass = getNMSClassWithoutException("ServerConnection");
|
||||
if (serverConnectionClass == null) {
|
||||
@@ -182,6 +183,9 @@ public final class NMSUtils {
|
||||
dataWatcherClass = getNMSClassWithoutException("DataWatcher");
|
||||
if (dataWatcherClass == null) {
|
||||
dataWatcherClass = getNMClassWithoutException("network.syncher.DataWatcher");
|
||||
if (dataWatcherClass == null) {
|
||||
dataWatcherClass = getNMClassWithoutException("network.syncher.SynchedEntityData");
|
||||
}
|
||||
}
|
||||
nmsItemClass = getNMSClassWithoutException("Item");
|
||||
if (nmsItemClass == null) {
|
||||
@@ -222,6 +226,9 @@ public final class NMSUtils {
|
||||
iChatBaseComponentClass = NMSUtils.getNMSClassWithoutException("IChatBaseComponent");
|
||||
if (iChatBaseComponentClass == null) {
|
||||
iChatBaseComponentClass = getNMClassWithoutException("network.chat.IChatBaseComponent");
|
||||
if (iChatBaseComponentClass == null) {
|
||||
iChatBaseComponentClass = getNMClassWithoutException("network.chat.Component");
|
||||
}
|
||||
}
|
||||
|
||||
tileEntityCommandClass = NMSUtils.getNMSClassWithoutException("TileEntityCommand");
|
||||
@@ -231,6 +238,37 @@ public final class NMSUtils {
|
||||
|
||||
tileEntityCommandTypeClass = SubclassUtil.getEnumSubClass(tileEntityCommandClass, 0);
|
||||
|
||||
//Isn't present on every version
|
||||
mojangEitherClass = Reflection.getClassByNameWithoutException("com.mojang.datafixers.util.Either");
|
||||
|
||||
registryMaterials = Reflection.getClassByNameWithoutException("net.minecraft.core.RegistryMaterials");
|
||||
|
||||
builtInRegistriesClass = Reflection.getClassByNameWithoutException("net.minecraft.core.registries.BuiltInRegistries");
|
||||
|
||||
if (builtInRegistriesClass != null) {
|
||||
mobEffectsRegistryField = Reflection.getField(builtInRegistriesClass, "e");
|
||||
|
||||
for (Field f : Reflection.getFields(builtInRegistriesClass)) {
|
||||
Type type = f.getGenericType();
|
||||
if (type instanceof ParameterizedType) {
|
||||
ParameterizedType pType = (ParameterizedType) type;
|
||||
if (pType.getActualTypeArguments()[0].equals(mobEffectListClass)) {
|
||||
mobEffectsRegistryField = f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Class<?> baseBlockPosClass = NMSUtils.getNMSClassWithoutException("BaseBlockPosition");
|
||||
if (baseBlockPosClass == null) {
|
||||
baseBlockPosClass = getNMClassWithoutException("core.BaseBlockPosition");
|
||||
}
|
||||
if (baseBlockPosClass != null) {
|
||||
getBaseBlockPosX = Reflection.getField(baseBlockPosClass, int.class, 0);
|
||||
getBaseBlockPosY = Reflection.getField(baseBlockPosClass, int.class, 1);
|
||||
getBaseBlockPosZ = Reflection.getField(baseBlockPosClass, int.class, 2);
|
||||
}
|
||||
vec3DClass = NMSUtils.getNMSClassWithoutException("Vec3D");
|
||||
if (vec3DClass == null) {
|
||||
vec3DClass = getNMClassWithoutException("world.phys.Vec3D");
|
||||
@@ -266,7 +304,11 @@ public final class NMSUtils {
|
||||
}
|
||||
|
||||
if (dataWatcherClass != null) {
|
||||
dataWatcherConstructor = dataWatcherClass.getConstructor(nmsEntityClass);
|
||||
try {
|
||||
dataWatcherConstructor = dataWatcherClass.getConstructor(nmsEntityClass);
|
||||
} catch (Exception ex) {
|
||||
dataWatcherConstructor = dataWatcherClass.getDeclaredConstructors()[0];
|
||||
}
|
||||
}
|
||||
|
||||
if (nmsItemStackClass != null && iMaterialClass != null) {
|
||||
@@ -309,6 +351,9 @@ public final class NMSUtils {
|
||||
} catch (ClassNotFoundException e) {
|
||||
//That is fine, it is probably a subclass
|
||||
chatSerializerClass = SubclassUtil.getSubClass(iChatBaseComponentClass, "ChatSerializer");
|
||||
if (chatSerializerClass == null) {
|
||||
chatSerializerClass = SubclassUtil.getSubClass(iChatBaseComponentClass, "Serializer");
|
||||
}
|
||||
}
|
||||
craftMagicNumbersClass = NMSUtils.getOBCClass("util.CraftMagicNumbers");
|
||||
|
||||
@@ -318,7 +363,12 @@ public final class NMSUtils {
|
||||
getNMSBlockFromMaterial = Reflection.getMethod(craftMagicNumbersClass, "getBlock", NMSUtils.blockClass, Material.class);
|
||||
|
||||
if (minecraftKeyClass != null) {
|
||||
minecraftKeyConstructor = minecraftKeyClass.getConstructor(String.class);
|
||||
try {
|
||||
minecraftKeyConstructorOrMethod = minecraftKeyClass.getConstructor(String.class);
|
||||
} catch (Exception ex) {
|
||||
minecraftKeyConstructorOrMethod = Reflection.getMethod(minecraftKeyClass, 0, String.class, char.class);
|
||||
}
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@@ -345,6 +395,9 @@ public final class NMSUtils {
|
||||
// Mappings changed with 1.18
|
||||
if (getBlockPosX == null) {
|
||||
getBlockPosX = Reflection.getMethod(NMSUtils.blockPosClass, "u", int.class);
|
||||
if (getBlockPosX == null) {
|
||||
|
||||
}
|
||||
}
|
||||
if (getBlockPosY == null) {
|
||||
getBlockPosY = Reflection.getMethod(NMSUtils.blockPosClass, "v", int.class);
|
||||
@@ -353,6 +406,17 @@ public final class NMSUtils {
|
||||
getBlockPosZ = Reflection.getMethod(NMSUtils.blockPosClass, "w", int.class);
|
||||
}
|
||||
}
|
||||
|
||||
if (mojangEitherClass != null) {
|
||||
mojangEitherLeft = Reflection.getMethod(mojangEitherClass, "left", Optional.class);
|
||||
mojangEitherRight = Reflection.getMethod(mojangEitherClass, "right", Optional.class);
|
||||
}
|
||||
|
||||
if (registryMaterials != null) {
|
||||
getRegistryId = Reflection.getMethod(registryMaterials, int.class, 0, 1);
|
||||
getRegistryById = Reflection.getMethod(registryMaterials, Optional.class, true, 0, int.class);
|
||||
}
|
||||
|
||||
worldSettingsClass = NMSUtils.getNMSClassWithoutException("WorldSettings");
|
||||
if (worldServerClass == null) {
|
||||
worldServerClass = getNMClassWithoutException("world.level.WorldSettings");
|
||||
@@ -379,8 +443,13 @@ public final class NMSUtils {
|
||||
public static Object getMinecraftServerInstance(Server server) {
|
||||
if (minecraftServer == null) {
|
||||
try {
|
||||
minecraftServer = Reflection.getField(craftServerClass, minecraftServerClass, 0)
|
||||
.get(server);
|
||||
Field f = Reflection.getField(craftServerClass, minecraftServerClass, 0);
|
||||
if (f == null) {
|
||||
//1.20.5 way
|
||||
minecraftServer = Reflection.getField(minecraftServerClass, minecraftServerClass, 0).get(null);
|
||||
} else {
|
||||
minecraftServer = f.get(server);
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -407,7 +476,7 @@ public final class NMSUtils {
|
||||
}
|
||||
|
||||
public static Class<?> getNMSClass(String name) throws ClassNotFoundException {
|
||||
return Class.forName(NMS_DIR + name);
|
||||
return Class.forName(ServerVersion.getNMSDirectory() + name);
|
||||
}
|
||||
|
||||
public static Class<?> getNMClass(String name) throws ClassNotFoundException {
|
||||
@@ -431,7 +500,7 @@ public final class NMSUtils {
|
||||
}
|
||||
|
||||
public static Class<? extends Enum<?>> getNMSEnumClass(String name) throws ClassNotFoundException {
|
||||
return (Class<? extends Enum<?>>) Class.forName(NMS_DIR + name);
|
||||
return (Class<? extends Enum<?>>) Class.forName(ServerVersion.getNMSDirectory() + name);
|
||||
}
|
||||
|
||||
public static Class<? extends Enum<?>> getNMSEnumClassWithoutException(String name) {
|
||||
@@ -452,7 +521,7 @@ public final class NMSUtils {
|
||||
}
|
||||
|
||||
public static Class<?> getOBCClass(String name) throws ClassNotFoundException {
|
||||
return Class.forName(OBC_DIR + name);
|
||||
return Class.forName(ServerVersion.getOBCDirectory() + name);
|
||||
}
|
||||
|
||||
public static Class<?> getNettyClass(String name) throws ClassNotFoundException {
|
||||
@@ -510,10 +579,18 @@ public final class NMSUtils {
|
||||
|
||||
public static Object getPlayerConnection(final Player player) {
|
||||
Object entityPlayer = getEntityPlayer(player);
|
||||
if (entityPlayer == null) {
|
||||
Class<?> entityPlayerClass = entityPlayer != null ? entityPlayer.getClass() : null;
|
||||
String className = entityPlayer != null ? ClassUtil.getClassSimpleName(entityPlayerClass) : "";
|
||||
if (entityPlayer == null
|
||||
|| className.contains("Fake")) {
|
||||
return null;
|
||||
}
|
||||
WrappedPacket wrappedEntityPlayer = new WrappedPacket(new NMSPacket(entityPlayer));
|
||||
//If we need to get the superclass, we get it
|
||||
if (!className.equals("EntityPlayer")
|
||||
&& ClassUtil.getClassSimpleName(entityPlayerClass.getSuperclass()).equals("EntityPlayer")) {
|
||||
entityPlayerClass = entityPlayerClass.getSuperclass();
|
||||
}
|
||||
WrappedPacket wrappedEntityPlayer = new WrappedPacket(new NMSPacket(entityPlayer), entityPlayerClass);
|
||||
return wrappedEntityPlayer.readObject(0, NMSUtils.playerConnectionClass);
|
||||
}
|
||||
|
||||
@@ -528,7 +605,8 @@ public final class NMSUtils {
|
||||
if (playerConnection == null) {
|
||||
return null;
|
||||
}
|
||||
WrappedPacket wrapper = new WrappedPacket(new NMSPacket(playerConnection), playerConnectionClass);
|
||||
Class<?> playerConClass = SERVER_COMMON_PACKETLISTENER_IMPL_CLASS != null ? SERVER_COMMON_PACKETLISTENER_IMPL_CLASS : playerConnectionClass;
|
||||
WrappedPacket wrapper = new WrappedPacket(new NMSPacket(playerConnection), playerConClass);
|
||||
try {
|
||||
return wrapper.readObject(0, networkManagerClass);
|
||||
} catch (Exception ex) {
|
||||
@@ -537,11 +615,17 @@ public final class NMSUtils {
|
||||
return wrapper.readObject(0, networkManagerClass);
|
||||
} catch (Exception ex2) {
|
||||
//Support for some custom plugins.
|
||||
playerConnection = wrapper.read(0, playerConnectionClass);
|
||||
wrapper = new WrappedPacket(new NMSPacket(playerConnection), playerConnectionClass);
|
||||
return wrapper.readObject(0, networkManagerClass);
|
||||
try {
|
||||
playerConnection = wrapper.read(0, playerConnectionClass);
|
||||
wrapper = new WrappedPacket(new NMSPacket(playerConnection), playerConnectionClass);
|
||||
return wrapper.readObject(0, networkManagerClass);
|
||||
} catch (Exception ex3) {
|
||||
//Print the original exception!
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Object getChannel(final Player player) {
|
||||
@@ -700,7 +784,12 @@ public final class NMSUtils {
|
||||
|
||||
public static Object generateMinecraftKeyNew(String text) {
|
||||
try {
|
||||
return minecraftKeyConstructor.newInstance(text);
|
||||
if (minecraftKeyConstructorOrMethod instanceof Constructor<?>) {
|
||||
return ((Constructor<?>)minecraftKeyConstructorOrMethod).newInstance(text);
|
||||
}
|
||||
else {
|
||||
return ((Method)minecraftKeyConstructorOrMethod).invoke(text, ':');
|
||||
}
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -744,7 +833,11 @@ public final class NMSUtils {
|
||||
|
||||
public static Object generateDataWatcher(Object nmsEntity) {
|
||||
try {
|
||||
return dataWatcherConstructor.newInstance(nmsEntity);
|
||||
if (dataWatcherConstructor.getParameterCount() == 2) {
|
||||
return dataWatcherConstructor.newInstance(nmsEntity, null);
|
||||
} else {
|
||||
return dataWatcherConstructor.newInstance(nmsEntity);
|
||||
}
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -780,6 +873,11 @@ public final class NMSUtils {
|
||||
|
||||
public static int getEffectId(Object nmsMobEffectList) {
|
||||
try {
|
||||
//1.20.2+
|
||||
if (getMobEffectListId == null) {
|
||||
Object registry = mobEffectsRegistryField.get(null);
|
||||
return (int) getRegistryId.invoke(registry, nmsMobEffectList);
|
||||
}
|
||||
return (int) getMobEffectListId.invoke(null, nmsMobEffectList);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
@@ -789,6 +887,10 @@ public final class NMSUtils {
|
||||
|
||||
public static Object getMobEffectListById(int effectID) {
|
||||
try {
|
||||
if (getMobEffectListById == null) {
|
||||
Object registry = mobEffectsRegistryField.get(null);
|
||||
return getRegistryById.invoke(registry, effectID);
|
||||
}
|
||||
return getMobEffectListById.invoke(null, effectID);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
@@ -822,4 +924,22 @@ public final class NMSUtils {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Optional<Object> getEitherLeft(Object either) {
|
||||
try {
|
||||
return (Optional<Object>) mojangEitherLeft.invoke(either);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Optional<Object> getEitherRight(Object either) {
|
||||
try {
|
||||
return (Optional<Object>) mojangEitherRight.invoke(either);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -196,7 +196,7 @@ public class NPC {
|
||||
if (dist > 8) {
|
||||
sentPacket = new WrappedPacketOutEntityTeleport(entityID, position, yaw, pitch, onGround);
|
||||
} else {
|
||||
sentPacket = new WrappedPacketOutEntity.WrappedPacketOutRelEntityMoveLook(entityID, distX, distY, distZ, (byte) yaw, (byte) pitch, onGround);
|
||||
sentPacket = new WrappedPacketOutEntity.WrappedPacketOutRelEntityMoveLook(entityID, distX, distY, distZ, yaw, pitch, onGround);
|
||||
}
|
||||
if (hasSpawned(player)) {
|
||||
PacketEvents.get().getPlayerUtils().sendPacket(player, sentPacket);
|
||||
@@ -256,7 +256,7 @@ public class NPC {
|
||||
if (dist > 8) {
|
||||
sentPacket = new WrappedPacketOutEntityTeleport(entityID, position, yaw, pitch, onGround);
|
||||
} else {
|
||||
sentPacket = new WrappedPacketOutEntity.WrappedPacketOutRelEntityMoveLook(entityID, distX, distY, distZ, (byte) yaw, (byte) pitch, onGround);
|
||||
sentPacket = new WrappedPacketOutEntity.WrappedPacketOutRelEntityMoveLook(entityID, distX, distY, distZ, yaw, pitch, onGround);
|
||||
}
|
||||
for (Player player : players) {
|
||||
if (hasSpawned(player)) {
|
||||
@@ -290,7 +290,7 @@ public class NPC {
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void moveDeltaAndRotate(List<Player> players, Vector3d deltaPosition, byte yaw, byte pitch) {
|
||||
public void moveDeltaAndRotate(List<Player> players, Vector3d deltaPosition, float yaw, float pitch) {
|
||||
this.position = this.position.add(deltaPosition);
|
||||
this.yaw = yaw;
|
||||
this.pitch = pitch;
|
||||
|
||||
@@ -92,8 +92,21 @@ public enum ClientVersion {
|
||||
*/
|
||||
v_1_18(757),
|
||||
|
||||
v_1_18_2(758),
|
||||
|
||||
v_1_19(759), v_1_19_1(760), v_1_19_3(761), v_1_19_4(762),
|
||||
/**
|
||||
* 1.20.3 and 1.20.4 have the same protocol version.
|
||||
* 1.20.5 and 1.20.6 have the same protocol version.
|
||||
*/
|
||||
v_1_20(763), v_1_20_2(764), v_1_20_3(765), v_1_20_5(766),
|
||||
|
||||
v_1_21(767),
|
||||
//TODO Update(checkpoint for things to look out for when updating)
|
||||
|
||||
LOWER_THAN_SUPPORTED_VERSIONS(v_1_7_10.protocolVersion - 1),
|
||||
HIGHER_THAN_SUPPORTED_VERSIONS(v_1_18.protocolVersion + 1),
|
||||
//TODO Update(checkpoint for things to look out for when updating)
|
||||
HIGHER_THAN_SUPPORTED_VERSIONS(v_1_21.protocolVersion + 1),
|
||||
/**
|
||||
* Pre releases just aren't supported, we would end up with so many enum constants.
|
||||
* This constant assures you they are on a pre-release.
|
||||
@@ -111,8 +124,10 @@ public enum ClientVersion {
|
||||
private static final int HIGHEST_SUPPORTED_PROTOCOL_VERSION = HIGHER_THAN_SUPPORTED_VERSIONS.protocolVersion - 1;
|
||||
|
||||
private static final Map<Integer, ClientVersion> CLIENT_VERSION_CACHE = new IdentityHashMap<>();
|
||||
//TODO Update(checkpoint for things to look out for when updating)
|
||||
private static final int[] CLIENT_VERSIONS = new int[]{5, 47, 107, 108, 109, 110, 210, 315, 316, 335, 338,
|
||||
340, 393, 401, 404, 477, 480, 485, 490, 498, 573, 575, 578, 735, 736, 751, 753, 754, 755, 756, 757};
|
||||
340, 393, 401, 404, 477, 480, 485, 490, 498, 573,
|
||||
575, 578, 735, 736, 751, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767};
|
||||
private int protocolVersion;
|
||||
|
||||
ClientVersion(int protocolVersion) {
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Map;
|
||||
@@ -275,6 +276,7 @@ public final class PlayerUtils {
|
||||
return GameProfileUtil.getGameProfileSkin(gameProfile);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Object getChannel(Player player) {
|
||||
String name = player.getName();
|
||||
Object channel = channels.get(name);
|
||||
|
||||
@@ -139,6 +139,23 @@ public final class Reflection {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Method getMethod(Class<?> cls, Class<?> returning, boolean checkIfIsNotReturnType, int index, Class<?>... params) {
|
||||
int currentIndex = 0;
|
||||
for (Method m : cls.getDeclaredMethods()) {
|
||||
boolean isReturnType = returning == null || m.getReturnType().equals(returning);
|
||||
if (Arrays.equals(m.getParameterTypes(), params)
|
||||
&& (checkIfIsNotReturnType ? !isReturnType : isReturnType)
|
||||
&& index == currentIndex++) {
|
||||
m.setAccessible(true);
|
||||
return m;
|
||||
}
|
||||
}
|
||||
if (cls.getSuperclass() != null) {
|
||||
return getMethod(cls.getSuperclass(), null, index, params);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Method getMethod(final Class<?> cls, final String name, Class<?> returning, Class<?>... params) {
|
||||
for (final Method m : cls.getDeclaredMethods()) {
|
||||
if (m.getName().equals(name)
|
||||
@@ -188,6 +205,24 @@ public final class Reflection {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Method getMethod(final Class<?> cls, final Class<?> returning, final int index, int amountOfArguments) {
|
||||
if (cls == null) {
|
||||
return null;
|
||||
}
|
||||
int currentIndex = 0;
|
||||
for (final Method m : cls.getDeclaredMethods()) {
|
||||
if ((returning == null || m.getReturnType().equals(returning)) && m.getParameterTypes().length == amountOfArguments
|
||||
&& index == currentIndex++) {
|
||||
m.setAccessible(true);
|
||||
return m;
|
||||
}
|
||||
}
|
||||
if (cls.getSuperclass() != null) {
|
||||
return getMethod(cls.getSuperclass(), returning, index);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Method getMethodCheckContainsString(Class<?> cls, String nameContainsThisStr, Class<?> returning) {
|
||||
if (cls == null) {
|
||||
return null;
|
||||
|
||||
@@ -31,7 +31,6 @@ import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spigotmc.SpigotConfig;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
@@ -95,10 +94,6 @@ public final class ServerUtils {
|
||||
return npcManager;
|
||||
}
|
||||
|
||||
public boolean isBungeeCordEnabled() {
|
||||
return SpigotConfig.bungee;
|
||||
}
|
||||
|
||||
public BoundingBox getEntityBoundingBox(Entity entity) {
|
||||
Object nmsEntity = NMSUtils.getNMSEntity(entity);
|
||||
Object aabb = NMSUtils.getNMSAxisAlignedBoundingBox(nmsEntity);
|
||||
|
||||
@@ -43,11 +43,28 @@ public enum ServerVersion {
|
||||
v_1_15(573), v_1_15_1(575), v_1_15_2(578),
|
||||
v_1_16(735), v_1_16_1(736), v_1_16_2(751), v_1_16_3(753), v_1_16_4(754), v_1_16_5(754),
|
||||
v_1_17(755), v_1_17_1(756),
|
||||
v_1_18(757), v_1_18_1(757),
|
||||
v_1_18(757), v_1_18_1(757), v_1_18_2(758),
|
||||
v_1_19(759), v_1_19_1(760), v_1_19_2(760), v_1_19_3(761), v_1_19_4(762),
|
||||
//Same protocol version for 1.20 and 1.20.1. Same protocol version for 1.20.3 and 1.20.4.
|
||||
//Same protocol version for 1.20.5 and 1.20.6.
|
||||
v_1_20(763), v_1_20_1(763), v_1_20_2(764), v_1_20_3(765), v_1_20_4(765), v_1_20_5(766), v_1_20_6(766),
|
||||
v_1_21(767),
|
||||
//TODO Update (checkpoint)
|
||||
ERROR(-1);
|
||||
|
||||
private static final String NMS_VERSION_SUFFIX = Bukkit.getServer().getClass().getPackage().getName()
|
||||
.replace(".", ",").split(",")[3];
|
||||
private static final String NMS_VERSION_SUFFIX, OBC_DIRECTORY;
|
||||
|
||||
static {
|
||||
String cbPackage = Bukkit.getServer().getClass().getPackage().getName();
|
||||
String temp;
|
||||
try {
|
||||
temp = cbPackage.replace(".", ",").split(",")[3];
|
||||
} catch (Exception ex) {
|
||||
temp = "";
|
||||
}
|
||||
NMS_VERSION_SUFFIX = temp + ".";
|
||||
OBC_DIRECTORY = cbPackage + ".";
|
||||
}
|
||||
private static final ServerVersion[] VALUES = values();
|
||||
public static ServerVersion[] reversedValues = new ServerVersion[VALUES.length];
|
||||
private static ServerVersion cachedVersion;
|
||||
@@ -124,11 +141,11 @@ public enum ServerVersion {
|
||||
}
|
||||
|
||||
public static String getOBCDirectory() {
|
||||
return "org.bukkit.craftbukkit." + (getNMSSuffix());
|
||||
return OBC_DIRECTORY;
|
||||
}
|
||||
|
||||
public static ServerVersion getLatest() {
|
||||
return reversedValues[0];
|
||||
return reversedValues[1];
|
||||
}
|
||||
|
||||
public static ServerVersion getOldest() {
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
name: packetevents
|
||||
version: 1.8.4
|
||||
main: io.github.retrooper.packetevents.PacketEventsPlugin
|
||||
author: retrooper
|
||||
softdepend:
|
||||
- ProtocolLib
|
||||
- ProtocolSupport
|
||||
- ViaVersion
|
||||
- Geyser-Spigot
|
||||
Reference in new issue
Block a user