Skip to content

Commit

Permalink
Fix WrappedPacketInCustomPayload and added CONFIG packet event
Browse files Browse the repository at this point in the history
  • Loading branch information
retrooper committed Oct 7, 2023
1 parent 012bcae commit 289a711
Show file tree
Hide file tree
Showing 10 changed files with 222 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@
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.custompayload.WrappedPacketInCustomPayload;
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.setslot.WrappedPacketOutSetSlot;
Expand All @@ -31,6 +33,8 @@
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() {
Expand All @@ -54,6 +58,24 @@ public void onPacketPlayReceive(PacketPlayReceiveEvent event) {
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());
System.out.println("name: " + cp.getChannelName());
if (cp.getChannelName().contains("brand")) {
System.out.println("Data: " + ((new String(cp.getData(), StandardCharsets.UTF_8))));
}
}
}
@Override
public void onPacketConfigReceive(PacketConfigReceiveEvent event) {
if (event.getPacketId() == PacketType.Play.Client.CUSTOM_PAYLOAD) {
WrappedPacketInCustomPayload cp = new WrappedPacketInCustomPayload(event.getNMSPacket());
System.out.println("name: " + cp.getChannelName());
if (cp.getChannelName().contains("brand")) {
System.out.println("Data: " + ((new String(cp.getData(), StandardCharsets.UTF_8))));
}
}
}
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ public void onPacketLoginReceive(PacketLoginReceiveEvent event) {
public void onPacketLoginSend(PacketLoginSendEvent event) {
}

public void onPacketConfigReceive(PacketConfigReceiveEvent event) {
}

public void onPacketConfigSend(PacketConfigSendEvent event) {
}

public void onPacketPlayReceive(PacketPlayReceiveEvent event) {
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@
* @since 1.8
*/
public enum PacketState {
STATUS, HANDSHAKING, LOGIN, PLAY
STATUS, HANDSHAKING, LOGIN, CONFIG, PLAY
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,15 @@
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;
private static Method CUSTOM_PACKET_PAYLOAD_MINECRAFT_KEY, CUSTOM_PACKET_PAYLOAD_PACKETDATASERIALIZER;
private static byte isVersion_1_17 = -1;

public WrappedPacketInCustomPayload(NMSPacket packet) {
super(packet);
Expand All @@ -38,26 +43,67 @@ public WrappedPacketInCustomPayload(NMSPacket packet) {
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);
}
}

private Object getModernPayloadObject() {
return readObject(0, CUSTOM_PACKET_PAYLOAD);
}

public String getChannelName() {
if (strPresent) {
if (customPacketPayloadPresent) {
Object payload = getModernPayloadObject();
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);
}
}

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);
}
}

public byte[] getData() {
if (byteArrayPresent) {
if (customPacketPayloadPresent) {
Object payload = getModernPayloadObject();
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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,14 @@ public PacketData read(Player player, Object channel, Object packet) {
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);
Expand Down Expand Up @@ -157,6 +165,17 @@ public PacketData write(Player player, Object channel, Object packet) {
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);
Expand Down Expand Up @@ -323,7 +342,11 @@ private PacketState getPacketState(Player player, Object packet) {
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;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

public interface ByteBufUtil {

Object buffer();

Object newByteBuf(byte[] data);

void retain(Object byteBuf);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@

public final class ByteBufUtil_7 implements ByteBufUtil {

@Override
public Object buffer() {
return Unpooled.buffer();
}

@Override
public Object newByteBuf(byte[] data) {
return Unpooled.wrappedBuffer(data);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@

public final class ByteBufUtil_8 implements ByteBufUtil {

@Override
public Object buffer() {
return Unpooled.buffer();
}

@Override
public Object newByteBuf(byte[] data) {
return Unpooled.wrappedBuffer(data);
Expand Down

0 comments on commit 289a711

Please sign in to comment.